隨筆

多線程

  • 死鎖的條件,如何打破,如何避免
    四個(gè)條件:
    1.互斥 同一資源在同一時(shí)間只能由一個(gè)進(jìn)程占用,其他進(jìn)程只能等待釋放資源。
    2.占用且請求 進(jìn)程獨(dú)占資源A同時(shí)申請請求資源B
    3.不可剝奪 進(jìn)程在獨(dú)占資源時(shí)不可被其他進(jìn)程強(qiáng)制奪走
    4.循環(huán)等待 進(jìn)程間形成循環(huán)等待環(huán)
    打破死鎖從以上條件入手:
    互斥是資源固有的特性,不可打破。
    破壞占用且請求:進(jìn)程在請求資源時(shí)將所有需要獨(dú)占的資源一次性占用?;蛘咦陨聿徽加觅Y源只是請求新的資源。
    破壞不可剝奪:進(jìn)程在請求其他進(jìn)程占用的資源時(shí),等待期間釋放自身占用的資源。
    破壞循環(huán)等待:將所有資源進(jìn)行順序編號,資源稀缺的給大的編號,進(jìn)程只能先請求小的資源進(jìn)而申請大的。
    避免死鎖:
    不限制每個(gè)進(jìn)程申請資源的命令,而是動(dòng)態(tài)的在進(jìn)程申請資源命令時(shí)動(dòng)態(tài)的進(jìn)行檢查,通過檢查結(jié)果來是否分配資源。實(shí)現(xiàn)為:銀行家算法。具體算法不詳訴。

  • JMM JVM的共享內(nèi)存模型

  • 如何創(chuàng)建線程池,隊(duì)列都有哪些?拒絕策略都有哪些?任務(wù)過多時(shí)都是如何處理的
    創(chuàng)建線程池四種方式
    1.newFiexedThreadPool() 創(chuàng)建固定數(shù)量線程的線程池。
    2.newCachedThreadPool()創(chuàng)建可緩存的線程池
    3.newSingleThreadExecutor()創(chuàng)建單線程的executor
    4.newScheduledThreadPool()創(chuàng)建支持定時(shí)及周期性執(zhí)行的線程池
    隊(duì)列有三種:
    1.有界緩沖隊(duì)列ArrayBlockingQueue 任務(wù)過多時(shí),超過corePoolSize則進(jìn)入定長隊(duì)列,隊(duì)列滿時(shí)啟動(dòng)新線程直到maximumPoolSizes,執(zhí)行拒絕策略
    2.無界緩沖隊(duì)列LinkedBlockingQueue,超過corePoolSize則進(jìn)入無界隊(duì)列,maximumPoolSizes無效,這也是為何阿里規(guī)約限制使用Executor的原因。
    3.無緩沖等待隊(duì)列SynchronousQueue,不存儲(chǔ)直接交給消費(fèi)者,超過corePoolSize直接新啟動(dòng)線程,達(dá)到maximumPoolSizes則等待。
    拒絕策略有四種:
    1.丟失拋異常AbortPolicy
    2.丟棄不拋異常DiscardPolicy
    3.丟棄最前邊的任務(wù)執(zhí)行最新的任務(wù)DiscardOldestPolicy
    4.由調(diào)用線程執(zhí)行該任務(wù)CallerRunsPolicy

  • 線程生命周期
    新建(New)、就緒(Runnable)、運(yùn)行(Running)、阻塞(Blocked)和死亡(Dead)五種狀態(tài)
    當(dāng)創(chuàng)建Thread類的一個(gè)實(shí)例(對象)時(shí) t=new Thread(),此線程進(jìn)入新建狀態(tài)(未被啟動(dòng))。
    t.start().線程已經(jīng)被啟動(dòng),正在等待被分配給CPU時(shí)間片,也就是說此時(shí)線程正在就緒隊(duì)列中排隊(duì)等候得到CPU資源
    t.run()運(yùn)行

  • synchronized原理
    由jvm字節(jié)碼中可以看到ACC_SYNCHRONIZED,對同步塊使用了monitorenter和monitorexit指令,隱式的實(shí)現(xiàn)了lock,unlock。

  • jdk對synchronized做了哪些優(yōu)化
    jdk1.6對鎖做了優(yōu)化,在對象頭中包含了輕量鎖,重量鎖,偏向鎖。
    synchronized使用的鎖對象是存儲(chǔ)在Java對象頭里。它是輕量級鎖和偏向鎖的關(guān)鍵,偏向線程ID指向自己
    https://www.cnblogs.com/wuzhenzhao/p/10250801.html

  • ReentrantLock
    ReentrantLock是可重入的獨(dú)占鎖。比起synchronized功能更加豐富,支持公平鎖實(shí)現(xiàn),支持中斷響應(yīng)以及限時(shí)等待等等。可以配合一個(gè)或多個(gè)Condition條件方便的實(shí)現(xiàn)等待通知機(jī)制。

  • CAS、ABA問題
    CAS樂觀鎖操作,Compare and Swap 這是一個(gè)重量鎖的實(shí)現(xiàn)。
    ABA A改為B又改為A,這種問題使用版本號控制解決。

  • J.U.C java.util.concurrent。
    CompareAndSet 利用Unsafe類的JNI方法實(shí)現(xiàn)CAS,無鎖算法
    https://segmentfault.com/a/1190000015558984

