如何准备 2022 年的系统设计面试 - Fahim


对于许多软件工程师来说,系统设计面试仍然是一个神秘的挑战。
大多数工程师以前从未真正在大型系统上工作过,因此必须解释如何构建一个似乎令人生畏。而且因为系统设计面试的问题可以是开放式的,所以很难知道正确的准备方法。
在我在 Microsoft 和 Facebook 从事分布式系统工作 8 年之前,我确实有这种感觉。但是现在,作为一个参加过数百次系统设计面试(在桌子两边)的人,我可以向你保证,有一条路可以通过。
在这篇文章中,我将讨论:

  1. 面试官在系统设计面试中寻找什么
  2. 任何开发人员(或 TPM 或 EM)如何准备自信地回答系统设计问题

我在系统设计方面的个人背景
2008 年 4 月,我加入了 Microsoft 的一个内部团队,致力于一个构建分布式存储解决方案的大型项目。
亚马逊在 2006 年推出了他们的简单存储服务,而在我加入团队的同一个月,谷歌推出了他们的 PaaS 解决方案 Google App Engine,因此我们处于云计算的早期抢占先机。不到两年后,该项目作为一个新产品类别向全世界推出:Microsoft Azure。
当我加入 Azure 团队时,我来自 Exchange。我了解服务器存储和客户端管理,但不是这种规模,当然也不是分布在世界各地。这需要在工作中大量学习。

今天,我和其他云工程师在早期学到的经验被编入了系统设计学科。现在对于许多公司来说,系统设计面试在开发人员面试过程中发挥着重要作用——这意味着它对于找到工作和让你的职业生涯走上良好的轨道至关重要。

我通过数百次系统设计面试学到了什么
到我开始 Educative 时,我已经以面试者和面试官的身份参与了数百个面试循环。随着 Educative 规模的扩大,我参与了数百次。
在 Facebook 和微软从事网络规模系统工作的经验教会了我进行系统设计面试的两个关键技能:

  1. 如何快速学习分布式系统的基础知识并将这些原则应用于解决实际问题
  2. 如何在面试系统设计时评估候选人

这是违反直觉的部分:在系统设计面试中,公司实际上并没有尝试测试您的系统设计经验。
成功的候选人很少有在大型系统上工作的经验,面试官知道这一点。同样,这是一门仅存在大约 15 年的学科,并且与软件工程中的其他所有内容一样,它正在迅速发展。

关键是为 SDI 做好准备,并打算应用这些知识。

您如何准备系统设计面试?
在系统设计面试中,面试官要求候选人设计一个网络规模的应用程序。例如,他们可能会要求您设计 Instagram设计 YouTube设计 Uber

与编码面试问题不同,系统设计面试是自由形式的讨论,没有正确或错误的答案。相反,面试官试图评估候选人就系统的不同方面进行对话的能力,并根据对话期间可能演变的需求评估解决方案。
思考对话的最佳方式是想象你和一位同事被要求设计一个大型系统,而你正在白板上讨论细节。在提出解决方案之前,您要了解需求、范围和约束。

那么,如果您从未在现实生活中构建过系统,您将如何在面试中设计一个系统呢?要破解您的系统设计面试,您需要在三个方面做好准备:

  1. 分布式系统基础
  2. 大型网络应用的架构
  3. 设计分布式系统

这些维度中的每一个都流入下一个维度。

如果您不了解基础知识,就不会准备好构建服务;如果您不知道如何将这些系统组合在一起,您将无法设计特定的解决方案;一旦您设计了大型系统,您就可以吸取经验教训并将其整合到您的基础知识中。

让我们按顺序查看这些维度中的每一个。

