Agent 面试通关 / 11

AI 代码分析与测试:覆盖率、插桩、代码过滤

用 Agent 做自动化代码测试是一个热门落地方向。面试官考这个方向时,不只关心“你会不会让模型生成测试”,更关心你对代码分析的底层原理和边界认知——什么代码能自动测、什么代码不能、为什么。


代码分析与过滤

Q:分支覆盖率是怎么统计的?原理有没有了解过?代码插桩具体是怎么实现的?

来源:抖音基础架构 Agent 一面

新手答:“用 coverage 工具跑一下就行。”

高手答

分支覆盖率 = 被执行的分支数 / 总分支数。核心是代码插桩(Instrumentation)

  1. 解析阶段:先把源代码解析成 AST,识别所有分支点——if/elseswitch/case、三元表达式、&&/|| 短路运算
  2. 插桩阶段:在每个分支入口插入计数器代码
  3. 执行阶段:运行插桩后的代码,计数器记录每个分支被执行的次数
  4. 统计阶段:汇总所有计数器,计算覆盖率
# 插桩前
if x > 0:
    return x
else:
    return -x

# 插桩后(概念示意)
if x > 0:
    __cov[12] += 1  # branch 12: if-true
    return x
else:
    __cov[13] += 1  # branch 13: if-false
    return -x

具体实现方式分两类:

  • 源码级插桩(Istanbul/nyc、coverage.py):在 AST 层面改写代码,插入计数器
  • 字节码级插桩(JaCoCo):不改源码,在类加载时修改字节码,性能开销更小

差距在哪:新手只知道“跑工具”。高手理解工具背后的四个阶段和两种实现路径。面试官考的是底层原理认知。


Q:对于代码解析有没有前置分析?有效性判断怎么实现的?未来让你来优化这些指标你会怎么设计?

来源:抖音基础架构 Agent 一面

新手答:“直接把代码发给模型就行。”

高手答

前置分析是生成质量的关键,不做前置分析等于盲目生成:

前置分析做什么

  1. AST 解析提取函数签名、参数类型、返回类型
  2. 依赖分析:这个函数调用了哪些外部模块、类、函数
  3. 复杂度评估:圈复杂度、嵌套深度、分支数量——决定需要生成多少测试用例
  4. 可测性判断:有没有全局状态依赖、有没有不可控的外部调用

有效性判断分三级:

  1. 语法有效性:生成的测试代码能不能通过解析器
  2. 编译有效性:import 能不能解析、类型能不能对齐
  3. 语义有效性:断言是否合理——测试是不是在检查有意义的行为,而不是 assert True

优化设计思路

  • 低复杂度函数(纯函数、无依赖)用轻量模板快速生成,省 token
  • 高复杂度函数做路径分析,按分支拆分成多次生成任务,每次只关注一条路径
  • 引入变异测试做质量评估——故意改待测代码里的运算符或常量,看生成的测试能不能检测出来

差距在哪:新手跳过了分析直接生成。高手展示了完整的前置分析链路和三级有效性判断,且能从执行者视角切换到设计者视角。面试官考的是工程优化能力。


Q:有没有思考过哪些代码会让模型生成的准确度和覆盖率降低?这些用 AST 和 LSP 都生成不了单测的代码如何过滤?

来源:抖音基础架构 Agent 一面

新手答:“复杂代码肯定效果差。”

高手答

有几类代码是“模型杀手”:

代码类型 为什么难 示例
动态代码 运行时才确定行为,静态分析看不到 eval()getattr()、元编程
重副作用代码 依赖外部状态,无法纯靠输入输出验证 数据库操作、网络请求、文件系统
复杂继承链 模型难以追踪多层继承和方法覆盖 深度继承 + mixin + 装饰器
隐式依赖 依赖全局变量、环境变量、配置文件 依赖 os.environ 的逻辑
并发代码 执行顺序不确定,测试难以复现 多线程竞争、异步回调链

过滤策略

  1. 静态标记:用 AST 扫描,标记含有 evalexec__import__ 等动态特征的函数
  2. 复杂度阈值:圈复杂度超过阈值(比如 20)的函数标记为“需要人工辅助”
  3. 依赖深度检查:用 LSP 或调用图分析,外部依赖层数超过阈值的降级处理
  4. 历史成功率:记录每类代码特征的生成成功率,低于阈值的自动跳过或降级到“只生成基础用例”

