跳到主要内容
SUN / 笔记
← 全部文章

AI Coding 笔试高分指南

资料核对日期:2026-08-21

适用场景:限时完成复杂后端工程、业务规则或游戏规则题;考试内置 AI 只能查看和修改代码,AI 不能自行运行测试;对话记录、Token 消耗和最终自动评测都可能进入评价。

一、先理解真正的评分逻辑

牛客当前公开说明采用“结果 + 过程”双维度评价:

  • 结果分关注任务完成度;
  • 过程分关注 AI 协作质量;
  • 结果分未达门槛时,过程分不计入总分;
  • 过程分主要看 AI 对话质量和 Token 效率;
  • 对话质量进一步观察指令设计、产出审核、异常归因调优和现实约束校准。

具体企业可以配置不同题目和评价方式,公开资料没有给出统一权重。因此不要编造“代码 60%、Prompt 20%”之类公式。

考场上可以使用下面的优先级:

先保证结果门槛,再提高需求覆盖和测试强度,最后压缩无效 Token。

这不是说 Token 不重要,而是不能为了少聊两轮,交出一份没有覆盖核心规则的代码。

二、这种笔试与日常 Agent Coding 的关键区别

日常 Agent Coding 限时 AI Coding 笔试
Agent 可以反复运行测试和读取日志 AI 可能只有读写文件能力
可以慢慢探索和重构 时间、轮次和 Token 都有限
团队可以补需求和评审 考生必须独立解释歧义
关注长期维护和交付流程 首先关注隐藏评测覆盖率
过程文档可以很完整 对话必须短、清楚并直接推进代码

因此你不是把任务“完全委托给 AI”,而是给 AI 建立一个受限反馈回路:

flowchart LR
    A["人:提取需求与风险"] --> B["AI:检查仓库与接口"]
    B --> C["人:确认方案和优先级"]
    C --> D["AI:限定范围修改"]
    D --> E["人:运行或静态检查"]
    E --> F["AI:根据新证据修正"]
    F --> G["人:需求追踪与最终提交"]
    E -->|"发现遗漏"| A

先确认“不能测试”到底指什么

  • 情况 A:AI 不能运行,但考生可以点击 Run/Test。 让 AI 写测试,由你手动运行,再把准确失败信息交给 AI。
  • 情况 B:整个环境都不能执行代码。 只能进行静态一致性审查、样例手推、状态转换推演和测试代码检查。交卷时不要声称测试已经通过。

这两种情况的策略不同。开考第一件事就是检查规则、按钮、已有脚本和允许操作。

三、拿分公式:覆盖率 × 正确性 × 协作效率

可以把一次答题质量理解为:

得分能力 = 需求覆盖率 × 核心逻辑正确性 × 测试杀伤力 × 对话信息密度

四项中任何一项接近零,整体都会明显下降:

  • 少实现一条规则,隐藏测试会直接失败;
  • 代码很多但接口签名变了,可能无法被评测加载;
  • 测试只覆盖 Happy Path,无法发现 AI 的边界错误;
  • 每轮都让 AI 重新读全仓库,Token 会被上下文和重复分析耗尽。

四、建议的考场时间分配

下面用百分比表示,可以适配 60、90 或 120 分钟考试。

时间段 目标 最晚必须得到的产物
0%~8% 读考试规则和仓库 可编辑范围、入口、接口、测试能力
8%~20% 结构化需求 需求—代码—测试矩阵、歧义与假设
20%~30% 定最小方案 数据结构、状态不变量、预计文件
30%~65% 完成核心实现 主路径可静态闭合,不破坏既有接口
65%~83% 写高价值测试 正常、边界、非法、状态序列和属性
83%~93% 对抗性审查与修补 隐藏用例清单、确认后的最小修复
93%~100% 最终提交检查 需求逐条覆盖、Diff 干净、无未完成占位

两个纪律:

  1. 到 65% 时间点仍没有完整主路径,就停止架构优化,先完成可评测版本;
  2. 最后 7% 时间不再做大重构,只处理确定的编译、接口和高概率逻辑错误。

五、第一轮不要写代码:建立需求追踪矩阵

让 AI 读取题目、README、入口、类型定义和现有测试,然后输出一张短表:

