Redian新闻
>
我自己编了个Java面试题
avatar
我自己编了个Java面试题# Java - 爪哇娇娃
d*g
1
现实工作中的一个实例。大家看有没有水平。看谁给的解最优。要求写代码。
怎样去掉xml中的前缀。比如输入是abcd,要求输出为abcd>。
主要不是考算法,是看实现细节里的很多讲究。
avatar
a*w
2
String out = in.replace("abc:", "");

ef

【在 d****g 的大作中提到】
: 现实工作中的一个实例。大家看有没有水平。看谁给的解最优。要求写代码。
: 怎样去掉xml中的前缀。比如输入是abcd,要求输出为abcd: >。
: 主要不是考算法,是看实现细节里的很多讲究。

avatar
d*g
3
多谢参与。但不是固定前缀的,可以是

abcd


【在 a*w 的大作中提到】
: String out = in.replace("abc:", "");
:
: ef

avatar
a*i
4
string.replaceAll("?

【在 d****g 的大作中提到】
: 多谢参与。但不是固定前缀的,可以是
:
: abcd
:
:

avatar
d*g
5

这个匹配下滑线吗?还有closing tag 哪?

【在 a****i 的大作中提到】
: string.replaceAll(": ?
avatar
w*u
6
这是为了考什么呢?
懂不懂regular expression?

【在 d****g 的大作中提到】
:
: 这个匹配下滑线吗?还有closing tag 哪?

avatar
a*w
7
显然是在问作业题。

【在 w****u 的大作中提到】
: 这是为了考什么呢?
: 懂不懂regular expression?

avatar
d*g
8
不是。如果你还要匹配closing tag.就要replaceall两遍。
如果是个大xml, 上百k,就有 garbage collection concern.
avatar
u*s
9
一遍就可以,pattern 把 /也加上,{0,1}
不需要考虑匹配,反正都去掉
Unix下sed 也行

★ 发自iPhone App: ChineseWeb 7.8

【在 d****g 的大作中提到】
: 不是。如果你还要匹配closing tag.就要replaceall两遍。
: 如果是个大xml, 上百k,就有 garbage collection concern.

avatar
d*g
10
regular expression 我还真不熟, 但是 ’/‘ 不能去掉的。
我们原来的code 还改了两个element的name, replaceall了五遍。在production三天两
头仍OOM。
avatar
z*e
11
上xslt
avatar
l*s
12
cuihua, bring up c++

【在 d****g 的大作中提到】
: regular expression 我还真不熟, 但是 ’/‘ 不能去掉的。
: 我们原来的code 还改了两个element的name, replaceall了五遍。在production三天两
: 头仍OOM。

avatar
r*r
13
介不是面试题,就是寻求点帮助,好的解法吧?
如果不熟悉 RE, 或担心文件过大,就用 XML SAX parser 逐个元素读取文件,遇到每
个 node 中的 qName, 用 replace() 替换,重新输出的文件就是你需要的了。文件再
大也没事。
如果用 Regular Expression, 还要考虑是否 body text 中是否出现的 ""
字符的情况。

【在 d****g 的大作中提到】
: regular expression 我还真不熟, 但是 ’/‘ 不能去掉的。
: 我们原来的code 还改了两个element的name, replaceall了五遍。在production三天两
: 头仍OOM。

avatar
z*e
14
Regular Expression这题写起来非常麻烦
而且Regular Expression并不比xslt简单多少
还不如直接上xslt,不仅规范,而且可以复用代码
但是xslt也要求一定的基础,大多数人未必觉得适应
比较好的方法是上freemarker+xml parsing lib
读和写分成两块,用dom/sax读入
parse完之后,用freemarker写好的template输出
avatar
r*r
15
不过,不管用什么语言,基本的 RE 还是要会点的,至少知道怎么看 documentation.
像这么简单的匹配,应该很快就会的。
avatar
r*r
16
除非文件特复杂,有特殊要求,否则直接用 java 自己的 SAX parser 就足够了吧。

【在 z****e 的大作中提到】
: Regular Expression这题写起来非常麻烦
: 而且Regular Expression并不比xslt简单多少
: 还不如直接上xslt,不仅规范,而且可以复用代码
: 但是xslt也要求一定的基础,大多数人未必觉得适应
: 比较好的方法是上freemarker+xml parsing lib
: 读和写分成两块,用dom/sax读入
: parse完之后,用freemarker写好的template输出

avatar
z*e
17
可以啊
理论上可行,但是用java代码输出xml非常不直观
但是一般我把freemarker看成是xml输出的一个优化
类似jsp是servlet的一个优化一样

【在 r******r 的大作中提到】
: 除非文件特复杂,有特殊要求,否则直接用 java 自己的 SAX parser 就足够了吧。
avatar
z*e
18
正则表达是很多人没学过,在大学里面是选修课

【在 r******r 的大作中提到】
: 不过,不管用什么语言,基本的 RE 还是要会点的,至少知道怎么看 documentation.
: 像这么简单的匹配,应该很快就会的。

avatar
r*r
19
也是,很奇怪。一个 EE 的 PHD,另读了一个 MS 的 master. 到公司实习,有个问题
,我说这用 RE 就行了。他问,Regular Expression 是什么?
。。。

【在 z****e 的大作中提到】
: 正则表达是很多人没学过,在大学里面是选修课
avatar
d*g
20
靠, 不需要帮助。
我最后决定自己parse string. 从头到尾parse一遍找之间的tag.
有prefix的strip掉。代码写好看了考的是基本功。细节处是看对
string的空间分配的理解。好多细节我都是头次弄清楚。比如
string a= b.substring(0,256); a 新占多少字节?
stringbuffer sb;
sb.tostring() 和 new string (sb) 有没有区别?
一般我会认为这种问题无聊,但这个case都oom了,就寸土必争了。

【在 r******r 的大作中提到】
: 介不是面试题,就是寻求点帮助,好的解法吧?
: 如果不熟悉 RE, 或担心文件过大,就用 XML SAX parser 逐个元素读取文件,遇到每
: 个 node 中的 qName, 用 replace() 替换,重新输出的文件就是你需要的了。文件再
: 大也没事。
: 如果用 Regular Expression, 还要考虑是否 body text 中是否出现的 ""
: 字符的情况。

avatar
g*g
21
你从parse string开始,很容易出错。比如CDATA 的部分,比如comment的部分。
要我也用SAXParser。

【在 d****g 的大作中提到】
: 靠, 不需要帮助。
: 我最后决定自己parse string. 从头到尾parse一遍找之间的tag.
: 有prefix的strip掉。代码写好看了考的是基本功。细节处是看对
: string的空间分配的理解。好多细节我都是头次弄清楚。比如
: string a= b.substring(0,256); a 新占多少字节?
: stringbuffer sb;
: sb.tostring() 和 new string (sb) 有没有区别?
: 一般我会认为这种问题无聊,但这个case都oom了,就寸土必争了。

avatar
u*s
22
substring bug 应该已经fix了
差别就是 .intern()

【在 d****g 的大作中提到】
: 靠, 不需要帮助。
: 我最后决定自己parse string. 从头到尾parse一遍找之间的tag.
: 有prefix的strip掉。代码写好看了考的是基本功。细节处是看对
: string的空间分配的理解。好多细节我都是头次弄清楚。比如
: string a= b.substring(0,256); a 新占多少字节?
: stringbuffer sb;
: sb.tostring() 和 new string (sb) 有没有区别?
: 一般我会认为这种问题无聊,但这个case都oom了,就寸土必争了。

avatar
t*a
23
自己parse string很累的。。。。。
substring不新占空间。。。
没区别,new string(sb) 也还是调用sb.toString()

【在 d****g 的大作中提到】
: 靠, 不需要帮助。
: 我最后决定自己parse string. 从头到尾parse一遍找之间的tag.
: 有prefix的strip掉。代码写好看了考的是基本功。细节处是看对
: string的空间分配的理解。好多细节我都是头次弄清楚。比如
: string a= b.substring(0,256); a 新占多少字节?
: stringbuffer sb;
: sb.tostring() 和 new string (sb) 有没有区别?
: 一般我会认为这种问题无聊,但这个case都oom了,就寸土必争了。

avatar
d*g
24
substring 不新占空间是对的。
new string(sb)也不新分配空间。sb.tostring 在size很大还不整的情况下从新copy一
便,所以double.
此外, stringbuffer new 的时候要注意 new stringbuffer(in.size). 否则会不停
double. 浪费空间。

【在 t***a 的大作中提到】
: 自己parse string很累的。。。。。
: substring不新占空间。。。
: 没区别,new string(sb) 也还是调用sb.toString()

avatar
t*a
25
真的?
我记得sb.tostring() 不过就是把里面的char[]整出来创建一个string而已,至少
tostring这个方法怎么都不会再分配新的char[]的
要不您老再看看StringBuffer的源代码

【在 d****g 的大作中提到】
: substring 不新占空间是对的。
: new string(sb)也不新分配空间。sb.tostring 在size很大还不整的情况下从新copy一
: 便,所以double.
: 此外, stringbuffer new 的时候要注意 new stringbuffer(in.size). 否则会不停
: double. 浪费空间。

avatar
d*g
26
我看的原代码里, stringbuffer.tostring检查多余空间。如果超过几百个字节,就从
新copy.
avatar
d*g
27
Here is the source code.
public synchronized String toString () {
int wasted = value.length - count;
if (wasted >= 768 || (wasted >= INITIAL_SIZE && wasted >= (value.length
>> 1))) {
return new String(value, 0, count);
}
shared = true;
return new String (0, count, value);
}

【在 t***a 的大作中提到】
: 真的?
: 我记得sb.tostring() 不过就是把里面的char[]整出来创建一个string而已,至少
: tostring这个方法怎么都不会再分配新的char[]的
: 要不您老再看看StringBuffer的源代码

avatar
t*a
28
是我错了。。。。

length

【在 d****g 的大作中提到】
: Here is the source code.
: public synchronized String toString () {
: int wasted = value.length - count;
: if (wasted >= 768 || (wasted >= INITIAL_SIZE && wasted >= (value.length
: >> 1))) {
: return new String(value, 0, count);
: }
: shared = true;
: return new String (0, count, value);
: }

avatar
d*g
29
Here is my implementation. google了很久,本以为是个很基本的use case,但最后没
有找到好办法。写出来也不算太麻烦。没有考虑general的solution,也没有考虑CDData
和comment.对我们这个app应该足够了。
public static String removeNameSPace(String input1) {
String ret = null;
int strStart = 0;
boolean finished = false;
if ( input1 != null ){
StringBuffer sb = new StringBuffer(input1.length());
while (!finished){

int start = input1.indexOf('int end = input1.indexOf('>', strStart);
if ( start != -1 && end != -1){
//Appending anything before 'sb.append(input1, strStart, start + 1);

String tag = input1.substring(start + 1, end);
if ( tag.charAt(0) == '/'){
//Appending '/' if it is "sb.append('/');
tag = tag.substring(1);
}

int colon = tag.indexOf(':');
if ( colon != -1){
tag = tag.substring(colon + 1);
}
//Appending tag with prefix removed, and ">"
sb.append(tag).append('>');
strStart = end + 1;
} else {
finished = true;
}
}
ret = new String(sb);
}
return ret;
}
avatar
g*g
30
没找对API,比如XPath干这个应该很容易。

CDData

【在 d****g 的大作中提到】
: Here is my implementation. google了很久,本以为是个很基本的use case,但最后没
: 有找到好办法。写出来也不算太麻烦。没有考虑general的solution,也没有考虑CDData
: 和comment.对我们这个app应该足够了。
: public static String removeNameSPace(String input1) {
: String ret = null;
: int strStart = 0;
: boolean finished = false;
: if ( input1 != null ){
: StringBuffer sb = new StringBuffer(input1.length());
: while (!finished){

avatar
d*g
31
这个case主要的意思是对Java GC的理解。
谁都知道Java里面String相加要小心,但这个情况里,原来的程序员想都没多想就连用
了5个replaceAll.写出来也简单。要我也不会多想。
但我们1.5G的heap,在输入String 250k的时候,连连仍OOM.因为Java GC痛恨large
object. 250k的object要连着分配好几个copy是个big deal.很多人都知道,但很容易
就不优先考虑这个问题。

【在 g*****g 的大作中提到】
: 没找对API,比如XPath干这个应该很容易。
:
: CDData

avatar
t*a
32
substring对于gc可是有隐患的,比如说你从一个250k的string里面拿一个3字节的
substring出来,然后原始string你就不要了,但是因为substring里面会保持对那个原
始char[]的引用,于是这个char[]就一直不会被回收。。。
所以我觉得如果你真要处理大xml文件的话,最好别一下子就把整个文件load到string
里。可以逐行处理嘛,每个小string生存周期都很短,gc对这种young generation处理
很快,所以虽然好似多分配空间而且minor gc次数更多,但performance可能更好

【在 d****g 的大作中提到】
: 这个case主要的意思是对Java GC的理解。
: 谁都知道Java里面String相加要小心,但这个情况里,原来的程序员想都没多想就连用
: 了5个replaceAll.写出来也简单。要我也不会多想。
: 但我们1.5G的heap,在输入String 250k的时候,连连仍OOM.因为Java GC痛恨large
: object. 250k的object要连着分配好几个copy是个big deal.很多人都知道,但很容易
: 就不优先考虑这个问题。

avatar
d*g
33
你说的subString的隐患很有道理。还好我的subString也没有返回,所以没有保持对那
个原始char[]的引用。但我能看到很容易忽略这个问题。
对,问题的关键是最开始就不该有250k的输入String.但这个输入是一个web service返
回的。这个结果要送到下游web service 。下游web service 很蠢,要求以String的形
式送进一个field,还不支持prefix.所以没办法。

string

【在 t***a 的大作中提到】
: substring对于gc可是有隐患的,比如说你从一个250k的string里面拿一个3字节的
: substring出来,然后原始string你就不要了,但是因为substring里面会保持对那个原
: 始char[]的引用,于是这个char[]就一直不会被回收。。。
: 所以我觉得如果你真要处理大xml文件的话,最好别一下子就把整个文件load到string
: 里。可以逐行处理嘛,每个小string生存周期都很短,gc对这种young generation处理
: 很快,所以虽然好似多分配空间而且minor gc次数更多,但performance可能更好

avatar
d*g
34
Tada,这个是java.util.regex.Matcher的实现。用的是new StringBuffer()和sb.
toString()。这个会新分配250k + 250k + 125k + 64k +32k 的空间。
public String replaceAll(String replacement) {
reset();
boolean result = find();
if (result) {
StringBuffer sb = new StringBuffer();
do {
appendReplacement(sb, replacement);
result = find();
} while (result);
appendTail(sb);
return sb.toString();
}
return text.toString();
}

【在 d****g 的大作中提到】
: 你说的subString的隐患很有道理。还好我的subString也没有返回,所以没有保持对那
: 个原始char[]的引用。但我能看到很容易忽略这个问题。
: 对,问题的关键是最开始就不该有250k的输入String.但这个输入是一个web service返
: 回的。这个结果要送到下游web service 。下游web service 很蠢,要求以String的形
: 式送进一个field,还不支持prefix.所以没办法。
:
: string

avatar
t*a
35
原来是这样。。。。我以前也遇到过几乎一模一样的问题,不过当时也没管这个
message会不会很大,就直接parse到java object, 然后又输出成xml了。。。。楼主这
项目做的很闹心啊。。。。。

【在 d****g 的大作中提到】
: 你说的subString的隐患很有道理。还好我的subString也没有返回,所以没有保持对那
: 个原始char[]的引用。但我能看到很容易忽略这个问题。
: 对,问题的关键是最开始就不该有250k的输入String.但这个输入是一个web service返
: 回的。这个结果要送到下游web service 。下游web service 很蠢,要求以String的形
: 式送进一个field,还不支持prefix.所以没办法。
:
: string

avatar
d*g
36
其实要是size小,我的例子里用replaceAll就比较好。很多coding时候的性能担心都是
多余的。可读性反而更重要些。
最好是测试时注意一下性能分析,再看要不要优化代码。我现在实际在infrastrucutre
组,专门热衷给程序员挑刺。:)

【在 t***a 的大作中提到】
: 原来是这样。。。。我以前也遇到过几乎一模一样的问题,不过当时也没管这个
: message会不会很大,就直接parse到java object, 然后又输出成xml了。。。。楼主这
: 项目做的很闹心啊。。。。。

avatar
r*r
37
需求帮助有啥不好的。
互相学习

【在 d****g 的大作中提到】
: 靠, 不需要帮助。
: 我最后决定自己parse string. 从头到尾parse一遍找之间的tag.
: 有prefix的strip掉。代码写好看了考的是基本功。细节处是看对
: string的空间分配的理解。好多细节我都是头次弄清楚。比如
: string a= b.substring(0,256); a 新占多少字节?
: stringbuffer sb;
: sb.tostring() 和 new string (sb) 有没有区别?
: 一般我会认为这种问题无聊,但这个case都oom了,就寸土必争了。

avatar
F*n
38
多想想是好时,但你这个主要的问题是没有必要弄String
大的Text要当成Stream来处理,不要搞成一个大String
其它的都是次要的,没必要钻牛角尖,用SAXParser够了

infrastrucutre

【在 d****g 的大作中提到】
: 其实要是size小,我的例子里用replaceAll就比较好。很多coding时候的性能担心都是
: 多余的。可读性反而更重要些。
: 最好是测试时注意一下性能分析,再看要不要优化代码。我现在实际在infrastrucutre
: 组,专门热衷给程序员挑刺。:)

avatar
d*g
39
True,基本上Java支持大String支持的很差.
难怪很多需要处理大xml的framework都很狡猾的用OutputStream做参数,而不是返回
String。比如JAXB Marshaller.
void marshal(Object jaxbElement, OutputStream os)
但有多少人费劲吧拉的传进ByteArrayOutputStream,或StringWriter 好整出来了
String? String就是好操作。所以大String上犯错误的空间还是很大的。

【在 F****n 的大作中提到】
: 多想想是好时,但你这个主要的问题是没有必要弄String
: 大的Text要当成Stream来处理,不要搞成一个大String
: 其它的都是次要的,没必要钻牛角尖,用SAXParser够了
:
: infrastrucutre

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。