2.偏头痛杨的中高级java后端面试题攻略系列之io&nio篇(持续更新)

版权声明:偏头痛杨:本文为博主原创文章,未经作者允许不得转载,版权必究! https://blog.csdn.net/piantoutongyang/article/details/80259892
前戏
要是以为io就只是用于一个文件的上传和下载那你可就大错特错了。。。
但凡涉及到网络通信,都离不开io的知识。。。
其中NIO是重中之重,想深入学习NIO的童鞋可以去玩netty底层代码。
切记NIO不能只停留在表面概念阶段,这样被面试官发现会大大的减分。
NIO要结合java的网络编程知识体系,把代码写出来,加深印象。


IO

什么是序列化,反序列化,如何实现序列化?
序列化是允许将内存中的java对象转换成与平台无关的二进制流,通过硬盘或网络进行传输。
反序列化是将二进制流转换成内存中的java对象。
默认可通过ObjectOutputStream、ObjectInputStream实现序列化与反序列化。


请解释 Serializable接口、serialVersionID的作用?
必须让类实现java.io.Serializable接口表示该类的对象支持序列化机制,该接口没有需要实现的方法,
他仅仅告诉java底层该类的对象是可以进行序列化的,
并且序列化版本ID由serialVersionUID变量提供。

变量serialVersionUID是一个静态的long型的常量,用于在序列化和反序列化过程中,
起到一个辨别类的序列化版本作用,如果两个类名完全相同,
则通过serialVersionUID来判断该类是否符合要求,如果不行则抛异常。

当一个类升级后(对原有类进行修改并编译成class文件),只要serialVersionUID保持不变,
序列化机制会把他们当成同一个序列化版本。

如果不显式定义则jvm会自动计算创建serialVersionUID,
而修改后的类与修改前的类计算结果往往不同,而造成版本不兼容问题。
我们应该显式的定义个serialVersionUID,即使在某个对象被序列化之后,
它所对应的class文件被修改了,该对象也依然可以被正确的反序列化。


NIO
什么是NIO?为什么要使用NIO?
传统IO读取数据时,如果数据源没有数据则会导致线程阻塞,都是阻塞式的输入输出。
传统IO都是通过字节的移动来处理,一次只能处理一个字节,效率不高。

JDK1.4新增了一系列改进的IO处理功能,被称为NIO。
NIO采用内存映射文件的方式来处理输入输出,NIO将文件或文件的一段区域映射到内存中,
这样就可以像访问内存一样访问文件了。非阻塞, 性能大幅度提高。

Channel(通道)是传统输入输出的模拟,在NIO中所有数据的传输都需要通过通道。
Channel有个map()方法,可以直接将"一块数据"映射到内存中。
传统IO是面向流的处理,NIO是面向块的处理。

Buffer可以理解成一个容器,本质上是一个数组,数据通过Channel传输之前都需要放入到Buffer中,
Buffer像竹筒,去Channel里取水,也允许使用Channel直接将文件的模块数据映射成Buffer。

NIO需要使用Buffer、Channel、Selector结合使用才能方显威力(具体参考java非阻塞网络编程)
把Socket通过Channel注册到Selector,使用一个线程在Selector中轮询,
发现Channel有读写的事件,就可以分配给其他线程来处理(通常使用线程池)。


什么是BIO、NIO、AIO?
BIO
NIO
AIO
同步阻塞
同步非阻塞
异步非阻塞
jdk1.4以前
jdk1.4
jdk1.7(NIO.2)
网络连接时,一个请求一个线程,在数据没有开始传输以及数据没有传输完毕前,线程要进行阻塞,系统资源消耗大,吞吐量低。
网络连接时,多个请求对应一个或少量线程,在数据没有开始传输,线程不阻塞,而是轮询check哪个请求的数据来了才去服务哪个请求,需要结合selector以及线程池。
未完待续
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作


NIO的reactor模型是什么(滴滴面试题)?
未完待续。


NIO的Selector的内部实现poll与epoll解释?(滴滴面试题)
未完待续。


NIO的实现原理?
未完待续。

猜你喜欢

转载自blog.csdn.net/piantoutongyang/article/details/80259892