MySQL---事务管理

1.关于事务

  理解和学习事务,不能只站在程序猿的角度来理解事务,而是要站在使用者(用户)的角度来理解事务。

比如支付宝转账,A转了B100块前,在程序猿的角度来看,是两条update操作,A -100块,B +100块。但是站在使用者的角度,这就是一条转账逻辑。

事务就是一组 DML 语句组成,这些语句在逻辑上存在相关性,这一组 DML 语句要么全部成功,要么全部失败,是一个整体。MySQL 提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的数据是不相同的。
事务就是要做的或所做的事情,主要用于处理操作量大,复杂度高的数据。

事务具有四个属性:

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

一致性: 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
(也就是说,一个事务在开始之前和和事务结束之后,它的结果是可预期的。比如A转给B100块,如果成功了,那么A -100块,B +100块;如果失败了,那么A,B都不变。不会出现,A -100,但是B没变的这种情况。)
虽然说一致性是事务的一大属性,但是MYSQL并没有从技术层面上来实现它,一致性是通过原子性,隔离性,持久性来保证的。

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

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

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

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

一致性( C onsistency

隔离性( I solation ,又称独立性)

持久性( D urability )。

 MYSQL中存在的大量的事务,它们也是需要先被描述,然后再组织的,这样管理起来的。其实就是将一批SQL语句打包成一个事务对象,将这个对象放在事务执行的事务列表里。

2.为什么要存在事务?

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

后面我们将MYSQL的一行信息称为一条记录。

3.了解事务的提交方式 

在MYSQL的两大存储引擎Innodb和MYISAM,只有Innodb支持事务。

事务的提交方式有两种:

1.自动提交。

2.手动提交。

我们可以查看我们的MYSQL的提交方式

mysql> show variables like 'autocommit';

ON表示了它是自动提交的。

我们也可以设置它的提交方式

set autocommit=0;show variables like 'autocommit';

0是关闭,1是打开。 

4.准备工作
 

我们知道,mysqld是一个网络服务,那么我们可以查看

netstat -nltp

 

可以看到,端口号为3306就是我们的mysql网络服务。 

另外可以查看我们mysql和mysqld文件所在的位置

首先我们先将隔离级别设置成为读未提交

set global transaction isolation level read uncommitted;

 但是设置好后,需要登录mysql会话才能生效

此时我们输入

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;

 5.事务的基本操作

这里我们看到事务是自动提交的。

 有两种方式可以开启事务

start transaction;begin;

推荐 使用begin 

设置保存点(比如p1)

savepoint p1;

这是可以方便我们定向回滚的。比如

在插入一条数据后

insert into account values(1,'张三',123.2);

我们看到另一个开启事务的会话可以直接看到更新的结果

然后我们回到插入数据前的保存点p1。

rollback to p1;

 

数据就消失了

也可以直接

rollback;

 直接回到最开始的地方。

如果想结束事务

commit;

事务回滚只能在事务运行期间,如果事务已经提交了,就不能回滚了。

6.事务异常验证与产出的结论 

当mysql遇到异常情况(比如强制关闭会话),事务会自动回滚。

但是如果事务已经commit了,那么mysql的数据就不会受到影响,已经持久化了。

另外关于事务的自动提交,如果我们手动开启事务,比如使用begin,那么即便mysql的设置是自动提交,手动开启的事务=必须要手动提交。那么此外,所有的SQL语句都是自动开启的事务,因为又是手动提交,所以每一条SQL都是一个事务,并且执行完就提交了。 

7.事务隔离性理论

数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性

数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别

隔离级别:(由低到高)

读未提交【 Read Uncommitted : 在该隔离级别,所有的事务都可以看到其他事务没有提交的
执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多
并发问题,如脏读,幻读,不可重复读等,我们上面为了做实验方便,用的就是这个隔离性。
就比如说,两个事务同时运行,一方对表插入了数据,还没有提交,另一个事务直接就能查看到更新的结果。

读提交【 Read Committed :该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL
认的)。它满足了隔离的简单定义 : 一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select , 可能得到不同的结果。

比如两个事务同时运行,其中一个事务对表插入了数据,只有提交了,另一个事务才能查看到更新的结果。 

可重复读【 Repeatable Read : 这是 MySQL 默认的隔离级别,它确保同一个事务,在执行
中,多次读取操作数据时,会看到同样的数据行。但是会有幻读问题。

