大厂 Java 面试实录:Spring Boot/Cloud、Kafka、Redis、JVM、K8s、RAG 一条龙(小Y翻车版)

大厂 Java 面试实录:Spring Boot/Cloud、Kafka、Redis、JVM、K8s、RAG 一条龙(小Y翻车版)

故事背景

某互联网大厂「内容社区 + 音视频 + AIGC」事业群,招聘 Java 后端。

  • 面试官(M):严肃、节奏快、喜欢追问"为什么"。
  • 候选人小Y(Y):会一点,但不多;简单题能答上,难题开始"玄学输出"。

业务设定:社区用户上传短视频(UGC),平台提供内容推荐;同时接入 AIGC 文生文/文生视频能力,支持"智能客服 + 企业文档问答(RAG)"。系统微服务化,跑在 Kubernetes 上,核心链路包含 Kafka、Redis、MySQL/ES、对象存储、CDN。


第一轮(基础到进阶):从接口到线程,再到数据库与缓存

Q1:Spring Boot 里一个"发布视频"的接口,你会怎么设计?涉及哪些组件?

M: "用户上传短视频,提交标题、标签、封面,返回发布结果。你先说接口怎么设计。"

Y: "就......POST /video/publish,然后用 Spring MVC 接一下,存数据库,返回成功。"

M: "至少方向对。那参数校验、幂等、异步处理你考虑了吗?"

Y: "校验用 @Valid,幂等就......靠感觉?异步可以 @Async。"

M: "好,算你知道一些点,我们继续。"


Q2:你说用 @Async,那线程池怎么配置?为什么不直接用默认?

Y: "默认应该也行吧......反正它会开线程。"

M: "默认线程池容易把服务打挂,讲讲线程池参数:核心线程、最大线程、队列、拒绝策略。"

Y: "核心线程就是常驻的,最大线程是上限,队列是排队......拒绝策略就丢掉?"

M: "能说到这不错,但还不够。我们先记下,后面解析里展开。"


Q3:发布成功后要写 MySQL,用 MyBatis/Hibernate/JPA 你怎么选?连接池用 HikariCP 为什么更常见?

Y: "我用 MyBatis,SQL 可控。Hibernate/JPA 自动生成 SQL 容易翻车。HikariCP......听说快?"

M: "回答得还行。那你知道 HikariCP 为什么快、以及连接池关键指标怎么监控吗?"

Y: "因为它......轻量?监控可以看连接数?"

M: "好,有点概念。"


Q4:热门视频列表要扛流量,你会怎么用 Redis?如何避免缓存击穿/穿透/雪崩?

Y: "Redis 缓存热门列表,击穿就加锁,穿透加布隆过滤器,雪崩加随机过期。"

M: "不错,这题算你稳了。那本地缓存 Caffeine 什么时候用?"

Y: "呃......可能 QPS 太高的时候?"

M: "可以,下一轮我们上微服务链路。"


第二轮(微服务链路):从网关到消息队列,再到可观测与容错

Q1:发布视频后要做转码、封面抽帧、内容审核,你会怎么解耦?Kafka/RabbitMQ 怎么选?

Y: "用消息队列异步。Kafka 吞吐高,RabbitMQ 延迟低......吧?我选 Kafka。"

M: "理由还算像样。那说说 Kafka 的 topic/partition/consumer group,以及如何保证至少一次/恰好一次?"

Y: "partition 提高并行,consumer group 分摊消费。至少一次就是重试,恰好一次就是......不开重复?"

M: "开始飘了,但继续。"


Q2:微服务调用:OpenFeign + Resilience4j 你会怎么做超时、重试、熔断、限流?

Y: "Feign 调用,Resilience4j 加重试和熔断。超时就配置......限流也配置。"

M: "配置只是表象,核心是'哪些接口该重试、哪些不该',以及重试风暴怎么避免。你说说?"

Y: "应该......对幂等接口重试?不幂等就不重试。风暴就少重试。"

M: "还行,有方向。"


Q3:你们用 Spring Cloud/Consul/Eureka 做服务发现。为什么现在很多团队更偏向 K8s Service + DNS?

Y: "因为 Kubernetes 方便?省得自己搭?"

M: "嗯,算是。那你知道 K8s 下灰度发布/滚动升级对 Java 服务有什么坑吗?"

Y: "坑就是......可能会断流?我加个睡眠?"

M: "这回答很'水货',但我喜欢你诚实。"


Q4:链路追踪:Micrometer + Prometheus/Grafana + Jaeger/Zipkin 怎么串起来?

