得物后端一面:AI 能力追问 + Java 并发与秒杀设计
- 轮次
- 一面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
半小时,无手撕。
- 请做一下自我介绍。
- 介绍一个你觉得有挑战性的项目。
- 聊天机器人项目中引入了哪些 AI 模型能力?接 AI 进来帮助做什么决策?
- 这个项目类似于监控平台吗?它起辅助定位还是什么作用?
- 它可能给出错误信息吗?如何优化或防止幻觉?
- 简单介绍 Java 内存模型。
- 线程间数据交换有什么手段?
- 如何保证原子性?
- volatile 的机制能简单介绍一下吗?
- volatile 底层如何保证可见性?
- volatile 如何防止指令重排?
- Spring Boot 在项目中主要是当微服务用,还是普通 Java 分模块开发?
- Spring Boot 自动装配机制你清楚吗?
- Bean 的生命周期能介绍一下吗?
- 如何设计高并发秒杀活动,保证不超卖?
- 秒杀场景下,如何兼顾性能与防超卖?
- Lua 脚本中的 Key 如何设计?
- Redis 不可用时,系统有自愈能力吗?
- 如何保障 Redis 高可用?
- 稳定性设计方面有什么经验?
《参考解析》
volatile 三个问题一起答
它保证可见性与有序性,不保证原子性。可见性来自写操作后把该缓存行刷回主存、并使其他核心的副本失效,读操作因此总能拿到最新值;有序性靠内存屏障禁止编译器和处理器把 volatile 读写重排到屏障另一侧。i++ 是读改写三步,volatile 拦不住并发覆盖,计数场景仍然要用锁或原子类。
线程间数据交换
共享内存配同步手段是最常见的:synchronized、Lock、原子类、阻塞队列。队列把「交换数据」和「解耦线程速度」合在一起,生产者消费者场景优先用它,比手写 wait/notify 更难出错。
Spring Boot 自动装配
入口是启动类上的 @SpringBootApplication,它带出 @EnableAutoConfiguration,后者通过 AutoConfigurationImportSelector 读取各 jar 包 META-INF 下的自动配置类清单,再按 @ConditionalOnClass、@ConditionalOnMissingBean 这类条件筛选,只装配当前 classpath 与配置真正需要的 Bean。
秒杀防超卖
判断库存与扣减必须在一个原子操作里完成。Redis 用 Lua 脚本把「读库存 + 比较 + 减一」合成一次执行,单线程模型天然串行,不会出现并发超卖;扣减成功后写一条异步消息落库,前端先返回排队结果。真正的兜底是数据库层的唯一约束和库存字段的非负校验——缓存层放过的量必须有最终一致性的账可对。
Lua 脚本的 Key 设计
每个商品一个库存 Key,并挂上活动维度前缀,方便按活动批量预热与清理。Redis Cluster 下脚本里出现的所有 Key 必须落在同一个 slot,通常用 hash tag 把商品维度固定住;不要在一个脚本里跨多个散列的商品 Key。库存 Key 同时存总库存与已售量,便于对账和回补。
Redis 高可用
主从加哨兵解决故障切换,Cluster 解决容量与写扩展。但题里问的「自愈」不只是切换:要能扛住热点 Key 打满单分片、大 Key 阻塞主线程、以及缓存整体不可用时数据库不被击穿。常见组合是本地缓存做一级、集群做二级、限流与降级开关兜底,并保留直连数据库的最小可用路径。