成都市支付宝面试归来
成都支付宝面试归来
昨天,支付宝在成都招聘,一直关心阿里巴巴的招聘信息,所以一收到消息,马上从外地赶过去。到了,才发现,这次他们只招有工作经验的。虽然我是应届毕业的,但是在读研期间,也在公司上过班,有过几个项目开发经验,所以当时我就好说歹说,表现自己一定能胜任这份工作,不会比别人的差的。最后,他们的技术总监总算给了我一个机会,让我面试工,呵呵,这儿再一次感谢支付宝的HR和他们的技术总监Tommy(不知道拼对了么)。
因为我做过多个项目,一直对架构很感兴趣,最近又一直在研究Spring,Hibernate,Struts的源代码,而且前面也有了面试经验,所以前面的技术问题都比较简单的搞定了。但最后一个现现场编程题,现在在我看来,确实让我这个缺乏大型项目经验的人露了马脚。
题目是这样子的:写一个类,读一个txt文件,从中找到aliy这个词,并记录该字符串所在的行数和每一行中的位置。
我第一反应这个问题很简单,每次循环读一行字符串,然后用String.index方法就可以搞定了。但是在写代码的时候,我却把PrintReader搞错了,写成PrintWriter,唉,用管了IDE就是这样子啊。后来就和技术总监聊这个类还需要什么改进的地方。在他的提醒下,我才注意到。
第一 每一行不一定只有一个关键词,这是我所没有注意到的,当然在实际的开发中我后来是可以发现的。后来我还想到用正则表达式。还有就是字符可以设置token,直接split几段,还是能找到,当然这三种方法的效率,我确实不太清楚。
第二 性能的问题,他说,如果是读一个1G的文件,那怎么办。我当时第一反应是那就分段读,然后用多线程处理每一段的字符串。这个问题是我回答的最失败的地方,在回来的车上,我才反应过来,准备的回答应该是通过设置缓存区来读文件。
回答的如此差,我也不报什么希望了。不过还是要给朋友们提点经验吧,特别是那些刚毕业的,有点项目经验的朋友,因为我们可能面临的问题都是这个。那个时候我在公司上班的时候,有写代码,也有做框架,项目经理始终说的“先把做出来再改进” 事实上在小公司真的很忙很累,对于没有什么经验的人来说,能做出来已经不错了,所以后来那个“再改进”通常就被忽略了,像面对上面的那个问题,虽然事后能想到,但是对于有工作经验的人来,马上就能够反应过来。所以在以后的开发中,除了灵活运用基础知识,还就要从代码的质量方面去多考虑,这样才能够慢慢成长。
我对你写的这个比较感兴趣,能否共享下源代码呢。
呵呵
这个我自己也没有,因为公司的开发内网是封闭的,偶不是骇客,没得那个技术。。
除非一行一行的抄出来。。
个人也不是很赞同公司的做法。
而且我觉得两年前写的东西也不是很好,对日志的格式要求搞,没有用正则表达式处理这个问题,没有做ui接口,只能将分析后的日志分类到各个不同的文本文件中。
我对你写的这个比较感兴趣,能否共享下源代码呢。
呵呵
这个source我也没有,因为开发在公司内网,所有的代码都拿不出来,偶不是骇客,没那个技术。
不好意思。个人也不是很赞同公司的做法。
我用BufferedReader去一行行读一个450M的文件,然后每行去检验在不在一个size 为100左右的 ArrayList里面,整个文件匹配完需要6分钟。。。
时间都在IO上
数据结构学多了就成了学究了,动不动就说一些数据结构的名词,这谁都会说,关键是给出你的解决方案!
数据结构学多了就成了学究了,动不动就说一些数据结构的名词,这谁都会说,关键是给出你的解决方案!
呵呵,前面已经说了,读取时一部分一部分的读,处理完就释放然后再读下一部分,这个过程可以是一行行的读,也可以用SLEEK之类的方法定位待读字节位置,然后按字节读,方法很多,自己网上查;查找的就不用多说了,要算法代码网上也很多,另外我说的那些不算学究,发明那些东西创造那些东西的才是学究,希望你搞清关系。如果这都叫学究,那你们也太井底之蛙了吧。。。
ls大哥以为数据库是神仙,呵呵。
好些个地方能不用数据库就不用的,否则太多的地方要cactch了。
ls大哥以为数据库是神仙,呵呵。
好些个地方能不用数据库就不用的,否则太多的地方要cactch了。
“好些个地方能不用数据库就不用的”,很不理解哈,做数据存取的,又有这么大的规模,当然是能用数据库则用数据库啊。见过任何mis不用数据库而用文件来做数据存取的吗?本质上数据库的存取也是对数据库文件的存取,但细节被数据库封装了,不用考虑很多底层问题,何乐而不为?
昨天,支付宝在成都招聘,一直关心阿里巴巴的招聘信息,所以一收到消息,马上从外地赶过去。到了,才发现,这次他们只招有工作经验的。虽然我是应届毕业的,但是在读研期间,也在公司上过班,有过几个项目开发经验,所以当时我就好说歹说,表现自己一定能胜任这份工作,不会比别人的差的。最后,他们的技术总监总算给了我一个机会,让我面试工,呵呵,这儿再一次感谢支付宝的HR和他们的技术总监Tommy(不知道拼对了么)。
因为我做过多个项目,一直对架构很感兴趣,最近又一直在研究Spring,Hibernate,Struts的源代码,而且前面也有了面试经验,所以前面的技术问题都比较简单的搞定了。但最后一个现现场编程题,现在在我看来,确实让我这个缺乏大型项目经验的人露了马脚。
题目是这样子的:写一个类,读一个txt文件,从中找到aliy这个词,并记录该字符串所在的行数和每一行中的位置。
我第一反应这个问题很简单,每次循环读一行字符串,然后用String.index方法就可以搞定了。但是在写代码的时候,我却把PrintReader搞错了,写成PrintWriter,唉,用管了IDE就是这样子啊。后来就和技术总监聊这个类还需要什么改进的地方。在他的提醒下,我才注意到。
第一 每一行不一定只有一个关键词,这是我所没有注意到的,当然在实际的开发中我后来是可以发现的。后来我还想到用正则表达式。还有就是字符可以设置token,直接split几段,还是能找到,当然这三种方法的效率,我确实不太清楚。
第二 性能的问题,他说,如果是读一个1G的文件,那怎么办。我当时第一反应是那就分段读,然后用多线程处理每一段的字符串。这个问题是我回答的最失败的地方,在回来的车上,我才反应过来,准备的回答应该是通过设置缓存区来读文件。
回答的如此差,我也不报什么希望了。不过还是要给朋友们提点经验吧,特别是那些刚毕业的,有点项目经验的朋友,因为我们可能面临的问题都是这个。那个时候我在公司上班的时候,有写代码,也有做框架,项目经理始终说的“先把做出来再改进” 事实上在小公司真的很忙很累,对于没有什么经验的人来说,能做出来已经不错了,所以后来那个“再改进”通常就被忽略了,像面对上面的那个问题,虽然事后能想到,但是对于有工作经验的人来,马上就能够反应过来。所以在以后的开发中,除了灵活运用基础知识,还就要从代码的质量方面去多考虑,这样才能够慢慢成长。
9 楼
former
2007-03-21
wuhua 写道
former 写道
那位总监提出的假设是很实际的,我曾经写过一个日志分析类,当然内容比这个面试的复杂一些,除了找到一些关键的词还要对进出日志做对应,按时间排序等等。文件大小不到1G,由于没有使用缓存,导致OutOfMemorey...
后来自己做个缓存,每读200行flush一次,才搞定。
我对你写的这个比较感兴趣,能否共享下源代码呢。
呵呵
这个我自己也没有,因为公司的开发内网是封闭的,偶不是骇客,没得那个技术。。
除非一行一行的抄出来。。
个人也不是很赞同公司的做法。
而且我觉得两年前写的东西也不是很好,对日志的格式要求搞,没有用正则表达式处理这个问题,没有做ui接口,只能将分析后的日志分类到各个不同的文本文件中。
10 楼
former
2007-03-21
wuhua 写道
former 写道
那位总监提出的假设是很实际的,我曾经写过一个日志分析类,当然内容比这个面试的复杂一些,除了找到一些关键的词还要对进出日志做对应,按时间排序等等。文件大小不到1G,由于没有使用缓存,导致OutOfMemorey...
后来自己做个缓存,每读200行flush一次,才搞定。
我对你写的这个比较感兴趣,能否共享下源代码呢。
呵呵
这个source我也没有,因为开发在公司内网,所有的代码都拿不出来,偶不是骇客,没那个技术。
不好意思。个人也不是很赞同公司的做法。
11 楼
卒子99
2007-03-21
我觉得这个问题不复杂啊,可以用LineNumberReader处理,它是扩展了BufferedReader,可以设置缓冲区大小。如果像楼上的朋友,需要要有涉及多个处理过程,那就使用管道就应该可以搞定了
12 楼
unser
2007-03-28
http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/
大家到这里看一看吧,是英文版
大家到这里看一看吧,是英文版
13 楼
spinach
2007-03-28
只用vc写过一个类似的日志分析器
分别在子线程里读并解析日志
每次读一定数量的行到内存里
不然高频率io太耗资源了
解析完就马上释放了内存
当然不忘定量Sleep下
分析个几百M的日志文件似乎还马马虎虎
分别在子线程里读并解析日志
每次读一定数量的行到内存里
不然高频率io太耗资源了
解析完就马上释放了内存
当然不忘定量Sleep下
分析个几百M的日志文件似乎还马马虎虎
14 楼
eyejava
2007-03-30
卒子99 写道
我觉得这个问题不复杂啊,可以用LineNumberReader处理,它是扩展了BufferedReader,可以设置缓冲区大小。如果像楼上的朋友,需要要有涉及多个处理过程,那就使用管道就应该可以搞定了
我用BufferedReader去一行行读一个450M的文件,然后每行去检验在不在一个size 为100左右的 ArrayList里面,整个文件匹配完需要6分钟。。。
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
如果选择大打印出来,也挺耗时的
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
如果选择大打印出来,也挺耗时的
16 楼
newyoung
2007-05-29
卒子99 写道
昨天用我也弄了一个代码测试了一下。文件大小有589,839K,不过不知道楼上的朋友怎么存储匹配的结果。放内存中肯定要OutOfMemomry,我写到文件中,产生的日志有600多M。所以我在测试的时候就没有存储结果了。下面是代码
...
...
时间都在IO上
17 楼
诺铁
2007-05-30
性能问题,楼主的回答也不能算错的。 性能无非是时间换空间,空间换时间。 没有说运行环境,和性能目标,仅仅"1G大小的文件"这个条件不足以做判断。
18 楼
Caixiaopig
2007-05-30
是不是用NIO操作,效率比较高。
19 楼
ddandyy
2007-05-30
一般情况一行一行读 是不会内存溢出的
除非一行的数据就有几百M
除非一行的数据就有几百M
20 楼
ken1984
2007-05-30
一行行读应该可以,至于要在N个里面查找,用一些查找算法就行了,比如二分查找,或者把ARRAYLIST做成二叉排序树等等。。。
21 楼
magice
2007-06-01
ken1984 写道
一行行读应该可以,至于要在N个里面查找,用一些查找算法就行了,比如二分查找,或者把ARRAYLIST做成二叉排序树等等。。。
数据结构学多了就成了学究了,动不动就说一些数据结构的名词,这谁都会说,关键是给出你的解决方案!
22 楼
ken1984
2007-06-01
magice 写道
ken1984 写道
一行行读应该可以,至于要在N个里面查找,用一些查找算法就行了,比如二分查找,或者把ARRAYLIST做成二叉排序树等等。。。
数据结构学多了就成了学究了,动不动就说一些数据结构的名词,这谁都会说,关键是给出你的解决方案!
呵呵,前面已经说了,读取时一部分一部分的读,处理完就释放然后再读下一部分,这个过程可以是一行行的读,也可以用SLEEK之类的方法定位待读字节位置,然后按字节读,方法很多,自己网上查;查找的就不用多说了,要算法代码网上也很多,另外我说的那些不算学究,发明那些东西创造那些东西的才是学究,希望你搞清关系。如果这都叫学究,那你们也太井底之蛙了吧。。。
23 楼
umbrella
2007-06-01
数据结构都不懂的话,那玩笑就开大了。
24 楼
liquidthinker
2007-06-05
如果问我的话,我就回答为什么会出现这样的问题,改用数据库不可以吗?没有写文件,自然不用读文件,也不会有那么多细节需要处理,都交给数据库就行了.
25 楼
cxj_2000
2007-06-07
liquidthinker 写道
如果问我的话,我就回答为什么会出现这样的问题,改用数据库不可以吗?没有写文件,自然不用读文件,也不会有那么多细节需要处理,都交给数据库就行了.
ls大哥以为数据库是神仙,呵呵。
好些个地方能不用数据库就不用的,否则太多的地方要cactch了。
26 楼
liquidthinker
2007-06-08
cxj_2000 写道
liquidthinker 写道
如果问我的话,我就回答为什么会出现这样的问题,改用数据库不可以吗?没有写文件,自然不用读文件,也不会有那么多细节需要处理,都交给数据库就行了.
ls大哥以为数据库是神仙,呵呵。
好些个地方能不用数据库就不用的,否则太多的地方要cactch了。
“好些个地方能不用数据库就不用的”,很不理解哈,做数据存取的,又有这么大的规模,当然是能用数据库则用数据库啊。见过任何mis不用数据库而用文件来做数据存取的吗?本质上数据库的存取也是对数据库文件的存取,但细节被数据库封装了,不用考虑很多底层问题,何乐而不为?
27 楼
ddandyy
2007-06-08
对某些业务来说 数据库是不合适的
比如我现在这个项目就有 是和别的公司的数据库要交互 我们就是用文件来做的 共用一个数据库显然是不现实的 安全性根本就无法保证
比如我现在这个项目就有 是和别的公司的数据库要交互 我们就是用文件来做的 共用一个数据库显然是不现实的 安全性根本就无法保证
28 楼
卒子99
2007-06-09
晕,这个问题还在争啊,看来真是一个经典问题啊,呵呵