Y: "Micrometer 上报指标到 Prometheus,Grafana 看图;Jaeger 看 trace。"

M: "不错。那你如何定位一次发布视频接口'偶发 3 秒延迟'是 JVM GC 还是下游慢?"

Y: "看 Grafana......看一眼就知道?"

M: "你这属于'望诊'。我们后面写清楚方法。"


第三轮(高阶综合):JVM、数据一致性、RAG/Agent 与安全

Q1:你遇到过 JVM 频繁 Full GC 吗?线上怎么排查?

Y: "遇到过。就调大堆内存,或者重启。"

M: "这是'治标'。要说:指标、dump、定位对象、分析引用链。"

Y: "嗯......我会看下日志。"

M: "行,我们当你愿意学。"


Q2:发布视频要写 MySQL,同时发 Kafka 消息给转码服务。如何避免数据库成功但消息没发(或反过来)?

Y: "用分布式事务?比如......两阶段提交?"

M: "大厂很少直接上 2PC。你至少说出 Outbox/本地消息表、事务消息、幂等消费。"

Y: "对对对,本地消息表我听过,就是放一张表里。"

M: "还算有救。"


Q3:AIGC 智能客服要做企业文档问答(RAG)。你怎么设计:向量化、向量库、检索、提示填充、会话内存、工具调用?

Y: "RAG 就是把文档喂给大模型。向量库用 Milvus。然后问答就能回。"

M: "这回答像把 PPT 读了一遍。那:如何降低幻觉?如何做权限隔离?如何让模型能调用'订单查询'工具?"

Y: "幻觉就......加个提示词说不要胡说?权限隔离......按用户过滤?工具调用我没做过。"

M: "OK,知道你短板在哪了。"


Q4:安全:JWT + OAuth2/Keycloak 在 B 端 SaaS 多租户怎么落地?

Y: "JWT 放用户信息,OAuth2 登录授权。Keycloak 统一做 SSO。"

M: "不错。那租户隔离如何做?token 里放 tenantId 安全吗?"

Y: "放里面......应该可以?加密一下?"

M: "嗯,回答不够严谨。"


面试收尾

M: "整体来说,你基础还行,场景化和深度不足,尤其是 Kafka 语义、可观测落地、RAG 工程化。回去等通知吧,有结果 HR 会联系你。"

Y: "好的老师......不是,好的面试官。"


题目答案与解析(按业务场景讲清楚)

下面把每一题按"业务需求 → 技术点 → 推荐做法/要点"展开,新手可直接照着学习。

第一轮解析

1)发布视频接口设计(Spring MVC / Jakarta EE 思路类似)

业务需求:用户提交发布请求后,需快速返回;转码/审核等耗时操作异步。

技术点

  • Spring MVC Controller + DTO 校验:@RestController@Valid@Validated
  • 幂等:防止用户重复点击导致重复发布
  • 异步化:先落库,再发消息触发后续流程
  • API 文档:Swagger/OpenAPI

推荐做法

  • API:POST /api/v1/videos
  • 请求体包含:title、tags、coverUrl、videoObjectKey、clientRequestId
  • 幂等键:userId + clientRequestId(或业务唯一键)
  • 返回:videoId、status=PENDING
  • 后续:Kafka 事件 VideoCreated 驱动转码/审核

2)@Async 与线程池配置

业务需求:异步任务(如生成封面、调用审核)不能把 Tomcat/Netty 线程占满。

技术点

  • 默认 SimpleAsyncTaskExecutor 不复用线程,风险大
  • ThreadPoolTaskExecutor/自定义 Executor
  • 参数含义:
    • corePoolSize:常驻线程数
    • maxPoolSize:突发上限
    • queueCapacity:缓冲队列
    • keepAliveSeconds:非核心线程存活
    • rejectedExecutionHandler:拒绝策略(Abort/CallerRuns/Discard/DiscardOldest)

推荐要点

  • IO 密集型:线程数可略大,但要有队列与限流
  • 拒绝策略常用 CallerRunsPolicy(把压力"反压"回调用方),比悄悄丢任务更安全
  • 配合监控:线程池活跃数、队列长度、拒绝次数

3)MyBatis vs JPA/Hibernate;HikariCP

业务需求:发布写入、查询列表、复杂筛选(可能还要 ES 同步)。

技术点

  • MyBatis:SQL 可控、便于性能调优
  • JPA/Hibernate:开发效率高,但需警惕 N+1、懒加载、复杂查询性能
  • HikariCP:默认在 Spring Boot 中广泛使用

