史上最全的Android面試題集錦(十一)

5、類加載器

程序在啟動(dòng)的時(shí)候,并不會(huì)一次性加載程序所要用的所有class文件,而是根據(jù)程序的需要,通過Java的類加載機(jī)制(ClassLoader)來(lái)動(dòng)態(tài)加載某個(gè)class文件到內(nèi)存當(dāng)中的,從而只有class文件被載入到了內(nèi)存之后,才能被其它c(diǎn)lass所引用。所以ClassLoader就是用來(lái)動(dòng)態(tài)加載class文件到內(nèi)存當(dāng)中用的。

5.1、雙親委派原理

每個(gè)ClassLoader實(shí)例都有一個(gè)父類加載器的引用(不是繼承關(guān)系,是一個(gè)包含的關(guān)系),虛擬機(jī)內(nèi)置的類加載器(Bootstrap ClassLoader)本身沒有父類加載器,但是可以用做其他ClassLoader實(shí)例的父類加載器。

當(dāng)一個(gè)ClassLoader 實(shí)例需要加載某個(gè)類時(shí),它會(huì)試圖在親自搜索這個(gè)類之前先把這個(gè)任務(wù)委托給它的父類加載器,這個(gè)過程是由上而下依次檢查的,首先由頂層的類加載器Bootstrap CLassLoader進(jìn)行加載,如果沒有加載到,則把任務(wù)轉(zhuǎn)交給Extension CLassLoader視圖加載,如果也沒有找到,則轉(zhuǎn)交給AppCLassLoader進(jìn)行加載,還是沒有的話,則交給委托的發(fā)起者,由它到指定的文件系統(tǒng)或者網(wǎng)絡(luò)等URL中進(jìn)行加載類。還沒有找到的話,則會(huì)拋出CLassNotFoundException異常。否則將這個(gè)類生成一個(gè)類的定義,并將它加載到內(nèi)存中,最后返回這個(gè)類在內(nèi)存中的Class實(shí)例對(duì)象。

5.2、 為什么使用雙親委托模型

JVM在判斷兩個(gè)class是否相同時(shí),不僅要判斷兩個(gè)類名是否相同,還要判斷是否是同一個(gè)類加載器加載的。

避免重復(fù)加載,父類已經(jīng)加載了,則子CLassLoader沒有必要再次加載。

考慮安全因素,假設(shè)自定義一個(gè)String類,除非改變JDK中CLassLoader的搜索類的默認(rèn)算法,否則用戶自定義的CLassLoader如法加載一個(gè)自己寫的String類,因?yàn)镾tring類在啟動(dòng)時(shí)就被引導(dǎo)類加載器Bootstrap CLassLoader加載了。

6、集合

Java集合類主要由兩個(gè)接口派生出:Collection和Map,這兩個(gè)接口是Java集合的根接口。

Collection接口是集合類的根接口,Java中沒有提供這個(gè)接口的直接的實(shí)現(xiàn)類。但是卻讓其被繼承產(chǎn)生了兩個(gè)接口,就是 Set和List。Set中不能包含重復(fù)的元素。List是一個(gè)有序的集合,可以包含重復(fù)的元素,提供了按索引訪問的方式。

Map是Java.util包中的另一個(gè)接口,它和Collection接口沒有關(guān)系,是相互獨(dú)立的,但是都屬于集合類的一部分。Map包含了key-value對(duì)。Map不能包含重復(fù)的key,但是可以包含相同的value。

6.1、區(qū)別

List,Set都是繼承自Collection接口,Map則不是;

