Java IO:BIO和NIO區(qū)別及各自應(yīng)用場景
一個面向流、一個面向緩沖區(qū)
一個是阻塞式的、一個非阻塞
一個沒有io多路復(fù)用器、一個有
NIO,I/O多路復(fù)用(IOmultiplexing)是一種更好的方法,調(diào)用select函數(shù)時,其內(nèi)部會維護一張監(jiān)聽的套接字的列表,其會一直阻塞直到其中某一個套接字有數(shù)據(jù)準(zhǔn)備好才返回,并告訴是哪個套接字可讀,這時再調(diào)用該套接字的read函數(shù)效率更高。
NIO適用場景
服務(wù)器需要支持超大量的長時間連接。比如10000個連接以上,并且每個客戶端并不會頻繁地發(fā)送太多數(shù)據(jù)。例如總公司的一個中心服務(wù)器需要收集全國便利店各個收銀機的交易信息,只需要少量線程按需處理維護的大量長期連接。
Jetty、Mina、Netty、ZooKeeper等都是基于NIO方式實現(xiàn)。
BIO適用場景
適用于連接數(shù)目比較小,并且一次發(fā)送大量數(shù)據(jù)的場景,這種方式對服務(wù)器資源要求比較高,并發(fā)局限于應(yīng)用中。
OOM 里面的jstack/top
使用top -c?會列出當(dāng)前的進程列表
如果你知道的是哪個進程, 只是不知道哪個pid , 這個命令可以幫助你。
ps -ef| grep 'java'
jstack -l 1 | grep 0x21?查看下這個線程的棧信息
Java序列化
一、序列化的含義、意義及使用場景
序列化:將對象寫入到IO流中
反序列化:從IO流中恢復(fù)對象
意義:序列化機制允許將實現(xiàn)序列化的Java對象轉(zhuǎn)換位字節(jié)序列,這些字節(jié)序列可以保存在磁盤上,或通過網(wǎng)絡(luò)傳輸,以達(dá)到以后恢復(fù)成原來的對象。序列化機制使得對象可以脫離程序的運行而獨立存在。
使用場景:所有可在網(wǎng)絡(luò)上傳輸?shù)膶ο蠖急仨毷强尚蛄谢?,比如RMI(remote method invoke,即遠(yuǎn)程方法調(diào)用),傳入的參數(shù)或返回的對象都是可序列化的,否則會出錯;所有需要保存到磁盤的java對象都必須是可序列化的。通常建議:程序創(chuàng)建的每個JavaBean類都實現(xiàn)Serializeable接口。
二、序列化實現(xiàn)的方式
如果需要將某個對象保存到磁盤上或者通過網(wǎng)絡(luò)傳輸,那么這個類應(yīng)該實現(xiàn)Serializable接口或者Externalizable接口之一。
?使用transient關(guān)鍵字選擇不需要序列化的字段
Java序列化算法
所有保存到磁盤的對象都有一個序列化編碼號
當(dāng)程序試圖序列化一個對象時,會先檢查此對象是否已經(jīng)序列化過,只有此對象從未(在此虛擬機)被序列化過,才會將此對象序列化為字節(jié)序列輸出。
如果此對象已經(jīng)序列化過,則直接輸出編號即可。
volatile的作用
當(dāng)一個變量被標(biāo)記為volatile的時候,這個變量將被放在主存里面,而不是CPU的緩存里面。當(dāng)這個變量被讀取的時候,是從主存讀取,當(dāng)這個變量被寫入的時候,是寫入到主存。意味著讀寫volatile的變量,效率會比非volatile的變量低,只保證可見性
正確的使用場景,基本符合一個原則:一寫多讀:有一個數(shù)據(jù),只由一個線程更新,其他線程都來讀取。
arraylist是否線程安全
方式一:?
? ? ? ?能力強的小伙伴可以自己寫一個ArrayList的包裝類,在調(diào)用add()方法、update()以及remove()的時候加鎖,具體的實現(xiàn)方式小伙伴們自行決定,在這里就不多描述了。
方式二:
? ? ? ?使用Collections工具類進行操作:List?objects = Collections.synchronizedList(new ArrayList<>());這個ArrayList的操作方式是線程安全的。
方式三:
? ? ? 使用JUC包,new CopyOnWriteArrayList<>();方法也是線程安全的。首先這個包引入import? java.util.concurrent.CopyOnWriteArrayList;是來源于并發(fā)包的。底層實現(xiàn)也是數(shù)組。?原理是添加元素的時候首先會給原數(shù)組加鎖,之后取原數(shù)組的長度,然后在此基礎(chǔ)上復(fù)制一份并把長度+1,然后再把原數(shù)組的元素添加到新數(shù)組,然后再解鎖,做到了線程安全,使用ReentrantLock加鎖。但是在get方法是不加鎖的,所以執(zhí)行效率會比較高。
一、Redo log
重做日志用來實現(xiàn)事務(wù)的持久性,即D特性。它由兩部分組成:
①內(nèi)存中的重做日志緩沖
②重做日志文件
讀數(shù)據(jù)先從緩沖池讀,沒有再去磁盤
寫數(shù)據(jù)先寫緩沖池,定期刷到磁盤
二、Undo log
第二部分是Undo log,它可以實現(xiàn)如下兩個功能:
1.實現(xiàn)事務(wù)回滾
2.實現(xiàn)MVCC
HTTP協(xié)議主要特點
1、簡單快速:客戶向服務(wù)器請求服務(wù)時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務(wù)器聯(lián)系的類型不同。由于HTTP協(xié)議簡單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快。
2、靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對象。正在傳輸?shù)念愋陀蒀ontent-Type加以標(biāo)記。
3.無連接:無連接的含義是限制每次連接只處理一個請求。服務(wù)器處理完客戶的請求,并收到客戶的應(yīng)答后,即斷開連接。采用這種方式可以節(jié)省傳輸時間。
4.無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議。無狀態(tài)是指協(xié)議對于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時它的應(yīng)答就較快。
5、支持B/S及C/S模式。
HashMap為什么使用紅黑樹
更加通用,相對于完全平衡二叉樹(AVL),AVL查找速度庫快,添加,刪除慢
在CurrentHashMap中是加鎖了的,實際上是讀寫鎖,如果寫沖突就會等待,
如果插入時間過長必然等待時間更長,而紅黑樹相對AVL樹他的插入更快!
事務(wù)傳播行為
REQUIRED(Spring默認(rèn)的事務(wù)傳播類型)
如果當(dāng)前沒有事務(wù),則自己新建一個事務(wù),如果當(dāng)前存在事務(wù),則加入這個事務(wù)
SUPPORTS
當(dāng)前存在事務(wù),則加入當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方法執(zhí)行
MANDATORY
當(dāng)前存在事務(wù),則加入當(dāng)前事務(wù),如果當(dāng)前事務(wù)不存在,則拋出異常。
NOT_SUPPORTED
始終以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則掛起當(dāng)前事務(wù)
NEVER
不使用事務(wù),如果當(dāng)前事務(wù)存在,則拋出異常
NESTED
如果當(dāng)前事務(wù)存在,則在嵌套事務(wù)中執(zhí)行,否則REQUIRED的操作一樣(開啟一個事務(wù))
代理
靜態(tài)代理在我們的代碼運行之前,代理類的.class文件就已經(jīng)存在