面试手撕 / AI Coding

AI Coding 笔试手撕通关指南:五类岗位题型、隐藏用例与限时交付

AI Coding 工程题不是“让模型替你写完代码”,而是要求你在受限环境中,把一份需求说明转化为一个可运行、可验证、可提交的程序。代码生成只是其中一环;真正影响交付质量的,往往是需求理解、约束表达、测试设计和风险控制。

本页整理一套可迁移的考场工作流。文中的业务场景和提示词均为方法示例,不是对真实题目的复刻,也不代表任何公司的固定题型或评分规则。具体要求始终以当场题面为准。


1. 先认识题型:从“写函数”变成“交付系统”

传统算法题通常给定函数签名、输入输出与样例;AI Coding 工程题则可能提供:

  • 一份 Markdown 或类似格式的需求文档;
  • 浏览器 IDE、已有项目骨架或空仓库;
  • 一个可以对话并修改代码的模型;
  • 指定的语言、入口、启动命令、端口和依赖限制;
  • 公开样例、基础检查或部分可见测试;
  • 限时提交及不可见的评测用例。

常见考试流程可以概括为:

  1. 阅读题面,确认环境与交付物;
  2. 把需求转换为功能清单、接口契约和约束清单;
  3. 指挥模型完成最小可运行闭环;
  4. 本地启动、调用或执行程序;
  5. 补充边界测试,根据失败信息做小范围修复;
  6. 复跑回归测试,核对启动方式和最终文件后提交。

公开样例通过,只能证明某条已知路径可以工作。隐藏用例通常还会检查非法输入、边界值、重复请求、非法状态迁移、精度以及失败后的数据一致性。因此,目标不应停在“程序能动”,而应推进到“关键行为可以被验收”。


2. 读完题面,先产出四张清单

不要一上来只说“实现这个项目”。模型会自行补全未说明的部分,而这些“合理猜测”很可能恰好违反评测契约。更稳妥的做法是先整理四张清单。

2.1 环境清单

逐项记录:

  • 允许的语言与版本;
  • 指定框架、入口文件和目录;
  • 启动命令、监听地址与端口;
  • 能否联网、能否安装依赖;
  • 输入输出位置、工作目录和文件命名;
  • 提交时需要保留或禁止修改的文件。

环境要求不是实现细节,而是验收的一部分。业务逻辑正确但启动命令不匹配,评测程序仍可能无法访问服务。

2.2 契约清单

HTTP 题应逐项抄清:

  • 请求方法和路径;
  • 路径参数、查询参数、请求头与请求体;
  • 必填字段、类型、范围和默认值;
  • 响应状态码、JSON 层级、字段名与字段类型;
  • 失败响应的格式及错误码。

CLI 或文件处理题则要锁定:

  • 参数名和调用方式;
  • 标准输入、标准输出、标准错误的职责;
  • JSON、CSV 等数据格式及编码;
  • 输出顺序、换行、退出码和文件副作用。

契约要精确,不要把 order_id 擅自改成 id,也不要把题面要求的整数输出成字符串。

2.3 规则清单

将自然语言规则改写为可判断的条件,例如:

  • 哪些状态可以迁移到哪些状态;
  • 金额使用整数最小单位还是定点小数;
  • 折扣、税费、上下限和取整顺序;
  • 资源不存在、参数非法、权限不足、业务冲突分别如何响应;
  • 同一业务请求再次到达时,是返回既有结果、拒绝,还是重新计算;
  • 操作中途失败时,哪些数据必须保持不变。

2.4 验收清单

把大需求拆成一组可以立即证明完成的功能块:

  • “创建订单:校验商品、计算金额、持久化并返回指定结构”;
  • “取消订单:只允许指定状态取消,重复取消行为符合题面”;
  • “执行分析:读取数据、按要求分层统计、输出结论与依据”。

不要按“先写数据层、再写服务层、最后写接口层”来切任务。技术分层本身通常无法独立验收,且多轮对话后模型容易丢失跨层约束。更实用的判断标准是:这一块完成后,能否立刻运行一个测试证明它正确?


3. 五类岗位题型及各自的失分点

不同岗位虽然都使用 AI 辅助编码,但交付物和评分重点并不相同。先判断题型,再决定时间花在哪里:

