软件测试——性能测试工具JMeter

news2024/11/30 15:41:54

1.JMeter介绍

Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件。JMeter小巧轻便且免费,逐渐成为了主流的性能测试工具,是每个测试人员都必须要掌握的工具之一。

环境要求:

需要Java8或者更高的版本。

1.1 JMeter的下载

1)登陆JMeter的官网:Apache JMeter - Download Apache JMeter

2)点击要下载的版本即可自动下载

3)下载完毕后,进行解压

4)解压完毕后,就会出现如下文件

1.2 JMeter的打开

方式一:点击bat文件

点击进入bin文件夹

在bin文件夹下有一个jmeter.bat文件

双击运行后会先打开cmd窗口

然后就会启动jemter

方式二:配置环境变量(推荐)

将bin目录所在的文件夹复制下来

打开系统的环境变量配置

双击Path,进入Path环境变量的配置,先点击新建,然后复制刚刚的路径,最后点击确定。

然后我们使用win+r键,输入cmd打开命令提示符窗口

输入jmeter后能运行出出来则说明配置成功了。

1.3 JMeter配置中文

方法一:手动更改

依次点击左上角的"Options" -> "Choose Language" -> "Chinese(Simplified)"

但是这种方法不是一劳永逸的,下次重新登陆还是英文的。

方法二:更改配置文件(推荐)

在bin文件夹下有一个jmeter.properties文件。

使用Ctrl+f查找language

将找到的第四个language=en改成zh_CN

然后将文件保存,重新打开JMeter就是中文了。

1.4 JMeter元件作用域和执行顺序

在JMeter中,元件的作用域和执行顺序是非常重要的概念。

作用域:

JMeter元件的作用域主要由测试计划的树形结构中的元件父子关系来确定。

执行顺序:

取样器(sampler)元件内组件不依赖其他元件就可执行,因此取样器不存在作用问题元件作用域只对它的子节点有作用,其他作用域默认根据测试计划中树形结构来定;

2. JMeter基本使用流程

这里先带大家简单见一下JMeter怎么使用,后面每个组件都会详细介绍

1)点击左上角的编辑->添加->线程(用户)->线程组

创建完之后如下所示:

在创建完线程组之后,我们就可以来性能测试了,现在我们要选择进行性能测试的对象,就以测试网页http://www.baidu.com/s?ie=utf-8&wd=jmeter为例。

在线程组下点击添加->取样器->HTTP请求

创建完成后,填写上如下内容:

在设置完成后,点击左上角的运行。

此时会跳出来一个弹窗,意思是我们需要先保存才能运行。

我们保存完毕后,再次点击运行,可以看到下面两个框变红了,说明他们正在运行。

运行的结果我们现在是没法直接看到的。

我们点击线程组->添加->监听器->查看结果树

此时再次点击运行,就可以发现结果树页面下包含一个HTTP请求。

在取样器结果中,我们就可以查看本次测试的结果,并且能查看请求报文和响应数据。

如果想测试并发场景,可以将线程组中的线程数修改一下,这里的线程数指的其实是虚拟用户数,JMeter会以虚拟用户的身份去访问这个网站。

设置好线程数后,回到结果树,为了不让上一次的查询结果对这一次产生干扰,我们点击清除按钮,进行清除。

清除之后再次运行,我们就能看到出现了10个HTTP请求。

3. 重点组件

3.1 线程组

添加线程组

参数解释

右边的选项从上往下,依次来看

  • 名称:线程组的名字,可任意填写。
  • 注释:对线程组的介绍,可写可不写。
  • 在取样器错误后要执行的动作:即请求错误后要执行的动作,若在当前线程组下存在多个HTTP请求中,某个请求出错了,会根据选项来执行后续的动作,默认为继续执行。
  • 线程数:虚拟用户数(并发数),用于设置发送的请求次数。
  • Ramp-Up时间(秒):性能测试运行时间,单位为秒,若线程数为10,Ramp-Up时间为2,意思是发送10个请求必须在2秒内完成。
  • 循环测试:测试执行的次数
    • 配置指定次数:控制脚本循环执行的次数(最终运行次数 = 循环测试数 * 线程数)
    • 配置循环永远:需要调度器配合使用,否则就是死循环(设置脚本执行时间,延迟启动时间:脚本等待指定时间才能运行)

