关于一道大数据量大文件的面试题

问题: 

有100W个文件存储单词,每个文件有80M到10G的大小,设计一种数据结构找出出现次数最多的前10个单词

备用解决方案:


我的想法是用红黑树的思想来做,设计树节点结构
struct Node
{
  bool operator >=(Node&);
  char words[];
  int count;
};

把每个单词出现的情况构造成node插入树节点,但是这样可能内存不够的问题没有考虑到,直接
被鄙视了。。。面试官说这是很简单的一道题。。。。。
看来人的弱小时掩饰不了的,听听各位牛人们的设计思想

 

(1)可以用hash表,但不要用那个线性链表,把它换成堆就可以了吧(堆保存10个次数最多的单词),每读入一个数据,更新hash表,再更新那个堆就行了。

 

(2)不用考虑分布式吧。你写的是应用程序,负载平衡应该自动由系统来完成。

你所考虑的,一个是如何并发,另一个是单个操作如何提升效率。10G的文件,一般是不会直接全部读入内存的,若是个文件都这么搞,服务器再怎么大,也早崩溃了。现在的主流服务器,内存也就32G-64G左右。所以,文件操作肯定是用流。不过这些都不用考虑。你所考虑的,是用一个什么数据结构来实现一段数据的操作。

 

(3)先hash,hash值相同的单词输入一个文件;再分别读取hash后的文件,求得每个单词的个数存入一个文件;最终再读读取含单词统计个数的文件,建立大顶堆即可求的结果。
大数据处理基本思想丢是大变小,分而治之

 

(4)hash+大根堆

 

 

(5)小根堆是可以,但先得统计单词的出现次数。
考虑仅仅面对的是单词,100w个单词重复应该挺高了,统计次数可以用trie树吧,能节省内存,而且也是精确的。
然后查找树中出现次数最多的前10个。遍历整棵树,构建小根堆就可以了。

 

(6)july博客里有讲海量数据处理,但的确讲的有地方不对,正统的办法借助外存来计数(B树之类),其实也就是数据库.

为什么说内存中处理有问题.

首先,极有可能大量的字符串哈希到同一个文件中,对于这种情况,july说可以对大文件再次哈希,这个我没有异议。 但这就意味着同一个字符串,可能出现在多个文件中,每个文件分别得到top 10计数的字符串,问题规模相对变小了,而且每个文件top10进行归并得到的计数绝对不等于所有文件中的top10,这是完全错误的想法,可以自己设想情景。

假设A文件中若干字符串,它们的计数都很大,1-10名都出现了100次,第11名字符串是'STR',出现了99次,所以落选了。

B文件中也有若干字符串,第一名是‘STR’,出现了10次,2-10名都是一些不是A中的字符串。

很明显,归并之后,‘STR’明明是99+10次的,却悲剧的排在第11名,只计了10个。全都是因为A文件中牛逼的字符串太多了,'STR'已经不在前10被抛弃了。 即便B文件中'STR'争取了第一名也无济于事。


所以,我认为应该多利用数据库,谁说数据库就没技术含量了,学问太大了。

 

 

(7)使用位图算法。 
每个单词可以经过哈希等算法换算为一个唯一的long型数字

 

 

http://topic.csdn.net/u/20110826/20/582c4e12-86e7-4d15-8a65-0edce1eeed86.html?seed=746420099&r=75246646#r_75246646

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值