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

【Netty】Netty中的超时处理与心跳机制(十九)

文章目录

  • 前言
  • 一、超时监测
  • 二、IdleStateHandler类
  • 三、ReadTimeoutHandler类
  • 四、WriteTimeoutHandler类
  • 五、实现心跳机制
    • 5.1. 定义心跳处理器
    • 5.2. 定义 ChannelInitializer
    • 5.3. 编写服务器
    • 5.4. 测试
  • 结语

前言

回顾Netty系列文章:

  • Netty 概述(一)
  • Netty 架构设计(二)
  • Netty Channel 概述(三)
  • Netty ChannelHandler(四)
  • ChannelPipeline源码分析(五)
  • 字节缓冲区 ByteBuf (六)(上)
  • 字节缓冲区 ByteBuf(七)(下)
  • Netty 如何实现零拷贝(八)
  • Netty 程序引导类(九)
  • Reactor 模型(十)
  • 工作原理详解(十一)
  • Netty 解码器(十二)
  • Netty 编码器(十三)
  • Netty 编解码器(十四)
  • 自定义解码器、编码器、编解码器(十五)
  • Future 源码分析(十六)
  • Promise 源码分析(十七)
  • 一行简单的writeAndFlush都做了哪些事(十八)

一、超时监测

Netty 的超时类型 IdleState 主要分为以下3类:

  • ALL_IDLE : 一段时间内没有数据接收或者发送。
  • READER_IDLE : 一段时间内没有数据接收。
  • WRITER_IDLE : 一段时间内没有数据发送。

针对上面的 3 类超时异常,Netty 提供了 3 类ChannelHandler来进行监测。

  • IdleStateHandler : 当 Channel 一段时间未执行读取、写入或者两者都未执行时,触发 -IdleStateEvent 事件。
  • ReadTimeoutHandler :在一定时间内未读取任何数据时,引发 ReadTimeoutEvent 事件。
  • WriteTimeoutHandler :当写操作在一定时间内无法完成时,引发 WriteTimeoutEvent 事件。

二、IdleStateHandler类

IdleStateHandler 包括了读\写超时状态处理,观察以下 IdleStateHandler 类的构造函数源码。

public IdleStateHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) {this((long)readerIdleTimeSeconds, (long)writerIdleTimeSeconds, (long)allIdleTimeSeconds, TimeUnit.SECONDS);
}public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit) {this(false, readerIdleTime, writerIdleTime, allIdleTime, unit);
}public IdleStateHandler(boolean observeOutput, long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit) {this.writeListener = new ChannelFutureListener() {public void operationComplete(ChannelFuture future) throws Exception {IdleStateHandler.this.lastWriteTime = IdleStateHandler.this.ticksInNanos();IdleStateHandler.this.firstWriterIdleEvent = IdleStateHandler.this.firstAllIdleEvent = true;}};this.firstReaderIdleEvent = true;this.firstWriterIdleEvent = true;this.firstAllIdleEvent = true;ObjectUtil.checkNotNull(unit, "unit");this.observeOutput = observeOutput;if (readerIdleTime <= 0L) {this.readerIdleTimeNanos = 0L;} else {this.readerIdleTimeNanos = Math.max(unit.toNanos(readerIdleTime), MIN_TIMEOUT_NANOS);}if (writerIdleTime <= 0L) {this.writerIdleTimeNanos = 0L;} else {this.writerIdleTimeNanos = Math.max(unit.toNanos(writerIdleTime), MIN_TIMEOUT_NANOS);}if (allIdleTime <= 0L) {this.allIdleTimeNanos = 0L;} else {this.allIdleTimeNanos = Math.max(unit.toNanos(allIdleTime), MIN_TIMEOUT_NANOS);}}

在上述源码中,构造函数可以接收以下参数:

  • readerIdleTimeSecond:指定读超时时间,指定 0 表明为禁用。

  • writerIdleTimeSecond:指定写超时时间,指定 0 表明为禁用。

  • allIdleTimeSecond:在指定读写超时时间,指定 0 表明为禁用。

IdleStateHandler 使用示例:

public class MyChannelInitializer extends ChannelInitializer<Channel> {@Overrideprotected void initChannel(Channel channel) throws Exception {channel.pipeline().addLast("idleStateHandler",new IdleStateHandler(60,30,0));channel.pipeline().addLast("myHandler",new MyHandler());}
}public class MyHandler extends ChannelDuplexHandler {@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {if(evt instanceof IdleStateEvent){IdleStateEvent e = (IdleStateEvent) evt;if(e.state() == IdleState.READER_IDLE){ctx.close();}else if(e.state() == IdleState.WRITER_IDLE){ctx.writeAndFlush(new PingMessage());}}}
}

在上述示例中,IdleStateHandler 设置了读超时时间为 60 秒,写超时时间为 30 秒。MyHandler 是针对超时事件 IdleStateEvent 的处理。

  • 如果 30 秒内没有出站流量(写超时)时发送 ping 消息的示例。
  • 如果 60 秒内没有入站流量(读超时)时,连接关闭。

三、ReadTimeoutHandler类

ReadTimeoutHandler 类包括了读超时状态处理。ReadTimeoutHandler 类的源码如下:

public class ReadTimeoutHandler extends IdleStateHandler {private boolean closed;public ReadTimeoutHandler(int timeoutSeconds) {this((long)timeoutSeconds, TimeUnit.SECONDS);}public ReadTimeoutHandler(long timeout, TimeUnit unit) {super(timeout, 0L, 0L, unit);//禁用了写超时、读写超时}protected final void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {assert evt.state() == IdleState.READER_IDLE;//只处理读超时this.readTimedOut(ctx);}protected void readTimedOut(ChannelHandlerContext ctx) throws Exception {if (!this.closed) {ctx.fireExceptionCaught(ReadTimeoutException.INSTANCE);//引发异常ctx.close();this.closed = true;}}
}

从上述源码可以看出,ReadTimeoutHandler 继承自 IdleStateHandler,并在构造函数中禁用了写超时、读写超时,而且在处理超时时,只会针对 READER_IDLE状态进行处理,并引发 ReadTimeoutException 异常。
ReadTimeoutHandler 的使用示例如下:

public class MyChannelInitializer extends ChannelInitializer<Channel> {@Overrideprotected void initChannel(Channel channel) throws Exception {channel.pipeline().addLast("readTimeoutHandler",new ReadTimeoutHandler(30));channel.pipeline().addLast("myHandler",new MyHandler());}
}//处理器处理ReadTimeoutException 
public class MyHandler extends ChannelDuplexHandler {@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {if(cause instanceof ReadTimeoutException){//...}else {super.exceptionCaught(ctx,cause);}}
}

在上述示例中,ReadTimeoutHandler 设置了读超时时间是 30 秒。

四、WriteTimeoutHandler类

WriteTimeoutHandler 类包括了写超时状态处理。WriteTimeoutHandler 类的源码如下:

public class WriteTimeoutHandler extends ChannelOutboundHandlerAdapter {private static final long MIN_TIMEOUT_NANOS;private final long timeoutNanos;private WriteTimeoutHandler.WriteTimeoutTask lastTask;private boolean closed;public WriteTimeoutHandler(int timeoutSeconds) {this((long)timeoutSeconds, TimeUnit.SECONDS);}public WriteTimeoutHandler(long timeout, TimeUnit unit) {ObjectUtil.checkNotNull(unit, "unit");if (timeout <= 0L) {this.timeoutNanos = 0L;} else {this.timeoutNanos = Math.max(unit.toNanos(timeout), MIN_TIMEOUT_NANOS);}}public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {if (this.timeoutNanos > 0L) {promise = promise.unvoid();this.scheduleTimeout(ctx, promise);}ctx.write(msg, promise);}public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {WriteTimeoutHandler.WriteTimeoutTask task = this.lastTask;WriteTimeoutHandler.WriteTimeoutTask prev;for(this.lastTask = null; task != null; task = prev) {task.scheduledFuture.cancel(false);prev = task.prev;task.prev = null;task.next = null;}}private void scheduleTimeout(ChannelHandlerContext ctx, ChannelPromise promise) {WriteTimeoutHandler.WriteTimeoutTask task = new WriteTimeoutHandler.WriteTimeoutTask(ctx, promise);task.scheduledFuture = ctx.executor().schedule(task, this.timeoutNanos, TimeUnit.NANOSECONDS);if (!task.scheduledFuture.isDone()) {this.addWriteTimeoutTask(task);promise.addListener(task);}}private void addWriteTimeoutTask(WriteTimeoutHandler.WriteTimeoutTask task) {if (this.lastTask != null) {this.lastTask.next = task;task.prev = this.lastTask;}this.lastTask = task;}private void removeWriteTimeoutTask(WriteTimeoutHandler.WriteTimeoutTask task) {if (task == this.lastTask) {assert task.next == null;this.lastTask = this.lastTask.prev;if (this.lastTask != null) {this.lastTask.next = null;}} else {if (task.prev == null && task.next == null) {return;}if (task.prev == null) {task.next.prev = null;} else {task.prev.next = task.next;task.next.prev = task.prev;}}task.prev = null;task.next = null;}protected void writeTimedOut(ChannelHandlerContext ctx) throws Exception {if (!this.closed) {ctx.fireExceptionCaught(WriteTimeoutException.INSTANCE);ctx.close();this.closed = true;}}//...
}

从上述源码可以看出,WriteTimeoutHandler 在处理超时时,引发了 WriteTimeoutException 异常。
WriteTimeoutHandler 的使用示例如下:

public class MyChannelInitializer extends ChannelInitializer<Channel> {@Overrideprotected void initChannel(Channel channel) throws Exception {channel.pipeline().addLast("writeTimeoutHandler",new WriteTimeoutHandler(30));channel.pipeline().addLast("myHandler",new MyHandler());}
}//处理器处理ReadTimeoutException 
public class MyHandler extends ChannelDuplexHandler {@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {if(cause instanceof WriteTimeoutException ){//...}else {super.exceptionCaught(ctx,cause);}}
}

在上述示例中,WriteTimeoutHandler 设置了写超时时间是 30 秒。

五、实现心跳机制

针对超时的解决方案——心跳机制。
在程序开发中,心跳机制是非常常见的。其原理是,当连接闲置时可以发送一个心跳来维持连接。一般而言,心跳就是一段小的通信。

5.1. 定义心跳处理器

public class HeartbeatServerHandler extends ChannelInboundHandlerAdapter {// (1)心跳内容private static final ByteBuf HEARTBEAT_SEQUENCE = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Heartbeat",CharsetUtil.UTF_8));  @Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt)throws Exception {// (2)判断超时类型if (evt instanceof IdleStateEvent) {IdleStateEvent event = (IdleStateEvent) evt;String type = "";if (event.state() == IdleState.READER_IDLE) {type = "read idle";} else if (event.state() == IdleState.WRITER_IDLE) {type = "write idle";} else if (event.state() == IdleState.ALL_IDLE) {type = "all idle";}// (3)发送心跳ctx.writeAndFlush(HEARTBEAT_SEQUENCE.duplicate()).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);System.out.println( ctx.channel().remoteAddress()+"超时类型:" + type);} else {super.userEventTriggered(ctx, evt);}}
}

对上述代码说明:

