系统设计面试 5 步曲

2.  设计整体架构图

明确了需求,接下来可以来画一下系统的大体架构了。考虑系统需要涉及哪些模块,这些模块之间的关系,以及数据在这些模块之间是怎么流转的。

通常,我们会画  5-10  个部分表示系统的核心模块。如果系统比较复杂,可能会画更多的模块。具体要将系统分成多少模块,并没有确定的规则,如果有,可以参考领域驱动设计中的 DDD 设计原则(这又是一个很值得探讨的话题,后续谈)。

如下所示,是我在做的一个模拟面试系统的初期架构图。

用户注册或登录后,完善一些技能信息,可以作为面试官来出题,也可以通过系统匹配,和其他人通过在线协作工具进行模拟面试,面试完之后相互评价反馈。底层的数据库有冗余备份。

然后,我们可以将这些组件分解,根据系统的需求进行进一步的详细设计。

3.  模块 详细 设计

系统设计的面试过程中,因为面试时间的限制,不太可能对架构图中的所有模块都做详细设计,而是对其中的关键模块进行详细设计。

在这个步骤中,我们可以分析不同的解决方案,它们各自的优缺点,以及怎么来做权衡,最终选择其中的一种方案。

比如上述模拟面试系统中的答题模块,可能需要更深入考虑以下问题:

  • 答题可能会涉及语音和视频,怎么去存储大量的数据?

  • 怎么做数据分区,分区之后数据怎么做备份?

  • 预约系统的匹配算法怎么设计,让时间和技术背景相对合适的人,进行模拟面试?

  • 在线协作过程怎么做回放?是录屏,还是根据信令做增量?

  • 哪些地方用缓存?缓存数据怎么做更新,是 Cache Aside 还是异步双写,或其他?

4.  实体和接口设计

有了模块的详细设计,接下来就可以做实体设计了。具体来说就是,根据 OOD 的设计思想,模块中需要哪些 Object Object 中有哪些成员,对应的数据库表结构怎么设计。

然后再设计 符合   Restful 风格的 接口,注意接口的命名规范。

5. 预估系统规模以及 系统瓶颈

预估系统的规模也是系统设计的重点之一。简单地说,就是设计的这个系统,将来需要部署多少台应用服务器,需要多少的存储容量,需要多大的带宽等。特别是带宽,有时候你会发现,可能应用先挂了,但是服务器内存, cpu ,负载等各项指标是正常的,这时极有可能是网络带宽爆了。

当然,既然是预估,通常就不需要精准的计算,只要预估出一个数量级或者能预估出增长的趋势即可。

知道了系统的规模后,接下来再探讨一下未来系统可能存在的瓶颈。可以 从可用性,可靠性,可扩展性几方面展开,如果系统是分布式的,那么 怎么 在  CAP  中做权衡,权衡后的 解决方案是什么。系统设计,重在权衡!

总结

系统设计是一个很大的话题,以上总结的  5  点是高度浓缩后的简化方案,每一步 也不是严格区分的,更多的时候是穿插在一起进行。

特别需要注意的一点是:系统设计面试的各个环节都需要和面试官交流沟通,把  Ta  想象成就是你未来的同事,不要惜字如金,闷声不响。

最后推荐一下系统设计的  5 星资源,资料不在多,在于精。

1.《 Designing Data-Intensive Applications 》中文版《 数据密集型应用系统设计》

2.  https://github.com/donnemartin/system-design-primer