MySQL:事务的理解

news2025/4/19 15:16:18

一、CURD不加控制,会有什么问题 

(1)因为,MySQL里面存的是数据,所以很有可能会被多个客户访问,所以mysqld可能一次会接受到多个关于CURD的请求。(2)且mysql内部是采用多线程来完成数据存储等相关工作的,所以必然会存在对数据并发访问的场景      ——>会导致一些多请求并发可能产生的异常结果

       比如同行转账,按道理是我减100,你加100,但是因为我是同行所以用的是一张数据库的表,可能我减100的时候还没做完网络或者数据库出问题等其他原因导致没有给你加100,那么整个操作就会出现一个中间过程(我减了但是你没有加),这就有问题,在这种情况下我们允许异常产生,一旦操作没有完成我们应该把减掉的100再加回来,就好像什么都没做,等待下次合适的时候再去转账。这就相当于转账之后不要有中间过程,而是在转的时候一旦出现异常就直接进行回滚,因为不回滚的话就会有问题,必须得回滚保证和初始的状态一样,这就叫我们的回滚操作。在高并发的场景下数据或多或少都会出现这样的问题,所以这也就要求mysql必须要有针对这类问题的解决方案。

二、CURD满足什么属性,能解决上述问题?

1. 买票的过程得是原子的吧(要么不抢,要么抢到,出现中间状态会回滚)

2. 买票互相应该不能影响吧(我买的时候你正好过来,我的行为不能影响你,也就是彼此之间得是割裂的)

3. 买完票应该要永久有效吧 ( 购买成功这个情况必须得做持久化 )

4. 买前,和买后都要是确定的状态吧(买前就是没买,买后就是买了,不允许有不确定的状态)

三、什么是事务?

       事务就是一组DML语句组成,这些语句在逻辑上存在相关性(单独一条是没有意义的,比如转账就应该至少有两条sql语句,即我减100,你加100,整体在一起才有转账逻辑,所以事务一定要站在mysql的上层去看待sql语句,具体完成一个由多条sql语句构成的应用层功能,在业务上有具体含义的动作),这一组DML语句要么全部成功,要么全部失败,是一个整体。MySQL提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的数据是不相同的。

    事务就是要做的或所做的事情,主要用于处理操作量大,复杂度高的数据。假设一种场景:你毕业了,学校的教务系统后台 MySQL 中,不再需要你的数据,要删除你的所有信息(一般不会:) ), 那么要删除你的基本信息(姓名,电话,籍 贯等)的同时,也删除和你有关的其他信息,比如:你的各科成绩,你在校表现,甚至你在论坛发过的文章等。这样,就需要多条 MySQL 语句构成,那么所有这些操作合起来,就构成了一个事务。

      正如我们上面所说,一个 MySQL 数据库,可不止你一个事务在运行,同一时刻,甚至有大量的请求被包装成事务, 在向 MySQL 服务器发起事务处理请求。而每条事务至少一条 SQL ,最多很多 SQL ,这样如果大家都访问同样的表数据,在不加保护的情况,就绝对会出现问题。甚至,因为事务由多条 SQL 构成,那么,也会存在执行到一半出错或者 不想再执行的情况,那么已经执行的怎么办呢 ? 

      所以,一个完整的事务,绝对不是简单的sql集合,还需要满足如下四个属性:

1、原子性一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过 一样。

2、一致性在事务开始之前和事务结束以后,数据库的完整性没有被破坏。(一种状态变为另一种状态结果是可预期的)这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

3、隔离性数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交( Read uncommitted )、读提交 ( read committed )、可重复读( repeatable read )和串行化( Serializable )

4、持久性事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

mysql从技术上只要保证了134,就可以做到2,所以134是因 2是果(还需要上层用户配合) 

上面四个属性,可以简称为 ACID 。

原子性(Atomicity,或称不可分割性)

一致性(Consistency)

隔离性(Isolation,又称独立性)

持久性(Durability)

        mysql需要帮不同的客户端处理不同的事务请求,所以运行期间在自身内部必然存在大量的事务,所以他必须得将事务按照先描述后组织的形式管理起来,所以mysql会把这些事务打包描述成对象,然后放入到事务执行列表里,并帮我们解决一系列执行事务时可能出现的问题