ID 题目规则 输入与前置状态 期望结果 相关接口 测试类别 状态
R1 示例:同一玩家不能连续行动 轮到 A,A 已行动 拒绝且状态不变 applyMove 非法状态 未实现
R2 示例:重复请求只能生效一次 相同 idempotencyKey 返回原结果 createOrder 幂等 未实现

这张表是整场考试的控制面:

  • 防止 AI 只实现自己最熟悉的部分;
  • 让每轮修改都能指向具体规则;
  • 最终可以逐条检查,没有“应该差不多”的模糊判断;
  • 对话记录也能体现你在拆解和审核任务。

第一轮 Prompt

text
先不要修改代码。请阅读题目说明、README、现有目录、公共接口和测试。

只输出精简分析:
1. 按 R1、R2……列出所有可独立验收的规则;
2. 标出输入、输出、状态变化、异常、边界和性能约束;
3. 建立“规则—相关文件/接口—建议测试”矩阵;
4. 区分题目明确事实、从代码确认的事实、必须声明的假设;
5. 指出最可能导致隐藏测试失败的 5 个点;
6. 给出最小修改文件清单。

禁止修改代码,禁止泛泛讲最佳实践,控制在可快速审核的篇幅。

你必须审核这张表。若 AI 漏掉一句题目条件,此时补充最便宜;写完代码再发现,代价最大。

六、第二轮:先钉死接口、不变量和状态机

复杂后端题和游戏题最容易错的不是语法,而是状态组合。

实现前至少确定:

  • 评测会调用哪些公开函数、类、路由或命令;
  • 哪些签名、返回结构和错误语义不能改变;
  • 核心状态有哪些;
  • 每个操作的前置条件、状态变化和失败后状态;
  • 永远必须成立的不变量;
  • 重复、乱序、并发或非法操作如何处理;
  • 最大输入下的时间和空间复杂度。

方案 Prompt

text
基于已经确认的 R1~Rn,不要重新复述全部题目。

请先检查现有公开接口和调用方,然后给出最小实现方案:
- 必须保持不变的签名和输出格式;
- 核心数据结构与状态不变量;
- 每个操作的前置条件、成功转移、失败行为;
- 只修改哪些文件,为什么;
- 复杂度和最危险的边界。

优先复用现有结构,不新增依赖,不重构无关代码。
方案控制在 40 行内,等待我确认后再修改。

不要让 AI 同时比较五套架构。笔试需要的是最小正确方案,不是技术选型报告。

七、第三轮:按可评测纵向切片实现

推荐顺序:

  1. 保持公开入口和签名;
  2. 建立最小数据结构;
  3. 完成一个端到端主路径;
  4. 补业务分支和非法操作;
  5. 最后处理性能优化和代码整理。

实现 Prompt

text
现在实现 R1~Rk 的最小完整闭环。

要求:
- 只修改刚才确认的文件;
- 保持所有公开接口、返回格式和已有兼容行为;
- 失败操作不能留下部分状态;
- 不新增依赖,不写占位实现,不修改无关代码;
- 复杂规则集中在可测试的纯函数或明确状态转换中;
- 同步补充对应测试,但不要声称已经运行。

修改后重新读取实际文件,简短报告:
1. R1~Rk 分别落在哪个符号;
2. 哪些规则仍未实现;
3. 哪些地方只能静态确认。

一次只做一个有明确边界的切片。但也不要碎成“新增一个字段”“再新增一个 if”这种几十轮微指令,否则 Token 和时间会被往返消耗。

八、测试不是交付附件,而是隐藏评测模拟器

让 AI 直接说“写全面测试”通常只会得到几个 Happy Path。你需要指定测试设计维度。

8.1 通用六类测试

类别 要找的错误
正常路径 基本功能没有闭合
边界值 0、1、上限、空输入、最后一个元素
非法输入 空值、格式错误、未知 ID、重复数据
状态序列 单步正确但连续操作后错误
不变量/属性 总量守恒、排序稳定、状态互斥、失败不改状态
压力与复杂度 小样例正确但最大输入超时或爆内存

8.2 后端工程题重点

  • 缺少字段、额外字段、错误类型和超长输入;
  • 身份、角色、资源所有者和越权组合;
  • 重复请求、幂等键、重试和部分失败;
  • 分页边界、排序稳定性、过滤组合;
  • 事务失败后是否留下脏数据;
  • 并发更新、版本冲突和竞态;
  • 时间、时区、过期和临界时刻;
  • 外部依赖超时、异常与空响应;
  • 返回码、错误类型和 JSON 字段是否精确符合契约。

