系统设计面试技巧:从高级设计到深入研究

本文首发于公众号:更AI (power_ai),欢迎关注,编程、AI干货及时送!

面试

你刚刚得到了梦寐以求的公司现场面试机会。招聘协调员给你发送了当天的日程安排。扫视这个列表,你对此感到非常满意,直到你的目光落在这个面试环节上——系统设计面试。

系统设计面试经常让人感到紧张。问题可能含糊如“设计一个知名的产品X?”。问题含糊不清,似乎过于宽泛。你的疲倦可以理解。毕竟,谁能在一个小时内设计出一个需要数百甚至数千名工程师来构建的热门产品呢?

好消息是没有人期望你能做到。真实世界的系统设计极其复杂。例如,Google搜索看似简单,但支撑这种简单性的技术数量真的令人震惊。如果没有人期望你在一个小时内设计一个真实世界的系统,那么系统设计面试有什么好处呢?

系统设计面试模拟了现实生活中的问题解决,其中两位同事在一个模糊的问题上进行合作,并找出一个满足他们目标的解决方案。问题是开放式的,没有完美的答案。与你投入设计过程的工作相比,最后的设计不那么重要。这使你能够展示你的设计技巧,捍卫你的设计选择,并以建设性的方式回应反馈。

让我们换个角度,考虑面试官走进会议室见到你时的想法。面试官的主要目标是准确地评估你的能力。她最不希望的是由于面试进展不顺,没有足够的信号,而给出无定论的评价。面试官在系统设计面试中在寻找什么?

许多人认为系统设计面试完全关注一个人的技术设计能力。但它的意义远超过这一点。一场有效的系统设计面试能够明确反映出一个人的合作能力、在压力下工作的能力,以及以建设性方式解决模糊性的能力。提出好问题的能力也是一项必要的技能,许多面试官特别关注这一技能。

一个好的面试官也会寻找警示信号。过度工程化是许多工程师的一个真正问题,因为他们喜欢设计的纯粹性,忽略了权衡。他们通常没有意识到过度工程化系统的复合成本,许多公司为这种无知付出了高昂的代价。在系统设计面试中,你当然不想展示出这种倾向。其他警示信号包括思维狭隘、固执等。

在本章中,我们将介绍一些有用的提示,并引入一个简单而有效的框架来解决系统设计面试问题。

有效的系统设计面试的四步过程

每场系统设计面试都是不同的。一场优秀的系统设计面试是开放式的,没有一种解决方案能适用于所有情况。然而,每场系统设计面试都有一些步骤和常见领域需要涵盖。

步骤1 - 理解问题并确定设计范围

“为什么老虎会吼叫?”

班级后面有只手快速地举了起来。

“是的,吉米?”,老师回答道。

“因为他饿了。”

“很好,吉米。”

在他的童年里,吉米总是第一个回答课堂问题的孩子。无论他是否知道答案,每当老师提出问题时,教室里总有一个孩子喜欢试图回答问题。那个孩子就是吉米。

吉米是个优秀的学生。他以快速知道所有答案为荣。在考试中,他通常是第一个完成问题的人。他是老师在任何学术比赛中的首选。

但是,别像吉米一样。

在系统设计面试中,未经思考就迅速给出答案并无加分。未全面理解需求就回答,这是一个巨大的警示标志,因为面试并不是一个知识问答比赛,没有正确答案。

所以,不要立刻跳进去给出一个解决方案。放慢速度。深入思考,询问问题以澄清需求和假设。这是极其重要的。

作为工程师,我们喜欢解决困难的问题并立即进入最终设计阶段;然而,这种方法可能会导致你设计错误的系统。作为一名工程师最重要的技能之一就是能提出正确的问题,做出合适的假设,并收集构建系统所需的所有信息。所以,不要害怕提问。

当你提出一个问题时,面试官要么直接回答你的问题,要么让你做出自己的假设。如果后者发生,就把你的假设写在白板或纸上。你可能稍后需要它们。

