五、系统设计面试(第一部分)

原文:Chapter 5: System Design Interviews (Part I)

译者:飞龙

协议:CC BY-NC-SA 4.0

自豪地采用谷歌翻译

这是我们的“谷歌面试准备系列指南”的第五章。

从 Gainlo 的调查来看,系统设计面试是人们所害怕的第一件事。 并不针对谷歌面试准备,而是所有的公司。

部分原因是系统设计问题通常是开放式的,所以没有标准答案。 另外,这个问题也难以准备,因为你不知道你的解决方案是否工作。

让我们在这一章解决所有这些问题。 我将简要介绍一下如何评估系统设计面试,然后提供准备和面试策略的实用技巧。

系统设计面试是什么

对于这个话题的新手,我会简单地解释一下。对于 Google,Facebook,Uber 等大多数顶尖公司来说,现场面试中至少有一个是系统设计面试。

在这个面试中,你将被要求设计一个特定的系统,并与面试官就所有细节进行激烈的讨论。但是,由于这个问题是相当开放的,面试官可以决定讨论的方向。考虑到这一点,即使是同一个问题,你可能会与不同的面试官进行完全不同的讨论。

这也是我从来不担心面试者是否曾经看到过这个问题的原因。我们以“设计一个网络爬虫”这个问题为例。作为面试官,我可以将面试集中在整个爬虫基础结构上,我可以具体讨论如何去除 URL,还可以询问如何检测页面是否已经更新。

也可能会要求你在系统设计面试中写下一些代码。但是我没有看到与一般的编程面试有太大的区别,在本章中我们不会涉及到这一部分,因为你可以参考前面的章节。

系统设计面试如何评估?

我坚信,如果你不能评估一件事情,你就不能改善它。大多数人不知道如何评估系统设计面试,他们如何做好准备?这就像你在玩游戏而不知道规则。

与编程面试不同,系统设计问题没有标准答案,因此评估过程更为主观。不过,作为一个面试官,我仍然会有一些东西。

首先,我会评估设计是否真的有效。虽然没有实现来验证,根据工作经验和一些常识,如果给出这个问题,我会问自己是否会尝试提出的方法。多数情况下,很明显的是要判断设计是否有问题,我只是用一些例子来挑战候选人。例如,如果我要求他检查某个网址是否曾经被抓取过,我会看看解决方案是否处理了t.co/xyz这样的短网址或带有 UTM 参数的网址。这是最低的要求。如果候选人不能做到这一点,我就不会深究,或者我可能会另外提出一个问题。

其次,我会检查可行性。有些候选人会提出只在理论上有效的解决方案。它可能需要无限的内存或系统是不是很复杂。无论如何,我会请他解决这个问题。验证它的一个好方法是,问自己需要多少时间和多少工程师才能实现这个设计。就个人而言,我更喜欢轻松简单的设计。如果你在一两个星期内无法制作原型,我可能会要求你简化它。

有时,候选人会想出一个复杂的解决方案,需要大量的数据和一些 ML 组件和流水线。现实中很难实现,因为这样做风险很大。你不想花一年时间在这个未经证实的想法上,那可能就是行不通的。

第三,我希望候选人清楚他在说什么。更具体地说,我想确保他知道系统应该以特定方式设计的原因,约束是什么,以及是否有其他解决方案。通常,设计问题会模糊描述。好的候选人能够告诉你什么是假设,以及如何将这个设计与其他人进行比较。为了使它更清楚,问问自己什么是替代解决方案,以及为什么以这种方式构建系统而不是其他解决方案。

在下面的部分中,我将重点介绍一些实用的技巧,并使用它们开始准备。

如何准备系统设计面试

我们不得不承认,经验胜过一切。这就是为什么一些有经验的工程师根本不需要准备。但是,你还可以做很多事情,来做出重大改变。

项目

如果你离你的面试还有一段时间(至少6个月),构建一些东西是绝对值得的。事实上每个人都可以参与宏观设计,但是只有那些真正从事细节工作的人才能把所有的事情都考虑进去。

如果你是一个学生,你可以参加一个实习,你也可以为你感兴趣的项目工作。贡献一些开源项目也是一个好主意。重要的不是要从事哪个项目,而是要从事一些工作。

我认为这很重要的原因是,没有实际工作的情况下,你不知道你的设计是否有效。有了一些实践经验,你很快就会意识到很多事情很难实现,但乍一看似乎是合理的。例如,如果你想要检查自上次抓取以来,网页内容是否已更新,并依赖 HTML 是否保持不变,则会发现许多网页的内容相同,但注释,侧边栏等内容被改变了。这是一个我认为不适用的设计,虽然这听起来很合理。

好奇心

通常对一切都很好奇很重要。一个不错的做法是选择你每天使用的任何产品,比如 Youtube,想想你将如何从头开始设计系统。

有时产品可能会非常复杂,你也可以设计一个像 Facebook 朋友推荐的功能。如果你有时间,编写一些代码来实现一个原型是一个加分项。但重要的是,你应该试图深入细节。

尽管系统设计问题没有任何标准答案,但你仍然可以搜索如何实现这些产品/功能。将其与你自己的设计进行比较,了解其差异。强烈推荐 High Scalability(高可扩展性),但不要在特定工具上花费太多时间(请参阅“什么不重要”)。

注:一个窍门是,很多面试官喜欢问与公司有关的设计问题。例如,你更有可能在 Google 面试中设计 Google 产品/功能。情况并非总是如此,但应该重视公司的产品或类似产品。

实践

类似于编码问题,你还需要练习系统设计面试。有几种方法。你可以做一些谷歌搜索,看看别人会如何处理相同的问题,并与你的设计进行比较。例如,系统设计面试问题集是一个非常详细的常见问题分析。

更好的方法是与更有经验的人一起练习。如果你有在工业界一段时间的朋友,那太好了。向他们请求帮助。如果你不想打扰他们,你可以在 Gaino 上模拟面试。我认为互动练习总是比较好,因为整个面试过程比考试更像讨论。

什么不重要

一个常见的错误是,许多人对特定的技术过于重视。例如,他们在如何使用 AWS ,如何配置 Google 云平台以及如何使用特定的 Web 框架上花了很多时间。

我不是说这些没用,其实这些绝对是好东西。然而,从系统设计面试的角度来说,我认为面试官更关心对知识的理解而不是特定的技术。

例如,在讨论处理大数据时,作为一个面试官,我想讨论的是,如何将数据分发到多台机器上,如何将它们聚合到一起,以及如何平均分配负载。如果有人告诉我他将在 AWS 上使用 Hadoop,我会要求更多的细节,他最终还是会回答上面的所有问题。

经验法则是更多关注每个工具是如何设计的,而不是使用什么工具。

总结

系统设计面试的所有提示很难在一章内完成。我们将在下一篇文章中讨论一些现场策略。

如果本章只有一件事情,那么我希望现在就开始着手。大多数人花太多的时间来规划,但他们真正需要的是做东西。

顺便提一下,如果你想得到资深的面试官的更多指导,可以查看 Gainlo,以便与 Google,Facebook 等公司的工程师进行模拟面试。