8.3 游戏规则题重点

  • 合法与非法动作是否严格区分;
  • 回合顺序、行动次数和资源消耗;
  • 棋盘或地图边界;
  • 胜负、平局和游戏结束后的再次操作;
  • 连续技能、叠加效果和优先级;
  • 同时触发多个规则时的结算顺序;
  • 重复行动是否幂等或必须拒绝;
  • 随机数能否注入或固定种子;
  • 失败动作是否保持原状态;
  • 一长串合法动作后的状态不变量。

测试 Prompt

text
请作为隐藏测试出题人,基于 R1~Rn 和当前实现设计测试。

先给测试矩阵,再写测试代码。必须覆盖:
1. 每条规则至少一个正例;
2. 每个条件的反例和边界;
3. 关键状态的连续操作序列;
4. 失败前后状态不变;
5. 至少 3 个跨规则组合;
6. 最大输入或复杂度风险;
7. 公共接口、返回格式和异常类型。

测试必须复用仓库现有框架和风格,互相独立,不依赖执行顺序,不修改生产代码来迎合测试。
AI 没有执行权限,因此不要声称测试已通过;写完后静态检查导入、签名、fixture 和断言。

九、AI 不能运行测试时,怎样验证

没有执行反馈时,要把一次动态验证拆成五种静态证据。

9.1 需求追踪

要求 AI 对每条 R1~Rn 指向实际代码符号和对应测试。找不到明确位置,就按未完成处理。

9.2 接口一致性

检查:

  • 函数、类、路由和构造参数;
  • 返回值、错误类型和序列化字段;
  • 导入路径、包名和可见性;
  • 所有调用点是否同步;
  • 测试调用方式是否与生产接口一致。

9.3 样例手推

选择最小正例、最小反例和一个长状态序列,让 AI 逐步列出输入前状态、分支条件和输出后状态。只允许引用实际代码,不允许按“理想实现”解释。

9.4 不变量审查

让 AI 搜索所有会写核心状态的路径,逐个证明:

  • 成功路径满足不变量;
  • 失败路径没有部分修改;
  • 早返回不会跳过清理;
  • 重复调用不会意外累积;
  • 集合、计数和索引始终一致。

9.5 测试代码静态编译审查

测试本身也可能写错。检查测试框架、导入、fixture、异步写法、断言 API、可见性和命名规则。一个无法被发现或无法编译的测试没有价值。

静态审查 Prompt

text
不要继续扩展功能。请重新读取所有实际改动文件和直接调用方,做静态一致性审查:

- 逐条映射 R1~Rn 到代码与测试;
- 检查公开签名、导入、类型、返回格式和错误语义;
- 对 3 个最危险状态序列按实际分支手推;
- 搜索所有核心状态写入点,检查失败是否原子;
- 检查测试能否被现有测试框架发现并编译;
- 只报告有文件和符号证据的问题。

发现确定问题时只做最小修复;不做风格重构。

十、用对抗审查提高隐藏测试通过率

接近完成时,不要再问“还有什么可以优化”。这个问题范围太大,容易诱发无关修改。

改成:

text
现在进入隐藏评测对抗审查。假设你要让当前提交失败:

1. 从题目每个限定词推导一个最可能的隐藏用例;
2. 优先检查接口契约、空/一/上限、非法状态、长序列、重复调用、顺序依赖和复杂度;
3. 对每个用例指出当前代码的实际执行路径和预期结果;
4. 将问题分为“已证实缺陷”“可能风险”“不影响”;
5. 只修复已证实缺陷,不新增功能、不改公共接口。

输出最多 10 个高价值用例,避免泛泛罗列。

对抗审查应该发生在主逻辑完成之后。太早做会让 AI 在不稳定代码上产生大量猜测和重复上下文。

十一、Token 效率的正确理解

Token 效率 = 有效需求覆盖和缺陷消除 ÷ 总对话成本

高效不是每轮只说十个字,而是每轮都带来可审核进展。

