4

系统设计面试 5 步曲

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=Mzg3NjU1NzM1Mw%3D%3D&%3Bmid=2247487468&%3Bidx=1&%3Bsn=236ae67ade24b3310d2a4183da1aa649&%3Bchksm=cf312aaaf846a3bca24d6bd1d153c18052c7d3c72106261bdd190bb55bc34f3e0e01ff2fd0ba&%3Btoken=889455774&%3Blang=zh_CN
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

B3I3euq.jpg!mobile

Photo by  Cookie the Pom  on  Unsplash

今天说说  System Design 的话题。

现在,越来越多的大厂会考察候选人的系统设计能力。和算法面试不同, 系统设计面试题常常是开放式的,没有所谓的正确 或错误答案。 系统设计 注重候选 人的 能力,对需求的分解能力,以及在 试过程中和面试官之间的沟通能力。

系统 力,通常来源于 过往 目经验的积累和沉淀。但并不是说,项目做得多,系统设计能力一定强,如果总是  CRUD ,架构能力就会受限。除了需满足基本的功能, 系统 往往更侧重考察候选人怎么应对 大规模复杂系统的挑战

以下,结合自身的架构经验和系统设计面试经验,总结了一些 “套路”, Enjoy ~

iIfMnae.png!mobile

1. 理解需求

我们需要明确系统设计的首要目标:满足需求。或者更狭隘地说,是满足面试官提出的需求。

需求一般包括功能性需求和非功能性需求两方面。

  • 功能性需求

    功能性需求,是指显性的需求,是用户切切实实能看到,能用到的功能。功能性需求是一个系统设计的主要目标,也是 baseline

    简单的说,功能性需求,就是明确在具体哪个场景下,输入什么,输出什么,怎么实现输入和输出的函数关系。

  • 非功能需求

    非功能 性需求,是指非显性的需求。通常会涉及 用性、可扩展性、可靠性、高并发等要求。

    我们和面试官沟通明确功能性需求的同时,也要明确,要设计的系统大概有多少的用户,高峰期的 QPS  在哪个数量级,接口响应时间需要做到多少毫秒等。

2.  设计整体架构图

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

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

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

AVfMVfz.png!mobile

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK