海量数据面试题
哈希切割
给一个超过100G 大小的 log fifile, log中存着 IP 地址, 设计算法找到出现次数最多的 IP 地址? 与上题条件相同, 如何找到 top K 的 IP ?如何直接用 Linux 系统命令实现?
思路:
- 先把这这个 log fifie 分成拆分成很多个小文件。小文件的大小并不是相等的,而是在拆分过程中,根据某个哈希函数把 ip 进行哈希的方式存储在一个个小文件中,尽量让相同的 ip 在同一个小文件中。
- 在上面拆分的过程中需要将整个文件遍历一遍,在遍历的过程中,顺便建立一个哈希表,对 ip 采用哈希函数求得 key 值,然后对所有 ip 出现的次数进行记录。并且维护一个遍历记录当前出现次数最多的 ip,拆分完也就知道那个 ip 出现次数最多。
- 维护一个大小为 K 的小堆。先插入 K 个 ip 后,每次在 1 过程分类 ip 的时候都根据哈希表比较一下。最后这个堆的元素,就是 Top K IP。
使用 Linux 命令实现对一个文件的哈希值计算。
md5sum
位图应用
1. 给定 100 亿个整数,设计算法找到只出现一次的整数。
思路:
- 使用两个位图的对应位表示一个整数的状态。也就是说用两个比特位来表示一个整数的状态。
- 00 表示没出现过
- 01 表示出现过一次
- 10 表示出现一次以上
- 因为整个的最大范围也就是 42 亿多,所以创建两个 500M 的数组来作为存储所有整数状态的位图。
- 将所有整数表示到位图中,状态为 01 的比特位经过计算就可以得到只出现一次的整数。
2. 给两个文件,分别有 100 亿个整数,我们只有 1G 内存,如何找到这两个文件的交集?
思路:
- 创建两个大小为 500M 的整形数组分别作为两个文件的位图。
- 将两个文件的所有数字分别表示到这两个位图中。
- 对两个位图进行与运算,就可以找到交集啦。
布隆过滤器
1. 给两个文件,分别有 100 亿个 query, 我们只有 1G 内存,如何找到两个文件交集?
思路:
近似算法:先将一个文件的所有 query 放进一个布隆过滤器中,然后用第二个文件对这个已经填充好第一个文件的布隆过滤器进行查找。
精确算法:利用哈希切割的方法对两个大文件进行切割,将相同的 query 放进相同编号的小文件里,然后打开一个小文件的同时也打开另一个相同编号的小文件,就可以查看是否存在。
2. 如何才能使 BloomFilter 支持删除操作?
思路:
原本布隆过滤器的底层封装着位图,可是如果要支持删除操作,就需要将原本的位图换成数组采用引用计数的方式,每次删除引用计数 -1。
但是这个做法会大大的违背布隆过滤器节约空间的初衷。
倒排索引
给上千个文件,每个文件大小为 1K ~ 100M。给 n 个词,设计算法对每个词找到所有包含它的文件,只有 100K 内存
思路:
对文件进行哈希切割,然后用单词名((文件里的单词)作为 map 的 key,value是一个链表,链表保存文件名。然后对文件进行遍历,将文件里的单词进行插入,最后插完之后所有的单词以及每个单词对应的文件名就保存在了map里。
然后给一个单词,现在 map 里找到对应单词,然后就可以得到包含该单词所有的文件名。
叮~?