3.2 HTTP取样器

添加取样器

参数解释

  • 协议:向目标服务器发送HTTP请求协议,可以是HTTP或HTTPS,默认为HTTP
  • 服务器名称或IP :HTTP请求发送的目标服务器名称或IP
  • 端口号:目标服务器的端口号,http协议端口号80,https端口号443
  • 请求方法:发送HTTP请求的方法,可用方法包括GET、POST、HEAD、PUT、DELETE等
  • 路径:目标URL路径(URL中去掉服务器地址、端口及参数后剩余部分,在http://www.baidu.com/s?ie=utf-8&wd=jmeter例子中,路径就是/s)
  • 内容编码:编码方式,默认为ISO-8859-1编码
  • 参数:在请求中发送的URL参数,可以将URL中所有参数设置在本表中,表中每行为一个参数(对应URL中的 name=value),在我们的例子:http://www.baidu.com/s?ie=utf-8&wd=jmeter中,参数有两个,分别为ie=utf-8和wd=jmeter。

以http://www.baidu.com/s?ie=utf-8&wd=jmeter网页为例,HTTP取样器填写如下:

注意:

参数可以点击添加直接配置。

也可以使用消息体数据,采用json格式进行配置。

3.3 查看结果树

创建查看结果树

参数介绍

重点关注取样器结果,请求,响应数据这三个选项。

当我们请求失败时,如我们设置以一个错误的域名,取样器结果如下:

请求中的内容如下,我们可以在这里检查是否是请求的IP或参数不正确。

因为这个请求是没有响应的,所以响应数据显示HttpHostConnectException,即http连接异常。

注意:

左上角有一个下来菜单,可以选择展示方式,默认Text为文本格式。不太好看,我们可以设置为Json格式。

3.4 HTTP请求默认值

如果你要多次访问同一个web系统,每次都需要重新输入协议,地址,端口等内容非常麻烦,可以设置HTTP请求的默认值。

配置

此时我们再创建一个新的HTTP请求,这个新的请求中什么内容都没有

直接点击运行,可以发现该HTTP请求居然请求成功了。

这就是HTTP请求默认值的好处,可以帮我们省去很多重复的填写。

之所以叫他默认值,因为如果我们自己手动配置,就使用手动配置的,如果请求中没有配置,就去请求默认中取。

3.5 HTTP信息头管理器

一个http请求会发送请求到服务器,请求里面包含:请求头、请求正文、请求体,请求头就是信息头,当我们配置好信息头后,配置的信息头会跟随HTTP请求一起发送给服务器,常用于传送cookie,token或者伪造头的场景。

设置HTTP信息头管理器

假设现在有这样一个网站,这个网站在登陆成功之后,会发送给客户端一个报文,报文中包含如下字段,其中有个字段data。该网站要求每次在该网站申请服务(发送http请求)时,都要携带data字段,不携带的说明不是该网站的登陆用户,返回一个401错误页面。

在发送http请求时,我们添加一个名为user_token_header的字段,值就是上面提到的data。

当添加这个字段后再次发起一个http请求时,就可以成功访问该页面了。

也就说我们要想访问这个网站,就必须携带user_toke_header,所以我们就可以使用HTTP信息头管理器。

添加完之后,我们再点击运行,可以发现请求头中自动帮我们添加了user_token_header。

3.6 JSON提取器

在HTTP信息头管理器中,我们说到了当有一个网站在登陆成功后会发送一个data,当我们需要使用登陆页面才能使用的功能时,每次的请求都需要添加data字段。

那么现在的问题时,网站每次发送的data都不一样,那么我们就需要手动修改,非常麻烦,所以我们可以使用JSON提取器来提取其中的data字段,然后将他放到信息头管理器中。

JSON提取器的作用:接⼝响应成功,通过提取返回值对应字段,可用于其他接口的参数配置

添加JSON提取器

提取响应数据肯定是在发送数据之后,所以叫后置处理器。

介绍

其中json提取需要通过json操作符。

如果说返回的json如下所示,我们想要提取出data对应的值。

首先使用$选中根据元素,即{},使用.data就能选中到data。

我们可以打开左边的JSON JMESPath Tester来检查我们的json提取是否正确。

我们将json提取的内容输入进去,然后点击右边的Test即可进行测试,测试的结果正是我们想要提取的,所以这个json提取的内容就是正确的。

所以我们的JSON提取器用就可以写如下内容。

然后还要修改HTTP信息头管理器,以前的user_token_header是写死的,而现在修改之后就能以不变应万变。

如果现在响应的data修改了。

请求头中的user_token_header就能提取出data了。

如果有多个http请求,json提取器提取的字段会发生覆盖

json提取器的原理是提取同级中从上往下http响应中的字段。

假设下面场景:博客系统,其中“登陆”页和“列表页”都会返回一个data,后面在这个系统中所有的http请求都需要携带“登陆”页返回的data,否则认为请求非法。

执行过程:

  1. “提取用户登陆凭证”是一个json提取器,我们设置好之后,就可以提取到往后遇到的http响应中的data字段。
  2. “登陆”是一个http请求页,当发起请求后,会返回一个http响应,其中包含data字段,那么json提取器就提取到了这个data,此时变量token中保存的就是“登陆”页的data字段。
  3. “列表页”包含子集,所以先执行他的子集“HTTP信息头管理器”,此时会提取变量token中的字段,也就是“登陆”页的data,这个信息头将作为列表页的http请求头字段,也就是说“列表页”的http请求中user_token_header中的data是“登陆”中欧的data,所以“列表页”可以成功登陆。
  4. “列表页”是一个http请求页,他的响应中也包含了data,所以json提取后,将token中的值覆盖为“列表页”的data。
  5. “用户信息”中的“HTTP信息头管理器”提取token,提取到的是“列表页”的data字段,没有“登陆”的data,所以“用户信息”访问失败。

上面的过程中出现了一个问题:“列表页”中的data字段会覆盖掉“登陆”中的data,最终导致访问“用户信息”失败。

解决办法也很简单,改变一下执行顺序即可,json提取器是“登陆”子集,也就是它只会提取“登陆”中的data,然后将提到的值保存至“HTTP信息头管理器”中的token变量。

而“列表页”虽然有data,但是没有了json提取器,所以“HTTP信息头管理器”中的token值就不会改变了。

如何编写json提取

我们想要提取json中的数据,就要用到json的操作符,这篇文章json操作符详细的介绍了json操作符的使用,感兴趣的同学可以取看看。

3.7 用户定义的变量

还是以上面的博客系统为例,假设“列表页”的功能是保存了多篇博客,每个博客以blogid为标识符区分,我们创建一个http请求命名为详情页,每个详情页都是访问具体的某一篇博客。

如下图所示,其中blogid=1993,表示要访问的是blogid为1993的博客。

假如说现在有200个详情页,分别都是不同的blogid,我想让他们的blogid都变成1993,如何实现?

如果手动一个一个修改就太麻烦了,我们可以创建一个用户定义的变量来解决这个场景。

 添加用户定义的变量

然后我们创建一个id,值为1993。

然后将所有详情页中的blogid设置为${id},现在所有的blogid的值都为id了,如果后面想把所有的blogid设置为1992,则直接修改id,非常方便。

3.8 JSON断言

接口发送请求成功,响应码为200并不能完全代表接口请求成功,我们更多需要关注接口响应数据是否符合预期。

我们可以使用JSON断言来判断响应数据是否与预期数据相等。

添加JSON断言

添加JSON断言配置

注意:

  • 1)若不选Additionally assert value,表示添加断言值,则可用来判断字段是否存在,比如仅要判断data字段是否存在,则不选。
  • 2)选择Additionally assert value,则必须添加Expected Value期望的断言值(精确匹配,区分大小写
  • 3)若不选Match as regular expression正则匹配,则Expected Value必须填写完整,少一个字符都会导致断言失败
  • 4)若选择Match as regular expression支持正则匹配,则Expected Value可以仅写上部分关键词即可断言成功

