提交 9803d3a9 编写于 作者: W wizardforcel

2022-11-19 17:15:20

上级 1fc408ad
# 零、序言
我们很高兴你决定加入我们学习系统设计面试。系统设计面试问题是所有技术面试中最难解决的。这些问题要求受访者为一个软件系统设计一个架构,这个软件系统可以是新闻提要、谷歌搜索、聊天系统等。这些问题令人生畏,没有一定的模式可循。这些问题通常范围很广,也很模糊。这些过程是开放式的,没有标准或正确的答案是不清楚的。
公司广泛采用系统设计面试,因为这些面试中测试的沟通和解决问题的技能与软件工程师日常工作所需的技能相似。受访者的评估基于她如何分析一个模糊的问题,以及她如何一步一步地解决问题。测试的能力还包括她如何解释想法,与他人讨论,以及评估和优化系统。在英语中,使用“她”比使用“他或她”或在两者之间跳跃更流畅。为了便于阅读,我们在整本书中使用了阴性代词。没有不尊重男性工程师的意思。
......
# 一、从零扩展到数百万用户
设计一个支持数百万用户的系统极具挑战性,这是一个需要不断改进和完善的旅程。在这一章中,我们构建了一个支持单个用户的系统,并逐步将其扩展到服务数百万用户。读完这一章,你将掌握一些技巧,帮助你解决系统设计面试问题。
## 单服务器设置
......@@ -320,7 +322,7 @@ CDN 回退:你应该考虑你的网站/应用如何应对 CDN 故障。如果有
分片将大型数据库分成更小、更容易管理的部分,称为分片。每个分片共享相同的模式,尽管每个分片上的实际数据对于该分片是唯一的。
图 1-21 显示了一个分片数据库的例子。用户数据根据用户 id 分配给数据库服务器。每当您访问数据时,都会使用哈希函数来查找相应的碎片。在我们的例子中, user_id % 4 被用作散列函数。如果结果等于 0,shard 0 用于存储和获取数据。如果结果等于 1,则使用碎片 1。同样的逻辑也适用于其他碎片。
图 1-21 显示了一个分片数据库的例子。用户数据根据用户 id 分配给数据库服务器。每当您访问数据时,都会使用哈希函数来查找相应的碎片。在我们的例子中, user_id % 4 被用作哈希函数。如果结果等于 0,shard 0 用于存储和获取数据。如果结果等于 1,则使用碎片 1。同样的逻辑也适用于其他碎片。
![A close up of a logo Description automatically generated](../images/00024.jpeg)
......@@ -332,7 +334,7 @@ CDN 回退:你应该考虑你的网站/应用如何应对 CDN 故障。如果有
分片是扩展数据库的一项伟大技术,但它远非完美的解决方案。它给系统带来了复杂性和新的挑战:
重新共享数据 :当 1)由于快速增长,单个碎片无法再容纳更多数据时,需要重新共享数据。2)由于数据分布不均匀,某些碎片可能比其他碎片更快耗尽。当分片耗尽时,需要更新分片函数并四处移动数据。将在第五章讨论的一致散列法是解决这个问题的常用技术。
重新共享数据 :当 1)由于快速增长,单个碎片无法再容纳更多数据时,需要重新共享数据。2)由于数据分布不均匀,某些碎片可能比其他碎片更快耗尽。当分片耗尽时,需要更新分片函数并四处移动数据。将在第五章讨论的一致哈希法是解决这个问题的常用技术。
名人问题 :这也叫热点关键问题。对特定碎片的过度访问可能会导致服务器过载。想象一下凯蒂·佩里、贾斯汀比伯和 Lady Gaga 的数据都出现在同一个碎片上。对于社交应用来说,这个碎片将会被读操作淹没。为了解决这个问题,我们可能需要为每个名人分配一个碎片。每个碎片甚至可能需要进一步的划分。
......
# 二、信封背面估计
在系统设计面试中,有时你会被要求使用粗略估计来估计系统容量或性能需求。根据谷歌高级研究员 Jeff Dean 的说法,“信封背面的计算是你使用思维实验和常见性能数字的组合来创建的估计,以获得满足你要求的设计的良好感觉”[1]。
您需要对可伸缩性基础有一个很好的认识,以便有效地进行预估。应该很好地理解以下概念:2 的幂,每个程序员都应该知道的延迟数字,以及可用性数字。
......
此差异已折叠。
此差异已折叠。
为了实现水平扩展,在服务器之间高效、均匀地分配请求/数据非常重要。一致散列是实现这一目标的常用技术。但首先,让我们深入研究一下这个问题。
# 五、设计一致哈希
为了实现水平扩展,在服务器之间高效、均匀地分配请求/数据非常重要。一致哈希是实现这一目标的常用技术。但首先,让我们深入研究一下这个问题。
## 老调重弹问题
......@@ -6,7 +8,7 @@
server index = hash(key)% N,其中 N 是服务器池的大小。
让我们用一个例子来说明它是如何工作的。如表 5-1 所示,我们有 4 台服务器和 8 个带散列的字符串键。
让我们用一个例子来说明它是如何工作的。如表 5-1 所示,我们有 4 台服务器和 8 个带哈希的字符串键。
![A screenshot of a cell phone Description automatically generated](../images/00052.jpeg)
......@@ -14,7 +16,7 @@ server index = hash(key)% N,其中 N 是服务器池的大小。
![A close up of text on a white background Description automatically generated](../images/00053.jpeg)
当服务器池的大小固定且数据分布均匀时,这种方法非常有效。然而,当添加新的服务器或者移除现有的服务器时,问题 出现 。例如,如果服务器 1 脱机,服务器池的大小将变为 3。 使用相同的散列函数,我们得到一个键的相同散列值。但是应用模运算给了我们不同的服务器索引,因为服务器的数量减少了 1。 我们应用 hash % 3 : 得到如表 5-2 所示的结果
当服务器池的大小固定且数据分布均匀时,这种方法非常有效。然而,当添加新的服务器或者移除现有的服务器时,问题 出现 。例如,如果服务器 1 脱机,服务器池的大小将变为 3。 使用相同的哈希函数,我们得到一个键的相同哈希值。但是应用模运算给了我们不同的服务器索引,因为服务器的数量减少了 1。 我们应用 hash % 3 : 得到如表 5-2 所示的结果
![A screenshot of a cell phone Description automatically generated](../images/00054.jpeg)
......@@ -22,7 +24,7 @@ server index = hash(key)% N,其中 N 是服务器池的大小。
![A screenshot of a cell phone Description automatically generated](../images/00055.jpeg)
如图 5-2 所示,大部分的键都是重新分配的,而不仅仅是原来存储在离线服务器(服务器 1)中的那些。 这意味着当服务器 1 离线时,大多数缓存客户端将连接到错误的服务器来获取数据。这导致了高速缓存未命中的风暴。一致散列是缓解这一问题的有效技术。
如图 5-2 所示,大部分的键都是重新分配的,而不仅仅是原来存储在离线服务器(服务器 1)中的那些。 这意味着当服务器 1 离线时,大多数缓存客户端将连接到错误的服务器来获取数据。这导致了高速缓存未命中的风暴。一致哈希是缓解这一问题的有效技术。
## 一致哈希
......@@ -30,7 +32,7 @@ server index = hash(key)% N,其中 N 是服务器池的大小。
### 哈希空间和哈希环
现在我们了解了一致性哈希的定义,让我们看看它是如何工作的。假设 SHA-1 作为哈希函数 f, 哈希函数的输出 范围为 : x0,x1,x2,x3,…,xn 。在密码学中,SHA-1 的散列空间从 0 到 2^160 - 1。这意味着 x0 对应于 0, xn 对应于 2^160 - 1,中间的所有其他哈希值落在 0 和 2^160-1 之间。图 5-3 显示了散列空间。
现在我们了解了一致性哈希的定义,让我们看看它是如何工作的。假设 SHA-1 作为哈希函数 f, 哈希函数的输出 范围为 : x0,x1,x2,x3,…,xn 。在密码学中,SHA-1 的哈希空间从 0 到 2^160 - 1。这意味着 x0 对应于 0, xn 对应于 2^160 - 1,中间的所有其他哈希值落在 0 和 2^160-1 之间。图 5-3 显示了哈希空间。
![A close up of a logo Description automatically generated](../images/00056.jpeg)
......@@ -40,13 +42,13 @@ server index = hash(key)% N,其中 N 是服务器池的大小。
### 哈希服务器
使用相同的哈希函数 f ,我们基于服务器 IP 或名称将服务器映射到环上。图 5-5 显示了 4 个服务器被映射到散列环上。
使用相同的哈希函数 f ,我们基于服务器 IP 或名称将服务器映射到环上。图 5-5 显示了 4 个服务器被映射到哈希环上。
![A necklace on a table Description automatically generated](../images/00058.jpeg)
### 哈希键
值得一提的是,这里使用的 hash 函数与“重散列问题”中的不同,没有模运算。如图 5-6 所示,4 个缓存键(key0、key1、key2 和 key3)被散列到散列环上
值得一提的是,这里使用的 hash 函数与“重哈希问题”中的不同,没有模运算。如图 5-6 所示,4 个缓存键(key0、key1、key2 和 key3)被哈希到哈希环上
![A close up of a necklace Description automatically generated](../images/00059.jpeg)
......@@ -66,19 +68,19 @@ server index = hash(key)% N,其中 N 是服务器池的大小。
### 移除一个服务器
当服务器被移除时,只有一小部分密钥需要用一致的散列法重新分配。在图 5-9 中,当 服务器 1 被移除后,只有 key1 必须重新映射到 服务器 2 。其余的键不受影响。
当服务器被移除时,只有一小部分密钥需要用一致的哈希法重新分配。在图 5-9 中,当 服务器 1 被移除后,只有 key1 必须重新映射到 服务器 2 。其余的键不受影响。
![A picture containing necklace Description automatically generated](../images/00062.jpeg)
### 两个问题的基本处理方法
一致性散列算法是由 Karger 等人在麻省理工学院提出的[1]。基本步骤是:
一致性哈希算法是由 Karger 等人在麻省理工学院提出的[1]。基本步骤是:
使用均匀分布的散列函数将服务器和密钥映射到环上。
使用均匀分布的哈希函数将服务器和密钥映射到环上。
要找出一个密钥映射到哪个服务器,从密钥位置开始顺时针方向走,直到找到环上的第一个服务器。
这种方法发现了两个问题。首先,考虑到可以添加或移除服务器,不可能为环上的所有服务器保持相同大小的分区。分区是相邻服务器之间的散列空间。分配给每个服务器的环上的分区的大小可能非常小或相当大。在图 5-10 中,如果去掉 s1 , s2 的 分区(用双向箭头突出显示)是 s0 和 s3 的 分区的两倍。
这种方法发现了两个问题。首先,考虑到可以添加或移除服务器,不可能为环上的所有服务器保持相同大小的分区。分区是相邻服务器之间的哈希空间。分配给每个服务器的环上的分区的大小可能非常小或相当大。在图 5-10 中,如果去掉 s1 , s2 的 分区(用双向箭头突出显示)是 s0 和 s3 的 分区的两倍。
![A close up of a necklace Description automatically generated](../images/00063.jpeg)
......@@ -114,13 +116,13 @@ server index = hash(key)% N,其中 N 是服务器池的大小。
## 总结起来
在本章中,我们深入讨论了一致性哈希,包括为什么需要它以及它是如何工作的。一致散列的好处包括:
在本章中,我们深入讨论了一致性哈希,包括为什么需要它以及它是如何工作的。一致哈希的好处包括:
添加或删除服务器时,最小化的密钥会重新分配。
因为数据分布更均匀,所以水平缩放更容易。
缓解热点关键问题。对特定碎片的过度访问可能会导致服务器过载。想象一下凯蒂·佩里、贾斯汀比伯和 Lady Gaga 的数据都在同一个碎片上。一致散列通过更均匀地分布数据来帮助缓解这个问题。
缓解热点关键问题。对特定碎片的过度访问可能会导致服务器过载。想象一下凯蒂·佩里、贾斯汀比伯和 Lady Gaga 的数据都在同一个碎片上。一致哈希通过更均匀地分布数据来帮助缓解这个问题。
一致性哈希在现实世界的系统中被广泛使用,包括一些著名的:
......
# 六、设计键值存储
键值存储,也称为键值数据库,是一种非关系数据库。每个唯一标识符都存储为一个键及其相关值。这种数据配对被称为“键-值”对。
在键-值对中,键必须是唯一的,与键相关联的值可以通过键来访问。键可以是纯文本或散列值。出于性能原因,短键效果更好。钥匙长什么样?下面举几个例子:
在键-值对中,键必须是唯一的,与键相关联的值可以通过键来访问。键可以是纯文本或哈希值。出于性能原因,短键效果更好。钥匙长什么样?下面举几个例子:
纯文本密钥:“上次登录时间”
......@@ -122,11 +124,11 @@ CA(一致性和可用性)系统:CA 键值存储支持一致性和可用性,同
添加或删除节点时,尽量减少数据移动。
第五章中讨论的一致散列法是解决这些问题的一个很好的技术。让我们从高层次上重新审视一下一致性散列是如何工作的。
第五章中讨论的一致哈希法是解决这些问题的一个很好的技术。让我们从高层次上重新审视一下一致性哈希是如何工作的。
首先,服务器被放置在一个哈希环上。在图 6-4 中,八个服务器,分别用 s0,s1,…,s7 表示,放置在哈希环上。
接下来,一个密钥被散列到同一个环上,并存储在顺时针方向移动时遇到的第一个服务器上。例如, key0 使用此逻辑存储在 s1 中。
接下来,一个密钥被哈希到同一个环上,并存储在顺时针方向移动时遇到的第一个服务器上。例如, key0 使用此逻辑存储在 s1 中。
![A necklace with a piece of paper Description automatically generated](../images/00073.jpeg)
......@@ -282,7 +284,7 @@ If W + R > N 强一致性得到保证,因为必须至少有一个重叠节点
提示切换用于处理临时故障。如果副本永久不可用怎么办?为了处理这种情况,我们实现了一个反熵协议来保持副本同步。反熵包括比较副本上的每一条数据,并将每个副本更新到最新版本。Merkle 树用于不一致性检测和最小化传输的数据量。
引自维基百科[7]:“hash 树或 Merkle 树是 中的树,其中每个非叶节点都用其子节点的标签或值(在叶的情况下)的散列来标记。散列树允许高效和安全地验证大型数据结构的内容”。
引自维基百科[7]:“hash 树或 Merkle 树是 中的树,其中每个非叶节点都用其子节点的标签或值(在叶的情况下)的哈希来标记。哈希树允许高效和安全地验证大型数据结构的内容”。
假设密钥空间从 1 到 12,下面的步骤展示了如何构建 Merkle 树。突出显示的方框表示不一致。
......@@ -290,7 +292,7 @@ If W + R > N 强一致性得到保证,因为必须至少有一个重叠节点
![A close up of a keyboard Description automatically generated](../images/00082.jpeg)
步骤 2:一旦创建了存储桶,使用统一的散列方法对存储桶中的每个关键字进行散列(图 6-14)。
步骤 2:一旦创建了存储桶,使用统一的哈希方法对存储桶中的每个关键字进行哈希(图 6-14)。
![A screenshot of a cell phone Description automatically generated](../images/00083.jpeg)
......@@ -322,7 +324,7 @@ If W + R > N 强一致性得到保证,因为必须至少有一个重叠节点
协调器是充当客户端和键值存储之间的代理的节点。
使用一致散列法将节点分布在环上。
使用一致哈希法将节点分布在环上。
系统是完全分散的,因此添加和移动节点可以是自动的。
......
# 七、设计分布式系统中的唯一 ID 生成器
在这一章中,你被要求在分布式系统中设计一个唯一的 ID 生成器。您首先想到的可能是在传统数据库中使用带有 auto_increment 属性的主键。然而, auto_increment 在分布式环境中不起作用,因为单个数据库服务器不够大,并且在最小延迟的情况下跨多个数据库生成唯一的 id 具有挑战性。
这里有几个唯一 id 的例子:
......
# 八、设计 URL 缩短器
在这一章中,我们将解决一个有趣而经典的系统设计面试问题:设计一个像 tinyurl 这样的 URL 缩短服务。
## 第一步——了解问题并确定设计范围
......@@ -106,11 +108,11 @@ API 端点促进了客户端和服务器之间的通信。我们将设计 REST
每个 的哈希值 都可以映射回 longURL 。
深入讨论散列函数的详细设计。
深入讨论哈希函数的详细设计。
## 步骤 3 -设计深度潜水
到目前为止,我们已经讨论了 URL 缩短和 URL 重定向的高级设计 - 。在本节中,我们将深入探讨以下内容:数据模型、散列函数、URL 缩短和 URL 重定向。
到目前为止,我们已经讨论了 URL 缩短和 URL 重定向的高级设计 - 。在本节中,我们将深入探讨以下内容:数据模型、哈希函数、URL 缩短和 URL 重定向。
### 数据模型
......@@ -120,7 +122,7 @@ API 端点促进了客户端和服务器之间的通信。我们将设计 REST
### 哈希函数
Hash 函数用于将一个长 URL 散列成一个短 URL,也称为 hashValue 。
Hash 函数用于将一个长 URL 哈希成一个短 URL,也称为 hashValue 。
#### 哈希值长度
......@@ -130,11 +132,11 @@ Hash 函数用于将一个长 URL 散列成一个短 URL,也称为 hashValue
当 n = 7,62 ^ n = ~3.5 万亿 时,3.5 万亿容纳 3650 亿个 URL 绰绰有余,所以 的长度 hashValue 为 7。
我们将探讨两种类型的 URL 缩写散列函数。第一个是“哈希+冲突解决”,第二个是“base 62 转换”。让我们一个一个来看。
我们将探讨两种类型的 URL 缩写哈希函数。第一个是“哈希+冲突解决”,第二个是“base 62 转换”。让我们一个一个来看。
#### 哈希+冲突解决
为了缩短一个长 URL,我们应该实现一个散列函数,将一个长 URL 散列成一个 7 个字符的字符串。一个简单的解决方案是使用众所周知的散列函数,如 CRC32、MD5 或 SHA-1。下表比较了对该 URL 应用不同哈希函数后的哈希结果:https://en.wikipedia.org/wiki/Systems_design.
为了缩短一个长 URL,我们应该实现一个哈希函数,将一个长 URL 哈希成一个 7 个字符的字符串。一个简单的解决方案是使用众所周知的哈希函数,如 CRC32、MD5 或 SHA-1。下表比较了对该 URL 应用不同哈希函数后的哈希结果:https://en.wikipedia.org/wiki/Systems_design.
![A screenshot of a cell phone Description automatically generated](../images/00104.jpeg)
......@@ -216,7 +218,7 @@ URL 重定向的流程总结如下:
## 步骤 4 -总结
在本章中,我们讨论了 API 设计、数据模型、散列函数、URL 缩短和 URL 重定向。
在本章中,我们讨论了 API 设计、数据模型、哈希函数、URL 缩短和 URL 重定向。
如果在面试结束时有额外的时间,这里有一些额外的谈话要点。
......
# 九、设计网络爬虫
在这一章中,我们关注网络爬虫设计:一个有趣而经典的系统设计面试问题。
网络爬虫被称为机器人或蜘蛛。搜索引擎广泛使用它来发现 web 上新的或更新的内容。内容可以是网页、图像、视频、PDF 文件等。网络爬虫从收集一些网页开始,然后跟随这些网页上的链接来收集新的内容。图 9-1 显示了爬行过程的一个可视化例子。
......@@ -316,7 +318,7 @@ DNS 解析器是爬虫的瓶颈,因为由于许多 DNS 接口的同步性质
除了性能优化,健壮性也是一个重要的考虑因素。我们提出了几种提高系统鲁棒性的方法:
一致散列:这有助于在下载者之间分配负载。可以使用一致散列来添加或删除新的下载器服务器。更多细节请参考第 5 章:设计一致散列
一致哈希:这有助于在下载者之间分配负载。可以使用一致哈希来添加或删除新的下载器服务器。更多细节请参考第 5 章:设计一致哈希
保存抓取状态和数据:为了防止失败,抓取状态和数据被写入存储系统。通过加载保存的状态和数据,可以轻松重启中断的爬网。
......@@ -400,7 +402,7 @@ DNS 解析器是爬虫的瓶颈,因为由于许多 DNS 接口的同步性质
1998 年。
【11】伯顿·布鲁姆。具有容许误差的散列编码中的空间/时间权衡。美国计算机学会通讯,第 13 卷第 7 期,第 422 - 426 页,1970 年 7 月。
【11】伯顿·布鲁姆。具有容许误差的哈希编码中的空间/时间权衡。美国计算机学会通讯,第 13 卷第 7 期,第 422 - 426 页,1970 年 7 月。
【12】谷歌动态渲染:[https://developers . Google . com/search/docs/guides/Dynamic-Rendering](https://developers.google.com/search/docs/guides/dynamic-rendering)
......
# 十、设计通知系统
近年来,通知系统已经成为许多应用程序中非常流行的功能。通知提醒用户重要信息,如突发新闻、产品更新、事件、产品等。它已经成为我们日常生活中不可或缺的一部分。在这一章中,你被要求设计一个通知系统。
通知不仅仅是移动推送通知。三种通知格式是:移动推送通知、SMS 消息和电子邮件。图 10-1 显示了这些通知的一个例子。
......
# 十一、设计新闻订阅系统
在这一章中,你被要求设计一个新闻订阅系统。什么是新闻订阅源?根据脸书的帮助页面,“新闻提要是在你的主页中间不断更新的故事列表。新闻源包括状态更新、照片、视频、链接、应用活动 、 ,以及你在脸书上关注的人、页面和群组的赞。这是一个常见的面试问题。常见的类似问题有:设计脸书新闻提要、Instagram 提要、Twitter 时间线等。
![A screenshot of a cell phone Description automatically generated](../images/00138.jpeg)
......@@ -146,7 +148,7 @@ Web 服务器:Web 服务器将请求路由到新闻订阅服务。
获取新闻提要很慢,因为新闻提要不是预先计算的。
我们采用了一种混合方法,以获得两种方法的优点并避免其中的缺陷。因为快速获取新闻提要至关重要,所以我们对大多数用户使用推送模型。对于有很多朋友/关注者的名人或用户,我们让关注者按需拉新闻内容,以避免系统过载。一致散列是一种缓解热键问题的有用技术,因为它有助于更均匀地分布请求/数据。
我们采用了一种混合方法,以获得两种方法的优点并避免其中的缺陷。因为快速获取新闻提要至关重要,所以我们对大多数用户使用推送模型。对于有很多朋友/关注者的名人或用户,我们让关注者按需拉新闻内容,以避免系统过载。一致哈希是一种缓解热键问题的有用技术,因为它有助于更均匀地分布请求/数据。
让我们仔细看看扇出服务,如图 11-5 所示。
......
# 十二、设计聊天系统
在这一章中,我们将探索一个聊天系统的设计。几乎每个人都使用聊天应用。图 12-1 显示了市场上一些最流行的应用程序。
![A picture containing flower Description automatically generated](../images/00146.jpeg)
......
# 十三、设计搜索自动补全系统
在谷歌上搜索或在亚马逊购物时,当你在搜索框中输入时,一个或多个匹配的搜索词就会呈现在你面前。此功能被称为自动完成、提前键入、随键入搜索或增量搜索。图 13-1 展示了一个谷歌搜索的例子,当在搜索框中输入“晚餐”时,显示了一个自动完成的结果列表。搜索自动完成是许多产品的重要功能。这就引出了面试问题:设计一个搜索自动完成系统,也叫“设计 top k”或“设计 top k 最常搜索的查询”。
![A screenshot of a cell phone Description automatically generated](../images/00165.jpeg)
......@@ -256,7 +258,7 @@ Trie 缓存。 Trie Cache 是一个分布式缓存系统,将 Trie 保存在内
1。文档存储:由于每周都会构建一个新的 trie,所以我们可以定期对其进行快照、序列化,并将序列化后的数据存储在数据库中。像 MongoDB [4]这样的文档存储非常适合序列化数据。
2。键值存储:通过应用以下逻辑,可以用散列表的形式[4]来表示 trie:
2。键值存储:通过应用以下逻辑,可以用哈希表的形式[4]来表示 trie:
trie 中的每个前缀都映射到哈希表中的一个键。
......
# 十四、设计 YouTube
在这一章中,你被要求设计 YouTube。这个问题的解决方案可以应用于其他面试问题,比如设计一个视频分享平台,如网飞和 Hulu。图 14-1 显示了 YouTube 主页。
![A screenshot of a social media post Description automatically generated](../images/00184.jpeg)
......
# 十五、设计谷歌云盘
近年来,Google Drive、Dropbox、微软 OneDrive、苹果 iCloud 等云存储服务变得非常流行。在这一章中,你被要求设计 Google Drive。
在开始设计之前,让我们花点时间了解一下 Google Drive。Google Drive 是一种文件存储和同步服务,可以帮助您在云端存储文档、照片、视频和其他文件。您可以从任何电脑、智能手机和平板电脑上访问您的文件。您可以轻松地与朋友、家人和同事分享这些文件[1]。图 15-1 和 15-2 分别显示了 Google drive 在浏览器和移动应用上的样子。
......
# 十六、继续学习
设计好的系统需要多年的知识积累。一个捷径是深入现实世界的系统架构。以下是一些有用的阅读材料。我们强烈建议您关注共享原则和底层技术。研究每项技术并了解它能解决什么问题,这是巩固您的知识基础和优化设计流程的一个好方法。
## 现实世界的系统
......
# 十七、后记
恭喜你!您已到达本面试指南的末尾。你已经积累了设计系统的技能和知识。不是每个人都有学习你所学的东西的纪律。花点时间拍拍自己的背。你的努力会有回报的。
找到一份理想的工作是一个漫长的旅程,需要大量的时间和努力。熟能生巧。祝你好运!
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册