更新時(shí)間:2020-08-10 16:11:48 來源:動(dòng)力節(jié)點(diǎn) 瀏覽2234次
1.為什么等待和通知是在Object類而不是Thread中聲明的?
一個(gè)棘手的Java問題,如果Java編程語言不是你設(shè)計(jì)的,你怎么能回答這個(gè)問題呢。Java編程的常識(shí)和深入了解有助于回答這種棘手的Java核心方面的面試問題。
為什么wait,notify和notifyAll是在Object類中定義的而不是在Thread類中定義
這是有名的Java面試問題,招2~4年經(jīng)驗(yàn)的到高級Java開發(fā)人員面試都可能碰到。
這個(gè)問題的好在它能反映了面試者對等待通知機(jī)制的了解,以及他對此主題的理解是否明確。就像為什么Java中不支持多繼承或者為什么String在Java中是final的問題一樣,這個(gè)問題也可能有多個(gè)答案。
為什么在Object類中定義wait和notify方法,每個(gè)人都能說出一些理由。從我的面試經(jīng)驗(yàn)來看,wait和nofity仍然是大多數(shù)Java程序員最困惑的,特別是2到3年的開發(fā)人員,如果他們要求使用wait和notify,他們會(huì)很困惑。因此,如果你去參加Java面試,請確保對wait和notify機(jī)制有充分的了解,并且可以輕松地使用wait來編寫代碼,并通過生產(chǎn)者-消費(fèi)者問題或?qū)崿F(xiàn)阻塞隊(duì)列等了解通知的機(jī)制。
為什么等待和通知需要從同步塊或方法中調(diào)用,以及Java中的wait,sleep和yield方法之間的差異,如果你還沒有讀過,你會(huì)覺得有趣。為何wait,notify和notifyAll屬于Object類?為什么它們不應(yīng)該在Thread類中?以下是我認(rèn)為有意義的一些想法:
1)wait和notify不僅僅是普通方法或同步工具,更重要的是它們是Java中兩個(gè)線程之間的通信機(jī)制。對語言設(shè)計(jì)者而言,如果不能通過Java關(guān)鍵字(例如synchronized)實(shí)現(xiàn)通信此機(jī)制,同時(shí)又要確保這個(gè)機(jī)制對每個(gè)對象可用,那么Object類則是的正確聲明位置。記住同步和等待通知是兩個(gè)不同的領(lǐng)域,不要把它們看成是相同的或相關(guān)的。同步是提供互斥并確保Java類的線程安全,而wait和notify是兩個(gè)線程之間的通信機(jī)制。
2)每個(gè)對象都可上鎖,這是在Object類而不是Thread類中聲明wait和notify的另一個(gè)原因。
3)在Java中為了進(jìn)入代碼的臨界區(qū),線程需要鎖定并等待鎖定,他們不知道哪些線程持有鎖,而只是知道鎖被某個(gè)線程持有,并且他們應(yīng)該等待取得鎖,而不是去了解哪個(gè)線程在同步塊內(nèi),并請求它們釋放鎖定。
4)Java是基于Hoare的監(jiān)視器的思想。在Java中,所有對象都有一個(gè)監(jiān)視器。
線程在監(jiān)視器上等待,為執(zhí)行等待,我們需要2個(gè)參數(shù):
一個(gè)線程
一個(gè)監(jiān)視器(任何對象)
在Java設(shè)計(jì)中,線程不能被指定,它總是運(yùn)行當(dāng)前代碼的線程。但是,我們可以指定監(jiān)視器(這是我們稱之為等待的對象)。這是一個(gè)很好的設(shè)計(jì),因?yàn)槿绻覀兛梢宰屓魏纹渌€程在所需的監(jiān)視器上等待,這將導(dǎo)致“入侵”,導(dǎo)致在設(shè)計(jì)并發(fā)程序時(shí)會(huì)遇到困難。請記住,在Java中,所有在另一個(gè)線程的執(zhí)行中侵入的操作都被棄用了(例如stop方法)。
2.為什么Java不支持運(yùn)算符重載?
另一個(gè)類似棘手的Java問題。為什么C++支持運(yùn)算符重載而Java不支持?有人可能會(huì)說+運(yùn)算符在Java中已被重載用于字符串連接,不要被這些論據(jù)所欺騙。
與C++不同,Java不支持運(yùn)算符重載。Java不能為程序員提供自由的標(biāo)準(zhǔn)算術(shù)運(yùn)算符重載,例如+,-,*和/等。如果你以前用過C++,那么Java與C++相比少了很多功能,例如Java不支持多重繼承,Java中沒有指針,Java中沒有引用傳遞。另一個(gè)類似的問題是關(guān)于Java通過引用傳遞,這主要表現(xiàn)為Java是通過值還是引用傳參。雖然我不知道背后的真正原因,但我認(rèn)為以下說法有些道理,為什么Java不支持運(yùn)算符重載。
1)簡單性和清晰性。清晰性是Java設(shè)計(jì)者的目標(biāo)之一。設(shè)計(jì)者不是只想復(fù)制語言,而是希望擁有一種清晰,真正面向?qū)ο蟮恼Z言。添加運(yùn)算符重載比沒有它肯定會(huì)使設(shè)計(jì)更復(fù)雜,并且它可能導(dǎo)致更復(fù)雜的編譯器,或減慢JVM,因?yàn)樗枰鲱~外的工作來識(shí)別運(yùn)算符的實(shí)際含義,并減少優(yōu)化的機(jī)會(huì),以保證Java中運(yùn)算符的行為。
2)避免編程錯(cuò)誤。Java不允許用戶定義的運(yùn)算符重載,因?yàn)槿绻试S程序員進(jìn)行運(yùn)算符重載,將為同一運(yùn)算符賦予多種含義,這將使任何開發(fā)人員的學(xué)習(xí)曲線變得陡峭,事情變得更加混亂。據(jù)觀察,當(dāng)語言支持運(yùn)算符重載時(shí),編程錯(cuò)誤會(huì)增加,從而增加了開發(fā)和交付時(shí)間。由于Java和JVM已經(jīng)承擔(dān)了大多數(shù)開發(fā)人員的責(zé)任,如在通過提供垃圾收集器進(jìn)行內(nèi)存管理時(shí),因?yàn)檫@個(gè)功能增加污染代碼的機(jī)會(huì),成為編程錯(cuò)誤之源,因此沒有多大意義。
3)JVM復(fù)雜性。從JVM的角度來看,支持運(yùn)算符重載使問題變得更加困難。通過更直觀,更干凈的方式使用方法重載也能實(shí)現(xiàn)同樣的事情,因此不支持Java中的運(yùn)算符重載是有意義的。與相對簡單的JVM相比,復(fù)雜的JVM可能導(dǎo)致JVM更慢,并為保證在Java中運(yùn)算符行為的確定性從而減少了優(yōu)化代碼的機(jī)會(huì)。
4)讓開發(fā)工具處理更容易。這是在Java中不支持運(yùn)算符重載的另一個(gè)好處。省略運(yùn)算符重載使語言更容易處理,這反過來又更容易開發(fā)處理語言的工具,例如IDE或重構(gòu)工具。Java中的重構(gòu)工具遠(yuǎn)勝于C++。
3.如何使用雙重檢查鎖定在Java中創(chuàng)建線程安全的單例?
艱難的核心Java面試問題.這個(gè)Java問題也常被問:什么是線程安全的單例,你怎么創(chuàng)建它。好吧,在Java 5之前的版本,使用雙重檢查鎖定創(chuàng)建單例Singleton時(shí),如果多個(gè)線程試圖同時(shí)創(chuàng)建Singleton實(shí)例,則可能有多個(gè)Singleton實(shí)例被創(chuàng)建。從Java 5開始,使用Enum創(chuàng)建線程安全的Singleton很容易。但如果面試官堅(jiān)持雙重檢查鎖定,那么你必須為他們編寫代碼。記得使用volatile變量。
4.為什么枚舉單例在Java中更好
枚舉單例是使用一個(gè)實(shí)例在Java中實(shí)現(xiàn)單例模式的新方法。雖然Java中的單例模式存在很長時(shí)間,但枚舉單例是相對較新的概念,在引入Enum作為關(guān)鍵字和功能之后,從Java5開始在實(shí)踐中。本文與之前關(guān)于Singleton的內(nèi)容有些相關(guān),其中討論了有關(guān)Singleton模式的面試中的常見問題,以及10個(gè)Java枚舉示例,其中我們看到了如何通用枚舉可以。這篇文章是關(guān)于為什么我們應(yīng)該使用Eeame作為Java中的單例,它比傳統(tǒng)的單例方法相比有什么好處等等。
5.Java枚舉和單例模式
Java中的枚舉單例模式是使用枚舉在Java中實(shí)現(xiàn)單例模式。單例模式在Java中早有應(yīng)用,但使用枚舉類型創(chuàng)建單例模式時(shí)間卻不長.如果感興趣,你可以了解下構(gòu)建者設(shè)計(jì)模式和裝飾器設(shè)計(jì)模式。
1)枚舉單例易于書寫
這是迄今為止最大的優(yōu)勢,如果你在Java 5之前一直在編寫單例,你知道,即使雙檢查鎖定,你仍可以有多個(gè)實(shí)例。雖然這個(gè)問題通過Java內(nèi)存模型的改進(jìn)已經(jīng)解決了,從Java 5開始的volatile類型變量提供了保證,但是對于許多初學(xué)者來說,編寫起來仍然很棘手。與同步雙檢查鎖定相比,枚舉單例實(shí)在是太簡單了。如果你不相信,那就比較一下下面的傳統(tǒng)雙檢查鎖定單例和枚舉單例的代碼
以上就是動(dòng)力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)的小編針對“2020年比較難的Java軟件開發(fā)面試題”的內(nèi)容進(jìn)行的回答,希望對大家有所幫助,如有疑問,請?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
初級 202925
初級 203221
初級 202629
初級 203743