SWE / RE / ML · System Design

Calendar多设备同步:日月年视图、事件版本与删除

视图是时间范围查询,多设备修改需要明确冲突合同。

题目重点:视图是时间范围查询,多设备修改需要明确冲突合同。

题意与假设

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

  • 创建event,日/月/年view,多设备同步。训练单用户calendar,允许离线草稿;共享邀请/完整重复规则不自动加入scope。
  • event存UTC instant及IANA zone标识,all-day以本地日期单独类型。时区规则由可靠库处理,不固定所有时区偏移或把一天永远视24小时。

解题路线

  1. Event(id,calendar,start/end,type,timezone,title,version,deleted)与每用户change sequence。视图查询区间交叠start<view_end且end>view_start,用半开边界;year view可聚合摘要,不能拉全历史才画一年。
  2. 写带client_event_id/idempotency key,server分配新version及change seq。设备按cursor拉changes并定期完整snapshot校准,实时push只提示有变化,不替代持久change feed。
  3. 离线更新使用base_version条件写;训练冲突显式409+当前版本,由用户或字段级规则处理。不能把last-write-wins默认为正确,尤其start/end来自不同设备时合并可能形成end<start。
  4. 删除写tombstone,offline设备恢复能知道删除;tombstone保留期结束后旧cursor必须完整重同步,不能让过期设备把已删除事件重新上传。
  5. 夏令时、本地日期与device timezone变化分开:会议瞬时固定、all-day日期语义不同;用户切timezone展示会变,存储真实开始时刻不自动变。

手动走一遍

事件[10:00,11:00)在11:00开始的view不相交;跨午夜事件应在两天展示,不只查start落在哪天。A离线改时间、B在线删事件;A同步base_version过期,不能默默复活。

规模与取舍

时间范围查询取决于索引和交叠记录数,返回K事件O(K),同步O(cursor之后changes)。离线保留/删除归档与索引体积增长需预算,端上cache不能成为唯一历史。

易错点与追问

容易失分的边界

  • 不同设备用本地墙钟决定winner,时钟偏差覆盖更晚事实。
  • 删除物理移除无tombstone,离线设备看不到变化。

继续深挖

  • 加入recurrence/例外修改后怎样区分series与instance版本?
  • 多人共享calendar时,权限更新和离线写冲突如何处理?
✓已复制微信号!