面试手撕 / AI Coding
AI Coding 笔试手撕通关指南:五类岗位题型、隐藏用例与限时交付
AI Coding 工程题不是“让模型替你写完代码”,而是要求你在受限环境中,把一份需求说明转化为一个可运行、可验证、可提交的程序。代码生成只是其中一环;真正影响交付质量的,往往是需求理解、约束表达、测试设计和风险控制。
本页整理一套可迁移的考场工作流。文中的业务场景和提示词均为方法示例,不是对真实题目的复刻,也不代表任何公司的固定题型或评分规则。具体要求始终以当场题面为准。
1. 先认识题型:从“写函数”变成“交付系统”
传统算法题通常给定函数签名、输入输出与样例;AI Coding 工程题则可能提供:
- 一份 Markdown 或类似格式的需求文档;
- 浏览器 IDE、已有项目骨架或空仓库;
- 一个可以对话并修改代码的模型;
- 指定的语言、入口、启动命令、端口和依赖限制;
- 公开样例、基础检查或部分可见测试;
- 限时提交及不可见的评测用例。
常见考试流程可以概括为:
- 阅读题面,确认环境与交付物;
- 把需求转换为功能清单、接口契约和约束清单;
- 指挥模型完成最小可运行闭环;
- 本地启动、调用或执行程序;
- 补充边界测试,根据失败信息做小范围修复;
- 复跑回归测试,核对启动方式和最终文件后提交。
公开样例通过,只能证明某条已知路径可以工作。隐藏用例通常还会检查非法输入、边界值、重复请求、非法状态迁移、精度以及失败后的数据一致性。因此,目标不应停在“程序能动”,而应推进到“关键行为可以被验收”。
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 -> 无
实际状态与迁移必须照题面填写。合法迁移要成功,非法跳转、终态修改和重复操作也要有确定行为。
金额与精度
金额规则至少确认四件事:
- 内部表示:整数分、Decimal,还是题面指定类型;
- 运算顺序:先折扣还是先叠加费用;
- 舍入规则:四舍五入、向下取整或其他规则;
- 边界行为:负值是否归零、是否存在上下限。
不要默认二进制浮点能够稳定表示十进制金额,也不要自行添加题面没有要求的取整方式。
错误码分层
参数错误、资源不存在、权限失败和业务冲突不是同一类错误。具体 HTTP 状态码与业务错误码必须服从题面;若题面明确区分,就不要全部用一个通用错误响应代替。
幂等
若题面要求幂等,或操作涉及扣款、状态推进等不可重复副作用,应按指定规则处理重复请求,避免重复扣款或重复推进状态。创建类请求如果没有幂等键或业务唯一性约束,两次请求也可能合法地产生两个资源,因此不要自行发明幂等语义。可根据题面使用幂等键、业务唯一键或“已完成则返回原结果”等策略,同时测试:
- 完全相同的请求重复到达;
- 幂等键相同但业务参数不同;
- 首次请求失败后再次提交;
- 已到终态后再次执行动作。
失败无副作用
校验失败或业务拒绝时,不应留下半条记录、提前扣减库存或推进状态。推荐顺序是:先校验全部前置条件,再计算变更,最后一次性提交。若运行环境支持事务,可用事务保障原子性;否则要避免在校验过程中逐步写入共享状态。
三条跨接口通道
当题面反复要求失败无副作用、重复写安全和虚拟时间推进时,不要在每个接口里分别补丁式处理。可以先建立三条公共通道:
- 统一校验入口:所有前置条件通过前不修改共享状态;批量操作先完成整批校验,再统一提交。
- 统一重放处理:执行写操作前检查幂等键或题面指定的业务键;命中后返回既有结果,不重复产生副作用。
- 统一时间推进:若题目使用逻辑时钟,将到期、衰减和结算集中放在推进时钟的流程中,避免每个业务接口自行判断时间。
只有题面出现对应要求时才实现这些机制,不能把经验模式擅自写成题目没有规定的业务语义。
3.2 算法训练与模型后处理
算法岗常见两种方向,准备方式不同:
- 训练型:给带标签的历史数据,要求训练模型并提高指定指标。
- 后处理型:已有模型输出,要求完成校准、去重、合并、排序、排队或报告生成。
训练型首先要检查离线环境、可用依赖、运行时限、内存和 CPU 约束。不要默认常用机器学习库已经安装;先用现有标准库或已确认依赖建立一个能够完整训练、预测并生成合规文件的基线,再逐步增加特征和模型复杂度。
指标停滞时,优先审计:
- 指标是全局计算,还是按请求、用户或批次分组后计算;
- 训练特征在预测时是否真实可得,是否存在标签泄漏或未来信息;
- 评测集是否来自新时间段、新设备或新批次,导致数据分布变化;
- 本地验证集的划分是否模拟了真实评测边界。
算法正确但提交文件不合规,仍可能直接失分。建议单独编写输出校验脚本,至少检查:
- 输出行数与输入要求一致;
- 样本编号无丢失、重复或错误重排;
- 预测值没有
NaN或无穷大; - 列名、大小写、顺序和数据类型符合题面;
- 主程序正常退出,输出文件已完整落盘。
后处理型则应先把模型输出视为待清洗数据,围绕校准目标、约束冲突、稳定排序和异常兜底设计验收用例,而不是重新训练一个题面没有要求的模型。
3.3 数据分析与归因
数据分析题通常给出数据和一个待验证的业务判断。交付物可能是脚本、统计结果、图表数据或结构化结论。
核心风险是把相关性直接当成原因。总体指标存在差异时,应检查样本分布是否不同,例如按城市、时段、订单类型、渠道或天气分层。一个稳妥流程是:
- 检查字段、缺失值、异常值和口径;
- 复现总体指标,确认分母与过滤条件;
- 按题面相关维度分层对比;
- 检查样本量、权重和混杂因素;
- 区分“数据支持的观察”与“仍需验证的因果解释”;
- 输出结论、证据、限制和可执行建议。
这类题不应照搬后端项目的分层架构。更合适的可验收链路是:取数校验 → 指标复现 → 分层分析 → 结论表达。
若题面要求计算下推到数据库,应在 SQL 中完成过滤、聚合和必要分层,不要无条件把整表拉到内存。输出业务结论时同时给出样本量、口径、主要证据和限制,避免把观察到的相关性写成已经证明的因果关系。
3.4 Agent 记忆与模型输出治理
Agent 题的关键假设通常是:上游模型输出不稳定,不能直接信任或写入系统状态。可能出现结构变化、字段别名、非 JSON 内容、跨用户信息、敏感类别、过期事实以及同一轮中的自相矛盾。
一条稳妥的处理链路包括:
- 宽容解析:接受题面允许的多种形态,解析失败进入明确兜底路径;
- 严格校验:确认用户归属、字段类型、证据范围和敏感规则;
- 冲突处理:同轮矛盾、事实修订和重复事实按明确优先级处理;
- 生命周期治理:过期、衰减、容量淘汰和终态处理遵循题面时钟;
- 幂等与审计:同一轮重放不重复写入,修订和审计记录可追溯;
- 闭环自查:检索结果进入生成前再次过滤,生成结果按要求做安全或一致性检查。
测试时不要只喂标准 JSON。还应根据题面构造字段缺失、别名、错误类型、跨用户内容、敏感事实、过期事实、重复调用和解析失败等输入,确认系统能拒绝、降级或记录,而不是崩溃或污染记忆。
3.5 游戏开发与对抗策略
游戏开发类题可能只允许提交一个决策函数,地图、引擎和样例代码均为只读。评分也可能不是通过固定用例,而是与多个未知对手进行对抗后统计胜率。
准备时遵循三个顺序:
- 先读引擎,再写策略:从代码确认回合顺序、同时决策或先后决策、伤害结算、碰撞、资源消耗和终局条件;文字说明与引擎不一致时按题面规定确定权威来源。
- 先保证合法和不崩溃:所有分支都返回合法动作,对空候选、异常状态和极端输入设置保守兜底,避免被系统代选并累计违规。
- 先建立稳定基线,再提升胜率:先实现能完整打完一局的保守策略,再一次只修改一个决策因素,通过批量对局比较胜率、违规率和超时率。
若双方同时决策,策略不能依赖“看到对手本回合动作后再响应”的假设。对抗评分也意味着单个样例成功并不能证明策略有效,应使用不同初始状态、随机种子和对手风格做重复模拟。
3.6 工具与引擎
这类题可能要求实现命令行工具、静态检查器、调度器或媒体处理程序,常见接口是“读 JSON、写 JSON”或操作指定文件。
它的难点通常不是把主流程写出来,而是识别朴素方案的失效条件:
- 代码分析若只用正则,可能无法正确处理语法嵌套、注释和字符串;题目要求语义准确时,应考虑 AST 或语言解析器;
- 调度若只用 FIFO,可能无法满足优先级、资源约束或抢占规则;
- 媒体处理若机械复用码流或只处理视频轨,可能违反时间轴、编码或音轨要求;
- 文件工具若忽略退出码、标准错误和原子写入,主结果即使正确也可能验收失败。
拿到题后先问:“最直观的实现会在哪些输入上失效?”再将答案写入实现约束。领域方案必须由题面需求驱动,不能因为某个示例提到 AST、抢占或转码,就无条件套用。
4. 第一轮指令:一次写清执行边界
第一轮指令的目标不是展示文采,而是减少模型猜测。下面是可复用模板,方括号内容必须替换为当场题面信息。
你要在当前仓库中实现题面要求的程序。先阅读现有文件和需求,再执行修改。
【环境与交付】
- 语言/版本:[原样填写]
- 入口与启动命令:[原样填写]
- 端口或输入输出方式:[原样填写]
- 依赖与联网限制:[原样填写]
- 禁止修改的文件:[原样填写]
【功能与业务规则】
1. [规则一,保留题面中的条件、顺序和例外]
2. [规则二]
3. [规则三]
【接口或输入输出契约】
- [方法、路径、请求字段、成功状态与响应字段]
- [失败条件、状态码/退出码、错误结构]
【边界与一致性】
- 缺字段、类型错误、越界、空值按题面处理,程序不得崩溃。
- 金额/精度/舍入严格按题面实现。
- 非法状态迁移必须拒绝。
- 重复请求按题面的幂等规则处理。
- 失败操作不得改变已有状态或产生部分写入。
【执行顺序】
1. 先复述你识别出的硬约束和待修改文件;有歧义时明确列出,不要自行发明规则。
2. 建立最小可运行闭环,再按可验收功能块推进。
3. 每完成一块就运行对应测试,不要等到最后一起验证。
4. 最后按规定命令启动或执行程序,并报告测试命令、结果和剩余风险。
如果时间极短,可以压缩表述,但不要删掉环境、契约和验收。尤其要写死响应字段名、入口和启动方式。
5. 用测试驱动模型,而不是等隐藏用例判错
5.1 最小闭环之后立刻测试
开发顺序建议采用:
- 建立可启动、可调用的最小闭环;
- 实现一个完整功能块;
- 写正常路径和失败路径测试;
- 运行测试并保存结果;
- 做最小修复;
- 重跑本功能与既有回归测试;
- 再进入下一个功能块。
这样可以把故障限制在最近一次改动内,避免最后同时面对启动、接口、状态和数据四类问题。
5.2 让模型生成“攻击当前实现”的测试
以下模板用于自测,不代表真实隐藏用例:
请逐条对照当前需求与现有实现,新增一组可直接运行的测试。
现在只写测试,不修改业务代码。
覆盖范围:
- 缺字段、错误类型、空值、非法枚举、越界输入;
- 0、负数、最大值、空集合、单元素;
- 每条合法状态迁移,以及跳步、回退、终态修改;
- 重复提交与幂等键冲突;
- 金额精度、舍入顺序、上下限;
- 资源不存在、权限失败、业务冲突的响应差异;
- 失败前后数据快照一致,确认失败无副作用;
- 需求中已写明、但当前实现可能遗漏的规则。
先列出“需求条目 -> 测试用例”的对应关系,再生成测试文件并运行。
报告失败用例,但不要顺手修改实现。
“只写测试,不改业务代码”很重要,否则模型可能同时修改测试和实现,使测试失去诊断价值。
5.3 失败后使用可执行的纠错模板
不要只说“好像有问题”或“再改一下”。一次有效纠错应包含:失败证据、期望行为、改动范围和复验方式。
以下测试失败:[粘贴完整命令与失败输出]
对应需求:[粘贴相关原文或准确转述]
实际行为:[当前结果]
期望行为:[应有结果]
先分析根因,指出准备修改的文件与代码范围,不要重写无关模块。
采用满足需求的最小改动修复;已经通过的行为保持不变。
修复后重跑:
1. 当前失败测试;
2. 同功能块的边界测试;
3. 全量回归测试。
最后报告改动、测试结果和仍未覆盖的风险。
如果暂时不希望模型直接改代码,可加一条硬约束:
先不要修改文件。只回答根因、拟修改位置、潜在回归影响;等我确认后再执行。
6. 模型卡住时:缩小问题、换会话、能回滚
6.1 先补全证据
修复前提供完整信息:
- 执行命令;
- 完整错误栈,而非最后一行;
- 相关输入与期望输出;
- 最近一次改动;
- 已通过且不得破坏的测试。
先让模型说明根因和影响范围,再决定是否授权修改。对一个局部错误大幅重写文件,通常会增加回归风险。
6.2 同一问题反复失败就换会话
同一会话里连续出现错误修复尝试时,旧方案可能持续干扰判断。如果同一个问题经过少量轮次仍无进展,可开启新会话,只提供:
- 必要需求;
- 当前代码状态;
- 可复现命令;
- 完整报错;
- 已排除的原因。
新会话不是“从头重做”,而是清理错误上下文。切换前应保存当前可运行版本。
6.3 每次高风险修改前建立回滚点
可以使用版本控制提交、IDE 快照或复制关键文件。若修改后通过的测试变少、评测结果下降或主流程损坏,应先回到最近的稳定状态,再从更小的改动重新尝试。不要把剩余时间押在连续的大范围补丁上。
7. 按比例分配时间,而不是背绝对分钟数
场次时长可能不同,用比例比固定分钟表更稳妥:
| 阶段 | 建议占比 | 交付物 |
|---|---|---|
| 阅读需求与列清单 | 10% | 环境、契约、规则、功能优先级 |
| 编写第一轮指令 | 15% | 完整约束与验收方式 |
| 开发最小闭环与核心功能 | 40% | 可启动、主路径可运行 |
| 生成边界测试并修复 | 25% | 边界覆盖与回归结果 |
| 收尾与提交 | 10% | 干净启动、文件核对、稳定版本 |
这不是评分公式,而是一份时间预算参考。若题面明确给出功能权重,应以题面为准调整开发顺序。
时间紧张时,也不要把测试阶段完全删掉。宁可减少低权重功能,也要保留对核心路径、接口契约和失败行为的验证。短场次返工空间更小,前置约束反而更重要。
功能优先级怎么排
可按以下顺序判断:
- 评测必须访问的入口和启动链路;
- 题面明确高权重的主流程;
- 与主流程绑定的输入校验、状态和错误响应;
- 幂等、精度、失败一致性等跨场景规则;
- 低权重扩展和非必要优化。
“做了很多”不等于“可验收的部分很多”。先让核心功能完整闭环,再扩展覆盖面。
8. 考场清单
开始前
- 确认语言、版本、入口、启动命令与端口
- 确认联网和第三方依赖限制
- 确认输入输出格式及禁止修改的文件
- 标记题面权重、必做项和可延后项
- 建立初始可回滚状态
读题后
- 列出所有接口或 CLI 契约
- 固定请求与响应字段名、类型、状态码或退出码
- 画出状态机及所有非法迁移
- 写清金额、精度、舍入和边界规则
- 写清错误分类、幂等语义和失败副作用要求
- 按可立即测试的功能块拆任务
开发中
- 先跑通最小闭环
- 每完成一个功能块就执行测试
- 保存完整错误输出,不凭印象修复
- 要求模型做局部修改,不覆盖无关逻辑
- 修改后先跑失败用例,再跑回归测试
- 高风险变更前保存稳定版本
提交前
- 用题面规定的命令从干净状态启动
- 覆盖正常、非法、边界、重复和终态场景
- 检查金额精度与输出类型
- 验证失败前后状态一致
- 检查标准输出中没有调试日志污染结果
- 核对依赖、入口、端口、目录与文件名
- 保留最后一段时间提交,不在截止前做无回滚点的大改
9. 可复用提示词速查
以下提示词都是通用训练模板,使用时必须填入本场需求,不应将其描述为任何公司的真实试题或标准答案。
需求审计
阅读需求和当前仓库,先不要改代码。输出四部分:
1. 环境与启动约束;
2. 接口/输入输出契约;
3. 业务规则、状态机、精度与错误规则;
4. 按优先级排列的可验收功能块。
每一项标注依据;不确定的地方单独列出,不自行假设。
最小闭环
只实现第一个可验收功能块:[填写功能]。
它必须包含入口、必要校验、核心逻辑、规定输出和可运行测试。
不要预先重构其他模块。完成后执行题面指定命令并报告结果。
契约核对
逐项比较需求文档与当前实现,检查路径、方法、参数位置、字段名、字段类型、状态码、错误体、退出码和输出格式。
只输出差异清单及对应文件位置,暂时不要修改代码。
状态与副作用审计
根据题面生成状态迁移矩阵,为每条合法迁移和非法迁移设计测试。
额外验证终态不可修改、重复请求符合幂等要求,以及失败前后持久化状态完全一致。
先写测试并运行,不修改业务实现。
最小修复
基于完整失败输出定位根因。只修改造成该失败的最小范围,不更改已经通过测试所依赖的契约。
修复后依次运行失败用例、相关边界用例和全量回归;若回归失败,停止扩大修改并报告差异。
提交审计
按题面做提交前审计:从干净环境执行指定启动/运行命令,检查入口、端口、依赖、文件路径、输出格式和调试日志;运行现有全部测试。
不要新增功能,只修复会阻止启动、破坏契约或导致现有测试失败的问题。
10. 十条考场规则速记
下面是对前文工作流的最后速查,不替代各章节中的详细说明:
- 题面规则尽量原样搬入指令:条件、顺序和例外不要凭印象概括,避免语义在转述中变形。
- 第一轮就锁定交付环境:语言版本、入口、启动命令、端口、依赖、联网限制和验收方式一次交代清楚。
- 业务规则和接口契约逐字核对:路径、方法、请求字段、响应字段、状态码及规则执行顺序必须与题面一致。
- 先排主干,再做叶子功能:优先完成入口、启动链路和高权重主流程,不要机械地按文档顺序开发。
- 最小闭环后就让模型写测试攻击当前实现:先只生成测试,不同步修改业务代码;开发中持续回归,提交前再做一次完整复验。
- 报错先诊断再授权修改:提供完整错误栈,先确认根因、改动位置和回归影响,避免无关重写。
- 同一问题连续三轮没有进展就换会话:保留稳定版本,用需求、代码状态、复现命令和完整报错建立干净上下文。
- 按题面检查七类风险场景:非法输入、负数与归零规则、数值精度、空集合、幂等、终态和失败无副作用;不适用的场景不要自行添加规则。
- 写完一个可验收功能块就运行一次:不要把启动、接口、状态和数据问题全部堆到最后处理。
- 按比例留出验收时间并准备复盘:建议将约四分之一时间用于造用例、修复和回归;提交后能说明需求、方案及问题处理过程。
其中“连续三轮”和“四分之一时间”是便于执行的经验阈值,不是所有平台统一规定。若题面给出明确评分权重或时间建议,应以题面为准。
11. 总结:把 AI 当作可验证的执行者
AI Coding 工程题的稳定解法可以压缩为一条闭环:
锁定契约 → 拆成可验收功能块 → 跑通最小闭环 → 用边界测试检验实现 → 小步纠错并回归 → 卡住换会话 → 结果变差就回滚。
模型负责提高实现速度,你负责定义“什么才算正确”。只要环境、接口、状态、金额、错误、幂等和失败一致性都能被明确表达并反复验证,面对不同业务外壳时,仍可以复用同一套限时交付方法。