1、什么是 BIO、NIO、AIO?
BIO、NIO、AIO 都是 Java 常用的 IO 模型。
BIO (Blocking IO) 是传统的 IO 模型,它在读写数据时会阻塞线程,直到数据读写完成,适用于并发不高的场景。
NIO (Non-blocking IO) 是 Java 的新 IO 模型,它在读写数据时不会阻塞线程,而是通过轮询的方式检查是否有数据可读写,适用于并发量较高、连接数多、连接时间短的场景,例如实时聊天室、在线游戏等的场景。
AIO (Asynchronous IO) 是 JDK 7 开始引入的新 IO 模型,它的读写方式与 NIO 相似,但在读写数据时,不需要自己手动轮询是否有数据可读写,而是交由系统完成,适用于高并发且处理较大数据量、连接数多、连接时间长的场景,例如 HTTP 长连接、文件操作等
总的来说,BIO 的并发处理能力较差,NIO 的并发处理能力较好,但使用起来较为复杂,AIO 的并发处理能力最好,但也是最为复杂的一种 IO 模型。选择适合自己场景的 IO 模型是非常重要的。
面试官问到这个问题,可能想了解你对 Java 中不同的 I/O 模型的了解程度,以及你能否根据不同的业务需求选择合适的 I/O 模型。同时,他可能还想了解你在实际开发中使用过哪些 I/O 模型,以及它们的应用场景。
2、 MySQL 事务有哪些隔离级别、分别有什么特点,以及 MySQL 的默认隔离级别是什么?
MySQL 事务有四种隔离级别:
读未提交(Read Uncommitted):事务可以读取未提交的数据,可能会读到脏数据,会导致幻读、不可重复读、脏读等问题;
读已提交(Read Committed):只能读取已经提交的数据,可以避免脏读问题,但是可能会遇到不可重复读、幻读问题;
可重复读(Repeatable Read):保证同一个事务中多次读取同一数据的结果是一致的,避免了脏读和不可重复读问题,但是可能会遇到幻读问题;
序列化(Serializable):最高的隔离级别,可以避免所有并发问题,但是并发性能非常低,开销很大。
MySQL 的默认隔离级别是可重复读(Repeatable Read)。
其中,脏读指一个事务读到了另一个事务未提交的数据,不可重复读指同一个事务多次读取同一数据得到不同结果,幻读指同一个事务前后读取的数据集合不一致。
在实际使用中,应该根据具体情况选择合适的隔离级别,权衡数据的一致性和并发性能。
3、Redis 的单线程模型,IO 多路复用是什么?
Redis 是一款基于内存的高性能键值存储系统,采用单线程模型的设计。在 Redis 中,所有客户端的请求都是由一个单线程来处理的,这个单线程不断地从客户端套接字中读取命令请求,并将命令请求放入一个请求队列中。接着,Redis 的事件处理器会按照一定的规则选择一个请求进行处理,处理完之后将响应结果返回给客户端。
单线程模型的优点是可以避免多线程并发访问共享数据时的竞争和死锁问题,简化了系统的设计和调试。此外,由于 Redis 的内存访问速度非常快,因此单线程处理请求也能够保证足够的性能。
IO 多路复用是指在一个线程中同时监听多个文件描述符,一旦某个文件描述符就绪,就立即处理对应的事件。在 Redis 中,采用的是基于 epoll 的 IO 多路复用技术,可以实现高效的事件监听和响应。
在 Redis 中,客户端的请求是由一个单线程来处理的,而 IO 操作却是通过 epoll 多路复用技术实现的。这种设计方式既能充分利用 CPU 的计算能力,又能够保证足够的 IO 处理能力,从而实现了高效的键值存储服务。