  • 定义了心跳时,要发送的内容。

  • 判断是不是 IdleStateEvent 事件,是则处理。

  • 将心跳内容发送给客户端。

5.2. 定义 ChannelInitializer

HeartbeatHandlerInitializer用于封装各类ChannelHandler,代码如下:

public class HeartbeatHandlerInitializer extends ChannelInitializer<Channel> {private static final int READ_IDEL_TIME_OUT = 4; // 读超时private static final int WRITE_IDEL_TIME_OUT = 5;// 写超时private static final int ALL_IDEL_TIME_OUT = 7; // 所有超时@Overrideprotected void initChannel(Channel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new IdleStateHandler(READ_IDEL_TIME_OUT,WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS)); // (1)pipeline.addLast(new HeartbeatServerHandler()); // (2)}
}

对上述代码说明如下:

  • 添加了一个IdleStateHandler到 ChannelPipeline,并分别设置了读、写超时的时间。为了方便演示,将超时时间设置的比较短。
  • 添加了HeartbeatServerHandler,用来处理超时时,发送心跳。

5.3. 编写服务器

服务器代码比较简单,启动后侦听 8083 端口。

public final class HeartbeatServer {static final int PORT = 8083;public static void main(String[] args) throws Exception {// 配置服务器EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new HeartbeatHandlerInitializer());// 启动ChannelFuture f = b.bind(PORT).sync();f.channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}
}

5.4. 测试

首先启动 HeartbeatServer,客户端用操作系统自带的 Telnet 程序即可:

telnet 127.0.0.1 8083

可以看到客户端与服务器的交互效果如下图。
在这里插入图片描述

结语

文章如果对你有帮助,看完记得点赞、关注、收藏。

相关文章:

【Netty】Netty中的超时处理与心跳机制(十九)

文章目录 前言一、超时监测二、IdleStateHandler类三、ReadTimeoutHandler类四、WriteTimeoutHandler类五、实现心跳机制5.1. 定义心跳处理器5.2. 定义 ChannelInitializer5.3. 编写服务器5.4. 测试 结语 前言 回顾Netty系列文章&#xff1a; Netty 概述&#xff08;一&#…...

尚硅谷大数据hadoop教程_mapReduce

p67 课程介绍 p68概述 p69 mapreduce核心思想 p70 wordcount源码 序列化类型 mapReduce三类进程 p71 编程规范 用户编写的程序分成三个部分&#xff1a;Mapper、Reducer和Driver。 P72 wordcount需求案例分析 p 73 -78 案例环境准备 &#xff08;1&#xff09;创建maven…...

一键启停脚本

在/root 目录下创建bin文件夹再创建你的文件 文件里面写如下命令 #!/bin/bash if [ $# -lt 1 ] then echo "No Args Input..." exit ; fi case $1 in "start") echo " 启动集群 " echo " --------------- 启动 -------…...

20230604_Hadoop命令操作练习

20230604_Hadoop命令操作示例 再HDFS中创建文件夹&#xff1a;/itcast/it heima&#xff0c;如存在请删除&#xff08;跳过回收站&#xff09;。 hdfs dfs -mkdir -p /itcast/itheima上传/etc/hosts文件到hdfs的/itcast/itheima内。 hadoop fs -put /etc/hosts /itcast/itheima…...

hashCode 与 equals(重要)?

hashCode () 作用是获取哈希码&#xff0c;也称为散列码&#xff0c;实际上是返回一个int 整数&#xff0c;哈希码作用是确定该对象在哈希表中的索引位置&#xff1b;hashCode() 定义在JDK的Object.java中&#xff0c;意味着Java中的任何类都包含有hashCode() 函数。 散列表存…...

华为OD机试(2023.5新题) 需要打开多少监控器(java,py,c++,js)

华为OD机试真题目录:真题目录 本文章提供java、python、c++、jsNode四种代码 题目描述 某长方形停车场,每个车位上方都有对应监控器,当且仅当在当前车位或者前后左右四个方向任意一个车位范围停车时,监控器才需要打开 给出某一时刻停车场的停车分布,请统计最少需要打开…...

209.长度最小的子数组

2023.6.1 这道题的关键是滑动窗口法&#xff0c;滑动窗口法应设定好窗口左侧的右移条件与窗口右侧的移动条件 本例中先初始化好用到的各种值 循环的终止条件是滑动窗口右侧超出列表的范围 走来 cur_sum nums[right] 是将cur_sum的值更新为当前滑动窗口[left,right]的值之和 接…...

react antd Modal里Form设置值不起作用

问题描述&#xff1a; react antd Modal里Form设置值不起作用&#xff0c;即使用form的api。比如&#xff1a;编辑时带出原有的值。 造成的原因&#xff1a;一般设置值都是在声明周期里设置&#xff0c;比如&#xff1a;componentDidMounted里设置&#xff0c;hook则在useEff…...

idea连接Linux服务器

一、 介绍 配置idea的ssh会话和sftp可以实现对linux远程服务器的访问和文件上传下载&#xff0c;是替代Xshell的理想方式。这样我们就能在idea里面编写文件并轻松的将文件上传到linux服务器中。而且还能远程编辑linux服务器上的文件。掌握并熟练使用&#xff0c;能够大大提高我…...

在windows环境下使用winsw将jar包注册为服务(实现开机自启和配置日志输出模式)

前言 Windows系统使用java -jar m命令行运行Java项目会弹出黑窗。首先容易误点导致程序关闭&#xff0c;其次我们希望能在Windows系统做到开机自动启动。因此对于SpringBoot程序&#xff0c;目前主流的方法是采用winsw&#xff0c;简单容易配置 1.下载winsw工具 https://git…...

汽车通用款一键启动舒适进入拓展蓝牙4G网络手机控车系统

1.PKE无钥匙舒适进入功能,靠近车门自动开锁,离开车门自动上锁 2.一键启动/熄火 3.远程遥控启动/熄火 4.遥控设防盗/解除防盗 5.遥控开后尾箱锁负信号输出(需要原车自带尾箱马达和继电器&#xff09; 6.静音防盗/解除防盗 7.启动车后踩脚刹自动上锁 8.熄火车辆后自动开锁…...

QSettings Class

QSettings类 QSettings类公共类型&#xff08;枚举&#xff09;公有成员函数静态成员函数函数作用这个类写文件的特征 QSettings类 QSettings类提供持久的独立于平台的应用程序设置。 头文件:#include< QSettings >qmake:QT core继承&#xff08;父&#xff09;:QObje…...

【vue】关于vue中的插槽

当在Vue.js中构建可复用的组件时&#xff0c;有时候需要在父组件中传递内容给子组件。Vue的插槽&#xff08;slot&#xff09;机制提供了一种灵活的方式来实现这种组件间通信。 插槽允许你在父组件中编写子组件的内容&#xff0c;然后将其传递给子组件进行渲染。这样&#xff…...

Springboot整合Mybatis Plus【超详细】

文章目录 Mybatis Plus简介快速整合1&#xff0c;导入依赖2&#xff0c;yml文件中配置信息3&#xff0c;启动类上加上扫描mapper接口所在包的注解4&#xff0c;编写配置类5&#xff0c;实现自动注入通用字段接口&#xff08;非必需&#xff09;6&#xff0c;编写生成器工具类 使…...

接口测试-使用mock生产随机数据

在做接口测试的时候&#xff0c;有的接口需要进行大量的数据进行测试&#xff0c;还不能是重复的数据&#xff0c;这个时候就需要随机生产数据进行测试了。这里教导大家使用mock.js生成各种随机数据。 一、什么是mock.js mock.js是用于生成随*机数据&#xff0c;拦截 Ajax 请…...

Kohl‘s百货的EDI需求详解

Kohls是一家美国的连锁百货公司&#xff0c;成立于1962年&#xff0c;总部位于美国威斯康星州的门多西。该公司经营各种商品&#xff0c;包括服装、鞋子、家居用品、电子产品、化妆品等&#xff0c;并拥有超过1,100家门店&#xff0c;分布在美国各地。本文将为大家介绍Kohls的E…...

二叉树part6 | ● 654.最大二叉树 ● 617.合并二叉树 ● 700.二叉搜索树中的搜索 ● 98.验证二叉搜索树

文章目录 654.最大二叉树思路代码 617.合并二叉树思路代码 700.二叉搜索树中的搜索思路代码 98.验证二叉搜索树思路官方题解代码困难 今日收获 654.最大二叉树 思路 前序遍历构造二叉树。 找出数组中最大值&#xff0c;然后递归处理左右子数组。 时间复杂度On2 空间复杂度On …...

Linux命令记录

Shells 查看当前系统shell cat /etc/shells # 输出 # /etc/shells: valid login shells /bin/sh /bin/bash /usr/bin/bash /bin/rbash /usr/bin/rbash /bin/dash /usr/bin/dash查看正在使用的shell echo $SHELL # 输出 /bin/bashLinux文件结构 bin&#xff1a;系统可执行文件b…...

eBPF 入门实践教程十五:使用 USDT 捕获用户态 Java GC 事件耗时

eBPF (扩展的伯克利数据包过滤器) 是一项强大的网络和性能分析工具&#xff0c;被广泛应用在 Linux 内核上。eBPF 使得开发者能够动态地加载、更新和运行用户定义的代码&#xff0c;而无需重启内核或更改内核源代码。这个特性使得 eBPF 能够提供极高的灵活性和性能&#xff0c;…...

Linux :: vim 编辑器的初次体验:三种 vim 常用模式 及 使用:打开编辑、退出保存关闭vim

前言&#xff1a;本篇是 Linux 基本操作篇章的内容&#xff01; 笔者使用的环境是基于腾讯云服务器&#xff1a;CentOS 7.6 64bit。 学习集&#xff1a; C 入门到入土&#xff01;&#xff01;&#xff01;学习合集Linux 从命令到网络再到内核&#xff01;学习合集 目录索引&am…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...