Stack Overflow 上人气爆表的10个 Java 问题
2019獨角獸企業重金招聘Python工程師標準>>>
1、?為什么兩個(1927年)時間相減得到一個奇怪的結果?
(3623個贊)
如果執行下面的程序,程序解析兩個間隔1秒的日期字符串并比較:
| 1 2 3 4 5 6 7 8 9 10 | 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 |
為什么 ld4-ld3 不是1(因為我希望這兩個時間差是一秒),而是353?
如果將日期字符串各加一秒:
| 1 2 | String str3 = "1927-12-31 23:54:08" ;? String str4 = "1927-12-31 23:54:09" ; |
ld4-ld3 的結果是1.
| 1 2 3 4 5 6 7 | sun.util.calendar.ZoneInfo[ id = "Asia/Shanghai" , offset=28800000,dstSavings=0, useDaylight= false , transitions=19, lastRule=null] Locale(Locale.getDefault()): zh_CN |
解決方案
這是上海時區,在12月31日有一個變化。
查閱這個網址來了解上海在1927年時區變化的細節。基本上在1927年年底的午夜,始終會回撥5分52秒。所以“1927-12-31 23:54:08”實際上發生了兩次,看起來Java解析了后一次的時間作為當地的日期和時間導致了差異。
2、Java是“引用傳遞”還是“值傳遞”?
(2480個贊)
我一直認為Java是引用傳遞;然而,我看了一堆博客(例如這篇)聲稱不是這樣的。我認為我沒有理解它們之間的區別。
給個解釋?
解決方案
Java一直是值傳遞。不幸的是,他們決定把指針叫做引用,因此新人總是被搞暈。因為這些引用也是通過值傳遞的。
3、一個關于Java += 操作符的問題
(2223贊)
直到今天我認為這個例子:
| 1 | i += j; |
只是一個簡寫的:
| 1 | i = i + j; |
但如果這樣做:
| 1 2 | int i = 5 ; long j = 8 ; |
然而 i = i + j; 沒法編譯,而 i += j; 就可以編譯。
這意味著i += j;?實際上是i = (type of i) (i + j)的簡寫么?
解決方案
總有人問這類問題,JLS里有答案。參見?§15.26.2復合賦值運算符。摘錄:
E1?op=?E2 型的復合賦值表達式等價于?E1?=?(T)((E1)?op?(E2)),這里 T 是 E1 的類型,不同的是 E1 只計算一次。
一個例子,引自?§15.26.2
[...] 下面的代碼是正確的:
| 1 2 | short x = 3 ; x += 4.6 ; |
x的結果等于7,因為它等價于:
| 1 2 | short x = 3 ; x = ( short )(x + 4.6 ); |
換句話說,你的假設是正確的。
4、HashMap 和 Hashtable 之間的不同?
(1769個贊)
Java中?HashMap?和?Hashtable的不同是什么?
非多線程應用中使用哪個更有效率?
解決方案
Java 中 HashMap 和 HashTable 有幾個不同點:
Hashtable?是同步的,然而?HashMap不是。 這使得HashMap更適合非多線程應用,因為非同步對象通常執行效率優于同步對象。
Hashtable 不允許 null 值和鍵。HashMap允許有一個 null 鍵和人一個 NULL 值。
HashMap的一個子類是LinkedHashMap。所以,如果想預知迭代順序(默認的插入順序),只需將HashMap轉換成一個LinkedHashMap。用Hashtable就不會這么簡單。
因為同步對你來說不是個問題,我推薦使用HashMap。如果同步成為問題,你可能還要看看ConcurrentHashMap。
5、(如何)?讀取或者把一個 InputStream 轉成一個 String
(1724個贊)
如果你有一個?java.io.InputStream 對象,如處理這個對象并生成一個字符串?
假定我有一個?InputStream?對象,它包含文本數據,我希望將它轉化成一個字符串(例如,這樣我可以將流的內容寫到一個log文件中)。
InputStream?轉化成 String 最簡單方法是什么?
解決方案
使用?Apache commons?IOUtils庫來拷貝InputStream到StringWriter是一種不錯的方式,類似這樣:
| 1 2 3 | StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, encoding); String theString = writer.toString(); |
甚至
| 1 2 3 | // NB: does not close inputStream, you can use IOUtils.closeQuietly for that // 注意:不關閉inputStream,你可以使用 IOUtils.closeQuietly String theString = IOUtils.toString(inputStream, encoding); |
或者,如果不想混合Stream和Writer,可以使用?ByteArrayOutputStream。
6、為什么Java中的密碼優先使用 char[] 而不是String?
(1574個贊)
在Swing中,密碼字段有一個getPassword()(返回 char數組)方法而不是通常的getText()(返回String)方法。同樣的,我遇到過一個建議,不要使用 String 來處理密碼。
為什么String涉及到密碼時,它就成了一個安全威脅?感覺使用char數組不太方便。
解決方案
String是不可變的。這意味著一旦創建了字符串,如果另一個進程可以進行內存轉儲,在GC發生前,(除了反射)沒有方法可以清除字符串數據。
使用數組操作完之后,可以顯式地清除數據:可以給數組賦任何值,密碼也不會存在系統中,甚至垃圾回收之前也是如此。
所以,是的,這是一個安全問題 – 但是即使使用了char數組,僅僅縮小了了攻擊者有機會獲得密碼的窗口,它值針對制定的攻擊類型。
7、遍歷HashMap的最佳方法
(1504個贊)
遍歷HashMap中元素的最佳方法是什么?
解決方案
這樣遍歷entrySet:
| 1 2 3 4 5 6 7 8 | public static void printMap(Map mp) { ???? Iterator it = mp.entrySet().iterator(); ???? while (it.hasNext()) { ???????? Map.Entry pair = (Map.Entry)it.next(); ???????? System.out.println(pair.getKey() + " = " + pair.getValue()); ???????? it.remove(); // avoids a ConcurrentModificationException ???? } } |
更多請查閱Map。
8、(如何)從數組創建ArrayList
(1468個贊)
我有一個數組,初始化如下:
| 1 | Element[] array = { new Element( 1 ), new Element( 2 ), new Element( 3 )}; |
我希望將這個數組轉化成一個ArrayList類的對象。
解決方案
| 1 | new ArrayList<Element>(Arrays.asList(array)) |
9、產生一個Java的內存泄露
(1478個贊)
我有過一個面試,被問到如何產生一個Java內存泄露。不用說,我感到相當傻,甚至如何產生一個的線索都沒有。
那么怎么才能產生一個內存泄露呢?
解決方案
在純Java中,有一個很好的方式可以產生真正的內存泄露(通過執行代碼使對象不可訪問但仍存在于內存中):
應用產生一個長時間運行的線程(或者使用一個線程池加速泄露)。
線程通過一個(可選的自定義)類加載器加載一個類。
該類分配大內存(例如,new byte[1000000]),賦值給一個強引用存儲在靜態字段中,再將它自身的引用存儲到ThreadLocal中。分配額外的內存是可選的(泄露類實例就夠了),但是這樣將加速泄露工作。
線程清除所有自定義類的或者類加載器載入的引用。
重復上面步驟。
這樣是有效的,因為ThreadLocal持有對象的引用,對象持有類的引用,接著類持有類加載器的引用。反過來,類加載器持有所有已加載類的引用。這會使泄露變得更加嚴重,因為很多JVM實現的類和類加載都直接從持久帶(permgen)分配內存,因而不會被GC回收。
10、使用Java在一個區間內產生隨機整數數
(1422個贊)
我試著使用Java生成一個隨機整數,但是隨機被指定在一個范圍里。例如,整數范圍是5~10,就是說5是最小的隨機值,10是最大的。5到10之間的書也可以是生成的隨機數。
解決方案
標準的解決方式(Java1.7 之前)如下:
| 1 2 3 4 5 6 7 8 9 | import java.util.Random; public static int randInt( int min, int max) { ???? Random rand; ???? int randomNum = rand.nextInt((max - min) + 1 ) + min; ???? return randomNum; } |
請查看相關的JavaDoc。在實踐中,java.util.Random?類總是優于?java.lang.Math.random()。
特別是當標準庫里有一個直接的API來完成這個工作,就沒有必要重復制造輪子了。
原文鏈接:?nolsit?翻譯:?ImportNew.com?-?liken
譯文鏈接:?http://www.importnew.com/16841.html
[?轉載請保留原文出處、譯者和譯文鏈接。]
轉載于:https://my.oschina.net/u/1252704/blog/529704
總結
以上是生活随笔為你收集整理的Stack Overflow 上人气爆表的10个 Java 问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows 10的应用体验之二
- 下一篇: 购物车Demo,前端使用AngularJ