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