日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

漫画:老板扣了我1000,因为我没记住阿里巴巴开发手册的这条规则。

發布時間:2024/1/17 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 漫画:老板扣了我1000,因为我没记住阿里巴巴开发手册的这条规则。 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文故事構思來源于脈脈上的一篇帖子“一行代碼引發的血案”。

其實關于字符串的文章,我之前也寫過一篇《詭異的字符串問題》,字符串對于我們開發者而言,可以用最近很流行的一句話“用起來好嗨喲,仿佛人生達到了巔峰”。

確實大家都用的很嗨,很便利,但 JDK 的工程師在背后付出了努力又有幾個人真的在意呢?

咱們今天就通過一個例子來詳細的說明。

public class StringTest {public static void main(String[] args) {// 無變量的字符串拼接String s = "aa"+"bb"+"dd";System.out.println(s);// 有變量的字符串拼接String g = "11"+s+5;System.out.println(g);// 循環中使用字符串拼接String a = "0";for (int i = 1; i < 10; i++) {a = a + i;}System.out.println(a);// 循環外定義StringBuilderStringBuilder b = new StringBuilder();for (int i = 1; i < 10; i++) {b.append(i);}System.out.println(b);} } 復制代碼

有同學可能會說,這么一段代碼,怎么來區分呢?既然我在對話中說了 Java 從 JDK5 開始,便在編譯期間進行了優化,那么編譯期間 javac 命令主要干了什么事情呢?一句話歸根結底,那么肯定就是把 .java 源碼編譯成 .class 文件,也就是我們常說的中間語言——字節碼。然后 JVM 引擎再對 .class 文件進行驗證,解析,翻譯成本地可執行的機器指令,這只是一個最簡單的模型,其實現在的 JVM 引擎后期還會做很多優化,比如代碼熱點分析,JIT編譯,逃逸分析等。

說到這里,我記得之前群里有同學說,字節碼長得太丑了,看了第一眼就不想看第二眼,哈哈,丑是丑點,但是很有內涵,能量強大,實現了跨平臺性。

關于怎么查看字節碼,我之前分享過兩個工具,一個 JDK 自帶的 javap,另一個IDEA的插件 jclasslib Bytecode viewer。今天給你再分享一個,我之前破解 apk 常用的工具 jad,它會讓你看字節碼文件輕松很多。

先說一下,我分別用 Jdk 1.6 - 1.8 自帶的 javap 工具進行了反編譯,發現生成的 JVM 指令是一樣的,所以在此處不會列出每一個版本生成的指令文件。為了便于大家閱讀指令文件,這里用jad工具生成,代碼如下。

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. // Jad home page: http://www.kpdus.com/jad.html // Decompiler options: packimports(3) annotate // Source File Name: StringTest.javaimport java.io.PrintStream;public class StringTest {public StringTest(){// 0 0:aload_0 // 1 1:invokespecial #1 <Method void Object()>// 2 4:return }public static void main(String args[]){String s = "aabbdd";// 0 0:ldc1 #2 <String "aabbdd">// 1 2:astore_1 System.out.println(s);// 2 3:getstatic #3 <Field PrintStream System.out>// 3 6:aload_1 // 4 7:invokevirtual #4 <Method void PrintStream.println(String)>String g = (new StringBuilder()).append("11").append(s).append(5).toString();// 5 10:new #5 <Class StringBuilder>// 6 13:dup // 7 14:invokespecial #6 <Method void StringBuilder()>// 8 17:ldc1 #7 <String "11">// 9 19:invokevirtual #8 <Method StringBuilder StringBuilder.append(String)>// 10 22:aload_1 // 11 23:invokevirtual #8 <Method StringBuilder StringBuilder.append(String)>// 12 26:iconst_5 // 13 27:invokevirtual #9 <Method StringBuilder StringBuilder.append(int)>// 14 30:invokevirtual #10 <Method String StringBuilder.toString()>// 15 33:astore_2 System.out.println(g);// 16 34:getstatic #3 <Field PrintStream System.out>// 17 37:aload_2 // 18 38:invokevirtual #4 <Method void PrintStream.println(String)>String a = "0";// 19 41:ldc1 #11 <String "0">// 20 43:astore_3 for(int i = 1; i < 10; i++)//* 21 44:iconst_1 //* 22 45:istore 4//* 23 47:iload 4//* 24 49:bipush 10//* 25 51:icmpge 80a = (new StringBuilder()).append(a).append(i).toString();// 26 54:new #5 <Class StringBuilder>// 27 57:dup // 28 58:invokespecial #6 <Method void StringBuilder()>// 29 61:aload_3 // 30 62:invokevirtual #8 <Method StringBuilder StringBuilder.append(String)>// 31 65:iload 4// 32 67:invokevirtual #9 <Method StringBuilder StringBuilder.append(int)>// 33 70:invokevirtual #10 <Method String StringBuilder.toString()>// 34 73:astore_3 // 35 74:iinc 4 1//* 36 77:goto 47System.out.println(a);// 37 80:getstatic #3 <Field PrintStream System.out>// 38 83:aload_3 // 39 84:invokevirtual #4 <Method void PrintStream.println(String)>StringBuilder b = new StringBuilder();// 40 87:new #5 <Class StringBuilder>// 41 90:dup // 42 91:invokespecial #6 <Method void StringBuilder()>// 43 94:astore 4for(int i = 1; i < 10; i++)//* 44 96:iconst_1 //* 45 97:istore 5//* 46 99:iload 5//* 47 101:bipush 10//* 48 103:icmpge 120b.append(i);// 49 106:aload 4// 50 108:iload 5// 51 110:invokevirtual #9 <Method StringBuilder StringBuilder.append(int)>// 52 113:pop // 53 114:iinc 5 1//* 54 117:goto 99System.out.println(b);// 55 120:getstatic #3 <Field PrintStream System.out>// 56 123:aload 4// 57 125:invokevirtual #12 <Method void PrintStream.println(Object)>// 58 128:return } } 復制代碼

這里說一下分析結果。

1、無變量的字符串拼接,在編譯期間值都確定了,所以 javac 工具幫我們把它直接編譯成一個字符常量。

2、有變量的字符串拼接,在編譯期間變量的值無法確定,所以運行期間會生成一個StringBuilder 對象。

3、循環中使用字符串拼接,循環內,每循環一次就會產生一個新的 StringBuilder 對象,對資源有一定的損耗。

4、循環外使用 StringBuilder,循環內再執行 append() 方法拼接字符串,只會成一個 StringBuilder 對象。

因此,對于有循環的字符串拼接操作,建議使用 StringBuilder 和 StringBuffer,對性能會有一定的提升。

其實上面的結論,《阿里巴巴Java開發手冊》中有所提到,此文正好與該條結論相對應。

一個簡單的字符串,用起來確實簡單,背后付出了多少工程師的心血,在此,深深地佩服詹爺。

PS:本文原創發布于微信公眾號 「Java面試那些事兒」,關注并回復「1024」,免費領學習資料。 原文地址


轉載于:https://juejin.im/post/5c400d44f265da614f708e68

總結

以上是生活随笔為你收集整理的漫画:老板扣了我1000,因为我没记住阿里巴巴开发手册的这条规则。的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。