题目重点:视图是时间范围查询,多设备修改需要明确冲突合同。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 创建event,日/月/年view,多设备同步。训练单用户calendar,允许离线草稿;共享邀请/完整重复规则不自动加入scope。
- event存UTC instant及IANA zone标识,all-day以本地日期单独类型。时区规则由可靠库处理,不固定所有时区偏移或把一天永远视24小时。
解题路线
- Event(id,calendar,start/end,type,timezone,title,version,deleted)与每用户change sequence。视图查询区间交叠start<view_end且end>view_start,用半开边界;year view可聚合摘要,不能拉全历史才画一年。
- 写带client_event_id/idempotency key,server分配新version及change seq。设备按cursor拉changes并定期完整snapshot校准,实时push只提示有变化,不替代持久change feed。
- 离线更新使用base_version条件写;训练冲突显式409+当前版本,由用户或字段级规则处理。不能把last-write-wins默认为正确,尤其start/end来自不同设备时合并可能形成end<start。
- 删除写tombstone,offline设备恢复能知道删除;tombstone保留期结束后旧cursor必须完整重同步,不能让过期设备把已删除事件重新上传。
- 夏令时、本地日期与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时,权限更新和离线写冲突如何处理?
