mysql操作语句与事务
数据库设计范式
数据库设计的三大范式
-
第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项,即列中的每个值都应该是单一的、不可分割的实体。例如,如果一个表中的“地址”列包含了省、市、区等多个信息,那么这就不符合第一范式,需要将地址拆分为多个列,如“省份”、“城市”和“详细地址”。
-
第二范式(2NF):在满足第一范式的基础上,要求数据库表中的每一列都必须完全依赖于主键,而不是仅仅依赖于主键的一部分。这意味着表中的每一行数据都可以被唯一标识,并且非主键列必须完全依赖于整个主键,而不是主键的某一部分。
-
第三范式(3NF):在满足第二范式的基础上,要求数据库表中的每一列数据都必须直接依赖于主键,而不能间接依赖。这有助于进一步减少数据冗余,提高数据的独立性和一致性。
数据库设计范式的作用和好处
- 减少数据冗余:通过范式设计,可以确保每个属性只存储一次,避免了数据的重复存储。
- 增加数据完整性:范式设计确保了数据的依赖关系清晰,减少了数据不一致的情况。
- 简化数据修改操作:通过合理的表结构设计,可以简化数据的插入、删除和更新操作,提高数据库的维护效率。
sql操作
sql指令有如下几种
-
DDL(Data Definition Language):数据定义语言,用于定义数据库对象,包括数据库、表、字段等。主要操作包括创建、修改和删除数据库和表。例如,创建数据库的语句为
CREATE DATABASE database_name,创建表的语句为CREATE TABLE table_name (column1 datatype, column2 datatype, ...)。 -
DML(Data Manipulation Language):数据操作语言,用于对数据库表中的数据进行增删改操作。主要包括
INSERT(插入)、DELETE(删除)、UPDATE(更新)等语句。例如,插入数据的语句为INSERT INTO table_name (column1, column2) VALUES (value1, value2)。 -
DQL(Data Query Language):数据查询语言,用于查询数据库中的记录。主要语句为
SELECT,用于从表中检索数据。例如,查询表中所有记录的语句为SELECT * FROM table_name。 -
DCL(Data Control Language):数据控制语言,用于控制数据库的用户权限和安全设置。主要包括
GRANT(授权)、REVOKE(撤销权限)等语句。例如,授权用户访问表的语句为GRANT SELECT ON database.table TO 'username'@'host';
DDL语句
新建表 create table
CREATE TABLE `test_db` (
`id` bigint(20) UNSIGNED NOT NULL COMMENT 'id',
`price` int(8) NOT NULL COMMENT '价格',
`name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '名字',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '测试表' ROW_FORMAT = Compact;
新建表后的结构

修改表
增加列“test” 类型为varchar
ALTER TABLE test_db
ADD COLUMN test VARCHAR(255);
结构

可以看到多了个test列 类型为 varchar
修改字段类型
把表test_db test列修改成 int类型
ALTER TABLE test_db
MODIFY COLUMN test INT;
结构

可以看到test列类型修改成了int类型
修改列的名字且修改类型成varchar
ALTER TABLE test_db
CHANGE COLUMN test test_update VARCHAR(255);
修改后结构

删除列
ALTER TABLE test_db
DROP COLUMN test_update;
删除后结构

删除表
现在表结构及数据

删除表中所有的数据 TRUNCATE TABLE test_db
TRUNCATE TABLE test_db;
清除后

表还存在但是之前的数据全部被清除
删除表结构及数据
原表结构及数据

DROP TABLE IF EXISTS test_db;
再次查看表数据

可以看到表已被删除
DML语句
首先新建一张表
DROP TABLE IF EXISTS `test_db`;
CREATE TABLE `test_db` (
`id` bigint(20) UNSIGNED NOT NULL COMMENT 'id',
`price` int(8) NOT NULL COMMENT '价格',
`name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '名字',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '测试表' ROW_FORMAT = Compact;
插入新增数据
INSERT INTO test_db (id, price,name) VALUES (1, 3, "测试");
插入后数据

修改数据
UPDATE test_db SET id = 3, price = 30, name="33" WHERE id = 1;
修改后表数据

删除部分数据
DELETE FROM test_db where id=3;
删除后表数据

事务
特点
事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
而且事务有个很重要的特点,简称ACID
ACID代表原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)
-
原子性(Atomicity):原子性确保事务中的所有操作要么全部完成,要么全部不执行。事务是不可分割的最小工作单元,如果事务中的任何操作失败,整个事务都会回滚到事务开始之前的状态。
-
一致性(Consistency):一致性确保事务将数据库从一个一致的状态转变到另一个一致的状态。这意味着数据库在事务开始之前和完成之后都必须遵守所有的业务规则、完整性约束等。如果事务违反了这些规则,整个事务将被回滚,数据库将保持之前的一致状态12。
-
隔离性(Isolation):隔离性确保并发事务的执行不会互相干扰。事务应该独立于彼此运行,使得它们不能看到彼此的中间状态。数据库系统通常通过锁定对象来实现隔离性,根据不同的隔离级别,事务可以看到其他事务的提交或未提交的更改。
-
持久性(Durability):持久性确保一旦事务被提交,它对数据库的改变就是永久性的。即使系统出现故障,如崩溃或电源故障,事务的效果也不会丢失。数据库通过将事务日志记录到非易失存储介质来实现持久性。
这些特性共同作用,确保数据库在面对各种操作时能够保持数据的完整性和一致性。ACID属性是关系型数据库管理系统(RDBMS)的基石,使得数据库能够在出现故障或错误时保持数据的完整性和可靠性
常见事务问题
在开发过程中,有多个线程同时对db操作时会出现并发事务问题:脏读、不可重复读、幻读
| 问题 | 描述 |
| 脏读 | 一个事务读到另外一个事务还没有提交的数据。 |
| 不可重复读 | 一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。 |
| 幻读 | 一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了”幻影”。 |
为了应对这种情况,mysql有如下几类事务隔离级别
- 读未提交(Read Uncommitted):最低级别的隔离,允许事务读取未提交的数据,可能会导致脏读、不可重复读和幻读。
- 读已提交(Read Committed):允许事务读取已经提交的数据,可以避免脏读,但可能会导致不可重复读和幻读。
- 可重复读(Repeatable Read):确保在同一事务中多次读取相同的数据,可以避免脏读和不可重复读,但可能会出现幻读。这是MySQL的默认隔离级别。
- 串行化(Serializable):最高的隔离级别,强制事务串行执行,避免脏读、不可重复读和幻读,但可能会影响并发性能。
除了设置事务隔离级别,还有其它的解决办法
解决脏读:
还可以加锁
解决不可重复读:
1,可以加表锁和行锁使得给定行数据不会被其它的事务修改,但是但在高并发的场景下可能会影响性能
START TRANSACTION;
SELECT * FROM table_name WHERE condition FOR UPDATE; 行级锁
-- 在此期间,其他事务无法修改这些行
COMMIT;LOCK TABLES table WRITE; 表级锁
-- 进行一些操作 在此期间,其他事务无法修改这张表
UNLOCK TABLES;
2,乐观锁,版本号,在表中添加一个版本号字段,每次数据更新时增加版本号。在读取数据时获取版本号,更新数据时检查版本号是否改变
START TRANSACTION;
SELECT version FROM table WHERE id = 1; -- 获取当前版本号
UPDATE table SET data = 'new_data', version = version + 1 WHERE id = 1 AND version = <当前版本号>;
IF ROW_COUNT() = 0 THEN-- 版本号已改变,处理冲突或回滚ROLLBACK;
ELSECOMMIT;
END IF;
3,时间戳,类似于版本号,使用时间戳字段来检测数据是否被其他事务修改。更新时检查时间戳是否相同
START TRANSACTION;
SELECT timestamp FROM table WHERE id = 1; -- 获取当前时间戳
UPDATE table SET data = 'new_data', timestamp = NOW() WHERE id = 1 AND timestamp = <当前时间戳>;
IF ROW_COUNT() = 0 THEN-- 时间戳已改变,处理冲突或回滚ROLLBACK;
ELSECOMMIT;
END IF;
解决幻读:
1,排他锁 SELECT ... FOR UPDATE
2,共享锁 SELECT ... LOCK IN SHARE MODE
3,使用间隙锁(Gap Locks)和临键锁(Next-Key Locks)
操作演示
首先看看mysql当前默认隔离级别
SELECT @@transaction_isolation;

