Java面試腦圖思維導圖_第1頁
Java面試腦圖思維導圖_第2頁
Java面試腦圖思維導圖_第3頁
Java面試腦圖思維導圖_第4頁
Java面試腦圖思維導圖_第5頁
已閱讀5頁,還剩44頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

Java面試?算法o排序算法?比較排序?交換排序o冒泡排序o快速排序?插入排序o簡單插入排序o希爾排序?選擇排序o簡單選擇排序o堆排序?歸并排序o二路歸并排序o多路歸并排序?非比較排序?計數(shù)排序?桶排序?基數(shù)排序o查找算法?二分查找?順序查找?插值查找?斐波那契查找?樹表查找?分塊查找??Springospring????o優(yōu)點??哈希查找創(chuàng)建出來的對象作用域singleton?spring容器初始化時創(chuàng)建對象,設置lazy-init為true時,調(diào)用getBean時才會創(chuàng)建對象ototype?無論是否設置lazy-init,都只會在getBean時才會創(chuàng)建對象?為每個請求創(chuàng)建一個對象session?為每個session創(chuàng)建一個對象IOC?控制反轉(zhuǎn),別名依賴注入o由SpringIOC容器來負責對象的生命周期和對象之間的關系?InversionofcontrolAOP?定義o分散在各個方法中的重復代碼提取出來,然后在程序編譯或運行時,再將這些提取出來的代碼應用到需要執(zhí)行的地方。這種提取機制的方式。?動態(tài)代理方式oCGLIB代理?類oJDK動態(tài)代理?接口?JavaAOP框架oAspectJ?區(qū)別?與SpringAOPoAspectJ?編譯時增強o基于字節(jié)碼操作?SpringAOPo運行時增強o基于代理?實用?日志?事務?權限?異常捕獲?事務o傳播機制?REQUIRED?如果有事務,那么加入事務,沒有的話新建一個(默認情況下)?NOT_SUPPORTED?容器不為這個方法開啟事務?REQUIRES_NEW?不管是否存在事務,都創(chuàng)建一個新的事務,原來的掛起,新的執(zhí)行完畢,繼續(xù)執(zhí)行老的事務?MANDATORY?必須在一個已有的事務中執(zhí)行,否則拋出異常?NEVER?必須在一個沒有的事務中執(zhí)行,否則拋出異常(與Propagation.MANDATORY相反)?SUPPORTS?如果其他bean調(diào)用這個方法,在其他bean中聲明事務,那就用事務.如果其他bean沒有聲明事務,那就不用事務.?線程安全問題o發(fā)生在單例Bean中,當多個線程訪問對象的非靜態(tài)成員變量時,寫操作會有線程安o解決?ThreadLocal將變量保存起來?如何解決循環(huán)依賴的問題o通過三級緩存o構造器方式的循環(huán)依賴?描述?A有構造器A(B),B有構造器B(A)?無法解決?BeanCurrentlyInCreationExceptiono類屬性的循環(huán)依賴?描述?基于引用傳遞?創(chuàng)建A,B對象,并不立即設置其屬性,統(tǒng)一放入一個Map中,設置屬性時從?如何為我們創(chuàng)建對象o1.通過構造器創(chuàng)建對象o2.通過靜態(tài)工廠創(chuàng)建o3.通過實例工廠創(chuàng)建?SpringMVCoSpringMVC的工作流程?1.用戶發(fā)送請求至前端控制器DispatcherServlet?2.DispatcherServlet收到請求調(diào)用HandlerMapping處理器映射器?3.處理器映射器找到具體的處理器(HandlerExecutionChain),返給DispatchServlet?4.DispatcherServlet調(diào)用HandlerAdapter處理器適配器?5.HandlerAdapter經(jīng)過適配調(diào)用具體的處理器(Controller,也叫后端控制器)。?6.Controller執(zhí)行完成返回ModelAndView?7.HandlerAdapter將controller執(zhí)行結(jié)果ModelAndView返回給DispatcherServlet?8.DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器?9.ViewReslover解析后返回具體View?10.DispatcherServlet根據(jù)View進行渲染視圖?11.DispatcherServlet響應用戶?注解面試點oComponent注解與Bean注解的區(qū)別?Component注解注解在類上,表示Spring將會為這個類創(chuàng)建bean?Bean注解寫在方法上,表示將該方法的返回值注冊為一個spring應用上下文?Mysqlo隔離級別?默認?可重復讀o定義?這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在并發(fā)讀取數(shù)據(jù)時,會看到同樣的數(shù)據(jù)行。o問題?幻讀?定義o幻讀指當用戶讀取某一范圍的數(shù)據(jù)行時,另一個事務又在該范圍內(nèi)插入了新行,當用戶再讀取該范圍的數(shù)據(jù)行時,?解決oo模式會發(fā)現(xiàn)有新的“幻影”行。InnoDB和Falcon存儲引擎通過多版本并發(fā)控制(MVCC,MultiversionConcurrencyControl)機制解決了該問題?快照讀?讀取的是記錄的可見版本?當前讀o實現(xiàn)技術是mvcc?防止幻讀?四種?ReadUncommitted(讀取未提交內(nèi)容)臟讀o啥也不做(查詢也不加鎖)?導致臟讀,不可重復讀,幻讀o問題?臟讀?定義o所謂的臟讀,其實就是讀到了別的事務回滾前的臟數(shù)據(jù)?。比如事務B執(zhí)行過程中修改了,這樣事務A就形成了臟o不可重復讀o幻讀?ReadCommitted(讀取提交內(nèi)容)大部分數(shù)據(jù)庫的默認隔離級別?一個事務只能看見已經(jīng)提交事務所做的改變。這種隔離級別也稱所謂的不可重復讀(NonrepeatableRead)o使用快照,避免臟讀,但避免不了不可重復讀,幻讀?問題o不可重復讀?當前事務先進行了一次數(shù)據(jù)讀取,然后再次讀取到的數(shù)據(jù)是別的事務修改成功的數(shù)據(jù),導致兩次讀取到的數(shù)據(jù)不匹配,也就照應了不可重復讀的語義?發(fā)生在update,delete中o幻讀?RepeatableRead(可重復讀)?定義o事務A在讀到一條數(shù)據(jù)之后,此時事務B對該數(shù)據(jù)進行了修改并提交,那么事務A再讀該數(shù)據(jù),讀到的還是原來的內(nèi)容。?問題o讀快照,不可修改,但避免不了新增刪除,所以會產(chǎn)生幻讀o幻讀?事務A首先根據(jù)條件索引得到N條數(shù)據(jù),然后事務B改變了這N條數(shù)據(jù)之外的M條或者增添了M條符合事務A搜索條件的數(shù)據(jù),導致事務A再次搜索發(fā)現(xiàn)有NM產(chǎn)生了幻讀。?insert中o解決?MVCC與Next-Key?Serializable(可串行化)?這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數(shù)據(jù)行上加上表級共享鎖。在這個級別,可能導致大量的超時現(xiàn)象和鎖競爭。o兩種事務隔離技術?mvcc?mvcc的優(yōu)勢是不加鎖,并發(fā)性高。缺點是不是實時數(shù)據(jù)。?next-key?next-key的優(yōu)勢是獲取實時數(shù)據(jù),但是需要加鎖?索引o數(shù)據(jù)結(jié)構?B+tree?支持范圍查詢?Hash?范圍查找不支持?創(chuàng)建時候可以選擇創(chuàng)建什么數(shù)據(jù)類型的索引o為何用B+tree?1.平衡二叉樹的話數(shù)據(jù)一多,樹高就高,增加IO次數(shù),不利于查詢?2.為何不用B樹o一張表最多可以建多少個索引?一個表最多16個索引,最大索引長度256字節(jié)o問題?雖然提高查詢效率,犧牲插入,刪除性能,會索引重排性較高,經(jīng)常不發(fā)生變更的,經(jīng)常查詢的字段可以建立索引o比如電話號碼?索引失效?SQL語句寫法oorounion?優(yōu)化查詢,調(diào)優(yōu)oexplain執(zhí)行計劃,查看各方面的數(shù)據(jù),或建索引oInnoDB表必須有主鍵??保證會有主鍵索引樹的存在(因為數(shù)據(jù)存放在主鍵索引樹上面),如果沒有mysql會自己生成一個rowid作為自增的主鍵主鍵索引o為什么推薦使用整型的自增主鍵??方便查找比較?新增數(shù)據(jù)的時候只需要在最后加入,不會大規(guī)模調(diào)整樹結(jié)構?MyISAM與InnoDBo區(qū)別一?MyISAM?表相關文件有三個o表數(shù)據(jù)與索引文件分開存儲?InnoDB?表相關文件有二個o索引與數(shù)據(jù)在同一個文件中(.idb)o區(qū)別二?InnoDB?行級鎖,支持事務,支持外鍵o適合高并發(fā),重負荷?MyISAM?表級鎖,不支持事務o一般小項目可以使用?鎖o全局鎖o表鎖o行鎖o間隙鎖o讀寫鎖oInnoDB如何加鎖?鎖機制o共享/排它鎖?共享鎖(ShareLocks,記為S鎖),讀取數(shù)據(jù)時加S鎖?共享鎖之間不互斥,簡記為:讀讀可以并行?排他鎖(eXclusiveLocks,記為X鎖),修改數(shù)據(jù)時加X鎖?排他鎖與任何鎖互斥,簡記為:寫讀,寫寫不可以并行o普通的select仍然可以讀到數(shù)據(jù)(快照讀)。o意向鎖?表級別的鎖?InnoDB為了支持多粒度鎖機制(multiplegranularitylocking),即允許行級鎖與表級鎖共存,而引入了意向鎖(intentionlocks)。意向鎖是指,未來的某個時刻,事務可能要加共享/排它鎖了,先提前聲明一個o記錄鎖?記錄鎖,它封鎖索引記錄o間隙鎖?它封鎖索引記錄中的間隔,或者第一條索引記錄之前的范圍,又或者最后一條索引記錄之后的范圍。依然是o臨鍵鎖?記錄鎖與間隙鎖的組合,它的封鎖范圍,既包含索引記錄,又包含索引區(qū)間。o插入意向鎖o自增鎖?自增鎖是一種特殊的表級別鎖(table-levellock),專門針對事務插入AUTO_INCREMENT類型的列。?MVCCo多版本并發(fā)控制oMVCC只在RC和RR兩個隔離級別下工作,其他兩個隔離級別都和MVCC不兼容o目的?為了實現(xiàn)數(shù)據(jù)庫的并發(fā)控制而設計的一種協(xié)議?Rediso單線程?有種情況嚴格意義上并不是單線程的?RDB時(命令:bgsave)o會Fork出一個子線程在后臺備份數(shù)據(jù),但還是可以操作rediso數(shù)據(jù)結(jié)構?String字符串?hash哈西?set集合?zset有序集合?SortSeto排行榜?list列表?還有三種特殊的?bitMap?Geo?HelperLogLog?5.0?StreamoRedlock(紅鎖)o為何這么快?Redis處理的這些請求都是計算型?純內(nèi)存操作?帶有I/O多路復用功能o持久化?1.RDB隔一段時間將內(nèi)存快照寫入硬盤?2.AOP?同時開啟AOP數(shù)據(jù)全一點但是速度慢,RDB速度快但數(shù)據(jù)不全,一般應急都先用RDB先恢復大部分,然后使用AOF補全剩下的數(shù)據(jù)o集群(高可用)?主備同步?啟動數(shù)據(jù)初始化?rewriteoINCR命令(分布式鎖)o分布式鎖框架RedissionoSub/PuboBitMapo常見問題?雙寫一致性面試o如何保證緩存與數(shù)據(jù)庫的雙寫一致性??1.讀的時候,先讀緩存,緩存沒有的話,就讀數(shù)據(jù)庫,然后取出數(shù)據(jù)后放入緩存,同時返回響應。?2.更新的時候,先更新數(shù)據(jù)庫,然后再刪除緩存。o最初的緩存不一致問題?描述先更新數(shù)據(jù)庫,再刪除緩存。如果刪除緩存失敗了,那么會導致數(shù)據(jù)庫中是新數(shù)據(jù),緩存中是舊數(shù)據(jù),數(shù)據(jù)就出現(xiàn)了不一致。?解決?先刪除緩存,再更新數(shù)據(jù)庫。如果數(shù)據(jù)庫更新失敗了,那么數(shù)據(jù)庫中是舊數(shù)據(jù),緩存中是空的,那么數(shù)據(jù)不會不一致。因為讀的時候緩存沒有,所以去讀了數(shù)據(jù)庫中的舊數(shù)據(jù),然后更o復雜的數(shù)據(jù)不一致問題分析?描述?數(shù)據(jù)發(fā)生了變更,先刪除了緩存,然后要去修改數(shù)據(jù)庫,此時還沒修改。一個請求過來,去讀緩存,發(fā)現(xiàn)緩存空了,去查詢數(shù)據(jù)庫,查到了修改前的舊數(shù)據(jù),放到了緩存中。隨后數(shù)據(jù)變更的程序完成了數(shù)據(jù)庫的修改。完了,數(shù)據(jù)庫和緩存中的數(shù)據(jù)不一樣了?出現(xiàn)?每秒并發(fā)讀是幾萬?解決?<左側(cè)灰色框>o簡單也可以說?雙刪操作處理?先刪除緩存,再刪除數(shù)據(jù)庫,過1s后再刪除緩存,防止刪除數(shù)據(jù)庫數(shù)據(jù)時,數(shù)據(jù)又寫入緩存?并發(fā)競爭?大Key?熱點Key?緩存擊穿?緩存擊穿?定義o緩存中的key一般設有過期時間,這個key在不停的扛著大并發(fā),如果KEY過期了,恰在這個時候,有大量的并發(fā)請求訪問這個key,則這些請求都會到達DB,導致DB瞬間壓力過大,DB般是指熱點數(shù)據(jù)。?解決o1.定時更新?后臺設置一個Job定時去刷新緩存的過期時間o2.檢查更新?將過期時間一并存入緩存,獲取到后,判斷是否小于一定時間,小于后,在更新過期時間,同1o3.分級緩存o4.加鎖o5.簡單的將熱點key設置成永不過期?緩存穿透?指有人用數(shù)據(jù)庫中不存在的某個key訪問,數(shù)據(jù)庫中沒有該key值,自然也不會寫入緩存中,所有該請求的查詢都會直接到數(shù)據(jù)庫。如果對該key的并發(fā)訪問量過大,則會壓垮數(shù)據(jù)庫。?解決o從請求出發(fā)?對查出為空的key,也在緩存中建立keyvalue對,只是過期時間設的短一點,比如5minetes。o從數(shù)據(jù)庫出發(fā)?采用過濾器,把所有數(shù)據(jù)庫中不可能存在的數(shù)據(jù)hash到一張大的bitmap中,如果key在數(shù)據(jù)庫中不存o布隆過濾器?對可能的key做一定的hash并存儲在Bitmap里,不存在就過濾掉,存在的就按正常流程走?緩存雪崩?定義o緩存雪崩,是指在某一個時間段,緩存集中過期失效。?解決o1.分散緩存過期時間?如果是熱點key的話就設置永不過期?致命的緩存雪崩,是緩存服務器某個節(jié)點宕機或斷網(wǎng)o對數(shù)據(jù)庫服務器造成的壓力是不可預知的,很有可能瞬間就把o使用場景?不適合?數(shù)據(jù)量太大、數(shù)據(jù)訪問頻率非常低的業(yè)務都不適合使用Redis。?例子?SortSeto排行榜?計數(shù)器/限速器o點贊;收藏數(shù);請求限流?好友關系o集合,并集,交集?簡單消息隊列o除了Redis自身的發(fā)布/訂閱模式,我們也可以利用List來實現(xiàn)一個隊列機制靠,但是步解耦?Session共享?訪問的uv統(tǒng)計oHelperLoglogo網(wǎng)絡層使用epoll解決高并發(fā)問題?RPC?Docker?微服務?SpringCloudoEureka?服務注冊流程oZuul?網(wǎng)關ofeighohytrix?熔斷器?判斷什么時候回熔斷oribbon?負載均衡?負載均衡的策略有多少種o輪詢o權重?Dubboo調(diào)用鏈路?Kafka?RabbitMQoVhost?內(nèi)部有屬于自己的channel,queue,exhange?作用?應用隔離o消息基于什么傳輸?信道?信道是建立在真實的TCP連接內(nèi)的虛擬連接,且每條TCP連接上的信道數(shù)量沒有限制?為何不基于TCP?TCP連接的創(chuàng)建和銷毀開銷較大,且并發(fā)數(shù)受系統(tǒng)資源限制,會造成性能瓶頸o消息如何分發(fā)?若該隊列至少有一個消費者訂閱,消息將以循環(huán)(round-robin)的方式發(fā)送o名詞?Publisher?routingKey?exchange?bindKey?queue?Customer?Nginxo單個IP訪問頻率過多拉黑設置o過濾IP方式?1.過濾單個IP?2.過濾地址段?3.過濾所有地址?4.只允許單個IPo負載均衡?輪詢?一致性Hash?加權?MongoDBo什么是MongoDB?MongoDB是一個文檔數(shù)據(jù)庫,提供好的性能,領先的非關系型數(shù)據(jù)庫。o存儲結(jié)構?BSON?什么是BSONo一種類似JSON的二進制的存儲格式?與JSON的區(qū)別o多了date類型與二進制的數(shù)據(jù)oNoSQL?NotOnlySQLo優(yōu)點?存儲結(jié)構易擴展?查詢速度更快oGridFS?存儲大量小文件功能?例如:存儲用戶頭像o一條文檔最大16Mo分片技術?分片是將數(shù)據(jù)水平切分到不同的物理節(jié)點。當應用數(shù)據(jù)越來越大的時候,數(shù)據(jù)量也會越來越大。當數(shù)據(jù)量增長時,單臺機器有可能無法存儲數(shù)據(jù)或可接受的讀取寫入吞吐量。利用分片技術可以添加更多的機器來應對數(shù)據(jù)量增加以及讀o支持的數(shù)據(jù)類型?String,Integer,Double,Boolean,Object,ObjectID,Arrays,Min/Maxkeys,Datetime,keys,RegularExpression等ObjectIDIDIDID、三個字節(jié)的增量計數(shù)器?設計模式o支持主鍵外鍵關系?默認是不支持的,需要硬編碼,實現(xiàn)難度較大且不夠直觀o基本命令?創(chuàng)建索引?db.collection.createIndex()?查詢?db.collectionName.find({key:value})?更新?db.collection.update({key,value},{$set:{key:value}})?刪除?db.collection.remove()o場景?1.隨時應對動態(tài)增加的數(shù)據(jù)項時可以優(yōu)先考慮使用NoSQL數(shù)據(jù)庫?2.在處理非結(jié)構化/半結(jié)構化的大數(shù)據(jù)時?3.在水平方向上進行擴展時MongoDB?MongoDB支持存儲過程,它是javascript寫的,保存在db.system.js表o事務o索引o一些查詢指令?大于小于?$gt$lt$gte$lte?數(shù)組包含?{$elemMatch:{$eq:key}}{$elemMatch:{$eq:{name:1}}}o不支持事務?更多的是在代碼層面去對事務有所實現(xiàn)o1.單例模式?懶漢?餓漢?雙重檢查?volatileo2.工廠模式o3.代理模式o4.策略模式o5.狀態(tài)模式o6.觀察者模式o7.模板模式o8.建造者模式o9.適配器模式o10.裝飾器模式?JVMo內(nèi)存泄漏?定義?該被釋放的對象沒有釋放,一直被某個或某些實例所持有卻不再被使C?解決?1.盡早釋放無用對象的引用好的辦法是使用臨時變量的時候,讓引用變量在推出活動域后自動設置為null,暗示垃圾收集器來收集該對存泄漏。?2.程序進行字符串處理時,盡量避免使用String,而應該使用ing?3.盡量少用靜態(tài)變量因為靜態(tài)變量是全局的,存在方法區(qū),GC不會回收?4.避免集中創(chuàng)建對象,尤其是大對象,如果可以的話盡量使用流操作?5.盡量運用對象池技術以提高系統(tǒng)性能?6.不要在經(jīng)常調(diào)用的方法中創(chuàng)建對象,尤其忌諱在循環(huán)中創(chuàng)建對象?7.優(yōu)化配置?達到一定質(zhì)變即會引起內(nèi)存溢出ojava程序運行較慢?GC為了能夠正確釋放對象,GC必須監(jiān)控每一個對象的運行狀態(tài),包括對象o垃圾回收?垃圾回收器?CMS?G1?回收機制?標記-清除算法?標記-整理算法?標記-復制算法?分代回收?年輕代?老年代?永久代/元空間o內(nèi)存模型?堆?棧?方法區(qū)?本地方法棧?程序計數(shù)器ojava類的加載機制?定義?1.代碼被編譯器編譯后生成的二進制字節(jié)流(.class)文件?2.JVM把Class文件加載到內(nèi)存,并進行驗證、準備、解析、初始化?3.形成被JVM直接使用的Java類型?流程?加載-》驗證-》準備-》解析-》初始化-》使用-》卸載?面試點o類的初始化時機?主動引用實例。即通過new的方式,new一?調(diào)用類的靜態(tài)變量(非final修飾的常量)和靜態(tài)方法?通過反射對類進行調(diào)用。?初始化某個類的子類,則父類也會被初始化?Java虛擬機啟動時,指定的main方法所在的化。?被動引用?子類調(diào)用父類的靜態(tài)變量,只有父類初始化,?通過數(shù)據(jù)定義引用類,不會觸發(fā)類的初始化?final常量不會觸發(fā)類的初始化,因為編譯階段o類的生命周期?開始當一個類被加載、連接、初始化后,它的生命周期?當這個類的class對象不再被引用,即類不可觸及時,Class對象就會結(jié)束生命周期。這個類在方法區(qū)的數(shù)據(jù)。?總結(jié)?所以,一個類結(jié)束生命周期,取決于代表它的?類的加載器?種類o啟動類加載器:BootStrapClassLoader?主要來加載java核心類庫,無法被直接調(diào)用o擴展類加載器:ExtensionClassLoader?用來加載jvm提供的擴展類庫中的java類o系統(tǒng)類加載器:SystemClassLoader?Java應用都由他來加載o用戶自定義ClassLoader,繼承抽象類ClassLoadero生命周期?執(zhí)行了System.exit()方法.?程序正常執(zhí)行結(jié)束。?程序在執(zhí)行過程中遇到了異?;蝈e誤而并未處理,導致異常終止。?由于依賴的操作系統(tǒng)出現(xiàn)錯誤,而導致Java虛擬機進程終止。o性能調(diào)優(yōu)?1.設置堆的最大最小值?-xms-xmx?2.調(diào)整年輕代老年代的比例?原則就是減少gcstwoSTWdSTWJava用程序的其他所有線程都被掛起(除了垃圾收集幫助器之外)。Java中一種全與JVM交互;這些現(xiàn)象多半是由于gc引起。oFullGC內(nèi)存泄漏排查?jasvism?dump?監(jiān)測配置自動dumpoCPU100%?Top命令查看進程資源消耗,然后是jdkbin目錄下的jstack命令查看堆棧信息找出對應出現(xiàn)問題的代碼位置o內(nèi)存溢出?內(nèi)存大小不夠;是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,出現(xiàn)outofmemory;比如申請了一個integer,但給它存了long才能存下的數(shù),?多線程o線程池?參數(shù)意義?核心線程數(shù)corePoolSizeo默認無線程,接到任務就常見,除非初始預創(chuàng)建,一個或者全部?最大線程數(shù)maximumPoolSizeo當workQueue滿后,線程總數(shù)小于maximunPoolSize時,創(chuàng)建線程處理任務?空閑時間keepAliveTimeo線程數(shù)大于corePoolSize時,無任務時線程終止?緩沖隊列workQueueoLinkedBlockingQueue?無界隊列?無界:小心內(nèi)存溢出oArrayBlockingQueue?運行機制?流程o1.默認無線程數(shù)(不初始創(chuàng)建),任務來了就創(chuàng)建新的線程o2.如果任務過來,線程池中的線程數(shù)小于corePoolSize,也會新增線程去處理任務;o3.當任務過來,線程池中的線程數(shù)等于corePoolSize時,workQueue未滿,會將任務新加入到queue中;o4.若任務過來,線程池中的線程數(shù)等于corePoolSize且workQueue中任務已滿,但線程數(shù)小于maximumPoolSize,還會創(chuàng)建新的線程去處理任務;o5.若任務過來,線程總數(shù)等于maximumPoolSize,workQueue已滿,則觸發(fā)拒絕策略;?優(yōu)先級ocorePoolSize>WorkQueue>MaximumPoolSize>拒絕策略?拒絕策略?拋異常?丟棄?重試?丟棄最早提交的任務?狀態(tài)?new?runnable就緒o等待cpu的調(diào)度?start()后?runningocpu調(diào)度后?blockingosleep()后,等待cpu的重新調(diào)度?deado執(zhí)行完畢?什么時候需要用到線程池?當線程創(chuàng)建與銷毀的時間大于線程任務執(zhí)行的時間o多線程一定是最快的嗎?不一定?redis是單線程的o因為IO操作時,常發(fā)生阻塞,這時多線程的強大就體現(xiàn)出來了?多線程會頻繁切換線程上下文o方法?join()?等待該線程先執(zhí)行完畢后才會往下執(zhí)行?wait()?釋放鎖?不阻塞?yiely()?讓出cpu的使用權,重新讓所有線程爭搶cpu執(zhí)行機會?sleep()?阻塞?不釋放鎖onotify()與notifyAll()有什么區(qū)別?IOoBIOoNIOo粘包拆包o多路復用oNettyo序列化?MQTT協(xié)議o介紹?輕量級基于代理的發(fā)布/訂閱的消息傳輸協(xié)議?TCP/IPo協(xié)議?QOS服務質(zhì)量?Qos=0o客戶端只發(fā)一次,無論是否收到,?導致只會消費一次消息?用于一些不是很重要的數(shù)據(jù)?Qos=1o客戶端發(fā)送一次消息,服務器給個回復,客戶端若沒收到,一直發(fā)送?導致會產(chǎn)生至少一個消息?比如狀態(tài)的變更,多收一次也沒關系?Qos=2o客戶端緩存消息,并發(fā)送給服務端,服務端收到并緩存消息,并給回復消息,客戶端收到后在發(fā)個消息給服務端,服務端收到后發(fā)送消息給訂閱端,并發(fā)消息給客戶端,客戶端把緩存的消息刪除,訂閱方收到消息后,緩存消息,給服務端發(fā)個收到消息,服務端又發(fā)個回復消息,訂閱方消費信息,刪除消息,并發(fā)給服務端一個完成的消息,服務端刪除消息,?確保一次傳輸o發(fā)布方與服務器有四次通信,一次消息發(fā)送,兩次消息的互相確認,一次服務器發(fā)給發(fā)布方完成的消息o訂閱方不一定要在線o第三方:EMQ服務器?共享訂閱?集合oHashMap?1.7?數(shù)組+鏈表oEntry?頭插?會產(chǎn)生什么問題o1.resize()擴容的時候,rehash重新插入時產(chǎn)生環(huán)形鏈表,調(diào)用get方法后發(fā)生死循環(huán)?擴容o條件?條件1:總size大于閾值(數(shù)組長度*加載因子)的時候?條件2:存放新值的時候與當前存放的數(shù)據(jù)發(fā)生Hash碰撞?1.8?數(shù)組+鏈表+紅黑樹o當鏈表長度大于8的時候,且數(shù)組長度大于64的時候,轉(zhuǎn)化。oNode?hash,key,value,next?尾插o解決環(huán)形鏈表,防止死循環(huán)?擴容o存放新值時,數(shù)組數(shù)據(jù)總數(shù)大于閾值,并不要求發(fā)生hash碰撞?擴容機制?新數(shù)組為原數(shù)據(jù)大小的兩倍,數(shù)據(jù)重新hash,重新放入數(shù)組中?多線程不安全?1.7o形成環(huán)形鏈表,發(fā)生死循環(huán),丟失數(shù)據(jù)?1.8o多個線程插入同一位置,導致數(shù)據(jù)丟失?疑問?為何1.8加入紅黑樹o默認使用二分法查詢紅黑樹,查詢效率更高?為何1.8改為尾插法o不會產(chǎn)生環(huán)形鏈表,解決死循環(huán)問題?為何擴容需要重新hasho獲取index值與數(shù)組長度有關?擴容為2的次冪?方便位運算?數(shù)據(jù)均勻分布?遍歷?1.entrySet()然后獲取迭代器遍歷?2.建一個BiCusumer的子類,用forEach()遍歷?3.用keySet()然后獲取key的迭代器遍歷?4.用values()進行值遍歷oHashTable?線程安全,性能不佳原因?所有方法都加了synchronized,使線程串行oConcurrentHashMap?1.8前?鎖分段技術(Segment)繼承了ReentrantLocko數(shù)據(jù)分為16份,分別加鎖?擴容:將每段Segment下的數(shù)組擴大至兩倍o優(yōu)點:快速定位和減少重排次數(shù)?1.8后?放棄了索鎖分段技術?CAS+Synchronized?CAS?比較和替換?不接受NullKey與NullValue?數(shù)組+鏈表+紅黑樹?安全失敗?采用安全失敗機制的集合容器,在遍歷時不是直接在集合內(nèi)容上訪問的,而是先復制原有集合內(nèi)容,在拷貝的集合上進行遍歷。?為何是線程安全的?Segment分段鎖,將數(shù)據(jù)分為16份,分別加鎖?CAS+Synchronized?類加載器?BootstrapClassLoadero所以可以使用Unsafe.getUnsafe()方法oArrayList?數(shù)組?查詢快(按角標查詢),刪除新增較慢?線程不安全oLinkedList?帶有頭結(jié)點與尾節(jié)點的雙向鏈表?插入方式有兩種,頭插與尾插?查詢比較慢,刪除新增比較快o快速失敗?java.util下的集合類ArrayList,HashMap等?在使用迭代器對集合對象進行遍歷的時候,如果A線程正在對集合進行遍歷,此時B線程對集合進行修改(增加、刪除、修改),或者A線程在遍歷過程中對集合進行修改,都會導致A線程拋出ConcurrentModificationException異常。?動態(tài)代理ocglib動態(tài)代理oJdk動態(tài)代理?Mybatiso#與¥的區(qū)別?#{}使用的預處理模式?${}使用的字符串替換的方式oDao與xml方法匹配?mapper標簽上的namespace指定o嵌套查詢與嵌套結(jié)果o插入數(shù)據(jù)獲取ID?1.設置useGeneratedKeys?2.selectKey?selectLAST_INSERT_ID();oSqlSession后續(xù)執(zhí)行?1.SqlSession中有executor?2.executor默認指向CachingExecutor,對象中有二級緩存,不走緩存就走delegate(裝飾器)BaseExecutor的query?3.BaseExecutor抽象類的query中存在一級緩存,若不走緩存,實際走的就是三個執(zhí)行器的doQuery函數(shù)o執(zhí)行器?SimpleExecutor?不重復使用預處理?select或者update?ReuseExecutor?select或者update?重復使用預處理o不關閉statement對象,放入map中重復使用?BatchExecutor?必須手動的刷新oexecutor.doFlushStatements(),簡稱批處理刷新o緩存?一級緩存?概要?緩存的命中條件o1.同一會話o2.方法名,類名必須一致(statementid必須一致)o3.RowBounds結(jié)果條數(shù)一致,結(jié)果范圍一致o4.sql一致,參數(shù)一致?如何保證數(shù)據(jù)一致性?會話級緩存o必須是同一會話才會命中?緩存Map的key值是什么oCacheKey?BaseExecutor的createCacheKey方法?參數(shù):statementID,offset,limit,sql,參數(shù)o決定命中條件?如何判斷兩個CacheKey相等?兩個cachekey對象的HashCode是否相等?判斷checksum是否相等oupdate時checkSum+=HashCode?判斷count是否相等oupdate時count++?逐一判斷以上五個元素是否相等?二級緩存?應用級別的緩存o隨應用的生命周期?緩存Map的key值是什么?默認是不開啟的o需要在xml中配置cache標簽?eviction緩存回收策略?1.軟引用?2.弱引用?3.先進先出o按照緩存進入的順序來移除它們?4.最少使用的o移除最長時間不被使用的對象o可以全局配置?cacheEnabled?共享緩存中數(shù)據(jù)進行序列化操作和反序列化操作o實現(xiàn)Serializable?共同?修改操作o清除緩存操作?因為不需要訪問緩存并會更改數(shù)據(jù)?緩存采用同一個緩存基類,二級緩存實現(xiàn)比較復雜,一級比較簡單;所以二級緩存比一級緩存復雜的多o動態(tài)SQL?where,if,foreach,set,wheno表中字段與對象屬性名不一致?1.sql語句中使用as轉(zhuǎn)換?2.xml中使用resultMap的property,column屬性建立映射關系?3.如果是駝峰命名與下劃線形式,可以使用全局配置mapUnderscoreToCamelCase=true來配置o批量插入如何實現(xiàn)?Session與CookieoCookie?瀏覽器禁用后Session不可使用,可使用URL重寫:URL拿到就可以登錄?客戶端?最大為4K?大部分瀏覽器最大可以設置20個Cookieo都是會話跟蹤技術oSession?服務端?session的實現(xiàn)依賴于Cookie,SessionId存在Cookie中?Jenkins?K8S?SpringBoot?ZooKeepero選舉機制?Git?秒殺系統(tǒng)o限流(攔截請求)o客戶的惡意下單?鎖osynchronized?底層實現(xiàn)原理?方法oACC_SYNCHRONIZED?執(zhí)行線程需要先獲取到monitor?代碼塊omonitorenteromonitorexito程序計數(shù)器?enter加1,exit或者異常減一?兩者區(qū)別o方法:設置ACC_SYNCHRONIZED實現(xiàn)?jvm層面?鎖膨脹(鎖升級)?過程o無鎖o偏向鎖?利用了對象頭中的ThreadId不會釋放?比較對象頭中的ThreadID是否與自身一致,一致則變?yōu)闊o鎖狀態(tài),不一致則判斷對方是否存活,存活則升級為輕量級鎖,死亡則變?yōu)闊o鎖狀態(tài)?JVM參數(shù)?偏向鎖是默認開啟的,而且開始時間一般是比應用程序啟動慢幾秒,如果不想有這個延遲,那么可以使用-XX:BiasedLockingStartUpDelay=0;ovolatile?不想要偏向鎖,那么可以通過-XX:-UseBiasedLocking=false來設置;o輕量級鎖?自旋獲取資源o重量級鎖?原因o發(fā)生了資源的爭搶?缺點o升級不可逆?特征保證?可見性o內(nèi)存強制刷新?可重入性o計數(shù)器?原子性o單一線程持有?有序性oLock?底層實現(xiàn)原理?jdk層面?ReentrantReadWriteLock?ReadLock?WriteLock?ReentrantLock?FairSync?NonfairSyncoCAS?2?如何保證不同線程可見性?被volatile修飾的變量,在發(fā)生寫操作時,會發(fā)出一個匯編指令,這個指令會觸發(fā)mesi協(xié)議,會存在有一個總線嗅探的東西,這個總線嗅探會讓cpu不斷檢測主內(nèi)存中該變量的值,一旦有變化,其他的cpu會立即將該變量從自己的緩存中清除,再去主內(nèi)存中去重新獲取這個值?緩存行鎖定?在store之前l(fā)ock,write回主內(nèi)存之后unlock,解決了并發(fā)寫問題?一個線程改變值后,另一個線程立刻知曉?作用?1.保證內(nèi)存可見性o保證修改了volatile的值會立即更新到主存,其他的線程操作時都會獲取新值?2.防止指令重排?volatile僅能實現(xiàn)變量的修改可見性,不能保證原子性?比如說,對基本數(shù)據(jù)的操作,都分為三步,從自己線程緩存中拿出,操作,再寫入緩存,再寫入主存?然后,如果說取出數(shù)據(jù)后,cpu切出,另一個線程對該值操作,并成功寫入主存,切回來后,操作完重新寫入。o鎖的分類?1?樂觀鎖o拿不到鎖繼續(xù)執(zhí)行?CAS?悲觀鎖o拿不到鎖一直嘗試去拿鎖?常見的線程鎖?樂觀鎖策略?公平鎖?非公平鎖?3?重入鎖?不可重入鎖?死鎖?條件o1.互斥?都需要等待其他線程釋放鎖o2.不可搶占o3.占有且等待o4.循環(huán)等待?形成等待環(huán)路o2.不可搶占?簡介o線程A拿著鎖等待B釋放,線程B拿著鎖等待B釋放?破壞o不會破壞1o破壞2,線程A等待另一個資源,一段時間主動釋放持有資源o3,每個線程一次性獲取所有資源o破壞2,線程A等待另一個資源,一段時間主動釋放持有資源o3,每個線程一次性獲取所有資源oCAS(無鎖)?CAS的作用是比較當前工作內(nèi)存中的值和主內(nèi)存中的值,如果相同則執(zhí)行規(guī)定操作,否則繼續(xù)比較直到主內(nèi)存和工作內(nèi)存中的值一致為止?存在的問題?ABA問題o解釋?因為CAS會檢查舊值有沒有變化,這里存在這樣一個AB,然后再ACAS發(fā)現(xiàn)舊值并沒有變化依o解決?可以沿襲數(shù)據(jù)庫中常用的樂觀鎖方式,添加一個版本號?自旋時間過長o使用CAS時非阻塞同步,也就是說不會將線程掛起,會自旋 (無非就是一個死循環(huán))進行下一次嘗試,如果這里自旋時間過長對性能是很大的消耗。?只能保證一個共享變量的原子操作o解釋o解決方案?利用對象整合多個共享變量,即一個類中的成員變量就是這幾個共享變量。然后將這個對象做CAS操作就可來保證引用對象之間的原子性。oCASvsSynchronized?主要的區(qū)別?CAS并不是武斷的間線程掛起,當CAS操作失敗后會進行一定的嘗時的掛起喚醒的操作,因此也叫做非阻塞同步。o當對一個共享變量執(zhí)行操作時CAS能保證其原子性,如果對多個共享變量進行操作,CAS就不能保證其原子性。?元老級的Synchronized(未優(yōu)化前)最主要的問題是:在存在線程競爭的情況下會出現(xiàn)線程阻塞和喚醒鎖帶來的性能問題,因為這是一種互斥同步(阻塞同步)。o操作系統(tǒng)的臨界區(qū)機制?牽扯到用戶態(tài)與內(nèi)核態(tài)之間的轉(zhuǎn)變oSynchronized與Lock區(qū)別?1.Synchronized是jvm的底層實現(xiàn),而Lock是jdk的一個接口,提供了各I?2.Synchronzied會自動釋放鎖,Lock需要手動unlock?3.Synchronized會自動中斷,而Lock可以中斷也可以不中斷?4.Synchronized可以鎖方法與代碼塊,lock只能鎖代碼塊?5.Synchronized是非公平鎖,ReentrantLock可以指定是否為公平鎖?6.Synchronized不能知道線程有沒有拿到鎖,而Lock能?7.Lock可以使用讀鎖提高線程讀效率?劣勢:鎖的升級不可逆oThreadLocal?ThreadLocal是一個本地線程副本變量工具類?線程隔離特性?什么時候用?將私有線程和該線程存放的副本對象做一個映射,各個線程之間的變特別適用于各個線程依賴不同的變量值完成操作的場景。?ThreadLocalMap?ThreadLocalMap是ThreadLocal的內(nèi)部類,沒有實現(xiàn)Map接口,?Entryokey只能是ThreadLocal對象?Hash沖突怎么解決o和HashMap的最大的不同在于,ThreadLocalMap結(jié)構非常簡單,沒有next引用,也就是說ThreadLocalMap中解決Hash沖突的方式并非鏈表的方式,而是采用線性探測的方式?線性探測o初始key的hashcode值確定元素在table數(shù)組中的位置,如果發(fā)現(xiàn)這個位置上已經(jīng)有其他key值的元素被占用,則利用固定的算法尋找一定步長的下個位置,依次判斷,直至找到能夠?內(nèi)存泄漏?ThreadLocal在沒有外部對象強引用時,發(fā)生GC時弱引用Key會被回收,而Value不會回收,如果創(chuàng)建ThreadLocal的線程一直持續(xù)運行,那么這個Entry對象中的value就有可能一直得不到回收,發(fā)生內(nèi)存泄o解決remove方法,將Entry節(jié)點和Map的引用關系移除,這樣整個Entry對象在GCRoots分析后就變成不?Linuxo1.查詢進程ps-ef|grepxxxo2.動態(tài)查看日志tail-fxxx.logo3.查看所有用戶?cat/etc/passwd?條目:admin:x:1000:1000:centos-loumt:/home/admin:/bin/bash?解釋:用戶名:用戶密碼(文件不安全,移至/etc/shadow中):用戶ID:組ID(與/etc/group有關):注釋:家目錄:可以看成是否可以登錄,/sbin/nologin就是不可以登錄o4.tar包?taro5.從某個文件內(nèi)查詢某個內(nèi)容?grep"內(nèi)容"文件路徑?分布式o分布式鎖?1.Redis的RedLock?zk鎖o分布式事務一致性?Java基礎o三大特性?封裝?面向?qū)ο蟮姆庋b即是將一個對象的屬性與行為定義在一個類中,其中私有不公開的用private去修飾,公開的用public修飾,也提供修改屬性的set與獲取屬性的get?繼承?可以使用一個基礎類來定義一個更具體的類,用關鍵字extends該基礎類,可以修改基礎方法,新增屬性與行為,提供代碼的重用性,也體現(xiàn)了該語言的擴展性?多態(tài)?編譯時與運行時類型不一致就是多態(tài)性,多態(tài)增強了軟件的靈活性和o同步異步?相對于服務器而言?數(shù)據(jù)結(jié)構?觸發(fā)IO時,同步等待其返回,數(shù)據(jù)返回后才繼續(xù)往下,異步是不等待返回值直接往下走,內(nèi)核通知后結(jié)果返回o阻塞非阻塞?相對于客戶端而言?簡單理解為需要做一件事能不能立即得到返回應答,如果不能立即獲得返回,需要等待,那就阻塞了,否則就可以理解為非阻塞。oservletofiltero內(nèi)存模型(JMM)oJDK與JRE的區(qū)別?JRE是Java基礎運行環(huán)境,包含JVM與Java核心類庫?JDK是Java開發(fā)環(huán)境,包含除JRE以外的Java開發(fā)工具,如Javac.exe,Jar.exe,Java.exeoJVM是Java虛擬機,是Java能夠跨平臺的核心o序列化與反序列化有什么作用?轉(zhuǎn)儲?兩種介質(zhì)之間的傳輸,比如內(nèi)存到數(shù)據(jù)庫,比如對象在網(wǎng)絡上的傳輸?序列化:對象轉(zhuǎn)為有序字節(jié)流?反序列化:字節(jié)流轉(zhuǎn)為對象?Java工具oJMeter?多線程測試工具oPostManoJava反編譯?javap-v*.class?緩存與數(shù)據(jù)庫在高并發(fā)中不一致解決方案如下:更新數(shù)據(jù)的時候,根據(jù)數(shù)據(jù)的唯一標識,將操作路由之后,發(fā)送到一個jvm內(nèi)部隊列中。讀取數(shù)據(jù)的時候,如果發(fā)現(xiàn)數(shù)據(jù)不在緩存中,那么將重新讀取數(shù)據(jù)+更新緩存的操作,根據(jù)唯一標識路由之后,也發(fā)送同一個jvm內(nèi)部隊列中。一個隊列對應一個工作線程,每個工作線程串行拿到對應的操作,然后一條一條的執(zhí)行。這樣

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論