锁定老帖子 主题:面试遇到大数据量的问题到底在考什么?
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-03-17
楼上为什么不直接用data流写int和读int,你这样做法有什么优势?
|
|
返回顶楼 | |
发表时间:2010-03-17
开始那个读文件算法乱写的 现改为如下 :
优势是是先判断高位 高位如果比现在的小 就无须继续判断低位 缓存依然是 40M 机器好的自己改 总共耗时5分钟 public static void printMax() throws IOException{ String path="d:/bf"; File file=new File(path); FileInputStream fis=new FileInputStream(file); byte[] max=new byte[4]; byte[] b=new byte[40000000]; for(int i=0;i<100;i++){ fis.read(b); for(int j=0;j<10000000;j+=4){ if((b[j]>max[0])&&(b[j+1]>max[1])&&(b[j+2]>max[2])&&(b[j+3]>max[3])){ max[0]=b[j]; max[1]=b[j+1]; max[2]=b[j+2]; max[3]=b[j+3]; } } System.out.println(i+"%"); } fis.close(); int intMax=0; for(int i=0;i<4;i++){ intMax+=max[i]<<(3-i); } System.out.println(intMax); } |
|
返回顶楼 | |
发表时间:2010-03-17
一帮人长篇大论, 连楼主最基础的算法是对是错都没看明白。
这么明显的错误没人知道?数据切分来取交集??? A和A1没有交集, A和B1可以有交集么?A就这么被你丢掉了。。。 真搞笑, 顺序执行的程序还在用线程。。。。。 |
|
返回顶楼 | |
发表时间:2010-03-17
看懵掉了 楼上正解。。。
|
|
返回顶楼 | |
发表时间:2010-03-17
veryls 写道 楼主,这种题会想到多线程真牛逼,先去看看计算机原理,看看cpu,内存是怎么工作的,再来谈多线程
++,真是服了YOU! 我只想说LZ实在太有才,不是我等敢与之比肩的. |
|
返回顶楼 | |
发表时间:2010-03-17
flysunsystem 写道 veryls 写道 楼主,这种题会想到多线程真牛逼,先去看看计算机原理,看看cpu,内存是怎么工作的,再来谈多线程
4G的数据放在文本文件中如果是8G或者16G的数据呢?你想怎么搞定?看你写这两句话,貌似很牛逼,牛逼给个思路解决。 引用抛哥个一句话,牛b的人往往是牛逼哄哄。 |
|
返回顶楼 | |
发表时间:2010-03-17
跟多线程没有什么关系吧
第一题:数据再大也不怕,分组读入,只用读入数据保存当前最大值和最小值,然后继续读入数据,跟最大最小值比较,符合就替换,复杂度应该是O(n) 第二题:我的想法是先对2个集合排序,然后遍历一次求集合,排序复杂度是O(nlogn),遍历一次复杂度是O(n),总共大约是O(nlogN+n),不过还有更快的方法,都是整数的话,用位图法,一个位代表一个整数,2个集合就设置2个位图,读入数据,置相应的位图为1,全部读入后对2个位图做与操作,再读入每个位所代表的数据,复杂度是O(n) |
|
返回顶楼 | |
发表时间:2010-03-17
已经把一个完整的CPU给你用了,你还多线程个什么劲啊,又不是让你跟很多程序同时运行,什么思路啊,还感觉自己很牛逼了
|
|
返回顶楼 | |
发表时间:2010-03-18
最后修改:2010-03-18
基本上考的是
数据结构和算法,而已有一定的技巧性。 推荐看一本《编程珠玑》 通过你的描述. 如果你的机器上int 为32位的话。 int max ,int min 先按无符号的数据来算吧,最大的值为4294967295 不到 43亿。 也就是可以说,去除重复后,文件中的整数不会超过43亿个。 43亿个整数 int 大小 4294967295 * 4B(每个int四个字节) 约等于 17179869180 B(字节)约等于16777215KB 约等于16383MB 约等于 16G 放入内存排序不要想了。 问题是找出最大的和最小的值。 那么,可以确定的是,最大值一定在 0-4294967295 之间。 如果定义一个数组int[4294967295]可以做的话,一个好的办法。 是用类似桶排序的原理。将对应的值扔到对应下标的数组里,如果有1233这个整数,就把下标1233的值设置为1. 那么最后一个不为空的位置 就是最大值,第一个不为空的就是最小值。 时间复杂度为 O(N),空间O(N),但是N太大,内存扛不住。 每个数组元素 取值只有1和0. 用Int型有些浪费了。用一个二进制位就可以表示了。 如果把int[4294967295] 型数组,每个元素大小缩小32倍。int 大小是32位,那么这个数组 可以表示为 bit[4294967295] 大小约等于4294967295/8 = 536870911B约等于534287KB约等于512M了. 那么别说是4G了,8G,100G也不会过这个范围。 算法描述如下 1bit = byte/8; bit[4294967295] = init{0}; for(遍历文件)//可以批量读入提高性能。 { 取一个整数 X setBit(x);//将第x位值设置为1 } //找出最大值 for(int i = 4294967295;i>=0;i--) { if(bit[i]==1)return i;//i为最大值 } //找出最小值 for(int int = 0; i <= 4294967295;i++) { if(bit[i]==1)return i;//i为最小值 } 如果你觉得单线程处理不够快,那么就引入多线程。 把文件分割成N块(前提是你知道如何分割)如果分割不了,可以用两个线程首位读文件,两个指针相遇结束。 每个线程都执行 setBit(x)操作,并且不需要同步,但是多线程不一定可以提高性能啊。 如果是无符号数据的话,略微变形也可以解决。 第二个问题,也可以用类似方法解决,不过数组元素大小设置2bit就可以了。空间也不会超过1G的。 另外,如果不把数据读取内存中。 int max = 文件第一个int数据 int min = 文件第一个int数据 for(遍历文件)//可以批量读入提高性能。 { 取一个元素X if(max<X)max = x; if(min>X)min = x; } print(max); print(min); 这样也可以解第一个问题。 |
|
返回顶楼 | |
发表时间:2010-03-18
比大小用多线程确实有点牵强了,lz的思想不过是用一个有限大缓存数组多次去读取解决大型文件。
|
|
返回顶楼 | |