核心思路:不是所有代码都适合自动生成测试,把资源集中在 ROI 最高的代码上

差距在哪:新手只知道“复杂的不行”,说不出具体是哪类复杂。高手分了五类难测代码且给出四种过滤策略。面试官考的是边界思维——你有没有想过“什么做不了”。


生成代码验证

Q:如何测试 AI 生成代码的正确性?

来源:蚂蚁集团 Agent 开发一面 【字节实习Agent开发一面追问:代码Agent生成结果有效性/准确率量化】【小红书 Agent 岗一面追问:Agent 自主生成测试程序的实现】 / 字节中国交易与广告 AI 全栈二面 / 蚂蚁 Agent 开发一面

新手答:“跑一下看能不能通过。”

高手答

“跑一下”只能验证“能不能运行”,不能验证“逻辑对不对”。AI 生成的代码最危险的问题不是编译报错,而是看起来能跑、但行为不符合预期

测试 AI 生成代码的正确性,分三个层次

第一层:静态验证(零成本、秒级反馈)

检查项 工具 能抓什么问题
类型检查 TypeScript / mypy 参数类型不匹配、返回值类型错误
Lint 规则 ESLint / Ruff 代码风格违规、常见 bug 模式
安全扫描 Semgrep / Bandit SQL 注入、XSS、硬编码凭证
Import 检查 编译器 引用了不存在的模块或 API

AI 经常生成“看起来合理但引用了不存在的 API”的代码。静态检查能秒级拦住这类问题。

第二层:动态验证(中等成本、分钟级反馈)

  1. 已有测试套件回归:生成的代码不能破坏已有功能。跑一遍现有的单元测试和集成测试
  2. AI 自生成测试:让 AI 同时生成代码和对应的测试用例。虽然 AI 生成的测试也可能有 bug,但能抓住明显的逻辑错误(如边界条件、空值处理)
  3. 属性测试(Property-based Testing):用 Hypothesis / fast-check 生成大量随机输入,验证代码是否满足不变量(如“排序后数组长度不变”)。对于纯函数特别有效

第三层:语义验证(高成本、但最可靠)

  1. Spec 对比:如果有明确的技术规格(接口定义、行为描述),用另一个模型或规则引擎检查生成的代码是否符合 Spec
  2. Mutation Testing:对生成的测试用例做变异测试——故意在代码里引入 bug,看测试能不能发现。如果测试发现不了人为注入的 bug,说明测试本身不可靠
  3. 人工抽检:对关键路径的代码做人工 review,重点看业务逻辑正确性和边界条件

验证流程编排

flowchart TB
    A["AI 生成代码"] --> B["静态验证\n(类型/lint/安全)"]
    B -->|失败| C["反馈错误\n让 AI 修复"]
    B -->|通过| D["动态验证\n(回归测试 + 自生成测试)"]
    D -->|失败| C
    D -->|通过| E["关键路径?"]
    E -->|是| F["语义验证\n(Spec 对比 + 人工 review)"]
    E -->|否| G["合入"]
    F --> G

差距在哪:新手的”跑一下”只覆盖了”能不能运行”。高手从静态(类型/lint/安全)、动态(回归/自生成/属性测试)、语义(Spec 对比/变异测试/人工)三层构建了完整的正确性验证体系。面试官考的是你对 AI 生成代码测试有没有系统性的方法论——不是”测了没有”,而是”怎么测才可靠”。

追问:AI 写的代码如何验证?(更偏实操角度)

来源:字节实习二面

上面的三层体系是方法论,实际操作中还需要验证策略的选择

代码类型 验证重点 推荐手段
纯函数/工具函数 输入输出正确性 属性测试 + 边界用例
API 路由/接口 状态码、响应格式、鉴权 集成测试 + 契约测试
业务逻辑 符合需求规格 Spec 对比 + 人工 review
数据库操作 数据一致性、幂等性 事务测试 + 回滚验证

核心原则:AI 生成的代码和人写的代码用同一套验证标准,不要因为是 AI 写的就降低标准,也不要因为是 AI 写的就额外怀疑。唯一的区别是 AI 代码更容易出”看起来对但语义错”的问题——所以在语义验证层要比人写的代码投入更多精力。


