Java面试必学-吐血推荐
最近在B站上制作了關(guān)于java面試的視頻,希望各位大佬可以給點指導(dǎo)意見,作為一個老學(xué)姐,我認(rèn)為有責(zé)任把知識分享給大家
【Java學(xué)姐】SQL調(diào)優(yōu)必備Explain查看執(zhí)行計劃各項參數(shù)解析:https://www.bilibili.com/video/BV1iZ4y1j7Wp/
【Java面試必問】Mysql索引/存儲引擎/行表鎖/分庫分表/主從復(fù)制:https://www.bilibili.com/video/BV1DK4y1C7o7/
【Java學(xué)姐】8分鐘搞懂MySQL為什么用B+樹做索引:https://www.bilibili.com/video/BV1Ka4y1t7ev/
【Java面試必問】Redis持久化/復(fù)制/雪崩/擊穿/雙寫一致性/過期策略:https://www.bilibili.com/video/BV1E7411S7Dh/
【JAVA學(xué)姐】10分鐘學(xué)會如何查看生產(chǎn)服務(wù)器各項狀態(tài)指標(biāo): https://www.bilibili.com/video/BV1s7411D7zE/
【Java面試必問】GC垃圾回收算法: https://www.bilibili.com/video/BV1H7411Q7M8/
【Java面試必問】JVM調(diào)優(yōu)參數(shù)解析及Java虛擬機內(nèi)存模型:? https://www.bilibili.com/video/BV1G7411Q7Hz/
【Java面試必問】【多線程開發(fā)必用JUC】Java并發(fā)包-JUC:? https://www.bilibili.com/video/BV14E411F7qS/
【Java面試必問】學(xué)姐帶你學(xué)面試急救包-基礎(chǔ)講解:https://www.bilibili.com/video/BV1LE411F79v/
?
注:為節(jié)約大家的時間,可以開啟1.5倍速觀看。
==========以下是jvm部分筆記,可觀看視頻講解=========
5、java鎖
①公平鎖:隊列先來后到? ?new ReentrantLock(true);
②非公平鎖 :可以插隊(可造成優(yōu)先級反轉(zhuǎn)和饑餓的現(xiàn)象)? ? new ReentrantLock();
③可重入鎖(遞歸鎖):ReentrantLock/Syncronized 類似于大門鑰匙---防止死鎖
同一線程外層函數(shù)獲取鎖后,內(nèi)層遞歸函數(shù)仍然能獲取該鎖(內(nèi)層會自動獲取鎖)
即:線程可以進入任何一個它已經(jīng)擁有的鎖所同步著的代碼塊
④自旋鎖:嘗試獲取鎖的線程不會立即阻塞,而是采用循環(huán)的方式嘗試獲取鎖,好處:減少線程上下文切換的消耗,缺點:循環(huán)會消耗CPU
⑤獨占鎖(寫):該鎖一次只能被一個線程所持有。ReentrantLock/Syncronized
⑥共享鎖(讀):該鎖可被多個線程所持有。
ReentrantReadWriteLock:讀鎖是共享鎖,寫鎖是獨占鎖。
讀鎖的共享鎖可保證并發(fā)讀是非常高效的,讀寫,寫讀,寫寫的過程是互斥的。
寫操作:原子+獨占
6、線程排序常用鎖
①CountDownLatch:秦滅六國一統(tǒng)華夏,線程減到0才執(zhí)行主線程(減法)
②CyclicBarrier:集齊7顆龍珠,可以召喚神龍(加法)
③Semaphore:信號燈,多個線程搶多份資源。示例:爭車位
作用:一個是用于多個共享資源的互斥使用,另一個用于并發(fā)線程數(shù)的控制
7、阻塞隊列:可以使擁擠的線程進行等待,避免失敗率(自己理解)代碼
多線程領(lǐng)域的阻塞:在某些情況下會掛起線程(阻塞),一旦條件滿足,被掛起的線程又會自動被喚醒
①阻塞隊列有沒有好的一面:BlockingQueue可以不用關(guān)心阻塞和喚醒,BlockingQueue全包
②不得不阻塞,你如何管理:
當(dāng)阻塞隊列是空時,從隊列中獲取元素的操作會被阻塞
當(dāng)阻塞隊列是滿時,往隊列里添加元素的操作會被阻塞
以上可以理解為蛋糕店成產(chǎn)蛋糕,蛋糕柜空時,消費者阻塞;當(dāng)?shù)案夤駶M時,生產(chǎn)者阻塞
Collection的實現(xiàn)類有List和Queue
③Queue的實現(xiàn)類有:BlockingQueue接口
<1>ArrayBlockingQueue:由數(shù)組結(jié)構(gòu)組成的有界阻塞隊列
<2>LinkedBlockingQueue:由鏈表結(jié)構(gòu)組成的有界(大小默認(rèn)Integer.MAX_VALUE)阻塞隊列
<3>PriorityBlockingQueue:支持優(yōu)先級排序的無界阻塞隊列
<4>DelayQueue:使用優(yōu)先級隊列實現(xiàn)的延遲無界阻塞隊列
<5>SynchronousQueue:不存儲元素的阻塞隊列,也即單個元素的隊列
<6>LinkedTransferQueue:由鏈表結(jié)構(gòu)組成的無界阻塞隊列
<7>LinkedBlockingDeque:由鏈表結(jié)構(gòu)組成的雙向阻塞隊列
④阻塞隊列的核心方法:ArrayBlockingQueue
<1>異常:add(e),remove(),element()
<2>特殊值:offer(e) ,poll(),peek()--- 成功true,失敗false?
<3>阻塞:put(e),take()
<4>超時退出:offer(e,time,unit),poll(time,unit)
⑤阻塞隊列用在哪里?
Syncronized-ReentrantLock
【注】多線程企業(yè)級模板口訣:線程操作資源類,判斷-干活-喚醒通知,嚴(yán)防多線程狀態(tài)下的虛假喚醒
<1>生產(chǎn)者消費者模式:
<2>線程池:
<3>消息中間件:生產(chǎn)一個,消費一個
⑥Syncronized-ReentrantLock區(qū)別
Syncronized:JVM層面,java關(guān)鍵字,底層monitor,不需要手動釋放,
不可中斷,除非拋出異常或正常運行完成,非公平鎖,要么喚醒一個線程,要么喚醒全部線程
ReentrantLock:api層面,類,需要手動釋放,可中斷,可設(shè)置超時方法也可在代碼塊中調(diào)用interrupt方法,默認(rèn)非公平鎖,構(gòu)造方法傳true為公平鎖,可以用來實現(xiàn)分組喚醒需要喚醒的線程們(精確喚醒)
練習(xí):ABC三個線程,A打印5次,B打印10次,C打印15次,循環(huán)3次,按順序
8、線程池
<1>為什么要用線程池?
線程池主要是控制運行的線程的數(shù)量,處理過程中將任務(wù)放入隊列,然后在線程創(chuàng)建后啟動這些任務(wù),如果線程數(shù)量超過了最大數(shù)量,超出數(shù)量的線程排隊等候,等其他憲曾執(zhí)行完畢,再從隊列中取出任務(wù)來執(zhí)行。
主要特點:線程復(fù)用,控制最大并發(fā)數(shù),管理線程
<2>創(chuàng)建線程的四種方式:
繼承Thread類
實現(xiàn)Runnable接口:無返回值,不拋異常,實現(xiàn)run方法
實現(xiàn)Callable接口:有返回值,會拋異常,實現(xiàn)call方法
通過線程池
①callable
<3>線程池框架:底層ThreadPoolExecutor
①ExecutorService threadPool = Executors.new FixedThreadPool(int)-一池固定線程數(shù)
②Executors.newSingleThreadExecutor()-一池一個線程
③Executors.newCachedThreadPool()可擴容的一池多線程
上述三種工作中用哪種?一個都不用,用ThreadPoolExecutor自己創(chuàng)建,工具類封裝好的有界隊列長度過大
<4>線程池的7大重要參數(shù)
①corePoolSize:線程池中的核心線程數(shù)(類似于銀行網(wǎng)點的窗口數(shù))
②maximumPoolSizse:線程池能夠容納同時執(zhí)行的最大線程數(shù)(類似于銀行窗口開放數(shù))
③keepAliveTime:多余的空閑線程的存活時間
④unit:keepAliveTime的單位
⑤workQueue:任務(wù)隊列,被提交但尚未被執(zhí)行的任務(wù)(阻塞隊列)
⑥threadFactory:表示生成線程池中工作線程的線程工廠,用于創(chuàng)建線程一般用默認(rèn)的即可
⑦h(yuǎn)andler:決絕策略,表示當(dāng)隊列滿了并且工作線程大于等于線程池的最大線程數(shù)
<5>線程池的底層工作原理
比如銀行辦公窗口滿了,阻塞隊列(候客區(qū))也滿了,這個時候需要擴容銀行的加班窗口,擴容后新進來的會直接搶占新擴容的加班窗口,若任務(wù)還在持續(xù)增加會啟動飽和拒絕策略,若熱任務(wù)量下降了(多余空閑線程的存活時間)會縮容
<6>線程池的拒絕策略
AbortRolicy(默認(rèn)):直接拋出異常,阻止運行
CallerRunsPoclicy:調(diào)用者運行機制
DiscardOldestPolicy:拋棄隊列中等待最久的任務(wù)
DiscardPolicy:直接丟棄任務(wù),不處理也不拋異常
<7>合理配置線程池如何考慮?
CPU密集型:CPU核數(shù)+一個線程
IO密集型:
①任務(wù)線程并不是一直在執(zhí)行任務(wù),則應(yīng)配置盡可能多的線程,如CPU核數(shù)*2
②大部分線程都阻塞,需要多配置線程數(shù),參考公式:CPU核數(shù)/(1-阻塞系數(shù)) --阻塞系數(shù)在0.8~0.9之間
9、死鎖編碼及定位分析
<1>產(chǎn)生死鎖的原因:系統(tǒng)資源不足,進程運行推進的順序不合適,資源分配不當(dāng)
<2>解決:jps定位進程,jstack找到死鎖查看
總結(jié)
以上是生活随笔為你收集整理的Java面试必学-吐血推荐的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式系统CAP定理
- 下一篇: cmake使用方法(详细)