日期:2014-05-20  浏览次数:20719 次

新浪面试题 java实现以及分析? 求助
原文http://bbs.csdn.net/topics/360185918   看了半天不是很理解 ,再拿出来  看看各位的意见!

有一个大小为2G的文件,存储微博里的粉丝关系。文件有两列,每列都是一个整型数。如某一行的两列分别为:123456 654321。
则代表id为654321的用户是id为123456的用户的粉丝。如果用户123456又是654321的粉丝,则称这两个用户互粉。
要求找出文件里所有的互粉用户。

对这个问题没有实现思路?主要是问问各位大牛 java来实现的思路

1 有一个大小为2G的文件   去掉这一句的,也就是用普通大小的文件,  如何来实现?

2 加上  有一个大小为2G的文件  这个限制   我们又该如何去设计和优化?


------解决方案--------------------
引用:
第一点:
读取出来  用一个MAP存储,遍历 map,对于每一个 如果有 map.get(key) = value;map.get(value) = key;那么这两个互粉。然后保存到另一个数组或list什么的面里,移除这个key值,继续下一条。直到完成。另外存储的数组或list里面的就是有互粉的


互粉的话,应该是两条记录。
不知道这样行不:
1. 用List<String> strList存一行记录,String格式要求为:a b
(a、b表示两个用户,以空格分隔。)
2. 每读取一行就拼装String strTmp="a b"和String strReverse="b a",若strReverse在strList中存在,则说明a b为互粉用户,记录到List<String> fenList中,并且strList.remove(strReverse);
3. 若strReverse在strList中不存在,则 strList.add(strTmp);

极限情况下,所有人都不互粉,如果内存不够的话,可能需要做个数据库来辅助存储下strList的数据了(当然,直接使用数据库也是一种思路)。


------解决方案--------------------
2G只是一个大小的概念,它可能是4g,20g,200g,所以把一个nG的大文件拆分成小文件。这样比单纯依靠内存的方式更具有适应性和扩展性(PS:我处理过最恶心的文件有52G大,接手的时还以为自己看错了。)

hash是比较常见的办法,但是因为有互粉,单纯针对一个id做分段,很可能互粉的两条记录被拆到不同的文件里去。

既然id是整数,简单的办法是把两个id相加得到一个值idres,互粉的两条记录idres必然是相同的。

现在可以针对idres做一致性hash了,然后把2g的文件,写入n个小文件(比如1m)里,并且互粉的两条数据必然在同一个文件里。

现在无论用性能好或坏的算法,都无所谓了,重复而且固定量的小数据处理,把互粉的用户选出来。


这么做的好处是:
1. 最坏情况下性能可靠。
也就是说无论文件中互粉的两个用户间隔多远,互粉查询算法有多差(这一步也许是个新手来完成的),运算性能不会有明显的问题。

2. 运行时资源需求低
拆分文件只是一个输入输出流,照抄网上的读文件,那么源文件也就占用一个缓冲区。

3. 扩展性好
源文件大小变化再大,都适用这个设计。

缺点:
1. 文件拆分会造成大量的io操作
2. 理想条件下,花费时间不如特定的算法

------解决方案--------------------
可以用数据库不
 create table fans(
 id number(6),
 fansid number(6));

select * from fans a,fans b where a.id=b.fanid and a.fanid=b.id;


------解决方案--------------------