大厂Java面试实战:Spring Boot/Cloud + Redis/Kafka + K8s + RAG/Agent 追问全流程(小Y翻车记)

大厂Java面试实战:Spring Boot/Cloud + Redis/Kafka + K8s + RAG/Agent 追问全流程(小Y翻车记)

场景:某互联网大厂「内容社区 + 音视频 + AIGC」业务线,一面。

角色:

  • 面试官(严肃):不笑,但句句致命。
  • 小Y(搞笑水货):简单题能答,复杂题开始"我感觉""应该是"。

第一轮:从内容社区入口到基本功(Java/JVM/Spring Boot/DB)

Q1(业务起点):内容社区的"发帖"接口,你会怎么设计?

面试官 :我们有UGC内容社区,用户发帖(文字+图片+视频链接)。你用 Spring Boot 写一个 POST /posts,你会考虑哪些点?

小Y :就......Controller 接一下 DTO,然后 Service 存数据库。图片视频我就放 OSS,然后存 URL。要不我再加个 @Valid

面试官:基本方向对。那你会做幂等吗?比如用户手滑点两次。

小Y:可以......前端禁用按钮?

面试官:后端也要。继续。


Q2(延伸到数据库):帖子写入与"热度"字段,如何避免并发写热点?

面试官 :帖子有 like_countcomment_count,高并发下怎么更新?

小Y :直接 update set like_count = like_count + 1?数据库很强的。

面试官:强是强,但你得解释"强在哪里"。行锁?热点行?缓存?

小Y:嗯......行锁......应该会锁住那一行,然后排队。

面试官:至少知道行锁。继续。


Q3(JVM基本功):线上偶发Full GC,你怎么排查?

面试官:发帖高峰期偶发 RT 抖动,监控看到 Full GC,你的排查路径?JDK 11。

小Y :我会先看看日志......然后 jmap 一下?或者重启。

面试官:重启是最后一步。你说说:GC 日志、堆转储、谁在分配、是不是大对象。

小Y:哦对对,看 GC 日志,看看是不是内存泄漏。大概这样。

面试官:至少方向没偏。


Q4(框架理解):Spring Boot 自动配置原理你能讲清楚吗?

面试官 :为什么你引入 spring-boot-starter-web 就有 Tomcat、MVC、Jackson?

小Y:因为它"自动"。

面试官 :......你说 @SpringBootApplication 包含什么?spring.factories(或新版本的自动配置导入)怎么加载?

小Y :这个我记得是......@EnableAutoConfiguration 会扫描 classpath,满足条件就注入 Bean。

面试官:还不错。


第二轮:引入分布式与高并发(Redis/Kafka/Spring Cloud/Resilience4j)

Q1(场景升级):帖子发布后要异步做"内容审核 + 提取标签 + 推送Feed",怎么解耦?

面试官:发帖接口必须 200ms 内返回,但后面要走审核、AIGC标签、Feed 扩散。你怎么设计?

小Y:用 MQ!比如 Kafka。发帖成功发个消息,然后消费者去做审核和推送。

面试官:为什么 Kafka?RabbitMQ 行不行?怎么保证"至少一次/恰好一次"?

小Y:Kafka 吞吐高。恰好一次......我记得 Kafka 有事务?反正不会丢。

面试官:不会丢≠不会重复。


Q2(缓存与一致性):Feed 流用 Redis 缓存,怎么处理缓存穿透/击穿/雪崩?

面试官:用户打开首页,Feed 读 Redis,缓存没命中就查 DB。怎么防穿透、击穿、雪崩?

小Y:穿透可以用布隆过滤器;击穿加互斥锁;雪崩加随机过期时间。

面试官:很好。这些你做过?

小Y:嗯......看过文章,理论上会。

面试官:至少背得对。


Q3(分布式调用):审核服务挂了,发帖还能成功吗?怎么做降级与隔离?

面试官:你用 Spring Cloud/OpenFeign 调审核服务,审核服务慢/挂,会把发帖拖死。怎么做?

小Y:可以设置超时、重试,然后......熔断?用 Resilience4j。

面试官:说说舱壁隔离、限流、重试风暴怎么避免。

小Y:舱壁就是线程池隔离;限流就是 QPS 限制;重试风暴......少重试?

