大厂Java面试实录:Spring Boot/Cloud + Redis/Kafka + JWT + RAG/Agent(小Y翻车版)

大厂Java面试实录:Spring Boot/Cloud + Redis/Kafka + JWT + RAG/Agent(小Y翻车版)

故事背景

你面试的是一家互联网大厂的"电商内容社区 + AIGC 智能客服"团队:

  • 前台:内容流(UGC)+ 商品详情 + 下单
  • 中台:库存/订单/支付
  • 智能化:AIGC 导购与客服(企业知识库问答)

面试官(严肃、逻辑强)VS 程序员小Y(搞笑、基础能答,复杂就开始"艺术化表达")。


第一轮(基础到实战起步):做一个"内容社区 + 商品详情"服务

目标:Spring Boot 单体起步,逐渐引入缓存、数据库与接口规范。

Q1:你用 Spring Boot 做内容流接口,如何设计分页与排序?

面试官: 内容流接口 GET /feeds,支持按时间倒序、按热度排序,你怎么做?

小Y: 这个简单,pagesizesort 三件套嘛。时间倒序就 createTime desc,热度就 likeCount desc。Spring Data JPA 直接 Pageable 搞定。

面试官: 还行。那"翻页重复/漏数据"怎么避免?

小Y: 呃......加个事务?或者让用户少刷新。

面试官: ......(沉默两秒)我们先往下。

Q2:商品详情页 QPS 很高,你怎么用 Redis 做缓存?

面试官: 商品详情 GET /items/{id},热点商品 QPS 很高,你的缓存策略?

小Y: Redis 啊,key=item:{id},先查 Redis,没命中查 DB 再 set。加个过期时间,比如 10 分钟。

面试官: 缓存穿透、击穿、雪崩?

小Y: 穿透就......把不存在的也缓存一下?击穿加锁,雪崩随机过期。

面试官: 方向对。你打算用什么实现?

小Y: Spring Cache 注解 @Cacheable,一键上车。

面试官: 还不错,知道 Spring Cache 的底层抽象么?

小Y: 就是......让你不用写 Redis 代码。

Q3:你选 MyBatis 还是 JPA?怎么做数据库迁移?

面试官: 内容表、商品表、点赞表,你用 JPA 还是 MyBatis?为什么?

小Y: JPA 开发快,MyBatis 可控。我一般看心情......呃看业务复杂度。

面试官: 数据库 schema 变更怎么做?

小Y: Flyway 或 Liquibase。我们用 Flyway,因为名字短。

面试官: ......行,至少知道工具。

Q4:单元测试怎么写?Mock 哪些?

面试官: 你怎么测试"点赞接口"既写库又发消息?

小Y: JUnit 5 + Mockito。Repository mock 掉,消息也 mock 掉。AssertJ 写断言。

面试官: 如果要做端到端?

小Y: Selenium?

面试官: 这是 Web UI 自动化......(叹气)继续。


第二轮(微服务与稳定性):点赞上报、异步化、链路追踪

目标:从单体走向微服务,Kafka 异步、Spring Cloud、可观测性。

Q1:点赞量/评论数如何异步更新?Kafka 还是 RabbitMQ?

面试官: 点赞接口高峰期很爆,你如何把"写库 + 更新计数"拆开?

小Y: 用 Kafka。点赞服务写一条消息到 topic,计数服务消费更新 Redis 或 ES。

面试官: 为什么 Kafka?

小Y: 因为它快,而且大厂都用。

面试官: ......那幂等怎么保证?

小Y: 消费端加个 try-catch,失败重试。

Q2:服务发现与配置管理:Eureka/Consul 怎么选?

面试官: 你们上 Spring Cloud,注册中心用什么?

小Y: Eureka 经典,Consul 也行。我们用......看公司祖传。

面试官: 配置中心、灰度发布怎么做?

小Y: Git 里改配置,发版就灰度了。

Q3:熔断限流怎么做?Resilience4j 你会怎么用?

面试官: 内容流依赖"用户画像服务",它慢了会拖垮你,怎么办?

