Java面试必面技术点(一)——IO模型
马上进入“金九银十”的黄金九月,身边很多小伙伴也都在找工作。我认为简单的面试问题能答好,答出细节,比问啥都说会,再一深问就哑口无言来的太好。所以先来一个面试技术点总结专题总结一下面试高频出现的技术点。
面试经常被问到BIO、NIO和AIO有什么的区别?在工作中什么场景下用到过?下面就来深入了解下这些IO模型吧。
I/O模型简介
I/O 模型简单的理解:就是用什么样的通道进行数据的发送和接收,其很大程度上决定了程序通信的性能;
Java共支持3种网络编程模型/IO模式:BIO、NIO、AIO
重点概括:
BIO:同步阻塞IO。jdk1.4之前只有BIO,也就是我们在Java基础中的IO。同步阻塞的意思是在读写操作时,程序阻塞,直到操作完成后才进行下步操作。
NIO:同步非阻塞IO。 NIO的核心是Channel(通道)、Buffer(缓冲区)和Selector(选择器)。一个线程对应一个Selector,下边管理多个Channel,Channel相当于BIO中的连接.
AIO:异步非阻塞IO。与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步非阻塞的。
BIO
BIO(Block IO)同步阻塞IO,我们平常所说的IO指的就是BIO,也是Java基础中的IO;
Jdk1.4之前都是采用BIO的形式;
BIO服务器实现的模式是一个连接对应一个线程,即客户端有连接请求时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。
如下图所示即为BIO模式,一个连接占用一个线程进行读写操作。
BIO缺点分析:
每个请求都需要创建独立的线程,与对应的客户端进行数据Read,业务处理,数据Write;
当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大;
连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在Read操作上,造成线程资源的浪费
NIO是事件驱动,即为连接中有数据,通道才打开;BIO不是事件驱动,连接一直保持,因此就造成了资源的浪费。
NIO
Java NIO全称Java Non-blocking IO,是指JDK提供的新API。从JDK1.4开始,Java提供了一系列改进输入/输出的新特性,被统称为NIO(也被成为New IO),是同步非阻塞的;
NIO相关的类都被放在java.nio包及其子包下,并且对原java.io包中的很多类进行改写;
NIO有三大核心部分:Channel(通道)、Buffer(缓冲区)、Selector(选择器);
NIO是面向缓冲区,或者被称为面向块(内存块也就是缓存)编程的,数据读取到一个它稍后处理的缓冲区,需要时间时可在缓冲区中前后移动,这就增加了处理过程中的灵活性,使用它可以提供非阻塞式的高伸缩性网络;
如下图所示为BIO模式。一个线程对应一个Selector,Selector为多路复用器,可以管理多个Channel。当Channel中有消息发送过来时,Selector轮询到这个Channel,处理其数据,当Channel中没有数据,Selector去处理其他Channel中的数据,甚至是干自己的事情,这就使资源的利用率提高。现在常用的网络编程框架Netty也是NIO模式。
NIO优点:
Java NIO的非阻塞模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变得可以读取之前,该线程可以继续做其他的事情。非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。
AIO
对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。
类似于AJAX的异步调用,AIO的读写方法都是异步执行,执行成功之后主动调用回调函数做下一步操作。
自我感觉AIO本来是为了改进因为BIO阻塞和同步带来的资源浪费。但是由于连接多的时候,要求同时启动和管理很多线程,资源占用相比BIO并没有很大优化,编程却变得更加复杂。所以AIO有点矫枉过正的意思。
补充:
更多学习和交流,请关注订阅号:猿事如此