大厂Java面试实录:Spring Boot/Cloud、JVM、Redis、Kafka、MyBatis 到 RAG/Agent 的三轮连环问(含答案详解)

大厂Java面试实录:Spring Boot/Cloud、JVM、Redis、Kafka、MyBatis 到 RAG/Agent 的三轮连环问(含答案详解)

场景:某互联网大厂「内容社区 + 音视频 + AIGC 智能客服」业务线。

角色:严肃面试官(M),搞笑水货程序员小Y(Y)。

规则:三轮面试,每轮 3~5 题,问题有业务衔接、逐步加深。


第一轮:内容社区 + 音视频上传(基础能力核验)

Q1:登录态怎么做?JWT 放哪儿?

M: 你们社区要支持 App/Web 登录,后端 Spring Boot。你会怎么做登录态?JWT 放哪里?怎么刷新?

Y: JWT 嘛......就发给前端存起来。一般放 localStorage?然后每次请求带上。刷新......再发一个新的?

M:(皱眉)"存起来"不等于"安全"。你至少要说清楚 Web 与 App 的差异、XSS/CSRF 风险与刷新策略。

Y: 那我改口:放 Cookie?HttpOnly 的那种。刷新就......加个 refresh token?

M: 这回答终于像个后端了。继续。


Q2:Spring MVC 和 WebFlux 的选择:上传大文件、并发高怎么选?

M: 音视频上传比较大、并发也高。Spring MVC 和 Spring WebFlux 你怎么选?为什么?

Y: WebFlux 是异步的,肯定快,所以都用 WebFlux。

M:(摇头)"肯定快"属于面试大忌。什么时候 WebFlux 真有收益?什么时候反而更复杂?

Y: 呃......线程少的时候?I/O 多的时候?

M: 方向对了。你先记住:I/O 密集 + 非阻塞链路完整,WebFlux 才体现优势。


Q3:数据库表怎么设计?MyBatis/JPA 怎么选?

M: UGC 内容:帖子、评论、点赞、收藏。你给一个简化的表设计,并说下 MyBatis 和 JPA 怎么选。

Y: 表就:postcommentlike。点赞表就 user_id + post_id 做联合主键。MyBatis 比较灵活,JPA 自动化。

M: 还行。那你会加哪些索引?分页怎么做?

Y: 索引......给 post.created_time 加?分页就 limit offset

M:(叹气)基础题你可以,但"limit offset"在大表会翻车。下一轮我们就从这里加深。


Q4:连接池你用 HikariCP 还是 C3P0?为什么?

M: Spring Boot 默认 HikariCP,你了解原因吗?

Y: 因为快?

M:(点头)至少知道"快"。那快在哪里?

Y: 这个......实现比较优秀?锁少?

M: 好,知道大方向即可。进下一轮。


第二轮:高并发 feed + 消息队列 + 缓存(架构进阶)

Q1:社区首页 feed 流怎么做?缓存怎么用?

M: 首页 feed:关注的人发帖要快速出现。你用 Redis 怎么设计?用 Spring Cache 还是自己写?

Y: Redis 当然缓存帖子列表。Spring Cache 一加注解就好了,@Cacheable

M:(严肃)"注解一加就好了"是事故的起点。你要解释:

  1. 缓存 key 设计;2) 过期策略;3) 缓存击穿/穿透/雪崩;4) 写一致性。

Y: key 就 feed:userId,过期 5 分钟。击穿......加锁?穿透......布隆过滤器?雪崩......随机过期?一致性......最终一致。

M: 这题回答得不错,继续。


Q2:点赞高并发:如何防止重复点赞与计数不准?

M: 点赞 QPS 很高,怎么保证不重复点赞?计数怎么准?

Y: 数据库加唯一约束 user_id + post_id,重复插入就失败。计数用 update post set like_count=like_count+1

M: 你说的是"能跑",但在热点帖子上会被打爆。你会用 Redis 吗?

Y: 用 Redis set 存点赞用户?然后计数用 incr?

M: 对,这就是方向。那 Redis 和 DB 怎么对账?

Y: 定时任务同步?

M: 可以。记住要讲清楚"写路径"和"读路径"。


Q3:Kafka / RabbitMQ / Pulsar 选哪个?用于什么?

M: 你要做"发帖后异步生成封面、转码、审核、推送 feed",消息队列怎么选?

Y: Kafka 吞吐高,所以用 Kafka。

M:(追问)Kafka 的"至少一次"语义会导致什么问题?如何做到幂等?

Y: 会重复消费。幂等就......消费端判断一下?

M: 判断什么?用什么存?说不出来就扣分。

Y: 用 Redis 记录 messageId?如果处理过就跳过。