Q:AI 生成的代码线下测试没问题,上线后出了问题怎么办?

来源:字节实习二面

新手答:”回滚,然后重新让 AI 生成。”

高手答

这个问题的核心是线下和线上环境的差异导致测试覆盖不足。回滚只是止血,关键是搞清楚为什么线下测没出来。

第一步:定位”差在哪”

线下测试和线上环境的常见差异:

差异维度 线下环境 线上环境
数据规模 几百条测试数据 百万级真实数据
并发量 单线程跑测试 高并发请求
数据分布 干净、均匀 存在脏数据、极端值、编码问题
依赖服务 Mock 或测试环境 真实服务(可能超时、降级)
配置差异 本地配置 线上配置(环境变量、Feature Flag)

第二步:分类处理

flowchart TB
    A[“线上问题”] --> B{“问题类型?”}
    B -->|”功能错误”| C[“对比线下/线上数据差异\n补充边界测试用例”]
    B -->|”性能问题”| D[“压测 + Profiling\n找到瓶颈”]
    B -->|”兼容性问题”| E[“检查依赖版本\n配置差异”]
    C --> F[“修复后加入回归套件”]
    D --> F
    E --> F

第三步:建立防复发机制

  1. 线上流量回放:录制线上真实请求,在测试环境回放。这是缩小线下/线上差异最有效的手段
  2. 灰度发布:AI 生成的代码不直接全量上线,先灰度 5% 流量,观察错误率和性能指标
  3. AI 代码标记:在 git commit 中标记哪些代码是 AI 生成的,线上出问题时优先排查这些文件
  4. 断言增强:在 AI 生成的代码关键路径加 assertion,线上触发时直接报警而不是静默错误

差距在哪:新手的”回滚重新生成”是事后补救,没有分析根因。高手从定位差异(为什么线下没测出来)、分类处理(不同问题类型的排查路径)、防复发(流量回放/灰度/标记/断言)三层建立了系统化的应对方案。面试官考的是你对”测试环境和生产环境差异”的工程认知——这不是 AI 特有的问题,传统软件开发也一样,但 AI 生成代码的不可预测性让这个问题更突出。


Q:工程级 Code Agent 处理项目上下文、生成代码时有哪些核心挑战?

来源:蚂蚁Agent一二面(Code Agent方向) / 字节 AI 应用开发二面

新手答:”就是上下文太长放不下的问题。”

高手答

工程级 Code Agent 面临的挑战远不止上下文长度,核心有:

  1. 上下文选择问题:真实项目数万文件,Agent 需要判断哪些文件与当前任务相关——这本身就是一个检索+推理问题
  2. 跨文件依赖理解:修改一个函数可能影响 N 个调用方,Agent 需要追踪依赖链(import graph / call graph)
  3. 代码一致性:生成的代码必须遵循项目已有的命名规范、错误处理模式、架构分层,不能”风格割裂”
  4. 增量编辑 vs 全量生成:真实场景是在已有代码上改几行,而不是从零生成,需要精确定位+最小化修改
  5. 编译/运行验证闭环:生成的代码不只是语法正确,还需要能通过编译、测试、lint 检查——需要 Agent 有执行环境反馈
  6. 安全性约束:不能引入注入漏洞、不能泄露密钥、不能修改不该改的文件

这些瓶颈应分层定位:检索层看是否拿到正确代码和规范,规划层看改动范围与依赖是否完整,执行层看工具权限、环境和失败恢复,验证层看是否有独立 Oracle。工程交付不能用“生成了代码”或“命令执行成功”收口,而要留下最小 diff、依赖影响、可复现验证命令、测试与安全门禁结果,以及仍未覆盖的风险;无法验证的部分应明确交给人,而不是让同一个生成模型自证正确。

差距在哪:面试官要看你是否有”从 Demo 到工程”的认知跨越——玩具级 Code Agent 只管生成,工程级还要管选择、验证、安全。


Q:Coding Agent 如何执行人工交互测试,例如操作浏览器并验证页面行为?

来源:小红书 Agent 岗一面 / 蚂蚁 Agent 开发一面

