本文首发于公众号:更AI (power_ai),欢迎关注,编程、AI干货及时送!
你刚刚得到了梦寐以求的公司现场面试机会。招聘协调员给你发送了当天的日程安排。扫视这个列表,你对此感到非常满意,直到你的目光落在这个面试环节上——系统设计面试。
系统设计面试经常让人感到紧张。问题可能含糊如“设计一个知名的产品X?”。问题含糊不清,似乎过于宽泛。你的疲倦可以理解。毕竟,谁能在一个小时内设计出一个需要数百甚至数千名工程师来构建的热门产品呢?
好消息是没有人期望你能做到。真实世界的系统设计极其复杂。例如,Google搜索看似简单,但支撑这种简单性的技术数量真的令人震惊。如果没有人期望你在一个小时内设计一个真实世界的系统,那么系统设计面试有什么好处呢?
系统设计面试模拟了现实生活中的问题解决,其中两位同事在一个模糊的问题上进行合作,并找出一个满足他们目标的解决方案。问题是开放式的,没有完美的答案。与你投入设计过程的工作相比,最后的设计不那么重要。这使你能够展示你的设计技巧,捍卫你的设计选择,并以建设性的方式回应反馈。
让我们换个角度,考虑面试官走进会议室见到你时的想法。面试官的主要目标是准确地评估你的能力。她最不希望的是由于面试进展不顺,没有足够的信号,而给出无定论的评价。面试官在系统设计面试中在寻找什么?
许多人认为系统设计面试完全关注一个人的技术设计能力。但它的意义远超过这一点。一场有效的系统设计面试能够明确反映出一个人的合作能力、在压力下工作的能力,以及以建设性方式解决模糊性的能力。提出好问题的能力也是一项必要的技能,许多面试官特别关注这一技能。
一个好的面试官也会寻找警示信号。过度工程化是许多工程师的一个真正问题,因为他们喜欢设计的纯粹性,忽略了权衡。他们通常没有意识到过度工程化系统的复合成本,许多公司为这种无知付出了高昂的代价。在系统设计面试中,你当然不想展示出这种倾向。其他警示信号包括思维狭隘、固执等。
在本章中,我们将介绍一些有用的提示,并引入一个简单而有效的框架来解决系统设计面试问题。
每场系统设计面试都是不同的。一场优秀的系统设计面试是开放式的,没有一种解决方案能适用于所有情况。然而,每场系统设计面试都有一些步骤和常见领域需要涵盖。
“为什么老虎会吼叫?”
班级后面有只手快速地举了起来。
“是的,吉米?”,老师回答道。
“因为他饿了。”
“很好,吉米。”
在他的童年里,吉米总是第一个回答课堂问题的孩子。无论他是否知道答案,每当老师提出问题时,教室里总有一个孩子喜欢试图回答问题。那个孩子就是吉米。
吉米是个优秀的学生。他以快速知道所有答案为荣。在考试中,他通常是第一个完成问题的人。他是老师在任何学术比赛中的首选。
但是,别像吉米一样。
在系统设计面试中,未经思考就迅速给出答案并无加分。未全面理解需求就回答,这是一个巨大的警示标志,因为面试并不是一个知识问答比赛,没有正确答案。
所以,不要立刻跳进去给出一个解决方案。放慢速度。深入思考,询问问题以澄清需求和假设。这是极其重要的。
作为工程师,我们喜欢解决困难的问题并立即进入最终设计阶段;然而,这种方法可能会导致你设计错误的系统。作为一名工程师最重要的技能之一就是能提出正确的问题,做出合适的假设,并收集构建系统所需的所有信息。所以,不要害怕提问。
当你提出一个问题时,面试官要么直接回答你的问题,要么让你做出自己的假设。如果后者发生,就把你的假设写在白板或纸上。你可能稍后需要它们。
需要问哪些问题呢?提问以理解确切的需求。以下是一些帮助你开始的问题:
例子
如果你被要求设计一个新闻订阅系统,你需要问一些能帮助你澄清需求的问题。你和面试官之间的对话可能如下所示:
候选人 :这是一个移动应用还是一个网页应用?或者两者都有?
面试官 :两者都有。
候选人 :产品最重要的功能是什么?
面试官 :发布帖子并查看朋友的新闻订阅。
候选人 :新闻订阅是按照逆时间顺序排列,还是按照特定顺序排列?特定顺序意味着每篇帖子都有不同的权重。例如,来自你亲密朋友的帖子比来自群组的帖子更重要。
面试官 :为了简化问题,我们假设订阅是按照逆时间顺序排序的。
候选人 :一个用户可以拥有多少个朋友?
面试官 :5000个。
候选人 :流量量是多少?
面试官 :每日活跃用户(DAU)1000万。
候选人 :订阅内容可以包含图片、视频,还是只包含文本?
面试官 :它可以包含媒体文件,包括图片和视频。
以上是一些你可以向面试官提问的示例问题。理解需求并澄清模糊性非常重要。
在这一步,我们的目标是制定一个高级设计,并与面试官就设计达成一致。在这个过程中与面试官合作是个好主意。
如果可能,通过一些具体的用例。这将帮助你框架出高级设计。这也可能帮助你发现你尚未考虑到的边缘情况。
我们是否应该在这里包含API端点和数据库模式?这取决于问题。对于像“设计Google搜索引擎”这样的大型设计问题,这有点太低级了。对于像设计多人扑克游戏后端这样的问题,这是公平的。与面试官沟通。
示例
让我们用“设计一个新闻推送系统”来演示如何处理高级设计。这里你不需要理解系统实际如何工作。所有的细节将在第11章中解释。
在高级别上,设计分为两个流程:信息发布和新闻推送的构建。
信息发布:当用户发布一条信息时,相应的数据会被写入缓存/数据库,并且这条信息会被推送到朋友的新闻推送中。
新闻推送构建:新闻推送是通过按照时间倒序排列朋友们的帖子来构建的。
图3-1和图3-2分别展示了信息发布和新闻推送构建流程的高级设计。
在这一步,你和面试官应该已经达成了以下目标:
你应该和面试官一起确定并优先考虑架构中的组件。值得强调的是,每次面试都是不同的。有时,面试官可能会暗示她喜欢关注高级设计。有时,对于一个高级候选人面试,讨论可能会集中在系统性能特性上,很可能会关注瓶颈和资源估计。在大多数情况下,面试官可能希望你深入探讨一些系统组件的细节。对于URL短链接,深入研究将长URL转换为短URL的哈希函数设计是有趣的。对于聊天系统,如何降低延迟和如何支持在线/离线状态是两个有趣的话题。
时间管理非常重要,因为很容易被那些无法展示你能力的细节所牵引。你必须拿出一些证据来展示给你的面试官。尽量不要陷入不必要的细节。例如,在系统设计面试中详细讨论Facebook信息流排名的EdgeRank算法并不理想,因为这会花费大量宝贵的时间,而且不能证明你设计可扩展系统的能力。
此时,我们已经讨论了新闻推送系统的高级设计,面试官对你的提议表示满意。接下来,我们将研究两个最重要的用例:
图3-3和图3-4展示了这两个用例的详细设计,这将在第11章中详细解释。
在最后这个步骤,面试官可能会问你一些后续问题,或者给你自由讨论其他额外的点。以下是一些可能的方向:
总的来说,我们总结了一份应该做和不应该做的清单。
应该做的
不应该做的
系统设计面试问题通常非常宽泛,而45分钟或一个小时的时间不足以覆盖整个设计。时间管理至关重要。你应该在每个步骤上花费多少时间呢?以下是一个非常粗略的指南,它告诉你如何在45分钟的面试环节中分配时间。请记住,这只是一个大致的估计,实际的时间分配取决于问题的范围和面试官的需求。
步骤1 理解问题并确定设计范围:3 - 10分钟
步骤2 提出高层设计并获得认可:10 - 15分钟
步骤3 深入设计:10 - 25分钟
步骤4 结束:3 - 5分钟
你好,我是拾叁,7年开发老司机、互联网两年外企5年。怼得过阿三老美,也被PR comments搞崩溃过。这些年我打过工,创过业,接过私活,也混过upwork。赚过钱也亏过钱。一路过来,给我最深的感受就是不管学什么,一定要不断学习。只要你能坚持下来,就很容易实现弯道超车!所以,不要问我现在干什么是否来得及。如果你还没什么方向,可以先关注我[公众号:更AI (power_ai)],这里会经常分享一些前沿资讯和编程知识,帮你积累弯道超车的资本。