今日份阿里Java后端面試真題,看完你學(xué)會了嘛没炒?附面試福利

一. 談?wù)勀銓ava平臺的理解? "Java 是解釋執(zhí)行"涛癌,這句話正確么?

典型回答:

Java本身是一種面向?qū)ο蟮恼Z言,最顯著的特點(diǎn)有兩個方面,一個是所謂的"書寫一次,到處運(yùn)行";能夠非常容易地獲得跨平臺能力;另外就是垃圾收集器(GC),Java通 過垃圾收集器回收分配內(nèi)存,大部分情況下送火,程序員不需要自己操心內(nèi)存的分配和回收拳话。我們?nèi)粘=佑|到JRE或者JDK。JRE也就是Java運(yùn)行環(huán)境,包含了JVM和Java類庫,以及一些模塊等种吸。而JDK可以看作是JRE的一個超集,提供了更多的工具,比如編譯器各種診斷工具弃衍。

"對于Java是解釋執(zhí)行"這句話,這個說法不準(zhǔn)確骨稿。我們開發(fā)的Java的源代碼,首先通過Javac編譯成為字節(jié)碼,然后在運(yùn)行時通過Java虛擬機(jī)內(nèi)嵌的解釋器將字節(jié)碼轉(zhuǎn)換為最終的機(jī)器碼笨鸡。但是常見的JVM,比如我們大數(shù)據(jù)情況使用的0racleJDK提供的HostpotJVM,提供了JIT編譯器,就是通常所說的動態(tài)編譯器,JIT能夠在運(yùn)行時將熱點(diǎn)代碼(高頻調(diào)用的方法和代碼塊)編譯成機(jī)器碼,這種情況下部分熱點(diǎn)就屬于編譯執(zhí)行,而不是解釋執(zhí)行姜钳。這樣類似于緩存技術(shù),運(yùn)行時在遇到熱點(diǎn)代碼可以直接執(zhí)行,而不是先解釋在執(zhí)行坦冠。

知識擴(kuò)展:

在運(yùn)行時 , JVM通過類加載器加載字節(jié)碼,解釋或者編譯執(zhí)行形耗。就像我們前面提到的,主流的Java版本中,如JDK8實(shí)際是解釋和編譯混合的一種模式,即所謂的混合模式。JIT編譯器分為多種模式(Server模式C1ient模式AOT模式)通常運(yùn)行在Server模式的JVM,會進(jìn)行上萬次調(diào)用以收集足夠的信息進(jìn)行高效編譯,client模式這個門限是1500次辙浑。

Oracle Hostpot JVM內(nèi)置了兩個不同的JIT compiler,C1對應(yīng) 前面說的client模式激涤,適用于對于啟動速度敏感的應(yīng)用,比如普通Java桌面應(yīng)用;C2對應(yīng)Server模式,它的優(yōu)點(diǎn)是為長時間運(yùn)行的服務(wù)器端應(yīng)用設(shè)計的判呕。

Java虛擬機(jī)啟動時倦踢, 可以指定不同的參數(shù)對運(yùn)行模式進(jìn)行選擇。比如鲸阻,執(zhí)行"-Xint",就是告訴JVM只進(jìn)行解釋執(zhí)行,不對代碼進(jìn)行編譯,這種模式拋棄了JIT可能帶來的性能優(yōu)勢躺坟。畢竟解釋器是逐條讀入,逐條解釋運(yùn)行的匠题。與其相對性的,還有一個"Xcomp"參數(shù),這是告訴JVM關(guān)閉解釋器,不要進(jìn)行解釋執(zhí)行,或者叫做最大優(yōu)化級別晤碘。那你可能會問這種模式是不是最高效啊?簡單來說,還真未必功蜓。"-Xcomp" 會導(dǎo)致JVM啟動變慢非常多..

除了日常最常見的Java使用模式园爷,其實(shí)還有一種新的編譯方式,即所謂的AOT,直接將字節(jié)碼編譯成機(jī)器碼,這樣就避免了JIT預(yù)熱等各方面的開銷,比如Oracle JDK 9就引入了實(shí)性質(zhì)的AOT特性,并且增加了jaotc工具式撼。

