面试题答案
一键面试设计思路
- 字节流与字符流无缝切换:
- 定义抽象的流基类,比如
AbstractStream
,字节流和字符流类继承自该基类。 - 字节流类如
ByteStream
负责处理字节层面的数据读写,字符流类如CharStream
通过将字节流作为内部成员,并结合字符编码来处理字符数据。在字符流类的构造函数中传入字节流实例,实现两者关联。例如:
public class CharStream { private ByteStream byteStream; private String charsetName; public CharStream(ByteStream byteStream, String charsetName) { this.byteStream = byteStream; this.charsetName = charsetName; } }
- 定义抽象的流基类,比如
- 资源管理避免内存泄漏:
- 使用
try - finally
块或者Java 7引入的try - with - resources
语句来确保流资源正确关闭。例如在AbstractStream
类中定义抽象的close()
方法,由具体的字节流和字符流类实现。
public abstract class AbstractStream { public abstract void close() throws IOException; } public class ByteStream extends AbstractStream { private FileInputStream fis; public ByteStream(String filePath) throws FileNotFoundException { fis = new FileInputStream(filePath); } @Override public void close() throws IOException { if (fis!= null) { fis.close(); } } }
- 对于缓存资源,采用引用计数或者弱引用等方式管理,确保不再使用时能被垃圾回收机制回收。
- 使用
- 编码转换:
- 在字符流类中,利用
Charset
类及其相关的CharsetEncoder
和CharsetDecoder
进行编码转换。例如在CharStream
的读操作中:
import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; public class CharStream { //... public String read() throws IOException, CharacterCodingException { byte[] buffer = new byte[1024]; int length = byteStream.read(buffer); ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, length); Charset charset = Charset.forName(charsetName); CharsetDecoder decoder = charset.newDecoder(); CharBuffer charBuffer = decoder.decode(byteBuffer); return charBuffer.toString(); } }
- 在字符流类中,利用
- 缓冲区管理:
- 为字节流和字符流分别设计缓冲区。字节流可使用
ByteBuffer
,字符流可使用CharBuffer
。 - 在读取和写入操作中,合理设置缓冲区大小,根据平台和数据量动态调整。例如在字节流的写操作中:
import java.nio.ByteBuffer; public class ByteStream { //... public void write(byte[] data) throws IOException { ByteBuffer buffer = ByteBuffer.wrap(data); while (buffer.hasRemaining()) { fis.write(buffer.get()); } } }
- 为字节流和字符流分别设计缓冲区。字节流可使用
关键代码片段示例(以Java为例)
- 字节流读取:
import java.io.FileInputStream; import java.io.IOException; public class ByteStream { private FileInputStream fis; public ByteStream(String filePath) throws FileNotFoundException { fis = new FileInputStream(filePath); } public int read(byte[] buffer) throws IOException { return fis.read(buffer); } public void close() throws IOException { if (fis!= null) { fis.close(); } } }
- 字符流读取(依赖字节流):
import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.io.IOException; public class CharStream { private ByteStream byteStream; private String charsetName; public CharStream(ByteStream byteStream, String charsetName) { this.byteStream = byteStream; this.charsetName = charsetName; } public String read() throws IOException, CharacterCodingException { byte[] buffer = new byte[1024]; int length = byteStream.read(buffer); ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, length); Charset charset = Charset.forName(charsetName); CharsetDecoder decoder = charset.newDecoder(); CharBuffer charBuffer = decoder.decode(byteBuffer); return charBuffer.toString(); } }
在其他编程语言中,也可以遵循类似的设计思路,比如在C++中可以通过继承体系设计流类,利用智能指针管理资源,使用iconv
库处理编码转换等。