需要问哪些问题呢?提问以理解确切的需求。以下是一些帮助你开始的问题:

  • 我们打算构建哪些具体功能?
  • 产品有多少用户?
  • 公司预计的扩张速度有多快?预计在3个月、6个月和一年内的规模是多少?
  • 公司的技术栈是什么?有哪些现有的服务可能帮助你简化设计?

例子

如果你被要求设计一个新闻订阅系统,你需要问一些能帮助你澄清需求的问题。你和面试官之间的对话可能如下所示:

候选人 :这是一个移动应用还是一个网页应用?或者两者都有?

面试官 :两者都有。

候选人 :产品最重要的功能是什么?
面试官 :发布帖子并查看朋友的新闻订阅。

候选人 :新闻订阅是按照逆时间顺序排列,还是按照特定顺序排列?特定顺序意味着每篇帖子都有不同的权重。例如,来自你亲密朋友的帖子比来自群组的帖子更重要。
面试官 :为了简化问题,我们假设订阅是按照逆时间顺序排序的。

候选人 :一个用户可以拥有多少个朋友?
面试官 :5000个。

候选人 :流量量是多少?
面试官 :每日活跃用户(DAU)1000万。

候选人 :订阅内容可以包含图片、视频,还是只包含文本?
面试官 :它可以包含媒体文件,包括图片和视频。

以上是一些你可以向面试官提问的示例问题。理解需求并澄清模糊性非常重要。

步骤2 - 提出高级设计并获得认可

在这一步,我们的目标是制定一个高级设计,并与面试官就设计达成一致。在这个过程中与面试官合作是个好主意。

  • 提出设计的初始蓝图。征求反馈。把你的面试官当作队友,一起工作。许多好的面试官喜欢讨论并参与其中。
  • 在白板或纸上画出包含关键组件的盒图。这可能包括客户端(移动/网页)、API、网络服务器、数据存储、缓存、CDN、消息队列等。
  • 进行粗略计算,评估你的蓝图是否符合规模限制。大声思考。在深入前,如果需要做粗略计算,先与面试官沟通。

如果可能,通过一些具体的用例。这将帮助你框架出高级设计。这也可能帮助你发现你尚未考虑到的边缘情况。

我们是否应该在这里包含API端点和数据库模式?这取决于问题。对于像“设计Google搜索引擎”这样的大型设计问题,这有点太低级了。对于像设计多人扑克游戏后端这样的问题,这是公平的。与面试官沟通。

示例

让我们用“设计一个新闻推送系统”来演示如何处理高级设计。这里你不需要理解系统实际如何工作。所有的细节将在第11章中解释。

在高级别上,设计分为两个流程:信息发布和新闻推送的构建。

  • 信息发布:当用户发布一条信息时,相应的数据会被写入缓存/数据库,并且这条信息会被推送到朋友的新闻推送中。

  • 新闻推送构建:新闻推送是通过按照时间倒序排列朋友们的帖子来构建的。

图3-1和图3-2分别展示了信息发布和新闻推送构建流程的高级设计。

系统设计面试技巧:从高级设计到深入研究_第1张图片

系统设计面试技巧:从高级设计到深入研究_第2张图片

第3步 - 深入设计

在这一步,你和面试官应该已经达成了以下目标:

  • 对总体目标和功能范围达成一致
  • 勾画出整体设计的高级蓝图
  • 从面试官那里获得了对高级设计的反馈
  • 根据她的反馈,对深入研究的领域有了一些初步的想法

你应该和面试官一起确定并优先考虑架构中的组件。值得强调的是,每次面试都是不同的。有时,面试官可能会暗示她喜欢关注高级设计。有时,对于一个高级候选人面试,讨论可能会集中在系统性能特性上,很可能会关注瓶颈和资源估计。在大多数情况下,面试官可能希望你深入探讨一些系统组件的细节。对于URL短链接,深入研究将长URL转换为短URL的哈希函数设计是有趣的。对于聊天系统,如何降低延迟和如何支持在线/离线状态是两个有趣的话题。

