青蛙小白
目录

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 分钟

这是一个简单的预估,为每一步实际分配的时间取决于问题的复杂程度和面试官的要求。

评论