四、为什么会有事务

       事务被 MySQL 编写者设计出来(不是天然就有的,而是使用过程中发现应用层需要才被设计出来的),本质是为了当应用程序访问数据库的时候,事务能够简化我们的编程模型,不需要我们去考虑各种各样的潜在错误和并发问题.(你只需要说你的需求,其他的我帮你处理)可以想一下当我们使用事务时,要么提交,要么回滚,我们不会去考虑网络异常了,服务器宕机了,同时更改一个数据怎么办对吧?因此事务本质上是为了应用层服务的.而不是伴随着数据库系统天生就有的.

备注:我们后面把 MySQL 中的一行信息,称为一行记录

五、事务的版本支持

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务, MyISAM 不支持。

查看数据库引擎 :

mysql> show engines \G         -- 行显示
*************************** 1. row ***************************
     Engine: InnoDB    -- 引擎名称
     Support: DEFAULT   -- 默认引擎
     Comment: Supports transactions, row-level locking, and foreign keys--支持事务、行级锁,外键
Transactions: YES       -- 支持事务
         XA: YES
 Savepoints: YES       -- 支持事务保存点
*************************** 2. row ***************************
     Engine: MRG_MYISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
         XA: NO
 Savepoints: NO
*************************** 3. row ***************************
     Engine: MEMORY    --内存引擎
     Support: YES
     Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
         XA: NO
Savepoints: NO
*************************** 4. row ***************************
     Engine: BLACKHOLE
     Support: YES
     Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
         XA: NO
 Savepoints: NO
*************************** 5. row ***************************
     Engine: MyISAM    
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO           -- MyISAM不支持事务
         XA: NO
 Savepoints: NO
*************************** 6. row ***************************
     Engine: CSV
     Support: YES
     Comment: CSV storage engine
Transactions: NO
         XA: NO
 Savepoints: NO
*************************** 7. row ***************************
     Engine: ARCHIVE
     Support: YES
     Comment: Archive storage engine
Transactions: NO
         XA: NO
 Savepoints: NO
*************************** 8. row ***************************
     Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
         XA: NO
 Savepoints: NO
*************************** 9. row ***************************
     Engine: FEDERATED
     Support: NO
     Comment: Federated MySQL storage engine
Transactions: NULL
         XA: NULL
 Savepoints: NULL
9 rows in set (0.00 sec)

六、事务的提交方式

事务的提交方式常见的有两种: 自动提交、手动提交

查看事务提交方式 :

show variables like 'autocommit';

 

用 SET 来改变 MySQL 的自动提交模式:

SET AUTOCOMMIT=0;            #SET AUTOCOMMIT=0 禁止自动提交

mysql> SET AUTOCOMMIT=1;           #SET AUTOCOMMIT=1 开启自动提交

七、事务常见操作方式

简单银行用户表

## Centos 7 云服务器,默认开启3306 mysqld服务
netstat -nltp

## 为了便于演示,我们将mysql的默认隔离级别设置成读未提交

set global transaction isolation level READ UNCOMMITTED;

## 设置了却没有用 ,因为需要重启终端才可以

select @@tx_isolation;

创建测试表

create table if not exists account(
   id int primary key, 
   name varchar(50) not null default '', 
   blance decimal(10,2) not null default 0.0
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

7.1 正常演示 - 证明事务的开始与(定向)回滚

mysql> show variables like 'autocommit';  -- 查看事务是否自动提交。我们故意设置成自动提交,看看该选项是否影响begin   从这一行往后所有的语句都属于这个事务

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit   | ON   |
+---------------+-------+
1 row in set (0.00 sec)
mysql> start transaction;               -- 开始一个事务begin也可以,推荐begin

Query OK, 0 rows affected (0.00 sec)
mysql> savepoint save1;                -- 创建一个保存点save1(根据需求设置保存点)

Query OK, 0 rows affected (0.00 sec)
mysql> insert into account values (1, '张三', 100);   -- 插入一条记录

Query OK, 1 row affected (0.05 sec)
mysql> savepoint save2;                 -- 创建一个保存点save2

Query OK, 0 rows affected (0.01 sec)
mysql> insert into account values (2, '李四', 10000);  -- 在插入一条记录

Query OK, 1 row affected (0.00 sec)
mysql> select * from account;             -- 两条记录都在了

+----+--------+----------+
| id | name   | blance   |
+----+--------+----------+
|  1 | 张三   |   100.00 |
|  2 | 李四   | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
mysql> rollback to save2;                 -- 回滚到保存点save2(定向回滚)

Query OK, 0 rows affected (0.03 sec)
mysql> select * from account;             -- 一条记录没有了

+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)
mysql> rollback; -- 直接rollback,回滚在最开始,哪怕你一个回滚点都没设置也可以