可以看到隔离级别为可重复读(Repeatable Read)
读未提交
修改事务隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT @@transaction_isolation;
脏读
1,会话1session 开启事务查询数据
START TRANSACTION;
select * from test_db;

2,会话2session 开启事务增加条数据
START TRANSACTION;
INSERT INTO test_db (id, price,name) VALUES (133, 1, "增加条数据");
3,会话1session 查询表数据

此时会话1看到了事务2未提交的数据13,出现了脏读
不可重复读
1,事务1开启查询id=13的数据
START TRANSACTION;
select * from test_db where id=13;

2,事务2修改id=13的price=30
START TRANSACTION;
UPDATE test_db SET price = 30 WHERE id = 13;
3,事务1查看id=13的表数据

此时出现了不可重复读:前后两次查询数据不一致
幻读
1,事务1开启 进行范围查询
START TRANSACTION;
select * from test_db where id>32;
2,事务2插入新数据id=161
START TRANSACTION;
INSERT INTO test_db (id, price,name) VALUES (161, 1, "增加条数据");
3,事务1再次范围查询 id>32的数据

此时出现了幻读,本来没有id=161的数据,再次查询出现了id=161的数据
读已提交
修改事务隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED ;
SELECT @@transaction_isolation;
脏读
1,事务1开启查询数据
START TRANSACTION;
select * from test_db;

