秒杀项目常见问题

秒杀项目常见面试题

0、讲一下你这个高并发抢购系统

这是一个模拟了高并发场景的商城系统,它具备秒杀功能,并在经过几个版本的迭代之后成为支持高并发的高性能系统。为了解决秒杀场景下的高并发问题。引入了redis作为缓存中间件,主要作用是缓存预热、预减库存等等。针对高并发场景进行了页面优化,缓存页面至浏览器,前后端分离降低服务器压力,加快用户访问速度。在安全性问题上,我使用双重MD5密码校验,隐藏了秒杀接口地址,设置了接口限流防刷。最后还使用数学公式验证码不仅可以防恶意刷访问,还起到了削峰的作用。通过Jmeter压力测试,系统的QPS从150/s提升到2000/s。

1、秒杀中如何处理超卖问题?(网易)(百度)(美团)(滴滴)(字节)

直接由数据库操作库存的sql语句如下所示。依靠MySQL中的排他锁实现

 update table_prmo set num = num - 1 WHERE id = 1001 and num > 0

利用redis的单线程特性预减库存处理秒杀超卖问题!!!

  1. 在系统初始化时,将商品以及对应的库存数量预先加载到Redis缓存中;(缓存预热)
  2. 接收到秒杀请求时,在Redis中进行预减库存(decrement),当Redis中的库存不足时,直接返回秒杀失败,否则继续进行第3步;
  3. 将请求放入异步队列中,返回正在排队中;
  4. 服务端异步队列(MQ)将请求出队,出队成功的请求可以生成秒杀订单,减少数据库库存,返回秒杀订单详情。

2、秒杀中如何解决重复下单问题?(网易)

mysql唯一索引(商品索引)+ 分布式锁

3、热点数据失效(缓存击穿)问题如何解决?(网易)(美团)

设置热点数据永远不过期。

4、缓存和数据库数据一致性如何保证?(shopee)(美团)(网易)

  • 使用canal组件实现(canal的原理,模拟MySQL的主从复制机制)

  • 更新数据库后立即删缓存,然后下一次查缓存找不到数据后会再次从数据库同步到缓存。

5、减库存成功了,但是生成订单失败了,该怎办?(shopee)(美团)(华为)

非分布式的系统中使用Spring提供的事务功能即可。

分布式事务:将减库存与生成订单操作组合为一个事务。要么一起成功,要么一起失败。

CAP理论(只能保证 CP、AP)、BASE理论(最终一致性,基本可用性、柔性事务)。

分布式事务的两个协议以及几种解决方案:

  1. 全局消息
  2. 基于可靠消息(MQ)的分布式事务
  3. TCC
  4. 最大努力通知

seata分布式事务控制组件。

6、做了什么限流削峰的措施?(字节)(美团)(华为)

秒杀令牌(token)加秒杀大闸限制入口流量。线程池技术限制瞬时并发数。验证码做防刷功能。

7、如何解决客户的恶意下单问题?(shopee)

封IP,nginx中有一个设置,单个IP访问频率和次数多了之后有一个拉黑操作。

8、多机器扣减库存,如何保证它的线程安全的?(shopee)(美团)(华为)

分布式锁。redission客户端实现分布式锁

9、如何去减Redis中的库存?(华为)

decrement API减库存,increment API回增库存。以上的指令都是原子性的。

10、缓存中的数据突然失效,导致请求全部打到了数据库,如何解决?(字节)

典型的缓存雪崩问题,给缓存中的数据的过期时间加随机数。

11、如果项目中的Redis挂掉,如何减轻数据库的压力?(滴滴)(华为)

redis集群,主从模式、哨兵模式、集群模式。

主从模式中:如果主机宕机,使用slave of no one 断开主从关系并且把从机升级为主机。

哨兵模式中:自动监控master / slave的运行状态,基本原理是:心跳机制+投票裁决。

每个sentinel会向其它sentinel、master、slave定时发送消息(哨兵定期给主或者从和slave发送ping包(IP:port),正常则响应pong,ping和pong就叫心跳机制),以确认对方是否“活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的“主观认为宕机” Subjective Down,简称SDOWN)。