另外,JVM作為一個強(qiáng)大的平臺童社,不僅僅只有Java語言可以運(yùn)行在JVM上,本質(zhì)上合規(guī)的字節(jié)碼都可以運(yùn)行,Java語言自身也為此提供了便利,我們可以看到類似ClojureScala Groovy JRuby Jython等 大量JVM語言,活躍在不同的場景。

二. 請對比Exception和Error,另外著隆,運(yùn)行時異常與一般異常有什么區(qū)別?

典型回答:

Exception和Error都是繼承了Throwable類,在Java中只有Throwable類型的實(shí)例才可以被拋出或者捕獲,它是異常處理機(jī)制的基本組成類型扰楼。Exceptoin和Error體現(xiàn)了Java平臺設(shè)計者對于不同異常情況的分類。Exception是程序正常運(yùn)行中,可以預(yù)料的意外情況美浦,可以并且應(yīng)該被捕獲,進(jìn)行相應(yīng)處理弦赖。Error是指在正常情況下,不大可能出現(xiàn)的情況,絕大部分的Error都會導(dǎo)致處于非正常的不可恢復(fù)狀態(tài)。既然是非正常情況,所以不便于也不需要捕獲,常見的比如.OutofMemoryError之類抵代,都是Error的子類腾节。

Exceptoin又分為可檢查異常和不檢查異常,可檢查異常在代碼里必須顯示地進(jìn)行捕獲處理,這是編譯器檢查的一部分荤牍。不檢查異常就是所謂的運(yùn)行時異常案腺,類似于Nul1PointerException ArrayIndex0utofBoundsException之類,通常是可以編碼避免的邏輯錯誤,具體根據(jù)需要來進(jìn)行判斷是否需要捕獲,并不會在編譯期強(qiáng)制要求。

知識擴(kuò)展:

在開發(fā)中盡量不要捕獲類似Exceptio這樣的通用異常,而是應(yīng)該捕獲特定異常.這是因為我們在日常的開發(fā)和合作中康吵,我們讀代碼的機(jī)會往往超過寫代碼,軟劈榨,件工程是門協(xié)作的藝術(shù),所以我們有義務(wù)讓自己的代碼能夠直接地體現(xiàn)出盡量多的信息,而泛泛的Exception之類,恰恰隱藏了我們的目的。另外晦嵌,我們也要保證程序不會捕獲到我們不希望捕獲的異常同辣。比如,你可能更希望RuntimeException 被擴(kuò)散出來,而不是被捕獲拷姿。

在開發(fā)中不要生吞異常。這是異常處理中要特別注意的事情,因為很可能會導(dǎo)致非常難以診斷的詭異情況旱函。生吞異常,往往是基于假設(shè)這段代碼可能不會發(fā)生,或者感覺忽略異常是無所謂的,但是千萬不要在產(chǎn)品代碼做這種假設(shè)!如果我們不把異常拋出來,或者也沒有輸出日志之類,程序可能在后續(xù)代碼以不可控的方式結(jié)束响巢。沒有人能夠輕易判斷究竟是哪里出了異常,以及是什么原因產(chǎn)生了異常。

在開發(fā)中不要輸出標(biāo)準(zhǔn)錯誤(STERR)棒妨,因為有時候你很難判斷出到底輸出到哪里去了踪古。尤其是分布式系統(tǒng),如果發(fā)生異常,但是無法找到堆棧軌跡,這純屬是為診斷設(shè)置障礙。所以最好使用產(chǎn)品日志,詳細(xì)地輸出到日志系統(tǒng)里券腔。

