Java基礎(chǔ)八股文背誦版v0.2
寫在最前面
秋招也進行了快兩個月了,小牛的八股文也進行了補充和更新,之后逐步放出八股文背誦版v0.2版本,給大家秋招助力?。ü娞?/strong>后端技術(shù)小牛說,后臺回復(fù)interviewtop,獲取面試八股文pdf版)
最近有收到讀者的一些反饋,感謝了我開發(fā)了網(wǎng)站http://interviewtop.top,對他們面試產(chǎn)生了巨大幫助,更有讀者給我發(fā)了小紅包贊助我。當(dāng)然啦,我也知道大家還是以學(xué)生群體為主,紅包和贊助免了哈!
我之前還是學(xué)生身份,分別租了阿里云騰訊云等等云服務(wù)器的9.9元學(xué)生套餐,利用各個廠的學(xué)生福利云服務(wù)器負載均衡做服務(wù)器后端,這幾個月,由于已經(jīng)成為社會人了,當(dāng)然沒這點福利了(9.9同等配置社會人現(xiàn)在得近200,所以還在上學(xué)的同學(xué)有需求這個羊毛可以薅一把)。而且隨著大家使用頻率的增高,配置要求當(dāng)然也不一定打的住了。
我目前的想法是,我的公眾號interviewtop和后端技術(shù)小牛說,會發(fā)一點廣告,負擔(dān)一下服務(wù)器和運營成本。真的覺著小牛給你們幫助的同學(xué)們,就多給小牛的文章來點閱讀量吧,謝謝大家了!給大家鞠躬!
除此之外,interviewtop網(wǎng)站也需要大家的幫助和支持!如果大家有面經(jīng),希望大家能貢獻一下:
在全部和對應(yīng)題庫下點擊搜索

搜索自己的面試題

點擊這題我面試見過,貢獻一下自己的面試經(jīng)歷

