常见面试题-Netty中ByteBuf类

news2024/11/27 4:38:20

了解 Netty 中的 ByteBuf 类吗?

答:

在 Java NIO 编程中,Java 提供了 ByteBuffer 作为字节缓冲区类型(缓冲区可以理解为一段内存区域),来表示一个连续的字节序列。

Netty 中并没有使用 Java 的 ByteBuffer,而是使用了新的缓冲类型 ByteBuf,特性如下:

  • 允许自定义缓冲类型

  • 复合缓冲类型中内置的透明的零拷贝实现

  • 开箱即用的动态缓冲类型,具有像 StringBuffer 一样的动态缓冲能力

  • 不再需要调用 flip() 方法

    Java 的 ByteBuffer 类中,需要使用 flip() 来进行读写两种模式的切换

  • 正常情况下具有比 ByteBuffer 更快的响应速度

Java 中的 ByteBuffer:

主要需要注意有 3 个属性:position、limit、capacity

  • capacity:当前数组的容量大小
  • position:写入模式的可写入数据的下标,读取模式的可读取数据下标
  • limit:写入模式的可写入数组大小,读取模式的最多可以读取数据的下标

假如说数组容量是 10,那么三个值初始值为:

position = 0
limit = 10
capacity = 10

假如写入 4 个字节的数据,此时三个值如下:

position = 4
limit = 10
capacity = 10

如果切换到读取数据模式(使用 flip()),会改变上边的三个值,会从 position 的位置开始读取数据到 limit 的位置

position = 0
limit = 4
capacity = 10

Netty 中的 ByteBuf:

ByteBuf 主要使用两个指针来完成缓冲区的读写操作,分别是: readIndexwriteIndex

  • 当写入数据时,writeIndex 会增加
  • 当读取数据时,readIndex 会增加,但不会超过 writeIndex

ByteBuf 的使用:

public static void main(String[] args) {
    ByteBuf buffer = Unpooled.buffer(10);
    System.out.println("----------初始化ByteBuf----------");
    printByteBuffer(buffer);

    System.out.println("----------ByteBuf写入数据----------");
    String str = "hello world!";
    buffer.writeBytes(str.getBytes());
    printByteBuffer(buffer);

    System.out.println("----------ByteBuf读取数据----------");
    while (buffer.isReadable()) {
        System.out.print((char)buffer.readByte());
    }
    System.out.println();
    printByteBuffer(buffer);


    System.out.println("----------ByteBuf释放无用空间----------");
    buffer.discardReadBytes();
    printByteBuffer(buffer);

    System.out.println("----------ByteBuf清空----------");
    buffer.clear();
    printByteBuffer(buffer);
}
private static void printByteBuffer(ByteBuf buffer) {
    System.out.println("readerIndex:" + buffer.readerIndex());
    System.out.println("writerIndex:" + buffer.writerIndex());
    System.out.println("capacity:" + buffer.capacity());
}
/**输出**/
----------初始化ByteBuf----------
readerIndex:0
writerIndex:0
capacity:10
----------ByteBuf写入数据----------
readerIndex:0
writerIndex:12
capacity:64
----------ByteBuf读取数据----------
hello world!
readerIndex:12
writerIndex:12
capacity:64
----------ByteBuf释放无用空间----------
readerIndex:0
writerIndex:0
capacity:64
----------ByteBuf清空----------
readerIndex:0
writerIndex:0
capacity:64

ByteBuf 的 3 种使用模式:

