面試官 什麼是NIO?NIO的原理是什麼?

2021-10-03 18:11:55 字數 2893 閱讀 6332

首先說一下核心區別:

nio是以塊的方式處理資料,但是io是以最基礎的位元組流的形式去寫入和讀出的。所以在效率上的話,肯定是nio效率比io效率會高出很多。

nio不在是和io一樣用outputstream和inputstream 輸入流的形式來進行處理資料的,但是又是基於這種流的形式,而是採用了通道和緩衝區的形式來進行處理資料的。

還有一點就是nio的通道是可以雙向的,但是io中的流只能是單向的。

還有就是nio的緩衝區(其實也就是乙個位元組陣列)還可以進行分片,可以建立唯讀緩衝區、直接緩衝區和間接緩衝區,唯讀緩衝區很明顯就是字面意思,直接緩衝區是為加快 i/o 速度,而以一種特殊的方式分配其記憶體的緩衝區。

補充一點:nio比傳統的bio核心區別就是,nio採用的是多路復用的io模型,普通的io用的是阻塞的io模型,兩個之間的效率肯定是多路復用效率更高

bytebuffer

charbuffer

shortbuffer

intbuffer

longbuffer

floatbuffer

doublebuffer

1.這一步其實是當我們剛開始初始化這個buffer陣列的時候,開始預設是這樣的

2、但是當你往buffer陣列中開始寫入的時候幾個位元組的時候就會變成下面的圖,position會移動你資料的結束的下乙個位置,這個時候你需要把buffer中的資料寫到channel管道中,所以此時我們就需要用這個buffer.flip()方法,

3、當你呼叫完2中的方法時,這個時候就會變成下面的圖了,這樣的話其實就可以知道你剛剛寫到buffer中的資料是在position---->limit之間,然後下一步呼叫clear()

4、這時底層作業系統就可以從緩衝區中正確讀取這 5 個位元組資料傳送出去了。在下一次寫資料之前我們在調一下 clear() 方法。緩衝區的索引狀態又回到初始位置。(其實這一步有點像io中的把轉運位元組陣列char buf = new char[1024]不足1024位元組的部分給強制重新整理出去的意思)

1、這裡還要說明一下 mark,當我們呼叫mark()時,它將記錄當前 position 的前乙個位置,當我們呼叫 reset 時,position 將恢復 mark 記錄下來的值

2.clear()方法會:清空整個緩衝區。position將被設回0,limit被設定成 capacity的值(這個個人的理解就是當你在flip()方法的基礎上已經記住你寫入了多少位元組資料,直接把position到limit之間的也就是你寫入已經記住的資料給「複製」到管道中)

3.當你把緩衝區的數局寫入到管道中的時候,你需要呼叫flip()方法將buffer從寫模式切換到讀模式,呼叫flip()方法會將position設回0,並將limit設定成之前position的值。buf.flip();(其實我個人理解的就相當於先記住緩衝區緩衝了多少資料)

public void selector() throws ioexception  else if 

((key.readyops() & selectionkey.op_read) == selectionkey.op_read) 

buffer.flip();

}it.remove();}}

}}

首先是先建立serversocketchannel 物件,和真正處理業務的執行緒池

然後給剛剛建立的serversocketchannel 物件進行繫結乙個對應的埠,然後設定為非阻塞

然後建立selector物件並開啟,然後把這selector物件註冊到serversocketchannel 中,並設定好監聽的事件,監聽 selectionkey.op_accept

接著就是selector物件進行死迴圈監聽每乙個channel通道的事件,迴圈執行 selector.select() 方法,輪詢就緒的 channel

從selector中獲取所有的selectorkey(這個就可以看成是不同的事件),如果selectorkey是處於 op_accept 狀態,說明是新的客戶端接入,呼叫 serversocketchannel.accept 接收新的客戶端。

然後對這個把這個接受的新客戶端的channel通道註冊到serversocketchannel上,並且把之前的op_accept 狀態改為selectionkey.op_read讀取事件狀態,並且設定為非阻塞的,然後把當前的這個selectorkey給移除掉,說明這個事件完成了

如果第5步的時候過來的事件不是op_accept 狀態,那就是op_read讀取資料的事件狀態,然後呼叫本文章的上面的那個讀取資料的機制就可以了

建立 nio 執行緒組 eventloopgroup 和 serverbootstrap。

設定 serverbootstrap 的屬性:執行緒組、so_backlog 選項,設定 nioserversocketchannel 為 channel,設定業務處理 handler

繫結埠,啟動伺服器程式。

在業務處理 timeserverhandler 中,讀取客戶端傳送的資料,並給出響應

op_accept 的處理被簡化,因為對於 accept 操作的處理在不同業務上都是一致的。

在 nio 中需要自己構建 bytebuffer 從 channel 中讀取資料,而 netty 中資料是直接讀取完成存放在 bytebuf 中的。相當於省略了使用者程序從核心中複製資料的過程。

在 netty 中,我們看到有使用乙個解碼器 fixedlengthframedecoder,可以用於處理定長訊息的問題,能夠解決 tcp 粘包讀半包問題,十分方便。

推薦閱讀

程式設計師增加收入實用指南

說 4 個關鍵的技術趨勢

乙個培訓班出來的程式設計師

程式設計·思維·職場

歡迎掃碼關注

面試官問你 知道什麼是ABA問題嗎?

在開始問題闡述之前呢,我們先看一則小故事 在開始問題的闡述之前,我們先來看一則小故事 北宋宋真宗皇后死後,當時他的兩位愛妃劉妃和李妃都懷了孕,很顯然,誰生了兒子,誰就有可能立為正宮。劉妃久懷嫉妒之心,唯恐李妃生了兒子被立為皇后,於是與宮中總管都堂郭槐定計,在接生婆尤氏的配合下,乘李妃分娩時由於血暈而...

面試你的面試官

大多數面試都是面試官從簡歷,學歷,經歷,技術,為人上對你 乙個求職者 一番拷問,以確定是否是他們想要的人。而這些對找到適合你的工作的確沒什麼用。某公司某職位需要你,而某公司某職位不一定是你想要的!如果你想找到適合你的公司 如果你想找到適合你的職位 記得面試你的面試官,沒錯!做出很重要的職業決定前,面...

面試官的總結

近期2周面試了一些人。有一些感觸。有的人工作幾年,物件導向有幾大特性 各特性之間的差別也不清楚 有的人。問他時,他說,這個簡單,僅僅是我不會,這些理論的東西在平時工作中。用的少。有的人,不清楚過載和重構的差別,然後我說你回去在看看。前幾天,看到一則笑話 一高僧問我 一根魚竿和一筐魚,你選哪個?我說 ...