歡迎關(guān)注專欄:后端架構(gòu)技術(shù)精選孵户。里面有大量關(guān)于的Java高級(jí)架構(gòu)知識(shí)點(diǎn)分享萧朝,還有各種面試趣聞以及程序員身邊事,如有好文章也歡迎投稿哦夏哭。
快手高開及以上職級(jí)面試 是沒有筆試或者機(jī)試的检柬,所以從第一輪開始就是直接面對(duì)面試官。
一輪
主要考察對(duì)Java基礎(chǔ)的理解和深入程度竖配。
Spring 原理何址,Spring IOC、AOP进胯。
這個(gè)問題 最好可以多說一點(diǎn)用爪,比如 對(duì)于IOC,不妨把Bean 如何加載胁镐、如何初始化以及如何注冊到IOC容?中的詳細(xì)過程說一下偎血, 涉及BeanDefinition、BeanFactory也深入細(xì)節(jié)聊一下盯漂。一個(gè)請求過來在Spring中發(fā)生了哪些事情颇玷。
這個(gè)問題不妨把一個(gè)請求過來 在TCP層面上建立連接、操作系統(tǒng)如何處理連接宠能、Web容器?接收到連接對(duì)象后做了哪些事情亚隙、Spring 如何對(duì)接收到的請求進(jìn)行處理都說一下磁餐,當(dāng)然最終還是 落在Spring 容器內(nèi)部如何處理一個(gè)請求违崇,這個(gè)過程一定要說清楚,需要體現(xiàn)細(xì)節(jié)诊霹。在說前面的內(nèi)容的時(shí)候羞延,可以放心面試官不會(huì)打斷你。手寫一個(gè)棧脾还,實(shí)現(xiàn) push伴箩,pop方法,以及 max(獲取最大的元素)方法鄙漏,要求時(shí)間復(fù)雜度為 O(1)嗤谚。
這是一個(gè)考察數(shù)據(jù)結(jié)構(gòu)的問題,一方面需要候選人對(duì)數(shù)據(jù)結(jié)構(gòu)有所了了解怔蚌,一方面也需要候選人對(duì)代碼有駕馭能力(畢竟要手寫代碼)巩步。面試官會(huì)給一定的時(shí)間,在這段時(shí)間里面試官不會(huì)打擾你桦踊,并盡可能為你提供方便椅野,比如簽字筆不好用面試官會(huì)幫你更換。據(jù)我個(gè)人經(jīng)驗(yàn),凡是面對(duì)需要寫代碼的問題竟闪,都不要急著放棄离福,靜下心來,仔細(xì)思考炼蛤,都是可以寫得不錯(cuò)的妖爷。如果沒能寫出來,面試官會(huì)問你實(shí)現(xiàn)思路路理朋,如果你的思路很優(yōu)化赠涮,一樣可以過了這道題,但是前提是你的代碼不能一行都不寫暗挑。
對(duì)于數(shù)據(jù)結(jié)構(gòu)的考察的話笋除,我建議看一下 jdk中對(duì)于 List、Stack炸裆、Tree垃它、Set 的實(shí)現(xiàn),比如至少你要知道如果讓你實(shí)現(xiàn)一個(gè)單鏈表你會(huì)如何實(shí)現(xiàn)烹看,比如你可能會(huì)定義一個(gè)Node節(jié)點(diǎn)国拇,里面有當(dāng)前節(jié)點(diǎn)的key和value,還有對(duì)于下一個(gè)節(jié)點(diǎn)的引用惯殊。如果你對(duì)這一塊的內(nèi)容還不是很清楚酱吝,可以關(guān)注我的公眾號(hào):《Java技術(shù)zhai》,我之前在上面是有詳細(xì)分享過的土思,對(duì)于熟悉jdk對(duì)于各種數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)务热,這道題是很容易易過的。JVM內(nèi)存結(jié)構(gòu)
這個(gè)問題需要你能畫出JVM內(nèi)存結(jié)構(gòu)的圖己儒,畫出方法區(qū)崎岂、堆、程序計(jì)算器?闪湾、虛擬機(jī)棧冲甘、本地方法棧,并說出每一個(gè)部分具體是什么作用途样,比如哪些是線程共享的江醇,哪些是線程獨(dú)享的,哪些地方存放了什么數(shù)據(jù)何暇,為什么會(huì)這樣存放陶夜,哪些虛擬機(jī)參數(shù)對(duì)這些空間大小是有影響的,可以如何配置赖晶。這些都比較常規(guī)律适。手寫一個(gè)單例
這個(gè)基本上大多數(shù)公司都會(huì)考察的辐烂。要寫一個(gè) 基于懶漢式的 雙重檢測的單例。單例有三個(gè)比較關(guān)鍵的點(diǎn):
- 私有構(gòu)造方法捂贿,避免外部new出對(duì)象纠修;
- 保證唯一性;
- 提供一個(gè)全局訪問點(diǎn)厂僧;
另外懶漢式雙重檢測的實(shí)現(xiàn)方式有三點(diǎn)需要注意的地方:
- 全局訪問點(diǎn)必須是靜態(tài)的扣草,外界使用可以通過類直接調(diào)用;
- 在進(jìn)入鎖之后還需要校驗(yàn)颜屠;
- 保存單例例對(duì)象的私有變量一定要用volatile修飾辰妙,這個(gè)地方 可以多說一些,比如 volatile防止指令重排序甫窟,保證內(nèi)存可見性(JVM層面 和 CPU層面 可以分別說)密浑。volatile 這個(gè)地方能說的東西還是很多的,基本上可以與面試官再聊二十分鐘了粗井。
- HashMap
對(duì)于 HashMap 其實(shí)一般高級(jí)崗位及以上不再會(huì)問這個(gè)東西了尔破,一旦問了,肯定不是讓你只說一下數(shù)組+鏈表的浇衬。對(duì)于它的實(shí)現(xiàn)懒构,不同版本實(shí)現(xiàn)方式不一樣。在jdk1.8之后耘擂,HashMap 除了數(shù)組+鏈表之外胆剧,引入了紅黑樹。那么好了醉冤,你需要說明對(duì)于引入了紅黑樹的 HashMap 如何put一個(gè)元素秩霍,以及鏈表是在何時(shí)轉(zhuǎn)化為紅黑樹的。比如首先需要知道這個(gè)元素落在哪一個(gè)數(shù)組里冤灾,獲取hashcode后并不是對(duì)數(shù)組長度取余來確定的前域,而是高低位異或求與來得到的。這個(gè)地方首先得知道 異或韵吨、與是做什么樣的運(yùn)算的,然后說一下在HashMap中的實(shí)現(xiàn)移宅,比如hashcode 無符號(hào)右移16位后和原h(huán)ashcode 做異或運(yùn)算归粉,這相當(dāng)于把hashcode的高16位拿過來 和 hashcode的 低16位 做異或運(yùn)算,因?yàn)闊o符號(hào)右移后 前面高16位都補(bǔ)零漏峰,這就是前面說的 "高低位異或“糠悼,進(jìn)而是 ”求與“,和誰求與呢浅乔,和 數(shù)組長度減1 求與倔喂。
說到這里起碼能夠證明你是看過源碼的铝条,接下來說說你的思考。
比如 我們知道 對(duì)于hashmap 初始化容量決定了數(shù)組大小席噩,一般我們對(duì)于數(shù)組這個(gè)初始容量的設(shè)置是有規(guī)律的班缰,它應(yīng)該是 2^n 。這個(gè)初始容量的設(shè)置影響了HashMap的效率悼枢,那又涉及到影響HashMap效率的主要因素埠忘,比如初始容量和負(fù)載因子。當(dāng)已用數(shù)組達(dá)到容量與負(fù)載因子的乘積之后會(huì)進(jìn)行一個(gè)rehash的過程馒索,這個(gè)地方涉及到的 如何rehash 及各種算法如果有時(shí)間也是可以說的莹妒,沒有時(shí)間不說也沒有關(guān)系〈律希回到剛才說的 2^n, 可以說說它為什么是2^n旨怠。當(dāng)我們說什么東西為什么是這樣的時(shí)候,我們一般從兩個(gè)角度考慮蜈块,一個(gè)是這樣做有什么好處运吓,另一個(gè)是不這樣做有什么壞處。我們剛才說到”求與“這個(gè)過程疯趟,如果不是 2^n, 會(huì)導(dǎo)致較多的哈希碰撞(具體原因 可以自己分析一下 或者百度一下)拘哨,這個(gè)會(huì)影響HashMap的效率。
說完上面這些信峻,既表明你看過源碼倦青,又表明你有自己的思考了,當(dāng)然也可以進(jìn)一步說說它是在什么條件下以及 如何進(jìn)行擴(kuò)容的(如果時(shí)間允許盹舞,并且面試官也有耐心繼續(xù)聽下去)产镐。對(duì)于put操作,這才只是第一步踢步,找到數(shù)組的位置癣亚,接下來 要看這個(gè)位置也沒有元素,如果沒有获印,直接放進(jìn)去就可以述雾,如果有,要看怎么放進(jìn)去兼丰,jdk1.8中 對(duì)于HashMap的實(shí)現(xiàn)中玻孟,是基于Node(鏈表節(jié)點(diǎn)) 和TreeNode(紅黑樹節(jié)點(diǎn)) 的,當(dāng)然它們繼承了Entry鳍征。那么 如果數(shù)組當(dāng)前位置已經(jīng)有了元素黍翎,就得知道這個(gè)元素 是 鏈表的節(jié)點(diǎn)還是紅黑樹的節(jié)點(diǎn),以便便 進(jìn)一步確認(rèn)接下來要put的元素 是以鏈表的方式插入還是以紅黑樹的方式插入艳丛,這個(gè)地方 在源碼中 進(jìn)行了一個(gè)類型的判斷匣掸,如果是鏈表的節(jié)點(diǎn)趟紊,就以鏈表的方式把要put的節(jié)點(diǎn)插入到 next為null的節(jié)點(diǎn)上,如果是紅黑樹的節(jié)點(diǎn)碰酝,就要以紅黑樹的方式插入一個(gè)節(jié)點(diǎn)霎匈。接下來 其實(shí)不是考察的重點(diǎn),但是也可以說說:
- 為什么要引入紅黑樹砰粹;
- 如何在紅黑樹中插入一個(gè)節(jié)點(diǎn)唧躲;
對(duì)于這兩個(gè)問題,首先 引入 紅黑樹的好處是為了提高查詢效率碱璃,要說出O(log2(n))弄痹,但是 在提高查找效率的同時(shí)也在插入的時(shí)候更加耗時(shí),那可以說一下為什么更加耗時(shí)嵌器,自然帶出第二個(gè)問題肛真,如何在紅黑樹中插入一個(gè)節(jié)點(diǎn),比如當(dāng)插入一個(gè)節(jié)點(diǎn)的時(shí)候我們會(huì)默認(rèn)它是紅色的(這個(gè)地方可以結(jié)合紅黑樹特點(diǎn)說一下我們?yōu)槭裁茨J(rèn)它是紅色的爽航,從黑色高度以及相鄰兩節(jié)點(diǎn)不同為紅色入手)蚓让,插入后如果父節(jié)點(diǎn)是黑色的 就不需要?jiǎng)恿肆耍偃缡羌t色的讥珍,就需要進(jìn)行左旋和右旋操作历极,如果很了解,可以細(xì)說左旋右旋如何實(shí)現(xiàn)衷佃,如果不不是很了了解趟卸,到此為止也ok。
說到這里氏义,我們忽略略了一個(gè)重要的點(diǎn)锄列,就是鏈表轉(zhuǎn)換為紅黑樹的條件,說出 鏈表長度到8(相當(dāng)于紅黑樹開始第四層) 以及 數(shù)組大小達(dá)到64 就已經(jīng)夠了了惯悠,也可以進(jìn)一步說一下 鏈表是如何轉(zhuǎn)換為紅黑樹的邻邮。說完也可以說一下 ConcurrentHashMap中也是一樣的,然后接下來就引入對(duì)ConcurrentHashMap的理解克婶,比如在什么地方會(huì)涉及到線程安全問題以及ConcurrentHashMap是如何解決的筒严,說說CAS,說完CAS再說說AQS鸠补,自由發(fā)揮吧萝风。
JVM四種引用類型
這個(gè)問題比較簡單,強(qiáng)引用紫岩、弱引用、軟引用睬塌、虛引用泉蝌,說一下它們各自的特點(diǎn)和GC對(duì)它們的不同處理方式歇万,再說一下常見的應(yīng)用場景 或者 jdk的實(shí)現(xiàn)中對(duì)它們的使用,比如 ThreadLocal 的靜態(tài)內(nèi)部類 ThreadLocalMap勋陪,它的Key是弱引用的贪磺,也可以說一下 在你的理解中 為什么它是弱引用的,假如不是 會(huì)怎么樣诅愚。SpringBoot 啟動(dòng)過程
這個(gè)主要是從它基于Spring的事件發(fā)布和監(jiān)聽機(jī)制開始說起 就沒什么問題寒锚。
二輪
繼續(xù)考察Java基礎(chǔ),和對(duì)應(yīng)用技術(shù)的掌握违孝,比如過往項(xiàng)目中所用的一些框架刹前,在這一輪中會(huì)被問到。
類加載過程
加載 鏈接 初始化雌桑,鏈接又分為驗(yàn)證準(zhǔn)備和解析喇喉,每一個(gè)階段 是做了什么 要說清楚。Object a = new Object()校坑; 這行代碼做了了哪些事情拣技,需要從類加載開始說起,這個(gè)相當(dāng)于上面問題的延續(xù)耍目,所以 一定要清楚 每一個(gè)環(huán)節(jié) 做了哪些事情的膏斤,否則這個(gè)問題不可能說清楚。說完類加載的過程 再說一下 開辟內(nèi)存空間邪驮、初始化內(nèi)存空間以及把內(nèi)存地址賦值給變量a莫辨,接下來可以進(jìn)一步說一下JVM 或者CPU層面對(duì)指令的優(yōu)化,以及在某些時(shí)刻我們需要避免它做這樣的優(yōu)化耕捞,比如在單例中我們的實(shí)例需要用volatile修飾 避免指令重排序(可以說一下 在new一個(gè)對(duì)象的過程中如果指令重排序了會(huì)導(dǎo)致什么結(jié)果)衔掸。
接下來主要是對(duì)過往項(xiàng)目中用到的框架、工具的考察
- maven的熟練程度俺抽,比如問問 <scope> 有哪些類型
- Linux命令行的熟練程度敞映,比如 問問
() 區(qū)別
- 消息隊(duì)列列的熟練程度,比如問問Kafka分區(qū)磷斧,如何分區(qū)等等(因?yàn)槲疫^往項(xiàng)目經(jīng)驗(yàn)中寫了kafka振愿,所以才會(huì)被問及,如果寫了其他消息隊(duì)列弛饭,也可能會(huì)被問及)
- Netty冕末,從NIO開始說 肯定是沒錯(cuò)的,再說說Netty的實(shí)現(xiàn)方式侣颂,以及它除了IO之外還干了哪些事情档桃。
三輪
這一輪主要考察對(duì)于過往項(xiàng)目的業(yè)務(wù)理解
根據(jù)過往項(xiàng)目經(jīng)驗(yàn) 依次介紹業(yè)務(wù)
這就需要 在面試之前 把自己的做過的項(xiàng)目好好總結(jié)一下,它們主要做的業(yè)務(wù)是什么憔晒,解決了什么問題藻肄,架構(gòu)是什么樣的蔑舞,以及你在其中做了哪些工作。這個(gè)地方一定要準(zhǔn)備充分嘹屯,至少要能扛得住面試官三連問攻询。否則會(huì)被認(rèn)為 你不太清楚你們之前做的到底是什么,那你在業(yè)務(wù)能力方面 可能是不太match的州弟。你有什什么問題想問面試官的
這個(gè)地方因人而異钧栖,但無論怎樣,都不要什么都不問婆翔,至少你要表現(xiàn)一點(diǎn)對(duì)于崗位的興趣吧拯杠。
比如問一下 公司業(yè)務(wù),團(tuán)隊(duì)構(gòu)成浙滤,技術(shù)棧阴挣,以及你所應(yīng)聘的這個(gè)崗位大概做哪些工作
四輪
HR面試。這一輪可以說是斗智斗勇的一個(gè)環(huán)節(jié)纺腊,會(huì)考察一些軟技能畔咧、個(gè)人成長、職業(yè)素質(zhì)揖膜,也會(huì)問一下期望薪資誓沸。
本次快手面經(jīng)分享完畢,覺得有收獲的朋友可以幫我點(diǎn)個(gè)關(guān)注與轉(zhuǎn)發(fā)壹粟!
贈(zèng)人玫瑰拜隧,手有余香,我是不那么正經(jīng)的技術(shù)zhai趁仙,歡迎你的關(guān)注~