题目重点:题目只给列表 dataflow 题型;以显式训练假设拆解商家目录、营业与库存事件、配送覆盖、实时过滤、列表排序、缓存失效和端到端新鲜度。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练场景:用户打开 Eats 的一个地区列表页,返回当前可配送、可接单的餐厅摘要并分页;前端会展示营业、ETA 和简要菜单/价格信息。题目未明示这些字段,实际面试先问输出契约。
- 商家有相对稳定的目录字段(名称、地址、菜系、配送区),也有快速变化的营业开关、接单能力、菜单可售和预计送达;列表可容忍秒级展示滞后,但下单时必须重新校验。
- 示例规模取百万商家、峰值十万列表请求/秒、营业状态数秒变更,仅用于讨论索引/缓存,不代表 Uber 实际数据。
解题路线
- 数据源分开:商家目录写入权威数据库,营业与可接单状态由商家/运营系统产生事件,菜单库存和配送范围各有所有者,ETA 来自实时供给服务。每个事件带 merchantId、版本/时间、来源,摄入层按幂等键去重并处理乱序。
- 物化一个区域索引:按地理覆盖找到粗候选商家,再把目录静态字段与最新状态合并成 listing projection。热状态变更做增量更新,必要时定期从事实源重建/对账,防止漏事件导致已关门商家长期上榜。跨地区配送区不可只按餐厅所在格过滤。
- 查询路径先根据用户位置从空间索引取候选,合并餐厅状态与配送可行性,按约定排序并分页;分页游标应绑定过滤条件、排序版本和快照时间,避免连续翻页时状态变化造成明显重复/跳项。对超大候选集用两阶段过滤与有限 Top K,不能对全城餐厅每次做实时 ETA。
- 缓存可按地理区域、时段与过滤条件复用候选,但营业/可接单变化需主动失效或短 TTL;响应带 dataAsOf,让陈旧数据可观测。下单交易对营业、菜单价格/库存、配送可行性再做最终核验,列表展示不是支付承诺。
- 追踪事件产生→投影更新→查询可见的延迟,按城市、商家和事件类型分组监控;配置回放、死信队列、schema 兼容与重建流程,避免单次流任务故障后需要手工补所有列表。
手动走一遍
商家 R 从营业切为暂停接单,事件版本 12 写入状态事实源并进入变更流;投影处理器更新 R 的可见状态,区域缓存失效。某用户在事件传播前仍可能看到 R,但点击下单时由交易服务再次校验并返回明确的不可下单原因。随后延迟到达的版本 11 事件不能把 R 又改回营业。
规模与取舍
N 商家、每秒 U 次状态更新、每秒 Q 次列表查询。直接每次扫描 N 为 O(QN),需区域候选索引把每次搜索缩为 C 家,再做 O(C) 过滤和 O(C log K) Top K。状态投影存储 O(N),事件处理吞吐约 O(U),多区域复制与缓存失效量取决于商家覆盖的区域数。
易错点与追问
容易失分的边界
- 把静态商家目录缓存当实时营业事实源,关门/暂停接单更新无法及时反映。
- 只看餐厅与用户直线距离,不验证配送范围和当前可接单状态。
- 把列表页上的可见状态视为下单最终承诺,未在交易环节重检库存、价格和配送。
- 异步事件乱序覆盖新状态,或缺少 dataAsOf/对账而无法发现长期陈旧。
继续深挖
- 如果改成个性化推荐列表,如何在此可行候选之上加 q45 的召回/排序而保持实时硬过滤?
- 大型活动期间某个区域写入和查询同时爆发,怎样拆热点并避免缓存雪崩?
- 商家菜单大批量改价时,如何维护列表摘要、详情页及结算价格的一致性边界?
