数据库事务
一 事务的概念
为什么要有事务,我们先前没学事务,也能写sql语句,事务的意义是什么? 由来: 是为了服务应用层开发,降低开发难度。假如没有事务,那我们身为开发人员,要处理转账需求,此时一定是有多条sql语句对两个账号进行操作,mysqld就是一个网络服务,支持多个客户端对服务端的数据做curd,mysqld则是多线程处理这些请求,多线程一条一条执行sql语句,那这两句sql就是割裂开来的,我们怎么知道要让这两个线程先执行,这就很难设计。一个线程执行了扣除我账户的钱,此时另一个线程还没执行将我的钱加到你的账户中,此时其它线程读取我们的账户信息,得到的存款都是错误的。
所以我们就要在mysqld上再实现一层,能够将多条sql语句合并成一个需求,保证在这个需求处理完之前别人不能来访问,如何保证别人不来访问数据,也就是分配一个锁给这个需求,如果是以一句sql语句为单位分配锁,就无法解决上述场景,这个是事务串行化隔离的雏形,所以为了使用方便,免得每个使用者都手动实现sql语句的合并,mysqld就提供了事务。这里还简单引入了隔离性,因为sql语句合并成事务后,还是会有并发访问的问题,这个时候要用隔离性来解决。
二 事务演示
1 准备工作
mysqld本质是一个网络服务,为了研究事务,我们将隔离级别设置为读未提交,这是最低的,设置后要重启客户端,之后的客户端启动后都是这个隔离级别,意义: 为了方便研究事务。
创建测试表
2 事务的基本操作
然后提交方式为On,表示打开自动提交。
启动事务,往后所有的sql语句都是一个事务,
begin(begin 等价 start启动事务)让另一个客户端2也启动一个事务,此时有两个客户端都启动了事务
客户端1 设置保存点s1
然后客户端1开始插入数据,
客户端2也能看到,这个和隔离级别设置最低有关系,这个隔离级别下两个并发的事务可以看到互相的修改结果。
客户端1 多次设置保存点,可以支持后续回滚。
客户端2都能看到。
回滚操作,此时就回到s3节点,
那数据应该会少一条王五的,确实如此。
此时就是提交事务了,start和提交之间的sql语句都在一个事务内。
rollback默认回滚,是直接回滚到初始情况。
注意,回滚只能在事务间执行,提交后就不能回滚,虽然下面显示回滚成功,但是通过查询数据来看,回滚并未生效。
3 异常情况处理
当我们在事务中使用ctrl + \使得客户端崩溃
再次登录查询,发现自动回滚了。
但是只要提交了后,客户端崩溃也不会导致回滚影响先前的结果,这就是事务的持久性。可是我们一直是打开自动提交的,为什么先前崩溃没有自动提交呢,这是因为我们的事务都是手动begin开启的,此时这个提交方式不起作用,终止进程也不会自动提交,不提交那回滚就会恢复数据了。
此时我们不手动启动事务,而是一句句sql指令来测试,此时每句sql指令就是一个事务,这个自动提交是否打开,在客户端崩溃就会有不同的表现。关闭自动提交。
删除数据
然后程序崩溃,会自动回滚,因为该事务没有被提交,属于未完成出错,mysql选择回滚。
但如果自动提交开了
再模拟客户端崩溃
数据就真的被删除了,崩溃后不会回滚,就是因为崩溃后,自动提交了,显然这个自动提交只适用于自动启动的事务。
4 事务的隔离性和原子性
先前了解事务时我们提到事务的由来,是为了合并sql语句,同时保证:事务所有操作要么全部成功,要么失败,回滚,不会只完成一半,从用户层的角度来看,就是事务执行返回的结果要么是执行前,要么是执行后,不是指另一起一个事务来看,而是我们使用者查看事务的执行结果只会有两种状态,这就是事务的原子性。
虽然事务是原子的,但不是意味着他们之间是不会互相影响的,先前说那mysqld一定会并发处理多个事务,那就一定会出现事务并发访问的问题,我们要让事务执行时不被干扰,这个不被干扰就是隔离性,这个不被干扰我们很容易理解成完全不受干扰,数据库实际上允许事务收到不同程度的干扰,这就是和隔离级别相关了,完全不被干扰实际上是最高隔离级别。
问题1 事务并发到来,一个事务要对数据更新,另一个要查询,谁先执行?
串行化下应该谁先来谁先执行,在非串行化下是并发执行的。至于事务应不应该看到并发事务的更新结果,这个得看隔离级别,如果能看到,这说明事务之间能互相影响,干扰,毫无隔离性,如果看不到,查询结果确实不是数据库中最新的数据,这种数据不一致符合预期吗,这个下面再解释。
问题2 为什么要有四个隔离级别
数据库早期研发时考虑到多个事务并发访问数据的问题,例如脏读,不可重复读,幻读,需要我们解决各个问题,从读未提交到,读提交,可重复读到串行化,隔离级别越来越高,并发访问问题越来越少,数据一致性越来越高,并发越小,性能越差。
不同的隔离级别对不同的事务进行隔离,有些对并行的隔离,有些对未来的事务进行隔离,全都隔离就是串行化执行了,此时就不会出现查询结果不是最新的了,保持了高度的数据一致,出现数据不一致问题也并非是出错,要结合场景要求,如上所说,有时候需要减少一致性为并发让步,一个事务在读的时候允许其它事务并发来跑,这些事务修改了数据就有了数据一致性问题,所以问1结尾说数据不一致结合某些并发高的场景来看是符合预期的。
那串行化执行一定是符合的吗,有没有场景要考虑往后的事务影响呢? 我想应该是有的,如果真有了,可以用建立事务间的依赖关系使得事务执行时考虑后面的事务。注: 是运行中的事务相互隔离,对未来的,已经提交的事务不需要讨论隔离性,因为都影响不到自己。
三 隔离级别
1 隔离级别的查看
第二种和第三种是一样的
每次登录就是创建一个会话,会用全局的隔离级别初始化当前会话隔离级别,全局应该是保存在mysqld服务端。会话的概念: 客户端登录,就是创建了一个会话,生命周期是从登陆到断开。
级别设置:对谁设置(session/ global),设置级别是什么
注意,设置全局的,不会对已经有的会话隔离级别进行修改,要重新登录,服务端重新创建会话的管理信息,我们的隔离级别才会被初始化。
2 隔离级别的演示
读未提交
启动两个客户端,分别启动一个事务,显然这两个事务是并行的
一个客户端一改,事务还没结束,另一个客户端能看到该客户端的操作结果
在更新的时候,两个事务是会申请独占锁,这个锁是行级的,所以当两个,事务对同一行做update修改就会触发锁冲突,导致阻塞。注意,有时候只有一个事务在更新时,此时根据资料显示,事务应该持有独占锁,实际上我们查看这个事务却并没有持有锁,但是一旦有别的事务也来更新,我们原来的事务会立刻分配到锁,使得后续事务无法得到锁而休眠,这就是锁的延迟分配。因为只有一个事务的时候没必要加锁,当真正用的时候再分配,减少锁的管理,是对性能的优化。
这就是读未提交,读到了别人还未提交的状态。原理:所有事务都是看最新的缓存数据,此时undo log中还会保留历史数据用于回滚,不用于版本控制。
读提交
让两个客户端隔离级别为读提交,然后各起一个事务。
,
客户端2先查看初始的数据
客户端1插入
此时另一个客户端2看不到这个变化,自己却看得到,如何实现各个客户端看得不一样? 版本控制,后面隔离性原理会慢慢提及。
只有当这个curd的事务提交了,其它的并行事务才能看到结果。
没有看到最新的数据,屏蔽了并行事务对数据的修改,只会看到已经提交的事务,这就解决了脏读问题。却导致在一个事务内多次调用select,结果可能不一样,这就是不可重复读问题。不可重复读是问题吗? 会造成什么问题? 样例如下,当下面两个事务在并发运行时,
小张先执行了三行select,此时tom已经被搜索出来了,然后小王改了立马提交,此时小张又会查出第二个tom,这种重复读取的场景下就出问题了。
但是并不意味这个隔离等级无意义,因为这个解决了脏读问题,牺牲了一些性能用于版本控制。
可重复读
两个并行的事务无法互相看到结果,只有在事务结束,然后启动的事务才能看到。rc和rr由于版本控制,在读取时不加锁,但是更新时会申请独占锁。
同时启动两个事务,事务1做如下更新
事务2就算等事务1提交了也看不见,重复读结果不变,这就是可重复读。
只有在事务1提交后启动的事务才看得到,这个等我们了解版本控制就理解了。
可重复读由于版本控制,1 不是能够自行消除幻读影响吗,当我的事务在运行时,已经形成了快照,别的事务做的修改和插入都会对数据打上事务id,我一比较就发现该事务是未来的或者并行的,就看不到该数据。快照读下mvcc确实能解决幻读问题,但是在当前读下还是会有幻读问题,解决: next-key和gap行锁解决的。
现象1 事务2如果先不select,等事务1执行完修改事务提交后再select,此时就能看到新的数据,如果是先select一次,等事务1执行完修改事务提交再次select查看,此时就看不到最新的数据。这个也是和版本控制相关,也是rr和rc的差别。
串行化
上面隔离等级是解决读写并发的问题,写写并发只能用串行化解决,是依赖锁解决的。此时还是同时启动两个客户端,分别启动事务ab,各自select查询,此时事务不会阻塞,我们可以通过select * from information_schema.innodb_locks查看锁的信息,其实此时是加了共享锁的,只是还没有真正分配,所以查不出来。当事务a要修改,此时就被卡住了,因为事务b会瞬间将应该分配的共享锁分配下来,事务a不会分配共享锁(原因后面提),而此时事务a要申请独占锁对该资源进行加锁,会被事务b的共享锁阻塞,这两个锁从定义上就知道,两个锁是互斥的,不能两个事务分别持有对同一个资源进行加锁。
那为什么事务a没有分配共享锁呢,因为它已经在申请独占锁了,就不会再分配共享锁,免得到时候还要释放。一个事务对于一个资源只会加一把锁,不能同时加共享和独占锁。
3 版本控制
后面要解释版本控制(mvcc)的原理,解释完这个版本控制,有助于我们理解rr和rc隔离级别的实现。
先来两个前置知识。
1 事务要分先后,用什么来区分,事务到来时会被分配一个事务id,id越小,事务越先来。我们在rc和rr中曾多次提及事务先后的概念,就是通过事务id来区分的。
2 mysqld会同时处理多个事务的情况,这些事务要被执行,挂起,销毁,也就是mysqld会对事务进行管理,也就是调度处理,处理完就要删除该事务。管理: 对事务用结构体进行描述,然后将这些结构体对象组织起来,这个就是事务的具体化。
接下来再认识三个隐藏字段,还有undo log和read view,它们组成了mvcc。mysql会在建表的时候给表多建几列,这几列用来保存隐藏字段。
字段1 事务id
当事务a修改了表的某行后,会先保存修改该行数据到undo log中,然后再去修改表的数据,这样就知道历史数据是什么,可以回滚,而且记录该行修改事务id也会被更新成事务a的。
字段2 回滚指针
我们先前说了某行数据被修改前,数据会先复制一份在undo log中,然后直接对该行进行操作,该行会有一个指针,指向历史版本,方便找到历史版本进行读取。
字段3 默认的主键索引
我们先前没建立索引select慢,就是因为没用上这个主键索引,根据一个普通列进行select只能暴力遍历。
字段4 flag隐藏字段
表示数据是否被删除,意义: 这些数据是存在叶子节点里的page页,是在内存的,我们不需要清空内存的数据,直接删除会导致我们要调整page内的数据存储位置,我们只需要标记这个数据是无效的,之后刷新的时候不将其持久化即可。
创建一个测试表,插入一条数据。
很久前曾提及,一句sql指令默认为一个事务,所以此时上面插入的这行数据记录的修改事务id就是先前insert事务id,id就随便用个数字,完整行如下:
5 undo日志
就是一块缓冲区,专门用来保存版本数据。开始模拟mvcc。现在有一个事务(id为10),对student表进行修改,将name改成李四。修改前先保存一份在undo log中,然后返回保存地址。
执行完后如下,mysql存了两份记录,一份是原本用于修改,一份是副本用于其它事务读取。
如果之后又来了个事务11,要对刚刚那个数据进行修改,将年龄改成38,此时不是对历史数据进行修改,还是复制一份到undo log中,然后对原本进行修改。
undo log只会保存事务运行期间的历史版本,事务运行期间可以多次修改,就会有多个版本,但是提交完后不一定会释放(因为它们的历史版本会被其它事务读取,不能立刻释放),这个释放可以理解成free释放。上面undo log中的版本链是用于版本控制的,而回滚操作不是将这里面的数据覆盖式回滚,而是在undo log中记录相反的sql。
补充1 delete和insert如何保存历史版本?
delete就是直接保存一份数据到undo log中。
insert没有历史版本,undo log不会形成版本链,但是还要存放一些信息用于回滚操作,也就是一句相反的sql语句。
补充2 select是查看历史数据还是最新的数据?
如果读历史版本,这就说明了事务结束,版本不一定能删除,要等select读完,所以上面说版本不一定在事务提交后立刻释放。当前读:就是读最新的数据,增删改都叫当前读,因为增删改只能对当前数据进行操作,不能修改历史版本信息,下面就是select当前读,正常的select都是读历史版本,又叫快照读。
快照读就是查看历史版本。所以为什么rc,rr读写能并发,就是因为读是读历史数据,而写是修改最新的,读写是不同位置,当然可以不加锁并发执行。
补充3 那select什么时候当前读,什么时候快照读呢? 快照读又应该读哪个历史版本?
我们先前说隔离性是防止事务被干扰,而在多版本控制下,防止被干扰就是让它们看到不同的版本信息,事务已经有先后的概念了,那一个事务来了,肯定可以看到undo log先前事务修改的版本数据(因为我们的事务执行是要时间的,那就一定会有新的事务来,它可能也会对数据做修改,然后在undo log中产生历史版本),并行的和未来的事务产生的版本我们认为看不到,这样我们的事务运行就看不到后续事务产生的版本,也就不会被干扰,这就是隔离性。显然select默认就是快照读,因为快照读具有隔离性。
但是如何让不同的事务看到不同的内容,应该看到哪个版本,由read view决定。
4 read view
read view就是一个类,mysqld处理事务时,往往会在服务端创建这个快照类对象。 undo log里面有不同的版本数据,所有事务对这些版本都有自己的可见性,不是所有版本的数据都能看见,而read view就是用来描述事务的可见性的, 这个可见性为隔离性服务的,当事务看到的是不同版本的数据,本质就实现了一种隔离。
当我们的事务执行快照读的时候就会创建read view 结构体(不是事务一来就创建),就会初始化这个结构体。接下来介绍read view的成员,最重要的就下面四个字段。
1 m_ids
当事务快照读的时候,此时会用该对象保存并行事务的id。
2 low_limit_id
记录还未分配的下一个事务id,当大于等于这个id值,都能说明这些事务对于当前事务来说是未来的事务。
3 up_limit_id
这个是m_ids列表中的最小值,我们可以用这个值表明提交事务的id,小于这个id值的事务一定是已经提交了的,因为事务是先后到来的,如果一个事务的id比m_ids中的最小值还小,这说明它比这些并行事务还早来,那么就一定处于并行或者提交状态,不在列表里就只能是提交了。
为什么low_limit_id不是m_mids中的最大值,这并不能表示未来的事务,例如当前事务id是4,m_mids记录了2,3,后来的5,6事务提前跑完了,此时我们发现low记录成4就有问题。
我们知道版本链条中每个版本都记录了事务id,表明是被某个事务修改的,而根据上面分析我们知道哪些事务id对我来说是未来的事务,哪些是并行的,哪些是已经提交的,那我们遍历版本链,我们就能找到一个最新的而且是已提交事务产生的版本,这就是解决了脏读问题。这个版本就代替了最新的数据被事务看到,我们的事务就看不到最新的数据,就不会被干扰。
可见性判断样例:
假设来了11,12,13,14,15五个事务,然后12,14事务提交了,此时我们启动事务进行快照读,11,13,15就是并行的事务,用m_ids记录。up_limit_id记录的就是11,只有提交了的才能看到(因为隔离性,看到未提交的,或者是后续的事务的数据,这就说明事务被干扰了),我们由上面推理得出11之前的都提交了,所以遇到版本是由小于11的事务或者事务id小于up_limit_id,大于up_limit_id,然后又不在m_mids列表中的都是已经提交的事务,这些事务产生的版本都可读取,如果是由自己修改的,那也可以读取,这就是rc和rr为什么只能看到提交后的事务的原因。
5 read view 实验
假设有如下记录,然后有四个事务在运行。
事务2开始快照读,也就是创建read view结构体,事务4将name张三改成李四,且已经提交了,而事务1,3还在并行。
生成的read view应该如下图。
m_ids记录了并行事务id,up_limit_id也就是1了,而low_limit_id就认为是5,因为此时我们就认为四是最后一个事务,所以5是尚未分配的下一个事务id。
版本如下,name为李四的是最新的行,指向历史版本,接下来看看事务2应该看到哪个版本。
开始遍历版本链,先遍历最新的数据,发现对该数据修改的事务是4,4 > up_limit_id,这个条件不满足还不能说明事务还未提交,然后和low_limit_id比较,小于5,说明这个版本不是未来事务形成的,但是还要看看事务是否已经提交,就是看在不在m_ids表中,在就说明是活跃的事务,不在就说明已经提交了,可以看到就返回了,如果不能看到就要继续去undo log找下一条数据进行判断,显然是返回最先遇到的且可看到的数据。
不过为什么是最先遇到的呢,因为有多个事务可以对该行形成版本,这个版本也有新旧顺序,可见性判断中我们的事务可以看到多个版本,当然应该返回事务能看到的所有版本中最新的,如果返回老的,那就加重数据不一致了。
前面提及过read view并非是创建事务形成的,而是select快照读才创建的,而这个read view的更新在下面两种隔离级别表现不一样。
6 rc和rr区别
一般select 都是快照读,但是显然这个快照读在各个隔离级别上表现不一样?,本质是read view的更新次数不一样。
级别设为可重复读,这个设置可以看前面,设置全局,然后重启会话,初始化会话的隔离级别,表现是: 多次select结果不变,哪怕用另一个事务在修改,提交后,也不会影响我当前事务的select读取结果。
表设计如下。
表中原始数据如下。
事务a,b开启快照读,此时read view结构体就被创建了。
因为事务a改了数据,就一定会在undo log形成版本链。
当我们不是快照读的时候,就能读到最新数据,显然可重复读结果不变,说得是重复快照读,而不是重复当前读保持不变。
而为什么事务b快照读看不到也很正常,新的版本是并行事务产生的,自己在创建read view时将事务a列入了并行事务,所以看不到修改。
案例2
事务b在事务a修改时并没有调用select,此时它就还没生成版本快照,当事务a提交后,再调用select生成版本快照,此时事务a在read view中就会被认定为是已经提交的事务,可以读取,所以我们发现在rr级别下read view创建的时机会导致显示的不同,这也回答了隔离级别演示时提到的问题。
rc级别下:
rr级别只有一个read view,而且不更新,一直用第一次select创建的read view,所以事务a只要被列入并行事务,那事务b就一直认为事务a是并行的,rc级别也只有一个read view,但是每次select就更新。
所以读提交(rc)可以一直看到别人提交后更新的数据,就是因为我们一直在更新read view,可以一直将提交的事务纳入到可读取的事务列之中,导致我们能一直看到别人提交后的结果。所以rc是不可重复读的,因为每次结果会不同。这个多版本控制(mvcc): 使得读写可以不加锁并发,因为访问的是不同的位置,不同的版本数据。
相关文章:
数据库事务
一 事务的概念 为什么要有事务,我们先前没学事务,也能写sql语句,事务的意义是什么? 由来: 是为了服务应用层开发,降低开发难度。假如没有事务,那我们身为开发人员,要处理转账需求,此时一定是有…...
Python statistics 模块
在数据分析和科学计算中,统计学是一个非常重要的工具。 Python 提供了一个内置的 statistics 模块,专门用于处理基本的统计计算。本文将详细介绍 statistics 模块的功能和使用方法,帮助初学者快速掌握如何使用这个模块进行基本的统计分析。 …...
AI知识-TF-IDF技术(Term Frequency-Inverse Document Frequency)
摘要 TF-IDF(Term Frequency-Inverse Document Frequency)是一种常见的统计方法,用于评估一个词对于一个文档集或一个语料库中的其中一份文档的重要性。本文将全面阐述TF-IDF的通俗理解、技术原理、应用场景,并做以总结。 通俗理…...
spring cloud的核心模块有哪些
Spring Cloud 的核心模块就像一套精心设计的工具箱,每个模块都扮演着特定的角色,共同构建起微服务架构的坚实基础。 1. Spring Cloud Netflix(部分组件已迁移或弃用,但仍是理解 Spring Cloud 的重要参考): …...
java_将数据存入elasticsearch进行高效搜索
使用技术简介: (1) 使用Nginx实现反向代理,使前端可以调用多个微服务 (2) 使用nacos将多个服务管理关联起来 (3) 将数据存入elasticsearch进行高效搜索 (4) 使用消息队列rabbitmq进行消息的传递 (5) 使用 openfeign 进行多个服务之间的api调用 参…...
RAG中的文本切分策略详解
RAG中的文本切分策略详解 1. 选择RAG中的文本切分策略 1.1 不同的文本切分策略 1. CharacterTextSplitter - 这是最简单的方法。它默认基于字符(默认为"")来切割,并且通过字符的数量来衡量块的长度 2. RecursiveCharacterTextSplitter - 基于字符列表拆分文本。 …...
1-1 电场基本概念
目录: 目录 目录: 1.0 电荷守恒定律 2.0 互斥与相吸 3.0 电场的概念 4.0 库伦定律 5.0 矢量的概念 1.0 电荷守恒定律 电荷守恒定律是物理学中的一个基本原理,它指出在一个封闭系统内,电荷的总量是保持不变的。这意味着电荷既…...
SpringBoot初始化执行自定义接口
SpringBoot初始化执行自定义接口 直接加载接口的方法上即可 PostConstructpublic void init() {//加载初始化数据}PostConstruct是一个在Java EE 5规范中引入的注解,用于标记在依赖注入完成后需要执行的方法。这个注解定义在javax.annotation包中,而不…...
【Ubuntu与Linux操作系统:一、Ubuntu安装与基本使用】
第1章 Ubuntu安装与基本使用 1.1 Linux与Ubuntu Linux是一种开源、类Unix操作系统内核,拥有高稳定性和强大的网络功能。由于其开源性和灵活性,Linux被广泛应用于服务器、嵌入式设备以及桌面环境中。 Ubuntu是基于Debian的一个流行Linux发行版…...
C++大端小端判断方法
文章目录 大端小端定义判断方法方法一:利用联合体(Union)特性判断方法二:通过指针类型转换判断方法三:利用位运算与移位操作判断方法四:使用系统提供的字节序相关宏(特定平台支持) 联…...
【IO编程】标准IO和文件IO的对比
标准 I/O 和 文件 I/O 是两种常见的输入输出操作方式。它们的核心功能都是处理数据流,但使用场景和实现方式有所不同,适用于不同的需求。 标准 I/O 标准 I/O 是指与标准输入、标准输出和标准错误流(分别为 stdin、stdout 和 stderr…...
C#范围表达式,模式匹配,逆变和协变--11
目录 一.范围表达式 1.概述 2.语法 3.代码示例 4.实现原理 5.应用场景 二.模式匹配 1.概述 2.核心概念 3.常用模式类型 4.Switch表达式 5.使用示例 6.优势 三.逆变和协变 1.概述 2.泛型类型参数的变性 3.协变示例 4.逆变示例 5.注意事项 6.应用场景 总结 一…...
矩阵求逆的几种方式
矩阵求逆的几种方式(以二阶为例) 矩阵求逆的方法有多种,以下是常用的几种方式总结: 1. 行列式公式法 这是最常见的方法,适用于 2 2 2 \times 2 22矩阵。 对于矩阵: Φ [ a b c d ] , \Phi \begin{bma…...
全新市场阶段, Plume 生态不断壮大的 RWAfi 版图
加密市场在 2024 年迎来了新的里程碑。BTC 不仅成功推出 ETF,以 BTC 为代表的主流加密货币还在一系列传统金融机构的推动下逐步与主流金融市场接轨。与此同时,随着特朗普成功当选下一任美国总统,他承诺推出一系列友好的加密政策,并…...
HTTPS SSL/TLS 工作流程
目录 一、HTTP/HTTPS 简介1、HTTP协议相关内容2、HTTPS协议3、HTTP版本差异: 二、HTTPS 协议工作流程解析1. 客户端请求 SSL 握手2. 服务端接收 SSL 握手连接3. TLS 握手中的密钥协商4. HTTP 数据的加密与解密5. 安全性保障 三、HTTPS 协议的相关知识拓展1. TLS 与 …...
基于异步IO的io_uring
基于异步IO的io_uring 1. io_uring的实现原理 io_uring使用了一种异步IO机制,它通过一对环形缓冲区(ring buffer)实现用户态于内核态之间的高效通信,用户只需将IO请求放入提交队列,当内核完成IO请求时,会将结果放入完成队列&…...
【redis】centos7下安装redis7
在CentOS 7下安装Redis7可以通过以下两种方法实现:手动编译安装和使用YUM进行安装。 CentOS 7系统的环境和版本: $ cat /etc/centos-release CentOS Linux release 7.9.2009 (Core)手动编译安装 参考官方文档:https://redis.io/docs/lates…...
信息系统项目管理-采购管理-采购清单示例
序号类别产品/服务名称规格/功能描述数量备注1硬件服务器高性能处理器,大容量存储10HP、DELL2网络设备高速路由器和交换机10华为3工作站多核处理器,高分辨率显示器25国产设备4移动检查设备手持式移动检查仪,可连接云平台30国产设备5打印机和扫…...
python 代码使用 DeepXDE 库实现了一个求解二维非线性偏微分方程(PDE)的功能
import deepxde as dde import numpy as np import matplotlib.pyplot as plt import tensorflow as tf# 设置时空计算域 Lx 1 # x 范围从 0 到 1 Ly 1 # y 范围从 0 到 1 Lt 0.05 # t 范围从 0 到 0.05 geom dde.geometry.Rectangle([0, 0], [Lx, Ly]) # 空间域 timed…...
后端技术选型 sa-token校验学习 下 结合项目学习 后端鉴权
目录 后端注册拦截器 实现对 WebMvcConfigurer 接口的类实现 静态变量 方法重写 注册 Spring Framework拦截器 Sa-Token中SaServletFilter拦截器 思考 为什么使用两个拦截器 1. Spring Framework 拦截器 2. SaServletFilter 为什么要注册两个拦截器? 总结 …...
继承(8)
大家好,今天我们来学习一下继承方式相关的知识,有助于我们对java的继承有更深的了解,话不多说,来看。 1.10 继承方式 在现实生活中,事物之间的关系是非常复杂,灵活多样。 Java中支持以下几种继承方式: 单继承: 多层…...
深度学习-图神经网络-超图概念及在Hyper-YOLO的应用(小白也看懂)
为什么需要超图? 在一个复杂系统中,某些节点(实体)之间的互动可能不是仅限于两个节点之间的关系,而是多个节点同时参与的更复杂的关系(超边)。简单说就是为了更好的描述事物之间的关系…...
django基于Python的校园个人闲置物品换购平台
Django 基于 Python 的校园个人闲置物品换购平台 一、平台概述 Django 基于 Python 的校园个人闲置物品换购平台是专为校园师生打造的一个便捷、环保且充满活力的线上交易场所。它借助 Django 这一强大的 Python Web 开发框架,整合了校园内丰富的闲置物品资源&…...
opencv的NLM去噪算法
NLM(Non-Local Means)去噪算法是一种基于图像块(patch)相似性的去噪方法。其基本原理是: 图像块相似性:算法首先定义了一个搜索窗口(search window),然后在该窗口内寻找…...
嵌入式系统中的 OpenCV 与 OpenGLES 协同应用
🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 一、OpenCV 在嵌入式中的基石地位二、OpenGLES 为嵌入式图形渲染赋能三、二者协同的精妙之处四、面临的挑战与应对策略 在嵌入式开…...
第三十六章 Spring之假如让你来写MVC——拦截器篇
Spring源码阅读目录 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如让你来写IOC容器——加载资源篇 第三章 Spring之假如让你来写IOC容器——解析配置文件篇 第四章 Spring之假如让你来写IOC容器——XML配置文件篇 第五章 Spring之假如让你来写…...
DDD - 如何运用 DDD 进行数据库设计
文章目录 Pre概述领域对象持久化的思想领域模型的设计传统的 4 种关系1. 一对一关系2. 多对一关系3. 一对多关系4. 多对多关系 继承关系的 3 种设计1. 继承关系的第一种方案:整个父类与子类都写入一张表2. 继承关系的第二种方案:各子类各自对应各自的表3…...
OSPF - 特殊报文与ospf的机制
👠1 携带FA地址的5类LSA 除去7类转5类的LSA会携带FA地址,还有一种情况会有FA地址 FA地址:forwarding address 转发地址,解决次优路径,避免环路5类LSA FA地址不为0,则直接通过FA地址去往目标网段 FA地址为0,…...
VSCode 插件
VSCode 插件 1. GitHub Copilot - AI 代码助手 功能:根据上下文提供实时代码补全,支持自然语言转代码,提供符合现代编程规范的建议。进阶技巧: 使用快捷键 Alt ] 切换多个建议。写注释时,描述业务逻辑而不是具体实现…...
jQuery CSS 类
jQuery CSS 类 引言 在网页设计和开发中,CSS(层叠样式表)起着至关重要的作用,它负责定义网页的布局、颜色、字体等视觉效果。jQuery,作为一个快速、小巧且功能丰富的JavaScript库,极大地简化了HTML文档的…...
CentOS下安装Docker
Docker 必须要在Linux环境下才能运行,windows下运行也是安装虚拟机后才能下载安装运行,菜鸟教程 下载安装 linux 依次执行下边步骤 更新 yum yum update 卸载旧的Docker yum remove docker docker-client docker-client-latest docker-common doc…...
SQLAlchemy
https://docs.sqlalchemy.org.cn/en/20/orm/quickstart.htmlhttps://docs.sqlalchemy.org.cn/en/20/orm/quickstart.html 声明模型 在这里,我们定义模块级构造,这些构造将构成我们从数据库中查询的结构。这种结构被称为 声明式映射,它同时定…...
2025年第三届“华数杯”国际赛A题解题思路与代码(Python版)
游泳竞技策略优化模型代码详解 第一题:速度优化模型 在这一部分,我们将详细解析如何通过数学建模来优化游泳运动员在不同距离比赛中的速度分配策略。 1. 模型概述 我们的模型主要包含三个核心文件: speed_optimization.py: 速度优化的核…...
深入架构剖析 博客点赞逻辑 strategy 策略模式 策略接口 上下文 具体策略 项目实战
目录 点赞策略上下文 策略上下文代码详解 1. 策略模式概述 2. 核心组件 3. 代码解读 LikeStrategyContext 类 LikeTypeEnum 枚举 LikeStrategy 接口 具体策略类 4. 如何使用这个设计 5. 优点 6. 总结 具体代码实现 定义枚举类 从控制层传入参数到上下文 在策略上…...
嵌入式Linux之C语言开发基础
一、C 语言编译过程 Linux 的 C 语言开发,一般选择 GCC 工具链进行编译,示例: 1.mkdir helloworld 2.cd helloworld // 1.main.c #include "hello.h" int main() {say_hello();return 0; } // 2.hello.h #ifndef __HELLO_H__ #de…...
std::accumulate
std::accumulate 是 C 标准库中的一个算法,定义在 <numeric> 头文件中。它用于计算给定范围内元素的累积值(通常是一个和,但也可以是其他类型的累积操作)。 template< class InputIt, class T > T accumulate( Input…...
计算机网络 (33)传输控制协议TCP概述
一、定义与基本概念 TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。它工作在OSI模型的第四层,即传输层,为用户提供可靠的、有序的和无差错的数据传输服务。TCP协议与UDP协议是传输层的两大主要协议,但两者在设计上有明显的不同&…...
Gitee图形界面上传(详细步骤)
目录 1.软件安装 2.安装顺序 3.创建仓库 4.克隆远程仓库到本地电脑 提交代码的三板斧 1.软件安装 Git - Downloads (git-scm.com) Download – TortoiseGit – Windows Shell Interface to Git 2.安装顺序 1. 首先安装git-2.33.1-64-bit.exe,顺序不能搞错2. …...
【STM32-学习笔记-6-】DMA
文章目录 DMAⅠ、DMA框图Ⅱ、DMA基本结构Ⅲ、不同外设的DMA请求Ⅳ、DMA函数Ⅴ、DMA_InitTypeDef结构体参数①、DMA_PeripheralBaseAddr②、DMA_PeripheralDataSize③、DMA_PeripheralInc④、DMA_MemoryBaseAddr⑤、DMA_MemoryDataSize⑥、DMA_MemoryInc⑦、DMA_DIR⑧、DMA_Buff…...
苍穹外卖08——(涉及接收日期格式数据、ApachePOI导出报表、sql获取top10菜品数据)
营业额统计 service层 在需要处理空值、与数据库交互或使用集合时,Integer 、Double是更好的选择。 // 导入string工具类 import org.apache.commons.lang.StringUtils; Service // 标记该类为Spring的服务组件 Slf4j // 引入日志功能 public class Repor…...
Node.js——fs(文件系统)模块
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
【Docker】入门教程
目录 一、Docker的安装 二、Docker的命令 Docker命令实验 1.下载镜像 2.启动容器 3.修改页面 4.保存镜像 5.分享社区 三、Docker存储 1.目录挂载 2.卷映射 四、Docker网络 1.容器间相互访问 2.Redis主从同步集群 3.启动MySQL 五、Docker Compose 1.命令式安装 …...
Ubuntu中使用miniconda安装R和R包devtools
安装devtools环境包 sudo apt-get install gfortran -y sudo apt-get install build-essential -y sudo apt-get install libxt-dev -y sudo apt-get install libcurl4-openssl-dev -y sudo apt-get install libxml2.6-dev -y sudo apt-get install libssl-dev -y sudo apt-g…...
大语言模型预训练、微调、RLHF
转发,如有侵权,请联系删除: 1.【LLM】3:从零开始训练大语言模型(预训练、微调、RLHF) 2.老婆饼里没有老婆,RLHF里也没有真正的RL 3.【大模型微调】一文掌握7种大模型微调的方法 4.基于 Qwen2.…...
啥!GitHub Copilot也免费使用了
文章目录 前言免费版直接修复代码多文件上下文Agent模式总结 前言 最近,GitHub 给开发者们带来了一个好消息:他们的 AI 编程助手 GitHub Copilot 现在可以免费使用了!以前,每个月要花 10 美元才能享受的服务,现在对所…...
【Ubuntu与Linux操作系统:五、文件与目录管理】
第5章 磁盘存储管理 5.1 Linux磁盘存储概述 磁盘存储是Linux系统存储数据的重要组件,它通过分区和文件系统组织和管理数据。Linux支持多种文件系统,如ext4、xfs和btrfs,并以块的形式管理存储设备。 1. 分区与文件系统: 分区&am…...
【PDF转Word】 PDF在线转word文档 好用!优质网站资源推荐
大家在工作与学习中,经常需要将PDF文件转换为Word格式以便进行编辑和修改。很多人都不知道怎么操作,今天我们介绍一个非常好用的工具:小白工具网,可以在线帮忙大家快速把PDF转换成word格式。 小白工具网提供的PDF转Word功能&…...
计算机网络 (38)TCP的拥塞控制
前言 TCP拥塞控制是传输控制协议(Transmission Control Protocol,TCP)避免网络拥塞的算法,是互联网上主要的一个拥塞控制措施。 一、目的 TCP拥塞控制的主要目的是防止过多的数据注入到网络中,使网络能够承受现有的网络…...
构造函数的原型原型链
代码示例 // 定义一个构造函数 Test function Test() {this.name 张三 }; //向构造函数的原型添加一个属性 age18 Test.prototype.age 18;//使用构造函数 Test 来实例化一个新对象 const test new Test();//向 Object.prototype 添加了一个名为 sex 的属性,其值…...
2025华数杯国际赛A题完整论文讲解(含每一问python代码+数据+可视化图)
大家好呀,从发布赛题一直到现在,总算完成了2025“华数杯”国际大学生数学建模竞赛A题Can He Swim Faster的完整的成品论文。 本论文可以保证原创,保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文…...