一网打尽海量数据面试问题

     原文发表于:

      周末,深圳,又是大雨。今天来聊海量数据。

      海量数据,是BAT笔试面试中的常客,TMD也纷纷效仿,其余公司也紧随其后。在实际工作中,也确实会涉及到类似问题。

      海量数据,从时间上讲,难以快速处理。从空间上讲,难以一次加载到内存。针对海量数据,我们需要对时间和空间进行预估,而不是一根筋蛮力处理。

       海量数据处理的常见思路如下:

扫描二维码关注公众号,回复: 12272123 查看本文章

       1. 哈希分治,重新分类

       2. hash map, O(1)查找

       3. hash map, 统计计数

       4. bitmap, 节省空间

       5. bloom filter, 节省空间

       6. trie树,节省时间

       7. 文件桶,化大为小

       8. 堆,求出top K

       9. 快速排序,局部求解

       10. 外排序,多路归并

       在很多场景下,要综合使用上述多种方法和工具。也可能会用到其它的一些奇技淫巧,比如异或,比如纯数学。

       接下来,我们直接看海量数据相关的问题。

问题1

      问题:有100亿个uint32元素,判断其中是否有相同元素。内存限制:1K

      如果不够敏感,则会在这个问题上陷入死局。任何一个程序员都应该在3秒内知道一些常识,比如:

      a. 一天有8万多秒

      b. uint32的最大值接近43亿

     所以,根据抽屉原理可知,100亿个uint32元素中,必然存在相同的元素。

问题2

      问题:有40亿个uint32元素,判断其中是否有相同元素。内存限制:1.2G

     40亿个uint32元素,无法直接加载到内存中,可以考虑使用2个bitmap, 总占用内存为1G. bitmap的知识请参考:

      笔试面试题目:求整数的交集(使用bitmap)

     具体来说,就是创建两个bitmap,即bm1和bm2, 用它们对元素x进行标记,可以记录x的四种可能情况:

bm1[x] bm2[x] 含义
0 0 x出现0次
0 1 x出现1次
1 0 x出现2次
1 1 x出现多次

       

问题3     

      问题:有40亿个uint32元素,判断其中是否有相同元素。内存限制:0.6G

      

      显然,2个bitmap需要内存是1G,  不符合要求。怎么办呢?可以使用一个bitmap.  bitmap的知识请参考:

      笔试面试题目:求整数的交集(使用bitmap)

     具体来说,就是把40亿个元素读到bitmap中做标记,并统计bitmap中的元素个数count,然后用count跟40亿进行比较,便可以判断是否存在相同元素。

问题4   

      问题:有40亿个uint32元素,试去重。内存限制0.6G

   

      显然,直接读到bitmap中即可,直接实现去重,内存消耗512M. 关于bitmap的知识请参考:

      笔试面试题目:求整数的交集(使用bitmap)

问题5

      问题:有40亿个不重复的uint32元素,试排序。内存限制0.6G

     由于元素不重复,故可直接读到bitmap中,然后直接遍历,就实现了排序,内存消耗512M, bitmap的知识请参考:

      笔试面试题目:求整数的交集(使用bitmap)

问题6

      问题:有40亿个uint32元素,试排序。内存限制0.6G

     元素可能有重复值,故不适合用bitmap. 此时,可以考虑使用桶排序,桶是海量数据处理的天然利器,参考:

      华山论剑之桶排序

     当然,如果对多路归并排序有所了解,也可以考虑多路归并排序。多路归并其实也用到了桶的思想,但每个桶之间,需要通过归并实现排序。显然,多路归并排序不如直接使用上述桶排序。

问题7

      问题:有40亿个不重复的uint32元素,求top K. 内存限制0.6G

      由于元素不重复,故可直接读到bitmap中,实际上就实现了排序,那么获取top K就易如反掌了。bitmap的知识请参考:

     笔试面试题目:求整数的交集(使用bitmap)

问题8

      问题:有40亿个uint32元素,求top K. 内存限制0.6G

      元素可能重复,故不适合直接使用bitmap来做。堆是非常适合这种情况的,参考如下:

      笔试面试题目:求top-K(使用堆)

      

问题9

      问题:有40亿个不重复的uint32元素,求中位数。内存限制0.6G

       

      由于元素不重复,故可以直接读到bitmap中,实际上就实现了排序,然后找中位数就易如反掌了,内存消耗512M, bitmap的知识请参考:

      笔试面试题目:求整数的交集(使用bitmap)

问题10

      问题:有40亿个uint32元素,求中位数。内存限制0.6G

       

     元素可能重复,故不适合直接使用bitmap, 此时可以考虑用桶,参考如下:

     笔试面试题目:求海量数据的中位数

问题11

      问题:有40亿个uint32元素,判断n是否存在于这40亿个元素中。内存限制0.6G

       

     直接bitmap搞起,把40亿个元素读到bitmap中,然后判断bitmap[n]的值是否为1即可,内存消耗512M, bitmap的知识请参考:

     笔试面试题目:求整数的交集(使用bitmap)

问题12

     问题:A文件有40亿个url, 判定给定url是否在其中,允许有一定的误判率。内存限制0.6G

  

     Bloom Filter就是为这种场景而生的,直接参考:

     判断元素是否存在于集合中(使用Bloom Filter)

问题13

      问题:A文件有40亿个uint32元素, B文件有4万个uint32整数,求交集。内存限制0.6G

  

      这个问题,直接用bitmap,直接参考:

      笔试面试题目:求整数的交集(使用bitmap)

问题14

      问题:A文件有40亿个uint32元素, B文件有4万个uint32整数,求交集。内存限制10M

  

     由于可用内存很小,故无法使用bitmap. 可以考虑哈希分治的思想,化大为小,直接看如下第15题的思路即可。

问题15

      问题:A文件有40亿个url, B文件有4万个url,求交集。内存限制100M

  

     显然,需要化大为小,可采用哈希分治的思想,直接参考:

     笔试面试题目:求url的交集(使用哈希分治)

问题16

      问题:某文件有黑客攻击的海量来源IP,  求次数最多的IP. 

  

      这个问题,首先要计算出每个IP的次数,然后对次数求top K,  具体如下:

      Step1: 通过哈希分治, 把相同的IP划分到相同的小文件桶中。

      Step2: 使用hash map统计每个小文件桶中IP出现的次数,求出每个小文件桶中次数最多的IP.

      Step3: 遍历每个小文件桶, 求出全局出现次数最多的IP.

问题17

      问题:在某台服务器的100个文件中,记录着黑客访问的来源IP,  求次数最多的10个IP.

  

     首先要使用哈希分治,将100个文件中的相同IP分配到相同的文件中,然后采用如上第16题类似的方法,求出访问次数的top 10.

问题18

      问题:文件总共有1万行,每行一个单词,统计出现次数最多的10个单词。

  

     总共才1万行,内存完全能容纳下所有数据,故可直接在内存中处理,用hash map来统计频次就行,然后对频次进行排序。

      另外,可以用trie树来做,直接参考:

      搜索引擎提示功能的实现(使用trie树)

      注意,trie树除了用于计数,还能用来查找、前缀匹配、去重和排序,用途大大的。

     

猜你喜欢

转载自blog.csdn.net/stpeace/article/details/109543892