详解yolov5和yolov8以及目标检测相关面试

一、与yoloV4相比,yoloV5的改进

  • 输入端:在模型训练阶段,使用了Mosaic数据增强、自适应锚框计算、自适应图片缩放
  • 基准网络:使用了FOCUS结构和CSP结构
  • Neck网络:在Backbone和最后的Head输出层之间插入FPN_PAN结构
  • Head输出层:训练时的损失函数GIOU_Loss,预测筛选框的DIOU_nns

二、yolov5网络结构

预处理

在模型预处理阶段,使用了Mosaic数据增强、自适应锚框计算、自适应图片缩放

CutMix:将2张图进行拼接

Mosaic:在CutMix基础上进行改进,采用4张图片,按照随机缩放,随机裁剪和随机排布的方式进行拼接

优点:将几张图组合成一张图,不仅可以丰富数据集,极大的提升网络训练速度,降低模型内存

自适应锚框计算(可选)

就是model的yaml的

anchors:- [10,13, 16,30, 33,23]- [30,61, 62,45, 59,119]- [116,90, 156,198, 373,326]

 分别对应预设的不同尺度的锚框的长宽,这些值是预先通过K-means聚类得到的,每个长宽比都是一个点,通过统计每个框的长宽比得到一组具有代表形的锚框

在yolo系列算法中,针对不同的数据集,都需要设定特定长宽的锚点框。在网络训练阶段,模型在初始阶段,模型在初始锚点框的基础上输出对应的预测框,计算其与GT框之间的差距,并执行反向更新操作,从而更新整个网络的参数,因此设定初始锚点框是比较关键的一环。
在yoloV3和yoloV4中,训练不同的数据集,都是通过单独的程序运行来获得初始锚点框。而在yoloV5中将此功能嵌入到代码中,每次训练,根据数据集的名称自适应的计算出最佳的锚点框,用户可以根据自己的需求将功能关闭或者打开,指令为:

parser.add_argument("-nuautoanchor", action='store_true', help='disable autoancher check') # 如果需要打开,只需要在训练代码时增加'-nuautoanchor'选项即可

自适应图片放缩,

若原图为1000x800,网络输入为640x640,注意并不是等比例放缩的,而是按照更长边的比例放缩,短的边就用黑色填充

 

 

黑边填充数值:

  • 计算需要填充黑边宽度:104
  • yoloV5执行5次下采样:2^5=32,对该数值取模:104%32=8
  • 将填充区域分散到两边:8/2=4

网络结构

1、Focus结构:

原始的640x640x3的图像输入FOCUS结构,采用切片操作(邻近下采样、类似于swin的plat操作),先变成320x320x12的特征图,再经过一次卷积操作,最终变成320x320x32的特征图。

2、CSP结构

  • CSP1_X结构应用于Backbone主干网络中
  • CSP2_X结构应用于Neck网络中
  • 其实就是n个带残差的卷积 + 1个残差卷积

3、SPP结构

多个并行的maxpool操作+cat,注意C3就是:CSP Bottleneck with 3x3 Convolution

v5主要使用Leaky ReLU

它是 ReLU 的变体。与 ReLU 在输入为负数时输出 0 不同,Leaky ReLU 在输入为负数时输出一个较小的负数值。这可以缓解 ReLU 的“死亡神经元”问题,即一些神经元在训练过程中可能会完全停用。

以上网络为backbone,实现5倍下采样,最终下采样倍数为5倍,即大小为20、40、80

4、FPN+PAN的结构

yoloV5的Neck仍采用了FPN+PAN结构,FPN层自顶向下可以捕获强语义特征,而PAN则通过自底向上传达强定位特征,通过组合这两个模块,可以很好的完成目标定位的功能。

借一下yolov8的图,来描述这个neck,为什么需要上采样,因为融合不同尺度的特征

损失函数

yolov5有三个损失函数分别是回归损失(边界框)、置信度损失(对象损失)、分类损失

回归损失用的是CIOU loss 置信度和分类损失用的是BCE loss,分别是二分类和多分类

