《Spring Boot + Kafka + Redis + MyBatis + Kubernetes + RAG:互联网大厂Java面试三轮连环问(含答案详解)》

角色设定

  • 面试官(M):语气严肃、追问到位。
  • 小Y(Y):自称“全栈架构师”,简单题能答,复杂题开始“凭感觉”。

业务背景(贯穿三轮)

你要面试的岗位负责一个内容社区与UGC平台

  • 用户发帖/发视频(UGC),需要上传、转码、审核、推荐
  • 平台引入 AIGC:用户可用 AI 生成文案/封面;平台也用 AI 做内容审核与问答客服
  • 系统为微服务架构:内容服务、审核服务、推荐服务、搜索服务、用户服务等。

第一轮:从“能跑起来”到“跑得稳”(Java/JVM + Spring Boot + Web)

Q1:你用 Spring Boot 做内容发布接口 /posts,如何设计参数校验、异常处理与统一返回?

M: 说说你会怎么做,别光说“加个注解”。

Y: 这个简单!我一般就 @RestController 然后 @Valid,不行就 try-catch 一把梭……统一返回我就 new Result()

M: @Valid 和全局异常处理能说具体点吗?

Y: 嗯……大概就是 @ControllerAdvice,然后把异常转成 JSON……

M: 还行。下一题。


Q2:Spring MVC 与 Spring WebFlux 的差异?什么场景下你会选 WebFlux?

M: 你们视频上传、转码回调、审核回调很多,怎么选?

Y: WebFlux 就是更快,因为是响应式嘛……适合高并发。

M: “更快”不严谨。你说下线程模型?背压?

Y: 线程模型……嗯……反正不是一个请求一个线程。背压就是……别把人压死?

M: ……


Q3:JVM 内存结构、GC 选择与线上 OOM 排查思路(Java 8/11/17)

M: 内容服务发布高峰期 OOM,怎么定位?你在 Java 8 和 17 的选择上有什么差异?

Y: JVM 内存就是堆、栈、方法区。OOM 就加内存……或者重启。GC 我一般用默认的。

M: 你至少要说出:堆 dump、MAT、GC 日志、以及常见 OOM 类型。

Y: 对对对,可以 dump 一下……然后用个工具看看。

M: 好,进入第二轮。


第二轮:从“单体CRUD”到“微服务链路”(DB/ORM + MQ + Cache + Resilience)

Q1:内容发布如何做到“写库 + 发审核消息”一致?(MyBatis/JPA + Kafka/RabbitMQ + 事务)

M: 你写入帖子表成功了,但 Kafka 消息没发出去,审核服务收不到怎么办?

Y: 这个我懂!加事务!数据库事务和 Kafka 事务一起提交。

M: 你确定你们 Kafka 和数据库能一个事务?

Y: 嗯……应该可以吧?要不就 try-catch 重试。

M: ……


Q2:Redis 在内容社区里怎么用?缓存穿透、击穿、雪崩怎么处理?(Redis + Caffeine + Spring Cache)

M: 帖子详情 /posts/{id},热点帖子访问量暴涨,你怎么做缓存?

Y: Redis 缓存一下就行,key 用 post:id。穿透就……加个布隆过滤器?击穿就加锁,雪崩就随机过期时间。

M: 这题答得不错。那你会用 Caffeine 吗?

Y: 会!就是本地缓存,更快。我一般 Redis + Caffeine 双写。

M: 双写一致性怎么保证?

Y: 这个……靠缘分。


Q3:微服务治理:OpenFeign + Resilience4j + 熔断限流

M: 审核服务慢了,内容发布接口被拖死,你怎么做超时、重试、熔断、隔离?

Y: Feign 配个超时,再重试几次。熔断就让它别调了。

M: 你讲下 Resilience4j 的 Bulkhead、CircuitBreaker、RateLimiter 在你业务里的组合?

Y: Bulkhead……是船舱隔离?我觉得都差不多,配置下就行。

M: ……继续。


Q4:数据库连接池与迁移:HikariCP + Flyway/Liquibase

M: 你们高峰期数据库连接暴涨,怎么设置 HikariCP?表结构迭代怎么控制?

Y: 连接池就调大点。迁移就……手工执行 SQL?

M: 好,第三轮。


第三轮:从“能用”到“可观测 + AI 落地”(K8s/监控/链路追踪 + RAG/Agent)

Q1:Kubernetes 部署内容服务:滚动发布、就绪探针、资源限制怎么配?

M: 新版本发布后错误率升高,如何快速回滚?

Y: K8s 我会用,直接 kubectl apply。回滚就再 apply 回去。

M: 探针、HPA、requests/limits 的意义?

Y: 探针就是探活;HPA 就自动扩容;limits 就限制一下别太浪。

M: 勉强过。


Q2:可观测:Micrometer + Prometheus/Grafana + ELK + Jaeger/Zipkin

M: 线上接口慢,你怎么在 10 分钟内定位是 DB 慢、下游慢还是 GC 抖动?

