`
卒子99
  • 浏览: 74121 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论
阅读更多
   昨天,支付宝在成都招聘,一直关心阿里巴巴的招聘信息,所以一收到消息,马上从外地赶过去。到了,才发现,这次他们只招有工作经验的。虽然我是应届毕业的,但是在读研期间,也在公司上过班,有过几个项目开发经验,所以当时我就好说歹说,表现自己一定能胜任这份工作,不会比别人的差的。最后,他们的技术总监总算给了我一个机会,让我面试工,呵呵,这儿再一次感谢支付宝的HR和他们的技术总监Tommy(不知道拼对了么)。
   因为我做过多个项目,一直对架构很感兴趣,最近又一直在研究Spring,Hibernate,Struts的源代码,而且前面也有了面试经验,所以前面的技术问题都比较简单的搞定了。但最后一个现现场编程题,现在在我看来,确实让我这个缺乏大型项目经验的人露了马脚。
   题目是这样子的:写一个类,读一个txt文件,从中找到aliy这个词,并记录该字符串所在的行数和每一行中的位置。
   我第一反应这个问题很简单,每次循环读一行字符串,然后用String.index方法就可以搞定了。但是在写代码的时候,我却把PrintReader搞错了,写成PrintWriter,唉,用管了IDE就是这样子啊。后来就和技术总监聊这个类还需要什么改进的地方。在他的提醒下,我才注意到。
   第一   每一行不一定只有一个关键词,这是我所没有注意到的,当然在实际的开发中我后来是可以发现的。后来我还想到用正则表达式。还有就是字符可以设置token,直接split几段,还是能找到,当然这三种方法的效率,我确实不太清楚。
   第二  性能的问题,他说,如果是读一个1G的文件,那怎么办。我当时第一反应是那就分段读,然后用多线程处理每一段的字符串。这个问题是我回答的最失败的地方,在回来的车上,我才反应过来,准备的回答应该是通过设置缓存区来读文件。
   回答的如此差,我也不报什么希望了。不过还是要给朋友们提点经验吧,特别是那些刚毕业的,有点项目经验的朋友,因为我们可能面临的问题都是这个。那个时候我在公司上班的时候,有写代码,也有做框架,项目经理始终说的“先把做出来再改进” 事实上在小公司真的很忙很累,对于没有什么经验的人来说,能做出来已经不错了,所以后来那个“再改进”通常就被忽略了,像面对上面的那个问题,虽然事后能想到,但是对于有工作经验的人来,马上就能够反应过来。所以在以后的开发中,除了灵活运用基础知识,还就要从代码的质量方面去多考虑,这样才能够慢慢成长。
分享到:
评论
28 楼 卒子99 2007-06-09  
晕,这个问题还在争啊,看来真是一个经典问题啊,呵呵
27 楼 ddandyy 2007-06-08  
对某些业务来说  数据库是不合适的

比如我现在这个项目就有  是和别的公司的数据库要交互  我们就是用文件来做的  共用一个数据库显然是不现实的  安全性根本就无法保证
26 楼 liquidthinker 2007-06-08  
cxj_2000 写道
liquidthinker 写道
如果问我的话,我就回答为什么会出现这样的问题,改用数据库不可以吗?没有写文件,自然不用读文件,也不会有那么多细节需要处理,都交给数据库就行了.


ls大哥以为数据库是神仙,呵呵。

好些个地方能不用数据库就不用的,否则太多的地方要cactch了。


“好些个地方能不用数据库就不用的”,很不理解哈,做数据存取的,又有这么大的规模,当然是能用数据库则用数据库啊。见过任何mis不用数据库而用文件来做数据存取的吗?本质上数据库的存取也是对数据库文件的存取,但细节被数据库封装了,不用考虑很多底层问题,何乐而不为?
25 楼 cxj_2000 2007-06-07  
liquidthinker 写道
如果问我的话,我就回答为什么会出现这样的问题,改用数据库不可以吗?没有写文件,自然不用读文件,也不会有那么多细节需要处理,都交给数据库就行了.


ls大哥以为数据库是神仙,呵呵。

好些个地方能不用数据库就不用的,否则太多的地方要cactch了。
24 楼 liquidthinker 2007-06-05  
如果问我的话,我就回答为什么会出现这样的问题,改用数据库不可以吗?没有写文件,自然不用读文件,也不会有那么多细节需要处理,都交给数据库就行了.
23 楼 umbrella 2007-06-01  
数据结构都不懂的话,那玩笑就开大了。
22 楼 ken1984 2007-06-01  
magice 写道
ken1984 写道
一行行读应该可以,至于要在N个里面查找,用一些查找算法就行了,比如二分查找,或者把ARRAYLIST做成二叉排序树等等。。。

数据结构学多了就成了学究了,动不动就说一些数据结构的名词,这谁都会说,关键是给出你的解决方案!


呵呵,前面已经说了,读取时一部分一部分的读,处理完就释放然后再读下一部分,这个过程可以是一行行的读,也可以用SLEEK之类的方法定位待读字节位置,然后按字节读,方法很多,自己网上查;查找的就不用多说了,要算法代码网上也很多,另外我说的那些不算学究,发明那些东西创造那些东西的才是学究,希望你搞清关系。如果这都叫学究,那你们也太井底之蛙了吧。。。
21 楼 magice 2007-06-01  
ken1984 写道
一行行读应该可以,至于要在N个里面查找,用一些查找算法就行了,比如二分查找,或者把ARRAYLIST做成二叉排序树等等。。。

数据结构学多了就成了学究了,动不动就说一些数据结构的名词,这谁都会说,关键是给出你的解决方案!
20 楼 ken1984 2007-05-30  
一行行读应该可以,至于要在N个里面查找,用一些查找算法就行了,比如二分查找,或者把ARRAYLIST做成二叉排序树等等。。。
19 楼 ddandyy 2007-05-30  
一般情况一行一行读  是不会内存溢出的
除非一行的数据就有几百M
18 楼 Caixiaopig 2007-05-30  
是不是用NIO操作,效率比较高。
17 楼 诺铁 2007-05-30  
性能问题,楼主的回答也不能算错的。 性能无非是时间换空间,空间换时间。 没有说运行环境,和性能目标,仅仅"1G大小的文件"这个条件不足以做判断。
16 楼 newyoung 2007-05-29  
卒子99 写道
昨天用我也弄了一个代码测试了一下。文件大小有589,839K,不过不知道楼上的朋友怎么存储匹配的结果。放内存中肯定要OutOfMemomry,我写到文件中,产生的日志有600多M。所以我在测试的时候就没有存储结果了。下面是代码


...

时间都在IO上
15 楼 卒子99 2007-04-01  
昨天用我也弄了一个代码测试了一下。文件大小有589,839K,不过不知道楼上的朋友怎么存储匹配的结果。放内存中肯定要OutOfMemomry,我写到文件中,产生的日志有600多M。所以我在测试的时候就没有存储结果了。下面是代码


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.LinkedList;
import java.util.List;

public class SearchKeyDemo {

final public String fileName;

final public String key;

//缓冲区大小
int size = 8 * 1024;

List<String> list = new LinkedList<String>();

public SearchKeyDemo(String fileName, String key) {
this.fileName = fileName;
this.key = key;
             if(this.fileName==null||this.key==null)
               throw new NullPointException();

}

public void pocessSearch() {

File file = new File(fileName);
if (file.isFile() == false || key == null || key.length() <= 0) {
return;
}
FileInputStream input = null;
LineNumberReader reader = null;
try {
input = new FileInputStream(file);

// 读数据
reader = new LineNumberReader(new InputStreamReader(input), size);
String s = null;
while ((s = reader.readLine()) != null) {
proccessLine(reader.getLineNumber(), s, key);
}

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {

}
}
if (input != null) {
try {
input.close();
} catch (IOException e) {

}
}
}
}

public List<String> getList() {
return list;
}

public void proccessLine(final int line, String value, String key) {
int index = 0;
do {
// 获取子串
String subString = value.substring(index);
if (subString == null || subString.trim().length() <= 0) {
break;
}
int position = getKeyIndex(subString, key);
if (position < 0) {
break;
}
index += position;
// 保存得到的记录
// list.add(line + "行," + index + "列");
// 要检查的子串长度小于关键字的字符串的长度,则退出
if (index + 2 * key.length() > value.length()) {
break;
}
index += key.length();
} while ((index + key.length()) < value.length());

}

/**
* 得到当前字符串的第一个关键字所在的位置
*
* @param value
* @param key
* @return
*/
public int getKeyIndex(String value, String key) {
return value.indexOf(key);
}

/**
* @param args
*/
public static void main(String[] args) {

SearchKeyDemo demo = new SearchKeyDemo("C:/test.txt", "alibaba");
long start = System.currentTimeMillis();
demo.pocessSearch();
long end = System.currentTimeMillis();
System.out.println("用时:" + (end - start) + "ms");

}
}

得到了一组结果:
缓存区大小     耗时(ms)
默认        57187
10*1024           55809 
12*1024            55063
8*1027            54672

如果选择大打印出来,也挺耗时的
14 楼 eyejava 2007-03-30  
卒子99 写道
我觉得这个问题不复杂啊,可以用LineNumberReader处理,它是扩展了BufferedReader,可以设置缓冲区大小。如果像楼上的朋友,需要要有涉及多个处理过程,那就使用管道就应该可以搞定了

我用BufferedReader去一行行读一个450M的文件,然后每行去检验在不在一个size 为100左右的 ArrayList里面,整个文件匹配完需要6分钟。。。
13 楼 spinach 2007-03-28  
只用vc写过一个类似的日志分析器
分别在子线程里读并解析日志
每次读一定数量的行到内存里
不然高频率io太耗资源了
解析完就马上释放了内存
当然不忘定量Sleep下
分析个几百M的日志文件似乎还马马虎虎
12 楼 unser 2007-03-28  
11 楼 卒子99 2007-03-21  
我觉得这个问题不复杂啊,可以用LineNumberReader处理,它是扩展了BufferedReader,可以设置缓冲区大小。如果像楼上的朋友,需要要有涉及多个处理过程,那就使用管道就应该可以搞定了
10 楼 former 2007-03-21  
wuhua 写道
former 写道
那位总监提出的假设是很实际的,我曾经写过一个日志分析类,当然内容比这个面试的复杂一些,除了找到一些关键的词还要对进出日志做对应,按时间排序等等。文件大小不到1G,由于没有使用缓存,导致OutOfMemorey...
后来自己做个缓存,每读200行flush一次,才搞定。

我对你写的这个比较感兴趣,能否共享下源代码呢。
呵呵

这个source我也没有,因为开发在公司内网,所有的代码都拿不出来,偶不是骇客,没那个技术。
不好意思。个人也不是很赞同公司的做法。
9 楼 former 2007-03-21  
wuhua 写道
former 写道
那位总监提出的假设是很实际的,我曾经写过一个日志分析类,当然内容比这个面试的复杂一些,除了找到一些关键的词还要对进出日志做对应,按时间排序等等。文件大小不到1G,由于没有使用缓存,导致OutOfMemorey...
后来自己做个缓存,每读200行flush一次,才搞定。

我对你写的这个比较感兴趣,能否共享下源代码呢。
呵呵


这个我自己也没有,因为公司的开发内网是封闭的,偶不是骇客,没得那个技术。。
除非一行一行的抄出来。。
个人也不是很赞同公司的做法。
而且我觉得两年前写的东西也不是很好,对日志的格式要求搞,没有用正则表达式处理这个问题,没有做ui接口,只能将分析后的日志分类到各个不同的文本文件中。

相关推荐

Global site tag (gtag.js) - Google Analytics