微信搜索 【微觀技術】,關注這個不喜歡內卷的程式員,
精彩文章匯總 GitHub https://github.com/aalansehaiyang/technology-talk ,Star 12K ,匯總java生態圈常用技術框架、開源中間件,系統架構、資料庫、大公司架構案例、常用三方類別庫、專案管理、線上問題排查、個人成長、思考等知識
大家好,我是Tom哥~
關于Java面試,面試官一般喜歡問哪些問題?
本文對一些高頻問題做了匯總,為了便于大家查找問題,了解全貌,整理個目錄,我們可以快速全域了解關于 JAVA

接下來,我們逐條來看看每個問題及答案
JDK、JRE、JVM 三者有什么關系?
答案:
- JDK(全稱 Java Development Kit),Java開發工具包,能獨立創建、編譯、運行程式,
JDK = JRE + java開發工具(javac.exe/java.exe/jar.exe)
- JRE(全稱 Java Runtime Environment),能運行已編譯好的程式,但不能創建程式
JRE = JVM + java核心類別庫
- JVM (全稱 Java Virtual Machine),java虛擬機,
java創建物件有哪些方式?
答案:
-
1、new 創建物件
-
2、反射機制創建物件
-
3、通過clone方法
-
4、序列化機制
== 和 equals 有什么區別?
答案:
-
== ,如果是基本資料型別,比較兩個值是否相等;如果是物件,比較兩個物件的參考是否相等,指向同一塊記憶體區域
-
equals,用于物件之間,比較兩個物件的值是否相等,
hashCode()的作用?
答案:生成哈希碼,int型別,用于確定該物件在哈希表中的索引位置,每個類中都包含這個方法,
String、StringBuffer、StringBuilder 有什么區別?
答案
-
1、String,采用
final修飾,物件不可變,執行緒安全,如果對一個已經存在的String物件修改,會重新創建一個新物件,并把值放進去, -
2、StringBuffer,采用
synchronized關鍵字修飾,執行緒安全 -
3、StringBuilder,非執行緒安全,但效率會更高些,適用于單執行緒,
try-catch-finally,如catch中return了,還會執行finally嗎?
答案:當然啦,會在return之前執行,
行程和執行緒的區別?
答案:
-
行程:是一個程式的執行流程,是系統進行資源分配和調度的基本單位,作用是程式能夠并發執行提高資源利用率,因為行程的創建、銷毀、切換產生大量的時間和空間的開銷,所以行程的數量不能太多
-
執行緒:是比行程更小的能獨立運行的基本單位,他是行程的一個物體,可以減少程式并發執行時的時間和空間開銷,使得作業系統具有更好的并發性,多個執行緒可以共享行程的系統資源,執行緒基本不擁有系統資源,只有一些運行時必不可少的資源,比如程式計數器、暫存器和堆疊,行程則占有堆,
整理了一份大廠常考面試題,這份pdf包括 Java基礎、Java并發、JVM、MySQL、Redis、Spring、MyBatis、Kafka、設計模式等面試題,分享給大家,
下載地址:百度云鏈接:https://pan.baidu.com/s/1XHT4ppXTp430MEMW2D0-Bg 提取碼: s3ab
synchronized 的內部原理?
答案:java提供的原子性內置鎖,也被稱為監視器鎖,使用synchronized之后,會在編譯之后在同步的代碼塊前后加上monitorenter和monitorexit位元組碼指令,依賴作業系統底層互斥鎖實作,實作原子性操作和解決共享變數的記憶體可?性問題,
內部處理程序(內部有兩個佇列waitSet和entryList,):
-
1、當多個執行緒進入同步代碼塊時,首先進入
entryList -
2、有一個執行緒獲取到monitor鎖后,就賦值給當前執行緒,并且計數器+1
-
3、如果執行緒呼叫wait方法,將釋放鎖,當前執行緒置為null,計數器-1,同時進入
waitSet等待被喚醒,呼叫notify或者notifyAll之后又會進入entryList競爭鎖 -
4、如果執行緒執行完畢,同樣釋放鎖,計數器-1,當前執行緒置為null

