J2SE基礎(chǔ)~2
開心一刻:不要羨慕別人,幸福其實(shí)就是一碗白開水,你每天都在喝,不要羨慕別人喝的飲料有各種顏色,其實(shí)未必有你的白開水解渴!有這么一則寓言:“豬說假如讓我再活一次,我要做一頭牛,工作雖然累點(diǎn),但名聲好,讓人愛憐;牛說加入讓我再活一次,我要做一頭豬,吃罷睡,睡罷吃,不出力,不流汗,活得賽神仙;鷹說假如讓我再活一次,我要做一只雞,渴了有水,餓了有米,有房住,還受人保護(hù);雞說假如讓我再活一次,我要做一只鷹,可以翱翔天空,云游四海,任意捕兔殺雞”。幸福如人飲水,冷暖自知。你不是我,怎知我走過的路?怎知我心中的苦與樂?所以,真的不必去羨慕別人。明白自己所擁有的,想清楚自己真正想要的,才會(huì)真正快樂。扯了這么多還是看文章吧,想必你來這里也不是看我扯淡的,哈哈~ ~ !
下面正式進(jìn)入干貨區(qū),喜歡的話、雙擊、評(píng)論、轉(zhuǎn)發(fā),動(dòng)一動(dòng)你的小手讓更多的人知道!關(guān)注帥比~楊
HashMap和ConcurrentHashMap的區(qū)別,HashMap的底層源碼。
TreeMap、HashMap、LindedHashMap的區(qū)別。
Collection包結(jié)構(gòu)與Collections的區(qū)別。
try catch finally,try里有return,finally還執(zhí)行么?
Excption與Error包結(jié)構(gòu)。OOM你遇到過哪些情況,SOF你遇到過哪些情況。
Java面向?qū)ο蟮娜齻€(gè)特征與含義。
Override和Overload的含義及區(qū)別。
interface與abstract類的區(qū)別。
static class 與non static class的區(qū)別。
java多態(tài)的實(shí)現(xiàn)原理。
實(shí)現(xiàn)多線程的兩種方法:Thread與Runable。
線程同步的方法:sychronized、lock、reentrantLock等。
鎖的等級(jí):方法鎖、對(duì)象鎖、類鎖。
寫出生產(chǎn)者消費(fèi)者模式。
ThreadLocal的設(shè)計(jì)理念與作用。
ThreadPool用法與優(yōu)勢(shì)。
Concurrent包里的其他東西:ArrayBlockingQueue、CountDownLatch等等。
wait()和sleep()的區(qū)別。
foreach與正常for循環(huán)效率對(duì)比。
Java IO與NIO。
反射的作用與原理。
泛型常用特點(diǎn),List能否轉(zhuǎn)為List。
解析XML的幾種方式的原理與特點(diǎn):DOM、SAX、PULL。
Java與C++對(duì)比。
Java1.7與1.8新特性。
設(shè)計(jì)模式:單例、工廠、適配器、責(zé)任鏈、觀察者等等。
JNI的使用。
1. HashMap和ConcurrentHashMap的區(qū)別,HashMap的底層源碼。
HashMap
底層數(shù)組+鏈表實(shí)現(xiàn),可以存儲(chǔ)null鍵和null值,線程不安全初始size為16,擴(kuò)容:newsize = oldsize*2,size一定為2的n次冪擴(kuò)容針對(duì)整個(gè)Map,每次擴(kuò)容時(shí),原來數(shù)組中的元素依次重新計(jì)算存放位置,并重新插入元素后才判斷該不該擴(kuò)容,有可能無效擴(kuò)容(插入后如果擴(kuò)容,如果沒有再次插入,就會(huì)產(chǎn)生無效擴(kuò)容)當(dāng)Map中元素總數(shù)超過Entry數(shù)組的75%,觸發(fā)擴(kuò)容操作,為了減少鏈表長度,元素分配更均勻計(jì)算index方法:index = hash & (tab.length - 1)ConcurrentHashMap底層采用分段的數(shù)組+鏈表實(shí)現(xiàn),線程安全通過把整個(gè)Map分為N個(gè)Segment,可以提供相同的線程安全,但是效率提升N倍,默認(rèn)提升16倍。(讀操作不加鎖,由于HashEntry的value變量是 volatile的,也能保證讀取到最新的值。)
Hashtable的synchronized是針對(duì)整張Hash表的,即每次鎖住整張表讓線程獨(dú)占,ConcurrentHashMap允許多個(gè)修改操作并發(fā)進(jìn)行,其關(guān)鍵在于使用了鎖分離技術(shù)。有些方法需要跨段,比如size()和containsValue(),它們可能需要鎖定整個(gè)表而而不僅僅是某個(gè)段,這需要按順序鎖定所有段,操作完畢后,又按順序釋放所有段的鎖。擴(kuò)容:段內(nèi)擴(kuò)容(段內(nèi)元素超過該段對(duì)應(yīng)Entry數(shù)組長度的75%觸發(fā)擴(kuò)容,不會(huì)對(duì)整個(gè)Map進(jìn)行擴(kuò)容),插入前檢測(cè)需不需要擴(kuò)容,有效避免無效擴(kuò)容
2. TreeMap、HashMap、LindedHashMap的區(qū)別。
Map: 在數(shù)組中我們是通過數(shù)組下標(biāo)來對(duì)其內(nèi)容索引的,而在Map中我們通過對(duì)象來對(duì)對(duì)象進(jìn)行索引,用來索引的對(duì)象叫做key,其對(duì)應(yīng)的對(duì)象叫做value。這就是我們平時(shí)說的鍵值對(duì)。
HashMap 是一個(gè)最常用的Map,它根據(jù)鍵的HashCode 值存儲(chǔ)數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度。HashMap最多只允許一條記錄的鍵為Null;允許多條記錄的值為Null,且不支持線程的同步,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫HashMap,可能會(huì)導(dǎo)致數(shù)據(jù)的不一致。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。
LinkedHashMap是Map接口的哈希表和鏈接列表實(shí)現(xiàn),具有可預(yù)知的迭代順序。此實(shí)現(xiàn)提供所有可選的映射操作,并允許使用null值和null鍵。此類不保證映射的順序,特別是它不保證該順序恒久不變。 LinkedHashMap實(shí)現(xiàn)與HashMap的不同之處在于,后者維護(hù)著一個(gè)運(yùn)行于所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,該迭代順序可以是插入順序或者是訪問順序。 注意,此實(shí)現(xiàn)不是同步的。如果多個(gè)線程同時(shí)訪問鏈接的哈希映射,而其中至少一個(gè)線程從結(jié)構(gòu)上修改了該映射,則它必須保持外部同步。
TreeMap 不僅可以保持順序,而且可以用于排序;HashMap通常比TreeMap快一點(diǎn)(樹和哈希表的數(shù)據(jù)結(jié)構(gòu)使然),建議多使用HashMap,在需要排序的Map時(shí)候才用TreeMap。
3. Collection包結(jié)構(gòu)與Collections的區(qū)別。
Collection是集合類的上級(jí)接口,子接口主要有Set 和List。
Collections是針對(duì)集合類的一個(gè)幫助類,提供了操作集合的工具方法:一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作
Collections常用方法:
- sort(Collection)方法的使用(含義:對(duì)集合進(jìn)行排序)。
- binarySearch(Collection,Object)方法的使用(含義:查找指定集合中的元素,返回所查找元素的索引)。
- max(Collection),max(Collection,Comparator)方法的使用(前者采用Collection內(nèi)含自然比較法,后者采用Comparator進(jìn)行比較)。
- min(Collection),min(Collection,Comparator)方法的使用(前者采用Collection內(nèi)含自然比較法,后者采用Comparator進(jìn)行比較)。
- indexOfSubList(List list,List subList)方法的使用(含義:查找subList在list中首次出現(xiàn)位置的索引)。
- lastIndexOfSubList(List source,List target)方法的使用(含義:查找target在list中最后出現(xiàn)位置的索引)。
- reverse()方法的使用(含義:反轉(zhuǎn)集合中元素的順序)。
- rotate(List list,int m)方法的使用(含義:集合中的元素向后移m個(gè)位置,在后面被遮蓋的元素循環(huán)到前面來)。
感興趣可以來這里看些小demo:
4. try catch finally,try里有return,finally還執(zhí)行么?
這個(gè)說實(shí)話真的看基本功了,相信平時(shí)工作認(rèn)真的小伙伴應(yīng)該也答得出來,這里我貼上代碼。細(xì)節(jié)決定成敗你們贊同嗎?
try {
System.out.println("try");
return;
} catch (Exception e) {
System.out.println("catch");
}finally{
System.out.println("finally");
}
想必驗(yàn)證這個(gè)問題是個(gè)很簡單的問題,但你剛剛認(rèn)為對(duì)了嗎?
*ps: *只有在try里面調(diào)用System.exit(0)來退出JVM的情況下finally塊中的代碼才不會(huì)執(zhí)行。
5. Excption與Error包結(jié)構(gòu)。OOM你遇到過哪些情況,SOF你遇到過哪些情況。
Exception
(1) 可以是可被控制(checked) 或不可控制的(unchecked)。
(2) 表示一個(gè)由程序員導(dǎo)致的錯(cuò)誤。
(3) 應(yīng)該在應(yīng)用程序級(jí)被處理。
Error
(1) 總是不可控制的(unchecked)。
(2) 經(jīng)常用來用于表示系統(tǒng)錯(cuò)誤或低層資源的錯(cuò)誤。
(3) 如何可能的話,應(yīng)該在系統(tǒng)級(jí)被捕捉
出現(xiàn)OOM的場(chǎng)景:
- 加載對(duì)象過大
- 相應(yīng)資源過多,來不及加載。
解決方案:
- 內(nèi)存引用上做一些處理,常用的有軟引用。
- 內(nèi)存中加載圖片直接在內(nèi)存中做處理(如邊界壓縮)這個(gè)Glide\Fresco 圖片框架可能封裝好了
- 優(yōu)化Delivk虛擬機(jī)的堆內(nèi)存分配、自定義堆內(nèi)存大小
- 合適的場(chǎng)景動(dòng)態(tài)回收內(nèi)存
SOF
程序中一旦出現(xiàn)死循環(huán)或者是大量的遞歸調(diào)用,在不斷的壓棧過程中,造成棧容量超過默認(rèn)大小而導(dǎo)致溢出。
棧溢出的原因:
- 遞歸調(diào)用
- 大量循環(huán)或死循環(huán)
- 全局變量是否過多
- 數(shù)組、List、map數(shù)據(jù)過
總結(jié):Error 表示系統(tǒng)級(jí)的錯(cuò)誤和程序不必處理的異常,是一種很嚴(yán)重的問題無法通過程序修復(fù),比如內(nèi)存溢出,不可能指望程序能處理這樣的情況; Exception 表示需要捕捉或者需要程序進(jìn)行處理的異常,是一種設(shè)計(jì)或?qū)崿F(xiàn)問題,它表示如果程序運(yùn)行正常從不會(huì)發(fā)生的情況。而OOM和SOF大都是由于編碼不當(dāng)造成的程序內(nèi)存占用過高導(dǎo)致的問題,所以為了避免程序少出問題養(yǎng)成一個(gè)好的編程習(xí)慣是很重要的這個(gè)就需要大家多多總結(jié)和實(shí)踐了。
感興趣的小伙伴可以來這里看看:https://developer.android.com/topic/performance/memory.html
6. Java面向?qū)ο蟮娜齻€(gè)特征與含義。
封裝、繼承、多態(tài)
封裝:通常認(rèn)為封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來,對(duì)數(shù)據(jù)的訪問只能通過已經(jīng)定義的接口。面向?qū)ο蟮谋举|(zhì)就是將現(xiàn)實(shí)世界描繪成一系列完全自治、封閉的對(duì)象。我們?cè)陬愔芯帉懙姆椒ň褪菍?duì)實(shí)現(xiàn)細(xì)節(jié)的一種封裝;我們編寫一個(gè)類就是對(duì)數(shù)據(jù)和數(shù)據(jù)操作的封裝??梢哉f,封裝就是隱藏一切可隱藏的東西,只向外界提供最簡單的編程接口。
繼承:
繼承是子對(duì)象繼承父對(duì)象的屬性和行為,亦即父對(duì)象擁有的屬性和行為,其子對(duì)象也就擁有了這些屬性和行為。這非常類似大自然中的物種遺傳(孩子跟父親是很像的,且也可以有自己的獨(dú)立行為)。
多態(tài):
多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力,代碼中就是同一個(gè)接口使用不同的實(shí)例而執(zhí)行不同操作。
一張圖看明白多態(tài):

