• 算法通关村第十五关:白银挑战-海量数据场景下的热门算法题


    白银挑战-海量数据场景下的热门算法题

    1.从40亿中产生一个不存在的整数

    题目要求:
    给定一个输入文件,包含40亿个非负整数,请设计一个算法,产生一个不存在该文件中的整数,假设你有1GB的内存来完成这项任务。

    进阶拓展:如果只有10MB的内存可用,该怎么办?

    1.1 位图存储大数据的原理

    假设用哈希表来保存出现过的数,如果40亿个数都不同,则哈希表的记录路为 40亿 条。
    占用空间统计:1个32位整数占用 4B,40亿个占用 40* 100 000 000 *4B ≈ 16 GB

    如果用位方式(俗称位图)统计:40亿/8 B = 5* 100 1000 1000 ≈ 0.5 GB

    占用大小 0.5 GB , 对应的bit数组的长度 0.5*1024*1024*1024*8 = 4 294 967 295 (42亿)

    具体实现:
    创建一个4 294 967 295长度的bit数组 bitArr
    遍历40亿个无符号数组,把bitArr对应位置的值设置为1,如,遇到1000,bitArr[1000] = 1
    遍历完成之后,bitArr数组中,不为1的位置索引就是没有出现的数

    位图存储核心:存储的并不是这40亿个数据本身,而是其对应的位置

    1.2 使用10MB来存储

    只有10MB内存,位图也不能搞定了,需要另寻他法。这里我们可以使用分块思想,时间换空间,通过两次遍历来搞定。

    确定需要划分块的个数:
    40亿个数 需要500MB的空间,如果只有10MB的空间,至少需要50个块。一般划分都是使用2的整数倍,这里划分成64个块比较合理

    将2^32(42亿)划分成 64(2^6) 个块,每个块是 232/26 = 2^26 = 67 108 864 个数,如:

    • 第0区间:0 ~ 2^26 - 1
    • 第1区间:2^26 ~ 2^27 - 1
    • 第i区间:(i)*2^26 ~ (i+1)2^26 - 1
    • … …
    • 第63区间:(26-1)*226 ~ 2^32 - 1

    一共有 40 亿个数,统计落在每一个区间上的数有多少,至少有一个区间上的数少于 2^26 个
    如果落在某区间上的数少于 2^26 个,则该区间中存在没有出现过的数

    第一次遍历:
    申请长度为 64 的整形数组,countArr[0…63],统计区间i上的数有多少。遍历 40亿 个数,根据遍历值决定哪一个区间上的计数增加。
    此时使用的内存为 64*4B = 256B

    第二次遍历:
    假设第 37 区间上的数少于 2^26

    1. 申请长度为 2^26 的位数组bitArr,占用 2^26 / 8 B = 2^23 B = 2^3 MB = 8MB的空间
    2. 遍历 40亿 个数,此时遍历只关注落在第 37 区间上的数,记为 num (num满足 num // 2^26 == 37),其他区间的数忽略
    3. 如果num在第 37 区间上,bitArr[num] = 1
    4. 遍历 40亿 个数完成后,查找bitArr上未设置成1的数,如bitArr[i] != 1,则 2^26*37 + i 就是40亿中没有出现过的数

    总结:

    1. 根据10MB的内存限制,确定统计区间的大小,即第二次遍历时 bitArr 的大小
    2. 利用区间计数的方式,找到计数不足的区间,这个区间上肯定有没出现的数
    3. 对这个区间上的数做bit map映射,再遍历bit map,找到一个没出现的数
    1.3 如何确定分块的区间

    保证第二次遍历时每个块都能放进限制的空间中

    上面例子中,2^23B < 10MB < 224B,223B = 8MB,所以每块大小确定为8MB,分成64块;
    所以至少分成 64 块,分成128块、256块也是可以的。

    2.用2GB内存在 20亿 个整数中找到出现次数最多的数

    题目要求:
    有一个包含 20亿 个全是32位整数的大文件,在其中找到出现次数最多的数,要求内存限制为 2GB。

    思路分析
    在很多整数中找到出现次数最多的数,通常做法是用哈希表做词频统计,key为整数,value为出现次数
    20亿<2^32-1 value不会溢出,一条记录占用内存 4B+4B = 8B
    当哈希表记录数为 2亿 条时,需要占用内存 2亿*8B = 1.6GB内存
    极端情况,20亿个整数都不同,需要20亿条记录,占用16GB内存,不满足要求

    内存溢出解决办法:

    1. 把包含 20亿 个数的大文件用哈希函数分成16个小文件
    2. 然后对每一个小文件用哈希表来统计每种数出现的次数,得到16个小文件中各自出现次数最多的数及其次数统计
    3. 后面选出这16个小文件中各自的第一名中谁出现的次数最多即可

    根据哈希函数的性质

    • 同一种数不可能被散列到不同的小文件上
    • 每个小文件中不同的数一定不会大于2亿种

    注:
    此处哈希函数自己定义,比如此处可将哈希函数定义为 num % 16,将大文件数据分成16份
    类似nginx或者一些负载均横的技术能够做到的那样子,来了一个数据,根据Hash原则,将其打到不同的机器上去

    总结

    把一个大的集合通过哈希函数分配到多台机器中,或者分配到多个文件里,这种技巧是处理大数据面试时最常用的技巧之一。
    但是具体分配多少台机器,分配到多少个文件,在解题时一定要确定下来,面试官指定或者具体的限制
    本题中确定分成16个文件,就是根据内存限制 2GB 的条件来确定的

    3.从100亿个URL中查找的问题

    题目:有一个包含 100 亿个URL的大文件,假设每个URL占用64B,请找出其中所有重复的URL

    补充问题:某搜索公司一天的用户搜索词汇是海量的(百亿数据量),请设计一种求出每天热门 top 100词汇的可行办法

    思路分析

    使用解决大数据问题的常规方法:
    把大文件通过哈希函数分配到机器,或者把大文件拆分成小文件,一直进行这种规划,直到划分的结果满足资源限制的要求。

    1. 首先,需要向面试官询问资源上的限制有哪些?包括内存、计算时间等要求。
    2. 明确限制条件之后,将每条URL通过哈希函数分配到若干台机器或者拆分成若干小文件,此处若干由具体的资源限制来计算出精确的数量
    3. 然后处理每一个小数量的集合

    牢记,哈希函数,分流/分小文件,处理小数量集合

    补充问题分析:
    还是用分流的思路来处理,加上堆结构和外排序的手段进行处理

    处理每一个小文件/每一台机器的时候,通过哈希表统计每种词及其词频
    哈希表记录建立完成后,遍历哈希表的过程中使用大小为 100 的小根堆 来筛选出每一个小文件/每一台机器的top100
    然后不同机器/不同小文件 之间的top100再进行外排序或者继续利用小根堆,最终求出整个百亿数据量中的top100

    总结

    对于top k的问题,除用哈希函数分流和用哈希表做词频统计之外,还经常用堆结构和外排序的手段进行处理

    4.从40亿个非负整数中找到出现两次的数

    题目要求:
    32位无符号整数的范围是 0~2^32 - 1(4294967295),现在有 40 亿个无符号整数,可以使用最多1GB的内存,找出所有出现了两次的数。

    注:本题可以看做是第一题的进阶问题,这里将出现次数限制在了两次

    思路分析

    • 可以用 bit map 的方式来表示数出现的情况
      申请一个长度为 (2^32-1)*2 的 bit 类型的数组bitArr,用2个位置表示一个数出现的词频;
      bitArr占用空间计算 (2^32-1)*2 bit = 2^3 * 2^10 * 2^10 * 2^10 - 2 bit ≈ 1GB
    • 具体操作,遍历 40亿 个非负整数
      如,num数字
      未出现(初始设置) bitArr[num2]和bitArr[num2+1]分别设置为 00
      首次出现 bitArr[num2]和bitArr[num2+1]分别设置为 01
      2次出现 bitArr[num2]和bitArr[num2+1]分别设置为 10

      2次出现 bitArr[num2]和bitArr[num2+1]分别设置为 11

    • 遍历 bitArr
      若 bitArr[i2]和[i2+1]为10,则i就是出现了两次的数
  • 相关阅读:
    Flask Web 安装bootstrap失败pip install bootstrap
    ERC-7401:嵌套 NFT 标准的全新篇章
    C#的Array 类使用说明
    算法学习-优先队列(堆)
    【服务器数据恢复】Linux网站服务器的数据恢复案例
    Day3:面试必考题目
    【华为上机真题 2022】TLV解码
    .NET C#基础(7):接口 - 人如何和猫互动
    重磅开赛!“山东工行杯”山东省第五届数据应用创新创业大赛报名火热进行中!
    信贷风控指南丨人工智能专家直播解析信贷评分卡模型
  • 原文地址:https://blog.csdn.net/qq_41662142/article/details/132708315