三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

产业互联网大厂Java面试实录:JDK17、Redis分布式锁、Kafka订单削峰、Seata分布式事务、Spring AI+RAG智能供应链助手,谢飞机三轮被虐哭(附完整答案解析)

产业互联网大厂Java面试实录:JDK17、Redis分布式锁、Kafka订单削峰、Seata分布式事务、Spring AI+RAG智能供应链助手,谢飞机三轮被虐哭(附完整答案解析)

产业互联网大厂Java面试实录:JDK17、Redis分布式锁、Kafka订单削峰、Seata分布式事务、Spring AI+RAG智能供应链助手,谢飞机三轮被虐哭(附完整答案解析)

一、面试开场

面试官老K(推了推金丝眼镜,面前摆着一沓厚厚的简历):你好,我是产业互联网事业部技术负责人老K,今天面试的是资深Java开发岗。我们平台连接上下游工厂、经销商、物流、仓储,日处理订单千万级,你先做个自我介绍吧。

谢飞机(穿着格子衫,背着一个印着「Hello World」的帆布包,紧张地搓手):面试官好,我叫谢飞机,花名「Bug制造机」,五年Java经验,精通……精通「重启大法」和「CV大法」,擅长把能跑的代码改到不能跑……

老K(嘴角抽搐):……行,那我们直接开始吧。


二、第一轮 · 筑基期(核心语言与工程基础)

老K:我们产业互联网平台有大量老旧系统,正在做技术升级。第一个问题,你平时用哪个版本的JDK?JDK 8、11、17有什么区别?为什么Spring Boot 3.x强制要求JDK 17?

谢飞机:我……我平时用JDK 8,公司老项目都是8。8到11到17,嗯……数字越大越新嘛!8是经典款,11是……是「三分糖去冰奶茶」,17是「一起发」,图个吉利!Spring Boot 3.0强制JDK 17,那肯定是因为……因为17比较贵?显得公司有排面!

老K(额头冒出青筋):……下一个问题。线上有一台订单服务OOM了,你怎么办?

谢飞机:OOM啊?简单!先重启,不行就加内存,256G拉满!再不行就……就换一台更大的机器!

老K:……那如果重启之后又OOM了呢?

谢飞机:那就再重启!重启解决不了的问题,就说明……说明该换工作了!

老K(深呼吸):……行吧,下一个。你们的项目用Maven还是Gradle?遇到过依赖冲突吗?怎么解决?

谢飞机:用Maven,报错就mvn clean,还报错就mvn clean install,还报错就……删依赖!谁报错删谁!把同事写的代码也删了,世界就清净了。

老K(手已经开始抖了):……好的,进入第二轮。


三、第二轮 · 历劫期(中间件与分布式核心)

老K:我们的供应链系统有订单、库存、结算、物流多个服务,数据库层你们用MyBatis还是JPA?为什么?

谢飞机:这个我知道!MyBatis!因为「JPA一时爽,排查火葬场」!MyBatis SQL自己写,看得见摸得着,就像自己做的饭,难吃也知道难吃在哪。

老K(难得点了点头):嗯,这个回答还算有点道理。那连接池呢?HikariCP、C3P0、Druid你了解吗?为什么HikariCP是默认首选?

谢飞机:HikariCP!名字短加载快!C3P0名字像科幻电影机器人,Druid像游戏里的德鲁伊!反正我用HikariCP,因为它……因为它快!

老K:……快在哪你知道吗?

谢飞机:快在……快在名字短,打字快!

老K(血压飙升):下一个!我们大促时库存扣减经常超卖,你会怎么做?

谢飞机:加锁!Redis分布式锁!setnx一把梭!先setnx lock 1,拿到锁就扣库存,完事del lock,完美!

老K:那如果拿到锁的服务挂了,锁永远不会释放怎么办?

谢飞机:啊这……那就……那就等它挂完再重启,重启之后锁就没了!

老K:……那如果锁提前过期了,别的线程拿到锁,两个线程同时扣库存呢?

谢飞机:啊?还有这种事?那……那说明锁也想下班了!

