Java 面试实战:Spring Boot + Kafka + Redis + Spring Security + RAG 场景下的 3 轮深挖问答
场景:互联网大厂电商与大数据 AI 服务平台,正在招聘 Java 开发工程师。
角色:严肃的面试官,和一位“经验丰富但总差一点”的水货程序员燕双非。
第一轮:订单与库存的基础链路
面试官:先聊一个基础场景。我们现在做一个秒杀商品下单接口,服务端用 Spring Boot,数据库用 MyBatis,缓存用 Redis。你会怎么设计接口流程?
燕双非:这个简单,先查 Redis 有没有库存,有就直接扣减,然后落库,最后返回成功。Spring Boot 写个 Controller 就行,MyBatis 负责 SQL,Redis 负责快。
面试官:思路方向对,先走缓存再落库,确实能减轻数据库压力。那如果 Redis 扣减成功了,数据库更新失败,怎么办?
燕双非:那就……重试一下?不行就补偿一下?反正我们可以加个 try-catch。
面试官:补偿是对的,但你得说清楚补偿链路。比如用消息队列异步补偿,或者通过事务消息、最终一致性来处理。继续说,为什么秒杀场景里会特别强调防重复提交和幂等?
燕双非:因为用户手抖会点很多次,或者网络卡了会重发请求。幂等就是让他点十次也只能成功一次。
面试官:这句话说得还行。那你会用什么方式做幂等?
燕双非:可以用 token,或者订单号唯一索引,或者 Redis setnx。具体看老板喜欢哪个。
第二轮:消息驱动与权限控制
面试官:现在我们把下单链路升级一下。订单创建后要发 Kafka 消息,通知库存服务、积分服务、优惠券服务分别处理。你会怎么保证消息不丢、不重,并且消费者能水平扩展?
燕双非:Kafka 本身挺稳的,应该不会丢吧。消费者多开几个实例,谁抢到算谁的。
面试官:“应该不会丢”不是面试答案。你至少要讲 producer 端 acks、重试、幂等生产者,consumer 端 offset 提交时机,以及业务幂等。那如果库存服务处理很慢,怎么避免把自己压垮?
燕双非:那就限流,或者把线程池调大一点,实在不行让 Kafka 多分几个 partition。
面试官:分区能提升并发,但不是无限加线程。这里还要考虑消费速率、背压、失败重试和死信队列。继续,订单系统涉及用户登录,Spring Security + JWT 你会怎么做权限校验?
燕双非:登录后发一个 JWT,后面请求带着 token 就行。Spring Security 配个过滤器,解析一下用户名和角色,放到上下文里。
面试官:可以,至少主流程对。那 JWT 过期了怎么办?如果要踢下线、黑名单控制、刷新令牌,你怎么设计?
燕双非:这个……可以把 token 存 Redis,过期就删掉。踢下线的话也存 Redis,黑名单也存 Redis。反正 Redis 很万能。
面试官:思路接近实战,但要区分短 token、refresh token、黑名单、设备维度会话管理。不要把所有东西都混成一个 Redis key。下一轮我们讲点更贴近线上故障的。
第三轮:AI 检索、链路追踪与容灾
面试官:我们现在给电商客服接入一个 AI 智能助手,要求支持企业文档问答、订单知识库检索和客服推荐回复。你会怎么结合 Spring AI、RAG、向量数据库来做?
燕双非:就是把文档丢进去做 embedding,存到 Milvus 里。用户问问题时先做语义检索,再把结果塞给大模型,应该就能回答了。Spring AI 负责调用模型,挺方便的。
面试官:方向正确。那如果检索出来的文档有旧版本、答案冲突,或者模型开始胡说八道,怎么控制幻觉?
燕双非:那就多喂点资料,或者提示词写得严格一点。实在不行让模型少说话。
面试官:提示词、检索质量、重排、置信度阈值、答案引用来源,这些都要结合。最后一个问题,线上客服系统调用链很长:Web 层、订单服务、库存服务、AI 服务、消息队列、缓存、数据库。你会怎么做链路追踪和指标监控?
燕双非:可以上 Prometheus 看指标,Grafana 画图,Jaeger 看链路。日志用 SLF4J 配 Logback,出问题就查 traceId。要是还不行,就……重启试试。
面试官:前半段回答不错,后半段有点水,但至少方向清楚。今天先到这,你回去等通知吧。
问题详解:从业务到技术的完整拆解
1. 秒杀下单链路为什么要先查 Redis 再落库?
秒杀场景的核心矛盾是高并发和资源稀缺。Redis 适合做库存预扣,因为它吞吐高、延迟低,能在流量峰值时快速挡住大部分请求。常见做法是:
- 请求先校验参数和登录态;
- 用 Redis 预扣库存,必要时配合 Lua 保证原子性;
- 扣减成功后写入订单表;
- 落库失败时触发补偿逻辑,避免缓存和数据库不一致。
需要注意的是,Redis 只是“前置削峰”,最终仍要回到数据库做真实持久化。
2. 为什么要做幂等?常见幂等方案有哪些?
在网络重试、用户重复点击、消息重复投递等情况下,同一业务请求可能被执行多次。幂等的目标是“同一个业务动作,无论执行多少次,结果都一样”。
常见方案包括:
- 唯一业务键 + 数据库唯一索引:例如订单号唯一,重复写入直接失败;
- Redis setnx/token:先拿到一次性令牌才允许提交;
- 状态机控制:例如订单只能从待支付流转到已支付一次;
- 消息消费幂等:消费记录表、去重表、业务唯一约束等。
在电商系统里,幂等通常要覆盖接口层、消息层和任务层。
3. Kafka 在订单链路中如何保证“尽量不丢、不重”?
Kafka 是电商异步解耦的常见选择。设计时要同时关注生产者、Broker 和消费者三端:
- 生产者端:开启幂等生产者,合理设置 acks,必要时做重试;
- Broker 端:分区数决定并发度,副本决定可靠性;
- 消费者端:处理成功后再提交 offset,失败时重试或进入死信队列;
- 业务层:无论消息是否重复,都要保证业务幂等。
注意:Kafka 能降低丢消息概率,但“绝对不丢”通常意味着要结合事务、补偿和业务容错一起设计。
4. Spring Security + JWT 在大厂项目里怎么落地?
典型流程是:
- 用户登录成功后签发 JWT;
- 客户端在后续请求中携带 JWT;
- 服务端过滤器解析 JWT,构造认证对象,写入 SecurityContext;
- 基于角色、权限或资源标识做鉴权。
进一步完善时,常会加入:
- Access Token + Refresh Token 双令牌机制;
- Redis 会话管理,用于踢下线、设备管理、黑名单控制;
- 过期与刷新策略,避免长期 token 泄露带来的风险。
在高安全场景下,还会结合设备指纹、异地登录告警、风控规则等能力。
5. RAG 为什么比“直接问大模型”更适合企业客服?
企业客服问答的关键是准确性和可追溯性。直接问大模型容易出现幻觉,尤其在订单政策、售后规则、促销说明这类强业务约束场景里风险很大。RAG 的核心思路是:
- 先把企业文档、FAQ、知识库切分并做向量化;
- 用户提问后先做语义检索;
- 将召回内容作为上下文交给大模型生成答案;
- 必要时附带引用来源、文档版本和置信度。
这样能显著降低幻觉,同时让答案更贴近企业真实规则。
6. 如何提升 RAG 的效果并控制幻觉?
实战中通常从以下几个方向优化:
- 文档清洗与切分:按语义段落切块,避免碎片化;
- Embedding 模型选择:让向量更贴近业务语义;
- 向量库召回:Milvus、Chroma、Redis Vector 等;
- 重排模型:对初筛结果做精排,提高相关性;
- 提示词约束:要求模型仅基于检索内容回答;
- 答案引用:输出来源,增强可解释性;
- 兜底策略:检索不到时明确说“不知道”,而不是瞎编。
企业客服里,“少答错”往往比“答得像”更重要。
7. Prometheus、Grafana、Jaeger、日志系统分别解决什么问题?
当系统拆成 Web、订单、库存、AI、消息队列多个服务后,排障必须依赖可观测性体系:
- Prometheus:采集指标,例如 QPS、错误率、延迟、队列堆积;
- Grafana:把指标做成看板,便于观察趋势;
- Jaeger/Zipkin:链路追踪,定位一次请求经过了哪些服务;
- SLF4J + Logback/Log4j2:记录业务日志,结合 traceId 串联请求上下文。
线上排障时,一般是“指标发现异常、链路定位位置、日志看具体原因”三步配合。
8. 这个场景里为什么要让“燕双非”式回答也能成立一半?
因为很多面试并不是背概念,而是看候选人能否把基础知识和业务串起来。像“Redis 先挡流量”“JWT 放在请求头”“Prometheus 看指标”这些回答,说明候选人有基本经验;而“补偿、幂等、重试、链路追踪、幻觉控制”这些内容,则体现出候选人是否经历过真实线上环境。
真正的大厂面试,往往不是要你一句话背出标准答案,而是希望你能沿着业务链路把系统讲清楚。
感谢阅读,希望这篇文章能帮助你在 Java 面试中更有思路,也希望你能把这些知识真正用到项目里,顺利拿到心仪的 offer。

81

被折叠的 条评论
为什么被折叠?