Query OK, 0 rows affected (0.00 sec)
mysql> select * from account;             -- 所有刚刚的记录没有了

Empty set (0.00 sec)

commit;--就是把该事务给提交了 无法回滚

但是一般我们很少手动rollback,事务大多数都是为了非正常情况 

7.2 非正常演示1 - 证明未commit,客户端崩溃,MySQL自动会回滚(隔离级别设置为读未提交)

-- 终端A
mysql> select * from account;          -- 当前表内无数据
Empty set (0.00 sec)

mysql> show variables like 'autocommit'; -- 依旧自动提交
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit   | ON   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> begin;                            --开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account values (1, '张三', 100);   -- 插入记录
Query OK, 1 row affected (0.00 sec)

mysql> select * from account;           --数据已经存在,但没有commit,此时同时查看终端B
+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)
mysql> Aborted                          -- ctrl + \ 异常终止MySQL 

--终端B
mysql> select * from account;           --终端A崩溃前
+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

mysql> select * from account;          --数据自动回滚
Empty set (0.00 sec)

 7.3 非正常演示2 - 证明commit了,客户端崩溃,MySQL数据不会在受影响,已经持久化

--终端 A 
mysql> show variables like 'autocommit'; -- 依旧自动提交 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | ON | 
+---------------+-------+ 
1 row in set (0.00 sec) 
 
mysql> select * from account; -- 当前表内无数据 
Empty set (0.00 sec) 
 
mysql> begin; -- 开启事务 
Query OK, 0 rows affected (0.00 sec) 
 
mysql> insert into account values (1, '张三', 100); -- 插入记录 
Query OK, 1 row affected (0.00 sec) 
 
mysql> commit; --提交事务 
Query OK, 0 rows affected (0.04 sec) 
 
mysql> Aborted -- ctrl + \ 异常终止MySQL 
 
--终端 B 
mysql> select * from account; --数据存在了,所以commit的作用是将数据持久化到MySQL中 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) 

7.4 非正常演示3 - 对比试验。证明begin操作会自动更改提交方式,不会受MySQL是否自动提交影响

手动begin就必须手动commit,跟是否是自动提交毫无关系 

-- 终端 A 
mysql> select *from account; --查看历史数据 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) 
 
mysql> show variables like 'autocommit'; --查看事务提交方式 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | ON | 
+---------------+-------+ 
1 row in set (0.00 sec) 
 
mysql> set autocommit=0; --关闭自动提交 
Query OK, 0 rows affected (0.00 sec) 
 
mysql> show variables like 'autocommit'; --查看关闭之后结果 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | OFF | 
+---------------+-------+ 
1 row in set (0.00 sec) 
 
mysql> begin; --开启事务 
Query OK, 0 rows affected (0.00 sec) 
 
mysql> insert into account values (2, '李四', 10000); --插入记录 
Query OK, 1 row affected (0.00 sec) 
 
mysql> select *from account; --查看插入记录,同时查看终端B
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) 
 
mysql> Aborted --再次异常终止 
 
-- 终端B 
mysql> select * from account; --终端A崩溃前 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) 
 
mysql> select * from account; --终端A崩溃后,自动回滚 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec)

7.5 非正常演示4 - 证明单条 SQL 与事务的关系

--实验一 
-- 终端A 
mysql> select * from account; 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) 
 
mysql> show variables like 'autocommit'; 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | ON | 
+---------------+-------+ 
1 row in set (0.00 sec) 
 
mysql> set autocommit=0; --关闭自动提交 
Query OK, 0 rows affected (0.00 sec) 
 
mysql> insert into account values (2, '李四', 10000); --插入记录
Query OK, 1 row affected (0.00 sec) 
 
mysql> select *from account; --查看结果,已经插入。此时可以在查看终端B 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) 
 
mysql> ^DBye --ctrl + \ or ctrl + d,终止终端 
 
--终端B 
mysql> select * from account; --终端A崩溃前 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) 
 
mysql> select * from account; --终端A崩溃后 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) 
 
 
-- 实验二 
--终端A 
mysql> show variables like 'autocommit'; --开启默认提交 
+---------------+-------+ 
| Variable_name | Value | 
+---------------+-------+ 
| autocommit | ON | 
+---------------+-------+ 
1 row in set (0.00 sec) 
 
mysql> select * from account; 
+----+--------+--------+ 
| id | name | blance | 
+----+--------+--------+ 
| 1 | 张三 | 100.00 | 
+----+--------+--------+ 
1 row in set (0.00 sec) 
 
