大厂Java面试实战:Spring Boot + Redis + Kafka + Kubernetes + RAG 的三轮追问(附答案解析)

大厂Java面试实战:Spring Boot + Redis + Kafka + Kubernetes + RAG 的三轮追问(附答案解析)

角色设定

  • 面试官(M):语气平稳、追问精准、不给水分。
  • 小Y(Y):自称"全栈架构师",简单题能答,复杂题开始"灵魂出窍"。

业务背景

一家内容社区(UGC)正在做两件事:

  1. 发帖/评论高并发,要求热点内容"秒开"。
  2. 上线一个**企业文档问答(RAG)**的智能客服,要求可观测、可扩展、可降级。

第一轮:单体到服务化的基础功(4题)

Q1:Spring Boot 项目里,为什么一般不用 new 创建服务对象,而是交给容器?

M: 解释下 Spring IoC/DI 对可测试性和解耦的价值。

Y: 因为......@Autowired 比较方便,new 了它可能就不生效。

M: 方向对了。再补一句:为什么对测试有帮助?

Y: 呃......能 mock?

M: 可以。


Q2:UGC 发帖接口做成 REST,你会怎么设计幂等?

M: 说说幂等键、数据库唯一约束、以及在分布式下如何避免重复发帖。

Y: 我会加个 token......放 Redis 里,来一次删一次。

M: 还可以。但如果 Redis 抖了呢?

Y: 那就......重试?

M: 好,我们后面再聊。


Q3:数据库连接池你选 HikariCP 的理由?以及常见参数怎么定?

Y: 因为快。

M: 快是结果,原因是什么?比如实现机制、线程模型?

Y: 它......算法很先进。

M:(沉默两秒)继续。


Q4:你如何用 Flyway/Liquibase 管理线上表结构变更?

Y: 我一般直接在 Navicat 上改,然后同步一下。

M:(眼神更严肃)


第二轮:缓存、消息、微服务链路(4题)

Q5:热点帖子详情页"秒开",你会怎么用 Redis?

M: 说出缓存模式、TTL、穿透/击穿/雪崩的治理,以及与本地缓存 Caffeine 的组合。

Y: 我就 get,没有就查数据库,再 set

M: 这是最基础。那击穿怎么防?

Y: 加锁?比如 synchronized

M:(点头)至少知道"锁"。


Q6:评论异步审核与通知,用 Kafka 还是 RabbitMQ?

M: 从吞吐、顺序、消费语义、延迟、消息堆积与回溯说。

Y: Kafka 吞吐高,RabbitMQ 更可靠。

M: "更可靠"怎么定义?ACK、重试、死信?

Y: 就是......它比较传统。


Q7:微服务调用用 OpenFeign,如何做超时、重试、熔断与降级?

M: 说说 Resilience4j 和 Spring Cloud 的组合,别只会配置。

Y: 我会把 timeout 配大一点。

M:(轻叹)那我们继续。


Q8:链路追踪你怎么做?Jaeger/Zipkin/Micrometer/Prometheus 在体系里各干什么?

Y: Prometheus 就是看 CPU;Jaeger 就是看调用。

M:(语气缓和一点)至少你没把它们和 ELK 搞混。


第三轮:云原生 + AI RAG 的综合追问(4题)

Q9:服务上 Kubernetes 后,健康检查怎么设计?

M: readiness/liveness 的差异?Spring Boot Actuator 怎么配?

Y: 就写个 /health,返回 200。

M: 如果依赖的数据库挂了,readiness 应该怎样?

Y: 也 200......不然用户访问不到。

M:(摇头)


Q10:你们要做"企业文档问答(RAG)",从上传文档到问答,你的技术链路怎么设计?

M: 讲清:文档加载、切分、向量化(embedding)、向量库(Milvus/Chroma/Redis)、检索、提示填充、回答生成,以及如何减少幻觉。

Y: 就把文档丢给大模型,它就会回答。

M:(非常平静)那是"祈祷式架构"。


Q11:RAG 系统如何做会话内存与权限控制?

M: 聊天会话内存放哪里?如何隔离租户?如何用 Spring Security/OAuth2/JWT?

Y: JWT 就是加密的 token,放啥都行。

M: JWT 不是"想放啥就放啥"。


Q12:RAG+工具调用(Agent)落地:如何把"查订单/开工单/查物流"变成工具执行框架?

M: 讲讲 MCP/工具调用标准化、幂等、审计、以及失败重试。

Y: 让模型自己请求接口就行......

M:(收起简历)好的,今天先到这。


面试结束

M: 你回去等通知吧。如果后续进入下一轮,我们会让你补一份"RAG 方案设计 + 缓存一致性"的文档。