如果登陆成功,会返回一个非空的data,那么我们就可以通过data来判断登陆是否成功(不能简单以返回码来判断成功,可能存在返回码为200,但是响应信息为登陆错误的场景)

使用正则表达式,\S表示能匹配一个非空的字符,+表示匹配一个或多个,两个结合在一起就变成了能匹配一个非空字符或者多个非空字符,这样就能成功匹配data了。

3.9 同步定时器(集合点)

我们前面介绍了线程组的概念,我们说的线程指的就是虚拟用户,假如说我们现在将线程数改为5。

每个线程组都会执行一遍下面的测试案例,也就是说一共会执行5遍。

在运行之后,右上角会显示此次运行的时间,一共是1秒钟,那么现在的问题是,这5个线程是同时执行的(并发),还是执行完一个之后再执行第二个(串行)。

我们点击运行时间右边的黄色三角形就可以查看进程状态。

结论:这5个进程是串行完成测试计划的,谁先准备好谁先执行

如果我们想要让这5个进程同时执行测试计划,即我们要实现并发,我们需要添加同步定时器。

添加同步定时器

配置同步定时器

模拟用户组的数量:每次释放的线程数量。当设置为0时,等同于线程组中设置的用户数量。

当配置完成后,我们再来看一下添加完同步定时器之后有什么区别

