Java 大厂面试实录:Spring Boot + Kafka + Redis + RAG,从电商下单到智能客服的 3 轮深挖
Java 大厂面试实录:Spring Boot + Kafka + Redis + RAG,从电商下单到智能客服的 3 轮深挖
场景:互联网大厂 Java 求职面试
人物:严肃面试官 & 搞笑水货程序员「燕双非」
第一轮:电商下单链路与高并发基础
面试官:我们先从电商场景开始。你来设计一个“秒杀下单”接口,Spring Boot 和 Spring MVC 负责入口,JPA/MyBatis 负责落库,你会怎么分层?
燕双非:我会先控制器接收请求,然后服务层做业务校验,仓储层或者 Mapper 负责数据库操作。订单表、库存表、流水表分开,避免一个方法写到底,像一锅乱炖。
面试官:回答得还行,至少知道分层。那如果并发很高,库存不能超卖,你会怎么处理?
燕双非:我会先加锁,最好是数据库乐观锁,版本号更新库存。再加 Redis 做库存预扣,成功后发消息到 Kafka 异步创建订单。这样前台快,后台慢慢算。
面试官:不错,已经有点大厂味了。那你说说 Redis 预扣和数据库扣减之间怎么保证一致性?
燕双非:嗯……我一般会……先用事务包起来,然后……如果失败就回滚。Redis 那边可能……做个补偿吧,具体我再想想。
面试官:思路方向是对的,但要说清楚。继续,Kafka 消息如果重复消费了,怎么防重?
燕双非:我会给每条消息一个业务唯一键,比如订单号,消费前先查 Redis 或数据库有没有处理过,有就直接跳过。嗯,像查作业有没有交过。
第二轮:订单履约、支付回调与分布式治理
面试官:订单创建后要进入履约流程,可能会调用物流系统。你会选 Dubbo、OpenFeign 还是 gRPC?为什么?
燕双非:如果是内部 Java 服务,Dubbo 或 OpenFeign 都行。OpenFeign 配合 Spring Cloud 比较顺手,调用像写本地方法;如果要更高性能和强约束,可以考虑 gRPC。
面试官:可以。那支付回调场景下,外部渠道异步通知你的接口,你如何设计幂等?
燕双非:回调接口必须幂等。可以根据支付流水号和状态做唯一约束,重复通知直接返回成功。再配合签名校验、时间戳防重放,避免有人拿着旧请求反复敲门。
面试官:很好。那如果订单服务、库存服务、支付服务之间出现局部失败,你打算怎么做容错?
燕双非:用 Resilience4j 做熔断、限流和隔离,失败时快速降级;关键链路可以用消息队列做最终一致性。比如支付成功后发事件,库存和积分各自订阅处理。
面试官:那消息最终一致性里,你怎么避免“支付成功但库存没减”的问题?
燕双非:这个……可以用补偿任务吧,比如定时扫表,发现支付成功但库存没扣,就补一刀。或者……事务消息?我感觉差不多。
面试官:方向上没错,细节要更严谨。最后一个问题,Spring Cache 适合放在哪里?
燕双非:适合放在商品详情、配置字典、热点店铺信息这种读多写少的数据上。比如首页爆款商品,先查 Caffeine,本地没有再查 Redis,再没有才查数据库,能少打很多次接口。
第三轮:智能客服、RAG 与可观测性
面试官:现在公司要做一个智能客服系统,能回答订单、物流、退款问题,还要能基于企业文档问答。你会怎么设计?
燕双非:我会用 Spring AI 做接入层,前面是聊天会话内存,后面接 RAG。先把企业文档做文档加载、切分、向量化,存到向量数据库,比如 Milvus 或 Redis 向量能力里。用户提问后做语义检索,找相关片段,再把上下文拼给大模型生成回答。
面试官:不错,已经知道链路了。那 Agent 和普通 RAG 的区别是什么?
燕双非:普通 RAG 更像“查资料再回答”,Agent 更像“会自己干活的客服”。它不仅能检索,还能按工具调用标准化去调用订单查询、物流查询、退款申请这些工具,遇到复杂流程还能自己规划步骤。
面试官:很好。那如果模型开始胡说八道,也就是 AI 幻觉,你准备怎么办?
燕双非:我会限制它的回答范围,只允许基于检索到的企业知识和真实工具结果作答;再加置信度阈值、引用来源展示、敏感问题转人工。不能让它一本正经地瞎编。
面试官:这个思路对。最后,系统上线后你怎么监控它的效果?
燕双非:可以用 Micrometer 接 Prometheus 和 Grafana 看接口延迟、错误率、召回率;链路追踪用 Jaeger 或 Zipkin;日志用 Logback 加结构化字段,方便排查用户一句话到底走了哪条链路。
面试官:今天先到这里吧。整体看你有些点答得还可以,但有些地方还需要继续沉淀。你先回去等通知吧。
问题详解:结合电商与智能客服场景深入理解
1. Spring Boot / Spring MVC 分层设计
在秒杀下单场景中,Controller 负责接收请求与参数校验,Service 负责业务编排,Repository/Mapper 负责数据访问。这样做的好处是职责单一、便于测试,也方便将库存扣减、订单创建、优惠券核销拆成独立能力。
2. 超卖控制:乐观锁、Redis 预扣与消息异步化
高并发秒杀不能只靠“先查再改”,否则容易出现并发穿透。常见做法是:
- 数据库乐观锁:通过 version 字段或库存条件更新防止并发写冲突。
- Redis 预扣:先在缓存层扣减库存,快速拦截绝大多数请求。
- Kafka 异步落单:将创建订单、发券、发通知等动作异步化,削峰填谷。
Redis 与数据库之间的一致性通常依赖事务消息、补偿任务、Outbox 模式或基于事件的最终一致性设计,而不是单纯“一个事务全包住”。
3. 消息幂等与防重
Kafka 这类 MQ 默认是至少一次投递语义,重复消费必须被接受并处理。幂等方案包括:
- 业务唯一键 + 数据库唯一约束
- Redis 去重标记
- 消费表记录消息状态
核心原则是:重复执行不会改变最终结果。
4. Dubbo、OpenFeign、gRPC 的选择
内部 Java 微服务常用 OpenFeign 配合 Spring Cloud,开发体验好、与治理能力结合紧密;Dubbo 更偏高性能 RPC 和服务治理;gRPC 基于 HTTP/2 和 Protobuf,适合强类型、跨语言、高性能调用场景。选择时重点看团队栈、性能要求、跨语言需求和生态成熟度。
5. 支付回调的幂等与安全
支付回调通常要做到:签名校验、时间戳校验、防重放、状态机约束、唯一流水号幂等。业务层应确保“已支付”状态只会成功一次,即使回调重复到达,也只返回同样结果。
6. Resilience4j 的容错价值
在订单、库存、支付这种强依赖链路里,任一服务抖动都可能放大故障。Resilience4j 可用于:
- 熔断:连续失败后快速失败,保护下游
- 限流:控制突发流量
- 隔离:避免资源互相拖垮
配合 MQ 可把强耦合流程改造成“事件驱动 + 最终一致性”。
7. Spring Cache、Redis 与 Caffeine 的分层缓存
热点商品详情、店铺信息、系统配置适合做多级缓存:
- Caffeine:本地缓存,延迟低
- Redis:分布式缓存,容量更大
- 数据库:最终数据源
这种设计可以显著减少数据库压力,但要注意缓存穿透、击穿和雪崩问题。
8. RAG 的核心链路
企业文档问答中,RAG 的基本流程是:
- 文档加载:从 PDF、Word、网页、知识库中抽取内容
- 切分:按语义或长度切成 chunk
- 向量化:使用 Embedding 模型将文本转成向量
- 入库:存入 Milvus、Chroma、Redis Vector 等向量数据库
- 检索:根据用户问题做语义检索,找相关 chunk
- 生成:把检索结果与问题一起送给大模型生成答案
这样可以显著降低大模型“凭空编造”的概率。
9. Agent、工具调用与复杂工作流
Agent 不只是回答问题,还能根据目标主动规划步骤并调用工具,例如查询订单、查询物流、发起退款、创建工单。工具调用标准化后,可以让模型输出结构化指令,再由系统执行,增强可控性和扩展能力。
10. AI 幻觉治理
治理思路包括:
- 限制知识来源:只允许基于企业知识库与真实工具结果回答
- 结果引用:展示答案依据
- 置信度控制:低置信度时转人工
- 高风险问题兜底:金融、医疗、法律等场景要额外谨慎
真正可用的企业智能客服,不是“会说”,而是“少胡说、能闭环”。
11. 可观测性与线上稳定性
上线后要通过 Prometheus + Grafana 看指标,用 Jaeger/Zipkin 看链路,用结构化日志定位问题。对 AI 服务来说,还应补充检索命中率、回答采纳率、转人工率、幻觉率等业务指标。
总结
这套面试题从电商秒杀、支付回调、分布式治理,一路延伸到企业智能客服与 RAG/Agent,覆盖了传统 Java 后端和 AI 应用的核心能力。希望这篇文章能帮助大家在面试中更好地理解业务场景与技术实现,少背八股,多讲出真正能落地的方案。
感谢阅读,希望能帮助到大家。
更多推荐




所有评论(0)