2019年最新Java面試題整合

2019年最新Java面試題整合

天津卓眾教育      2022-04-18 07:42:01     7

2019年最新Java面試題整合,  List、Set、Map是否繼承自Collection接口?  答:List、Set 是,Map 不是。Map是鍵值對映射容器,與List和Set有明顯的區(qū)別

課程價(jià)格 請咨詢

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

詳細(xì)介紹

 

  List、Set、Map是否繼承自Collection接口?

  答:List、Set 是,Map 不是。Map是鍵值對映射容器,與List和Set有明顯的區(qū)別,而Set存儲(chǔ)的零散的元素且不允許有重復(fù)元素(數(shù)學(xué)中的集合也是如此),List是線性結(jié)構(gòu)的容器,適用于按數(shù)值索引訪問元素的情形。

  闡述ArrayList、Vector、linkedList的存儲(chǔ)性能和特性。

  答:ArrayList 和Vector都是使用數(shù)組方式存儲(chǔ)數(shù)據(jù),此數(shù)組元素?cái)?shù)大于實(shí)際存儲(chǔ)的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號(hào)索引元素,但是插入元素要涉及數(shù)組元素移動(dòng)等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector中的方法由于添加了synchronized修飾,因此Vector是線程安全的容器,但性能上較ArrayList差,因此已經(jīng)是Java中的遺留容器。linkedList使用雙向鏈表實(shí)現(xiàn)存儲(chǔ)(將內(nèi)存中零散的內(nèi)存單元通過附加的引用關(guān)聯(lián)起來,形成一個(gè)可以按序號(hào)索引的線性結(jié)構(gòu),這種鏈?zhǔn)酱鎯?chǔ)方式與數(shù)組的連續(xù)存儲(chǔ)方式相比,內(nèi)存的利用率更高),按序號(hào)索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可,所以插入速度較快。Vector屬于遺留容器(Java早期的版本中提供的容器,除此之外,Hashtable、Dictionary、BitSet、Stack、Properties都是遺留容器),已經(jīng)不推薦使用,但是由于ArrayList和linkedListed都是非線程安全的,如果遇到多個(gè)線程操作同一個(gè)容器的場景,則可以通過工具類Collections中的synchronizedList方法將其轉(zhuǎn)換成線程安全的容器后再使用(這是對裝潢模式的應(yīng)用,將已有對象傳入另一個(gè)類的構(gòu)造器中創(chuàng)建新的對象來增強(qiáng)實(shí)現(xiàn))。

  補(bǔ)充:遺留容器中的Properties類和Stack類在設(shè)計(jì)上有嚴(yán)重的問題,Properties是一個(gè)鍵和值都是字符串的特殊的鍵值對映射,在設(shè)計(jì)上應(yīng)該是關(guān)聯(lián)一個(gè)Hashtable并將其兩個(gè)泛型參數(shù)設(shè)置為String類型,但是Java API中的Properties直接繼承了Hashtable,這很明顯是對繼承的濫用。這里復(fù)用代碼的方式應(yīng)該是Has-A關(guān)系而不是Is-A關(guān)系,另一方面容器都屬于工具類,繼承工具類本身就是一個(gè)錯(cuò)誤的做法,使用工具類最好的方式是Has-A關(guān)系(關(guān)聯(lián))或Use-A關(guān)系(依賴)。同理,Stack類繼承Vector也是不正確的。Sun公司的工程師們也會(huì)犯這種低級錯(cuò)誤,讓人唏噓不已。

  Collection和Collections的區(qū)別?

  答:Collection是一個(gè)接口,它是Set、List等容器的父接口;Collections是個(gè)一個(gè)工具類,提供了一系列的靜態(tài)方法來輔助容器操作,這些方法包括對容器的搜索、排序、線程安全化等等。

  List、Map、Set三個(gè)接口存取元素時(shí),各有什么特點(diǎn)?

  答:List以特定索引來存取元素,可以有重復(fù)元素。Set不能存放重復(fù)元素(用對象的equals()方法來區(qū)分元素是否重復(fù))。Map保存鍵值對(key-value pair)映射,映射關(guān)系可以是一對一或多對一。Set和Map容器都有基于哈希存儲(chǔ)和排序樹的兩種實(shí)現(xiàn)版本,基于哈希存儲(chǔ)的版本理論存取時(shí)間復(fù)雜度為O(1),而基于排序樹版本的實(shí)現(xiàn)在插入或刪除元素時(shí)會(huì)按照元素或元素的鍵(key)構(gòu)成排序樹從而達(dá)到排序和去重的效果。

  TreeMap和TreeSet在排序時(shí)如何比較元素?Collections工具類中的sort()方法如何比較元素?

  答:TreeSet要求存放的對象所屬的類必須實(shí)現(xiàn)Comparable接口,該接口提供了比較元素的compareTo()方法,當(dāng)插入元素時(shí)會(huì)回調(diào)該方法比較元素的大小。TreeMap要求存放的鍵值對映射的鍵必須實(shí)現(xiàn)Comparable接口從而根據(jù)鍵對元素進(jìn)行排序。Collections工具類的sort方法有兩種重載的形式,第一種要求傳入的待排序容器中存放的對象比較實(shí)現(xiàn)Comparable接口以實(shí)現(xiàn)元素的比較;第二種不強(qiáng)制性的要求容器中的元素必須可比較,但是要求傳入第二個(gè)參數(shù),參數(shù)是Comparator接口的子類型(需要重寫compare方法實(shí)現(xiàn)元素的比較),相當(dāng)于一個(gè)臨時(shí)定義的排序規(guī)則,其實(shí)就是通過接口注入比較元素大小的算法,也是對回調(diào)模式的應(yīng)用(Java中對函數(shù)式編程的支持)。

  Thread類的sleep()方法和對象的wait()方法都可以讓線程暫停執(zhí)行,它們有什么區(qū)別?

  答:sleep()方法(休眠)是線程類(Thread)的靜態(tài)方法,調(diào)用此方法會(huì)讓當(dāng)前線程暫停執(zhí)行指定的時(shí)間,將執(zhí)行機(jī)會(huì)(CPU)讓給其他線程,但是對象的鎖依然保持,因此休眠時(shí)間結(jié)束后會(huì)自動(dòng)恢復(fù)(線程回到就緒狀態(tài),請參考第66題中的線程狀態(tài)轉(zhuǎn)換圖)。wait()是Object類的方法,調(diào)用對象的wait()方法導(dǎo)致當(dāng)前線程放棄對象的鎖(線程暫停執(zhí)行),進(jìn)入對象的等待池(wait pool),只有調(diào)用對象的notify()方法(或notifyAll()方法)時(shí)才能喚醒等待池中的線程進(jìn)入等鎖池(lock pool),如果線程重新獲得對象的鎖就可以進(jìn)入就緒狀態(tài)。

  補(bǔ)充:可能不少人對什么是進(jìn)程,什么是線程還比較模糊,對于為什么需要多線程編程也不是特別理解。簡單的說:進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位;線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。線程的劃分尺度小于進(jìn)程,這使得多線程程序的并發(fā)性高;進(jìn)程在執(zhí)行時(shí)通常擁有獨(dú)立的內(nèi)存單元,而線程之間可以共享內(nèi)存。使用多線程的編程通常能夠帶來更好的性能和用戶體驗(yàn),但是多線程的程序?qū)τ谄渌绦蚴遣挥押玫?,因?yàn)樗赡苷加昧烁嗟腃PU資源。當(dāng)然,也不是線程越多,程序的性能就越好,因?yàn)榫€程之間的調(diào)度和切換也會(huì)浪費(fèi)CPU時(shí)間。時(shí)下很時(shí)髦的Node.js就采用了單線程異步I/O的工作模式。

  線程的sleep()方法和yield()方法有什么區(qū)別?

  答:1、sleep()方法給其他線程運(yùn)行機(jī)會(huì)時(shí)不考慮線程的優(yōu)先級,因此會(huì)給低優(yōu)先級的線程以運(yùn)行的機(jī)會(huì);yield()方法只會(huì)給相同優(yōu)先級或更高優(yōu)先級的線程以運(yùn)行的機(jī)會(huì);

  2、 線程執(zhí)行sleep()方法后轉(zhuǎn)入阻塞(blocked)狀態(tài),而執(zhí)行yield()方法后轉(zhuǎn)入就緒(ready)狀態(tài);

  3、sleep()方法聲明拋出InterruptedException,而yield()方法沒有聲明任何異常;

  4、sleep()方法比yield()方法(跟操作系統(tǒng)CPU調(diào)度相關(guān))具有更好的可移植性。

  當(dāng)一個(gè)線程進(jìn)入一個(gè)對象的synchronized方法A之后,其它線程是否可進(jìn)入此對象的synchronized方法B?

  答:不能。其它線程只能訪問該對象的非同步方法,同步方法則不能進(jìn)入。因?yàn)榉庆o態(tài)方法上的synchronized修飾符要求執(zhí)行方法時(shí)要獲得對象的鎖,如果已經(jīng)進(jìn)入A方法說明對象鎖已經(jīng)被取走,那么試圖進(jìn)入B方法的線程就只能在等鎖池(注意不是等待池哦)中等待對象的鎖。

  請說出與線程同步以及線程調(diào)度相關(guān)的方法。

  答:wait():使一個(gè)線程處于等待(阻塞)狀態(tài),并且釋放所持有的對象的鎖;

  sleep():使一個(gè)正在運(yùn)行的線程處于睡眠狀態(tài),是一個(gè)靜態(tài)方法,調(diào)用此方法要處理InterruptedException異常;

  notify():喚醒一個(gè)處于等待狀態(tài)的線程,當(dāng)然在調(diào)用此方法的時(shí)候,并不能確切的喚醒某一個(gè)等待狀態(tài)的線程,而是由JVM確定喚醒哪個(gè)線程,而且與優(yōu)先級無關(guān);

  notityAll():喚醒所有處于等待狀態(tài)的線程,該方法并不是將對象的鎖給所有線程,而是讓它們競爭,只有獲得鎖的線程才能進(jìn)入就緒狀態(tài)。

  提示:關(guān)于Java多線程和并發(fā)編程的問題,建議大家看我的另一篇文章《關(guān)于Java并發(fā)編程的總結(jié)和思考》。

  補(bǔ)充:Java 5通過Lock接口提供了顯式的鎖機(jī)制(explicit lock),增強(qiáng)了靈活性以及對線程的協(xié)調(diào)。Lock接口中定義了加鎖(lock())和解鎖(unlock())的方法,同時(shí)還提供了newCondition()方法來產(chǎn)生用于線程之間通信的Condition對象;此外,Java 5還提供了信號(hào)量機(jī)制(semaphore),信號(hào)量可以用來限制對某個(gè)共享資源進(jìn)行訪問的線程的數(shù)量。在對資源進(jìn)行訪問之前,線程必須得到信號(hào)量的許可(調(diào)用Semaphore對象的acquire()方法);在完成對資源的訪問后,線程必須向信號(hào)量歸還許可(調(diào)用Semaphore對象的release()方法)。

      以上就是天津卓眾教育Java培訓(xùn)機(jī)構(gòu)小編介紹的“2019年最新Java面試題整合”的內(nèi)容,希望對大家有幫助,如有疑問,請?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。

 

相關(guān)推薦

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

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

Java高級開發(fā)工程師面試題

2019史上最全java面試題題庫大全800題

哪有資深java工程師面試題

 

Java面試題

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