基礎(chǔ)

  • ArrayList和LinkedList
    ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList是基于鏈表結(jié)構(gòu)。
    modCount是ArrayList中的一個(gè)成員變量。
  • 什么是fail—fast?
    快速失效系統(tǒng),先考慮異常情況,一旦發(fā)現(xiàn)異常立馬終止。業(yè)務(wù)設(shè)計(jì)接口檢測拋出異常就是這個(gè)東西。還有一種是指Java集合的一種錯(cuò)誤檢測機(jī)制,當(dāng)多個(gè)線程對部分集合進(jìn)行結(jié)構(gòu)上的改變的操作時(shí),有可能會(huì)產(chǎn)生fail-fast機(jī)制,這個(gè)時(shí)候就會(huì)拋出ConcurrentModificationException。
  • HashMap的put、擴(kuò)容原理,1.7和1.8的數(shù)據(jù)結(jié)構(gòu)
put

擴(kuò)容

1.7 hashmap 數(shù)組+鏈表
1.8 數(shù)組+鏈表+紅黑樹 鏈表長度大于8轉(zhuǎn)為紅黑樹


image.png

image.png

image.png

為何鏈表長度為8,hashcode之后的頻率遵循泊松分布,泊松分布對照表中鏈表為8的概率非常小。

  • HashMap并發(fā)問題
    主要出在擴(kuò)容階段,當(dāng)兩個(gè)線程同時(shí)resize時(shí)鏈表會(huì)成環(huán)狀鏈表,當(dāng)調(diào)用get時(shí)會(huì)陷入死循環(huán)。
  • TCP粘包,為什么出現(xiàn),如何解決?
    tcp為提高性能,發(fā)送端會(huì)將需要發(fā)送的數(shù)據(jù)發(fā)送到緩沖區(qū),等待緩沖區(qū)滿了之后,再將緩沖中的數(shù)據(jù)發(fā)送到接收方。同理,接收方也有緩沖區(qū)這樣的機(jī)制,來接收數(shù)據(jù)。
    約定數(shù)據(jù)包長度這樣可以清晰的獲取到我們需要的數(shù)據(jù);使用分隔符;每個(gè)數(shù)據(jù)包的開頭利用2個(gè)或者4個(gè)字節(jié)填充整個(gè)數(shù)據(jù)包的長度
  • TCP如何實(shí)現(xiàn)消息可靠性、滑動(dòng)窗口
    TCP確認(rèn)重傳機(jī)制,滑動(dòng)窗口為TCP不是每一段報(bào)文都進(jìn)行ACK,如果接收方期望的報(bào)文一直沒來,其他的報(bào)文則會(huì)放入滑動(dòng)窗口緩沖區(qū)。
  • TCP三次握手四次揮手
    1.客戶端首先要SYN=1,表示要?jiǎng)?chuàng)建連接,
    2.服務(wù)端接收到后,要告訴客戶端:我接受到了!所以加個(gè)ACK=1,就變成了ACK=1,SYN=1
    3.理論上這時(shí)就創(chuàng)建連接成功了,但是要防止一個(gè)意外(重試多次建立連接問題),所以客戶端要再發(fā)一個(gè)消息給服務(wù)端確認(rèn)一下,這時(shí)只需要ACK=1就行了。
    在四次揮手時(shí),
    1.首先客戶端請求關(guān)閉客戶端到服務(wù)端方向的連接,這時(shí)客戶端就要發(fā)送一個(gè)FIN=1,表示要關(guān)閉一個(gè)方向的連接
    2.服務(wù)端接收到后是需要確認(rèn)一下的,所以返回了一個(gè)ACK=1
    3.這時(shí)只關(guān)閉了一個(gè)方向,另一個(gè)方向也需要關(guān)閉,所以服務(wù)端也向客戶端發(fā)了一個(gè)FIN=1 ACK=1
    4.客戶端接收到后發(fā)送ACK=1,表示接受成功
  • 事務(wù)的隔離級別、mysql和oracle默認(rèn)是什么,都解決了什么問題
    read uncommitted 未提交讀 所有事務(wù)都可以看到?jīng)]有提交事務(wù)的數(shù)據(jù)。
    read committed 提交讀 事務(wù)成功提交后才可以被查詢到。
    repeatable 重復(fù)讀 同一個(gè)事務(wù)多個(gè)實(shí)例讀取數(shù)據(jù)時(shí),可能將未提交的記錄查詢出來,而出現(xiàn)幻讀。mysql默認(rèn)級別
    Serializable可串行化 強(qiáng)制的進(jìn)行排序,在每個(gè)讀讀數(shù)據(jù)行上添加共享鎖。會(huì)導(dǎo)致大量超時(shí)現(xiàn)象和鎖競爭。
  • 事務(wù)的特性
    ACID-原子性 一致性 隔離性 持久性
  • 快照讀和當(dāng)前讀
    快照讀 即讀取數(shù)據(jù)的可見版本,數(shù)據(jù)可能是歷史數(shù)據(jù)。主要通過MVCC(多版本控制)和undo log 來實(shí)現(xiàn),優(yōu)勢是不加鎖,并發(fā)性高。缺點(diǎn)是不是實(shí)時(shí)數(shù)據(jù)
    當(dāng)前讀 是通過加record lock(記錄鎖)和gap lock(間隙鎖)來實(shí)現(xiàn)的 (select ... for update)
    InnoDB為每行記錄添加了一個(gè)事務(wù)ID,每當(dāng)修改數(shù)據(jù)時(shí),將當(dāng)事務(wù)ID寫入。
  • 樂觀鎖、悲觀鎖、間隙鎖、行鎖、表鎖的使用場景
    樂觀鎖 讀的時(shí)候不加鎖,只有在更新的時(shí)候判斷版本號進(jìn)行更新
    悲觀鎖 讀的時(shí)候就加上鎖
    間隙鎖 當(dāng)我們用范圍條件檢索數(shù)據(jù),并請求共享或排他鎖時(shí),InnoDB會(huì)給符合范圍條件的已有數(shù)據(jù)記錄的索引項(xiàng)加鎖;對于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做“間隙(GAP)”。InnoDB也會(huì)對這個(gè)“間隙”加鎖
    行鎖 鎖顆粒度為行級
    表鎖 表共享讀鎖(Table Read Lock)和表獨(dú)占寫鎖(Table Write Lock)
    B數(shù) B+樹、聚簇索引和非聚簇索引
    B數(shù)為多叉數(shù),和平衡二叉樹不同的是搜索路徑不止兩條,同樣遵循左小右大原則
    B+樹 B+的搜索與B-樹也基本相同,區(qū)別是B+樹只有達(dá)到葉子結(jié)點(diǎn)才命中(B-樹可以在
    非葉子結(jié)點(diǎn)命中)
    B+的特性:
    1.所有關(guān)鍵字都出現(xiàn)在葉子結(jié)點(diǎn)的鏈表中(稠密索引),且鏈表中的關(guān)鍵字恰好
    是有序的;
    2.不可能在非葉子結(jié)點(diǎn)命中;
    3.非葉子結(jié)點(diǎn)相當(dāng)于是葉子結(jié)點(diǎn)的索引(稀疏索引),葉子結(jié)點(diǎn)相當(dāng)于是存儲(chǔ)
    (關(guān)鍵字)數(shù)據(jù)的數(shù)據(jù)層;
    4.更適合文件索引系統(tǒng);
    B*樹:在B+樹基礎(chǔ)上,為非葉子結(jié)點(diǎn)也增加鏈表指針,將結(jié)點(diǎn)的最低利用率
    從1/2提高到2/3;
    聚簇索引 innodb中根據(jù)主鍵生成B+樹,葉子節(jié)點(diǎn)存儲(chǔ)的是行記錄數(shù)據(jù),也將聚集索引的葉子節(jié)點(diǎn)稱為數(shù)據(jù)頁。
    非聚簇索引  在聚簇索引之上創(chuàng)建的索引稱之為輔助索引,輔助索引訪問數(shù)據(jù)總是需要二次查找。輔助索引葉子節(jié)點(diǎn)存儲(chǔ)的不再是行的物理位置,而是主鍵值
     MyISAM索引文件和數(shù)據(jù)文件是分離的,索引文件僅保存數(shù)據(jù)記錄的地址。而在InnoDB中,表數(shù)據(jù)文件本身就是按B+Tree組織的一個(gè)索引結(jié)構(gòu)
  • mvcc多版本并發(fā)控制
    在每一行數(shù)據(jù)會(huì)隱藏式創(chuàng)建兩個(gè)列。行創(chuàng)建時(shí)的版本號和刪除時(shí)的版本號。
    每行數(shù)據(jù)都存在一個(gè)版本,每次數(shù)據(jù)更新時(shí)都更新該版本。修改時(shí)Copy出當(dāng)前版本隨意修改,各個(gè)事務(wù)之間無干擾。保存時(shí)比較版本號,如果成功(commit),則覆蓋原記錄;失敗則放棄copy(rollback)
  • redolog、undolog、binlog
    redolog 重做日志 是每個(gè)數(shù)據(jù)在更新時(shí)將更新記錄到redo日志中,定時(shí)刷入磁盤。
    和undolo同屬于事務(wù)日志,不同的是redo是前滾日志。保證了事務(wù)的持久性
    undolog 回滾日志,保存了事務(wù)數(shù)據(jù)更新前一個(gè)數(shù)據(jù),保證了事務(wù)的原子性。
    binlog 歸檔日志,主要用于主從復(fù)制,記錄了相關(guān)sql記錄。
  • 索引失效的場景
    1.有 or 的
    2.like 前綴%
    3.字符串值為數(shù)字,不加單引號的
    4.聯(lián)合索引不按順序
    5.不要對索引列進(jìn)行聚合函數(shù)操作
  • Redis數(shù)據(jù)類型,底層數(shù)據(jù)結(jié)構(gòu)
    string hash list set zset bitmap hyteloglog geo stream
  • 緩存穿透、緩存擊穿 緩存雪崩
    查詢一個(gè)不存在的key ,緩存null,布隆過濾器
    key 過期后大量的請求打在db上,db查詢加鎖及限流
    緩存雪崩 大量的key同一時(shí)間過期,隨機(jī)時(shí)間
  • mysql和redis 一致性問題
    給緩存設(shè)置合理的過期時(shí)間,或者進(jìn)行補(bǔ)償。或者使用阿里開源canal ,對mysql的binlog進(jìn)行訂閱,對redis在進(jìn)行處理。

