海量数据找出现次数最多
分治法 + HashMap (HashMap 不要局限在 Java 语言)
将 2.5 亿个整数,分批操作,例如分成 250 万一批,共100批次。每批使用循环遍历一次,存入 HashMap<int1,int2> 里面,int1 对应这个数,int2 对应它出现的次数,没出现就默认是 1 次。每操作完一批,就进行当前的 HashMap 的去重操作,读出 int2 > 1 的,排除掉。接下来的批次,以此类推,得出 100,剩下的自然就是不重复的。
用数组实现栈:
使用数组来模拟栈的实现,首先考虑到数组的长度是固定的,所以使用栈就必须给一个特定的长度,即最大长度MaxSize。自定义一个栈顶指针, 初始化数据为-1,因为数组的索引值是从0开始的,为了不引起冲突,从-1开始。
栈为空:当top=-1时,即等于初始化数据,没有任何元素存在数组中,则说明栈为空。
栈满:随着添加元素,栈顶指针将会往后移动,但是要考虑到数组的长度是固定的,就存在一个满的情况。判断条件是当top=MaxSize-1时,栈就满了。比如定义3个大小的数组,放入一个数据1,top从-1变为0,再放入一个数据2,top从0变成1,再放入一个数据3,top从1变成2.这时候数组已经满了,判断条件即为top =MaxSize,为栈满。
进栈:进栈前先判断栈是否满了,否则不能进栈。将top+1,在将数组索引为top的元素赋值为添加进来的数据。
出栈:出栈前先判断栈是否为空,否则不能出栈。如果不为空,先取栈顶的元素,即索引值为top的元素,然后在将top-1。
遍历栈:遍历时也要判断栈中是否为空,遍历数据也是从栈顶元素开始遍历, 一直遍历到栈底就结束了。
模拟商品抢购:
使用排它锁
使用redis队列,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,推荐使用(mysql事务在高并发下性能下降很厉害,文件锁的方式也是)
角斗场,怎么保证数据的一致性
用分布式锁
Redis实现分布式锁
最简单的方法是使用 setnx 命令。key 是锁的唯一标识,按业务来决定命名。比如想要给一种商品的秒杀活动加锁,可以给 key 命名为 “lock_sale_商品ID” 。而 value 设置成什么呢?我们可以姑且设置成 1。加锁的伪代码如下:
setnx(lock_sale_商品ID,1)
当一个线程执行 setnx 返回 1,说明 key 原本不存在,该线程成功得到了锁;当一个线程执行 setnx 返回 0,说明 key 已经存在,该线程抢锁失败。
解锁
有加锁就得有解锁。当得到锁的线程执行完任务,需要释放锁,以便其他线程可以进入。释放锁的最简单方式是执行 del 指令,伪代码如下:
del(lock_sale_商品ID)
释放锁之后,其他线程就可以继续执行 setnx 命令来获得锁。