阿里巴巴面试 java 问题,有 1024 个字符串,用 subString 读取一万次可行么?说说原理

2016-03-25 11:16:52 +08:00
 li00li

阿里巴巴面试 java 问题,有 1024 个字符串,用 subString 读取一万次可行么?说说原理

有人可以详细的说一下么?

2829 次点击
所在节点    问与答
9 条回复
SpicyCat
2016-03-25 11:39:44 +08:00
题目没看懂。
是说一个字符串长度是 1024 ,然后能不能执行 substring 方法一万次?
Jelen
2016-03-25 11:44:52 +08:00
完全没看懂这题
incompatible
2016-03-25 12:02:41 +08:00
substring 会生成新的字符串。由于 java.lang.String 的特殊性,每个生成的字符串都会在永久代里产生一个字符串常量(当一万次调用每次采用的都是不同的 startIndex 和 endIndex 时)。如果启动 jvm 时为永久代分配的空间不够多,那么就会产生 OutOfMemoryError

所以我猜这道题考察的主要是 String 的 intern 以及 jvm 内存模型方面的知识。

ps :以上是针对 jdk6 来说的。 jdk7 和 jdk8 中的变化可以参考下面这个文章:
http://java-performance.info/string-intern-in-java-6-7-8/
incompatible
2016-03-25 12:13:58 +08:00
抱歉,以上关于 String.substring()会在永久代产生字符串常量的说法是错误的。 substring 只会在堆内分配新空间,不会在永久代分配空间。
Infernalzero
2016-03-25 13:49:13 +08:00
首先得看是 jdk6 还是 7
不同的版本 subString 方法的实现是不同的
6 里面 subString 会保存原 String 对象的引用,如果大字符串截取少量 String 会浪费很多内存
7 里面就是用 Arrays.copyOfRange 了
主要就是看 public String(char value[], int offset, int count)这个构造方法
总之,具体得看使用场景了,根据要截取的字符串大小和原字符串的比较来判断用哪种方式
Fred84
2016-03-25 14:14:29 +08:00
假设 1024 个字符串的对象为 a ,每次调用 a.substring 返回的字符串对象会保留 a 对象内存的引用(详见 substring 源码),如果调用了 1 万次,每次调用完毕后没有及时释放(比如你把这些对象都放在一个全局容器中),那么很可能会出现 OOM 的错误。
li00li
2016-03-25 14:21:10 +08:00
@SpicyCat 其实我当时也没有太懂
li00li
2016-03-25 14:21:44 +08:00
@incompatible 谢谢
SoloCompany
2016-03-26 15:03:50 +08:00
你说 intern 会进入 PermGen/MetaSpace 还好理解, substring 甚至是 new String 就是个普通对象操作和 PermGen/MetaSpace 有什么直接关联吗, 唯一有的坑仅仅是 Java 7 开始 substring 的实现不再是 o(0) 而是有了 o(n) 的复制, 因为委员会认为这一点点复制的性能消耗在大多数情况下基本可以忽略, 为了避免对一个很大的字符串进行 substring 的时候因为保留着源字符串内部缓冲区的引用而无法释放内存而可能产生的问题, 并且这个选择是无法由 API 的使用者自己区决定的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/266249

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX