锁定老帖子 主题:论String操作时间复杂度
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2013-05-04
以下类中,method1和method2的时间复杂度一样吗?为什么。 public class Test { public static final int MB = 1024 * 1024; public static final long TIMES = 500000000L; public static void main(String[] args) throws InterruptedException { method1(); method2(); } //从字节码来看,method1重复new StringBuilder 然后append,显然不高效。这里排除jit优化。 public static void method1() { String s = ""; for (int i = 0; i < 100; i++) { s += "a"; } System.out.println(s); } public static void method2() { // //b StringBuilder sb = new StringBuilder(); for (int i = 0; i < 100; i++) { sb.append("a"); } System.out.println(sb.toString()); } } 我当时的回答是应该一样,因为我实在找不出说明他们不一样的地方。但是面试官这么问肯定有原因的,我只是从效率方面来分析,比如说method1会通过StringBuilder来做,没有后面method2好。后来面试官纠正了提问,说从时间复杂度来考虑。我直接跟他说了,我只能看出是一样的,可能method2会更好些。面试官好像不是很满意。 回来我从源码着手看,感觉不靠谱,后来看到有人分析用字节码来看。可以看到编译器怎么翻译的。经过证实,跟我的想法一样。字节码如下: Compiled from "Test.java" public class Test extends java.lang.Object{ public static final int MB; public static final long TIMES; public Test(); Code: 0: aload_0 1: invokespecial #16; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.lang.InterruptedException; Code: 0: invokestatic #27; //Method method1:()V 3: invokestatic #30; //Method method2:()V 6: return public static void method1(); Code: 0: ldc #35; //String 2: astore_0 3: iconst_0 4: istore_1 5: goto 31 8: new #37; //class java/lang/StringBuilder 11: dup 12: aload_0 13: invokestatic #39; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 16: invokespecial #45; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 19: ldc #48; //String a 21: invokevirtual #50; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: invokevirtual #54; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 27: astore_0 28: iinc 1, 1 31: iload_1 32: bipush 100 34: if_icmplt 8 37: getstatic #58; //Field java/lang/System.out:Ljava/io/PrintStream; 40: aload_0 41: invokevirtual #64; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 44: return public static void method2(); Code: 0: new #37; //class java/lang/StringBuilder 3: dup 4: invokespecial #73; //Method java/lang/StringBuilder."<init>":()V 7: astore_0 8: iconst_0 9: istore_1 10: goto 23 13: aload_0 14: ldc #48; //String a 16: invokevirtual #50; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: pop 20: iinc 1, 1 23: iload_1 24: bipush 100 26: if_icmplt 13 29: getstatic #58; //Field java/lang/System.out:Ljava/io/PrintStream; 32: aload_0 33: invokevirtual #54; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 36: invokevirtual #64; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 39: return } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2013-05-04
从面试官那里得到的反馈是,他好像不大满意。
|
|
返回顶楼 | |
发表时间:2013-05-05
其实这样几角旮旯的东西实在没有太大意义。好的程序员是不会写method1,也就无从知晓其差别了。
|
|
返回顶楼 | |
发表时间:2013-05-05
怎么没人鸟呢 难道这里大牛都不屑一顾啊
|
|
返回顶楼 | |
发表时间:2013-05-05
1、面试官不一定都是对的
2、谁也不知道面试官到底想的是什么,除了他自己 |
|
返回顶楼 | |
发表时间:2013-05-06
最后修改:2013-05-06
其实他是想考你字符串+效率不好这个点
但实际上编译器经过优化,会把这两段代码编译成类似的高效代码 |
|
返回顶楼 | |
发表时间:2013-05-06
最后修改:2013-05-06
如果我是这个面试官问同样的这个问题的话,目的有几点。
1、看看你的编程思想,看看你是在什么情况下使用这两种方式。 2、看看你平时的编码习惯是否规范。 3、看看你是否平时喜欢自我更新。 4、看看你是否是程序员里面的“完美主义者”。 大概就是这样吧。 有的时候面试不单单考验面试者的技术,还要考验综合素质(会影响团队、项目)。 |
|
返回顶楼 | |
发表时间:2013-05-06
时间复杂度?不都是O(n)么。是不是lz把面试官的问题听歪啦
|
|
返回顶楼 | |
发表时间:2013-05-06
效率来说,当然method2高一些。如果面试官不友善,我会说,实际开发中,根本不允许用method1、metod2这么弱智的命名方式,命名要望文知意等等,瞎扯呗
|
|
返回顶楼 | |
发表时间:2013-05-06
我想,面试官问的是这二者在操作时,应该如何取舍吧?取舍的理由是什么?这才是回答的关键吧。
|
|
返回顶楼 | |