基于Sharding-jdbc实现水平分库、垂直分库、读写分离

一、实现水平分库

需求说明

水平分库是把同一个表的数据按一定规则拆到不同的数据库中,每个库可以放在不同的服务器上。
接下来咱们继续对快速入门中的例子进行完善。

实现步骤

将原有order_db库拆分为order_db_1、order_db_2

CREATE DATABASE order_db_1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
CREATE DATABASE order_db_2 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

再分别对每个库建立同样的表结构

DROP TABLE IF EXISTS t_order_1;CREATE TABLE t_order_1 (`order_id` BIGINT ( 20 ) NOT NULL COMMENT '订单id',`price` DECIMAL ( 10, 2 ) NOT NULL COMMENT '订单价格',`user_id` BIGINT ( 20 ) NOT NULL COMMENT '下单用户id',`status` VARCHAR ( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',PRIMARY KEY ( `order_id` ) USING BTREE 
) ENGINE = INNODB CHARACTER 
SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;DROP TABLE IF EXISTS t_order_2;CREATE TABLE t_order_2 (`order_id` BIGINT ( 20 ) NOT NULL COMMENT '订单id',`price` DECIMAL ( 10, 2 ) NOT NULL COMMENT '订单价格',`user_id` BIGINT ( 20 ) NOT NULL COMMENT '下单用户id',`status` VARCHAR ( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',PRIMARY KEY ( `order_id` ) USING BTREE 
) ENGINE = INNODB CHARACTER 
SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

 在application.properties中配置分片分库规则

# 端口号
server.port=56000
# 应用名称
spring.application.name=sharding_shuiping_dbsharding
# 表示spring中发现的bean会覆盖之前相同名称的bean
spring.main.allow-bean-definition-overriding=true
# 该配置项,将数据库中带有下划线的字段名称映射成驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true# 以下配置为sharding-jdbc分片规则配置# 1.定义数据源
#定义数据源名称
spring.shardingsphere.datasource.names=m1,m2
#数据源连接数据库
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/order_db_1?useUnicode=true
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123456spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/order_db_2?useUnicode=true
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=123456# 2.指定订单表的数据分布情况,配置数据节点 下面的't_order'是逻辑表,这个名字可以自己起一个   m1.t_order_$->{1..2}表示利用行表达式来实现动态表
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=m$->{1..2}.t_order_$->{1..2}# 3.指定t_order表中的主键生成策略#表示告诉sharding-jdbc数据库表中的那一个字段进行主键生成
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
#指定具体的主键生成策略  -> 雪花算法
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE# 4.指定t_order表的分片策略(分片策略=分片键+分片算法):主键为偶数路由到t_order_1中,否则插入到t_order_2中#告诉分片键是哪一个字段
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.shardingColumn=order_id
#确定采取什么样的分片算法
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.algorithmExpression=t_order_$->{order_id % 2 + 1}# 5.指定分库策略#告诉分库需要采用的分片键是哪一个字段
spring.shardingsphere.sharding.tables.t_order.databaseStrategy.inline.shardingColumn=user_id
#确定采取什么样的分库算法
spring.shardingsphere.sharding.tables.t_order.databaseStrategy.inline.algorithmExpression=m$->{user_id % 2 + 1}# 6.指定,打开sharding-jdbc提供的sql输出日志配置
spring.shardingsphere.props.sql.show=true# 日志配置
logging.level.root=info
logging.level.org.springframework=info
logging.level.com.lcc=debug
logging.level.druid.sql=debug

mapper代码如下:

@Mapper
public interface OrderMapper {/*** 这里t_order就是sharding-jdbc中的逻辑表*/@Insert("insert into t_order(price,user_id,status) values(#{price},#{userId},#{status})")public int insertOrder(Order order);@Select("<script>" +"select " +"* " +"from t_order t " +"where t.order_id in " +"<foreach collection='orderIds' item='id' open='(' separator=',' close=')'>" +"#{id}" +"</foreach>" +" AND user_id = #{userId}" +"</script>")public List<Map> selectListByUserIdAndOrderIds(@Param("userId") Long userId,@Param("orderIds") List<Long> orderIds);
}

 测试代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingShuipingDBShardingApplicationTests {@Autowiredprivate OrderMapper orderMapper;@Testpublic void insertDBShardingTest(){for (int i = 0; i < 10; i++) {Order order = new Order();order.setStatus("success_"+i);order.setUserId(1L);order.setPrice(new BigDecimal((i+1)*5));int result = orderMapper.insertOrder(order);System.out.println(result);}for (int i = 0; i < 10; i++) {Order order = new Order();order.setStatus("success_"+i);order.setUserId(2L);order.setPrice(new BigDecimal((i+1)*5));int result = orderMapper.insertOrder(order);System.out.println(result);}}@Testpublic void selectDBShardingTest(){List<Long> orderIds = new ArrayList<>();orderIds.add(1074752838191546368L);orderIds.add(1074752838183157761L);Long userId = 2L;List<Map> maps = orderMapper.selectListByUserIdAndOrderIds(userId,orderIds);for (Map map : maps) {System.out.println(map);}}
}

二、实现垂直分库

需求说明

是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用。接下来看一下在单库中实现垂直分库操作。

实现步骤

新增user数据库

#创建数据库 
CREATE DATABASE user_db CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';#创建表
DROP TABLE IF EXISTS t_user;CREATE TABLE t_user (user_id BIGINT ( 20 ) NOT NULL COMMENT '用户id',fullname VARCHAR ( 255 ) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL COMMENT '用户姓名',user_type CHAR ( 1 ) DEFAULT NULL COMMENT '用户类型',PRIMARY KEY ( user_id ) USING BTREE 
) ENGINE = INNODB CHARACTER 
SET = 'utf8' COLLATE = 'utf8_general_ci' ROW_FORMAT = Dynamic;

  在application.properties中配置分片分库规则

# 端口号
server.port=56000
# 应用名称
spring.application.name=sharding_chuizhi_dbsharding
# 表示spring中发现的bean会覆盖之前相同名称的bean
spring.main.allow-bean-definition-overriding=true
# 该配置项,将数据库中带有下划线的字段名称映射成驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true# 以下配置为sharding-jdbc分片规则配置# 1.定义数据源
#定义数据源名称
spring.shardingsphere.datasource.names=m1,m2
#order数据源连接数据库
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/order_db?useUnicode=true
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123456
#user数据源连接数据库
spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/user_db?useUnicode=true
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=123456# 2.指定订单表的数据分布情况,配置数据节点 下面的't_order'是逻辑表,这个名字可以自己起一个   m1.t_order_$->{1..2}表示利用行表达式来实现动态表
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=m1.t_order_$->{1..2}# 2.1 指定t_order表中的主键生成策略#表示告诉sharding-jdbc数据库表中的那一个字段进行主键生成
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
#指定具体的主键生成策略  -> 雪花算法
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE# 2.2 指定t_order表的分片策略(分片策略=分片键+分片算法):主键为偶数路由到t_order_1中,否则插入到t_order_2中#告诉分片键是哪一个字段
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.shardingColumn=order_id
#确定采取什么样的分片算法
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.algorithmExpression=t_order_$->{order_id % 2 + 1}# 3 指定订单表的数据分布情况,配置数据节点 下面的't_order'是逻辑表,这个名字可以自己起一个   m1.t_order_$->{1..2}表示利用行表达式来实现动态表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m2.t_user# 3.1 指定t_user表中的主键生成策略#表示告诉sharding-jdbc数据库表中的那一个字段进行主键生成
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
#指定具体的主键生成策略  -> 雪花算法
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE# 3.2 指定t_user表的分片策略(分片策略=分片键+分片算法):主键为偶数路由到t_order_1中,否则插入到t_order_2中#告诉分片键是哪一个字段
spring.shardingsphere.sharding.tables.t_user.tableStrategy.inline.shardingColumn=user_id
#确定采取什么样的分片算法
spring.shardingsphere.sharding.tables.t_user.tableStrategy.inline.algorithmExpression=t_user# 4.指定,打开sharding-jdbc提供的sql输出日志配置
spring.shardingsphere.props.sql.show=true# 日志配置
logging.level.root=info
logging.level.org.springframework=info
logging.level.com.lcc=debug
logging.level.druid.sql=debug

 添加userMapper接口

@Mapper
public interface UserMapper {/*** 这里t_order就是sharding-jdbc中的逻辑表*/@Insert("insert into t_user(fullname,user_type) values(#{fullname},#{userType})")public int insertUser(@Param("fullname") String fullname,@Param("userType") String userType);@Select("<script>" +"select " +"* " +"from t_user t " +"where t.user_id in " +"<foreach collection='userIds' item='id' open='(' separator=',' close=')'>" +"#{id}" +"</foreach>" +"</script>")public List<Map> selectListByUserIds(@Param("userIds") List<Long> userIds);
}

  添加orderMapper接口

@Mapper
public interface OrderMapper {/*** 这里t_order就是sharding-jdbc中的逻辑表*/@Insert("insert into t_order(price,user_id,status) values(#{price},#{userId},#{status})")public int insertOrder(Order order);@Select("<script>" +"select " +"* " +"from t_order t " +"where t.order_id in " +"<foreach collection='orderIds' item='id' open='(' separator=',' close=')'>" +"#{id}" +"</foreach>" +"</script>")public List<Map> selectListByOrderIds(@Param("orderIds") List<Long> orderIds);
}

测试代码如下

@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingChuizhiDBShardingApplicationTests {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate UserMapper userMapper;@Testpublic void insertOrderTest(){for (int i = 0; i < 10; i++) {Order order = new Order();order.setStatus("success_"+i);order.setUserId(1L);order.setPrice(new BigDecimal((i+1)*5));int result = orderMapper.insertOrder(order);System.out.println(result);}}@Testpublic void selectOrderTest(){List<Long> orderIds = new ArrayList<>();orderIds.add(1074752838191546368L);orderIds.add(1074752838183157761L);List<Map> maps = orderMapper.selectListByOrderIds(orderIds);for (Map map : maps) {System.out.println(map);}}@Testpublic void insertUserTest(){for (int i = 0; i < 10; i++) {userMapper.insertUser("lcc"+i,i+"");}}@Testpublic void selectUserTest(){List<Long> userIds = new ArrayList<>();userIds.add(1074769306459308033L);userIds.add(1074769306564165632L);List<Map> maps = userMapper.selectListByUserIds(userIds);for (Map map : maps) {System.out.println(map);}}
}

可以发现,不同的表会去到不同的数据库 

三、实现读写分离

什么是读写分离

面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。 对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。

通过一主多从的配置方式,可以将查询请求均匀的分散到多个数据副本,能够进一步的提升系统的处理能力。 使用多主多从的方式,不但能够提升系统的吞吐量,还能够提升系统的可用性,可以达到在任何一个数据库宕机,甚至磁盘物理损坏的情况下仍然不影响系统的正常运行。

读写分离和分库分表有什么关系呢

读写分离的数据节点中的数据内容是一致的,而水平分片的每个数据节点的数据内容却并不相同。将水平分片和读写分离联合使用,能够更加有效的提升系统的性能。

Sharding-JDBC读写分离则是根据SQL语义的分析,将读操作和写操作分别路由至主库与从库。它提供透明化读写分离,让使用方尽量像使用一个数据库一样使用主从数据库集群。

所以,基于Sharding-jdbc的读写分离只是将写请求路由到一个节点上,读请求路由到另一个节点上,而其中这些数据库节点数据之间的同步由数据库内部或者其他中间件完成,这不是Sharding-jdbc需要完成的。

docker搭建mysql一主一从架构

我们将基于MySQL:5.7.41版本进行搭建

主节点环境搭建

主节点文件夹创建

mkdir /usr/local/mysql_zhu_cong/mysql_master/data
mkdir /usr/local/mysql_zhu_cong/mysql_master/log
mkdir /usr/local/mysql_zhu_cong/mysql_master/conf

主节点文件配置

vim /usr/local/mysql_zhu_cong/mysql_master/conf/my.cnf

 文件内容如下:

[mysqld]
character_set_server=utf8#开启日志
log-bin=mysql-bin
#设置服务id,主从服务不能一致
server-id=1#设置需要同步的数据库
binlog-do-db=user_db#屏蔽系统库同步
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema

 启动容器

docker run --name mysql_zhu_cong_master \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /usr/local/mysql_zhu_cong/mysql_master/data:/var/lib/mysql \
-v /usr/local/mysql_zhu_cong/mysql_master/log:/var/log/mysql \
-v /usr/local/mysql_zhu_cong/mysql_master/conf:/etc/mysql/conf.d \
-dp 3316:3306 \
mysql:5.7.41

从节点环境搭建

从节点文件夹创建

mkdir /usr/local/mysql_zhu_cong/mysql_slave#复制主节点信息
cp -r /usr/local/mysql_zhu_cong/mysql_master/data /usr/local/mysql_zhu_cong/mysql_slave/
cp -r /usr/local/mysql_zhu_cong/mysql_master/log /usr/local/mysql_zhu_cong/mysql_slave/
cp -r /usr/local/mysql_zhu_cong/mysql_master/conf /usr/local/mysql_zhu_cong/mysql_slave/

请注意,主从 MySQL下的数据(data)目录下有个文件auto.cnf,文件中定义了uuid,要保证主从数据库实例的 uuid不一样,建议直接删除掉,重启服务后将会重新生成。

rm /usr/local/mysql_zhu_cong/mysql_slave/data/auto.cnf

编辑从节点配置文件

vim /usr/local/mysql_zhu_cong/mysql_slave/conf/my.cnf

 文件内容如下:

[mysql]
default_character_set=utf8
[mysqld]
character_set_server=utf8#开启日志
log-bin=mysql-bin
#设置服务id,主从服务不能一致
server-id=2#设置需要同步的数据库
replicate_wild_do_table=user_db.%#屏蔽系统库同步
replicate_wild_ignore_table=mysql.%
replicate_wild_ignore_table=information_schema.%
replicate_wild_ignore_table=performance_schema.%

 启动容器

docker run --name mysql_zhu_cong_slave \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /usr/local/mysql_zhu_cong/mysql_slave/data:/var/lib/mysql \
-v /usr/local/mysql_zhu_cong/mysql_slave/log:/var/log/mysql \
-v /usr/local/mysql_zhu_cong/mysql_slave/conf:/etc/mysql/conf.d \
-dp 3326:3306 \
mysql:5.7.41

主从同步搭建

连接上主节点,执行以下命令

--授权主备复制专用账号
GRANT replication SLAVE ON *.* TO 'db_sync'@'%' IDENTIFIED by 'db_sync';
--刷新权限
FLUSH PRIVILEGES;
--确认位点 记录下文件名以及位点 
SHOW MASTER STATUS;

得到以下结果:

 

 连接上从节点,执行以下命令

--先停止同步 
STOP SLAVE; 
--修改从库指向主库,使用上一步记录的文件名以及位点 
CHANGE MASTER TO master_host='192.168.149.128',master_port=3316, master_user='db_sync', master_password='db_sync', master_log_file='mysql-bin.000002', master_log_pos=584; 
--启动同步 
START SLAVE; 
--查看从库状态Slave_IO_Running和Slave_SQL_Runing都为yes说明同步成功,如果不为yes,请 检查error_Log,然后排查相关异常 
SHOW SLAVE STATUS

在上面的命令中, 第二条命令,其中的master_log_file='mysql-bin.000002', master_log_pos=584两个配置项就是根据上面标红部分叫你记下来的内容

验证

修改master中的user_db,如下:

 

打开slave中的user_db,我们发现,已经自动将修改后的结果同步过来了

至此,读写分离的MySQL环境已经搭建完毕

Sharding-jdbc代码实现

在application.properties中配置分片分库规则

# 端口号
server.port=56000
# 应用名称
spring.application.name=sharding_duxiefenli
# 表示spring中发现的bean会覆盖之前相同名称的bean
spring.main.allow-bean-definition-overriding=true
# 该配置项,将数据库中带有下划线的字段名称映射成驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true# 以下配置为sharding-jdbc分片规则配置# 1.定义数据源
#定义数据源名称
spring.shardingsphere.datasource.names=m0,s0
#order数据源连接数据库
spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://192.168.149.128:3316/user_db?useUnicode=true
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=123456
#user数据源连接数据库
spring.shardingsphere.datasource.s0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.s0.url=jdbc:mysql://192.168.149.128:3326/user_db?useUnicode=true
spring.shardingsphere.datasource.s0.username=root
spring.shardingsphere.datasource.s0.password=123456# 2.主库从库逻辑数据源定义ds0为user_db,指定谁是主库,谁是从库
spring.shardingsphere.sharding.master-slave-rules.ds0.masterDataSourceName=m0
spring.shardingsphere.sharding.master-slave-rules.ds0.slaveDataSourceNames=s0# 3.配置分片策略
spring.shardingsphere.sharding.tables.t_user.actualDataNodes=ds0.t_user
#分片键
spring.shardingsphere.sharding.tables.t_user.tableStrategy.inline.shardingColumn=user_id
#分片算法
spring.shardingsphere.sharding.tables.t_user.tableStrategy.inline.algorithmExpression=t_user# 4.配置主键生成策略
spring.shardingsphere.sharding.tables.t_user.keyGenerator.column=user_id
spring.shardingsphere.sharding.tables.t_user.keyGenerator.type=SNOWFLAKE# 5.指定,打开sharding-jdbc提供的sql输出日志配置
spring.shardingsphere.props.sql.show=true# 日志配置
logging.level.root=info
logging.level.org.springframework=info
logging.level.com.lcc=debug
logging.level.druid.sql=debug

userMapper代码如下:

@Mapper
public interface UserMapper {/*** 这里t_order就是sharding-jdbc中的逻辑表*/@Insert("insert into t_user(fullname,user_type) values(#{fullname},#{userType})")public int insertUser(@Param("fullname") String fullname,@Param("userType") String userType);@Select("<script>" +"select " +"* " +"from t_user t " +"where t.user_id in " +"<foreach collection='userIds' item='id' open='(' separator=',' close=')'>" +"#{id}" +"</foreach>" +"</script>")public List<Map> selectListByUserIds(@Param("userIds") List<Long> userIds);
}

测试代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingDuxiefenliApplicationTests {@Autowiredprivate UserMapper userMapper;@Testpublic void insertUserTest(){for (int i = 0; i < 10; i++) {userMapper.insertUser("lcc_duxiefenli_"+i,i+"");}}@Testpublic void selectUserTest(){List<Long> userIds = new ArrayList<>();userIds.add(1074769306459308033L);userIds.add(1074769306564165632L);List<Map> maps = userMapper.selectListByUserIds(userIds);for (Map map : maps) {System.out.println(map);}}
}

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

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

相关文章

基于前后端分离的食堂采购系统源码:从设计到开发的全流程详解

本篇文章&#xff0c;笔者将从系统设计到开发的全过程进行详解&#xff0c;帮助开发者和企业了解如何高效构建一套完善的食堂采购系统。 一、系统需求分析 在开发一套基于前后端分离的食堂采购系统前&#xff0c;必须对业务需求和功能模块进行详细分析&#xff0c;确保系统设…

第三十一章 Spring之假如让你来写事务——融入IOC容器篇

Spring源码阅读目录 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如让你来写IOC容器——加载资源篇 第三章 Spring之假如让你来写IOC容器——解析配置文件篇 第四章 Spring之假如让你来写IOC容器——XML配置文件篇 第五章 Spring之假如让你来写…

【笔记】记录一个python初见的语法(一)

在看书里的代码时了解了一个python的语法知识&#xff0c;是有关class类的。 代码如下&#xff1a; class Vocab: #save"""文本词表"""def __init__(self, tokensNone, min_freq0, reserved_tokensNone):if tokens is None:tokens []if rese…

LabVIEW面向对象编程有什么特点?

LabVIEW面向对象编程&#xff08;OOP&#xff09;的特点主要体现在它如何结合传统面向对象编程&#xff08;OOP&#xff09;的理念与LabVIEW的图形化编程模式&#xff0c;提供灵活的抽象和模块化的功能。以下是LabVIEW面向对象编程的几个主要特点&#xff1a; ​ 1. 类&#x…

【LC】240. 搜索二维矩阵 II

题目描述&#xff1a; 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,…

一级考试真题(2019)

一级考试真题&#xff08;2019&#xff09;

AudioSegment 将音频分割为指定长度时间片段 - python 实现

DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” -------------------------------------------------------------…

【kubernetes】k8s集群的简述与搭建

简述 Kubernetes&#xff08;简称 K8s&#xff09;是一个开源的容器编排平台&#xff0c;用于自动化部署、扩展和管理容器化应用程序 关键特性 自动化部署和回滚&#xff1a;Kubernetes 可以自动化地部署和回滚应用程序&#xff0c;确保应用程序始终处于预期的状态。服务发现…

C++ 内存管理和模板与STL

此篇目是之后各种C库的基础 目录 内存管理 内存分布 内存管理方式 new和delete operator new 与 operator delete函数 实现原理 定位new表达式(placement-new) 模板基础 泛型编程 模板 函数模板 类模板 STL 组成部分 内存管理 内存分布 int globalVar 1; //全局变量 静…

在 Ubuntu 24.04.1 LTS (WSL) 中使用 openssl 生成 keybox.xml

看到“生成 keybox.xml”&#xff0c;大概率都会联想到 PIF 和 Tricky Store。这里就不多解释它们的用途了。最近在网上看到生成非 AOSP keybox 的教程&#xff0c;在这里做一些补充&#xff0c;并将代码打包成一个 Python 脚本。 参考自&#xff1a; Idea 提供者&#xff1a…

Redis篇-1--入门介绍

1、Redis概述 ‌Redis&#xff08;Remote Dictionary Server&#xff09;&#xff0c;全称为远程字典服务。‌是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。 Redis提供了多种数据类型的存储&#xff0c;来适应不同场景下的存储需…

antdv-<a-button>中属性的使用

UI组件库&#xff08;User Interface Component Library&#xff09;是一种预先构建好的、可重用的用户界面元素集合&#xff0c;旨在帮助开发者更快速、更简便地构建用户界面。这些组件通常包括按钮、表单、导航栏、模态框等&#xff0c;能够提供一致的外观和交互风格&#xf…

简单的多网卡选择指定网卡ip注册

简单的多网卡选择指定网卡ip注册 我们公司服务器上面有多个网卡&#xff0c;多网卡则本地ip有多个ip,我们启动服务的时候需要选定他特定的ip&#xff0c;我们服务需要特定的ip进行注册&#xff0c;才能进行正常的通讯功能&#xff0c;我们需要使用如下配置进行特定ip选择&…

鸿蒙NEXT开发案例:颜文字搜索器

【引言】 本文将介绍一个名为“颜文字搜索器”的开发案例&#xff0c;该应用是基于鸿蒙NEXT平台构建的&#xff0c;旨在帮助用户快速查找和使用各种风格的表情符号。通过本案例的学习&#xff0c;读者可以了解如何在鸿蒙平台上进行数据处理、UI设计以及交互逻辑的实现。 【环…

快速部署一套K8s集群-v1.28

快速部署一套K8s集群-v1.28 1.前置知识点 1.1 生产环境可部署Kubernetes集群的两种方式 目前生产部署Kubernetes集群主要有两种方式: kubeadmKubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。 二进制包从github下载发行版的二进…

【硬件测试】基于FPGA的4ASK调制解调通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR

目录 1.算法仿真效果 2.算法涉及理论知识概要 3.Verilog核心程序 4.开发板使用说明和如何移植不同的开发板 5.完整算法代码文件获得 1.算法仿真效果 本文是之前写的文章: 《基于FPGA的4ASK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR》 的…

用友U8+ API接口使用教程

前言 U8和其他的公开的开放API接口有一些差异&#xff0c;他是需要先对接的到代理服务器&#xff0c;通过代理服务器进行对接&#xff0c;所以只要保证U8能上网就能对接&#xff0c;和畅捷通T的模式有点类似 流程&#xff1a; 注册成为开发者&#xff08;用于创建用友U8 API应…

检查读取数据寄存器输出的多扇出

为使第二寄存器被 RAM 原语吸收&#xff0c;来自存储器阵列的数据输出位的扇出必须为 1 。这在下图中进行了说明。 检查地址 / 读取数据寄存器上的复位信号 不应复位存储器阵列。只有 RAM 的输出可以容许复位。复位必须是同步的&#xff0c;以便将输出寄存器推断到 RAM 基元…

MongoDB-ObjectID 生成器

前言 MongoDB中一个非常关键的概念就是 ObjectID&#xff0c;它是 MongoDB 中每个文档的默认唯一标识符。了解 ObjectID 的生成机制不仅有助于开发人员优化数据库性能&#xff0c;还能帮助更好地理解 MongoDB 的设计理念。 什么是 MongoDB ObjectID&#xff1f; 在 MongoDB …

渗透测试工具 -- SQLmap安装教程及使用

随着网络安全问题日益严峻&#xff0c;渗透测试成为了保护信息安全的重要手段。而在渗透测试的众多工具中&#xff0c;SQLmap凭借其强大的自动化SQL注入检测和利用能力&#xff0c;成为了网络安全专家必备的利器。那么&#xff0c;你知道如何高效地使用SQLmap进行漏洞扫描吗&am…