2,事务2开启增加表数据 id=15 不提交事务
START TRANSACTION;
INSERT INTO test_db (id, price,name) VALUES (191, 39, "增加条数据");
3,事务1再次查看数据

可以看到未读取到事务2未提交的数据
4,事务2提交
commit;
5,事务1再次查看数据

可以看到当事务2提交了,事务1才可以看到新增的数据
所以当前隔离级别没有脏读问题
不可重复读
1,事务1开启查看数据id=13
START TRANSACTION;
select * from test_db where id=13;

2,事务2开启修改id=13的数据 price=13
START TRANSACTION;
UPDATE test_db SET price = 13 WHERE id = 13;
commit;
3,事务1再次查看数据id=13

此时两次数据不一致,出现了不可重复读
幻读
1,事务1开启范围查询
START TRANSACTION;
select * from test_db where id>30 and id<35;
2,事务2插入id=33数据
START TRANSACTION;
INSERT INTO test_db (id, price,name) VALUES (33, 39, "增加条数据");
3,事务1再次进行范围查询

此时同一事务范围查询中出现了原来没有的数据行,即幻读
可重复读
现在来演示下在可重复读下各类事务问题
脏读:
会话1session 开启事务插入一条数据
START TRANSACTION;
INSERT INTO test_db (id, price,name) VALUES (3, 1, "测试");
会话1session查看表数据

可以看到多了条数据
会话2session查看表数据

可以看到会话2看不到会话1未提交的事务插入的数据
会话1提交事务
commit;
会话2查看表数据

可以看到会话2可以看到会话1提交事务后插入的数据
所以可重复读(Repeatable Read)解决了脏读的问题
不可重复读:
会话1session开启事务且读且表数据
START TRANSACTION;
select * from test_db;

会话2session开启事务且进行插入数据再查看数据提交事务
START TRANSACTION;
INSERT INTO test_db (id, price,name) VALUES (7, 1, "3");
INSERT INTO test_db (id, price,name) VALUES (11, 1, "3");
select * from test_db;
commit

可以看到会话2多了2条数据
会话1再次查看数据 此时会话1还未提交事务

可以看到会话1在事务哪看到的数据还是3条和原来保持相同
这样即解决了不可重复读(事务内两次看到的数据不同的问题)
幻读:
原表数据

业务操作:当id=31的表数据不存在的时候插入一条数据id=31
正常情况下:
会话1session开启事务条件查询 id=31的数据
START TRANSACTION;
select * from test_db where id=31;
查询表数据为空

此时会话1增加一条数据
INSERT INTO test_db (id, price,name) VALUES (31, 1, "正常情况下增加表数据");

多线程多事务操作:当id=32的表数据不存在的时候插入一条数据id=32
1,会话1session查询id=32的数据
START TRANSACTION;
select * from test_db where id=32;
数据为空

2,事务2开启插入id=32的数据
START TRANSACTION;
INSERT INTO test_db (id, price,name) VALUES (32, 1, "多事务情况下增加表数据");
select * from test_db where id=32;

事务2看到新增的数据 成功新增数据
3,事务1插入数据
INSERT INTO test_db (id, price,name) VALUES (32, 1, "多事务情况下增加表数据");

此时出现了幻读现象
select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。
因此可重复读会出现幻读现象
串行化
修改数据隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT @@transaction_isolation;

幻读
1,事务1开启查询数据
START TRANSACTION;
select * from test_db;