新手答:“让 Agent 打开浏览器点几下,看看页面有没有报错。”

高手答

人工交互测试不是“模型凭感觉点页面”,而是 Harness 给 Agent 提供可观察、可控制、可复现的交互环境。典型链路是:

  1. 启动隔离的测试服务与浏览器会话,固定代码版本、数据集、账号权限和 viewport。
  2. Agent 根据验收标准生成测试意图,但通过 Playwright/WebDriver 等结构化工具读取 DOM、可访问性树和元素定位符,并执行点击、输入、键盘、滚动和上传。
  3. 每一步记录 action、目标元素、页面 URL、DOM/可访问性快照、控制台错误、网络失败、截图和时间戳。
  4. 断言不能只看截图:优先验证 DOM 状态、接口响应、数据库副作用和可访问性;视觉回归再用基线截图或区域差异补充。
  5. 失败时保存 trace/video/HAR,Agent 基于证据定位问题并在限定次数内修复、重跑。支付、发消息、删除数据等外部副作用必须 Mock、沙箱化或人工确认。

对于确实需要人判断的主观问题,可以暂停到 WAITING_FOR_REVIEW,把截图、操作轨迹、预期与实际结果交给测试者确认;不能把“人工交互测试”误解成 Agent 可以绕过授权偷偷执行真实操作。

差距在哪:高手会把自然语言测试意图落实为浏览器自动化协议、机器可验证断言、证据留存和副作用隔离。


Q:如何用 Agent 自动化测试一个现有软件项目,并划分规划、执行、Oracle 与人工门禁?

来源:蚂蚁集团效能研发面经【0824 百度二面追问:长期演进框架的上下文与产物治理】

新手答:“让 Agent 阅读需求和代码,生成测试用例,运行失败后自动修复,最后把报告交给人看。”

高手答

测试现有项目不能从“生成几个用例”开始。首先冻结待测 commit、依赖、配置和数据基线,在隔离环境中探查项目的构建命令、测试框架、服务拓扑、公开接口、已有用例、历史缺陷和变更范围。规划器据此建立风险模型,把测试目标拆成单元、契约、集成、UI、性能与安全任务,并明确每项前置条件、预算、允许的副作用和通过标准。

四类角色的边界应显式分开:

层次 主要职责 关键约束
Planner 选择风险点、生成测试计划、安排依赖与重试 不直接判定系统正确,也不擅自扩大测试范围
Executor 准备数据,调用测试框架、API、浏览器或故障注入工具 沙箱运行、最小权限、幂等清理、完整保留日志与 trace
Oracle 根据规格、不变量和外部证据判断实际结果是否正确 优先确定性断言;与生成器解耦;不可被 Agent 随意修改
Human Gate 确认需求歧义、高风险副作用、基线变更和发布决策 看到证据、差异与剩余风险,而不只是模型结论

Oracle 是最容易被忽略的部分。HTTP 200、页面出现文字或“模型觉得合理”都不等于正确。应按强度使用编译/类型检查、Schema、业务不变量、数据库状态、契约、金标样例、差分测试和 metamorphic relation;只有无法形式化的视觉或语义判断才由模型辅助,并抽样交给人复核。测试生成器和 Oracle 若使用相同模型、相同上下文,可能一起误解需求,因此关键验收集应由独立来源维护并设为只读。

执行器把每步 action、环境、实际结果和证据写入结构化 run;失败先分类为产品缺陷、测试缺陷、环境故障或 flaky,再决定重跑、补充观测还是提交缺陷。Agent 可以提出代码或测试修复,但不能通过删断言、改金标、扩大超时来制造通过。连续失败、需求冲突、破坏性操作、权限提升和验收基线变化必须暂停到人工门禁。

最终报告应给出覆盖的风险、可复现命令、失败证据、未执行项、flaky 情况和剩余风险。衡量系统时看有效缺陷发现率、误报率、稳定复现率和人工复核成本,不能只看生成用例数或覆盖率上涨。

追问:既有自动化框架长期迭代,怎么避免 Agent 每次全量读库,并管理需求、版本和产物?

