注:本文首發(fā)于碼農(nóng)那些事頭條號(hào)谈山。
前幾天分享了一個(gè)唯品會(huì)的面試經(jīng)驗(yàn)俄删,今天分享下阿里巴巴的Java面試經(jīng)驗(yàn)。為了幫助大家更好的掌握知識(shí)奏路,每一個(gè)題目我都會(huì)進(jìn)行詳細(xì)的解答說明畴椰。關(guān)于自我介紹和自己的項(xiàng)目介紹這塊就跳過了,直接進(jìn)入技術(shù)題問答鸽粉。
1.Object類的hashCode和equals方法的作用是什么斜脂,子類重寫時(shí)需要注意什么?
一開始聽到這個(gè)問題時(shí)触机,我是有點(diǎn)懵的帚戳,不太理解到底想問什么玷或。hashCode方法作用是返回一個(gè)哈希值,equals方法則是用于比較是否相等片任。關(guān)于子類重寫時(shí)需要注意什么庐椒,我只想到了hashCode由于是哈希值嘛,肯定需要盡可能的保證分布均勻蚂踊,由于是第一個(gè)問題约谈,一下子也沒進(jìn)入狀態(tài),說來說去只能說出要盡可能均勻犁钟。
這個(gè)問題的答案其實(shí)在Effective Java中有詳細(xì)說明棱诱,里面專門有條目來講相關(guān)的問題±远總結(jié)一下就是:
1.覆蓋equals方法時(shí)需要遵循通用約定:自反性迈勋、對(duì)稱性、傳遞性醋粟、一致性.
2.覆蓋equals方法時(shí)總要覆蓋hashCode方法.
3.如果兩個(gè)對(duì)象是equlals的靡菇,那么它們的hashCode值必須相等(否則put到Map中可能get不到).
4.一個(gè)好的hashCode方法通常傾向于“為不相等的對(duì)象產(chǎn)生不同的hashCode值”。
由此可見米愿,我說要盡可能使得hash值分布均勻厦凤,其實(shí)只是勉強(qiáng)答了第四個(gè)小點(diǎn)。
2.HashMap是否線程安全育苟,線程安全的定義较鼓,想要線程安全時(shí)怎么辦,ConcurrentHashMap實(shí)現(xiàn)原理
HashMap顯然不是線程安全的违柏。關(guān)于線程安全的定義博烂,我在面試時(shí)多次被問到這個(gè)問題∈看過Java并發(fā)編程那本經(jīng)典書籍的人應(yīng)該會(huì)有點(diǎn)印象禽篱,書上也說線程安全沒有非常明確的定義,書上給了一種定義馍惹。
當(dāng)多個(gè)線程訪問某個(gè)類時(shí)躺率,不管運(yùn)行時(shí)環(huán)境采用何種調(diào)度方式或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)調(diào)讼积,這個(gè)類都能表現(xiàn)出正確的行為肥照,那么就稱這個(gè)類是線程安全的。[Java并發(fā)編程實(shí)戰(zhàn)]勤众。
在線程安全的定義中,最核心的概念就是正確性鲤脏。在線程安全類中封裝了必要的同步機(jī)制们颜,因此客戶端無需進(jìn)一步采取同步措施吕朵。
額外提一句,我這邊是把多個(gè)小問題都列在了一起窥突;實(shí)際上面試時(shí)努溃,面試官會(huì)根據(jù)你的回答而進(jìn)一步深入問。如果你回答HashMap是線程安全的阻问,那很可能面試官就不問你怎么樣叫線程安全了梧税,因?yàn)槟阕罨A(chǔ)的就回答錯(cuò)誤了。當(dāng)你回答出線程安全版本ConcurrentHashMap時(shí)称近,就會(huì)進(jìn)一步問你ConcurrentHashMap的實(shí)現(xiàn)原理第队,層層遞進(jìn)。
需要注意的一點(diǎn)是刨秆,當(dāng)你回答ConcurrentHashMap實(shí)現(xiàn)原理時(shí)凳谦,如果你想拿到更高的評(píng)價(jià),那至少也要分別說下JDK 1.7中和JDK 1.8中ConcurrentHashMap各自的實(shí)現(xiàn)衡未,兩個(gè)不同版本的實(shí)現(xiàn)區(qū)別有哪些尸执,為什么要這么做。如果你不管三七二十一缓醋,上來就說ConcurrentHashMap內(nèi)部是由多個(gè)Segment段組成(默認(rèn)16個(gè))如失,巴拉巴拉....那就很平庸了。
3.快排和冒泡算法排序比較哪個(gè)快送粱?描述下快排的過程岖常?
感覺這個(gè)像是個(gè)小陷阱,不過陷阱設(shè)置得也不明顯葫督,一般學(xué)過數(shù)據(jù)結(jié)構(gòu)的人就不至于答錯(cuò)竭鞍,除非真的工作太久記不清了。答案是和輸入有關(guān)橄镜,比較需問清楚比的是什么偎快,是比較最壞時(shí)間復(fù)雜度還是平均時(shí)間復(fù)雜度。
關(guān)于快排的過程洽胶,如果工作太久了晒夹,一下子可能還真說不清楚了。面試時(shí)姊氓,只隱約記得算法導(dǎo)論還是哪本書上提到快排分two way和three way丐怯,還有各種變種,比如取pivot(基準(zhǔn))時(shí)就可以是取第一個(gè)元素翔横,多個(gè)元素取中值读跷,多個(gè)中取隨機(jī)一個(gè)等等。
4.有一個(gè)類有一個(gè)成員變量和一個(gè)方法禾唁,當(dāng)創(chuàng)建100個(gè)該類對(duì)象時(shí)效览,內(nèi)存里有多少個(gè)成員變量和多少個(gè)方法无切?
這個(gè)問題是我這次面試中,感覺最靈活的一個(gè)問題了丐枉,非扯呒考察技術(shù)水平。
首先瘦锹,方法不在對(duì)象中,不管這個(gè)類有多少個(gè)對(duì)象弯院,方法都是共用的辱士,只有1個(gè)抽兆。
其次识补,容易想到的一點(diǎn)就是辫红,成員個(gè)數(shù)和是否static有關(guān)凭涂,如果是static的,那就是類級(jí)別的變量贴妻,即使有100個(gè)對(duì)象也都是共用的切油,也只有一個(gè)成員變量了。
然后名惩,面試官就問澎胡,還有沒有別的可能了娩鹉,直覺告訴我攻谁,肯定還有我沒想到的點(diǎn)弯予,但是想來想去戚宦,似乎也就是這兩點(diǎn)了。我就問面試官锈嫩,能否給點(diǎn)提示受楼。
注意,面試時(shí)呼寸,如果真的回答不了艳汽,可以讓面試官給你點(diǎn)提示,既表明你在認(rèn)真思考对雪,也表現(xiàn)出你的溝通能力。
面試官問我了解ClassLoader嗎?怎么判斷兩個(gè)對(duì)象是不是屬于同一個(gè)類甚牲?然后我就回答了這個(gè)問題蝶柿,但是我還是沒反應(yīng)過來這和剛才的問題有什么聯(lián)系丈钙,面試官再三提示,我才明白過來雏赦,如果成員是static,但是當(dāng)由不同ClassLoader加載則仍然會(huì)不止一個(gè)成員變量芙扎。
5.然后順著ClassLoader,面試官繼續(xù)問雙親委托加載原理戒洼,為什么要雙親委托加載,如何打破雙親委托加載圈浇?Tomcat中的ClassLoader怎么做的寥掐?
ClassLoader類是個(gè)抽象類磷蜀,這邊著重提一下它的幾個(gè)關(guān)鍵方法:
loadClass:實(shí)現(xiàn)了雙親委托加載的過程召耘,如果所有父類都無法加載褐隆,則由自己調(diào)用findClass進(jìn)行加載污它;
findClass:默認(rèn)實(shí)現(xiàn)是拋出ClassNotFoundException庶弃,需由子類去實(shí)現(xiàn)怎么找到指定類衫贬,讀取class文件到byte流的過程歇攻,然后通過調(diào)用defineClass來返回Class對(duì)象固惯;
defineClass:將byte字節(jié)流解析成JVM能識(shí)別的Class對(duì)象掉伏;
Tomcat中的ClassLoader有分多個(gè)層次缝呕,如CommonClassLoader、WebAppClassLoader供常,這個(gè)不同版本還有點(diǎn)不同,細(xì)節(jié)就不展開了栈暇。
今天的內(nèi)容有點(diǎn)深入,畢竟是阿里的面試題箍镜,難度還是不小的煎源,而且這個(gè)只是一面的面試題。分享阿里的面試經(jīng)驗(yàn)手销,并非一定是要進(jìn)阿里不可,也是一個(gè)學(xué)習(xí)的過程图张。大家如果對(duì)自己的技術(shù)能力有信心,可以投下阿里的崗位祸轮,看看自己掌握的是否扎實(shí)。
本頭條號(hào)會(huì)不定期分享程序員的面試經(jīng)驗(yàn)适袜,以及程序員需要掌握的技術(shù)干貨柄错,喜歡就關(guān)注我吧~
完苦酱。