- 复习 figma 的做法方案
- 需要能回答这个问题
- How would you design a real-time collaboration feature for Canva, allowing multiple users to edit a design simultaneously?这是一个非常经典的System Design问题,也是Canva的核心功能之一。
- 我感觉自己回答得不够深入,特别是在处理冲突和保证数据一致性方面。我的思路是这样的。首先,我把系统分为前端和后端。前端负责渲染设计元素,捕捉用户的操作,并将这些操作发送给后端。后端负责处理这些操作,维护设计的唯一真实状态,并将更新广播给所有协作者。在客户端,用户的每一个操作,比如移动一个元素,改变颜色,或者添加文本,都会被序列化成一个操作事件。这个事件会包含操作类型,元素ID,以及操作的参数。比如 faction: “move”, elementld: “123”, position: {x: 100, y:200}}。这些事件会通过WebSocket发送给后端,因为WebSocket可以提供低延迟的双向通信。在服务器端,我设计了一个中央服务器来处理所有的协作会话。每个设计文档都有一个对应的会话。当一个用户加入协作时,他的客户端会与服务器建立一个Websocket连接,并加入到该设计的会话中。服务器会维护每个设计文档的当前状态,可以是一个JSON对象或者其他数据结构。当服务器收到一个来自用户的操作事件时,它会首先验证这个操作的合法性,然后更新文档的中央状态。更新完成后,服务器会将这个操作事件广播给会话中的所有其他客户端。其他客户端收到事件后,就在本地应用这个操作,从而更新自己的视图。
- 面试官追问的第一个点是,如何处理操作冲突。比如两个用户同时移动同一个元素。我当时提出的解决方案是基于时间戳的“最后写入者获胜”LWW。每个操作都带有一个客户端生成的时间戳,服务器在处理时,如果发现冲突,就简单地接受时间戳最新的那个操作。现在回想起来,这个方案太简单了。它不能保证操作的意图,可能会导致非预期的结果。更好的方法应该是使用OperationalTransformation简称OT或者Conflict-free ReplicatedData Types简称CRDTS。OT通过转换操作来解决冲突,保证最终一致性,但实现非常复杂。CRDTS则通过设计一种特殊的数据结构,使得在任何顺序下应用操作都能得到相同的结果,从而天然地避免了冲突。我当时对OT和CRDT的理解只停留在概念层面,没有能够深入地讲解它们的工作原理和实现细节,这可能是一个主要的失分点。
- 面试官追问的第二个点是,如何保证系统的可扩展性。如果一个设计有成干上万的协作者怎么办?我提出的方案是使用多个服务器实例,通过一个负载均衡器来分发请求。每个设计会话会被分配到一个特定的服务器上。