Throw early,catch late伏穆。在開發(fā)中可能會出現(xiàn)各種情況,比如獲取配置失敗之類的。在發(fā)現(xiàn)問題的時候,第一時間拋出纷纫,能夠更加清晰地反映問題,這是Throw early枕扫。 catch late就是 我們經(jīng)常煩惱的問題,捕獲異常后,需要怎么處理?最差的方式,就是我們前面提到的"生吞異常",本質(zhì)上就是掩蓋問題。如果實(shí)在不知道如何處理辱魁,可以選擇保留原有異常的cause信息,直接再拋出或者構(gòu)建新的異常拋出去烟瞧。在更高層,因為有了清晰的(業(yè)務(wù))邏輯,往往會更清楚合適的處理方式是什么。

有時候,我們會根據(jù)需要自己定義異常商叹,這個時候除了保證提供足夠的信息燕刻,還需要考慮兩點(diǎn)。一是否需要定異常CheckedException,因為這種類型的設(shè)計初衷是為了從異常情況恢復(fù),作為異常設(shè)計者,我們往往有充足信息進(jìn)行分類剖笙。在保證診斷信息足夠的同時,也要考慮避免包含敏感信息,因為那樣可能會導(dǎo)致潛在的安全問題卵洗。如果我們看Java的標(biāo)準(zhǔn)類庫,你可能注意到類似java. net. ConnectException,出錯信息是類似"Connection refused", 而不包含具體的機(jī)器名IP端口等,一個重要的考量就是信息安全。類似的情況在日志系統(tǒng)中也有,比如,用戶數(shù)據(jù)一般是不可以輸出到日志里面的弥咪。

try-catch代碼段會產(chǎn)生額外的性能開銷,或者換個角度來說,它往往會影響JVM對代碼進(jìn)行優(yōu)化,所以建議僅捕獲有必要的代碼段.盡量不要一個大的try包住整段代碼过蹂,與此同時,利用異常控制代碼流程聚至,也不是一個好主意,遠(yuǎn)比我們通常意義上的條件語句要低效酷勺。

額外:

NoClassDeF oundError和ClassNotFoundException的區(qū)別?

首先NoClassDeFoundError是一個錯誤,ClassNotFoundException是一個異常扳躬。ClassNotFoundException的產(chǎn)生原因,Java支持使用Class. froName方法來動態(tài)地加載類,任意一個類的類名如果被作為參數(shù)傳遞給這個方法都將導(dǎo)致該類被加載到JVM內(nèi)存中,如果這個類在類路徑中沒有被找到,那么此時就會在運(yùn)行時拋出ClassNotFoundException異常脆诉。

另外還有一個導(dǎo)致ClassNotFoundException的原因就是,當(dāng)一個類已經(jīng)被某個類加載器加載到內(nèi)存中,此時另一個類加載器又嘗試著動態(tài)地從同一個包中加載這個類贷币。

NoClassDeFoundError產(chǎn)生的原因在于:如果JVM或者ClassLoader實(shí)例嘗試加載類的時候找不到類的定義击胜。例如要查找的類在編譯的時候是存在的,運(yùn)行的時候,找不到了役纹。這個時候就會導(dǎo)致NoClassDefFoundError.造成該問題的原因可能是打包過程中漏掉了部分類,或者jar包出現(xiàn)損壞或者篡改偶摔。解決這個問題的辦法就是查找那些在開發(fā)期間存在與類路徑下,但在運(yùn)行期間卻不在類路徑下的類。

三. 對比Hashtable促脉、HashMap辰斋、TreeMap有什么不同?

典型回答:

HashTable HashMap TreeMap都是最常見的一些Map實(shí) 現(xiàn),是以鍵值對的形式存儲和操作數(shù)據(jù)的容器類型策州。

HashTable是早期Java類庫提供的一個哈希表實(shí)現(xiàn),本身是同步的,不支持nu11鍵和值,由于同步導(dǎo)致的性能開銷,所以已經(jīng)很少被推薦使用。

HashMap是應(yīng)用更加廣泛的哈希表實(shí)現(xiàn)宫仗,行為大致.上與HashTable- -致,主要區(qū)別在于HashMap不是同步的够挂,支持nul1鍵和值等。通常情況下, HashMap進(jìn)行put或者get操作,可以達(dá)到常數(shù)時間的性能锰什,所以它是絕大部分利用鍵值對存儲場景的首選,比如下硕,實(shí)現(xiàn)一個用戶ID和用戶信息對應(yīng)的運(yùn)行時存儲結(jié)構(gòu)丁逝。

