对线面试官 - Java IO 经典面试问题突击篇
面试官:关于 BIO、NIO、以及 AIO 有了解吗可以简单聊一聊吗?
面试官心理分析:
主要是想考察 io 这些基础知识的掌握程度,各种流的使用,
派大星:当然可以的。
首先聊一下 BIO 网络通信原理
最传统的网络通信模型就是 BIO,同步阻塞式IO
。通俗的讲就是服务端创建一个 ServerSocket,客户端用一个 Socket 去连接那个 Server Socket,ServerSocket 接收到一个 Socket 的连接请求就创建一个 Socket 和一个线程去和那个 Socket 进行通信。
客户端和服务端的 Socket 从而进行同步阻塞式的通信,客户端 Socket 发送一个请求,服务端 Socket 进行处理后返回响应,响应不许是等处理完后才返回的。
这种方式最大的缺点就是,每一次客户端接入都需要在服务端创建一个线程来服务这个客服端。如果客户端较多的情况下会导致服务端的线程数量激增。从而导致服务器端程序的负载过高,甚至容易崩溃宕机。
优化的点就是可以创建一个线程池,来固定数量处理客户端的请求。但是如果高并发请求的时候也会导致各种的请求排队和延时。毕竟没有那么多的线程去处理。
其次聊一下 NIO:
JDK1.4 中引入了 NIO,这是一种同步非阻塞的IO
。基于Reactor模型
。在 NiO 中存在一个Buffer
的概念,也就是缓冲区,一般都是将数据写入到 Buffer 中,然后从 Buffer 中读取数据。具体的 Buffer 有:IntBuffer、LongBuffer、CharBuffer、等多种针对于基础类型的 Buffer。在 NIO 还有Channel
的概念。NIO 中都是通过 Channel 来进行数据读写的;还有selector
,这是多路复用器,selector 会不断轮询注册的 Channel,如果某个 Channel 上发生了读写事件,selector 会将这些 Channel 获取出来。我们便可通过 selector key 获取有读写的 Channel,就可以进行 IO 操作。一个 selector 就通过一个线程便能轮询很多的 Channel。这同时也意味着服务端可以接入很多的客户端。
其实具体实现简单的讲就是一个线程处理大量的客户端请求,通过一个线程轮询大量的 Channel,每次就获取一批有事件的 Channel,然后对每个请求启动一个线程处理即可。实际使用中可以结合CachedThreadPool
线程池。
NIO 的核心就是非阻塞的。selector 一个线程便可以不停地轮询 Channel,所有的客户端请求都不会阻塞,直接就会进来,大不了就是等待一下排队而已。
最后说一下 AIO:
AIO 是基于Proactor
模型的。就是异步非阻塞模型
。简单来讲:每个连接发送过来的请求都会绑定一个 Buffer,然后通知操作系统去异步完成读。此时运行的程序是可以处理别的请求的,等操作系统完成数据读取之后就会调用你的接口,将操作系统异步读完的数据给到你,然后便可以对这个数据进行处理并将结果返回。写的时候也是给操作系统一个 Buffer,让操作系统自己获取数据去完成写操作,写完之后通知即可。
与 BIO 不同的是:BIO 的工作线程从 Channel 中读取数据是同步的,是工作线程自己完成的,同时往 Channel 中写回数据也是工作线程自己完成。这些动作都是同步的。而 AIO 则是异步的。在 AIO 中工作线程读取数据的时候,只需要提供一个 Buffer 给操作系统,然后工作线程即可处理别的事情,读数据的动作交给操作系统,操作系统内核会去完成读取数据并将数据放入到提供的 Buffer 中。操作系统内核完成这一些列读数据的操作后会回调你的接口通知已经完成并将存好数据的 Buffer 交给工作线程。写数据同理一样的操作。
面试官:不错,掌握的可以,那你可以说说简单聊聊什么同步阻塞、同步非阻塞、异步非阻塞吗?
派大星:可以的,其实上面已经大致说了一些,下面我在简单阐述一下:
为什么 BIO 叫同步非阻塞呢。其实这个不是针对网络编程模型来说的,是针对文件 IO 操作来说的,也就是磁盘文件的 IO 读写(FileInputStream),因为 BIO 的流读写文件,指的是发起 IO 的请求直接 hang 死,必须等着 IO 处理完成才能返回。
NIO 为什么是同步非阻塞。简单来说就是通过 NIO 的 FileChannel 发起的文件 IO 操作,其实是发起之后就返回了,在这期间可以处理别的事情,这就是非阻塞,只不多接下来你还是需要不断地去轮询操作系统查看 IO 操作是否完成了。
AIO 之所以是异步非阻塞的,简单来说就是当你通过 AIO 发起文件 IO 操作之后会立马返回可以处理别的事情,等到操作系统处理完成后会通过回调告诉你已经处理完成了。不需要你主动轮询(这就是同步)。异步是操作系统主动通知你。
面试官:不错。很好。期待你加入我的团队。
如有问题,欢迎加微信交流:w714771310,备注- 技术交流 。或关注微信公众号【码上遇见你】。
版权声明: 本文为 InfoQ 作者【派大星】的原创文章。
原文链接:【http://xie.infoq.cn/article/2d12a53daea12b77af86819a0】。
本文遵守【CC BY-ND】协议,转载请保留原文出处及本版权声明。
评论