六戰(zhàn)六捷之我的面試心得
自我介紹
一般面試官都會(huì)讓你自我介紹,我覺(jué)得自我介紹主要是有兩個(gè)作用
第一個(gè)是給面試官留出時(shí)間來(lái)看你的簡(jiǎn)歷,他好想一下問(wèn)你什么問(wèn)題比較好
第二個(gè)就是面試官想聽(tīng)一下你的表達(dá)是否存在問(wèn)題
一般而言建議自我介紹最好提前寫(xiě)好,先過(guò)幾遍,讓腦袋里面有一個(gè)大概。時(shí)間就控制在三分鐘左右就好了,太長(zhǎng)背不了,太短面試官簡(jiǎn)歷沒(méi)看完。
附上我常用的自我介紹給大家參考
你好,我叫張三,先后呆過(guò)X家公司,已經(jīng)有X年的Java開(kāi)發(fā)經(jīng)驗(yàn),第一家公司是XXXXX,主要是做XXXX,我主要負(fù)責(zé)XXXX。第二家公司是做什么什么的,我主要負(fù)責(zé)什么,在最近做的一個(gè)項(xiàng)目里面,取得了某某成果.....
當(dāng)然上面的內(nèi)容肯定不夠三分鐘,所以請(qǐng)大家根據(jù)自己的實(shí)際情況進(jìn)行適當(dāng)擴(kuò)充
八股文
這些問(wèn)題呢,一般都是有跡可循,網(wǎng)上分享的面經(jīng)也是一大堆,我主要是想和大家分享一些我印象比較深刻的八股文的題的思路。
講講ThreadLocal
我一聽(tīng)這個(gè)開(kāi)場(chǎng)感覺(jué)就很穩(wěn),之前有寫(xiě)過(guò)ThreadLocal相關(guān)的內(nèi)容。我直接一把梭,面試官久久無(wú)言。
首先講下ThreadLocal底層數(shù)據(jù)結(jié)構(gòu),然后延伸到用法,由于子線程無(wú)法獲取到父線程ThreadLocal的值,所以延伸到了 InheritableThreadLocal。
又因?yàn)樵谑褂镁€程池的時(shí)候InheritableThreadLocal并不能解決獲取父線程值的問(wèn)題,因?yàn)榫€程池中的線程是復(fù)用的,可能在子線程中對(duì)值進(jìn)行了修改,使子線程獲取到的值并不正確。我又給引申到了 alibaba TransmittableThreadLocal,再順便講下它的原理。
最后講下ThreadLocal可能會(huì)出現(xiàn)內(nèi)存泄漏需要注意,又把怎么排查內(nèi)存泄漏的方法講了下。
講完這些,面試官一般都不會(huì)再繼續(xù)問(wèn)了,因?yàn)槲野阉胝f(shuō)的都說(shuō)了。
之前關(guān)于ThreadLocal的文章,可以看這里
如果讓你設(shè)計(jì)一個(gè)線程池,你怎么設(shè)計(jì)?
這其實(shí)就是說(shuō)線程池的,只需要把線程池的核心原理講下就行了。
先說(shuō)線程池主要是通過(guò)ThreadPoolExecutor來(lái)創(chuàng)建的,再說(shuō)下幾個(gè)參數(shù)的作用,網(wǎng)上分析線程池的文章一大堆,面試的時(shí)候可不是寫(xiě)文章,一定要在有限時(shí)間說(shuō)重點(diǎn)。
比如重點(diǎn)說(shuō)下原理,主要是幾個(gè)參數(shù)的作用,阻塞隊(duì)列一定要用有界隊(duì)列,拒絕策略有幾個(gè),默認(rèn)的行為是什么,再講講特殊的策略CallerRunsPolicy(如果線程池未關(guān)閉,則交給調(diào)用線程池的線程執(zhí)行)
最后還可以引申講下Tomcat的線程池優(yōu)先擴(kuò)容到最大線程數(shù),來(lái)不及處理的多余任務(wù)才會(huì)放入到隊(duì)列中。
最后收個(gè)題,如果你設(shè)計(jì),線程池的參數(shù)允許動(dòng)態(tài)調(diào)整,線程池是提供了參數(shù)進(jìn)行設(shè)置的。
關(guān)聯(lián)文章
為什么阿里建議你不要使用Executors來(lái)創(chuàng)建線程池?
講講redis分布式鎖
就要講下setNX這個(gè)命令,然后說(shuō)下有什么問(wèn)題(比如業(yè)務(wù)未執(zhí)行完成鎖就釋放了,或者釋放鎖的不是同一個(gè)線程等等問(wèn)題),然后引申到redLock,再引申到 redission實(shí)現(xiàn)的分布式鎖,重點(diǎn)講下說(shuō)下setnx+lua以及watchDog
然后還可以引申到 zookeeper實(shí)現(xiàn)分布式鎖,說(shuō)下有序節(jié)點(diǎn),臨時(shí)節(jié)點(diǎn),事件監(jiān)聽(tīng)等,一般是使用開(kāi)源客戶端curator的實(shí)現(xiàn)。
最后再比較下兩者區(qū)別,比如
redis獲取不到鎖會(huì)一直不斷嘗試獲取,比較消耗性能 redis數(shù)據(jù)并不是強(qiáng)一致性,極端情況下可能會(huì)出現(xiàn)問(wèn)題,redlock也無(wú)法完全保證 zk設(shè)計(jì)定位就是強(qiáng)一致性,鎖模型健壯,適合做分布式鎖 zk獲取不到鎖,只需要添加監(jiān)聽(tīng)器就行了,不用一直輪訓(xùn)
zk也有缺點(diǎn),就是較多客戶端頻繁申請(qǐng)加鎖,釋放鎖,對(duì)于zk集群的壓力會(huì)比較大。
time_wait過(guò)多怎么辦?
從四次揮手到怎么產(chǎn)生time_wait,再到多了會(huì)怎樣?怎么解決。這就是一個(gè)順序鏈條。
TCP連接處在 TIME_WAIT 狀態(tài),這個(gè)是TCP協(xié)議規(guī)定的,四次揮手時(shí)主動(dòng)關(guān)閉方所處的 一個(gè)狀態(tài),會(huì)等待2個(gè)MSL(MSL=2分鐘),所以在這個(gè)時(shí)間段內(nèi)不會(huì)釋放端口,如果并發(fā)量大的話,會(huì)導(dǎo)致端口不夠用,從而影響新的TCP連接。
我們可以通過(guò)設(shè)置對(duì)應(yīng)的系統(tǒng)參數(shù)(reuse_buckts,好像叫這個(gè),參數(shù)為什么不寫(xiě)全?我寫(xiě)了也記不住,干脆只需要知道有參數(shù)可以控制就行了),重用這些連接。
tomcat調(diào)優(yōu)怎么做?
可以從I/O模型,JVM內(nèi)存,線程池以及網(wǎng)絡(luò)優(yōu)化四個(gè)方面答。
如果tomcat跑到windows上可以考慮使用NIO2,因?yàn)閺牟僮飨到y(tǒng)層面實(shí)現(xiàn)了真正的異步IO,如果是在Linux服務(wù)器上,就還是建議使用NIO,因?yàn)镴VM是在應(yīng)用層面通過(guò)epoll實(shí)現(xiàn)的異步IO。
JVM內(nèi)存就涉及到j(luò)vm內(nèi)存模型(不是JMM),然后針對(duì)年輕代,老年代,metaspace等分別進(jìn)行說(shuō)明,以及一些配置的參數(shù),垃圾回收器等。
網(wǎng)絡(luò)優(yōu)化的話可以從tcp的半連接隊(duì)列和accept隊(duì)列說(shuō)起。
半連接隊(duì)列:保存 SYN_RECV 狀態(tài)的連接。
隊(duì)列長(zhǎng)度由net.ipv4.tcp_max_syn_backlog設(shè)置
accept 隊(duì)列:保存 ESTABLISHED 狀態(tài)的連接。
隊(duì)列長(zhǎng)度為min(net.core.somaxconn,backlog)。其中 backlog 是我們創(chuàng)建 ServerSocket 時(shí)指定的參數(shù),最終會(huì)傳遞給 listen 方法。backlog在tomcat中對(duì)應(yīng)的是acceptCount的值。
acceptCount默認(rèn)值是 100,net.core.somaxconn的默認(rèn)值是 128。
你可以想象在高并發(fā)情況下當(dāng) Tomcat 來(lái)不及處理新的連接時(shí),這些連接都被堆積在 accept 隊(duì)列中,而acceptCount參數(shù)可以控制 accept 隊(duì)列的長(zhǎng)度,超過(guò)這個(gè)長(zhǎng)度時(shí),內(nèi)核會(huì)向客戶端發(fā)送RST,這樣客戶端會(huì)觸發(fā)“Connection reset”異常
所以配置tomcat的時(shí)候我們需要考慮這兩個(gè)參數(shù)的值
kafka exactly once如何保證?
at least once + 冪等 = exactly once,kafka可以保證at least once
Producer 的冪等性指的是當(dāng)發(fā)送同一條消息時(shí),數(shù)據(jù)在 Server 端只會(huì)被持久化一次,數(shù)據(jù)不丟不重,不過(guò)這里是有條件
只能保證 Producer 在單個(gè)會(huì)話內(nèi)不丟不重 冪等性不能跨多個(gè) Topic-Partition,只能保證單個(gè) partition 內(nèi)的冪等性,當(dāng)涉及多個(gè) Topic-Partition 時(shí),這中間的狀態(tài)并沒(méi)有同步。配置 enable.idempotence 設(shè)置為 true
Producer 冪等性的實(shí)現(xiàn)原理,Kafka Producer 在實(shí)現(xiàn)時(shí)有以下兩個(gè)重要機(jī)制:
PID(Producer ID),用來(lái)標(biāo)識(shí)每個(gè) producer client sequence numbers,client 發(fā)送的每條消息都會(huì)帶相應(yīng)的 sequence number,Server 端就是根據(jù)這個(gè)值來(lái)判斷數(shù)據(jù)是否重復(fù)
同時(shí)producer 在設(shè)置冪等性時(shí),
要求 MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION 小于等于 5, 因?yàn)?server 端只會(huì)緩存最近 5 個(gè) batch。
如果想要保證多個(gè)partition,則需要事務(wù)
mysql索引優(yōu)化要注意哪些點(diǎn)?
先從mysql B+樹(shù)結(jié)構(gòu)(頁(yè))說(shuō)起,然后講講注意點(diǎn)。比如
不要超過(guò)三張表join join的時(shí)候小表驅(qū)動(dòng)大表 盡量走主鍵索引,避免回表 為區(qū)分度大的列建立索引 最左匹配原則,like 'xx%' 查詢需要的列,而不是所有列,不要使用計(jì)算,函數(shù)等 explain ..............
Synchronized和ReentrantLock有什么不一樣
先說(shuō)原理,再比較異同點(diǎn)。
Synchronized從偏向鎖 ---> 輕量級(jí)鎖 ---> 重量級(jí)鎖 ---> CLH隊(duì)列 ---> pthread
ReentrantLock ---> 用法 ---> 原理(AQS) ---> UnSafe.park ---> pthread
還可以引申下AQS下的其他并發(fā)工具類(lèi)
感興趣的可以去看下我寫(xiě)的并發(fā)編程系列。
看了Synchronized源碼,請(qǐng)別和我說(shuō)它慢
這波對(duì)AbstractQueuedSynchronizer的解析,我給自己打99分!
SpringBean如何解決循環(huán)依賴(lài)?
我知道你要說(shuō)三級(jí)緩存,說(shuō)之前最好看下源碼形成自己的思想,光背是背不住的。
然后面試官會(huì)問(wèn)你只要兩級(jí)行不行?如果你說(shuō)不行,那面試到這里就結(jié)束了。
如果你說(shuō)行,就好好想想問(wèn)什么需要三級(jí)呢?(代理)
項(xiàng)目
qps,rps多少?
線上遇到過(guò)讓你覺(jué)得最有難度的問(wèn)題?
如果你負(fù)責(zé)的項(xiàng)目流量陡增10倍怎么辦?
你這個(gè)項(xiàng)目的亮點(diǎn)在哪里?
文字越少,問(wèn)題越大。
說(shuō)實(shí)話這些開(kāi)放性問(wèn)題問(wèn)得比重是遠(yuǎn)比八股文大的,因?yàn)榘斯晌木W(wǎng)上一大堆,但是這些項(xiàng)目上相關(guān)的,每個(gè)人都是獨(dú)一無(wú)二的。所以平常的時(shí)候要多思考這類(lèi)問(wèn)題,多總結(jié)。
以上就是常常被問(wèn)最有代表性的問(wèn)題,希望對(duì)大家有幫助。
回答不上來(lái)怎么辦?
你覺(jué)得躺平怎么樣?
有些問(wèn)題回答不上來(lái)很正常,大家理解可能不一樣,而且就算回答上來(lái)了,說(shuō)不定也不是面試官想要的。
遇到不清楚意思的,多問(wèn)問(wèn)。實(shí)在不會(huì)的就回答不會(huì)好了,或者跟面試官講講你的思路也行,把這場(chǎng)面試當(dāng)成一場(chǎng)技術(shù)交流,心態(tài)會(huì)好很多。
面試之前最好把一些常問(wèn)的,做到心中有數(shù)
要自信呀
只要夠自信,面試就成功了50%。
最后,看到這兒了,我的自信值得你點(diǎn)個(gè)贊嗎?(手動(dòng)狗頭)