Y: 好的好的,我回去就"深入研究一下"。


答案解析(把小Y含糊的地方一次讲清)

下面按题号给出可直接背诵+可落地的解释,结合"内容社区 + 智能客服RAG"的业务。

A1:为什么交给 Spring 容器(IoC/DI)而不是 new

  • 解耦:依赖以接口形式注入(DI),调用方不关心实现类创建细节,方便替换实现(例如本地实现→远程实现)。
  • 生命周期与横切能力:容器能统一管理单例/原型、初始化/销毁,并织入 AOP(事务、鉴权、日志、监控)。
  • 可测试性
    • 单元测试可用 Mockito 替换依赖:@Mock + @InjectMocks 或 Spring Test 的 @MockBean
    • 依赖可配置(profile),测试环境可换 H2、Testcontainers。

A2:发帖接口幂等设计(防重复提交)

业务:用户网络抖动、App 重试、网关重放都可能导致重复发帖

可组合方案:

  1. 幂等键(Idempotency-Key):客户端生成 UUID,放 Header;服务端记录 key→结果。
  2. Redis 去重 (快路径):
    • SET key value NX EX 60 成功才处理;失败直接返回"重复提交"。
    • 注意:需返回同一幂等键对应的相同结果(可把创建的 postId 缓存起来)。
  3. 数据库兜底唯一约束 (最终一致的防线):
    • 例如 unique(user_id, client_token) 或业务唯一号。
    • 即使 Redis 故障也能靠 DB 防重复。
  4. 分布式下的失败处理
    • 处理超时要能查到"是否已成功落库"。
    • 对外返回可用"查询创建结果"的接口。

A3:HikariCP 为什么快、参数怎么定

  • 快的原因(工程化点)
    • 更少的锁竞争与对象创建;连接获取路径短。
    • 连接检测策略更高效(避免频繁 test query)。
  • 关键参数 (经验值需压测校准):
    • maximumPoolSize:常见按 CPU核数DB承载 综合定;不要盲目大。
    • minimumIdle:稳定流量可设为接近 max;波动大可偏小。
    • connectionTimeout:获取连接超时(如 300ms~2s),用于快速失败。
    • idleTimeout/maxLifetime:避免连接被 LB/防火墙断开(maxLifetime 通常 < DB 连接回收时间)。

A4:Flyway/Liquibase 做表结构版本化

业务:多人协作、灰度发布、回滚审计。

  • 核心思想:把 DDL 变更当作代码提交(Git),由流水线自动执行。
  • Flyway:以 版本号脚本 为主(V1__init.sql)。
  • Liquibase:支持 XML/YAML/SQL,适合更复杂的变更描述与回滚。
  • 最佳实践
    • 禁止手工直改生产;所有变更必须可追溯。
    • 脚本向前兼容(先加字段再读写切换,再删字段)。

A5:Redis 缓存热点内容:模式与三大问题治理

业务:帖子详情、作者信息、评论数。

  1. 缓存模式
    • Cache-Aside(旁路缓存):读:先缓存后 DB;写:先 DB 再删除/更新缓存。
  2. TTL :热点长 TTL + 随机抖动(ttl + rand(0..N))防雪崩。
  3. 穿透(查不存在):布隆过滤器 / 缓存空值(短 TTL)/ 参数校验。
  4. 击穿 (热点 key 过期瞬间):
    • 互斥锁(Redis 分布式锁)/ singleflight;只让一个线程回源 DB。
  5. 雪崩 (大量同时过期或 Redis 故障):
    • TTL 打散、分批预热、降级(返回兜底页/旧数据)。
  6. 本地缓存 Caffeine + Redis
    • Caffeine 抗极致热点;Redis 做跨实例共享。
    • 注意一致性:可用消息通知或短 TTL。

A6:Kafka vs RabbitMQ(评论审核与通知)

  • Kafka
    • 优势:高吞吐、可回溯(按 offset 重放)、适合日志/行为流/事件总线。
    • 关注:顺序性在分区内;消费语义通常是至少一次(配合幂等)。
  • RabbitMQ
    • 优势:低延迟、路由灵活(topic/direct/fanout)、ACK/死信队列更易用。
    • 适合:业务命令型消息、需要复杂路由与延迟队列场景。
  • 落地建议(本场景)
    • 审核流水、行为流:Kafka。
    • 站内信/短信/邮件触达:RabbitMQ 或 Kafka+专用消费者均可。

A7:OpenFeign + Resilience4j:超时、重试、熔断、降级