M: 可以,这是常见方案。更严谨的还有:业务唯一键 + 去重表 + 事务外盒(outbox)等。


Q4:链路追踪与监控怎么落地?

M: 微服务多了,怎么做监控告警?

Y: Prometheus + Grafana。链路追踪 Jaeger。

M: Micrometer 在哪里?日志怎么统一?

Y: Micrometer 采指标。日志用 ELK。

M: 这题回答不错。


第三轮:AIGC 智能客服(RAG/Agent + 工具调用 + 安全与工程化)

业务:社区新增"智能客服",用户问"视频上传失败怎么办""如何申诉封禁"。客服要能查企业知识库(SOP/FAQ),必要时调用内部工单系统。

Q1:你会如何设计一个 RAG(检索增强生成)链路?

M: 给我一个端到端 RAG 方案:从文档到回答。

Y: RAG 就是"先搜再问"。把文档丢进去,然后向量化,最后让大模型回答。

M:(严肃)太笼统。具体:文档怎么切分?embedding 用什么?向量库选什么?召回后怎么拼提示词?

Y: 切分就按段落......embedding 用 OpenAI?向量库用 Milvus?提示词就把内容塞进去。

M:(记录)你知道关键名词,但缺工程细节。继续。


Q2:Agent(智能代理)和"工具执行框架"怎么做?

M: 客服需要"查询订单状态/工单状态/用户封禁原因",这不是纯问答。你怎么让模型调用工具?

Y: 用函数调用。Spring AI 有工具调用。

M: 那"工具调用标准化"怎么保证?参数校验、权限、审计怎么做?

Y: 参数就校验一下......权限用 Spring Security?审计写日志。

M: 这题你答得还行,但不够系统。


Q3:怎么降低 AI 幻觉(Hallucination)?

M: 模型胡说八道怎么办?

Y: 提示词写严一点:不要编。

M: 只有提示词不够。你还要说:检索置信度阈值、引用来源、拒答策略、结构化输出校验。

Y: 那就加个阈值,检索不到就让它说"不知道"。然后把引用链接贴出来。

M: 方向正确。


Q4:聊天会话内存怎么存?如何做多租户隔离?

M: 客服要记住用户上下文(会话内存),你存哪?Redis?数据库?怎么做多租户?

Y: 存 Redis,key 带上 tenantId + userId。设置过期时间。

M:(点头)简单场景可行。复杂场景还要考虑:敏感信息脱敏、加密、访问审计。


Q5:你们要上生产:CI/CD、灰度、回滚怎么做?

M: 从提交代码到上线,你的流水线怎么设计?

Y: GitLab CI 或 Jenkins。打包 Docker,部署 Kubernetes。灰度......按比例发布?回滚就回到上一版镜像。

M: 可以。至少没把"手动 scp"当最佳实践。


面试结束

M: 今天先到这。你基础面还可以,但复杂问题需要更具体的落地细节。回去等通知,有结果我们会在一周内联系。

Y: 好的好的,我回去就把"幂等"和"RAG 切分"背熟......不是,研究透。


题目答案详解(按业务场景讲透,让小白能学会)

说明:以下为"标准可落地回答"。面试时不必全背,但要能讲清:为什么这样做、关键风险点、工程落地细节


第一轮详解:登录、Web 框架、ORM、连接池

1) 登录态:JWT + Spring Security + OAuth2(或自建)

业务场景:社区 App/Web 登录后,调用发帖、点赞等接口。

推荐方案(Web)

  • access_token(JWT)放 HttpOnly + Secure Cookie,降低 XSS 盗 token 风险。
  • 防 CSRF:
    • 若 Cookie 携带 token:使用 SameSite=Lax/Strict + CSRF Token(Spring Security 自带)
    • 或改为 Authorization Header(前端存内存/安全容器)以规避 CSRF,但要防 XSS。
  • refresh_token
    • 单独存放(也建议 HttpOnly Cookie),生命周期更长
    • 刷新时校验 refresh token、签发新 access token

推荐方案(App)

  • token 通常放系统安全存储(Keychain/Keystore)。

技术点

  • Spring Security 过滤器链:OncePerRequestFilter 解析 JWT,构造 Authentication
  • JWT 关键字段:sub(用户)、exp(过期)、jti(唯一 ID,便于吊销/黑名单)。
  • 吊销策略:Redis 黑名单(短期)/refresh token 旋转(长期)。

2) Spring MVC vs WebFlux:取决于链路是否"全异步/非阻塞"