面试官:可以。


Q4(数据一致性):发帖写库成功但发Kafka失败,怎么办?

面试官:你先写 MySQL,再发 Kafka。如果写库成功但发消息失败,Feed 就不同步了。怎么保证最终一致?

小Y:加事务?数据库和 Kafka 一个事务。

面试官:跨系统事务很难。你听过 Outbox/本地消息表 吗?

小Y:听过......就是先写一张消息表,然后定时任务发?

面试官:不错,继续。


第三轮:云原生 + 可观测 + AI-RAG(K8s/Prometheus/Jaeger/Spring AI/向量库)

Q1(音视频场景):视频上传后要转码、截图、生成字幕,如何做"任务编排"?

面试官:音视频处理是典型长耗时 pipeline:上传→转码→截图→ASR字幕→审核。你怎么编排?

小Y:用消息队列串起来,一个服务消费完再发下一个主题。或者搞个工作流引擎。

面试官:那失败重试与幂等呢?比如转码重复执行成本很高。

小Y:用任务ID去重?重复就不做。

面试官:可以。


Q2(Kubernetes):你的发帖服务在K8s里,如何做灰度发布与自动扩缩容?

面试官:K8s里怎么灰度?怎么基于指标扩缩容?

小Y:灰度就是多起几个 Pod,然后慢慢切流。扩缩容可以 HPA,看 CPU。

面试官:只看 CPU 不够,QPS/延迟呢?

小Y:可以用 Prometheus 指标,然后自定义扩缩容......具体 YAML 我记不清。

面试官:嗯。


Q3(可观测性):线上"发帖慢"你怎么定位是哪一环?

面试官:用户投诉发帖慢。你如何用 Micrometer + Prometheus/Grafana + ELK + Jaeger 定位?

小Y:Grafana 看 RT,ELK 查日志,Jaeger 看链路。然后就能找到慢的地方。

面试官:你至少知道工具的分工。那 TraceId 如何贯穿日志?

小Y:MDC?

面试官:对。


Q4(AI加分题):我们做"企业知识库问答"给审核同学用,RAG怎么落地?

面试官 :现在要做一个内部"审核规则问答",文档很多。你用 Spring AI 怎么做 RAG?向量库用 Milvus/Chroma/Redis 都行。

小Y:RAG 就是先把文档向量化,存到向量库,然后问问题时去检索相似内容,再把内容塞给大模型。

面试官:不错。那如何降低幻觉?如何做会话记忆?Agent 什么时候需要?

小Y:幻觉就......多给上下文?记忆就是把聊天记录存起来。Agent 就是让它能调用工具,比如查数据库。

面试官:回答有点虚,但方向对。


面试收尾

面试官:今天先到这里。你基础还可以,分布式一致性和云原生细节需要更扎实,AI/RAG 也要多做落地。回去等通知,有消息 HR 会联系。

小Y:好的老师,我回去就把"我感觉"换成"我验证过"。


参考答案与知识点拆解(按业务链路讲清楚)

目标:把面试中的问题补齐成可落地方案,小白按这份复盘能搭出"内容社区 + 音视频 + AIGC/RAG"的基础架构。

第一轮答案:接口设计、并发计数、JVM、自动配置

A1 发帖接口如何设计(Spring Boot + 幂等 + 校验)

业务目标POST /posts 在 200ms 内返回,主体写入成功即可,耗时任务异步。

关键点

  1. DTO校验@Valid + Hibernate Validator;限制标题长度、正文大小、URL白名单等。
  2. 幂等
    • 客户端生成 Idempotency-Key(或请求唯一ID),服务端用 Redis SETNX / DB 唯一索引保存处理结果。
    • 幂等窗口例如 5~10 分钟。
  3. 安全:Spring Security + JWT/OAuth2,接口鉴权、限流(网关或 Resilience4j RateLimiter)。
  4. 落库 :MySQL/PostgreSQL,字段包含 post_id(雪花/UUID)、user_idcontentmedia_urlsstatus(待审核/已发布/驳回)。
  5. 返回 :只返回 post_id + 状态(例如 PENDING_REVIEW),后续进度由异步通知/轮询查询。

A2 点赞/评论数并发更新(热点行问题)