2,事务2开启插入数据

此时事务2被锁住
3,事务1提交
commit;
4,此时锁被释放,事务2插入数据执行成功

此时,在事务1开启的情况下,事务2无法进行修改和删除操作,脏读、不可重复读、幻读均被解决
实际应用场景
- 读未提交:适用于对数据一致性要求不高的场景,如某些实时分析系统。
- 读已提交:适用于对数据一致性要求较高的场景,如银行系统的查询操作。
- 可重复读:适用于需要确保数据一致性的场景,如银行系统的转账操作。
- 串行化:适用于对数据一致性要求极高且可以接受较低并发性能的场景。
springboot事务传播机制
在Spring Boot中,事务管理是一个非常重要的特性,它可以帮助你确保数据的一致性和完整性。Spring Boot使用Spring框架的声明式事务管理功能,这使得通过注解的方式来管理事务变得非常简单和直观。Spring事务的传播行为(Propagation behavior)是指在同一个方法的不同调用中,如何共享事务的上下文。
Spring事务的传播行为类型
Spring定义了多种事务传播行为,每种行为定义了事务应该如何开始,以及如何在不同的事务边界之间进行交互。以下是一些常见的事务传播行为:
-
REQUIRED(默认):支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
-
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
-
MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
-
REQUIRES_NEW:总是新建一个新的事务,并且挂起当前事务(如果存在的话)。
-
NOT_SUPPORTED:不使用事务,如果当前存在事务,则挂起该事务。
-
NEVER:不使用事务,如果当前存在事务,则抛出异常。
-
NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则其行为与REQUIRED类似。
DEFAULT(-1),READ_UNCOMMITTED(1),READ_COMMITTED(2),REPEATABLE_READ(4),SERIALIZABLE(8);
@Transactional(isolation=Isolation.DEFAULT) //以全局数据库隔离级别为主
@Transactional(isolation=Isolation.READ_UNCOMMITTED) //读未提交
@Transactional(isolation=Isolation.READ_COMMITTED) //读已提交
@Transactional(isolation=Isolation.REPEATABLE_READ) //可重复读
@Transactional(isolation=Isolation.SERIALIZABLE) //串行化
REQUIRED(默认)
情况一:
@Override@Transactional(propagation = Propagation.REQUIRED)public Result methodA(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("测试下");user_test.setPhone("131");user_test.setPassword("3");save(user_test);methodB(phone,session);int value = 1/0;
}public Result methodB(String phone, HttpSession session) {return Result.ok();}
这里methodA出现了异常导致数据库回滚
表中不会增加数据
此时把异常的语句改到未加入事务的方法中
情况二:
@Override@Transactional(propagation = Propagation.REQUIRED)public Result methodA(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("测试下");user_test.setPhone("131");user_test.setPassword("3");save(user_test);methodB(phone,session);
}public Result methodB(String phone, HttpSession session) {int value = 1/0;return Result.ok();}
这里methodB出现了异常,由于事务机制设置了REQUIRED(默认):支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。methodB无事务,但被有事务的methodA调用了,所以methodB加入methodA事务,所以methodB和methodA处于同个事务
情况三:修改事务注解方法
@Overridepublic Result methodA(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("测试下");user_test.setPhone("131");user_test.setPassword("3");save(user_test);methodB(phone,session);
}@Transactional(propagation = Propagation.REQUIRED)
public Result methodB(String phone, HttpSession session) {int value = 1/0;return Result.ok();}
此时数据仍然会插入成功,methodA无事务而且无事务注解,所以无论是否有异常,都不会回滚,methodB判断无事务所以会开启事务,此时methodB抛出异常了,不会影响到methodA,所以数据会插入成功
这两个函数处于同个事务,无论在哪里异常了,都会回滚不插入数据
情况四:
@Override
@Transactional(propagation = Propagation.REQUIRED)public Result methodA(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("A");user_test.setPhone("133333333");user_test.setPassword("3");save(user_test);methodB(phone,session);
}@Transactional(propagation = Propagation.REQUIRED)
public Result methodB(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("B");user_test.setPhone("1333333331");user_test.setPassword("3");save(user_test);int value = 1/0;return Result.ok();}
此时数据不会插入,methodA无事务但有事务注解,会新建个事务,methodB有事务注解且判断当前有事务,会加入事务和methodB共用同个事务,此时methodB抛出异常了,两条数据均不会插入
这两个函数处于同个事务,无论在哪里异常了,都会回滚不插入数据
SUPPORTS
情况一:
@Override
@Transactional(propagation = Propagation.SUPPORTS)public Result methodA(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("A");user_test.setPhone("133333333");user_test.setPassword("3");save(user_test);methodB(phone,session);
}@Transactional(propagation = Propagation.SUPPORTS)
public Result methodB(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("B");user_test.setPhone("1333333331");user_test.setPassword("3");save(user_test);int value = 1/0;return Result.ok();}
methodA无事务但有事务注解,会已无事务来执行函数,methodB无事务但有事务注解,会已无事务来执行函数,则会插入两条数据