业务:评论服务调用用户服务、风控服务。

  • 超时:连接超时 + 读超时要合理(例如 200ms~1s);不要"配大点"。
  • 重试 :只对幂等请求重试(GET/查询);写操作要用幂等键。
  • 熔断:下游错误率高时打开熔断,保护线程池与自身可用性。
  • 隔离:Bulkhead(舱壁)限制并发,避免某下游拖死全部。
  • 降级:返回兜底数据(例如用户昵称"匿名用户"),并打点报警。

A8:可观测体系:Micrometer/Prometheus/Grafana/ELK/Jaeger

  • Micrometer:应用侧指标门面(埋点、Timer、Counter)。
  • Prometheus:拉取并存储时序指标(QPS、P99、线程池、GC)。
  • Grafana:指标可视化与告警。
  • ELK:日志采集检索(排查错误堆栈、业务日志)。
  • Jaeger/Zipkin:分布式追踪(traceId/spanId),定位慢点在谁。

A9:Kubernetes 健康检查:readiness vs liveness

  • livenessProbe:进程是否"活着"。失败会重启 Pod。
  • readinessProbe:是否"可接流量"。失败会从 Service Endpoints 摘除。
  • 正确做法
    • DB/Redis 不可用时:readiness 失败(不接新流量),但 liveness 不一定失败(避免无意义重启风暴)。
    • Spring Boot Actuator:暴露 /actuator/health/liveness/actuator/health/readiness

A10:企业文档问答 RAG 全链路设计

业务:企业内部 SOP、产品手册、工单知识库。

  1. 文档加载(Document Loader):PDF/Word/网页/Confluence 等。
  2. 切分(Chunking):按标题/段落/Token 切块,保留元数据(来源、权限、时间)。
  3. 向量化(Embedding):选 embedding 模型(OpenAI/Ollama),把 chunk→向量。
  4. 向量数据库:Milvus/Chroma/Redis Vector,存向量+metadata。
  5. 检索:语义检索(TopK)+ 关键词 BM25(可选混合检索)。
  6. 提示填充(Prompt):把检索到的片段作为 context,拼装系统提示与约束。
  7. 生成回答:LLM 输出,并要求引用来源。
  8. 降低幻觉
    • 只允许基于检索片段回答;无依据时输出"未找到"。
    • 输出带引用;增加事实核验(自检/多路检索)。

A11:会话内存与权限控制(多租户)

  • 会话内存
    • 短期:Redis(conversationId→messages/summary),设置 TTL。
    • 长期:MySQL/ES(可检索)或对象存储(审计)。
  • 权限控制
    • Spring Security + OAuth2/OIDC(Keycloak)统一登录。
    • JWT 放的是"声明(claims)",不是加密保险箱;敏感信息不放 JWT。
    • 文档检索要做租户隔离:metadata 带 tenantId、docACL,检索过滤。

A12:Agent + 工具调用(MCP/标准化)如何落地

业务:客服问"订单到哪了""给我开工单"。

  • 工具执行框架
    • 定义工具 schema(name/params/权限/幂等等),模型只负责"选择工具+填参"。
    • 服务端负责鉴权、参数校验、限流、审计。
  • MCP/工具调用标准化
    • 把外部系统能力(订单、物流、工单)以标准接口暴露,便于扩展。
  • 幂等与审计
    • 写操作必须有幂等键;所有工具调用落库记录(谁、何时、做了什么)。
  • 失败处理
    • 重试只用于幂等工具;非幂等需要补偿/人工确认。

小结:如果你要把这场面试"答满分"

  • UGC:缓存一致性 + MQ 解耦 + 可观测。
  • 云原生:K8s 探针与限流熔断。
  • AI:RAG 不是"把文档丢给模型",而是一条工程链路;权限与审计必须先行。
相关推荐
wuxuanok1 小时前
Maven 编译报错:java.lang.NoSuchFieldError: JCImport 问题总结
java·开发语言·maven
薛定谔的猫19821 小时前
gradio学习代码部分
java·前端·javascript
阿丰资源1 小时前
基于SpringBoot+MySQL+Maven+Vue的旅游网站的设计与实现(源码+数据库+文档一键运行)
数据库·spring boot·mysql
酉鬼女又兒1 小时前
Leetcode 26.删除有序数组中的重复项 双指针巧解有序数组去重:从快慢指针到原地修改算法的精髓
java·数据结构·算法·leetcode·职场和发展·蓝桥杯·排序算法
ch.ju1 小时前
Java程序设计(第3版)第二章——循环结构4
java
字节高级特工2 小时前
迈入Redis:持久化
数据库·redis·缓存
knight_9___2 小时前
RAG面试篇11
java·面试·职场和发展·agent·rag·智能体
念越2 小时前
Java 文件操作与IO流详解(File类 + 字节流 + 字符流全总结)
java·开发语言·io
绿草在线2 小时前
SpringBoot请求与响应全解析
spring boot·后端·lua