大厂 Java 面试实录:Spring Boot微服务/Kafka/Redis/K8s可观测性 + RAG Agent(小Y社死版)

大厂 Java 面试实录:Spring Boot 微服务 + Kafka/Redis + K8s 可观测性 + RAG/Agent(小Y社死版)

故事背景

某互联网大厂电商事业部,准备做一个**"AIGC 智能客服 + 内容社区(UGC)"**的融合项目:

  • 用户在商品页/社区发帖里提问(物流、售后、尺码、活动规则)。
  • 客服系统先走知识库检索(RAG) ,不够再走工单/人工
  • 高并发、强可观测、要能灰度、要能抗故障。

面试官(严肃、惜字如金) vs 候选人小Y(搞笑水货但自信)。


第一轮:从单体到微服务的基本功(3-5问,循序渐进)

Q1(场景引入):

面试官: 电商客服入口在 App 内,QPS 高峰 2w+。你会怎么用 Spring Boot 快速搭一个「会话服务」?核心接口怎么设计?

小Y: 这题我熟!Spring Boot 起手 @RestController,然后 POST /chat/sendGET /chat/history。存储我先用 MySQL,缓存 Redis,保证丝滑。

面试官: 嗯,接口拆得还算直观。那你怎么考虑幂等?

小Y: 幂等...就是别重复嘛。可以传个 requestId,然后......就不重复了。

面试官: (点头)方向对,细节后面再补。


Q2(JVM 基础):

面试官: Java 11/17 下,面对大量短生命周期对象(每条消息都要序列化/反序列化、拼 prompt),你会如何看 GC?G1 适合吗?

小Y: GC 我懂,G1 就是"均匀地回收",适合大堆。我们用它就行了,反正不会 OOM。

面试官: (沉默 1 秒)你说的"不会 OOM"依据是什么?

小Y: 依据是......我感觉。

面试官: 好,我们继续。


Q3(数据库与连接池):

面试官: 会话消息落库,MySQL 写多读多。为什么大厂几乎都用 HikariCP?C3P0 的问题在哪?

小Y: HikariCP 快!C3P0...比较老。大概就是性能差点。

面试官: 还行,至少知道主流。


Q4(API 设计与序列化):

面试官: 给我一个消息发送接口的 OpenAPI/Swagger 关键要点。JSON 用 Jackson 没问题,但如果要做跨语言网关,为什么很多团队会选 Protobuf?

小Y: Swagger 就写注解 @Operation 啥的。Protobuf...因为它"更小更快"?

面试官: 对,继续保持。


第二轮:微服务稳定性与链路(3-5问,层层加压)

Q1(Kafka/消息链路):

面试官: 智能客服要把用户消息异步投递到「检索服务」和「LLM 编排服务」。Kafka 怎么保证不丢消息?至少说出生产端与消费端各一条策略。

小Y: 不丢消息...Kafka 天生就不丢吧。生产端我开个 acks=all,消费端我......自动提交 offset?

面试官: (眉头一动)自动提交 offset 你确定?

小Y: 呃......我觉得差不多。


Q2(分布式限流与熔断):

面试官: LLM 调用贵且慢。你会在 OpenFeign 或 WebClient 调用外部模型时怎么做超时、重试、熔断、隔离?Resilience4j 怎么落?

小Y: 这题我也会!设置 timeout,然后失败重试,熔断我就"关掉接口"......Resilience4j 就加依赖然后 @CircuitBreaker

面试官: 注解能写出来算入门,但隔离策略呢?线程池/信号量?

小Y: 隔离...就是别让它影响别的请求。可以多加点机器?

面试官: (叹气)继续。


Q3(Redis 缓存与一致性):

面试官: 商品规则、活动解释等 FAQ 可以缓存。你如何用 Spring Cache + Redis 做缓存?缓存穿透/击穿/雪崩怎么处理?

小Y: Spring Cache 我会 @Cacheable。穿透就加布隆过滤器,击穿就加锁,雪崩就加随机过期时间。

面试官: 这段回答不错,继续往下。


Q4(可观测性):

面试官: 线上出现"响应变慢",你如何用 Micrometer + Prometheus + Grafana 定位?分布式追踪 Jaeger/Zipkin 怎么串起来?

小Y: Grafana 看图,Prometheus 拉指标。Jaeger 就是看链路,慢在哪里一眼就知道。

面试官: (点头)方向对,但需要你说出关键指标和埋点位置。


第三轮:AIGC/RAG/Agent + 企业级落地(3-5问,终极拷打)

Q1(RAG 设计):

