题目重点:把注册、健康更新、距离计算和用户路由做成顺序状态机,按距离与名称稳定选第一个仍有容量的节点。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 经度范围 [-180,180]、纬度 [-90,90],capacity>0 且 name 全局唯一,注册后 load=0、healthy=true。
- 距离半径 R=6371 km,先用未取整的真实 Haversine 距离决定路由顺序,仅在输出时四舍五入到整数;若原题按取整距离破平局,要以测试/面试官确认为准。
- 训练版输出健康节点名按字母序拼接;题目说‘全部健康节点名’但未给顺序。NONE/no healthy 的大小写以题目示例区分。
解题路线
- 把命令解析与业务状态分离:REGISTER 原子验证并创建;失败不留下半个节点。SET_HEALTHY 只改指定节点状态,健康恢复不自动清零既有 load,除非题面要求。
- DISTANCE 先验证两点;角度转弧度,令 a=sin²(Δlat/2)+cos(lat1)cos(lat2)sin²(Δlon/2),c=2atan2(√a,√(1−a)),d=6371c。浮点误差使 a 略越 [0,1] 时先 clamp。
- ROUTE 先验证用户坐标,选所有 healthy 节点并按 (未舍入距离,name) 升序排序,再扫描至第一个 load<capacity;成功后 load+1,返回节点名、输出距离、健康名列表。若健康节点存在但都满,返回 None 加健康列表;零健康节点按题目描述的单独 NONE 输出。
- 测试非法边界、同名重复注册、健康反复切换、完全等距节点、就近节点已满而次近可用、全部满、空节点、负 0/180 经线附近以及取整边界。
手动走一遍
训练例 A、B 都健康且与用户等距,A 名称字母序在前但 load=capacity,则 ROUTE 扫过 A 并选择 B,B.load 增 1。下次若 B 也满,返回 None 和健康名单。不能因最近的 A 满载就直接失败。
规模与取舍
N 个中心、Q 个命令:注册/健康更新哈希期望 O(1),DISTANCE O(1);每次 ROUTE 全量计算和排序 O(N log N)、额外 O(N)。若只要最优可用节点,线性扫描维护最小 (distance,name) 可降到 O(N),但健康名单仍需收集。
易错点与追问
容易失分的边界
- 对舍入后的公里数排序,让真实距离不同的节点误按名称决定。
- 把不健康节点也放进候选或健康名单。
- 最近节点满了就返回 None,没继续找下一节点。
- ROUTE 失败仍增加 load。
- 极端经纬度使 Haversine 根号参数因浮点误差为负。
继续深挖
- 新增 RELEASE 命令时如何降低 load 并避免重复释放?
- 大规模中心时怎样用地理索引找近邻,且在容量与健康动态变化下保持正确性?
- 输出健康节点列表的稳定顺序与整数取整应如何写进协议?