可以看到所有线程都准备好了才会发送请求,而每个线程发送请求和完成的时间都不相同,所以有了先后顺序。

如果模拟用户组数量超过了线程组里配置的线程数?

线程组中配置线程数为5,我们将模拟用户组数量设置为50后,再次进行测试。

可以看到最终卡住了,因为我们设置的50个,他就会等待50个线程,但是实际上只有5个线程,它要等到剩下的45个线程都准备好才会继续执行。

结论:模拟用户数不能超过线程组中配置的线程数

如果模拟用户组数量小于线程组里配置的线程数?

线程组中配置线程数为5,我们将模拟用户组数量设置为3后,再次进行测试。

可以看到虽然模拟用户组只配置了3,但是5个线程组都会准备。但是当前面4个线程准备好之后,此时共有4个线程准备好,4大于等于3,就直接发送了,而第5个线程还在等待,此时只有1个线程在等待了,不能满足大于等于3,所以5号线程一直在等待另外2个线程来才能发送。

结论:当准备好的线程数>=配置数量,就直接发送请求,所以配置的数量小于线程数时,最好把循环打开,避免最后一次未准备好的线程数量达不到并发数陷入一直等待的状态。

3.10 事物控制器

在聚合报告中,可以看到有一个表格,其中Label表示标签样本,而一个Label就可以看成是一个事物。

现在我们想让“登陆”和用户信息”合并成一个事物,我们可以通过事物控制器来完成上面的功能。

添加事物控制器

当创建完成之后,我们将其命名未“登陆事物”,然后将“登陆”和“用户信息”都放在“登陆事物下”。

那么将这两个合并成一个“事物”有啥作用呢?

此时我们再次运行并打开聚合报告,可以看到“登陆事物”会将“登陆”和“用户信息”的平均时间、中位数等都加起来,这样就能方便我们进行性能分析。

