大厂Java面试实录:Spring Boot/WebFlux、JVM调优、Redis/Kafka、Spring Cloud 与 RAG/Agent 追问

大厂Java面试实录:Spring Boot/WebFlux、JVM调优、Redis/Kafka、Spring Cloud、Prometheus/ELK 与 RAG/Agent 追问

场景:某互联网大厂「内容社区 + UGC + AIGC 创作」业务,一次 Java 后端面试。

角色:

  • 面试官(严肃):追问细、喜欢从业务到技术逐层加压。
  • 小Y(搞笑水货程序员):简单题能答,复杂题开始"玄学编程"。

第一轮(基础能力):从UGC发帖接口开始

Q1(业务引入):UGC发帖接口你怎么设计?

面试官:我们是内容社区,用户发帖带文字+图片,可能还要触发审核、打标签、推送。你会怎么拆接口?

小Y :就一个 POST /posts 呗......参数 contentimages,然后我 postService.save() 一把梭。

面试官:那审核、打标签、推送都在一个事务里?

小Y :嗯......要不我加个 @Transactional?这样肯定稳。

面试官:至少你知道事务能兜底,但这会把一个"写库操作"绑上很多"异步链路"。我们先往下。


Q2(Spring MVC基础):你会怎么做参数校验与统一异常?

面试官:发帖接口怎么做参数校验,怎么让前端拿到统一错误码?

小Y@Valid + @RequestBody,然后写个 @ControllerAdvice 统一返回就行。

面试官:可以。那你会怎么区分"业务异常"和"系统异常"?

小Y :业务异常我就 throw new RuntimeException("业务不对")......系统异常也是 RuntimeException......反正都能被 Advice 抓住。

面试官:方向对了,但异常分层要更规范。继续。


Q3(JVM基础):线上接口偶发超时,你第一时间看什么?

面试官/posts 偶发超时,RT 从 50ms 飙到 5s。你先看 JVM 哪些指标?

小Y :先看 CPU......再看内存......然后 jstack 一下?

面试官:还行。那 GC 你会重点看什么?

小Y:看......是不是 Full GC 了。Full GC 就很慢。

面试官:对,至少抓住了重点。


Q4(数据库与连接池):写库慢,你怀疑连接池,你会怎么定位?

面试官:写库慢,你怎么判断是 SQL 慢还是连接池拿连接慢?

小Y:我看一下日志......SQL 打印出来......如果慢就加索引。

面试官:连接池呢?HikariCP 你会看哪些配置/指标?

小Y :呃......maximumPoolSize?我一般设 200,越大越好。

面试官:200 不一定更好,但你至少知道从池大小入手。


第二轮(进阶链路):从同步发帖到异步审核与消息队列

Q1(拆分与一致性):审核、打标签、推送你会怎么做异步?

面试官:发帖成功后要触发: 1)内容安全审核 2)NLP 打标签 3)给粉丝推送 你怎么拆?

小Y :我在 save() 后面开三个线程 new Thread() 跑就行。

面试官:线上你敢这么干?如果进程重启线程就没了。

小Y:那......我用线程池!

面试官:线程池也不解决可靠性。那你会用什么?

小Y:用 Kafka/RabbitMQ 发消息!

面试官:这就对了。那你怎么保证"发帖入库"和"发消息"一致?

小Y:加个大事务,把 Kafka 也一起事务?

面试官:......Kafka 事务不是这么用的。继续往下问。


Q2(Kafka/RabbitMQ):你怎么设计消息幂等与重复消费处理?

面试官:审核消息可能重复投递,消费者如何做到幂等?

小Y:我在消费的时候先查数据库,如果处理过就不处理。

面试官:用什么字段标识"处理过"?

小Y :就......加个 status,0 未处理 1 已处理。

面试官:基本思路可以。但高并发下会有竞态,你怎么避免?

小Y :加锁!synchronized

面试官:......跨 JVM 你打算 synchronized 谁?

小Y:那我用 Redis 锁!

面试官:好,至少你知道分布式锁这个工具。


Q3(缓存与热点):帖子详情是热点接口,你怎么用 Redis 缓存?

面试官GET /posts/{id} QPS 很高,怎么做缓存?

小Y:先查 Redis,没有就查 MySQL,再 set 到 Redis。

面试官:缓存穿透、击穿、雪崩怎么处理?

小Y:穿透就......加布隆过滤器?击穿......加锁?雪崩......加随机过期时间?

