大廠高頻面試題-Java系列
- String、StringBuffer、StringBuilder
- ArrayList和LinkedList差別
- HashMap底層實作
- ConcurrentHashMap原理,jdk7和jdk8版本的差別
- Java的異常體系
String、StringBuffer、StringBuilder
String是final的,不可變的,每次操作都會産生新的String對象
StringBuffer是線程安全的,StringBuilder是線程非安全的
StringBuffer内的方法是經過synchronized修飾的
性能:
StringBuilder>StringBuffer>String
ArrayList和LinkedList差別
ArrayList:基于動态數組,連續記憶體存儲,适合下标通路(随機通路),擴容機制:因為數組長度固定,超出長度存資料時需要建立數組,然後将老數組的資料拷貝到新數組,如果不是尾部插入資料還會涉及到元素的移動(往後複制一份,插入新元素),使用尾插法并指定初始容量可以極大提升性能、甚至超過linkedList(需要建立大量的node對象)
LinkedList:基于連結清單,可以存儲在分散的記憶體中,适合做資料插入及删除操作,不适合查詢:需要逐一周遊
周遊LinkedList必須使用iterator不能使用for循環,因為每次for循環體内通過get(i)取得某一進制素時都需要對list重新進行周遊,性能消耗極大。
另外不要試圖使用indexOf等傳回元素索引,并利用其進行周遊,使indexOf對list進行了周遊,當結果為空時會周遊整個清單。
HashMap底層實作
JDK8開始連結清單高度到8、數組長度超過64,連結清單轉變為紅黑樹,元素以内部類Node節點存在
計算key的hash值,二次hash然後對數組長度取模,對應到數組下标,
如果沒有産生hash沖突(下标位置沒有元素),則直接建立Node存入數組,
如果産生hash沖突,先進行equal比較,相同則取代該元素,不同,則判斷連結清單高度插傳入連結表,連結清單高度達到8,并且數組長度到64則轉變為紅黑樹,長度低于6則将紅黑樹轉回連結清單key為null,存在下标0的位置
ConcurrentHashMap原理,jdk7和jdk8版本的差別
JDK7:
ReentrantLock+Segment+HashEntry,一個Segment中包含一個HashEntry數組,每個
HashEntry又是一個連結清單結構
元素查詢:二次hash,第一次Hash定位到Segment,第二次Hash定位到元素所在的連結清單的頭部
鎖:Segment分段鎖 Segment繼承了ReentrantLock,鎖定操作的Segment,其他的Segment不受影響,并發度為segment個數,可以通過構造函數指定,數組擴容不會影響其他的segment
get方法無需加鎖,volatile保證
JDK8:
Synchronized+CAS+Node+紅黑樹,Node的val和next都用volatile修飾,保證可見性
查找,替換,指派操作都使用CAS
鎖:鎖連結清單的head節點,不影響其他元素的讀寫,鎖粒度更細,效率更高,擴容時,阻塞所有的讀寫
操作、并發擴容
讀操作無鎖:
Node的val和next使用volatile修飾,讀寫線程對該變量互相可見
數組用volatile修飾,保證擴容時被讀線程感覺
Java的異常體系
Java的所有異常都是來自頂級父類Throwable
Throwable有兩個子類,Exception和Error
Error是程式無法處理的錯誤,一旦出現程式就會停止運作
Exception不會導緻程式停止,又分為RuntimeException和CheckedException
RuntimeException發生在程式運作過程中,會導緻目前線程執行失敗
CheckedException發生在編譯過程中,會導緻編譯不過。