TreeMap則是基于紅黑樹的一種提供順序訪問的Map,和HashMap不同,它的getremove之類操作都是0(long(n)的時間復(fù)雜度汁胆,具體順序可以由指定的Comparator來決定或者根據(jù)鍵的自然順序來判斷。

知識擴(kuò)展:

HashMap實(shí)現(xiàn)原理是經(jīng)常被問到的一個問題,以下基于JDK1.8分析霜幼。

1. 內(nèi)部存儲

HashMap的內(nèi)部存儲是一個數(shù)組,數(shù)組的元素Node實(shí)現(xiàn)了Map.Entry接口(hash, key, value, next) , next非空時指向定位相同的另一個Entry,如圖:

JDK 8之前嫩码,其內(nèi)部是由數(shù)組+鏈表來實(shí)現(xiàn)的,而JDK 8對于鏈表長度超過8的鏈表將轉(zhuǎn)儲為紅黑樹罪既。

2. 容量(capacity)和負(fù)載因子(loadFactor)

簡單的說, capacity就是數(shù)組的大小铸题,loadFactory就是數(shù)組填滿程度的最大比列。當(dāng)數(shù)組中的元素的數(shù)目大于capaci ty*loadFactor時就需要擴(kuò)容,調(diào)整數(shù)組的大小為當(dāng)前的2 倍琢感。同時初始化容量的大小也是2的次冪(大于等于設(shè)定容量的最小次冪),則數(shù)組的大小在擴(kuò)容前后都將是2的次冪丢间。默認(rèn)的容量為16,負(fù)載因子為0.75。

3. put方法的大致的思路

  • 如果key的值為null,則將該鍵值對添加到table[0]處驹针,遍歷該鏈表烘挫,如果有key為null,則將value替換柬甥。
  • 如果key不為null,獲取key的hashCode值,經(jīng)過indexFor()方法運(yùn)算得到的值作為標(biāo)識,但由于hashCode的值并不唯一,經(jīng)過運(yùn)算獲取的值也不能保證唯一(哈希沖突),所以,經(jīng)過以上運(yùn)算得來的數(shù)值只能作為數(shù)組的索引饮六。
  • 當(dāng)通過索引定位到這個節(jié)點(diǎn)時,在遍歷該鏈表,判斷是否存在相同的key對象,如果存在就用新的value覆蓋舊的value
  • 如果不存在,就創(chuàng)建一個Entry對象添加到table[i]處,如果table[i]已經(jīng)存在其他元素苛蒲,那么新Entry對象將會保存在鏈表的表頭卤橄,通過next指針指向原有的Entry對象,形成鏈表結(jié)構(gòu)。
  • 當(dāng)鏈表的結(jié)構(gòu)太長時(默認(rèn)超過8個元素),鏈表就會轉(zhuǎn)為紅黑樹臂外。

4. get方法的大致的思路

  • 對key進(jìn)行nu11檢查窟扑。如果key是nu11,table[0]這個位置的元素將被返回
  • key的hashcode() 方法被調(diào)用漏健,然后計算hash值嚎货。
  • indexFor (hash, table. length)用來計算要獲取的Entry對象在table數(shù)組中的精確的位置(使用剛才計算的hash值)
  • 在獲取了table數(shù)組的索引之后,會迭代鏈表漾肮,調(diào)用equals()方法檢查key的相等性厂抖,如果equals()方法返回true,get方法返回Entry對象的value克懊,否則忱辅,返回null七蜘。

四. ArrayList Vector LinkedList的 區(qū)別?

典型回答:

這三者都是實(shí)現(xiàn)集合框架中的List,也就是所謂的有序集合,因此具體功能也比較類似,比如都提供按照位置進(jìn)行定位添加或者刪除的操作,都提供迭代器以遍歷其內(nèi)容等。但因為具體的設(shè)計區(qū)別在行為性能線程安全等方面,表現(xiàn)又有很大不同墙懂。

Vector是Java早期提供的線程安全的動態(tài)數(shù)組,如果不需要線程安全,并不建議選擇,畢竟同步是有額外開銷的橡卤。Vector內(nèi) 部是使用對象數(shù)組來保存數(shù)據(jù),可以根據(jù)需要自動的增加容量,當(dāng)數(shù)組以滿時,會創(chuàng)建新的數(shù)組,并拷貝原有數(shù)組數(shù)據(jù)。

ArrayList是應(yīng)用更加廣泛的動態(tài)數(shù)組實(shí)現(xiàn)损搬,它本身不是線程安全的,所以性能要好很多碧库。與Vector近似,ArrayList也是可以根據(jù)需要調(diào)整容量,不過兩者的調(diào)整邏輯有所區(qū)別, Vector在擴(kuò)容時會提高1倍,而ArrayList則是增加50%巧勤。

LinkedList顧明思議是Java提供的雙向鏈表,所以它不需要像.上面兩種那樣調(diào)整容量嵌灰,它也不是線程安全的。

Vector和ArrayList作為動態(tài)數(shù)組,其內(nèi)部元素以數(shù)組形式順序存儲的颅悉,所以非常適合隨即訪問的場合沽瞭。除了尾部出入元素和刪除元素,往往性能會相對較差,比如我們在中間位置插入一個元素,需要移動后續(xù)所有元素。而LinkedList進(jìn)行節(jié)點(diǎn)插入刪除卻要高效得很多,但是隨即訪問性能則要比動態(tài)數(shù)組慢剩瓶。

文末福利

限于篇幅驹溃,今日份大廠面試真題到此為止;需要的更多的Java后端面試題延曙、視頻學(xué)習(xí)資料豌鹤、架構(gòu)師成長路線圖的朋友點(diǎn)擊下方傳送門, 即可免費(fèi)領(lǐng)取面試資料和視頻學(xué)習(xí)資料

傳送門

筆者整理的面試題包含但不限于Kafka枝缔、Mysql布疙、Tomcat、Docker魂仍、Spring拐辽、MyBatis、Nginx擦酌、Netty俱诸、Dubbo、Redis赊舶、Netty睁搭、Spring cloud、分布式笼平、高并發(fā)园骆、性能調(diào)優(yōu)、微服務(wù)等架構(gòu)技術(shù)

以下是筆者整理的部分面試題截圖

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寓调,一起剝皮案震驚了整個濱河市锌唾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖晌涕,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滋捶,死亡現(xiàn)場離奇詭異,居然都是意外死亡余黎,警方通過查閱死者的電腦和手機(jī)重窟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惧财,“玉大人巡扇,你說我怎么就攤上這事】逯裕” “怎么了厅翔?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長帘靡。 經(jīng)常有香客問我知给,道長,這世上最難降的妖魔是什么描姚? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮戈次,結(jié)果婚禮上轩勘,老公的妹妹穿的比我還像新娘。我一直安慰自己怯邪,他們只是感情好绊寻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著悬秉,像睡著了一般澄步。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上和泌,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天村缸,我揣著相機(jī)與錄音,去河邊找鬼武氓。 笑死梯皿,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的县恕。 我是一名探鬼主播东羹,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼忠烛!你這毒婦竟也來了属提?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤美尸,失蹤者是張志新(化名)和其女友劉穎冤议,沒想到半個月后旬迹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡求类,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年奔垦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尸疆。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡椿猎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出寿弱,到底是詐尸還是另有隱情犯眠,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布症革,位于F島的核電站筐咧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏噪矛。R本人自食惡果不足惜量蕊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望艇挨。 院中可真熱鬧残炮,春花似錦、人聲如沸缩滨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脉漏。三九已至苞冯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侧巨,已是汗流浹背舅锄。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刃泡,地道東北人巧娱。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像烘贴,于是被迫代替她去往敵國和親禁添。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容