2026 Java + AI 高频面试题 30 道(11 月 7 日整理)
数据来源:今日国内技术社区(掘金 / CSDN DevPress / 博客园 / 面试鸭 / 技术公众号「AI 面试八股文」系列)近一个月 Java+AI 岗位面经与文章热度聚合。
配比:Java 运行时与底座 8 题 + Spring AI 与模型接入 7 题 + RAG 深水区 8 题 + Agent、评测与安全 7 题。
每题按「一句话 → 分条要点 → 踩坑/追问」作答,控制在 500 字内。
一、今日热度速览
- JDK 17 的商用支持 2026 年 9 月到期,升级题从"了解"变成"必答"。面试官会直接问"你们跑哪个 LTS、为什么不升 25",答不出授权和 pinning 两件事就露馅。
- 虚拟线程的问法变了。不再问"什么是虚拟线程",改问"我开了吞吐没涨,你帮我看看"——考排查,不考定义。
- MCP 从"会不会接"升级到"怎么授权"。2026-07-28 版规范把远程 Server 定为 OAuth 2.1 资源服务器,token 不许透传、工具描述要哈希固定,细节成了新区分点。
- Coding Agent 的 Harness 成了独立考点。同一个模型换个 Harness 分数差一截,能讲清"指令、上下文、工具、沙箱、审批、验证"这套外围系统的明显高一档。
- RAG 的追问全落到"怎么量化"。黄金集、Recall@k、Faithfulness、LLM 当裁判的偏差校准——没有评测体系的 RAG 项目,在面试官眼里等于没做过。
与上期(11-06)对比
| 类型 | 题目 |
|---|---|
| 新进榜 | JDK 17 到期与升级路线、紧凑对象头、Stream Gatherers、AI 服务可观测性、大模型网关、工具调用幂等、Spring AI 1.1 MCP 一等支持、Prompt 缓存、模型路由、结构化输出、Embedding 选型、向量索引选型、pre-filter、表格公式解析、Query 改写、噪声敏感度、RAG 评测体系、LLM-as-judge 偏差、Agentic RAG、Coding Agent Harness、AI 提效评测、FIM、MCP OAuth、工具投毒、HITL |
| 常驻高热 | 虚拟线程、Spring Boot 4 迁移、Spring AI 抽象、Function Calling、SSE 流式、混合检索、切片策略、多 Agent、提示词注入 |
| 退榜 | HashMap 底层、双亲委派、G1 与 CMS 对比、ScopedValue 细节(仍在考,已非主菜) |
二、Java 运行时与工程底座(Q1–Q8)
Q1. JDK 17 支持到期了,升级到 25 还是 27?路线怎么定?
- 事实:Oracle 对 JDK 17 的 Premier Support 2026 年 9 月结束,JDK 21 的免费条款同期到期。不买订阅就是合规问题,不是技术问题。
- 结论:新项目直接上 JDK 25 LTS(支持到 2030);27 不是 LTS,别当基线。
- 两个硬收益:JEP 491 修掉了
synchronized阻塞把虚拟线程钉在载体线程上的问题——25 是第一个虚拟线程能放心用的 LTS;ScopedValue 转正。 - 成本在两处:
javax.*→jakarta.*迁移;反射摸 JDK 内部的库被强封装挡死,先用jdeps --jdk-internals扫一遍。 - 顺序:先升框架依赖(老版本在新 JDK 上直接编译不过)→ 修编译 → 全量回归 → 灰度比 GC 和 P99。
- 追问"为什么不升 27":非 LTS、半年一版,企业不拿它做基线;但它的 G1 全场景默认、紧凑对象头默认,值得提前在预发验证。
Q2. 紧凑对象头解决了什么?对你有什么实际收益?
- 原来多大:64 位平台对象头 96 位(mark word 8 字节 + 类指针 4 字节),加对齐填充,一个空对象实占 16 字节。
- 改成了什么:压到 64 位,mark word 和类指针挤在一起。JDK 24 实验性引入,25 转正式特性,27 默认开启。
- 收益:每个对象省 4~8 字节。大对象无所谓,海量小对象(DTO、Map.Entry、缓存条目、消息对象)堆占用常降 10%~20%,同样的内存能多装一截缓存。
- 代价:mark word 变窄,锁状态和 hash 的编码方式变了,依赖对象布局的 Unsafe 代码会炸。上线前拿
-XX:+UseCompactObjectHeaders在预发跑一轮。 - AI 落点:高 QPS 下频繁拼 Prompt、造消息对象、包装检索结果,全是小对象密集场景,白捡的收益。
- 答题要点:说出"96 位 → 64 位"和"10%~20%"两个具体数,别只说"省内存"。
Q3. 虚拟线程开了,吞吐却没涨,你怎么排查?
- 先确认真的用上了:
jcmd Thread.dump_to_file,或 JFR 看VirtualThreadStart事件。常见翻车是只加了开关,业务还在用固定大小线程池。 - 一:被池化。套了
FixedThreadPool,载体线程复用死,并发还是那么点。一个任务一个虚拟线程,用Semaphore控并发。 - 二:pinning。JDK 21 上在
synchronized里做阻塞 IO 会钉住载体线程,ForkJoinPool 很快被打满。看 JFR 的jdk.VirtualThreadPinned,按栈顶换ReentrantLock,或直接上 24+。 - 三:下游才是瓶颈。数据库连接池 20、HTTP 连接池 50,上面开十万虚拟线程也只是排队。虚拟线程不创造下游容量。
- 四:CPU 打满。计算型任务开虚拟线程只增调度开销,老实回固定平台线程池。
- 一句话:它解决的是"线程太贵",不是"活太多"。吞吐没涨,八成瓶颈不在线程数上。
Q4. Spring AI 2.0 要 Spring Boot 4 打底,升级要注意什么?
- 基线:Spring AI 2.0 以 Boot 4 / Framework 7 为基线,Java 最低 17、推荐 25。停在 Boot 3.5 的要连跳两级。
- 四处必改:
- 自动配置模块化:一个技术一个 starter,只引
spring-boot-autoconfigure会缺类。 - Jackson 3:包名变
tools.jackson。AI 项目的结构化输出全靠它,这是最容易炸的地方。 - 测试:
@MockBean/@SpyBean移除,换@MockitoBean/@MockitoSpyBean。 - JSpecify 空安全:全框架铺开,编译警告会突然变多。
- 自动配置模块化:一个技术一个 starter,只引
- 手法:先跑 OpenRewrite 的 Boot 4 配方自动改,再手工修剩下;回归重点放 JSON 序列化和测试。
- 坑:Spring AI 1.x 和 2.0 的 starter 命名、包路径不同,混着引就
NoSuchMethodError。 - 升不动怎么拆:先升 Boot 4、Spring AI 留 1.1.x 打补丁,两件事别一刀切。
Q5. Stream Gatherers 是什么?什么场景用得上?
- 一句话:给
Stream补上了"自定义中间操作"。map/filter/flatMap不够用时,以前只能collect一把梭。 - JDK 24 转正(JEP 485),位置
java.util.stream.Gatherer。 - 和 Collector 的分界:Collector 只能在末尾做终止;Gatherer 是中间操作,能 1 对 N、N 对 1、有状态、能提前短路。
- 常用形态:
windowFixed(3)每三个一批、windowSliding(3)滑动窗口、fold做有状态去重。 - AI 落点:流式 token 按句子切分再推前端、长文本按语义边界攒批送翻译、SSE 里滑动窗口去重——以前都得手写 BufferedReader 循环。
- 坑:有状态的 Gatherer 在并行流里要提供 combiner,否则会退化;也别在里面做副作用。
Q6. AI 服务的可观测性怎么做?和普通微服务差在哪?
- 差三个维度:多了一层"模型"黑盒;指标是新的(TTFT、token、工具调用次数、检索命中率);一次请求是树状而非链状——检索 → 拼 Prompt → 模型 → 工具 → 再模型。
- 指标:Micrometer 打 QPS、P99、TTFT、输入输出 token、缓存命中率,按租户和功能打标签,才能算清"每次成功解决的成本"。
- 链路:OpenTelemetry 按 GenAI 语义约定建 span(
gen_ai.request.model、gen_ai.operation.name)。trace 里存 Prompt 摘要或哈希,别存全文——又贵又泄密。 - 日志:一次问答一条结构化记录:query、召回文档 ID 和分数、Prompt 版本、模型、token、耗时。这是排查幻觉的唯一证据。
- 采样:AI 请求又大又贵,保错误和慢请求,正常请求 1%~5%。
- 追问"怎么发现质量下降":看追问率、重问率、转人工率、点踩率——无标签场景下的代理指标。
Q7. 大模型网关该做什么?为什么不直接在业务里调 SDK?
- 不做的后果:五条业务线各引 SDK、各存密钥、各写重试限流,供应商一换改五处,账单出来没人认领。
- 职责(按重要性排):统一接入与协议转换(对外 OpenAI 兼容,内部适配各家);密钥与配额(虚拟 key,速率在这层卡死);路由与降级;可观测与计费;安全(PII 脱敏、审计、注入初筛)。
- 三个坑:
- 流式必须透传,网关一缓冲,首字时延直接翻倍。
- 超时要分层:网关 > 业务 > 单次模型,否则外层先断、内层还在烧钱。
- 别在网关做重试放大,网关重试叠业务重试,供应商被自己打挂。
- 一句话:网关就是"把模型当成一个需要被治理的外部依赖",和治理数据库、MQ 一套思路。
Q8. 模型要调工具改数据,怎么保证幂等和一致性?
- 本质:
tool_calls是不可靠网络上的远程调用。超时一重试,就可能重复扣款、重复发货。 - 一:幂等键。用模型返回的
call_id,执行前先INSERT抢幂等表,抢不到直接返回上次结果。 - 二:状态机。单据只允许单向流转,重复请求因状态不匹配天然被拒——比任何分布式锁都可靠。
- 三:拆事务边界。模型调用绝不进数据库事务,等 20 秒就占 20 秒连接。先落"处理中"记录,再独立事务更新结果。
- 跨服务:Saga 或本地消息表 + 补偿。别硬上 TCC,AI 链路太长,改造成本划不来。
- 高危动作:超阈值金额、不可逆操作强制人工确认,模型只出参数,不出决定权。
- 怎么验证:压测里专门注入超时和重复回调,看幂等表命中率和对账差异是否为 0。
三、Spring AI 与模型接入(Q9–Q15)
Q9. Spring AI 1.1 的 MCP「一等支持」是什么意思?
- 两件事:既能消费别人的 MCP Server,也能把自己的 Spring Bean 暴露成 MCP Server。
- 消费侧:
spring-ai-starter-mcp-client。stdio 用于本地进程,Streamable HTTP 用于远程——2025 版规范已废弃纯 SSE 传输,答 SSE 是旧知识。 - 暴露侧:
spring-ai-starter-mcp-server,带@Tool的方法直接发布,框架管协议和版本协商,原来的函数不用重写。 - 关键设计:MCP 工具被转成
ToolCallback,和本地@Tool完全同构,业务不区分远程还是本地。 - 1.1 的实质进步是 OAuth2:远程连接能走 OAuth,才算真能上生产。
- 什么时候不该用:纯本地、只有一个消费者、工具就两三个——直接
@Tool更简单,上 MCP 是过度设计,白加一层网络和鉴权负担。
Q10. Advisor 链的顺序为什么会出错?怎么定 order?
- 是什么:挂在
ChatClient调用链上的拦截器,能改请求、改响应、加记忆、打日志。本质是 Spring AOP 的 AI 版。 - 为什么敏感:
order小的在外层先执行。三个真实冲突:- 记忆必须先于检索。记忆先注入,检索能基于"这句话 + 历史"改写;反过来先检索,"那它呢"根本查不出来。
- 日志 Advisor 放最外层,放里面只能看到局部改写后的 Prompt。
- 敏感词校验放最内层,它要检查真正发出去的完整内容。
- 推荐顺序(外到内):日志埋点 → 限流 → 记忆 → 检索 → 安全校验 → 模型。响应方向自然倒过来。
- 坑:
QuestionAnswerAdvisor自带检索,别和手写检索 Advisor 同时挂,会检索两次。 - 一句话:顺序不是配置问题,是语义问题——先想清每一步依赖谁的输出。
Q11. Spring AI 的 ChatMemory 为什么拆成两层?怎么换 Redis?
- 两层分工:
ChatMemory管逻辑(按conversationId维护消息、控窗口、决定裁谁);ChatMemoryRepository管存储(默认 InMemory,可换 JDBC / Redis)。 - 好处:窗口策略和存储介质解耦。换 Redis 只换 Repository,Controller 一行不改。
- 窗口:
MessageWindowChatMemory按maxMessages留最近 N 条,系统消息不受裁剪影响,不用自己写截断。 - 隔离:传
ChatMemory.CONVERSATION_ID,不同 sessionId 互不可见。多租户 key 必须拼租户 ID,否则就是越权。 - Redis 实现:key 用
chat:mem:{tenant}:{sessionId}并设 TTL;消息多时用 List 做LPUSH+LTRIM,别整存整取。 - 坑:流式和同步接口要挂同一个记忆 Advisor,否则会出现"同步记得住、流式记不住"。
Q12. 结构化输出怎么做才稳?
- 三条路,可靠性递增:
- Prompt 里写"请输出 JSON":最脆,会加解释、加 ```json 包裹、字段名飘。只适合 demo。
- JSON Schema 约束解码:解码时 token 只能走合法分支,结构上一定合法,当前最优。
- 工具调用当输出通道:造一个"提交结果"的假工具让模型用参数提交,兼容性最好。
- Spring AI 侧:
BeanOutputConverter/.entity(Class),自动生成 Schema 并反序列化。 - Schema 三条铁律:字段用包装类型(
Integer不用int,缺字段才不会悄悄变 0);枚举值写死;嵌套别超三层,超了模型就漏字段。 - 翻车点:结构合法 ≠ 语义正确。金额算错、幻觉填 ID,Schema 管不了。
- 兜底:解析失败带错误信息重试一次,还失败就降级或转人工。重试要计预算,无限重试是烧钱黑洞。
Q13. Prompt Caching 是什么?能省多少?
- 原理:相同前缀的 KV 缓存可复用。命中部分按原价约 10% 计费,延迟也降。
- 生效条件(关键):前缀必须逐字节一致。所以稳定内容放前面:system → few-shot → 固定知识 → 最后才是用户问题。
- 最白费的做法:system 里塞当前时间、用户名、随机 ID。前缀一变缓存全废,动态内容一律往后放。
- 两家差异:Anthropic 显式标
cache_control断点,可标多段;OpenAI 是自动前缀缓存,约 1024 token 起。 - 收益:重复上下文多的场景,输入成本能砍 80%~90%——RAG 固定知识库、客服固定话术、代码助手固定系统提示都是受益场景。
- 坑:有 TTL,低频调用命中不了;缓存按模型和账号隔离,换模型就没了。
Q14. 多模型路由和主备怎么设计?
- 为什么:不同任务能力要求差十倍,成本也差十倍。全走最强模型,账单没法看。
- 三档路由:规则路由(意图分类 → 小/大模型,最简单);分类器路由(先判难度,多一次调用);级联(小模型先答,置信度低再升级,质量接近大模型但延迟翻倍)。
- 主备:同能力配多个供应商,健康检查 + 熔断切换,配置化别硬编码。切换方要保留同等的工具调用和结构化输出能力,否则切过去功能就残。
- 抽象:对外只暴露
ChatModel接口,业务不知道背后是谁。 - 两个坑:能力不对等(小模型不支持工具调用或 JSON Schema,路由表要标能力位);重试放大(总尝试次数必须有上限)。
- 怎么验证:按路由维度看"成功率 + 单次成本 + P99",只降本不看质量是自欺欺人。
Q15. 流式、工具调用、结构化输出同时用,会撞出什么坑?
- 本性冲突:流式要边生成边推,工具调用要停下等结果,结构化要整体合法才可用。
- 坑一:返回
tool_calls时正文是空的,前端长时间静默。要推一个"正在查询订单…"的状态帧。 - 坑二:一轮 ReAct 调三次工具就有三次中断,前端要按轮次拼接,别把每段当独立回答。
- 坑三:JSON 是一段段吐的,中途解析必失败。要么不流式,要么流式只推自然语言,结构化结果在流结束后单独下发一帧。
- 坑四:用户断线时 Flux 被 cancel,工具可能执行了一半——执行侧必须幂等。
- 工程建议:把事件类型显式建模:
delta/tool_start/tool_result/final/error,前端按类型分发别靠猜。 - 一句话:流式是传输层,工具调用是编排层,结构化是输出层,别在一个字符串里塞三种语义。
四、RAG 深水区(Q16–Q23)
Q16. RAG 效果怎么量化?黄金集怎么建?
- 先分两层,别用一个分数糊弄自己:
- 检索层(确定性,可做硬门禁):
Recall@k/ Hit Rate、MRR、Context Precision。 - 生成层(有波动):
Faithfulness、Answer Relevance、引用准确率。
- 检索层(确定性,可做硬门禁):
- 黄金集:80~150 条就够暴露回归。从线上真实 query 采样,覆盖高频 + badcase + 对抗样本,每条存
{question, ground_truth, relevant_doc_ids}。 - 省成本的关键:只标"哪几个 chunk 能回答",不要求写标准答案,标注成本立刻降一个量级。
- 接 CI:检索层阈值可卡 ±1%(同库同参数结果可复现);生成层固定 judge 版本 +
temperature=0,阈值放宽。 - 线上无标签:看代理指标——Top1 相似度均值是否下滑、拒答率、追问率、转人工率、P95 和单次成本。
- 一句话:没有黄金集的 RAG 项目等于没做,所有调优的效果判断最后都要落到这几个数上。
Q17. 用大模型当裁判打分,有什么偏差?怎么校准?
- 四种已知偏差:长度偏好(长答案分高,哪怕注水)、位置偏好(偏爱第一个)、自家偏好(偏爱同族模型)、宽松倾向(1~10 分制普遍给 7~8 分,没区分度)。
- 校准手法:
- 用二值或三档:"每个事实性陈述都能在给定文档找到依据 → 1,否则 0",比打分和人工一致率高得多。
- 两两对比时随机交换顺序,或两个顺序都跑取平均。
- 把证据喂给它:检索文档 + 参考答案一起给,别只给答案让它凭空判断。
- 拿几百条人工标注算一致率,低于 85% 的维度不要信。
- 必须固定:judge 模型版本、system prompt、
temperature=0。这三样一变,历史分数全部作废。 - 能用代码判的一律用代码:JSON 合法性、字段存在性、工具是否被正确调用、SQL 能否执行。
- 一句话:它是"便宜但会撒谎的实习生",用人给它定标,再让它干量大的活。
Q18. Embedding 模型怎么选?
- 四个维度按顺序看:
- 语言适配:中文别默认用英文模型,
bge-m3、bge-large-zh是常见起点。 - 维度与成本:1024 维是甜点。一亿条 chunk × 1024 维 float32 就是 400GB,先算清存储再选。
- 最大输入长度:512 token 的模型喂 800 token 的块会被静默截断——最隐蔽的召回丢失原因。
- 是否支持稀疏/多向量:
bge-m3三路输出,天然支持混合检索,省一套 BM25。
- 语言适配:中文别默认用英文模型,
- 怎么验证:别信榜单。拿黄金集跑 Recall@5,两三个候选实测,一天出结论。
- 要不要微调:领域黑话多(医疗、法律、内部代号)才考虑,通常提 5~10 个点;但先确认不是切分和清洗的问题,那是八成根因。
- 铁律:建库和查询必须同模型同版本。中途换模型不重建索引,等于用两个坐标系互查,结果全是噪声。
- 迁移:新模型建新 collection,双写一段时间,黄金集对比后再切流量。
Q19. 向量索引 HNSW、IVF、PQ 怎么选?
- 为什么需要:精确最近邻是 O(n) 全扫,上千万条就不可接受。用 ANN 拿一点召回损失换数量级性能。
- HNSW:多层图,上层粗导航、下层精查找。召回最高、查询最快、免训练;吃内存、构建慢、删除麻烦。
M取 16~64,efSearch是召回和延迟的旋钮。 - IVF:聚类成 N 簇,查询只扫最近
nprobe个。省内存、适合超大规模;但要训练,数据分布变了得重建,簇边界容易漏。 - PQ:切段量化成码本 ID,压缩 1/4 ~ 1/32,代价是精度。常和 IVF 组成 IVF-PQ,十亿级标准解。
- 口诀:千万级以内内存够 → HNSW;亿级以上 → IVF-PQ;要极致压缩、能接受掉点 → PQ 系。
- 更该先问的:库选谁。
pgvector上手最快、和业务库同事务;Milvus 抗十亿;ES 混合检索最顺。先定库,再调参。
Q20. 元数据过滤该在检索前还是检索后?
- 这是 RAG 里最容易做错、后果最重的选择。
- post-filter(先检索再过滤):取 Top-50 再按租户、权限、时间筛。两个致命问题——
- 过滤后可能一条不剩:Top-50 里只有 3 条属于当前租户,召回直接塌方。
- 无权文档已经进内存,日志、调试、异常栈都可能带出来。
- pre-filter(先过滤再检索):条件下推到索引层,只在合法子集做 ANN。正确做法,但实现质量差很大:
- 暴力筛 ID 再逐个算距离,条件宽松时等于全扫;
- 图索引上遍历跳过不合格节点,选择性高时连通性会断、召回下降,要配合提高
efSearch; - 按租户分 collection 最干净,但租户多了运维贵。
- 折中:小基数维度物理分区(租户),大基数维度索引过滤(时间、类型)。
- 底线:权限必须在检索前生效,绝不让模型参与鉴权。Prompt 写"不要回答无权内容"等于没写——数据已经在上下文里了。
- 权限变更:缓存 key 带权限版本号,变了就失效;引用溯源列表也要过同样过滤。
Q21. PDF 里的表格、公式、扫描件怎么处理?
- 为什么是分水岭:纯文本抽取拿 80 分容易,但合同金额、报价单、财报全靠表格。
- 电子版 PDF:用带版面分析的解析器(pdfplumber、PyMuPDF、MinerU、Unstructured),别用裸
pdftotext——它会把表格拍平成一行乱码。 - 扫描件:走 OCR 或多模态直接读图,先做版面检测再识别,否则阅读顺序全乱。
- 原生 Word / HTML:优先拿结构化源,Mammoth、python-docx 保留标题层级,比从 PDF 反推靠谱。
- 表格入库(关键):转 Markdown,表头必须保留;大表按行切块且每块重复表头;打
type=table标签,检索可加权。 - 公式:转 LaTeX 存原文,渲染交前端。图片:先过多模态生成结构化描述再入库,检索用描述、展示用原图。
- 验收:拿 20 份真实文档人工看阅读顺序和表格列有没有错位。不做这步,后面调优全是白费。
Q22. Query 改写有哪些手段?HyDE 真有用吗?
- 为什么必须改:query 又短又指代不明——"那它呢""多少钱"直接拿去检索,质量全靠运气。
- 四种,按成本排:
- 指代消解:把"它"换成上一轮的具体对象。多轮场景性价比最高,不做这个后面全白搭。
- 多查询扩展:生成 3~5 个同义问法并行检索再去重,召回提升明显,代价是多几次检索。
- HyDE:先让模型编一个假答案,用假答案的向量去检索。适合 query 太口语、和文档表述差太远(问"怎么报销",文档写"费用申请流程");精确查找型问题反而有害——型号、条款号、错误码会被假答案冲淡。
- Step-back:先问一个更泛的拿到背景,再检索具体问题。
- 成本:每次改写都是一次模型调用,延迟和 token 都要算账。简单 FAQ 做指代消解就够。
- 验证:改写前后在黄金集跑 Recall@5,没涨就砍掉。很多团队加了 HyDE 效果没变、延迟翻倍。
- 坑:改写版用来检索,但最终 Prompt 要放原始问题。
Q23. 检索里混了干扰内容,模型被带跑怎么办?
- 这个指标有名字:
Noise Sensitivity(噪声敏感度)——上下文塞进不相关段落时,答案正确率的下降幅度。它和 Faithfulness 是两个维度,要分开测。 - 为什么:模型对上下文一视同仁,没有"这条可信那条不可信"的判断力。你给 8 块,它可能拿最不像样的那块去答。
- 四种手段:
- 减少数量。Top-K 从 10 压到 3~5。多数情况下降噪最有效的动作是"少给"。
- 重排后按断崖截断(第 4 名分数掉一半就只给 3 块),别死守固定 K。
- 显式标注可信度:每块带来源和版本,Prompt 里限定"只能依据标注为【有效】的片段"。多版本冲突时特别好用。
- 强制引用 + 拒答:每个结论标
[doc_id],标不出来就不许说,同时治幻觉。
- 怎么测:把正确段落和 3 段无关内容混一起,看答案是否还正确,做成固定测试集进 CI。
- 反直觉结论:上下文不是越多越好。头尾位置最重要,中间最容易被忽略(Lost in the Middle)。
- 一句话:瓶颈通常在"给太多、没排序、没标注",不在"召回不够多"。
五、Agent、评测与安全(Q24–Q30)
Q24. RAG 和 Agentic RAG 有什么区别?什么时候真需要后者?
- 传统 RAG 是"一次检索":query → 检索 → 生成,一条直线。答不好只能回去调切分和模型。
- Agentic RAG 把检索变成工具:模型自己决定要不要查、查什么、查几次、够不够。典型是 ReAct 循环,信息不够就换个 query 再查。
- 多出三种能力:多跳(先查 CEO 是谁、再查他的学历,单次检索做不到);路由(该查制度库、工单库还是数据库);自我纠错(不满意就改写重试)。
- 什么时候真需要:问题本身多跳、要跨多个数据源、检索质量波动大需要"再试一次"。面向 C 端的简单 FAQ 上它就是负优化,延迟和成本各翻几倍。
- 代价清单:延迟 3~10 倍、成本 3~5 倍、路径不可预测、更难评测(要评路径不只评答案)。
- 防失控:最大检索轮次 3~5、总 token 预算、重复 query 检测、无进展就降级成单次 RAG。
- 一句话:用成本和延迟换复杂问题的准确率,先证明你的问题真的复杂。
Q25. Coding Agent 的 Harness 是什么?为什么同一个模型效果差一截?
- 定义:模型外面那套运行系统。模型只负责"想下一步",能不能干成靠 Harness。
- 组成(背下来):Instructions(项目规范)+ Context(检索与压缩)+ Tools(文件/Shell/测试/MCP)+ State(检查点)+ Sandbox + Permissions/Approvals + Verification(跑测试)+ Evals + Tracing + Budget。
- 为什么差一截:
- 上下文怎么给:只塞当前文件 vs 先给仓库地图再按需读,后者成功率明显高。
- 能不能自我验证:能跑测试并根据失败重试的,远胜"一次生成就交付"的。
- 有没有预算和终止条件:没上限的 Agent 会在一个 bug 上转二十圈。
- 怎么答才显水平:别背工具名和榜单分数,讲控制回路——定义范围 → 检查上下文 → 提议动作 → 执行 → 验证 → 收敛。
- 加分句:模型能力是买来的,Harness 才是工程。我做过最有效的改造是加失败测试和回滚点,收益比换模型更大。
- 追问怎么量化:固定模型和任务集,只换一个变量,多次跑取成功率和方差。单次跑通不算证据。
Q26. 怎么证明 AI 编码真的提效了?
- 先否掉三种错误:自报"效率提升 50%"、拿厂商榜单、只算代码行数。
- 三层指标:
- 任务层:一次通过率、最终成功率、返工次数。
- 过程层:步数、重试次数、人工介入次数。
- 运营层:总耗时、token 费用、缺陷率、安全事件数。
- 必须控变量:同仓库 commit、同任务描述、同模型、同预算和网络,每个条件跑 3~5 次。AI 输出方差大,单次说明不了任何问题。
- 最容易漏的是返工率:生成快了但改得更多,净收益可能是负的。
- 落地:从测试覆盖好、可回滚的仓库试点,用 20~50 个真实任务建基线再放开权限。
- 要盯的风险:AI 引的依赖可能是幻觉包名(会被投毒)、密钥写进代码、改动超出任务边界。
- 一句话:证明方式是受控实验 + 多维指标 + 可复现任务集,不是一张对比截图。
Q27. FIM(Fill-in-the-Middle)为什么适合代码补全?
- 普通生成是从左往右,只看前文。但写代码时插入点往往前有代码、后也有代码——只看前文,模型不知道下面已经写了什么。
- FIM 的做法:把文本切成
prefix和suffix,让模型同时看着两边生成中间那段。 - 两种训练排列:PSM(前文-后文-中间)是主流;SPM 换个顺序,对某些模型效果更好。
- 为什么有效:把"续写"变成了"填空"。输出必须和后面的代码语义连贯——变量名、返回类型、括号闭合都能对上。
- 它解释不了什么:只能解释单文件内的补全。多文件 Agent 靠的是检索、工具和循环,不是 FIM,混为一谈是明显减分项。
- 还依赖:邻近文件选取、语法树/符号信息、跨文件检索、延迟预算(补全要 200ms 级)、停止条件、用户接受信号。
- 追问"补全 vs Agent":补全出代码片段、无工具无状态,风险是"建议质量";Agent 出多步变更、有 Shell 副作用,必须配沙箱、审批、预算和验证。
Q28. MCP 的鉴权怎么做?token 能透传给上游吗?
- 定性:按 2026-07-28 版规范,受保护的远程 MCP Server 是 OAuth 2.1 资源服务器,不是授权服务器。
- 流程:请求 → 401 指向 Protected Resource Metadata → 发现授权服务器 → 注册 → 授权码 + PKCE(S256) +
resource参数(RFC 8707) → 带 token 访问。 - 两条硬规则:token 必须受众绑定,Server 要校验;禁止把 Client 的 token 透传给上游,否则上游会误以为是自己签发的——这就是混淆代理。
- 正确姿势:Server 用自己身份换上游 token(MCP proxy server),必须 per-client 同意 + 精确匹配
redirect_uri,否则旧授权码能被重放。 - 粒度:按工具划 scope,
jira:read/deploy:prod分级。权限不够时返回WWW-Authenticate指明 scope,走升级授权,生产部署人工批。 - 两个错:把工具藏起来当鉴权(模型看不见,服务端照旧执行);stdio 套 OAuth(规范要求从环境变量取凭据)。
Q29. 什么是工具投毒和 rug pull?怎么防?
- 投毒:恶意 Server 在工具名、描述、参数说明里藏指令。模型把描述当"指导"读,于是被引去调别的敏感工具、或把数据塞进某个参数外传。
- 防不胜防:Client 一连接就把工具描述塞进上下文,还没调用任何工具,攻击就已经发生,业内叫 line jumping。
- 规模数据:MCPTox 测过 20 个模型配置,平均攻击成功率 36.5%,能力越强的模型往往越容易被绕。
- rug pull:审查时描述是干净的,批准后 Server 悄悄改描述或改实现。
- 防御清单:只从受信注册表装 + 锁版本校验和;对完整工具定义做哈希固定(含
inputSchema、outputSchema、annotations,不只是 description);定义一变就重新审批;每 Server 最小权限 scope;跨 Server 隔离(阻止描述引用别的 Server 的工具);工具返回值当不可信输入。 - 关键细节:一个
readOnlyHint被翻转就能改变审批行为,而文本看不出任何变化。 - 诚实收尾:没有单一手段能完全防住,哈希也查不出 Server 代码被换。
Q30. Agent 的人机协同(HITL)怎么设计?哪些操作必须拦?
- 为什么必须有:Agent 的错误是有副作用的错误。答错一句话是体验问题,转错一笔账是事故。
- 按"影响面 × 可逆性"分级:
- 只读 → 自动放行,只记审计日志。
- 可逆写(改草稿、建提醒)→ 自动执行 + 事后通知 + 可撤销窗口。
- 不可逆 / 高金额(退款、转账、删数据、发外部邮件、部署生产)→ 强制人工确认,且展示完整参数。
- 敏感数据出境 → 直接禁止,不是确认。
- 确认界面要看具体参数,不是自然语言摘要。"将向订单 A123 退款 ¥499"比"即将执行退款操作"有用一百倍——摘要会掩盖参数错误。
- 别做成确认疲劳:每步都弹窗,用户会无脑点同意,等于没有。只在不可逆和高影响面处拦,其余靠事后审计。
- 技术落点:确认走独立接口,带一次性 nonce 和过期时间防重放;确认前状态落库,确认后由服务端执行,别让模型拿着"已批准"标记自己去调;trace 记录谁提的、谁批的、什么参数、何时执行。
- 一句话:本质不是"加个弹窗",是把决定权从模型手里收回到人手里,同时保证人看到的是真相。
六、30 秒答题模板
| 题型 | 结构 | 示例 |
|---|---|---|
| 概念题 | 一句话定义 → 内部机制 → 一个踩坑 | "HNSW 是分层图索引……我们把 M 调大后内存直接翻倍" |
| 排查题 | 先定位哪一环 → 证据是什么 → 怎么改 → 怎么验证 | "先看 JFR 的 pinned 事件,栈顶指向那把 synchronized" |
| 设计题 | 澄清场景 → 分层 → 说瓶颈和取舍 | "先确认是只读还是要写,写就得加幂等和确认" |
| 评测题 | 定义失败 → 建集合 → 选评分器 → 设门禁 | "先和产品定什么是不可接受的错误,再建 100 条黄金集" |
| 对比题 | 各自解决什么 → 何时选谁 → 能否组合 | "HNSW 用内存换召回,IVF-PQ 用精度换容量" |
最后一句:今年 Java+AI 岗位筛的不是"你会不会调模型",而是你能不能给一个不确定的东西划出确定的边界——升级路线、延迟预算、权限边界、成本上限、可回滚点。模型年年换,这些边界年年有用。