项目相关
设计中台库存扣减
高并发设计
主要涉及的问题是预扣减库存时,加锁避免多线程同时扣减的情况(分布式事务)。
业务解决方式
- 库存分段:将多个总库存分区,每个区分配一个锁来进行库存锁定与扣减;
- 缺点:库存分段实现麻烦,锁控制的范围不好确定。
库存占用:库存表加锁,在一个库存占用表中插入新数据并解锁,根据库存占用进行下单与扣减。
库存占用(加锁)的具体流程
整表加锁:利用
SELECT * FROM <table_name> WHERE <condition> FOR UPDATE语句,但并行操作被串行化,性能不高;- Redis分布式锁:使用Redis的
setnx命令获取分布式锁(该命令当key存在时返回0,不存在时创建并设置value返回1),拿到锁并处理完业务后释放锁(del命令删除对应的key);
⚠️注意点:
- 为了避免Redis挂掉或其他异常导致无法释放锁,在key的value上设置一个时间戳进行超时判断;
- 为了避免其他线程释放掉未超时到锁,在key的value上添加一个表示线程的特征码。
扣减过程出错造成的数据不一致
使用分布式系统的副本解决分布式系统数据异常的问题,一个分布式系统的副本具有多个,而这些副本的一致性分为以下几种:
- 强一致性:最难实现的最高一致性要求,任何时刻任何用户(节点)读到的任意副本都是最新的数据;
- 单调一致性:最实用的一致性要求,特定用户(节点)在任何时刻读到的任意副本都是最新的数据,只关注本用户的一致性;
- 会话一致性:只保证单个用户(节点)在单次会话中读到的都是最新的副本,同一用户不同会话和不同用户之间不保证;
- 最终一致性:一旦更新成功各个不同副本都是一致的,但达到一致的时间不保证,对于一个用户来说,他只要始终读一个确认的副本,这个副本上的数据永远是满足单调一致性的,但如果切换副本则不确定一致性;
- 弱一致性:强依赖于应用方的后续工作,用户无法在确定时间内读到更新后的副本。
数据库相关
分库分表
Redis原理
Java相关
overload和override
多态与继承
多态的概念与原理
static 与继承
算法
找出数组中相加为目标和的两个数字组合
输入:[1, -1, 5, 4, 2, 3, 1, 2, 2], 4
输出:[1, 3], [-1, 5], [2, 2], [2, 2], [3, 1], [2, 2]public List<Pair> findAllPairs(int[] array, int target) {Map<Integer, Integer> map = new HashMap<>();List<Pair> res = new ArrayList<>();for (int i : array) {if (map.containsKey(target - i)) {map.put(target - i, map.get(i) + 1);} else {map.put(target - i, 1);}}for (int i : array) {if (map.containsKey(i) && map.get(i) > 0) {Pair p = new Pair(i, target - i);map.put(target - i, map.get(i) - 1);res.add(p);}}}