为什么 HikariCP 常见(面试可答要点):

  • 代码路径短、锁竞争少,性能好
  • 连接泄漏检测(leakDetectionThreshold)
  • 指标清晰:active/idle/pending

监控建议

  • Micrometer 采集连接池指标 → Prometheus → Grafana
  • 关注:等待连接时间、连接耗尽、慢 SQL

4)Redis 缓存与三大风险

业务需求:热门列表 QPS 高,DB 扛不住。

技术点与解法

  • 缓存穿透(查不存在):
    • 布隆过滤器(RedisBloom/自实现)
    • 缓存空值(短 TTL)
  • 缓存击穿(热点 key 过期瞬间大量打 DB):
    • 互斥锁重建(Redis setnx)
    • 逻辑过期(value 带过期字段,后台刷新)
  • 缓存雪崩(大量 key 同时过期或 Redis 故障):
    • TTL 加随机抖动
    • 多级缓存(Caffeine + Redis)
    • 限流/降级/熔断

Caffeine 适用

  • 单机内热点非常集中、对延迟极敏感
  • 可做 L1,本地命中后不走网络

第二轮解析

1)Kafka 解耦转码/审核:基础概念与投递语义

业务需求:发布后触发多个异步流程(转码、抽帧、鉴黄、写 ES)。

Kafka 核心概念

  • Topic:事件类别(VideoCreated)
  • Partition:并行度与顺序单位(同 key 保序)
  • Consumer Group:同组分摊分区,实现水平扩展

至少一次 vs 恰好一次

  • 至少一次:消费失败可重试,但可能重复消费 → 要求消费端幂等
  • 恰好一次(Kafka EOS):依赖事务生产者/事务性消费-生产链路,工程复杂;很多团队退而求其次:至少一次 + 幂等

工程建议

  • 事件 key 用 videoId 保证同视频事件有序
  • 消费端幂等:以 eventId/videoId+eventType 做去重表或 Redis SET
  • 失败处理:重试 + DLQ(死信队列)

2)OpenFeign + Resilience4j:超时、重试、熔断、限流的正确姿势

业务需求:调用审核/用户服务/推荐服务,避免下游抖动拖垮上游。

关键点

  • 超时:必须有(连接超时、读超时)
  • 重试:只对幂等请求(GET、或业务幂等的 POST)
  • 熔断:下游错误率高时快速失败
  • 限流:保护自己与下游

避免重试风暴

  • 重试次数小(如 1~2 次)
  • 指数退避 + 抖动(避免同步重试)
  • 配合熔断:熔断打开时不再重试

3)服务发现:Eureka/Consul vs K8s Service

业务背景:上 K8s 后,服务实例由 K8s 管理,注册中心的价值下降。

K8s Service + DNS 优点

  • 原生、运维成本低
  • 与滚动升级/探针/弹性伸缩联动自然

滚动升级对 Java 的坑与对策

  • 坑:Pod 被 kill 时仍有连接/请求在途 → 断流
  • 对策:
    • readinessProbe:未就绪不接流量
    • preStop + 优雅停机(Spring Boot graceful shutdown)
    • 设置 terminationGracePeriodSeconds

4)可观测性:指标 + 日志 + Trace 联动定位延迟

业务需求:偶发 3 秒延迟,需要可定位。

体系串联

  • 指标(Metrics):Micrometer → Prometheus → Grafana
  • 日志(Logs):Logback/Log4j2 → ELK
  • 链路(Tracing):OpenTelemetry/Brave → Jaeger/Zipkin

定位方法(面试可背)

  1. Grafana 看接口 P95/P99 是否抬升
  2. 看 JVM 指标:GC 次数/停顿、堆使用、线程数
  3. 查下游依赖指标:DB 慢查询、连接池等待、Kafka lag
  4. 打开 trace:看 span 哪段耗时(DB、HTTP、序列化)
  5. 对应时间窗口去 ELK 查日志(异常、超时、重试)

第三轮解析

1)频繁 Full GC 排查(Java 8/11/17 通用)

业务现象:接口抖动、RT 飙升、CPU 高。

正确排查路径

  • 先看指标:GC 次数、GC pause、Old 区占用趋势
  • 采集:
    • jcmd <pid> GC.heap_info
    • jmap -dump:live,format=b,file=heap.hprof <pid>(谨慎)
  • 分析 hprof:MAT/VisualVM 查大对象与引用链
  • 常见根因:
    • 缓存无上限(Map 持有)
    • 线程池队列堆积持有大量对象
    • 大对象(大 JSON、byte[]、图片)
    • 不合理的日志/Trace 采样导致对象堆积

2)DB + Kafka 一致性:Outbox/本地消息表

