基于Python的Locust 性能测试指北(万字长文详解)

目录

Locust

我们为什么选择locust

Locust的核心部件

Locust内部运行调用链路

locust 实践

检查点(断言)

权重比例

参数化

Tag

集合点

分布式

docker 运行locust

高性能 FastHttpUser

测试gRPC等其他协议

其他

 资料获取方法


Locust

Locust 是比较常见的性能测试工具,底层基于 gevent。官方介绍 它是一款易于使用、可编写脚本且可扩展的性能测试工具,可以让我们使用常规 Python 代码定义用户的行为,而不必陷入 UI 或限制性领域特定语言中.

Locust具有无限的可扩展性(只要提供客户端python 代码,适用于所有协议的性能测试).

本文为开发性能自动化对比平台时学习相关内容的记录整理。

我们为什么选择locust

特点说明
开源免费Locust是一个开源项目,无需支付费用,可以自由使用和定制。
易于学习使用使用Python编写,学习路线平缓,拥有丰富的库和社区支持。
可扩展性灵活性高可以根据需要定制测试,以便更准确地评估应用程序的性能。第三方插件较多、 易于扩展。
实时统计提供实时统计功能和Web界面,方便监控和分析测试结果。
易于集成可以轻松地与持续集成和持续部署工具集成,自动运行性能测试。
适用大规模的性能测试支持分布式,可以轻松地在多台机器上运行测试,以模拟大量用户。这使得它非常适合进行大规模的性能测试。

Locust的核心部件

Master节点

负责协调和管理整个测试过程,包括启动和停止测试、分发任务、收集和汇总测试结果等。

Worker节点

实际执行测试任务的节点,根据Master节点分配的任务进行模拟用户行为。

Web UI

提供可视化的测试界面,方便用户查看测试结果、监控测试进度等。

测试脚本(Load Test Script)

测试脚本,定义模拟用户行为的逻辑和参数,由Worker节点执行。

Locust内部运行调用链路

时序图如下:

点击查看时序图说明

RunnerEventHookEnvironmentUserTaskSetstart()1fire()2create Environment and add user classes3start users and run tasks4run()5send requests and record statistics6wait for other users to finish7return8stop users and tasks9stop()10fire()11RunnerEventHookEnvironmentUserTaskSet

注:fire() 方法是 Locust 中的 EventHook 类中的一个方法,用于触发事件。在 Locust 的测试生命周期中,有多个事件可以被触发,例如测试开始、测试结束、用户启动、用户完成任务等。当这些事件发生时,EventHook 类会调用 fire() 方法,将事件传递给所有注册了该事件的回调函数。

locust 实践

locust安装

步骤说明
点击跳转安装 Python3.7+新版本标注需要Python3.7 or later
pip install locust安装 locust
执行locust检查是否安装成功
$ locust -V
locust 2.15.1 from /Users/bingohe/Hebinz/venvnew/lib/python3.9/site-packages/locust (python 3.9.17)

入门示例

使用 locust 编写用例时,约定大于配置:

test_xxx (一般测试框架约定)
dockerfile (docker约定)
locustfile.py (locust约定)

# locustfile.py
from locust import HttpUser, taskclass HelloWorldUser(HttpUser): # 父类是个User,表示要生成进行负载测试的系统的 HTTP“用户”。每个user相当于一个协程链接 ,进行相关系统交互操作@task  # 装饰器来标记为一个测试任务, 表示用户要进行的操作:访问首页 → 登录 → 增、删改查def hello_world(self):wait_time = between(1, 5)# self.client发送 HTTP 请求,模拟用户的操作self.client.get("/helloworld")

启动测试

GUI 模式启动 locust

在有locustfile.py文件的目录直接执行locust命令,然后访问:http://0.0.0.0:8089/ 即可看到下面的界面:

$ locust   
[2023-07-06 16:15:16,868] MacBook-Pro.local/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
[2023-07-06 16:15:16,876] MacBook-Pro.local/INFO/locust.main: Starting Locust 2.15.1

image