节省 Token 的有效方法

  • 不复制 AI 已经可以读取的完整代码,只指向文件和符号;
  • 第一轮一次性写清目标、约束、输出格式和禁止事项;
  • 限制读取范围,先入口、接口、测试,再扩展调用链;
  • 要求精简表格和结论,不生成长篇教程;
  • 将多个相关 Review 意见合并成一轮;
  • 修 Bug 时提供新证据:失败用例、实际分支或接口冲突;
  • 每轮结束只保留“已完成规则、剩余规则、风险、下一步”;
  • 没有新证据时不要原样重问;
  • 连续两轮没有缩小问题,停止补丁,回到需求或根因;
  • 最后审查只允许最小修复,防止上下文再次膨胀。

看似省 Token、实际丢分的做法

  • 直接把原题复制给 AI,要求一次写完;
  • 为了少一轮而不做需求分析;
  • 让 AI 输出完整代码块,再让工具重复写入;
  • 每次都要求“重新全面分析整个项目”;
  • 让 AI 生成大量 README、架构文档和注释;
  • 用“再检查一下”“还是不对”代替具体证据;
  • 追求最少对话轮数,导致遗漏只能在最后大修。

十二、怎样让对话记录本身体现能力

评分者看到的高质量轨迹通常具有因果关系:

text
题目条件
→ 需求编号
→ 相关接口和风险
→ 限定范围的实现
→ 测试或静态证据
→ 定位到具体原因
→ 最小修复
→ 最终需求追踪

低质量轨迹则是:

text
帮我全部实现
→ 再优化
→ 还有问题
→ 你全面检查
→ 怎么还不对
→ 重新写一遍

对话质量不等于 Prompt 术语多。Role、Context、Chain of Thought 等标签不会自动得分;真正能说明能力的是你如何根据新事实缩小范围并纠正 AI。

十三、交卷前 10 项检查

  • [ ] 每条题目要求都有 R 编号、实现位置和至少一个测试;
  • [ ] 没有擅自改变评测入口、公开签名和输出格式;
  • [ ] 没有 TODO、占位返回、空实现和调试代码;
  • [ ] 正常、边界、非法、长序列和跨规则组合已覆盖;
  • [ ] 失败操作不会留下部分状态;
  • [ ] 重复调用、顺序、时间和随机性有确定语义;
  • [ ] 最大输入的复杂度可接受;
  • [ ] 测试能被现有框架发现,导入、fixture 和断言静态一致;
  • [ ] 最后 Diff 没有无关重构、新依赖和被误删的兼容逻辑;
  • [ ] 未运行的测试明确标记为未运行,没有让 AI 虚构通过结果。

十四、训练方法

每次模拟训练记录五个指标:

指标 记录方式
最终正确性 公开和隐藏测试通过数
需求覆盖 R1~Rn 中完成并有测试的比例
对话效率 有效推进轮数 / 总轮数
Token 效率 每解决一条规则或缺陷的 Token
人工掌控 能否脱离 AI 解释状态机、接口和失败原因

建议每周做三类训练:

  1. 需求编译训练:10 分钟内把复杂文字转成规则矩阵;
  2. 隐藏用例训练:只读实现,写出能击穿它的边界和状态序列;
  3. 完整模拟:严格限时、限制 AI 执行权限,并保存对话和 Token 复盘。

训练时可以使用自定评分表,但必须标明它不是平台真实权重。最重要的复盘问题不是“Prompt 写得漂不漂亮”,而是:

  • 哪条原题限定词没有进入实现;
  • 哪个测试最早可以发现错误;
  • 哪轮对话没有带来新证据;
  • 哪次无关修改消耗了最多时间;
  • 下一次怎样用更短的规则矩阵避免重犯。

一页速查

text
0. 看规则:AI 不能跑,还是整个平台不能跑?
1. 读仓库:入口、接口、测试、数据结构、禁止修改项
2. 编译需求:R1~Rn + 状态 + 边界 + 假设
3. 定最小方案:接口不动、不变量明确、文件可控
4. 做主闭环:先能被评测,再补分支
5. 写强测试:边界、非法、序列、属性、组合、最大输入
6. 静态验证:签名、导入、调用点、手推、不变量
7. 对抗审查:像隐藏测试作者一样攻击实现
8. 最小修复:有证据才改,不做大重构
9. 最终追踪:每条要求都有代码和测试

优先级:结果门槛 > 需求/测试覆盖 > 对话质量 > 无效 Token 压缩

参考资料

相关笔记

相关文章

强化学习笔记 →上下文工程 →Mission: 掌握多模态 LoRA 与 QLoRA →