1. IO流的分类有哪些?
- 按照流向分为输入流和输出流;
- 按照实现功能分为节点流和处理流。节点就是从一个特定的地方读写数据,包括数组操作,管道操作和文件操作;处理流对已存在的流进行封装和处理,包括缓冲操作,打印操作和转化操作等;
- 按照处理数据的单位分为字节流和字符流
2. 为什么有字节流还要有字符流?
- 字节流是 java 用来 ASCII 字符文件的,但 java 也支持其他字符,比如 unicode,为了方便操作字符且不会乱码,就提供了字符流。
3. 什么是 java 序列化?
- 将对象进行流化,对流化后的对象进行读写操作或者网络传输。要序列化的对象必须实现 Serializable 接口。
4. 对象序列化的过程是什么?
- 用输出流构造一个 ObjectOutputStream 对象,然后调用其 writeObject(Object obj) 方法即可将对象转化成流,反序列化就是用输入流。
5. 如何克隆对象?
- 重写 Object 的 clone 方法;
- 通过序列化和反序列化克隆。
6. BIO、NIO 和 AIO 有什么区别?
- BIO 是同步阻塞 IO,并发性不好;
- NIO 是同步非阻塞 IO,JDK1.4 开始引入,基于通道和缓冲区操作,实现了 IO 多路复用;
- AIO 是异步非阻塞 IO,并发性很好,基于事件和回调机制,目前还未广泛使用。
7. 说说你对 NIO 的认识? NIO 的核心就是缓冲区(Buffer)、通道(Channel)和选择器(Selector)。 (1). 缓冲区(Buffer)就是用来存储数据的,八种基本类型只有 Boolean 类型没有提供对应的缓冲区。
- 核心属性:capacity,缓冲区的容量;limit,界线,缓冲区可用区域和已用区域的分界线;position,当前的位置。
- 核心方法:allocate,分配缓冲区;put,往缓冲区写数据;get,从缓冲区读数据;
(2). 通道(Channel)就是源位置与目标位置之间打开的连接,数据传输的通路。
- 核心实现类:FileChannel,操作文件的通道;DatagramChannel,通过 UDP 读取网络数据的通道;SocketChannel,通过 TCP 读取网络数据的通道;ServerSocketChannel,监听 TCP 连接的通道。
- 核心方法:transferTo/transferFrom,通道间的数据传输;write,将缓冲区数据写入通道;read,把通道数据读取到缓冲区。
(3). 选择器用于IO多路复用,将channel都注册到选择器上,它会监听哪些通道有事件发生,然后进行处理。
8. 知道零拷贝吗?
- 首先普通拷贝的过程是,源文件先经过 DMA 拷贝到内核 buffer,然后通过 CPU 拷贝到用户 buffer,接着再通过 CPU 拷贝到 socket buffer,最后通过 DMA 拷贝到协议栈。这里经过了四次拷贝,并且伴随着三次用户态的转换,用户态转为内核态,再转为用户态,最后又转为内核态。
- 零拷贝不是不拷贝,是可以不经过用户 buffer,直接从内核 buffer 通过 CPU 拷贝到 socket buffer,且这里拷贝的内容非常少,只拷贝长度、偏移量等信息。通过 linux 的 sendFile 函数即可实现零拷贝。java NIO 中的 transferFrom/transferTo 方法就通过 sendFile 函数实现了零拷贝。