指标详解:

  • Number of users 模拟用户数,默认 1
  • Spawn rate : 生产数 (每秒)、 =>jmeter : Ramp-Up Period (in seconds), 默认 1
  • Host (e.g. http://www.example.com) => 测试目标 svr 的 绝对地址

填写 host点击 start 之后就会对被测服务如http://{host}/helloworld 发起请求。请求统计数据如下:

image

WebUI Tab说明:

Tab名称功能描述
New test点击该按钮可对模拟的总虚拟用户数和每秒启动的虚拟用户数进行编辑
Statistics类似于 JMeter 中 Listen 的聚合报告
Charts测试结果变化趋势的曲线展示图,包括每秒完成的请求数(RPS)、响应时间、不同时间的虚拟用户数
Failures失败请求的展示界面
Exceptions异常请求的展示界面
Download Data测试数据下载模块,提供三种类型的 CSV 格式的下载,分别是:Statistics、responsetime、exceptions

需要说明的是webui 模式有很多限制,主要用于调试,下面将要介绍的命令行模式更为常用。

命令行模式启动 locust
locust -f locustfile.py --headless -u 500 -r 10  --host http://www.example.com  -t 1000s

​ 框架是通过命令locust运行的,常用参数有:

参数含义
-f 或 --locustfile指定测试脚本文件的路径
--headless以非 GUI 模式运行测试
-u 或 --users指定并发用户数
-r 或 --spawn-rate指定用户生成速率(即每秒生成的用户数)
-t 或 --run-time指定测试运行的最大时间 (单位:秒),与--no-web一起使用
--csv将测试结果输出到 CSV 文件中
--html将测试结果输出为 HTML 报告
--host或者 -H指定被测服务的地址
-L日志级别,默认为INFO

检查点(断言)

Locust默认情况下会根据HTTP状态码来判断请求是否成功。对于HTTP状态码范围在200-399之间的响应,Locust会将其视为成功。对于HTTP状态码在400-599之间的响应,Locust会将其视为失败。

如果需要根据响应内容或其他条件来判断请求是否成功,需要手动设置检查点:

  • 使用self.client提供的catch_response=True`参数, 添加locust提供的ResponseContextManager类的上下文方法手动设置检查点。
  • ResponseContextManager里面的有两个方法来声明成功和失败,分别是successfailure。其中failure方法需要我们传入一个参数,内容就是失败的原因。
from locust import HttpUser, task, betweenclass MyUser(HttpUser):# 思考时间:模拟真实用户在浏览应用程序时的行为wait_time = between(1, 5)@taskdef my_task(self):# 基于Locust提供的ResponseContextManager上下文管理器,使用catch_response=True 参数来捕获响应,手动标记成功或失败,with self.client.get("/some_page", catch_response=True) as response:# 检查状态码是否为200且响应中包含 "some_text"if response.status_code == 200 and "some_text" in response.text:# 如果满足条件,标记响应为成功response.success()else:# 如果条件不满足,根据具体情况生成错误信息error_message = "Unexpected status code: " + str(response.status_code) if response.status_code != 200 else "Expected text not found in the response"# 标记响应为失败,并报告错误信息response.failure(error_message)

权重比例

如果需要请求有不同的比例,在Locust中,可以通过在@task装饰器中设置weight参数为任务分配权重来实现。权重越高,任务被执行的频率就越高。

from locust import HttpUser, task, betweenclass MyUser(HttpUser):wait_time = between(1, 5)# 设置权重为3,这个任务将被执行的频率更高@task(3)def high_frequency_task(self):self.client.get("/high_frequency_page")# 设置权重为1,这个任务将被执行的频率较低@task(1)def low_frequency_task(self):self.client.get("/low_frequency_page")

在这个示例中,我们为high_frequency_task任务设置了权重为3,而为low_frequency_task任务设置了权重为1。这意味着在模拟用户执行任务时,high_frequency_task任务被执行的频率将是low_frequency_task任务的3倍。通过设置权重,我们可以根据实际需求调整不同任务在性能测试中的执行频率。

点击查看在Locust内部权重的实现原理

参数化

在现实世界中,用户的行为通常是多样化的。他们可能使用不同的设备、操作系统、网络条件等。为了更好地模拟这些场景,我们需要在测试中使用不同的参数。

在性能测试中,参数化是一种非常重要的技术手段。它允许我们使用不同的数据集运行相同的测试场景,从而更好地模拟真实世界的用户行为。常用的参数化方法有两种。

使用 Locust 的内置参数化功能

from locust import HttpUser, task, between
from locust.randoms import random_string, random_numberclass MyUser(HttpUser):wait_time = between(1, 5)@taskdef random_data(self):random_str = random_string(10)random_num = random_number(0, 100)self.client.post("/random", json={"text": random_str, "number": random_num})

从外部文件读取参数

以已经配置成白名单的鉴权 session 为例:

import csv
from locust import HttpUser, taskclass CSVReader:def __init__(self, file, **kwargs):try:file = open(file)except TypeError:passself.file = fileself.reader = csv.reader(file, **kwargs)  # iteratordef __next__(self):try:return next(self.reader)except StopIteration:# 如果没有下一行,则从头开始读self.file.seek(0, 0)return next(self.reader)session = CSVReader("session.csv")class MyUser(HttpUser):@taskdef index(self):customer = next(ssn_reader)self.client.get(f"/pay?session={customer[0]}")

Tag

Locust中,标签(Tag)是用于对任务进行分类和筛选的一种方法。通过给任务添加标签,可以在运行Locust时只执行具有特定标签的任务。这在执行特定场景的性能测试或组织大量任务时非常有用。

使用场景

有时候我们会在同一个文件中写多个测试场景,但是运行的时候只想运行其中一部分,即当一个测试文件中的task不止一个时,我们可以通过@tag给task打标签进行分类,在执行测试时,通过--tags name执行指定带标签的task。

以下是一个使用标签的示例:

from locust import HttpUser, task, between, tagclass MyUser(HttpUser):wait_time = between(1, 5)# 给任务添加一个名为 "login" 的标签@tag("login")@taskdef login_task(self):self.client.post("/login", json={"username": "user", "password": "pass"})# 给任务添加一个名为 "profile" 的标签@tag("profile")@taskdef profile_task(self):self.client.get("/profile")# 给任务添加两个标签:"shopping" 和 "checkout"@tag("shopping", "checkout")@taskdef checkout_task(self):self.client.post("/checkout")

在这个示例中,我们为三个任务分别添加了不同的标签。login_task任务具有"login"标签,profile_task任务具有"profile"标签,而checkout_task任务具有"shopping""checkout"两个标签。

运行Locust时,可以通过使用--tags--exclude-tags选项来指定要执行或排除的标签。例如,要仅执行具有"login"标签的任务,可以运行:

locust --tags login

要排除具有"shopping"标签的任务,可以运行:

locust --exclude-tags shopping

这样,我们就可以根据需要执行特定场景的性能测试,而不需要修改代码。

点击查看如何在Locust属性中指定 tag

集合点

什么是集合点?

集合点用以同步虚拟用户,以便恰好在同一时刻执行任务。在[测试计划]中,可能会要求系统能够承受1000 人同时提交数据,可以通过在提交数据操作前面加入集合点,这样当虚拟用户运行到提交数据的集合点时,就检查同时有多少用户运行到集合点,如果不到1000 人,已经到集合点的用户在此等待,当在集合点等待的用户达到1000 人时,1000 人同时去提交数据,从而达到测试计划中的需求。

注意:Locust框架本身没有直接封装集合点的概念 ,需要间接通过gevent并发机制,使用gevent的锁来实现。

在 Locust 中 实现集合点前,我们先了解两个概念:

  • gevent 中的 Semaphore 信号量
  • locust 中的事件钩子 all_locusts_spawned
Semaphore

信号量(Semaphore)是一种用于控制对共享资源访问的同步原语。它是计算机科学和并发编程中的一个重要概念,最早由著名计算机科学家Edsger Dijkstra于1960s提出。信号量用于解决多线程或多进程环境中的临界区问题,以防止对共享资源的竞争访问。

点击查看`Semaphore`实现原理

all_locusts_spawned 事件

在 Locust 中,事件是一个非常重要的概念。事件允许我们在 Locust 的生命周期中的特定时刻执行自定义的操作。通过监听和处理这些事件,我们可以扩展 Locust 的功能,以满足测试需求。

spawning_complete 是 Locust 中的一个事件,表示所有的 Locust 用户(user)已经生成完成。当 Locust 开始运行测试并生成用户时,它会逐渐创建用户实例。一旦所有的用户都被创建,spawning_complete 事件就会被触发。你可以在这个事件中执行一些特定的操作,例如输出日志消息、收集统计信息或执行其他自定义操作。

要监听 spawning_complete 事件,你可以使用 locust.events.spawning_complete 事件钩子。例如:

from locust import events@events.spawning_complete.add_listener
def on_spawning_complete():print("All users have been spawned!")

在这个示例中,当所有的用户生成完成时,我们会输出一条消息 "All users have been spawned!"。你可以根据需要替换为其他操作。

点击查看 `Locust` 生命周期中其他的事件

了解完上面两个概念,接下来我们只需要两步走:

  • 在脚本启动时,使用all_locust_spawned.acquire() 阻塞进程
  • 编写一个函数,在 用户全部创建完成时触发 all_locust_spawned.release()

示例代码:

from locust import HttpUser, task, between
from gevent.lock import Semaphore
from locust import eventsall_locust_spawned = Semaphore()
all_locust_spawned.acquire()  # 阻塞class MyUser(HttpUser):wait_time = between(1, 1)def on_start(self):global all_locust_spawnedall_locust_spawned.wait(3)  # 同步锁等待时间@taskdef task_rendezvous(self):self.client.get("/rendezvous")# 添加集合点事件处理器
@events.spawning_complete.add_listener  # 所有的Locust实例产生完成时触发
def on_spawning_complete(**_kwargs):global all_locust_spawnedall_locust_spawned.release()

分布式

当我们需要大量的并发用户,而单个计算机可能无法生成足够的负载来模拟这种情况时,分布式压力测试可以解决这个问题,我们可以通过将压力测试分布到多个计算机上来生成更大的负载,并更准确地评估系统的性能。

Locust 的限制

Locust 使用 Python 的 asyncio 库来实现异步 I/O,这意味着它可以充分利用多核 CPU 的性能。然而,由于 Python 的全局解释器锁(GIL)限制,单个 Python 进程无法充分利用多核 CPU。

为了解决这个问题,Locust 支持在单个计算机上运行多个从节点(worker node),这样可以充分利用多核 CPU 的性能。

当在单台计算机上运行多个从节点时,每个从节点将运行在一个单独的进程中,从而避免了 GIL 的限制。这样,我们可以充分利用多核 CPU 的性能,生成更大的负载。

单机主从模式

注意: slave 的节点数要小于等于本机的处理器数

在单机主从模式下,主节点和从节点都运行在同一台计算机上。这种模式适用于在本地开发环境中进行压力测试,或者在具有多核 CPU 的单台服务器上进行压力测试。以下是在单机主从模式下实现分布式压力测试的步骤:

  1. 安装 Locust:在计算机上安装 Locust,使用 pip install locust 命令进行安装。

  2. 编写 Locust 测试脚本:编写一个 Locust 测试脚本,这个脚本将在主节点和从节点上运行。将此脚本保存为 locustfile.py

  3. 启动主节点:在计算机上运行 locust --master 命令启动主节点,监听默认端口(8089)。

  4. 启动从节点:在计算机上运行 locust --worker --master-host 127.0.0.1 命令启动一个从节点。根据需要,可以启动多个从节点。

  5. 运行分布式压力测试:访问 Locust 的 Web 界面(http://127.0.0.1:8089),开始测试。

单机模式下,如何让每个从节点都运行在不同的 CPU 上

点击查看如何单机模式下,每个从节点都运行在不同的 CPU 上

多机主从模式

操作与单机模式基本一样,访问 Locust 的 Web 界面时访问的时主节点的地址(http://MASTER_IP_ADDRESS:8089)。

因为主节点和从节点之间通过网络通信。因此,在选择主节点和从节点的计算机时,需要确保它们之间的网络连接畅通。此外,为了获得准确的测试结果,务必确保主节点和从节点之间的网络延迟较低。

分布式模式下的命令参数

命令参数说明
--master将当前 Locust 实例作为主节点(master node)运行。
--worker将当前 Locust 实例作为从节点(worker node)运行。
--master-host指定主节点的 IP 地址或主机名。默认值为 127.0.0.1
--master-port指定主节点的端口号。默认值为 5557
--master-bind-host指定主节点绑定的 IP 地址或主机名。默认值为 *(所有接口)。
--master-bind-port指定主节点绑定的端口号。默认值为 5557
--expect-workers指定主节点期望连接的从节点数量。默认值为 1

--expect-workers 参数用于指定主节点期望连接的从节点数量。如果实际连接的从节点数量没有达到这个值,主节点会继续等待,直到足够的从节点连接上来。

在实际运行分布式压力测试时,主节点会在 Web 界面上显示连接的从节点数量。如果实际连接的从节点数量没有达到 --expect-workers 指定的值,你可以在 Web 界面上看到一个警告消息,提示你主节点正在等待更多从节点的连接。

docker 运行locust

使用 容器的方式运行 locust 的优势和缺点都非常明显:

优势描述
环境一致性Docker 可以确保在不同计算机上运行的 Locust 环境是一致的。
便于部署使用 Docker 可以简化 Locust 的部署过程。
易于扩展Docker 可以与容器编排工具结合使用,实现 Locust 从节点的自动扩展。
隔离性Docker 容器提供了一定程度的隔离性,将 Locust 运行环境与宿主机系统隔离。
缺点描述
性能开销Docker 容器可能存在一定程度的性能损失,与在宿主机上直接运行 Locust 相比。
学习曲线对于不熟悉 Docker 的用户,可能需要一定时间学习 Docker 的基本概念和使用方法。
系统资源占用运行 Docker 容器需要消耗一定的系统资源(如 CPU、内存、磁盘空间等)。

但是以下这些场景使用 Docker 来运行 Locust 是一个更好的选择:

  1. 分布式压力测试:在分布式压力测试中,需要在多台计算机上运行 Locust 主节点和从节点。使用 Docker 可以确保所有节点的运行环境一致,简化部署过程。

  2. 云环境部署:如果你需要在云环境(如 AWS、Azure、GCP 等)中进行压力测试,使用 Docker 可以简化部署过程,并充分利用云平台提供的容器服务(如 Amazon ECS、Google Kubernetes Engine 等)。

  3. CI/CD 集成:如果你需要将压力测试集成到持续集成/持续部署(CI/CD)流程中,使用 Docker 可以简化集成过程。许多 CI/CD 工具(如 Jenkins、GitLab CI、Travis CI 等)都支持 Docker 集成。

  4. 避免环境冲突:如果你的开发或测试环境中已经安装了其他 Python 应用程序,可能会出现依赖项冲突。使用 Docker 可以将 Locust 运行环境与宿主机系统隔离,避免潜在的环境冲突。

  5. 团队协作:在团队协作过程中,使用 Docker 可以确保每个团队成员都使用相同的 Locust 运行环境,从而避免因环境差异导致的问题。

具体使用步骤

  1. 首先,确保你已经安装了 Docker。如果尚未安装,请参考 Docker 官方文档 以获取适用于你的操作系统的安装说明。

  2. 编写一个 Locust 测试脚本。例如,创建一个名为 locustfile.py 的文件,内容如下:

from locust import HttpUser, task, betweenclass MyUser(HttpUser):wait_time = between(1, 5)@taskdef my_task(self):self.client.get("/")
  1. 使用以下命令从 Docker Hub 拉取官方的 Locust 镜像:
docker pull locustio/locust
  1. 使用以下命令在 Docker 中运行 Locust。
docker run --rm -p 8089:8089 -v $PWD:/mnt/locust locustio/locust -f /mnt/locust/locustfile.py --host TARGET_HOST

在这个命令中,我们将当前目录(包含 locustfile.py 文件)挂载到 Docker 容器的 /mnt/locust 目录。然后,我们使用 -f 参数指定要运行的 Locust 测试脚本,并使用 --host 参数指定目标主机地址。

  1. 访问 Locust 的 Web 界面。在浏览器中打开 http://localhost:8089,你将看到 Locust 的 Web 界面。在这里,你可以开始压力测试并查看结果。

通过以上步骤,你可以在 Docker 中运行 Locust,无需在本地环境中安装 Locust。

总之,在需要确保环境一致性、简化部署过程、集成到 CI/CD 流程、避免环境冲突或团队协作的场景下,使用 Docker 来运行 Locust 是一个很好的选择。通过使用 Docker,你可以轻松地在不同的计算机或云环境中运行压力测试,从而实现更大规模的分布式压力测试。

高性能 FastHttpUser

Locust 的默认 HTTP 客户端使用http.client。如果计划以非常高的吞吐量运行测试并且运行 Locust 的硬件有限,那么它有时效率不够。

FastHttpUser 是 Locust 提供的一个特殊的用户类,用于执行 HTTP 请求。与默认的 HttpUser 不同,FastHttpUser 使用 C 语言库 gatling 编写的 httpclient 进行 HTTP 请求, 有时将给定硬件上每秒的最大请求数增加了 5 到 6 倍。在相同的并发条件下使用FastHttpUser能有效减少对负载机的资源消耗从而达到更大的http请求。

优势

  1. 性能FastHttpUser 的主要优势是性能。由于它使用 C 语言库进行 HTTP 请求,它的性能通常比默认的 HttpUser 更高。这意味着在相同的硬件资源下,你可以使用 FastHttpUser 生成更大的负载。

  2. 资源占用:与默认的 HttpUser 相比,FastHttpUser 通常具有较低的资源占用(如 CPU、内存等)。这意味着在进行压力测试时,你可以在同一台计算机上运行更多的并发用户。

  3. 更高的并发能力:由于 FastHttpUser 的性能和资源占用优势,它可以更好地支持大量并发用户的压力测试。这对于需要模拟大量并发用户的场景(如高流量 Web 应用程序、API 等)非常有用。

然而需要注意的是FastHttpUser 也有一些局限性。例如,它可能不支持某些特定的 HTTP 功能(如自定义 SSL 证书、代理设置等)。在选择使用 FastHttpUser 时,需要权衡性能优势和功能支持。如果测试场景不需要大量并发用户,或者需要特定的 HTTP 功能,使用默认的 HttpUser 可能更合适。

以下是一个使用 FastHttpUser 的 Locust 测试脚本示例:

from locust import FastHttpUser, task, betweenclass MyFastHttpUser(FastHttpUser):wait_time = between(1, 5)@taskdef my_task(self):self.client.get("/")

测试gRPC等其他协议

locust 并非 http 接口测试工具 , 只是内置了 “HttpUser” 示例 ,理论上来说,只要提供客户端,它可以测试任何协议。

其他

主流性能测试工具对比

下面是 Locust、JMeter、Wrk 和 LoadRunner 四款性能测试工具的优缺点和支持的功能的对比表格:

工具名称优点缺点支持的功能
Locust- 简单易用,支持 Python 语言
- 可以在代码中编写测试场景,灵活性高
- 可以使用分布式部署,支持大规模测试
- 支持 Web 和 WebSocket 测试
- 功能相对较少,不支持 GUI
- 对于非 Python 开发人员不太友好
- 在大规模测试时需要手动管理分布式节点
- HTTP(S)、WebSocket 测试
- 支持断言、参数化、数据驱动等功能
- 支持分布式测试
JMeter- 功能丰富,支持多种协议
- 支持 GUI,易于使用
- 支持分布式部署,支持大规模测试
- 支持插件扩展,可以扩展功能
- 性能较差,不适合高并发测试
- 内存占用较高,需要较大的内存
- 学习曲线较陡峭
- HTTP(S)、FTP、JDBC、JMS、LDAP、SMTP、TCP、UDP 等多种协议的测试
- 支持断言、参数化、数据驱动等功能
- 支持分布式测试
Wrk- 性能优异,支持高并发测试
- 支持 Lua 脚本编写,灵活性高
- 支持多种输出格式,方便结果分析
- 功能相对较少,不支持 GUI
- 只支持 HTTP 协议测试
- 学习曲线较陡峭
- HTTP(S) 测试
- 支持断言、参数化、数据驱动等功能
LoadRunner- 功能丰富,支持多种协议
- 支持 GUI,易于使用
- 支持分布式部署,支持大规模测试
- 支持插件扩展,可以扩展功能
- 价格较高,不适合小型团队使用
- 学习曲线较陡峭
- 对于非 Windows 平台的支持不够友好
- HTTP(S)、FTP、JDBC、JMS、LDAP、SMTP、TCP、UDP 等多种协议的测试
- 支持断言、参数化、数据驱动等功能
- 支持分布式测试

需要注意的是,这些工具的优缺点和支持的功能只是相对而言的,具体使用时需要根据实际需求和场景选择。


 资料获取方法

【留言777】

各位想获取源码等教程资料的朋友请点赞 + 评论 + 收藏,三连!

三连之后我会在评论区挨个私信发给你们~

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

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

相关文章

Squeeze-and-Excitation Networks阅读笔记一

文章目录 Abstract1 INTRODUCTION Abstract 卷积算子(convolution operator)是卷积神经网络(cnn)的核心组成部分,它使网络能够通过融合每层局部接受域内的空间和通道信息来构建信息特征。广泛的先前研究已经调查了这种…

Crescent QuickPak Crack

Crescent QuickPak Crack Crescent QuickPak是一个32位ActiveX组件的综合集合,用于使用Visual Basic开发应用程序,这将减少开发时间并提高生产力。Crescent QuickPak包含Internet功能,用于打开、读取和解析IIS日志文件,将日志文件…

K8s operator从0到1实战

Operator基础知识 Kubernetes Operator是一种用于管理和扩展Kubernetes应用程序的模式和工具。它们是一种自定义的Kubernetes控制器,可以根据特定的应用程序需求和业务逻辑扩展Kubernetes功能。 Kubernetes Operator基于Kubernetes的控制器模式,通过自…

Stephen Wolfram:嵌入的概念

The Concept of Embeddings 嵌入的概念 Neural nets—at least as they’re currently set up—are fundamentally based on numbers. So if we’re going to to use them to work on something like text we’ll need a way to represent our text with numbers. And certain…

FPGA优质开源项目 – PCIE通信

本文介绍一个FPGA开源项目:PCIE通信。该工程围绕Vivado软件中提供的PCIE通信IP核XDMA IP建立。Xilinx提供了XDMA的开源驱动程序,可在Windows系统或者Linux系统下使用,因此采用XDMA IP进行PCIE通信是比较简单直接的。 本文主要介绍一下XDMA I…

复习之selinux的管理

一、什么是selinux? SELinux,Security Enhanced Linux 的缩写,也就是安全强化的 Linux,是由美国国家安全局(NSA)联合其他安全机构(比如 SCC 公司)共同开发的,旨在增强传统 Linux 操…

针对java程序员的了解细节操作系统与进程

一、💛 操作系统(浅浅概念):是用来搞管理软件的 1.对下,要管理各种硬件设备 2.对上,要给应用程序提供一个稳定的运行环境 二、💙 进程:正在运行的程序,假如程序没有运行就不叫程序,…

质检工具(FindBugs、CheckStyle、Junit、Jmeter、Apifox)

1、Findbugs IDEA软件中可以装该插件,2018版本以前主要搜索FindBugs-IDEA 、2018版本以后主要搜索 SpotBugs。 1.1、FindBugs-IDEA安装及使用流程: 1.2、SpotBugs安装及使用流程: 2、Checkstyle IDEA软件中可以装该插件,所有版本的插件一致:CheckStyle 2.1、安装流程…

-bash: ./startup.sh: Permission denied解决

今天在Linux上启动Tomcat,结果弹出:-bash: ./startup.sh: Permission denied 的提示。 这是因为用户没有权限,而导致无法执行。用命令chmod 修改一下bin目录下的.sh权限就可以了。 在Tomcat的bin目录下 ,输入命令行 :c…

通过C语言设计的推箱子(控制台终端)

一、项目介绍 推箱子游戏是一款经典的益智小游戏,玩家需要控制主角角色将几个木箱按照要求推到指定位置。在控制台终端中,可以使用字符来表示不同的游戏元素,例如 ‘#’ 表示墙壁, ’ ’ 表示空地, ‘$’ 表示木箱&am…

14-4_Qt 5.9 C++开发指南_QUdpSocket实现 UDP 通信_UDP组播

文章目录 1. UDP组播的特性2. UDP 组播实例程序的功能3. 组播功能的程序实现4. 源码4.1 可视化UI设计4.2 mainwindow.h4.3 mainwindow.cpp 1. UDP组播的特性 下图简单表示了组播的原理。UDP 组播是主机之间“一对一组”的通信模式,当多个客户端加入由一个组播地址定…

FPGA优质开源项目 - UDP RGMII千兆以太网

本文介绍一个FPGA开源项目:UDP RGMII千兆以太网通信。该项目在我之前的工作中主要是用于FPGA和电脑端之间进行图像数据传输。本文简要介绍一下该项目的千兆以太网通信方案、以太网IP核的使用以及Vivado工程源代码结构。 Vivado 的 Tri Mode Ethernet MAC IP核需要付…

接口自动化测试Mock Get和Post请求

Mock可以模拟一个http接口的后台响应,可以模拟request,response 下载 moco-runner-0.11.0-standalone.jar 下载链接: https://pan.baidu.com/s/1bmFzvJPRnDlQ-cmuJ_3iRg 提取码: kpjv 确保安装了jdk,cmd下可以运行java -version 一、模拟不带参的get请求…

数据结构:双向链表的实现(C实现)

个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》 文章目录 前言 一、实现思路1.节点的结构(ListNode)2.新节点的创建(BuyListNode)3.头结点的创建(ListCreate)4.双向链表的销毁(ListDestroy)5.双向链表的打印(ListPrint)6.双向链表的尾插(ListPu…

6.5.tensorRT高级(1)-alphapose模型导出、编译到推理(无封装)

目录 前言1. alphapose导出2. alphapose推理3. 讨论总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。 本次课程学习 tensorRT 高级-alphap…

ROS添加节点

1 下载项目源码 (1)这里我使用是哔哩哔哩的博主源码机器人工匠王杰 https://github.com/6-robot/wpr_simulation.git (2)建立工作空间 在主目录下载建立如下文件夹 catkin_ws----       ----src (3)…

MySQL — InnoDB介绍

文章目录 InnoDB 主要特点InnoDB 架构In-Memory StructuresBuffer PoolChange BufferAdaptive Hash IndexLog Buffer On-Disk StructuresSystem TablespaceFile-Per-Table TablespacesGeneral TablespacesUndo TablespacesTemporary TablespacesDoublewrite BufferRedo LogUndo…

【Datawhale AI 夏令营第二期】AI 量化模型预测挑战赛

文章目录 赛题分析赛题背景赛事任务赛题数据集评价指标 Baseline实践导入模块EDA特征工程模型训练与验证结果输出 改进 赛题分析 赛题背景 量化金融在国外已经有数十年的历程,而在国内兴起还不到十年。这是一个极具挑战的领域。量化金融结合了数理统计、金融理论、…

【雕爷学编程】MicroPython动手做(29)——物联网之SIoT 2

知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…

[PyTorch][chapter 46][LSTM -1]

前言: 长短期记忆网络(LSTM,Long Short-Term Memory)是一种时间循环神经网络,是为了解决一般的RNN(循环神经网络)存在的长期依赖问题而专门设计出来的。 目录: 背景简介 LSTM C…