面试官: 我们要做企业知识库问答:商品说明、售后政策、物流规则、社区规范。请你描述 RAG 的链路:文档加载、切分、向量化、向量库、召回、重排、提示填充。并说说如何降低幻觉。

小Y: RAG 我最近也看了!就是先把文档放进去,然后问的时候去搜出来,再喂给大模型。降低幻觉嘛......就让它"别瞎说"。

面试官: (冷笑一声)"别瞎说"写在 prompt 里确实有用,但不够。


Q2(Agent 与工具调用):

面试官: 用户问"我的订单为什么还没发货",Agent 需要调用工具:订单查询、物流轨迹、优惠券补偿规则。你怎么设计工具执行框架?MCP/Google A2A/函数调用标准化你了解多少?

小Y: Agent 就是让模型自己干活。我可以给它三个接口地址,它会自己请求。MCP 我听过,好像是"模型上下文协议",A2A 就是......AI to AI?

面试官: (面无表情)了解程度:听过。


Q3(会话记忆与权限安全):

面试官: 会话内存怎么做?哪些信息可以长期记忆,哪些必须短期?如何用 Spring Security + OAuth2/JWT 做用户鉴权,避免越权查订单?

小Y: 记忆就存 Redis!长期短期都存。鉴权用 JWT,解析一下就知道是谁。越权...就别让他查到别人的。

面试官: 你说的都是结论,没有机制。


Q4(云原生与灰度):

面试官: 我们上 K8s,LLM 编排服务要灰度发布。你如何用 Kubernetes + Jenkins/GitLab CI 做流水线?如何用指标与日志判断灰度是否扩大?

小Y: K8s 就 rolling update,Jenkins 点一下就行。灰度看错误率,如果没错就全量。

面试官: (合上笔记本)今天先到这。


面试收尾

面试官: 你的基础题还可以,但在分布式可靠性、可观测落地、以及 RAG/Agent 工程化细节上需要加强。你先回去等通知,有结果我们 HR 会联系。

小Y: 好的好的,我回去就把"别瞎说"优化成"请你务必不要瞎说"!


文末学习区:本场所有问题的「详细答案与落地要点」

下面按轮次逐题给出更工程化、更可落地的答案(结合电商智能客服/UGC 业务)。


第一轮答案

1)会话服务怎么设计?接口、幂等、存储

业务点:用户可能重复点击发送、网络重试;客服系统必须保证"同一条消息不重复入库、不重复触发下游"。

接口建议(示例):

  • POST /api/v1/conversations/{cid}/messages
    • Header: Idempotency-Key(或 body 里的 requestId
    • Body: {senderId, content, clientTs, msgType, attachments...}
  • GET /api/v1/conversations/{cid}/messages?cursor=...&limit=...(游标分页)

幂等实现(常用三选一,可组合):

  1. 数据库唯一约束(conversation_id, request_id) 建唯一索引;插入用 insert ... on duplicate key(MySQL)或捕获唯一键异常。
  2. Redis 幂等键SETNX idem:{cid}:{requestId} 1 EX 300,成功才执行后续;用于"先挡住重复请求"。
  3. 消息链路幂等 :下游消费端基于 messageId 做去重表/Redis set。

存储建议:

  • 写扩展:分库分表或按会话分片;
  • 读优化:最近消息放 Redis(ZSET/列表)或 ES 做全文检索(投诉/工单检索)。

2)JVM/G1:大量短对象如何看 GC?

业务点:prompt 拼装、JSON/Protobuf 序列化、日志 MDC、链路对象都会制造短命对象,容易造成 Young GC 频繁;当延迟抖动时要能定位。

为什么 G1 常用

  • 适合大堆、可预测停顿(目标 pause time);
  • Region 化回收,Mixed GC 能逐步回收老年代。

怎么评估"不会 OOM"

  • 观察 Old Gen 增长趋势、to-space exhaustedHumongous 分配;
  • 开启 GC 日志(Java 11/17):
    • -Xlog:gc*:file=gc.log:time,uptime,level,tags
  • jcmd, jstat, async-profiler 看分配热点。

优化抓手

  • 减少大对象/超长字符串拼接(用 StringBuilder、复用 buffer);
  • 避免把大对象放进缓存;
  • 控制日志量(尤其是大 JSON 打印)。

3)HikariCP vs C3P0

结论:HikariCP 轻量、延迟低、并发性能好、监控指标友好;C3P0 较老,配置复杂且性能/稳定性在现代高并发场景下不占优。

工程建议

  • 连接池大小不是越大越好,通常与 DB CPU/IO 能力匹配;
  • 指标:active, idle, pending,以及慢 SQL 监控。

