海量数据面试题

1.给出一个超过100G的log file, log中存着ip地址,设计算法找到出现次数最多的ip地址?

思路:

由于文件超过100G,所以我们只能对文件切分,然后再利用数据结构来求解。难点就是如何切分效率最高???

解决方法

这个时候我们可以使用哈希切分,将同一个ip都分割在同一个文件,注意同一个ip经过同一个散列哈希函数一定会进入同一个文件中,然后再统计每一个文件中出现最多的ip的次数,最后将这些进行顺序比较就能的到结果。

又出现一个新的问题?

最极端的情况:如果经过哈希散列函数之后一个ip次数特别多,多到存放这个ip的文件存储不了,怎么办?

这种情况虽然概率很低,但也有可能,博主具体的做法是将这个文件在切分(普通的切分)成若干个小文件,将每一个小文件加载到内存中使用hashTable求出ip出现的次数,最后再将这些小文件的结果汇总后在求出出现次数最多的ip。



2.在上一题的基础上,如何快速找到Top K的ip?

解决方法:

在上一题的基础上,可以借助堆,如果想求每个文件出现次数最多的前K个ip,我们可以使用最小堆,逐个进堆,向下调整,最后堆的元素就是所需元素。如果是次数最小的前K个ip,同理,键一个大堆。



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

ps:100亿 * sizeof(int) ≈ 40G

方法一:切分 + 哈希

首先,我们可以把这100亿个整数分成100份,平均每一份400M左右,再把每一份加载到内存中,使用哈希表进行查找只出现一次的数,最后把这一百份的查找结果汇总到一起在进行查找。

方法二:bitmap(位图)

这个题不能直接用位图,因为这些数有可能出现0次,1次,两次。。。。,只用一个bit位无法表示,所以我们要改变一下思路,不在用比特位来表示每一个数的次数,题目只要求一次,我们可以把情况化为三种情况:出现0次的数字,出现1次的数字,和出现 > 1次的数字。具体做法就是用两个bit位表示,00表示出现0次的数字,01表示出现一次的数字,10(11)表示出现 > 1次的数字。

整型能表示42亿9千万多个数,至少要16G才能存下这些数字,如果换成两个bit位表示的话只需要1G的内存就足够了。因为这些整数有可能有负数,所以我们可以将负数映射到位图的后半部分,也就是将这些负数当做无符号的数看待。

方法三:

整数有32位,我们依次从第一位到第三十二位来划分,每一位分成 0 和 1 两种情况,相同的分成一组,一直划分到第三十二位,这样最多只需要三十二次划分就能判断出出现一次数字。



4.给定两个文件,分别有100亿个整数,只提供1G内存,如何找出两文件交集?

方法一:切分 + 暴力

把一个文件切分成100多份,分别把每一份加载到内存中,然后用第二个文件中的数据到每一份中都进行查找。这种方法的时间复杂度是O(N^2)。

方法二:切分 + 哈希

先对一个文件进行切分,不过这次切分的时候使用一个散列函数,将相同的数都分割到一个文件中去,注意相同的数一定会进入同一个文件,并给这些文件进行编号。再对第二个文件中的数据也使用这个散列函数,并给切分后的文件也进行编号。最后,编号相同的文件即是两个文件的交集,这种方法的时间复杂度是O(N).

方法三:bitmap(位图)

将一个文件中的数据映射到位图中(大约需要500M),然后再用第二个文件数据映射,如果该位图位置为一,则为交集这种方法的时间复杂度是O(N)。但存在误差(因为布隆过滤器的一个位,可能表示多个key)



5.给定两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件的交集?分别给出精确算法和近似算法?

精确算法:哈希切分

如果要得到精确的结果的话,我们可以使用哈希切分,第四题的方法2是一样的,不过在这个题中要将query转换成一个整形,然后再经过散列函数映射到文件中去。

近似算法:bloomfilter(布隆过滤器)

如果要得到近似结果的话可以使用布隆过滤器,和第四题方法三一样。因为布隆过滤器的一个位,可能表示多个key。



6. 10亿个整数找它们的中位数,只有1G内存

方法:

双层桶划分(分而治之)的策略。

我们将10亿个数划分成 10000 个区域。对数据进行第一次扫描,统计各个落到各个区域内的数字的个数。 第一次扫描后,通过统计就可以知道,中位数在哪个区域内,以及它是这个区域的第几大的数字。

进行第二次扫描,这次只统计落到目标区域内的数字,同时结合Bitmap记录都出现了哪些数字。最后通过Bitmap和第一次扫描的结论,就可以找到那个中位数了。

总结: 对于大数据问题,一般都采取分而治之的方法,即:对数据进行分割,之后再利用数据结构的知识求解。可以说这种方法是能够解决绝大多数大数据问题的,但是重点是我怎么划分,有时候如果划分合理的话,就能够极大的提高解决问题的效率。

此外针对某些大数据问题还有其它更优的解决办法,比如bitmap、bloomfilter、Trie树等,所以针对具体问题我们要具体分析,看哪一种方法更优。

针对大数据问题百试不爽的方法就是:切分+数据结构。

你可能感兴趣的:(C++,c++)