“在 2G 大小的文件中,找出高频 top100 的单词?”
这是一个典型的 top k 问题,在面试的时候,会产生很多变体。
但是不管怎么变,top k 问题的本质是一样的。
另外,对于这类问题,我们可以发散自己的思维去回答,因为这类问题本身没有啥标准答案。
这个问题的关键因素有两个:
- 2G 大小的文件,意味着文件很大并且也无法一次性 load 到内存里面
- 需要从这么大的文件中做筛选,如果用普通的思维方法,查找速度很慢
因此可以从这两个方面着手去思考回答思路。
思路
关于这个问题,我说一下我的回答思路
- 把 2G 的文件进行分割成大小为 512KB 小文件,总共得到 2048 个小文件,避免一次性读入整个文件造成内存不足。
- 定义一个长度为 2048 的 hash 表数组,用来统计每个小文件中单词出现的频率。
- 使用多线程并行遍历 2048 个小文件,针对每个单词进行 hash 取模运算分别存储到长度为 2048 的 hash 表数组中inthash=Math.abs(word.hashCode() %hashTableSize);hashTables[hash].merge(word, 1, Integer::sum);
- 接着再遍历这 2048 个 hash 表,把频率前 100 的单词存入小顶堆中
- 最后,小顶堆中最终得到的 100 个单词,就是 top 100 了。
这种解决方案的核心思想是将大文件分割为多个小文件,然后采用分治和堆的算法,来解决这个问题。