4)Swagger/OpenAPI 与 Protobuf

Swagger 要点

  • 请求/响应 schema 清晰;错误码与示例齐全;
  • 幂等字段说明(Idempotency-Key);
  • 分页方式(cursor vs pageNo)明确。

Protobuf 常用于跨语言

  • 二进制体积小、序列化快;
  • 强 schema、向后兼容机制(字段号);
  • 适合 gRPC(高性能内部 RPC)。

第二轮答案

1)Kafka 如何保证不丢消息(生产端/消费端)

生产端(Producer)

  • acks=all + enable.idempotence=true(幂等生产)
  • 合理设置 retriesdelivery.timeout.ms,避免无止境阻塞;
  • 关键主题设置副本数 replication.factor>=3min.insync.replicas 合理。

消费端(Consumer)

  • 关闭自动提交enable.auto.commit=false
  • 处理成功后再提交 offset(手动 commit);
  • 失败进入重试队列/死信队列(DLQ),避免卡死;
  • 做业务幂等:基于 messageId 去重。

业务解释:客服消息若丢失会导致"用户发了但系统没回应",体验灾难;宁可重复也别丢,所以要"至少一次 + 幂等"。


2)Resilience4j:超时、重试、熔断、隔离

目标:外部 LLM/检索服务慢或抖动时,不拖垮主链路。

落地组合:

  • TimeLimiter:严格控制单次调用时长;
  • Retry:只对可重试错误重试(超时/5xx),并设置退避;
  • CircuitBreaker:错误率/慢调用率超过阈值打开;
  • Bulkhead(隔离)
    • SemaphoreBulkhead:限制并发数(适合反应式/非阻塞);
    • ThreadPoolBulkhead:线程池隔离(适合阻塞调用)。

关键点

  • 不要"无脑重试"导致雪崩;
  • 熔断打开时返回降级:
    • 给用户可解释的回复("当前繁忙,已为你创建工单");
    • 或返回 RAG 低成本答案。

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

  • 穿透 (查不存在):
    • 布隆过滤器(RedisBloom/自建);
    • 缓存空值(短 TTL)。
  • 击穿 (热点 key 失效瞬间):
    • 互斥锁重建(SETNX lock:key);
    • 提前异步刷新(逻辑过期)。
  • 雪崩 (大量 key 同时过期/Redis 故障):
    • TTL 加随机;
    • 多级缓存(Caffeine 本地 + Redis);
    • 限流/熔断 + 降级。

结合 Spring Cache:

  • @Cacheable + 自定义 key;
  • 对"活动规则"这类强一致性要求不高的数据非常合适。

4)Micrometer/Prometheus/Grafana + Jaeger/Zipkin

定位慢建议从三板斧:

  1. RED 指标(请求量 Rate、错误 Error、耗时 Duration)
  2. 关键依赖(DB、Redis、Kafka、外部 LLM)的耗时与错误率
  3. GC/CPU/线程池/连接池指标

Micrometer 埋点:

  • Controller(入口延迟、状态码)
  • Feign/WebClient(外呼耗时、错误码)
  • 数据库连接池(Hikari metrics)

分布式追踪:

  • 统一 traceId(W3C Trace Context / B3)
  • 在网关、服务端、消息消费端继续传递(Kafka header)
  • Jaeger/Zipkin 展示完整调用树,定位慢 span。

日志:

  • ELK(或 OpenSearch)按 traceId 关联。

第三轮答案

1)RAG 全链路与降低幻觉

链路

  1. 文档加载(文档库/工单/FAQ/商品说明):
    • Spring AI 文档加载器或自研 ETL;
  2. 清洗与切分(chunk):
    • 按段落/标题;控制 chunk size 与 overlap;
  3. 向量化(Embedding):
    • OpenAI / Ollama 本地模型;
  4. 向量库:
    • Milvus/Chroma/Redis Vector;
  5. 召回:
    • TopK 相似度 + 元数据过滤(类目、语言、时间、生效状态);
  6. 重排(Rerank):
    • 交叉编码器/规则重排,提高相关性;
  7. 提示填充(Prompt stuffing):
    • 将检索片段以"证据"形式加入 system/user prompt;
  8. 生成答案 + 引用证据:
    • 返回引用来源(文档 id、段落)。

降低幻觉(工程手段,不靠"求你别瞎说"):

  • 回答必须基于证据:无证据则拒答/转人工;
  • 设定置信度阈值:向量相似度过低直接降级;
  • 输出结构化:如 JSON schema,减少自由发挥;
  • 对关键字段做工具校验:订单号、金额、时间必须走工具查询;
  • 评测与回归:用标注集评估命中率/幻觉率。