ByteBuf 共有 3 种使用模式:

  • 堆缓冲区模式(Heap Buffer)

    堆缓冲区模式又称为 “支撑数据”,其数据存放在 JVM 的堆空间

    优点:

    • 数据在 JVM 堆中存储,可以快速创建和释放,并且提供了数组直接快速访问的方法

    缺点:

    • 每次数据与 IO 进行传输时,都需要将数据复制到直接缓冲区(这里为什么要将数据复制到直接缓冲区的原因在上边的 直接内存比堆内存快在了哪里? 问题中已经讲过)

    创建代码:

    ByteBuf buffer = Unpooled.buffer(10);
    
  • 直接缓冲区模式(Direct Buffer)

    直接缓冲区模式属于堆外分配的直接内存,不占用堆的容量

    优点:

    • 使用 socket 传输数据时性能很好,避免了数据从 JVM 堆内存复制到直接缓冲区

    缺点:

    • 相比于堆缓冲区,直接缓冲区分配内存空间和释放更为昂贵

    创建代码:

    ByteBuf buffer = Unpooled.directBuffer(10);
    
  • 复合缓冲区模式(Composite Buffer)

    本质上类似于提供一个或多个 ByteBuf 的组合视图

    优点:

    • 提供一种方式让使用者自由组合多个 ByteBuf,避免了复制和分配新的缓冲区

    缺点:

    • 不支持访问其支撑数据,如果要访问,需要先将内容复制到堆内存,再进行访问

    创建代码:

    public static void main(String[] args) {
    //        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Test.class);
        // 创建一个堆缓冲区
        ByteBuf heapBuf = Unpooled.buffer(2);
        String str1 = "hi";
        heapBuf.writeBytes(str1.getBytes());
        // 创建一个直接缓冲区
        ByteBuf directBuf = Unpooled.directBuffer(5);
        String str2 = "nihao";
        directBuf.writeBytes(str2.getBytes());
        // 创建一个复合缓冲区
        CompositeByteBuf compositeByteBuf = Unpooled.compositeBuffer(10);
        compositeByteBuf.addComponents(heapBuf, directBuf);
        // 检查是否支持支撑数组,发现并不支持
        if (!compositeByteBuf.hasArray()) {
            for (ByteBuf buf : compositeByteBuf) {
                // 第一个字节偏移量
                int offset = buf.readerIndex();
                // 总共数据长度
                int length = buf.readableBytes();
                byte[] bytes = new byte[length];
                // 不支持访问支撑数组,需要将内容复制到堆内存中,即 bytes 数组中,才可以进行访问
                buf.getBytes(offset, bytes);
                printByteBuffer(bytes, offset, length);
            }
        }
    }
    
    private static void printByteBuffer(byte[] array, int offset, int length) {
        System.out.println("array:" + array);
        System.out.println("array->String:" + new String(array));
        System.out.println("offset:" + offset);
        System.out.println("len:" + length);
    }
    /**输出**/
    array:[B@4f8e5cde
    array->String:hi
    offset:0
    len:2
    array:[B@504bae78
    array->String:nihao
    offset:0
    len:5
    

Netty 中 ByteBuf 如何分配?有池化的操作吗?

答:

ByteBuf 的分配接口定义在了 ByteBufAllocator 中,他的直接抽象类是 AbstractByteBufAllocator,而 AbstractByteBufAllocator 有两种实现:PooledByteBufAllocatorUnpooledByteBufAllocator

在这里插入图片描述

  • PooledByteBufAllocator 提供了池化的操作,将 ByteBuf 实例放入池中,提升了性能,将内存碎片化减到了最小UnpooledByteBufAllocator。(这个实现采用了一种内存分配的高效策略,成为 jemalloc,已经被好几种现代操作系统所采用)
  • UnpooledByteBufAllocator 在每次创建缓冲区时,都会返回一个新的 ByteBuf 实例,这些实例由 JVM 负责 gc 回收

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1259720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计|基于SpringBoot+MyBatis框架的仿天猫商城购物系统设计与实现

计算机毕业设计|基于SpringBootMyBatis框架的仿天猫商城购物系统设计与实现 迷你仿天猫商城是一个基于SSM框架的综合性B2C电商平台,需求设计主要参考天猫商城的购物流程:用户从注册开始,到完成登录,浏览商品,加入购物…

操作系统的中断与异常(408常考点)

为了进行核心态和用户态两种状态的切换,引入了中断机制。 中断是计算机系统中的一种事件,它会打断CPU当前正在执行的程序,转而执行另一个程序或者执行特定的处理程序。中断可以来自外部设备(如键盘、鼠标、网络等)、软…

微信小程序体验版提交审核,提示接口未配置在app.json文件且无权限

在火狐浏览器 打开微信公众平台 发布小程序 弹窗一闪而过 是因为 放开这里就可以了

西南科技大学电路分析基础实验A1(元件伏安特性测试 )

目录 一、实验目的 二、实验设备 三、预习内容(如:基本原理、电路图、计算值等) 1、测定线性电阻的伏安特性 2、二极管伏安特性测试 3、测定实际电压源的伏安特性 四、实验数据及结果分析(预习写必要实验步骤和表格) 1、测定线性电阻的伏安特性 2、二极管伏安特性测…

diffusion model (九) EmuEdit技术小结

文章目录 背景1 核心思想2 方法2.1 方法建模2.2 数据工程2.2.1 image-edit任务类别定义2.2.2 指令集生成2.2.3 图片对的生成 3 结果 Paper: https://emu-edit.metademolab.com/assets/emu_edit.pdf Project web: https://emu-edit.metademolab.com/ Code: have not opensourc…

qInstallMessageHandler的学习

背景:需要做一个日志系统。 把信息重定向到txt文件中。 参考: QT 调试信息如何输出到文件(qDebug/qWarning/qCritical/qFatal)-CSDN博客 Qt 之 qInstallMessageHandler(重定向至文件)-CSDN博客 demo…

掌握反转链表的艺术:LeetCode 206 深入解析与优化 - 双指针与递归方法精讲

LeetCode.206反转链表 1.问题描述2.解题思路3.代码 1.问题描述 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入&#xff1a…

【html+css】表单元素

目录 表单元素 展示图 简约写法&#xff1a; 完美写法 表单元素 输入框 单选框 复选框 下拉框 按钮 展示图 简约写法&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><t…

UIkit-UIAlertContent

简单Demo //注意&#xff01;&#xff01;&#xff01;必须放在viewController的viewDidAppear里面&#xff0c;viewDidLoad里面不行 - (void)viewDidAppear:(BOOL)animated {// 创建 UIAlertControllerUIAlertController *alertController [UIAlertController alertControll…

数据结构-二叉树(1)

1.树概念及结构 1.1树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 1.有一个特殊的结点&…

【C++】静态成员

静态成员就是在成员变量和成员函数前加上关键字static&#xff0c;称为静态成员。 静态成员分为&#xff1a; 静态成员变量 所有对象共享同一份数据在编译阶段分配内存类内声明&#xff0c;类外初始化 静态成员函数 所有对象共享同一个函数静态成员函数只能访问静态成员变量 …

[极客大挑战2023] Crypto/PWN/Reverse

这个网站真辛苦&#xff0c;每次都要回到all&#xff0c;屏幕随时卡。界面有待进步老远。也不提示结束&#xff0c;结果现在才听说结束了&#xff0c;才开始记录一下。 还跟往常一样&#xff0c;WM不作&#xff0c;其它也AK不了&#xff0c;总是差点。 Crypto SignIn 53594…

leetcode刷题详解六

124. 二叉树中的最大路径和 这个解析很好 所有树的题目&#xff0c;都想成一颗只有根、左节点、右节点 的小树。然后一颗颗小树构成整棵大树&#xff0c;所以只需要考虑这颗小树即可。接下来分情况&#xff0c; 按照题意&#xff1a;一颗三个节点的小树的结果只可能有如下6种情…

OpenCV完结篇——计算机视觉(人脸识别 || 车牌识别)

文章目录 Haar人脸识别方法Haar识别眼鼻口HaarTesseract进行车牌识别深度学习基础知识dnn实现图像分类 Haar人脸识别方法 scaleFactor调整哈尔级联器的人脸选框使其能框住人脸 官方教程指路 每个特征都是通过从黑色矩形下的像素总和减去白色矩形下的像素总和获得的单个值 级…

94.STM32外部中断

目录 1.什么是 NVIC&#xff1f; 2.NVIC寄存器 3.中断优先级 4.NVIC的配置 设置中断分组​编辑 配置某一个中断的优先级 5.什么是EXTI 6.EXTI和NVIC之间的关系 7.SYSCFG 的介绍 1.什么是 NVIC&#xff1f; NVIC是一种中断控制器&#xff0c;主要用于处理 ARM Cort…

如何将mobi、awz3、epub格式转化为pdf

偶然之间有个需求就是网上下载了一些书籍的格式没法打开看&#xff0c;或者是想把kindle的书籍转换成pdf 那么经过一番折腾找到了两个可以用的工具站分享给大家&#xff0c;有需要的可是尝试下&#xff0c;小编这边测试了可以用&#xff0c;就是下载的时候慢的一匹。。。 第一…

【C++】类型转换 ④ ( 子类 和 父类 之间的类型转换 - 动态类型转换 dynamic_cast )

文章目录 一、子类 和 父类 之间的类型转换 - 动态类型转换 dynamic_cast1、构造父类和子类2、子类 和 父类 之间的类型转换 - 隐式类型转换3、子类 和 父类 之间的类型转换 - 静态类型转换 static_cast4、子类 和 父类 之间的类型转换 - 重新解释类型转换 reinterpret_cast5、…

时间序列预测实战(二十)自研注意力机制Attention-LSTM进行多元预测(结果可视化,自研结构)

一、本文介绍 本文给大家带来的是我利用我自研的结构进行Attention-LSTM进行时间序列预测&#xff0c;该结构是我专门为新手和刚入门的读者设计&#xff0c;包括结果可视化、支持单元预测、多元预测、模型拟合效果检测、预测未知数据、以及滚动长期预测&#xff0c;大家不仅可…

2023-2024-1-高级语言程序设计-字符数组

7-1 凯撒密码 为了防止信息被别人轻易窃取&#xff0c;需要把电码明文通过加密方式变换成为密文。输入一个以回车符为结束标志的字符串&#xff08;少于80个字符&#xff09;&#xff0c;再输入一个整数offset&#xff0c;用凯撒密码将其加密后输出。恺撒密码是一种简单的替换…

DIO算法

歌声和语音声带振动周期的快速可靠F0估计方法 原文题目&#xff1a; Fast and reliable F0 estimation method based on the period extraction of vocal fold vibration of singing voice and speech 发表在&#xff1a; AES 35TH INTERNATIONAL CONFERENCE, London, UK, 200…