先为框架建立由代码索引、接口/fixture schema、测试能力目录和历史失败摘要组成的可版本化上下文,而不是保存一段越来越长的会话。新需求进入后生成稳定的 requirement_id,拆成带验收条件和依赖的任务;每次运行固定代码 commit、需求版本、测试数据快照和 Agent 配置,只加载变更符号及其调用者、已有用例和相关领域规则。

计划、生成用例、运行日志、失败证据、人工结论和最终报告都绑定 run_id + requirement_version + code_commit。场景级用例用前置状态、动作和业务不变量串联,已完成任务由确定性状态记录,不让模型根据聊天历史猜进度。需求变更时生成显式 diff,标记哪些用例仍有效、哪些需重算;这样既能增量读取,也能回答某个结论对应哪版需求和代码。

差距在哪:新手把 Agent 当“会写测试的脚本”。高手把规划、受控执行、可信 Oracle 和人工责任拆开,解决了测试环境、判定独立性、副作用、失败分类和发布门禁,才能让自动化结果进入真实研发流程。


Q:AI 生成代码在哪些场景更具落地价值?应用边界在哪?

来源:蚂蚁Agent一二面(Code Agent方向)

新手答:”写 CRUD 和简单逻辑的时候好用,复杂的不行。”

高手答

高价值场景

  1. 模板化代码:CRUD、API 接口、表单校验、配置文件——模式固定,人写是重复劳动
  2. 测试用例生成:给定函数签名和文档,批量生成单测/边界用例,提升覆盖率
  3. 代码迁移/重构:语言升级(Python2→3)、框架迁移(Vue2→3),规则明确且量大
  4. 文档与注释:代码已有、补充说明性文字,错了影响小
  5. 胶水代码:数据格式转换、API 对接,逻辑简单但写起来繁琐

应用边界(不适合的场景)

  1. 核心业务逻辑:涉及复杂业务规则、边界条件多、错误代价高的代码
  2. 性能关键路径:需要对底层实现细节有深刻理解的优化代码
  3. 安全敏感代码:加密、认证、权限控制——AI 可能引入微妙漏洞
  4. 创新型架构设计:没有先例可参考的全新设计,需要人的判断

差距在哪:面试官要看你有没有”工具理性”——知道什么时候用、什么时候不用,而不是全盘接受或全盘否定。


Q:AI 测试平台中,人和 AI 的职责边界如何划分?

来源:快手测试开发实习一面(2026-08-12)

新手答:“AI 负责生成和执行用例,人负责最后看结果。”

高手答

边界不应按“步骤”粗分,而应按确定性、风险和可验证性划分:

工作 AI 适合承担 人/确定性系统必须负责
用例设计 从需求和历史缺陷扩展候选场景、补边界 定义测试目标、风险优先级和发布门槛
执行 调用接口/UI 驱动,探索页面路径,生成测试数据 隔离环境、账号权限、并发和副作用控制
校验 解释日志、聚类失败、提出根因假设 状态码、Schema、数据库副作用等硬断言
维护 建议修复定位符、识别重复用例 审批基线变化,防止把产品回归“修成预期”
发布 汇总风险和证据 高风险变更的最终 go/no-go 决策

AI 适合处理开放且高成本的“候选生成和证据解释”,代码适合执行稳定规则,人负责定义目标和承担高风险决策。评估 AI 测试能力不能只看生成用例数,而要看有效缺陷发现率、误报率、稳定重跑率、覆盖增量和人工节省时间。

还要设置升级人工条件:需求语义冲突、模型置信度低、支付/删除等真实副作用、视觉主观判断、连续修复失败,以及 AI 提议修改测试基线。所有 AI 决策保留输入、模型版本、工具轨迹和证据,确保人能复核。

差距在哪:新手把 AI 当成全自动测试员。高手明确 AI、确定性系统和人的责任边界,并把风险门禁、证据和指标纳入平台设计。面试官考的是能否让 AI 测试真正进入发布流程,而不是只做演示。


Q:TDD 如何接入 Coding Agent?测试门禁应该放在生成流程的哪个阶段?

来源:深信服 Agent 三面(2026-08-23)

新手答:“让 Agent 先写测试再写代码,最后跑一下测试。”

高手答

