面试中问最常问的海量数据处理你拿捏了没?

目录

问题一:在40亿数据中查找一个元素是否存在?

 1.位图解决相关问题

问题二:给一个超过100G大小的log fifile, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 与上题条件相同,如何找到top K的IP?

2.哈希切割

问题三:给定100亿个整数,设计算法找到只出现一次的整数?

1.双位图法:

2.单位图法:

3.比特位法:

问题四:给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?

方法一(哈希切割):

方法二(位图):

问题五:个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数。

问题六:给两个文件,分别有100亿个query(字符串),我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法。


问题一:在40亿数据中查找一个元素是否存在?

 1.位图解决相关问题

不了解位图的可以看我关于位图详细介绍的文章充充电:http://t.csdn.cn/85NPThttp://t.csdn.cn/85NPT

首先我们来计算一下不用位图的方式来查询四十亿数据。那么我们首先大概计算一下40亿数据大概是占用多少内存。

我们可以看到40亿数据有大约16个G我们采用内部排序(这里查找的本质就是排序,就是在查找的过程中对每个元素进行排序对比)是很难进行的因为要一次性将16G的数据全部都加载到内存中才可以一一进行查找比对。但是实际中我们的内存可能只有8G或者16G要是将这16G的数据全部都加载到内存中肯定是不合理的。那么就需要外部排序,但是外部排序也需要对文件进行合并排序,排序复杂而且耗费时间。那么我们就可以用位图的方式来轻松解决。

我们可以看到用位图的方式我们只需要申请512M数据就可以实现40亿的数据的查找。具体的方式就是用这512M的位图每个比特位1和0两个状态来表示每个数据是否存在。如果存在就为1不存在就为0。那么我们通过计算要判断的数据在位图中的位置,查看位图中比特位是否为1,从而来判断该元素是否存在。

问题二:给一个超过100G大小的log fifile, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 与上题条件相同,如何找到top K的IP?

2.哈希切割

这里我们插入介绍哈希切割因为下面应用位图解决的题还可以用哈希切割来解决。

刚刚我们上面看了用位图来处理海量数据我们可以发现是非常简单的但是也是仅仅限于查找某个元素是否在某个区间中出现。那么我们对于在海量数据中求解top-k的问题还需要用哈希来解决。例如下面问题:

  • 答案:1.面对这样一个问题我们首先想到要统计每个数据出现的次数。那么我们就需要将每个数据放到unordered_map当中然后统计次数但是显然这是不合理的,100G的数据全部加载到内存中内存肯定爆满,那么这样显然是不行的。
  • 2.那么我们顺其自然的就像到了将100G的数据进行分组将其分为100份也就是每个文件中存放1G的数据然后将每个文件中出现最多次数的ip地址求出来,然后再在这一百个出现次数最多的ip地址中求出出现次数最多的那一个ip地址这样貌似就将问题解决了。但是我们不得不还要考虑一个问题,那就是你不可以保证同一个ip地址都在同一个相同的文件当中。

  • 3.我们分析到上面那一步之后我们发现现在最主要的问题就是解决相同ip地址分布在不同的文件中的问题,那么我们可以想到一个办法,那就是哈希桶,将相同的ip地址放到同一个文件中。
  • 3.1首先我们要考虑分为多少个组合适:
  • 我们来分析一下,如果我们将文件像上面一样分为一百份,也就是一百个哈希桶,这样看似合理,但是不要忘了还有哈希冲突。有可能多个ip地址都集中分布在同一个桶中,而一些桶中没有ip地址。对于ip地址多的桶,我们就可能无法一次性将桶中的ip地址都读入到内存中。那么我们就考虑分为更多的桶,例如200个300个,让ip地址在各个桶中的数量分布均匀。
  • 3.2接下来我们就要将ip地址往对应的文件当中放
  • a:首先将每个ip地址转化为整型数字,直接利用库函数进行转化。这里将字符串形式的ip地址转化为一个无符号的32位整数之后可以更好的利用空间,因为字符串的点分十进制的方式的ip地址最大占16个字节(带'\0')这里转化位一个无符号的整型数字可以直接节省大约4倍的空间。

  • b:我们将读进来的ip地址转化为整型数字之后对整型数字%哈希桶数量然后将相应的ip地址放入相应的文件中。
  • 进行上面的操作之后那么我们就将相同的ip地址都放入到相同的文件当中了。
  • c:接下来我们就可以在每个文件当中统计每个文件当中出现最多的ip地址(这里我们还可以用多线程的方式来进行处理每个线程处理一个文件,让CPU利用率达到最高,而且这些多线程之间也不需要进行同步互斥处理,因为这些文件直接也没有相关联),然后将这些出现次数最多的ip地址进行排序就可以找到出现次数最多的ip地址了。
  • 4.解决top-k问题:
  • 我们可以利用上面求出来的每个文件中出现次数最多的k个ip地址来创建一个小堆,然后利用堆排序比较剩下的元素(也就是后续文件中所得到的出现次数最多的元素)与堆顶元素的大小。如果剩下的元素比堆顶元素大那么就替换堆顶元素然后向下调整。这样循环直到所有元素都比较完成,在堆中的元素就是top-k元素。

