java面試題1
1.談談你對java是解釋執行這句話的理解
-
這句話不準確。java程式碼首先是通過javac命令編譯成位元組碼,在執行時被直譯器轉為機器碼。
-
但是常見的jvm,例如hotspot,都提供了JIT動態編譯,能夠在執行時將熱點程式碼編譯成機器碼,這種情況下的程式碼就屬於是編譯執行,而不是解釋執行。
-
還有一種新的編譯方式,即AOT,直接將位元組碼編譯為機器碼
2.Exception 和 Error 有什麼區別?
-
都繼承了throwable介面,java中只有Throwable示例才可以被丟擲或者是捕獲。
-
Error是指,在正常情況下不大可能出現的情況,會導致程式處於非正常的不可恢復狀態。例如OutOfMemeoryError。
-
Exception分為可檢查異常和不可檢查異常。可檢查異常是在程式碼裡必須顯示的進行catch的異常,例如IOException等;不可檢查異常就是所謂的執行時異常,例如nullPointException等。
-
需要注意的情況。不要捕獲類似於Exception這樣的通用異常,要對不同的異常進行特定處理;不要生吞異常,可以通過打日誌等,展示異常。
-
try catch 程式碼快不要包含過多程式碼,因為會產生額外的效能開銷,並且會影響jvm對程式碼的優化。
3.談談你對final,finally,finallize的理解
-
final可以用來修飾類,方法,變數。修飾類表示類不可被繼承,修飾方法表示方法不可被重寫,修飾變量表示變數是不可被修改的。
-
finally 是用來保證重點程式碼一定會被執行的機制,例如jdbc關閉資料庫連結,unlock等操作
-
finallize 可以用來保證物件在被垃圾回收前完成特定資源的回收。
-
在java7中可以用try with resource 來省略掉 finally 關閉資源的程式碼
-
給物件宣告final 只是表示物件的引用不會被修改,但是不能防止物件的內容被改變,例如list依然可以用add方法來給集合新增元素。一個有效的方法是,將集合物件宣告為final,並且將集合中的每一屬性也設定為private final,且不提供set方法。對於get方法可以用 copy on write的方式來實現。
-
在什麼場景下finally 語句中的程式碼不會被執行,例如一段try catch finally 程式碼快中,在catch在try環節丟擲異常,進入到catch環節,並且在catch環節又丟擲異常,那麼finally 部分就不會被執行。或者在finally 程式碼快執行之前呼叫了 system.exit()方法。
4.強引用,軟引用,弱引用,幻象引用的區別
-
強引用就是我們常見的最普通的引用,只要還有強引用指向的一個物件,垃圾回收器就不會回收這個物件
-
軟引用,是一種相對強引用的弱化引用,還有當jvm記憶體不足的時候,也就是丟擲OOM錯誤之前才會回收軟引用物件,通常用作記憶體敏感的快取
-
弱引用,不能使物件避免垃圾回收。當試圖獲取物件的時候,如果物件還在,就返回,如果物件不在,則重新進行例項化。同樣可以用作快取。
-
幻象引用,用來提供在finallize之後,做某種事情的機制。也可以用來監控物件的建立和銷燬。
5.String、StringsBuffer、StringBuilder的區別
-
String 是final類,
-
StringBUffer本質是一個執行緒安全的字元序列,相關方法都加了synchronized關鍵字
-
StringsBuilder是一個執行緒不安全的字元序列,相對於StringBuffer來說,只是在相關的方法上去掉了synchronized關鍵字。
-
在java8 之後,字串的拼接操作,會被編譯為StringBuilder操作。可以通過反編譯手段看。
-
最初的String 是用 char陣列實現的,後來改為 byte陣列。原因是拉丁語的字元只佔一個字元位,而char佔用兩個字元位置。這樣做可以使資料更加緊湊。
6.動態代理是基於什麼實現的?
-
JDK的動態代理是基於介面的,需要對應的代理類有實現的介面,通過反射來實現。
-
Cglib是通過建立代理類的子類來實現對代理類的擴充套件。
-
動態代理的應用:監控,日誌,事務,RPC框架的序列化和反序列化,診斷,限流,安全策略。
7.int 和 Integer
-
Integer會預設快取 -128 到 127 之間的資料,通過Integer.valueOf(),會呼叫到快取,並且可以通過引數 -XX:AutoBoxCacheMax=N 修改快取的範圍。 Boolean會快取 true 和 false;Short 快取範圍也是 -128 到 127;Byte數值有限會全部快取;Character 會快取 ‘\u0000’到’\u007F’。
-
Integer是一個final類。
-
原始的執行緒安全型別應該是用 AtomicInteger ,AtomicBoolean等。
8.對比Vector、ArrayList、LinkedList有何區別?
-
Vector 內部以陣列儲存,隨機訪問效能較高,除了在尾部刪除插入元素,效能會相對較差。方法實現全部加了synchronized 同步,是執行緒安全的。
-
Vector 內部以陣列儲存,隨機訪問效能較高,除了在尾部刪除插入元素,效能會相對較差。不是執行緒安全的。
-
LinkedList 繼承了List 和Queen 但是儲存形式是以Node的連結串列的形式儲存的,並且是雙向連結串列,每一個節點都儲存有前一個和後一個節點的引用。同時也不是執行緒安全的。
9.TreeSet、HashSet、LinkedHashSet
-
TreeSet支援自然順序訪問,
-
HashSet 是利用雜湊演算法實現,如果雜湊雜湊正常,增刪改查等操作都可以達到常數時間
-
LinkedHashSet 是一個雙向連結串列。
10.Hashtable、HashMap、TreeMap
-
HashTable擴充套件了Dictionary類,結構於HashMap明顯不同,是執行緒安全的類,都加了synchronized
-
HashMap通常就是放入、訪問或者刪除,而對順序沒有特別要求,HashMap 在這種情況下基本是最好的選擇。
-
LinkedHashMap 通常提供的是遍歷順序符合插入順序,它的實現是維護一個雙向連結串列。
-
對於 TreeMap,它的整體順序是由鍵的順序關係決定的,通過 Comparator 或 Comparable(自然順序)來決定。
-
HashMap的儲存是一個數組,通過hash演算法將不同的值放在不同的索引位置上,然後如果兩個索引值相同,則在同一個索引下,搞一個連結串列。
-
Java8在連結串列長度預設>64的時候,會改為紅黑樹的結構。
-
HashMap的resize方法,有兩個功能,建立初始表格和擴容。