老K(手捂住胸口):……行,缓存呢?缓存穿透、击穿、雪崩怎么解决?

谢飞机:这个我会!背过!穿透用「布隆过滤器+缓存空值」,击穿用「互斥锁+逻辑过期」,雪崩用「过期时间加随机值+多级缓存」!口诀是「防空、加锁、错峰」!

老K(惊讶):哟,这个背得挺熟!不错,继续加油。

谢飞机(得意地翘起二郎腿):那是,我可是背了三天三夜!

老K:……下一个,我们订单量高峰时数据库扛不住,用Kafka削峰,怎么保证消息不丢失?

谢飞机:Kafka是「King」!王者不丢消息!大厂产品怎么会丢呢?不会丢的!

老K:……如果Broker宕机了呢?

谢飞机:那就……那就说明它累了,重启一下就好了!

老K(深呼吸):最后一个,下单、扣库存、减余额、加积分,跨服务怎么保证数据一致性?

谢飞机:Seata!撒点海盐就一致了!Seata有四种模式,AT、TCC、SAGA、XA,就像……就像四种口味的薯片,海盐味、烧烤味、番茄味、原味!我全都要!

老K:……那AT模式底层原理是什么?

谢飞机:AT就是……就是「啊他」!啊,他帮我搞定了!

老K(已经说不出话了):……好的,进入第三轮。


四、第三轮 · 飞升期(实时通信与AI应用)

老K:我们平台有百万台工厂设备需要实时上报状态,前端要实时看到设备监控大屏,用什么方案?

谢飞机:WebSocket!长连接!百万连接?简单!for循环挨个发消息!一台服务器发不完就……就发两遍!

老K:……百万连接你一台服务器扛得住?内存够吗?

谢飞机:不够就……就加内存!256G拉满!再不行就上「分布式for循环」,每台服务器各发各的!

老K(冷笑):……那你告诉我,服务端怎么知道消息该发给哪台设备?

谢飞机:啊这……发给所有设备!让设备自己认领!谁的数据谁拿!

老K(彻底无语):……最后一个方向,我们想做一个供应链智能助手,让上下游企业用自然语言查库存、查订单、问物流,你怎么做?

谢飞机:这个我会!Spring AI!ChatClient用起来跟JdbcTemplate一个味儿!然后RAG,先搜后答!把企业文档、订单数据向量化存到向量数据库,用户问问题先做语义检索,再丢给大模型生成答案!

老K(眼睛一亮):哦?这个说得不错!那向量数据库你选什么?

谢飞机:Milvus!大数据量、高并发就选它!小项目用Chroma,Redis Stack也能做向量检索,便宜够用!Embedding可以用OpenAI的,也可以用Ollama本地部署,数据不出域!

老K(点头):可以,那MCP是什么?

谢飞机:MCP就是「AI界的USB-C」!统一接口标准!AI想调哪个工具就调哪个工具,插上就能用!像咱们的订单系统、库存系统,只要实现MCP协议,AI就能直接调用!

老K(难得露出笑容):那Agentic RAG和普通RAG有什么区别?

谢飞机:普通RAG是「先搜后答」,一条直线;Agentic RAG是「AI侦探」!先搜,答案不够就再搜,还能调工具查实时数据,反复推理直到找到答案!就像侦探查案,线索不够就继续查!

老K(鼓掌):不错!最后一个问题,AI会一本正经地胡说八道,也就是幻觉,怎么解决?

谢飞机:这个我知道!幻觉只能缓解,不能消除!第一,RAG给足上下文,让它「有据可依」;第二,提示词约束,让它「不知道就说不知道」;第三,温度参数调低;第四,输出做校验;第五,引用溯源,答案带出处;第六,人工兜底审核!

老K(沉默片刻,看了看手表):好了,今天的面试就到这里。你回去等通知吧。

谢飞机(眼睛一亮):太好了!这已经是我集齐的第七张「等通知」卡片了!再集一张就能召唤神龙了!

老K(小声嘀咕):……你回去记得把HikariCP的FastList、Redisson看门狗、Kafka的acks=all、Seata AT原理、JWT黑名单背一下,下次面试用得上。