IoU Loss:即预测框与GT框之间的交集/预测框与GT框之间的并集。这种损失存在一些问题:
(1)如状态1所示,当预测框和GT框不相交时,即IoU=0,此时无法反映两个框之间的距离,此时该损失函数不可导,即IoU Loss无法优化两个框不相交的情况。(2)如状态2和状态3所示,当两个预测框大小相同时,那么这两个IoU也相同,IoU Loss无法区分两者相交这种情况。

 GIoU Loss:为了解决以上的问题,GIoU损失应运而生,GIoU Loss中增加了相交尺度的衡量方式,缓解了单纯IoU Loss时存在的一些问题。

 DIoU Loss:针对IoU和GIoU损失所存在的问题,DIoU为了解决如何最小化预测框和GT框之间的归一化距离这个问题,DIoU Loss考虑了预测框与GT框的重叠面积和中心点距离,当GT框包裹预测框的时候,直接度量2个框的距离,因此DIoU Loss的收敛速度更快一些。

 CIoU Loss:在DIoU Loss的基础上增加了一个影响因子,将预测框和GT框的长宽也考虑进来。计算方法如下:将GT框的重叠面积、中心点距离和长宽比全部考虑进来

IOU_Loss主要考虑了检测框和GT框之间的重叠面积。

GIOU_Loss在IOU的基础上,引入最小外接矩形及外接矩形与并集的差集

DIOU_Loss在IOU和GIOU的基础上,同时考虑了边界框中心点距离信息。

CIOU_Loss在DIOU的基础上,又考虑了边界框宽高比的尺度信息。

后处理

NMS:非极大值抑制用于去除重复的边界框,只保留置信度最高的边界框,过程不赘述

训练的文件与指标

查准率

与confidence成正比,好理解

查全率

与confidence成反比,好理解

准确率

用的少

PR曲线

即以Recall为横坐标,Precision为纵坐标组成的曲线

AP(PR曲线下面积)

平均精度,不是严格的面积

mAP50(mean Average Precision)

在iou=50%的各类别的平均精度

F1-Score

查准率和查全率的综合评估指标

BECWithLogits loss

计算objectness score和class probability score的损失,结合了Sigmiod和BCELoss函数

三、yolov8

yolov8主要涉及到:backbone 使用C2f模块,检测头使用了anchor-free + Decoupled-head,损失函数使用了分类BCE、回归CIOU + DFL(新增项目)的组合,框匹配策略由静态匹配改为了Task-Aligned Assigner匹配方式、最后 10 个 epoch 关闭 Mosaic 的操作、训练总 epoch 数从 300 提升到了 500。

预处理

  基础输入仍然为640*640,预处理如:缩放、填充、mosiac等

网络结构

  1)连续使用两个3*3卷积直接降低了4倍分辨率。

最终下采样倍数为5倍,即大小为20、40、80

  2)c2f 模块

残差分支+多个带残差的卷积主分支+split操作,split操作通常用于将特征图分成多个部分,以便进行不同的处理或用于不同的路径。

SiLU

SiLU 也被称为 Swish 激活函数,它类似于线性函数和 Sigmoid 函数的组合,是一种平滑且具有非线性特性的激活函数。

3)sppf 模块

对比v5的spp,将简单的并行max pooling 改为串行+并行的方式。对比如下(左边是SPP,右边是SPPF):

neck & head

检测头以及匹配机制

    Head 部分变化最大,从原先的耦合头变成了解耦头,并且从 YOLOv5 的 Anchor-Based 变成了 Anchor-Free。

Yolov5: 检测和分类共用一个卷积(coupled head)并且是anchor based ,其 卷积输出为(5+N class)*3,其中 5为bbox 四个值+ 一个obj 值 (是否有目标),N class 为类别数,3为anchor 的数量,默认是3个

YOLOv8:检测和分类的卷积是解耦的(decoupled),如右图,上面一条支路是框的卷积,框的特征图channel为4*regmax,关于这个regmax 后面我们详细的解释,并不是anchor;分类的channel 为类别数。

  因此主要的变化可以认为有三个:1)coupled head -> decoupled head ;2)obj 分支消失;3)anchor based——> anchor free

1. Anchor-Based

v5中Anchor-Based的使用方式为one_stage——在网络的多尺度上展开anchor boxes,以直接预测物体的类别和 anchor box偏移量。
v5中目标的反算为:特征图数据 * 预设锚框参数的宽高 = 目标的位置(并不是直接预测目标的位置)。即回归

其中特征图数据则包含了中心点偏移量、宽高偏移量等数据。

2. Anchor-Free

