互联网大厂Java面试实录:从SpringBoot到分布式秒杀系统
互联网大厂Java面试实录:从SpringBoot到分布式秒杀系统
面试场景介绍
某互联网大厂后端开发岗位面试现场,面试官张工(资深架构师),候选人谢飞机(自称"全栈开发工程师")。
第一轮:基础框架与数据库(共4题)
张工:你好,先简单介绍一下你自己,重点说说最熟悉的技术栈。
谢飞机:咳咳,我是谢飞机,江湖人称"谢半桶水",主要精通Java、Python、Go...啊不,主要是Java!SpringBoot用得贼溜,数据库也会一点点MySQL...
张工:好,那我们从基础开始。你简历上写熟练使用SpringBoot,请解释一下@SpringBootApplication注解包含了哪些核心注解?
谢飞机:这个简单!@SpringBootApplication就是三个注解的组合嘛——@Configuration、@EnableAutoConfiguration、@ComponentScan,相当于告诉Spring"这里有个配置类,自动扫描组件,自己找配置文件"!
张工:不错,回答正确。那如果是电商秒杀场景,如何保证库存数据的准确性?
谢飞机:嗯...可以用数据库的乐观锁或者悲观锁呗,在update的时候加个where版本号...哦对,还有Redis预减库存!
张工:很好,知道Redis了。那Redis的持久化机制有哪几种?各自优缺点是什么?
谢飞机:这个...好像是RDB和AOF吧?RDB是快照,AOF是日志记录...哪个快我不太记得了,反正都用过...
张工:基本概念对了,但细节还需要加强。最后一个问题,MyBatis的一级缓存和二级缓存有什么区别?
谢飞机:一级缓存是SqlSession级别的,用完就没了;二级缓存是Mapper级别的,可以共享...具体怎么配置我想想...有点模糊了...
张工:好,基础部分就先这样,我们进入下一轮。
第二轮:微服务与中间件(共4题)
张工:假设你的秒杀系统部署在Kubernetes集群中,请说明服务注册与发现的工作原理。
谢飞机:这个...就是用Eureka或者Nacos对吧?服务启动时注册中心,消费者通过注册中心获取提供者列表...
张工:没错。如果某个商品秒完单后,订单系统需要异步处理物流信息,你会选择什么方案?
谢飞机:消息队列嘛!用Kafka或者RabbitMQ,生产者发消息,消费者消费,解耦...
张工:很好。那如果消息消费失败了怎么办?如何保证消息的可靠性投递?
谢飞机:失败的话就重试呗...手动ack还是自动ack...这个记不太清了,反正有重试机制...
张工:再问一个实际的,Spring Cloud中OpenFeign和RestTemplate的区别是什么?
谢飞机:这个我知道!OpenFeign是基于动态代理的声明式调用,RestTemplate是编程式的...OpenFeign更优雅一些...
张工:回答准确。最后一个,分布式事务如何解决?你了解Seata吗?
谢飞机:呃...Seata好像是阿里巴巴开源的?TCC模式两阶段提交...具体原理我研究得不多...
张工:好,微服务部分到此为止,我们聊聊高并发场景。
第三轮:实战场景与系统设计(共4题)
张工:如果现在要你设计一个支持百万并发的秒杀系统,请画出整体架构图并说明关键技术点。
谢飞机:额...前端静态资源CDN加速,接口层做限流熔断,Redis预扣库存,MQ异步下单,数据库最终一致性...大概是这样...
张工:思路是对的。那具体来说,如何防止超卖?请详细说明你的实现方案。
谢飞机:这个...Redis原子操作decrement,数据库乐观锁version字段,还有Lua脚本保证原子性...应该够了吧...
张工:考虑比较全面。如果秒杀过程中出现热点商品,如何优化缓存策略?
谢飞机:本地缓存Caffeine配合分布式缓存Redis,多级缓存架构...不过热点key击穿的问题怎么处理我有点忘了...
张工:监控体系呢?如何快速定位线上故障?
谢飞机:Prometheus收集指标,Grafana展示,ELK分析日志,Jaeger链路追踪...这些我都用过...
张工:好的,技术方面就聊到这里。你觉得还有什么想补充的吗?
谢飞机:那个...我还会一点前端Vue和React,算不算加分项?
张工:哈哈,全栈确实有优势。今天的面试就到这里,结果会在3个工作日内通过邮件通知你,谢谢。
谢飞机:谢谢张工!希望能收到好消息!
面试答案解析与技术详解
一、SpringBoot核心注解详解
| 注解 | 功能说明 | |------|----------| | @SpringBootApplication | 组合注解入口 | | @Configuration | 标识配置类 | | @EnableAutoConfiguration | 开启自动装配 | | @ComponentScan | 组件扫描 |
二、库存数据准确性保障方案
// 方案1:数据库乐观锁
UPDATE product_stock
SET stock = stock - 1, version = version + 1
WHERE id = 1 AND stock > 0 AND version = ?;
// 方案2:Redis预扣库存
redis.decr("stock:1001"); // 原子操作
// 方案3:分布式锁
RLock lock = redissonClient.getLock("lock:product:1001");
lock.lock(10, TimeUnit.SECONDS);
try {
// 执行扣减逻辑
} finally {
lock.unlock();
}
三、Redis持久化机制对比
| 特性 | RDB | AOF | |------|-----|-----| | 存储方式 | 二进制快照 | 命令日志 | | 恢复速度 | 快 | 慢 | | 数据完整性 | 可能丢失 | 完整 | | 文件大小 | 小 | 大 |
四、MyBatis缓存机制
- 一级缓存:SqlSession级别,默认开启,同一会话内有效
- 二级缓存:Namespace级别,需手动配置,跨会话共享
五、秒杀系统完整架构图
用户请求 → CDN静态资源
↓
Nginx负载均衡
↓
API网关(限流/鉴权)
↓
┌──────────────────────┐
│ 前置过滤层 │
│ - 黑名单IP │
│ - 频率限制 │
│ - 验证码 │
└──────────────────────┘
↓
┌──────────────────────┐
│ 库存预扣层 │
│ - Redis原子操作 │
│ - Lua脚本 │
│ - 布隆过滤器防穿透 │
└──────────────────────┘
↓
┌──────────────────────┐
│ 消息队列缓冲 │
│ - Kafka/RocketMQ │
│ - 削峰填谷 │
└──────────────────────┘
↓
┌──────────────────────┐
│ 订单服务 │
│ - 创建订单 │
│ - 库存落库 │
└──────────────────────┘
↓
┌──────────────────────┐
│ 后续业务 │
│ - 支付 │
│ - 物流 │
│ - 通知 │
└──────────────────────┘
六、防止超卖的三道防线
- 第一道:Redis预扣 - 原子操作,快速拦截
- 第二道:数据库乐观锁 - 版本号校验,最终兜底
- 第三道:业务层幂等 - 防止重复下单
七、监控告警体系
| 层级 | 工具 | 作用 | |------|------|------| | 基础设施 | Prometheus | CPU、内存、磁盘 | | 应用性能 | SkyWalking/Jaeger | 链路追踪 | | 日志分析 | ELK Stack | 错误排查 | | 可视化 | Grafana | 仪表盘展示 |
给求职者的建议
- 基础知识要扎实:框架底层原理必须理解透彻
- 实战经验是关键:多参与真实项目,积累踩坑经验
- 系统化思维:能够画出架构图,理解各组件协作关系
- 持续学习:新技术层出不穷,保持学习能力
- 沟通表达能力:清晰表达技术方案,展现思考过程
本文基于真实面试场景改编,仅供学习交流,如有雷同纯属巧合
更多推荐

所有评论(0)