SWE / IC5 · Onsite Coding / AI-enhanced Pilot

Coinbase 交易历史分页:时间并列 ID Cursor 与 Amount 排序

VO 题目给 15 条 transaction 样例与 time/user/currency 过滤;IC5 追问 timestamp 并列、amount 排序和缺索引超时。

题目重点: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 打破并列。

解题路线

  1. 先过滤时间、user、currency,再按复合键排序;第一页取前 limit 条,返回 last=(time,id) 编码 cursor。后页只取 key>last 的记录,limit+1 判断 hasMore;反向分页需反转比较和结果顺序。
  2. 不能只在 cursor 中放 time:样例 t=10 有 id20 与 id21,若第一页在 id20 截止,下一页用 time>10 会漏 id21;若用 time≥10 又可能重播 id20。
  3. 内存版可线性过滤 O(N) 并排序;生产 DB 建与常见 filter+sort 匹配的复合索引,例如 (user_id,currency,time,id) 或按查询频率调整。索引太多增加写放大,不能声称一个索引覆盖全部组合。
  4. amount 排序必须给 cursor 记录 (amount,id) 与排序字段;旧版 time cursor 要版本化/拒绝跨排序复用。超时日志若显示 amount 缺索引,可评估建索引、限制时间范围、异步查询或预聚合,不加索引的方案也有精确性/成本取舍。
  5. 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 如何签名防止客户端篡改?
  • 多字段可选过滤如何选索引?
✓已复制微信号!