当前位置: 首页 > news >正文

【Netty篇】Handler Pipeline 详解

在这里插入图片描述

目录

    • 一、 Handler & Pipeline——流水线上的“特种部队”与“生产线”
      • 1、 ChannelHandler —— 流水线上的“特种兵”👮‍♂️
      • 2、 ChannelPipeline —— 生产线上的“接力赛跑”🏃‍♀️🏃‍♂️
    • 二、 代码实例
      • 1、 服务端代码示例
      • 2、 客户端代码示例
      • 3、 执行顺序详解
      • 补充说明:ctx.channel().write(msg) vs ctx.write(msg)
      • 顺序模拟
    • 三、 总结:特种兵与流水线的完美协作🎉

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!

🌟了解 Netty 请看 : 【Netty篇】幽默的讲解带你入门 Netty !建议收藏

其他优质专栏: 【🎇SpringBoot】【🎉多线程】【🎨Redis】【✨设计模式专栏(已完结)】…等

如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning

准备好迎接一场别开生面的流水线派对了吗?😄 今天我们要用幽默风趣的方式来聊聊 Netty 中的 Handler 和 Pipeline,它们在 Netty 中究竟扮演什么角色,又如何协同配合,把数据“打造成产品”。


了解 Netty 的 Channel 请看:【Netty篇】Channel 详解
了解 Netty 的 Future & Promise 请看:【Netty篇】Future & Promise 详解


一、 Handler & Pipeline——流水线上的“特种部队”与“生产线”

1、 ChannelHandler —— 流水线上的“特种兵”👮‍♂️

在 Netty 中,每个 ChannelHandler 就像一名训练有素的特种兵,负责处理 Channel 上的各种事件。它们可以分为两大阵营:

  • 入站处理器(Inbound Handler)
    通常继承自 ChannelInboundHandlerAdapter,专门负责处理从网络上“进厂”的原材料——比如读取客户端发送的数据、进行解码、执行业务逻辑,并在处理完毕后调用 ctx.fireChannelRead(msg) 把数据往后传递。

  • 出站处理器(Outbound Handler)
    通常继承自 ChannelOutboundHandlerAdapter,主要负责把数据“打包出厂”,对写回网络的数据进行编码、记录日志等处理。它们的调用顺序与入站处理器正好相反(逆序执行)。

简单来说,当数据在流水线上运动时,入站 Handler 就像一道道工序,在数据“进厂”时依次对它进行处理;而当数据需要“出厂”发往客户端时,则经过一系列出站 Handler 的“最后打扮”,保证成品美美哒地呈现!🍔

2、 ChannelPipeline —— 生产线上的“接力赛跑”🏃‍♀️🏃‍♂️

ChannelPipeline 则是把所有这些 Handler 组织在一起的数据处理链,它本质上就是一个双向链表,每个节点是一个包装了 ChannelHandler 的 ChannelHandlerContext。在这条流水线上:

  • 入站数据 按添加顺序(从头到尾)依次经过每个 Handler,就像在接力赛中顺次把接力棒传给下一个队友;
  • 出站数据 则会以相反的顺序(从尾到头)经过所有出站 Handler,就像在倒着跑的接力赛中,把数据从尾端“传回”前端进行最后处理。

光看的话比较单调,直接上代码,我们来详细解读代码和顺序吧!


二、 代码实例

1、 服务端代码示例

下面这段代码在服务端注册了 3 个入站 Handler 和 3 个出站 Handler。我们来看一下每个 Handler 的作用和执行流程。

