Java高級工程師常見面試題(二)-Java IO

博主其他相關文章:《Java高級工程師常見面試題-總結》

1. 講講IO裏面的常見類,字節流、字符流、接口、實現類、方法阻塞。

            基於字節的io操作:

            

            

            基於字符的io操作:

           

            

IO常用類

文件流:FileInputStream/FileOutputStream, FileReader/FileWriter

這四個類是專門操作文件流的,用法高度相似,區別在於前面兩個是操作字節流,後面兩個是操作字符流。它們都會直接操作文件流,直接與OS底層交互。因此他們也被稱爲節點流。

注意使用這幾個流的對象之後,需要關閉流對象,因爲java垃圾回收器不會主動回收。不過在Java7之後,可以在 try() 括號中打開流,最後程序會自動關閉流對象,不再需要顯示地close。

包裝流:PrintStream/PrintWriter/Scanner

PrintStream可以封裝(包裝)直接與文件交互的節點流對象OutputStream, 使得編程人員可以忽略設備底層的差異,進行一致的IO操作。因此這種流也稱爲處理流或者包裝流。

PrintWriter除了可以包裝字節流OutputStream之外,還能包裝字符流Writer

Scanner可以包裝鍵盤輸入,方便地將鍵盤輸入的內容轉換成我們想要的數據類型。

字符串流:StringReader/StringWriter

這兩個操作的是專門操作String字符串的流,其中StringReader能從String中方便地讀取數據並保存到char數組,而StringWriter則將字符串類型的數據寫入到StringBuffer中(因爲String不可寫)。

轉換流:InputStreamReader/OutputStreamReader

這兩個類可以將字節流轉換成字符流,被稱爲字節流與字符流之間的橋樑。我們經常在讀取鍵盤輸入(System.in)或網絡通信的時候,需要使用這兩個類

緩衝流:BufferedReader/BufferedWriter , BufferedInputStream/BufferedOutputStream

沒有經過Buffered處理的IO, 意味着每一次讀和寫的請求都會由OS底層直接處理,這會導致非常低效的問題。

經過Buffered處理過的輸入流將會從一個buffer內存區域讀取數據,本地API只會在buffer空了之後纔會被調用(可能一次調用會填充很多數據進buffer)。

經過Buffered處理過的輸出流將會把數據寫入到buffer中,本地API只會在buffer滿了之後纔會被調用。

BufferedReader/BufferedWriter可以將字符流(Reader)包裝成緩衝流,這是最常見用的做法。

另外,BufferedReader提供一個readLine()可以方便地讀取一行,而FileInputStream和FileReader只能讀取一個字節或者一個字符,

因此BufferedReader也被稱爲行讀取器

總結上面幾種流的應用場景:

FileInputStream/FileOutputStream 需要逐個字節處理原始二進制流的時候使用,效率低下

FileReader/FileWriter 需要組個字符處理的時候使用

StringReader/StringWriter 需要處理字符串的時候,可以將字符串保存爲字符數組

PrintStream/PrintWriter 用來包裝FileOutputStream 對象,方便直接將String字符串寫入文件

Scanner 用來包裝System.in流,很方便地將輸入的String字符串轉換成需要的數據類型

InputStreamReader/OutputStreamReader , 字節和字符的轉換橋樑,在網絡通信或者處理鍵盤輸入的時候用

BufferedReader/BufferedWriter , BufferedInputStream/BufferedOutputStream , 緩衝流用來包裝字節流後者字符流,提升IO性能,BufferedReader還可以方便地讀取一行,簡化編程。

2. 講講NIO。

Java NIO(New IO)是一個可以替代標準Java IO API的IO API(從Java 1.4開始),Java NIO提供了與標準IO不同的IO工作方式。

Java NIO: Channels and Buffers(通道和緩衝區)

標準的IO基於字節流和字符流進行操作的,而NIO是基於通道(Channel)和緩衝區(Buffer)進行操作,數據總是從通道讀取到緩衝區中,或者從緩衝區寫入到通道中。

Java NIO: Non-blocking IO(非阻塞IO)

