NIO面试题大全
创新互联建站长期为1000多家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为白沙黎族企业提供专业的成都网站制作、成都做网站,白沙黎族网站改版等技术服务。拥有10年丰富建站经验和众多成功案例,为您定制开发。目录
文档索引
面试题汇总
Q:什么是同步、异步、阻塞、非阻塞?
Q:操作系统有哪些IO模型?
Q:多路复用IO模型系统怎么实现?select、poll、epoll区别?
Q:NIO比BIO相比有什么优势?
Q:NIO有哪些组件?
Q:NIO存在哪些问题?
Q:什么是零拷贝?
A: 一次IO的过程主要是:应用向操作系统发起IO指令(read、write),操作系统内核准备数据(把IO外部设备的数据,加载到内核缓冲区),准备完毕后将数据从内核空间复制到用户空间。
内核准备数据过程中,用户进程是否被阻塞
阻塞:用户进程直到内核数据准备完成,才返回
非阻塞:用户进程不等待内核数据准备完成,立即返回
将数据从内核空间复制到用户空间时,用户进程是否被阻塞
同步:用户进程等待数据从内核空间复制到用户空间
异步:用户进程不等待数据复制,内核复制完成后,发送信号通知进程
Q:操作系统有哪些IO模型?A: 有五种模型:阻塞IO、非阻塞IO、多路复用IO、信号渠道IO、异步IO
阻塞IO:阻塞等待数据准备(阻塞),数据准备好后,等待数据从内核复制到用户空间(同步)
非阻塞IO:不等待数据准备(非阻塞),通过轮询方式判断数据准备好后,等待数据从内核复制到用户空间(同步)
多路复用IO:发生请求后,将socket注册到select,select轮询检查多个socket数据是否准备好(非阻塞),数据准备好后,等待数据从内核复制到用户空间(同步)
信号渠道IO:发生请求后,内核通过信号量标志数据是否准备好(非阻塞),数据准备好后,等待数据从内核复制到用户空间(同步)
异步IO:发生请求后,不等待数据准备(非阻塞),数据准备好后,内核将数据复制到用户空间,然后发送信号通知数据已经复制完成(异步)
Q:多路复用IO模型系统怎么实现?select、poll、epoll区别?A: 多路复用IO模型目前操作系统有select、poll、epoll三种方式
select:select函数仅仅知道有几个I/O事件发生了,但并不知道具体是哪几个socket连接有I/O事件,还需要轮询去查找,时间复杂度为O(n),处理的请求数越多,所消耗的时间越长。
poll:poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态, 但是它没有大连接数的限制,原因是它是基于链表来存储的
epoll:epoll可以理解为event pool,不同与select、poll的轮询机制,epoll采用的是事件驱动机制,每个fd上有注册有回调函数,当网卡接收到数据时会回调该函数,同时将该fd的引用放入rdlist就绪列表中。
当调用epoll_wait检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可。如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户。
Q:NIO比BIO相比有什么优势?A:
1、BIO是面向流的传输;NIO是面向块传输,按块处理数据要比按字节处理数据快得多
2、BIO是采用同步阻塞机制,一个线程资源只能处理一个链接;NIO是采用多路复用IO,可以处理多个链接
3、NIO使用了零拷贝,提高了传输性能
Q:NIO有哪些组件?A:
1、Channel
Channel 是对数据的源头和数据目标点流经途径的抽象
ServerSocketChannel:用于监听新的TCP连接的通道,负责读取&相应,通常用于服务端的实现
SocketChannel:用于发起TCP连接,读写网络中的数据,通常用于客户端的实现
2、Selector
Selector是通道注册器,多个Channel均可以注册到Selector,Selector负责监听每个Channel的几个事件:链接就绪、写就绪、读就绪,当某个Channel注册就绪的事件发生,则Selector不再阻塞,返回事件集合,然后按事件不同分发处理
3、Buffer
Buffer就是一个内存块,底层是一个数组。Buffer提供了一组方法轻松使用内存块,Channel读取或写入数据都必须经过Buffer
Q:NIO存在哪些问题?A:
1、半包读写
TCP是面向连接的传输协议,TCP传输的数据是以流的形式,而数据流是没有明确的开始结尾边界,所以TCP也没办法判断哪一段流属于哪一个消息,故存在粘包和半包问题
2、断连重连
服务端出现异常时,客户端可能存在连接断开需重新连接的情况
Q:什么是零拷贝?A: 一次IO读写(如从硬盘发送网卡)的过程:应用发出read指令,CPU进行上下文切换,由用户态转为内核态,CPU通知DMA开始读取数据,DMA从磁盘读取数据到内核缓冲,DMA完成后,向CPU发出中断,CPU从内核缓冲复制到用户缓冲,复制完成后,read指令返回,CPU由内核态转为用户态。
应用发出write指令,CPU进行上下文切换,由用户态转为内核态,CPU从用户缓冲复制到socket缓冲,DMA将socket缓冲写入到网卡,写入完成后,write指令返回,CPU由内核态转为用户态。
故整个IO读写过程涉及两次系统调用,四次上下文切换
通过上面的过程,我们可以看出同样的数据,从内核缓存复制到用户缓冲,再复制到内核缓冲
操作系统提供了mmap,使得应用和操作系统可共享内核缓冲,此时就无需再将数据从内核缓冲复制到用户缓冲,发起write指令后,CPU直接从内核缓冲复制到socket缓冲
但mmap只是减少了一次CPU复制事件,操作系统提供sendfile函数可以减少一次系统调用,发起sendfile后,上下文切换到内核空间,DMA将数据复制到内核缓冲区,CPU将数据从内核缓冲复制到socket缓冲,再经由DMA从socket缓冲复制到网卡,sendfile指令返回,上下文切换到用户空间。
可以发现本次sendfile仅仅发生了2次上下文切换以及3次拷贝(2次DMA拷贝+1次CPU拷贝)
linux2.4版本后,对sendfile做了优化升级,引入SG-DMA技术,它可以直接从内核空间缓冲区中将数据读取到网卡,这样的话还可以省去CPU拷贝
CPU把内核缓冲区中的文件描述符信息(包括内核缓冲区的内存地址和偏移量)直接发送到socket缓冲区,DMA控制器根据文件描述符信息直接把数据从内核缓冲区拷贝到网卡
可以看到sendfile + DMA发生了2次上下文切换以及2次数据拷贝,全程没有通过CPU来搬运数据,所有的数据都是通过DMA进行传输的,实现了零拷贝
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