StackOverflow發展到目前,已經成爲了全球開發者的金礦。它可以幫助咱們找到在各個領域遇到的問題的最有用的解決方案,同時咱們也會從中學習到不少新的東西。這篇文章是在咱們審閱了StackOverflow上最流行的Java問題以及答案後從中挑出來的。即便你是一個有豐富經驗的開發者,也能從中學到很多東西。java
https://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array數據庫
StackOverflow上最多投票的一個Java問題是: 爲何處理一個排序數組要比非排序數組快的多 。爲了回答這個問題,你須要使用分支預測(branch prediction)。分支預測是一種架構,旨在經過在真實的路徑發生前猜想某一分支的下一步來提高處理過程。數組
分支在這裏即一個if語句。這樣的話,若是是一個排序數組,那麼分支預測將會進行,不然不會進行。安全
StackOverflow上的一個回答者,連接:http://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array/11227902#11227902bash
試圖使用鐵路和火車來簡單介紹這個概念。假設你在鐵軌鏈接處要決定火車要走哪條路,你會選擇左邊仍是右邊?你能夠攔住火車,而後問司機該往那裏,可是這樣會讓整個過程變慢。所以你只能去猜正確的方向,那麼如何去猜呢?最好的辦法就是經過觀察目前這個火車每次通過時的路線,推測出正確的方向。架構
這就是分支預測:識別模式並使用它。app
不幸的是,這個問題的提問者是分支預測失敗的受害者。由於他的分支沒有任何能夠識別出的模式,因此預測出的行爲是隨機的。dom
http://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords-in-java學習
另外一個流行的Java問題是: 爲何在Java中有關密碼的地方更加喜歡使用char[]而不是String?其實原始的問題更加具體一些,就是問的在Swing中,password控件有一個getPassword方法(返回char[]而不是getText()返回的String)。ui
其實這裏不用驚訝-這是一個安全問題。String是不可變的,意味着一旦它被建立了,那麼你就不可能去修改它。這也意味着在GC以前,你對這些數據不能作任何處理。所以,只要有人可以訪問你的內存,那麼String就有可能被他獲取到。
這也就是爲何要使用char數組。你能夠顯示地清除數據或者覆蓋它。這樣密碼這種敏感數據即便GC尚未進行也不會再在系統留下痕跡。
http://blog.takipi.com/the-top-10-exceptions-types-in-production-java-applications-based-on-1b-events/
即便不少開發者傾向於忽略對受檢異常的處理,StackOverflow上仍然有不少關於異常的問題。其中一個最流行的問題是: 什麼是NullPointerException,我該怎麼處理它 ?對此,咱們並無感到驚訝,由於這個問題也是在生產環境的Java應用中排名第一的異常。
實際上,當NullPointerException(或者其餘exception)在系統出現的時候,咱們能夠發出一個告警。由於這種異常通常狀況下都是業務代碼邏輯有問題形成(筆者注)。
http://stackoverflow.com/questions/15182496/why-does-this-code-using-random-strings-print-hello-world
這個問題給出了下面的代碼,並打印出了」hello world」。
System.out.println(randomString(-229985452) + " " + randomString(-147909649));
public static String randomString(int i){
Random ran = new Random(i);
StringBuilder sb = new StringBuilder();
while (true)
{
int k = ran.nextInt(27);
if (k == 0)
break;
sb.append((char)('`' + k));
}
return sb.toString();
}
複製代碼
其實,選擇一組隨機的整數並非隨機的。給定一個seed參數(在這個例子中是-229985452和-147909649), 那麼每次隨機,一樣的seed則會產生一樣的輸出。
Random(-229985452).nextInt(27)產生的前六個數字:8, 5, 12, 12, 15, 0
Random(-147909649).nextInt(27)產生的前六個數字:23, 15, 18, 12, 4, 0
這樣,最終輸出的就是」hello world」。
http://stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result
public static void main(String[] args) throws ParseException {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str3 = "1927-12-31 23:54:07";
String str4 = "1927-12-31 23:54:08";
Date sDt3 = sf.parse(str3);
Date sDt4 = sf.parse(str4);
long ld3 = sDt3.getTime() /1000;
long ld4 = sDt4.getTime() /1000;
System.out.println(ld4-ld3);
}
複製代碼
按說上面的代碼最後的結果應該是1,但實際的輸出倒是353。其實,這是一個時區的問題。1927年12月31號24:00,上海時間往回調整了5分鐘52秒,所以」1927-12-31 23:54:08」發生了兩次,Java將後面一次實例化成了本地的這個時間。所以和前一秒的差距成了353。
咱們須要指出,若是你試着來運行這段代碼,結果並不必定是353。Jon Skeet指出了這一點,連接:
http://stackoverflow.com/a/6841479/5982245
在時區數據庫項目2014版中,這個改變的時間點改到了1900-12-31,所以成了344秒的差距。
http://stackoverflow.com/questions/13883166/uncatchable-chucknorrisexception
這裏有一個很明顯的問題: 若是有exception被拋出,可是沒有任何辦法去catch,那麼應用會崩潰嗎? 或者如這個問題所問:是否能夠寫一段Java代碼讓一個假設的java.lang.ChuckNorrisException沒法被捕獲。
答案是能夠,可是這裏有一個」可是」。你能夠編譯一段代碼拋出一個ChuckNorrisException,可是在Runtime時動態生成一個並不繼承於Throwable接口的ChuckNorrisException類。固然,爲了讓這個過程能夠進行,你須要關閉掉字節碼驗證。jtahlborn給出了完整的解決辦法。連接:
http://stackoverflow.com/a/13883510/5982245
哈希表是另一個在StackOverflow上流行的問題系列。許多用戶都想要知道全部集合類之間的區別,何時該使用哪一種集合。
迭代順序是主要考慮的因素。使用HashMap則忽略了全部的順序信息,也就是獲取元素的順序和你插入元素的順序是沒有任何關係的;使用TreeMap則會獲得一個排序好的迭代集合;使用LinkedHashMap則是一個FIFO的順序。
若是你仍是對這些感到困惑,這裏有一個相關說明的圖表能夠參考(Rebel Labs製做。連接:
http://zeroturnaround.com/wp-content/uploads/2016/04/Java-Collections-cheat-sheet.png。
對於Java,其實關鍵的不在於你懂多少,而是在於你能夠一直學到更多的東西。StackOverflow不只在code上的一些問題能夠幫助咱們,也有助於咱們回過頭來去深刻地學習一些咱們已經知道的知識。