程式設計師必知面試技術,程式設計面試IO模型有幾種?分別是什麼?
《Java網路程式設計面試題》
出版單位:北京尚學堂優效學院
優效學院由清華大學著名的IT教育領導者馬士兵老師創辦,是一家線上線下相互融合的網際網路+培訓機構。公司均由海外留學生和國內行業精英人士擔任授課講師,主要成員均碩士且擁有十多年的行業經驗。畢業學生就職於國內BAT以及海外著名公司。優效學院,名師執教,高效學習,成就未來。
著:張洋
11年工作經驗 曾就職聯眾遊戲(程式設計師)、眾信旅遊(Team Leader)、精智教育(聯合創始人)、中國石化(大資料高階顧問) 精通javaEE體系、網際網路產品架構,熟悉Sap Bw/HANA、多個大資料專案經驗
20180926版
IO模型有幾種?分別是什麼?
在《Unix網路程式設計》一書中提到了五種IO模型
分別是:阻塞IO、非阻塞IO、多路複用IO、訊號驅動IO以及非同步IO。
下面就分別來介紹一下這5種IO模型的異同。
1.阻塞IO模型
最傳統的一種IO模型,即在讀寫資料過程中會發生阻塞現象。
當使用者執行緒發出IO請求之後,核心會去檢視資料是否就緒,如果沒有就緒就會等待資料就緒,而使用者執行緒就會處於阻塞狀態,使用者執行緒交出CPU。當資料就緒之後,核心會將資料拷貝到使用者執行緒,並返回結果給使用者執行緒,使用者執行緒才解除block狀態。
典型的阻塞IO模型的例子為:
data = socket.openinputstream();
如果資料沒有就緒,就會一直阻塞在read方法。
2.非阻塞IO模型
當使用者執行緒發起一個read操作後,並不需要等待,而是馬上就得到了一個結果。如果結果是一個error時,它就知道資料還沒有準備好,於是它可以再次傳送read操作。一旦核心中的資料準備好了,並且又再次收到了使用者執行緒的請求,那麼它馬上就將資料拷貝到了使用者執行緒,然後返回。
所以事實上,在非阻塞IO模型中,使用者執行緒需要不斷地詢問核心資料是否就緒,也就說非阻塞IO不會交出CPU,而會一直佔用CPU。
典型的非阻塞IO模型一般如下:
虛擬碼
while(true){
new MyThread(socket)
}
class MyThread{
data = socket.read();
if(data!= error){
處理資料
break;
}
但是對於非阻塞IO就有一個非常嚴重的問題,在while迴圈中需要不斷地去詢問核心資料是否就緒,這樣會導致CPU佔用率非常高,因此一般情況下很少使用while迴圈這種方式來讀取資料。
3.多路複用IO模型
多路複用IO模型是目前使用得比較多的模型。Java NIO實際上就是多路複用IO。
在多路複用IO模型中,會有一個執行緒不斷去輪詢多個socket的狀態,只有當socket真正有讀寫事件時,才真正呼叫實際的IO讀寫操作。因為在多路複用IO模型中,只需要使用一個執行緒就可以管理多個socket,系統不需要建立新的程式或者執行緒,也不必維護這些執行緒和程式,並且只有在真正有socket讀寫事件進行時,才會使用IO資源,所以它大大減少了資源佔用。
在Java NIO中,是通過selector.select()去查詢每個通道是否有到達事件,如果沒有事件,則一直阻塞在那裡,因此這種方式會導致使用者執行緒的阻塞。
也許有朋友會說,我可以採用 多執行緒+ 阻塞IO 達到類似的效果,但是由於在多執行緒 + 阻塞IO 中,每個socket對應一個執行緒,這樣會造成很大的資源佔用,並且尤其是對於長連線來說,執行緒的資源一直不會釋放,如果後面陸續有很多連線的話,就會造成效能上的瓶頸。
而多路複用IO模式,通過一個執行緒就可以管理多個socket,只有當socket真正有讀寫事件發生才會佔用資源來進行實際的讀寫操作。因此,多路複用IO比較適合連線數比較多的情況。
另外多路複用IO為何比非阻塞IO模型的效率高是因為在非阻塞IO中,不斷地詢問socket狀態時通過使用者執行緒去進行的,而在多路複用IO中,輪詢每個socket狀態是核心在進行的,這個效率要比使用者執行緒要高的多。
不過要注意的是,多路複用IO模型是通過輪詢的方式來檢測是否有事件到達,並且對到達的事件逐一進行響應。因此對於多路複用IO模型來說,一旦事件響應體很大,那麼就會導致後續的事件遲遲得不到處理,並且會影響新的事件輪詢。
4.訊號驅動IO模型
在訊號驅動IO模型中,當使用者執行緒發起一個IO請求操作,會給對應的socket註冊一個訊號函式,然後使用者執行緒會繼續執行,當核心資料就緒時會傳送一個訊號給使用者執行緒,使用者執行緒接收到訊號之後,便在訊號函式中呼叫IO讀寫操作來進行實際的IO請求操作。
5.非同步IO模型
非同步IO模型才是最理想的IO模型,在非同步IO模型中,當使用者執行緒發起read操作之後,立刻就可以開始去做其它的事。
而另一方面,從核心的角度,當它受到一個asynchronous read之後,它會立刻返回,說明read請求已經成功發起了,因此不會對使用者執行緒產生任何block。
然後,核心會等待資料準備完成,然後將資料拷貝到使用者執行緒,當這一切都完成之後,核心會給使用者執行緒傳送一個訊號,告訴它read操作完成了。
也就說使用者執行緒完全不需要實際的整個IO操作是如何進行的,只需要先發起一個請求,當接收核心返回的成功訊號時表示IO操作已經完成,可以直接去使用資料了。
也就說在非同步IO模型中,IO操作的兩個階段都不會阻塞使用者執行緒,這兩個階段都是由核心自動完成,然後傳送一個訊號告知使用者執行緒操作已完成。
使用者執行緒中不需要再次呼叫IO函式進行具體的讀寫。
這點是和訊號驅動模型有所不同的
在訊號驅動模型中,當使用者執行緒接收到訊號表示資料已經就緒,然後需要使用者執行緒呼叫IO函式進行實際的讀寫操作;而在非同步IO模型中,收到訊號表示IO操作已經完成,不需要再在使用者執行緒中呼叫iO函式進行實際的讀寫操作。
注意,非同步IO是需要作業系統的底層支援,在Java 7中,提供了Asynchronous IO。也就是java中的AIO NIO2.0
前面四種IO模型實際上都屬於同步IO,只有最後一種是真正的非同步IO,因為無論是多路複用IO還是訊號驅動模型,IO操作的第2個階段都會引起使用者執行緒阻塞,也就是核心進行資料拷貝的過程都會讓使用者執行緒阻塞。
本文章為連載內容,大家可以持續關注小編,我將盡其所能的為大家提供技術性實踐資料、文章、視訊。
感謝大家的支援!
相關文章
- 程式設計師必備:技術面試準備手冊程式設計師面試
- 程式設計師必知的六種隔離技術程式設計師
- 程式設計師面試什麼最重要?程式設計師面試
- 程式設計師應知:你有幾種武器程式設計師
- 程式設計師面試必備規程程式設計師面試
- IT程式設計師面試技巧有哪些?程式設計師面試
- 程式設計師面試中有幾大法則程式設計師面試
- 面試阿里P6,Java程式設計師必須掌握的技術面試阿里Java程式設計師
- 為什麼高階程式設計師討厭程式設計面試? - Adam程式設計師面試
- 好程式設計師:Java程式設計師面試秘籍程式設計師Java面試
- Java程式設計師面試必須要掌握的面試題Java程式設計師面試題
- 準備程式設計師面試?你需要了解這 14 種程式設計面試模式程式設計師面試模式
- 程式設計師面試技巧程式設計師面試
- 如何面試程式設計師?面試程式設計師
- 2013程式設計師面試什麼最重要?程式設計師面試
- 好程式設計師Java培訓Java程式設計師必學技術程式設計師Java
- 怎麼面試(社招)程式設計師?面試程式設計師
- 程式設計師程式碼面試指南程式設計師面試
- 還吐槽程式設計師的面試是:面試造航母,工作擰螺絲?華為表率必須現場程式設計!程式設計師面試
- 程式設計師面試經驗程式設計師面試
- 程式設計師面試資料程式設計師面試
- 糟糕的程式設計師面試程式設計師面試
- PHP程式設計師面試題PHP程式設計師面試題
- 華為程式設計師面試要改:網上程式設計 90 分鐘,現場程式設計 30 分鐘程式設計師面試
- 黑客和程式設計師有什麼區別?程式設計師目標是成神,黑客目標是弒神!黑客程式設計師
- 我是設計師面試官,你有什麼想問我的?面試
- 征服 JavaScript 面試:什麼是函數語言程式設計?JavaScript面試函數程式設計
- 程式設計師精美簡歷Top榜—面試必備程式設計師面試
- 看BAT技術面試官如何挑選Java程式設計師BAT面試Java程式設計師
- 程式設計師如何在技術面試表現得更出色?程式設計師面試
- 《C程式設計專家》:程式設計師面試(附2)C程式程式設計師面試
- IT程式設計師必知!TCP/IP為什麼會有這麼多的致命漏洞?程式設計師TCP
- 【1024程式設計師節】程式設計師,你學程式設計的初衷是什麼?程式設計師
- 什麼是程式設計師思維?程式設計師
- 我為什麼是程式設計師?程式設計師
- 什麼是真正的程式設計師?程式設計師
- 什麼是真正的程式設計師程式設計師
- 漫談程式設計師系列:程式設計師到底是什麼角色程式設計師