public class NetServer {public static void main(String[] args) {// 配置服务器引导类,用于启动和绑定网络服务器new ServerBootstrap()// 设置事件循环组,处理I/O操作.group(new NioEventLoopGroup())// 指定通道类型为NIO服务器Socket通道.channel(NioServerSocketChannel.class)// 设置通道初始化器,用于配置管道处理逻辑.childHandler(new ChannelInitializer<NioSocketChannel>() {/*** 初始化通道,设置通道的管道处理器* @param ch 要初始化的通道*/protected void initChannel(NioSocketChannel ch) {// 添加入站处理器,处理接收到的消息ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {System.out.println("这是第 1 道入站工序");// 将消息传递给管道中的下一个入站处理器ctx.fireChannelRead(msg);     // 1}});ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {System.out.println("这是第 2 道入站工序");// 将消息传递给管道中的下一个入站处理器ctx.fireChannelRead(msg);     // 2}});ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {System.out.println("这是第 3 道入站工序");// 将消息写入管道,准备发送给客户端ctx.channel().write(msg);     // 3}});// 添加出站处理器,处理待发送的消息ch.pipeline().addLast(new ChannelOutboundHandlerAdapter(){@Overridepublic void write(ChannelHandlerContext ctx, Object msg,ChannelPromise promise) {System.out.println("这是第 1 道出站工序");// 继续处理写操作,将消息写入管道ctx.write(msg, promise);      // 4}});ch.pipeline().addLast(new ChannelOutboundHandlerAdapter(){@Overridepublic void write(ChannelHandlerContext ctx, Object msg,ChannelPromise promise) {System.out.println("这是第 2 道出站工序");// 继续处理写操作,将消息写入管道ctx.write(msg, promise);     // 5}});ch.pipeline().addLast(new ChannelOutboundHandlerAdapter(){@Overridepublic void write(ChannelHandlerContext ctx, Object msg,ChannelPromise promise) {System.out.println("这是第 3 道出站工序");// 继续处理写操作,将消息写入管道ctx.write(msg, promise);       // 6}});}})// 绑定端口8080,启动服务器.bind(8080);}
}

2、 客户端代码示例

public class NetClient {public static void main(String[] args) {// 配置客户端new Bootstrap()// 指定事件循环组,处理I/O操作.group(new NioEventLoopGroup())// 指定通道类型.channel(NioSocketChannel.class)// 设置通道初始化器,配置管道处理器.handler(new ChannelInitializer<Channel>() {@Overrideprotected void initChannel(Channel ch) {// 添加字符串编码器到管道,以便发送字符串消息ch.pipeline().addLast(new StringEncoder());}})// 连接到指定的主机和端口.connect("127.0.0.1", 8080)// 添加监听器,在连接成功后执行操作.addListener((ChannelFutureListener) future -> {// 发送消息到服务器future.channel().writeAndFlush("hello,world");});}
}

分别运行服务端和客户端,查看运行结果

在这里插入图片描述

3、 执行顺序详解

  1. 入站处理器(Inbound)
    数据刚刚从客户端传入时,会依次触发三个入站 Handler:

    • 第一个 Handler 打印 这是第 1 道入站工序,调用 ctx.fireChannelRead(msg) 传给下一个 Handler。
    • 第二个 Handler 打印 这是第 2 道入站工序,同样调用 ctx.fireChannelRead(msg)
    • 第三个 Handler打印 这是第 3 道入站工序,然后调用 ctx.channel().write(msg) 触发出站处理器。
  2. 出站处理器(Outbound)
    当第三个入站 Handler 调用 ctx.channel().write(msg) 时,它开始从 Pipeline 尾部查找出站处理器,并依次执行:

    • 最后一个出站 Handler(Handler6)打印 这是第 3 道出站工序,调用 ctx.write(msg, promise) 将消息交给前一个出站 Handler;
    • 然后 Handler5 打印 这是第 2 道出站工序
    • 接着 Handler4 打印 这是第 1 道出站工序

    完成后消息会真正被写出到 Channel 中。这里的关键是:出站 Handler 的执行顺序与它们添加的顺序相反,也就是从尾部开始触发。

  3. 输出流程图

在这里插入图片描述

这就完美地展现了入站与出站的“正序与逆序”运行机制。😎

补充说明:ctx.channel().write(msg) vs ctx.write(msg)

