面试题---大数据处理

1、给一个超过100G大小的log file ,log中存着IP地址,设计算法找到出现次数最多的IP地址?
我们先考虑一下,100G大小的文件,一般是无法存到普通的计算机中的,我们的硬盘根本没这么大; 我们可以使用前面讲的位图,一个整形32位,最多可以存42亿多的数据,100G的大文件,最多需要3.2G就可以放进去,但是却难以统计最多的IP地址。

为了解决上面的问题,我们可以把大文件放到小文件中,再来统计就会很容易 。
算法思想:哈希切分
(1)哈希函数hash(IP)%1000个文件,这样大文件就可以分成1000个小文件。 
(2)通过同一个散列函数映射到相应的文件,此时同一个ip一定会映射到同一个文件
(3)字符串哈希函数将字符串转换为整数
(4)用<ip,次数>统计,底层用unordered_map实现

2、和上面的条件相同,如何统计Top K的IP?
(1)本题采用哈希切分,如上题,统计每个ip出现的次数
(2)用文件的前K个数建小堆
(3)用K+1个数和堆顶相比,大的话替换,调整堆

3、给定100亿个整数,设计算法找到只出现一次的整数 

我们有几种方法:
(1)遍历:内存足够的情况,常规的算法是将这个100亿个整数放到内存中然后用查找 ,时间复杂度O(N^2)
(2)排序:对数据排序,寻找出现一次的数,时间复杂度O(Nlog2N+N)
(3)如上,哈希切割
(4)分组:根据数的二进制表示分组,从最高位位依次往下。
(5)用位图,位图一般表示一种状态。所以需要扩展: 

我们可以分为三种状态:不存在 、存在一次 、存在多次
用位图的扩展:
2个位表示一种状态,00表示不存在,01表示存在1次,10表示多次 。

4、给定两个文件,分别有100亿个整数,我们只有1G的内存,如何找到两个文件的交集?
有以下考虑方式:

(1)将一个文件切割成1000份,分别将每一份加载到内存中,然后用第二个文件中的数据到每一份中查找,时间复杂度为(O(N^2))。

(2)哈希切分。通过一个散列函数,将相同的数映射到同一个文件中,并对文件进行编号。如果两个文件存在交集,一定会在编号相同的文件中产生交集,这时候只需要将他们编号相同的文件比较即可,时间复杂度为(O(N))。
如下图:

(3)位图。将一个文件中的数据映射到位图中,然后再用第二个文件中的数据到位图中查找。时间复杂度为(O(N))。
5、1个文件有100亿个int,1G的内存如何找到出现次数不超过2次的整数
和第三题相同,不过此题有存储空间的要求,因此首先考虑1G内存。
按照前面我们学的位图,一个整形32位大约可以存储40多亿整数,100亿个整数大约需要1.25G的内存,可是此时的内存只有1G如何存储呢?
我们可以用两个比特位来表示一个数,这样512M左右的内存就可以存下。
这里我们同样用:
01表示数字出现1次,10表示数字出现2次,11表示数字超过两次
这样就可以快速找到出现次数不超过2次的数字

6、给定两个文件,分别有100亿个query,我们只有1G的内存,如何找到两个文件的交集,给出精确算法和估计算法
可以发现和第四题很像:
估计算法步骤:
(1) 通过字符串哈希算法,将字符串转换成数字
(2) 通过散列函数将这些数字映射到内存中
(3) 判断映射的位置是否都存在,存在表明有交集.
精确算法:
同样这时100G的大文件,和前面查找交集一样,我们把这两个大文件A,B分别按照hash切分,分成1000分的小文件,这样就可以放到内存中,然后我们拿A中的小文件分别和B中的比对,这样就可以找到两个文件的交集
7、如何扩展BloomFile使它支持删除

由于布隆过滤器查找,不存在为准确,存在为不准确。
如果很多个元素拥有相同的BIT位,此时删除其中一个位,会影响到其他的数据,所以不能删除。
因此要删除可以采用对每个位进行引用计数。

8、如何扩展BloomFile使它支持计数
在位图中我们知道,用位就可以表示数字的状态,这样就可以计数
9、给上千个文件,每个文件的大小都在在1K~100M,给n个词,设计算法找到每个包含它的文件,只有100k的内存 

倒排索引思想,比如在浏览器中搜索python显示的内容,网页会给出所有的python相关的内容,同时python变成高亮。百度网页是从爬虫来的,在搜索中采用分词。
(1)一个文件info 准备用来保存n个词和包含其的文件信息。
(2)首先把n个词分成x份。对每一份用生成一个布隆过滤器(因为对n个词只生成一个布隆过滤器,内存可能不够用)。把生成的所有布隆过滤器存入外存的一个文件Filter中。
(3)将内存分为两块缓冲区,一块用于每次读入一个布隆过滤器,一个用于读文件(读文件这个缓冲区使用相当于有界生产者消费者问题模型来实现同步),大文件可以分为更小的文件,但需要存储大文件的标示信息(如这个小文件是哪个大文件的)。
(4)对读入的每一个单词用内存中的布隆过滤器来判断是否包含这个值,如果不包含,从Filter文件中读取下一个布隆过滤器到内存,直到包含或遍历完所有布隆过滤器。如果包含,更新info 文件。直到处理完所有数据。删除Filter文件。