Java基礎(chǔ)
JDK、JRE、JVM
JVM java虛擬機(jī),運(yùn)行java程序的程序,包含類加載器、內(nèi)存、執(zhí)行引擎
JRE java運(yùn)行環(huán)境,包含JVM和一組運(yùn)行java程序最基本的類庫
JDK java開發(fā)工具,包含JRE和一些開發(fā)類庫,比如java編譯命令,javac反編譯命令
JVM有哪些實(shí)現(xiàn)
hospot、Zing、J9、JRockit
java基本類型
- byte 8位 有符號整形
- short 16位 有符號整形
- char 16位 無符號字符型
- int 32位 有符號整形
- long 64位 有符號整形
- float 32位 有符號單精度浮點(diǎn)型
- double 64位 有符號雙精度浮點(diǎn)型
- boolean 1位 true或false
可見性修飾符
- public 可見
- protected 子類可見
- default 同包可見
- private 類內(nèi)可見
重載和重寫
- 重載 方法名相同,參數(shù)不同,返回值無所謂;方法名+參數(shù)形成全限定名
- 重寫 子類繼承父類,寫一個(gè)與父類方法名和參數(shù)都一樣的方法,會覆蓋父類方法;重寫的方法可見性修飾符不能低于父類,異常不能超過父類,否則在多態(tài)下會有問題
位運(yùn)算
- &與運(yùn)算
- |或運(yùn)算
- ^異或運(yùn)算 無進(jìn)位加法
左移 相當(dāng)于/2
無符號左移 相當(dāng)于/2
- <<右移 相當(dāng)于*2
位運(yùn)算執(zhí)行優(yōu)先級低于加減乘除
final關(guān)鍵字
修飾類 代表此類不可被繼承
修飾方法 代表此方法不可被重寫
修飾變量 代表此變量一旦賦值就不可以被修改
局部內(nèi)部類使用局部變量時(shí)為什么要加final
局部內(nèi)部類的生命周期可能會大于創(chuàng)建他的方法,而局部變量的生命周期是跟隨方法的,所以為了保證超出方法的生命周期之后還能訪問到局部變量,內(nèi)部類復(fù)制局部變量的引用,為了保證局部變量不修改,使用final修飾
String為什么要定義為final
String類被設(shè)計(jì)成不可變的類,主要執(zhí)行了三點(diǎn):
1.char數(shù)組使用final修飾
2.提供的方法不會修改char數(shù)組元素
3.使用final修飾類,防止方法被重寫
String類被設(shè)計(jì)為不可變的類:
1.主要原因,要復(fù)用字符串緩存池,享元模式
2.使用安全,比如在傳遞字符串過程中,不會導(dǎo)致字符串被改變
3.線程安全,沒有并發(fā)問題
new一個(gè)類的過程
類加載階段 static屬性和static代碼塊組成<cinit>方法被調(diào)用
類實(shí)例化階段 按順序給成員變量賦值、非靜態(tài)代碼塊、構(gòu)造方法
有父類,優(yōu)先父類的靜態(tài)加載和非靜態(tài)加載
String StringBuilder StringBuffer
String 字符串類 不可變 字符串常量池
StringBuilder 可變長字符串,append操作,內(nèi)部維護(hù)一個(gè)char數(shù)組,使用System.arraycopy進(jìn)行數(shù)組擴(kuò)容和拼接;線程不安全
StringBuffer append使用的synconized修飾保證線程安全
抽象類和接口
接口 全是抽象方法,沒有成員變量,可以有常量,可以多實(shí)現(xiàn),沒有構(gòu)造方法,描述的是能力
抽象類 可以有抽象方法,也可以有普通方法,不可以new,描述的是一類相同或相似的事物的屬性
異常
Throwable 所有異常的頂級父接口
Error 繼承Throwable 多為系統(tǒng)級異常 比如OOM
Exception 繼承Throwable checked異常
RuntimeException 繼承Exception unchecked異常
反射
java提供反射機(jī)制,供程序運(yùn)行階段創(chuàng)建對象,或動態(tài)修改對象內(nèi)容;
獲取filed或者method比較耗時(shí),可以使用緩存提升性能
內(nèi)部類
- 成員內(nèi)部類 生命周期依賴外部類實(shí)例化對象,可以訪問外部類的所有屬性
- 靜態(tài)內(nèi)部類 static修飾,依賴外部類class對象,可以訪問外部類所有靜態(tài)屬性HashMap.Entry
- 局部內(nèi)部類 定義在方法內(nèi)部,非靜態(tài),可以訪問外部類的所有成員屬性,訪問局部屬性需要加final(1.8之后不用加,隱式加)
- 匿名內(nèi)部類 不需要定義,可以訪問外部類的所有成員屬性,訪問局部屬性需要加final(1.8之后不用加,隱式加),多用于lambda表達(dá)式創(chuàng)建接口實(shí)現(xiàn)。
泛型
提供了編譯時(shí)類型安全檢測機(jī)制,編譯階段去泛型,
泛型方法,泛型類可以對參數(shù)進(jìn)行類型限制,返回值使用泛型,可以省卻強(qiáng)制轉(zhuǎn)換
<? extend XXXX> <? super XXXX>
序列化和transient
java序列化有兩種形式 實(shí)現(xiàn)Serializable接口和實(shí)現(xiàn)Externalizable
通過ObjectInputStream和ObjectOutputStream進(jìn)行序列化和反序列化
被transient標(biāo)記的屬性不會被序列化。
如果對象聲明了readObject和writeObject方法,對象在被序列化的時(shí)候會執(zhí)行對象的readObject和writeObject方法。
深表復(fù)制和淺表復(fù)制
java中實(shí)現(xiàn)Cloneable接口,才可以使用Object提供clone方法;
默認(rèn)的clone只是淺表復(fù)制,如果需要深表復(fù)制,需要自己實(shí)現(xiàn);
淺表復(fù)制 基本對象復(fù)制值,引用對象復(fù)制地址
深表復(fù)制 都復(fù)制值
深表復(fù)制要注意循環(huán);
BIO、NIO、AIO
- 阻塞IO 同步阻塞,用戶發(fā)出IO操作,會阻塞在那里直到數(shù)據(jù)準(zhǔn)備好,比如read操作
- 非阻塞IO 同步非阻塞,同步指讀數(shù)據(jù)同步,用戶發(fā)出IO操作,read操作會返回空或拋出異常,告知用戶線程數(shù)據(jù)還沒有準(zhǔn)備好,可以先去干別的;用戶可以將一些沒返回的IO操作緩存,定時(shí)去輪詢r(jià)ead
- IO多路復(fù)用 用戶發(fā)出IO操作,read操作會返回空或拋出異常,告知用戶線程數(shù)據(jù)還沒有準(zhǔn)備好;內(nèi)核提供方法,獲取一批已經(jīng)準(zhǔn)備好數(shù)據(jù)的IO,用戶直接輪詢這些IO操作就好了
- AIO 異步非阻塞,數(shù)據(jù)準(zhǔn)備跟讀數(shù)據(jù)都是異步的,用戶發(fā)出IO操作,由內(nèi)核監(jiān)聽IO準(zhǔn)備情況,用戶先去干別的,內(nèi)核會在數(shù)據(jù)準(zhǔn)備完成之后通知用戶,用戶說讀數(shù)據(jù),然后再去干別的,數(shù)據(jù)讀完會通知用戶來使用。
IO多路復(fù)用(select/poll/epoll)演變
select是內(nèi)核內(nèi)部輪詢準(zhǔn)備好的數(shù)據(jù),但是有數(shù)據(jù)量限制最多1000;poll本質(zhì)上還是select,只是沒有數(shù)據(jù)量限制了
epoll是一種信號驅(qū)動的,先epoll_create申請一個(gè)epoll空間,epoll_ctl向epoll空間中注冊監(jiān)聽事件,然后使用epoll_wait等待時(shí)間的到來,根據(jù)不同的時(shí)間類型來進(jìn)行操作
IO中的阻塞主要在兩個(gè)階段,數(shù)據(jù)準(zhǔn)備(硬件->內(nèi)核)和數(shù)據(jù)讀?。▋?nèi)核->用戶)
Java中的NIO
面向緩存,buffer、selector、chanel
socket來了之后綁定一個(gè)chanel,selector記錄下這個(gè)chanel進(jìn)行輪詢,讀取到的數(shù)據(jù)寫入buffer
Java集合和Map
ArrayList
內(nèi)部為數(shù)組結(jié)構(gòu); 初始10,擴(kuò)容 a+a/2; 按下標(biāo)檢索快,刪除元素、擴(kuò)容慢
LinkedList
內(nèi)部為鏈表結(jié)構(gòu);增刪元素快,按下標(biāo)檢索慢,需要迭代;遍歷速度比arrayList快一丟丟
HashSet
無序不重復(fù)集合,內(nèi)部復(fù)用HashMap
TreeSet
有序set,內(nèi)部復(fù)用TreeMap
TreeMap
有序map,內(nèi)部為紅黑樹
HashTable
同步map,內(nèi)部數(shù)組+鏈表 synconized
HashMap
JDK1.7 數(shù)組+鏈表,鏈表頭插法
JDK1.8 數(shù)組+鏈表+紅黑樹,數(shù)組長度超過64、鏈表長度超過8轉(zhuǎn)化為紅黑樹、泊松分布,會退化;鏈表尾插法
初始16,記載因子0.75;擴(kuò)容為2的n次冪,超過容量*加載因子后觸發(fā)擴(kuò)容;hash 高16^低16 ;數(shù)組下標(biāo)計(jì)算 (hash& 數(shù)組長度-1) ;擴(kuò)容需要rehash,創(chuàng)建一個(gè)新的數(shù)組,hash完成替換老數(shù)組;
JDK動態(tài)代理
關(guān)鍵是實(shí)現(xiàn)InvocationHandler,通過Proxy.newProxyInstance獲取代理對象