问题本质update post set like_count = like_count + 1 where id=? 会对同一行加锁(InnoDB 行锁),高并发时形成热点,吞吐下降。

常见方案

  1. Redis 计数 + 异步回写 (推荐):
    • 点赞先 INCR post:like:{id}
    • 定时/批量(Kafka/定时任务)回写 DB;
    • 需要处理:宕机丢数据(AOF/RDB)、回写幂等、对账。
  2. 分片计数 :对同一 post 的计数拆成 N 个 key:post:like:{id}:{shard},读时汇总,写时随机打散。
  3. 数据库层优化:减少频繁写热点,或把计数拆表;但核心仍是"写扩散"。

A3 Full GC 排查路径(JDK 11)

步骤(从快到慢):

  1. 确认现象 :Prometheus/Grafana 看 jvm_gc_pause_seconds、RT、CPU、容器内存。
  2. 开启/分析 GC 日志 :JDK11 用 -Xlog:gc*:file=gc.log:time,uptime,level,tags
  3. 定位原因
    • 内存泄漏(Old 区持续上涨);
    • 大对象/突刺(瞬时分配导致晋升);
    • 不合理堆设置(容器内存限制下 Xmx 过大/过小)。
  4. 堆转储jmap -dump:live,format=b,file=heap.hprof <pid>(注意线上风险),用 MAT/VisualVM 分析 dominator tree。
  5. 结合分配剖析:JFR/async-profiler 看热点分配。

A4 Spring Boot 自动配置原理

核心链路:

  1. @SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan
  2. @EnableAutoConfiguration 通过 AutoConfigurationImportSelector 导入候选配置类。
  3. 候选配置来源:
    • Spring Boot 2.x:META-INF/spring.factories
    • Spring Boot 3.x:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  4. @ConditionalOnClass/@ConditionalOnMissingBean/@ConditionalOnProperty 等条件注解决定是否生效。

第二轮答案:MQ解耦、缓存三大问题、熔断隔离、最终一致性

B1 异步解耦:Kafka/RabbitMQ怎么选?如何保证语义

场景:发帖后触发:审核、标签、Feed、推送。

选型

  • Kafka:高吞吐、顺序性(分区内)、适合日志流/事件流、可回放。
  • RabbitMQ:路由灵活、延迟队列等能力强,业务命令型消息常用。

至少一次(at-least-once):最常用。

  • 生产者:发送成功确认(acks=all)
  • 消费者:处理成功后再提交 offset
  • 代价:可能重复,需要 消费者幂等

恰好一次(exactly-once):Kafka 事务 + 幂等生产者 + 下游支持事务/幂等;工程复杂,通常仍以"至少一次 + 幂等"落地。

B2 Redis 缓存穿透/击穿/雪崩

  1. 穿透 (查不存在的 key):
    • 布隆过滤器(Bloom Filter)挡掉绝大多数非法请求;
    • 缓存空值(短 TTL)。
  2. 击穿 (热点 key 过期瞬间大量并发打 DB):
    • 互斥锁/单飞:SETNX lock,只有一个线程回源;
    • 逻辑过期:后台异步刷新,前台先返回旧值。
  3. 雪崩 (大量 key 同时过期):
    • TTL 加随机抖动;
    • 分层缓存(Caffeine + Redis);
    • 限流/降级保护 DB。

B3 审核服务慢/挂:Resilience4j 的组合拳

  • Timeout:上游调用设置严格超时(比如 50~100ms)。
  • Bulkhead(舱壁):线程池/信号量隔离,避免把主业务线程耗尽。
  • CircuitBreaker(熔断):错误率/慢调用超阈值打开熔断,快速失败。
  • RateLimiter(限流):保护下游。
  • Retry(重试):仅对幂等请求;设置退避(exponential backoff)避免重试风暴。
  • Fallback(降级) :审核不可用时:
    • 发帖仍成功,但状态置为 PENDING_REVIEW
    • 由异步审核补偿。

B4 写库成功但发消息失败:Outbox(本地消息表)

目标:保证"写库"和"发事件"最终一致。

做法:同一个 DB 事务内:

  1. post
  2. outbox_event 表(event_id, aggregate_id, payload, status)