ps:打印機(jī)根據(jù)產(chǎn)物可以分為彩色和黑色打印機(jī)。他們都具有打印的作用,但是產(chǎn)物類似卻不同。彩色打印機(jī)打印效果:彩色;黑白打印機(jī)打印效果:黑白色;其實(shí)這就是多態(tài)。
7. Override和Overload的含義及區(qū)別。
Overload 是重載的意思,Override 是覆蓋的意思,也就是重寫。
Overload(重載) 表示同一個(gè)類中可以有多個(gè)名稱相同的方法,但這些方法的參數(shù)列表各不相同(即參數(shù)個(gè)數(shù)、類型或順序不同)。
Override(重寫) 表示子類中的方法可以與父類中的某個(gè)方法的名稱和參數(shù)完全相同,通過子類創(chuàng)建的實(shí)例對(duì)象調(diào)用這個(gè)方法時(shí),將調(diào)用子類中的定義方法,這相當(dāng)于把父類中定義的那個(gè)完全相同的方法給覆蓋了,這也是面向?qū)ο缶幊痰亩鄳B(tài)性的一種表現(xiàn)。(ps:子類覆蓋父類的方法時(shí),只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,因?yàn)樽宇惪梢越鉀Q父類的一些問題,不能比父類有更多的問題。子類方法的訪問權(quán)限只能比父類的更大,不能更小。如果父類的方法 是 private 類型,那么,子類則不存在覆蓋的限制,相當(dāng)于子類中增加了一個(gè)全新的方法。)
8. interface與abstract類的區(qū)別。
簡單來說,接口(interface)是公開的,里面不能有私有的方法或變量,是用于讓別人使用的,而抽象類是可以有私有方法或私有變量的,另外,實(shí)現(xiàn)接口一定要實(shí)現(xiàn)接口里定義的所有方法,而實(shí)現(xiàn)抽象類(abstract)可以有選擇地重寫需要用到的方法。一般的應(yīng)用里,最頂級(jí)的是接口,然后是抽象類實(shí)現(xiàn)接口,最后才到具體類實(shí)現(xiàn)。
9. static class 與non static class的區(qū)別。
static class
- 靜態(tài)內(nèi)部類不需要有指向外部類的引用;
- 靜態(tài)類只能訪問外部類的靜態(tài)成員,不能訪問外部類的非靜態(tài)成員;
non static class
- 非靜態(tài)內(nèi)部類需要持有對(duì)外部類的引用;
- 非靜態(tài)內(nèi)部類能夠訪問外部類的靜態(tài)和非靜態(tài)成員;
- 一個(gè)非靜態(tài)內(nèi)部類不能脫離外部類實(shí)體被創(chuàng)建;
- 一個(gè)非靜態(tài)內(nèi)部類可以訪問外部類的數(shù)據(jù)和方法;
10. java多態(tài)的實(shí)現(xiàn)原理。
上面“6. Java面向?qū)ο蟮娜齻€(gè)特征與含義”已經(jīng)進(jìn)行多態(tài)的解釋。實(shí)現(xiàn)原理大致是:程序在運(yùn)行期間編譯器會(huì)去查找函數(shù)所對(duì)應(yīng)的具體對(duì)象,不同的對(duì)象相同的函數(shù)可以運(yùn)行出不同的結(jié)果。(ps:我與小伙伴共同進(jìn)步,哪里有問題或者您覺得自己的理解更全面歡迎拍磚留下腳?。。?/p>
未完待續(xù)~~~
喜歡有幫助的話、雙擊、評(píng)論、轉(zhuǎn)發(fā),動(dòng)一動(dòng)你的小手讓更多的人知道!關(guān)注 帥比-楊