谢飞机(边收拾包边嘟囔):HikariCP……FastList……看门狗……这是啥啊……算了,先点个外卖压压惊。

彩蛋:三个月后,谢飞机靠着本文的答案解析,成功入职了竞品产业互联网公司,成了老K的对手公司的技术骨干。


五、文末答案解析(小白学习版,16大考点)

考点1:JDK 8/11/17特性对比与选型

| 版本 | 核心特性 | 适用场景 | |------|---------|---------| | JDK 8 | Lambda、Stream、Optional、新日期API、默认方法 | 存量系统维护,生态最成熟 | | JDK 11 | 新增String API、HTTP Client、ZGC实验、Epsilon垃圾回收器 | 中间版本,LTS,云厂商主流 | | JDK 17 | 密封类、模式匹配、Switch表达式增强、ZGC转正、Spring Boot 3.x强制 | 新项目首选,Spring Boot 3.x要求 |

选型建议:新项目直接JDK 17 + Spring Boot 3.x;老项目至少升级到11,最终向17看齐。

考点2:JVM内存分区与OOM排查四板斧

内存分区:堆(对象实例)、虚拟机栈(栈帧,局部变量)、本地方法栈、方法区/元空间(类元数据)、程序计数器。

OOM排查四板斧口诀

  1. jps找进程PID
  2. jmap -dump:format=b,file=heap.hprof <pid>导出堆快照
  3. jstack <pid>看线程栈,找死锁、高CPU线程
  4. 用MAT分析堆快照,找「内存泄漏嫌疑人」——大对象、集合膨胀、未释放连接

考点3:Maven/Gradle依赖冲突四板斧

  1. mvn dependency:tree查看依赖树
  2. mvn dependency:analyze分析未使用/重复依赖
  3. 使用exclusion排除冲突传递依赖
  4. 引入BOM(Bill of Materials)统一管理版本,如 Spring Cloud BOM

考点4:MyBatis vs JPA + HikariCP核心原理

MyBatis:SQL手写,灵活可控,适合复杂查询、报表、产业互联网的多表联查场景;缺点是要自己维护SQL。

JPA/Hibernate:对象关系映射,开发快,但复杂查询容易产生N+1问题(查1条主记录再查N条关联),排查困难。

HikariCP为什么快

  • FastList:自定义ArrayList,优化get()移除操作,避免ArrayList.remove()的从头扫描
  • ConcurrentBag:无锁读设计,借还连接性能极高
  • 字节码精简、无反射代理,启动更快

考点5:缓存穿透/击穿/雪崩对比表

| 问题 | 现象 | 解决方案 | |------|------|---------| | 穿透 | 查不存在的key,直接打DB | 布隆过滤器 + 缓存空值(短TTL) | | 击穿 | 热点key过期瞬间大量请求打DB | 互斥锁 + 逻辑过期(异步重建) | | 雪崩 | 大量key同时过期 | 过期时间加随机值 + 多级缓存(本地+Redis) |

口诀:防空(穿透)、加锁(击穿)、错峰(雪崩)。

考点6:Redis分布式锁三大坑 + Redisson看门狗