Anchor-Based的局限性
①Anchor的设置需要手动去设计(长宽比,尺度大小,anchor的数量),对不同数据集也需要不同的设计,相当麻烦。
②Anchor的匹配机制使得极端尺度(特别大/小的object)被匹配到的频率,相对于大小适中的object被匹配到的频率更低,网络在学习时不容易学习这些极端样本。
③Anchor的庞大数量使得存在严重的不平衡问题,涉及到采样、聚类的过程。但聚类的表达能力在复杂情况下是有限的
④Anchor-Based为了兼顾多尺度下的预测能力,推理得到的预测框也相对较多,在输出处理时的nms计算也会更加耗时。

原理

训练中直接学习各种框形状。推理时不依靠聚类,而是根据学习到的边框距离/关键点位置,拟合物体尺寸。
v8中使用的方法是:Center-based methods——基于中心点的方法。先找中心/中心区域,再预测中心到四条边的距离。

v8中目标的反算为:在特征图每个grid(特征图中的单个框)上,预测框四条边与grid中心点的偏移值 (“左上右下”相对于中心点的距离)。

个人理解:Anchor-Free通过不依赖数据集中的先验知识,使网络对“物体形状”有更好的表达能力,更具泛化潜能。在运动物体、尺寸不一物体检测上有所提升,同时检测被遮挡物体时也能更加灵活

3、样本分配策略

正样本总很少,负样本(即无目标区域)总太多。会导致模型学习不均衡。因此,我们需要样本分配策略来解决这一问题。

1. 静态策略

静态分配策略是训练开始之前就确定的,这种分配策略通常基于经验得出,可以根据数据集的特点进行调整。但是不够灵活,可能无法充分利用样本的信息,导致训练结果不佳。

损失函数

Loss 计算包括 2 个分支: 分类和回归分支,没有了之前的 objectness 分支。

分类损失:

回归损失

基于CIOU,虽然v8的CIOU使用方式与v5保持一致,但引入Anchor-Free的Center-based methods(基于中心点)后,模型从输出“锚框大小偏移量(offest)”变为"预测目标框左、上、右、下边框距目标中心点的距离(ltrb = left, top, right, bottom)"。

