本來(lái)約的三點(diǎn)的面試,但是面試官提前上線看到我在線就說(shuō)提前開(kāi)始吧。
菜鳥的回答:
面試官你好,我叫張三,河南人,畢業(yè)于XX大學(xué),從XX年畢業(yè)后就一直從事java開(kāi)發(fā),差不多 3年了吧。來(lái)貴公司面試,尋求一份java開(kāi)發(fā)工作。
自我介紹要說(shuō)幾個(gè)點(diǎn):你是誰(shuí),你的優(yōu)點(diǎn)是什么?這么多年你干了啥?在學(xué)校獲得過(guò)什么獎(jiǎng)?對(duì)哪些技術(shù)有深入研究?是否有高并發(fā)系統(tǒng)的設(shè)計(jì)?是否參與過(guò)什么大型項(xiàng)目?
總之,把你有的家底都亮出來(lái),讓人家知道你哪方面相對(duì)比較強(qiáng)。
這個(gè)問(wèn)題其實(shí)是因人而異的,對(duì)于剛?cè)腴T的朋友,叫他搭建個(gè)項(xiàng)目就覺(jué)得很有挑戰(zhàn)性。
而對(duì)于大牛來(lái)說(shuō),“挑戰(zhàn)性”已經(jīng)不在是技術(shù)。更多的是何如包裝項(xiàng)目哄好老板,如何壓榨自己的下屬才是項(xiàng)目有挑戰(zhàn)性的點(diǎn)。
而在面試環(huán)節(jié),有“挑戰(zhàn)性”是對(duì)于面試官而言的一個(gè)標(biāo)準(zhǔn)。如果這個(gè)項(xiàng)目業(yè)務(wù)這個(gè)技術(shù)點(diǎn)面試官?zèng)]接觸過(guò),聽(tīng)起來(lái)很難,那這個(gè)就是一個(gè)“有挑戰(zhàn)”的項(xiàng)目。
如果面試官對(duì)你所說(shuō)的挑戰(zhàn)項(xiàng)目很熟悉,此時(shí)可能對(duì)你來(lái)說(shuō)是個(gè)機(jī)會(huì)也是個(gè)挑戰(zhàn),回答出面試官?zèng)]遇到的問(wèn)題,已經(jīng)如何解決的,那面試官妥妥的佩服你,反之,面試官知道的這個(gè)項(xiàng)目的問(wèn)題,問(wèn)你你答不上來(lái),那就回面試大打折扣了。
比如說(shuō):五六年前,你的技術(shù)棧中有dubbo、Spring Boot 那是很吃香的,但是現(xiàn)在已經(jīng)是標(biāo)配了。
但是有大數(shù)據(jù)、高并發(fā)、架構(gòu)改造經(jīng)驗(yàn)的開(kāi)發(fā)者還是少,因?yàn)榻^大部分公司都沒(méi)法發(fā)展成為大公司。但。這個(gè)也是隨著軟件工程怎么發(fā)展都無(wú)法改變的事。
所以對(duì)于有挑戰(zhàn)的項(xiàng)目具有以下幾個(gè)特點(diǎn):
1、大數(shù)據(jù)量
2、高并發(fā)
3、架構(gòu)改造
只要你的項(xiàng)目能和這幾個(gè)東西沾一點(diǎn)邊,那你的項(xiàng)目level就高至少一級(jí)。
這里,我給你一個(gè)回答的模板:
1、我負(fù)責(zé)的是這個(gè)xxx業(yè)務(wù)項(xiàng)目,這個(gè)業(yè)務(wù)的是用來(lái)xxx的。
2、前期為了快速試錯(cuò),快速響應(yīng)市場(chǎng),前期使用了簡(jiǎn)單的xxxx方案。
3、隨著業(yè)務(wù)的發(fā)展,這個(gè)方案在xxx方面出現(xiàn)xxx的技術(shù)問(wèn)題。
4、為了解決這些技術(shù)難點(diǎn),最終用了xxx方案,然后介紹這些方案,同時(shí)這些方案是怎么解決這些技術(shù)問(wèn)題的。
就如實(shí)的說(shuō)自己的學(xué)習(xí)歷程,但要注意,學(xué)習(xí)要體現(xiàn)出自己是主動(dòng)的,另外,標(biāo)注自己有個(gè)好習(xí)慣:記筆記,好幾下不如爛筆頭。
推薦看官網(wǎng),看書,看視頻。
學(xué)習(xí)過(guò)程中,不斷實(shí)踐,不斷反思,不斷總結(jié)。
我們可以從五個(gè)方面來(lái)回答:
線程是否安全:HashMap 是非線程安全的, HashTable 是線程安全的。因?yàn)?HashTable 內(nèi)部的方法基本都經(jīng)過(guò) synchronized 修飾。(如果你要保證線程安全的話就使用 ConcurrentHashMap);
效率:因?yàn)榫€程安全的問(wèn)題, HashMap 要比 HashTable 效率高一點(diǎn)。另外, HashTable基本被淘汰,不要在代碼中使用它;
對(duì) Null key 和 Null value 的支持:HashMap 可以存儲(chǔ) null 的 key 和 value,但 null 作為鍵只能有一個(gè),null 作為值可以有多個(gè);HashTable 不允許有 null 鍵和 null 值,否則會(huì)拋出NullPointerException 。
初始容量帶下和每次擴(kuò)充容量大小的不同 :
① 創(chuàng)建時(shí)如果不指定容量初始值, Hashtable默認(rèn)的初始大小為 11,之后每次擴(kuò)充,容量變?yōu)樵瓉?lái)的 2n+1。HashMap 默認(rèn)的初始化大小為 16。之后每次擴(kuò)充,容量變?yōu)樵瓉?lái)的 2 倍。
② 創(chuàng)建時(shí)如果給定了容量初始值,那么Hashtable 會(huì)直接使用你給定的大小,而 HashMap 會(huì)將其擴(kuò)充為 2 的冪次方大?。?HashMap 中的tableSizeFor()方法保證)。
底層數(shù)據(jù)結(jié)構(gòu):JDK1.8 以后的 HashMap 在解決哈希沖突時(shí)有了較大的變化,當(dāng)鏈表長(zhǎng)度大于閾值(默認(rèn)為 8)(將鏈表轉(zhuǎn)換成紅黑樹前會(huì)判斷,如果當(dāng)前數(shù)組的長(zhǎng)度度大于 64,那么會(huì)選擇先進(jìn)行數(shù)組擴(kuò)容,而不是轉(zhuǎn)換為紅黑樹)時(shí),將鏈表轉(zhuǎn)化為紅黑樹,以減少搜索時(shí)間。Hashtable 沒(méi)有這樣的機(jī)制。
盡管是普通不能再普通的面試題了,可面試中,照樣很大部分人同學(xué)回答的不好?;卮鹬刑岬搅?的n次冪,面試官很有可能會(huì)繼續(xù)追問(wèn)相關(guān)的問(wèn)題,如果還不清楚的,建議對(duì)HashMap進(jìn)行系統(tǒng)的學(xué)習(xí)。
我的博客上之前發(fā)過(guò)兩篇文章:
HashMap在put添加元素過(guò)程可以分為下面9個(gè)步驟:
可以看看我博客上的博文:三年必備HashMap源碼:http://www.woaijava.cc/blog/211
紅黑樹(Red Black Tree)是一種特化的AVL樹(平衡二叉樹),都是在進(jìn)行插入和刪除操作時(shí)通過(guò)特定操作保持二叉查找樹的平衡,從而獲得較高的查找性能。
紅黑樹的特點(diǎn)有5個(gè):
結(jié)點(diǎn)是紅色或黑色。
根結(jié)點(diǎn)是黑色。
所有葉子都是黑色(葉子是NIL結(jié)點(diǎn))
每個(gè)紅色結(jié)點(diǎn)的兩個(gè)子結(jié)點(diǎn)都是黑色。(從每個(gè)葉子到根的所有路徑上不能有兩個(gè)連續(xù)的紅色結(jié)點(diǎn))
從任一結(jié)點(diǎn)到其每個(gè)葉子的所有路徑都包含相同數(shù)目的黑色結(jié)點(diǎn)。
其實(shí)這個(gè)問(wèn)題不難,難得是可能有的面試官會(huì)問(wèn)紅黑樹的操作,左旋轉(zhuǎn)右旋轉(zhuǎn)...,我面試過(guò)幾百人,能說(shuō)出來(lái)寥寥無(wú)幾。
B+樹的特點(diǎn)有兩個(gè):
B+樹一般是1道3層。
InnoDB頁(yè)的大小默認(rèn)是16KB:
所以,兩層的B+樹可以存儲(chǔ):16*1638=26208條數(shù)據(jù);三層的B+樹可以存儲(chǔ):16*1638*1638=42928704條數(shù)據(jù)。
B+樹是多叉樹結(jié)構(gòu),每個(gè)結(jié)點(diǎn)都是一個(gè)16k的數(shù)據(jù)頁(yè),能存放較多索引信息,所以扇出很高。三層左右就可以存儲(chǔ)2kw左右的數(shù)據(jù)。也就是說(shuō)查詢一次數(shù)據(jù),如果這些數(shù)據(jù)頁(yè)都在磁盤里,那么最多需要查詢三次磁盤IO。
跳表是鏈表結(jié)構(gòu),一條數(shù)據(jù)一個(gè)結(jié)點(diǎn),如果最底層要存放2kw數(shù)據(jù),且每次查詢都要能達(dá)到二分查找的效果,2kw大概在2的24次方左右,所以,跳表大概高度在24層左右。最壞情況下,這24層數(shù)據(jù)會(huì)分散在不同的數(shù)據(jù)頁(yè)里,也即是查一次數(shù)據(jù)會(huì)經(jīng)歷24次磁盤IO。
因此存放同樣量級(jí)的數(shù)據(jù),B+樹的高度比跳表的要少,如果放在MySQL數(shù)據(jù)庫(kù)上來(lái)說(shuō),就是磁盤IO次數(shù)更少,因此B+樹查詢更快。
而針對(duì)寫操作,B+樹需要拆分合并索引數(shù)據(jù)頁(yè),跳表則獨(dú)立插入,并根據(jù)隨機(jī)函數(shù)確定層數(shù),沒(méi)有旋轉(zhuǎn)和維持平衡的開(kāi)銷,因此跳表的寫入性能會(huì)比B+樹要好。
其實(shí),MySQL的存儲(chǔ)引擎是可以換的,以前mysql 5.5是myisam,后來(lái)才有的innodb,它們底層索引用的都是B+樹。也就是說(shuō),你完全可以造一個(gè)索引為跳表的存儲(chǔ)引擎裝到MySQL里。事實(shí)上,facebook造了個(gè)rocksDB的存儲(chǔ)引擎,里面就用了跳表。直接說(shuō)結(jié)論,它的寫入性能確實(shí)是比innodb要好,但讀性能確實(shí)比innodb要差不少。感興趣的話,可以在文章最后面的參考資料里看到他們的性能對(duì)比數(shù)據(jù)。
因?yàn)锽+樹的原理是 葉子節(jié)點(diǎn)存儲(chǔ)數(shù)據(jù),非葉子節(jié)點(diǎn)存儲(chǔ)索引,B+樹的每個(gè)節(jié)點(diǎn)可以存儲(chǔ)多個(gè)關(guān)鍵字,它將節(jié)點(diǎn)大小設(shè)置為磁盤頁(yè)的大小,充分利用了磁盤預(yù)讀的功能。每次讀取磁盤頁(yè)時(shí)就會(huì)讀取一整個(gè)節(jié)點(diǎn),每個(gè)葉子節(jié)點(diǎn)還有指向前后節(jié)點(diǎn)的指針,為的是最大限度的降低磁盤的IO。因?yàn)閿?shù)據(jù)在內(nèi)存中讀取耗費(fèi)的時(shí)間是從磁盤的IO讀取的百萬(wàn)分之一,而Redis是 內(nèi)存中操作數(shù)據(jù),不涉及IO,因此使用了跳表;
這道題,也可以用在問(wèn)你會(huì)哪些SQL優(yōu)化的時(shí)候。
1、數(shù)據(jù)庫(kù)設(shè)計(jì)和表創(chuàng)建時(shí),考慮性能問(wèn)題,比如:?jiǎn)伪聿灰刑嘧侄?,建議在20以內(nèi)、索引并不是越多越好,要根據(jù)查詢有針對(duì)性的創(chuàng)建,考慮在WHERE和ORDER BY命令上涉及的列建立索引,可根據(jù)EXPLAIN來(lái)查看是否用了索引還是全表掃描、選擇合適的數(shù)據(jù)類型、選擇合適索引類型等。
2、SQL編寫時(shí)需要注意,比如:列表數(shù)據(jù)不要拿全表,要使用LIMIT來(lái)分頁(yè),每頁(yè)數(shù)量也不要太大、可通過(guò)開(kāi)啟慢查詢?nèi)罩緛?lái)找出較慢的SQL、避免select *,將需要查找的字段列出來(lái)等。
3,存儲(chǔ)引擎選擇,MyISAM適合SELECT密集型的表,而InnoDB適合INSERT和UPDATE密集型的表 。
4、分庫(kù)分表,比如:分庫(kù)把一個(gè)數(shù)據(jù)庫(kù)分成多個(gè),建議做個(gè)讀寫分離就行了,真正的做分庫(kù)也會(huì)帶來(lái)大量的開(kāi)發(fā)成本,得不償失!不推薦使用、分表就是把一張大表,按照如上過(guò)程都優(yōu)化了,還是查詢卡死,那就把這個(gè)表分成多張表,把一次查詢分成多次查詢,然后把結(jié)果組合返回給用戶。分表分為垂直拆分和水平拆分,通常以某個(gè)字段做拆分項(xiàng)。比如以id字段拆分為100張表:表名為 tableName_id%100。但:分表需要修改源程序代碼,會(huì)給開(kāi)發(fā)帶來(lái)大量工作,極大的增加了開(kāi)發(fā)成本,故:只適合在開(kāi)發(fā)初期就考慮到了大量數(shù)據(jù)存在,做好了分表處理,不適合應(yīng)用上線了再做修改,成本太高等。
5、硬件升級(jí),這辦法是最簡(jiǎn)單的,相對(duì)的成本也高,老板就不愿意了。
6、數(shù)據(jù)庫(kù)升級(jí),比如:把MySQL數(shù)據(jù)庫(kù)換成大數(shù)據(jù)引擎處理數(shù)據(jù)、換成阿里云POLARDB,POLARDB 是阿里云自研的下一代關(guān)系型分布式云原生數(shù)據(jù)庫(kù),100%兼容MySQL,存儲(chǔ)容量最高可達(dá) 100T,性能最高提升至 MySQL 的 6 倍。
方法一:如果 a 表 tid 是自增長(zhǎng),并且是連續(xù)的,b表的id為索引。SQL語(yǔ)句如下。
select * from a,b where a.tid = b.id and a.tid>500000 limit 200;
方法二:如果 a 表的 tid 不是連續(xù)的,那么就需要使用覆蓋索引,tid 要么是主鍵,要么是輔助索引,b 表 id 也需要有索引。SQL語(yǔ)句如下。
select * from b, (select tid from a limit 50000,200) a where b.id = a.tid;
JVM內(nèi)存結(jié)構(gòu)有:程序計(jì)數(shù)器 、堆內(nèi)存 、 方法區(qū) 和 棧 (java虛擬機(jī)棧和本地方法棧)。
程序計(jì)數(shù)器(Program Counter Register)是一塊較小的內(nèi)存空間,它的作用可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。在虛擬機(jī)的概念模型里(僅是概念模型,各種虛擬機(jī)可能會(huì)通過(guò)一些更高效的方式去實(shí)現(xiàn)),字節(jié)碼解釋器工作時(shí)就是通過(guò)改變這個(gè)計(jì)數(shù)器的值來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個(gè)計(jì)數(shù)器來(lái)完成。
堆內(nèi)存是JVM中最大的一塊由年輕代和老年代組成,而年輕代內(nèi)存又被分成三部分, Eden空間 、 From Survivor空間 、 To Survivor空間 ,默認(rèn)情況下年輕代按照 8:1:1 的比例來(lái)分配;
方法區(qū)存儲(chǔ)類信息、常量、靜態(tài)變量等數(shù)據(jù),是線程共享的區(qū)域,為與Java堆區(qū)分,方法區(qū)還有一個(gè)別名Non-Heap(非堆);棧又分為java虛擬機(jī)棧和本地方法棧主要用于方法的執(zhí)行。方法區(qū)可理解為一種規(guī)范,其實(shí)現(xiàn)比如永久代、元空間。
Java虛擬機(jī)棧(Java Virtual Machine Stacks)也是線程私有的,它的生命周期與線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法被執(zhí)行的時(shí)候都會(huì)同時(shí)創(chuàng)建一個(gè)棧幀(Stack Frame)用于存儲(chǔ)局部變量表、操作棧、動(dòng)態(tài)鏈接、方法出口等信息。每一個(gè)方法被調(diào)用直至執(zhí)行完成的過(guò)程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過(guò)程。
本地方法棧(Native Method Stacks)與虛擬機(jī)棧所發(fā)揮的作用是非常相似的,其區(qū)別不過(guò)是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。虛擬機(jī)規(guī)范中對(duì)本地方法棧中的方法使用的語(yǔ)言、使用方式與數(shù)據(jù)結(jié)構(gòu)并沒(méi)有強(qiáng)制規(guī)定,因此具體的虛擬機(jī)可以自由實(shí)現(xiàn)它。
如果沒(méi)有Survivor,Eden區(qū)每進(jìn)行一次Minor GC ,并且沒(méi)有年齡限制的話, 存活的對(duì)象就會(huì)被送到老年代。這樣一來(lái),老年代很快被填滿,觸發(fā)Major GC(因?yàn)镸ajor GC一般伴隨著Minor GC,也可以看做觸發(fā)了Full GC)。老年代的內(nèi)存空間遠(yuǎn)大于新生代,進(jìn)行一次Full GC消耗的時(shí)間比Minor GC長(zhǎng)得多。
面試官可能會(huì)問(wèn):執(zhí)行時(shí)間長(zhǎng)有什么壞處?
頻發(fā)的Full GC消耗的時(shí)間很長(zhǎng),會(huì)影響大型程序的執(zhí)行和響應(yīng)速度。
假如增加老年代空間,更多存活對(duì)象才能填滿老年代。雖然降低Full GC頻率,但是隨著老年代空間加大,一旦發(fā)生Full GC,執(zhí)行所需要的時(shí)間更長(zhǎng)。
假如減少老年代空間,雖然Full GC所需時(shí)間減少,但是老年代很快被存活對(duì)象填滿,Full GC頻率增加。
所以Survivor的存在意義,就是減少被送到老年代的對(duì)象,進(jìn)而減少Full GC的發(fā)生,Survivor的預(yù)篩選保證,只有經(jīng)歷16 次Minor GC還能在新生代中存活的對(duì)象,才會(huì)被送到老年代。
這問(wèn)題有的面試官是禮貌性的問(wèn),也不是很注意你回答什么,因?yàn)榇藭r(shí)估計(jì)面試就是涼涼啦。
但是,有反問(wèn)的機(jī)會(huì),大部分還是覺(jué)得你不錯(cuò),被錄取的概率非常大,所以還是得慎重回答
不管ta是怎么樣的心態(tài),咱們表現(xiàn)好自己就行。
這個(gè)問(wèn)題看上去可有可無(wú),其實(shí)很關(guān)鍵,一般面試官不喜歡說(shuō)“沒(méi)問(wèn)題”的人,因?yàn)槠浜茏⒅貑T工的個(gè)性和創(chuàng)新能力。企業(yè)不喜歡求職者問(wèn)個(gè)人福利之類的問(wèn)題,如果有人這樣問(wèn):貴公司對(duì)新入公司的員工有沒(méi)有什么培訓(xùn)項(xiàng)目,我可以參加嗎?或者說(shuō)貴公司的晉升機(jī)制是什么樣的?企業(yè)將很歡迎,因?yàn)轶w現(xiàn)出你對(duì)學(xué)習(xí)的熱情和對(duì)公司的忠誠(chéng)度以及你的上進(jìn)心。
以上就是順豐科技面試的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!
每個(gè)人都需要一臺(tái)速度更快、更穩(wěn)定的 PC。隨著時(shí)間的推移,垃圾文件、舊注冊(cè)表數(shù)據(jù)和不必要的后臺(tái)進(jìn)程會(huì)占用資源并降低性能。幸運(yùn)的是,許多工具可以讓 Windows 保持平穩(wěn)運(yùn)行。
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號(hào)
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://m.miracleart.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號(hào)