先由人或 Spec Agent 把需求转成可验收行为、边界和不可变约束,测试生成 Agent 补充单元、契约和回归用例,但关键验收测试不能与实现使用完全相同的上下文和模型,否则容易共同误解需求。实现 Agent 每个小步都运行窄测试,提交候选变更前再通过类型检查、lint、单元测试、集成测试、安全扫描和受影响回归集。

门禁至少有三层:工具调用前校验写入范围;生成过程中用快速测试提供反馈;合并或发布前由独立执行环境运行不可被 Agent 修改的验收集。失败时保留代码、测试、环境和模型版本,限制自动修复轮数,超过预算转人工,不能让 Agent 通过删除或弱化测试来“修复”。

差距在哪:新手把 TDD 理解成执行顺序,高手设计了独立验收、分层门禁、防篡改和失败预算。面试官考的是 AI 生成速度提高后,质量控制能否同步自动化而不失去可信度。


Q:AI Coding 如何完成多来源账单分析应用,并证明交付结果可信?

来源:CVTE 视源股份 AI Coding(2026-08-12)

新手答:“读取微信和支付宝 CSV,分类后生成图表。”

高手答:先探查两类账单 schema、编码、时区、金额符号和唯一键,定义统一交易模型;退款、转账、朋友还款和消费必须用可解释规则并保留原始行与转换血缘。用对账不变量验证总收入/支出、重复记录和退款关联,未知类型进入待确认清单。交付代码、依赖锁定、README、测试、分析报告和可复现命令;敏感字段脱敏,结论引用具体交易集合。

差距在哪:新手只做图表,高手解决数据契约、可解释分类、对账和可复现交付。


Q:Coding Agent 如何做增量代码审查,避免大仓库全量逐行扫描?

来源:PDD 秋招提前批一面(2026-08-21)

新手答:“只审查 git diff 和修改文件。”

高手答:从 diff 构建变更符号和依赖影响图,扩展到调用者、接口契约、配置、测试和数据迁移;静态规则先筛确定问题,Agent 只读取相关切片和历史约束。按风险决定扩展深度,高风险公共 API 触发跨仓检索和集成测试。审查结果绑定代码位置、证据和受影响测试,并用基线误报率和漏陷回流持续校准。

差距在哪:新手缩小文件范围,高手用语义影响分析控制上下文与风险覆盖。


Q:Coding Agent 能否自举开发自身?如何避免生成器与验证器同源导致循环确认?

来源:平安健康保险 AI 应用开发一面

新手答:“可以,直接让 Coding Agent 修改自己的代码,再让它运行测试验证就行。”

高手答

先区分两种自举:用 Agent 辅助开发其代码库,和让运行中的 Agent 修改并替换自身。前者可以走普通研发流程;后者涉及执行者、被测对象和发布控制面重合,风险高得多,不能让当前进程覆盖自己后继续宣布成功。

候选版本在隔离分支、worktree 或 Sandbox 中生成,由稳定版控制器启动独立进程验证。需求 Spec、关键回归集、权限策略和发布门禁设为只读,候选不能修改;测试结果绑定候选 commit、依赖和运行环境。生成器与 Reviewer 即使用不同 Prompt,如果共享同一错误需求或模型偏差,仍可能一起判断错误,因此关键 Oracle 要来自编译器、类型系统、业务不变量、独立验收集和人工审批,而不是另一次“模型觉得正确”。

发布采用影子运行或小流量灰度,比较稳定版与候选版的任务成功率、副作用、成本和回滚能力。候选只能提出下一代版本,不能递归触发无限自我改写;设置最大代数、预算和无进展检测。控制面、凭据管理、审计与回滚器不允许由被更新的 Agent 单独改写。

差距在哪:新手把自举当普通代码生成,高手隔离稳定控制器与候选版本,用外部 Oracle、只读基线和发布门禁打破“自己生成、自己证明”的循环。


这类题的答题模式

AI 代码测试题的核心是底层原理 + 边界认知

1. 不只会用工具——要理解覆盖率统计和代码插桩的底层原理
2. 前置分析是质量关键——不分析就生成等于盲目
3. 有效性分三级——语法、编译、语义递进判断
4. 知道什么做不了——动态代码、重副作用、复杂继承是"模型杀手"
5. 过滤策略要可量化——复杂度阈值、历史成功率,不是拍脑袋

返回模块首页: