大厂 Java 面试实战:从 Spring Boot 微服务到 AI RAG 音视频平台全链路解析
场景:互联网大厂------"云声视频内容社区"(音视频 + UGC + AIGC)
角色:
- 严肃面试官:老程(资深 Java 架构师)
- 搞笑水货程序员:小Y(简历写"熟练掌握全栈 + AI + Web3.0")
一、面试开场:业务背景
老程:
我们是做音视频内容社区的,类似短视频 + 直播 + UGC 图文内容, 还有 AIGC 文本 + 图片生成,做推荐、搜索、IM、支付和本地生活服务, 你就按你熟悉的技术栈来聊。准备好了我们开始。
小Y:
没问题,我对 Java 生态和 AI 都了如指掌,可以随意问。
老程心里一紧:
......好,那就随意问。
第二部分:三轮面试问答(故事版)
第一轮:基础服务 & Spring Boot 音视频上传
本轮业务场景:
- 需求:实现"视频上传 + 转码 + 封面生成 + 元数据入库"的基础服务;
- 技术栈:Java 17、Spring Boot、Spring MVC、Hibernate/MyBatis、Redis、Kafka、ELK;
- 目标:考察 Java 基础、Spring Boot 基础、数据库与缓存、消息队列、日志与监控。
Q1:Java 基础 & JVM
老程:
我们后端主要用 Java 17,讲讲你在项目里怎么利用 Java SE 特性 (比如 Stream、Optional、并发包)和 JVM 调优来支撑高并发上传?
小Y:
这个嘛,我一般就是 new Thread,配合 synchronized, 然后再加一点 Stream 的 map、filter 就可以了。 JVM 调优的话,我觉得默认就挺好,一般也不用改, 实在不行我就多给点内存,-Xmx 调大点就完事了。
老程:
......那先记下。
Q2:Spring Boot 设计视频上传接口
老程:
设计一个"视频上传接口",用 Spring Boot + Spring MVC。 简单说一下:
- Controller 层接口大致长什么样?
- 文件上传通常怎么处理?
- 如何返回上传结果?
小Y:
Spring Boot 我很熟啊,我一般就是:
java@RestController public class VideoController { @PostMapping("/upload") public String upload(MultipartFile file) { // 保存一下 return "ok"; } }然后我就把文件直接存服务器本地盘上就行, 反正云盘都很大嘛,结果就统一返回 "ok", 前端自己判断就行。
老程:
你这个接口......能跑,但放在线上服务估计三天就爆。
不过基础 Controller 写法还行。
Q3:数据库与 ORM 设计
老程:
上传完视频,要存储元数据(标题、作者、时长、清晰度、状态等)。 你会怎么设计表结构、用什么 ORM?简要说说你的做法。
小Y:
ORM 我都用过,Hibernate、MyBatis、JPA 都了解。 表结构的话就一个 video 表,所有字段都往里塞, 比如 title、userId、duration、status、url 之类, 然后加一个 bigtext 存 JSON 扩展字段,就行。
ORM 的话随缘吧,项目里哪个多就用哪个, 反正都差不多,就是自动映射嘛。
老程:
"随缘 ORM",这个说法挺新。 不过你至少知道拆字段,勉强算过关。
Q4:上传后的异步处理(Kafka / RabbitMQ)
老程:
视频上传成功后,我们要异步做转码、截图、内容审核。 你会怎么设计异步流程?消息队列选 Kafka 还是 RabbitMQ?为什么?
小Y:
异步嘛,我一般就是 new 一个线程池,然后 submit 一个任务, 这样就异步了。消息队列的话,Kafka 和 RabbitMQ 我都熟, 感觉都差不多,谁好用用谁。
如果非要选,那就 Kafka 吧,听起来比较大数据。
老程:
......你这个选型依据挺"感性"。 回头我详细给你解释差异。
Q5:日志与监控(ELK、Prometheus、Grafana)
老程:
线上视频上传成功率很重要,我们会监控错误率、时延, 并通过 ELK、Prometheus+Grafana 来做监控和告警。 你会在代码中埋哪些关键日志?监控指标怎么上报?
小Y:
日志嘛,我一般就 log.info("上传成功")、log.error("失败")。 监控的话,我之前项目没这么复杂, 反正就是有问题看日志,没问题就不用看。
ELK、Prometheus 我在简历上写过, 但主要是别的同事在搞,我在旁边看着。
老程:
......好,这一轮先到这。
第一轮小结: 你基础 Spring Boot 写得出,Java 基础有点薄, 对 JVM、监控、消息队列的理解偏"demo 级"。
第二轮:微服务 & 高并发推荐 + 缓存 + 搜索
本轮业务场景:
- 需求:为短视频推荐流、搜索服务设计微服务架构;
- 技术栈:Spring Cloud、OpenFeign、Resilience4j、Redis/Ehcache、Elasticsearch、Kafka、Zipkin/Jaeger;
- 目标:考察微服务设计、缓存策略、搜索、链路追踪、熔断限流。
Q6:Spring Cloud 微服务拆分
老程:
假设我们有:
- 用户服务 user-service
- 视频服务 video-service
- 推荐服务 recommend-service
- 搜索服务 search-service
- 统计服务 stat-service
用 Spring Cloud 来做,简要说说你会如何拆分、调用(比如用 OpenFeign)、 以及如何做服务注册发现(Eureka / Consul)?
小Y:
微服务嘛,就是把原来一个项目拆成多个项目, 然后互相调用就行。
我一般就用 Feign 调一下别的接口就好了, 服务注册......现在不都云原生了吗? Kubernetes 会帮我们搞定吧,我觉得就不用管太多。
老程:
Kubernetes 确实能帮一部分,但你至少要知道 Spring Cloud 的基本组件。 回头我给你对比下 Eureka 和 Consul。
Q7:缓存设计:Redis + 本地缓存(Caffeine)
老程:
推荐流接口 QPS 很高,比如首页推荐流。 你会如何用 Redis + Caffeine 做多级缓存? 需要考虑:
- 缓存击穿 / 雪崩 / 穿透;
- 缓存一致性;
- 缓存 Key 设计。
小Y:
缓存我都用 Redis,Caffeine 没用过, 一般就是 set 一个 key,过期时间设长一点, 避免频繁查询数据库。
击穿、雪崩、穿透这些,我记得网上有文章, 反正我会加个 if (cache == null) 就查数据库再 set 回去。
Key 的话就 userId + page 吧,差不多够用。
老程:
行,至少知道会先读缓存再落 DB。 但生产级的设计远比你说的复杂,后面看看答案部分。
Q8:搜索服务:Elasticsearch + REST API
老程:
我们有视频搜索服务,需要支持按标题、标签、 内容描述、作者昵称进行搜索。 你会如何用 Elasticsearch + Spring Boot 实现? 大致讲讲索引结构和查询方式。
小Y:
ES 我了解,就是个"高级版数据库"。 反正就是建个 index,把字段放进去, 查询就用 term、match 那些, Spring Boot 里加个依赖就可以查了。
索引结构我觉得和 MySQL 差不多, 有字段名、有类型就行。
老程:
你说的也没错,但是非常"泛"。 具体 mapping、分词、权重这些你显然没实践过。
Q9:链路追踪与熔断限流(Resilience4j + Zipkin/Jaeger)
老程:
推荐接口调用链较长:
API网关 -> recommend-service -> user-service -> video-service -> stat-service偶尔下游变慢会拖垮整条链路。 你如何使用 Resilience4j 进行熔断、限流、隔离? 以及如何用 Zipkin / Jaeger 做链路追踪?
小Y:
熔断的话,我记得以前是 Hystrix, 现在好像是 Resilience4j, 我还没用过,但知道可以设置个超时时间, 超时就走 fallback。
链路追踪嘛,我简历写用过 Zipkin, 实际上是我同事接的,我主要写业务, 所以我知道有 traceId、spanId, 但细节没太关注。
老程:
至少你没瞎编,也算诚实。 不过我们这边链路追踪是必备项。
Q10:日志规范:Logback + SLF4J
老程:
说一下你在项目中如何统一日志框架? 比如用 SLF4J 统一门面,使用 Logback/Log4j2, 避免日志冲突和性能问题。
小Y:
日志我一般就 lombok 的 @Slf4j, 然后 log.info / log.error 用起来, 具体底层是 Logback 还是 Log4j2, 我就看 Spring Boot 默认啥就用啥。
老程:
......起码你没在一个项目里混用 N 种 Logger, 这点好评。
第三轮:AI + RAG + 智能客服 & 风控
本轮业务场景:
- 需求:为平台搭建"智能客服 + 风控审核 + 企业文档问答"系统;
- 技术栈:Spring AI、RAG(检索增强生成)、向量数据库(Milvus/Redis)、Embedding 模型(OpenAI/Ollama)、Agentic RAG、微服务调用工具框架;
- 目标:考察对 AI 应用工程化的理解,而不是单纯会调 API。
Q11:什么是 RAG?如何用于内容审核辅助
老程:
我们想用 RAG 做"内容审核辅助问答系统", 帮审核员快速查询平台规则, 以及结合历史违规案例给建议。
你先解释一下 RAG(检索增强生成)的基本流程, 再简单说说如何把它接到我们的 Java 微服务体系中?
小Y:
RAG,我听过,就是那种"先检索再生成"的东西, 流程大概就是:
- 先查一下数据库;
- 然后把内容丢给大模型;
- 大模型就给答案。
接到 Java 里,我觉得写个接口, 调用一下 OpenAI 的 API 就好了, 具体怎么检索、怎么分片就到时候看吧。
老程:
你说的是"灵魂版 RAG 概念", 但我们需要更工程化的方案。 最后我会在答案部分给出一个标准流程,你可以好好看看。
Q12:向量数据库与语义检索(Milvus/Redis/Chroma)
老程:
假设我们要把平台的审核规则文档、运营规则、FAQ 等, 存入向量数据库,用于语义检索。 你知道 Milvus 或 Redis 向量索引大概是怎么用的吗? 客户端-服务器架构中,Java 服务如何接入?
小Y:
向量数据库我知道是把文本变成向量, 然后存下来,查的时候算相似度。 Milvus 我没实战过,Redis 我知道有 module 支持向量。
Java 接入的话, 不就是写个 SDK 调一下客户端吗? 具体哪个字段建索引、怎么分片啥的,我还没深入研究。
老程:
至少理解大概概念, 但我们对"向量索引结构、召回性能调优"会有要求, 这块你还比较生疏。
Q13:Spring AI + 工具调用(Tool/Function Calling)
老程:
假设我们用 Spring AI 来封装 LLM 调用, 同时希望模型能调用我们的内部工具:
- 查询用户资料(user-service)
- 拉取订单数据(order-service)
- 查询风控标签(risk-service)
你能描述一个"工具调用框架"的大致设计吗? 比如:如何定义工具、如何标准化调用、如何做权限控制?
小Y:
工具调用我知道, 就是给大模型一个函数列表, 让它选择调用哪个函数。
设计的话,我觉得:
- 写一些接口给模型调用;
- 模型需要哪个就调用哪个;
- 权限的话就在接口里判断一下;
具体怎么规范工具定义、怎么统一输入输出, 我觉得可以到时候多参考一下开源项目......
老程:
你其实是在说"到时候再说"。 不过至少知道 Function Calling 的概念。
Q14:防止 AI 幻觉(Hallucination)
老程:
我们的企业文档问答系统面对的是审核员、客服, 如果 AI 胡说八道(幻觉),会有严重运营风险。 你有什么思路来降低幻觉, 比如:提示设计、RAG 策略、答案校验?
小Y:
幻觉啊,我觉得就是多给点上下文, 然后在 prompt 里告诉它不能瞎编, 让它严格根据文档回答, 实在不行就说"查不到"。
校验的话,可以让人工复审, 或者再调一次模型让它自检。
老程:
思路有一点,但具体工程化措施还有不少差距。
Q15:Agent & Agentic RAG + 复杂工作流
老程:
我们希望未来做一个"多 Agent 协同"的工作流:
- 一个 Agent 负责解析用户意图;
- 一个 Agent 负责调用搜索/向量检索;
- 一个 Agent 负责调用业务服务(订单、风控等);
- 最后一个 Agent 汇总答案。
你如何设计这样一个"Agent 工作流编排系统"? 比如:状态管理、会话内存、错误恢复、监控?
小Y:
这个就有点复杂了, 我目前还没做过这么先进的系统。 我理解就是"多个服务"互相调用, 但具体怎么编排、怎么存状态、怎么监控, 我还没想清楚......
不过我觉得可以参考一下现有的 Agent 框架, 像 LangChain、一些 Java 版本的之类, 然后我们再做二次开发。
老程:
嗯,这个回答比较诚实。 但这也意味着你在 AI 工程化方面还停留在"概念了解"阶段。
三、面试结束
老程整理了一下笔记:
好,今天就先到这。 你有些基础知识还不错, 但在 JVM、微服务治理、监控、AI 工程化这块有明显短板。
我们会综合考虑, 回去等通知吧。
小Y:
好的好的,那我先回去"熟练掌握"一下 JVM 和 Spring Cloud。
老程心里默默补了一句:
也希望你这次是真的去学,而不是只写在简历上。
四、标准答案与详细解析(小白也能看懂)
下面是对上面 15 个问题的详细答案与场景解析,帮助你系统学习。
提示:可以按模块阅读:
- Java 基础 & JVM
- Spring Boot & Web
- 数据库 & ORM & 缓存
- 消息队列 & 微服务
- 监控 & 日志
- 搜索 & 推荐
- AI & RAG & Agent
1. Java 基础 & JVM 调优(对应 Q1)
业务背景:
- 高并发视频上传服务,需要支撑每天千万级上传。
技术要点:
- Java 版本特性(Java 8/11/17);
- 并发编程(线程池、CompletableFuture);
- JVM 参数调优(堆大小、GC、JIT)。
1.1 Java SE 特性应用
- Stream API:用于对集合进行并行处理,例如:统计用户上传行为、过滤违规内容等。
- Optional:避免 NPE,提高代码可读性。
- CompletableFuture :用于异步调用,比如:
- 上传后并行触发转码、截图、内容审核。
示例:
java
CompletableFuture<Void> transcodeFuture = CompletableFuture.runAsync(() -> transcode(video));
CompletableFuture<Void> snapshotFuture = CompletableFuture.runAsync(() -> snapshot(video));
CompletableFuture<Void> auditFuture = CompletableFuture.runAsync(() -> audit(video));
CompletableFuture.allOf(transcodeFuture, snapshotFuture, auditFuture).join();
1.2 JVM 基本调优
- 基础参数:
-Xms/-Xmx:设置堆的初始与最大大小,减少频繁扩容;-Xmn:新生代大小;-XX:+UseG1GC:使用 G1 垃圾收集器,适合大内存低停顿场景。
- 调优手段:
- 结合
jstat、jmap、jstack分析 GC 日志与内存分布; - 使用
-XX:+PrintGCDetails分析 GC 行为; - 避免频繁创建大对象(比如上传时的缓存),复用 buffer。
- 结合
2. Spring Boot 视频上传接口设计(对应 Q2)
业务背景:
- 用户上传视频,需要支持断点续传、分片上传、回调通知。
技术点:
- Spring MVC 文件上传;
- 与对象存储(如 MinIO、OSS)集成;
- 统一返回结构与错误码。
2.1 Controller 基本设计
java
@RestController
@RequestMapping("/api/videos")
public class VideoController {
private final VideoService videoService;
public VideoController(VideoService videoService) {
this.videoService = videoService;
}
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<UploadResultDTO> upload(@RequestPart("file") MultipartFile file,
@RequestParam("title") String title,
@RequestParam("userId") Long userId) {
UploadResultDTO result = videoService.upload(file, title, userId);
return ResponseEntity.ok(result);
}
}
2.2 文件存储策略
- 不要 把大文件存本地磁盘:
- 使用对象存储(OSS、COS、S3、MinIO);
- 数据库只保存 URL 和元数据。
2.3 统一返回结构
java
@Data
public class ApiResponse<T> {
private int code; // 0 成功
private String message;
private T data;
}
3. 数据库 & ORM 设计(对应 Q3)
业务背景:
- 存储视频元数据 + 用户数据 + 审核状态。
技术点:
- 表结构设计;
- JPA / Hibernate / MyBatis 选型;
- 分库分表(视规模而定)。
3.1 视频表结构示例
sql
CREATE TABLE video (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
title VARCHAR(255) NOT NULL,
description TEXT,
duration INT NOT NULL,
cover_url VARCHAR(512),
video_url VARCHAR(512) NOT NULL,
status TINYINT NOT NULL COMMENT '0=上传中,1=转码中,2=审核中,3=已发布,4=审核不通过',
resolution VARCHAR(50),
create_time DATETIME NOT NULL,
update_time DATETIME NOT NULL,
INDEX idx_user (user_id),
INDEX idx_status (status)
);
3.2 ORM 选型建议
- 读多写多 + 复杂 SQL:MyBatis / MyBatis-Plus;
- 简单 CRUD + JPA 风格:Spring Data JPA / Hibernate;
- 高性能读写:考虑 Spring Data JDBC(更轻量)。
4. 异步处理:Kafka / RabbitMQ(对应 Q4)
业务背景:
- 上传视频后,需要进行转码、截图、审核;
- 确保任务可靠、可重试、可扩展。
4.1 为什么用消息队列而不是 new Thread?
- new Thread / 线程池:只能在单机范围内异步;
- 消息队列(Kafka / RabbitMQ):
- 解耦上传服务和处理服务;
- 支持失败重试、消费重平衡;
- 可水平扩展多个消费者实例。
4.2 Kafka vs RabbitMQ 简要对比
- Kafka :
- 擅长高吞吐、日志流、流处理;
- 适合转码任务日志、行为日志、高并发场景。
- RabbitMQ :
- 擅长复杂路由、可靠消息、低延迟;
- 适合订单、支付等需要强一致的消息。
针对视频转码流水线,Kafka 更常用。
5. 日志与监控(ELK、Prometheus、Grafana)(对应 Q5)
业务背景:
- 追踪上传成功率、错误率、延迟,线上快速排查。
5.1 日志埋点
关键日志:
- 上传开始 / 成功 / 失败;
- 转码开始 / 成功 / 失败;
- 每个步骤的耗时。
java
log.info("video_upload_start userId={} fileName={}", userId, file.getOriginalFilename());
long start = System.currentTimeMillis();
// 上传逻辑
long cost = System.currentTimeMillis() - start;
log.info("video_upload_success userId={} videoId={} cost={}ms", userId, videoId, cost);
通过 Logback 输出到文件,再用 Filebeat/Logstash 收集到 Elasticsearch,Kibana 分析。
5.2 指标监控(Micrometer + Prometheus)
- 指标例子:
- 上传成功率:
video_upload_success_total; - 上传失败率:
video_upload_failed_total; - 平均耗时:
video_upload_duration_seconds。
- 上传成功率:
java
Counter uploadSuccess = Counter
.builder("video_upload_success_total")
.register(meterRegistry);
Timer uploadTimer = Timer
.builder("video_upload_duration")
.register(meterRegistry);
Prometheus 抓取指标,Grafana 展示面板 + 告警。
6. 微服务拆分与调用(对应 Q6)
业务背景:
- 多业务域:用户、视频、推荐、搜索、统计;
- 微服务架构,提升可维护性与扩展性。
6.1 服务拆分原则
- 按业务域:User、Video、Recommend、Search、Stat;
- 避免过度拆分("微服务地狱")。
6.2 服务注册与发现
- Spring Cloud Netflix:Eureka;
- 或使用 Consul 作为配置 + 注册中心;
- 在 Kubernetes 中,可以使用 Service + DNS,但依然可结合 Spring Cloud。
6.3 OpenFeign 调用示例
java
@FeignClient(name = "user-service", path = "/api/users")
public interface UserClient {
@GetMapping("/{id}")
UserDTO getUserById(@PathVariable("id") Long id);
}
7. 缓存设计:Redis + Caffeine(对应 Q7)
业务背景:
- 推荐流接口,QPS 极高;
- 需要多级缓存减少数据库压力。
7.1 多级缓存架构
- 本地缓存(Caffeine) :
- 命中率高的热点数据,读写速度快;
- 适合小容量、短 TTL。
- 分布式缓存(Redis) :
- 主存储大部分缓存;
- 提供持久化能力;
- 回源 DB :
- 缓存未命中时才访问。
7.2 缓存击穿 / 雪崩 / 穿透
- 击穿 :热点 key 过期瞬间大量请求打到 DB。
- 方案:
- 加互斥锁(如 Redis 分布式锁);
- 使用"逻辑过期",后台异步刷新。
- 方案:
- 雪崩 :大量 key 同时过期。
- 方案:
- TTL 加随机值,错峰过期;
- 方案:
- 穿透 :查询不存在的数据,导致频繁落 DB。
- 方案:
- 对不存在的数据设置短 TTL 的空值缓存;
- 使用布隆过滤器拦截不存在的 key。
- 方案:
7.3 Key 设计
- 示例:
recommend:feed:{userId}:{page}- 便于精确控制与失效;
- 可结合用户分层(新用户 / 老用户)。
8. 搜索服务:Elasticsearch(对应 Q8)
业务背景:
- 按标题、标签、描述、作者进行搜索。
8.1 索引设计
示例 index:video_index
字段:
title: text + keyword(分词 + 精确匹配);tags: keyword;description: text;authorName: text;publishTime: date;playCount: long(用于排序)。
8.2 查询示例
使用 multi_match 搜索标题 + 描述:
json
{
"query": {
"multi_match": {
"query": "健身 视频",
"fields": ["title^3", "description", "tags"],
"type": "best_fields"
}
},
"sort": [
{"publishTime": "desc"}
]
}
Spring Boot 可用 Spring Data Elasticsearch 进行封装。
9. 链路追踪 & 熔断限流(对应 Q9)
业务背景:
- 链路复杂,某个服务变慢会影响整体;
- 需要熔断、降级、链路追踪。
9.1 Resilience4j 熔断
基本功能:
- 熔断(CircuitBreaker);
- 限流(RateLimiter);
- 隔离(Bulkhead);
- 重试(Retry)。
示例:
java
@CircuitBreaker(name = "recommendService", fallbackMethod = "fallback")
public RecommendResponse getRecommend(Long userId) {
return recommendClient.getRecommend(userId);
}
public RecommendResponse fallback(Long userId, Throwable t) {
// 返回兜底推荐
}
9.2 Zipkin / Jaeger 链路追踪
- 原理:在每个请求中传播 traceId / spanId;
- Spring Cloud Sleuth(或 Micrometer Tracing)集成;
- 前后端统一 traceId,问题排查快速定位。
10. 日志框架统一(对应 Q10)
业务背景:
- 统一日志输出格式,便于 ELK 收集与分析。
10.1 SLF4J + Logback
- 使用 SLF4J 作为统一日志接口;
- 底层使用 Logback;
- 避免引入 log4j、commons-logging 冲突。
logback-spring.xml 中统一制定日志格式:
xml
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n</pattern>
11. RAG 基本流程(对应 Q11)
业务背景:
- 为审核员提供"平台规则问答系统"。
11.1 RAG 流程
- 文档加载(Document Loading)
- 从文档库(PDF、Word、Markdown、Wiki)中加载内容;
- 分片(Chunking)
- 将长文档切成小段(如 512~1024 tokens),保留段落上下文;
- 向量化(Embedding)
- 使用 Embedding 模型(OpenAI、Ollama、本地模型)将每个文档片段转换为向量;
- 存入向量数据库
- 使用 Milvus / Chroma / Redis 向量索引;
- 在线检索(语义检索)
- 接收用户问题 -> 向量化 -> 在向量 DB 中召回相似片段;
- 提示填充(Prompt Filling)
- 将召回片段填入 Prompt(上下文);
- 生成回答
- 调用 LLM(如 OpenAI、企业内部大模型),基于上下文生成回答;
- 后处理 / 审核
- 筛选敏感内容、添加引用来源。
11.2 与 Java 微服务集成
- 使用 Spring Boot + Spring AI:
- 封装 RAG 流程为一个
rag-service:/api/rag/ask:对外提供问答接口;
- 其他服务(如审核后台)通过 OpenFeign / REST 调用;
- 封装 RAG 流程为一个
- 通过 Kubernetes 或 Spring Cloud 部署,统一监控和日志。
12. 向量数据库与语义检索(对应 Q12)
业务背景:
- 存储平台规则、FAQ 文档向量;
- 支持语义检索。
12.1 Milvus / Redis 向量存储
- Milvus :
- 专用向量数据库,支持 HNSW、IVF 等索引;
- 适合大规模向量(千万级以上)。
- Redis 向量索引 :
- Redis Stack 支持 Vector 类型;
- 适合中小规模向量检索。
12.2 Java 接入方式
- 使用官方或社区 Java SDK:
- Milvus Java Client;
- Redis Java 客户端(Lettuce / Jedis)。
- 封装统一的向量存储接口:
java
public interface VectorStore {
void save(String id, float[] vector, Map<String, Object> metadata);
List<SearchResult> search(float[] queryVector, int topK);
}
- 好处:可切换底层实现(Milvus / Redis / Chroma)。
13. Spring AI + 工具调用框架(对应 Q13)
业务背景:
- 智能客服系统需要调用内部服务:
- 用户信息、订单信息、风控信息等。
13.1 工具调用(Function Calling)概念
- 给 LLM 定义一组"工具"函数:
- 例如:
getUserProfile(userId)、getOrderList(userId);
- 例如:
- LLM 根据用户意图选择调用哪个工具;
- 工具执行结果返回给 LLM,作为后续回答的上下文。
13.2 工具调用框架设计
- 工具定义标准化 :
- 定义统一接口:
java
public interface AiTool {
String getName();
String getDescription();
ToolResult invoke(Map<String, Object> params);
}
- 工具注册中心 :
- 使用 Spring 容器自动扫描实现类;
- 权限控制 :
- 根据用户角色 / 会话上下文,控制工具可用范围;
- 调用日志 :
- 记录每次工具调用的输入、输出、耗时;
- 错误处理 :
- 工具调用失败时给 LLM 返回可解释的错误信息。
14. 防止 AI 幻觉(对应 Q14)
业务背景:
- 审核与客服场景容错率低。
14.1 提示设计(Prompt Design)
- 明确指示模型:
- 必须基于提供的文档回答;
- 不得编造平台规则;
- 查不到时必须回答"根据当前文档无法确定"。
示例:
你是平台审核规则助手,只能根据系统提供的文档内容回答问题。 如果文档中没有相关信息,请明确告知"文档中没有相关规定"。
14.2 策略:
- 限制回答长度,防止模型自由发挥太多;
- 增加引用来源:输出中标明参考文档和段落;
- 对敏感问题加入多模型交叉验证;
- 高危问题强制人工复审。
15. Agent & Agentic RAG + 工作流(对应 Q15)
业务背景:
- 构建复杂的多步骤工作流:
- 如"查询用户申诉记录 + 历史订单 + 风控标签 + 生成处理建议"。
15.1 多 Agent 协同设计
- Agent 类型:
- 意图识别 Agent:解析用户问题,确定需要调用哪些工具;
- 检索 Agent:负责文档 / 向量检索;
- 业务 Agent:负责调用订单、风控等服务;
- 汇总 Agent:汇总各 Agent 结果,生成最终响应。
15.2 状态管理 & 会话内存
- 会话状态存储:
- Redis / PostgreSQL / 会话存储服务;
- 记录用户历史问题、工具调用结果;
- 会话内存:
- 通过"摘要 + 向量化"减少上下文长度;
15.3 监控与错误恢复
- 对每个 Agent 的:
- 请求数、失败率、耗时进行监控;
- 工作流执行图:
- 使用链路追踪或可视化工具观察工作流;
- 错误恢复:
- 支持从某一步重新执行;
- 工具调用失败可重试或切换备用 Agent。
五、总结:面试官的建议
- 对 Java 基础:
- 扎实掌握集合、并发、JVM;
- 对微服务:
- 不只会写 Controller,要理解服务拆分、注册发现、熔断限流、链路追踪;
- 对中间件:
- 消息队列(Kafka/RabbitMQ)、缓存(Redis/Caffeine)、搜索(ES);
- 对 AI 工程化:
- RAG、向量数据库、工具调用、Agent 工作流;
如果你现在的水平跟小Y差不多,没有关系, 按照本文的"标准答案"模块,一块块补齐, 下次再去大厂面试,就不只是"会写在简历上",而是真正能落地的工程能力了。