题目重点:VO 题目给 15 条 transaction 样例与 time/user/currency 过滤;IC5 追问 timestamp 并列、amount 排序和缺索引超时。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版时间区间 [start,end],可选 user/currency 等值过滤,按 (time,id) 升序分页,id 全局唯一;limit>0。题目未定端点/方向,需在真实面试确认。
- cursor 为带版本和 filter/sort 指纹的 opaque token,包含最后返回的 (time,id);同一筛选与排序下才能继续。若新写入会修改视图,训练版只提供弱一致性遍历,需要快照 watermark 才保证不漏/不重。
- 按 amount 排序时训练版使用 (amount,id) 作为独立复合键;金额相同用 id 打破并列。
解题路线
- 先过滤时间、user、currency,再按复合键排序;第一页取前 limit 条,返回 last=(time,id) 编码 cursor。后页只取 key>last 的记录,limit+1 判断 hasMore;反向分页需反转比较和结果顺序。
- 不能只在 cursor 中放 time:样例 t=10 有 id20 与 id21,若第一页在 id20 截止,下一页用 time>10 会漏 id21;若用 time≥10 又可能重播 id20。
- 内存版可线性过滤 O(N) 并排序;生产 DB 建与常见 filter+sort 匹配的复合索引,例如 (user_id,currency,time,id) 或按查询频率调整。索引太多增加写放大,不能声称一个索引覆盖全部组合。
- amount 排序必须给 cursor 记录 (amount,id) 与排序字段;旧版 time cursor 要版本化/拒绝跨排序复用。超时日志若显示 amount 缺索引,可评估建索引、限制时间范围、异步查询或预聚合,不加索引的方案也有精确性/成本取舍。
- offset 简单但深页 O(offset+limit) 且插入删除时位移;keyset cursor 更适合稳定前行,但多条件过滤和任意跳页更复杂。对原 15 行样例做同时间戳分页、负 amount、空结果和过滤切换测试。
手动走一遍
样例里 user1/currency1 在 t=10 有 id20 与 id21。若 limit=1 且第一页最后是 (10,20),下一页条件 `(time,id)>(10,20)` 会保留 (10,21)。将排序换 amount 后,不能沿用 (10,20);需新版 cursor 如 (amount=15,id=20) 且绑定 amount 排序。
规模与取舍
内存 N 行过滤 O(N)、排序 O(M log M)、额外 O(M),M 为匹配行数;预建合适 DB B-tree 索引时定位 O(log N)、顺序取 limit 行约 O(limit),但不同过滤组合和快照一致性会改变成本。
易错点与追问
容易失分的边界
- cursor 只存 timestamp,漏/重同时间戳交易。
- 筛选条件变了还复用旧 cursor。
- amount 排序仍拿 time 字段当 cursor。
- 把深 offset 的成本与并发插入位移忽略。
- 见超时就盲目加索引,未分析查询频率、写入成本和选择率。
继续深挖
- 如何支持 amount 降序且 amount/id 并列?
- 新交易不断插入时如何提供快照视图?
- cursor 如何签名防止客户端篡改?
- 多字段可选过滤如何选索引?
