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

性能工具之 MySQL OLTP Sysbench BenchMark 测试示例

文章目录

  • 一、前言
  • 二、测试环境
    • 1、服务器配置
    • 2、测试拓扑
  • 三、测试工具安装
  • 四、测试步骤
    • 1、导入数据
    • 2、压测数据
    • 3、清理数据
  • 五、结果解析
  • 六、最后

一、前言

做为一名性能工程师掌握对 MySQL 的性能测试是非常必要的,本文基于 Sysbench 对MySQL OLTP(联机事务处理) 的 BenchMark 测试案例详细介绍具体方法。

二、测试环境

1、服务器配置

数据库服务器:

  • 操作系统:CentOS 7.6 64位
  • CPU:8核
  • 内存:16GB
  • 磁盘:500GB,最大吞吐量150 MB/s
  • 数据库版本:MySQL Community Server 8.0.37
  • 网络:局域网

测试服务器:

  • 操作系统:CentOS 7.6 64位
  • CPU:8核
  • 内存:16GB
  • 磁盘:500GB,最大吞吐量150 MB/s
  • 测试软件:sysbench-1.0.12
  • 网络:局域网

2、测试拓扑

在这里插入图片描述
📢注意:

  • 尽量不要在 MySQL 本服务器上进行测试,一方面可能无法体现网络(哪怕是局域网)的影响,另一方面,sysbench 的运行(并发数较高时)会影响挤压 MySQL 服务器性能。
  • 在开始 MySQL 测试之前,应针对数据库服务器做好 BenchMark 测试。

三、测试工具安装

Sysbench是一款基于LuaJIT的,模块化多线程基准测试工具,常用于数据库基准测试。通过内置的数据库测试模型,采用多线程并发操作来评估数据库的性能。了解Sysbench更多详情,请访问:https://github.com/akopytov/sysbench。

本次测试使用的Sysbench版本为1.0.12,具体的安装命令如下:

# wget -c https://github.com/akopytov/sysbench/archive/1.0.12.zip
# yum install autoconf libtool mysql mysql-devel vim unzip
# unzip 1.0.12.zip
# cd sysbench-1.0.12
# ./autogen.sh
# ./configure
# make
# make install
#sysbench --version

显示以下内容说明已安装成功。
在这里插入图片描述

四、测试步骤

请根据实际信息,替换数据库、连接IP与用户密码。

1、导入数据

(1)使用 MySQL 命令或第三方工具登录数据库,并创建测试数据库 “loadtest” 。

mysql -u root -P 3306 -h -p -e "create database loadtest"

(2)使用 sysbench 命令导入测试背景数据到 “loadtest” 数据库。

sysbench
--test=/usr/local/share/sysbench/tests/include/oltp_legacy/oltp.lua
--db-driver=mysql --mysql-db=loadtest --mysql-user=root
--mysql-password= --mysql-port=3306 --mysql-host= --oltp-tables-count=64 --oltp-table-size=10000000 --num-threads=20 prepare

脚本参数及其含义:

  • –test:指定要运行的测试脚本,这里选择的是一个OLTP(在线事务处理)负载测试脚本。oltp.lua是一个预定义的脚本,用于模拟常见的数据库操作。
  • –db-driver:指定数据库驱动程序,这里选择的是 MySQL。
  • –mysql-db:指定要测试的 MySQL 数据库名称,这里是loadtest数据库。
  • –mysql-user:指定用于连接 MySQL 数据库的用户名,这里是 root 用户。
  • mysql-password:指定用于连接 MySQL 数据库的密码,这里为空,意味着没有设置密码(不推荐在生产环境中使用空密码)。
  • –mysql-port:指定 MySQL 服务器监听的端口,这里是默认的 3306 端口。
  • –mysql-host:指定 MySQL 服务器的主机地址,这里为空,表示连接本地数据库。
  • –oltp-tables-count:指定用于测试的表的数量,这里是 64 个表。
  • –oltp-table-size:指定每个表中的行数,这里是 10,000,000 行。表示每个表有一千万条记录。
  • –num-threads:指定测试时使用的线程数,这里是 20 个线程。表示并发 20 个线程进行测试。
  • prepare:测试提前准备数据