情况二:
@Override
@Transactional(propagation = Propagation.REQUIRED)public Result methodA(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("A");user_test.setPhone("133333333");user_test.setPassword("3");save(user_test);methodB(phone,session);
}@Transactional(propagation = Propagation.SUPPORTS)
public Result methodB(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("B");user_test.setPhone("1333333331");user_test.setPassword("3");save(user_test);int value = 1/0;return Result.ok();}
此时不会插入数据,methodA有事务注解判断无事物则新建事务,methodB判断当前有事务则加入当前事务,抛出异常了,两个方法都会回滚
MANDATORY
情况一:
@Override
@Transactional(propagation = Propagation.REQUIRED)public Result methodA(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("A");user_test.setPhone("133333333");user_test.setPassword("3");save(user_test);methodB(phone,session);
}@Transactional(propagation = Propagation.MANDATORY)
public Result methodB(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("B");user_test.setPhone("1333333331");user_test.setPassword("3");save(user_test);int value = 1/0;return Result.ok();}
此时不会插入数据,methodA有事务注解判断无事物则新建事务,methodB判断当前有事务则加入当前事务,抛出异常了,两个方法都会回滚
情况二:
@Overridepublic Result methodA(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("A");user_test.setPhone("133333333");user_test.setPassword("3");save(user_test);methodB(phone,session);int value = 1/0;}@Transactional(propagation = Propagation.MANDATORY)
public Result methodB(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("B");user_test.setPhone("1333333331");user_test.setPassword("3");save(user_test);return Result.ok();}
此时不会插入数据,methodA有事务注解判断无事物则新建事务,methodB判断当前有事务则加入当前事务,抛出异常了,两个方法都会回滚
情况三:
@Override
@Transactional(propagation = Propagation.SUPPORTS)public Result methodA(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("A");user_test.setPhone("133333333");user_test.setPassword("3");save(user_test);methodB(phone,session);int value = 1/0;}@Transactional(propagation = Propagation.MANDATORY)
public Result methodB(String phone, HttpSession session) {User user_test = new User();user_test.setUserName("B");user_test.setPhone("1333333331");user_test.setPassword("3");save(user_test);return Result.ok();}
此时都会插入数据,methodA有事务注解判断无事物则以无事务来执行,methodB有事务注解判断当前无事务
REQUIRES_NEW
总是创建一个新的事务,如果当前存在事务,则挂起当前事务
NOT_SUPPORTED
以非事务的方式执行操作,如果当前存在事务,则挂起当前事务。这种传播类型说明方法都是非事务的,不管外层有没有事务
NEVER
以非事务的方式执行操作,如果当前存在事务,则抛出异常
NESTED
如果当前存在事务,则在当前事务中创建一个新的嵌套事务;如果当前没有事务,则创建一个新的任务
相关文章:
mysql操作语句与事务
数据库设计范式 数据库设计的三大范式 第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项,即列中的每个值都应该是单一的、不可分割的实体。例如,如果一个表中的“地址”列包含了省、市、区等多个信息…...
android Camera 的进化
引言 Android 的camera 发展经历了3个阶段 : camera1 -》camera2 -》cameraX。 正文 Camera1 Camera1 的开发中,打开相机,设置参数的过程是同步的,就跟用户实际使用camera的操作步骤一样。但是如果有耗时情况发生时,会…...
ASP.NET Core Filter
目录 什么是Filter? Exception Filter 实现 注意 ActionFilter 注意 案例:自动启用事务的筛选器 事务的使用 TransactionScopeFilter的使用 什么是Filter? 切面编程机制,在ASP.NET Core特定的位置执行我们自定义的代码。…...
Git 的起源与发展
序章:版本控制的前世今生 在软件开发的漫长旅程中,版本控制犹如一位忠诚的伙伴,始终陪伴着开发者们。它的存在,解决了软件开发过程中代码管理的诸多难题,让团队协作更加高效,代码的演进更加有序。 简单来…...
基于SpringBoot电脑组装系统平台系统功能实现五
一、前言介绍: 1.1 项目摘要 随着科技的进步,计算机硬件技术日新月异,包括处理器(CPU)、主板、内存、显卡等关键部件的性能不断提升,为电脑组装提供了更多的选择和可能性。不同的硬件组合可以构建出不同类…...
【智力测试——二分、前缀和、乘法逆元、组合计数】
题目 代码 #include <bits/stdc.h> using namespace std; using ll long long; const int mod 1e9 7; const int N 1e5 10; int r[N], c[N], f[2 * N]; int nr[N], nc[N], nn, nm; int cntr[N], cntc[N]; int n, m, t;void init(int n) {f[0] f[1] 1;for (int i …...
第 1 天:UE5 C++ 开发环境搭建,全流程指南
🎯 目标:搭建 Unreal Engine 5(UE5)C 开发环境,配置 Visual Studio 并成功运行 C 代码! 1️⃣ Unreal Engine 5 安装 🔹 下载与安装 Unreal Engine 5 步骤: 注册并安装 Epic Game…...
axios如何利用promise无痛刷新token
目录 需求 需求解析 实现思路 方法一: 方法二: 两种方法对比 实现 封装axios基本骨架 instance.interceptors.response.use拦截实现 问题和优化 如何防止多次刷新token 同时发起两个或以上的请求时,其他接口如何重试 最后完整代…...
玉米苗和杂草识别分割数据集labelme格式1997张3类别
数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):1997 标注数量(json文件个数):1997 标注类别数:3 标注类别名称:["corn","weed","Bean…...
【自学笔记】GitHub的重点知识点-持续更新
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 GitHub使用指南详细知识点一、GitHub基础与账户管理1. GitHub简介2. 创建与管理GitHub账户3. 创建与配置仓库(Repository) 二、Git基础与Git…...
string例题
一、字符串最后一个单词长度 题目解析:由题输入一段字符串或一句话找最后一个单词的长度,也就是找最后一个空格后的单词长度。1.既然有空格那用我们常规的cin就不行了,我们这里使用getline,2.读取空格既然是最后一个空格后的单词,…...
算法基础——一致性
引入 最早研究一致性的场景既不是大数据领域,也不是分布式系统,而是多路处理器。 可以将多路处理器理解为单机计算机系统内部的分布式场景,它有多个执行单元,每一个执行单元都有自己的存储(缓存),一个执行单元修改了…...
【数据采集】案例01:基于Scrapy采集豆瓣电影Top250的详细数据
基于Scrapy采集豆瓣电影Top250的详细数据 Scrapy 官方文档:https://docs.scrapy.org/en/latest/豆瓣电影Top250官网:https://movie.douban.com/top250写在前面 实验目的:基于Scrapy框架采集豆瓣电影Top250的详细数据。 电脑系统:Windows 使用软件:PyCharm、Navicat Python…...
设计模式 - 行为模式_Template Method Pattern模板方法模式在数据处理中的应用
文章目录 概述1. 核心思想2. 结构3. 示例代码4. 优点5. 缺点6. 适用场景7. 案例:模板方法模式在数据处理中的应用案例背景UML搭建抽象基类 - 数据处理的 “总指挥”子类定制 - 适配不同供应商供应商 A 的数据处理器供应商 B 的数据处理器 在业务代码中整合运用 8. 总…...
Spring Boot框架下的单元测试
1. 什么是单元测试 1.1 基本定义 单元测试(Unit Test) 是对软件开发中最小可测单位(例如一个方法或者一个类)进行验证的一种测试方式。在 Java 后端的 Spring Boot 项目中,单元测试通常会借助 JUnit、Mockito 等框架对代码中核心逻辑进行快…...
git中文件的状态状态切换
在 Git 中,文件的状态是指文件相对于 Git 仓库的当前情况。以下是一些常见的文件状态及其含义: 未跟踪(Untracked): 这是新创建的文件或从其他位置复制过来的文件,Git 还没有开始跟踪这些文件的更改。 这些…...
基于脉冲响应不变法的IIR滤波器设计与MATLAB实现
一、设计原理 脉冲响应不变法是一种将模拟滤波器转换为数字滤波器的经典方法。其核心思想是通过对模拟滤波器的冲激响应进行等间隔采样来获得数字滤波器的单位脉冲响应。 设计步骤: 确定数字滤波器性能指标 将数字指标转换为等效的模拟滤波器指标 设计对应的模拟…...
RabbitMQ快速上手及入门
概念 概念: publisher:生产者,也就是发送消息的一方 consumer:消费者,也就是消费消息的一方 queue:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理 exchang…...
自动化构建-make/Makefile 【Linux基础开发工具】
文章目录 一、背景二、Makefile编译过程三、变量四、变量赋值1、""是最普通的等号2、“:” 表示直接赋值3、“?” 表示如果该变量没有被赋值,4、""和写代码是一样的, 五、预定义变量六、函数**通配符** 七、伪目标 .PHONY八、其他常…...
计算机网络之计算机网络的分类
计算机网络可以根据不同的角度进行分类,以下是几种常见的分类方式: 1. 按照规模和范围: 局域网(LAN,Local Area Network):覆盖较小范围(例如一个建筑物或校园)…...
MySQl的日期时间加
MySQL日期相关_mysql 日期加减-CSDN博客MySQL日期相关_mysql 日期加减-CSDN博客 raise notice 查询目标 site:% model:% date:% target:%,t_shipment_date.site,t_shipment_date.model,t_shipment_date.plant_date,v_date_shipment_qty_target;...
响应式编程与协程
响应式编程与协程的比较 响应式编程的弊端虚拟线程Java线程内核线程的局限性传统线程池的demo虚拟线程的demo 响应式编程的弊端 前面用了几篇文章介绍了响应式编程,它更多的使用少量线程实现线程间解耦和异步的作用,如线程的Reactor模型,主要…...
智能小区物业管理系统推动数字化转型与提升用户居住体验
内容概要 在当今快速发展的社会中,智能小区物业管理系统的出现正在改变传统的物业管理方式。这种系统不仅仅是一种工具,更是一种推动数字化转型的重要力量。它通过高效的技术手段,将物业管理与用户居住体验紧密结合,无疑为社区带…...
从Proxmox VE开始:安装与配置指南
前言 Proxmox Virtual Environment (Proxmox VE) 是一个开源的虚拟化平台,基于Debian Linux,支持KVM虚拟机和LXC容器。它提供了一个强大的Web管理界面,方便用户管理虚拟机、存储、网络等资源。Proxmox VE广泛应用于企业级虚拟化、云计算和开…...
【Docker项目实战】使用Docker部署MinIO对象存储(详细教程)
【Docker项目实战】使用Docker部署MinIO对象存储 前言一、 MinIO介绍1.1 MinIO简介1.2 主要特点1.3 主要使用场景二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、下载MinIO镜像五、…...
【C++】B2115 密码翻译
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目解析💯1. 老师的做法代码实现:思路解析: 💯2. 我的做法代码实现:思路分析: 💯3. 老师…...
02.04 数据类型
请写出以下几个数据的类型: 整数 a ----->int a的地址 ----->int* 存放a的数组b ----->int[] 存放a的地址的数组c ----->int*[] b的地址 ----->int* c的地址 ----->int** 指向printf函数的指针d ----->int (*)(const char*, ...) …...
Leetcode—598. 区间加法 II【简单】
2025每日刷题(206) Leetcode—598. 区间加法 II 实现代码 class Solution { public:int maxCount(int m, int n, vector<vector<int>>& ops) {int ans m * n;int x ops.size();if(ops.empty()) {return ans;}int xm ops[0][0], ym …...
AI浪潮下的IT从业者:危机、机遇与进化之路
目录 0. 前言1. 当前形势:站在十字路口1.1 AI的突飞猛进1.2 行业现状分析 2. 核心应对策略2.1 技术深度与广度的平衡2.2 人机协同的工作模式2.3 持续学习与创新 3. 结语 0. 前言 在人工智能快速发展的今天,IT从业者面临前所未有的挑战与机遇。本文将从实…...
OpenCV:图像轮廓
目录 简述 1. 什么是图像轮廓? 2. 查找图像轮廓 2.1 接口定义 2.2 参数说明 2.3 代码示例 2.4 运行结果 3. 绘制图像轮廓 3.1 接口定义 3.2 参数说明 3.3 代码示例 3.4 运行结果 4. 计算轮廓周长 5. 计算轮廓面积 6. 示例:计算图像轮廓的面…...