小Y: 加超时、熔断。Resilience4j 注解加上,失败就走 fallback。

面试官: fallback 返回什么?

小Y: 返回默认画像,比如"该用户爱看猫"。

面试官: (忍笑)行,思路对。

Q4:链路追踪怎么打通?Micrometer + Prometheus + Jaeger?

面试官: 我想看一次请求从网关到内容服务再到画像服务的耗时,你怎么做?

小Y: Micrometer 把指标打到 Prometheus,Grafana 画图。链路追踪用 Jaeger 或 Zipkin。

面试官: traceId 怎么传?

小Y: 放 header 里,大家自觉传。


第三轮(安全 + AI 落地):AIGC 客服的 RAG/Agent 与风控

目标:从"业务可用"走向"安全可控 + AI 工程化"。

Q1:登录鉴权:Spring Security + JWT + OAuth2 怎么选?

面试官: App + Web + 小程序三端,怎么做统一鉴权?

小Y: JWT 就行,发个 token。Spring Security 配一下过滤器。

面试官: OAuth2 / Keycloak 呢?

小Y: 也能用,但我觉得 JWT 更"轻"。

面试官: token 失效、踢人、刷新怎么做?

小Y: 设置短过期,然后......让用户重新登录。

Q2:支付与风控:接口防重、幂等、分布式事务怎么做?

面试官: 下单支付回调可能重复通知,你怎么保证不重复记账?

小Y: 用唯一订单号,数据库加唯一索引。收到回调先查状态。

面试官: 库存扣减、订单创建、支付确认跨服务一致性?

小Y: 这个用分布式事务......或者最终一致性。具体怎么搞看框架。

Q3:企业知识库问答:RAG 的最小闭环怎么搭?

面试官: 我们要做"商家政策/售后规则/活动玩法"的客服问答,如何用 RAG?

小Y: 把文档丢到向量数据库,然后问问题就相似度搜索,找几段给大模型生成答案。

面试官: 文档怎么加载、怎么切分、embedding 用什么?

小Y: Spring AI 有现成的。切分就......按段落切。embedding 用 OpenAI 或 Ollama。

面试官: 幻觉怎么控制?

小Y: 让模型"不要幻觉"。

Q4:Agent 工具调用:MCP/工具执行框架你怎么设计?

面试官: 客服 Agent 需要"查订单、查物流、发优惠券",如何做工具调用标准化?

小Y: 设计几个 HTTP 接口给它调。MCP 就是......让它更会调工具。

面试官: 权限隔离、审计、超时、重试?

小Y: 日志打一下,超时设置 3 秒,重试 3 次,应该就行。


结束语

面试官: 今天先到这。你回去等通知吧,如果有后续我们会联系你。

小Y: 好的好的,我手机一直开着,外加心也一直开着。


文末答案详解(把小Y含糊的地方补齐)

按业务链路:内容流 → 商品详情 → 点赞异步 → 微服务稳定性 → 安全与支付 → RAG/Agent 客服。

1)内容流分页:为什么会"重复/漏数据"?怎么修

问题本质 :传统 offset/limit 在数据持续新增/删除时会导致翻页不稳定。

推荐方案

  • 游标分页(cursor pagination / seek method)
    • (createTime, id) 作为游标
    • 下一页条件:(createTime < lastTime) OR (createTime = lastTime AND id < lastId)
    • 排序:ORDER BY createTime DESC, id DESC
  • 热度排序通常需要"时间窗 + 预聚合"(否则全表排序昂贵):
    • 点赞/评论通过 Kafka 异步累计到 Redis
    • 定时任务把 Redis 的聚合落 ES 或 DB
    • 内容流按热度从 ES/Redis TopN 取,再回源补全

技术点:Spring MVC 参数设计(cursor、limit)、MyBatis/JPA 自定义查询、避免深分页。

