系统设计面试之前需要知道的八件事
原文:Things You Need to Know Before a System Design Interview
译者:飞龙
自豪地采用谷歌翻译
面试准备中最常见的问题是什么? 我可以立即告诉你:如何准备系统设计面试?
很多人害怕系统设计面试,因为没有一定的模式用于准备,问题相当灵活和不可预测。 另外,系统设计的问题通常是开放式的,没有标准或正确的答案,这使得准备过程更加困难。
我们已经花了整整一个月的时间来编写本指南,在系统设计面试之前告诉你一些你应该知道的事情,同时让你更加无忧无虑,因为系统设计面试并不像许多人想象的那样困难,一定的方式绝对可以帮助你适应它。
1. 系统设计面试中评估什么?
我们都知道,编程面试的重点是候选人的基本知识,所以会测试他的一般技术能力和分析能力。
但是,很少有人能清楚地说出系统设计面试的目的。所以在查看提示之前,最好从面试官的角度来理解系统设计面试。
在系统设计面试中,候选人经常被要求设计一个新的系统来解决一个开放式的问题,比如设计短网址服务。有时候这个问题可能相当普遍,比如你如何为 Youtube 设计推荐系统。
在这个过程中,讨论是核心。候选人更有可能主导对话,并和面试官讨论概要组件,细节,优点和缺点,以及一切。
与编程面试相比,系统设计面试更像软件工程师的日常工作。
面试时,主要评估你的沟通和解决问题的能力。给定一个开放的问题,你如何分析这个问题,你如何一步一步解决问题,你如何解释你的想法并与他人讨论,如何评估你的系统并优化它,是面试官最关心的。
所以让我们看看你能做些什么准备。
2. 亲自做项目
准备系统设计面试的最好方法是始终贯穿真实的项目和实践。很多人提前六个月或一年开始准备过程,这绝对是你的最佳实践。
我们看到的一个共同的模式是,你拥有的实践经验越多,在系统设计面试时就越好。这很容易理解,因为这些系统设计问题都来自现实生活中的产品,而那些从事过许多项目的人往往对这些问题有更好的理解,或者这只是他们之前解决的问题之一。
当被要求设计 Youtube 推荐系统时,它与其他许多推荐系统类似,因为很多概念在这里都很常见,
如果你有推荐经验,或者你已经阅读了一些文章/书籍或者思考过,你至少应该能够提出一些初步的想法。
如果你不知道要做什么,这里给你一些建议:
建立一个小型服务/产品来解决一个真正的问题 在 Github 上贡献开源项目 找到你喜欢的机器学习,网络等主题,并搜索一些你可以使用的项目 真正重要的是去做一些现实生活中的项目。你可能需要很长时间才能看到改进,但是在那个时候,你会注意到面试问题是多么的简单。而且,从长远来看,你将从中受益良多。
3. 熟悉基本知识
我不记得我强调了多少次,但这对于系统设计面试非常重要。由于系统设计问题是开放式的,可能涵盖许多技术领域,这里的基本知识远不止是数据结构和算法。
首先,毫无疑问,你应该非常擅长数据结构和算法。以短网址服务为例,如果你不清楚散列,时间/空间复杂度分析,你将无法提出一个好的解决方案。
通常情况下,在时间和内存效率之间有一个权衡,你必须非常精通大 O 分析才能把所有东西都弄清楚。
还有其他一些你最好熟悉的东西,尽管可能不会在面试中涉及。
- 抽象。系统设计面试是一个非常重要的话题。你应该清楚如何抽象系统,什么是可见的和不可见的其他组件,以及它背后的逻辑是什么。面向对象编程也是很重要的。
- 数据库。你应该清楚关于像关系数据库这样的基本概念。取决于你的水平(应届生或经验丰富的工程师),了解 NoSQL 可能是一个加分项。
- 网络。你应该能够清楚地解释,当你在浏览器中键入
gainlo.co
时会发生什么。例如应该清楚 DNS 查找和 HTTP。 - 并发。如果你能够识别系统中的并发问题,并告诉面试官如何解决这个问题,那将是非常棒的。有时候这个话题可能很难,但是需要了解一些基本的概念,比如说竞态条件,死锁是底线。
- 操作系统。有时你与面试官的讨论可能会非常深入,这时最好知道操作系统在底层如何工作。
- 机器学习(可选)。你不需要成为专家,但是一些基本的概念,如特征选择,通常 ML 算法的工作方式,最好熟悉它们。
- 请记住,重点在于要求你从头开始学习所有这些东西,这可能需要一年多的时间。真正重要的是每个主题背后的基本概念。例如,如果在面试中不能实现神经网络,那么完全没问题,但是你应该可以用一个句子解释它。
4. 自顶向下和模块化
这是解决系统设计问题的一般策略,也是向面试官解释的方法。最糟糕的情况是总是立即深入,只会把事情弄得一团糟。
相反,从概要想法开始,然后一步一步地弄清细节总是不错的,所以这应该是自顶向下的方法。为什么?因为许多系统设计的问题是非常普遍的,没有大方向就无法解决。
以 Youtube 推荐系统为例。我可能会首先把它分成前端和后端(面试官可能只会要求后端或特定部分,但我会涵盖整个系统让你明白)。对于后端,流程可以分为三步:收集用户数据(如他观看的视频,位置,偏好等),离线流水线生成推荐,并存储数据并提供给前端。然后,我们可以深入每个具体组件。
对于用户数据,我们可以列出我们认为的,与用户可能喜欢的视频相关的功能。对于流水线,我们可以讨论如何训练数据集等。我们可以做得更深入。由于Youtube 拥有巨大的数据集,离线流水线必须运行大量的数据,那么可能会使用 MapReduce 或 Hadoop。
我们可以通过逐层深入来继续这种分析,但我想在这里解释的想法是,你应该总是有一个大方向。
另一个技巧是模块化。就像我上面所说的,最好把系统分成不同的组件,这在现实生活中也是很好的做法。模块化不仅可以使你的设计对你和面试官更清晰,而且使测试更容易。
5. 优点和缺点
系统设计问题通常没有太多的限制。 因此,好的解决方案和不好的解决方案之间没有明确的界限。 在这种情况下,你有责任了解不同情况下的最佳方法。
最常见的权衡是在时间和内存之间。 你可以直接告诉面试官每个解决方案的优缺点,并要求他澄清你有多少内存的限制。
另外被要求优化系统的时候,你也可以把一些常见的约束放在那里,例如,如果你正在为驾照设计一些东西,你可以告诉面试官,假设驾照的最大长度可能是七是合理的, 通过这种方式,你可以将所有驾照存储在内存中,从而可以进一步优化系统。
6. 估计
在做估计时,你最好对数字有很好的感觉,这在实际项目中更为重要。更具体地说,你应该清楚地估计出你的系统或程序会消耗多少内存,运行速度有多快,根据你的估计,你将如何调整你的设计。
如果我们使用驾照的示例,那么当然可以假设内存足以存储所有美国驾照。但是,你首先估计你需要多少内存来存储,这会更令人印象深刻。
为了估计内存的消耗,你应该计算最大长度为七时有多少许可证,以及你将使用哪种数据结构来存储,然后计算出你需要多少内存,这会让你弄清楚,你的想法是否是可行的。
当决定存储介质时,内存当然不是唯一的解决方案。除了将所有内容存储在内存之外,你还可以存储在磁盘中,也可以存储在多台计算机上。最佳方法的选择实际上是估计时间和存储成本的问题。找出执行时间和内存限制的瓶颈,将会让你对整个系统有更清晰的认识。
7. 模拟面试
说实话,由于没有标准的答案,所以你自己练习系统设计面试并不容易。所以建议始终在一些有经验的工程师面前练习它。
而且通过这个过程,你会花大部分时间与面试官沟通和讨论,这是系统设计面试的主要内容。所以简而言之,我们强烈建议你不要自己练习系统设计面试。
像 Gainlo 这样的网站可以让你和谷歌,亚马逊等公司的员工进行模拟面试,这真的很有帮助。
8. 从现有系统中学习
这个方法是我通常建议人们去做的。每当你对某个系统感到好奇时,试着弄清楚这个系统如何设计。你可以先尝试自己设计,然后再和实际设计比较。最重要的是,试着理解为什么这样设计。数据大小,速度要求等一些限制可能迫使系统变成这样。
http://highscalability.com 有很多现实世界的系统设计的好文章。对于系统设计面试来说,这可能有些过头了,但是了解它们总是很好的。
你也会注意到,即使是同一种系统,不同的公司也可能有完全不同的设计方式。你肯定会从探索它们中学到很多。
总结
系统设计面试非常有趣,因为它更接近现实世界的产品。 准备的关键在于明确面试中的期望,并花费足够的时间和精力处理真正重要的事情。
如果你对系统设计问题没有标准答案感到害怕,你也可以克服它,因为你的答案始终正确。
我希望这篇文章能够让你不必担心系统设计面试,让我知道你对此有何看法。