岗位 常见交付形态 核心能力 优先目标
工程岗 内存态服务、接口与状态流转 需求取舍与一致性 主链路可运行,失败无副作用
算法岗 模型训练、预测或结果后处理 建模判断与指标提升 先产出合法基线,再迭代指标
数据分析岗 数据脚本、统计结果与业务结论 分层归因 证明或推翻结论,而非只计算总体数
Agent 岗 记忆、检索、生成与审计服务 防御不可靠模型输出 校验、治理、追溯与兜底闭环
游戏开发岗 单个决策函数或策略模块 规则理解与策略质量 永远返回合法动作,再提升胜率

题面的业务外壳可能变化,表中的划分也不是平台统一标准。真正需要识别的是:评测器最终读取什么、按什么指标给分,以及失败时是否会提供明确反馈。

3.1 HTTP 服务与业务系统

这类题要求实现可启动的服务,评测器通过 HTTP 直接调用接口。典型业务可能涉及订单、账户、审批、保险或核算。

接口契约

评测器往往按固定路径、状态码和字段读取结果。以下差异都可能导致失败:

  • POST /orders 写成 POST /order
  • 应返回 201 却返回 200
  • total_amount 被改名;
  • 错误响应缺少指定字段;
  • 空数组被输出成 null

实现前最好将每个接口写成“方法 + 路径 + 输入 + 成功响应 + 失败响应”的验收条目。

状态机

用显式迁移表管理状态,而不是散落的条件判断:

当前状态 -> 允许的下一状态
CREATED  -> CONFIRMED, CANCELED
CONFIRMED -> PROCESSING, CANCELED
PROCESSING -> COMPLETED
COMPLETED -> 无
CANCELED -> 无

实际状态与迁移必须照题面填写。合法迁移要成功,非法跳转、终态修改和重复操作也要有确定行为。

金额与精度

金额规则至少确认四件事:

  1. 内部表示:整数分、Decimal,还是题面指定类型;
  2. 运算顺序:先折扣还是先叠加费用;
  3. 舍入规则:四舍五入、向下取整或其他规则;
  4. 边界行为:负值是否归零、是否存在上下限。

不要默认二进制浮点能够稳定表示十进制金额,也不要自行添加题面没有要求的取整方式。

错误码分层

参数错误、资源不存在、权限失败和业务冲突不是同一类错误。具体 HTTP 状态码与业务错误码必须服从题面;若题面明确区分,就不要全部用一个通用错误响应代替。

幂等

若题面要求幂等,或操作涉及扣款、状态推进等不可重复副作用,应按指定规则处理重复请求,避免重复扣款或重复推进状态。创建类请求如果没有幂等键或业务唯一性约束,两次请求也可能合法地产生两个资源,因此不要自行发明幂等语义。可根据题面使用幂等键、业务唯一键或“已完成则返回原结果”等策略,同时测试:

  • 完全相同的请求重复到达;
  • 幂等键相同但业务参数不同;
  • 首次请求失败后再次提交;
  • 已到终态后再次执行动作。

失败无副作用

校验失败或业务拒绝时,不应留下半条记录、提前扣减库存或推进状态。推荐顺序是:先校验全部前置条件,再计算变更,最后一次性提交。若运行环境支持事务,可用事务保障原子性;否则要避免在校验过程中逐步写入共享状态。

三条跨接口通道

当题面反复要求失败无副作用、重复写安全和虚拟时间推进时,不要在每个接口里分别补丁式处理。可以先建立三条公共通道:

  1. 统一校验入口:所有前置条件通过前不修改共享状态;批量操作先完成整批校验,再统一提交。
  2. 统一重放处理:执行写操作前检查幂等键或题面指定的业务键;命中后返回既有结果,不重复产生副作用。
  3. 统一时间推进:若题目使用逻辑时钟,将到期、衰减和结算集中放在推进时钟的流程中,避免每个业务接口自行判断时间。

只有题面出现对应要求时才实现这些机制,不能把经验模式擅自写成题目没有规定的业务语义。

3.2 算法训练与模型后处理

