Java网络编程面试题(二)
# 10、Nio buffer 的内部结构是什么?
一个 buffer 主要由 position,limit,capacity 三个变量来控制读写的过程。此三个变量的含义见如下表格:
| 参数 | 写模式 | 读模式 |
|---|---|---|
| position | 当前写入的单位数据数量 | 当前读取的单位数据位置 |
| limit | 代表最多能写多少单位数据和容量是一样的 | 代表最多能读多少单位数据,和之前写入的单位数据量一致 |
| capacity | buffer 容量 | buffer 容量 |
Buffer 常见方法:
- flip(): 写模式转换成读模式
- rewind() :将 position 重置为 0 ,一般用于重复读。
- clear() :清空 buffer ,准备再次被写入 (position 变成 0 , limit 变成 capacity) 。
- compact(): 将未读取的数据拷贝到 buffer 的头部位。
- mark() 、 reset():mark 可以标记一个位置, reset 可以重置到该位置。
Buffer 常见类型: ByteBuffer 、 MappedByteBuffer 、 CharBuffer 、 DoubleBuffer 、 FloatBuffer 、 IntBuffer 、LongBuffer 、 ShortBuffer 。
**channel 常见类型 😗*FileChannel 、 DatagramChannel(UDP) 、 SocketChannel(TCP) 、 ServerSocketChannel(TCP)
# 11、Java NIO 中的 Channel是什么?有什么特点?
Channel:Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel:
打开一个SocketChannel并连接到互联网上的某台服务器。
一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。
打开 SocketChannel 下面是SocketChannel的打开方式:
SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));1
2关闭 SocketChannel
当用完SocketChannel之后调用SocketChannel.close()关闭SocketChannel:
socketChannel.close();从 SocketChannel 读取数据 :要从SocketChannel中读取数据,调用一个read()的方法之一。
ByteBuffer buf = ByteBuffer.allocate(48);int bytesRead = socketChannel.read(buf);非阻塞模式:可以设置 SocketChannel 为非阻塞模式(non-blocking mode).设置之后,就可以在异步模式下调用connect(), read() 和write()了。 如果SocketChannel在非阻塞模式下,此时调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()的方法。像这样:
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));
while(! socketChannel.finishConnect() ){
//wait, or do something else...
2
3
4
Java NIO Channel通道和流非常相似,主要有以下几点区别:
- 通道可以读也可以写,流一般来说是单向的(只能读或者写,所以之前我们用流进行IO操作的时候需要分别创建一个输入流和一个输出流)。
- 通道可以异步读写。
- 通道总是基于缓冲区Buffer来读写。
Java NIO中最重要的几个Channel的实现:
- FileChannel: 用于文件的数据读写
- DatagramChannel: 用于UDP的数据读写
- SocketChannel: 用于TCP的数据读写,一般是客户端实现
- ServerSocketChannel: 允许我们监听TCP链接请求,每个请求会创建会一个SocketChannel,一般是服务器实现
类层次结构

# 12、Java NIO中的Selector是什么?
Selector(选择器):
Selector 一般称 为选择器 ,当然你也可以翻译为 多路复用器 。它是Java NIO核心组件中的一个,用于检查一个或多个NIO Channel(通道)的状态是否处于可读、可写。如此可以实现单线程管理多个channels,也就是可以管理多个网络链接。使用Selector的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销
Selector的创建
Selector selector = Selector.open();
//注册Channel到Selector(Channel必须是非阻塞的)
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, Selectionkey.OP_READ);
2
3
4
SelectionKey介绍
一个SelectionKey键表示了一个特定的通道对象和一个特定的选择器对象之间的注册关系。从Selector中选择channel(Selecting Channels via a Selector) 选择器维护注册过的通道的集合,并且这种注册关系都被封装在SelectionKey当中.
停止选择的方法
wakeup()方法 和close()方法。
# 13、简单讲一下文件IO中的Path和Files
文件I/O基石:Path:
创建一个Path
File和Path之间的转换,File和URI之间的转换
获取Path的相关信息
移除Path中的冗余项
Files类:
Files.exists() 检测文件路径是否存在
Files.createFile() 创建文件
Files.createDirectories()和Files.createDirectory()创建文件夹
Files.delete()方法 可以删除一个文件或目录
Files.copy()方法可以吧一个文件从一个地址复制到另一个位置
获取文件属性
遍历一个文件夹
Files.walkFileTree()遍历整个目录