更新時(shí)間:2020-03-20 09:57:38 來源:動(dòng)力節(jié)點(diǎn) 瀏覽2901次
談?wù)凧ava反射機(jī)制,動(dòng)態(tài)代理是基于什么原理
反射機(jī)制是Java語(yǔ)言提供的一種基礎(chǔ)功能,賦予程序在運(yùn)行時(shí)自省(introspect,官方用語(yǔ))的能力。通過反射我們可以直接操作類或者對(duì)象,比如獲取某個(gè)對(duì)象的類定義,獲取類聲明的屬性和方法,調(diào)用方法或者構(gòu)造對(duì)象,甚至可以運(yùn)行時(shí)修改類定義。
動(dòng)態(tài)代理是一種方便運(yùn)行時(shí)動(dòng)態(tài)構(gòu)建代理、動(dòng)態(tài)處理代理方法調(diào)用的機(jī)制,很多場(chǎng)景都是利用類似機(jī)制做到的,比如用來包裝RPC調(diào)用、面向切面的編程(AOP)。
JDK動(dòng)態(tài)代理:基于Java反射機(jī)制實(shí)現(xiàn),必須要實(shí)現(xiàn)了接口的業(yè)務(wù)類才能用這種辦法生成代理對(duì)象。新版本也開始結(jié)合ASM機(jī)制。
cglib動(dòng)態(tài)代理:基于ASM機(jī)制實(shí)現(xiàn),通過生成業(yè)務(wù)類的子類作為代理類。
int和Integer有什么區(qū)別?談?wù)処nteger的值緩存范圍。
int是我們常說的整形數(shù)字,是Java的8個(gè)原始數(shù)據(jù)類型(PrimitiveTypes,boolean、byte、short、char、int、foat、double、long)之一。Java語(yǔ)言雖然號(hào)稱一切都是對(duì)象,但原始數(shù)據(jù)類型是例外。
Integer是int對(duì)應(yīng)的包裝類,它有一個(gè)int類型的字段存儲(chǔ)數(shù)據(jù),并且提供了基本操作,比如數(shù)學(xué)運(yùn)算、int和字符串之間轉(zhuǎn)換等。在Java5中,引入了自動(dòng)裝箱和自動(dòng)拆箱功能(boxing/unboxing),Java可以根據(jù)上下文,自動(dòng)進(jìn)行轉(zhuǎn)換,極大地簡(jiǎn)化了相關(guān)編程。
Integer的值默認(rèn)緩存是-128到127之間。緩存上限值實(shí)際是可以根據(jù)需要調(diào)整的,JVM提供了參數(shù)設(shè)置:-XX:AutoBoxCacheMax=N。
不管是Integer還Boolean等,都被聲明為“privatefnal”,所以,它們同樣是不可變類型!
對(duì)比Vector、ArrayList、LinkedList有何區(qū)別?
Vector是線程安全的動(dòng)態(tài)數(shù)組,。Vector內(nèi)部是使用對(duì)象數(shù)組來保存數(shù)據(jù),可以根據(jù)需要自動(dòng)增加容量,當(dāng)數(shù)組已滿時(shí),會(huì)創(chuàng)建新的數(shù)組,并拷貝原有數(shù)組數(shù)據(jù)。Vector在擴(kuò)容時(shí)會(huì)提高1倍
ArrayList是動(dòng)態(tài)數(shù)組實(shí)現(xiàn),不是線程安全的,性能要好很多。與Vector近似,ArrayList也是可以根據(jù)需要調(diào)整容量,不過兩者的調(diào)整邏輯有所區(qū)別。ArrayList擴(kuò)容時(shí)是增加50%。
Vector和ArrayList作為動(dòng)態(tài)數(shù)組,其內(nèi)部元素以數(shù)組形式順序存儲(chǔ)的,所以非常適合隨機(jī)訪問的場(chǎng)合。除了尾部插入和刪除元素,往往性能會(huì)相對(duì)較差,比如我們?cè)谥虚g位置插入一個(gè)元素,需要移動(dòng)后續(xù)所有元素。
LinkedList是Java提供的雙向鏈表,它不需要像上面兩種那樣調(diào)整容量,也不是線程安全的。LinkedList進(jìn)行節(jié)點(diǎn)插入、刪除卻要高效得多,但是隨機(jī)訪問性能則要比動(dòng)態(tài)數(shù)組慢。
TreeSet支持自然順序訪問,但是添加、刪除、包含等操作要相對(duì)低效(log(n)時(shí)間)。
HashSet則是利用哈希算法,理想情況下,如果哈希散列正常,可以提供常數(shù)時(shí)間的添加、刪除、包含等操作,但是它不保證有序。
LinkedHashSet,內(nèi)部構(gòu)建了一個(gè)記錄插入順序的雙向鏈表,因此提供了按照插入順序遍歷的能力,與此同時(shí),也保證了常數(shù)時(shí)間的添加、刪除、包含等操作,這些操作性能略低于HashSet,因?yàn)樾枰S護(hù)鏈表的開銷。
在遍歷元素時(shí),HashSet性能受自身容量影響,所以初始化時(shí),除非有必要,不然不要將其背后的HashMap容量設(shè)置過大。而對(duì)于LinkedHashSet,由于其內(nèi)部鏈表提供的方便,遍歷性能只和元素多少有關(guān)系。
Java提供的默認(rèn)排序算法:
對(duì)于原始數(shù)據(jù)類型,目前使用的是所謂雙軸快速排序,是一種改進(jìn)的快速排序算法,早期版本是相對(duì)傳統(tǒng)的快速排序
對(duì)于對(duì)象數(shù)據(jù)類型,目前則是使用TimSort,思想上也是一種歸并和二分插入排序結(jié)合的優(yōu)化排序算法
對(duì)比Hashtable、HashMap、TreeMap有什么不同?
元素特性:HashTable中的key、value都不能為null;HashMap中的key、value可以為null,很顯然只能有一個(gè)key為null的鍵值對(duì),但是允許有多個(gè)值為null的鍵值對(duì);TreeMap中當(dāng)未實(shí)現(xiàn)Comparator接口時(shí),key不可以為null;當(dāng)實(shí)現(xiàn)Comparator接口時(shí),若未對(duì)null情況進(jìn)行判斷,則key不可以為null,反之亦然。
順序特性:HashTable、HashMap具有無序特性。TreeMap是利用紅黑樹來實(shí)現(xiàn)的(樹中的每個(gè)節(jié)點(diǎn)的值,都會(huì)大于或等于它的左子樹種的所有節(jié)點(diǎn)的值,并且小于或等于它的右子樹中的所有節(jié)點(diǎn)的值),實(shí)現(xiàn)了SortMap接口,能夠?qū)Ρ4娴挠涗浉鶕?jù)鍵進(jìn)行排序。所以一般需要排序的情況下是選擇TreeMap來進(jìn)行,默認(rèn)為升序排序方式(深度優(yōu)先搜索),可自定義實(shí)現(xiàn)Comparator接口實(shí)現(xiàn)排序方式。
初始化與增長(zhǎng)方式:初始化時(shí):HashTable在不指定容量的情況下的默認(rèn)容量為11,且不要求底層數(shù)組的容量一定要為2的整數(shù)次冪;HashMap默認(rèn)容量為16,且要求容量一定為2的整數(shù)次冪。擴(kuò)容時(shí):Hashtable將容量變?yōu)樵瓉淼?倍加1;HashMap擴(kuò)容將容量變?yōu)樵瓉淼?倍。
HashMap基于哈希思想,實(shí)現(xiàn)對(duì)數(shù)據(jù)的讀寫。當(dāng)我們將鍵值對(duì)傳遞給put()方法時(shí),它調(diào)用鍵對(duì)象的hashCode()方法來計(jì)算hashcode,然后找到bucket位置來儲(chǔ)存值對(duì)象。當(dāng)獲取對(duì)象時(shí),通過鍵對(duì)象的equals()方法找到正確的鍵值對(duì),然后返回值對(duì)象。HashMap使用鏈表來解決碰撞問題,當(dāng)發(fā)生碰撞了,對(duì)象將會(huì)儲(chǔ)存在鏈表的下一個(gè)節(jié)點(diǎn)中。HashMap在每個(gè)鏈表節(jié)點(diǎn)中儲(chǔ)存鍵值對(duì)對(duì)象。當(dāng)兩個(gè)不同的鍵對(duì)象的hashcode相同時(shí),它們會(huì)儲(chǔ)存在同一個(gè)bucket位置的鏈表中,可通過鍵對(duì)象的equals()方法用來找到鍵值對(duì)。如果鏈表大小超過閾值(8),鏈表就會(huì)被改造為樹形結(jié)構(gòu)(紅黑樹)。
解決哈希沖突有哪些典型方法呢?
開放定址法:當(dāng)關(guān)鍵字key的哈希地址p=H(key)出現(xiàn)沖突時(shí),以p為基礎(chǔ),產(chǎn)生另一個(gè)哈希地址p1,如果p1仍然沖突,再以p為基礎(chǔ),產(chǎn)生另一個(gè)哈希地址p2,…,直到找出一個(gè)不沖突的哈希地址pi,將相應(yīng)元素存入其中。
再哈希法:當(dāng)哈希地址Hi=RH1(key)發(fā)生沖突時(shí),再計(jì)算Hi=RH2(key)……,直到?jīng)_突不再產(chǎn)生。這種方法不易產(chǎn)生聚集,但增加了計(jì)算時(shí)間。
鏈地址法:這種方法的基本思想是將所有哈希地址為i的元素構(gòu)成一個(gè)稱為同義詞鏈的單鏈表,并將單鏈表的頭指針存在哈希表的第i個(gè)單元中,因而查找、插入和刪除主要在同義詞鏈中進(jìn)行。鏈地址法適用于經(jīng)常進(jìn)行插入和刪除的情況。
Java提供了哪些IO方式?NIO如何實(shí)現(xiàn)多路復(fù)用?
傳統(tǒng)的java.io包,它基于流模型實(shí)現(xiàn),提供了我們最熟知的一些IO功能,比如File抽象、輸入輸出流等。交互方式是同步、阻塞的方式。
很多時(shí)候,人們也把java.net下面提供的部分網(wǎng)絡(luò)API,比如Socket、ServerSocket、HttpURLConnection也歸類到同步阻塞IO類庫(kù),因?yàn)榫W(wǎng)絡(luò)通信同樣是IO行為。
在Java1.4中引入了NIO框架(java.nio包),提供了Channel、Selector、Bufer等新的抽象,可以構(gòu)建多路復(fù)用的、同步非阻塞IO程序,同時(shí)提供了更接近操作系統(tǒng)底層的高性能數(shù)據(jù)操作方式。
在Java7中,NIO有了進(jìn)一步的改進(jìn),也就是NIO2,引入了異步非阻塞IO方式,也有很多人叫它AIO(AsynchronousIO)。異步IO操作基于事件和回調(diào)機(jī)制,可以簡(jiǎn)單理解為,應(yīng)用操作直接返回,而不會(huì)阻塞在那里,當(dāng)后臺(tái)處理完成,操作系統(tǒng)會(huì)通知相應(yīng)線程進(jìn)行后續(xù)工作。
NIO多路復(fù)用的局限性是什么呢?
由于nio實(shí)際上是同步非阻塞io,是一個(gè)線程在同步的進(jìn)行事件處理,當(dāng)一組事channel處理完畢以后,去檢查有沒有又可以處理的channel。這也就是同步+非阻塞。同步,指每個(gè)準(zhǔn)備好的channel處理是依次進(jìn)行的,非阻塞,是指線程不會(huì)傻傻的等待讀。只有當(dāng)channel準(zhǔn)備好后,才會(huì)進(jìn)行。那么就會(huì)有這樣一個(gè)問題,當(dāng)每個(gè)channel所進(jìn)行的都是耗時(shí)操作時(shí),由于是同步操作,就會(huì)積壓很多channel任務(wù),從而完成影響。那么就需要對(duì)nio進(jìn)行類似負(fù)載均衡的操作,如用線程池去進(jìn)行管理讀寫,將channel分給其他的線程去執(zhí)行,這樣既充分利用了每一個(gè)線程,又不至于都堆積在一個(gè)線程中,等待執(zhí)行
以上就是動(dòng)力節(jié)點(diǎn)Java培訓(xùn)機(jī)構(gòu)小編介紹的“2020年互聯(lián)網(wǎng)Java常見面試題”的內(nèi)容,希望對(duì)大家有幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743