1) 分布式系统基础
与其他任何事情一样,从基础开始很重要。分布式系统的基本原理(或构建块)可以为您提供在给定系统中什么是可能的和什么是不可能的框架。
您可以了解特定架构的限制以及为实现特定目标(例如一致性与写入吞吐量)必须做出的权衡。在最基本的层面上,您需要从分布式系统的优势、劣势和目的开始。能够谈论以下话题:
数据持久性和一致性
了解存储解决方案的故障率和读写过程中的损坏率的差异和影响。

复制
解锁数据持久性和一致性的关键;复制处理数据备份,但也能够大规模重复过程。

分区
也称为分片,分区在系统内的不同节点之间划分数据。由于复制跨节点分布数据,分区跨节点分布进程。这减少了对纯复制的依赖。

共识
您的一个节点在西雅图;另一个在拉合尔;另一个在伦敦。太平洋夏令时间上午 7:05 有系统请求。考虑到数据包的传输时间,这是否可以在远程节点中记录并正确同步,是否可以同意?这是一个简单的共识问题——所有节点都需要达成一致,这将防止错误进程运行,并确保整个系统的数据和进程的一致性和复制。

分布式事务
一旦达成共识,现在来自应用程序的事务需要跨数据库提交,并由所涉及的每个资源进行故障检查。读取、写入和提交的双向和三向通信在参与者节点之间共享。

2)大型Web应用的架构
我们已经知道,大多数大型应用程序都是 Web 应用程序。即使不是像 Netflix、Twitter 和 Amazon 这样的消费巨头,企业也正在从 Exchange 等本地系统转向微软、谷歌和 AWS 的云解决方案。这就是为什么最好了解此类系统的架构。
您必须了解以下主题:
N 层应用程序
处理发生在分布式系统的各个级别。一些进程在客户端上,一些在服务器上,而另一些在另一台服务器上——所有这些都在一个应用程序中。这些处理层称为层,了解这些层如何相互交互以及它们负责的特定流程是 Web 系统设计的一部分。

HTTP 和 REST
HTTP 是整个互联网运行的唯一 API——它是我们发送每封电子邮件、流式传输每部 Netflix 电影以及浏览每一个亚马逊列表的系统。REST 是一组设计原则,可直接与 HTTP API 进行交互,从而允许高效、可扩展的系统具有相互隔离的组件的假设。使用这些原则和开放 API,其他人可以更轻松地构建您的工作或通过扩展您自己的应用程序和服务来扩展您的功能。

DNS 和负载平衡
如果您有 99 个并发用户,通过 DNS 路由进行负载平衡可以确保服务器 A、B 和 C 各自处理 33 个客户端,而不是服务器 A 被 99 个客户端超载而服务器 B 和 C 闲置。将客户端请求路由到正确的服务器、处理发生的正确层,有助于确保系统稳定性。你需要知道如何做到这一点。

缓存
缓存可让大多数用户高速访问您最常请求的数据和应用程序。您的 Web 应用程序的问题是需要将哪些内容存储在缓存中;我们如何将流量引导到缓存;当我们在缓存中没有我们想要的东西时会发生什么?

流处理
流处理对数据流应用统一的处理。如果一个应用程序有连续的、一致的数据通过它,那么流处理允许在应用程序内有效地使用本地资源。

3) 设计分布式系统
这看起来很多,但老实说,只需要几周的准备时间——如果你有坚实的基础,那就更少了。
一旦您了解了分布式系统和 Web 架构的基础知识,就该应用这种学习和设计现实世界的系统了。寻找和优化这些问题的潜在解决方案将为您提供自信地进行系统设计面试的工具。
一旦你准备好练习你的技能,你就可以从现实世界的面试中解决一些示例问题——以及构建十种不同 Web 服务的技巧和方法。

结束的想法
世界比以往任何时候都更加紧密相连。
消费者和企业都在线,甚至遗留程序也正在迁移到云端。分布式系统是软件工程学科的现在和未来。
由于系统设计面试问题在开发人员面试中占了很大一部分,因此掌握分布式系统的工作知识将为您的职业生涯带来红利。