spring

  • IOC和AOP的理解及原理
    IOC就是典型的工廠模式,由sessionFactory去注入實(shí)例。通過IOC容器可以將依賴的對象創(chuàng)建等交給spring去處理
    AOP就是面向切面編程,分離關(guān)注點(diǎn)。動(dòng)態(tài)代理和靜態(tài)織入
  • Bean的生命周期
    大概分為9步:
    1,實(shí)例化bean對象
    2.設(shè)置對象屬性
    3.如果bean實(shí)現(xiàn)了beanNameAware則將會(huì)將bean的ID進(jìn)行傳遞
    4.如果bean實(shí)現(xiàn)了beanfatoryAware則傳遞工廠
    5.調(diào)用bean的前置處理器
    6,bean的初始化
    7.調(diào)用bean的后置處理器
    8.使用bean
    9.銷毀bean
  • 自動(dòng)注入方式有哪些,兩個(gè)注解的區(qū)別
    @Autowired 基于bytype的注入,默認(rèn)對象必須是存在的,是spring提供的注解
    @Resource 基于byname的注入,默認(rèn)對象可為null 是J2EE提供的注解
    @Inject 先基于name查找沒有則使用類型查找
  • MVC流程


    image.png
  • 分布式事務(wù)怎么做的
    1.XA saga TCC seata
    XA 兩階段提交 性能有問題 并不是所有資源都支持XA協(xié)議
    saga 基于應(yīng)用共享事務(wù)記錄執(zhí)行軌跡;然后通過異步重試確保交易最終一致
    TCC 的特點(diǎn)在于業(yè)務(wù)資源檢查與加鎖,一階段進(jìn)行校驗(yàn),資源鎖定,如果第一階段都成功,二階段對鎖定資源進(jìn)行交易邏輯,否則,對鎖定資源進(jìn)行釋放。應(yīng)用實(shí)施成本較高。
    Seata架構(gòu)的亮點(diǎn)主要有幾個(gè):
    應(yīng)用層基于SQL解析實(shí)現(xiàn)了自動(dòng)補(bǔ)償,從而最大程度的降低業(yè)務(wù)侵入性;
    將分布式事務(wù)中TC(事務(wù)協(xié)調(diào)者)獨(dú)立部署,負(fù)責(zé)事務(wù)的注冊、回滾;
    通過全局鎖實(shí)現(xiàn)了寫隔離與讀隔離。
  • CAP、BASE理論
    CAP原則又稱CAP定理,指的是在一個(gè)分布式系統(tǒng)中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區(qū)容錯(cuò)性),三者不可得兼。zk是CP,eurka是AP.
    BASE是對CAP中一致性和可用性權(quán)衡的結(jié)果,其來源于對大規(guī)模互聯(lián)網(wǎng)系統(tǒng)分布式實(shí)踐的結(jié)論,是基于CAP定理逐步演化而來的,其核心思想是即使無法做到強(qiáng)一致性(Strong consistency),但每個(gè)應(yīng)用都可以根據(jù)自身的業(yè)務(wù)特點(diǎn),采用適當(dāng)?shù)姆绞絹硎瓜到y(tǒng)達(dá)到最終一致性(Eventual consistency)。
  • 高并發(fā)之服務(wù)降級和服務(wù)熔斷
    犧牲局部,保全整體的措施
  • 令牌桶、漏桶、滑動(dòng)窗口算法
    控制數(shù)據(jù)注入到網(wǎng)絡(luò)的速率,平滑網(wǎng)絡(luò)上的突發(fā)流量
  • 分布式id如何生成
    1.主鍵自增
    2.redis
    3.雪花算法
    4,leaf 緩存一個(gè)號段 雙buffer

