最后
学习视频:
大厂面试真题:
在读取之后,索引 0 到 readIndex
位置的区域被视为废弃字节(discard)。可以调用discardReadBytes
方法,来释放这部分空间,其作用类似于 ByteBuffer
的compact()
方法,移除无用的数据,实现缓冲区的重复利用。如下图,展示了执行discardReadBytes
后的情况,相当于可写的空间变大了。
ByteBuf 的使用案例
为了更好的理解ByteBuf
,编写了以下示例:
public class ByteBufDemo {
/**
- @param args
*/
public static void main(String[] args) {
// 创建一个缓冲区
ByteBuf buffer = Unpooled.buffer(10);
System.out.println(“------------初始时缓冲区------------”);
printBuffer(buffer);
// 添加一些数据到缓冲区中
System.out.println(“------------添加数据到缓冲区------------”);
String s = “love”;
buffer.writeBytes(s.getBytes());
printBuffer(buffer);
// 读取数据
System.out.println(“------------读取数据------------”);
while (buffer.isReadable()) {
System.out.println(buffer.readByte());
}
printBuffer(buffer);
// 执行compact
System.out.println(“------------执行discardReadBytes------------”);
buffer.discardReadBytes();
printBuffer(buffer);
// 执行clear
System.out.println(“------------执行clear清空缓冲区------------”);
buffer.clear();
printBuffer(buffer);
}
/**
-
打印出ByteBuf的信息
-
@param buffer
*/
private static void printBuffer(ByteBuf buffer) {
System.out.println(“readerIndex:” + buffer.readerIndex());
System.out.println(“writerIndex:” + buffer.writerIndex());
System.out.println(“capacity:” + buffer.capacity());
}
}
复制代码
输出结果:
------------初始时缓冲区------------
readerIndex:0
writerIndex:0
capacity:10
------------添加数据到缓冲区------------
readerIndex:0
writerIndex:4
capacity:10
------------读取数据------------
108
111
118
101
readerIndex:4
writerIndex:4
capacity:10
------------执行discardReadBytes------------
readerIndex:0
writerIndex:0
capacity:10
------------执行clear清空缓冲区------------
readerIndex:0
writerIndex:0
capacity:10
Process finished with exit code 0
复制代码
对比ByteBuffer
和ByteBuf
两个示例可以看出,Netty 提供了更加方便地创建ByteBuf
的工具(unpooled
),同时,也不必再执行flip()
方法来切换读写模式。对比而言,ByteBuf
更加易于使用。
ByteBuf 的3种使用模式
ByteBuf
共有三种使用模式:堆缓冲区模式(Heap Buffer)、直接缓冲区模式(Direct Buffer)和 复合缓冲区模式(Composite Buffer)。
堆缓冲模式
堆缓冲区模式又称为
支撑数组
,其数据是存放在JVM的堆空间,通过将数据存储在数组中实现。
优点
:数据存储在JVM
堆中可以快速的创建和快速释放,并且提供了数据快速访问的方法;
缺点
:每次数据与 I/O 进行传输时,都需要将数据复制到直接缓冲区。
以下是堆缓冲区的代码示例:
public class ByteBufHeapBufferDemo {
/**
- @param args
*/
public static void main(String[] args) {
// 创建一个堆缓冲区
ByteBuf buffer = Unpooled.buffer(10);
String s = “waylau”;
buffer.writeBytes(s.getBytes());
// 检查是否是支撑数组
if (buffer.hasArray()) {
// 获取支撑数组的引用
byte[] array = buffer.array();
// 计算第一个字节的偏移量
int offset = buffer.readerIndex() + buffer.arrayOffset();
// 可读字节数
int length = buffer.readableBytes();
printBuffer(array, offset, length);
}
}
/**
-
打印出Buffer的信息
-
@param buffer
*/
private static void printBuffer(byte[] array, int offset, int len) {
System.out.println(“array:” + array);
System.out.println(“array->String:” + new String(array));
System.out.println(“offset:” + offset);
System.out.println(“len:” + len);
}
}
复制代码
输出结果:
array:[B@5b37e0d2
array->String:waylau
offset:0
len:6
Process finished with exit code 0
复制代码
直接缓冲区模式
直接缓冲区属于堆外分配的直接内存,不会占用堆得空间。
优点
:使用 socket 传输数据时性能很好,避免了数据从 JVM 堆内存复制到直接缓冲区的过程,提高了性能。
缺点
:相对于堆缓冲区而言,直接缓冲区分配内存空间和释放更为昂贵。
对于涉及大量的 I/O 数据的读写,建议使用直接缓冲区。而对于用于后端业务消息编解码模块,建议使用堆缓冲区。
以下是直接缓冲区代码示例:
public class ByteBufDirectBufferDemo {
/**
- @param args
*/
public static void main(String[] args) {
// 创建一个直接缓冲区
ByteBuf buffer = Unpooled.directBuffer(10);
String s = “waylau”;
buffer.writeBytes(s.getBytes());
// 检查是否是支撑数组.
// 不是支撑数组,则为直接缓冲区
if (!buffer.hasArray()) {
// 计算第一个字节的偏移量
int offset = buffer.readerIndex();
// 可读字节数
int length = buffer.readableBytes();
// 获取字节内容
byte[] array = new byte[length];
buffer.getBytes(offset, array);
printBuffer(array, offset, length);
}
}
/**
-
打印出Buffer的信息
-
@param buffer
*/
private static void printBuffer(byte[] array, int offset, int len) {
总结:心得体会
既然选择这个行业,选择了做一个程序员,也就明白只有不断学习,积累实战经验才有资格往上走,拿高薪,为自己,为父母,为以后的家能有一定的经济保障。
学习时间都是自己挤出来的,短时间或许很难看到效果,一旦坚持下来了,必然会有所改变。不如好好想想自己为什么想进入这个行业,给自己内心一个答案。
面试大厂,最重要的就是夯实的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。
最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。
大厂Java架构核心笔记(适合中高级程序员阅读):
的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。
最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。
大厂Java架构核心笔记(适合中高级程序员阅读):
[外链图片转存中…(img-VTHYHJSF-1715409446576)]