如果一个外卖配送单子要发布,现在有200个骑手都想要接这一单,如何保证只有一个骑手接到单子?
- 如果只是单机,采用volatile关键字修饰该订单采用CAS操作对其进行乐观锁操作。
- 采用redis,zookeeper分布式锁加锁。
- 消息队列 实现幂等接口
多个微信用户抢红包
类似 于秒杀系统
数据库加 乐观锁 悲观锁
在逻辑处理界面加分布式锁
消息队列
1000个任务分给10个人做
- 全局队列 每一个人都从一个队列中取
- 分成10个队列对应每一个人
如何把一个文件快速下发到100w个服务器
- 采用p2p网络形式 比如树状形式,网状形式 单个节点既可以从其他节点接收服务又可以向其他节点提供服务。
- 组播形式
TOP K问题
找到最大的k个数
- 维护一个小顶堆 每一次都与顶堆即最小的数进行比较。
建堆的时间复杂度为 O(KlogK) 有N个数 则为O(NKlogk)
//小顶堆
PriorityQueue<Integer> pq = new PriorityQueue<>();
//大顶堆
PriorityQueue<Integer> pq = new PriorityQueue<>((v1,v2)->v2-v1))
- 快排思想
将数据快速分为两堆,如果大的一堆大于k,则在大堆中继续递归,如果小于k则在另外一堆中找到第k-m个数。
时间复杂度为O(N) 最差为O(N*2)
空间复杂度为O(logN)
void partitionArray(int[] arr, int lo, int hi, int k) {
// 做一次 partition 操作
int m = partition(arr, lo, hi);
// 此时数组前 m 个数,就是最小的 m 个数
if (k == m) {
// 正好找到最小的 k(m) 个数
return;
} else if (k < m) {
// 最小的 k 个数一定在前 m 个数中,递归划分
partitionArray(arr, lo, m-1, k);
} else {
// 在右侧数组中寻找最小的 k-m 个数
partitionArray(arr, m+1, hi, k);
- 如果重复读很高,采用Hash去重
4.如果内存很小,先10亿个分成100份。在100份中找到最大的K个 再合到一起找最大的K个
提取某日访问次数最多的IP地址
将去进行取模 %1024 散列到1024个文件中
采用hashmap对其进行次数统计 最后用排序算法进行排序。
找到最热门的K个数据
数据太多 内存不够
首先对数据进行预处理,采用hash表统计次数 然后再排序
在2.5亿个整数中找出不重复的整数,内存不足以容纳这2.5亿个整数
位操作
采用bitmap方法来对每一个数据进行标记。0代表存在,1代表不存在。
海量数据排序
- 多路归并排序算法 在N个数中取M个数排序后放到内存中,然后多路归并算法进行合并
- 采用位图标志该数量的个数 标志完成后再遍历bitmap进行排序