比較難的java經(jīng)典面試題及答案

比較難的java經(jīng)典面試題及答案

深圳達(dá)內(nèi)教育      2022-04-18 18:00:01     14

比較難的java經(jīng)典面試題及答案,  為什么等待和通知是在Object類而不是Thread中聲明的?  一個(gè)棘手的Java問(wèn)題,如果Java編程語(yǔ)言不是你設(shè)計(jì)的,你怎么能回答

課程價(jià)格 請(qǐng)咨詢

上課時(shí)段: 授課校區(qū):

詳細(xì)介紹



  為什么等待和通知是在Object類而不是Thread中聲明的?


  一個(gè)棘手的Java問(wèn)題,如果Java編程語(yǔ)言不是你設(shè)計(jì)的,你怎么能回答這個(gè)問(wèn)題呢。Java編程的常識(shí)和深入了解有助于回答這種棘手的Java核心方面的面試問(wèn)題。


  為什么wait,notify和notifyAll是在Object類中定義的而不是在Thread類中定義


  這是有名的Java面試問(wèn)題,招2~4年經(jīng)驗(yàn)的到高級(jí)Java開(kāi)發(fā)人員面試都可能碰到。


  這個(gè)問(wèn)題的好在它能反映了面試者對(duì)等待通知機(jī)制的了解,以及他對(duì)此主題的理解是否明確。就像為什么Java中不支持多繼承或者為什么String在Java中是final的問(wèn)題一樣,這個(gè)問(wèn)題也可能有多個(gè)答案。


  為什么在Object類中定義wait和notify方法,每個(gè)人都能說(shuō)出一些理由。從我的面試經(jīng)驗(yàn)來(lái)看,wait和nofity仍然是大多數(shù)Java程序員最困惑的,特別是2到3年的開(kāi)發(fā)人員,如果他們要求使用wait和notify,他們會(huì)很困惑。因此,如果你去參加Java面試,請(qǐng)確保對(duì)wait和notify機(jī)制有充分的了解,并且可以輕松地使用wait來(lái)編寫(xiě)代碼,并通過(guò)生產(chǎn)者-消費(fèi)者問(wèn)題或?qū)崿F(xiàn)阻塞隊(duì)列等了解通知的機(jī)制。


  為什么等待和通知需要從同步塊或方法中調(diào)用,以及Java中的wait,sleep和yield方法之間的差異,如果你還沒(méi)有讀過(guò),你會(huì)覺(jué)得有趣。為何wait,notify和notifyAll屬于Object類?為什么它們不應(yīng)該在Thread類中?以下是我認(rèn)為有意義的一些想法:


  1)wait和notify不僅僅是普通方法或同步工具,更重要的是它們是Java中兩個(gè)線程之間的通信機(jī)制。對(duì)語(yǔ)言設(shè)計(jì)者而言,如果不能通過(guò)Java關(guān)鍵字(例如synchronized)實(shí)現(xiàn)通信此機(jī)制,同時(shí)又要確保這個(gè)機(jī)制對(duì)每個(gè)對(duì)象可用,那么Object類則是的正確聲明位置。記住同步和等待通知是兩個(gè)不同的領(lǐng)域,不要把它們看成是相同的或相關(guān)的。同步是提供互斥并確保Java類的線程安全,而wait和notify是兩個(gè)線程之間的通信機(jī)制。


  2)每個(gè)對(duì)象都可上鎖,這是在Object類而不是Thread類中聲明wait和notify的另一個(gè)原因。


  3)在Java中為了進(jìn)入代碼的臨界區(qū),線程需要鎖定并等待鎖定,他們不知道哪些線程持有鎖,而只是知道鎖被某個(gè)線程持有,并且他們應(yīng)該等待取得鎖,而不是去了解哪個(gè)線程在同步塊內(nèi),并請(qǐng)求它們釋放鎖定。


  4)Java是基于Hoare的監(jiān)視器的思想(http://en.wikipedia.org/wiki/...。在Java中,所有對(duì)象都有一個(gè)監(jiān)視器。


  線程在監(jiān)視器上等待,為執(zhí)行等待,我們需要2個(gè)參數(shù):


  一個(gè)線程


  一個(gè)監(jiān)視器(任何對(duì)象)


  在Java設(shè)計(jì)中,線程不能被指定,它總是運(yùn)行當(dāng)前代碼的線程。但是,我們可以指定監(jiān)視器(這是我們稱之為等待的對(duì)象)。這是一個(gè)很好的設(shè)計(jì),因?yàn)槿绻覀兛梢宰屓魏纹渌€程在所需的監(jiān)視器上等待,這將導(dǎo)致“入侵”,導(dǎo)致在設(shè)計(jì)并發(fā)程序時(shí)會(huì)遇到困難。請(qǐng)記住,在Java中,所有在另一個(gè)線程的執(zhí)行中侵入的操作都被棄用了(例如stop方法)。


  為什么Java不支持運(yùn)算符重載?


  另一個(gè)類似棘手的Java問(wèn)題。為什么C++支持運(yùn)算符重載而Java不支持?有人可能會(huì)說(shuō)+運(yùn)算符在Java中已被重載用于字符串連接,不要被這些論據(jù)所欺騙。


  與C++不同,Java不支持運(yùn)算符重載。Java不能為程序員提供自由的標(biāo)準(zhǔn)算術(shù)運(yùn)算符重載,例如+,-,*和/等。如果你以前用過(guò)C++,那么Java與C++相比少了很多功能,例如Java不支持多重繼承,Java中沒(méi)有指針,Java中沒(méi)有引用傳遞。另一個(gè)類似的問(wèn)題是關(guān)于Java通過(guò)引用傳遞,這主要表現(xiàn)為Java是通過(guò)值還是引用傳參。雖然我不知道背后的真正原因,但我認(rèn)為以下說(shuō)法有些道理,為什么Java不支持運(yùn)算符重載。


  1)簡(jiǎn)單性和清晰性。清晰性是Java設(shè)計(jì)者的目標(biāo)之一。設(shè)計(jì)者不是只想復(fù)制語(yǔ)言,而是希望擁有一種清晰,真正面向?qū)ο蟮恼Z(yǔ)言。添加運(yùn)算符重載比沒(méi)有它肯定會(huì)使設(shè)計(jì)更復(fù)雜,并且它可能導(dǎo)致更復(fù)雜的編譯器,或減慢JVM,因?yàn)樗枰鲱~外的工作來(lái)識(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)算符賦予多種含義,這將使任何開(kāi)發(fā)人員的學(xué)習(xí)曲線變得陡峭,事情變得更加混亂。據(jù)觀察,當(dāng)語(yǔ)言支持運(yùn)算符重載時(shí),編程錯(cuò)誤會(huì)增加,從而增加了開(kāi)發(fā)和交付時(shí)間。由于Java和JVM已經(jīng)承擔(dān)了大多數(shù)開(kāi)發(fā)人員的責(zé)任,如在通過(guò)提供垃圾收集器進(jìn)行內(nèi)存管理時(shí),因?yàn)檫@個(gè)功能增加污染代碼的機(jī)會(huì),成為編程錯(cuò)誤之源,因此沒(méi)有多大意義。


  3)JVM復(fù)雜性。從JVM的角度來(lái)看,支持運(yùn)算符重載使問(wèn)題變得更加困難。通過(guò)更直觀,更干凈的方式使用方法重載也能實(shí)現(xiàn)同樣的事情,因此不支持Java中的運(yùn)算符重載是有意義的。與相對(duì)簡(jiǎn)單的JVM相比,復(fù)雜的JVM可能導(dǎo)致JVM更慢,并為保證在Java中運(yùn)算符行為的確定性從而減少了優(yōu)化代碼的機(jī)會(huì)。


  4)讓開(kāi)發(fā)工具處理更容易。這是在Java中不支持運(yùn)算符重載的另一個(gè)好處。省略運(yùn)算符重載使語(yǔ)言更容易處理,這反過(guò)來(lái)又更容易開(kāi)發(fā)處理語(yǔ)言的工具,例如IDE或重構(gòu)工具。Java中的重構(gòu)工具遠(yuǎn)勝于C++。


  為什么char數(shù)組比Java中的String更適合存儲(chǔ)密碼?


  另一個(gè)基于String的棘手Java問(wèn)題,相信我只有很少的Java程序員可以正確回答這個(gè)問(wèn)題。這是一個(gè)真正艱難的核心Java面試問(wèn)題,并且需要對(duì)String的扎實(shí)知識(shí)才能回答這個(gè)問(wèn)題。


  這是最近在Java面試中向我的一位朋友詢問(wèn)的問(wèn)題。他正在接受技術(shù)主管職位的面試,并且有超過(guò)6年的經(jīng)驗(yàn)。如果你還沒(méi)有遇到過(guò)這種情況,那么字符數(shù)組和字符串可以用來(lái)存儲(chǔ)文本數(shù)據(jù),但是選擇一個(gè)而不是另一個(gè)很難。但正如我的朋友所說(shuō),任何與String相關(guān)的問(wèn)題都必須對(duì)字符串的特殊屬性有一些線索,比如不變性,他用它來(lái)說(shuō)服訪提問(wèn)的人。在這里,我們將探討為什么你應(yīng)該使用char[]存儲(chǔ)密碼而不是String的一些原因。


  字符串:1)由于字符串在Java中是不可變的,如果你將密碼存儲(chǔ)為純文本,它將在內(nèi)存中可用,直到垃圾收集器清除它.并且為了可重用性,會(huì)存在String在字符串池中,它很可能會(huì)保留在內(nèi)存中持續(xù)很長(zhǎng)時(shí)間,從而構(gòu)成安全威脅。


  由于任何有權(quán)訪問(wèn)內(nèi)存轉(zhuǎn)儲(chǔ)的人都可以以明文形式找到密碼,這是另一個(gè)原因,你應(yīng)該始終使用加密密碼而不是純文本。由于字符串是不可變的,所以不能更改字符串的內(nèi)容,因?yàn)槿魏胃亩紩?huì)產(chǎn)生新的字符串,而如果你使用char[],你就可以將所有元素設(shè)置為空白或零。因此,在字符數(shù)組中存儲(chǔ)密碼可以明顯降低竊取密碼的安全風(fēng)險(xiǎn)。


  2)Java本身建議使用JPasswordField的getPassword()方法,該方法返回一個(gè)char[]和不推薦使用的getTex()方法,該方法以明文形式返回密碼,由于安全原因。應(yīng)遵循Java團(tuán)隊(duì)的建議,堅(jiān)持標(biāo)準(zhǔn)而不是反對(duì)它。


  3)使用String時(shí),總是存在在日志文件或控制臺(tái)中打印純文本的風(fēng)險(xiǎn),但如果使用Array,則不會(huì)打印數(shù)組的內(nèi)容而是打印其內(nèi)存位置。雖然不是一個(gè)真正的原因,但仍然有道理。


  StringstrPassword=“Unknown”;


  char[]charPassword=newchar[]{'U','n','k','w','o','n'};


  System.out.println(“字符密碼:”+strPassword);


  System.out.println(“字符密碼:”+charPassword);


  輸出


  字符串密碼:Unknown


  我還建議使用散列或加密的密碼而不是純文本,并在驗(yàn)證完成后立即從內(nèi)存中清除它。因此,在Java中,用字符數(shù)組用存儲(chǔ)密碼比字符串是更好的選擇。雖然僅使用char[]還不夠,還你需要擦除內(nèi)容才能更安全。



      以上就是深圳達(dá)內(nèi)教育Java培訓(xùn)機(jī)構(gòu)小編介紹的“比較難的java經(jīng)典面試題及答案”的內(nèi)容,希望對(duì)大家有幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。


相關(guān)推薦


最新最全java面試題及答案(初級(jí)到高級(jí))


史上最全的中高級(jí)JAVA工程師面試題及答案匯總


Java高級(jí)開(kāi)發(fā)工程師面試題


2019史上最全java面試題題庫(kù)大全800題


哪有資深java工程師面試題


培訓(xùn)啦提醒您:交易時(shí)請(qǐng)核實(shí)對(duì)方資質(zhì),對(duì)于過(guò)大宣傳或承諾需謹(jǐn)慎!任何要求預(yù)付定金、匯款等方式均存在風(fēng)險(xiǎn),謹(jǐn)防上當(dāng)。