本文做者:黄小斜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站:黄小斜