还是这两个事务,其中一个事务对表插入了数据,但是就算它提交了,另一个事务也看不到更新的结果,只有当它也结束了才能看得到。 

串行化【 Serializable : 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,
从而解决了幻读的问题。它在每个读的数据行上面加上共享锁,。但是可能会导致超时和锁竞争
(这种隔离级别太极端,实际生产基本不使用)

 8.事务隔离级别的设置和查看。

1.查看隔离级别:

有三种方式:

-- 查看
mysql> SELECT @@global.tx_isolation; --查看全局隔级别
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
1 row in set, 1 warning (0.00 sec)mysql> SELECT @@session.tx_isolation; --查看会话(当前)全局隔级别
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ |
+------------------------+
1 row in set, 1 warning (0.00 sec)mysql> SELECT @@tx_isolation; --是上一种的简写方式,也是查看当前会话的
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)

 2.设置隔离级别

中括号表示可以省略,但是这里不建议

-- 设置当前会话 or 全局隔离级别语法
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ
COMMITTED | REPEATABLE READ | SERIALIZABLE}

比如将当前会话的隔离级别改为 读-提交

set session transaction isolation level read committed;

 9.事务隔离级别--读未提交

这种隔离级别几乎没有加锁,虽然效率高,但是问题也很多,严重不推荐使用。

读-未提交会产生脏读现象:

即一个事务在执行时,可以看到另一个事务的更新,但是没有提交的数据,就是脏读。

10.事务隔离级别--读提交 

在这个隔离级别下,一个事务在执行时,可以看到其他事务更新并且提交后的数据。

这样会带来一个后果:

就是在同一个事务内部,每次查询数据时,根据时间段的不同,可能会查询到不一样的结果,我们把这个现象称为不可重复读。 

事务的运行要保证其原子性,不可重复读会破坏原子性。

11.事务隔离级别--可重复读

可重复读解决了两个并发运行的事务,一方提交,不会影响另一个未提交的事务。 