算法岗常见两种方向,准备方式不同:

  • 训练型:给带标签的历史数据,要求训练模型并提高指定指标。
  • 后处理型:已有模型输出,要求完成校准、去重、合并、排序、排队或报告生成。

训练型首先要检查离线环境、可用依赖、运行时限、内存和 CPU 约束。不要默认常用机器学习库已经安装;先用现有标准库或已确认依赖建立一个能够完整训练、预测并生成合规文件的基线,再逐步增加特征和模型复杂度。

指标停滞时,优先审计:

  1. 指标是全局计算,还是按请求、用户或批次分组后计算;
  2. 训练特征在预测时是否真实可得,是否存在标签泄漏或未来信息;
  3. 评测集是否来自新时间段、新设备或新批次,导致数据分布变化;
  4. 本地验证集的划分是否模拟了真实评测边界。

算法正确但提交文件不合规,仍可能直接失分。建议单独编写输出校验脚本,至少检查:

  • 输出行数与输入要求一致;
  • 样本编号无丢失、重复或错误重排;
  • 预测值没有 NaN 或无穷大;
  • 列名、大小写、顺序和数据类型符合题面;
  • 主程序正常退出,输出文件已完整落盘。

后处理型则应先把模型输出视为待清洗数据,围绕校准目标、约束冲突、稳定排序和异常兜底设计验收用例,而不是重新训练一个题面没有要求的模型。

3.3 数据分析与归因

数据分析题通常给出数据和一个待验证的业务判断。交付物可能是脚本、统计结果、图表数据或结构化结论。

核心风险是把相关性直接当成原因。总体指标存在差异时,应检查样本分布是否不同,例如按城市、时段、订单类型、渠道或天气分层。一个稳妥流程是:

  1. 检查字段、缺失值、异常值和口径;
  2. 复现总体指标,确认分母与过滤条件;
  3. 按题面相关维度分层对比;
  4. 检查样本量、权重和混杂因素;
  5. 区分“数据支持的观察”与“仍需验证的因果解释”;
  6. 输出结论、证据、限制和可执行建议。

这类题不应照搬后端项目的分层架构。更合适的可验收链路是:取数校验 → 指标复现 → 分层分析 → 结论表达

若题面要求计算下推到数据库,应在 SQL 中完成过滤、聚合和必要分层,不要无条件把整表拉到内存。输出业务结论时同时给出样本量、口径、主要证据和限制,避免把观察到的相关性写成已经证明的因果关系。

3.4 Agent 记忆与模型输出治理

Agent 题的关键假设通常是:上游模型输出不稳定,不能直接信任或写入系统状态。可能出现结构变化、字段别名、非 JSON 内容、跨用户信息、敏感类别、过期事实以及同一轮中的自相矛盾。

一条稳妥的处理链路包括:

  1. 宽容解析:接受题面允许的多种形态,解析失败进入明确兜底路径;
  2. 严格校验:确认用户归属、字段类型、证据范围和敏感规则;
  3. 冲突处理:同轮矛盾、事实修订和重复事实按明确优先级处理;
  4. 生命周期治理:过期、衰减、容量淘汰和终态处理遵循题面时钟;
  5. 幂等与审计:同一轮重放不重复写入,修订和审计记录可追溯;
  6. 闭环自查:检索结果进入生成前再次过滤,生成结果按要求做安全或一致性检查。

测试时不要只喂标准 JSON。还应根据题面构造字段缺失、别名、错误类型、跨用户内容、敏感事实、过期事实、重复调用和解析失败等输入,确认系统能拒绝、降级或记录,而不是崩溃或污染记忆。

3.5 游戏开发与对抗策略

游戏开发类题可能只允许提交一个决策函数,地图、引擎和样例代码均为只读。评分也可能不是通过固定用例,而是与多个未知对手进行对抗后统计胜率。

准备时遵循三个顺序:

  1. 先读引擎,再写策略:从代码确认回合顺序、同时决策或先后决策、伤害结算、碰撞、资源消耗和终局条件;文字说明与引擎不一致时按题面规定确定权威来源。
  2. 先保证合法和不崩溃:所有分支都返回合法动作,对空候选、异常状态和极端输入设置保守兜底,避免被系统代选并累计违规。
  3. 先建立稳定基线,再提升胜率:先实现能完整打完一局的保守策略,再一次只修改一个决策因素,通过批量对局比较胜率、违规率和超时率。

