SWE · CodeSignal OA Four Levels

Coinbase Recipe Manager OA:搜索排序、版本历史与回滚

四级 OA 题从 recipe CRUD 到不区分大小写搜索、排序、用户与 rollback;明确快照所有权和版本 ID 语义。

题目重点:四级 OA 题从 recipe CRUD 到不区分大小写搜索、排序、用户与 rollback;明确快照所有权和版本 ID 语义。

题意与假设

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

  • 训练版 recipe=(id,name,size,ownerId,otherFields),id 唯一、size 非负;搜索只匹配 name,排序 size 同值再按 name/id,这些字段与 tie-break 是训练契约。
  • 每次成功修改(add/update/delete/rollback)产生全局递增 versionId 并记录该 recipe 的不可变快照或 tombstone;失败操作不产生版本。
  • rollback(recipeId,targetVersion) 将旧快照内容恢复为当前状态并再生成一个新版本,不删除后续历史;题目未明说,需核实际题面。

解题路线

  1. 用 id→当前 Recipe 保存 L1,CRUD 先校验唯一性、存在性和字段合法,再在单一 mutation 函数中更新当前状态与版本。
  2. search 对 name 做 Unicode/casefold 或题面要求的小写标准化;题目只说不区分大小写,locale 与中文大小写规则未给。list 先过滤再按指定 (size,name,id) 或 (name,id) 排序,limit 与方向按真实接口。
  3. addUser 独立维护 user ID→User;若 recipe owner 关联 user,应在 add/update 校验引用,题目只说新增 addUser,不能擅自要求每道菜都有 owner。
  4. versionHistory 保存每 recipe 的有序 (versionId,snapshot/deleted) 序列及 versionMap 用于 O(1) 定位;snapshot 必须深拷贝或用不可变对象,不能引用当前可变 dict。
  5. rollback 先检查目标版本属于同一 recipe、不是不可恢复状态,再用旧快照复制出新当前版本;测试回滚后继续更新、回滚到删除前和无效版本。

手动走一遍

训练例:v1 add R{name:'Soup',size:2},v2 update size=3,v3 delete,v4 rollback(R,v1) 后当前 R 为 size=2;历史仍有 v2/v3,v4 是新的恢复动作。若 v1/v2 共用同一可变对象,v2 更新会把 v1 的 size 也改为 3,回滚失真。

规模与取舍

CRUD 当前表平均 O(1),单 recipe V 版本 history 输出 O(V);versionMap 查找平均 O(1) 加复制 recipe 大小;N recipes 的 search/list 扫描 O(N),排序匹配 M 项 O(M log M)。版本存储随成功修改次数线性增长。

易错点与追问

容易失分的边界

  • 把 versionMap 指向当前对象,历史随更新变化。
  • 失败 add/update 也分配 version ID,造成与测试契约不符。
  • rollback 覆盖/删除后续历史,无法审计时间线。
  • 大小写不敏感 search 只转换 query 不转换 name。
  • 按 size 排序未定义并列规则,输出不稳定。

继续深挖

  • 删除后能否 rollback,tombstone 如何表示?
  • 大量 recipe 快照如何改事件日志或 copy-on-write?
  • 版本 ID 是全局还是每 recipe 局部?
  • 不同 locale 的 case-insensitive 搜索如何处理?
✓已复制微信号!