如果有些題題庫沒收錄,歡迎大家添加小牛微信,小牛后臺更新上!
Java語言具有哪些特點?
Java為純面向?qū)ο蟮恼Z言。它能夠直接反應(yīng)現(xiàn)實生活中的對象。 具有平臺無關(guān)性。java利用Java虛擬機運行字節(jié)碼,無論是在Windows、Linux還是MacOS等其它平臺對Java程序進行編譯,編譯后的程序可在其它平臺運行。 Java為解釋型語言,編譯器把Java代碼編譯成平臺無關(guān)的中間代碼,然后在JVM上解釋運行,具有很好的可移植性。 Java提供了很多內(nèi)置類庫。如對多線程支持,對網(wǎng)絡(luò)通信支持,最重要的一點是提供了垃圾回收器。 Java具有較好的安全性和健壯性。Java提供了異常處理和垃圾回收機制,去除了C++中難以理解的指針特性。 Java語言提供了對Web應(yīng)用開發(fā)的支持。
面向?qū)ο蟮娜筇匦裕?/span>
繼承:對象的一個新類可以從現(xiàn)有的類中派生,派生類可以從它的基類那繼承方法和實例變量,且派生類可以修改或新增新的方法使之更適合特殊的需求。
封裝:將客觀事物抽象成類,每個類可以把自身數(shù)據(jù)和方法只讓可信的類或?qū)ο蟛僮鳎瑢Σ豢尚诺倪M行信息隱藏。
多態(tài):允許不同類的對象對同一消息作出響應(yīng)。不同對象調(diào)用相同方法即使參數(shù)也相同,最終表現(xiàn)行為是不一樣的。
字節(jié)序定義以及Java屬于哪種字節(jié)序?
字節(jié)序是指多字節(jié)數(shù)據(jù)在計算機內(nèi)存中存儲或網(wǎng)絡(luò)傳輸時個字節(jié)的存儲順序。通常由小端和大端兩組方式。
小端:低位字節(jié)存放在內(nèi)存的低地址端,高位字節(jié)存放在內(nèi)存的高地址端。 大端:高位字節(jié)存放在內(nèi)存的低地址端,低位字節(jié)存放在內(nèi)存的高地址端。
Java語言的字節(jié)序是大端。
JDK與JRE有什么區(qū)別?
JDK:Java開發(fā)工具包(Java Development Kit),提供了Java的開發(fā)環(huán)境和運行環(huán)境。 JRE:Java運行環(huán)境(Java Runtime Environment),提供了Java運行所需的環(huán)境。
JDK包含了JRE。如果只運行Java程序,安裝JRE即可。要編寫Java程序需安裝JDK.
簡述Java訪問修飾符
default: 默認訪問修飾符,在同一包內(nèi)可見 private: 在同一類內(nèi)可見,不能修飾類 protected : 對同一包內(nèi)的類和所有子類可見,不能修飾類 public: 對所有類可見
構(gòu)造方法、成員變量初始化以及靜態(tài)成員變量三者的初始化順序?
先后順序:靜態(tài)成員變量、成員變量、構(gòu)造方法。詳細的先后順序:父類靜態(tài)變量、父類靜態(tài)代碼塊、子類靜態(tài)變量、子類靜態(tài)代碼塊、父類非靜態(tài)變量、父類非靜態(tài)代碼塊、父類構(gòu)造函數(shù)、子類非靜態(tài)變量、子類非靜態(tài)代碼塊、子類構(gòu)造函數(shù)。
接口和抽象類的相同點和區(qū)別?
相同點:
都不能被實例化。 接口的實現(xiàn)類或抽象類的子類需實現(xiàn)接口或抽象類中相應(yīng)的方法才能被實例化。
不同點:
接口只能有方法定義,不能有方法的實現(xiàn),而抽象類可以有方法的定義與實現(xiàn)。
實現(xiàn)接口的關(guān)鍵字為implements,繼承抽象類的關(guān)鍵字為extends。一個類可以實現(xiàn)多個接口,只能繼承一個抽象類。
當(dāng)子類和父類之間存在邏輯上的層次結(jié)構(gòu),推薦使用抽象類,有利于功能的累積。當(dāng)功能不需要,希望支持差別較大的兩個或更多對象間的特定交互行為,推薦使用接口。使用接口能降低軟件系統(tǒng)的耦合度,便于日后維護或添加刪除方法。
為什么Java語言不支持多重繼承?
為了程序的結(jié)構(gòu)能夠更加清晰從而便于維護。假設(shè)Java語言支持多重繼承,類C繼承自類A和類B,如果類A和B都有自定義的成員方法f(),那么當(dāng)代碼中調(diào)用類C的f()會產(chǎn)生二義性。Java語言通過實現(xiàn)多個接口間接支持多重繼承,接口由于只包含方法定義,不能有方法的實現(xiàn),類C繼承接口A與接口B時即使它們都有方法f(),也不能直接調(diào)用方法,需實現(xiàn)具體的f()方法才能調(diào)用,不會產(chǎn)生二義性。 多重繼承會使類型轉(zhuǎn)換、構(gòu)造方法的調(diào)用順序變得復(fù)雜,會影響到性能。
Java提供的多態(tài)機制?
Java提供了兩種用于多態(tài)的機制,分別是重載與覆蓋。
重載:重載是指同一個類中有多個同名的方法,但這些方法有不同的參數(shù),在編譯期間就可以確定調(diào)用哪個方法。 覆蓋:覆蓋是指派生類重寫基類的方法,使用基類指向其子類的實例對象,或接口的引用變量指向其實現(xiàn)類的實例對象,在程序調(diào)用的運行期根據(jù)引用變量所指的具體實例對象調(diào)用正在運行的那個對象的方法,即需要到運行期才能確定調(diào)用哪個方法。
重載與覆蓋的區(qū)別?
覆蓋是父類與子類之間的關(guān)系,是垂直關(guān)系;重載是同一類中方法之間的關(guān)系,是水平關(guān)系。 覆蓋只能由一個方法或一對方法產(chǎn)生關(guān)系;重載是多個方法之間的關(guān)系。 覆蓋要求參數(shù)列表相同;重載要求參數(shù)列表不同。 覆蓋中,調(diào)用方法體是根據(jù)對象的類型來決定的,而重載是根據(jù)調(diào)用時實參表與形參表來對應(yīng)選擇方法體。 重載方法可以改變返回值的類型,覆蓋方法不能改變返回值的類型。
final、finally和finalize的區(qū)別是什么?
final用于聲明屬性、方法和類,分別表示屬性不可變、方法不可覆蓋、類不可繼承。 finally作為異常處理的一部分,只能在try/catch語句中使用,finally附帶一個語句塊用來表示這個語句最終一定被執(zhí)行,經(jīng)常被用在需要釋放資源的情況下。 finalize是Object類的一個方法,在垃圾收集器執(zhí)行的時候會調(diào)用被回收對象的finalize()方法。當(dāng)垃圾回收器準(zhǔn)備好釋放對象占用空間時,首先會調(diào)用finalize()方法,并在下一次垃圾回收動作發(fā)生時真正回收對象占用的內(nèi)存。
出現(xiàn)在Java程序中的finally代碼塊是否一定會執(zhí)行?
當(dāng)遇到下面情況不會執(zhí)行。
當(dāng)程序在進入try語句塊之前就出現(xiàn)異常時會直接結(jié)束。 當(dāng)程序在try塊中強制退出時,如使用System.exit(0),也不會執(zhí)行finally塊中的代碼。
其它情況下,在try/catch/finally語句執(zhí)行的時候,try塊先執(zhí)行,當(dāng)有異常發(fā)生,catch和finally進行處理后程序就結(jié)束了,當(dāng)沒有異常發(fā)生,在執(zhí)行完finally中的代碼后,后面代碼會繼續(xù)執(zhí)行。值得注意的是,當(dāng)try/catch語句塊中有return時,finally語句塊中的代碼會在return之前執(zhí)行。如果try/catch/finally塊中都有return語句,finally塊中的return語句會覆蓋try/catch模塊中的return語句。
Java語言中關(guān)鍵字static的作用是什么?
static的主要作用有兩個:
為某種特定數(shù)據(jù)類型或?qū)ο蠓峙渑c創(chuàng)建對象個數(shù)無關(guān)的單一的存儲空間。 使得某個方法或?qū)傩耘c類而不是對象關(guān)聯(lián)在一起,即在不創(chuàng)建對象的情況下可通過類直接調(diào)用方法或使用類的屬性。
具體而言static又可分為4種使用方式:
修飾成員變量。用static關(guān)鍵字修飾的靜態(tài)變量在內(nèi)存中只有一個副本。只要靜態(tài)變量所在的類被加載,這個靜態(tài)變量就會被分配空間,可以使用''類.靜態(tài)變量''和''對象.靜態(tài)變量''的方法使用。 修飾成員方法。static修飾的方法無需創(chuàng)建對象就可以被調(diào)用。static方法中不能使用this和super關(guān)鍵字,不能調(diào)用非static方法,只能訪問所屬類的靜態(tài)成員變量和靜態(tài)成員方法。 修飾代碼塊。JVM在加載類的時候會執(zhí)行static代碼塊。static代碼塊常用于初始化靜態(tài)變量。static代碼塊只會被執(zhí)行一次。 修飾內(nèi)部類。static內(nèi)部類可以不依賴外部類實例對象而被實例化。靜態(tài)內(nèi)部類不能與外部類有相同的名字,不能訪問普通成員變量,只能訪問外部類中的靜態(tài)成員和靜態(tài)成員方法。
Java代碼塊執(zhí)行順序
父類靜態(tài)代碼塊(只執(zhí)行一次) 子類靜態(tài)代碼塊(只執(zhí)行一次) 父類構(gòu)造代碼塊 父類構(gòu)造函數(shù) 子類構(gòu)造代碼塊 子類構(gòu)造函數(shù) 普通代碼塊
Java中一維數(shù)組和二維數(shù)組的聲明方式?
一維數(shù)組的聲明方式:
type arrayName[] type[] arrayName
二維數(shù)組的聲明方式:
type arrayName[][] type[][] arrayName type[] arrayName[]
其中type為基本數(shù)據(jù)類型或類,arrayName為數(shù)組名字
String和StringBuffer有什么區(qū)別?
String用于字符串操作,屬于不可變類。String對象一旦被創(chuàng)建,其值將不能被改變。而StringBuffer是可變類,當(dāng)對象創(chuàng)建后,仍然可以對其值進行修改。
判等運算符==與equals的區(qū)別?
== 比較的是引用,equals比較的是內(nèi)容。
如果變量是基礎(chǔ)數(shù)據(jù)類型,== 用于比較其對應(yīng)值是否相等。如果變量指向的是對象,== 用于比較兩個對象是否指向同一塊存儲空間。
equals是Object類提供的方法之一,每個Java類都繼承自O(shè)bject類,所以每個對象都具有equals這個方法。Object類中定義的equals方法內(nèi)部是直接調(diào)用 == 比較對象的。但通過覆蓋的方法可以讓它不是比較引用而是比較數(shù)據(jù)內(nèi)容。
為什么要把String設(shè)計為不變量?
節(jié)省空間:字符串常量存儲在JVM的字符串池中可以被用戶共享。 提高效率:String會被不同線程共享,是線程安全的。在涉及多線程操作中不需要同步操作。 安全:String常被用于用戶名、密碼、文件名等使用,由于其不可變,可避免黑客行為對其惡意修改。
序列化是什么?
序列化是一種將對象轉(zhuǎn)換成字節(jié)序列的過程,用于解決在對對象流進行讀寫操作時所引發(fā)的問題。序列化可以將對象的狀態(tài)寫在流里進行網(wǎng)絡(luò)傳輸,或者保存到文件、數(shù)據(jù)庫等系統(tǒng)里,并在需要的時候把該流讀取出來重新構(gòu)造成一個相同的對象。
簡述Java中Class對象
java中對象可以分為實例對象和Class對象,每一個類都有一個Class對象,其包含了與該類有關(guān)的信息。
獲取Class對象的方法:
Class.forName(“類的全限定名”) 實例對象.getClass() 類名.class
Java反射機制是什么?
Java反射機制是指在程序的運行過程中可以構(gòu)造任意一個類的對象、獲取任意一個類的成員變量和成員方法、獲取任意一個對象所屬的類信息、調(diào)用任意一個對象的屬性和方法。反射機制使得Java具有動態(tài)獲取程序信息和動態(tài)調(diào)用對象方法的能力??梢酝ㄟ^以下類調(diào)用反射API。
Class類:可獲得類屬性方法 Field類:獲得類的成員變量 Method類:獲取類的方法信息 Construct類:獲取類的構(gòu)造方法等信息
簡述注解
Java 注解用于為 Java 代碼提供元數(shù)據(jù)。作為元數(shù)據(jù),注解不直接影響你的代碼執(zhí)行,但也有一些類型的注解實際上可以用于這一目的。
其可以用于提供信息給編譯器,在編譯階段時給軟件提供信息進行相關(guān)的處理,在運行時處理寫相應(yīng)代碼,做對應(yīng)操作。
簡述元注解
元注解可以理解為注解的注解,即在注解中使用,實現(xiàn)想要的功能。其具體分為:
@Retention: 表示注解存在階段是保留在源碼,還是在字節(jié)碼(類加載)或者運行期(JVM中運行)。 @Target:表示注解作用的范圍。 @Documented:將注解中的元素包含到 Javadoc 中去。 @Inherited:一個被@Inherited注解了的注解修飾了一個父類,如果他的子類沒有被其他注解修飾,則它的子類也繼承了父類的注解。 @Repeatable:被這個元注解修飾的注解可以同時作用一個對象多次,但是每次作用注解又可以代表不同的含義。
簡述Java異常的分類
Java異常分為Error(程序無法處理的錯誤),和Exception(程序本身可以處理的異常)。這兩個類均繼承Throwable。
Error常見的有StackOverFlowError,OutOfMemoryError等等。
Exception可分為運行時異常和非運行時異常。對于運行時異常,可以利用try catch的方式進行處理,也可以不處理。對于非運行時異常,必須處理,不處理的話程序無法通過編譯。
簡述throw與throws的區(qū)別
throw一般是用在方法體的內(nèi)部,由開發(fā)者定義當(dāng)程序語句出現(xiàn)問題后主動拋出一個異常。
throws一般用于方法聲明上,代表該方法可能會拋出的異常列表。
簡述泛型
泛型,即“參數(shù)化類型”,解決不確定對象具體類型的問題。在編譯階段有效。在泛型使用過程中,操作的數(shù)據(jù)類型被指定為一個參數(shù),這種參數(shù)類型在類中稱為泛型類、接口中稱為泛型接口和方法中稱為泛型方法。
簡述泛型擦除
Java編譯器生成的字節(jié)碼是不包涵泛型信息的,泛型類型信息將在編譯處理是被擦除,這個過程被稱為泛型擦除。
簡述Java基本數(shù)據(jù)類型
byte: 占用1個字節(jié),取值范圍-128 ~ 127 short: 占用2個字節(jié),取值范圍-2^15^ ~ 2^15^-1 int:占用4個字節(jié),取值范圍-2^31^ ~ 2^31^-1 long:占用8個字節(jié) float:占用4個字節(jié) double:占用8個字節(jié) char: 占用2個字節(jié) boolean:占用大小根據(jù)實現(xiàn)虛擬機不同有所差異
簡述自動裝箱拆箱
對于Java基本數(shù)據(jù)類型,均對應(yīng)一個包裝類。
裝箱就是自動將基本數(shù)據(jù)類型轉(zhuǎn)換為包裝器類型,如int->Integer
拆箱就是自動將包裝器類型轉(zhuǎn)換為基本數(shù)據(jù)類型,如Integer->int
簡述重載與重寫的區(qū)別
重寫即子類重寫父類的方法,方法對應(yīng)的形參和返回值類型都不能變。
重載即在一個類中,方法名相同,參數(shù)類型或數(shù)量不同。
簡述java的多態(tài)
Java多態(tài)可以分為編譯時多態(tài)和運行時多態(tài)。
編譯時多態(tài)主要指方法的重載,即通過參數(shù)列表的不同來區(qū)分不同的方法。
運行時多態(tài)主要指繼承父類和實現(xiàn)接口時,可使用父類引用指向子類對象。
運行時多態(tài)的實現(xiàn):主要依靠方法表,方法表中最先存放的是Object類的方法,接下來是該類的父類的方法,最后是該類本身的方法。如果子類改寫了父類的方法,那么子類和父類的那些同名方法共享一個方法表項,都被認作是父類的方法。因此可以實現(xiàn)運行時多態(tài)。
簡述抽象類與接口的區(qū)別
抽象類:體現(xiàn)的是is-a的關(guān)系,如對于man is a person,就可以將person定義為抽象類。
接口:體現(xiàn)的是can的關(guān)系。是作為模板實現(xiàn)的。如設(shè)置接口fly,plane類和bird類均可實現(xiàn)該接口。
一個類只能繼承一個抽象類,但可以實現(xiàn)多個接口。
簡述==與equals方法的區(qū)別
對于==,在基本數(shù)據(jù)類型比較時,比較的是對應(yīng)的值,對引用數(shù)據(jù)類型比較時,比較的是其內(nèi)存的存放地址。
對于equals方法,在該方法未被重寫時,其效果和==一致,但用戶可以根據(jù)對應(yīng)需求對判斷邏輯進行改寫,比如直接比較對象某個屬性值是否相同,相同則返回true,不同則返回false。需保證equals方法相同對應(yīng)的對象hashCode也相同。
簡述Object類常用方法
hashCode:通過對象計算出的散列碼。用于map型或equals方法。需要保證同一個對象多次調(diào)用該方法,總返回相同的整型值。 equals:判斷兩個對象是否一致。需保證equals方法相同對應(yīng)的對象hashCode也相同。 toString: 用字符串表示該對象 clone:深拷貝一個對象
簡述內(nèi)部類及其作用
成員內(nèi)部類:作為成員對象的內(nèi)部類??梢栽L問private及以上外部類的屬性和方法。外部類想要訪問內(nèi)部類屬性或方法時,必須要創(chuàng)建一個內(nèi)部類對象,然后通過該對象訪問內(nèi)部類的屬性或方法。外部類也可訪問private修飾的內(nèi)部類屬性。 局部內(nèi)部類:存在于方法中的內(nèi)部類。訪問權(quán)限類似局部變量,只能訪問外部類的final變量。 匿名內(nèi)部類:只能使用一次,沒有類名,只能訪問外部類的final變量。 靜態(tài)內(nèi)部類:類似類的靜態(tài)成員變量。
簡述String/StringBuffer與StringBuilder
String類采用利用final修飾的字符數(shù)組進行字符串保存,因此不可變。如果對String類型對象修改,需要新建對象,將老字符和新增加的字符一并存進去。
StringBuilder,采用無final修飾的字符數(shù)組進行保存,因此可變。但線程不安全。
StringBuffer,采用無final修飾的字符數(shù)組進行保存,可理解為實現(xiàn)線程安全的StringBuilder。
簡述Java序列化與反序列化的實現(xiàn)
序列化:將java對象轉(zhuǎn)化為字節(jié)序列,由此可以通過網(wǎng)絡(luò)對象進行傳輸。
反序列化:將字節(jié)序列轉(zhuǎn)化為java對象。
具體實現(xiàn):實現(xiàn)Serializable接口,或?qū)崿F(xiàn)Externalizable接口中的writeExternal()與readExternal()方法。
簡述JAVA的List
List是一個有序隊列,在JAVA中有兩種實現(xiàn)方式:
ArrayList 使用數(shù)組實現(xiàn),是容量可變的非線程安全列表,隨機訪問快,集合擴容時會創(chuàng)建更大的數(shù)組,把原有數(shù)組復(fù)制到新數(shù)組。
LinkedList 本質(zhì)是雙向鏈表,與 ArrayList 相比插入和刪除速度更快,但隨機訪問元素很慢。
Java中線程安全的基本數(shù)據(jù)結(jié)構(gòu)有哪些
HashTable: 哈希表的線程安全版,效率低 ConcurrentHashMap:哈希表的線程安全版,效率高,用于替代HashTable Vector:線程安全版Arraylist Stack:線程安全版棧 BlockingQueue及其子類:線程安全版隊列
簡述JAVA的Set
Set 即集合,該數(shù)據(jù)結(jié)構(gòu)不允許元素重復(fù)且無序。JAVA對Set有三種實現(xiàn)方式:
HashSet 通過 HashMap 實現(xiàn),HashMap 的 Key 即 HashSet 存儲的元素,Value系統(tǒng)自定義一個名為 PRESENT 的 Object 類型常量。判斷元素是否相同時,先比較hashCode,相同后再利用equals比較,查詢O(1)
LinkedHashSet 繼承自 HashSet,通過 LinkedHashMap 實現(xiàn),使用雙向鏈表維護元素插入順序。
TreeSet 通過 TreeMap 實現(xiàn)的,底層數(shù)據(jù)結(jié)構(gòu)是紅黑樹,添加元素到集合時按照比較規(guī)則將其插入合適的位置,保證插入后的集合仍然有序。查詢O(logn)
簡述JAVA的HashMap
JDK8 之前底層實現(xiàn)是數(shù)組 + 鏈表,JDK8 改為數(shù)組 + 鏈表/紅黑樹。主要成員變量包括存儲數(shù)據(jù)的 table 數(shù)組、元素數(shù)量 size、加載因子 loadFactor。HashMap 中數(shù)據(jù)以鍵值對的形式存在,鍵對應(yīng)的 hash 值用來計算數(shù)組下標(biāo),如果兩個元素 key 的 hash 值一樣,就會發(fā)生哈希沖突,被放到同一個鏈表上。
table 數(shù)組記錄 HashMap 的數(shù)據(jù),每個下標(biāo)對應(yīng)一條鏈表,所有哈希沖突的數(shù)據(jù)都會被存放到同一條鏈表,Node/Entry 節(jié)點包含四個成員變量:key、value、next 指針和 hash 值。在JDK8后鏈表超過8會轉(zhuǎn)化為紅黑樹。
若當(dāng)前數(shù)據(jù)/總數(shù)據(jù)容量>負載因子,Hashmap將執(zhí)行擴容操作。默認初始化容量為 16,擴容容量必須是 2 的冪次方、最大容量為 1<< 30 、默認加載因子為 0.75。
為何HashMap線程不安全
在JDK1.7中,HashMap采用頭插法插入元素,因此并發(fā)情況下會導(dǎo)致環(huán)形鏈表,產(chǎn)生死循環(huán)。
雖然JDK1.8采用了尾插法解決了這個問題,但是并發(fā)下的put操作也會使前一個key被后一個key覆蓋。
由于HashMap有擴容機制存在,也存在A線程進行擴容后,B線程執(zhí)行g(shù)et方法出現(xiàn)失誤的情況。
簡述java的TreeMap
TreeMap是底層利用紅黑樹實現(xiàn)的Map結(jié)構(gòu),底層實現(xiàn)是一棵平衡的排序二叉樹,由于紅黑樹的插入、刪除、遍歷時間復(fù)雜度都為O(logN),所以性能上低于哈希表。但是哈希表無法提供鍵值對的有序輸出,紅黑樹可以按照鍵的值的大小有序輸出。
Collection和Collections有什么區(qū)別?
Collection是一個集合接口,它提供了對集合對象進行基本操作的通用接口方法,所有集合都是它的子類,比如List、Set等。 Collections是一個包裝類,包含了很多靜態(tài)方法、不能被實例化,而是作為工具類使用,比如提供的排序方法:Collections.sort(list);提供的反轉(zhuǎn)方法:Collections.reverse(list)。
ArrayList、Vector和LinkedList有什么共同點與區(qū)別?
ArrayList、Vector和LinkedList都是可伸縮的數(shù)組,即可以動態(tài)改變長度的數(shù)組。 ArrayList和Vector都是基于存儲元素的Object[] array來實現(xiàn)的,它們會在內(nèi)存中開辟一塊連續(xù)的空間來存儲,支持下標(biāo)、索引訪問。但在涉及插入元素時可能需要移動容器中的元素,插入效率較低。當(dāng)存儲元素超過容器的初始化容量大小,ArrayList與Vector均會進行擴容。 Vector是線程安全的,其大部分方法是直接或間接同步的。ArrayList不是線程安全的,其方法不具有同步性質(zhì)。LinkedList也不是線程安全的。 LinkedList采用雙向列表實現(xiàn),對數(shù)據(jù)索引需要從頭開始遍歷,因此隨機訪問效率較低,但在插入元素的時候不需要對數(shù)據(jù)進行移動,插入效率較高。
HashMap和Hashtable有什么區(qū)別?
HashMap是Hashtable的輕量級實現(xiàn),HashMap允許key和value為null,但最多允許一條記錄的key為null.而HashTable不允許。 HashTable中的方法是線程安全的,而HashMap不是。在多線程訪問HashMap需要提供額外的同步機制。 Hashtable使用Enumeration進行遍歷,HashMap使用Iterator進行遍歷。
如何決定使用HashMap還是TreeMap?
如果對Map進行插入、刪除或定位一個元素的操作更頻繁,HashMap是更好的選擇。如果需要對key集合進行有序的遍歷,TreeMap是更好的選擇。
fail-fast和fail-safe迭代器的區(qū)別是什么?
fail-fast直接在容器上進行,在遍歷過程中,一旦發(fā)現(xiàn)容器中的數(shù)據(jù)被修改,就會立刻拋出ConcurrentModificationException異常從而導(dǎo)致遍歷失敗。常見的使用fail-fast方式的容器有HashMap和ArrayList等。 fail-safe這種遍歷基于容器的一個克隆。因此對容器中的內(nèi)容修改不影響遍歷。常見的使用fail-safe方式遍歷的容器有ConcurrentHashMap和CopyOnWriteArrayList。
HashSet中,equals與hashCode之間的關(guān)系?
equals和hashCode這兩個方法都是從object類中繼承過來的,equals主要用于判斷對象的內(nèi)存地址引用是否是同一個地址;hashCode根據(jù)定義的哈希規(guī)則將對象的內(nèi)存地址轉(zhuǎn)換為一個哈希碼。HashSet中存儲的元素是不能重復(fù)的,主要通過hashCode與equals兩個方法來判斷存儲的對象是否相同:
如果兩個對象的hashCode值不同,說明兩個對象不相同。 如果兩個對象的hashCode值相同,接著會調(diào)用對象的equals方法,如果equlas方法的返回結(jié)果為true,那么說明兩個對象相同,否則不相同。