多次查看,发现终端A在对应事务中insert的数据,在终端B的事务周期中,也没有什么影响,也符合可重复的特点。但是,一般的数据库在可重复读情况的时候,无法屏蔽其他事务insert的数据(为什么?因为隔离性实现是对数据加锁完成的,而insert待插入的数据因为并不存在,那么一般加锁无法屏蔽这类问题),会造成虽然大部分内容是可重复读的,但是insert的数据在可重复读情况被读取出来,导致多次查找时,会多查找出来新的记录,就如同产生了幻觉。这种现象,叫做幻读
(phantom read)。很明显,MySQL在RR级别的时候,是解决了幻读问题的(解决的方式是用Next-Key锁(GAP+行锁)解决的。

 

也就是说,幻读问题是insert数据操作时伴随出来的问题,属于不可重复度的情况的一种。

12.事务隔离级别--串行化 

对所有的操作进行加锁,也就是将所有的事务进行串行化,这样就不会存在安全问题,但是效率很低。

其中隔离级别越严格,安全性越高,但数据库的并发性能也就越低,往往需要在两者之间找一个平
衡点。

MYSQL默认的隔离级别是可重复读,并且解决了幻读的问题。 

13.关于一致性的理解 

一致性其实不是技术层面的概念,而是使用层面的概念。 

比如有一个事务在运行时,操作到一半时出现了异常,导致事务没有完成,那么那些完成了一半的操作使数据库处于一种不正确的状态,也就是不一致的状态。

所以:

事务执行的结果,必须使数据库从一个一致性状态,变到另一个一致性状态。当数据库只包含事务
成功提交的结果时,数据库处于一致性状态。如果系统运行发生中断,某个事务尚未完成而被迫中
断,而改未完成的事务对数据库所做的修改已被写入数据库,此时数据库就处于一种不正确(不一
致)的状态。因此一致性是通过原子性来保证的。

其实一致性和用户的业务逻辑强相关,一般 MySQL 提供技术支持,但是一致性还是要用户业务逻辑做支撑(比如要保证SQL是对的),也就是,一致性,是由用户决定的。

而技术上,通过AID保证C 。 

14.MVCC机制 

数据库的并发有三种场景:

- :不存在任何问题,也不需要并发控制

- 写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读

- :有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失

这里重点介绍读写。

多版本并发控制( MVCC )是一种用来解决 -写冲突 无锁并发控制 。

MYSQL为事务分配单向增长的事务 ID ,为每个修改保存一个版本,版本与事务 ID 关联,读操作只读该事务开始前的数据库的快照。 所以 MVCC 可以为数据库解决以下问题。
事务ID越小,说明这个事务来得越早。可以根据事务ID的大小来判断事务到来的顺序。
mysqld可能会同时面临处理多个事务的情况,事务也有自己的生命周期,mysqld要将这些事务管理起来,就需要先描述,再组织,所以在mysqld中一定是有一套对应的结构体/类对象,事务也有自己的结构体。

理解MVCC需要的三个前提知识:

3 个记录隐藏字段

undo 日志

Read View

3个记录隐藏字段:

其实我们在建表的时候,mysql会给我们加上3个隐藏字段。

DB_TRX_ID 6 byte ,最近修改 ( 修改 / 插入 ) 事务 ID ,记录创建这条记录 / 最后一次修改该记录的事务ID

DB_ROLL_PTR : 7 byte ,回滚指针,指向这条记录的上一个版本(简单理解成,指向历史版本就
行,这些数据一般在 undo log 中)

DB_ROW_ID : 6 byte ,隐含的自增 ID (隐藏主键),如果数据表没有主键, InnoDB 会自动以
DB_ROW_ID 产生一个聚簇索引 。如果我们指明了主键,那么就用我们指明的这个主键来建立索引。

补充:实际还有一个删除flag隐藏字段, 既记录被更新或删除并不代表真的删除,而是删除flag变了 

所以我们删除一条记录其实并不是真的把它删除了,而是改变了它的flag。这也是典型的用空间换时间的一种做法,并且如果出现了误删操作,还可以进行还原。

undo日志(log)

MYSQL将来是以服务进程的方式,在内存中运行。我们之前所讲的所有机制:索引,事务,隔离性,日志等,都是在内存中完成的,即在 MySQL 内部的相关缓冲区中,保存相关数据,完成各种判断操作。然后在合适的时候,将相关数据刷新到磁盘当中的。

所以可以简单理解为,undolog就是mysql中的一段内存缓冲区。

模拟MVCC的过程:

现在有一个事务 10( 仅仅为了好区分 ) ,对 student 表中记录进行修改 (update) :将 name( 张三 ) 改成
name( 李四 )
事务 10, 因为要修改,所以要先给该记录加行锁。
修改前,现将改行记录拷贝到 undo log 中,所以, undo log 中就有了一行副本数据。 ( 原理就是写
时拷贝 )
所以现在 MySQL 中有两行同样的记录。现在修改原始记录中的 name ,改成 ' 李四 ' 。并且修改原始
记录的隐藏字段 DB_TRX_ID 为当前 事务 10 ID, 我们默认从 10 开始,之后递增。而原始记录的回滚指针 DB_ROLL_PTR 列,里面写入 undo log 中副本数据的地址,从而指向副本记录,既表示我的上一个版本就是它。
事务 10 提交,释放锁。

 图中李四是最新的记录。

现在又有一个事务 11 ,对 student 表中记录进行修改 (update) :将 age(28) 改成 age(38)
事务 11, 因为也要修改,所以要先给该记录加行锁。
修改前,现将改行记录拷贝到 undo log 中,所以, undo log 中就又有了一行副本数据。此时,新的
副本,我们采用头插方式,插入 undo log
现在修改原始记录中的 age ,改成 38 。并且修改原始记录的隐藏字段 DB_TRX_ID 为当前 事务 11 的ID。而原始记录的回滚指针 DB_ROLL_PTR 列,里面写入 undo log 中副本数据的地址,从而指向副本记录,既表示我的上一个版本就是它。
事务 11 提交,释放锁。
这样,我们就有了一个基于链表记录的历史版本链。所谓的回滚,无非就是用历史数据,覆盖当前数据。
上面的一个一个版本,我们可以称之为一个一个的快照。

如果一个事务提交,undo log就清理掉了,自然也就不能回滚了。

一些思考:

上面是以更新( `upadte` )主讲的 , 如果是 `delete` 呢?一样的,别忘了,删数据不是清空,而是设置 flag为删除即可。也可以形成版本。

如果是 `insert` 呢?因为 `insert` 是插入,也就是之前没有数据,那么 `insert` 也就没有历史版本。但是 一般为了回滚操作,insert 的数据也是要被放入 undo log 中(此时对应的回滚操作就是delete),如果当前事务 commit 了,那么这个 undo log 的历史 insert 记录就可以被清空了。

总结一下,也就是我们可以理解成, `update` `delete` 可以形成版本链, `insert` 暂时不考虑。

那么 `select` 呢?
首先, `select` 不会对数据做任何修改,所以,为 `select` 维护多版本,没有意义。不过,此时有个问题,就是:
select 读取,是读取最新的版本呢?还是读取历史版本?

当前读:读取最新的记录,就是当前读。增删改,都叫做当前读, select 也有可能当前读,比如: select lock in share mode(共享锁 ), select for update (这个好理解,我们后面不讨论)
快照读:读取历史版本 ( 一般而言 ) ,就叫做快照读。

我们可以看到,在多个事务同时删改查的时候,都是当前读,是要加锁的。那同时有 select 过来,如果也要读取最新版( 当前读 ) ,那么也就需要加锁,这就是串行化。
但如果是快照读,读取历史版本的话,是不受加锁限制的。也就是可以并行执行!换言之,提高了效率,即MVCC的意义所在。

所以是隔离级别决定了select是当前读还是快照读。

那为什么要有隔离级别呢?
事务都是原子的。所以,无论如何,事务总有先有后。

但是经过上面的操作我们发现,事务从 begin->CURD->commit ,是有一个阶段的。也就是事务有执行前,执行中,执行后的阶段。但,不管怎么启动多个事务,总是有先有后的。

那么多个事务在执行中, CURD 操作是会交织在一起的。那么,为了保证事务的 有先有后 ,是不是应该让不同的事务看到它该看到的内容,这就是所谓的隔离性与隔离级别要解决的问题。

15.read view理论 

Read View 就是事务进行 快照读 操作的时候生产的 读视图 (Read View) ,在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID( 当每个事务开启时,都会被分配一个ID, 这个 ID 是递增的,所以最新的事务, ID 值越大 )

Read View MySQL 源码中 , 就是一个类,本质是用来进行可见性判断的。 即当我们某个事务执行快照读(也就是select的操作)的时候,对该记录创建一个 Read View 读视图,把它比作条件 , 用来判断当前事务能够看到哪个版本的数据,既可能是当前最新的数据,也有可能是该行记录的 undo log 里面的某个版本的数据。

read view结构体中重要的字段

class ReadView {
// 省略...
private:
/** 高水位,大于等于这个ID的事务均不可见*/
trx_id_t m_low_limit_id;/** 低水位:小于这个ID的事务均可见 */
trx_id_t m_up_limit_id;/** 创建该 Read View 的事务ID*/
trx_id_t m_creator_trx_id;/** 创建视图时的活跃事务id列表*/
ids_t m_ids;/** 配合purge,标识该视图不需要小于m_low_limit_no的UNDO LOG,
* 如果其他视图也不需要,则可以删除小于m_low_limit_no的UNDO LOG*/
trx_id_t m_low_limit_no;/** 标记视图是否被关闭*/
bool m_closed;// 省略...
};// 重点是这四个字段
m_ids; //一张列表,用来维护Read View生成时刻,系统正活跃的事务ID
up_limit_id; //记录m_ids列表中事务ID最小的ID(没有写错)
low_limit_id; //ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的
最大值+1(也没有写错)
creator_trx_id //创建该ReadView的事务ID

我们在实际读取数据版本链的时候,是能读取到每一个版本对应的事务 ID 的,即:当前记录的
DB_TRX_ID

那么,我们现在手里面有的东西就有,当前快照读的 ReadView 和 版本链中的某一个记录的

DB_TRX_ID
所以现在的问题就是,当前快照读,应不应该读到当前版本记录。

 

read view它生成对象后,只初始化一次。此时里面的字段m_ids表示的是当这个read view起来的时候,此时活跃的事务ID。那么有两种情况,是可以select到的:

1.当前创建该read view时的事务ID等于遍历到的记录的事务ID(DB_TRX_ID),说明是select自己,那么当然可以查看。

2.当初跟我们同时运行的事务,它们的事务ID可能比我们大,但是它们可能比我们先提交了,既然已经提交了,我们也可以查看。

那么,不能查看的也有两种情况:

1.正在运行的事务,我们不能查看,在m_ids中的。

2.当前的事务ID>=low_limit_id。说明是快照之后才提交的事务,也不应该看到。

read view是从版本链中遍历的,也就是undo log中遍历。 

我们可以看一下在mysql的源码中,对每次遍历的判断

 可见与我们刚刚分析的差不多,如果id小于最低水位,说明这些事务是在这个read view之前就提交了,如果id == 当前事务id,那么也返回true。

并且要注意:这个id是指我们从版本链中遍历到的事务的ID( DB_TRX_ID)。

如果id大于最高水位,说明这个事务是在read view之后创建的,肯定不能查看,所以返回false。

另外,如果m_ids是空的,说明此时就只有一个事务,当然能查看,所以也返回true。

总结:

read view是事务可见性的一个类,但是注意,它不是事务一创建出来就跟着有的(read view对象),而是当这个事务(已经存在)首次进行快照读的时候,mysql才会形成read view对象。

16.read view实验 

 现在有这样一条记录

然后有四个事务:

 根据事务id可以判断它们的创建的先后顺序,纵向代表它们的执行状态,并且可以看到事务4是先提交了的。

事务4的修改操作是:

修改name(张三)为name(李四)

注意:low_limit_id代表的是系统分配的最大的事务id 再 + 1。

那么此时事务2在进行快照读的时候,形成的read view对象的字段为:

//事务2的 Read View
m_ids; // 1,3
up_limit_id; // 1
low_limit_id; // 4 + 1 = 5,原因:ReadView生成时刻,系统尚未分配的下一个事务ID
creator_trx_id // 2

那么此时的版本链:

 因为只有事务4进行了修改并且提交,那么当事务2的read view创建时,读取该记录时,就会拿这个事务的DB_TRX_ID开始进行比较

//事务2的 Read View
m_ids; // 1,3
up_limit_id; // 1
low_limit_id; // 4 + 1 = 5,原因:ReadView生成时刻,系统尚未分配的下一个事务ID
creator_trx_id // 2
//事务4提交的记录对应的事务ID
DB_TRX_ID=4
//比较步骤
DB_TRX_ID(4)< up_limit_id(1) ? 不小于,下一步
DB_TRX_ID(4)>= low_limit_id(5) ? 不大于,下一步
m_ids.contains(DB_TRX_ID) ? 不包含,说明,事务4不在当前的活跃事务中。//结论
故,事务4的更改,应该看到。
所以事务2能读到的最新数据记录是事务4所提交的版本,而事务4提交的版本也是全局角度上最新的版本

到这里我们也发现,这不就是之前说的RC(读提交)隔离级别吗?

17.RC和RR的本质区别

我们在select语句后面加上 lock in share mode,表示加共享锁的方式读取,是当前读,不加就是快照读。

在RR级别下,(可重复读),有两个事务同时运行

 图中我们发现,事务B在事务A提交前就进行了快照读,那么也就形成了read view,在事务A提交后,事务B再使用快照读依旧不能读到更新后的结果。

还有另一种情况:

两种情况的唯一不同就是,后者事务B是在事务A提交后才进行的快照读,此时就能读到更新的结果。这就是RR隔离级别。

结论:

事务中快照读的结果是非常依赖该事务首次出现快照读的地方,即某个事务中首次出现快照读,决
定该事务后续快照读结果的能力

 

delete 同样如此

 

所以read view的形成的时机不同,会影响事务的可见性!! 

所以RC与RR的本质区别:

正是 Read View 生成时机的不同,从而造成 RC,RR 级别下快照读的结果的不同

 

RR 级别下的某个事务的对某条记录的第一次快照读会创建一个快照及 Read View, 将当前系统活
跃的其他事务记录起来(此后就不会变了!)

 

此后在调用快照读的时候,还是使用的是同一个 Read View ,所以只要当前事务在其他事务提交更
新之前使用过快照读,那么之后的快照读使用的都是同一个 Read View ,所以对之后的修改不可
见;

 

RR 级别下,快照读生成 Read View 时, Read View 会记录此时所有其他活动事务的快照,这些事
务的修改对于当前事务都是不可见的。而早于 Read View 创建的事务所做的修改均是可见

 

而在 RC 级别下的,事务中,每次快照读都会新生成一个快照和 Read View, 这就是我们在 RC 级别下的事务中可以看到别的事务提交的更新的原因

 

总之在 RC 隔离级别下,是每个快照读都会生成并获取最新的 Read View ;而在 RR 隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个 Read View

 

正是 RC 每次快照读,都会形成 Read View ,所以, RC 才会有不可重复读问题。

 

顺便说下读未提交,它直接都不形成read view,所以什么都能看到。 

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

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

相关文章

浅谈反射机制

1. 何为反射&#xff1f; 反射&#xff08;Reflection&#xff09;机制指的是程序在运行的时候能够获取自身的信息。具体来说&#xff0c;反射允许程序在运行时获取关于自己代码的各种信息。如果知道一个类的名称或者它的一个实例对象&#xff0c; 就能把这个类的所有方法和变…

【贪心 堆 优先队列】502. IPO

本文涉及知识点 贪心 堆 优先队列 LeetCode502. IPO 假设 力扣&#xff08;LeetCode&#xff09;即将开始 IPO 。为了以更高的价格将股票卖给风险投资公司&#xff0c;力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限&#xff0c;它只能在 IPO 之前完成最多 k…

ORB-SLAM3源码分析(案例分析)

一、ORB-SLAM3简介 ORB-SLAM3 (Oriented FAST and Rotated BRIEF SLAM 3) 是一种视觉SLAM&#xff08;Simultaneous Localization and Mapping&#xff0c;同时定位与地图构建&#xff09;系统&#xff0c;用于机器人和计算机视觉领域。它是ORB-SLAM系列的第三个版本&#xff…

非参数检测2——定义

定义&#xff1a;若研究二判定问题&#xff08;即判断有无信号&#xff09;的检测问题&#xff0c; 检测器的虚警概率可以由对输入数据统计特性提出微弱假设确定假设中不包含输入噪声的统计特性 则称该检测器为非参数检测器。 设计目标 在未知或时变环境下&#xff0c;有最…

【自动驾驶仿真在做什么——初学者总结(陆续补充)】

文章目录 基础概念自动驾驶级别再稍提一下ODD是什么&#xff1f; 自动驾驶仿真分类软件在环仿真硬件仿真 仿真究竟难在哪&#xff1f;关于lidar和radar区别一些名词解释 最近也是学习自动驾驶仿真相关知识&#xff0c;习惯去总结一下&#xff0c;方便自己回顾和总结&#xff0c…

【多媒体】富客户端应用程序GUI框架 JavaFX 2.0 简介

JavaFX 最初是由 Oracle 推出的一个用于开发富客户端应用程序的框架&#xff0c;它提供了丰富的用户界面控件、布局容器、3D图形绘制、媒体播放和动画等功能&#xff0c;旨在取代较旧的 Swing 框架。JavaFX 于 2007 年推出&#xff0c;2011 年 10 月发布了2.0 版本。JavaFX 2.0…

强强联合 | 人大金仓携手中国一汽引领国产数据库行业新浪潮

在国产化政策的推动下&#xff0c;人大金仓携手中国一汽联合开发更贴近汽车产业特定需求的数据库功能和组件。从2023年2月至今&#xff0c;人大金仓已累计部署690套数据库&#xff0c;适配应用系统170个&#xff0c;支撑中国一汽20多个核心系统和重要系统。目前&#xff0c;中国…

Okhttp hostnameVerifier详解

hostnameVerifier 方法简介核心原理参考资料 方法简介 本篇博文以Okhttp 4.6.0来解析hostnameVerfier的作用&#xff0c;顾名思义&#xff0c;该方法的主要作用就是鉴定hostnname的合法性。Okhttp在初始化的时候我们可以自己配置hostnameVerfier&#xff1a; new OkHttpClien…

计算机网络——数据链路层(以太网)

目录 局域网的数据链路层 局域网可按照网络拓扑分类 局域网与共享信道 以太网的两个主要标准 适配器与mac地址 适配器的组成与运作 MAC地址 MAC地址的详细介绍 局域网的mac地址格式 mac地址的发送顺序 单播、多播&#xff0c;广播mac地址 mac帧 如何取用…

YOLOX算法实现血细胞检测

原文:YOLOX算法实现血细胞检测 - 知乎 (zhihu.com) 目标检测一直是计算机视觉中比较热门的研究领域。本文将使用一个非常酷且有用的数据集来实现YOLOX算法,这些数据集具有潜在的真实应用场景。 问题陈述 数据来源于医疗相关数据集,目的是解决血细胞检测问题。任务是通过显微…

Linux基础指令及mysql(DQL)

[rootcentos ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/export/server/jdk/bin:/root/binls在/usr/bin/路径下 [rootcentos ~]# which ls alias lsls --colorauto/usr/bin/lschmod ux,gx,o-r work.txt 可以对文件的权限进行修改。 sudo chown 修…

Python从入门到放弃——整数类型变量

变量 前言 上一篇文章中我们学习了Print函数&#xff0c;并且深入的理解了Print函数的各个参数。明确了应该如何利用各种参数来实现我们想输出的效果。那么现在让我们来学习一下变量这一个知识点。 什么是变量 变量&#xff0c;作为编程中的核心概念之一&#xff0c;其重要性…

STM32和DHT11使用显示温湿度度(代码理解)+单总线协议

基于STM32CT&#xff0c;利用DHT11采集温湿度数据&#xff0c;在OLED上显示。一定要阅读DHT11数据手册。 1、 DHT11温湿度传感器 引脚说明 1、VDD 供电3.3&#xff5e;5.5V DC 2、DATA 串行数据&#xff0c;单总线 3、NC 空脚 4、GND 接地&#xff0c;电源负极 硬件电路 微…

docker部署kafka(单节点) + Springboot集成kafka

环境&#xff1a; 操作系统&#xff1a;win10 Docker&#xff1a;Docker Desktop 4.21.1 (114176)、Docker Engine v24.0.2 SpringBoot&#xff1a;2.7.15 步骤1&#xff1a;创建网络&#xff1a; docker network create --subnet172.18.0.0/16 net-kafka 步骤2&#xff1a;安…

秋招突击——7/4——复习{}——新作{最长公共子序列、编辑距离、买股票最佳时机、跳跃游戏}

文章目录 引言复习新作1143-最长公共子序列个人实现 参考实现编辑距离个人实现参考实现 贪心——买股票的最佳时机个人实现参考实现 贪心——55-跳跃游戏个人实现参考做法 总结 引言 昨天主要是面试&#xff0c;然后剩下的时间都是用来对面试中不会的东西进行查漏补缺&#xff…

MySQL 9.0 创新版发布,大失所望。。

大家好&#xff0c;我是程序员鱼皮。2024 年 7 月 1 日&#xff0c;MySQL 发布了 9.0 创新版本。区别于我们大多数开发者常用的 LTS&#xff08;Long-Term Support&#xff09;长期支持版本&#xff0c;创新版本的发布会更频繁、会更快地推出新的特性和变更&#xff0c;可以理解…

python库(5):Psutil库实现系统和硬件监控工具

1 psutil简介 psutil&#xff08;process and system utilities&#xff09;是一个跨平台库&#xff0c;用于检索运行中进程和系统利用率&#xff08;包括 CPU、内存、磁盘、网络等&#xff09;的信息&#xff0c;可以提供丰富的系统监控功能。 2 psutil安装 pip install -i …

CSS中 实现四角边框效果

效果图 关键代码 border-radius:10rpx ;background: linear-gradient(#fff, #fff) left top,linear-gradient(#fff, #fff) left top,linear-gradient(#fff, #fff) right top,linear-gradient(#fff, #fff) right top,linear-gradient(#fff, #fff) left bottom,linear-gradient(…

BeikeShop多国语言多货币商城系统源码基于Laravel框架

BeikeShop是基于 Laravel 开发的一款开源商城系统&#xff0c;支持多语言商城 多货币商城 100%全开源 ChatGPT OpenAI B2C商城系统 H5商城 PHP商城系统 商城源码 PC商城 跨境电商系统 跨境商城系统 电商商城系统 Laravel 10 框架开发系统&#xff0c;支持插件市场。 Event 机制…

配置基于不同端口的虚拟主机

更改配置文件&#xff0c;添加三个不同端口的虚拟主机 <directory /www> allowoverride none require all granted </directory><virtualhost 192.168.209.136:80> documentroot /www servername 192.168.209.136 </virtualhost><virtualhost 192.…