synchronized 和 ReentrantLock 的區別?
答案:
-
ReentrantLock 實作了Lock介面,synchronized是系統關鍵字
-
ReentrantLock需要手動指定鎖范圍,synchronized 支持同步塊、同步方法
-
都具有可重入性
-
默認都是非公平鎖,但 ReentrantLock 還支持公平模式,但性能會急劇下降
-
ReentrantLock 需要顯示的獲取鎖、釋放鎖
-
ReentrantLock 支持多種方式獲取鎖,
-
lock():阻塞模式來獲取鎖
-
lockInterruptibly:阻塞式獲取鎖,支持中斷
-
tryLock():非阻塞模式嘗試獲取鎖
-
tryLock(long timeout, TimeUnit unit):同上,支持時間設定
-
ReentrantLock 可以同時系結多個Condition條件物件,
AQS (AbstractQueuedSynchronizer 抽象佇列同步器 )的原理?
答案:AQS內部維護一個state狀態位,嘗試加鎖的時候通過CAS(CompareAndSwap)修改值,如果成功設定為 1,并且把當前執行緒ID賦值,則代表加鎖成功,
一旦獲取到鎖,其他的執行緒將會被阻塞進入阻塞佇列自旋,獲得鎖的執行緒釋放鎖的時候將會喚醒阻塞佇列中的執行緒,釋放鎖的時候則會把state重新置為0,同時當前執行緒ID置為空,
CAS 有什么缺點?
答案:在多執行緒場景下,更新變數值被其他執行緒跑了個對沖,CAS會出現ABA問題,解決方式有很多,
-
可以通過,自增版本號方式,永遠不會回退
-
Java中提供了
AtomicStampedReference,增加了標志欄位,更新時不光檢查值,還要檢查當前的標志是否等于預期標志,全部滿足條件才會更新 -
更多內容,CAS原理分析,解決銀行轉賬ABA難題
Java 都用過哪些鎖?
答案:
-
樂觀鎖、悲觀鎖
-
分布式鎖
-
獨占鎖、共享鎖
-
互斥鎖
-
讀寫鎖
-
公平鎖、非公平鎖
-
可重入鎖
-
自旋鎖
-
分段鎖
-
鎖升級(無鎖|偏向鎖|輕量級鎖|重量級鎖)
-
鎖優化技術(鎖粗化、鎖消除)
-
更多詳細內容,一文全面梳理各種鎖機制
HashMap原理?
答案:內部由陣列和鏈表組成,非執行緒安全,JDK1.7和1.8的主要區別在于頭插和尾插方式的修改,頭插容易導致HashMap鏈表死回圈,并且1.8之后加入紅黑樹對性能有提升,
-
put插入:key 計算hash值,取模,找到陣列位置,如果陣列中沒有元素直接存入,反之,則判斷key是否相同,key相同就覆寫,否則就會插入到鏈表的尾部,如果鏈表的?度超過8且資料總量超過64,則會轉換成
紅黑樹,最后判斷元素個數是否超過默認的?度(16)*負載因子(0.75),也就是12,超過則進行擴容, -
get查詢:計算出hash值,然后去陣列查詢,是紅黑樹就去紅黑樹查,鏈表就遍歷鏈表查詢就可以了,
紅黑樹的時間復雜度 O(logn);鏈表的時間復雜度 O(n),當鏈表過長時,紅黑樹能大大提高查詢性能,
ConcurrentHashMap 如何能保證執行緒安全的?
答案:ConcurrentHashmap在JDK1.7和1.8的版本改動比較大,
-
1.7 使用Segment + HashEntry 分段鎖的方式實作,
Segment繼承于ReentrantLock,HashEntry存盤鍵值對資料, -
1.8 采用陣列+ 鏈表 + 紅黑樹,鎖設計上拋棄了Segment分段鎖,采用 CAS + synchronized 實作,
ArrayList 和 LinkedList 有什么區別?
答案:
1、Arraylist
-
非執行緒安全
-
底層采用陣列存盤
-
插入、洗掉元素,時間復雜度受位置影響,默認是添加在串列的末尾,如果在位置 k 插入或洗掉一個元素,需要將k后面的元素后移或前移一位,
-
支持隨機訪問,根據索引下標序號,可以快速定位元素
-
需要連續的記憶體空間,中間不能有碎片
2、LinkedList
-
非執行緒安全
-
底層采用雙向回圈鏈表存盤
-
插入、洗掉元素,時間復雜度不受位置影響,只需要更改位置 k的前后指標地址,時間復雜度為 O(1)
-
不支持高效的隨機訪問
-
不需要連續的記憶體空間
volatile 原理?
答案:volatile宣告的變數,值被更新后對其他執行緒立即可?,
CPU會根據快取一致性協議,強制執行緒重新從主記憶體加載最新的值到自己的作業記憶體中,而不是直接用cpu快取中的值,
ThreadLocal 原理?
答案:ThreadLocal有一個靜態內部類ThreadLocalMap,ThreadLocalMap又包含了一個Entry陣列,Entry本身是一個弱參考,他的key是指向ThreadLocal的弱參考,Entry具備保存key – value鍵值對的能力,
在使用完之后呼叫remove方法洗掉Entry物件,避免出現記憶體泄露,
什么是作業記憶體、主記憶體?
答案:
-
作業記憶體:暫存器、CPU快取(L1、L2、L3)
-
主記憶體:主要是指物理記憶體
JUC并發包用過哪些執行緒安全的類?
答案:
-
ConcurrentHashMap
-
CountDownLatch、CyclicBarrier
-
Semaphore
-
BlockingQueue
-
ThreadPoolExecutor
-
ReentrantLock、ReentrantReadWriteLock
-
CompletableFuture
ThreadPoolExecutor 有哪些構造引數?
答案:核心執行緒數、最大執行緒數、最大空閑時間、時間單位、任務佇列、執行緒工廠、拒絕策略
-
更多內容,參考 史上最全ThreadPoolExecutor梳理(上篇)
-
更多內容,參考 史上最全ThreadPoolExecutor梳理(下篇)
ThreadPoolExecutor 的拒絕策略有哪些?
答案:
-
1、AbortPolicy:直接丟棄任務,拋出例外,這是默認策略
-
2、CallerRunsPolicy:只用呼叫者所在的執行緒來處理任務
-
3、DiscardOldestPolicy:丟棄等待佇列中最舊的任務,并執行當前任務
-
4、DiscardPolicy:直接丟棄任務,也不拋出例外
-
5、使用
RejectedExecutionHandler介面,自定義實作
執行緒有哪些狀態?是如何轉換?
答案:New、Runnable、Running、Blocked、Waiting、Timed Waiting、Terminated