业务场景:音视频上传大文件、并发较高。

  • Spring MVC(Servlet):线程模型直观,生态成熟。

    • 优点:对 JDBC/MyBatis 等阻塞式依赖兼容最好。
    • 缺点:高并发 I/O 时线程占用高。
  • Spring WebFlux(Reactor):适合 I/O 密集、连接数多、下游也是非阻塞(如 R2DBC、Reactive Redis、WebClient)。

    • 如果你用了阻塞 JDBC/MyBatis,却在 WebFlux 中调用,会把阻塞塞进事件循环/弹性线程池,复杂且收益变小。

结论(常见落地)

  • 上传服务可用 MVC + Nginx/对象存储直传(最常见、最稳)。
  • 若强需求长连接/高并发:WebFlux + 全链路 Reactive 才值得。

3) UGC 表设计、索引与分页

简化表

  • post(id, author_id, title, content, created_time, status, like_count, comment_count, ...)
  • comment(id, post_id, user_id, content, created_time, status, ...)
  • post_like(id, post_id, user_id, created_time) + 唯一约束 (post_id, user_id)

索引建议

  • post(author_id, created_time):查用户发布列表
  • post(created_time, id):按时间翻页
  • comment(post_id, created_time):帖子评论列表
  • post_like(post_id, user_id):去重与判断是否点过赞

分页建议

  • 小数据:limit offset 可以。
  • 大数据:用 游标分页/Keyset Pagination
    • where created_time < ? and id < ? order by created_time desc, id desc limit 20
    • 性能稳定,不会 offset 越大越慢。

MyBatis vs JPA

  • MyBatis:复杂 SQL、动态条件、性能可控。
  • JPA/Hibernate:开发效率高,但要避免 N+1、懒加载坑。
  • 大厂常见组合:核心链路 MyBatis,后台管理 JPA。

4) HikariCP 为什么是默认?

关键点

  • 性能好、实现精简、锁竞争少、连接获取快。
  • 配置合理即可:最大连接数、连接超时、泄漏检测。

第二轮详解:Feed、缓存、MQ、可观测

1) Feed 流:Redis Key 设计 + 三大问题

业务场景:关注的人发帖后,粉丝首页快速出现。

常见两类模式

  • 推模式(Fanout on write):发帖时把 postId 推到粉丝的 feed 列表(Redis ZSET/List)。读快写慢。
  • 拉模式(Fanout on read):读首页时现算关注列表 + 查帖子。写快读慢。

折中:大V用拉,小用户用推。

Redis Key

  • feed:{userId} -> ZSET(score=时间戳, value=postId)

缓存三大问题

  • 穿透:查不存在的 postId -> 布隆过滤器/空值缓存。
  • 击穿:热点 key 过期瞬间 -> 互斥锁/逻辑过期。
  • 雪崩:大量 key 同时过期 -> 过期随机化、分批预热。

一致性

  • 读路径优先:Redis miss -> DB -> 回填。
  • 写路径:DB 成功后删缓存(或更新缓存),并配合 MQ 异步修复。

2) 点赞高并发:Redis 去重 + 异步落库 + 对账

业务场景:热点帖子点赞 QPS 高。

推荐写路径

  1. Redis Set:SADD like:set:{postId} userId(返回 1 表示首次点赞)
  2. Redis 计数:INCR like:count:{postId}(或用 Hash)
  3. 发送 Kafka 消息:like_event(postId,userId,action)
  4. 消费端批量落库(MyBatis batch)

幂等

  • DB 层唯一约束 (post_id,user_id) 兜底
  • 消费端去重:Redis SETNX dedup:{eventId} 或去重表

对账

  • 定时任务把 Redis 计数与 DB 汇总对齐(以 DB 为准或以 Redis 为准取决于业务)

3) MQ 选型:Kafka / RabbitMQ / Pulsar

发帖后异步链路:转码、封面、审核、推送 feed。

  • Kafka:高吞吐、分区顺序、生态强(大数据)。适合日志/事件流。
  • RabbitMQ:路由灵活、延迟队列等,适合业务消息。
  • Pulsar:多租户、分层存储、队列/流一体。

至少一次语义问题

  • 可能重复消费 -> 必须幂等。

幂等常见做法

  • 业务唯一键(如 postId+action
  • 去重存储:Redis SETNX(带 TTL)、或 DB 去重表
  • Outbox 模式:业务写 DB 与消息记录同事务,异步投递,减少"写库成功但消息丢"的不一致。

4) 可观测:Micrometer + Prometheus + Grafana + ELK + Trace

  • 指标:Micrometer 埋点 -> Prometheus 抓取 -> Grafana 看板与告警。
  • 日志:SLF4J 门面 + Logback/Log4j2 实现;集中到 ELK。
  • 链路追踪:OpenTelemetry(或 Zipkin/Jaeger)串起 TraceId。

第三轮详解:RAG、Agent、工具调用、安全与工程化