  • ctx.channel().write(msg)
    从整个 Pipeline 的尾部开始查找出站处理器,这意味着总是会从最新添加的出站 Handler 开始执行。

  • ctx.write(msg)
    则从当前 Handler 的上一个出站 Handler 开始触发,如果在当前节点之前没有出站 Handler,则不会触发出站逻辑。

例如,在第三个入站 Handler中使用 ctx.channel().write(msg) 能确保出站 Handler 全部触发;如果改成 ctx.write(msg),而节点3自身后没有出站处理器,则可能只触发部分或不触发任何出站 Handler。

顺序模拟

上面的大致执行顺序你应该了解了,接下来实战一下看看具体效果是否真的是符合我们的想法。我已经在上面服务端代码标记好了需要操作的代码行,标记了 1、2、3、4、5、6,你需要先找到:

在这里插入图片描述

首先我将 1 处的代码注释掉,查看运行结果:

在这里插入图片描述

可以看到只打印了第一道工序,后面的都没有打印,接下来我把 1 处的代码注释回来,然后注释 2 处的代码,查看运行结果:

在这里插入图片描述

由输出结果咱可以得出结论:如果要调用下一个入站处理器,就必须使用 ctx.fireChannelRead(msg) 向下传递,出站也是同样的,你们可以自行的去试一下,比如注释掉 5 或者 6 来看一下输出结果

注意 : 你如果将 3 处的 ctx.channel().write(msg) 误写成了 ctx.write(msg),仅会打印 如下结果,因为节点 3 之前没有其它出站处理器了
在这里插入图片描述
6 处的 ctx.write(msg, promise) 误写成了 ctx.channel().write(msg) 会打印如下结果, 因为 ctx.channel().write() 是从尾部开始查找,结果又是节点 6 自己
在这里插入图片描述


三、 总结:特种兵与流水线的完美协作🎉

