本文做者:黃小斜java
轉載請務必在文章開頭註明出處和做者。git
Java做爲一門後端語言,對於網絡編程的支持是必不可少的,可是,做爲一個常常CRUD的Java工程師,不少時候都不須要接觸到網絡編程,天然而然地對這個東西不那麼重視了,畢竟,即便像是JVM虛擬機,Java多線程,在平時工做的時候還會用到一些,可是對於網絡編程,除非你作的東西確實是須要本身寫通信服務代碼的,好比網絡遊戲,以及偏向中間件方向的開發, 可能會接觸到一些網絡編程的實踐,要否則在平時的開發工做中確實很少見。程序員
讓咱們看下網絡編程在百度百科上的定義:網絡編程最主要的工做就是在發送端把信息經過規定好的協議進行組裝包,在接收端按照規定好的協議把包進行解析,從而提取出對應的信息,達到通訊的目的。github
那麼,爲何網絡編程重要呢,簡單來講,計算機之間之因此可以通訊,靠的就是網絡編程,只不過平時這些代碼不須要咱們本身來寫罷了,TCP/IP的協議代碼已經封裝在了Linux內核中 ,而Tomcat裏的代碼則負責處理一個個網絡請求,返回請求方須要的數據。再好比像netty這樣的網絡編程框架,也會把複雜的NIO處理邏輯封裝成簡單的API,即便如此,須要使用netty來作服務端開發的工程師仍然很少。面試
Java網絡編程對於Java工程師來講是很重要的能力,這也是我在接觸了一系列相關面試題,以及Tomcat和netty實現以後才逐漸意識到的,想要了解這兩個東西的實現原理,就必需要會網絡編程的知識,固然了,這一切的基礎就是你要首先懂得計算機網絡,這部份內容也能夠參考我關於計算機網絡的一篇文章。算法
計算機網絡之於Java網絡編程,比如數據結構之於算法,前者是後者的基礎,沒有前者的支撐,直接學習後者,是沒有意義的。編程
以前我也寫了一篇關於計算機網絡該怎麼學的文章,能夠先看看。整體來看,計算機網絡告訴咱們的是,兩臺計算機想要進行通訊,它們須要約定一種傳輸協議和編碼解碼的標準,所以計算機網絡一般分爲5層,而其中一些標準就包括TCP和IP,HTTP等等,這些協議都是爲了更好地實現網絡數據傳輸而產生的。後端
可是,這些協議只是協議而已,要真正在Java代碼裏實現網絡傳輸,就須要讓代碼實現協議,固然了,像TCP/IP這樣通用的協議棧。還輪不到Java應用程序本身來實現,不然也太麻煩了,Linux的內核裏已經對其進行了封裝,而且會向上提供API,因此Java應用程序只須要調用Linux內核提供的便可。tomcat
而再往上,也就是HTTP這類應用層協議,Java代碼是能夠直接進行解析或者組裝的,畢竟HTTP的報文比較簡單,咱們能夠直接經過Java提供的API進行操做,你們也都知道,Java裏有一些網絡編程的包,提供了一些經常使用於網絡通信的類,好比Socket能夠用來創建網絡鏈接,IO流則能夠用來處理網絡傳輸的IO輸入和輸出。服務器
換言之,網絡編程的實質就是先進行網絡鏈接,而後進行IO傳輸,而網絡IO這個東西里又大有門道,這部份內容咱們在下一節裏繼續分享。
說到這三個東西,相比學過Java的朋友都不會陌生,畢竟面試題也常常考,背也都背下來了。
可是這幾個東西爲何會有這樣的區別呢,不妨一塊兒來探究一下。
BIO是最原始的Java IO模式,也叫阻塞式IO,多個BIO處理必需要串行執行,由於IO此時被阻塞了。
而NIO則是相對較新的一種模式,它基於Linux的epoll來進行實現,經過一個線程對多個鏈接進行處理,當發現有活躍的鏈接時進行對應的IO處理,本質上是IO多路複用的一種實現。
而AIO和上面二者不太同樣,它強調的不是阻塞非阻塞,而是對IO的處理是異步化的,一般來講就是創建鏈接,而後提供一個處理完IO的回調接口,而後就能夠扔在一邊無論了,等待IO處理結束後回調相應的接口。值得一提的是,AIO須要底層操做系統的支持。
瞭解了BIO、NIO和AIO以後,你對於網絡編程中的幾個核心概念你應該已經有所瞭解了,接下來就不得不看看Java網絡編程中最牛掰的一個框架:netty了。比起NIO和BIO,瞭解netty的人應該更少了,其實,netty就是基於NIO實現的異步網絡編程框架,既有了NIO的高性能IO處理方式,又經過異步化編程使得netty的編程方式更加簡單高效。
我當時接觸netty的時候,仍是在學習RPC和分佈式服務的時候,我發現每當有RPC出現的地方,也總有網絡編程框架的身影,比如netty這樣的通信框架經常會被提到,我當時並不太理解通信框架是幹嗎用的,以致於我對RPC是什麼東西都不太理解。
當我如今搞懂了RPC以後,再去研究網絡編程框架就有了新的感受,其實,無論是RPC仍是HTTP,都須要通訊框架的支持,只不過支持HTTP的服務器已經有不少了,好比Tomcat,好比Nginx,這些服務器徹底能夠cover掉網絡框架,後面咱們也會再來聊一下Tomcat這個神奇的服務器。
Tomcat這個服務器咱們Java工程師一直在用,可是不少朋友對它其實知之甚少,只知道它能夠運行JavaWeb應用。
其實Tomcat這個服務器,也是基於NIO實現的一個服務器,不妨把Tomcat分爲兩個部分來看,一部分是connector,負責網絡鏈接,接受請求和處理請求,另外一部分是container,也就是容器,Tomcat本質上是一個servlet容器,這一部分負責的就是編排一系列容器裏的處理器、調用鏈以及層級結構,好比engine的下一層是host,host的下一層是context。
當一個網絡請求到達Tomcat時,connector先負責處理這個請求,再扔到container跑一遍拿到結果,但在生產環境中,connector一次性要處理的請求就多的去了,所以就必需要支持高併發以及IO多路複用,所以Tomcat也採用了NIO的IO處理方式,同時經過多線程進行請求處理,整體來講已經達到了很是不錯的性能了。
一個小小的Java網絡編程,竟然一會兒牽扯出這麼多複雜的知識點出來,先是計算機網絡,再到Java網絡編程API,再到BIO、NIO和AIO,而後又談到了Tomcat和netty。
其實,網絡編程的內容可能還不止這些,好比NIO的底層實現是基於Linux的epoll來完成了,而Linux的網絡IO模型有select、poll和epoll等方式,要真正搞懂NIO,你還須要搞懂epoll。
其實一開始我對於Java網絡編程也沒有什麼概念,只不過在看了不少面試題以後,才逐漸發現問題所在,好比BIO和NIO的區別,背了好幾回面試答案仍然不解其意,要是再問到epoll、poll和select的區別,更是徹底不得要領,究其緣由仍是不知道這些東西究竟是什麼,有什麼用,以及它們和一些實際場景間的關係。
所以,我以爲,網絡編程方向的面試題重在理解概念,對於計算機網絡、IO模型,以及網絡編程框架要可以真正理解了這些東西以後,你纔可以對面試題遊刃有餘,不然,這類面試題再怎麼背都不會有什麼效果,正如計算機網絡這種純理論的課程同樣,在不理解的狀況下,分析問題和回答問題確定是難以達到面試官要求的。
因此,請按照這樣的一個順序進行復習和實踐,相信這對於你學習網絡編程會有所幫助。
一、計算機網絡知識
二、Java網絡編程基礎
三、NIO、BIO、AIO
四、Linux的網絡IO模型:epoll、select和poll
五、netty網絡編程框架
六、Tomcat服務器
這方面能推薦的資源就很是多了,我儘可能按照先易後難的順序爲你們推薦資源
《Java網絡編程》
《netty權威指南》
《How Tomcat Work》
《Tomcat架構解析》
我整理一些Java網絡編程複習的視頻資源,習慣看視頻的朋友能夠了解一下。
Java技術倉庫《Java程序員複習指南》
https://github.com/h2pl/Java-Tutorial
整合全網優質Java學習內容,幫助你從基礎到進階系統化複習Java。
關於如何學習Java網絡編程,而且搞定相關面試題,咱們今天就講到這裏了,若是還有什麼疑問也能夠到我公衆號裏找我探討,後續會有更多的文章推出,包括如何系統性地學習JavaWeb,以及如何系統性地學習後端技術。敬請期待。
對了,你想問我文章裏提到的資源去哪找?我已經給你準備好了
文中提到的資源均可以避免費領取,在個人公衆號【程序員黃小斜】回覆「Java網絡編程「便可免費領取對應的資源。
若是以爲本文對你有幫助的話,請你也不要吝嗇你的「好看」哈,轉發朋友圈就是對我最大的支持啦,大家的支持是對我最大的鼓勵。
對本系列文章有什麼建議和意見,也歡迎留言告訴我,期待你的回饋。
微信公衆號:程序員黃小斜 知乎:黃小斜 B站:黃小斜