面試中的一些問題——JAVA(二)

11. HashMap和ConcurrentHashMap的區別,HashMap的底層源碼

A.Hashmap本質是數組加鏈表。根據key取得hash值,然後計算出數組下標,如果多個key對應到同一個下標,就用鏈表串起來,新插入的在前面。HashMap不是線程安全的。

值得注意的是HashMap不是線程安全的,如果想要線程安全的HashMap,可以通過Collections類的靜態方法synchronizedMap獲得線程安全的HashMap。            Map map = Collections.synchronizedMap(new HashMap());


B.ConcurrentHashMap:在hashMap的基礎上,ConcurrentHashMap將數據分爲多個segment(加入分段鎖),默認16個(concurrency level),然後每次操作對一個segment加鎖,避免多線程鎖的機率,提高併發效率(默認提高16倍)。

HashMap底層是數組+鏈表的結構,當發生hash衝突,在該位置存儲的就是一個鏈表了。


HashMap底層源碼:http://www.bubuko.com/infodetail-1161252.html。

12.TreeMap、HashMap、LindedHashMap的區別

HashMap,LinkedHashMap,TreeMap都屬於Map

Map 主要用於存儲鍵(key)值(value)對,根據鍵得到值,因此鍵不允許鍵重複,但允許值重複。

       HashMap 是一個最常用的Map,它根據鍵的HashCode 值存儲數據,根據鍵可以直接獲取它的值,具有很快的訪問速度。HashMap最多隻允許一條記錄的鍵爲Null;允許多條記錄的值爲Null;HashMap不支持線程的同步,即任一時刻可以有多個線程同時寫HashMap;可能會導致數據的不一致。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。
       LinkedHashMap LinkedHashMap也是一個HashMap,但是內部維持了一個雙向鏈表,保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時,先得到的記錄肯定是先插入的.也可以在構造時用帶參數,按照應用次數排序。
       TreeMap 不僅可以保持順序,而且可以用於排序,默認是按鍵值的升序排序
PS:LinkedHashMap在遍歷的時候會比HashMap慢,不過有種情況例外,當HashMap容量很大,實際數據較少時,遍歷起來可能會比LinkedHashMap慢,因爲LinkedHashMap的遍歷速度只和實際數據有關,和容量無關,而HashMap的遍歷速度和他的容量有關。

13. Collection包結構,與Collections的區別