1) RAG 端到端:文档加载 -> 切分 -> 向量化 -> 检索 -> 生成

业务场景:客服回答必须基于企业 SOP/FAQ,不能瞎编。

流程

  1. 文档加载:PDF/网页/Confluence/数据库(Spring AI 支持多种 DocumentLoader)
  2. 清洗:去导航、去噪、保留标题层级与来源 URL
  3. 切分(chunking)
    • 按标题/段落 + 最大 token(如 300~800 tokens)
    • 适当 overlap(如 50~100 tokens)减少上下文断裂
  4. 向量化(Embedding)
    • OpenAI / 本地 Ollama embedding 模型
  5. 向量库:Milvus/Chroma/Redis Vector(看规模与运维能力)
  6. 检索:相似度召回 topK + 过滤(租户/权限/文档类型)
  7. 重排(可选):用 reranker 提升相关性
  8. 提示填充(prompt stuffing)
    • system:约束必须基于引用回答
    • user:问题
    • context:检索片段 + 来源
  9. 输出:结构化(JSON)+ 引用来源

落地关键

  • 评估:命中率/可用率/拒答率
  • 版本:知识库增量更新(定时或事件驱动)

2) Agent + 工具执行框架:让模型"会办事"

业务场景:用户问"我账号为什么被封""工单进度"。需要调用内部系统。

设计要点

  • 工具(Tool)定义:
    • 名称、描述、入参 JSON Schema、出参结构
  • 工具调用标准化:
    • 统一网关/SDK
    • 参数校验(JSR-380/自定义校验)
    • 超时/重试/熔断(Resilience4j)
  • 权限:Spring Security + OAuth2(或 JWT)
    • 工具调用要带用户身份与租户信息
  • 审计:
    • 记录谁在何时调用了什么工具、输入输出摘要(注意脱敏)

Spring AI

  • 可用 Tool Calling 将方法暴露给模型;也可对接 MCP(模型上下文协议)/A2A 进行跨服务工具编排。

3) 降低幻觉:让模型"不会就说不会"

组合拳

  • 检索相似度阈值:低于阈值直接拒答或转人工
  • 强制引用:回答必须包含引用片段 ID/URL
  • 结构化输出校验:JSON Schema 校验失败就重试/拒答
  • 黑白名单与敏感词:避免越权回答
  • 小结:幻觉不是"提示词能解决的全部",要用工程约束。

4) 会话内存:Redis/DB + 多租户隔离

简单方案

  • Redis:chat:mem:{tenantId}:{userId}:{sessionId} TTL 30min
  • 存:最近 N 轮对话摘要(Summary Memory)而非全量,以控 token。

安全要点

  • 脱敏:手机号/身份证
  • 加密:敏感字段应用层加密(Bouncy Castle)
  • 审计与权限:租户隔离(tenantId 强制贯穿)

5) CI/CD:从代码到生产

  • Git 提交 -> CI(单测 JUnit5 + Mockito)
  • 构建:Maven/Gradle 打包
  • 镜像:Docker build + 扫描
  • 发布:Kubernetes 滚动/灰度(按流量比例)
  • 回滚:上一版本镜像 + 数据库变更用 Flyway/Liquibase 可回退策略
  • 观测:发布后关注 SLO、错误率、延迟、消费堆积。

文章小结(给小白的学习路线)

  1. 先补齐基础:Spring MVC、MyBatis、索引与分页、HikariCP。
  2. 再学并发与中间件:Redis 三大问题、Kafka 幂等、可观测体系。
  3. 最后上 AI 工程:RAG 切分与评估、Agent 工具调用、幻觉治理与权限审计。
相关推荐
benpaodeDD4 小时前
视频44——Tomcat标准输出流乱码问题
java·tomcat
2401_850491654 小时前
Bootstrap和OpenLayers结合开发的示例
jvm·数据库·python
Royzst4 小时前
集合进阶(Map集合)
java·前端·数据库
happymaker06264 小时前
LeetCodeHot100——1.两数之和(详细解答)
java·数据结构·学习·算法
fengxin_rou4 小时前
【Kafka 核心概念深度详解】:分区、消费者组、位点及存储消费实战指南
分布式·kafka
AI人工智能+电脑小能手4 小时前
【大白话说Java面试题 第60题】【JVM篇】第20题:垃圾收集算法和垃圾收集器有什么区别?
java·jvm·算法·面试
jran-4 小时前
Redis NoSQL&Redis架构&数据结构
数据库·redis·缓存
wand codemonkey4 小时前
(三十)web应用+【核心】+【规矩】+【原理】
java·开发语言·前端
逸Y 仙X4 小时前
文章三十三:Elasticsearch 文本分词器深入实战
java·大数据·elasticsearch·搜索引擎·全文检索