Java大厂面试真题:Spring Boot + Kafka + Redis 在电商场景下的实战应用

面试现场:谢飞机勇闯互联网大厂

面试官(严肃脸):请进。

谢飞机(推门撞到墙,扶了扶并不存在的眼镜):报、抱歉!电梯太滑......我是来面试Java开发的!

面试官:好,我们开始。你在简历上写了熟悉Spring Boot,能说说它是怎么实现自动配置的吗?

谢飞机 :这个我知道!是靠@SpringBootApplication注解,它里面有个@EnableAutoConfiguration,会去读META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,把一堆自动配置类加载进来!

面试官(微微点头):不错,那如果我想自定义一个Starter,该怎么做?

谢飞机 :呃......建个Maven项目,写个配置类,再注册到spring.factories里......啊不是,现在是.imports!然后别人引入依赖就能用了!

面试官:还行。那假设我们现在做一个秒杀系统,用户下单前要判断库存,你会怎么设计?

谢飞机 :用数据库啊!查一下stock > 0就扣减,简单明了!

面试官:高并发下呢?10万人同时抢100件商品?

谢飞机 :那......那我加个synchronized?或者用Redis先减库存!对,Redis原子操作DECR

面试官:有点思路了。如果Redis扣成功了,但数据库没扣成,怎么办?

谢飞机:呃......让老板赔钱?开玩笑的!可以用消息队列,比如Kafka,发个消息异步处理,失败就重试!

面试官:继续。如果订单创建后,要通知库存、物流、积分服务,你怎么保证最终一致性?

谢飞机:用Spring Cloud Alibaba的Dubbo?哦不对......用Spring Cloud Stream + Kafka,发事件!每个服务监听自己关心的topic!

面试官:如果消息丢了呢?

谢飞机:我......我让它多发几遍?或者消费者手动ACK?

面试官:还可以。最后一个问题:如何防止用户恶意刷单?

谢飞机 :加验证码!登录限制!IP限流!用Redis记录访问次数,比如INCR login:1.1.1.1,超过5次就封!

面试官(终于露出一丝微笑):回答得还算可以。这样吧,你先回去,等我们的通知。

谢飞机(激动):有戏!有戏!我一定在家等电话,24小时开机,连洗澡都带着手机!


真题解析:电商秒杀系统的架构设计

业务场景

电商平台在大促期间面临高并发请求,如"双11"秒杀活动。核心需求包括:

  • 高性能响应
  • 库存准确性
  • 订单最终一致性
  • 防刷与安全控制

技术点详解

1. Spring Boot 自动配置原理
  • @SpringBootApplication = @Configuration + @ComponentScan + @EnableAutoConfiguration
  • 自动配置类通过META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports注册
  • 条件化装配:@ConditionalOnClass, @ConditionalOnMissingBean等确保环境适配

应用场景 :简化第三方组件集成,如spring-boot-starter-data-redis自动配置LettuceConnectionFactory

2. 秒杀库存超卖问题

直接数据库扣减在高并发下会导致:

  • 数据库锁争抢(行锁、表锁)
  • 响应慢、连接池耗尽

解决方案

  • Redis预减库存 :利用DECR原子性,快速拦截无效请求
  • 内存标记:本地缓存标识商品是否已售罄,避免重复查Redis
  • RabbitMQ/Kafka削峰:异步处理订单,保护数据库
java 复制代码
// 示例:Redis扣库存
Long result = redisTemplate.execute((RedisCallback<Long>) connection -> 
    connection.decr(stockKey.getBytes())
);
if (result >= 0) {
    // 进入下单流程
} else {
    // 库存不足
}
3. 分布式事务与最终一致性

使用事件驱动架构(EDA)

  • 订单服务发布OrderCreatedEvent
  • 库存、物流、积分服务作为消费者订阅对应Topic
  • 消息中间件保障至少一次投递

补偿机制

  • 消费失败时重试(Kafka重试队列)
  • 定时对账任务修复不一致状态
4. 防刷限流策略
  • 接口级限流:使用Resilience4j或Sentinel,限制QPS
  • 用户维度限频 :Redis中以user_id为key计数,TTL=60s
  • 设备/IP识别:结合前端埋点与风控系统
  • 验证码挑战:高风险行为触发图形/短信验证码
java 复制代码
// 示例:Redis限流
String key = "limit:login:" + ip;
Long count = stringRedisTemplate.opsForValue().increment(key, 1);
if (count == 1) {
    stringRedisTemplate.expire(key, 1, TimeUnit.MINUTES);
}
if (count > 5) {
    throw new RuntimeException("请求过于频繁");
}
5. 微服务协同(Spring Cloud 实践)
  • 服务发现:Nacos/Eureka 注册订单、库存服务
  • 远程调用:OpenFeign 声明式调用
  • 熔断降级:Resilience4j 避免雪崩
  • 链路追踪:Jaeger + OpenTelemetry 记录全流程

架构图简析

复制代码
用户请求 → API网关(鉴权+限流)
         ↓
     Redis(库存预减)
         ↓
   Kafka(订单消息队列)
         ↓
订单服务 → 发布事件 → [库存|物流|积分]服务消费
         ↓
    MySQL持久化

总结

本场景综合考察了Java程序员对Spring生态、缓存、消息队列、分布式一致性、安全防护 的掌握程度。实际大厂面试中,不仅要求说出技术名词,更要能讲清为什么选这个方案、有没有替代方案、边界情况如何处理

建议学习路径:

  1. 掌握Spring Boot源码启动流程
  2. 动手搭建Kafka + Redis + MySQL的订单demo
  3. 使用JMeter压测并优化性能
  4. 学习Seata等分布式事务框架作为扩展

谢飞机虽然答得磕绊,但抓住了关键点。真正的高手,是在混乱中也能拎出主线的人。

相关推荐
小李广1 小时前
修改MS源码—开发新接口:查询所有项目下面的模块
java·linux·服务器
CHrisFC1 小时前
环境第三方检测机构LIMS系统选型:从合规基础到效率制胜
java·大数据·人工智能
么么...1 小时前
布隆过滤器详解:原理、实现与应用
java·数据结构·哈希算法·散列表
☀Mark_LY2 小时前
java读取excel文件返回JSON
java·json·excel
ITUnicorn2 小时前
【Vue2+SpringBoot在线商城】13-本项目运用到的技术
java·spring boot·redis·后端
仰泳之鹅2 小时前
【杂谈】C语言中的链接属性、声明周期以及static关键字
java·c语言·前端
weixin_531651812 小时前
Java 正则表达式
java·正则表达式
空空kkk2 小时前
Spring Boot项目的搭建
java·spring boot·后端
2501_940315262 小时前
【无标题】(leetcode933)最近的请求次数
java·前端·javascript