Skip to main content

qa

针对你提到的 OT、CRDT、Yjs(实时协同编辑)方向,面试官会结合你的简历岗位(通常是前端/全栈工程师协同应用开发分布式系统等)来提问。下面我按知识深度常见题型帮你梳理可能遇到的问题,并附上准备建议。


一、基础概念题(必问,用于判断你懂不懂)

  1. 什么是协同编辑中的“冲突”?举例说明。

    • 比如:A删掉字符“a”,B在“a”位置插入“b”,并发操作如何决定最终结果?
  2. OT(操作转换)的核心思想是什么?用一句话说清楚。

    • 答:将并发操作通过转换函数调整参数,使所有客户端按相同顺序执行后达到一致。
  3. CRDT 相比 OT 最大的优势是什么?

    • 答:无需中心化的转换逻辑,数学上保证无冲突(因为操作或状态满足交换律/幂等性)。
  4. Yjs 是基于 CRDT 的,为什么它比原生 CRDT 更受欢迎?

    • 答:优化了数据结构(StructStore)、支持多种数据类型、提供高效的网络和持久化绑定,性能接近 OT。

二、算法原理与对比题(考察理解深度)

  1. 请描述 OT 中一个具体的转换例子(如 insert(0, 'a') 和 insert(1, 'b') 并发时如何转换)。

    • 需要你能手画或口述:两个操作转换成对方坐标,保证最终文本一致。
  2. CRDT 分为状态 CRDT(CvRDT)和操作 CRDT(CmRDT),区别是什么?各自适用什么场景?

    • CvRDT:同步完整状态,适合点对点慢速同步;CmRDT:同步操作,适合实时协作。
  3. Yjs 如何处理删除操作?为什么需要“墓碑标记”?

    • 删除时不会立即清除数据,而是标记为 deleted,以保证其他客户端的并发插入能正确引用位置。
  4. OT 实现文本协同的难点在哪里?为什么说“实现正确的 OT 极其困难”?

    • 转换函数必须满足变换性质(TP1/TP2),且需要处理撤销、undo、复合操作等,容易出错。
  5. 为什么 Yjs 比传统 OT 更适合实现离线编辑?

    • 因为 CRDT 的操作可以独立、无序合并,客户端离线产生的操作队列无需与服务器转换,重新连接后直接交换并合并。

三、应用与设计题(考察工程能力)

  1. 如果让你设计一个多人实时文档编辑器(类似 Google Docs),你会选 OT 还是 CRDT/Yjs?理由是什么?

    • 开放性回答,但你需要能对比:
      • 选 Yjs:开发效率高、避免转换函数 bug、支持离线。
      • 选 OT:历史包袱(已有成熟库)、某些极端性能略优。
    • 结合团队能力和数据规模。
  2. Yjs 的“共享类型”(如 Y.Text, Y.Array)是如何实现“结构共享”的?

    • 类似 Immutable.js,更新产生新树根,未变化节点复用引用。
  3. 在协同应用中,如何处理“光标位置”和“选区”?OT 和 CRDT 各自的问题?

    • OT 需要额外转换光标位置,CRDT 中光标通常作为“扩展属性”处理,可能因延迟而闪烁。
  4. Yjs 的网络传输层如何处理大量操作?会有什么瓶颈?

    • 默认使用二进制编码和增量更新,瓶颈可能在于频繁的 GC(删除留下的墓碑)和 merge 时的计算。

四、扩展与陷阱题(判断知识边界)

  1. CRDT 是否完全不需要中心服务器?P2P 模式下如何处理用户加入/离开?

    • 回答:CRDT 理论上可去中心,但实际中仍需信令服务器或 DHT 发现节点,完全无中心很难保障顺序。
  2. OT 的“幻影问题”是什么?如何解决?

    • 幻影:客户端的某些操作在转换后不再代表用户原意。解决:加时间戳或使用“版本化操作”。
  3. Yjs 的“分片”或“文档拆分”如何实现大规模协同(如超过 100 人同时编辑)?

    • 可回答:Yjs 本身支持细粒度更新,但超大规模需要将文档拆分为多个子结构(如段落级 CRDT),并限制广播范围。
  4. 除了文本,协同编辑还支持哪些数据类型?试述 Yjs 的 Y.Map 如何保证并发 set 无冲突。

    • Map 使用 Last-Write-Win 或基于版本向量的方式,保证最终一致性。

五、开放行为题(看你是否有实际经验)

  1. 你是否读过 Yjs 或 ShareDB 的源码?讲一个你印象深刻的实现细节。

    • 如果没有,可以诚实说“只了解核心设计”,但描述一个你推测的细节(如删除墓碑、transaction 批量提交)。
  2. 你在项目中使用过 Yjs 吗?遇到了什么坑?如何解决?

    • 常见坑:历史记录膨胀(需要手动绑定 GC)、光标抖动、与后端的身份认证集成。
  3. 假设我们团队要做一个多人表格协同,你会推荐 Yjs 还是自动合并?为什么?

    • 表格的单元格依赖更复杂,可讨论用 Yjs 的 Y.Map + Y.Array,或者使用 OT 的“单元格锁定”方案。

准备建议

  • 熟读 Yjs 官方文档和一篇科普文章:至少理解 UpdateStructStoreTransaction 三个核心概念。
  • 手画 OT 转换例子:准备一个并发插入/删除的例子,用坐标转换演示。
  • 背诵优缺点对比表:OT / CRDT / Yjs 三者的核心差异(上一轮回答中已给)。
  • 准备一个开放设计回答:例如“如何设计协同白板的撤销/重做”(CRDT 下 undo 很难,需要额外记录操作栈)。

如果你愿意告诉我具体面试的岗位名称(如“前端协同应用开发”、“实时数据库工程师”),我可以进一步聚焦更精准的问题。祝你面试顺利!