若master被判断死亡之后,通过选举算法,从剩下的slave节点中选一台升级为master。并自动修改相关配置。

12、页面静态化

那就把能提前放入cdn服务器的东西都放进去,反正把所有能提升效率的步骤都做一下,减少真正秒杀时候服务器的压力。

13、秒杀系统面临的问题有哪些?(滴滴)(华为)(字节)(美团)

  1. 高并发
  2. 超卖、重复卖问题
  3. 脚本恶意请求
  4. 数据库扛不住
  5. 加了缓存之后的缓存三大问题(击穿、穿透、雪崩)

14、秒杀系统设计?

1、redis缓存预热、预减库存

2、MQ异步下单

15、分布式会话问题?(顺丰科技)(网易)(美团)

token+redis解决分布式会话问题。

Token是服务端生成的一串字符串,作为客户端进行请求的一个令牌,当第一次登录后,服务器生成一个userToken便将此Token返回给客户端,存入cookie中保存,以后客户端只需带上这个userToken前来请求数据即可,无需再次带上用户名和密码。二次登录时,只需要去redis中获取对应token的value,验证用户信息即可。

// 用户第一次登录时,经过相关信息的验证后将对应的登录信息以及凭证(token)存入reids中
String uuid = UUID.rondom().toString();
redisTemplate.opsForValue().set(uuid, userModel);
// token下发到客户端存入cookie中进行保存

// 再次登录时cookie携带着token到redis中找到对应的value不为空,表示该用户已经登陆过了,如果查询结果为空,则让该用户重新登陆,然后将用户信息保存到redis中。
// 一般设置一个过期时间,表示的就是多久后用户的登录态就失效了。

16、线程池的执行过程?(美团)(滴滴)

先说一下核心参数:

  • corePoolSize: 线程池核心线程数最大值
  • maximumPoolSize: 线程池最大线程数大小
  • keepAliveTime: 线程池中非核心线程空闲的存活时间大小
  • unit: 线程空闲存活时间的单位
  • workQueue: 存放任务的阻塞队列
  • threadFactory: 用于设置创建线程的工厂,可以给创建的线程设置有意义的名字,可方便排查问题。
  • handler: 线城池的饱和策略事件,主要有四种类型。

一个任务进来,先判断当前线程池中的核心线程数是否小于corePoolSize。小于的话会直接创建一个核心线程去提交业务。如果核心线程数达到限制,那么接下来的任务会被放入阻塞队列中排队等待执行。当核心线程数达到限制且阻塞队列已满,开始创建非核心线程来执行阻塞队列中的 业务。当线程数达到了maximumPoolSize且阻塞队列已满,那么会采用拒绝策略处理后来的业务。

17、你项目中难的难点是什么?(字节)(百度)(平安科技)(新浪)

一、限流、削峰部分的设计。

入口大流量限制

例如有10W用户来抢购10件商品,我们只放100个用户进来。

采取发放令牌机制(控制流量),根据商品id和一串uuid产生一个令牌存入redis中同时引入了秒杀大闸,目的是流量控制,比如当前活动商品只有100件,我们就发放500个令牌,秒杀前会先发放令牌,令牌发放完则把后来的用户挡在这一层之外,控制了流量。

获取令牌后会对比redis中用户产生的令牌,对比成功才可以购买商品

// 设置秒杀大闸
redistemplate.opsForValue().set("door_count"+promoId, itemModel.getStock()*5)
// 发放令牌时,先去redis获取当前大闸剩余令牌数
int dazha = redistemplate.opsForValue().get("door_count"+promoId)
    if (dazha <= 0) {
        // 抛出一个异常
        throw new exception;
    }else {
        String tocken = UUIDUtils.getUUID()+promoId;
        // 用户只有拥有这个token才有资格下单
        redistemplate.opsForValue().set(userToken, token);
    }

使用数学公式验证码削峰,用户在下单秒杀的时候需要先输入验证码,这样的话分散了同一时间下单的用户数量

二、用户登录的问题(分布式会话)

做完了分布式扩展之后,发现有时候已经登录过了但是系统仍然会提示去登录,后来经过查资料发现是cookie和session的问题。然后通过设置cookie跨域分享以及利用redis存储token信息得以解决。