2)商品详情 Redis 缓存:穿透/击穿/雪崩落地

  • 缓存穿透 (大量请求不存在的商品 id):
    • 缓存空值(短 TTL)+ 参数校验
    • 或 Bloom Filter(RedisBloom/Guava BloomFilter)
  • 缓存击穿 (单个热点 key 过期瞬间大量并发打 DB):
    • 互斥锁:SETNX lock:item:{id} + 过期时间
    • 或逻辑过期:value 带 expireAt,过期后异步刷新,读请求先返回旧值
  • 缓存雪崩 (大量 key 同时过期):
    • TTL 随机抖动:baseTTL + random(0,n)
    • 分批预热 + 限流 + 熔断

实现建议

  • Spring Cache(抽象)+ RedisCacheManager(实现)
  • 热点场景建议显式写缓存逻辑,方便加锁/逻辑过期/降级

3)JPA vs MyBatis 怎么选 + Flyway/Liquibase 的正确用法

  • JPA
    • 优点:开发快、实体映射省心、CRUD 强
    • 缺点:复杂 SQL、性能可控性、N+1 问题需经验
  • MyBatis
    • 优点:SQL 可控、复杂查询更直观
    • 缺点:样板代码更多

推荐落地

  • 简单 CRUD 用 JPA;复杂报表/多表 join 用 MyBatis

Flyway

  • 版本化脚本:V1__init.sqlV2__add_index.sql
  • 保证生产环境 schema 可追溯、可回滚(结合规范与审核)

4)测试:单元/集成/端到端怎么分层

  • 单元测试 :JUnit5 + Mockito + AssertJ
    • mock:外部依赖(DB、MQ、HTTP Client)
    • 不 mock:业务逻辑
  • 集成测试
    • Testcontainers 起 MySQL/Redis/Kafka
    • Spring Boot @SpringBootTest
  • 契约测试/接口测试
    • REST Assured / Postman/Newman
  • 端到端 UI:Selenium(适合 Web 前端 UI 测试,不是后端主力)

5)Kafka 异步点赞:幂等与一致性

典型链路

  1. 点赞服务写 DB(like 表)
  2. 写 Kafka 事件(LikeCreated
  3. 计数服务消费,更新 Redis 计数

幂等手段

  • 事件带唯一 id(eventId / likeId
  • 消费端用 Redis/DB 记录已处理 eventId(去重表/幂等表)
  • Kafka 消费位点提交与业务处理要配合(至少一次语义下必须做幂等)

进阶

  • Outbox Pattern:业务表与 outbox 表同库同事务写入,再由 CDC/任务发送 Kafka,避免"写库成功但发消息失败"。

6)服务发现/配置/灰度:别靠"祖传"和"Git改完就灰度"

  • 服务发现:
    • Spring Cloud 生态里常见:Eureka(历史)、Consul(更通用)
    • K8s 场景很多直接用 Kubernetes Service + DNS
  • 配置管理:
    • Spring Cloud Config / Nacos(若允许)/ Consul KV
    • 配合动态刷新(/actuator/refresh 或自动刷新机制)
  • 灰度:
    • 网关层按用户维度路由(Header/Cookie/UserId)
    • K8s canary(按比例/按流量镜像)

7)Resilience4j:超时、熔断、限流、舱壁的组合拳

  • Timeout:避免线程被慢调用拖死
  • CircuitBreaker:错误率/慢调用比例触发熔断
  • RateLimiter:保护自身
  • Bulkhead:隔离线程池/信号量,避免级联

fallback 设计

  • 返回可接受的"降级数据"(默认画像/空推荐)
  • 打点告警,避免静默失败

8)可观测性:指标、日志、追踪三件套

  • 指标 :Micrometer → Prometheus → Grafana
    • QPS、P99、线程池队列长度、GC、连接池活跃数
  • 日志 :SLF4J + Logback/Log4j2,统一 traceId
    • ELK(Elasticsearch + Logstash/FluentBit + Kibana)
  • 链路追踪 :OpenTelemetry / Brave → Jaeger/Zipkin
    • traceId/spanId 自动注入与透传(不要"大家自觉传")

