Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

海量数据相关的面试题已经是个老生常谈的话题了。相比于小量数据,海量数据存在两点限制:内存装不下或者读取太慢。

关于海量数据的面试题一般有一下几种:

  • 寻找出现次数最多/最少/没有出现的数

对于海量数据的处理方式也不外乎以下几种:

  • 分而治之(将大文件拆分成小文件)

  • hash

  • bitmap

题目

1. 海量日志数据,提取出某日访问百度次数最多的那个IP

思路

这是一道关于统计次数的题,一般使用hashmap或者bitmap就可以解决,使用hashmap时要注意空间是否满足要求。

这个问题有两个点:海量数据,次数最多。

先看第二个点。

把这个问题再提取一下:就是让你在海量数据里去找出现次数最多的那个数。

再提取一下:就是统计次数。问题就很清楚了,使用hash就可以解决。

然后再看第一个点。

海量数据,意味着数据太多,你的hash map内存可能放不下。怎么办?拆分!将这个海量数据拆分成若干个小文件,然后在每个小文件里统计出现次数最多的,最后综合所有的小文件中次数最多的ip找到王中王。是不是有点像归并排序?

那么怎么拆分?假设要拆分成N个文件,可以这么做:hash(IP)%N

拓展

这个问题是找出现次数最多的那个数。那么怎么找出现了一次的?或者,给定一个数,怎么判断它有没有在海量数据中出现过?下面我们一一来看。

  1. 2.5亿整数中找出不重复的整数。

    找出不重复的数,其实也是统计次数,统计只出现一次的那些数,所以上述分割+hash的算法依然可用,不过这里我们再给出另一种更简单的方法:基于bitmap的方法。

    对于每个数,我们使用2bit来表示,00表示出现0次,01表示出现1次,10表示出现多次。

    2.5亿个整数,需要多少bit才能表示完呢,假设这些整数都是int类型的,那么最多也就只有$2^{32}$种数,已经能表示20多亿了,完全够应付这里的2.5亿,再考虑到每个数用2bit来表示出现次数,一共需要$2^{32}*2$bit=1GB.就可以表示这2.5亿个数的出现次数了。

    需要注意的是,上面算出来的1G其实算是大的了,因为真正的并没有$2^{32}$个数,所以没必要开辟这么大空间,现在的开源实现如谷歌的EWAHCompressedBitmap已经对bitmap的内存分配做了很多优化,对于很稀疏的海量数据,那些稀疏数据之间的空缺是没必要申请空间的。

  1. 给定一个数,判断其是否在海量数据中。

    同样可以使用bitmap解决。

  2. 给一串连续的数,缺失了一个,如何找出缺失的那个?

    求和呀

  3. 32位无符号整数的范围是0~4294967295,现在有40亿个数,让你

    (a)找出所有缺失的数

    (b)只找出其中一个缺失的数

    ​ 划分区间,使用区间计数确定区间,然后再用bitmap

评论