面试官:回答得不错,这几个关键词都对。


Q4(微服务治理):审核服务偶发超时,你怎么做降级与重试?

面试官:审核服务是独立微服务,调用用 OpenFeign。偶发超时你怎么处理?

小Y:我把超时设置大一点......比如 30 秒。

面试官:那上游线程都被占满。更好的?

小Y:那就重试!一直重试到成功。

面试官:重试会放大流量雪崩。你知道 Resilience4j 吗?

小Y:知道!就是......断路器那个......我用过,但名字配置总记不住。

面试官:至少方向对:超时、限流、隔离、断路器、重试要组合使用。


第三轮(架构综合):可观测性 + 安全 + AIGC/RAG 追问

Q1(可观测性):一次"发帖→审核→打标签→推送"链路你怎么监控?

面试官:我们要求能定位:哪一段慢、哪一段报错、是否消息堆积。你会怎么做可观测性?

小Y:打日志!Logback!

面试官:只靠日志不够。指标、链路追踪呢?

小Y:Prometheus + Grafana 看指标,Jaeger/Zipkin 看链路。

面试官:Micrometer 用过吗?

小Y:用过......就是加依赖就有指标了那种。

面试官:行,至少知道组件栈。


Q2(安全):用户登录后发帖,怎么做鉴权与权限控制?

面试官:你会怎么做登录态?JWT 还是 Session?

小Y:JWT!因为无状态,最先进。

面试官:那 JWT 如何安全失效?比如用户被封禁后立刻不能发帖。

小Y:呃......JWT 不是不好失效吗......那就让它过期快一点?

面试官:这是典型问题。那 OAuth2/Keycloak 了解吗?

小Y:听过......Keycloak 是个登录的东西。

面试官:好,我们继续 AI。


Q3(AIGC/RAG):我们要做"企业级内容助手",从社区规则和历史帖子里回答问题,你怎么做RAG?

面试官:产品要一个"发帖助手":用户输入一句话,系统从社区规则、历史优质帖子里检索,再生成一段建议文案。你怎么落地?

小Y:用 ChatGPT......把所有文档丢给它,它就会回答。

面试官:文档 10GB 呢?

小Y:那就......分批丢?

面试官:你知道向量化、Embedding、向量数据库吗?

小Y:知道!向量就是......一串数字。数据库用 Milvus/Chroma/Redis 都行。

面试官:检索怎么做?

小Y:语义检索......topK......然后把结果拼进 prompt。

面试官:不错。那怎么降低幻觉?

小Y:让它"不要胡说八道"。

面试官:......我们希望更工程化:引用证据、回答约束、评估与回退。


Q4(Agent与工具调用):如果让AI自动"查违规词库、查用户历史、生成审核结论",你怎么设计工具执行框架?

面试官:你会让模型怎么调用内部服务?如何标准化?

小Y:我让它输出 JSON,然后我解析 JSON 调接口。

面试官:模型输出不稳定怎么办?

小Y:那我......多试几次?温度调低点?

面试官:MCP(模型上下文协议)/工具调用标准化了解吗?

小Y:呃......MCP 我看过文章,感觉挺厉害,但我还没来得及"深入实践"。

面试官:好的。


面试收尾

面试官:今天先到这。整体看你基础还行,关键词也能对上,但在一致性、可靠性、AI工程化落地上需要更系统的实战。你回去等通知,有结果我们 HR 会联系你。

小Y:好的老师!我回去就把 Kafka 事务和 MCP 都"深入一下"。


文末答案详解(按业务链路讲清楚)

目标:让小白能把"内容社区发帖 + 异步链路 + 可观测性 + 安全 + RAG/Agent"串起来。


第一轮答案详解:发帖接口与基础功

1)UGC 发帖接口如何设计(Spring Boot + 分层)

业务目标:用户发帖快速返回;审核/打标签/推送不阻塞用户。

推荐设计

  • POST /posts:只做核心写入(帖子基础信息落库、返回 postId)。
  • 非核心动作走异步事件:
    • PostCreatedEvent(Kafka/RabbitMQ/Pulsar 皆可)
    • 消费者分别做审核、标签、推送

技术要点

  • Spring MVC:Controller → Service → Repository/Mapper
  • DTO/VO 分离:入参 CreatePostRequest,出参 CreatePostResponse(postId)
  • 上传图片:可先走对象存储(OSS/S3),接口只保存 URL(避免大文件阻塞应用线程)