A.java.util.Collection 是一個集合接口(集合類的一個頂級接口)。它提供了對集合對象進行基本操作的通用接口方法。Collection接口在Java 類庫中有很多具體的實現。
B.java.util.Collections是一個包裝類(工具類/幫助)。它包含有各種有關集合操作的靜態多態方法。此類不能實例化,就像一個工具類,用於對集合中元素進行排序、搜索以及線程安全等各種操作,服務於Java的cllection框架。(例如:Collections.sort(list);

14. try catch finally,try裏有return,finally還執行麼?

1、不管有木有出現異常,finally塊中代碼都會執行;
2、當try和catch中有return時,finally仍然會執行;
3、finally是在return後面的表達式運算後執行的(此時並沒有返回運算後的值,而是先把要返回的值保存起來,管finally中的代碼怎麼樣,返回的值都不會改變,任然是之前保存的值),所以函數返回值是在finally執行前確定的;
4、finally中最好不要包含return,否則程序會提前退出,返回值不是try或catch中保存的返回值。

15. Excption與Error包結構。OOM你遇到過哪些情況,SOF你遇到過哪些情況


1. Throwable 
Throwable是 Java 語言中所有錯誤或異常的超類。 
Throwable包含兩個子類: Error 和 Exception 。它們通常用於指示發生了異常情況。 
Throwable包含了其線程創建時線程執行堆棧的快照,它提供了printStackTrace()等接口用於獲取堆棧跟蹤數據等信息。

2. Exception 
Exception及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件。

3. RuntimeException 
RuntimeException是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。 
編譯器不會檢查RuntimeException異常。 例如,除數爲零時,拋出ArithmeticException異常。RuntimeException是ArithmeticException的超類。當代碼發生除數爲零的情況時,倘若既"沒有通過throws聲明拋出ArithmeticException異常",也"沒有通過try...catch...處理該異常",也能通過編譯。這就是我們所說的"編譯器不會檢查RuntimeException異常"! 
如果代碼會產生RuntimeException異常,則需要通過修改代碼進行避免。 例如,若會發生除數爲零的情況,則需要通過代碼避免該情況的發生!

4. Error 
和Exception一樣, Error也是Throwable的子類。 它用於指示合理的應用程序不應該試圖捕獲的嚴重問題,大多數這樣的錯誤都是異常條件。 
和RuntimeException一樣, 編譯器也不會檢查Error。

Java將可拋出(Throwable)的結構分爲三種類型: 被檢查的異常(Checked Exception),運行時異常(RuntimeException)和錯誤(Error)。

(01) 運行時異常 
定義 : RuntimeException及其子類都被稱爲運行時異常。 
特點 : Java編譯器不會檢查它。 也就是說,當程序中可能出現這類異常時,倘若既"沒有通過throws聲明拋出它",也"沒有用try-catch語句捕獲它",還是會編譯通過。例如,除數爲零時產生的ArithmeticException異常,數組越界時產生的IndexOutOfBoundsException異常,fail-fail機制產生的ConcurrentModificationException異常等,都屬於運行時異常。 
雖然Java編譯器不會檢查運行時異常,但是我們也可以通過throws進行聲明拋出,也可以通過try-catch對它進行捕獲處理。 
如果產生運行時異常,則需要通過修改代碼來進行避免。 例如,若會發生除數爲零的情況,則需要通過代碼避免該情況的發生!

(02) 被檢查的異常 
定義 :  Exception類本身,以及Exception的子類中除了"運行時異常"之外的其它子類都屬於被檢查異常。 
特點:Java編譯器會檢查它。此類異常,要麼通過throws進行聲明拋出,要麼通過try-catch進行捕獲處理,否則不能通過編譯。例如,CloneNotSupportedException就屬於被檢查異常。當通過clone()接口去克隆一個對象,而該對象對應的類沒有實現Cloneable接口,就會拋出CloneNotSupportedException異常。 
被檢查異常通常都是可以恢復的。

(03) 錯誤 
定義 : Error類及其子類。 
特點 : 和運行時異常一樣,編譯器也不會對錯誤進行檢查。 
當資源不足、約束失敗、或是其它程序無法繼續運行的條件發生時,就產生錯誤。程序本身無法修復這些錯誤的。例如,VirtualMachineError就屬於錯誤。 
按照Java慣例,我們是不應該是實現任何新的Error子類的!

對於上面的3種結構,我們在拋出異常或錯誤時,到底該哪一種?《Effective Java》中給出的建議是: 對於可以恢復的條件使用被檢查異常,對於程序錯誤使用運行時異常。

16. Java面向對象的三個特徵與含義

1.封裝。將屬於某一類事物的所有共同特徵都歸到一類中。對外部不可見
2.繼承。擴展類的功能
3.多態。方法的重載、重寫。

17. Override和Overload的含義去區別

Overload(重載):一個類中可以創建多個方法,它們具有相同的名字,但具有不同的參數和不同的定義。調用方法時通過傳遞給它們的不同參數個數和參數類型來決定具體使用哪個方法。

返回值類型可以相同也可以不相同,無法以返回型別作爲重載函數的區分標準。


Override(重寫):子類對父類的方法進行重新編寫。如果在子類中的方法與其父類有相同的的方法名、返回類型和參數表,我們說該方法被重寫 (Overriding)。 

如需父類中原有的方法,可使用super關鍵字,該關鍵字引用了當前類的父類。子類函數的訪問修飾權限不能低於父類的。

18. Interface與abstract類的區別

含有abstract修飾符的class即爲抽象類,abstract 類不能創建的實例對象。含有abstract方法的類必須定義爲abstract class,abstract class類中的方法不必是抽象的。abstract class類中定義抽象方法必須在具體(Concrete)子類中實現,所以,不能有抽象構造方法或抽象靜態方法。如果的子類沒有實現抽象父類中的所有抽象方法,那麼子類也必須定義爲abstract類型。

接口(interface)可以說成是抽象類的一種特例,接口中的所有方法都必須是抽象的。接口中的方法定義默認爲public abstract類型,接口中的成員變量類型默認爲public static final。

下面比較一下兩者的語法區別:

1.抽象類可以有構造方法,接口中不能有構造方法。

2.抽象類中可以有普通成員變量,接口中沒有普通成員變量

3.抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。

4. 抽象類中的抽象方法的訪問類型可以是public,protected和(默認類型,雖然eclipse下不報錯,但應該也不行),但接口中的抽象方法只能是public類型的,並且默認即爲public abstract類型。

5. 抽象類中可以包含靜態方法,接口中不能包含靜態方法

6. 抽象類和接口中都可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型可以任意,但接口中定義的變量只能是public static final類型,並且默認即爲public static final類型。

7. 一個類可以實現多個接口,但只能繼承一個抽象類

19. Static class 與non static class的區別


內部靜態類不需要有指向外部類的引用。但非靜態內部類需要持有對外部類的引用。

非靜態內部類能夠訪問外部類的靜態和非靜態成員。靜態類不能訪問外部類的非靜態成員。他只能訪問外部類的靜態成員。

一個非靜態內部類不能脫離外部類實體被創建,一個非靜態內部類可以訪問外部類的數據和方法,因爲他就在外部類裏面。

static與non-static是對立的。static應當(注意是應當)使用類名來引用。而non-static必須(是必須)使用對象實例名來引用。

20. java多態的實現原理(個人覺得和Java後期綁定有關)

21. 實現多線程的兩種方法:Thread與Runable

A.繼承Thread

定義類繼承Thread

複寫Tread類中的run方法

調用線程的start方法

B.實現Runnable接口(避免了單繼承的侷限性,推薦使用這種方法)

定義類實現Runnable接口

覆蓋Runnable接口中的run方法

通過Thread類建立線程對象,將Runnable接口的子類對象作爲實際參數傳遞給Thread

調用線程的start方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章