版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Java程序員面試分類真題6(總分:100.00,做題時(shí)間:120分鐘)一、單項(xiàng)選擇題(總題數(shù):22,分?jǐn)?shù):44.00)1.
Java程序的執(zhí)行過(guò)程中用到一套JDK工具,其中,java.exe是指______。
(分?jǐn)?shù):2.00)
A.Java編譯器
B.Java解釋器
√
C.Java文檔生成器
D.Java類分解器解析:對(duì)于選項(xiàng)A,JDK中的編譯器為javac.exe,可以用來(lái)把Java代碼編譯為中間代碼.class文件。所以,選項(xiàng)A錯(cuò)誤。
對(duì)于選項(xiàng)B,java.exe是Java解釋器,用來(lái)解釋執(zhí)行通過(guò)javac編譯生成的.class文件。所以,選項(xiàng)B正確。
對(duì)于選項(xiàng)C,JDK文檔生成所使用的命令為javadoc.exe,而不是java.exe。所以,選項(xiàng)C錯(cuò)誤。
對(duì)于選項(xiàng)D,JDK也提供了很多類分析工具,例如jstack用來(lái)查看線程情況(觀察JVM中當(dāng)前所有線程的運(yùn)行情況和線程當(dāng)前狀態(tài),可以查看堆棧信息和運(yùn)行的線程的方法調(diào)用關(guān)系),jmap用來(lái)查看內(nèi)存堆情況。所以,選項(xiàng)D錯(cuò)誤。
所以,本題的答案為B。2.
Java之所以可以實(shí)現(xiàn)跨平臺(tái),是因?yàn)镴ava程序在運(yùn)行時(shí)使用了______。
(分?jǐn)?shù):2.00)
A.JRE(JavaRuntimeEnvironment)
B.JDK(JavaDevelopmentKit)
C.JVM(JavaVirtualMachine)
√
D.OS(OperatingSystem)解析:平臺(tái)獨(dú)立性指的是可以在一個(gè)平臺(tái)上編寫和編譯程序,而在其他平臺(tái)上運(yùn)行。保證Java語(yǔ)言具有平臺(tái)獨(dú)立性的機(jī)制為“中間碼”和“JVM”。Java程序被編譯后不是生成能在硬件平臺(tái)上可執(zhí)行的代碼,而是生成了一個(gè)中間代碼。不同的硬件平臺(tái)上會(huì)安裝有不同的JVM,由JVM來(lái)負(fù)責(zé)把中間代碼翻譯成硬件平臺(tái)能執(zhí)行的代碼。由此可以看出,JVM不具有平臺(tái)獨(dú)立性,與硬件平臺(tái)是相關(guān)的,它保證了Java可以實(shí)現(xiàn)跨平臺(tái)。
本題中,對(duì)于選項(xiàng)A,JRE是運(yùn)行Java程序所必須的環(huán)境的集合,包含JVM標(biāo)準(zhǔn)實(shí)現(xiàn)以及Java核心類庫(kù)。所以,選項(xiàng)A不正確。
對(duì)于選項(xiàng)B,JDK是Java語(yǔ)言開發(fā)的工具包,主要用于移動(dòng)設(shè)備、嵌入式設(shè)備上的Java應(yīng)用程序。包括javac、jar、javadoc、jdb、java、appletviewer、javah、Javap等基本組件。所以,選項(xiàng)B不正確。
對(duì)于選項(xiàng)C,JVM是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),是通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的。它是Java語(yǔ)言跨平臺(tái)的核心。所以,選項(xiàng)C正確。
對(duì)于選項(xiàng)D,OS全稱為OperatingSystem,指的是操作系統(tǒng),與Java跨平臺(tái)沒有關(guān)系。所以,選項(xiàng)D不正確。3.
釋放掉一個(gè)指定占據(jù)的內(nèi)存空間的方法是______。
(分?jǐn)?shù):2.00)
A.調(diào)用system.gc()方法
B.調(diào)用free()方法
C.賦值給該項(xiàng)對(duì)象的引用為null
D.程序員無(wú)法明確強(qiáng)制垃圾回收器運(yùn)行
√解析:在Java語(yǔ)言中,GC(GarbageCollection,垃圾回收)是一個(gè)非常重要的概念,它的主要作用是回收程序中不再使用的內(nèi)存。在使用C/C++語(yǔ)言進(jìn)行程序開發(fā)的時(shí)候,開發(fā)人員必須非常仔細(xì)地管理好內(nèi)存的分配與釋放,如果忘記或者錯(cuò)誤地釋放內(nèi)存往往會(huì)導(dǎo)致程序運(yùn)行不正確甚至是程序的崩潰。為了減輕開發(fā)人員的工作,同時(shí)增加系統(tǒng)的安全性與穩(wěn)定性,Java語(yǔ)言提供了垃圾回收器來(lái)自動(dòng)檢測(cè)對(duì)象的作用域,實(shí)現(xiàn)自動(dòng)地、把不再被使用的存儲(chǔ)空間釋放掉。
在Java語(yǔ)言中,釋放掉占據(jù)的內(nèi)存空間是由GC完成的,程序員無(wú)法直接強(qiáng)制釋放存儲(chǔ)空間,當(dāng)一個(gè)對(duì)象不被使用的時(shí)候,GC會(huì)將該對(duì)象標(biāo)記為垃圾,并在后面一個(gè)不確定的時(shí)間內(nèi)回收垃圾(程序員無(wú)法控制這個(gè)時(shí)間)。
給對(duì)象引用賦值為null,并且該對(duì)象無(wú)其他引用,GC會(huì)標(biāo)記該對(duì)象為垃圾,并在后面一個(gè)不確定的時(shí)間內(nèi)回收垃圾。所謂不確定是指什么時(shí)間回收,程序員無(wú)法控制。
本題中,對(duì)于選項(xiàng)A,開發(fā)人員可以通過(guò)調(diào)用System.gc()方法來(lái)通知垃圾回收器運(yùn)行,但是JVM也并不能保證垃圾回收器馬上就會(huì)運(yùn)行。因此,選項(xiàng)A錯(cuò)誤。
對(duì)于選項(xiàng)B,Java語(yǔ)言沒有提供free(釋放)方法。因此,選項(xiàng)B錯(cuò)誤。
對(duì)于選項(xiàng)C,當(dāng)把對(duì)象的引用設(shè)置為null時(shí),GC會(huì)標(biāo)記該對(duì)象為垃圾,并在后面一個(gè)不確定的時(shí)問內(nèi)回收垃圾。因此,選項(xiàng)C錯(cuò)誤。
對(duì)于選項(xiàng)D,程序員無(wú)法明確強(qiáng)制垃圾回收器運(yùn)行。因此,選項(xiàng)D正確。4.
下面關(guān)于垃圾回收的描述中,正確的是______。
(分?jǐn)?shù):2.00)
A.對(duì)象空間被回收掉之后,會(huì)執(zhí)行該對(duì)象的finalize方法
B.一個(gè)對(duì)象一旦成為垃圾,就立刻被回收掉
C.finalize方法和C++語(yǔ)言的析構(gòu)函數(shù)完全是一回事
D.一個(gè)對(duì)象成為垃圾是因?yàn)椴辉儆幸弥钢?,但是線程并非如此
√解析:在Java語(yǔ)言中,當(dāng)沒有對(duì)象引用指向原先分配給某個(gè)對(duì)象的內(nèi)存時(shí),該內(nèi)存便成為垃圾。Java虛擬機(jī)的一個(gè)系統(tǒng)級(jí)線程會(huì)自動(dòng)釋放該內(nèi)存塊。當(dāng)一個(gè)對(duì)象不再被引用的時(shí)候,內(nèi)存回收它占領(lǐng)的空間,以便空間被后來(lái)的新對(duì)象使用,不僅如此,垃圾回收除了釋放沒用的對(duì)象,也可以清除內(nèi)存記錄碎片。
本題中,對(duì)于選項(xiàng)A,finalize方法是在對(duì)象空間被回收前調(diào)用的。所以,選項(xiàng)A錯(cuò)誤。
對(duì)于選項(xiàng)B,成為垃圾的對(duì)象,只有在下次垃圾回收器運(yùn)行的時(shí)候才會(huì)被回收,而不是馬上被清理。所以,選項(xiàng)B錯(cuò)誤。
對(duì)于選項(xiàng)C,在C++語(yǔ)言中,調(diào)用了析構(gòu)函數(shù)后,對(duì)象一定會(huì)被銷毀,而Java語(yǔ)言調(diào)用了finalize方法,垃圾卻不一定會(huì)被回收,因此,finalize方法與C++語(yǔ)言的析構(gòu)函數(shù)是不同的概念。所以,選項(xiàng)C錯(cuò)誤。
對(duì)于選項(xiàng)D,當(dāng)一個(gè)對(duì)象不再被引用后就成為垃圾,而垃圾是可以被回收的,但是線程就算沒有被引用也可以獨(dú)立運(yùn)行,因此,它與對(duì)象不同。所以,選項(xiàng)D正確。5.
有如下代碼:
10.publicObjectm(){
11.Objecto=newFloat(3.1f);
12.Object[]oa=new()bject[1];
13.oa[0]=o;
14.o=null;
15.oa[0]=null;
16.print'return0';
17.}
當(dāng)Float對(duì)象在第11行被創(chuàng)建后,______能夠被垃圾回收。
(分?jǐn)?shù):2.00)
A.14行以后
B.13行以后
C.15行以后
√
D.16行以后解析:具體而言,垃圾回收器主要負(fù)責(zé)完成3項(xiàng)任務(wù):分配內(nèi)存、確保被引用對(duì)象的內(nèi)存不被錯(cuò)誤地回收以及回收不再被引用的對(duì)象的內(nèi)存空間。
垃圾回收器的存在,一方面把開發(fā)人員從釋放內(nèi)存的復(fù)雜的工作中解脫出來(lái),提高了開發(fā)人員的生產(chǎn)效率;另外一方面,對(duì)開發(fā)人員屏蔽了釋放內(nèi)存的方法,可以避免因?yàn)殚_發(fā)人員錯(cuò)誤地操作內(nèi)存從而導(dǎo)致應(yīng)用程序的崩潰,保證了程序的穩(wěn)定性。但是,垃圾回收也帶來(lái)了問題,為了實(shí)現(xiàn)垃圾回收,垃圾回收器必須跟蹤內(nèi)存的使用情況,釋放沒用的對(duì)象,在完成內(nèi)存的釋放后還需要處理堆中的碎片,這些操作必定會(huì)增加JVM的負(fù)擔(dān),從而降低程序的執(zhí)行效率。
對(duì)于對(duì)象而言,如果沒有任何變量去引用它,那么該對(duì)象將不可能被程序訪問,因此,可以認(rèn)為它是垃圾信息,可以被回收。只要有一個(gè)以上的變量引用該對(duì)象,該對(duì)象就不會(huì)被垃圾回收。
對(duì)于本題而言,首先,在第11行定義了一個(gè)Float對(duì)象o,接著,在第13行把這個(gè)對(duì)象的引用賦值給數(shù)組oa[0]的第一個(gè)元素,此時(shí)這個(gè)Float對(duì)象有兩處被引用的地方,分別為o和oa[0];在第14行中執(zhí)行o=null后,這個(gè)Float對(duì)象仍然被oa[0]引用,在執(zhí)行完第15行后這個(gè)Float對(duì)象沒有被任何變量引用了,因此,就具備了被垃圾回收器回收的條件。所以,選項(xiàng)C正確。6.
有下面代碼:
interfaceAnimal{publicvoidtest();}
publicclassHourseimplementsAnimal{
publicvoidtest(){
...}
publicstaticVoidmain(String[]args)
{
Animala1=newHourse();
Animala2=newHourse();
Animala3=newHourse();
a1=a2;a2=null;a3=a1;
}
}
當(dāng)程序執(zhí)行到a1=a2;a2=null;a3=a1;這行時(shí),將被垃圾回收器回收的對(duì)象個(gè)數(shù)為______。
(分?jǐn)?shù):2.00)
A.1
B.2
√
C.3
D.4
E.5
F.6解析:為了便于理解,給下面三個(gè)新建的對(duì)象起個(gè)別名:
Animala1=newHourse();
//對(duì)象1
Animala2=newHourse();
//對(duì)象2
Animala3=newHourse();
//對(duì)象3
在執(zhí)行語(yǔ)句a1=a2后,a1和a2都指向?qū)ο?,此時(shí)對(duì)象1不再被引用,因此,可以被垃圾回收器回收。在執(zhí)行語(yǔ)句a2=null后,由于a1仍然執(zhí)行對(duì)象2,因此,對(duì)象2不能被回收。在執(zhí)行語(yǔ)句a3=a1后,a3也指向?qū)ο?,此時(shí)對(duì)象3不再被引用,也可以被回收。因此,總共有2個(gè)對(duì)象被回收。所以,選項(xiàng)B正確。7.
下列關(guān)于內(nèi)存回收的描述中,正確的是______。
(分?jǐn)?shù):2.00)
A.程序員必須創(chuàng)建一個(gè)線程來(lái)釋放內(nèi)存
B.內(nèi)存回收程序負(fù)責(zé)釋放無(wú)用內(nèi)存
√
C.內(nèi)存回收程序允許程序員直接釋放內(nèi)存
D.內(nèi)存回收程序可以在指定的時(shí)間釋放內(nèi)存對(duì)象解析:8.
在Java語(yǔ)言中,下面接口以鍵一值對(duì)的方式存儲(chǔ)對(duì)象的是______。
(分?jǐn)?shù):2.00)
A.java.util.List
B.java.util.Map
√
C.java.util.Collection
D.java.util.Set解析:對(duì)于選項(xiàng)A,List中保存了相同類型的多個(gè)元素,元素是按照存入的順序存儲(chǔ)的,元素可以重復(fù)。所以,選項(xiàng)A錯(cuò)誤。
對(duì)于選項(xiàng)B,Map是以鍵一值對(duì)的方式來(lái)存儲(chǔ)對(duì)象的,并且鍵不允許重復(fù)。所以,選項(xiàng)B正確。
對(duì)于選項(xiàng)C,java.util.Collection是一個(gè)集合接口,它提供了對(duì)集合對(duì)象進(jìn)行基本操作的通用接口方法。而Set與List是它的兩個(gè)具體的接口,由于Set與List都不是以鍵一值對(duì)的方式來(lái)存儲(chǔ)對(duì)象的,因此,Collection接口也不是。所以,選項(xiàng)C錯(cuò)誤。
對(duì)于選項(xiàng)D,Set中也保存了相同類型的多個(gè)元素,元素是不能重復(fù)的。所以,選項(xiàng)D錯(cuò)誤。
下表是各接口的區(qū)別。各接口的區(qū)別類型是否有序是否允許重復(fù)是否線程同步Collection否是
ListArrayList否是否Vector是LinkedList否SetHashSet否否否TreeSet是否MapHashMap否<key,value>,
key不允許重復(fù)否TreeMaD是否Hashtable否是
所以,本題的答案為B。9.
list是一個(gè)ArrayList的對(duì)象,當(dāng)將選項(xiàng)______的代碼填到//tododelete處時(shí),可以在Iterator遍歷的過(guò)程中正確并安全地刪除一個(gè)list中保存的對(duì)象。
Iteratorit=list.iterator();
imindex=0;
while(it.hasNext())
{
Objectobj=it.next();
if(needDelete(obj))//needDelete返回boolean,決定是否要?jiǎng)h除
{
//tododelete
}
index++;
}
(分?jǐn)?shù):2.00)
A.it.remove();
√
B.list.remove(index);
C.list.remove(ohj);
D.list.delete(index);解析:Iterator支持從源集合中安全地刪除對(duì)象,刪除的方法為在Iterator上調(diào)用remove()方法。這樣做的好處是可以避免ConcurrentModifiedException異常發(fā)生,當(dāng)打開Iterator迭代集合時(shí),同時(shí)又在對(duì)集合進(jìn)行修改。有些集合不允許在迭代時(shí)刪除或添加元素,但是調(diào)用Iterator的remove()方法是個(gè)安全的做法。
remove()方法的作用為從迭代器指向的集合中移除迭代器返回的最后一個(gè)元素(可選操作),每次調(diào)用next()方法只能調(diào)用一次此方法。如果在進(jìn)行迭代時(shí),用調(diào)用此方法之外其他方式修改了該迭代器所指向的集合,那么迭代器的行為是不明確的。因此,選項(xiàng)A正確。10.
下面創(chuàng)建Map集合的方式中,正確的是______。
(分?jǐn)?shù):2.00)
A.Mapm=newMap(newCollection())
B.Mapm=newMap(10,2,40)
C.Mapm=newMap()
D.Map是接口,所以不能實(shí)例化
√解析:Java為數(shù)據(jù)結(jié)構(gòu)中的映射定義了一個(gè)接口java.util.Map,它有三個(gè)實(shí)現(xiàn)類:HashMap、Hashtable和TreeMap。由于接口中的方法都沒有實(shí)現(xiàn),因此,不能直接使用new來(lái)實(shí)例化一個(gè)接口,原因是new只能用來(lái)實(shí)例化非抽象的類。所以,選項(xiàng)D正確。
本題中,一種正確的寫法為Map<String,String>m=newHashMap<String,String>(),把實(shí)例化HashMap對(duì)象的實(shí)例賦值給Map接口變量m。11.
以下不是Collection的子接口的是______。
(分?jǐn)?shù):2.00)
A.List
B.Set
C.SortedSet
D.HashMap
√解析:Collection的框架如圖所示。
由此可見,HashMap不是Collection的子接口,List和set是Collection的子接口,SortedSet繼承了Set接口,因此,也屬于Collection的子接口。所以,選項(xiàng)D正確。
Collection框架12.
在Java語(yǔ)言中,位于集合框架的頂層的接口是______。
(分?jǐn)?shù):2.00)
A.Collection
√
B.Collections
C.List
D.Iterator解析:Collection是一個(gè)集合接口。它提供了對(duì)集合對(duì)象進(jìn)行基本操作的通用接口方法。實(shí)現(xiàn)該接口的類主要有List和Set,該接口的設(shè)計(jì)目標(biāo)是為各種具體的集合提供最大化的統(tǒng)一的操作方式。
由此可見,選項(xiàng)A正確,選項(xiàng)C和選項(xiàng)D錯(cuò)誤。
Collections是針對(duì)集合類的一個(gè)包裝類,它提供一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序和線程安全化等操作,其中的大多數(shù)方法都是用來(lái)處理線性表。Collections類不能實(shí)例化,如同一個(gè)工具類,服務(wù)于Collection框架。因此,Collections不是一個(gè)集合框架類,選項(xiàng)D錯(cuò)誤。
所以,本題的答案為A。13.
欲構(gòu)造ArrayList類的一個(gè)實(shí)例,此類繼承了List接口,下列方法中,正確的是______。
(分?jǐn)?shù):2.00)
A.ArrayListlist=newObject()
B.Listlist=newArrayList()
√
C.Listlist=newList()
D.ArrayListlist=newList()解析:對(duì)于選項(xiàng)A,在Java語(yǔ)言中,可以把子類的對(duì)象賦值給父類的引用變量,但是不可以把父類的對(duì)象賦值給子類的引用,Object是所有類的父類,因此,也是ArrayList的父類,所以,這種寫法是不合法的,如果換成語(yǔ)句Objecto=newArrayList()就合法了。所以,選項(xiàng)A錯(cuò)誤。
對(duì)于選項(xiàng)B,ArrayList實(shí)現(xiàn)了List接口。所以,選項(xiàng)B正確。
對(duì)于選項(xiàng)C與選項(xiàng)D,由于List是接口,因此,不能被實(shí)例化。所以,選項(xiàng)C與選項(xiàng)D錯(cuò)誤。
所以,本題的答案為B。14.
Java語(yǔ)言的接口java.util.Collection定義了許多方法,以下方法中,不是Collection接口所定義的是______。
(分?jǐn)?shù):2.00)
A.booleancontainsAll(Collectionc)
B.intsize()
C.compareTo(Objectobj)
√
D.booleanequals(Object0)解析:java.util.Collection是一個(gè)集合接口,它提供了對(duì)集合對(duì)象進(jìn)行基本操作的通用接口方法。Collection接口在Java類庫(kù)中有很多具體的實(shí)現(xiàn)。具體而言,Collection主要方法見下表。Collection主要方法方法描述add(Ee)把對(duì)象e添加到容器中addAll(Collection<?extendsE>c)把c中的所有對(duì)象添加到容器中clear()清空容器contains(Objecto)如果容器中有對(duì)象o,那么返回true,否則,返回falsecontainsAll(Collection<?>c)如果容器中包含c中所有的對(duì)象,那么返回true,否則,返回falseequals(Objecto)判斷對(duì)象o是否和容器相等hashCode()返回容器的hash值isEmpty()如果容器為空,返回trueiterator()返回這個(gè)容器的迭代器remove(Objecto)從列表中刪除對(duì)象oremoveAll(Collection<?>c)從列表中刪除那些在c中存在的對(duì)象retainAll(Collection<?>c)列表中移除未包含在指定Collection中的所有元素size()返回容器中元素的個(gè)數(shù)toArray()返回一個(gè)數(shù)組,數(shù)組中包含容器中所有的元素toArray(T[]a)與方法toArray類似,不同之處為返回?cái)?shù)組的類型與參數(shù)指定的類型相同
所以,本題的答案為C。15.
ArrayLista1=newArrayList(20)中的list擴(kuò)充了______次。
(分?jǐn)?shù):2.00)
A.0
√
B.1
C.2
D.4解析:在Java語(yǔ)言中,創(chuàng)建ArrayList對(duì)象的時(shí)候可以不指定其空間大小,在這種情況下,列表默認(rèn)的大小為10,在后面使用的過(guò)程中,如果發(fā)現(xiàn)列表的大小不夠用,此時(shí)會(huì)擴(kuò)充為原來(lái)大小的1.5倍。
對(duì)于本題而言,在初始化ArrayList對(duì)象的時(shí)候,顯式地指定了列表的大小為20,因此,創(chuàng)建出來(lái)的列表對(duì)象的長(zhǎng)度為20,在這個(gè)過(guò)程中不需要擴(kuò)展,即擴(kuò)展次數(shù)為0。所以,選項(xiàng)A正確。
如果把題目改成ArrayListlist=newArrayList(),接著向列表里插入20條記錄,那么這個(gè)列表在插入第11條記錄的時(shí)候就需要擴(kuò)展一次。16.
欲構(gòu)造ArrayList類的一個(gè)實(shí)例,此類繼承了List接口,下列方法正確的是______。
(分?jǐn)?shù):2.00)
A.ArrayListmyList=newLinkedList();
B.ListmyList=newArrayList();
√
C.ArrayListmyList=newList();
D.ListmyList=newList();解析:17.
下列屬于容器型構(gòu)件的是______。
(分?jǐn)?shù):2.00)
A.JButton
B.JEdit
C.JPanel
√
D.JTextField解析:容器型構(gòu)件是指可以在這個(gè)構(gòu)件中添加其他的構(gòu)件來(lái)構(gòu)建復(fù)雜的界面應(yīng)用程序。
本題中,對(duì)于選項(xiàng)A,JButton是按鈕控件,用來(lái)響應(yīng)用戶的單擊事件,它不是容器控件。因此,選項(xiàng)A錯(cuò)誤。
對(duì)于選項(xiàng)B,Swing庫(kù)中沒有JEdit控件。因此,選項(xiàng)B錯(cuò)誤。
對(duì)于選項(xiàng)C,JPanel是一個(gè)容器型構(gòu)件,可以在JPanel中添加其他的構(gòu)件。因此,選項(xiàng)C正確。
對(duì)于選項(xiàng)D,JTextField是一個(gè)輕量級(jí)組件,它允許編輯單行文本,也不是一個(gè)容器型的構(gòu)件。因此,選項(xiàng)D錯(cuò)誤。18.
每個(gè)使用Swing構(gòu)件的程序必須有一個(gè)______
(分?jǐn)?shù):2.00)
A.標(biāo)簽
B.按鈕
C.菜單
D.容器
√解析:Swing是一個(gè)用于開發(fā)Java應(yīng)用程序用戶界面的開發(fā)工具包,它提供了大量模塊化組件來(lái)方便開發(fā)人員構(gòu)建用戶界面。在使用Swing開發(fā)界面應(yīng)用程序的時(shí)候,圖形界面至少要有一個(gè)頂級(jí)Swing容器,這個(gè)頂級(jí)Swing容器主要用來(lái)為其他Swing組件在屏幕上的繪制和處理事件提供支持,常見的頂級(jí)容器為JFrame、JDialog和JApplet。至于其他的控件,可以根據(jù)實(shí)際的需求而定,可以使用,也可以不用。所以,選項(xiàng)D正確。19.
如果希望控件在界面上按表格行分列排列,應(yīng)使用的布局管理器是______。
(分?jǐn)?shù):2.00)
A.BoxLayout
B.GridLayout
√
C.FlowLouLayout
D.BorderLayout解析:Swing是一個(gè)用于開發(fā)Java應(yīng)用程序用戶界面的開發(fā)工具包。利用Swing豐富、靈活的功能和模塊化組件,開發(fā)人員可以只用很少的代碼來(lái)創(chuàng)建優(yōu)雅的用戶界面。
具體而言,Swing中主要有如下幾種布局容器:
1)FlowLayout:把控件按照由左向右順序水平放置在容器中,如果在一行無(wú)法放下,就放到下一行。
2)BorderLayout:將整個(gè)容器劃分成東南西北中五個(gè)方位來(lái)放置控件,放置控件時(shí)需要指定控件放置的方位。
3)BoxLayout:可以指定在容器中是否對(duì)控件進(jìn)行水平或者垂直放置,它是比FlowLayout要更為靈活的一個(gè)布局容器。
4)GridLayout:將整個(gè)容器劃分成一定的行和一定的列,可以指定控件放在某行某列上。
5)GridBagLayout:GridBagLayout是Swing當(dāng)中最靈活也是最復(fù)雜的布局管理器,可對(duì)控件在容器中的位置進(jìn)行比較靈活的調(diào)整。
通過(guò)上面的分析可知,選項(xiàng)B正確。20.
在Applet子類中,一般需要重載父類的______方法來(lái)完成一些畫圖操作。
(分?jǐn)?shù):2.00)
A.stop()
B.start()
C.init()
D.paint()
√解析:Applet程序的開發(fā)必須繼承Applet類,它有如下5個(gè)比較重要的方法:
(1)init()
當(dāng)ADplet啟動(dòng)的時(shí)候,調(diào)用完構(gòu)造方法后,就會(huì)調(diào)用init方法做一些初始化的工作。因此,這個(gè)方法中一般做一些初始化的工作。所以,選項(xiàng)C錯(cuò)誤。
(2)start()
Applet第一次啟動(dòng)后,調(diào)用完init方法后,就會(huì)調(diào)用start方法來(lái)啟動(dòng)需要的一些線程。或者當(dāng)用戶離開HTML頁(yè)面,然后重新返回頁(yè)面的時(shí)候,start方法也會(huì)被調(diào)用。所以,選項(xiàng)A錯(cuò)誤。
(3)paint(Graphicsg)
Applet每次重繪的時(shí)候都會(huì)調(diào)用paint方法進(jìn)行畫圖。在開發(fā)的時(shí)候,需要繼承這個(gè)類完成自己的畫圖的工作。所以,選項(xiàng)D正確。
(4)stop()
這個(gè)方法與start方法是相對(duì)應(yīng)的,當(dāng)用戶離開HTML頁(yè)面的時(shí)候,stop方法會(huì)被調(diào)用,用來(lái)停止start方法中啟動(dòng)的線程。所以,選項(xiàng)B錯(cuò)誤。
(5)destory()
當(dāng)Applet終止運(yùn)行時(shí),destory方法會(huì)被調(diào)用,用來(lái)釋放所占用的資源。
所以,本題的答案為D。21.
paint()方法使用的參數(shù)類型是______。
(分?jǐn)?shù):2.00)
A.Graphics
√
B.Graphics2D
C.String
D.Color解析:22.
容器被重新設(shè)置大小后,哪種布局管理器的容器中的組件大小不隨容器大小的變化而改變?______
(分?jǐn)?shù):2.00)
A.CardLayout
B.FlowLayout
√
C.BorderLayout
D.GridLayout解析:二、多項(xiàng)選擇題(總題數(shù):8,分?jǐn)?shù):16.00)1.
下列關(guān)于Java語(yǔ)言的編譯過(guò)程的描述中,正確的有______。
(分?jǐn)?shù):2.00)
A.環(huán)境變量可在編譯sourcecode時(shí)指定
√
B.在編譯程序時(shí),所能指定的環(huán)境變量不包括classpath
C.javac一次可同時(shí)編譯數(shù)個(gè)Java源文件
√
D.javac.exe能指定編譯結(jié)果要置于哪個(gè)目錄(directory)
√解析:本題中,對(duì)于選項(xiàng)A,環(huán)境變量在編譯時(shí)可以通過(guò)java-classpath來(lái)指定,因此,選項(xiàng)A正確,選項(xiàng)B錯(cuò)誤。對(duì)于選項(xiàng)C,javac*.java就可以編譯多個(gè)java文件,因此,選項(xiàng)C正確。對(duì)于選項(xiàng)D,javac.exe有個(gè)-d選項(xiàng)來(lái)指定編譯結(jié)果存放的目錄,因此,選項(xiàng)D正確。
所以,本題的答案為ACD。2.
以下關(guān)于HashMap與Hashtbale的說(shuō)法中,正確的是______。
(分?jǐn)?shù):2.00)
A.迭代HashMap采用快速失敗機(jī)制,而Hashtable不是
√
B.Hashtable允許null值作為key和value,而HashMap不可以
C.HashMap不是同步的,而Hashtable是同步的
√
D.兩者都是用key-value方式獲取數(shù)據(jù)
√解析:HashMap和Hashtable通過(guò)對(duì)象來(lái)進(jìn)行索引,用來(lái)索引的對(duì)象叫作key,其對(duì)應(yīng)的對(duì)象叫作value。二者具有許多相似之處,但也有很多不同之處。以下重點(diǎn)介紹二者的不同之處,具體而言,它們的不同之處體現(xiàn)在以下幾個(gè)方面:
1)它們都實(shí)現(xiàn)了Map接口,HashMap允許空(null)鍵值(key)(但需要注意的是,最多只允許一條記錄的鍵為null,不允許多條記錄的值為null),而Hashtable不允許。
2)HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因?yàn)閏ontains方法容易讓人引起誤解。Hashtable繼承自Dictionary類,而HashMap繼承自AbstractMap類。
3)Hashtable的方法是線程安全的,而HashMap不是線程安全的。當(dāng)多個(gè)線程訪問Hashtable時(shí),不需要開發(fā)人員對(duì)它進(jìn)行同步,而對(duì)于HashMap,開發(fā)人員必須提供額外的同步機(jī)制。所以,效率上HashMap可能高于Hashtable。
4)“快速失敗”也就是fail-fast,它是Java集合的一種錯(cuò)誤檢測(cè)機(jī)制。當(dāng)多個(gè)線程對(duì)集合進(jìn)行結(jié)構(gòu)上的改變操作時(shí),就有可能會(huì)產(chǎn)生fail-fast事件。例如,假設(shè)存在兩個(gè)線程,它們分別是線程1與線程2,當(dāng)線程1通過(guò)Iterator(迭代器)在遍歷集合A中的元素時(shí),如果線程2修改了集合A的結(jié)構(gòu)(刪除或增加新的元素),那么,此時(shí)程序就會(huì)拋出ConcurrentModificationException異常,從而產(chǎn)生fail-fast事件。
由于Hashtable是線程安全的,因此,沒有采用快速失敗機(jī)制,而HashMap是非線程安全的,迭代HashMap采用了快速失敗機(jī)制。
從以上分析可知,選項(xiàng)A、選項(xiàng)C、選項(xiàng)D的描述都是正確的,只有選項(xiàng)B的描述不正確,因?yàn)镠ashtable不允許鍵值為null。
所以,本題的答案為ACD。3.
以下關(guān)于HashMap和Hashtable的描述中,正確的是______。
(分?jǐn)?shù):2.00)
A.Hashtable不允許null鍵或值
√
B.Hashtable類不是同步的,而HashMap類是同步的
C.都實(shí)現(xiàn)了Map接口
√
D.HashMap不允許null鍵或值解析:4.
Hashtable和HashMap的區(qū)別是______。
(分?jǐn)?shù):2.00)
A.Hashtable是一個(gè)散列表,該類繼承了AbstractMap,實(shí)現(xiàn)了Map接口
B.HashMap是內(nèi)部基于散列表實(shí)現(xiàn),該類繼承AbstractMap,實(shí)現(xiàn)Map接口
√
C.Hashtable線程安全的,而HashMap是線程不安全的
√
D.Hashtable直接使用對(duì)象的hashCode,而HashMap重新計(jì)算hash值
E.Properties類繼承了Hashtable類,而Hashtable類則繼承Dictionary類
√解析:5.
以下關(guān)于Map的用法中,正確的有______。
(分?jǐn)?shù):2.00)
A.newjava.util.SortedMap().put("keyl","valuel");
B.newjava.util.Map().put("keyl","valuel");
C.newjava.util.HashMap().put(null,null);
√
D.newjava.util.TreeMap().put(0,null);
√解析:對(duì)于選項(xiàng)A,SortedMap繼承了Map,使按鍵保持升序排列,它還是個(gè)接口,因此,也無(wú)法直接實(shí)例化。所以,選項(xiàng)A錯(cuò)誤。
對(duì)于選項(xiàng)B,Map是一個(gè)接口,因此,它無(wú)法直接實(shí)例化。所以,選項(xiàng)B錯(cuò)誤。
對(duì)于選項(xiàng)C和D,HashMap和TreeMap都實(shí)現(xiàn)了接口Map,它們是兩個(gè)具體的實(shí)現(xiàn)類,因此,可以實(shí)例化。所以,選項(xiàng)C與選項(xiàng)D正確。6.
下列接口中,直接繼承自Collection接口的是______。
(分?jǐn)?shù):2.00)
A.List
√
B.Map
C.Set
√
D.HashMap解析:7.
下列關(guān)于Collection類結(jié)構(gòu)的描述中,正確的是______。
(分?jǐn)?shù):2.00)
A.HashSet繼承自AbstractSet
√
B.AbstractSet繼承自Set
C.LinkedList繼承自List
√
D.WeakMap繼承自HashMap解析:8.
以下關(guān)于JDK中LinkedBlockingQueue和ConcurTentLinkedQueue的描述中,正確的是______。
(分?jǐn)?shù):2.00)
A.兩個(gè)數(shù)據(jù)接口都是線程安全的
√
B.內(nèi)部都是使用鎖來(lái)進(jìn)行同步
√
C.都可以配置最大元素?cái)?shù)量
D.都是基于鏈表實(shí)現(xiàn)
√解析:在Java多線程應(yīng)用中,隊(duì)列的使用頻率很高。隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),它有兩個(gè)基本操作:在隊(duì)列尾部添加一個(gè)元素以及從隊(duì)列頭部移除一個(gè)元素。如果向一個(gè)已經(jīng)滿了的阻塞隊(duì)列中添加一個(gè)元素或者從一個(gè)空的阻塞隊(duì)列中移除一個(gè)元索,都將導(dǎo)致線程阻塞。
在講解后面的知識(shí)之前,首先對(duì)阻塞與非阻塞進(jìn)行分析。什么是阻塞?什么是非阻塞?阻塞與非阻塞關(guān)注的是程序在等待調(diào)用結(jié)果(消息、返回值)時(shí)的狀態(tài)。阻塞調(diào)用指的是在調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起,調(diào)用線程只有在得到結(jié)果之后才會(huì)返回,而非阻塞調(diào)用指的是在不能立刻得到結(jié)果之前,該調(diào)用不會(huì)阻塞當(dāng)前線程。舉個(gè)簡(jiǎn)單例子加以說(shuō)明,小王打電話給書店老板老張,詢問書店是否有《Java程序員面試筆試真題與解析》這本書,如果是阻塞式調(diào)用,小王會(huì)一直把自己“掛起”,直到得到這本書有沒有的結(jié)果,如果是非阻塞式調(diào)用,小王會(huì)不管老張有沒有告訴自己,小王先做自己的事情了,當(dāng)然,小王也要偶爾過(guò)來(lái)檢查一下老張有沒有返回結(jié)果。
Java語(yǔ)言提供的線程安全的隊(duì)列可以分為阻塞隊(duì)列和非阻塞隊(duì)列,其中,阻塞隊(duì)列的典型例子是LinkedBlockingQueue,非阻塞隊(duì)列的典型例子是ConcurrentLinkedQueue,在應(yīng)用中要根據(jù)實(shí)際需要選用阻塞隊(duì)列或者非阻塞隊(duì)列。以下將分別對(duì)這兩種隊(duì)列進(jìn)行介紹。
LinkedBlockingQueue是一個(gè)線程安全的阻塞隊(duì)列,實(shí)現(xiàn)了先進(jìn)先出等特性,一般用在生產(chǎn)者和消費(fèi)者模型的開發(fā)中。它的底層采用鏈表的方式來(lái)實(shí)現(xiàn),采用鎖機(jī)制來(lái)實(shí)現(xiàn)多線程同步,提供了一個(gè)構(gòu)造方法來(lái)指定隊(duì)列的大小,如果不指定隊(duì)列的大小,隊(duì)列的默認(rèn)大小為Intege.MAX_VKLUE(它表示int類型能夠表示的最大值,值為2^31-1的常量)。
ConcurrentLinkedQueue是一個(gè)基于鏈表實(shí)現(xiàn)的、無(wú)界的、線程安全的隊(duì)列。無(wú)界表示它沒有提供一個(gè)構(gòu)造方法來(lái)指定隊(duì)列的大小。為了能提高并發(fā)量,它通過(guò)使用更加細(xì)粒度鎖的機(jī)制使得在多線程環(huán)境下不需要對(duì)所有的數(shù)據(jù)進(jìn)行鎖定從而提高運(yùn)行效率。
通過(guò)以上分析可知,選項(xiàng)A、選項(xiàng)B與選項(xiàng)D正確。三、論述題(總題數(shù):20,分?jǐn)?shù):40.00)1.
描述Java類加載器的原理及其組織結(jié)構(gòu)。
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(Java語(yǔ)言是一種具有動(dòng)態(tài)性的解釋型語(yǔ)言,類只有被加載到JVM中后才能運(yùn)行。當(dāng)運(yùn)行程序時(shí),JVM會(huì)將編譯生成的.class文件按照需求和一定的規(guī)則加載到內(nèi)存中,并組織成為一個(gè)完整的Java應(yīng)用程序。這個(gè)加載過(guò)程是由加載器來(lái)完成的,具體而言,就是由ClassLoader和它的子類來(lái)實(shí)現(xiàn)的。類加載器本身也是一個(gè)類,其實(shí)質(zhì)是把類文件從硬盤讀取到內(nèi)存中。
類的加載方式分為隱式裝載與顯式裝載兩種。隱式裝載指的是程序在使用new等方式創(chuàng)建對(duì)象的時(shí)候,會(huì)隱式地調(diào)用類的加載器把對(duì)應(yīng)的類加載到JVM中。顯式裝載指的是通過(guò)直接調(diào)用class-forName()方法來(lái)把所需的類加載到JVM中。
任何一個(gè)工程項(xiàng)目都是由許多個(gè)類組成的,當(dāng)程序啟動(dòng)時(shí),只把需要的類加載到JVM中,其他的類只有被使用到的時(shí)候才會(huì)被加載,采用這種方法,一方面可以加快加載速度,另一方面可以節(jié)約程序運(yùn)行過(guò)程中對(duì)內(nèi)存的開銷。此外,在Java語(yǔ)言中,每個(gè)類或接口都對(duì)應(yīng)一個(gè).class文件,這些文件可以被看成是一個(gè)個(gè)可以被動(dòng)態(tài)加載的單元,因此,當(dāng)只有部分類被修改的時(shí)候,只需要重新編譯變化的類即可,而不需要重新編譯所有的文件,因此,加快了編譯速度。
在Java語(yǔ)言中,類的加載是動(dòng)態(tài)的,它并不會(huì)一次性將所有類全部加載后再運(yùn)行,而是保證程序運(yùn)行的基礎(chǔ)類(例如基類)完全加載到JVM中,至于其他類,則在需要的時(shí)候才加載。在Java語(yǔ)言中,可以把類分為三類:系統(tǒng)類、擴(kuò)展類和自定義類。Java語(yǔ)言針對(duì)這三種不同的類提供了三種類型的加載器,這三種加載器的關(guān)系如下:
BootstrapLoader-負(fù)責(zé)加載系統(tǒng)類(jre/lib/rt.jar的類)
|
--ExtClassLoader-負(fù)責(zé)加載擴(kuò)展類(jar/lib/ext/*.jar的類)
|
--AppClassLoader-負(fù)責(zé)加載應(yīng)用類(classpath指定的目錄或jar中的類)
以上這三個(gè)類是怎么協(xié)調(diào)工作來(lái)完成類的加載呢?其實(shí),它們是通過(guò)委托的方式實(shí)現(xiàn)的。具體而言,就是當(dāng)有類需要被加載時(shí),類裝載器會(huì)請(qǐng)求父類來(lái)完成這個(gè)載入工作,父類會(huì)使用其自己的搜索路徑來(lái)搜索需要被載入的類,如果搜索不到,才會(huì)由子類按照其搜索路徑來(lái)搜索待加載的類。下例可以充分說(shuō)明加載器的工作原理。
publicclassTestLoader
{
publicstaticvoidmain(String[]args)throwsException
{
//調(diào)用class加載器
ClassLoaderclApp=TestLoader.class.getClassLoader();
System.out.println(clApp);
//調(diào)用上一層Class加載器
ClassLoaderclExt=clApp.getParem();
System.out.println(clExt);
//調(diào)用根部Class加載器
ClassLoaderclBoot=clExt.getParent();
System.out.println(clBoot);
}
}
程序的運(yùn)行結(jié)果為:
sun.misc.Launcher$AppClassLoader@19821f
sun.misc.Launcher$ExtClassLoader@addbf1
null
從上例可以看出,TestLoader類是由AppClassLoader來(lái)加載的。另外需要說(shuō)明的一點(diǎn)是,由于BootstrapLoader是使用C++語(yǔ)言來(lái)實(shí)現(xiàn)的,因此,在Java語(yǔ)言中,是看不到它的,此時(shí)程序會(huì)輸出null。
類加載的主要步驟分為以下三步:
1)裝載:根據(jù)查找路徑找到相對(duì)應(yīng)的class文件,然后導(dǎo)入。
2)鏈接:鏈接又可以分為三個(gè)小的步驟,具體如下:
①檢查:檢查待加載的class文件的正確性。
②準(zhǔn)備:給類中的靜態(tài)變量分配存儲(chǔ)空間。
③解析:將符號(hào)引用轉(zhuǎn)換成直接引用(這一步是可選的)。
3)初始化:對(duì)靜態(tài)變量和靜態(tài)代碼塊執(zhí)行初始化工作。)解析:2.
JVM的工作原理是什么?
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(為了便于管理,JVM在執(zhí)行Java程序的時(shí)候,會(huì)把它所管理的內(nèi)存劃分為多個(gè)不同區(qū)域,如圖所示。
JVM管理的內(nèi)存區(qū)域
以下將分別對(duì)這些區(qū)域進(jìn)行介紹。
(1)class文件
class文件是Java程序編譯后生成的中間代碼,這些中間代碼將會(huì)被JVM解釋執(zhí)行。
(2)類裝載器子系統(tǒng)
類裝載器子系統(tǒng)負(fù)責(zé)把class文件裝載到內(nèi)存中,供虛擬機(jī)執(zhí)行。
JVM有兩種類裝載器,分別是啟動(dòng)類裝載器和用戶自定義類裝載器。其中,啟動(dòng)類裝載器是JVM實(shí)現(xiàn)的一部分;用戶自定義類裝載器則是Java程序的一部分,必須是ClassLoader類的子類。常見的類加載器主要有如下幾種:
1)BootstrapClassLoader。這是JVM的根ClassLoader,它是用C++語(yǔ)言實(shí)現(xiàn)的,當(dāng)JVM啟動(dòng)時(shí),初始化此ClassLoader,并由此ClassLoader完成$JAVA_HoME中jre/lib/rt.jar(SunJDK的實(shí)現(xiàn))中所有class文件的加載,這個(gè)jar中包含了Java規(guī)范定義的所有接口以及實(shí)現(xiàn)。
2)ExtensionClassLoader。JVM用此ClassLoader來(lái)加載擴(kuò)展功能的一些jar包。
3)SystemClassLoader。JVM用此ClassLoader來(lái)加載啟動(dòng)參數(shù)中指定的Classpath中的jar包以及目錄,在SunJDK中,ClassLoader對(duì)應(yīng)的類名為AppClassLoader。
4)User-DefinedClassLoader。User-DefinedClassLoader是Java開發(fā)人員繼承ClassLoader抽象類自行實(shí)現(xiàn)的ClassLoader,基于自定義的ClassLoader可用于加載非Classpath中的jar以及目錄。
(3)方法區(qū)
方法區(qū)用來(lái)存儲(chǔ)被虛擬機(jī)加載的類信息、常量、靜態(tài)變量和編譯器編譯后的代碼等數(shù)據(jù)。在類加載器加載class文件時(shí),這些信息將會(huì)被提取出來(lái),并存儲(chǔ)到方法區(qū)中。由于這個(gè)區(qū)域是所有線程共享的區(qū)域,因此,它被設(shè)計(jì)為線程安全的。
方法區(qū)中還存放了運(yùn)行時(shí)的常量池,最典型的應(yīng)用就是字符串常量,例如,定義了如下語(yǔ)句:Strings="Hello";Strings1="Hello";,其中,“Hello”是字符串常量,存儲(chǔ)在常量池中,兩個(gè)字符串引用s和s1都指向常量池中的“Hello”。
(4)堆
堆是虛擬機(jī)啟動(dòng)的時(shí)候創(chuàng)建的被所有線程共享的區(qū)域。這塊區(qū)域主要用來(lái)存放對(duì)象的實(shí)例,通過(guò)new操作創(chuàng)建出來(lái)的對(duì)象的實(shí)例都存儲(chǔ)在堆空間中,因此,堆就成為垃圾回收器管理的重點(diǎn)區(qū)域。
(5)虛擬機(jī)棧
棧是線程私有的區(qū)域,每當(dāng)有新的線程創(chuàng)建時(shí),就會(huì)給它分配一個(gè)??臻g,當(dāng)線程結(jié)束后,棧空間就被回收,因此,棧與線程擁有相同的生命周期。棧主要用來(lái)實(shí)現(xiàn)Java語(yǔ)言中方法的調(diào)用與執(zhí)行,每個(gè)方法在被執(zhí)行的時(shí)候,都會(huì)創(chuàng)建一個(gè)棧幀用來(lái)存儲(chǔ)這個(gè)方法的局部變量、操作棧、動(dòng)態(tài)鏈接和方法出口等信息。當(dāng)進(jìn)行方法調(diào)用時(shí),通過(guò)壓棧與彈棧操作進(jìn)行??臻g的分配與釋放。當(dāng)一個(gè)方法被調(diào)用的時(shí)候,會(huì)壓入一個(gè)新的棧幀到這個(gè)線程的棧中,當(dāng)方法調(diào)用結(jié)束后,就會(huì)彈出這個(gè)棧幀,從而回收調(diào)用這個(gè)方法使用的??臻g。
(6)程序計(jì)數(shù)器
程序計(jì)數(shù)器也是線程私有的資源,JVM會(huì)給每個(gè)線程創(chuàng)建單獨(dú)的程序計(jì)數(shù)器。它可以被看作是當(dāng)前線程執(zhí)行的字節(jié)碼的行號(hào)指示器,解釋器的工作原理就是通過(guò)改變這個(gè)計(jì)數(shù)器的值來(lái)確定下一條需要被執(zhí)行的字節(jié)碼指令,程序控制的流程(循環(huán)、分支、異常處理、線程恢復(fù))都是通過(guò)這個(gè)計(jì)數(shù)器來(lái)完成的。
(7)本地方法棧
本地方法棧與虛擬機(jī)棧的作用是相似的,唯一不同的是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native(本地)方法服務(wù)。Native(本地)方法接口都會(huì)使用某種本地方法棧,當(dāng)線程調(diào)用Java方法時(shí),JVM會(huì)創(chuàng)建一個(gè)新的棧幀并壓入虛擬機(jī)棧。然而當(dāng)它調(diào)用的是本地方法時(shí),虛擬機(jī)棧保持不變,不會(huì)在線程的虛擬機(jī)棧中壓入新的幀,而是簡(jiǎn)單地動(dòng)態(tài)鏈接并直接調(diào)用指定的本地方法。如果某個(gè)虛擬機(jī)實(shí)現(xiàn)的本地方法接口使用的是C++連接模型,那么,它的本地方法棧就是C++棧。
(8)執(zhí)行引擎
執(zhí)行引擎主要負(fù)責(zé)執(zhí)行字節(jié)碼。方法的字節(jié)碼是由Java虛擬機(jī)的指令序列構(gòu)成的,每一條指令包含一個(gè)單字節(jié)的操作碼,后面跟隨0個(gè)或多個(gè)操作數(shù)。當(dāng)執(zhí)行引擎執(zhí)行字節(jié)碼時(shí),首先會(huì)取一個(gè)操作碼,如果這個(gè)操作碼有操作數(shù),會(huì)接著取得它的操作數(shù)。然后執(zhí)行這個(gè)操作,執(zhí)行完成后會(huì)繼續(xù)取得下一個(gè)操作碼執(zhí)行。
在執(zhí)行方法時(shí),JVM提供了四種指令來(lái)執(zhí)行:
1)invokestatic:調(diào)用類的static方法。
2)invokevirtual:調(diào)用對(duì)象實(shí)例的方法。
3)invokeinterface:將屬性定義為接口來(lái)進(jìn)行調(diào)用。
4)invokespecial:調(diào)用一個(gè)初始化方法、私有方法或者父類的方法。
(9)垃圾回收器
垃圾回收器的主要作用是回收程序中不再使用的內(nèi)存。)解析:3.
如何查看Java程序使用內(nèi)存的情況?
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(在Java語(yǔ)言中,每個(gè)Java應(yīng)用程序都有一個(gè)Runtime類實(shí)例,Runtime類提供了多個(gè)查看內(nèi)存使用情況的方法,如下例所示:
classTest
{
publicstaticvoidmain(String[]args)
{
//得到JVM中的空閑內(nèi)存量(單位是字節(jié))
System.out.println(RuntimegetRuntime().freeMemory());
//得到JVM內(nèi)存總量(單位是字節(jié))
System.out.println(Runtime.getRuntime().totalMemory());
//JVM試圖使用的最大內(nèi)存量(單位是字節(jié))
System.out.println(Runtime.getRuntime().maxMemory());
//可用處理器的數(shù)目
System.out.println(Runtime.getRuntime().availableProcessors());
}
}
程序的運(yùn)行結(jié)果為:
250588512
253231104
3747086336
4)解析:4.
垃圾回收器的原理是什么?垃圾回收器是否可以馬上回收內(nèi)存?如何通知虛擬機(jī)進(jìn)行垃圾回收?
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(在Java語(yǔ)言中,GC(GarbageCollection,垃圾回收)是一個(gè)非常重要的概念,它的主要作用是回收程序中不再使用的內(nèi)存。在使用C/C++語(yǔ)言進(jìn)行程序開發(fā)的時(shí)候,開發(fā)人員必須非常仔細(xì)地管理好內(nèi)存的分配與釋放,如果忘記或者錯(cuò)誤地釋放內(nèi)存往往會(huì)導(dǎo)致程序運(yùn)行不正確甚至是程序的崩潰。為了減輕開發(fā)人員的工作,同時(shí)增加系統(tǒng)的安全性與穩(wěn)定性,Java語(yǔ)言提供了垃圾回收器來(lái)自動(dòng)檢測(cè)對(duì)象的作用域,實(shí)現(xiàn)自動(dòng)地把不再被使用的存儲(chǔ)空間釋放掉。具體而言,垃圾回收器主要負(fù)責(zé)完成3項(xiàng)任務(wù):分配內(nèi)存、確保被引用對(duì)象的內(nèi)存不被錯(cuò)誤地回收以及回收不再被引用的對(duì)象的內(nèi)存空間。
垃圾回收器的存在,一方面把開發(fā)人員從釋放內(nèi)存的復(fù)雜的工作中解脫出來(lái),提高了開發(fā)人員的生產(chǎn)效率;另外一方面,對(duì)開發(fā)人員屏蔽了釋放內(nèi)存的方法,可以避免因?yàn)殚_發(fā)人員錯(cuò)誤地操作內(nèi)存從而導(dǎo)致應(yīng)用程序的崩潰,保證了程序的穩(wěn)定性。但是,垃圾回收也帶來(lái)了問題,為了實(shí)現(xiàn)垃圾回收,垃圾回收器必須跟蹤內(nèi)存的使用情況,釋放沒用的對(duì)象,在完成內(nèi)存的釋放后,還需要處理堆中的碎片,這些操作必定會(huì)增加JVM的負(fù)擔(dān),從而降低程序的執(zhí)行效率。
對(duì)于對(duì)象而言,如果沒有任何變量去引用它,那么該對(duì)象將不可能被程序訪問,因此,可以認(rèn)為它是垃圾信息,可以被回收。只要有一個(gè)以上的變量引用該對(duì)象,該對(duì)象就不會(huì)被垃圾回收。
對(duì)于垃圾回收器來(lái)說(shuō),它使用有向圖來(lái)記錄和管理堆內(nèi)存中的所有對(duì)象,通過(guò)這個(gè)有向圖就可以識(shí)別哪些對(duì)象是“可達(dá)的”(有引用變量引用它就是可達(dá)的),哪些對(duì)象是“不可達(dá)的”(沒有引用變量引用它就是不可達(dá)的),所有“不可達(dá)”對(duì)象都是可被垃圾回收的。如下例所示:
publicclassTest
{
publicstaticvoidmain(String[]a)
{
Integeri1=newInteger(1);
Integeri2=newInteger(2);
i2=i1;
//someothercode
}
}
上述代碼在執(zhí)行到語(yǔ)句i2=i1后,內(nèi)存的引用關(guān)系如圖所示。
內(nèi)存的引用關(guān)系
此時(shí),如果垃圾回收器正在進(jìn)行垃圾回收操作,在遍歷上述有向圖的時(shí)候,資源2所占的內(nèi)存是不可達(dá)的,垃圾回收器就會(huì)認(rèn)為這塊內(nèi)存已經(jīng)不會(huì)再被使用了,因此,就會(huì)回收該塊內(nèi)存空間。
由于垃圾回收器的存在,Java語(yǔ)言本身沒有給開發(fā)人員提供顯式釋放已分配內(nèi)存的方法,也就是說(shuō),開發(fā)人員不能實(shí)時(shí)地調(diào)用垃圾回收器對(duì)某個(gè)對(duì)象或所有對(duì)象進(jìn)行垃圾回收。但開發(fā)人員可以通過(guò)調(diào)用System.gc()方法來(lái)通知垃圾回收器運(yùn)行,當(dāng)然,JVM也并不會(huì)保證垃圾回收器馬上就會(huì)運(yùn)行。由于gc方法的執(zhí)行會(huì)停止所有的響應(yīng),去檢查內(nèi)存中是否有可回收的對(duì)象,這會(huì)對(duì)程序的正常運(yùn)行以及性能造成極大的威脅,所以,在實(shí)際編程中,不推薦頻繁使用gc方法。)解析:5.
下面代碼是否可以進(jìn)行優(yōu)化?如果可以,怎么進(jìn)行優(yōu)化?
for(inti=0;i<1000;i++){
Objectobject=newObject();
System.out.println("objectnameis"+object);
}
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(可以進(jìn)行優(yōu)化,優(yōu)化后的代碼為:
Objectobject;
for(inti=0;i<1000;i++)
{
object=newObject();
System.out.println("objectnameis"+object);
}
題目中的寫法,object的作用范圍為for循環(huán)內(nèi)部,每當(dāng)執(zhí)行一次循環(huán)的時(shí)候,就需要在棧中分配一個(gè)存儲(chǔ)空間給object使用,這次循環(huán)結(jié)束后,object的作用域就結(jié)束了,就需要回收object占用的??臻g。本題中,由于循環(huán)次數(shù)為1000次,所以,需要分配1000次存儲(chǔ)空間,同時(shí)回收1000次存儲(chǔ)空間,開銷是非常大的。
如果改用上述寫法后,object在整個(gè)for循環(huán)執(zhí)行的過(guò)程中都是可見的。因此,就不需要不斷地在棧中給object申請(qǐng)與釋放空間,顯然,此種方法具有更高的效率。)解析:6.
如何能使JVM的堆、棧和持久代(perm)發(fā)生內(nèi)存溢出?
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(在Java語(yǔ)言中,通過(guò)new實(shí)例化的對(duì)象都存儲(chǔ)在堆空間中,因此,只要不斷地用new實(shí)例化對(duì)象且一直保持對(duì)這些對(duì)象的引用(垃圾回收器無(wú)法回收),實(shí)例化足夠多的實(shí)例出來(lái)就會(huì)導(dǎo)致堆溢出,示例代碼如下:
List<Object>1=newArrayList<Object>();
while(true)
1.add(newObject());
上面這段代碼會(huì)一直不停地創(chuàng)建Object的對(duì)象,并存儲(chǔ)在List里面。因?yàn)閯?chuàng)建出來(lái)的對(duì)象一直被引用,所以垃圾回收器無(wú)法進(jìn)行回收,在創(chuàng)建一定的數(shù)量后,就會(huì)出現(xiàn)堆溢出。
2)在方法調(diào)用的時(shí)候,棧用來(lái)保存上下文的一些內(nèi)容。由于棧的大小是有上限的,當(dāng)出現(xiàn)非常深層次的方法調(diào)用的時(shí)候,就會(huì)把棧的空間用完,最簡(jiǎn)單的棧溢出的代碼就是無(wú)限遞歸調(diào)用,示例代碼如下:
publicclassTest
{
publicstaticvoidf()
{
System.out.println("Hello");
f();
}
publicstaticvoidmain(String[]args)
{
f();
}
}
程序運(yùn)行的過(guò)程中會(huì)不斷地輸出“Hello”,輸出一會(huì)兒后就會(huì)拋出java.lang.StackOverflowError異常。
3)持久代。在Java語(yǔ)言中,當(dāng)一個(gè)類第一次被訪問的時(shí)候,JVM需要把類加載進(jìn)來(lái),而類加載器就會(huì)占用持久代的空間來(lái)存儲(chǔ)classes信息,持久代中主要包含以下的信息:類方法、類名、常量池和JVM使用的內(nèi)部對(duì)象等。當(dāng)JVM需要加載一個(gè)新的類的時(shí)候,如果持久代中沒有足夠的空間,此時(shí)就會(huì)拋出Java.Lang.OutOfMemoryError:PermGenSpace異常。所以,當(dāng)代碼加載足夠多類的時(shí)候就會(huì)導(dǎo)致持久代溢出。當(dāng)然,并不是所有的Java虛擬機(jī)都有持久代的概念。)解析:7.
Java堆被劃分成老年代和年輕代,它們有什么區(qū)別?
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(根據(jù)對(duì)象的生命周期的長(zhǎng)短把對(duì)象分成不同的種類(年輕代、年老代和持久代),并分別進(jìn)行內(nèi)存回收,也就是分代垃圾回收。
分代垃圾回收算法的主要思路如下:把堆分成兩個(gè)或者多個(gè)子堆,每一個(gè)子堆被視為一代。在運(yùn)行的過(guò)程中,優(yōu)先收集那些年幼的對(duì)象,如果一個(gè)對(duì)象經(jīng)過(guò)多次收集仍然存活,那么就可以把這個(gè)對(duì)象轉(zhuǎn)移到高一級(jí)的堆里,減少對(duì)其的掃描次數(shù)。
目前最常用的JVM是SUN公司(現(xiàn)被Oracle公司收購(gòu))的HotSport,它采用的算法為分代回收。
HotSport把JVM中堆空間劃分為三個(gè)代:年輕代(YoungGeneration)、老年代(OldGeneration)和永久代(PermanentGeneration)。以下將分別對(duì)這三個(gè)代進(jìn)行分析。
1)年輕代:被分成3個(gè)部分,一個(gè)Eden區(qū)和兩個(gè)相同的Survivor區(qū)。Eden區(qū)主要用來(lái)存儲(chǔ)新建的對(duì)象,Survivor區(qū)也被叫作from和to區(qū),Survivor區(qū)是大小相等的兩塊區(qū)域,在使用“復(fù)制”回收算法時(shí),作為雙緩存,起內(nèi)存整理的作用,因此,Survivor區(qū)始終都保持一個(gè)是空的。
2)老年代:主要存儲(chǔ)生命周期較長(zhǎng)的對(duì)象、超大的對(duì)象(無(wú)法在新生代分配的對(duì)象)。
3)永久代:存放代碼、字符串常量池和靜態(tài)變量等可以持久化的數(shù)據(jù)。SunJDK把方法區(qū)實(shí)現(xiàn)在了永久代。
由于永久代基本不參與垃圾回收,所以,這里重點(diǎn)介紹的是年輕代和老年代的垃圾回收方法。
新建對(duì)象優(yōu)先在Eden區(qū)分配內(nèi)存,如果Eden區(qū)已滿,在創(chuàng)建對(duì)象的時(shí)候,會(huì)因?yàn)闊o(wú)法申請(qǐng)到空間而觸發(fā)minorGc操作,minorGc主要用來(lái)對(duì)年輕代垃圾進(jìn)行回收:把Eden區(qū)中不能被回收的對(duì)象放入到空的Survivor區(qū),另一個(gè)Survivor區(qū)里不能被垃圾回收器回收的對(duì)象也會(huì)被放入到這個(gè)Survivor區(qū),這樣能保證有一個(gè)Survivor區(qū)是空的。如果在這個(gè)過(guò)程中發(fā)現(xiàn)Survivor區(qū)也滿了,就會(huì)把這些對(duì)象復(fù)制到老年代,或者Survivor區(qū)并沒有滿,但是有些對(duì)象已經(jīng)存在非常長(zhǎng)的時(shí)間,這些對(duì)象也將被放到老年代中,如果老年代也被放滿了,就會(huì)觸發(fā)fullGC。
引申:什么情況下會(huì)觸發(fā)fullGC,如何避免?
fullGC是用來(lái)清理整個(gè)堆空間,包括年輕代和永久代,所以fullGC會(huì)造成很大的系統(tǒng)資源開銷。因此,通常需要盡量避免fullGC操作。
下面介紹幾種常見的fullGC產(chǎn)生的原因以及避免的方法。
1)調(diào)用System.gc()方法會(huì)觸發(fā)fullGC,因此,在編碼的時(shí)候盡量避免調(diào)用這個(gè)方法。
2)老年代空間不足。由于老年代主要用來(lái)存儲(chǔ)從年輕代轉(zhuǎn)入的對(duì)象、大對(duì)象和大數(shù)組,因此,為了避免觸發(fā)fullGC,應(yīng)盡量做到讓對(duì)象在MinorGC階段被回收,不要?jiǎng)?chuàng)建過(guò)大的對(duì)象及數(shù)組。由于在MinorGC時(shí),只有Survivor區(qū)放不下的對(duì)象才會(huì)被放入老年代,而此時(shí)只有老年代也放不下才會(huì)觸發(fā)fullGC,因此,另外一種避免fullGC的方法如下:根據(jù)實(shí)際情況增大Survivor區(qū)、老年代空間或調(diào)低觸發(fā)并發(fā)GC(并發(fā)垃圾回收)的概率。
3)永久代滿。永久代主要存放class相關(guān)的信息,當(dāng)永久代滿的時(shí)候,也會(huì)觸發(fā)fullGC。為了避免這種情況的發(fā)生,可以增大永久代的空間(例如-XX:MaxPermSize=16m:設(shè)置永久代大小為16M)。為了避免永久代滿引起的fullGC,也可以開啟CMS回收永久代選項(xiàng)(開啟的選項(xiàng)為+CMSPermGenSweepingEnabled-XX:+CMSClassUnloadingEnabled。CMS利用和應(yīng)用程序線程并發(fā)的垃圾回收線程來(lái)進(jìn)行垃圾回收操作。
需要注意的是,Java8中已經(jīng)移除了永久代,新加了一個(gè)稱為元數(shù)據(jù)區(qū)的native內(nèi)存區(qū),所以,大部分類的元數(shù)據(jù)都在本地內(nèi)存中分配。)解析:8.
List<?extendsT>和List<?superT>之間有什么區(qū)別?
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(<?extendsT>表示類型的上界,也就是說(shuō)參數(shù)化的類型的可能是T或是T的子類。例如,下面的寫法都是合法的賦值語(yǔ)句:
List<?extendsNumber>list=newArrayList<Number>();
List<?ExtendsNumber>list=newArrayList<Integer>();//Integer是Number的子類
List<?ExtendsNumber>list=newArrayList<Float>();//Float也是Number的子類
<?extendsT>被設(shè)計(jì)為用來(lái)讀數(shù)據(jù)的泛型(只能讀取類型為T的元素),原因如下:
1)在上面賦值的示例中,對(duì)讀數(shù)據(jù)進(jìn)行分析:
①不管給list如何賦值,可以保證list里面存放的一定是Number類型或其子類,因此,可以從list列表里面讀取Number類型的值。
②不能從list中讀取Integer,因?yàn)閘ist里面可能存放的是Float值,同理,也不可以從list里面讀取Float。
2)對(duì)寫數(shù)據(jù)進(jìn)行分析:
①不能向list中寫Number,因?yàn)閘ist中有可能存放的是Float。
②不能向list中寫Integer,因?yàn)?ist中有可能存放的是Float。
③不能向list中寫Float,因?yàn)閘ist中有可能存放的是Integer。
從上面的分析可以發(fā)現(xiàn),只能從List<?extendsT>讀取T,因?yàn)闊o(wú)法確定它實(shí)際指向列表的類型,所以無(wú)法確定列表里面存放的實(shí)際的類型,也就無(wú)法向列表里面添加元素。
<?superT>表示類型下界,也就是說(shuō),參數(shù)化的類型是此類型的超類型(父類型)。
List<?superFloat>list=newArrayList<Float>()
List<?superFloat>list=newArrayList<Number>();
//Number是Float的父類
List<?superFloat>list=newArrayList<Object>();
//Object是Number的父類
<?superT>被設(shè)計(jì)為用來(lái)寫數(shù)據(jù)的泛型(只能寫入T或T的子類類型),不能用來(lái)讀,分析如下:
1)讀數(shù)據(jù)。無(wú)法保證list里面一定存放的是Float類型或Number類型,因?yàn)橛锌赡艽娣诺氖荗bject類型,唯一能確定的是list里面存放的是Object或其子類,但是無(wú)法確定具體子類的類型。正是由于無(wú)法確定list里面存放數(shù)據(jù)的類型,因此,無(wú)法從list里面讀取數(shù)據(jù)。
2)寫數(shù)據(jù)。
①可以向list里面寫入Float類型的數(shù)據(jù)(不管list里面實(shí)際存放的是Float、Number或Object,寫入Float都是允許的);同理,也可以向list里面添加Float子類類型的元素。
②不可以向list里面添加Number或Object類型的數(shù)據(jù),因?yàn)閘ist中可能存放的是Float類型的數(shù)據(jù)。
下面給出一個(gè)以上兩個(gè)泛型使用的場(chǎng)景:
publicclassCollections
{
publicstatic<T>
voidcopy(List<?superT>dest,List<?extendsT>src)
{
for(inti=0;i<src.size();i++)
dest.set(i,src.get(i));
}
})解析:9.
ArrayList、Vector和LinkedList有什么特點(diǎn)?
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(ArrayList、Vector和LinkedList類均在java.util包中,都是可伸縮的數(shù)組,即可以動(dòng)態(tài)改變長(zhǎng)度的數(shù)組。
ArrayList和Vector都是基于存儲(chǔ)元素的Object[]array來(lái)實(shí)現(xiàn)的,它們會(huì)在內(nèi)存中開辟一塊連續(xù)的空間來(lái)存儲(chǔ)。由于數(shù)據(jù)存儲(chǔ)是連續(xù)的,因此,它們支持用序號(hào)(下標(biāo)、索引)來(lái)訪問元素,同時(shí),索引數(shù)據(jù)的速度比較快。但是在插入元素的時(shí)候需要移動(dòng)容器中的元素,所以,對(duì)數(shù)據(jù)的插入操作執(zhí)行速度比較慢。ArrayList和Vector都有一個(gè)初始化的容量的大小,當(dāng)里面存儲(chǔ)的元素超過(guò)這個(gè)大小的時(shí)候,就需要?jiǎng)討B(tài)地?cái)U(kuò)充它們的存儲(chǔ)空間。為了提高程序的效率,每次擴(kuò)充容量的時(shí)候,不是簡(jiǎn)單地?cái)U(kuò)充一個(gè)存儲(chǔ)單元,而是一次就會(huì)增加多個(gè)存儲(chǔ)單元。Vector默認(rèn)擴(kuò)充為原來(lái)的兩倍(每次擴(kuò)充空間的大小是可以設(shè)置的),而ArrayList默認(rèn)擴(kuò)充為原來(lái)的1.5倍(沒有提供方法來(lái)設(shè)置空間擴(kuò)充的方法)。
ArrayList與Vector最大的區(qū)別就是Synchronization(同步)的使用,沒有一個(gè)ArrayList的方法是同步的,而Vector的絕大多數(shù)方法(例如add、insert、remove、set、equals、hashCode等)都是直接或者間接同步的,所以,Vector是線程安全的,ArrayList不是線程安全的。正是由于Vector提供了線程安全的機(jī)制,使其性能上也要略遜于ArrayList。
LinkedList是采用雙向列表來(lái)實(shí)現(xiàn)的,對(duì)數(shù)據(jù)的索引需要從列表頭開始遍歷,因此,隨機(jī)訪問的效率比較低,但是插入元素的時(shí)候不需要對(duì)數(shù)據(jù)進(jìn)行移動(dòng),插入效率較高。同時(shí),LinkedList不是線程安全的。
那么,在實(shí)際使用時(shí),如何從這幾種容器中選擇合適的使用呢?當(dāng)對(duì)數(shù)據(jù)的主要操作為索引或只在集合的末端增加、刪除元素,使用ArrayList或Vector效率比較高。當(dāng)對(duì)數(shù)據(jù)的操作主要為指定位置的插入或刪除操作,使用LinkedList效率比較高。當(dāng)在多線程中使用容器時(shí)(即多個(gè)線程會(huì)同時(shí)訪問該容器),選用Vector較為安全。)解析:10.
HashMap和Hashtable有什么區(qū)別?
(分?jǐn)?shù):2.00)__________________________________________________________________________________________
正確答案:(Java為數(shù)據(jù)結(jié)構(gòu)中的映射定義了一個(gè)接口java.util.Map,它有三個(gè)實(shí)現(xiàn)類:HashMap、Hashtable和TreeMap。Map是用來(lái)存儲(chǔ)鍵一值對(duì)的數(shù)據(jù)結(jié)構(gòu),在數(shù)組中通過(guò)數(shù)組下標(biāo)來(lái)對(duì)其內(nèi)容進(jìn)行索引,而在Map中,則是通過(guò)對(duì)象來(lái)進(jìn)行索引,用來(lái)索引的對(duì)象叫作key,其對(duì)應(yīng)的對(duì)象叫作value。
HashMap是一個(gè)最常用的Map,它根據(jù)鍵的HashCode值存儲(chǔ)數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度。由于HashMap與Hashtable都采用了hash方法進(jìn)行索引,因此,二者具有許多相似之處,它們主要有如下的一些區(qū)別:
1)HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)(非線程安全的實(shí)現(xiàn)),它們都實(shí)現(xiàn)了Map接口,主要區(qū)別在于HashMap允許空(null)鍵值(key)(但需要注意,HashMap最多只允許一條記錄的鍵為null,不允許多條記錄的值為null),而Hashtable不允許空(null)鍵值(key)。
2)HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因?yàn)閏ontains方法容易讓人引起誤解。Hashtable繼承自Dictionary類,而HashMap是Java1.2引進(jìn)的Mapinterface的一個(gè)實(shí)現(xiàn)。
3)Hashtable的方法是線程安全的,而HashMap由于不支持線程的同步,所以,它不是線程安全的。在多個(gè)線程訪問Hashtable時(shí),不需要開發(fā)人員對(duì)它進(jìn)行同步,而對(duì)于HashMap,開發(fā)人員必須提供額外的同步機(jī)制。所以,效率上HashMap可能高于Hashtable。
4)Hashtable使用Enumeration進(jìn)行遍歷,HashMap使用Iterator進(jìn)行遍歷。
5)Hashtable和HashMap采用的hash/rehash算法都幾乎一樣,所以,性能不會(huì)有很大的差異。
6)Hashtable中hash數(shù)組默認(rèn)大小是11,增加的方式是old*2+1。在HashMap中,hash數(shù)組的默認(rèn)大小是16,而且一定是2的指數(shù)。
7)hash值的使用不同,Hashtable直接使用對(duì)象的hashC
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 大型項(xiàng)目施工組織設(shè)計(jì)方案
- 城市建設(shè)圍擋管理方案
- 跨學(xué)科閱讀活動(dòng)實(shí)施方案
- 銷售團(tuán)隊(duì)管理人員360度反饋評(píng)估方案
- 銀行業(yè)疫情防控方案與應(yīng)急預(yù)案
- 中小學(xué)課外文藝活動(dòng)方案
- 特色文化街區(qū)幕墻裝飾工程施工組織設(shè)計(jì)方案
- 醫(yī)院電梯安全風(fēng)險(xiǎn)控制方案
- 電力機(jī)修廠故障排查方案
- 培訓(xùn)機(jī)構(gòu)教師師德師風(fēng)提升方案
- 消防安全培訓(xùn)內(nèi)容
- 2024-2030年辣椒種植行業(yè)市場(chǎng)深度分析及發(fā)展策略研究報(bào)告
- 變電站綠化維護(hù)施工方案
- 校園展美 課件 2024-2025學(xué)年人美版(2024)初中美術(shù)七年級(jí)上冊(cè)
- 2024版《糖尿病健康宣教》課件
- ktv保安管理制度及崗位職責(zé)(共5篇)
- 腦出血試題完整版本
- 義務(wù)教育信息科技課程標(biāo)準(zhǔn)(2022年版)考試題庫(kù)及答案
- 建筑施工安全生產(chǎn)責(zé)任書
- 新員工三級(jí)安全教育考試試題參考答案
- 公司年會(huì)策劃及執(zhí)行服務(wù)合同
評(píng)論
0/150
提交評(píng)論