如何设计Google文档
如何设计 Google 文档
系统设计面试通常具有开放性,要求候选人具备广泛的知识储备。为了在此类面试中表现出色,重要的是覆盖不同的领域,而不是专注于单个主题。我们花费了大量时间筛选系统设计问题进行分析,主要标准如下:
- 问题流行且经典
- 确保所选问题的多样性
- 分析思路可迁移至其他面试问题
本周,我们将讨论如何设计 Google 文档。您会发现,它与我們先前分析的问题截然不同。
问题:如何设计 Google 文档
我假设大家都了解 Google 文档 是什么,因此不再浪费篇幅介绍该产品。
乍看之下,这个问题似乎非常笼统,事实也确实如此。Google 文档是一个功能庞大的系统。如果您花几分钟思考这个问题,可能会意识到它比表面上看起来复杂得多。
作为面试官,我不想将讨论范围局限于产品的特定功能。相反,我倾向于让问题更广泛、更宏观,以便观察候选人如何逐步解决模糊的问题。
系统组件拆解
我们在 以前的文章 中多次强调,当问题规模很大时,建议先提供高级解决方案。抽象解决方案的一种有效方法是将大型系统划分为较小的组件。
显然,Google 文档是一个庞大的系统,拥有众多功能,包括文档存储、共享、格式设置、编辑等。实际上,如果不将其分解为不同的子问题,几乎无法解决这个宏观问题。
如果您尚未考虑此问题,建议花 5-10 分钟尝试自己回答,然后再查看我们的分析。另外值得注意的是,如果您的解决方案与我们不同,这完全没问题,因为这个问题是开放性的。

我们可以将整个系统分为以下主要部分:
- 文件存储:由于 Google 文档是 Google 云端硬盘 的一部分,因此存储功能也包含在内。该系统允许用户将文件(文档)分组到文件夹中,并支持编辑、创建、删除等操作,其工作方式类似操作系统。
- 在线编辑和格式化:毫无疑问,在线编辑是 Google 文档的核心功能之一。它支持 Microsoft Office 的几乎所有功能,甚至更多。
- 协作:Google 文档允许多人同时编辑一个文档,这令人惊叹,当然也是一项技术挑战。
- 访问控制:您可以与朋友共享文档并赋予不同的权限(所有者、只读、允许评论等)。
这里忽略了一些次要功能,例如 插件、拼写检查、发布到 Web 等。
存储与格式化
我将这两个主题放在一起讨论,因为实现了存储和格式设置后,就创建了一个非常基本且初级的 Google 文档版本。即使没有访问控制和协作功能,单个用户仍然可以使用它来编辑文档。
在某种程度上,存储和格式化可以分别视为后端和前端。
恕我直言,Google 文档(或 Google 云端硬盘)的存储系统非常接近操作系统。它具有文件夹、文件、所有者等概念。
因此,要构建这样的系统,基本的构建块是一个文件对象,其中包含内容、父对象、所有者以及其他元数据(如创建日期)。父级表示文件夹关系,根目录的父级为空。我不会深入讨论如何扩展系统,因为构建分布式系统非常复杂,需要考虑一致性、复制等诸多因素。
对于前端格式化,一个有趣的问题是如何存储具有相应格式的文档。如果您知道 Markdown,那么它绝对是最好的解决方案之一。尽管 Google 文档的实现可能更复杂,但 Markdown 的基本思想仍然适用。
并发协作机制

Google 文档最酷的功能之一是多人可以同时编辑一个文档。您将如何设计此功能?
老实说,这不是一个容易的问题。您不能只让每个人独立工作,然后合并每个人的副本或让最后一个编辑获胜。如果您尝试过协作编辑功能,实际上可以看到其他人在做什么,并得到即时反馈。
如果您使用 Git 进行版本控制,此处的一些想法可能相似。首先,让我们考虑最简单的情况——只有 2 个人正在编辑同一文档。假设文档内容为 "abc"。
基本上,服务器可以为每个人保留文档的副本,并跟踪完整的修订历史记录。当用户 A 在开头添加 "x" 来编辑文档时,此更改将与 A 看到的最后一个修订版本一起发送到服务器。假设此时用户 B 删除了最后一个字符 "c",并将此更改发送到服务器。
由于服务器知道针对哪个修订版本进行了更改,它将相应地调整更改。更具体地说,B 的更改是删除第三个字符 "c";但当 A 在开头添加 "x" 后,原第三个字符变成了第四个字符,因此 B 的操作将被转换为删除第四个字符。
这称为 操作转换(Operational Transformation, OT)。如果您从未听说过,也没关系。其基本思想是根据每个人的修订和其他协作者的修订,对每个人的操作进行转换。
访问控制
Google 文档使您可以邀请协作者访问具有 不同权限级别 的每个文档。
朴素的解决方案应该不难。对于每个文件,您可以保留一个具有相应权限的协作者列表(例如只读、所有者等)。当一个人想要执行特定操作时,系统将检查其权限。
通常,我想问一下扩展这种访问控制系统的挑战。
众所周知,将系统扩展到数百万用户时,可能会有很多问题。我想在这里提及的几点包括:
- 速度:当所有者更新文件夹的权限(例如,删除特定的查看者)时,此更新应传播到其所有子级。速度可能是一个瓶颈。
- 一致性:当存在多个副本时,保持每个副本的一致性很重要,尤其是当多人同时更新权限时。
- 传播:可能有很多传播案例。除了更新文件夹的权限外,还应反映到文件夹的所有子级。如果您向某人授予文档 D 的读取权限,那么他可能也对文档 D 的所有父级具有读取权限。如果有人删除了文件 D,我们可能会撤销他对文件 D 父级的阅读许可(也许不会,这更多是产品决定)。
总结
再说一次,Gainlo 团队中没有一个人曾经参与过 Google Docs 的实际构建。这篇文章并不是教您如何从头开始构建 Google 文档。
相反,我想通过这篇文章为您提供有关如何进行系统设计面试以及如何解决模糊问题的更多思路。
设计像 Google Docs 这样的复杂系统可能会令人生畏。但是,一旦将系统划分为较小的组件,它将变得更加简单。
说明:本文基于经典系统设计面试思路整理。文中提到的操作转换(OT)是解决并发编辑的经典方案,目前业界也有使用 CRDT(无冲突复制数据类型)等其他方案。文章内容侧重于面试方法论,具体技术实现可能随版本演进有所变化。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/ru-he-she-ji-google-wen-dang.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。