JVM

  • 共享內(nèi)存區(qū)
    程序計(jì)數(shù)器
    Java虛擬機(jī)棧
    本地方法棧
    Java堆
    方法區(qū)
  • 幾種OOM


    image.png
  • 類加載機(jī)制
    JVM類加載機(jī)制分為五個(gè)部分:加載,驗(yàn)證,準(zhǔn)備,解析,初始化
  • 雙親委派機(jī)制
    如果一個(gè)類加載器收到了類加載器的請求.它首先不會(huì)自己去嘗試加載這個(gè)類.而是把這個(gè)請求委派給父加載器去完成.每個(gè)層次的類加載器都是如此.因此所有的加載請求最終都會(huì)傳送到Bootstrap類加載器(啟動(dòng)類加載器)中.只有父類加載反饋?zhàn)约簾o法加載這個(gè)請求(它的搜索范圍中沒有找到所需的類)時(shí).子加載器才會(huì)嘗試自己去加載。
    雙親委派模型的優(yōu)點(diǎn):java類隨著它的加載器一起具備了一種帶有優(yōu)先級的層次關(guān)系.
  • 新生代默認(rèn)多少次晉升老年代
    MaxTenuringThreshold 默認(rèn)為15,并不是指15次gc晉升,有動(dòng)態(tài)閾值調(diào)整
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容