为配合Anchor-Free、以及提升泛化性,在v8中,增加了DFL损失( Distribution Focal Loss。DFL以交叉熵的形式,去优化与标签y最接近的一左一右2个位置的概率,从而让网络更快的聚焦到目标位置及邻近区域的分布。

在实际训练中,DFL将与CIOU损失结合使用。
在第一部分,通过DFL对“边界框分布概率”和标签的“分布概率”进行损失计算,从而对每条边进行优化。
在第二部分,将“边界框分布概率”还原为预测框,通过CIOU损失对预测框和标签的“实际框”进行损失计算,从而对预测框整体进行优化。

yolo中训练和推理时不一样的地方

如图像预处理,NMS等

目标检测相关知识

两阶段检测和一阶段检测

代表算法分别是fastrcnn、yolo,都是利用了锚框,区别在于:

两阶段的fastrcnn(准):Region Proposals+RoI Pooling,即预设锚框,再将生成的候选区域(区域提议)映射到卷积特征图上,并通过 RoI Pooling 操作特区锚框的特征,类似于LaneATT

一阶段的yolo(快):YOLO 将图像划分为网格(grid),每个网格负责预测特定区域的目标。以直接预测相对于网格单元的中心和尺寸的偏移量,以及边界框的宽度和高度的偏移量。

过拟合和欠拟合

过拟合是指模型在训练数据上表现很好,但在未见过的测试数据上表现不佳的现象。换句话说,模型对训练数据的噪声和细节进行了过度学习,导致它无法很好地泛化到新数据上

解决:减少模型复杂度、正则化、数据增强

欠拟合是指模型在训练数据和测试数据上都表现不佳的现象。模型无法捕捉到数据中的潜在模式,导致训练误差和测试误差都较高

解决:增加模型复杂度、减少正则化

梯度消失和梯度爆炸

梯度消失:通常发生在深层网络中,当梯度从输出层反向传播到输入层时,经过多个层次的链式法则,梯度值可能会变得非常小,几乎无法对权重进行有效的更新。

原因:网络太深、激活函数问题:如 Sigmoid 和 Tanh,在输入值较大或较小时,会导致梯度变得非常小。

梯度爆炸:梯度值变得非常大,导致网络的权重更新过度,模型参数发散,训练过程不稳定。梯度爆炸使得模型参数更新幅度过大,可能导致训练失败或模型不收敛。

原因:

  • 激活函数问题:一些激活函数(如在激活值较大时)可能导致梯度值快速增大。
  • 深层网络:梯度在经过多个层次的链式法则传播时,可能会逐渐增大。
  • 大学习率:过大的学习率会导致梯度更新过度,从而引发梯度爆炸。

解决:

        合适的激活函数、合适的权重初始化方法、调整学习率

激活函数的了解

sigmoid:输出范围固定在 0 到 1,适合二分类问题。在输入较大或较小时梯度接近于零,导致梯度消失;梯度计算较慢。

Tanh:常用于隐藏层,比 Sigmoid 更适合处理数据,因为输出范围是 −1-1−1 到 111。输入过大或过小时仍然会导致梯度消失。

ReLU:计算简单,能有效缓解梯度消失问题。但可能导致“死亡 ReLU”问题,即某些神经元在训练过程中始终输出 0,无法更新。

Leaky ReLU:它是 ReLU 的变体。与 ReLU 在输入为负数时输出 0 不同,Leaky ReLU 在输入为负数时输出一个较小的负数值。这可以缓解 ReLU 的“死亡神经元”问题

softmax和sigmoid

softmax:适合多分类问题,将输出的类别转换为和为1的概率分布

sigmoid:适合二分类问题,映射到0-1的值,但和不为1,只是起一个映射方法的作用:大的越大,小的越小

归一化、正则化

正则化是用于防止模型过拟合的一种技术,通过在损失函数中添加额外的约束,来减少模型的复杂度,从而提高模型的泛化能力。常见的正则化技术包括:L1、L2、Droupt随机丢弃

批量归一化(Batch Normalization,BN) 是一种用于加速训练和稳定模型的方法,通过对每一层的输入进行归一化处理,使其具有均值为零和方差为一的分布。能够缓解梯度消失和梯度爆炸问题,加速模型的训练过程,通常使模型收敛更快。

inpalce操作

Inplace 操作 是指在计算过程中直接修改输入变量的值,若为false:创建新的变量来存储结果

残差网络为什么能解决梯度消失的问题

      同时Resnet确实也存在解决梯度消失的作用,主要作用机理是跳跃连接的存在使得求导时可以将倒数直接回传到上一层,实现梯度的跨层传播                          

描述一下各类优化器及其公式

 1. 梯度下降

2. 随机梯度下降(sgd)

3. 小批量梯度下降

6. Adagrad

8. Adam

python 深拷贝浅拷贝的区别

在浅拷贝时,拷贝出来的新对象的地址和原对象是不一样的,但是新对象里面的可变元素(如列表)的地址和原对象里的可变元素的地址是相同的, 因此对原对象的元素改变时,新对象也会随之改变

深拷贝会对原对象里的可变元素指向新地址,原对象的改变不会对新对象造成影响。  

python列表和元组区别

       列表是动态数组,它们不可变且可以重设长度(改变其内部元素的个数)。
       元组是静态数组,它们不可变,且其内部数据一旦创建便无法改变。
       元组缓存于Python运行时环境,这意味着我们每次使用元组时无须访问内核去分配内存

python 生成器和迭代器什么区别?

都是用于迭代遍历时的

          迭代器:迭代器是一个对象,实现了 __iter__()__next__() 方法,允许你逐个遍历元素,直到没有元素可遍历。

class MyIterator:def __init__(self, data):self.data = dataself.index = 0def __iter__(self):return selfdef __next__(self):if self.index < len(self.data):result = self.data[self.index]self.index += 1return resultelse:raise StopIteration# 使用自定义迭代器
my_iter = MyIterator([1, 2, 3])
for item in my_iter:print(item)

         生成器::生成器是使用 yield 关键字的函数,每次调用 yield 时,生成器会返回一个值并记住当前的执行状态,以便下次迭代继续执行。

def my_generator():yield 1yield 2yield 3# 使用生成器
gen = my_generator()
for item in gen:print(item)

Dice loss的优缺点。

       优点:对于正负样本不均衡的情况效果好。

       缺点:对小样本训练波动大; 拟合不平滑,如果没有IoU则网络不知道该怎么引导梯度进行衰减。

python的装饰器

装饰函数,在不修改代码的前提下,封装一些其他简易的功能,使用:@func

python的一些魔法函数

也称为双下划线方法(Dunder Methods)

def __repr__(self)当直接打印类的实例化对象时,系统将会自动调用该方法,输出对象的自我描述信息,用来告诉外界对象具有的状态信息 def __str__(self),好像和repr类似

def __len__(self):同上

__getitem__(self, key):获取指定键的值,obj[key] 访问时使用。

@property 将方法变成属性调用,调用时不加括号,并且它的属性类似私有属性,无法进行赋值,由构造函数就定好  
@staticmethod:静态方法:可以在不实例化的情况下从类中调用该方法,没有self参数,且无法用任何init的参数,就跟一个扎根在类中的外部函数一样。
@classmethod:可以在不实例化的情况下从类中调用该方法,没有self参数,但需要一个‘cls’参数,且可以用类的属性,方法,可以用init的参数

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

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

相关文章

[NOIP2009 提高组] 最优贸易(含代码题解)

[NOIP2009 提高组] 最优贸易 题目描述 C C C 国有 n n n 个大城市和 m m m 条道路&#xff0c;每条道路连接这 n n n 个城市中的某两个城市。任意两个城市之间最多只有一条道路直接相连。这 m m m 条道路中有一部分为单向通行的道路&#xff0c;一部分为双向通行的道路&am…

NLP-使用Word2vec实现文本分类

Word2Vec模型通过学习大量文本数据&#xff0c;将每个单词表示为一个连续的向量&#xff0c;这些向量可以捕捉单词之间的语义和句法关系。本文做文本分类是结合Word2Vec文本内容text&#xff0c;预测其文本标签label。以下使用mock商品数据的代码实现过程过下&#xff1a; 1、…

JMeter的使用方法

软件安装&#xff1a; 参考链接&#xff1a;JMeter 下载安装及环境配置&#xff08;包含jdk1.8安装及配置&#xff09;_jmeter5.2.1需要什么版本的jdk-CSDN博客 前置知识储备&#xff1a; JMeter的第一个案例 增加线程数 线程&#xff08;thread&#xff09;是操作系统能够进…

ROS2入门到精通—— 2-8 ROS2实战:机器人安全通过狭窄区域的方案

0 前言 室内机器人需要具备适应性和灵活性&#xff0c;以便在狭窄的空间中进行安全、高效的导航。本文提供一些让机器人在狭窄区域安全通过的思路&#xff0c;希望帮助读者根据实际开发适当调整和扩展 1 Voronoi图 Voronoi图&#xff1a;根据给定的一组“种子点”&#xff0…

【数据挖掘】词云分析

目录 1. 词云分析 2. Python 中的 WordCloud 库 1. 词云分析 词云&#xff08;Word Cloud&#xff09;是数据可视化的一种形式&#xff0c;主要用于展示文本数据中单词的频率和重要性。它具有以下几种主要用途和意义&#xff1a; 1. 文本分析 • 识别关键主题&#xff1a;通…

AI学习记录 - 图像识别的基础入门

代码实现&#xff0c;图像识别入门其实非常简单&#xff0c;这里使用的是js&#xff0c;其实就是把二维数组进行公式化处理&#xff0c;处理方式如上图&#xff0c;不同的公式代表的不同的意义&#xff0c;这些意义网上其实非常多&#xff0c;这里就不细讲了。 const getSpecif…

JavaScript构造函数小挑战

// 编码挑战 #1 /* 使用构造函数实现一辆汽车。一辆汽车有一个品牌和一个速度属性。speed 属性是汽车当前的速度&#xff0c;单位为 km/h&#xff1b; a. 执行一个 “accelerate ”方法&#xff0c;将汽车的速度提高 10&#xff0c;并将新速度记录到控制台&#xff1b; 3. a.…

VSCode python autopep8 格式化 长度设置

ctrl, 打开设置 > 搜索autopep8 > 找到Autopep8:Args > 添加项--max-line-length150

等保测评练习卷17

等级保护初级测评师试题17 姓名: 成绩: 判断题(101=10分)1. 关于安全区域边界的安全审计,三级系统的要求包括应对审计进程进行保护,防止未经授权的中断。( F ) 是安全计算环境的安全审计 2.…

秋招突击——7/22——复习{堆——前K个高频元素}——新作{回溯——单次搜索、分割回文串。链表——环形链表II,合并两个有序链表}

文章目录 引言复习堆堆——前K个高频元素个人实现复习实现二参考实现 新作单词搜索个人实现参考实现 分割回文串个人实现参考实现 环形链表II个人实现参考实现 两个有序链表个人实现 总结 引言 又是充满挑战性的一天&#xff0c;继续完成我们的任务吧&#xff01;继续往下刷&a…

WebRTC QoS方法十三.2(Jitter延时的计算)

一、背景介绍 一些报文在网络传输中&#xff0c;会存在丢包重传和延时的情况。渲染时需要进行适当缓存&#xff0c;等待丢失被重传的报文或者正在路上传输的报文。 jitter延时计算是确认需要缓存的时间 另外&#xff0c;在检测到帧有重传情况时&#xff0c;也可适当在渲染时…

【目标检测实验系列】EMA高效注意力机制,融合多尺度特征,助力YOLOv5检测模型涨点(文内附源码)

1. 文章主要内容 本篇博客主要涉及多尺度高效注意力机制&#xff0c;融合到YOLOv5s模型中&#xff0c;增加模型提取多尺度特征的能力&#xff0c;助力模型涨点。&#xff08;通读本篇博客需要7分钟左右的时间&#xff09;。 2. 简要概括 论文地址&#xff1a;EMA论文地址 如下…

Blender材质-PBR与纹理材质

1.PBR PBR:Physically Based Rendering 基于物理的渲染 BRDF:Bidirection Reflectance Distribution Function 双向散射分散函数 材质着色操作如下图&#xff1a; 2.纹理材质 左上角&#xff1a;编辑器类型中选择&#xff0c;着色器编辑器 新建着色器 -> 新建纹理 -> 新…

音视频入门基础:H.264专题(17)——FFmpeg源码获取H.264裸流文件信息(视频压缩编码格式、色彩格式、视频分辨率、帧率)的总流程

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…

【开源库编译 | zlib】 zlib库最新版本(zlib-1.3.1)在Ubuntu(Linux)系统下的 编译 、交叉编译(移植)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

《书生大模型实战营第3期》入门岛 学习笔记与作业:Git 基础知识

文章大纲 Git 是什么&#xff1f;-- 分布式版本控制系统版本控制系统简介Git 基本概念1. 安装 Git1.1 Windows 系统1.2 Linux 系统 2. Git 托管平台3. 常用 Git 操作4. tips4.1 全局设置 vs. 本地设置4.2 如何配置4.3 验证设置4.4 Git 四步曲 5. 常用插件6. 常规开发流程 作业其…

js+css侧边导航菜单 可收缩

jscss侧边导航菜单 可收缩https://www.bootstrapmb.com/item/14774 创建一个可收缩的侧边导航菜单需要使用JavaScript来处理交互&#xff0c;而CSS则用来设置样式和动画效果。以下是一个简单的示例&#xff0c;展示了如何创建一个可收缩的侧边导航菜单。 HTML 结构 html<!…

重修之路1

我也不知道我现在处于个什么状态&#xff0c;我在以前写代码时知道部分方法如何使用&#xff0c;但是也仅限于此我并不了其如何实现&#xff0c;让我感到迷茫我是越来越菜了随着AI的发展它写出的代码简洁高效甚至让我有些看不懂&#xff0c;以至于我开始怀疑自己的JS基本功因此…

【接口测试】params传参与body传参区别

文章目录 一.params传参二.body传参三.两者区别说明 一.params传参 params传参一般用于get请求 params传参时,参数会附于URL后面以问号形式展示。 示例&#xff1a; http://ip地址:端口号/login?usernamexm&pwd111二.body传参 body传参一般用于post请求 body传参时需…

MacOS安装SDKMan管理Java版本

文章目录 1 简介2 安装与卸载2.1 安装2.2 卸载 3 使用3.1 查看其他工具&#xff1a;支持 Ant, Maven 等3.2 查看Java版本3.3 安装Java&#xff0c;加上相关的版本3.4 设置Java版本(全局)3.5 只在当前窗口生效3.6 卸载1 默认环境无法卸载 4 jdk安装的位置5 与IDEA集成参考 1 简介…