2026大厂AI工程师面试必考:Spring AI核心50题精讲
2026/4/30大约 7 分钟
2026大厂AI工程师面试必考:Spring AI核心50题精讲
适读人群:准备2026年春招/秋招AI相关岗位的Java工程师
阅读时长:约20分钟
文章价值:50道高频面试题 + 深度答案解析 + 源码追踪
面试趋势分析
2026年,AI工程师面试呈现三大趋势:
- 框架层深度考察:不再停留在"会用",要求理解源码原理
- 系统设计必考:给你一个业务场景,要你设计完整的AI应用架构
- 生产问题排查:如何排查LLM调用慢、响应质量差、成本失控等真实问题
Spring AI作为Java AI领域的标准框架,在2026年的面试中出现频率极高。本文整理了50道最高频考题,配以深度解析。
核心概念类(Q1-Q15)
Q1:Spring AI的核心抽象层是什么?设计理念是什么?
答案:
Spring AI的核心设计理念是"用Spring的方式构建AI应用"——通过统一抽象层屏蔽不同LLM提供商的差异,就像Spring Data统一了各种数据库访问一样。
核心抽象层包括:
设计理念体现:
ChatModel是底层接口,不同厂商各自实现(OpenAiChatModel、OllamaChatModel等)ChatClient是高级门面,在ChatModel上叠加了Advisor链、defaultXxx配置- 业务代码只依赖抽象,切换模型提供商无需改动业务逻辑
Q2:ChatClient 和 ChatModel 的区别,什么时候用哪个?
答案:
| 维度 | ChatModel | ChatClient |
|---|---|---|
| 层次 | 底层接口 | 高级封装 |
| Advisor支持 | ❌ | ✅ |
| default配置 | ❌ | ✅ (system/advisors/tools) |
| 状态管理 | 无状态 | 可以通过Advisor管理会话 |
| 使用场景 | 简单单次调用、工具库开发 | 生产业务代码 |
// ChatModel - 底层,无状态
@Autowired
ChatModel chatModel;
Prompt prompt = new Prompt("解释Java虚拟机");
ChatResponse response = chatModel.call(prompt);
// ChatClient - 高级,功能丰富
@Autowired
ChatClient.Builder builder;
ChatClient client = builder
.defaultSystem("你是Java技术专家")
.defaultAdvisors(new MessageChatMemoryAdvisor(memory))
.build();
String answer = client.prompt()
.user("解释Java虚拟机")
.call()
.content();面试答题重点:生产代码推荐ChatClient,因为它封装了Advisor链机制,让你可以透明地插入对话历史、RAG检索、日志监控等横切关注点。
Q3:Advisor机制的本质是什么?执行顺序如何?
答案:
Advisor本质是AOP思想在AI调用链中的应用。它是一种拦截器模式,允许在LLM调用前后插入自定义逻辑。
执行顺序规则:
- Advisor按
Order值从小到大排列,值越小越先执行(越靠外层) - 推荐Order配置:SimpleLoggerAdvisor(最外层) > MessageChatMemoryAdvisor > QuestionAnswerAdvisor(最内层,靠近LLM)
- 类似AOP的around advice:前置从外到内,后置从内到外
ChatClient client = builder
.defaultAdvisors(
new SimpleLoggerAdvisor(), // Order=0(最外层)
new MessageChatMemoryAdvisor(memory), // Order=1
new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()) // Order=2(最内层)
)
.build();Q4:Spring AI的Auto-Configuration是如何工作的?
答案:
Spring AI的自动配置遵循标准的Spring Boot Auto-Configuration机制:
关键配置:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
base-url: https://api.openai.com # 可替换为代理地址
chat:
options:
model: gpt-4o
temperature: 0.7
max-tokens: 2048面试加分点:提到可以通过@ConditionalOnMissingBean覆盖自动配置,注入自定义的ChatModel实现(例如实现带Mock的测试Bean)。
Q5:如何实现多LLM提供商的动态切换?
答案:
生产环境常见需求:根据不同业务场景使用不同模型(成本控制、能力互补)。
@Configuration
public class MultiModelConfig {
@Bean("openAiClient")
public ChatClient openAiClient(OpenAiChatModel openAiModel) {
return ChatClient.builder(openAiModel)
.defaultSystem("你是OpenAI驱动的助手")
.build();
}
@Bean("deepSeekClient")
public ChatClient deepSeekClient(OllamaChatModel ollamaModel) {
return ChatClient.builder(ollamaModel)
.defaultSystem("你是DeepSeek驱动的助手")
.build();
}
}
@Service
public class SmartRoutingService {
private final Map<String, ChatClient> clientMap;
public SmartRoutingService(
@Qualifier("openAiClient") ChatClient openAiClient,
@Qualifier("deepSeekClient") ChatClient deepSeekClient
) {
this.clientMap = Map.of(
"premium", openAiClient,
"standard", deepSeekClient
);
}
public String chat(String query, String tier) {
ChatClient client = clientMap.getOrDefault(tier, clientMap.get("standard"));
return client.prompt().user(query).call().content();
}
}RAG架构类(Q16-Q30)
Q16:RAG的检索质量差,有哪些优化手段?
答案(按优先级排列):
核心优化代码示例:
// 混合检索:向量检索 + 关键词检索结果融合
@Service
public class HybridSearchService {
private final VectorStore vectorStore;
private final KeywordSearchService keywordSearch;
public List<Document> hybridSearch(String query) {
// 向量检索
List<Document> vectorResults = vectorStore.similaritySearch(
SearchRequest.query(query).withTopK(10)
);
// 关键词检索(BM25)
List<Document> keywordResults = keywordSearch.search(query, 10);
// RRF融合排序(Reciprocal Rank Fusion)
return rerankByRRF(vectorResults, keywordResults, 5);
}
private List<Document> rerankByRRF(
List<Document> list1, List<Document> list2, int topK
) {
Map<String, Double> scores = new HashMap<>();
int k = 60; // RRF参数,通常取60
for (int i = 0; i < list1.size(); i++) {
scores.merge(list1.get(i).getId(), 1.0 / (k + i + 1), Double::sum);
}
for (int i = 0; i < list2.size(); i++) {
scores.merge(list2.get(i).getId(), 1.0 / (k + i + 1), Double::sum);
}
return scores.entrySet().stream()
.sorted(Map.Entry.<String, Double>comparingByValue().reversed())
.limit(topK)
.map(e -> findDocById(e.getKey(), list1, list2))
.collect(Collectors.toList());
}
}Q17:分块(Chunking)策略如何选择?
答案:
| 分块策略 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 固定大小分块 | 均匀文本 | 简单、一致 | 可能截断语义 |
| 递归字符分块 | 通用文本 | 尊重语义边界 | 块大小不均 |
| 语义分块 | 高质量文档 | 语义完整性好 | 计算成本高 |
| 文档结构分块 | 结构化文档(MD/HTML) | 保留文档结构 | 依赖格式 |
| 父子分块 | 精度要求高 | 检索精细,生成完整 | 存储翻倍 |
Spring AI实现父子分块:
@Service
public class ParentChildChunkService {
private final VectorStore vectorStore;
public void indexWithParentChild(List<Document> docs) {
TokenTextSplitter parentSplitter = new TokenTextSplitter(1000, 50, true);
TokenTextSplitter childSplitter = new TokenTextSplitter(200, 20, true);
for (Document parent : parentSplitter.apply(docs)) {
String parentId = UUID.randomUUID().toString();
parent.getMetadata().put("chunk_type", "parent");
parent.getMetadata().put("chunk_id", parentId);
List<Document> children = childSplitter.apply(List.of(parent));
children.forEach(child -> {
child.getMetadata().put("chunk_type", "child");
child.getMetadata().put("parent_id", parentId);
});
// 子块存入向量库(用于检索)
vectorStore.add(children);
// 父块存入关系库(用于生成时获取完整上下文)
parentDocStore.save(parentId, parent);
}
}
}生产实践类(Q31-Q45)
Q31:如何实现AI接口的限流和熔断?
答案:
@Service
public class ResilientAiService {
private final ChatClient chatClient;
private final RateLimiter rateLimiter;
// 使用Resilience4j实现熔断+限流
@CircuitBreaker(name = "aiService", fallbackMethod = "fallbackChat")
@RateLimiter(name = "aiRateLimit")
@Retry(name = "aiRetry")
public String chat(String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
// 降级方案
public String fallbackChat(String message, Exception e) {
log.warn("AI服务降级,原因:{}", e.getMessage());
return "抱歉,AI服务暂时不可用,请稍后重试。";
}
}application.yml配置:
resilience4j:
circuitbreaker:
instances:
aiService:
slidingWindowSize: 10
failureRateThreshold: 50
waitDurationInOpenState: 30s
ratelimiter:
instances:
aiRateLimit:
limitForPeriod: 100 # 每秒100次
limitRefreshPeriod: 1s
timeoutDuration: 500ms系统设计类(Q46-Q50)
Q46:设计一个高并发的LLM推理服务,如何保障P99延迟在5秒内?
参考答案(系统设计要点):
关键优化手段:
- Semantic Cache:相似问题直接命中缓存,命中率通常20-40%
- 流式输出:首token延迟感知从5s降到1s以内
- 连接池复用:避免每次请求重建HTTP连接
- 请求批处理:合并相同时间窗口内的独立请求
- 模型路由:简单问题路由到快速小模型
学习建议
Spring AI面试准备的三个层次:
- 会用:每个API都亲手写过Demo
- 懂原理:核心类的源码看过一遍
- 能设计:能根据业务场景给出合理的Spring AI架构方案
