Day09
1. 请你说说ArrayList和LinkedList的区别
- ArrayList的实现是基于数组的,LinkedList的实现是基于双向链表
- 对于随机访问,ArrayList要优于LinkedList
- 对于插入和删除操作,LinkedList要优于ArrayList,因为当元素被添加到LInkedList任意位置的时候,不需要像ArrayList那样重新计算大小或者是更新索引
- LInkedList比ArrayList更占内存,引入LInkedList除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素
2. 请你说说List与Set的区别
- List和Set都是Collection接口的子接口,它们的主要区别在于元素的有序性和重复性
- List代表有序的元素可以重复的集合,每个集合元素都有对应的顺序索引,它默认按元素的添加顺序设置元素的索引;另外List允许使用重复元素
- Set代表无序的元素不可重复的集合,它通常不能记住元素的添加顺序。Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set,则会引发失败,添加方法将返回false
- 虽然Set代表无序的集合,但是有支持排序的实现类,即TreeSet。TreeSet可以确保集合元素处于排序状态,并支持自然排序和定制排序两种排序方式,它的底层是由TreeMap实现的。TreeSet也是非线程安全的,但是它的内部元素的值不能为null
3. 请你说说BIO、NIO、AIO
- BIO是阻塞IO,当用户线程发送请求后会一直阻塞直到内核将数据准备完成
- NIO是非阻塞IO,用户线程发送请求后,可以做其他工作,并不断询问内核数据,但在数据复制阶段,用户线程依然处于阻塞状态
- BIO和NIO都是同步IO。AIO是异步IO,当用户线程发送请求后,内核会返回一个回调函数,但该回调函数不包含数据,之后用户线程可以去处理其他操作,当数据准备好后,内核会将数据发送给用户线程,而不必像同步IO那样用户线程自己去读取
- BIO只能处理一个请求,NIO可以处理多个请求。IO多路复用在NIO的基础上加入了事件机制,将用户请求注册到多路复用器上,然后监视是否有IO事件发生,如果有,会通知用户线程,IO多路复用方式主要有select,poll,epoll
4. 请你说说IO多路复用
- 在I/O编程过程中,当需要同时处理多个客户端接入请求时,可以利用多线程或者IO多路复用技术进行处理
- IO多路复用技术通过把多个IO的阻塞复用到同一个select的阻塞上,从而使得系统在单线程的情况下可以同时处理多个客户端请求
- 与传统的多线程/多进程模型比,IO多路复用的最大优势是系统开销小,系统不需要创建新的额外进程或者线程,也不需要维护这些进程和线程的运行,降低了系统的维护工作量,节省了系统资源
- 目前支持的IO多路复用的系统调用有select、pselect、poll、epoll,在linux网络编程中,很长一段时间都使用select做轮询和网络事件通知,然而select的一些固有缺陷导致了它的应用受到了很大限制,最终linux不得不在新的内核版本中寻找select的替代方案,最终选择了epoll。
- IO多路复用:单个线程同时操作多个IO请求。select调用:查询有多少个fd需要进行IO操作,特点是轮询次数多,内存开销大,支持文件描述符的个数有限。poll调用:和select几乎差不多。但是它的底层数据结构为链表,所以支持的fd的个数没有上限。epoll:更加高效的调用方式,底层的数据结构为红黑树加链表,避免大内存分配和轮询
5. 请你讲一下Java NIO
- NIO弥补了原来同步阻塞IO的不足,它在标准Java代码中提供了高速的、面向块的IO。通过定义包含数据的类,以及通过块的形式处理这些数据。
- NIO包含三个核心的组件:Buffer,Channel、Selector。Buffer是一个对象,它包含一些写入或者要读出的数据。在读取数据时,他是直接读到缓冲区中的。在写入数据时,写入到缓冲区中,任何时候访问NIO中的数据,都是通过缓冲区进行操作。Channel是一个通道,就像自来水管一样,网络数据通过Channel读取和写入。通道和流的不同之处在于通道是双向的,流只是在一个方向上移动而且通道可以用于读、写或者同时读写。Selector会不断地轮询注册在其上的Channel,如果某个Channel上面有新的TCP连接接入、读和写事件,这个Channel就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以获取就绪Channel的集合,进行后续的IO操作