若双方同时决策,策略不能依赖“看到对手本回合动作后再响应”的假设。对抗评分也意味着单个样例成功并不能证明策略有效,应使用不同初始状态、随机种子和对手风格做重复模拟。

3.6 工具与引擎

这类题可能要求实现命令行工具、静态检查器、调度器或媒体处理程序,常见接口是“读 JSON、写 JSON”或操作指定文件。

它的难点通常不是把主流程写出来,而是识别朴素方案的失效条件:

  • 代码分析若只用正则,可能无法正确处理语法嵌套、注释和字符串;题目要求语义准确时,应考虑 AST 或语言解析器;
  • 调度若只用 FIFO,可能无法满足优先级、资源约束或抢占规则;
  • 媒体处理若机械复用码流或只处理视频轨,可能违反时间轴、编码或音轨要求;
  • 文件工具若忽略退出码、标准错误和原子写入,主结果即使正确也可能验收失败。

拿到题后先问:“最直观的实现会在哪些输入上失效?”再将答案写入实现约束。领域方案必须由题面需求驱动,不能因为某个示例提到 AST、抢占或转码,就无条件套用。


4. 第一轮指令:一次写清执行边界

第一轮指令的目标不是展示文采,而是减少模型猜测。下面是可复用模板,方括号内容必须替换为当场题面信息。

你要在当前仓库中实现题面要求的程序。先阅读现有文件和需求,再执行修改。

【环境与交付】
- 语言/版本:[原样填写]
- 入口与启动命令:[原样填写]
- 端口或输入输出方式:[原样填写]
- 依赖与联网限制:[原样填写]
- 禁止修改的文件:[原样填写]

【功能与业务规则】
1. [规则一,保留题面中的条件、顺序和例外]
2. [规则二]
3. [规则三]

【接口或输入输出契约】
- [方法、路径、请求字段、成功状态与响应字段]
- [失败条件、状态码/退出码、错误结构]

【边界与一致性】
- 缺字段、类型错误、越界、空值按题面处理,程序不得崩溃。
- 金额/精度/舍入严格按题面实现。
- 非法状态迁移必须拒绝。
- 重复请求按题面的幂等规则处理。
- 失败操作不得改变已有状态或产生部分写入。

【执行顺序】
1. 先复述你识别出的硬约束和待修改文件;有歧义时明确列出,不要自行发明规则。
2. 建立最小可运行闭环,再按可验收功能块推进。
3. 每完成一块就运行对应测试,不要等到最后一起验证。
4. 最后按规定命令启动或执行程序,并报告测试命令、结果和剩余风险。

如果时间极短,可以压缩表述,但不要删掉环境、契约和验收。尤其要写死响应字段名、入口和启动方式。


5. 用测试驱动模型,而不是等隐藏用例判错

5.1 最小闭环之后立刻测试

开发顺序建议采用:

  1. 建立可启动、可调用的最小闭环;
  2. 实现一个完整功能块;
  3. 写正常路径和失败路径测试;
  4. 运行测试并保存结果;
  5. 做最小修复;
  6. 重跑本功能与既有回归测试;
  7. 再进入下一个功能块。

这样可以把故障限制在最近一次改动内,避免最后同时面对启动、接口、状态和数据四类问题。

5.2 让模型生成“攻击当前实现”的测试

以下模板用于自测,不代表真实隐藏用例:

请逐条对照当前需求与现有实现,新增一组可直接运行的测试。
现在只写测试,不修改业务代码。

覆盖范围:
- 缺字段、错误类型、空值、非法枚举、越界输入;
- 0、负数、最大值、空集合、单元素;
- 每条合法状态迁移,以及跳步、回退、终态修改;
- 重复提交与幂等键冲突;
- 金额精度、舍入顺序、上下限;
- 资源不存在、权限失败、业务冲突的响应差异;
- 失败前后数据快照一致,确认失败无副作用;
- 需求中已写明、但当前实现可能遗漏的规则。

先列出“需求条目 -> 测试用例”的对应关系,再生成测试文件并运行。
报告失败用例,但不要顺手修改实现。