mysql> insert into account values (2, '李四', 10000); 
Query OK, 1 row affected (0.01 sec) 
mysql> select *from account; --数据已经插入 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) 
 
mysql> Aborted --异常终止 
 
--终端B 
mysql> select * from account; --终端A崩溃前 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) 
 
mysql> select * from account; --终端A崩溃后,并不影响,已经持久化。autocommit起作用 
+----+--------+----------+ 
| id | name | blance | 
+----+--------+----------+ 
| 1 | 张三 | 100.00 | 
| 2 | 李四 | 10000.00 | 
+----+--------+----------+ 
2 rows in set (0.00 sec) 

7.6 结论

1、只要输入begin或者start transaction,事务便必须要通过commit提交,才会持久化,与是否设置set autocommit无关。

2、事务可以手动回滚,同时,当操作异常,MySQL会自动回滚

3、对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交。(select有特殊情况,因为 MySQL 有MVCC )

从上面的例子,我们能看到事务本身的原子性(回滚),持久性(commit)

7.7 事务操作注意事项  

1、如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是事务还没有提交)

2、如果一个事务被提交了(commit),则不可以回退(rollback)

3、可以选择回退到哪个保存点

savepoint save1; 设置保存点     rollback to save2;回退保存点

4、InnoDB 支持事务, MyISAM 不支持事务

5、开始事务可以使 start transaction 或者 begin

 0

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

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

相关文章

python 基础:句子缩写

n int(input()) for _ in range(n):words input().split()result ""for word in words:result word[0].upper()print(result)知识点讲解 input()函数 用于从标准输入(通常是键盘)读取用户输入的内容。它返回的是字符串类型。例如在代码中…

Ruoyi-vue plus 5.2.2 flowble 结束节点异常错误

因业务要求, 我在结束节点的结束事件中,制作了一个归档的事件,来执行一个业务。 始终都会报错, 错误信息 ${archivTemplateListener} did not resolve to an implementation of interface org.flowable.engine.delegate.Execution…

Sublime Text使用教程(用Sublime Text编写C语言程序)

Sublime Text 是一款当下非常流行的文本编辑器,其功能强大(提供有众多的插件)、界面简洁、还支持跨平台使用(包括 Mac OS X、Linux 和 Windows)。 在程序员眼中,Sublime Text 不仅仅是一个文本编辑器&…

【1】k8s集群管理系列--包应用管理器之helm

一、helm概述 Helm核心是模板,即模板化K8s YAML文件。 通过模板实现Chart高效复用,当部署多个应用时,可以将差异化的字段进行模板化,在部署时使用-f或 者–set动态覆盖默认值,从而适配多个应用 helm工作流程&#xf…

Mysql表的操作(2)

1.去重 select distinct 列名 from 表名 2.查询时排序 select 列名 from 表名 order by 列名 asc/desc; 不影响数据库里面的数据 错误样例 : 但结果却有点出乎意料了~为什么会失败呢? 其实这是因为书写的形式不对,如果带了引号,…

智能物联网网关策略部署

