23.什么是索引?索引有哪些分类?
24.讲一下乐观锁和悲观锁。
25.消息队列如何保证消息不丢?
生产者使用确认机制(如ACK)确保消息成功发送至Broker;Broker采用持久化存储(如磁盘写入)和副本同步防止数据丢失;消费者处理成功后手动提交确认,失败时触发重试
26.设计一个支持万人同时抢购商品的秒杀系统,如何解决超卖、库存扣减和高并发请求问题?
- 超卖问题即库存扣减时出现负数。解决超卖问题需要保证库存扣减的原子性。
解决方案:
使用Redis的原子操作:Redis是单线程的,可以使用DECR命令来原子性减库存,如果库存不足则返回错误。 推荐使用Redis的原子操作来扣减库存,因为Redis性能高,且原子操作可以避免超卖。
- 库存扣减 将商品库存提前加载到Redis中,秒杀时直接操作Redis库存。扣减库存的步骤:
用户发起秒杀请求。
检查Redis中商品库存是否大于0。
使用Redis的DECR命令扣减库存,如果返回结果大于等于0,则扣减成功;否则扣减失败,回滚(使用INCR命令加回库存)。
扣减成功后,将订单信息发送到消息队列,由订单服务异步处理生成订单。
注意:如果使用DECR命令,库存不足时返回负数,我们需要先判断库存是否大于0,然后再扣减?实际上,我们可以使用Lua脚本来保证原子性,因为DECR操作是原子性的,但是判断和扣减两个操作需要原子性,所以使用Lua脚本将两个操作合并。
- 高并发请求处理 限流:在网关层使用限流策略,如令牌桶、漏桶等,限制每秒请求数,防止系统被压垮。
异步处理:将秒杀请求分为两步,第一步是库存扣减,第二步是订单生成。库存扣减使用Redis快速完成,然后发送消息到消息队列,由订单服务异步消费,生成订单。这样可以将同步的订单生成操作异步化,提高响应速度。
缓存:将商品信息、库存等缓存到Redis,减少数据库访问。
队列削峰:将大量的秒杀请求放入消息队列,然后慢慢消费,避免瞬间高峰压垮数据库。
27.MySQL 中的 MVCC 是什么?Read View 在 MVCC 中如何工作?如果没有 MVCC 会怎样?
28.联合索引的存储结构与最左前缀原则
联合索引的存储结构是将多个列的值组合在一起形成一个复合键,按照字典序进行排序存储。 最左前缀原则指的是在使用联合索引时,查询条件必须从索引的最左列开始,才能有效利用索引进行加速查询。
29.ConcurrentHashMap 线程安全的具体实现方式。
30.synchronized和Lock有什么区别?
我的博客 首先,在实现层面,synchronized是JVM级别的内置锁,而Lock是JDK提供的API接口。
其次,在使用方式上,synchronized会自动管理锁的获取和释放,使用更简单但不够灵活;Lock需要手动控制,必须在finally块中释放锁,但提供了更丰富的功能。
功能特性方面,Lock支持尝试非阻塞获取锁、超时获取锁,可中断的锁获取,可以创建公平锁,以及多个条件队列,这些是synchronized不具备的。
在性能上,低竞争时synchronized有优势,高竞争时Lock表现更好。实际选择时,简单的同步场景用synchronized,复杂需求或需要精细控制时用Lock
全部评论
(0) 回帖