2)参数校验与统一异常(Jakarta Validation + ControllerAdvice)

做法

  • 入参校验:@Valid @RequestBody + 字段上 @NotBlank @Size ...
  • 统一异常:
    • @RestControllerAdvice
    • @ExceptionHandler(MethodArgumentNotValidException.class) 返回统一错误码

异常分层建议

  • BizException:可预期业务错误(如"内容为空""用户被封禁")
  • SysException:不可预期系统错误(NPE、下游超时)
  • 返回结构示例:{code, message, traceId}

3)线上超时:JVM 与线程维度如何排查

先看现象属于哪类

  • CPU 飙高:可能死循环、序列化/加密过重、热点锁竞争
  • RT 偶发飙高:常见是 STW GC、下游抖动、线程池/连接池耗尽

JVM/GC 要看

  • GC 次数与耗时(Young/Old/Full)
  • Old 区占用是否持续上升(内存泄漏风险)
  • 线程状态(jstack 看 BLOCKED、WAITING、RUNNABLE)

常用工具

  • JDK:jcmd, jstack, jmap(线上谨慎), GC log
  • APM:New Relic/自建链路追踪

4)写库慢:区分 SQL 慢 vs 连接池慢(HikariCP)

判断路径

  1. 看 SQL 执行时间(MyBatis/JPA 日志、慢查询日志)
  2. 看连接池等待时间(Hikari 指标:等待队列、active/idle)

HikariCP 关键点

  • maximumPoolSize 不是越大越好:受 DB 最大连接数、CPU、事务时间影响
  • 观察:
    • 连接获取耗时(pool wait)
    • active connections 是否长期满
  • 优化:缩短事务、分页、加索引、减少 N+1

第二轮答案详解:异步、消息、缓存、治理

1)为什么要用 MQ 而不是 new Thread

业务目标:可靠触发审核/标签/推送,且可削峰。

MQ 价值

  • 解耦:发帖服务不关心审核细节
  • 削峰:Kafka/RabbitMQ 缓冲流量
  • 可靠性:消费失败可重试/死信队列

2)"入库 + 发消息"一致性怎么做(Outbox / 事务消息)

推荐:Outbox Pattern(通用、易落地)

  • 同一个本地事务内: 1)写 posts 表 2)写 outbox_event 表(事件内容、状态)
  • 后台 Job/CDC(Debezium)把 outbox 事件投递到 Kafka
  • 投递成功再把 outbox 状态置为已发送

好处:避免"库写成功但消息没发出去"或反过来。


3)消息幂等与重复消费

核心:MQ 至少一次投递(at-least-once)很常见,消费者必须幂等。

常用做法

  • 每条消息带唯一键:eventId/messageId
  • 消费侧幂等表:processed_event(event_id, processed_time)
    • 插入成功才执行业务
    • 插入失败(唯一键冲突)说明处理过,直接 ack

竞态避免

  • 使用 DB 唯一约束比 synchronized 更可靠
  • Redis 锁适合某些场景,但要考虑过期/续期/可重入等复杂度

4)Redis 缓存:穿透/击穿/雪崩

  • 穿透 :请求不存在的 postId
    • 缓存空值(短 TTL)
    • 布隆过滤器(Guava/RedisBloom)
  • 击穿 :热点 key 过期瞬间
    • 互斥锁/SingleFlight
    • 逻辑过期(返回旧值 + 后台刷新)
  • 雪崩 :大量 key 同时过期
    • TTL 加随机
    • 多级缓存(Caffeine + Redis)
    • 限流/熔断

Spring 可用:Spring Cache + Caffeine/Redis 实现本地+分布式缓存。


5)微服务治理:OpenFeign + Resilience4j

不要:一味调大超时、无限重试。

推荐组合

  • 超时:合理设置 connect/read timeout
  • 重试:只对幂等请求;限制次数;指数退避
  • 断路器:错误率/慢调用触发,快速失败保护系统
  • 隔离:线程池/信号量隔离,避免拖垮主线程池
  • 降级:返回"审核中"状态或进入人工队列

第三轮答案详解:可观测性 + 安全 + RAG/Agent

1)可观测性三件套:Logs/Metrics/Traces

日志(ELK)

  • Logback/Log4j2 + JSON 格式
  • 统一字段:traceIduserIdpostId