在进行页面性能测试或API性能测试时,事物控制器可以帮助测试人员更准确地评估系统性能,尤其是在涉及多个接口或操作的复杂场景中。例如,在订单提交的过程中,可能需要调共多个接口,并且某些接口可能依赖于前⼀个接口的结果。在这种情况下,使用事务控制器可以将这些接口统一视为一个事务进行性能测试,从而得到更接近真实场景的性能测试结果。

3.11 CSV数据文件设置

以登陆接口为例,当我们执行登陆接口的性能测试时,手动配置了用户名和密码为固定的username和password,然而实际使用中不可能只有一个用户登陆,为了模拟更真实的登录环境,我们需要提供更多的用户username和password来实现登录操作。

添加CSV数据文件设置

配置CSV数据文件设置

  • 文件名:填写csv文件的路径。建议使用绝对路径。
  • 文件编码:UTF-8
  • 变量名称:从csv数据文件中读起的数据需要保存到的变量名,有多个变量使用逗号分隔。
  • 是否忽略首行:是否从csv数据文件第一行开始读取。
  • 分隔符:要求与csv数据文件中多列的分隔符一致。
  • 遇到文件结束符再次循环:若选择为True当数据不够的时候会从头取。若选择False,则需要勾选下面的配置,遇到文件结束符停止线程,这里如果不勾选,请求将会报错。

其中的csv文件就是我们常说的excel,csv文件内容如下,第一列是账号,第二列是密码。

我们将读取到的账号和密码保存至username和password两个变量中

那么我们就可以配置CSV数据文件如下图所示。

既然我们将用户名和密码都保存至username和password中,所以登陆页面就可以去这两个变量中取了。

都配置好之后,点击执行,第一个登陆请求中的username就被设置为了zhangsan,password为123456。

而第二个登陆请求中的username变成了lisi,password为123456

3.12 HTTP Cookie管理器

我们前面说到的登陆凭证是在登陆之后,响应报头中包含了一个data字段,往后必须携带data字段才视为登陆用户。

而另一种场景就是使用Cookie来验证是否是已登录用户。如下图所示,当请求头中没有携带Cookie时,虽然能返回响应,但是响应报头中的userId为0,并且username为空,这表示未登录。

当我们携带了Cookie再访问同样的接口时,此时返回的就是正确的userId和username,表明我们是已经登陆的用户,可以享受该网页的服务了。

创建HTTP Cookie管理器

Cookie管理器的作用是:自动获取接口中的Cookie信息,带入到其他接口请求中。

如上图所示,登陆有两个子集,先执行了登陆-0,此时它的http响应数据中收到了一个Cookie,而这个Cookie会被Cookie管理器接收到;在执行登陆-1时,会将接受到的Cookie放到登陆-1的请求头体重。

在没有添加Cookie管理器时,http请求体如下:

而添加了Cookie管理器之后的http请求体如下:

Cookie管理器会自动提取Cookie,如果有需要手动添加的场景,直接添加即可。

3.13 插件

在真实企业压测场景中,我们通常为一点一点的逐步增加线程数,比如我们的期望最大并发为10000,但是我们不能一上来就测试10000,而是慢慢加,比如100->1000->3000->6000->8000->10000。

因此需要安装新的插件来支持线程数的配置,下载连接:JMeter插件

点击“plugins-manager.jar”就可以下载了。

将下载好的文件放到Jmeter下的lib文件夹下的ext文件夹

我们重新打开jmeter之后,就可以发现右上角多了一个小蝴蝶。

当我们点击之后

我们安装两个插件,监听器和线程组

1)监听器插件

2)线程组

点击右下角的Apply Changes and Restart JMeter就可以下载了,下载完成后会自动重启JMeter。

当添加完成后,可以看到线程选项中多了很多。

监听器中也多了。

3.13.1 Stepping Thread Group