Y: 我会看日志,ELK 搜一下。然后……再看看 Grafana。

M: 链路追踪怎么串起来?traceId 怎么传?

Y: 这个我记得 Spring Cloud 会自动带……

M: ……


Q3:AI:用 Spring AI 做“企业文档问答客服”(RAG + 向量库 Milvus/Chroma/Redis)

M: 你们社区要做客服机器人:回答“帖子被下架原因”“申诉流程”。怎么用 RAG 降低幻觉?

Y: 这个我最近在看!RAG 就是把文档丢给模型。向量库就……存向量。幻觉就提示它别瞎说。

M: 你能说出:文档加载、切分、Embedding、语义检索、提示填充、引用来源、以及会话记忆怎么做吗?

Y: 嗯……大概就是先向量化,再搜,再拼 prompt。会话记忆……就是把聊天记录存起来。

M: 好,最后一个问题。


Q4:Agent(智能代理)+ 工具调用:让客服机器人能“查订单/查申诉状态”

M: 用户问“我昨天申诉的帖子审核到哪一步了?”机器人需要调用内部接口。你如何设计工具执行框架、防止越权与提示注入?

Y: Agent 就是让模型自己决定调哪个接口。越权的话……加鉴权。提示注入就……别让它注入?

M: 行。今天先到这。


面试收尾

M: 你基础还行,但在一致性、可观测、以及 AI 工程化落地上需要更系统的方法。我们后续会综合评估,你先回去等通知,有结果 HR 会联系你。


题目答案详解(按三轮顺序,含业务场景与技术点)

目标:让小白也能把“为什么这么做、怎么落地、常见坑”学下来。

第一轮答案详解

1)Spring Boot 接口:校验、异常、统一返回

业务场景:内容发布 /posts 入参包含 title、content、mediaUrls、categoryId,需要校验长度/非空/格式;错误要统一给前端。

推荐做法

  • DTO + Bean Validation:@NotBlank @Size @Pattern,控制器参数 @Valid@Validated
  • 全局异常:@RestControllerAdvice + @ExceptionHandler 处理:
    • MethodArgumentNotValidException(Body 校验失败)
    • ConstraintViolationException(Query/Path 校验失败)
    • 业务异常(自定义 BizException
  • 统一返回结构:code/message/data/traceId
  • 日志:在异常处理器里记录必要上下文,避免吞异常。

关键点:不要在 controller 里 try-catch 到处写;用全局异常更可维护。


2)Spring MVC vs WebFlux:什么时候用 WebFlux

业务场景

  • 视频上传后会有转码回调、审核回调;同时还要调用对象存储、审核服务等外部 IO。

差异核心

  • Spring MVC:Servlet 模型,典型“一个请求一个线程”,适合传统同步阻塞 IO(JDBC)。
  • Spring WebFlux:基于 Reactor 的响应式,事件循环/少量线程处理大量连接,适合高并发 + 大量非阻塞 IO(如 WebClient、R2DBC、响应式 Redis)。
  • 背压(Backpressure):下游处理不过来时,上游能减速,避免内存堆积(响应式流规范的一部分)。

选型建议

  • 如果核心链路强依赖阻塞 JDBC(MyBatis/JPA),盲上 WebFlux 可能得不偿失。
  • WebFlux 更适合网关、聚合层、长连接(SSE/WebSocket)、大量外部 HTTP 调用。

3)JVM/GC 与 OOM 排查

业务场景:内容发布高峰 OOM,可能来自:

  • 大对象(图片/视频元数据)驻留
  • 缓存误用(本地缓存无限增长)
  • 线程池任务堆积

定位步骤

  1. 先确认 OOM 类型:Java heap space / Metaspace / unable to create new native thread
  2. 开启关键参数:
    • -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=...
    • GC 日志(Java 11+ 用 -Xlog:gc*
  3. 用 MAT/VisualVM 分析 dump:看 dominator tree、泄漏嫌疑。
  4. 看 GC 日志判断:频繁 Full GC?晋升失败?

Java 8 vs 17

  • Java 8 默认 Parallel/(常见配置 CMS);Java 17 常用 G1/ZGC 等更现代的收集器选择(以具体版本与需求定)。

第二轮答案详解

1)写库 + 发 MQ 一致性:Outbox/事务消息/最终一致

业务场景:发布帖子后必须触发“审核任务”。若 DB 成功但 MQ 失败,会漏审。

常见正确方案(二选一/组合):

  • Outbox Pattern(强烈推荐):
    1. 本地事务:写 posts + 写 outbox_event(待发送事件表)
    2. 异步投递器轮询 outbox 表,发送 Kafka
    3. 发送成功后标记已发送
    • 优点:不依赖分布式事务;可重试;可审计
  • Kafka 事务:只能保证 Kafka 内部事务一致,不等于与数据库跨资源一致。
  • 最终一致:消费者幂等(用业务唯一键去重),配合重试与死信队列。