本文是生成 64 张表,每张表有1千万数据,合计导入6亿4千万条数据。

显示下面信息说明已经成功完成测试数据生成:

WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
WARNING: --num-threads is deprecated, use --threads instead
sysbench 1.0.12 (using bundled LuaJIT 2.1.0-beta2)......
Inserting 10000000 records into 'sbtest63'
Creating secondary indexes on 'sbtest63'...
Creating table 'sbtest64'...
Inserting 10000000 records into 'sbtest64'
Creating secondary indexes on 'sbtest64'...
[root@ecs-825d-1113052 ~]#

生产的表结构如下:

CREATE TABLE sbtest (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
k INTEGER UNSIGNED DEFAULT '0' NOT NULL,
c CHAR(120) DEFAULT '' NOT NULL,
pad CHAR(60) DEFAULT '' NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB

生产数据样例如下:
在这里插入图片描述

这里用到 oltp.lua 这个关键脚本,我们单独拿出分析下,源码如下:

[root@ecs-825d-1113052 ~]# cat /usr/local/share/sysbench/tests/include/oltp_legacy/oltp.lua
-- 匹配test路径并检查
pathtest = string.match(test, "(.*/)")
if pathtest thendofile(pathtest .. "common.lua")
elserequire("common")
end-- 线程初始化函数
function thread_init()-- 设置变量set_vars()-- 检查数据库驱动和表引擎类型if (((db_driver == "mysql") or (db_driver == "attachsql")) and mysql_table_engine == "myisam") thenlocal ilocal tables = {}-- 为每个表构建锁定语句for i=1, oltp_tables_count dotables[i] = string.format("sbtest%i WRITE", i)end-- 设置锁定和解锁查询begin_query = "LOCK TABLES " .. table.concat(tables, " ,")commit_query = "UNLOCK TABLES"else-- 默认使用事务的开始和提交语句begin_query = "BEGIN"commit_query = "COMMIT"end
end-- 获取范围查询的条件字符串
function get_range_str()local start = sb_rand(1, oltp_table_size)return string.format(" WHERE id BETWEEN %u AND %u",start, start + oltp_range_size - 1)
end-- 定义事件函数
function event()local rslocal ilocal table_namelocal c_vallocal pad_vallocal query-- 随机选择一个表table_name = "sbtest".. sb_rand_uniform(1, oltp_tables_count)-- 如果没有跳过事务,则开始事务if not oltp_skip_trx thendb_query(begin_query)end-- 如果不是仅写操作if not oltp_write_only then-- 执行点查询for i=1, oltp_point_selects dors = db_query("SELECT c FROM ".. table_name .." WHERE id=" .. sb_rand(1, oltp_table_size))end-- 如果需要执行范围查询if oltp_range_selects then-- 简单范围查询for i=1, oltp_simple_ranges dors = db_query("SELECT c FROM ".. table_name .. get_range_str())end-- 范围求和查询for i=1, oltp_sum_ranges dors = db_query("SELECT SUM(K) FROM ".. table_name .. get_range_str())end-- 范围排序查询for i=1, oltp_order_ranges dors = db_query("SELECT c FROM ".. table_name .. get_range_str() .. " ORDER BY c")end-- 范围去重查询for i=1, oltp_distinct_ranges dors = db_query("SELECT DISTINCT c FROM ".. table_name .. get_range_str() .. " ORDER BY c")endendend-- 如果不是只读操作if not oltp_read_only then-- 执行索引更新for i=1, oltp_index_updates dors = db_query("UPDATE " .. table_name .. " SET k=k+1 WHERE id=" .. sb_rand(1, oltp_table_size))end-- 执行非索引更新for i=1, oltp_non_index_updates doc_val = sb_rand_str("###########-###########-###########-###########-###########-###########-###########-###########-###########-###########")query = "UPDATE " .. table_name .. " SET c='" .. c_val .. "' WHERE id=" .. sb_rand(1, oltp_table_size)rs = db_query(query)if rs thenprint(query)endend-- 执行删除和插入操作for i=1, oltp_delete_inserts doi = sb_rand(1, oltp_table_size)rs = db_query("DELETE FROM " .. table_name .. " WHERE id=" .. i)c_val = sb_rand_str("###########-###########-###########-###########-###########-###########-###########-###########-###########-###########")pad_val = sb_rand_str("###########-###########-###########-###########-###########")rs = db_query("INSERT INTO " .. table_name ..  " (id, k, c, pad) VALUES " .. string.format("(%d, %d, '%s', '%s')",i, sb_rand(1, oltp_table_size) , c_val, pad_val))endend-- 如果没有跳过事务,则提交事务if not oltp_skip_trx thendb_query(commit_query)end
end

这段 oltp.lua 代码的主要步骤如下:

  • 路径匹配与加载配置:
    • 检查并获取脚本的路径。
    • 如果路径存在,加载 common.lua 文件;否则使用 require 函数加载模块。
  • 线程初始化 (thread_init):
    • 初始化变量。
    • 根据数据库驱动和表引擎类型,决定是否使用锁表操作。
    • 如果数据库驱动是 mysql 或 attachsql 且表引擎为 myisam,则构建锁定和解锁查询语句。
    • 否则,使用默认的事务控制语句(BEGIN 和 COMMIT)。
  • 获取范围查询字符串 (get_range_str):
    • 随机生成一个起始ID。
    • 返回一个用于范围查询的条件字符串,指定查询范围为从起始ID到起始ID加上范围大小减去1。
  • 事件处理 (event):
    • 定义事件函数,该函数是 Sysbench 测试的核心部分
    • 事件函数包括以下操作:
      • 随机选择一个表。
      • 如果没有跳过事务,则开始事务。
      • 根据配置执行不同类型的查询和更新操作,包括点查询、范围查询、索引更新、非索引更新、删除和插入操作。
      • 范围查询包括简单范围查询、求和范围查询、排序范围查询和去重范围查询。
      • 如果没有跳过事务,则提交事务。

这段代码是典型的OLTP(联机事务处理)负载测试脚本,通过模拟多种数据库操作(查询、更新、删除、插入),来评估数据库在高并发访问场景下的性能表现。

2、压测数据

sysbench
--test=/usr/local/share/sysbench/tests/include/oltp_legacy/oltp.lua
--db-driver=mysql --mysql-db=loadtest --mysql-user=root
--mysql-password= --mysql-port=3306 --mysql-host=--oltp-tables-count=64
--oltp-table-size=10000000 --max-time=3600 --max-requests=0
--num-threads=200 --report-interval=3 --forced-shutdown=1 run

脚本参数及其含义:

  • –test:指定要运行的测试脚本,这里选择的是一个OLTP(在线事务处理)负载测试脚本。oltp.lua是一个预定义的脚本,用于模拟常见的数据库操作。
  • –db-driver:指定数据库驱动程序,这里选择的是 MySQL。
  • –mysql-db:指定要测试的 MySQL 数据库名称,这里是 loadtest 数据库。
  • –mysql-user:指定用于连接 MySQL 数据库的用户名,这里是 root 用户。
  • mysql-password:指定用于连接 MySQL 数据库的密码,这里为空,意味着没有设置密码(不推荐在生产环境中使用空密码)。
  • –mysql-port:指定 MySQL 服务器监听的端口,这里是默认的 3306 端口。
  • –mysql-host:指定 MySQL 服务器的主机地址,这里为空,表示连接本地数据库。
  • –oltp-tables-count:指定用于测试的表的数量,这里是 64 个表。
  • –oltp-table-size:指定每个表中的行数,这里是 10,000,000 行。表示每个表有一千万条记录。
  • –max-time:指定测试的最大持续时间为3600秒(1小时)。
  • –max-requests:指定要执行的最大请求数。值为0表示请求数不受限制,直到达到最大时间。
  • –num-threads:指定测试时使用的线程数,这里是 200 个线程。表示并发 200 个线程进行测试。
  • –report-interval:指定报告中间结果的时间间隔(每3秒报告一次)。
  • –forced-shutdown:指定如果达到最大时间,Sysbench应该强制关闭测试(1表示启用)。
  • run:开始运行测试的命令。

简要说明就是并发200线程,压测1小时,每3秒打印一次结果等。

3、清理数据

测试完成后,可以运行以下脚本清理测试数据:

sysbench
--test=/usr/local/share/sysbench/tests/include/oltp_legacy/oltp.lua
--db-driver=mysql --mysql-db=loadtest --mysql-user=root
--mysql-password= --mysql-port=3306 --mysql-host= --oltp-tables-count=64 --oltp-table-size=10000000--max-time=3600 --max-requests=0 --num-threads=200 cleanup

脚本参数及其含义:

  • –test:指定要运行的测试脚本,这里选择的是一个OLTP(在线事务处理)负载测试脚本。oltp.lua是一个预定义的脚本,用于模拟常见的数据库操作。
  • –db-driver:指定数据库驱动程序,这里选择的是 MySQL。
  • –mysql-db:指定要测试的 MySQL 数据库名称,这里是 loadtest 数据库。
  • –mysql-user:指定用于连接 MySQL 数据库的用户名,这里是 root 用户。
  • mysql-password:指定用于连接 MySQL 数据库的密码,这里为空,意味着没有设置密码(不推荐在生产环境中使用空密码)。
  • –mysql-port:指定 MySQL 服务器监听的端口,这里是默认的 3306 端口。
  • –mysql-host:指定 MySQL 服务器的主机地址,这里为空,表示连接本地数据库。
  • –oltp-tables-count:指定用于测试的表的数量,这里是 64 个表。
  • –oltp-table-size:指定每个表中的行数,这里是 10,000,000 行。表示每个表有一千万条记录。
  • –max-time:指定测试的最大持续时间为3600秒(1小时)。
  • –max-requests:指定要执行的最大请求数。值为0表示请求数不受限制,直到达到最大时间。
  • –num-threads:指定测试时使用的线程数,这里是 200 个线程。表示并发 200 个线程进行测试。
  • cleanup:测试完成后对数据库进行清理。

五、结果解析

以下为压测过程中打印的结果:

[ 3522s ] thds: 200 tps: 153.98 qps: 3119.87 (r/w/o: 2155.68/656.24/307.95) lat (ms,95%): 1235.62 err/s: 0.00 reconn/s: 0.00
[ 3525s ] thds: 200 tps: 157.36 qps: 2992.89 (r/w/o: 1997.37/680.79/314.72) lat (ms,95%): 4358.09 err/s: 0.00 reconn/s: 0.00
[ 3528s ] thds: 200 tps: 85.33 qps: 1852.86 (r/w/o: 1400.23/281.98/170.65) lat (ms,95%): 1258.08 err/s: 0.00 reconn/s: 0.00

测试结束后,查看输出文件,如下所示:

FATAL: The --max-time limit has expired, forcing shutdown...
SQL statistics:queries performed:read:                            5358024write:                           1530377other:                           765297total:                           7653698transactions:                        382581 (106.24 per sec.)queries:                             7653698 (2125.42 per sec.)ignored errors:                      0      (0.00 per sec.)reconnects:                          0      (0.00 per sec.)Number of unfinished transactions on forced shutdown: 200General statistics:total time:                          3601.0196stotal number of events:              382581Latency (ms):min:                                  4.72avg:                               1881.83max:                              10972.9295th percentile:                   4128.91sum:                            719951371.94Threads fairness:events (avg/stddev):           1913.9050/24.88execution time (avg/stddev):   3599.7569/1.81

是不是有点晕,那我们稍微翻译下,如下所示:

FATAL: The --max-time limit has expired, forcing shutdown...
#SQL统计部分表明了总查询量以及每秒执行的查询和事务数量。这些数据有助于了解数据库的处理能力和性能表现。
SQL statistics(SQL统计信息):queries performed(查询执行情况):read(读查询):                          5358024write(写查询):                         1530377other(其它查询):                        765297total(总查询):                         7653698transactionss(事务):                        382581 (106.24 per sec.) (每秒106.24次)queries(查询):                             7653698 (2125.42 per sec.) (每秒2125.42次)ignored errors(忽略的错误):                      0      (0.00 per sec.) (每秒0次)reconnect(重连)s:                          0      (0.00 per sec.) (每秒0次)# 强制关闭时未完成的事务数量为200,表明在测试过程中有200个事务未能完成,这可能与测试环境或配置有关。
Number of unfinished transactions on forced shutdown: 200General statistics(一般统计信息):total time(总时间):                          3601.0196stotal number of events(事件总数):              382581#延迟数据展示了不同百分位的延迟情况,这些数据对分析数据库响应时间和性能瓶颈很有用。
Latency(延迟) (ms):min(最小延迟):                                  4.72avg(平均延迟):                               1881.83max(最大延迟):                              10972.9295th percentile(95%分位延迟):                4128.91sum(延迟总和):                          719951371.94#线程公平性数据表明,每个线程处理的事件数的平均值和标准差,以及每个线程的执行时间的平均值和标准差。
Threads fairness(线程公平性):events (avg/stddev)(事件(平均值/标准差)):           1913.9050/24.88execution time (avg/stddev)(执行时间(平均值/标准差)):   3599.7569/1.81

这些数据展示了MySQL在高并发负载下的性能情况,主要关注点包括:

  • 查询和事务的执行率:每秒查询和事务数量表明了数据库的吞吐量。
  • 延迟:延迟数据(平均、最大和95%分位)显示了数据库的响应时间和性能瓶颈。
  • 未完成事务:强制关闭时未完成的事务数提示了潜在的事务处理问题。
  • 线程公平性:线程间的负载均衡情况,标准差较低表示负载分配较为均衡。

主要关注的性能指标有:

  • TPS :Transaction Per Second,数据库每秒执行的事务数,每个事务中包含18条SQL语句。
  • QPS :Query Per Second,数据库每秒执行的SQL数,包含insert、select、update、delete等。
  • 延迟:Latency,数据库执行的事务耗时。

Sysbench默认提交的事务中包含18条SQL语句,具体执行语句和条数如下:

主键SELECT语句,10条:
SELECT c FROM ​{rand_table_name} where id={rand_id};范围SELECT语句,4条:
SELECT c FROM ​{rand_table_name} WHERE id BETWEEN {rand_id_start} AND ${rand_id_end};
SELECT SUM(K) FROM ​{rand_table_name} WHERE id BETWEEN {rand_id_start} AND ${rand_id_end};
SELECT c FROM ​{rand_table_name} WHERE id BETWEEN {rand_id_start} AND ${rand_id_end} ORDER BY c;
SELECT DISTINCT c FROM ​{rand_table_name} WHERE id BETWEEN {rand_id_start} AND ${rand_id_end} ORDER BY c;UPDATE语句,2条:
UPDATE ​{rand_table_name} SET k=k+1 WHERE id={rand_id}
UPDATE ​{rand_table_name} SET c={rand_str} WHERE id=${rand_id}DELETE语句,1条:
DELETE FROM ​{rand_table_name} WHERE id={rand_id}INSERT语句,1条:
INSERT INTO ​{rand_table_name} (id, k, c, pad) VALUES ({rand_id},​{rand_k},{rand_str_c},${rand_str_pad})

这些结果可以用于性能调优和瓶颈分析,从而提升 MySQL 数据库在实际应用中的表现。

从Sysbench测试结果来看,这台MySQL服务器在高并发负载下的性能表现有以下几个关键点:

  • 事务处理能力:
    • 每秒事务数(TPS)为106.24次。
    • 总事务数为 382581。
  • 查询处理能力:
    • 每秒查询数(QPS)为 2125.42次。
    • 总查询数为 7653698。
  • 延迟:
    • 平均延迟为 1881.83 毫秒,较高,说明在负载压力下,响应时间比较长
    • 最大延迟为 10972.92 毫秒,非常高,表明在高负载下可能存在严重的性能瓶颈
    • 95% 分位延迟为 4128.91 毫秒,表示大多数请求的响应时间在 4 秒以上,体验较差
  • 未完成事务:
    • 强制关闭时未完成的事务数为 200,表明在高负载下有一部分事务未能及时处理完成。
  • 线程公平性:
    • 每个线程处理的事件数的标准差为 24.88,表明线程间的负载分配较为均衡。
    • 每个线程的执行时间的标准差为 1.81,表明线程执行时间也较为一致。

这里我们可以对比下某云的测试结果:
在这里插入图片描述

数据服务器资源监控数据:
在这里插入图片描述
我们可以看到CPU峰值到75%左右,磁盘峰值写入速率达50MB/s,峰值读取速率达 100MB/s。

六、最后

我们可以看到从测试结果的结果来看,MySQL数据库的性能表现并不好,那么我们接下来应对MySQL数据库进行性能调优并再次验证,希望本文能对你的工作带来一点点帮助,如果有用别忘了点个赞,多谢。

相关文章:

性能工具之 MySQL OLTP Sysbench BenchMark 测试示例

文章目录 一、前言二、测试环境1、服务器配置2、测试拓扑 三、测试工具安装四、测试步骤1、导入数据2、压测数据3、清理数据 五、结果解析六、最后 一、前言 做为一名性能工程师掌握对 MySQL 的性能测试是非常必要的,本文基于 Sysbench 对MySQL OLTP(联…...

【QT】QCustomPlot库中iSelectPlottables的使用

QCP::iSelectPlottables 是 QCustomPlot 库中的一个枚举值,用于控制选择交互。QCustomPlot 是一个用于创建绘图和数据可视化的Qt库。 QCP::iSelectPlottables 允许用户选择图表中的绘图对象(如图形、曲线、柱状图等)。 应用场景 QCP::iSele…...

字节跳动联手博通:5nm AI芯片诞生了?

字节跳动联手博通:5nm AI芯片诞生了? 前言 就在6月24日,字节跳动正在与美国博通合作开发一款5纳米工艺的专用集成电路(ASIC) AI处理器。这款芯片旨在降低采购成本并确保高端AI芯片的稳定供应。 根据报道,尽管芯片设计工作进展顺利…...

【数据结构与算法】动态查找表(二叉排序树,二叉平衡树)详解

二叉排序树的数据结构。 struct TreeNode {ElemType data;TreeNode *left, *right; }; using BiTree TreeNode *;结构体包含三个成员: data 是一个 ElemType 类型的变量,用于存储二叉搜索树节点的数据。left 是一个指向 TreeNode 类型的指针&#xff…...

PyTorch中“No module named ‘torch._six‘“的报错场景及处理方法

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引入 在使用PyTorch时,您可能会遇到"No module named ‘torch._six’"的错误。这通常是因为PyTorch的某些…...

Spring Boot 集成 MinIO 实现文件上传

Spring Boot 集成 MinIO 实现文件上传 一、 Minio 服务准备 MinIO的搭建过程参考 Docker 搭建 MinIO 对象存储。 登录MinIO控制台&#xff0c;新建一个 Bucket&#xff0c;修改 Bucket 权限为公开。 二、MinIO 集成 添加 MinIO 依赖 <!-- https://mvnrepository.com/ar…...

目标跟踪——KCF源码用python实现

from numpy.fft import fft2, ifft2, fftshift import cv2 import numpy as npclass HOG:def __init__(self, winSize):""":param winSize: 检测窗口的大小"""self.winSize winSizeself.blockSize (8, 8)self.blockStride (4, 4)self.cellSiz…...

前端 转换笔记

<!DOCTYPE html> <html> <head> <meta charset"utf-8" /> <title>转换</title> <style> .box{ /* 盒子摆在body的正中间 */ position: absolut…...

个人开发笔记

开发笔记 开发常见问题Vue开发中页面flex滚动布局&#xff0c;内容置顶问题功能快捷键 开发常见问题 Vue开发中页面flex滚动布局&#xff0c;内容置顶问题 直接操作路由&#xff1a; const router createRouter({routes: routes,history: createWebHashHistory(),scrollBeha…...

pdf压缩,pdf压缩在线,pdf文件太大怎么变小

在数字化时代&#xff0c;PDF文档因其跨平台、保持原样、易于阅读和打印等特点&#xff0c;成为了我们日常工作和生活中不可或缺的一部分。然而&#xff0c;随着PDF文件的不断累积&#xff0c;存储空间逐渐变得紧张&#xff0c;特别是在处理大量大型PDF文件时&#xff0c;如何有…...

Go 如何使用指针灵活操作内存

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

【面试干货】Java中的++操作符与线程安全性

【面试干货】Java中的操作符与线程安全性 1、什么是线程安全性&#xff1f;2、 操作符的工作原理3、 操作符与线程安全性4、如何确保线程安全&#xff1f;5、 结论 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java编程中&#xff0c;操…...

NLP学习与踩坑记录(持续更新版)

NLP学习与踩坑记录&#xff08;持续更新版&#xff09; OSError: Cant load tokenizer for bert-base-uncased.google.protobuf.message.DecodeError: Error parsing messageDeepspeed 本博客记录了博主在学习NLP时遇到了各种各样的问题与解决方法&#xff0c;供大家参考&#…...

Java也能做OCR!SpringBoot 整合 Tess4J 实现图片文字识别

文章目录 1. 环境准备1.1 安装 Tesseract OCR 引擎1.2 引入 Tess4J 依赖 2. 创建 Spring Boot 项目2.1 初始化项目2.2 目录结构 3. 编写 OCR 功能代码3.1 创建服务层3.2 创建控制器层 4. 配置 Tesseract 语言包5. 运行和测试5.1 启动 Spring Boot 应用5.2 使用 Postman 或 cURL…...

微信小程序常用标签及其用法

大家好&#xff0c;我是linzi&#xff0c;今天我来给大家分享一下微信小程序一些个常用的标签及其用法 1. <view> 标签 <view> 标签是小程序中最常用的标签之一&#xff0c;用于组织和布局页面上的内容&#xff0c;类似于HTML中的 <div> 标签。 <view …...

开发查询订单信息fastGPT智能体工作流 将工作流接入到人工客服系统

我在抖音上发布了视频 https://www.douyin.com/video/7382446337482099977 下面是主要内容介绍 【视频标题&#xff1a;】开发查询订单信息fastGPT智能体工作流 将工作流接入到人工客服系统 #智能体 #FastGPT #客服系统-----------【视频行业分类&#xff1a;】<3C数码>-…...

Flink集群运行模式

我们了解了flink的一个集群的一个基础架构&#xff0c;包括里面核心的一些组件&#xff0c;比如说job manager&#xff0c;task manager等一些组件的一些主要的一些组成。本节课程开始我们学习flink的一个集群部署模式。首先我们来看一下flink集群部署模式究竟应该有哪一些种类…...

XSS 安全漏洞介绍及修复方案

简介 XSS&#xff08;Cross Site Scripting&#xff09;是一种常见的 Web 安全漏洞&#xff0c;攻击者通过在网页中注入恶意脚本代码&#xff0c;使得网页在用户端执行这些脚本&#xff0c;从而窃取用户信息或者进行其他恶意操作。为了防止 XSS 攻击&#xff0c;可以使用正则表…...

基于STM32的智能仓库管理系统

目录 引言环境准备智能仓库管理系统基础代码实现&#xff1a;实现智能仓库管理系统 4.1 数据采集模块4.2 数据处理与分析4.3 通信模块实现4.4 用户界面与数据可视化应用场景&#xff1a;仓库管理与优化问题解决方案与优化收尾与总结 1. 引言 智能仓库管理系统通过使用STM32嵌…...

LeetCode —— 只出现一次的数字

只出现一次的数字 I 本题依靠异或运算符的特性&#xff0c;两个相同数据异或等于0&#xff0c;数字与0异或为本身即可解答。代码如下: class Solution { public:int singleNumber(vector<int>& nums) {int ret 0;for (auto e : nums){ret ^ e;}return ret;} };只出…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...