Java基本知识
一、I/O
分字節(jié)流和字符流
字節(jié)流由InputStream和OutputStream讀入和寫(xiě)入
DataInputStream繼承自FilterInputStream,可以讀取基本數(shù)據(jù)類型(char, byte, short, int, long, double, float, boolean)和String類型
字符流有FileReader,FileWriter,StringReader,StringWriter,CharArrayReader,CharArrayWriter,BufferedReader和BufferedWriter
InputStreamReader可以把InputStream轉(zhuǎn)化為Reader,而OutputStreamReader可以把OutputStream轉(zhuǎn)化為Writer。
二、如何使用DataInputStream
Socket socket;
DataInputStream in = new DataInputStream( new BufferedInputStream( socket.getInputStream() ) );
in.readByte(); in.readUTF();
三、標(biāo)準(zhǔn)I/O重定向
Java的System類提供一些簡(jiǎn)單的靜態(tài)方法調(diào)用,允許我們對(duì)標(biāo)準(zhǔn)I/O和錯(cuò)誤I/O流進(jìn)行重定向:
SetIn(InputStream)
SetOut(PrintStream)
SetErr(PrintStream)
I/O重定向操作的是字節(jié)流而不是字符流,因此我們是用InputStream和OutputStream而不是Reader和Writer
四、NIO
NIO與I/O最重要的區(qū)別是數(shù)據(jù)打包和傳輸?shù)姆绞健T瓉?lái)的I/O以流的方式處理數(shù)據(jù),而NIO以塊的方式處理數(shù)據(jù)。
面向流的I/O系統(tǒng)一次一個(gè)字節(jié)地處理數(shù)據(jù)。一個(gè)輸入流產(chǎn)生一個(gè)字節(jié)的數(shù)據(jù),一個(gè)輸出流消費(fèi)一個(gè)字節(jié)的數(shù)據(jù)。為流式數(shù)據(jù)創(chuàng)建過(guò)濾器非常容易。鏈接幾個(gè)過(guò)濾器,以便每個(gè)過(guò)濾器只負(fù)責(zé)單個(gè)復(fù)雜處理機(jī)制的一部分,這樣也是相對(duì)簡(jiǎn)單的。不利的一面是,面向流的I/O 通常相當(dāng)慢。
面向塊的I/O系統(tǒng)以塊的形式處理數(shù)據(jù)。每一個(gè)操作都在一步中產(chǎn)生或者消費(fèi)一個(gè)數(shù)據(jù)塊。按塊處理數(shù)據(jù)比按(流式的)字節(jié)處理數(shù)據(jù)要快得多。但是面向塊的I/O缺少一些面向流的I/O所具有的優(yōu)雅性和簡(jiǎn)單性。
通道和緩沖區(qū)是NIO中的核心對(duì)象,幾乎在每一個(gè)I/O操作中都要使用它們。所有數(shù)據(jù)都通過(guò)Buffer對(duì)象來(lái)處理。您永遠(yuǎn)不會(huì)將字節(jié)直接寫(xiě)入通道中,相反,您是將數(shù)據(jù)寫(xiě)入包含一個(gè)或者多個(gè)字節(jié)的緩沖區(qū)。同樣,您不會(huì)直接從通道中讀取字節(jié),而是將數(shù)據(jù)從通道讀入緩沖區(qū),再?gòu)木彌_區(qū)獲取這個(gè)字節(jié)。
通道與流的不同之處在于通道是雙向的。而流只是在一個(gè)方向上移動(dòng)(一個(gè)流必須是InputStream或者OutputStream的子類), 而Channel可以用于讀、寫(xiě)或者同時(shí)用于讀寫(xiě)。因?yàn)樗鼈兪请p向的,所以通道可以比流更好地反映底層操作系統(tǒng)的真實(shí)情況。特別是在 UNIX 模型中,底層操作系統(tǒng)通道是雙向的。
Java NIO非堵塞技術(shù)實(shí)際是采取Reactor模式,或者說(shuō)是Observer模式為我們監(jiān)察I/O端口,如果有內(nèi)容進(jìn)來(lái),會(huì)自動(dòng)通知我們,這樣,我們就不必開(kāi)啟多個(gè)線程死等,從外界看,實(shí)現(xiàn)了流暢的I/O讀寫(xiě),不堵塞了。
NIO 有一個(gè)主要的類Selector,這個(gè)類似一個(gè)觀察者,只要我們把需要探知的socketchannel告訴Selector,我們接著做別的事情,當(dāng)有事件發(fā)生時(shí),他會(huì)通知我們,傳回一組SelectionKey,我們讀取這些Key,就會(huì)獲得我們剛剛注冊(cè)過(guò)的socketchannel,然后,我們從這個(gè)Channel中讀取數(shù)據(jù),放心,包準(zhǔn)能夠讀到,接著我們可以處理這些數(shù)據(jù)。
Selector內(nèi)部原理實(shí)際是在做一個(gè)對(duì)所注冊(cè)的channel的輪詢?cè)L問(wèn),不斷的輪詢(目前就這一個(gè)算法),一旦輪詢到一個(gè)channel有所注冊(cè)的事情發(fā)生,比如數(shù)據(jù)來(lái)了,他就會(huì)站起來(lái)報(bào)告,交出一把鑰匙,讓我們通過(guò)這把鑰匙來(lái)讀取這個(gè)channel的內(nèi)容。
了解了這個(gè)基本原理,我們結(jié)合代碼看看使用,在使用上,也在分兩個(gè)方向,一個(gè)是線程處理,一個(gè)是用非線程,后者比較簡(jiǎn)單。
五、Java如何存儲(chǔ)數(shù)據(jù)
JVM只能回收Heap中的內(nèi)容
六、Primitive Type
| Primitive type | Size | Minimum | Maximum | Wrapper type |
| char | 16bits | Unicode 0 | Unicode 215-1 | Character |
| byte | 8bits | -128 | 127 | Byte |
| short | 16 bits | -215 | 215-1 | Short |
| int | 32 bits | -231 | 231-1 | Integer |
| long | 64 bits | -263 | 263-1 | Long |
| float | 32 bits | ? | ? | Float |
| double | 64 bits | ? | ? | Double |
| boolean | ? | ? | ? | ? |
七、Java為什么可以移植
Java每種基本數(shù)據(jù)類型所占存儲(chǔ)空間大小不隨硬件架構(gòu)變化而變化.
八、將float或者double值轉(zhuǎn)成整型值后,總是將小數(shù)部分砍掉,而不是四舍五入。Math.random()范圍為[0,1)。
九、java類加載原理和過(guò)程
java中默認(rèn)有三種類加載器:啟動(dòng)類加載器,擴(kuò)展類加載器,系統(tǒng)類加載器(也叫應(yīng)用類加載器)。
啟動(dòng)類加載器bootstrap負(fù)責(zé)加載jre/lib中的系統(tǒng)類,這種類加載器都是用c語(yǔ)言實(shí)現(xiàn)的,在java程序中沒(méi)有辦法獲得這個(gè)類加載器,對(duì)于java程序是一個(gè)概念而已,基本上不用考慮它的存在,像String,Integer這樣的類都是由啟動(dòng)類加載器加載器的。
擴(kuò)展類加載器ExtClassLoader負(fù)責(zé)加載jre/lib/ext中的類,一般使用java實(shí)現(xiàn),這是一個(gè)真正的java類加載器,和普通的類加載器一樣,其實(shí)這個(gè)類加載器對(duì)我們來(lái)說(shuō)也不是很重要,我們可以通過(guò)java程序獲得這個(gè)類加載器。
系統(tǒng)類加載器AppClassLoader加載第一個(gè)應(yīng)用類的加載器(其實(shí)這個(gè)定義并不準(zhǔn)確,下面你將會(huì)看到),也就是執(zhí)行java MainClass 時(shí)加載MainClass的加載器,這個(gè)加載器使用java實(shí)現(xiàn),使用的很廣泛,負(fù)責(zé)加載classpath中指定的類。
類加載器之間有一定的關(guān)系(父子關(guān)系),我們可以認(rèn)為擴(kuò)展類加載器的父加載器是啟動(dòng)類加載器(當(dāng)然不這樣認(rèn)為也是可以的,因?yàn)閱?dòng)類加載器表現(xiàn)在java中就是一個(gè)null),不過(guò)系統(tǒng)類加載器的父加載器一定是擴(kuò)展類加載器,類加載器在加載類的時(shí)候會(huì)先給父加載器一個(gè)機(jī)會(huì),只有父加載器無(wú)法加載時(shí)才會(huì)自己去加載。
在ClassLoader.java(ExtClassLoader和AppClassLoader的間接父類)中的loadClass(name)首先在內(nèi)存中查找該類是否被load進(jìn)來(lái)了,如果沒(méi)有l(wèi)oad進(jìn)來(lái)則依雙親委派原則進(jìn)行查找,你的類裝載器首先將請(qǐng)求傳遞給它的雙親類裝載器,然后將這個(gè)請(qǐng)求一路委派直到委派給啟動(dòng)類裝載器。則啟動(dòng)類裝載器可以將java.ang.String類返回給你的類裝載器,因?yàn)閱?dòng)類裝載器可以找到這個(gè)類,所以就不必在擴(kuò)展類裝載器中查找了,否則將在擴(kuò)展類裝載器查找,如果再找不到就在系統(tǒng)類裝載器查找,如果系統(tǒng)類裝載器也找不到就試圖從網(wǎng)絡(luò)下載這個(gè)類。不同類裝載器中的類不能訪問(wèn)彼此的包內(nèi)可見(jiàn)成員。另外說(shuō)明一點(diǎn),包名不能以java.開(kāi)頭,否則會(huì)拋出SecurityException。
十、類實(shí)例化途徑?
十一、ConcurrentHashMap底層實(shí)現(xiàn)
?pasting
十二、Volatile
十三、
十四、
pasting?
pasting?
轉(zhuǎn)載于:https://www.cnblogs.com/siodoon/p/5314580.html
總結(jié)
- 上一篇: 数据库死锁的解决办法
- 下一篇: 如何在高并发环境下设计出无锁的数据库操作