关键点

  • 不要幻想“数据库事务 + MQ 事务”天然原子。
  • 必须考虑幂等(审核消息重复投递)和补偿(漏发补发)。

2)Redis 缓存与三大问题

业务场景:帖子详情热点访问。

  • 缓存穿透(查不存在的 id):
    • 布隆过滤器(RedisBloom/自建)
    • 缓存空值(短 TTL)
  • 缓存击穿(热点 key 过期瞬间大量打 DB):
    • 互斥锁/单飞(Redis 分布式锁或本地锁)
    • 逻辑过期(后台刷新)
  • 缓存雪崩(大量 key 同时过期):
    • TTL 随机化
    • 分批预热

Redis + Caffeine 两级缓存

  • Caffeine:极低延迟,适合单机热点。
  • Redis:跨实例共享。

一致性建议

  • 以 DB 为准:更新 DB 后删缓存(cache-aside),而不是双写。
  • 删缓存失败要重试;可用 MQ 异步删。

3)Feign + Resilience4j:超时、重试、熔断、隔离

业务场景:审核服务慢导致发布接口线程耗尽。

组合建议

  • Timeout:严格控制(例如 200~500ms,按业务)
  • Retry:只对幂等请求重试;设置最大次数 + 指数退避
  • CircuitBreaker:失败率/慢调用比例触发熔断,快速失败保护系统
  • Bulkhead(舱壁隔离):限制并发/线程池隔离,防止下游拖垮上游
  • RateLimiter:保护自身或下游(例如审核服务限流)

关键点

  • “重试”会放大流量,熔断打开时应禁止重试。
  • 对外部依赖要做隔离,否则会发生级联故障。

4)HikariCP 与数据库迁移

连接池要点

  • HikariCP 常用参数:
    • maximumPoolSize:别盲目调大,受 DB max_connections 与 SQL 耗时影响
    • minimumIdle:维持一定空闲
    • connectionTimeout:拿不到连接的等待时间,避免线程挂死
  • 性能排查:慢 SQL、索引、事务范围、连接泄漏(leakDetectionThreshold)。

表结构迁移

  • Flyway/Liquibase 管版本化 SQL:
    • 每次上线带 migration 脚本
    • CI/CD 执行,避免“手工 SQL 漏执行”

第三轮答案详解

1)K8s:滚动发布、探针、回滚

业务场景:内容服务灰度发布。

  • RollingUpdate:逐步替换 Pod。
  • Probes:
    • readinessProbe:就绪才接流量(避免冷启动接请求)
    • livenessProbe:死了重启
  • 资源:requests/limits 防止抢占;配合 HPA 按 CPU/自定义指标扩缩。
  • 回滚:kubectl rollout undo deployment/... 或 Helm rollback。

2)可观测体系:指标 + 日志 + 链路

10 分钟定位慢的套路:

  1. 指标(Metrics):Micrometer 暴露 QPS、延迟、线程池、JVM GC;Prometheus 抓取;Grafana 看趋势。
  2. 日志(Logs):Logback/Log4j2 + JSON 格式;ELK 检索错误堆栈与关键字段。
  3. 链路(Tracing):Jaeger/Zipkin 还原一次请求各 span 耗时;
    • traceId/spanId 通过 HTTP header 传播(如 W3C traceparent)

关键点:只有日志不够;链路能告诉你“慢在谁”。


3)Spring AI 落地 RAG:降低幻觉

业务场景:客服回答下架原因/申诉流程,必须可追溯。

RAG 流程

  1. 文档加载(PDF/网页/内部知识库)
  2. 文档切分(chunk)+ 去噪
  3. Embedding 向量化(OpenAI/Ollama 等)
  4. 写入向量库(Milvus/Chroma/Redis Vector)
  5. 查询时:语义检索 topK + 过滤(权限/时间/标签)
  6. 提示填充:把检索到的片段作为“上下文”喂给模型
  7. 输出时:要求引用来源(chunk id/文档链接)

降低幻觉

  • 只允许基于检索内容回答;无依据就输出“不确定/请人工”。
  • 输出附带引用;设置温度参数;对敏感问题走规则兜底。

4)Agent + 工具调用:可控地“让模型调接口”

业务场景:机器人查“申诉状态”,需要调用内部 appeal-service

设计要点

  • 工具标准化:定义 tool schema(入参、出参、超时、错误码)。
  • 鉴权:工具调用必须带用户身份(JWT/OAuth2),后端二次鉴权。
  • 防提示注入:
    • 工具参数做白名单校验
    • 不让模型直接拼 SQL/URL
    • 对外部内容(用户输入/文档)进行隔离与清洗
  • 审计与回放:记录每次 tool 调用的输入输出与 traceId。

文章小结

这场面试用“内容社区 + UGC + AIGC 审核/客服”的真实链路,把 Java 基础、微服务一致性、缓存与消息、可观测、K8s 以及 Spring AI 的 RAG/Agent 工程化串起来:基础题能背不够,关键在于能讲清业务风险与落地方案

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