面试题答案
一键面试数据读取方式不同点
- 字节流读取(传统IO):
- 传统IO以流的方式顺序读取数据,每次从流中读取一个字节或字节数组。例如
InputStream
的read()
方法每次读取一个字节,read(byte[] b)
方法每次读取一定数量字节到字节数组中。这种读取方式是阻塞式的,即当没有数据可读时,线程会被阻塞等待数据到达。 - 示例代码:
try (InputStream inputStream = new FileInputStream("test.txt")) { int data; while ((data = inputStream.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); }
- 传统IO以流的方式顺序读取数据,每次从流中读取一个字节或字节数组。例如
- 缓冲区读取(NIO):
- NIO基于通道(Channel)和缓冲区(Buffer)进行数据读取。数据从通道读取到缓冲区,缓冲区是一个数据容器,如
ByteBuffer
。NIO的读取是非阻塞式的,线程可以询问通道是否有数据可读,而不必一直阻塞等待。 - 示例代码:
try (FileChannel channel = new FileInputStream("test.txt").getChannel()) { ByteBuffer buffer = ByteBuffer.allocate(1024); int bytesRead = channel.read(buffer); while (bytesRead != -1) { buffer.flip(); while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } buffer.clear(); bytesRead = channel.read(buffer); } } catch (IOException e) { e.printStackTrace(); }
- NIO基于通道(Channel)和缓冲区(Buffer)进行数据读取。数据从通道读取到缓冲区,缓冲区是一个数据容器,如
实际应用场景表现差异
- 传统IO:
- 适合场景:适用于简单、数据量较小且对性能要求不是特别高的场景。例如读取配置文件,配置文件通常数据量不大,传统IO简单直接的读取方式足以满足需求。
- 表现:由于是阻塞式读取,在读取大文件或网络连接不稳定时,线程会阻塞等待数据,可能导致程序响应性变差。例如在读取一个非常大的日志文件时,如果使用传统IO,在读取过程中主线程会一直阻塞,无法处理其他任务。
- NIO:
- 适合场景:适用于高并发、大数据量传输的场景,如网络服务器端开发。例如在开发一个高性能的HTTP服务器时,NIO可以同时处理多个客户端连接,不会因为某个连接暂时没有数据可读而阻塞整个线程。
- 表现:NIO的非阻塞特性使得程序可以更高效地利用系统资源,提高并发处理能力。但NIO的编程模型相对复杂,需要开发者处理缓冲区的状态管理等问题,如
flip()
、clear()
等操作。