秒杀项目的面试问题记录,求助及欢迎讨论

该帖子在秋招时写的,现在楼主已经上岸了。整理一下答案。

但如果牛友点进来,是想找秒杀项目做。

那我必须说:请不要做秒杀项目

人均秒杀导致的,不只是简历大量重复。其实真正的问题是:面试官问的问题,已经有很多人回答过,那他肯定听过更好的答案,那你的答案即使原本是合格线的,在面试官看来,也就不及格了。那这样,你就只有提出更好的回答。或者面试官提出难度更高的问题,然后这样一个死循环。

楼主是建议自己去做一些轮子,这里可以推荐另一个牛友的帖子,一个RPC框架。

一个简易的rpc框架实现完整教程

再次提示,做秒杀,三思而后行。

如果牛友是来讨论秒杀的问题、答案,可以继续往后看了。


首先先总结一下我的简历中秒杀项目的知识点

  • Redis分布式缓存的实现
  • Redis预减库存
  • 内存标记(HashMap)标记是否已结束
  • RabbitMQ入队

上面都是基础点了,我额外有

  • RabbitMQ可靠性传输的实现 (发送方,broker , 接收方)三方
  • RabbitMQ的消息幂等性实现
  • Jmeter进行的压测
  • 对异常消息的入库记录及Redis对预减库存的补偿

秒杀代码的逻辑就是

1.查看内存标记HashMap,看是否已结束

2.判断这个秒杀订单形成没有,避免重复秒杀

3 setnx,判断该用户是否请求过,返回提示"等待结果"

4 Lua脚本,判断Redis是否有库存,有就扣。没有设置HashMap已结束

5 正常入队MQ

我也写了博客,记录相关的实现,有需要的可以看一下,跳转

(有些问题,博客还没来得及更新,谨慎参考)


先指出个本质设计上的问题:

如果库存为N,其实Redis不应该放N,而应该是2N、3N等

因为放N,若有X条异常消息,无法正常消费

  • 会出现少卖:有库存,买不到

  • 如果回补库存,则设计内存标识的重新开放。

    虽然可以通过MQ实现,但其实有延迟,而且成本大

    而对于秒杀场景,关键就是前几秒,因此MQ的延迟实现意义不大。

(而且这样处理后,其实异常数据就不需要回补了,因为你设置的并不是N,少量的异常数据不会导致少卖)


(此处需要呼吁大佬们提供一下解决思路,挺多问题都没解决的)

面试问题

  1. 针对单个商品,有10w+的库存,怎么优化Redis?

    综合下评论区老哥的答案。

    大概想法是多个相互独立的Redis集群。

    比如10w个库存,10个Redis集群,一个集群分1w。

    存在的问题:某个集群卖完了,但实际其他集群还有。

    楼主认为类似上述的放x倍N的思想,每个集群放2W或3W,再

    配合nginx的最少访问负载策略,能很大程度解决这个问题。

    但感觉并不是最优解。

  2. 如何保证不超卖的情况下,提高效率

    推荐阅读:写的很好,秒杀系统优化方案(上)吐血整理

  3. 项目本身是否多线程

    这里说的不是多线程访问,而是指程序本身是否多线程。

    答了无额外处理,依靠springboot的调度。


    楼主查阅资料,只有一个跟多线程扯上的。

    是一位牛友告知的,队列泄洪的概念。

    我感觉跟常规的理解有点区别。

    这种用的是多线程来限制访问,表象上看反而是降低了访问速度,但可能是出于大量请求等导致的崩溃的问题,这块不太清楚。因此具体请百度

二、内存标识HashMap的相关问题

  1. 对Redis库存进行补充后(异常或退款),如何反馈到内存标记

    上面已经说了,已经放X倍的N,来避免这种情况。

    当然,该问题的答案是:

    1. 单机环境下,把HashMap的范围改为public,补充库存后,直接重置HashMap为true。

    2. 集群环境下,就把补充的消息推送到MQ,各个节点进行监听,修改本地的HashMap。或者直接依靠集群的同步机制完成。

    3. 直接依靠定时任务,根据redis的库存定时更新HashMap的值。

      这种方法缺点也很明显,定时间隔长了,实时性不强。间隔短,性能低

  1. HashMap的问题

    • 线程安全问题:不安全,但不影响。因为后续还是会经过Redis库存判断。

      为了线程安全换ConcurrentHashMap之类的,反而不值得

    • OOM问题:采用Guava,利用其自带的LRU解决。


三、压测相关:

  • load average高,不一定是CPU资源紧张,如何排查

    磁盘IO问题,相关命令: vmstat、iostat

(仍然没思路的↓)

  • 如何检测、定位项目的性能瓶颈在哪

    答了把方法细拆,分别压测对应方法。但反应不理想

  • 除了CPU占用率外,还有什么能判断是否到底瓶颈?

#秋招##项目#
全部评论
大家好,我叫夹嗦
4 回复 分享
发布于 2020-08-20 22:57
其实我真的不太建议人均秒杀的,应该我在网易听他们面试官说,碰到秒杀项目的,除非真的特别优秀,不然基本过不了
2 回复 分享
发布于 2020-08-22 11:08
哈哈,这个帖子好。
1 回复 分享
发布于 2020-08-20 18:10
请问什么是秒杀项目呀,是说楼主项目做得很快吗?😂
1 回复 分享
发布于 2020-08-21 16:37
秒杀是一个模块,你要是单写一个秒杀肯定是不行的,现在电商包括的模块很多,秒杀只是比较热的模块而已,包含但不仅限于
1 回复 分享
发布于 09-10 09:39 陕西
针对单个商品,有10w+的库存,怎么优化Redis? 这个我感觉面试官是不是想考察bitmap,节省内存的方案
点赞 回复 分享
发布于 2020-08-20 15:50
m
点赞 回复 分享
发布于 2020-08-20 16:37
点赞 回复 分享
发布于 2020-08-20 16:45
m
点赞 回复 分享
发布于 2020-08-20 18:26
关于问题3"项目本身是否多线程" 我在处理下单请求里开了一个newFixedThreadPool来限制为固定数量的请求,不知道这属不属于
点赞 回复 分享
发布于 2020-08-20 18:56
确实我也没考虑过这个单线程多线程的问题。。总觉得是Spring会自动为每一个请求创建一个线程。。prototype好像只是避免了线程安全问题啊,跟单线程多线程有什么关系吗?
点赞 回复 分享
发布于 2020-08-20 19:16
m
点赞 回复 分享
发布于 2020-08-20 19:20
m
点赞 回复 分享
发布于 2020-08-20 21:38
m
点赞 回复 分享
发布于 2020-08-20 22:08
好帖,不知道面试官会不会看到这个帖子呀😆
点赞 回复 分享
发布于 2020-08-20 22:11
真就人均秒杀呗
点赞 回复 分享
发布于 2020-08-20 23:01
mark一下
点赞 回复 分享
发布于 2020-08-20 23:20
大佬好人!期待更新
点赞 回复 分享
发布于 2020-08-20 23:41
太棒了
点赞 回复 分享
发布于 2020-08-20 23:42
m
点赞 回复 分享
发布于 2020-08-21 02:25

相关推荐

努力学习的小绵羊:我反倒觉得这种挺好的,给不到我想要的就别浪费大家时间了
点赞 评论 收藏
分享
43 557 评论
分享
牛客网
牛客企业服务