问题三:给定100亿个整数,设计算法找到只出现一次的整数?

对于题目说100亿这样的大量数据处理我们第一时间就可以想到用上面的哈希分割方式来解决问题,但是用上面的方式虽然可以求解出正确的答案,可过于耗费时间。我们可以直接用位图的方式来解决问题:

1.双位图法:

  • 我们可以用一个位图来标记数据的出现与否,另一个位图来标记数据是否出现过。具体方式如下

2.单位图法:

  • 我们也可以只用一个位图来进行数据的筛选,可以用两个比特位来表示一个数据的出现次数。

  • 用上面的位图表示方法将每个数字表示出来之后我们最后检测每两个bit位,如果为01的话,那么就找到了只出现一次的数字。

3.比特位法:

  • 我们也可以巧妙的利用不同数字的每个对应的比特位一定是有差异的这一特点来查找不同的数字。

  • 下图中我们举例从第三位最为最高位开始划分,但是实际中我们从整数的最高位开始,也就是从32位开始对所有整数开始划分,直到一个集合中只剩下一个元素。

问题四:给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?

  • 方法一(哈希切割):

    • 先像上面一样将元素用除留余数法放到对应的哈希桶(也就是对应的文件中)中,然后再将另一个文件中的元素也进行同样的方式对其进行除留余数法运算得到的结果然后和对应的哈希桶中去找,如果在哈希桶中找到元素那么这个元素就是与另外一个文件中的交集。
  • 方法二(位图):

    • 这里看到求交集我们就可以想到用位图,就是将两个位图进行按位与操作那么就可以得到两个文件的交集。因为一个整数最多表示2^32个数字,也就是要2^32个比特就可以将其全部表示出来,那么我们用位图就只需要512M的空间就可以将2^32个数全部表示出来。而且题目中给的内存空间大小刚好是1G大小,那么我们就可以用两个位图来表示两个文件中的数字。
    • 具体步骤:
    • a:给定两个位图其中两个位图的bit位数都为2^32个bit。
    • b:将两个文件中的数据映射到位图当中。
    • c:将两个位图进行按位与操作,将结果保存到位图一中。
    • d:然后只需检测位图一中位置为1的元素即可。(找并集只要将所有元素进行按位与操作即可。找差集如果是位图一减位图二的差集那么用位图一和位图二的交集的位图取反之后和位图一相与即可。(A-B=(~(A&B) ) &A ))

问题五:个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数。

  • 答案:这里我们直接可以用上面解决只出现一次数字的单位图法来解决问题,用两个比特位刚好可以表示数字出现0次出现1次出现2次出现多次

问题六:给两个文件,分别有100亿个query(字符串),我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法。

  • 方法一(精确算法哈希分割):
    • 首先我们来谈论精确算法,就是哈希分割,大致思路其实就是和上面的方式类似的我们将一个文件当中的数据经过哈希函数将每个数据分布到哈希桶中。然后我们在利用哈希函数计算另一个文件当中的每个数据的哈希地址,然后我们将拿到的哈希地址到对应的哈希桶中去查找元素,如果找到那么就是两个文件中的交集元素。
  • 方法二(近似算法位图):
    • 因为每个数据是一个字符串那么我们可以想办法将字符串转化位一个整数,然后映射到位图当中。那么就是利用哈希函数将字符串转化为整型数字然后全部映射到位图当中,但是这种方式一定是有缺陷的,那就是字符串经过哈希函数计算后得到整型数字这一过程中一定是会产生哈希冲突的,导致多个不同的字符串都映射到位图中的同一个位置,那么我们找字符串并集的时候就会导致寻找不准确,比如两个字符串是不同的但是经过计算后得到的整型数字确实一样的,这种情况下就会得到不准确的并集。那么我们这里就会用到一种结构来优化这里的位图,使他变得比较准确,那就是布隆过滤器。对于布隆过滤器不了解的可以看我对于布隆过滤器的详细解析文章:http://t.csdn.cn/5PDBQicon-default.png?t=M5H6http://t.csdn.cn/5PDBQ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月半木斤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值