题目重点:结合 IC15 onsite 的 category leaderboard 与实时追问,定义排名口径、写入状态、Top K 查询和流批一致性。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版每个 item 可属于一个或多个 category,事件可能改变 item 的分数;查询 topK(category,window),同分按 itemId 升序稳定排序。
- 设每秒 5 万分数事件、500 个 category、查询 p95 100ms,分别比较小时级批量榜与秒级实时榜;题目未明确这些数字。
- 分数是可加的事件贡献,重复 eventId 只计一次;实际若分数来自模型或不可逆更新,应改状态更新逻辑。
解题路线
- 先固定用户看到的榜单语义:分数来源、时间窗、刷新频率、删除/作弊过滤和并列规则,避免只选存储结构。
- 批量版从可回放事件日志按 category/window 聚合得分,排序生成版本化 Top K 快照,查询走缓存;成本与可复现性好,但窗口内变化不可立即反映。
- 实时版用分区流处理按 (category,item) 累积分数,维持有序索引或分片候选 Top K;更新带幂等键并由 checkpoint 恢复,迟到事件触发状态修正。
- 热点 category 拆分为局部候选榜并周期合并;查询展示榜单版本、生成时间与是否可能滞后,批量回算定期校准实时状态。
- 对比系统目标:实时性越高,写放大、重排频率和故障恢复成本越高;若产品只要每日榜,批处理更简单。
手动走一遍
摄影分类 A 得 10 分、B 得 9 分,B 收到一条 +3 事件。小时批量榜在下一次快照前仍显示 A 第一;实时榜在去重、更新分数索引后显示 B 第一。若该事件重试两次,eventId 去重必须防止 B 虚增到 15。
规模与取舍
单 category 有 M 项时全量排序 O(M log M);有序索引单次分数更新约 O(log M)、Top K O(K),总状态 O(Σ各 category 项数)。实际热点、分片合并和窗口过期决定资源;训练 QPS 仅用于估算。
易错点与追问
容易失分的边界
- 没有定分数和同分顺序就谈 Redis sorted set。
- 实时累计只增不删,滑动窗口过期后榜单错误。
- 跨分区热门 category 更新形成单点热点。
- 故障重放重复计分或恢复期间对外展示无版本的半成品。
继续深挖
- item 同属多个 category,更新扇出如何控制?
- 需要好友榜、地域榜时,维度组合会如何膨胀?
- 实时榜与每日正式榜不同,产品如何展示并解释差异?
