题目重点:多篇 Uber Infra 与 VO 面经提到 Driver Location Heatmap。以每秒百万位置更新、十秒刷新为明确规模,设计最新司机状态、格子计数、历史回放和热点分片。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 热力图显示每个地理格内当前可用司机的数量,按 10 秒刷新。活跃司机需最近一次位置未过期且状态可接单;过期阈值、格子分辨率由需求澄清,不在题目中硬填一个官方值。
- 题目的 100 万司机×每秒一次等于约 100 万位置事件/秒,十秒窗约 1,000 万事件;这是输入负载,不是十秒内 1,000 万个不同司机。
- 司机可能移动跨格、重复上报、乱序上报或下线;热力图需按司机最新有效位置去重,不把每次 GPS 上报都累加为一个新司机。
解题路线
- 摄入层按 driverId 分区,验证事件 ID、时间戳和单调序列;记录每位司机当前格、状态与最后有效时间。旧事件被新序列覆盖时忽略。
- 处理一次有效移动:如果从格 A 到格 B,原子或可恢复地对 A 计数减一、B 加一;同格更新只刷新时效。司机超时/下线触发反向扣减。热点格可拆成多个计数分片,再在发布时合并。
- 每 10 秒发布带版本/水位线的格子快照供地图读取;原始位置事件另写可回放日志与历史存储,用于审计、回填和不同时间窗口分析,不让历史查询拖慢实时写路径。
手动走一遍
司机 d 最初在格 A,上报 A 两次后移到 B。按最新状态计数应从 A=1,B=0 变为 A=0,B=1;若直接统计三条事件,会误成 A=2,B=1。若 B 的旧事件晚于新事件到达,按司机序列拒绝回退。
规模与取舍
输入约 10^6 事件/秒,十秒约 10^7 条。单条状态更新期望 O(1);状态规模 O(活跃司机数+格子数),原始事件存储按保留期线性增长。发布快照扫描有变化的格子或聚合分片,成本 O(活跃变化格数+热点分片数)。
易错点与追问
容易失分的边界
- 把上报次数当司机数量会被重试和高频上报放大;必须有 per-driver 最新状态和去重/覆盖语义。
- 单个城市中心格可能成为写热点,按地理格单 key 聚合会争用;需要更细分辨率或计数分片与分层汇总。
- 只使用实时内存态无法回答历史热力图或故障回放;题目明确提到历史数据,须保留可追溯原始流。
继续深挖
- 若 API 查询附近司机 ID 而非只要热度计数,要增加可按格检索的当前司机集合,并按状态/时效做最终核验;这是另一个服务读取目标。
- 对大规模数据要讨论端到端延迟、10 秒快照漏发率、司机位置过期率、计数守恒(移动前后总数不变)和重放后结果一致性。