18、项目中Redis都做了些什么?

  1. 作为缓存中间件提升系统性能
  2. 预减库存,防止超卖功能实现
  3. redis设置热点数据永不过期

19、项目中RabbitMQ都做了什么?

  1. 作为异步下单的中间件,利用队列排队下单缓解数据库的并发压力。

20、线程池技术中核心线程数的取值有经验值吗?(美团)(滴滴)

CPU密集型业务:N+1

IO密集型业务:2N+1

21、TPS提升了多少?(美团)

基础架构下的tps是200

经过做动静分离、nginx反向代理并做了分布式扩展、引入redis中间件后达到了2500 tps。

26、一个人同时用电脑和手机去抢购商品,会颁发几个token?(美团)

首先多台设备登录属于SSO问题,用户登录一端之后另外一端可以通过扫码等形式登录。虽然用户登录了多台设备,但是用户名是一样的。为用户办法的token是相同的。我们为一个用户只会颁发一个token。

27、如何利用线程池实现了流量削峰?

设置最大线程数来限制浪涌流量

28、线程池的拒绝策略能详细说一下吗?(美团)

ThreadPoolExecutor.AbortPolicy://丢弃任务并抛出RejectedExecutionException异常。
DiscardPolicy://丢弃任务,但是不抛出异常。
DiscardOldestPolicy://丢弃队列最前面的任务,然后重新提交被拒绝的任务
CallerRunsPolicy://由调用线程(提交任务的线程)处理该任务

29、被线程池拒绝掉的那部分用户的秒杀令牌还有效吗?(美团)

无效,会从redis中删除,

30、线程池中阻塞队列的大小设置为多少合适?(美团)

设置为秒杀商品的个数减去核心线程数最合适。

31、项目上线之后想看JVM的GC情况在Linux中用什么命令?(美团)

jstat -gc vmid count
jstat -gc 12538 5000 // 表示将12538进程对应的Java进程的GC情况,每5秒打印一次

32、你做这个项目有什么预期吗?(美团)

33、秒杀令牌(token)每秒钟生成多少个?(美团)

跟随用户的请求会动态变化,令牌桶机制可以控制每秒生成令牌的个数。

34、能不能详细描述一下使用MQ异步减redis与MySQL库存的过程?(美团)

redis中库存减成功后,生成一条消息包含了商品信息、用户信息消息由MQ的生产者生产,经由queue模式发送给消费方,即订单生成的业务模块,在该模块会消费这条消息,根据其中的信息进行订单的生成,以及数据库的修改操作。

35、做到了什么程度、库存量与并发度是多少?(美团)

QPS:单机2000/s

36、MySQL中的表是怎么设计的?(美团)(字节)

秒杀用户表、商品信息表、秒杀商品表(记录该商品的秒杀始末时间,秒杀价和剩余量)、秒杀订单表(记录了秒杀用户名和秒杀的商品还有订单号)、订单详情表(通过秒杀订单号来查找对应的订单详情,里面记载更详实的业务信息)、

37、假设现在你的项目需要多人协作,有没有好的办法做一个协调?(美团)(华为)

38、如何只使用MySQL保证商品没有超卖?(大华)

将查库存、减库存两个sql语句作为一个事务进行控制,保证每一个库存只能被一个用户消费。两条语句都执行成功进行事务提交,否则回滚。但这样会导致并发很低。但也没办法。

39、数据库改库存的SQL?(美团)

update table set stock = stock-1 where prom_id = ? and stock > 1;

40、如何防止用户一直点击下单按钮?(华为)

前端限制:一次点击之后按钮置灰几秒钟。

后端限制:由于秒杀令牌的设置,用户的一个下单请求会先判断用户当前是否已经持有令牌了,因为用户全局只能获取一次令牌,然后存入到Redis缓存中。用户有令牌的话直接返回 “正在抢购中”。

