面试突击:口述原理、项目包装与亮点提炼
面试突击:口述原理、项目包装与亮点提炼
一、自我介绍模板
1.1 结构
自我介绍 = 基本信息 + 技术栈 + 项目经验 + 个人亮点
时间控制:1~3 分钟
1.2 示例
面试官好,我叫 XXX,X 年 Java 后端开发经验。
技术方面,我主要使用 SpringBoot + SpringCloud Alibaba 技术栈,
熟悉 Nacos 服务治理、Sentinel 限流熔断、Gateway 网关、OpenFeign 远程调用。
分布式方面有 Seata 分布式事务和 RabbitMQ 的实际使用经验。
数据库熟悉 MySQL 调优和分库分表思想,缓存使用 Redis + Redisson 解决分布式锁问题。
最近做的项目是 XXX(一句话介绍项目),
我主要负责 XXX 模块,解决了 XXX 问题(亮点)。
我希望能在一个技术氛围好的团队持续成长,谢谢。
1.3 注意事项
- 不要背简历:面试官手里有你的简历
- 不要说"精通":用"熟悉"、"了解"、"有实践经验"
- 引导面试官:提到的技术和项目是你准备好的,引导对方往你熟悉的方向问
- 自信但谦虚:"我对 XXX 有一定理解,但也在持续深入学习中"
二、项目包装
2.1 项目描述模板
项目背景:做什么的,服务什么用户
技术栈:用了什么技术,为什么选这些技术
我的职责:负责哪些模块,解决了什么问题
项目成果:数据指标(QPS 提升 XX%、RT 降低 XX%、减少了 XX 故障)
2.2 把普通项目包装出彩
普通描述 vs 包装后的描述
| 普通描述 | 包装后 |
|----------|--------|
| 做了个商城项目 | 做了一个高并发电商系统,支撑日活 10 万用户,峰值 QPS 5000+ |
| 用了 Redis 做缓存 | 引入 Redis 缓存层,将热点商品查询 RT 从 200ms 降低到 5ms,缓存命中率 95%+ |
| 做了防超卖 | 通过 Redisson 分布式锁 + Redis 预扣库存,解决并发场景下的库存超卖问题 |
| 用了 MQ | 通过 RabbitMQ 异步解耦订单流程,将下单响应时间从 2s 降低到 200ms |
| 做了日志记录 | 搭建基于 AOP 的统一日志链路,配合 TraceId 实现全链路追踪 |
2.3 项目亮点提炼公式
亮点 = 问题场景 + 技术方案 + 对比效果
示例:
场景:秒杀场景下库存超卖
方案:Redisson 分布式锁 + Redis 预扣库存 + Lua 脚本原子操作
效果:从超卖到零超卖,QPS 提升 10 倍
三、高频八股文口述模板
3.1 Redis 分布式锁
问:Redis 分布式锁怎么实现?
答:
1. 用 SETNX 命令加锁,只有第一个能设置成功
2. 设置过期时间防止死锁(EX 参数)
3. 释放锁时用 Lua 脚本保证原子性,先判断是不是自己的锁再删除
4. Redisson 的看门狗机制:后台线程自动续期,默认 30 秒,每 10 秒续一次
5. 可重入锁用 Hash 结构实现,key 是锁,field 是线程 ID,value 是计数器
追问:Redis 集群下有问题吗?
答:
有。Redis 主从切换时可能丢失锁(主节点加了锁还没同步到从节点就挂了,新主节点没有锁)。
解决:RedLock 算法,在多个独立的 Redis 实例上分别加锁,大部分成功就认为加锁成功。
但实际上 RedLock 也有争议,最稳妥的还是用 ZooKeeper/etcd 做分布式锁。
3.2 缓存一致性
问:数据库和缓存怎么保持一致?
答:
常用的方案是"先更新数据库,再删除缓存"(Cache-Aside Pattern)。
为什么是删除而不是更新缓存?因为更新缓存可能有并发写问题,而且如果缓存计算逻辑复杂的话更新代价大。
为什么不是先删缓存再更新 DB?因为有并发问题:
线程 A 删了缓存 -> 线程 B 读缓存未命中,查 DB 旧数据写入缓存 -> 线程 A 更新 DB -> 缓存和 DB 不一致
这个方案也不是 100% 一致,存在短暂不一致的窗口。
如果对一致性要求高,可以用 Canal 监听 MySQL binlog,异步删除缓存,配合重试机制保证最终一致性。
3.3 MySQL 索引
问:为什么用 B+ 树做索引?
答:
1. B+ 树非叶子节点只存索引不存数据,单页能存更多键值,树更矮(通常 3 层就能存千万级数据)
2. 叶子节点用链表连接,范围查询效率高(B 树需要中序遍历)
3. B+ 树查询效率稳定,所有数据都在叶子节点
追问:聚簇索引和非聚簇索引的区别?
答:
聚簇索引:叶子节点存整行数据,InnoDB 按主键建聚簇索引
非聚簇索引(二级索引):叶子节点存主键值,需要回表查完整数据
覆盖索引:如果查询的字段都在索引中,就不用回表,这叫覆盖索引
3.4 SpringBoot 自动装配原理
问:SpringBoot 自动装配是怎么实现的?
答:
核心是 @SpringBootApplication 注解,它包含三个注解:
1. @SpringBootConfiguration:标识这是个配置类
2. @ComponentScan:扫描当前包及子包
3. @EnableAutoConfiguration:自动装配的核心
@EnableAutoConfiguration 通过 @Import 导入 AutoConfigurationImportSelector,
它会读取 META-INF/spring.factories 文件(2.7+ 是 AutoConfiguration.imports),
里面列了所有自动配置类。
每个自动配置类用 @Conditional 注解判断条件(比如 classpath 下有某个类才生效),
满足条件就把 Bean 注册到 IoC 容器。
自定义 Starter 三步:
1. 写自动配置类,用 @Conditional 控制
2. 写 spring.factories,注册配置类
3. 打成 Jar 包,别人引入依赖就能用
3.5 Sentinel 限流熔断
问:Sentinel 怎么限流的?
答:
Sentinel 基于滑动窗口统计资源的 QPS/线程数/异常比例,
达到阈值后根据策略拒绝请求(直接拒绝、Warm Up 预热、匀速排队)。
熔断是基于熔断器的状态机:
CLOSED -> 正常放行,统计异常比例
OPEN -> 达到阈值后打开,所有请求直接拒绝
HALF_OPEN -> 等待窗口过后,放行一个请求探测
成功 -> CLOSED 恢复
失败 -> OPEN 继续熔断
生产上我们把规则持久化到 Nacos,通过配置中心动态修改限流规则。
3.6 MQ 消息可靠性
问:怎么保证消息不丢失?
答:
从三个环节保证:
生产者环节:
开启 Publisher Confirm 确认消息到达 Exchange
开启 Return Callback 确认消息路由到 Queue
消息落本地消息表,定时任务补偿
MQ 环节:
队列持久化 + 消息持久化
集群部署
消费者环节:
手动 ACK(处理完业务再确认)
处理失败走死信队列
消费幂等(消息 ID 去重)
3.7 Seata AT 模式
问:Seata AT 模式怎么工作的?
答:
AT 模式是 2PC 的改进版,通过自动生成 undo log 实现零侵入的分布式事务。
一阶段:
执行业务 SQL 前,先查询 before image
执行业务 SQL
再查询 after image
把 before/after image 存到 undo_log 表
本地事务提交(不阻塞)
二阶段提交:
异步删除 undo log
二阶段回滚:
用 undo_log 中的 before image 生成反向 SQL 恢复数据
校验 after image 和当前数据是否一致(防止覆盖其他事务的修改)
关键是用全局锁防止并发冲突。
四、项目亮点清单(可直接使用)
以下是可以直接套用到项目中的亮点,选择 2~3 个即可,不要贪多:
4.1 性能优化类
亮点 1:缓存优化
背景:商品详情接口 RT 200ms,DB 压力大
方案:引入 Redis 多级缓存(本地 Caffeine + Redis),缓存穿透用布隆过滤器
效果:RT 降低到 5ms,DB QPS 降低 90%
亮点 2:异步化改造
背景:下单接口同步调用短信/邮件服务,RT 2s
方案:通过 RabbitMQ 异步发送通知,核心链路解耦
效果:下单 RT 从 2s 降到 200ms,提升 10 倍
亮点 3:接口限流
背景:活动期间突发流量打垮服务
方案:Gateway 层按 IP 限流 + Sentinel 接口级限流 + Warm Up 冷启动
效果:系统稳定性提升,活动期间零宕机
4.2 高可用类
亮点 4:分布式锁解决超卖
背景:秒杀场景并发下库存超卖
方案:Redisson 分布式锁 + Redis 预扣库存 + Lua 原子操作
效果:零超卖,支撑 3000 QPS
亮点 5:分布式事务
背景:下单涉及订单/库存/账户三个服务,数据不一致
方案:Seata AT 模式保证强一致性,配合重试机制
效果:分布式事务成功率 99.9%+
亮点 6:服务降级
背景:下游服务不可用拖垮上游
方案:Sentinel 熔断降级 + Feign fallback 兜底
效果:下游故障不影响核心链路
4.3 工程化类
亮点 7:全链路追踪
背景:线上问题排查困难,跨服务调用链路不清晰
方案:Gateway 生成 TraceId,通过 Header 传递 + MDC 绑定,日志全链路串联
效果:排查时间从小时级降到分钟级
亮点 8:接口幂等
背景:网络重试导致订单重复创建
方案:Token 机制 + Redis Lua 原子校验 + 数据库唯一索引
效果:零重复订单
亮点 9:统一异常处理
背景:各服务异常处理不一致,前端体验差
方案:@RestControllerAdvice + 自定义异常枚举 + 错误码规范
效果:错误提示标准化,前端统一处理
五、面试回答技巧
5.1 STAR 法则
S(Situation):什么场景下遇到了什么问题
T(Task):你的任务是什么
A(Action):你做了什么(技术方案、选择理由)
R(Result):结果如何(数据指标)
示例:
S:我们做秒杀活动时,发现并发场景下库存会超卖
T:我需要解决这个问题,保证库存不超卖
A:我调研了几种方案,最终选了 Redisson 分布式锁...
R:上线后零超卖,支撑了 3000 QPS 的并发
5.2 不会的问题怎么回答
❌ 错误:不知道/没用过
✅ 正确:
"这个我没在实际项目中使用过,但我的理解是..."(说你知道的部分)
"我们项目用的是 XXX 方案,原理是..."(引导到你会的方向)
"这个我了解不深,但我对相关的 XXX 有一定研究"(主动引导)
5.3 反问环节
好问题:
"团队的技术栈是什么?"
"我如果加入的话主要负责哪个模块?"
"团队对新技术的态度是怎样的?"
"目前项目最大的技术挑战是什么?"
不要问:
"加班多吗?"(等 HR 面再问)
"你们公司是做什么的?"(面试前应该查过)
六、面试前准备清单
技术准备:
[ ] Redis:分布式锁、缓存一致性、持久化、主从、哨兵
[ ] MySQL:索引结构、事务隔离、慢查询优化、分库分表
[ ] SpringBoot:自动装配、AOP、事务、拦截器
[ ] SpringCloud:Nacos、Gateway、Sentinel、OpenFeign、Seata
[ ] RabbitMQ:交换机、确认机制、死信队列、消息丢失/重复/积压
[ ] JVM:内存结构、GC 收集器、OOM 排查、Arthas
[ ] 分布式:雪花算法、限流算法、幂等性、定时任务
项目准备:
[ ] 准备 1~2 个能深入讲的项目
[ ] 每个项目准备 2~3 个技术亮点
[ ] 能说出每个技术选型的"为什么"
[ ] 能画出核心流程图(口述即可)
软技能准备:
[ ] 1 分钟自我介绍
[ ] 准备反问问题
[ ] 了解目标公司和业务

浙公网安备 33010602011771号