阿里(天猫事业部)Java开发工程师 三面

#JAVA##JAVA面经##JAVA内推#

1. 如果让你设计天猫双11的秒杀系统,第一步你会考虑什么?

思路

核心是先明确“秒杀的核心痛点”,再定整体设计基调,突出优先级,贴合高并发场景。

回答示例

面试官您好,我第一步肯定会先明确秒杀系统的核心痛点和核心目标。核心痛点就是双11的瞬时高并发,比如每秒几十万甚至上百万请求,还有不能超卖、不能卡顿、数据要一致;核心目标就是扛住高并发、保证库存准确、提升用户体验。先把这两个定下来,后面所有的设计,比如限流、缓存、库存处理,都是围绕这两个点来做,不会偏离方向,避免做无用功。

2. 用户请求进来后,第一道防线设在哪里?

思路

突出“前置拦截”,选最贴近用户、能快速过滤无效请求的防线,结合实际场景说明。

回答示例

第一道防线肯定是CDN和前端限流。首先CDN能缓存静态资源,比如秒杀页面的图片、文案,用户不用直接请求后端服务器,先拦截掉大部分静态资源请求;然后前端做一层限流,比如按钮置灰、限制每秒点击次数,还有简单的参数校验,比如无效的商品ID直接拦截,不让无效请求传到后端。这样能先过滤掉一半以上的请求,减轻后端压力,这是最直接、成本最低的第一道拦截。

3. 库存扣减放在哪一层做?为什么?

思路

明确核心层(Redis),结合高并发、原子性需求,说明不放在其他层的原因,突出实操性。

回答示例

库存扣减我会放在Redis缓存层做,而不是直接放数据库。原因很简单,双11秒杀是高并发场景,数据库扛不住每秒几十万的扣减请求,而Redis是内存操作,速度快,能支撑高并发。而且扣减库存需要原子性,Redis+Lua能保证“查库存+扣库存”一步完成,不会出现并发问题;如果放数据库,即使加锁,也会出现锁等待、性能瓶颈,很容易把库打挂。另外,Redis扣减后,再异步同步到数据库,兼顾性能和数据一致性。

4. 如何防止超卖?

思路

围绕“原子性+双重校验”,结合前面的Redis+Lua,补充数据库兜底,覆盖全场景。

回答示例

防止超卖核心就是两点:保证扣减的原子性,加上双重校验。首先,用Redis+Lua脚本做原子扣减,脚本里先查库存,库存充足再扣减,整个过程不被打断,从源头避免超卖;然后,扣减成功后,异步同步到数据库时,数据库层面也要加校验,比如更新库存时,where条件里加上“库存>=扣减数量”,即使Redis出问题,数据库也能兜底,防止超卖;最后,还会做库存预热,把商品库存提前加载到Redis,避免运行时库存同步延迟导致的超卖。

5. 如果用Redis+Lua,脚本里关键逻辑是什么?

思路

口语化讲清脚本核心步骤,不写代码,突出“原子性+校验”,贴合秒杀场景。

回答示例

脚本里的关键逻辑就三步,很简单,全程保证原子性:第一步,先根据商品ID,从Redis里获取当前库存;第二步,判断库存是否充足,比如用户要抢1件,库存如果小于1,直接返回失败,不让扣减;第三步,库存充足的话,执行库存扣减操作,把库存减1,然后返回成功。整个脚本是一次性执行的,中间不会被其他请求打断,这样就确保了查库存和扣库存是一个原子操作,不会出现并发超卖。

6. 热点商品库存如何分片?

思路

结合热点商品的高并发问题,说明分片逻辑,突出“分散压力+均匀分布”,贴合实际落地。

回答示例

热点商品库存分片,核心是把一个商品的库存,分散到,避免单个节点被打崩。比如一个热点商品有10万库存,我会分成10片,每片1万库存,分别存在10个Redis节点上。用户请求进来后,根据用户ID或者商品ID做哈希,路由到对应的Redis节点,去扣减对应分片的库存。这样一来,原本集中在一个节点的高并发,就分散到10个节点上,每个节点的压力就小多了,也能避免单个节点挂掉导致整个商品秒杀失败。另外,分片的时候会预留一些备用分片,防止某个分片提前卖完,导致请求失败。

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

本专栏在精不在多,内容分为八股文、大厂真实面经,面试通过后将offer和面试题私发给我,可退还专栏的收益部分费用。欢迎大家共建专栏

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务