  • ChannelHandler 就像车间里的各路特种兵,不同的 Handler 负责不同的加工任务——有的负责“进料”(入站),有的负责“出货”(出站)。
  • ChannelPipeline 则是连接这些特种兵的生产线,就像流水线一样确保数据能够逐个被加工、转换后顺利送出。
  • 执行顺序
    • 入站:按照 Handler 添加的先后顺序依次处理(正序)。
    • 出站:按照 Handler 添加的逆序处理(倒序)。

这一切就好像是一场精心设计的接力赛,数据作为接力棒在各个 Handler 之间传递、加工,最终将高质量的产品“送达”客户端!🍔🚀

希望这份幽默而详细的讲解能让你对 Netty 的 Handler 和 Pipeline 有全新的认识。😄

相关文章:

【Netty篇】Handler Pipeline 详解

目录 一、 Handler & Pipeline——流水线上的“特种部队”与“生产线”1、 ChannelHandler —— 流水线上的“特种兵”&#x1f46e;‍♂️2、 ChannelPipeline —— 生产线上的“接力赛跑”&#x1f3c3;‍♀️&#x1f3c3;‍♂️ 二、 代码实例1、 服务端代码示例2、 客…...

Postman实现接口测试(附项目实战)

Postman实现接口测试&#xff08;附项目实战&#xff09; Postman实现接口测试 掌握如何安装Postman 掌握Postman的基本用法 掌握全局变量与环境变量 掌握Postman断言和关联 掌握如何读取外部文件实现参数化 掌握如何使用Newman生成HTML测试报告 1.Postman介绍和安装 Postman是…...

从零上手GUI Guider学习LVGL——Button

视频教程请关注我b站&#xff1a;同学_好好学习&#xff0c;这里只是做相应的笔记文稿 从零上手GUI Guider学习LVGL——Buttton 前言&#xff1a; 首先我们为什么要学习LVGL设计工具呢&#xff1f; 1 降低开发难度 2 提高开发效率 所以我们需要学习一款合适的设计工具 在b站很少…...

软件工程知识体系全面梳理

一、软件工程概述 1. 软件工程基本概念 定义&#xff1a;应用系统化、规范化、可量化的方法开发、运行和维护软件的学科 目标&#xff1a;提高软件质量、降低开发成本、控制开发周期 三要素&#xff1a;方法、工具、过程 2. 软件生命周期 可行性分析 → 需求分析 → 设计 …...

操作教程|通过DataEase制作MaxKB系统数据大屏

MaxKB&#xff08;Max Knowledge Brain&#xff09;是一款强大易用的企业级AI助手&#xff0c;支持RAG检索增强生成、工作流编排、MCP工具调用能力&#xff0c;目前正在被广泛应用于智能客服、企业内部知识库、学术研究与教育等场景。MaxKB可以帮助用户快速搭建面向不同应用场景…...

关于webpack的知识点

一、什么是webpack?它的核心概念是什么&#xff1f; webpack是现代JavaScript应用程序的打包工具 它的核心概念包括&#xff1a; 入口输出loaderplugin(插件)模式模块依赖图 二、webPack与Grunt\Grulp有什么区别&#xff1f; 首先Grunt/Gulp是任务运行器&#xff0c;用来实现流…...

Linux系统中的 sudo 权限会导致环境变量失效。

标题为什么 sudo 会破坏 配置的环境变量&#xff1f; 权限切换&#xff1a;sudo 以 root 用户 身份执行命令&#xff0c;root 用户的环境变量和当前用户&#xff08;user&#xff09;的环境变量是隔离的。 环境变量丢失&#xff1a;nvm 依赖的 PATH、等环境变量是通过用户 She…...

目标分割模型优化自身参数都是梯度下降算法吗?

在计算机视觉的深度学习任务中&#xff0c;诸如 CNN、FCN、U-Net、DeepLab 系列模型已成为图像分类与图像分割任务的核心架构。它们在网络结构和任务上有所差异&#xff0c;但是否共享同一种优化机制&#xff1f;是否都使用梯度下降&#xff1f;优化过程中又有什么本质区别&…...

前端请求传参与后端匹配的接收方式Content-Type类型

文章目录 一、Content-Type简介二、Content-Type类型三、常⽤类型3.1. application/json&#xff1a;JSON数据格式3.2. application/x-www-form-urlencoded&#xff1a;普通表单格式&#xff08;键值对&#xff09;3.3. multipart/form-data&#xff1a;多部分表单格式&#xf…...

解决:VSCode C++ conan 安装第三方库后 头文件报错

文章目录 1 头文件include路径查找报错参考 1 头文件include路径查找报错 找到conan_toolchain.cmake中 INCLUDE_PATH list(PREPEND CMAKE_INCLUDE_PATH "/Users/hanliqiang/.conan2/p/b/fmte8c4f7a755477/p/include")生成C编译配置 CtrlShiftP 中选择C Edit Confi…...

(leetcode算法题)309. 买卖股票的最佳时机含冷冻期

按照题目要求&#xff0c;研究对象是最后一天结束后获得的最大利润 那么就可以把问题拆分成 第 1 天结束后获得的最大利润&#xff0c; 第 2 天结束后获得的最大利润&#xff0c; 第 i 天结束后获得的最大利润&#xff0c; 由于规则中强调不能同时参与多笔交易&#xff0c…...

win10和win11系统修复工具各类故障解决

点赞关注一下哈&#xff1a; 在使用电脑时可能会遇到一些问题&#xff0c;通过上网查找解决方法费时费力&#xff0c;而有了这个小工具可以很方便的解决问题。有几十种解决方案&#xff0c;值得下载保存哦。 1、使用方法&#xff1a; 解压文件&#xff0c;双击文件夹内的exe文件…...

微硕WSP6949 MOS管在补水仪中的应用与市场分析

微硕WSP6949 MOS管在补水仪中的应用与市场分析 一、引言 补水仪作为一种常见的家用电器&#xff0c;其核心部件之一是驱动电路&#xff0c;而MOS管作为驱动电路中的关键元件&#xff0c;其性能直接影响到补水仪的运行效率和稳定性。微硕半导体推出的WSP6949 MOS管&#xff0c…...

【通过Zadig给鼠标适配器安装驱动后,鼠标动不了,无法恢复的解决办法】

【通过Zadig给鼠标适配器安装驱动后,鼠标动不了,无法恢复的解决办法 问题产生缘由感谢这位大佬提供的解决办法解决办法 问题产生缘由 通过Zadig给鼠标适配器安装USB GAMING MOUSE这个驱动后,鼠标动不了,无法恢复(重启电脑,卸载鼠标驱动再重装也不可以), 不过还好,我用的是笔记…...

基本表单的实现即登录注册页面的实现

1.登录页面&#xff08;opType.value0&#xff09; 2.注册页面&#xff08;opType.value1&#xff09; 3.注意 el-form-item中的prop对应的是rules里面的key值 <el-form-itemlabel"邮箱"prop"email"label-width"100px"> </el-form-i…...

JVM 什么是逃逸分析?它有哪些优化手段?

JVM 逃逸分析 (Escape Analysis) 是一种编译器优化技术&#xff0c;主要由即时编译器 (JIT Compiler) 在运行时进行&#xff0c;用于分析对象的作用域&#xff0c;判断对象是否会逃逸出方法或线程。 什么是逃逸&#xff1f; 在 JVM 的上下文中&#xff0c;“逃逸” 指的是对象…...

Spring AI与通义千问的完美结合:构建智能对话应用

Spring AI是Spring生态系统中的新成员,它为开发人员提供了一套简单而强大的工具,用于集成各种AI大模型。本文将介绍如何使用Spring AI与阿里云通义千问大模型进行集成,构建智能对话应用,帮助你快速掌握AI应用开发的核心技能。 引言 随着人工智能技术的快速发展,越来越多的…...

CST仿真天线流程

基础操作指导 如何建模、设置边界条件、端口激励等。 材料属性设置、网格划分优化。 仿真参数配置&#xff08;频域/时域仿真&#xff09;。 常见仿真案例 天线设计&#xff08;如微带天线、波导天线&#xff09;。 微波器件&#xff08;滤波器、功分器、耦合器&#xff0…...

Vue 组件化开发

引言 在当今的 Web 开发领域&#xff0c;构建一个功能丰富且用户体验良好的博客是许多开发者的目标。Vue.js 作为一款轻量级且高效的 JavaScript 框架&#xff0c;其组件化开发的特性为我们提供了一种优雅的解决方案。通过将博客拆分成多个独立的组件&#xff0c;我们可以提高…...

java + spring boot + mybatis 通过时间段进行查询

前端传来的只有日期内容&#xff0c;如&#xff1a;2025-04-17 需要在日期内容的基础上补充时间部分&#xff0c;代码示例&#xff1a; /*** 日志查询&#xff08;分页查询&#xff09;* param recordLogQueryDTO 查询参数对象* return 日志列表*/Overridepublic PageBean<…...

基于pycatia的CATIA自动化干涉检测系统开发全解析

引言 在智能制造时代&#xff0c;三维数模的干涉检测效率直接影响产品开发周期。本文基于Python的pycatia库&#xff0c;深入解析CATIA自动化干涉检测系统的开发要点与工业实践&#xff0c;结合达索系统最新技术趋势&#xff0c;为工程师提供一套高可靠性的二次开发方案。 一、…...

v-model进阶+ref+nextTick

一、v-model进阶 复习 v-model v-model: 双向数据绑定指令 数据 <-> 视图: 数据和视图相互影响, 因此被称为双向数据绑定指令 1> 数据变了, 视图也会跟着变 (数据驱动视图) 2> 视图变了, 数据也会跟着变 1. v-model 原理 v-model只是一个语法糖, 比较好用, …...

vscode+keil嵌入式软件开发全流程

vscodekeil嵌入式软件开发全流程 1 安装MinGW-w64 &#xff08;1&#xff09; MinGW-w64 是一个用于Windows操作系统的开发工具集&#xff0c;其包含了C语言编译器 GCC&#xff08;GNU Compiler Collection&#xff09;&#xff0c;官网地址&#xff1a;https://www.mingw-w6…...

GitHub 从入门到精通完全指南(2025版)

以下是GitHub 从入门到精通完全指南,整合优质教程及官方文档,涵盖基础操作、协作开发、高级功能及实战技巧,助你快速掌握 GitHub 全流程。 一、GitHub 入门篇 1. 注册与配置 注册 GitHub 账号 访问 GitHub 官网,点击“Sign Up”填写邮箱、用户名、密码完成注册。建议绑定双…...

总结【过往部分项目经历一(计算机图形学方向)】

总结【过往部分项目经历】 1.蜂窝填充算法2.孔洞识别算法3.扫掠轮廓计算4.二维排料算法5.最大内接圆算法 1.蜂窝填充算法 介绍: 主要从二维六角网格基本算法出发&#xff0c;基于自定义数据结构和拓扑关系&#xff0c;从二维到三维进行拓展&#xff0c;六角网格->六棱柱-&g…...

Flask(补充内容)配置SSL 证书 实现 HTTPS 服务

没有加密的http服务&#xff0c;就像在裸泳&#xff0c;钻到水里便将你看个精光。数据在互联网上传输时&#xff0c;如果未经加密&#xff0c;随时可能被抓包软件抓住&#xff0c;里面的cookie、用户名、密码什么的&#xff0c;它会看得一清二楚&#xff0c;所以&#xff0c;只…...

js逆向分享

某验三代 这玩意大家应该都人手一份了&#xff0c;也没啥好分享的了&#xff0c;需要注意的是&#xff0c;一共五个请求&#xff0c;分别是&#xff1a; "https://apiv6.geetest.com/gettype.php “https://apiv6.geetest.com/get.php” “https://api.geevisit.com/a…...

【cocos creator 3.x】速通3d模型导入, 模型创建,阴影,材质使用,模型贴图绑定

1、右键创建平面&#xff0c;立方体 2、点击场景根节点&#xff0c;shadows勾选enabled3、点击灯光&#xff0c;shadow enabled勾选 4、点击模型&#xff0c;勾选接收阴影&#xff0c;投射阴影&#xff08;按照需要勾选&#xff09; 5、材质创建 6、选中节点&#xff0c;找…...

CentOS 中安装 vim

1. 使用 Yum 安装 Vim 如果您的系统可以正常访问互联网&#xff0c;并且已经配置好了正确的 Yum 源&#xff0c;可以直接运行以下命令安装 vim&#xff1a; sudo yum install vim -y 如果默认的 vim 包不可用&#xff0c;可以尝试安装增强版 vim-enhanced&#xff1a; sudo yu…...

安全可靠+操作简捷——安科瑞预付费电表的用户体验升级

安科瑞顾强 在现代化用电场景中&#xff0c;预付费模式凭借其高效性与便捷性&#xff0c;已成为商业、工业及住宅用电管理的优选方案。安科瑞电气推出的DDSY1352/DTSY1352系列预付费电能表&#xff0c;搭配智能管理平台&#xff0c;为用户提供从精准计量、智能控制到数据分析的…...

AI与物联网的深度融合:开启智能生活新时代

在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;和物联网&#xff08;IoT&#xff09;作为两大前沿技术&#xff0c;正在加速融合&#xff0c;为我们的生活和工作带来前所未有的变革。这种融合不仅提升了设备的智能化水平&#xff0c;还为各行各业带来了新的机…...

赛灵思 XCVU095-2FFVB2104E XilinxFPGA Virtex UltraScale

XCVU095-2FFVB2104I 是 Xilinx&#xff08;现 AMD&#xff09;Virtex UltraScale 系列中的高端 FPGA 器件&#xff0c;基于 20nm 工艺&#xff0c;提供卓越的逻辑密度和高速串行 I/O 能力&#xff0c;广泛应用于 400G 网络、ASIC 原型验证及大型数据中心互联 该器件集成 1 176…...

leetcode0212. 单词搜索 II - hard

1 题目&#xff1a;单词搜索 II 官方标定难度&#xff1a;难 给定一个 m x n 二维字符网格 board 和一个单词&#xff08;字符串&#xff09;列表 words&#xff0c; 返回所有二维网格上的单词 。 单词必须按照字母顺序&#xff0c;通过 相邻的单元格 内的字母构成&#xff…...

解决 VSCode 中 NVM 配置后无法识别 Node 和 NPM 的问题

在开发中&#xff0c;我们经常需要使用 Node.js 和 NPM 来管理 JavaScript 项目依赖&#xff0c;而 NVM&#xff08;Node Version Manager&#xff09;是开发者在本地环境中管理多个 Node.js 版本的得力工具。不过&#xff0c;有时候在 VSCode 中配置完 NVM 后&#xff0c;可能…...

67.评论日记

我的评论本身也就是一种回答 沈阳车展帖子灵异失踪&#xff0c;究竟是谁干的&#xff1f;_哔哩哔哩_bilibili 2025年4月17日17:32:10...

Vscode 插件开发

文章目录 1、使用vscode官方插件生成框架&#xff0c;下载脚手架2、使用脚手架初始化项目&#xff0c;这里我选择的是js3、生成的文件结构如下&#xff0c;重要的就是以下两个文件4、代码5、打包使用6、发布官网地址7、publisher ID undefined provided in the extension manif…...

数据结构(6)

实验步骤&#xff1a; 任务一&#xff1a; 编写算法实现带头结点单链表的就地逆置,即利用原带头结点单链表的结点空间把元素序列 a0,al,……,an-i 逆置为 an-1,……,al, a0 [程序参数设计] 定义了一个带头结点的单链表结构体&#xff0c;并提供了初始化、尾部插入、打印、就地…...

【ROS】恢复行为

【ROS】恢复行为 前言恢复行为&#xff08;recovery_behavior&#xff09;概述恢复行为的参数示例&#xff1a;recovery_behavior.yaml 配置文件参数说明与配置原则恢复行为模块的参数设置reset_recovery&#xff08;重置行为&#xff1a;清除代价地图&#xff09;参数冲突说明…...

HashMap中put方法的执行流程

在 Java 编程中&#xff0c;HashMap 是一种常用的集合类&#xff0c;它以键值对&#xff08;Key-Value&#xff09;的形式存储数据&#xff0c;它具有高效查找、插入和删除的优势。 一.HashMap底层数据结构 JDK 1.7&#xff1a;采用 数组 链表 的结构。JDK 1.8&#xff1a;优…...

基于深度学习并利用时间信息在X射线血管造影中进行冠状动脉血管分割|文献速递-深度学习医疗AI最新文献

Title 题目 Deep learning based coronary vessels segmentation in X-ray angiographyusing temporal information 基于深度学习并利用时间信息在X射线血管造影中进行冠状动脉血管分割 01 文献速递介绍 有创冠状动脉造影&#xff08;ICA&#xff09;在冠状动脉疾病&#…...

JVM详解(曼波脑图版)

(✪ω✪)&#xff89; 好哒&#xff01;曼波会用最可爱的比喻给小白同学讲解JVM&#xff0c;准备好开启奇妙旅程了吗&#xff1f;(๑˃̵ᴗ˂̵)و &#x1f4cc; 思维导图 ━━━━━━━━━━━━━━━━━━━ &#x1f34e; JVM是什么&#xff1f;&#xff08;苹果式比…...

深度理解指针之例题

文章目录 前言题目分析与讲解涉及知识点 前言 对指针有一定了解后&#xff0c;讲一下一道初学者的易错题 题目分析与讲解 先定义一个数组跟一个指针变量 然后把数组名赋值给指针变量————也就是把首地址传到pulPtr中 重点是分析这一句&#xff1a; *&#xff08;pulPtr…...

Electricity Market Optimization(VI) - 机组组合问题的 GAMS 求解

根据之前的博客&#xff0c;我们考虑机组的启动成本只讨论考虑以下几种约束的机组组合问题&#xff1a; 功率平衡约束火电机组启停约束和爬坡约束备用容量约束 min ⁡ ∑ t 1 T ( C t g e n C t u c C t curt ) s.t. C t g e n ∑ i ∈ [ G ] c i ( p i , t c ) C t u c …...

【Leetcode 每日一题】2176. 统计数组中相等且可以被整除的数对

问题背景 给你一个下标从 0 0 0 开始长度为 n n n 的整数数组 n u m s nums nums 和一个整数 k k k&#xff0c;请你返回满足 0 ≤ i < j < n 0 \le i < j < n 0≤i<j<n&#xff0c; n u m s [ i ] n u m s [ j ] nums[i] nums[j] nums[i]nums[j] 且…...

赛灵思 XCVU3P‑2FFVC1517I XilinxFPGA Virtex UltraScale+

XCVU3P‑2FFVC1517I AMD Xilinx Virtex UltraScale 系列中的高端 FPGA&#xff0c;基于 TSMC 16 nm FinFET 工艺及第三代 3D IC 堆栈互连技术&#xff08;SSI&#xff09;&#xff0c;旨在为数据中心互连、高性能计算、网络加速和信号处理等苛刻应用提供领先的性能‑功耗比。…...

Rust 与 JavaScript 的 WebAssembly 互操作指南

1. Rust 中导入和导出 JS 函数 导入 JS 函数 Rust 代码中可以通过 extern 块导入 JavaScript 函数&#xff1a; #[link(wasm_import_module "mod")] // 指定 JS 模块名 extern { fn foo(); // 声明导入的 JS 函数 }如果没有指定 wasm_import_module&#xff0c;默…...

2025年特种设备安全管理 A 证考试全解析

对于想要获取特种设备安全管理 A 证的人员来说&#xff0c;了解考试的具体内容与形式是备考的关键。下面将为大家全面解析特种设备安全管理 A 证考试&#xff0c;助力大家顺利备考&#xff0c;成功取证。 特种设备安全管理 A 证考试内容丰富&#xff0c;涵盖多个重要领域。特种…...

TOA与AOA联合定位的高精度算法,三维、4个基站的情况,MATLAB例程,附完整代码

本代码实现了三维空间内目标的高精度定位,结合到达角(AOA) 和到达时间(TOA) 两种测量方法,通过4个基站的协同观测,利用最小二乘法解算目标位置。代码支持噪声模拟、误差分析及三维可视化,适用于无人机导航、室内定位等场景。订阅专栏后可获得完整代码 文章目录 运行结果…...

java 设计模式之策略模式

简介 策略模式&#xff1a;策略模式可以定制目标对象的行为&#xff0c;它尅通过传入不同的策略实现&#xff0c;来配置目标对象的行为。使用策略模式&#xff0c;就是为了定制目标对象在某个关键点的行为。 策略模式中的角色&#xff1a; 上下文类&#xff1a;持有一个策略…...

BH1750光照传感器---附代码

目录 BH1750简介BH1750指令集BH1750工作流程 BH1750简介 VCC-->电源正&#xff1b; ADDR-->地址端口&#xff1b; GND-->电源负&#xff1b; PA5-->SDA-->I2C数据线&#xff1b; PA3-->SCL-->I2C时钟线&#xff1b; DVI-->I2C端口参考电压&#xff1b…...