List特點(diǎn):元素有放入順序,元素可重復(fù); Set特點(diǎn):元素?zé)o放入順序,元素不可重復(fù),重復(fù)元素會(huì)覆蓋掉,(注意:元素雖然無(wú)放入順序,但是元素在set中的位置是有該元素的HashCode決定的,其位置其實(shí)是固定的,加入Set 的Object必須定義equals()方法;

LinkedList、ArrayList、HashSet是非線程安全的,Vector是線程安全的;

HashMap是非線程安全的,HashTable是線程安全的;

6.2、List和Vector比較

Vector是多線程安全的,線程安全就是說多線程訪問同一代碼,不會(huì)產(chǎn)生不確定的結(jié)果。而ArrayList不是,這個(gè)可以從源碼中看出,Vector類中的方法很多有synchronized進(jìn)行修飾,這樣就導(dǎo)致了Vector在效率上無(wú)法與ArrayList相比;

兩個(gè)都是采用的線性連續(xù)空間存儲(chǔ)元素,但是當(dāng)空間不足的時(shí)候,兩個(gè)類的增加方式是不同。

Vector可以設(shè)置增長(zhǎng)因子,而ArrayList不可以。

Vector是一種老的動(dòng)態(tài)數(shù)組,是線程同步的,效率很低,一般不贊成使用。

6.3、HashSet如何保證不重復(fù)

HashSet底層通過HashMap來(lái)實(shí)現(xiàn)的,在往HashSet中添加元素是

public boolean add(E e) {

return map.put(e, PRESENT)==null;

}

// Dummy value to associate with an Object in the backing Map

private static final Object PRESENT = new Object();

在HashMap中進(jìn)行查找是否存在這個(gè)key,value始終是一樣的,主要有以下幾種情況:

如果hash碼值不相同,說明是一個(gè)新元素,存;

如果hash碼值相同,且equles判斷相等,說明元素已經(jīng)存在,不存;

如果hash碼值相同,且equles判斷不相等,說明元素不存在,存;

如果有元素和傳入對(duì)象的hash值相等,那么,繼續(xù)進(jìn)行equles()判斷,如果仍然相等,那么就認(rèn)為傳入元素已經(jīng)存在,不再添加,結(jié)束,否則仍然添加;

6.4、HashSet與Treeset的適用場(chǎng)景

HashSet是基于Hash算法實(shí)現(xiàn)的,其性能通常都優(yōu)于TreeSet。為快速查找而設(shè)計(jì)的Set,我們通常都應(yīng)該使用HashSet,在我們需要排序的功能時(shí),我們才使用TreeSet。

TreeSet 是二叉樹(紅黑樹的樹據(jù)結(jié)構(gòu))實(shí)現(xiàn)的,Treeset中的數(shù)據(jù)是自動(dòng)排好序的,不允許放入null值

HashSet是哈希表實(shí)現(xiàn)的,HashSet中的數(shù)據(jù)是無(wú)序的,可以放入null,但只能放入一個(gè)null,兩者中的值都不能重復(fù),就如數(shù)據(jù)庫(kù)中唯一約束。

HashSet是基于Hash算法實(shí)現(xiàn)的,其性能通常都優(yōu)于TreeSet。為快速查找而設(shè)計(jì)的Set,我們通常都應(yīng)該使用HashSet,在我們需要排序的功能時(shí),我們才使用TreeSet。

6.5、HashMap與TreeMap、HashTable的區(qū)別及適用場(chǎng)景

HashMap 非線程安全,基于哈希表(散列表)實(shí)現(xiàn)。使用HashMap要求添加的鍵類明確定義了hashCode()和equals()[可以重寫hashCode()和equals()],為了優(yōu)化HashMap空間的使用,您可以調(diào)優(yōu)初始容量和負(fù)載因子。其中散列表的沖突處理主要分兩種,一種是開放定址法,另一種是鏈表法。HashMap的實(shí)現(xiàn)中采用的是鏈表法。

TreeMap:非線程安全基于紅黑樹實(shí)現(xiàn),TreeMap沒有調(diào)優(yōu)選項(xiàng),因?yàn)樵摌淇偺幱谄胶鉅顟B(tài)

原文鏈接:https://blog.csdn.net/xiangzhihong8/java/article/details/96280254

點(diǎn)擊下方鏈接免費(fèi)獲取Android進(jìn)階資料:

https://shimo.im/docs/tXXKHgdjPYj6WT8d/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容