面试题:
1、假设保存菜品成功,保存redis失败,问是否应该回滚菜品的数据?
需要回滚,在点餐时菜品需要先在Redis中完成预扣,如果redis中没有当前的菜品,则无法完成预扣,菜无法售卖
变化:假设保存的菜品的口味成功,保存到Redis失败,问是否应该回滚菜品分类的数据?
不需要,保存redis不会影响正常业务逻辑的执行

**
2、更新数据时,应该是先更新redis还是先更新数据库? 为什么?*
双写一致性问题
* 先更新数据库,考虑redis和mysql的数据时刻保持一致

1、什么是超卖现象?

在高并发情况下,当销量>实际库存 ,就会出现超卖现象;
观点:只要是存在实体商品售卖,就会有可能出现超卖现象;

2、如何解决超卖问题?

day05点餐平台-购物车、下单 - 图1
如何发现/测试超卖现象?
有两种回答:
1、通过Jmeter进行高并发压力测试;
2、有过类似业务场景经验,基于对数据库中的隔离级别(mysql可重复度、Oracle读已提交),发现并发情况下,会有读写不一致的问题;

有三种解决超卖方案:
1、数据库加锁(悲观锁/乐观锁)
—1、乐观锁并未真正加锁,效率高。一旦锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。
—2、悲观锁依赖数据库锁,效率低。更新失败的概率比较低。
实现方法:操作数据库的数据时,添加版本号,通过版本号识别数据是否一致
缺点:操作数据库次数增加,压力加大,性能降低
2、分布式锁
实现原理:Redisson的分布式锁,主要基于Lua脚本 (Lua脚本可以保证多个redis命令的原子性)
3、库存Redis【预扣】操作
redis中库存:业务需要
mysql库存:真正库存
时刻保证 mysql和redis库存一致 (双写一致性问题)

1、先将所有的菜品对应的库存保存到Redis, AtomicLong(key:dishId, vlaue:num)—>在并发情况下,保持数据++i,—i操作的原子性,使得数据保持一致性
2、更改数据库的库存之前,先去在redis 预扣
3、判断 redis中库存 >=0 库存足,可以扣减数据库库存, <0 库存不足,终止当前请求

3、菜品的库存第二天如何更新?更新菜品库存时为什么要加分布式锁?

02-解决超卖细节.png
基于spring bean的生命周期,@postconstruct 初始化库存,更新到redis中
为什么枷锁:多处模块都需要操作库存
1、点餐扣库存;
2、后台更新菜品库存;

4、整个购物车操作的流程是什么?

image.png

5、购物车使用的是什么存储的? 你是怎么考虑的?-Redis 4个点

购物车:在Redis中临时存储选购的菜品、选购的数量
其中数据结构就是OrderItemVo的json字符串,其结构如下:
day05点餐平台-购物车、下单 - 图4

6、购物车数据类型是什么? key是什么? value是什么?

Hash结构;
主key:业务类型常量+订单编号
辅key:dish_id
value:OrderItemVo
day05点餐平台-购物车、下单 - 图5

7、什么是联锁?

通过RedissonMultiLock,实现连锁
总体而言,就是将 key1、key2、key3 …… keyN 放到一个 List 集合中,然后迭代循环加锁,直到所有的都成功。解锁的时候就是再遍历锁进行释放锁

8、添加购物车为什么需要添加 菜品和订单 加联锁?

对菜品加锁是为了保证菜品库存的一致性(使用了atomicLong进行操作,所以项目添加购物车中没有进行加锁)
对订单加锁是为了保证订单的一致性,防止后台操作订单(后台可以修改订单的数量)
联锁:就是必须同时获取多把锁,才能进行操作

9、库存扣减的 时机?

出发点 扣库存时机 优点 缺点 实际应用
消费者 加购物车扣库存 下单一定可以买到菜品 占用菜品库存,导致菜品滞销—>延迟队列解决 jd、淘宝
商家 下单时扣减库存 不会占有库存 下单不一定可以买到菜品 唯品会

注意事项:恶意攻击问题
前端:按钮禁用,黑名单
后端:延时队列

10、添加和移除购物车 如何保证库存的一致性?(MySQL和Redis双写一致性问题)

时刻保证mysql和redis数据是一致的
mysql 成功 redis 成功
mysql 失败 redis 失败
上述两种:数据一致

  • mysql 成功 redis失败
    * mysql失败 redis成功

新增: 先保存mysql,在保存redis, 结合spring事务管理完成mysql回滚
修改: 先修改mysql,在修改 redis,
修改: 先删除mysql,在删除 redis,

https://blog.csdn.net/yulidrff/article/details/86296714
https://mp.weixin.qq.com/s/LqWiwzr1jdX0N9tAxw9gMQ

11、下单操作业务流程是什么?

image.png

12、购物车订单项 和 可核算订单项的合并逻辑?

基于菜品id是否相等,相等则更新呢菜品数量+1;不等则新增至可核算订单项
实现方案:冒泡排序(双层for循环)、map