SWE / Diagram Product Team · System Design / OOD

Microsoft 在线架构图编辑器:图形移动、成组与数据模型

针对箭头、圆形和文字等对象设计文档模型、分组变换、命中选择、撤销与多人协作的边界。

题目重点:针对箭头、圆形和文字等对象设计文档模型、分组变换、命中选择、撤销与多人协作的边界。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版文档包含 shapeId 唯一对象;几何坐标用浮点数,形状自带位置/尺寸/旋转,箭头可有端点锚定关系。
  • Group 是有序子对象集合,允许嵌套但不允许祖先环;一对象同一时刻只有一个父组。
  • 移动选中的形状/组用世界坐标 delta,组内对象保持相对位置;锚点连接的箭头是否跟随需产品规则确认。
  • 单用户编辑为主合同;多人实时冲突、权限、撤销另列追问。

解题路线

  1. 数据模型拆 SceneDocument、Shape、Group、Connector。按 ID 的哈希索引实现查找;渲染顺序单独存有序 ID 列表,不能从哈希表顺序推断 z-index。
  2. 形状存本地几何与到父组的变换矩阵;获取世界坐标时沿父链组合变换。移动组优先更新组变换一次,无需把每个子节点坐标重写,绘制和命中测试再应用组合矩阵。
  3. 箭头有自由端点或绑定 shapeId+anchor 的两类状态。若绑定,目标形状移动后在渲染时重新计算端点;若自由,按自身移动命令平移。避免箭头坐标与绑定对象双重更新。
  4. group 操作校验没有重复父级与祖先环,将选中节点从原父级拆出并放入新组,同时转换本地坐标以保持屏幕位置不跳。ungroup 做逆变换。
  5. 移动/成组命令记录对象 ID、前后变换和文档版本用于撤销;协作扩展需按操作序列处理同组并发重排,题目未要求具体 CRDT。

手动走一遍

圆形 A 与文字 B 成组 G,A/B 在 G 坐标系中分别位于 (10,20)/(30,20)。移动 G (+5,+7) 只改 G 的 transform,屏幕上两者分别移到 (15,27)/(35,27)。若箭头端点绑定 A,该端点重新投影到 A 的新世界坐标,未绑定的另一端点保持原位。

规模与取舍

ID 查找预期 O(1);组平移更新 O(1),但受影响对象的重绘/命中更新 O(k),k 为组内可见对象数。世界变换直接沿父链是 O(depth),可缓存并按版本失效。文档存储 O(对象数+连接关系数),空间索引可使局部命中从 O(n) 降为近似 O(log n+k),具体取决于索引和分布。

易错点与追问

容易失分的边界

  • 把 Group 实现成一次性拷贝子元素,后续移动/撤销 ID 关系混乱。
  • 组移动时既改父变换又改每个子坐标,造成双重平移。
  • 箭头只存两个绝对坐标,无法表示绑定形状后跟随移动。
  • 用普通 ID 哈希表迭代顺序作为层级绘制顺序。
  • 把外链产品的协作协议/源码细节说成面试原题。

继续深挖

  • 旋转组内对象后如何正确做世界坐标命中测试?
  • 多个用户同时移动同一组怎样确定最终位置?
  • 百万形状的大文档如何做 viewport 渲染、空间索引与分片加载?
  • 撤销 group 时如何保持子对象的世界位置?
✓已复制微信号!