Java NIO可以讓你非阻塞的使用IO,例如:當線程從通道讀取數據到緩衝區時,線程還是可以進行其他事情。當數據被寫入到緩衝區時,線程可以繼續處理它。從緩衝區寫入通道也類似。

Java NIO: Selectors(選擇器)

Java NIO引入了選擇器的概念,選擇器用於監聽多個通道的事件(比如:連接打開,數據到達)。因此,單個的線程可以監聽多個數據通道。

參考地址:http://ifeve.com/java-nio-all/

3. String 編碼UTF-8 和GBK的區別?

GBK是在國家標準GB2312基礎上擴容後兼容GB2312的標準(好像還不是國家標準)。GBK編碼專門用來解決中文編碼的,是雙字節的。不論中英文都是雙字節的。

UTF-8 編碼是用以解決國際上字符的一種多字節編碼,它對英文使用8位(即一個字節),中文使用24位(三個字節)來編碼。對於英文字符較多的論壇則用UTF-8 節省空間。另外,如果是外國人訪問你的GBK網頁,需要下載中文語言包支持。訪問UTF-8編碼的網頁則不出現這問題。可以直接訪問。

GBK包含全部中文字符;UTF-8則包含全世界所有國家需要用到的字符。

經常有人問網頁編寫UTF-8和GBK哪個編碼好,根據個人需要,如果你主要做中文程序的開發,客戶也主要是中國人的話就用GBK吧,因爲UTF-8編碼的中文使用了三個字節,用GBK節省了空間。

如果做英文網站開發,還是用utf-8吧,因爲utf-8中英文只佔一個字節。GBK中英文也是兩個字節的,並且國外客戶訪問GBK要下載語言包。

如果你的網站是中文的,但國外用戶也不少,最好也用UTF-8的吧。

UTF-8編碼的文字可以在各國各種支持UTF8字符集的瀏覽器上顯示。

比如,如果是UTF8編碼,則在外國人的英文IE上也能顯示中文,而無需他們下載IE的中文語言支持包。 所以,對於英文比較多的論壇 ,使用GBK則每個字符佔用2個字節,而使用UTF-8英文卻只佔一個字節。

UTF8是國際編碼,它的通用性比較好,外國人也可以瀏覽論壇,GBK是國家編碼,通用性比UTF8差,不過UTF8佔用的數據庫比GBK大。

4. 什麼時候使用字節流、什麼時候使用字符流?

字符流處理的單元爲2個字節的Unicode字符,操作字符、字符數組或字符串,

字節流處理單元爲1個字節,操作字節和字節數組。

所以字符流是由Java虛擬機將字節轉化爲2個字節的Unicode字符爲單位的字符而成的,

所以它對多國語言支持性比較好!

如果是音頻文件、圖片、歌曲,就用字節流好點,

如果是關係到中文(文本)的,用字符流好點

 

所有文件的儲存是都是字節(byte)的儲存,在磁盤上保留的並不是文件的字符而是先把字符編碼成字節,再儲存這些字節到磁盤。在讀取文件(特別是文本文件)時,也是一個字節一個字節地讀取以形成字節序列

字節流可用於任何類型的對象,包括二進制對象,而字符流只能處理字符或者字符串;

字節流提供了處理任何類型的IO操作的功能,但它不能直接處理Unicode字符,而字符流就可以。

兩者區別:

一.字節流在操作時不會用到緩衝區(內存),是直接對文件本身進行操作的。而字符流在操作時使用了緩衝區,通過緩衝區再操作文件。

二.在硬盤上的所有文件都是以字節形式存在的(圖片,聲音,視頻),而字符值在內存中才會形成。

5. 遞歸讀取文件夾下的文件,代碼怎麼實現

遞歸算法是一種直接或間接地調用自身的算法。

棧 主要是用來存放棧幀的,每執行一個方法就會出現壓棧操作,所以採用遞歸的時候產生的棧幀比較多,遞歸就會影響到內存,非常消耗內存,而使用for循環就執行了一個方法,壓入棧幀一次,只存在一個棧幀,所以比較節省內存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章