SDE2 · VO Round 3 System Design + Coding

Microsoft 外卖 10 公里餐厅搜索:空间候选召回与精确距离核验

以半径 10km 查附近餐厅,先覆盖相交网格召回、再按球面距离过滤;讨论营业状态、位置更新与排序。

题目重点:以半径 10km 查附近餐厅,先覆盖相交网格召回、再按球面距离过滤;讨论营业状态、位置更新与排序。

题意与假设

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

  • 训练版餐厅有 restaurantId、纬经度、服务状态;距离按球面直线 Haversine,10km 边界包含恰好等于半径者。
  • 返回所有在半径内且当前可服务的餐厅,可按距离升序分页;如果产品应按配送路网 ETA,须引入路线服务复排,不能用直线距离代替。
  • 餐厅位置相对静态,营业/接单状态可频繁变化;用户位置每次查询输入,权限和精度另问。

解题路线

  1. 将餐厅按地理网格/H3/geohash 之类空间索引登记。查询用户点时枚举所有与 10km 圆相交的格子,不只查用户所在格或固定 8 邻格:纬度和格子大小变化可能导致漏候选。
  2. 从这些格子取候选 restaurantId 并跨格去重,读取最新坐标/营业状态,对每个候选用 Haversine 精确比较 ≤10km,最后按距离和稳定 ID 排序分页。
  3. 索引可接受餐厅位置更新时异步维护,但查询阶段需用最新主记录复验;旧格子与新格子短暂并存时去重,若严格不漏还需更新顺序/双写协议。
  4. 规模较小时数据库空间索引与过滤足够;大规模热点地区可分片格子、缓存静态坐标、实时读取短 TTL 状态。监控漏召回测试、候选数、精排 p99、营业状态滞后。

手动走一遍

用户在格子边缘,餐厅在相邻甚至跨多个格子的 9.9km 处。只查同格会漏;枚举圆覆盖格取候选,再用精确距离确认。另一个 10.1km 餐厅可能被网格粗召回,最终被排除;网格负责不漏,距离计算负责不过收。

规模与取舍

查询成本约 O(G+C log C),G 为覆盖格数、C 为候选餐厅数,精确距离 O(C);索引存储 O(餐厅数) 加格子映射。实际吞吐受热门格子、餐厅密度、状态读与分页深度影响。若路网 ETA 排序,对少量候选再调用路线服务,成本另计。

易错点与追问

容易失分的边界

  • 只枚举固定 8 个邻格就断言覆盖 10km 半径。
  • 将经纬度欧氏差直接当公里,忽略纬度对经度距离的影响。
  • 只依赖可能滞后的空间索引营业状态,不做最终核验。
  • 把直线 10km 说成 10km 配送路程或 10 分钟 ETA。
  • 题目没有真实数据规模,不能声称必须用特定空间数据库。

继续深挖

  • 按道路 ETA 而非直线距离如何两阶段召回与复排?
  • 营业状态每秒变化时如何保持结果新鲜?
  • 高密度市中心 C 极大时如何限候选和分页?
  • 用户定位有误差时 10km 边界怎样处理?
✓已复制微信号!