1. 程式人生 > 實用技巧 >秋招面經總結(Java後端開發)

秋招面經總結(Java後端開發)

以下總結的面經都是我在秋招的過程中被問到的一些高頻問題,後面附上的一些答案是查閱了相關文章總結而出,也是個人觀點,如有錯誤,歡迎指出!

一 Java基礎

  1. Java和C語言有什麼區別?Java好在哪裡?
  2. 怎麼理解Java的跨平臺性,一次編譯到處執行?
  3. 面向物件和麵向過程的區別?
  4. 如何理解面向物件三大特性:封裝、繼承、多型?
  5. 類繼承會有什麼問題嗎,一般什麼情況下才會去用繼承?
  6. 為什麼重寫equals方法還要重寫hashcode方法?
  7. 深克隆和淺克隆
  8. 反射相關
  9. 註解的實現原理
  10. Lambda表示式的優缺點?
  11. Stream流式程式設計的好處?終止方法和延遲方法的區別是?終止方法存在的意義是什麼?
二 Java集合
  1. HashMap底層實現(JDK1.7使用陣列+連結串列;JDK1.8使用陣列+連結串列+紅黑樹)
  2. HashMap為什麼要引進紅黑樹?為什麼不用其他的平衡二叉樹之類的?紅黑樹的優勢在哪裡?(AVL樹的旋轉比紅黑樹的旋轉更加難以平衡和除錯,需要更高的旋轉次數)
  3. 連結串列會轉化為紅黑樹的兩個條件是?(①連結串列的長度達到8;②HashMap底層使用的table陣列長度length達到64;如果不滿足後者,將會觸發擴容方法)
  4. 連結串列長度大於8轉化為紅黑樹,小於6紅黑樹轉化為連結串列;為什麼不直接設定成大於8轉化成紅黑樹,小於8轉化成連結串列;(中間有個差值7進行過渡是為了避免連結串列和樹頻繁轉換,如果一個HashMap不停的插入、刪除元素,連結串列個數在8左右徘徊,就會頻繁的發生樹轉連結串列、連結串列轉樹,效率會很低)
  5. 把連結串列轉化為紅黑樹的閾值是8,為什麼不設定成其他值?(遵循泊松分佈,連結串列長度超過8的概率非常小)
  6. HashMap擴容機制,即resize方法?(JDK 1.7 會重新計算每個元素的雜湊值,JDK1.8是通過高位運算(e.hash & oldCap)來確定元素是否需要移動,如果運算結果值為0,那麼元素擴容後位置不變,結果值為1表示元素在擴容時位置發生了變化,新的下標位置等於原下標位置 + 原陣列長度)
  7. HashMap新增元素的步驟(put方法)、計算集合元素個數(size方法)
  8. HashMap為什麼是執行緒不安全的?(同時新增元素、同時擴容導致資料丟失,jdk1.7頭部倒序插入出現死迴圈導致CPU佔用100%)
  9. HashMap預設的載入因子是0.75,為什麼不設定成1或者0.5(從容量和效能考慮)
  10. HashMap發生雜湊衝突,新節點是插入到連結串列頭部還是連結串列的尾部,頭部倒序插入死迴圈是怎麼產生的?(jdk1.7採用頭部倒序插入,會導致死迴圈;jdk1.8使用尾部正序插入)
  11. Hashtable怎麼控制key value 不能為null?(當呼叫put方法時,首先會判斷value是否為null,為null的話直接丟擲空指標異常;對於key,由於Hashtable計算hash值是int hash = key.hashCode();直接取物件的hashcode,key為null就會報空指標異常;而HashMap計算hash值是return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16),key為null則hash值為0)
  12. ConcurrentHashMap底層採用的結構(分jdk1.7和jdk1.8),jdk1.7和jdk1.8分別採用什麼方式實現執行緒安全?(jdk1.7採用分段鎖,也就是為每一個segment加上ReentrantLock鎖;jdk1.8使用的是CAS機制加上synchronized鎖)
  13. ConcurrentMap中的size方法是如何實現的?多執行緒操作下,如果一個執行緒在查size方法,一個執行緒在執行put方法,底層是如何控制每次計算出來的值是正確的?
  14. HashSet的底層實現?(基於HashMap來實現的,new 一個 HashSet物件底層實際就是new了一個HashMap,並且使用預設的初始容量16和預設的載入因子0.75;當我們往HashSet裡面新增一個元素其實就是往HashMap裡面put了一個元素,並且是以key存在的,HashMap的value值都是一樣的,是一個靜態常量PRESENT,原始碼為:private static final Object PRESENT = new Object();
  15. BlockingQueue(阻塞佇列)如何實現生產者消費者模型?
  16. 執行緒安全的List有哪些?(Vector、CopyOnWriteArrayList、還可以使用Collections類的synchronizedList方法將執行緒不安全的List轉為執行緒安全的)
  17. 為什麼ArrayList查詢速度快?(ArrayList底層是基於陣列實現,可以根據元素下標進行查詢,查詢方式為(陣列首地址+元素長度*下標,基於這個位置讀取相應的位元組數就可以了),如果陣列存的是物件,怎麼根據下標定位元素所在位置?(物件陣列每個元素存放的是物件的引用,而引用型別如果開啟指標壓縮佔用4位元組,不開啟則佔用8位元組,所以物件陣列同樣適用上面的公式)
  18. ArrayList的擴容?(ArrayList底層是基於陣列實現,所以建立ArrayList會給陣列指定一個初始容量,預設值為10,因為必須指明陣列的長度才能給陣列分配空間;由於陣列的特性,ArrayList擴容是建立一個更大的陣列,然後將原來的元素拷貝到更大的陣列中,擴容的核心方法是Arrays.copyOf方法)
  19. ArrayList和LinkedList的區別,新增一個元素的時間複雜度各是多少,既然ArrayList新增元素效率沒有LinkedList高,為什麼我們平時用的比較多的還是ArrayList?
  20. 一般什麼情況下會用ArrayList,什麼情況用LinkedList?(如果只是普通的存取元素多用ArrayList,LinkedList一般用作棧、佇列)
  21. 將一個Map集合變成棧,如何實現?(我的思路是用TreeMap去實現,key存的是要入棧的元素,value存的是可以記錄他們入棧的一個先後順序的,例如時間戳,然後重寫Comparator比較器,根據value進行排序,遍歷Map時,先進的後面出)
  22. Map集合有迭代器嗎?遍歷輸出Map中所有元素有哪些方法?
三 多執行緒和Java鎖
  1. 執行緒池的三大方法、七大引數、四種拒絕策略(可以順帶談一下阿里巴巴開發手冊對於執行緒池使用的規範)
  2. 最大執行緒數如何定義?(從CPU密集型和IO密集型考慮)
  3. 執行緒池的五種狀態(Running、Shutdown、Stop、Tidying、Terminated)
  4. 執行緒池的任務執行流程、excute方法和 submit方法的區別?
  5. Synchronized鎖和Lock鎖的區別
  6. Java執行緒虛假喚醒(執行緒本應該處於wait狀態卻被喚醒了,解決方案是wait方法應該用while迴圈包裹,不用if)
  7. JMM的三種特性(原子性、可見性、有序性)、主記憶體和執行緒工作記憶體的八種互動動作
  8. volatile如何保證可見性(MESI快取一致性協議)
  9. volatile如何保證有序性(記憶體屏障——lock字首指令)
  10. synchronized和volatile的區別(volatile是一種非鎖機制,這種機制可以避免鎖機制引起的執行緒上下文切換和排程問題。因此,volatile的執行成本比synchronized更低;volatile只能保證可見性有序性;synchronized可以保證原子性可見性有序性)
  11. JUC包中的原子類如何保證原子性?(CAS機制和自旋鎖)
  12. CAS機制,會引發什麼問題,如何解決ABA問題?(CAS會導致ABA問題,解決ABA問題是使用版本號機制)
  13. 悲觀鎖和樂觀鎖的區別,應用?(java中的Synchronized關鍵字和lock鎖使用的都是悲觀鎖;CAS機制是樂觀鎖的一種實現方式)
  14. 公平鎖和非公平鎖(公平鎖按照先來先服務,不會出現飢餓;非公平鎖會導致飢餓,但是效率更高,預設的鎖都是非公平的)
  15. 自旋鎖和互斥鎖,自旋鎖的優缺點?(優點:減少上下文切換和使用者態核心態的切換帶來的開銷;缺點:迴圈等待消耗CPU)
  16. 可重入鎖和不可重入鎖(不可重入鎖容易導致死鎖發生,大多數鎖都是可重入的,例如Synchronized鎖和ReentrantLock)
  17. JDK1.6 Synchronized鎖升級(偏向鎖—輕量級鎖—重量級鎖)
  18. Synchronized鎖的底層實現,鎖的是什麼,其它執行緒如何判斷該鎖已經被佔用了?
  19. 死鎖產生的四個必要條件以及死鎖的處理策略
四 Mysql
  1. Myisam和InnoDB儲存引擎的區別?(Myisam不支援外來鍵也不支援事務,支援的是表鎖,當執行select操作時,自動給涉及的表加表鎖,當執行增刪改操作,自動給涉及的表加寫鎖;InnoDB支援外來鍵也支援事務,支援的是行鎖,當執行select操作時,不加任何鎖,當執行增刪改操作,自動給涉及的行加寫鎖)
  2. 間隙鎖是什麼?行鎖升級為表鎖的情況?
  3. InnoDB的行鎖有哪些?鎖住的是行還是索引?(Record Lock、Gap Lock、Next-Key Lock;鎖住的是索引,而不是行)
  4. 為什麼可重複讀隔離級別也可以解決幻讀?(通過Next-Key Lock可以消除幻讀)
  5. 併發事務處理帶來的四種問題和事務的隔離級別(丟失更新、髒讀、不可重複讀、幻讀;讀未提交、讀已提交、可重複讀、序列化)
  6. 如何理解Mysql預設的事務隔離級別可重複讀?
  7. 事務的ACID屬性是如何實現的?(原子性通過回滾日誌undo log實現;永續性通過重做日誌redo log實現;隔離性通過鎖和MVCC實現;而一致性則是通過原子性、隔離性、永續性來實現,只有滿足這三個特性,才能實現事務的一致性)
  8. 聚簇索引、非聚簇索引、回表查詢、覆蓋索引;
  9. 索引失效的情況?(違反最左字首法則、範圍查詢右邊的列索引失效、字串不加單引號、對索引列進行運算、頭部模糊匹配、使用不等於!=或者<>)
  10. explain分析執行計劃、SQL語句的優化
  11. mysql三大正規化(1NF即原子性,2NF即消除部分依賴,3NF即消除傳遞依賴)
  12. mysql索引的底層實現,為什麼用B+樹不用B樹?(B+樹IO次數更少、更適合範圍查詢、查詢效率更加穩定)
  13. 雜湊表查詢速度不是更快嗎,為什麼不直接使用雜湊表來做索引的底層資料結構?(雜湊表不支援範圍查詢)
五 Redis
  1. Redis五種基本資料型別的使用場景
  2. 快取穿透、快取擊穿、快取雪崩
  3. Redis的過期策略和記憶體淘汰機制
  4. Redis的zset底層資料結構,為什麼用跳躍表而不用紅黑樹
六 框架相關
  1. Spring AOP的實現原理?(基於動態代理模式,如果目標類實現了介面,那麼使用基於介面的動態代理,否則使用基於子類/cglib的動態代理)
  2. Spring AOP 的具體載入步驟?
  3. AOP和OOP的區別,分別適用什麼場景?
  4. Spring Bean的作用域,Spring Bean的生命週期(Bean的例項化—初始化Bean—使用Bean—Bean的銷燬)
  5. Spring容器建立物件的兩種時機,各有什麼優缺點?(一是Spring容器啟動時建立Bean,二是呼叫getBean方法時建立)
  6. SpringMVC的執行流程(可以順帶講一下介面卡模式)
  7. Mybatis的一級快取和二級快取?
  8. Mybatis中#和$的區別?
  9. Mybatis如何實現批量插入?
  10. Mybatis的xml檔案中,sql語句可以使用直接使用大於號小於號嗎?應該用什麼符號代替?
七 設計模式
  1. 請列舉出在 JDK 中幾個常用的設計模式?
  2. 什麼是設計模式?你是否在你的程式碼裡面使用過任何設計模式?
  3. Java 中什麼叫單例設計模式?請用 Java 寫出執行緒安全的單例模式
  4. 在 Java 中,什麼叫觀察者設計模式(observer design pattern)?
  5. 使用工廠模式最主要的好處是什麼?在哪裡使用?
  6. 舉一個用 Java 實現的裝飾模式(decorator design pattern)?它是作用於物件層次還是類 層次?
  7. 在 Java 中,為什麼不允許從靜態方法中訪問非靜態變數?
  8. 設計一個 ATM 機,請說出你的設計思路?
  9. 在 Java 中,什麼時候用過載,什麼時候用重寫?
八 網路
  1. TCP三次握手和四次揮手的過程,每次傳送的包的內容,客戶端和服務端的狀態?

  2. TCP三次握手可以攜帶資料嗎?TCP協議執行時階段?

  3. 為什麼是三次握手,可以四次握手或者兩次握手嗎?

  4. 為什麼握手是三次,而揮手要四次?

  5. TCP四次揮手為什麼需要TIME-WAIT階段等待2MSL,是哪一方有TIME-WAIT階段?(主動釋放釋放連線的那端)

  6. TCP的長連線和短連線

  7. 半連線佇列和全連線佇列,什麼是syn flood攻擊,如何應對syn flood攻擊?

  8. 在瀏覽器中輸入一個網址回車後發生了什麼?

  9. 域名解析過程的遞迴查詢和迭代查詢

  10. 瀏覽器輸入一個網址之後,按照TP/IP參考模型,從應用層到網路層各使用了哪些協議?

    (應用層:HTTP、DNS;傳輸層:TCP、UDP;網路層:IP、ICMP、ARP)

  11. ICMP協議的兩個應用——Ping和Traceroute

  12. IP地址和MAC地址有什麼區別?

  13. http和https的區別

  14. 網站為什麼要使用cookie和session;cookie和session有什麼區別?

  15. get請求和post請求的區別?

  16. TCP和UDP的區別以及各自的應用場景?

  17. epoll和select的區別?

九 JVM
  1. JVM記憶體模型(程式計數器、虛擬機器棧、本地方法棧、堆、方法區)

  2. JDK1.8做了哪些變化?(JDK1.7已經將原本位於永久代的字串常量池移到堆中了,但是永久代的概念還存在,JDK1.8才徹底廢除永久代,進而用元空間代替)

  3. 永久代和元空間,JDK1.8為什麼要使用元空間代替永久代?

  4. 元空間溢位?(元空間不屬於Java虛擬機器,使用的是本地記憶體,存放的是類及方法的一些資訊,動態載入類或者頻繁載入類資訊,但是沒有及時解除安裝,會導致元空間溢位)

  5. 物件建立的兩種方式(指標碰撞、空閒列表)、物件訪問定位的兩種方式(使用控制代碼、直接指標)

  6. 棧上分配與逃逸分析(JVM層面進行java效能優化的技巧)

  7. 判斷物件是否存活的兩種方式,引用計數法的缺點?(引用計數法、可達性分析法)

  8. 關於Object類的finalize()方法(jvm自動執行,無需手動呼叫,只能執行一次).

  9. java的四種引用(強引用、軟引用、弱引用、虛引用)

  10. 三種垃圾回收演算法,各自的優缺點(標記-清除法、標記-複製法、標記-整理法)

  11. Minor GC 和 Full GC 的區別,觸發條件,以及空間分配擔保策略?

  12. 記憶體溢位和記憶體洩露(記憶體洩露的堆積會導致記憶體溢位)

  13. JVM引數調優(-Xms、-Xmx、-Xss、-XX:NewRatio、-XX:SurvivorRatio、-XX:+PrintGCDetails、-HeapDumpOnOutOfMemory)

  14. 發生OOM如何解決(首先嚐試通過JVM引數調優擴大堆記憶體空間;再者dump出堆記憶體儲存快照,使用JProfile工具進行分析)

  15. 垃圾收集器(CMS問的居多,另外,如果談及發生gc會給使用者帶來什麼不好的體驗,可以談談Stop the World)

  16. 類載入機制的過程,準備階段做了哪些工作?(準備階段會給類的靜態變數分配記憶體(方法區)並賦初值,如果類的靜態變數被final修飾,那麼初始化的值就不是零值,而是宣告的值)

  17. 類的雙親委派模型定義,雙親委派模型的好處?如何破壞類的雙親委派模型?

十 作業系統
  1. linux的殭屍程序和孤兒程序的區別,如何清理殭屍程序?(kill殭屍程序的父程序)
  2. 如何檢視殭屍程序資訊?如何統計殭屍程序數量?(ps - ef | grep defunct;ps -ef | grep defunct | wc - l)
  3. 併發和並行的區別?
  4. 程序和執行緒的區別?
  5. 程序通訊的方式有哪些?(管道、訊息佇列、共享記憶體、訊號量、套接字Socket)

都整理在網盤了需要的可以點選這裡,暗號部落格園!