IO 模型有哪五種?
答案:
1、阻塞IO,當 應用B 發起讀取資料申請時,如果內核資料沒有準備好,應用B會一直處于等待資料狀態,直到內核把資料準備好了交給應用B才結束,
2、非阻塞IO,當應用B發起讀取資料申請時,如果內核資料沒有準備好會即刻告訴應用B,不會讓B在這里等待,
3、IO復用模型,行程通過將一個或多個fd傳遞給select,阻塞在select操作上,select幫我們偵測多個fd是否準備就緒,當有fd準備就緒時,select回傳資料可讀狀態,應用程式再呼叫recvfrom讀取資料,
4、信號IO,信號驅動IO不是用回圈請求詢問的方式去監控資料就緒狀態,而是在呼叫sigaction時候建立一個SIGIO的信號聯系,當內核資料準備好之后再通過SIGIO信號通知執行緒資料準備好后的可讀狀態,當執行緒收到可讀狀態的信號后,此時再向內核發起recvfrom讀取資料的請求,因為信號驅動IO的模型下應用執行緒在發出信號監控后即可回傳,不會阻塞,所以這樣的方式下,一個應用執行緒也可以同時監控多個fd,
5、異步IO,解決了應用程式需要先后查看資料是否就緒、發送接收資料請求兩個階段的模式,在異步IO的模式下,只需要向內核發送一次請求就可以完成狀態查詢和資料拷貝的所有操作,
阻塞IO 和 非阻塞IO 的區別?
答案:如果資料沒有就緒,在查看資料是否就緒的這個階段是一直等待?還是直接回傳一個標志資訊,
關于我:Tom哥,前阿里P7技術專家,出過專利,多年大廠實戰經驗,歡迎關注,我會持續輸出更多經典原創文章,為你大廠助力,
歡迎小伙伴找Tom哥嘮嗑聊天, 技術交流,圍觀朋友圈,人生打怪不再寂寞,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/382872.html
標籤:java
下一篇:python3基礎之集合set