#Java开发##java实习##面经##实习##秋招#
全部评论
请问超卖到底是在数据库层面(大于0)解决的呢,还是在redis预减库存这里解决的呢?感觉这两方面都解决了,是不是功能重复了?
1 回复 分享
发布于 2023-08-16 21:45 北京
感谢
点赞 回复 分享
发布于 2024-10-19 11:57 山东
感谢大佬!好全面!
点赞 回复 分享
发布于 2023-08-07 15:41 北京
楼主这个项目我做完了,可以私信我学习交流下关于项目的问题,没有资源也可以问我要
点赞 回复 分享
发布于 2023-04-27 21:34 安徽
您好,您知道牛客网的秒杀视频可以从哪里找到吗,牛客网里找不到了
点赞 回复 分享
发布于 2023-03-15 17:06 陕西
点赞 回复 分享
发布于 2023-03-04 22:52 浙江
感谢
点赞 回复 分享
发布于 2022-09-04 11:38 重庆
大佬有博客吗
点赞 回复 分享
发布于 2022-07-29 10:57
牛逼
点赞 回复 分享
发布于 2022-07-28 21:58
37题该怎么回答
点赞 回复 分享
发布于 2022-07-25 07:39
感谢!
点赞 回复 分享
发布于 2022-07-22 14:56
大佬我有个问题,就是如果用户在规定时间没有下单,需要取消订单应该怎么做?
点赞 回复 分享
发布于 2022-06-24 18:04
感谢大佬!
点赞 回复 分享
发布于 2022-06-07 10:36

相关推荐

05-31 10:19
已编辑
门头沟学院 Java
bg:双非一本,非理工类院校,学习java已经半年了,目前大二,期末考试已经结束。主要是跟着黑家和尚家两家课程联合学习的,mysql、redis、juc、jvm都学完了,算法也在正常刷,LC200道题,hot100算是一瓶子不满半瓶子晃荡水平,八股一直在进行着,感觉还可以。按部就班写了苍穹外卖和黑马点评。目标:想要快点找实习走出校园,且已经坚定选择走java这条路场景1:大二这年在研究所待着,参加了很多软件设计相关的大赛,但都是省三,而另一个同届小组都是国奖,老师就说“你不拿奖,你简历上写什么。你学这java没用,就是个0”。个人想法:这些软件比赛都是比ppt、比idea,我走的是开发的路,道不同啊,我不学java我还有其他选择吗?双非本还有其他选择吗?我请问呢老师??问题1:这些国奖真的很重要吗?面试会看这些吗?场景2:期末提前考是因为后面有一个月的实训,我们软工的是在机房跟企业的工程师学习vue+springboot,结课是开发一个全栈小项目。但是研究所老师给了我们更多选择,可以让我们去企业(小公司,一个是.net开发,另一个比较杂)。我的想法:就按原本的机房实训,我签个到直接回研究所沉淀java,写项目(老罗的easypan,我准备重构这写,想尽力写到符合企业级)。但老师说“别学习了,你学的都没用,去企业看看你就会发现你学的都是0”。问题2:难道企业的开发不用springboot么?还是说企业有很nb、很特别的什么是javaer不需要学习就可以胜任的开发工作吗?大家建议我去企业还是沉淀?去这种小企业还是十几个学生一起去实训的真的会有很大收获吗?真的有些焦虑了,这条路对于双非来说本就不容易,反对、否认的声音常常在耳边回荡。但我不会放弃,因为我个人觉着我没有其他选择了,一学期逃课率95%的我真的很想在java这条路上走下去,我深知跟着学校学(PS:这次期末考试javaWeb考的是JSP!!!)不会有任何结果,按自己的想法走java这条路或许有结果,比起相信老师的话我更信任自己。但念在他是老师,平时对我也挺好的,我也确实能在他身上学到一些东西,我事事都不反驳,有些认可的话我会去思考,但一些否定的话真的很让人怀疑自己,我真的不应该这样吗?当我问“那我应该学什么?我应该怎么做的时候?”他就说“这得你自己多看看,多想想,别把路走窄了。”.....老师很早就跟我们讲要定目标,我定了,但总是被否定....我以后还是会在研究所学习,免不了老师接着否定。我应该如何自处呢?各位佬怎么看?大家有过这样的经历吗?
爱睡觉的冰箱哥:问题1,ppt大赛含金量0,纯安慰自己 问题2,老师是沙贝,黑企不能去
点赞 评论 收藏
分享
评论
142
1154
分享

创作者周榜

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