“只写测试,不改业务代码”很重要,否则模型可能同时修改测试和实现,使测试失去诊断价值。

5.3 失败后使用可执行的纠错模板

不要只说“好像有问题”或“再改一下”。一次有效纠错应包含:失败证据、期望行为、改动范围和复验方式。

以下测试失败:[粘贴完整命令与失败输出]
对应需求:[粘贴相关原文或准确转述]
实际行为:[当前结果]
期望行为:[应有结果]

先分析根因,指出准备修改的文件与代码范围,不要重写无关模块。
采用满足需求的最小改动修复;已经通过的行为保持不变。
修复后重跑:
1. 当前失败测试;
2. 同功能块的边界测试;
3. 全量回归测试。
最后报告改动、测试结果和仍未覆盖的风险。

如果暂时不希望模型直接改代码,可加一条硬约束:

先不要修改文件。只回答根因、拟修改位置、潜在回归影响;等我确认后再执行。

6. 模型卡住时:缩小问题、换会话、能回滚

6.1 先补全证据

修复前提供完整信息:

  • 执行命令;
  • 完整错误栈,而非最后一行;
  • 相关输入与期望输出;
  • 最近一次改动;
  • 已通过且不得破坏的测试。

先让模型说明根因和影响范围,再决定是否授权修改。对一个局部错误大幅重写文件,通常会增加回归风险。

6.2 同一问题反复失败就换会话

同一会话里连续出现错误修复尝试时,旧方案可能持续干扰判断。如果同一个问题经过少量轮次仍无进展,可开启新会话,只提供:

  • 必要需求;
  • 当前代码状态;
  • 可复现命令;
  • 完整报错;
  • 已排除的原因。

新会话不是“从头重做”,而是清理错误上下文。切换前应保存当前可运行版本。

6.3 每次高风险修改前建立回滚点

可以使用版本控制提交、IDE 快照或复制关键文件。若修改后通过的测试变少、评测结果下降或主流程损坏,应先回到最近的稳定状态,再从更小的改动重新尝试。不要把剩余时间押在连续的大范围补丁上。


7. 按比例分配时间,而不是背绝对分钟数

场次时长可能不同,用比例比固定分钟表更稳妥:

阶段 建议占比 交付物
阅读需求与列清单 10% 环境、契约、规则、功能优先级
编写第一轮指令 15% 完整约束与验收方式
开发最小闭环与核心功能 40% 可启动、主路径可运行
生成边界测试并修复 25% 边界覆盖与回归结果
收尾与提交 10% 干净启动、文件核对、稳定版本

这不是评分公式,而是一份时间预算参考。若题面明确给出功能权重,应以题面为准调整开发顺序。

时间紧张时,也不要把测试阶段完全删掉。宁可减少低权重功能,也要保留对核心路径、接口契约和失败行为的验证。短场次返工空间更小,前置约束反而更重要。

功能优先级怎么排

可按以下顺序判断:

  1. 评测必须访问的入口和启动链路;
  2. 题面明确高权重的主流程;
  3. 与主流程绑定的输入校验、状态和错误响应;
  4. 幂等、精度、失败一致性等跨场景规则;
  5. 低权重扩展和非必要优化。

“做了很多”不等于“可验收的部分很多”。先让核心功能完整闭环,再扩展覆盖面。


8. 考场清单

开始前

  • 确认语言、版本、入口、启动命令与端口
  • 确认联网和第三方依赖限制
  • 确认输入输出格式及禁止修改的文件
  • 标记题面权重、必做项和可延后项
  • 建立初始可回滚状态

读题后

  • 列出所有接口或 CLI 契约
  • 固定请求与响应字段名、类型、状态码或退出码
  • 画出状态机及所有非法迁移
  • 写清金额、精度、舍入和边界规则
  • 写清错误分类、幂等语义和失败副作用要求
  • 按可立即测试的功能块拆任务

开发中

  • 先跑通最小闭环
  • 每完成一个功能块就执行测试
  • 保存完整错误输出,不凭印象修复
  • 要求模型做局部修改,不覆盖无关逻辑
  • 修改后先跑失败用例,再跑回归测试
  • 高风险变更前保存稳定版本

