3. A Framework For System Design Interviews
系统设计面试的框架
系统设计面试令人望而生畏。
你如何在短短一小时内设计一个流行的系统,而其他人却为此花费了数十年?
- 关键在于解决问题的过程,而不是你最终提出的解决方案。
- 目标是展示你的设计技巧,为你的选择辩护,并以建设性的方式回应反馈。
系统设计面试的目标是什么?
- 它远不止于评估一个人的技术设计能力。
- 它还在于评估协作能力、抗压能力、解决歧义的能力以及提出好问题的能力。
- 好的面试官同样也会关注一些危险信号。发现危险信号: 过度设计、心胸狭窄、固执等等。
3.1 有效系统设计面试的四个步骤
虽然每次面试都不同,但在任何面试中都有一些通用的步骤。
3.1.1 第一步: 理解问题并确定设计范围
在充分理解问题之前不要急于给出答案。事实上,在没有充分理解需求就回答可能是一个危险信号。
不要急于给出解决方案。要通过提问来澄清需求和假设。
作为工程师,我们倾向于跳过去解决难题。但这往往会导致设计出错误的系统。
当你得到答案(或者需要自己做出假设)时,把它们写在白板或纸上以免遗忘。
应该问什么问题? - 要理解确切的需求。一些例子:
- 我们需要构建哪些具体功能?
- 产品有多少用户?
- 公司预计多久需要扩展系统?预计3个月、6个月和1年后的系统规模是怎样的?
- 公司的技术栈是什么?可以利用哪些现有服务来简化设计?
比如说你要设计一个news feed(新鲜事信息流)系统,下面是一个对话示例:
- 候选人: 是移动端还是网页端,还是两者都有?
- 面试官: 都有。
- 候选人: 最重要的功能是什么?
- 面试官: 能发帖子并看到朋友的动态。
- 候选人: 帖子是如何排序的?仅按时间顺序还是根据亲密好友的帖子权重排序?
- 面试官: 为了简单起见,假设按时间顺序排序。
- 候选人: 每个用户最多可以有多少好友?
- 面试官: 5000
- 候选人: 流量规模如何?
- 面试官: 1000万日活用户(DAU)
- 候选人: 推送中是否包含媒体内容? - 图片、视频?
- 面试官: 可以包含媒体文件,包括视频和图片。
3.1.2 第二步: 提出高层级设计并获得认可
这一步的目标是制定高层级设计,同时与面试官互动。
- 提出一个设计蓝图,征求反馈。许多优秀的面试官会参与其中。
- 在白板或纸上上画出包含关键组件的框图。包括客户端(移动端,Web端)、API、Web服务器、数据存储、缓存、CDN、消息队列等。
- 做封底估算,评估蓝图是否符合规模约束。事先与面试官沟通是否需要这种估算。
你可以通过一些具体用例来完善设计。这可能帮助你发现边界情况。
是否要包含API端点和数据库schema设计?这取决于具体问题。对于大规模系统来说,这可能太低层级了。要与面试官沟通以确定这一点。
以设计新闻推送为例。 高层级功能:
- feed发布 - 用户创建帖子并将其写入缓存/数据库,然后推送到其他用户的新闻流中。
- feed流构建 - 通过按时序聚合好友的帖子来构建feed流。
图3.1 示例:feed发布:

图3.2 示例:feed流构建:

3.1.3 第三步: 深入设计
到目前为止你应该达到的目标:
- 就总体目标和功能达成一致
- 绘制了设计的高层级蓝图
- 获得了对高层级设计的反馈
- 获得了深入探讨时需要关注的领域的初步想法
在这个阶段,你应该与面试官一起确定优先关注哪些组件。
可能需要关注的示例事项:
- 高层级设计
- 系统性能特征
- 在大多数情况下,深入研究某些系统组件的细节
可以深入哪些细节?一些例子:
- 对于URL缩短器:将长URL转换为短URL的哈希函数
- 对于聊天系统 :降低延迟并支持在线/离线状态
面试中的时间管理很重要:不要过分关注那些无法展示你技能的细节。例如,不要过分关注Facebook的EdgeRank算法是如何工作的,因为这并不能展示你的设计能力。
图3.3 示例:feed发布深入设计:

图3.4 示例:feed流构建深入设计:

3.1.4 第四步: 总结
在这个阶段,面试官可能会问你一些后续问题,或者让你自由讨论任何你想讨论的内容。
以下是一些可以遵循的方向:
- 找出系统瓶颈并讨论改进方案。没有完美的设计,总有需要改进的地方。
- 总结你的设计。
- 故障场景(服务器故障、数据包丢失等)。
- 运维问题(监控、警报、日志、系统部署)。
- 需要进行扩展才能支持下一个规模增长曲线?例如,从100万用户到1000万用户。
- 提出其他改进点。
应该做的:
- 总是向面试官寻求明确的解释。不要认为你的假设是对的。
- 理解问题的需求。
- 没有正确或完美的答案。小公司的解决方案与大公司的解决方案不同。
- 让面试官知道你在想什么。
- 如果有可能,请提出多个方案。
- 一旦你和面试官就设计蓝图达成了一致,然后首先设计最关键的组件。
- 与面试官分享想法。他们应该与你合作。
不应该做的:
- 对于常见的面试问题没有做好准备。
- 在没有弄清需求和假设之前就给出解决方案。
- 一开始不要在单个组件上投入太多细节。最初要进行高层级次的设计。
- 如果遇到困难,思路卡住的时候,可以随时请求提示。
- 沟通,不要默默思考。
- 认为给出设计方案后面试就结束了。记住,面试官说结束才是真的结束。要尽早且尽量频繁地征求面试官的反馈。
3.2 面试中每一步的时间分配
45分钟不足以充分详细地涵盖任何设计。
以下是应该在每个步骤花费的大致时间指南:
- 理解问题并确定设计范围: 3-10 分钟
- 提出高层次设计并获得认可: 10-15 分钟
- 深入设计: 10-25 分钟
- 总结: 3-5 分钟
这是一个简单的预估,为每一步实际分配的时间取决于问题的复杂程度和面试官的要求。