三大坑

  1. setnx后进程崩溃,锁永不释放 → 必须设置过期时间(set key value NX EX
  2. 锁提前过期,A还没执行完,B拿到锁 → 用看门狗自动续期
  3. A删锁时误删B的锁 → value用UUID,删除前先比较(Lua脚本保证原子性)

Redisson看门狗机制:默认30秒有效期,每10秒自动续期,只要业务没执行完,锁就不会过期;服务宕机后锁自然过期释放,避免死锁。

考点7:Kafka三环节不丢失保障

生产者端acks=all(所有副本确认)+retries重试 + 幂等(enable.idempotence=true

Broker端min.insync.replicas=2(至少2个副本同步)+replication.factor=3(副本数≥3)

消费者端:手动提交offset(业务处理成功后再提交)+ 消费幂等(用唯一业务ID去重)

考点8:分布式事务四方案选型

| 方案 | 原理 | 适用场景 | |------|------|---------| | 2PC/XA | 两阶段提交,强一致 | 短事务、跨库操作少 | | TCC | Try-Confirm-Cancel,业务补偿 | 资金类、需要灵活控制 | | 可靠消息最终一致 | MQ + 本地消息表 | 下单、积分等异步场景 | | Seata AT | 自动生成回滚SQL,无侵入 | 微服务多库事务首选 |

Seata AT原理:事务开始记录「前镜像」,提交前记录「后镜像」,失败时根据镜像自动生成反向SQL回滚,业务代码零侵入。

考点9:注册中心CAP对比

  • Eureka:AP,集群节点互相注册,不选举,网络分区时优先可用性
  • Nacos:CP+AP切换,支持配置中心+注册中心,默认AP(临时实例)/CP(持久实例)
  • Consul:CP,强一致,Raft协议,支持多数据中心

考点10:WebSocket百万连接架构

  1. Netty作为通信底座,NIO非阻塞,单机可支撑数万连接
  2. ChannelGroup管理连接,避免for循环全量发送
  3. 粘性会话:网关层保证同一设备的WebSocket请求路由到同一节点
  4. Redis Pub/Sub:跨节点广播消息,设备在哪个节点都能收到
  5. 心跳机制:定期ping/pong,清理死连接

考点11:可观测性三件套

  • 指标(Metrics):Prometheus采集 + Grafana可视化,监控QPS、延迟、错误率
  • 日志(Logs):ELK Stack(Elasticsearch + Logstash + Kibana),Logback/SLF4J输出结构化日志
  • 链路追踪(Traces):Jaeger/Zipkin,配合Micrometer + Spring Cloud Sleuth,排查跨服务调用

考点12:JWT痛点与双Token方案

痛点:JWT无状态,服务端无法主动让Token失效;泄露后有效期内的Token无法作废。

方案:Access Token(短期,15分钟)+ Refresh Token(长期,7天)+ Redis黑名单(登出/改密时加入黑名单,拦截失效Token)。

考点13:Spring AI核心能力表

| 能力 | 说明 | |------|------| | ChatClient | 统一对话客户端,类似JdbcTemplate | | Embedding | 文本向量化,接入OpenAI/Ollama模型 | | Function Calling | 大模型调用Java方法(工具执行框架) | | ChatMemory | 会话记忆,多轮对话上下文管理 | | Advisors | 提示填充、RAG检索增强、安全过滤 |

考点14:RAG离线/在线双阶段全流程

离线阶段(知识入库):文档加载 → 切片 → Embedding向量化 → 存入向量数据库(Milvus/Chroma/Redis)

在线阶段(问答):用户问题 → Embedding向量化 → 语义检索TopK → 拼接Prompt(提示填充)→ 大模型生成带引用的答案

向量数据库选型:Milvus(海量高并发)、Chroma(轻量开发)、Redis Stack(复用Redis基础设施)。

考点15:MCP三大原语 + A2A + Agentic RAG

MCP(模型上下文协议)

  • tools/list:列出AI可用的工具
  • tools/call:AI调用工具
  • resources:暴露数据资源

定位:AI界的USB-C,统一工具调用标准化,让AI能接入任意系统(订单、库存、物流)。

A2A(Agent-to-Agent):智能体之间通信协议,多个Agent协作完成复杂工作流。

Agentic RAG vs 普通RAG:普通RAG「搜一次答一次」;Agentic RAG用ReAct循环(推理→行动→观察→再推理),检索不足时自动调工具、多轮检索,像侦探一样追查答案。

考点16:AI幻觉本质与6大缓解手段

本质:大模型基于概率生成文本,对不确定的知识会「编造」,且无法彻底消除。

6大缓解手段

  1. RAG检索增强,给足上下文
  2. 提示词约束「不知道就说不知道」
  3. 降低temperature参数
  4. 输出校验/规则过滤
  5. 答案引用溯源,附文档出处
  6. 人工审核兜底(高风险场景)

后记:本文为系列面试实录之一,关注我,看谢飞机如何集齐七张「等通知」卡片召唤神龙 🐉,也祝各位读者面试都能拿到满意的Offer!

← 返回列表