哪些可以免費做網站推廣優(yōu)化關鍵詞
21. JVM是如何處理異常(大概流程)?
如果發(fā)生異常,方法會創(chuàng)建一個異常對象(包括:異常名稱、異常描述以及異常發(fā)生時應用程序的狀態(tài)),并轉交給JVM。創(chuàng)建異常對象,并轉交給JVM的過程稱為拋出異常。
異常發(fā)生后,可能有一系列的方法調用,終才進入拋出異常的方法,這一系列方法調用的有序列表叫做調用棧。
JVM會順著調用棧去查找看是否有可以處理異常的代碼,如果有,則調用異常處理代碼。如果沒有,JVM就會將該異常轉交給默認的異常處理器(默認處理器為JVM 的一部分),默認異常處理器打印出異常信息并終止應用程序。
22. 請聊一下java的集合類,以及在實際項目中你是如何用的?
- 注意說出集合體系、常用類、接口、實現(xiàn)類。
- 高并發(fā)的集合類、參照集合增強內容。
- 在實際項目中引用。?
23. Java集合框架類圖:
24. ArrayList與LinkedList的區(qū)別?
- ArrayList基于動態(tài)數(shù)組(順序表)的數(shù)據結構,LinkedList基于鏈表(雙向鏈表)的數(shù)據結構;
- ArrayList隨機訪問快,LinkedList隨機訪問慢;
- ArrayList添加和刪除慢,LinkedList添加和刪除快;
- 此外,LinkedList還專門提供了操作表頭和表尾元素的方法,可當做堆棧、隊列和雙向隊列使用。
25. ArrayList與Vector的區(qū)別?
- 相同:底層都是數(shù)組實現(xiàn)的;
- ArrayList不是線程安全,但是效率高,Vector是線程安全,效率低(源碼中方法用synchronized修飾);
- ArrayList和Vector都采用線性連續(xù)存儲空間,默認容量大小都為10;存儲空間不足時,ArrayList默認1.5倍擴容 ,Vector默認1倍擴容;
- ArrayList可以通過Collections.synchronizedList(List list) 實現(xiàn)線程同步的集合。
- 注:Vector是java的遺留框架,遺留框架設計上存在問題,已經不再使用。遺留框架還有Hashtable、Dictionary、BitSet、Stack、Properties、Enumeration。
26. HashMap和Hashtable的區(qū)別?
- HashMap是非同步,非安全線程,但速度快;Hashtable是同步,安全線程,但速度慢。
- HashMap可以接受null值( key和value都可為空);Hashtable不可以。
- HashMap默認容量大小是16;Hashtable默認容量大小是11。
- HashMap的hash值重新計算過,Hashtable直接使用hashCode。
- HashMap繼承自AbstractMap類,Hashtable繼承自Dictionary類
27. HashMap在1.8中做了哪些優(yōu)化?
- 數(shù)據結構 --> 數(shù)組 + 鏈表 + 紅黑樹
- hash函數(shù) --> 高16參與Hash,降低Hash沖突
- 擴容優(yōu)化 --> 擴容時元素不需要進行重新計算位置。新位置 = 原位置 + 原數(shù)組長度
28. HashMap線程安全的方式?
HashMap不是線程安全的。
- 方法一:通過Collections.synchronizedMap()
- 方法二:使用ConcurrentHashMap
29. HashMap為什么擴容是兩倍?
- 將取模轉為位運算操作,提高運算效率,只有2的冪次方成立 -> (n-1)&hash
- 并且在容量是2的冪次方時,n-1的二進制會全為1,位運算時可以充分散列,避免不必要的哈希沖突。
30. HashMap為什么要使用紅黑樹?
- 紅黑樹是動態(tài)平衡的一棵二叉查找樹,可以加速查找。
- HashMap什么時候轉換紅黑樹(數(shù)組長度大于64,索引節(jié)點位置元素個數(shù)大于8轉換)、什么時候轉換鏈表(索引位置元素個數(shù)等于6時轉換)。
- 說一下向關聯(lián)的知識。
31. HashMap為什么用紅黑樹不用普通的AVL樹?
總:
AVL是高度平衡樹,調整頻率高,適合查詢多,修改少的場景。紅黑樹是弱平衡樹,調整頻率低,適合修改多場景。
AVL樹:
AVL樹是高度平衡樹,任何兩個左右子樹高度大于1時,就好動態(tài)調整到平衡。所以AVL樹適合用于插入與刪除次數(shù)比較少,但查找多的情況。
紅黑樹:
它也是一種平衡二叉樹,但每個節(jié)點帶顏色,可以是紅或黑。通過對任何一條從根到葉子的路徑上各個節(jié)點顏色的限制,確保沒有一條路徑會比其它路徑長出兩倍,所以紅黑樹是一種弱平衡二叉樹。紅黑樹從根到葉子的最長路徑不會超過最短路徑的2倍。
32. HashMap為什么在JDK 1.8之后不再有死循環(huán)的問題?
JDK1.8以前,導致死循環(huán)的主要原因是擴容后,節(jié)點的順序會反掉,可能會形成一個環(huán)形鏈。
原因:兩個線程同時調用了擴容方法,擴容同一索引位置。線程一執(zhí)行途中被掛起(Entry next = e.next;),線程二獲得執(zhí)行時間,執(zhí)行完擴容操作,線程一再次獲得執(zhí)行時間,會形成環(huán)形鏈,然后調用HashTable.get()時,出現(xiàn)了無限循環(huán)。
https://blog.csdn.net/huantai3334/article/details/104170984
33. 解決hash沖突的方式有哪些?
- 開放定址法 --> ThreadLocal
- 鏈地址法 --> HashMap
- 再哈希法(又叫雙哈希):當發(fā)生沖突時,重新計算哈希計算地址,直到無沖突。會增加計算時間。
- 建立公共溢出區(qū):將哈希表分為基本表和溢出表兩部分,凡是和基本表發(fā)生沖突的元素,一律填入溢出表。
34.Queue接口:
單端隊列與雙端隊列:
- Queue與Deque
阻塞隊列與非阻塞隊列:
- 阻塞隊列:(說一下箭頭后的裝逼知識)
- ArrayBlockingQueue ->有邊界;底層數(shù)組;不支持同時讀寫,底層用一把鎖(ReentrantLock)
- LinkedBlockingQueue ->可選擇的有邊界;支持同時讀寫,底層兩把鎖
- PriorityBlockingQueue -> 底層數(shù)據結構是堆 -> 數(shù)組與堆的轉換:heapInsert(插入堆)、heapify(堆化)
- DelayQueue -> 單機版延遲隊列;添加元素實現(xiàn)Delay接口,重寫兩個方法。
- SynchronousQueue -> 容量為0,put()添加一個元素后,會等待task()刪除一個元素
- LinkedBlockingDeque。
- 非阻塞隊列:PriorityQueue、ConcurrentLinkedQueue、LinkedTransferQueue。
隊列方法:(@&@)
35. 集合類是怎么解決高并發(fā)中的問題?
- 先說一下,非安全的集合類。
- 然后再說,普通的安全的集合類(Vector HashTable)。
- 最后說,JUC下的高并發(fā)集合類。
- ConcurrentHashMap和底層 -> ConcurrentHashMap和HashTable的區(qū)別(拓展點)。
- ConcurrentSkipListMap(Set):線程安全的有序的哈希表,它替代TreeMap。
- CopyOnWriteArrayList:寫入時,加鎖將原數(shù)據復制到另一個數(shù)組中,它只能保證數(shù)據的最終一致性,不適合頻繁寫入的操作。
36. JDK1.8的新特性?
- Lambda表達式。
- 函數(shù)式編程:Optional、Predicate、Supplier、Consumer、Function。
- 方法引用和構造器調用 --> :: 關鍵字來傳遞方法或者構造函數(shù)引用。
- 接口中可以有默認方法:default關鍵字。
- Stream API。
- 新時間日期API。
- CompletableFuture類。
37. Stream的并行操作原理?Stream并行的線程池是從哪里來的?
Stream的概念:
Stream專注于對容器對象進行各種非常便利、高效的聚合操作或者大批量數(shù)據操作。
三個操作步驟:
- 創(chuàng)建Stream:從一個數(shù)據源,如集合、數(shù)組中獲取流。
- 中間操作:一個操作的中間鏈,對數(shù)據源的數(shù)據進行操作。
- 終止操作:一個終止操作,執(zhí)行中間操作鏈,并產生結果。
Stream并行(parallel)原理:
它底層依賴于ForkJoinPool.commonPool線程池,這是一個JVM進程全局共享的線程。在ForkJoin上進行了一層封裝,將Stream不斷嘗試分解成更小的集合,然后使用ForkJoin框架分而治之。
38. 關于intern() pass
String a=new String("123")+new String("456"); // String b=new String("123456"); String intern = a.intern(); System.out.println(intern==a); // 注釋輸出true,取消注釋 輸出false
參考文章(不錯):
https://blog.csdn.net/qq_41884976/article/details/83353389
39. Java種的代理有幾種實現(xiàn)方式?
靜態(tài)代理:
在程序編譯前,代理類已經被創(chuàng)建完成。
動態(tài)代理:
- JDK:Proxy
- 面向接口的動態(tài)代理:代理一個對象去增強面向某個接口中定義的方法。
- 沒有接口不可用。
- 只能讀取到接口上的一些注解。
- 舉例:MyBatis DeptMapper dm=sqlSession.getMapper(DeptMapper.class)
- 第三方:CGlib
- 面向父類的動態(tài)代理(繼承)-> 底層原理:操作字節(jié)碼生成新的類 -> 大量使用可能導致元空間的溢出(拓展點)
- 有沒有接口都可以使用。
- 可以讀取類上的注解。
- 舉例: AOP 日志 性能檢測 事務
40. Java中的自增是線程安全的嗎,如何實現(xiàn)線程安全的自增?
- i++、++i 不是線程安全的。
- 解決1:增加Synchronized進行線程同步。
- 解決2:使用Reetrantent鎖進行鎖定(lock、unlock處理)。
- 解決3:AtomicInteger -> 使用Unsafe中的CAS -> CAS的ABA問題。