论坛首页 招聘求职论坛

面试遇到大数据量的问题到底在考什么?

浏览 21626 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2010-03-17  
楼上为什么不直接用data流写int和读int,你这样做法有什么优势?
0 请登录后投票
   发表时间: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);
	}
0 请登录后投票
   发表时间:2010-03-17  
一帮人长篇大论, 连楼主最基础的算法是对是错都没看明白。
这么明显的错误没人知道?数据切分来取交集???
A和A1没有交集, A和B1可以有交集么?A就这么被你丢掉了。。。
真搞笑, 顺序执行的程序还在用线程。。。。。
0 请登录后投票
   发表时间:2010-03-17  
看懵掉了  楼上正解。。。
0 请登录后投票
   发表时间:2010-03-17  
veryls 写道
楼主,这种题会想到多线程真牛逼,先去看看计算机原理,看看cpu,内存是怎么工作的,再来谈多线程

++,真是服了YOU! 我只想说LZ实在太有才,不是我等敢与之比肩的.
0 请登录后投票
   发表时间:2010-03-17  
flysunsystem 写道
veryls 写道
楼主,这种题会想到多线程真牛逼,先去看看计算机原理,看看cpu,内存是怎么工作的,再来谈多线程

4G的数据放在文本文件中如果是8G或者16G的数据呢?你想怎么搞定?看你写这两句话,貌似很牛逼,牛逼给个思路解决。


引用抛哥个一句话,牛b的人往往是牛逼哄哄。
0 请登录后投票
   发表时间:2010-03-17  
跟多线程没有什么关系吧

第一题:数据再大也不怕,分组读入,只用读入数据保存当前最大值和最小值,然后继续读入数据,跟最大最小值比较,符合就替换,复杂度应该是O(n)

第二题:我的想法是先对2个集合排序,然后遍历一次求集合,排序复杂度是O(nlogn),遍历一次复杂度是O(n),总共大约是O(nlogN+n),不过还有更快的方法,都是整数的话,用位图法,一个位代表一个整数,2个集合就设置2个位图,读入数据,置相应的位图为1,全部读入后对2个位图做与操作,再读入每个位所代表的数据,复杂度是O(n)

0 请登录后投票
   发表时间:2010-03-17  
已经把一个完整的CPU给你用了,你还多线程个什么劲啊,又不是让你跟很多程序同时运行,什么思路啊,还感觉自己很牛逼了
0 请登录后投票
   发表时间: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);

这样也可以解第一个问题。
0 请登录后投票
   发表时间:2010-03-18  
比大小用多线程确实有点牵强了,lz的思想不过是用一个有限大缓存数组多次去读取解决大型文件。
0 请登录后投票
论坛首页 招聘求职版

跳转论坛:
Global site tag (gtag.js) - Google Analytics