9)鉴权:JWT 只是起点,OAuth2/Keycloak 解决"统一身份"

  • JWT :适合无状态鉴权,但
    • 踢人/撤销困难(需黑名单或短 token + refresh token)
    • 权限变更实时性差
  • 推荐
    • OAuth2 + OIDC(统一登录)
    • Keycloak 作为 IdP(用户、角色、客户端、token 签发)
    • 资源服务用 Spring Security Resource Server 校验 JWT

token 刷新与踢人

  • access token 短(5-15 分钟)
  • refresh token 长 + 可撤销(服务端存储/会话)
  • 黑名单/版本号(tokenVersion)控制强制下线

10)支付回调幂等 + 跨服务一致性

  • 防重/幂等
    • DB 唯一键(payCallbackId/tradeNo
    • 状态机:订单状态只允许从 A → B,非法跳转拒绝
  • 一致性
    • 优先最终一致性:事件驱动(Kafka)+ 补偿
    • TCC/Saga 思路:库存预占→支付成功确认→失败释放
    • 关键:每步可重试、可补偿、可观测

11)RAG 最小闭环(Spring AI 视角)

目标:让模型"只基于检索到的企业文档回答",降低幻觉。

流水线

  1. 文档加载(PDF/HTML/Markdown/数据库)
  2. 清洗与切分(chunking:按语义/标题/长度;保留元数据:来源、更新时间、适用范围)
  3. 向量化(Embedding:OpenAI/Ollama 等)
  4. 写入向量库(Milvus/Chroma/Redis Vector)
  5. 查询:用户问题 → 向量检索 TopK → rerank(可选)
  6. 提示填充(Prompt Template):把检索片段、引用来源塞进 prompt
  7. 生成与后处理:引用标注、敏感信息过滤、置信度/拒答策略

控制幻觉

  • 强约束 prompt:仅使用给定 context,不足则明确说不知道
  • 输出必须带引用(source id)
  • 低相似度阈值直接拒答
  • 关键问题走人工或工具校验(订单/退款必须查实时系统)

12)Agent + 工具调用(MCP/标准化)的工程化要点

核心:把"模型调用外部系统"的能力做成可治理的工具层。

  • 工具标准化:
    • 工具描述(name/description/input schema/output schema)
    • 统一协议(可借鉴 MCP 思路:客户端-服务器架构、可扩展工具清单)
  • 权限与隔离:
    • 工具调用绑定用户身份(userId、scope)
    • 细粒度授权:只能查"本人订单"
  • 可靠性:
    • 超时、重试、熔断(Resilience4j)
    • 幂等(发券/改地址要 idempotency key)
  • 审计与合规:
    • 工具调用日志(入参脱敏、结果摘要、traceId)
    • 风控规则:频率限制、黑名单、敏感操作二次确认

典型"Agentic RAG"

  • 先 RAG 找到政策
  • 再调用工具查订单状态
  • 最后生成带引用、带实时数据的答复

到这里,小白可以按"内容流分页→缓存→消息→微服务稳定性→安全→RAG/Agent"完整走一遍大厂后端常见链路,把每个点都能落到工程实现。

相关推荐
Bat U1 小时前
JavaEE|多线程(六)
java·java-ee
Jackyzhe1 小时前
从零学习Kafka:生产者分区机制
分布式·学习·kafka
胡利光2 小时前
Context Engineering 实战 02|System Prompt 是架构决策,不是写说明书
java·架构·prompt
sinat_255487812 小时前
数组·学习笔记
java·javascript·笔记
江离w2 小时前
codex等vibe coding初始化后端项目指令
java
Paxon Zhang2 小时前
JavaEE 初阶大师之路之*线程,多线程编程,Thread类,变量捕获,中断线程* 一文全部搞懂!!
java·java-ee
xdscode2 小时前
Spring Boot Actuator 接入与运维实践指南
spring boot·后端·actuator
逻辑驱动的ken2 小时前
Java高频面试考点场景题16
java·开发语言·面试·职场和发展·求职招聘
DukeMr.Lee2 小时前
有声书实现
java·开发语言