创建后如下所示:

  • This group will start:启动多少个线程,同线程组中的线程数
  • First,wait for:等待多少秒才开始压测,一般默认为0
  • Then start:一开始有多少个线程数,一般默认为0
  • Next,add:下一次增加多少个线程数
  • threads every:当前运行多长时间后再次启动线程,即每一次线程启动完成之后的的持续时间; 
  • using ramp-up:启动线程的时间;若设置为5秒,表示每次启动线程都持续5秒
  • Then hold load for:线程全部启动完之后持续运行多长时间
  • finally,stop/threadsevery:多长时间释放多少个线程;若设置为5个和1秒,表示持续负载结束之后每1秒钟释放5个线程

启动方式:(重点与下面三个参数有关)

这三个选项表示:每隔30秒添加10个线程,这些线程要在5秒内准备完成。

结束方式:(重点与下面两个参数有关)

每隔1秒结束5个线程。

通过下面的图也可以看到,其中的横坐标表示秒数,纵坐标表示的线程数。

3.13.2 监听器

最常用的监听器如下图所示。

点击运行之后,折线图如下所示,他会动态的展示线程数与时间的关系图。

响应时间如下图所示:

吞吐量如下所示:

可以看到响应时间增大时吞吐量就会降低,即响应时间与吞吐量呈负相关。

4. 性能报告

在性能测试完毕之后,我们需要讲测试结果展示出来,JMeter可以帮助我们生成性能报告。

JMeter测试报告是⼀个全面且详细的文档,它提供了关于测试执行结果的详细信息,帮助用户全面评估系统的性能并进行性能优化。

生成性能测试报告的命令:

Jmeter -n -t 脚本文件 -l 日志⽂件 -e -o 目录

  • -n :无图形化运行(不打开JMeter
  • -t : 被运行的脚本
  • -l : 将运行信息写入日志文件,后缀为jtl的日志文件
  • -e :生成测试报告
  • -o :指定报告输出目录

注意:日志文件和目录可以不存在,若为已经存在的情况下需要保证内容为空,否则会出现错误!

例如:我们要将“第一个性能测试.jmx”生成性能测试报告,并将它放到rizhi目录下,命令如下:

生成完之后会发现rizhi目录下多了一个index.html文件。

双击运行:

5. 性能分析

通过三大指标来分析性能问题

4.1 响应时间

如果响应时间超过了要求,代表系统到了瓶颈

注意事项:分析在多少线程的情况下发生了超标

响应时间变化的原因:

  • 系统不稳定,有时快有时慢
  • 随着并发压力变大而慢慢变慢,响应时间变高

4.2 错误率(可靠性)

高并发场景下,系统是否能够正常处理业务

要求:99.99%可靠,99.9999%

错误率高的原因:

  • 接口请求错误
  • 服务器无法继续处理,达到了瓶颈(代码写的不好,内存泄漏、硬件资源等)
  • 后端系统限流(系统⾥配置了不能超过多少并发)、熔断、降级

什么是熔断、降级?

  • 熔断:防止系统因某个服务的故障而整体崩溃。当电商平台上用户支付时,收银台发现某个支付渠道,如微信支付失败率突增,超时严重,那么就可以临时把这个支付方式熔断掉。
  • 降级:主动关闭⼀些非核心功能,以确保核心功能的正常运行。某次腾讯视频挂了的时候,用户名称默认显示腾讯用户,这也是一种降级方式,用兜底名称做展示。

4.3 吞吐量

吞吐量越大,性能越好;吞吐量相对稳定或者变低,可能系统达到了性能瓶颈

吞吐量变化规律:

  • 波动很大:代表系统性能不稳定。
  • 慢慢变高,再趋于稳定:和并发量强相关。如果并发量小于吞吐量,慢慢增大并发量,吞吐量也会随之增加。
  • 慢慢变低,并发量也减少了:要么说明性能测试要结束了,并发减少;也可能是系统变的卡顿,从而导致响应时间变慢,导致单个线程发起的并发量变少。

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

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

相关文章

【C++算法】20.二分查找算法_x 的平方根

文章目录 题目链接:题目描述:解法C 算法代码:图解 题目链接: 69. x 的平方根 题目描述: 解法 暴力解法: 如果x17 从1,2,3,4,5......这些数里面找他们的平方…

拥抱 OpenTelemetry:阿里云 Java Agent 演进实践

作者:陈承 背景 在 2018 年的 2 月,ARMS Java Agent 的第一个版本正式发布,为用户提供无侵入的的可观测数据采集服务。6 年后的今天,随着软件技术的迅猛发展、业务场景的逐渐丰富、用户规模的快速增长,我们逐渐发现过…

【项目日记】仿mudou的高并发服务器 --- 实现HTTP服务器

对于生命,你不妨大胆一点, 因为我们始终要失去它。 --- 尼采 --- ✨✨✨项目地址在这里 ✨✨✨ ✨✨✨https://gitee.com/penggli_2_0/TcpServer✨✨✨ 仿mudou的高并发服务器 1 前言2 Util工具类3 HTTP协议3.1 HTTP请求3.2 HTTP应答 4 上下文解析模块…

从0在自己机器上部署AlphaFold 3

本文介绍如何在自己本地机器上安装AlphaFold 3。 在10月份,Google DeepMind的首席执行官Demis Hassabis和高级研究科学家John M. Jumper所领导的团队,利用AI技术成功预测了几乎所有已知蛋白质的结构,开发出备受赞誉的AlphaFold,并…

faiss库中ivf-sq(ScalarQuantizer,标量量化)代码解读-6

调试 经过gdb调试获取的调用栈内容如下&#xff0c;链接&#xff1a; 步骤函数名称文件位置说明1faiss::IndexFlatCodes::add/faiss/IndexFlatCodes.cpp:24在 add 方法中&#xff0c;检查是否已经训练完成&#xff0c;准备添加向量到索引中。2std::vector<unsigned char&g…

SQL进阶——子查询与视图

在SQL中&#xff0c;子查询和视图是两种强大的技术&#xff0c;用于处理复杂的查询、提高代码的重用性以及优化查询性能。子查询允许开发者在查询中嵌套其他查询&#xff0c;而视图则是对复杂查询的封装&#xff0c;可以简化开发工作并提高代码的可维护性。 本章将深入探讨如何…

【论文阅读】 Learning to Upsample by Learning to Sample

论文结构目录 一、之前的上采样器二、DySample概述三、不同上采样器比较四、整体架构五、设计过程&#xff08;1&#xff09;初步设计&#xff08;2&#xff09;第一次修改&#xff08;3&#xff09;第二次修改&#xff08;4&#xff09;第三次修改 六、DySample四种变体七、复…

Online Judge——【前端项目初始化】项目通用布局开发及初始化

目录 一、新建layouts二、更新App.vue文件三、选择一个布局&#xff08;Layout&#xff09;四、通用菜单Menu的实现菜单路由改为读取路由文件 五、绑定跳转事件六、同步路由到菜单项 一、新建layouts 这里新建一个专门存放布局的布局文件layouts&#xff1a; 然后在该文件夹&…

uniapp首页样式,实现菜单导航结构

实现菜单导航结构 1.导入字体图标库需要的文件 2.修改引用路径iconfont.css 3.导入到App.vue中 <style>import url(./static/font/iconfont.css); </style>导航区域代码 VUE代码 <template><view class"home"><!-- 导航区域 --><…

《代码随想录》刷题笔记——栈与队列篇【java实现】

文章目录 用栈实现队列用队列实现栈有效的括号我的解法代码随想录 删除字符串中的所有相邻重复项我的解法代码随想录栈解法字符串充当栈※双指针 逆波兰表达式求值我的解法代码随想录 滑动窗口最大值我的解法暴力解法暴力解法一点优化单调队列 代码随想录单调队列 前 K 个高频元…

STM32 ADC --- 知识点总结

STM32 ADC — 知识点总结 文章目录 STM32 ADC --- 知识点总结cubeMX中配置注解单次转换模式、连续转换模式、扫描模式单通道采样的情况单次转换模式&#xff1a;连续转换模式&#xff1a; 多通道采样的情况禁止扫描模式&#xff08;单次转换模式或连续转换模式&#xff09;单次…

UaGateway:实现OPC DA和OPC UA的高效转换

随着工业4.0和智能制造的深入推进&#xff0c;工业自动化系统之间的互联互通需求日益迫切。UaGateway作为一种高效的协议转换工具&#xff0c;正在成为各类工业应用中不可或缺的桥梁。本文将重点介绍UaGateway在实现OPC DA到OPC UA转换方面的主要功能、应用场景和实际案例。 Ua…

安能物流 All in TiDB 背后的故事与成果

导读 在数字化转型的浪潮中&#xff0c;安能物流通过技术创新不断提升物流效率&#xff0c;迈出了全链路 All in TiDB 的重要一步。本文将深入探讨安能物流如何选择 TiDB 作为核心数据库&#xff0c;以应对高并发、数据处理能力和系统可扩展性等挑战。通过 TiDB 的弹性扩展能力…

回声消除延时估计的一些方法

在音频信号处理&#xff0c;尤其是在回声消除和语音通信中&#xff0c;延时估计是一个至关重要的任务。回声消除技术旨在减少或消除在语音通信中由于信号反射而产生的回声。为了有效地实现这一点&#xff0c;系统需要准确估计发送信号和接收信号之间的延迟。通过了解延迟&#…

从简单的自动化脚本到复杂的智能助手:Agent技术的实践与应用

现代软件开发中&#xff0c;Agent技术正在悄然改变着我们构建应用程序的方式。一个Agent就像是一个能独立完成特定任务的智能助手&#xff0c;它可以感知环境、作出决策并采取行动。让我们通过实际案例&#xff0c;深入了解如何运用Agent技术来构建智能系统。 想象你正在开发一…

postman使用正则表达式提取数据实战篇!

之前篇章中postman多接口关联使用的是通过JSON提取器的方式进行提取。 除了JSON提取器提取数据外还可通过另一种方式——正则表达式来提取数据。 1、使用正则表达式提取器实现接口关联&#xff0c;match匹配 正则匹配表达式将需要提取的字段key:value都放入表达式中&#xff…

Flume 与 Kafka 整合实战

目录 一、Kafka 作为 Source【数据进入到kafka中&#xff0c;抽取出来】 &#xff08;一&#xff09;环境准备与配置文件创建 &#xff08;二&#xff09;创建主题 &#xff08;三&#xff09;测试步骤 二、Kafka 作为 Sink数据从别的地方抽取到kafka里面】 &#xff08;…

存储服务器一般做是做什么阵列?详细列举一下

存储服务器通常使用 RAID&#xff08;Redundant Array of Independent Disks&#xff09; 阵列技术来管理磁盘&#xff0c;以提高数据的性能、可靠性和可用性。所选择的 RAID 类型取决于存储服务器的具体用途和需求&#xff0c;比如性能要求、容量需求、容错能力等。 以下是存…

无人机的起降装置:探索起飞和降落的秘密 !

一、起降系统的运行方式 起飞方式 垂直起飞&#xff1a;小型无人机通常采用垂直起飞方式&#xff0c;利用螺旋桨产生的升力直接从地面升起。这种方式适用于空间有限或需要快速起飞的场景。 跑道起飞&#xff1a;大型无人机或需要较长起飞距离的无人机&#xff0c;可能会采用…

代码随想录day01--数组

两数之和 题目 地址&#xff1a;https://leetcode.cn/problems/two-sum/ 给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为目标值的那 两个 整数&#xff0c;并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数…