3 系统设计面试
你刚刚获得了梦想公司梦寐以求的现场面试机会。HR给你发来了当天的日程安排。扫了一眼名单,你感觉良好,直到你的目光落到了这个面试环节--系统设计面试。
系统设计面试通常让人望而生畏。可能是"设计一款知名产品 X"这样含糊不清的问题。问题模棱两可,似乎宽泛得不合理。你的疲惫是可以理解的。毕竟怎么可能有人会在一小时内设计出一款流行产品,而这款产品可是花费了成百上千名工程师的心血?
好在没人指望你能做到。现实世界的系统设计极其复杂。例如,谷歌搜索简单得令人难以置信;然而,支撑这种简单性的技术之多却着实令人吃惊。如果没人指望你在一小时内设计出一个真实世界的系统,那么系统设计面试又有什么好处呢?
系统设计面试模拟现实生活中的问题解决方式,让两个同事合作解决一个模糊的问题,并提出符合他们目标的解决方案。问题是开放式的,没有完美的答案。与你在设计过程中所付出的努力相比,最终的设计并不那么重要。这可以让你展示你的设计技巧,为你的设计选择辩护,并以建设性的方式回应反馈。
让我们换位思考一下,当面试官走进会议室与你见面时,她的脑子里在想些什么。面试官的首要目标是准确评估你的能力。她最不愿意看到的是,由于会议进行得不顺利,没有足够的信号,而给出不确定的评估。面试官在系统设计面试中需要注意什么?
很多人认为,系统设计面试就是考察技术设计能力。其实远不止这些。有效的系统设计面试会发出强烈的信号,显示一协作能力、在压力下工作的能力以及建设性地解决模糊问题的能力。提出好问题的能力也是一项基本技能,许多面试官都特别看重这项技能。
过度工程化是许多工程师的通病,因为他们乐于追求设计的纯粹性,而忽视了权衡利弊。他们往往没有意识到过度工程化系统所带来的复合成本,而许多公司都为这种无知付出了高昂的代价。你肯定不想在系统设计面试中表现出这种倾向。其他警示还包括思想狭隘、固执己见等。
在本章中,我们将介绍一些有用的技巧,并介绍一个简单有效的框架来解决系统设计面试问题。
3.1 有效系统设计面试的四步法
每个系统设计面试都是不同的。优秀的系统设计面试是开放式的,没有放之四海而皆准的解决方案。不过,每次系统设计面试都有一些步骤和共同点。
3.1.1 步骤1理解问题并确定设计范围
"老虎为什么吼叫?教室后面有人举起了手。"是的,吉米?"老师回答道。
"因为他饿了"。
"很好,吉米"
在吉米的童年里,他一直是班上第一个回答问题的人。每当老师提问时,教室里总有一个孩子不管自己是否知道答案,都喜欢抢着回答问题。这就是吉米。
吉米是个王牌学生。他以快速知道所有答案为荣。在考试中,他通常是第一个答完题的人。在任何学科竞赛中,他都是老师的首选。
不要像吉米一样。
在系统设计面试中,不假思索地快速给出答案不会给你加分。在没有透彻理解要求的情况下回答问题会让人大跌眼镜,因为面试不是小题大做。没有正确的答案。
因此,不要马上就给出解决方案。放慢速度。深入思考并提出问题,以澄清需求和假设。这一点非常重要。
作为一名工程师,我们喜欢解决棘手的问题并立即投入最终设计;然而,这种方法很可能会导致你设计出错误的系统。作为工程师,最重要的技能之一就是提出正确的问题,做出适当的假设,并收集构建系统所需的所有信息。因此,不要害怕提问。
当你提问时,面试官要么直接回答你的问题,要么要求你做出假设。如果是后者,请在白板或纸上写下你的假设。您以后可能会用到它们。
问什么样的问题?提问是为了了解确切的需求。以下是一份问题清单,可以帮助你开始提问:
- 我们要构建哪些具体功能?
- 产品有多少用户?
- 公司预计以多快的速度扩大规模?预计3个月、6个月和1年后的规模是多少?
-公司的技术栈是什么?您可以利用哪些现有服务来简化设计?
3.1.1.1 举例说明
如果要求你设计一个新闻推送系统,你需要提出一些有助于明确需求的问题。你和面试官之间的对话可能是这样的:
- 应聘者:这是移动应用程序吗?还是Web应用?还是两者都要?
- 面试官: 都是。
- 应聘者:产品最重要的功能是什么?
- 面试官 发布帖子和查看好友新闻推送的功能。
- 候选人:新闻推送是按时间倒序还是特定顺序排列的?特定顺序意味着每个帖子的权重不同。例如,来自好友的帖子比来自群组的帖子更重要。
- 面试官 为了简单起见,我们假设信息源是按时间倒序排序的。
- 候选人:一个用户可以有多少个好友?
- 面试官 5000
- 应聘者:流量是多少?
- 面试官 1000万日活跃用户(DAU)
- 应聘者:Feed可以包含图片、视频,还是只有文字?
- 面试官:可以包含媒体文件,包括图片和视频。
以上是您可以向面试官提出的一些示例问题。重要的是要理解需求并澄清模糊之处
3.1.2 步骤2提出高层次设计并获得认同
在这一步中,我们的目标是制定一个高层次的设计方案,并与面试官就设计方案达成一致。在此过程中,与面试官合作是个好主意。
-
提出设计的初步蓝图。征求反馈意见。把面试官当作队友,一起工作。许多优秀的面试官都喜欢谈论和参与。
-
在白板或纸上绘制包含关键组件的框图。这可能包括客户端(移动/网络)、API、网络服务器、数据存储、缓存、CDN、消息队列等。
-
进行包络(back-of-the-envelope)计算,评估你的蓝图是否符合规模限制。
如果可能,请举出几个具体的使用案例。这将有助于你确定高层次设计的框架。这些用例还可能帮助你发现尚未考虑的边缘情况。
我们是否应该在这里包含应用程序接口端点和数据库模式?这取决于问题的具体情况。对于像"设计Google搜索引擎"这样的大型设计问题来说,这有点太低级了。而对于为多人扑克游戏设计后台这样的问题来说,这倒是可以考虑的。与面试官沟通。
3.1.2.1 举例说明
让我们用"设计新闻源系统"来演示如何进行高级设计。在这里,你不需要了解系统的实际工作原理。第11章将解释所有细节。
在高层,设计分为两个流程:新闻源发布和新闻源构建。
- Feed发布:当用户发布帖子时,相应的数据会被写入缓存/数据库,帖子会被填充到好友的新闻源中。
- Newsfeed构建:按时间倒序聚合好友的帖子,构建新闻源。
参考资料
- 软件测试精品书籍文档下载持续更新 https://github.com/china-testing/python-testing-examples 请点赞,谢谢!
- 本文涉及的python测试开发库 谢谢点赞! https://github.com/china-testing/python_cn_resouce
- python精品书籍下载 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
- Linux精品书籍下载 https://www.cnblogs.com/testing-/p/17438558.html
- https://www.drawio.com/doc/faq/
3.1.3 步骤3深入设计
在这一步,您和您的面试官应该已经实现了以下目标:
- 商定总体目标和功能范围
- 勾勒出整体设计的高层次蓝图
- 获得面试官对高层次设计的反馈意见
- 根据面试官的反馈,对深入设计的重点领域有了一些初步想法
您应与面试官一起确定架构中的组件并确定其优先级。值得强调的是,每次面试都是不同的。有时,面试官可能会暗示她喜欢关注高层设计。有时,对于资深候选人的面试,讨论的可能是系统性能特征,重点可能是瓶颈和资源估算。在大多数情况下,面试官可能希望你深入探讨一些系统组件的细节。对于URL缩短器,深入探讨将长URL转换为短URL的哈希函数设计很有意思。对于聊天系统,如何减少延迟以及如何支持在线/离线状态是两个有趣的话题。
时间管理至关重要,因为您很容易被细枝末节所迷惑,而无法展现自己的能力。您必须准备好向面试官展示自己的信号。尽量不要涉及不必要的细节。例如,在系统设计面试中,详细谈论Facebook feed排名的EdgeRank算法并不理想,因为这会耗费大量宝贵时间,也无法证明你设计可扩展系统的能力。
3.1.3.1 示例
至此,我们已经讨论了新闻源系统的高层次设计,面试官对你的建议很满意。接下来,我们将研究两个最重要的用例:
-
Feed发布
-
新Feed检索
图3-3和图 3-4显示了这两个用例的详细设计,第11章将对此进行详细说明。
3.1.4 步骤4总结
在最后一步,面试官可能会问你一些后续问题,或者让你自由讨论其他问题。以下是一些应遵循的方向:
- 面试官可能希望您找出系统瓶颈,并讨论可能的改进措施。永远不要说你的设计是完美的,没有什么可以改进的。总有一些地方需要改进。这是展示您的批判性思维并给面试官留下良好印象的绝佳机会。
- 给面试官总结一下你的设计可能会有帮助。如果您提出了一些解决方案,这一点尤为重要。在长时间的讨论后,让面试官恢复记忆会很有帮助。
- 错误案例(服务器故障、网络丢失等)值得一谈。
- 运营问题值得一提。如何监控指标和错误日志?如何推出系统?
- 如何处理下一个规模曲线也是一个有趣的话题。例如,如果您当前的设计支持100万用户,那么要支持1000万用户,您需要做出哪些改变?
-如果您有更多时间,请提出您需要的其他改进措施。
最后,我们总结了一份"该做"和"不该做"的清单。
3.1.4.1 应该
- 始终要求澄清。不要认为你的假设是正确的。
- 了解问题的要求。
- 既没有正确答案,也没有最佳答案。为解决年轻初创公司的问题而设计的解决方案与为解决拥有数百万用户的成熟公司的问题而设计的解决方案是不同的。确保了解需求。
- 让面试官知道你在想什么。与面试官沟通。
- 如果可能,建议采用多种方法。
- 与面试官就蓝图达成一致后,深入了解每个组件的细节。先设计最关键的部分。
- 与面试官交流想法。好的面试官会把你当作队友来合作。
- 永不放弃。
3.1.4.2 不应该
- 不要对典型的面试问题毫无准备。
- 在未明确需求和假设之前,不要贸然提出解决方案。
- 不要在一开始就对单个组件进行过于详细的介绍。先给出高层次的设计,然后再深入研究。
- 如果遇到困难,不要犹豫,寻求提示。
- 再次,沟通。不要在沉默中思考。
- 不要以为给出设计方案后面试就结束了。直到面试官说你完成了,你才算完成。尽早并经常征求反馈意见。
3.1.5 时间管理
系统设计面试问题通常都很宽泛,45分钟或一个小时不足以涵盖整个设计。时间管理至关重要。你应该在每个步骤上花费多少时间?以下是45分钟面试时间分配的粗略指南。请记住,这只是粗略的估计,实际的时间分配取决于问题的范围和面试官的要求。
- 了解问题并确定设计范围: 3 - 10 分钟
- 提出高层次设计并获得认同:10 - 15 分钟
- 深入设计:10 - 25 分钟
- 总结: 3 - 5 分钟