新浪面试题 java实现以及分析? 求助
原文http://bbs.csdn.net/topics/360185918 看了半天不是很理解 ,再拿出来 看看各位的意见!
有一个大小为2G的文件,存储微博里的粉丝关系。文件有两列,每列都是一个整型数。如某一行的两列分别为:123456 654321。
则代表id为654321的用户是id为123456的用户的粉丝。如果用户123456又是654321的粉丝,则称这两个用户互粉。
要求找出文件里所有的互粉用户。
对这个问题没有实现思路?主要是问问各位大牛 java来实现的思路
1 有一个大小为2G的文件 去掉这一句的,也就是用普通大小的文件, 如何来实现?
2 加上 有一个大小为2G的文件 这个限制 我们又该如何去设计和优化?
------解决方案--------------------
互粉的话,应该是两条记录。
不知道这样行不:
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;
------解决方案--------------------