之后由后台任务/CDC:

  • 定时扫描 outbox_event 未投递事件 → 投递 Kafka → 标记已投递
  • 或用 Debezium 等 CDC 监听 outbox 表变更推 Kafka

消费者侧 :用 event_id 做幂等(去重表/Redis set)。

第三轮答案:音视频编排、K8s发布扩缩容、可观测、RAG落地

C1 音视频处理 pipeline:编排 + 幂等

推荐架构

  • 事件驱动(Kafka/Pulsar)+ 状态机(DB 状态)或工作流引擎(Temporal/Argo Workflows)
  • 每一步产物落对象存储(转码文件、截图、字幕文件)

幂等

  • job_id/media_id 作为幂等键;每一步写入 step 状态(SUCCESS/FAILED)
  • 重试只对失败步骤;若检测到产物已存在则直接跳过

C2 K8s 灰度发布与自动扩缩容

  • 灰度
    • Deployment 滚动更新(最基础)
    • 进阶:Service Mesh(Istio)或 Ingress 按比例/按 Header 分流(金丝雀)
  • 扩缩容 HPA
    • CPU/内存指标
    • 更合理:自定义指标(QPS、p95 延迟、队列堆积)
    • Prometheus Adapter 将指标暴露给 HPA

C3 可观测性:从"慢"定位到具体环节

  • 指标(Metrics) :Micrometer 埋点 http.server.requests、DB连接池、Kafka lag,自顶向下看 p95/p99。
  • 日志(Logs):Logback/Log4j2 + JSON 格式,统一 TraceId;ELK 查询异常与慢日志。
  • 链路(Traces):OpenTelemetry/Jaeger/Zipkin 看到一次请求跨服务耗时分布。
  • TraceId 贯穿
    • 在网关生成 TraceId
    • 通过 HTTP Header 透传
    • 日志 MDC 打印 traceId 字段

C4 RAG 落地:Spring AI + 向量库 + 反幻觉

流程

  1. 文档加载:PDF/HTML/Confluence/数据库 → 分段(chunk)
  2. 向量化(Embedding):OpenAI/Ollama embedding 模型
  3. 入库:Milvus/Chroma/Redis Vector
  4. 检索:相似度 + 元数据过滤(部门/版本/生效日期)
  5. 提示填充:把 topK 片段作为"证据"塞进 Prompt
  6. 生成回答:大模型输出 + 引用来源

降低幻觉

  • 强制"基于检索片段回答,不足则说不知道"
  • 输出带引用(source + chunk id)
  • 设置信心阈值:低于阈值直接拒答/转人工

会话记忆

  • 短期:把最近 N 轮对话做摘要(Conversation Summary Memory)
  • 长期:把重要事实向量化存储,按语义检索回填

Agent 何时需要

  • 问题需要"多步工具调用/复杂工作流"时:查库、查工单、触发审批、调用审核规则服务等
  • 采用工具执行框架(Tool Calling),并做权限控制与审计

完整面试链路总结: 发帖(Spring Boot + 幂等)→ 写库(MyBatis/JPA + 连接池)→ 事件(Kafka)→ 缓存(Redis)→ 微服务治理(Resilience4j)→ 云原生(K8s + HPA)→ 可观测(Prometheus/ELK/Jaeger)→ AI能力(Spring AI RAG/Agent)。

相关推荐
m0_737539372 小时前
Redis安装与常用命令
数据库·redis·bootstrap
桌面运维家2 小时前
vDisk虚拟磁盘隐藏指定系统操作指南
java·开发语言
Lyyaoo.2 小时前
JWT 令牌(待更新)
java·前端·javascript
Cyber4K2 小时前
【Kubernetes专项】温故而知新,重温技术原理(1)
云原生·容器·架构·kubernetes
jiayong232 小时前
第 40 课:任务详情抽屉里的编辑 / 删除联动强化
java·开发语言·前端·javascript·vue.js·学习
Counter-Strike大牛2 小时前
SpringBoot中使用POI+EasyExcel批量导出主子表信息,以箱单为例
windows·spring boot·后端
河阿里2 小时前
Java八股:面试高频50
java·面试
小谢小哥2 小时前
53-熔断降级详解
java·后端·架构
CodeMartain2 小时前
shardingsphere-spring 实现数据分片(一)
java·后端·spring