一场三小时的笔试,功能全跑通,代码实现放在同批里算合格偏上,租户隔离、幂等、8 路并发、流式导出、事务边界都做了。结果没过。
先把这份材料里的数字摆出来,它们是理解后面全部内容的前提:
- 一场三小时的笔试;
- 后端、幂等、时区、流式 CSV 加全部测试,记录耗时 5.27 分钟;
- 七条验收场景走完,记录耗时 4.2 分钟;
- 提交文档里写着「比计划节省 29.73 分钟」;
- 8 路并发打同一个 key,只产生一张单;
- 导出十万行,按 1000 行分批流式输出;
- AI 会话总时长 2.5 小时,真人指令只有十几条。
这七条里,最扎眼的是那个 29.73。
一、题目考的是什么
题目原文只有一个要求:做出一个能跑的小产品,并且展示你如何指挥、验证、纠正 AI。
评分维度列了七项:端到端正确性、系统设计、对 AI 输出的验证与纠偏、AI 上下文与委派、工程实践、UX 判断、优先级。
明确不评分的也写了:写了多少条 prompt、烧了多少 token、用哪个工具、有没有写测试。
这四行把常见的加分动作全堵死了。堆功能不加分,堆测试不加分,prompt 写得漂亮也不加分。剩下的只有边界上的判断,以及这些判断有没有留下能被复核的证据。
二、七个考点,每一条都是一排坑
| 表面需求 | 真正考点 | AI 生成代码一般会错成什么样 |
|---|---|---|
| 只能看到自己租户的数据 | 授权在服务端每个入口生效;越权返回 404 且没有副作用 | 只在列表接口加过滤,详情、导出、批量、撤销漏掉 |
| 同一个 key 重复提交只算一次 | 幂等结果落库、并发安全、重启后仍返回同一结果 | 内存字典挡重复,重启即失效;先查后插并发插出两张单 |
| 换一个业务对象复用同一个 key | 返回 409、不覆盖首次结果、payload 参与判等 | 直接覆盖;或只比 key 不比 payload |
| 批量生成,一次处理一批 | 只处理合格的那部分,逐条给成功 / 跳过 / 失败和原因 | 整批一个事务,一条失败全批回滚 |
| 显示当地时间 | UTC 时刻和本地日历日分离,跨夏令时,排序和导出都用本地日期 | 按 UTC 日期分组,跨夏令时错一天 |
| 导出十万行 | 流式输出、快照一致、稳定排序、列表仍可用、60 秒内完成 | 全查进内存再拼字符串;边翻页边导前后不一致 |
| 撤销一张单 | 撤销幂等、恰好一条审计、和状态变更原子提交 | 先改状态再写审计,留孤儿状态 |
需求一句话,实现一排坑,而且每一排坑都落在 AI 的默认写法里。
三、先说做对的六处
一、租户完全由 token 推导,tenant_id 传参越不了权,五个入口逐个校验。
二、写路径用 BEGIN IMMEDIATE 加 savepoint 配合唯一约束,单据和审计落在同一事务;还注入过审计失败,验证不会留孤儿单据。
三、幂等结果落库。8 路并发打同一个 key,只产生一张单和一条审计,重启后还能重放。
四、CSV 按 1000 行分批流式输出,保持快照,两次导出字节级一致,并和 SQL 期望结果逐行比对过。
五、验收用真实 HTTP、独立进程、barrier 并发,不是 mock 出来的假并发。
六、README 把已知缺陷写清楚了,包括单写库、浏览器内存、Unicode 排序、移动端。
这六处放日常工作里都算硬功夫。工程实现不是这次的失分原因。
四、五个失分点,按杀伤力排
第一条是工程判断,后四条都在代码之外。
1. 三道书面题全答偏
三道题分别问 schema 在线变更、缓存失效竞态、重试与资源隔离。
第一道问在线给一列改名,滚动发布期间怎么滚。材料的答案是「删列被进程占用、锁表、加重试、降低锁粒度」,这是在解决「怎么安全地删」,而题目问的是「怎么在不删的前提下换成新名」。
正确做法是四步:加新列、双写、回填、切读,等所有实例升级完再延迟删旧列。双写期里旧实例还在写旧列,所以删列必须等回滚窗口过去;回滚时新代码退回去只写旧列,新列的数据只能靠回填任务补。
第二道问缓存和数据库谁先动。材料说缩短 TTL,还说「锁住相关数据直到缓存更新」。TTL 缩短只是把窗口变窄,窗口还在。竞态真正发生在「删缓存」和「写缓存」之间:一个读请求带着旧值回来,把刚删掉的缓存又填回去,旧值从此长期驻留。
有效机制要让旧值填不回来,常见三种:写入带版本号、缓存 key 带版本号,读时版本对不上就丢弃;逻辑过期,先返回旧值再异步刷;订阅变更日志异步删,加消息重试。
第三道关于重试。一条链路重试三次,每层都重试三次,最下游承受的就是 3 的层数次方。线程池被占满之后,同一个池子上的无关接口一起排队,本来健康的接口被拖死。后半问更要紧:下游不健康时那个接口该返回什么,答案是快速失败,返回 503 或者上一次的快照加 Retry-After。
2. 书面题的答案被贴进了 AI 对话
材料里有一份「无 AI 章节」:这部分自己写,用来对照有 AI 时的水平。实际上,这几道题的答案原文出现在了 AI 对话里,还让 AI 帮忙计时。
AI 一个字都没改。但评审打开会话日志,看到「无 AI 章节」的答案躺在 AI 上下文里,结论只有一个:这条边界没被当真。
信任在这一层断掉,前面做得扎实的东西就被重新审视。8 路并发是真的吗,字节级一致是怎么比出来的,README 里的缺陷是自己发现的还是 AI 列的。
3. AI 协作证据只呈现了「AI 交付」
2.5 小时的会话日志里,真人指令只有十几条,内容是「帮我完成」「你继续开发」「继续」。读需求、定设计、写代码、跑验证、写 README、写决策日志,基本都由 AI 产出。决策日志里只有两三条真纠错,还是 AI 自述的口吻。
题目要的是「你怎么指挥、验证、纠偏 AI」,而材料呈现的是「AI 交付、人转述」。
4. 私有仓库打不开
交接文档自己列着三项未完成:从远程新 clone 一遍、确认评审能访问私有仓库、按渠道发送仓库 URL 和最终 SHA。私有仓库评审打不开,就等于不可评审,所有证据都放在仓库里,仓库打不开,证据全部作废。
5. 5.27 分钟和 29.73 分钟
上面这三个数字本来想证明效率,结果证明了记录不可信,而且用的是最容易被验证的方式。评审对照 git 时间戳,只能得出两个结论之一:记录失真,或者代码不是从零写的。两种都扣「可追溯、真实」的分。
范围上还做了中英双语和品牌化 UI,都不是题目要求,题目反而明确写了要控制范围,不算大错,但挤占了验证与纠偏的精力。
五、三条能带走的
一、功能清单是载体,分在边界上。题目写着「做一个能跑的小产品」,重点从来不在「能跑」。
二、AI 能替你做,替不了你判断。这类笔试看的是你在关键节点上有没有自己的意见,以及意见有没有留下证据。
三、提交前最后一公里属于交付。仓库打不开、SHA 对不上、耗时记录不可信,任何一件发生,前面做得再好也只能按「不可评审」处理。
笔试考的不是你会不会写,是你有没有真的在指挥。
上面「七个考点 / 真正考点 / AI 生成代码一般会错成什么样」那张对照表,可以直接截图保存,笔试前照着给自己的代码过一遍。
说明:文中五条失分点来自材料推断,评审方未提供正式反馈。若拿到具体评语,应先用评语校正假设,再决定改进优先级。