提交前

  • 用题面规定的命令从干净状态启动
  • 覆盖正常、非法、边界、重复和终态场景
  • 检查金额精度与输出类型
  • 验证失败前后状态一致
  • 检查标准输出中没有调试日志污染结果
  • 核对依赖、入口、端口、目录与文件名
  • 保留最后一段时间提交,不在截止前做无回滚点的大改

9. 可复用提示词速查

以下提示词都是通用训练模板,使用时必须填入本场需求,不应将其描述为任何公司的真实试题或标准答案。

需求审计

阅读需求和当前仓库,先不要改代码。输出四部分:
1. 环境与启动约束;
2. 接口/输入输出契约;
3. 业务规则、状态机、精度与错误规则;
4. 按优先级排列的可验收功能块。
每一项标注依据;不确定的地方单独列出,不自行假设。

最小闭环

只实现第一个可验收功能块:[填写功能]。
它必须包含入口、必要校验、核心逻辑、规定输出和可运行测试。
不要预先重构其他模块。完成后执行题面指定命令并报告结果。

契约核对

逐项比较需求文档与当前实现,检查路径、方法、参数位置、字段名、字段类型、状态码、错误体、退出码和输出格式。
只输出差异清单及对应文件位置,暂时不要修改代码。

状态与副作用审计

根据题面生成状态迁移矩阵,为每条合法迁移和非法迁移设计测试。
额外验证终态不可修改、重复请求符合幂等要求,以及失败前后持久化状态完全一致。
先写测试并运行,不修改业务实现。

最小修复

基于完整失败输出定位根因。只修改造成该失败的最小范围,不更改已经通过测试所依赖的契约。
修复后依次运行失败用例、相关边界用例和全量回归;若回归失败,停止扩大修改并报告差异。

提交审计

按题面做提交前审计:从干净环境执行指定启动/运行命令,检查入口、端口、依赖、文件路径、输出格式和调试日志;运行现有全部测试。
不要新增功能,只修复会阻止启动、破坏契约或导致现有测试失败的问题。

10. 十条考场规则速记

下面是对前文工作流的最后速查,不替代各章节中的详细说明:

  1. 题面规则尽量原样搬入指令:条件、顺序和例外不要凭印象概括,避免语义在转述中变形。
  2. 第一轮就锁定交付环境:语言版本、入口、启动命令、端口、依赖、联网限制和验收方式一次交代清楚。
  3. 业务规则和接口契约逐字核对:路径、方法、请求字段、响应字段、状态码及规则执行顺序必须与题面一致。
  4. 先排主干,再做叶子功能:优先完成入口、启动链路和高权重主流程,不要机械地按文档顺序开发。
  5. 最小闭环后就让模型写测试攻击当前实现:先只生成测试,不同步修改业务代码;开发中持续回归,提交前再做一次完整复验。
  6. 报错先诊断再授权修改:提供完整错误栈,先确认根因、改动位置和回归影响,避免无关重写。
  7. 同一问题连续三轮没有进展就换会话:保留稳定版本,用需求、代码状态、复现命令和完整报错建立干净上下文。
  8. 按题面检查七类风险场景:非法输入、负数与归零规则、数值精度、空集合、幂等、终态和失败无副作用;不适用的场景不要自行添加规则。
  9. 写完一个可验收功能块就运行一次:不要把启动、接口、状态和数据问题全部堆到最后处理。
  10. 按比例留出验收时间并准备复盘:建议将约四分之一时间用于造用例、修复和回归;提交后能说明需求、方案及问题处理过程。

其中“连续三轮”和“四分之一时间”是便于执行的经验阈值,不是所有平台统一规定。若题面给出明确评分权重或时间建议,应以题面为准。


11. 总结:把 AI 当作可验证的执行者

AI Coding 工程题的稳定解法可以压缩为一条闭环:

锁定契约 → 拆成可验收功能块 → 跑通最小闭环 → 用边界测试检验实现 → 小步纠错并回归 → 卡住换会话 → 结果变差就回滚。

模型负责提高实现速度,你负责定义“什么才算正确”。只要环境、接口、状态、金额、错误、幂等和失败一致性都能被明确表达并反复验证,面对不同业务外壳时,仍可以复用同一套限时交付方法。