场景题

如果一个外卖配送单子要发布,现在有200个骑手都想要接这一单,如何保证只有一个骑手接到单子?

  1. 如果只是单机,采用volatile关键字修饰该订单采用CAS操作对其进行乐观锁操作。
  2. 采用redis,zookeeper分布式锁加锁。
  3. 消息队列 实现幂等接口

多个微信用户抢红包

类似 于秒杀系统
数据库加 乐观锁 悲观锁
在逻辑处理界面加分布式锁
消息队列

1000个任务分给10个人做

  1. 全局队列 每一个人都从一个队列中取
  2. 分成10个队列对应每一个人

如何把一个文件快速下发到100w个服务器

  1. 采用p2p网络形式 比如树状形式,网状形式 单个节点既可以从其他节点接收服务又可以向其他节点提供服务。
  2. 组播形式

TOP K问题

找到最大的k个数

  1. 维护一个小顶堆 每一次都与顶堆即最小的数进行比较。
    建堆的时间复杂度为 O(KlogK) 有N个数 则为O(NKlogk)
//小顶堆
PriorityQueue pq = new PriorityQueue<>();

//大顶堆
PriorityQueue pq = new PriorityQueue<>((v1,v2)->v2-v1))
  1. 快排思想
    将数据快速分为两堆,如果大的一堆大于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);
  1. 如果重复读很高,采用Hash去重
    4.如果内存很小,先10亿个分成100份。在100份中找到最大的K个 再合到一起找最大的K个

提取某日访问次数最多的IP地址

将去进行取模 %1024 散列到1024个文件中
采用hashmap对其进行次数统计 最后用排序算法进行排序。

找到最热门的K个数据

数据太多 内存不够
首先对数据进行预处理,采用hash表统计次数 然后再排序

在2.5亿个整数中找出不重复的整数,内存不足以容纳这2.5亿个整数

位操作
采用bitmap方法来对每一个数据进行标记。0代表存在,1代表不存在。

海量数据排序

  1. 多路归并排序算法 在N个数中取M个数排序后放到内存中,然后多路归并算法进行合并
  2. 采用位图标志该数量的个数 标志完成后再遍历bitmap进行排序

你可能感兴趣的:(场景题)