业务需求:发布写库成功后必须"最终一定触发转码"。

问题:单体事务无法覆盖 DB 与 MQ。

常见工程解法

  • Outbox(本地消息表)
    1. 同一 DB 事务内:写业务表 + 写 outbox 表(待发送事件)
    2. 后台任务/CDC(如 Debezium)把 outbox 事件投递 Kafka
    3. 投递成功把 outbox 标记已发送
  • 消费端:幂等处理,支持重复投递

优点:不需要 2PC,可靠、可审计、易补偿。


3)RAG/Agent 工程化:降低幻觉、权限隔离、工具调用

业务需求:企业文档问答 + 客服工单查询,要求"答得对、可追溯、可控"。

RAG 标准链路

  1. 文档加载:PDF/Word/网页(文档加载器)
  2. 切分:按段落/标题,控制 chunk 大小
  3. 向量化:Embedding 模型(OpenAI/Ollama 等)
  4. 向量库:Milvus/Chroma/Redis Vector
  5. 检索:相似度 + 关键字混合检索(可加 rerank)
  6. 提示填充:把检索到的上下文塞入 prompt(带引用)
  7. 生成:LLM 输出

降低幻觉(可答要点)

  • 强制"基于上下文回答",无依据则说不知道
  • 输出附带引用片段/文档链接
  • 检索质量:chunk 合理、加 rerank
  • 评测:用离线问答集做准确率评估

权限隔离(B 端常见)

  • 向量数据加 tenantId / docAcl 字段
  • 检索时先按权限过滤再相似度排序(或先粗过滤)

Agent/工具调用

  • 让模型调用"订单查询/工单创建"等工具:
    • 定义 tool schema(名称、入参 JSON Schema、描述)
    • 模型输出 function call
    • 服务端执行工具 → 返回结果 → 模型二次总结
  • MCP(模型上下文协议)/标准化工具调用:统一工具接入与扩展

4)JWT + OAuth2/Keycloak:多租户 SaaS 落地

业务需求:同一套系统服务多个企业(租户),数据隔离。

推荐做法

  • OAuth2/OIDC:Keycloak 负责认证与签发 token
  • JWT 中可带:sub、roles、tenantId(或 tenant realm)

token 里放 tenantId 是否安全?

  • 可以放,但前提:
    • token 必须签名校验(RS256 等)
    • 服务端不能只"信任前端传参",而是信任已验证的 token claims
  • 更强隔离:
    • Keycloak realm per tenant(管理成本高)
    • 或统一 realm + tenant claim + 后端强制数据过滤

后端落地要点

  • Spring Security:把 tenantId 写入 SecurityContext
  • DB 层:MyBatis/JPA 拦截器自动追加 tenant 条件(谨慎处理跨租户后台账号)

学习路线(按本文覆盖栈)

  • Spring Boot/MVC → 参数校验、异常处理、线程池
  • MyBatis/JPA + HikariCP → 慢 SQL、连接池监控
  • Redis/Caffeine → 多级缓存与高并发风险
  • Kafka → 语义、幂等、DLQ、消费堆积
  • Resilience4j → 超时/重试/熔断/限流组合
  • Micrometer/Prometheus/Jaeger → 线上定位方法
  • JVM → GC 与 dump 分析
  • RAG/Agent → 检索、权限、工具调用、反幻觉

(完)

相关推荐
dFObBIMmai1 小时前
如何排查SQL存储过程内存溢出_优化大数据量临时表使用
jvm·数据库·python
无限进步_1 小时前
【C++】深入右值引用:移动语义与完美转发
java·开发语言·c++
霑潇雨1 小时前
原生 Zookeeper 实现分布式锁案例
java·分布式·zookeeper·云原生·maven
小王C语言1 小时前
【线程同步与互斥】:互斥量(锁)、条件变量(唤醒等待线程)、生产者消费者模型
java·开发语言
m0_470857641 小时前
mysql如何快速撤销所有数据库更改_通过事务回滚机制实现
jvm·数据库·python
iuvtsrt1 小时前
SQL触发器中调用外部接口如何操作_配置外部存储过程引用
jvm·数据库·python
我命由我123451 小时前
Jetpack Compose - 设置 Compose 编译器、设置 Compose 依赖项
android·java·java-ee·kotlin·android jetpack·android-studio·android runtime
m0_740653221 小时前
Redis如何查询附近的人_利用GEORADIUS指令进行Geo范围搜索
jvm·数据库·python
Jetev1 小时前
宝塔面板如何实现网站重定向_配置301永久跳转与域名更换
jvm·数据库·python