2)Agent 工具执行框架 + MCP/A2A/标准化

业务点:用户问"订单没发货",答案不能靠编;必须查订单状态、仓库出库、物流轨迹,再结合补偿规则。

工具执行框架核心要素:

  • 工具注册表(Tool Registry):name、描述、入参 schema、鉴权需求;
  • 工具网关(Tool Gateway):统一超时、重试、限流、审计日志;
  • 执行计划:
    • Planner(决定调用哪些工具、顺序)
    • Executor(实际调用并回填结果)
  • 结果校验:对关键字段做格式与权限校验。

**MCP(模型上下文协议)**理解:

  • 让模型以标准方式访问"工具/资源/提示",把工具能力外置到 MCP Server;
  • 客户端(你的 Java 服务)以 MCP Client 连接多个能力源(DB、搜索、内部 API)。

A2A(Agent-to-Agent)

  • 多 Agent 协作协议/模式:如"检索 Agent""订单 Agent""补偿 Agent"分工,通过标准消息互通。

落地建议(Java):

  • Spring AI + Tool/Function calling;
  • 工具调用强制加:超时、隔离、审计、脱敏。

3)会话记忆与安全(Spring Security + OAuth2/JWT)

会话记忆分层

  • 短期记忆 :本次会话上下文(最近 N 轮对话、用户当前问题)
    • 存 Redis,TTL 30min;
  • 长期记忆 :用户偏好(语言、常用地址等)
    • 存数据库,需用户授权、可删除;
  • 禁止记忆 :身份证、银行卡、病历等敏感信息(合规要求)
    • 做脱敏与 DLP(数据防泄漏)策略。

鉴权

  • OAuth2 登录后颁发 JWT(含 userId、scope、过期时间);
  • Spring Security:
    • Resource Server 校验 JWT 签名与过期;
    • 方法级鉴权 @PreAuthorize 控制 scope/role;
  • 防越权
    • 工具层(订单查询)必须校验 order.userId == token.userId
    • 不信任前端传的 userId。

4)K8s 灰度发布与 CI/CD

流水线(Jenkins/GitLab CI)

  • 单元测试(JUnit5/Mockito)→ 集成测试 → 构建镜像(Docker)→ 扫描(依赖/镜像漏洞)→ 推送镜像仓库 → 部署到 K8s

灰度策略

  • 金丝雀发布:10% 流量 → 30% → 100%
  • 或按用户分桶/按地域灰度。

放量依据(可观测)

  • SLI/SLO:P95/P99 延迟、5xx 错误率、下游 LLM 超时率、Kafka 消费堆积;
  • 业务指标:问题一次解决率、转人工率、投诉率;
  • 日志抽样:检查是否出现敏感信息泄露/幻觉关键词。

你可以怎么补齐"小Y缺的那块"

  • Kafka:至少一次语义 + 幂等消费 + DLQ
  • Resilience4j:隔离与降级策略要能说清
  • 可观测:指标/追踪/日志三件套要知道"埋在哪里,看什么图"
  • RAG/Agent:别停留在概念,能画出链路与拒答/校验机制
相关推荐
颖火虫盟主2 小时前
Conan C++ 包管理工具深度解析
java·jvm·c++
yumgpkpm2 小时前
Hadoop(CDH6、CDP7)在Qwen3.7大模型训练中的作用,(含部署、运行操作步骤)
大数据·hive·hadoop·分布式·zookeeper·spark·kafka
摇滚侠2 小时前
Java 零基础全套教程,IDEA 开发工具,笔记 59-61
java·笔记·intellij-idea
曹牧2 小时前
Eclipse:代码块折叠
java·ide·eclipse
DolphinDB智臾科技2 小时前
基于 DolphinDB 搭建微服务的 SpringBoot 项目
spring boot·微服务·架构
ForgeAI码匠2 小时前
后台权限不只是菜单隐藏:Forge Admin 的 RBAC 权限链路拆解
java·spring boot·spring·状态模式
一条泥憨鱼2 小时前
详解MyBatis 动态 SQL
java·数据库·sql·mysql·mybatis·动态sql
青枣八神2 小时前
Trae IDE 终端 JDK 版本与系统不一致的解决方案
java·开发语言·ide
密瓜智能2 小时前
MIG、Time-slicing 还是HAMi?密瓜智能CEO张潇本周六亮相JuiceFS Meetup,聊聊GPU共享的生产取舍
人工智能·云原生·kubernetes·开源·gpu算力·ai算力