首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
王茆茆
浙江大学 Java
发布于浙江
关注
已关注
取消关注
@需要努力的97:
秒杀项目常见问题
1.讲一下你这个高并发抢购系统(秒杀) 是什么,用了什么(Redis、动静分离、隐藏链接、限流、削峰),压测结果 这个系统主要是模拟秒杀活动,实现一个支持高并发的服务。 为了解决高并发带来的问题,我用Redis实现了缓存预热、预减库存的功能,通过使用Nginx实现动静分离来降低服务器的压力,加快用户访问速度。隐藏了秒杀接口地址,防止用户提前知道秒杀地址。还通过输入验证码的方式防止恶意秒杀,同时还起到了削峰的作用。最后通过Jmeter压力测试,QPS从最初的150/s提升到2000/s左右。 2.秒杀中如何处理超卖问题? 在定时上架秒杀商品时,使用分布式信号量作为商品的库存缓存到Redis中,当活动开始接收到秒杀请求时,在Redis中进行预减库存,如果Redis中的库存不足时,直接返回秒杀失败;如果有库存,就将请求放入异步队列中,给用户返回一个秒杀成功,正在创建订单,然后订单服务监听这个队列,生成秒杀订单,减少数据库库存等一系列操作。 3.秒杀中如何解决重复下单问题?(普通订单也一样操作) mysql唯一索引(商品索引)+ 分布式锁 4.热点数据失效(缓存击穿)问题如何解决? 因为每一场的秒杀活动持续的时间都是确定的嘛,所以可以把热点数据的过期时间设置的跟活动持续时间一样,这样活动一结束,热点数据自己就删除了,也不会导致在活动期间数据就失效了。 5.Redis缓存和数据库数据一致性如何保证? 使用canal组件实现(canal的原理,模拟MySQL的主从复制机制) 更新数据库后立即删缓存,然后下一次查缓存找不到数据后会再次从数据库同步到缓存。 6.★减库存成功了,但是生成订单失败了,该怎么办?(分布式事务的数据一致性问题) 使用mq来解决这个问题。如果扣减库存成功了但是下单失败了,订单服务就给mq发送一个消息,然后库存服务就来监听这个mq,如果能从mq中拿到消息说明订单失败了,然后就进行回滚操作。 【tips】seata虽然能控制分布式事务,但是不适合高并发,像下订单就是一个高并发操作,所以我们不用seata来实现下订单的分布式事务。因为seata实现分布式事务需要加锁,一加锁相当于把高并发变成串行化了。 7.做了什么限流削峰的措施? (1)点击秒杀按钮以后要先填一个验证码(前端); (2)在定时上架秒杀商品时,使用分布式信号量作为商品的库存缓存到Redis中,当活动开始接收到秒杀请求时,在Redis中进行预减库存,如果Redis中的库存不足时,直接返回秒杀失败; 8.如何解决客户的恶意下单问题? 如果客户想伪造请求来快速秒杀,通过我们的链接加密可以实现。 使用脚本的恶意请求可以用验证码来解决。 9.多机器扣减库存,如何保证它的线程安全的? 用redission实现分布式锁。在扣减库存前,先获取分布式锁getLock(),然后上锁lock,再进行扣减,最后再释放锁。 (1)如果扣减失败,没有释放锁会导致什么情况?怎么解决? 会造成死锁。 给锁设置过期时间,防止出意外释放不了锁造成死锁。 (2)怎么保证释放的就是自己的锁? 在getLock时可以给锁一个名字,只要名字一样就是同一把锁。 10.如何去减Redis中的库存? 在秒杀系统中Redis中的商品库存是用分布式信号量存的,通过tryAcquire()来获取信号量,获取信号量的操作就相当于扣减了库存。 【tips】tryAcquire()是不阻塞的,tryAcquire()不传参是获取一个信号量,tryAcquire(int n)是获取n个信号量(有这么多的话)。 11.缓存中的数据突然失效,导致请求全部打到了数据库,如何解决? (典型的缓存雪崩问题) 给缓存中的数据的过期时间加随机数。 12.如果项目中的Redis挂掉,如何减轻数据库的压力? 可以搭建redis集群,通过哨兵机制来监控主节点,如果主节点挂了就从从节点中选一个新的主节点,实现故障转移。 13.页面静态化 那就把能提前放入cdn服务器的东西都放进去,反正把所有能提升效率的步骤都做一下,减少真正秒杀时候服务器的压力。 14.秒杀系统面临的问题有哪些? 高并发、脚本恶意请求、加了缓存之后的缓存三大问题(击穿、穿透、雪崩)。 15.秒杀系统如何设计? 独立部署+动静分离+限流+熔断降级+缓存预热+异步订单+秒杀链接加密。 (1)独立部署 把秒杀系统单独作为一个微服务,这样一旦秒杀系统实在顶不住了,也不会影响其他服务。 (2)动静分离 使用Nginx实现动静分离,让静态资源从nginx直接返回,减轻服务器的压力。 (3)限流 前端限流+后端限流。 前端可以使用一个验证码,通过手速快慢可以进行一部分限流,还可以过滤机器人的恶意请求。 后端可以使用sentinel在网关设置一些限流规则,比如url必须正确;还可以用分布式信号量,在Redis中保存用分布式信号量代替库存,抢不到信号量就不用去查数据库了。 (4)熔断降级 如果出现问题,给前端返回一个快速失败的提示,将用户引导到一个降级页面,这样可以保证整个调用链不是阻塞的。 (5)缓存预热 使用定时任务在每天凌晨三点上架要秒杀的商品,将商品信息提前保存到Redis中。 (6)异步订单 秒杀成功后发送消息给mq然后给用户返回"秒杀成功,正在创建订单",让订单服务监听mq,然后异步进行订单创建、扣减库存等操作,这样可以防止一条秒杀请求阻塞等待订单完成才给用户返回结果。 (7)秒杀链接加密 缓存商品数据时给每个商品随机生成一个uuid,在发送秒杀请求时,必须保证请求带上skuId和这个随机码才能进来。 16.分布式会话问题? 在实现用户社交登录时,发现有时候已经登录过了但是系统还是会提示去登录,后来发现是session和cookie的问题,这个问题其实是在分布式下session不能共享的问题。用户第一次登录时把登录信息放在session里(session.setAttribute("sessionName",value)),然后把session保存在服务器里,并把token返回给浏览器的cookie,这样用户第二次请求时就带着有token的cookie,服务器就认为已经登陆过了。但是在分布式下会存在一些问题,首先这个过程只能在当前域名下(同一微服务)起作用,其次如果有多台服务器的话,两次请求转发到不同的服务器,即使是同一服务也不能共享session数据。 解决方案是通过SpringSession,自定义一个cookie的序列化器,先将作用域扩大到整个项目(setDomainName())。同时在用户第一次登录时,将session都存到Redis里,让所有服务都去Redis里根据sessionId去获取对应的session, 然后通过设置cookie跨域分享以及利用redis存储token信息得以解决。 17.线程池的执行过程? 当任务进来后,会先判断线程池中的核心线程数是否小于corePoolSize,如果小于的话会直接创建一个核心线程去处理任务;如果大于说明没有核心线程了,就将任务放入阻塞队列中等待。如果核心线程和阻塞队列都满了,就创建非核心线程,去处理阻塞队列中的任务。当线程数达到了maximumPoolSize并且阻塞队列也满了,就会采用拒绝策略来处理任务。 18.你项目中的难点是什么? (1)Feign远程调用丢失请求头问题 在进行远程调用时cookie需要带上sessionId,来标注用户登录状态的session,但是发现还是提示要先登录,而且cookie中并没有sessionId。后来查了资料发现feign在远程调用时会先构造一个新的请求,而这个新请求里面并没有请求头,所以导致没有携带sessionId。 解决:feign在构造请求之前可以经过请求拦截器(RequestInterceptor),通过拦截器的apply方法可以给请求加一些东西,但是默认情况下是没有拦截器的,那么我们就可以自己定义一个RequestIterceptor并重写apply方法,通过RequestContextHolder来获取原来请求中的sessionId,然后让后面feign构造的新请求携带上sessionId。 (2)用户登录的问题(分布式session) 在实现用户社交登录时,发现有时候已经登录过了但是系统还是会提示去登录,后来发现是session和cookie的问题。用户第一次登录时把登录信息放在session里(session.setAttribute("sessionName",value)),然后把session保存在服务器里,并把token返回给浏览器的cookie,这样用户第二次请求时就带着有token的cookie,服务器就认为已经登陆过了。但是在分布式下会存在一些问题,首先这个过程只能在当前域名下(同一微服务)起作用,其次如果有多台服务器的话,两次请求转发到不同的服务器,即使是同一服务也不能共享session数据。 解决方案是通过SpringSession,自定义一个cookie的序列化器,先将作用域扩大到整个项目(setDomainName())。同时在用户第一次登录时,将session都存到Redis里,让所有服务都去Redis里根据sessionId去获取对应的session。 19.项目中Redis都做了些什么? (1)在项目中用Redis保存购物车数据; (2)通过令牌机制实现接口的幂等性,将token保存在Redis中; (3)在实现社交登录时,将session存在Redis中来解决session共享问题; (4)在实现秒杀时,将秒杀商品信息缓存到Redis中。 20.项目中RabbitMQ都做了什么? 作为异步下单的中间件,实现解锁库存和定时关单。 (1)解锁库存 (超时未支付、用户自己取消订单、锁完库存但是其他远程调用失败了导致的订单回滚都要解锁库存) 当需要解锁库存的时候,比如说订单回滚了,就给交换机发送一个消息,然后交换机根据路由键转发给解锁mq,库存解锁服务监听到这个消息以后,就根据消息进行库存解锁的操作。——可以涉及到方法重载 【库存工作单表】记录了库存锁了多少,是哪个订单锁的,方便回滚。 (2)定时关单 当订单创建成功了,就给交换机发送(rabbitTemplate.convertAndSend())一个消息(订单实体对象),然后交换机根据路由键将消息转发到延迟队列,延迟队列设置了30min的过期时间,当30分钟一过,延迟队列会把过期的消息,再发给交换机,由交换机转发给关单的消息队列,由关单服务进行监听,关单服务拿到消息以后要先判断订单状态,如果是待支付状态,就进行关单,把订单状态设置为已取消;如果是其他状态就不用操作了。 21.线程池技术中核心线程数的取值有经验值吗? CPU密集型业务:N+1 IO密集型业务:2N 22.TPS(每秒处理的事务)提升了多少?如何提高tps? 基础架构下的tps是200,经过做动静分离、引入redis缓存、nginx反向代理(集群)后达到了2000左右。 23.一个人同时用电脑和手机去抢购商品,会颁发几个token? (多台设备登录属于SSO问题,用户登录一端之后另外一端可以通过扫码等形式登录。) 虽然用户登录了多台设备,但是用户名是一样的,所以为用户颁发的token是相同的,只会颁发一个token。 24.线程池的拒绝策略能详细说一下吗? AbortPolicy:直接丢弃任务,并抛出RejectedExecutionException拒绝执行异常; DiscardPolicy:丢弃(discard)任务,但是不抛出异常; DiscardOldestPolicy:丢弃位于阻塞队列最前面的任务(也就是最早进来的任务),然后重新提交被拒绝的任务; CallerRunsPolicy:由提交任务的线程处理该任务。 25.被线程池拒绝掉的那部分用户的秒杀令牌还有效吗? 无效,会从redis中删除,当该用户再去秒杀抢购时,需要重新获取秒杀令牌。 26.线程池中阻塞队列的大小设置为多少合适? 设置为(秒杀商品的个数 - 核心线程数)。这样的话所有秒杀任务最终都可以被处理,而不会说明明有库存,用户秒杀了但是队列满了导致秒杀任务被丢失了。 27.项目上线之后想看JVM的GC情况在Linux中用什么命令? jstat -gc vmid count // jstat-统计jvm信息的指令 jstat -gc 12538 5000 // 表示将12538进程对应的Java进程的GC情况,每5秒打印一次 29.能不能详细描述一下使用MQ异步减redis与MySQL库存的过程? redis中的库存减成功后,生成一条消息,包含了商品信息(包含了库存信息)和用户信息,然后将消息发送给交换机;交换机转发到生成订单服务监听的队列,然后该服务会消费这条消息,根据商品信息和用户信息创建一条订单,并修改数据库中对应商品的库存。 30.做到了什么程度、库存量与并发度是多少? QPS:单机2000/s 31.秒杀系统中MySQL中的表是怎么设计的? 秒杀用户表、商品信息表、秒杀商品表(记录该商品的秒杀始末时间,秒杀价和剩余量)、秒杀订单表(记录了秒杀用户名和秒杀的商品还有订单号)、订单详情表(通过秒杀订单号来查找对应的订单详情,里面记载更详实的业务信息)。 32.如何只使用MySQL保证商品没有超卖? 将查库存、减库存两个sql语句作为一个事务进行控制,保证每一个库存只能被一个用户消费。两条语句都执行成功进行事务提交,否则回滚。 缺点:低并发。 33.数据库改库存的SQL? update table set stock = stock-1 where sku_id = ? and stock > 1; 34.如何防止用户一直点击下单按钮?(防止重复下单、幂等性问题) 前端限制:一次点击之后按钮置灰几秒钟。 后端限制:由于秒杀令牌的设置,用户的一个下单请求会先判断用户当前是否已经持有令牌了,因为用户全局只能获取一次令牌,然后存入到Redis缓存中。用户有令牌的话直接返回 “正在抢购中”。 35.定时任务的框架选型?为什么选Quartz? 我了解的实现定时任务的方法有Java自带的,比如Timer和ScheduledExecutor,还有Quartz,我在项目中用的就是Quartz。 Timer是通过创建一个TimerTask,实现自己的run方法,然后通过Timer调用schedule方法来调度这个任务,可以指定延迟一段时间后再调度。Timer的缺点就是所有的任务都是用一个线程来调度的,也就是说这些任务是串行执行,不适合用在分布式中。 ScheduledExecutor是基于线程池设计的,每一个调度的任务都由线程池中的一个线程去执行,所以说这些任务时并发执行的。但是ScheduledExecutor只能实现基于开始时间与重复间隔定时任务,像设置每天3点执行一个任务就实现不了了,所以也不满足我的需求。 Quartz支持分布式调度任务,可以通过Cron表达式来实现更复杂的定时任务。怎么使用Quartz? 使用异步执行定时任务,来保证定时任务不阻塞。默认是阻塞的,需要等待上一次任务执行完才能执行下一个。因为默认情况下,定时任务线程池只设置了一个线程。首先要在配置类上@EnableSchedule开启定时任务功能,用@EnableAsync开启异步。然后创建一个调度类,在里面调用定时上架商品的业务逻辑(service),在方法的上面用@Scheduled注解标注每天3点的cron表达式。 36.定时上架商品的流程? 一到我们指定的时间,会先远程调用优惠服务,查出最近三天的秒杀活动(select * from 秒杀活动表 where starttime between xxx and xxx;),如果能查到最近三天的秒杀活动,再查活动关联的秒杀商品信息。然后把活动场次和商品信息缓存到Redis,同时用分布式信号量作为库存进行扣减,只要有一个秒杀请求进来信号量就减1,减到0就说明没库存了。 活动场次用起止时间作为key,关联的skuId作为value,这个value用list存; 商品信息用hash存,hash的key用skuId,剩下的商品信息就是hash的value。 分布式信号量要用Redisson的getSemaphore()方法获取,相当于创建了一个信号量对象,然后通过trySetPermits(库存数量)来设置有几个信号量也就是有多少库存。 37.如何进行秒杀链接加密? 在缓存商品信息时,给每个sku设置一个uuid随机码,这样即使有人知道要秒杀商品的id,也无法提前写好请求地址进行恶意秒杀。
点赞 31
评论 4
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
07-29 17:46
长亭科技_政企_安服(实习员工)
7.25腾讯cisg--安全技术--青云计划--一面挂
两个面试官拷打我,真的是说到哪里,问到哪里,真的是太难啦,有种说不出来的感觉,月底面试像是kpi,但是又鼎着青云计划我还是老老实实沉淀沉淀吧
腾讯一面2195人在聊
点赞
评论
收藏
分享
07-28 22:51
腾讯_CSIG_产品经理
腾讯内推腾讯内推码
欢迎大家投递哈,岗位多多,先到先得,感兴趣的话,腾讯全集团所有岗位都可以找我内推 热乎乎的内推码:EUTPZZRV 腾讯投递方式 腾讯为员工提供健全的福利保障和多样化的激励机制,助您实现财务和职业双丰收。 分享一些面经: 第一轮技术面 闭包作用及实际应用场景 HTTP/1.1、HTTP/2、HTTP/3的核心差异 实现红绿灯控制效果(异步时序逻辑) React Hooks的设计动机与类组件对比 浏览器事件代理原理及实际应用 手写Promise核心逻辑(包含resolve/reject) 数组去重与高频字符统计算法 Web安全防护措施(XSS、CSRF) 浏览器渲染流程与重排/重绘优化 跨域...
腾讯HR面2575人在聊
点赞
评论
收藏
分享
07-08 17:23
南京技师学院 安卓
mentor手把手教我包装简历
我的简历可以说是全是水份实习期间在给mentor打杂后面写简历把mentor干的活全写进去了然后发给他看让他锐评一下后续秋招每一轮面试都会问这个优化问题,大部分情况都能答出来,偶尔遇到面试官问的非常细的时候,我就再去骚扰mentor,让他给我解答,让简历里的这个点做到滴水不漏。
勇敢的马后炮炮手在写...:
你起一个中介作用
简历当中有水分算不算造假...
点赞
评论
收藏
分享
07-03 13:32
门头沟学院 产品经理
这简历居然拿了wxg
突然看到一年半前的简历,当时的我做梦都不敢想自己会拿到wxg offer吧,虽然因为职业规划不符拒了,但还是很开心被认可。
siestaaaaa...:
哥们这么帅直接干直播吧,别走弯路了
投递腾讯等公司10个岗位
点赞
评论
收藏
分享
07-29 16:22
韶音科技_产品经理(准入职员工)
韶音科技内推
2024-06-08,投递简历:提前批-机械结构工程师2024-06-30,专业笔试:使用的牛客题库,20道选择题+2道简答题,考察范围包括机设、机原、材料、力学、工艺等2024-07-24,HR面试邀约2024-08-02,HR面试,腾讯会议,约20min。面试流程如下: 1. 自我介绍 2. 人事问答: (1)你的研究方向?你们课题组的研究方向有哪些? (2)分工? (3)项目简述:项目背景?解决什么问题?你做了哪些工作?结构怎样设计的?工作过程中有探索性学习?动手实践吗?项目进展? (4)实验室有多少人? (5)博士有吗? (6)做项目会有...
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
百度提前批,三面被推迟一周,喜提秋招第一凉
4405
2
...
虾皮秋招一面
3625
3
...
干活最少的实习生因为长得漂亮转正了
2891
4
...
7.30滴滴提前批一面凉经
2803
5
...
QQ提前批一面凉经
2649
6
...
百度提前批 三面
2587
7
...
他拿大厂SSP Offer打牌是什么概念啊?25届双非之光
2397
8
...
7.30百度提前批一面
2193
9
...
上班一周,工资还没拿,先欠公司两千
1770
10
...
百度7.30二面
1606
创作者周榜
更多
正在热议
更多
#
简历上的经历如何包装
#
25886次浏览
750人参与
#
秋招被确诊为……
#
162205次浏览
725人参与
#
中兴秋招
#
204400次浏览
2284人参与
#
工作中哪个瞬间让你想离职
#
61553次浏览
554人参与
#
你最近一次加班是什么时候?
#
70919次浏览
350人参与
#
和同事相处最忌讳的是__
#
22279次浏览
230人参与
#
26届的你,投了哪些公司?
#
39472次浏览
443人参与
#
你遇到最难的面试题目是_
#
15837次浏览
195人参与
#
我对___祛魅了
#
44839次浏览
417人参与
#
如果校招重来我最想改变的是
#
271610次浏览
2849人参与
#
地平线求职进展汇总
#
52551次浏览
369人参与
#
你跟室友的关系怎么样?
#
6393次浏览
97人参与
#
如果可以选,你最想从事什么工作
#
565585次浏览
4699人参与
#
你最讨厌面试问你什么?
#
26595次浏览
295人参与
#
你最希望上岸的公司是?
#
134382次浏览
699人参与
#
什么样的背景能拿SSP?
#
33532次浏览
207人参与
#
如何快速融入团队?
#
15447次浏览
190人参与
#
柠檬微趣工作体验
#
6588次浏览
40人参与
#
秋招前后对offer的期望对比
#
302909次浏览
2229人参与
#
字节跳动工作体验
#
462371次浏览
4649人参与
#
打工人的精神状态
#
70915次浏览
1145人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务