时间管理非常重要,因为很容易被那些无法展示你能力的细节所牵引。你必须拿出一些证据来展示给你的面试官。尽量不要陷入不必要的细节。例如,在系统设计面试中详细讨论Facebook信息流排名的EdgeRank算法并不理想,因为这会花费大量宝贵的时间,而且不能证明你设计可扩展系统的能力。

示例

此时,我们已经讨论了新闻推送系统的高级设计,面试官对你的提议表示满意。接下来,我们将研究两个最重要的用例:

  1. 动态发布
  2. 新闻推送获取

图3-3和图3-4展示了这两个用例的详细设计,这将在第11章中详细解释。

系统设计面试技巧:从高级设计到深入研究_第3张图片

第四步 - 总结

在最后这个步骤,面试官可能会问你一些后续问题,或者给你自由讨论其他额外的点。以下是一些可能的方向:

  • 面试官可能希望你找出系统的瓶颈,并讨论可能的改进。永远不要说你的设计是完美的,没有什么可以改进的。总有一些地方可以改进。这是展示你的批判性思维并留下好的最后印象的大好机会。
  • 对面试官回顾一下你的设计可能会很有用。如果你提出了一些解决方案,这一点特别重要。在一次长时间的讨论后,刷新面试官的记忆可能会有所帮助。
  • 错误情况(服务器故障、网络中断等)都值得谈论。
  • 运维问题也值得一提。你如何监控指标和错误日志?如何推出系统?
  • 如何应对下一次规模曲线也是一个有趣的话题。例如,如果你当前的设计支持100万用户,你需要做什么改变来支持1000万用户?
  • 如果你有更多的时间,提出你需要的其他改进。

总的来说,我们总结了一份应该做和不应该做的清单。

应该做的

  • 总是要求澄清。不要假设你的假设是正确的。
  • 理解问题的需求。
  • 没有正确答案也没有最好的答案。为初创公司设计的解决方案与为拥有百万用户的成熟公司设计的解决方案是不同的。确保你理解需求。
  • 让面试官知道你在想什么。与你的面试官沟通。
  • 如果可能,提出多种方法。
  • 一旦你和面试官就设计蓝图达成一致,就详细讲解每个组成部分。先设计最关键的部分。
  • 向面试官提出想法。一个好的面试官会作为队友与你一起工作。
  • 永不放弃。

不应该做的

  • 不要对典型的面试问题毫无准备。
  • 不要在没有澄清需求和假设的情况下跳入解决方案。
  • 刚开始不要对单个组件详细讲解太多。首先给出高层设计,然后再深入研究。
  • 如果你遇到困难,不要犹豫要求提示。
  • 再次强调,进行沟通。不要静默思考。
  • 不要认为一旦你给出设计,你的面试就结束了。除非面试官说你结束了,否则你并没有结束。尽早并经常询问反馈。

每个步骤的时间分配

系统设计面试问题通常非常宽泛,而45分钟或一个小时的时间不足以覆盖整个设计。时间管理至关重要。你应该在每个步骤上花费多少时间呢?以下是一个非常粗略的指南,它告诉你如何在45分钟的面试环节中分配时间。请记住,这只是一个大致的估计,实际的时间分配取决于问题的范围和面试官的需求。

步骤1 理解问题并确定设计范围:3 - 10分钟

步骤2 提出高层设计并获得认可:10 - 15分钟

步骤3 深入设计:10 - 25分钟

步骤4 结束:3 - 5分钟

你好,我是拾叁,7年开发老司机、互联网两年外企5年。怼得过阿三老美,也被PR comments搞崩溃过。这些年我打过工,创过业,接过私活,也混过upwork。赚过钱也亏过钱。一路过来,给我最深的感受就是不管学什么,一定要不断学习。只要你能坚持下来,就很容易实现弯道超车!所以,不要问我现在干什么是否来得及。如果你还没什么方向,可以先关注我[公众号:更AI (power_ai)],这里会经常分享一些前沿资讯和编程知识,帮你积累弯道超车的资本。

你可能感兴趣的:(系统设计,面试,系统架构,设计规范)