实训背景 某智慧工厂需部署物联网网关,实现以下工业级安全管控需求: 设备准入控制:仅允许注册MAC地址的传感器接入(白名单:AA:BB:CC:DD:EE:FF)。协议合规性:禁止非Modbus TCP(端口…

Java学习总结-线程池

线程池是什么? 线程池就是一个可以复用线程的技术。 假若不用线程池的问题:创建新线程开销很大,不能来一个任务就就创建一个新线程。 如何创建线程池对象? 方法一:使用ExecutorService的实现类ThreadPoolExecutor创…

基于CNN-BiLSTM-GRU的深度Q网络(Deep Q-Network,DQN)求解移动机器人路径规划,MATLAB代码

一、深度Q网络(Deep Q-Network,DQN)介绍 1、背景与动机 深度Q网络(DQN)是深度强化学习领域的里程碑算法,由DeepMind于2013年提出。它首次在 Atari 2600 游戏上实现了超越人类的表现,解决了传统…

CVE-2025-29927 Next.js 中间件鉴权绕过漏洞

Next.js Next.js 是一个基于 React 的现代 Web 开发框架,用来构建高性能、可扩展的 Web 应用和网站。 CVE-2025-29927 Next.js 中间件鉴权绕过漏洞 CVE-2025-29927是Next.js框架中的一个授权绕过漏洞,允许攻击者通过特制的HTTP请求绕过在中间件中执行…

数据结构(五)——AVL树(平衡二叉搜索树)

目录 前言 AVL树概念 AVL树的定义 AVL树的插入 右旋转 左旋转 左右双旋 右左双旋 插入代码如下所示 AVL树的查找 AVL树的遍历 AVL树的节点个数以及高度 判断平衡 AVL树代码如下所示 小结 前言 前面我们在数据结构中介绍了二叉搜索树,其中提到了二叉搜…

C++类型转换详解

目录 一、内置 转 内置 二、内置 转 自定义 三、自定义 转 内置 四、自定义 转 自定义 五、类型转换规范化 1.static_case 2.reinterpret_cast 3.const_cast 4.dynamic_cast 六、RTTI 一、内置 转 内置 C兼容C语言,在内置类型之间转换规则和C语言一样的&am…

excel数据透视表大纲格式改为表格格式

现有这样一个数据透视表: 想要把他变成这样的表格格式: 操作步骤: 第一步: 效果: 第二步: 效果: 去掉分类汇总: 效果: 去掉展开/折叠按钮: 操作方式&#xf…

天梯集训+代码打卡笔记整理

1.着色问题 直接标注哪些行和列是被标注过的&#xff0c;安全格子的数量就是未标注的行*列 #include <bits/stdc.h> using namespace std;const int N 1e510; int hang[N],lie[N];int main(){int n,m;cin>>n>>m;int q;cin>>q;while(q--){int x,y;ci…

支付系统设计入门:核心账户体系架构

&#x1f449;目录 1 账户记账理论 2 账户设计 3 账户性能问题 4 账户核心架构 5 小结 第三方支付作为中立的第三方&#xff0c;截断了用户和商户的资金流&#xff0c;资金先从用户账户转移到第三方支付平台账户&#xff0c;得到双方确认后再从支付平台账户转移到商户账户。 支…

[LevelDB]Block系统内幕解析-元数据块(Meta Block)元数据索引块(MetaIndex Block)索引块(Index Block)

本文内容组织形式 Block的基本信息作用示意图举例说明 源码解析Footer格式写入&读取编码&解码 元数据块&#xff08;Meta Block&#xff09;构建&读取 元数据索引块构建&读取 索引块定义构建&读取核心方法-FindShortestSeparator&FindShortSuccessor作…

leetcode:905. 按奇偶排序数组(python3解法)

难度&#xff1a;简单 给你一个整数数组 nums&#xff0c;将 nums 中的的所有偶数元素移动到数组的前面&#xff0c;后跟所有奇数元素。 返回满足此条件的 任一数组 作为答案。 示例 1&#xff1a; 输入&#xff1a;nums [3,1,2,4] 输出&#xff1a;[2,4,3,1] 解释&#xff1a…

断言与反射——以golang为例

断言 x.(T) 检查x的动态类型是否是T&#xff0c;其中x必须是接口值。 简单使用 func main() {var x interface{}x 100value1, ok : x.(int)if ok {fmt.Println(value1)}value2, ok : x.(string)if ok {//未打印fmt.Println(value2)} }需要注意如果不接受第二个参数就是OK,这…

【数据结构】排序算法(下篇·开端)·深剖数据难点

前引&#xff1a;前面我们通过层层学习&#xff0c;了解了Hoare大佬的排序精髓&#xff0c;今天我们学习的东西可能稍微有点难度&#xff0c;因此我们必须学会思想&#xff0c;我很受感慨&#xff0c;借此分享一下&#xff1a;【用1520分钟去调试】&#xff0c;如果我们遇到了任…

山东大学软件学院创新项目实训开发日志(9)之测试前后端连接

在正式开始前后端功能开发前&#xff0c;在队友的帮助下&#xff0c;成功完成了前后端测试连接&#xff1a; 首先在后端编写一个测试相应程序&#xff1a; 然后在前端创建vue 并且在index.js中添加一下元素&#xff1a; 然后进行测试&#xff0c;测试成功&#xff1a; 后续可…

蓝桥杯C++组算法知识点整理 · 考前突击(上)【小白适用】

【背景说明】本文的作者是一名算法竞赛小白&#xff0c;在第一次参加蓝桥杯之前希望整理一下自己会了哪些算法&#xff0c;于是有了本文的诞生。分享在这里也希望与众多学子共勉。如果时间允许的话&#xff0c;这一系列会分为上中下三部分和大家见面&#xff0c;祝大家竞赛顺利…