互联网大厂 Java 面试实录:Spring Boot + Kafka + Redis + RAG 的三轮连环追问
场景:某互联网大厂的 Java 岗位面试现场,候选人是号称“做过很多项目”的水货程序员燕双非。面试官表情严肃,问题层层递进,从基础架构、业务落地到云原生与 AI 方案,一路把“会一点”和“懂很多”区分开来。
第一轮:用户增长与内容推荐系统
面试官:我们做的是一个内容社区 App,首页要支持高并发 feed 流。你先说说,为什么这个场景通常会用 Spring Boot,而不是传统的 Spring MVC 配一堆 XML?
燕双非:Spring Boot 启动快,少配点 XML,大家都比较开心,开发效率会高一点。
面试官:回答得还行。那如果首页接口需要按用户维度动态推荐,你会怎么设计缓存和数据库访问?
燕双非:我会先用 Redis 缓存热点用户的推荐结果,数据库层面再用 MyBatis 查一下,不行就再查一遍,应该就差不多了。
面试官:你说到了 Redis 和 MyBatis,但“再查一遍”不是设计。那如果缓存击穿、雪崩同时发生呢?
燕双非:呃……可以加锁、设过期时间随机一点,再做个降级,别让接口一下子全挂了。
面试官:至少知道方向。最后一个问题,这种 feed 流更新如果要做异步通知,你会考虑 Kafka 还是 RabbitMQ,为什么?
燕双非:我会优先 Kafka,因为消息吞吐高,适合用户行为流、埋点和推荐数据同步。RabbitMQ 更像适合一些需要复杂路由、低吞吐但业务控制精细的场景。
面试官:这个判断比较靠谱,继续保持。
第二轮:交易链路与风控校验
面试官:现在切换到电商下单场景。用户提交订单后,要做库存扣减、优惠券校验、支付预创建。你会怎么保证接口的幂等性?
燕双非:可以用订单号做唯一键,再加个 Redis 标记,重复请求直接拦住。
面试官:可以,说明你至少知道幂等入口控制。那如果要把订单写库、扣库存、发 MQ 消息串起来,怎么避免部分成功部分失败?
燕双非:嗯……我觉得可以先都成功再返回,失败就重试,不行就人工处理。
面试官:这回答不太能上线。你再考虑一下事务边界、消息最终一致性和补偿机制。
燕双非:哦,我可能会用本地事务配合消息表,先落库再投递消息,或者用 Outbox 思路保证消息不丢。库存和支付这类链路还要考虑幂等消费、重试和补偿。
面试官:这就像个做过事的人了。那如果支付链路要接 Spring Security + JWT,你怎么设计登录态和 token 刷新?
燕双非:前端拿 access token 调接口,refresh token 放得更安全一些;access token 短一点,过期后通过 refresh token 换新。后端要校验签名、过期时间和黑名单。
面试官:不错。最后一个追问,风控规则如果要实时更新,你会怎么让系统不重启就生效?
燕双非:可以把规则放配置中心或者数据库,配合定时刷新;更实时一点可以接消息通知,规则变更后推送到各个服务实例。
面试官:思路清晰,继续。
第三轮:云原生、AI 与企业级协同
面试官:现在我们做企业协同 SaaS,客户希望接入智能客服和知识问答。你如何把 Spring AI、RAG 和企业文档结合起来?
燕双非:先把文档切块,做向量化,存到向量数据库里。用户提问时先语义检索,再把检索到的内容拼到提示词里,让大模型基于上下文回答。
面试官:不错,你提到了检索增强生成。那如果企业文档经常更新,怎么保证回答不过时?
燕双非:要做增量索引更新,文档加载流程要能识别新增、修改和删除。向量库里的旧内容要及时清理,不然就会答错。
面试官:好。那如果系统接了多个工具,比如查工单、查订单、创建审批单,你如何理解 MCP 或工具调用标准化?
燕双非:我理解它就是把工具能力统一成标准接口,让模型知道什么时候调用什么工具,返回格式也统一,这样扩展起来更方便。
面试官:对,能把“会调用”提升到“可治理”就不错了。最后一个问题,服务端要做高并发长连接通知,比如 WebSocket 推送,你会关注什么?
燕双非:我会关注连接数、心跳、消息堆积、断线重连,还有多实例部署时会不会把消息发错机器。必要时可以结合 Redis Pub/Sub 或 MQ 做消息广播。
面试官:说得不错。今天就到这里吧,你回去等通知。
问题详解
1. 为什么内容社区首页常用 Spring Boot
在内容社区、UGC、推荐流场景中,业务迭代快、接口多、微服务多。Spring Boot 的优势是自动配置、约定优于配置、内嵌容器和成熟生态,可以快速搭建服务并减少样板代码。相比传统 Spring MVC 大量 XML 配置,Boot 更适合快速交付和持续演进。
2. Redis 缓存、MyBatis 与高并发推荐流
推荐结果通常具有明显热点,适合使用 Redis 缓存用户维度数据。数据库层面可用 MyBatis 处理复杂 SQL。实际设计中要考虑缓存击穿、雪崩、穿透:热点 Key 可加互斥锁或逻辑过期;缓存过期时间加随机值;空值缓存或布隆过滤器可减少穿透风险。
3. Kafka 与 RabbitMQ 的选择
Kafka 更适合大吞吐、顺序日志、埋点、行为流和异步解耦;RabbitMQ 更适合复杂路由、延迟任务和业务控制精细的场景。内容社区的行为流、推荐特征更新、日志采集通常更偏 Kafka。
4. 订单幂等、事务与最终一致性
电商下单链路中,用户可能重复点击、网络重试、消息重复投递,因此幂等是核心。常见做法包括业务唯一键、Redis 去重、数据库唯一约束、幂等表。跨服务协作时,不能依赖单体事务,通常采用本地事务 + 消息表、Outbox、可靠消息最终一致性、补偿任务等方案。
5. Spring Security + JWT 的登录态设计
access token 用于短期访问接口,refresh token 用于续期,二者职责不同。access token 过期时间短可降低泄漏风险;refresh token 可放在更安全的位置并支持黑名单失效。服务端要校验签名、过期时间、issuer、audience,并处理踢下线与注销场景。
6. 风控规则动态生效
风控规则不应依赖重启。常见方案是配置中心 + 本地缓存刷新,或者数据库存储规则后通过消息通知各节点更新。更复杂场景可使用规则引擎,支持灰度发布、版本管理和回滚。
7. Spring AI、RAG 与企业文档问答
RAG 的核心是“先检索,再生成”。企业文档先进行加载、清洗、切块、Embedding 向量化,存入向量数据库。查询时进行语义检索,把最相关的内容拼进上下文,再让大模型生成答案。这样可以减少幻觉,提高答案可追溯性。
8. 文档更新与索引维护
企业知识库不是静态的。必须支持增量更新、删除和版本控制,否则检索到旧文档会造成错误回答。实际系统中需要文档同步任务、变更事件、索引重建策略,以及检索结果时间戳或版本控制。
9. MCP 与工具调用标准化
MCP 可以理解为让模型与外部工具之间拥有统一协议。它的价值不只是“能调工具”,更在于可治理、可扩展、可审计。企业里常见的工单、审批、订单、知识库查询,都可以通过标准化工具接口接入 Agent 流程。
10. WebSocket 与实时推送
WebSocket 适合长连接和低延迟通知,但要关注连接管理、心跳保活、断线重连、消息顺序、多实例广播和背压问题。若部署多个实例,通常需要借助 Redis Pub/Sub、Kafka 或网关层做消息分发,避免只推到本机连接。
感谢阅读,希望这篇文章能帮助大家更好地准备 Java 面试,理解真实业务场景中的技术选择与落地方式,祝大家面试顺利,早日拿到心仪 offer。