系统设计面试 5 步曲
2. 设计整体架构图
明确了需求,接下来可以来画一下系统的大体架构了。考虑系统需要涉及哪些模块,这些模块之间的关系,以及数据在这些模块之间是怎么流转的。
通常,我们会画 5-10 个部分表示系统的核心模块。如果系统比较复杂,可能会画更多的模块。具体要将系统分成多少模块,并没有确定的规则,如果有,可以参考领域驱动设计中的 DDD 设计原则(这又是一个很值得探讨的话题,后续谈)。
如下所示,是我在做的一个模拟面试系统的初期架构图。
用户注册或登录后,完善一些技能信息,可以作为面试官来出题,也可以通过系统匹配,和其他人通过在线协作工具进行模拟面试,面试完之后相互评价反馈。底层的数据库有冗余备份。
然后,我们可以将这些组件分解,根据系统的需求进行进一步的详细设计。
3. 模块 详细 设计
系统设计的面试过程中,因为面试时间的限制,不太可能对架构图中的所有模块都做详细设计,而是对其中的关键模块进行详细设计。
在这个步骤中,我们可以分析不同的解决方案,它们各自的优缺点,以及怎么来做权衡,最终选择其中的一种方案。
比如上述模拟面试系统中的答题模块,可能需要更深入考虑以下问题:
-
答题可能会涉及语音和视频,怎么去存储大量的数据?
-
怎么做数据分区,分区之后数据怎么做备份?
-
预约系统的匹配算法怎么设计,让时间和技术背景相对合适的人,进行模拟面试?
-
在线协作过程怎么做回放?是录屏,还是根据信令做增量?
-
哪些地方用缓存?缓存数据怎么做更新,是 Cache Aside 还是异步双写,或其他?
4. 实体和接口设计
有了模块的详细设计,接下来就可以做实体设计了。具体来说就是,根据 OOD 的设计思想,模块中需要哪些 Object , Object 中有哪些成员,对应的数据库表结构怎么设计。
然后再设计 符合 Restful 风格的 接口,注意接口的命名规范。
5. 预估系统规模以及 系统瓶颈
预估系统的规模也是系统设计的重点之一。简单地说,就是设计的这个系统,将来需要部署多少台应用服务器,需要多少的存储容量,需要多大的带宽等。特别是带宽,有时候你会发现,可能应用先挂了,但是服务器内存, cpu ,负载等各项指标是正常的,这时极有可能是网络带宽爆了。
当然,既然是预估,通常就不需要精准的计算,只要预估出一个数量级或者能预估出增长的趋势即可。
知道了系统的规模后,接下来再探讨一下未来系统可能存在的瓶颈。可以 从可用性,可靠性,可扩展性几方面展开,如果系统是分布式的,那么 怎么 在 CAP 中做权衡,权衡后的 解决方案是什么。系统设计,重在权衡!
总结
系统设计是一个很大的话题,以上总结的 5 点是高度浓缩后的简化方案,每一步 也不是严格区分的,更多的时候是穿插在一起进行。
特别需要注意的一点是:系统设计面试的各个环节都需要和面试官交流沟通,把 Ta 想象成就是你未来的同事,不要惜字如金,闷声不响。
最后推荐一下系统设计的 2 个 5 星资源,资料不在多,在于精。
1.《 Designing Data-Intensive Applications 》中文版《 数据密集型应用系统设计》
2. https://github.com/donnemartin/system-design-primer