指标(Prometheus + Grafana)

  • QPS、RT、错误率
  • 线程池队列长度、DB 连接池 active/idle
  • Kafka lag(消费滞后)

链路追踪(Jaeger/Zipkin)

  • Spring Cloud Sleuth(或 OpenTelemetry)采集 span
  • 定位"发帖→发消息→审核→回写状态"哪段慢

Micrometer 负责把应用指标标准化暴露给 Prometheus。


2)JWT/Session 与"立刻失效"问题

JWT 优点 :无状态、易扩展。 难点:签发后在过期前很难强制失效。

工程解法

  • 短 TTL + Refresh Token
  • 引入 token 黑名单/版本号:
    • Redis 存 userTokenVersion
    • JWT 中带 version,校验不一致立刻失效
  • 统一认证中心:OAuth2 + Keycloak(适合多端、多系统 SSO)

Spring Security 可实现:

  • 鉴权过滤器校验 JWT
  • 方法级权限:@PreAuthorize

3)RAG 落地:向量化 + 语义检索 + Prompt 填充

业务目标:从"社区规则、历史优质帖子、FAQ"中找到证据,再生成建议文案。

典型流程

  1. 文档加载(规则/帖子/运营文档)→ 分段(chunking)
  2. Embedding 向量化(OpenAI/Ollama 等)
  3. 向量入库(Milvus/Chroma/Redis Vector)
  4. Query 来了:Embedding(query) → TopK 语义检索
  5. Prompt 填充:把检索结果作为 context,要求"基于证据回答"

降低幻觉(工程化,不靠"请别胡说"):

  • 让模型输出引用片段/来源
  • 设定回答约束:无证据则回答"不确定/需要补充信息"
  • 加评估:检索命中率、答案一致性
  • 关键场景回退:走模板回复或人工

Spring AI 可用来串:Embedding、VectorStore、ChatModel、Retriever。


4)Agent + 工具调用框架:让模型"会用内部系统"

业务例子:自动审核助手需要:

  • 查询违规词库服务
  • 查询用户历史违规次数
  • 调用内容安全模型
  • 生成审核结论并落库

关键点

  • 工具(Tool)需要标准化描述:name/description/JSON schema
  • 工具执行要可观测:每次调用有 traceId、耗时、入参脱敏
  • 输出不稳定要防御:
    • 严格 JSON schema 校验
    • 重试要有限制,失败要降级(人工队列)

MCP(模型上下文协议)价值

  • 统一"模型 ↔ 工具/资源"的调用协议
  • 让扩展能力更标准化(更像插件体系)

你可以带走的"面试回答模板"(一句话版)

  • 发帖:核心写入同步,审核/标签/推送异步事件化
  • 一致性:Outbox/CDC 保证库与消息一致
  • 幂等:eventId + 幂等表唯一约束
  • 缓存:穿透/击穿/雪崩三件套
  • 治理:超时+重试+断路器+隔离+降级(Resilience4j)
  • 可观测:ELK + Prometheus/Grafana + Jaeger/Zipkin(Micrometer/OpenTelemetry)
  • 安全:Spring Security + JWT(短 TTL + 版本号/黑名单)或 OAuth2/Keycloak
  • RAG:chunk → embedding → vector DB → topK → prompt
  • Agent:工具 schema + 执行可观测 + 失败降级,MCP 做标准化
相关推荐
一轮弯弯的明月1 小时前
Spring AOP编程
java·开发语言·spring boot·笔记·spring aop·学习心得
Sam_Deep_Thinking1 小时前
拼单功能的设计实战
java·架构
Boop_wu1 小时前
[Java项目] Spring Boot + WebSocket 实现网页在线聊天室|完整项目架构与实战讲解
spring boot·websocket·java-ee·mybatis
neo_Ggx231 小时前
Linux 日志检索速查:按时间、接口、Trace ID 查询完整请求链路
java·linux·服务器
ch.ju1 小时前
Java程序设计(第3版)第四章——什么是对象
java·开发语言
m0_609160491 小时前
如何使用Python查询MongoDB并转为Pandas DataFrame_数据分析集成实战
jvm·数据库·python
2301_792674861 小时前
java学习(day34)
java·开发语言·学习
woxihuan1234561 小时前
c++怎么利用std--variant处理多种二进制子协议包的自动分支解析【进阶】
jvm·数据库·python
拾光Ծ1 小时前
【Linux系统】线程(上)
java·linux·运维·jvm·线程·c/c++