面试官:说一下MySQL中的锁机制吧
5. 1MySQL有哪些锁?
为保证数据的一致性,需要对并发操作进行控制,因此产生了锁
。同时锁机制
也为实现MySQL的各个隔离级别提供了保证。 锁冲突 也是影响数据库并发访问性能
的一个重要因素。所以锁对数据库而言显得尤其重要,也更加复杂。
按照数据操作的类型,可以分为读锁、写锁。
-
读锁 :也称为 共享锁 、英文用 S 表示。针对同一份数据,多个事务的读操作可以同时进行而不会互相影响,相互不阻塞的。
-
写锁 :也称为 排他锁 、英文用 X 表示。当前写操作没有完成前,它会阻断其他写锁和读锁。这样就能确保在给定的时间里,只有一个事务能执行写入,并防止其他用户读取正在写入的同一资源。
在 MySQL 里,根据加锁的范围,可以分为全局锁、表级锁和行锁三类。
全局锁
使用全局锁,整个数据库就处于只读状态了。
-
应用场景:主要应用于做全库逻辑备份,这样在备份数据库期间,不会因为数据或表结构的更新,而出现备份文件的数据与预期的不一样。
-
缺点:业务只能读数据,而不能更新数据,这样会造成业务停滞。
-
避免方法:使用可重复读的隔离级别,在备份数据库之前先开启事务,整个数据库的数据就都是可重复读的,而且由于 MVCC 的支持,备份期间业务依然可以对数据进行更新操作。
# 加全局锁 FTWRL flush tables with read lock
表级锁
MySQL 里面表级别的锁有:表锁、元数据锁(MDL)、意向锁、AUTO-INC 锁。
-
表锁
表锁也有表级别的共享锁,表级别的独占锁。
表锁除了会限制别的线程的读写外,也会限制本线程接下来的读写操作。表锁的颗粒度太大,会影响并发性能,应该尽量避免使用表锁。
-
元数据锁(Meta Datebase Lock,MDL)
对一张表进行 CRUD 操作时,加的是 MDL 读锁;
- 只允许读,不能做结构的修改,比如修改表字段等。
对一张表做结构变更操作的时候,加的是 MDL 写锁;
- 只允许写,修改表结构时不能通过CRUD读取数据。
MDL 不需要显示调用,在事务提交后才会释放,这意味着事务执行期间,MDL 是一直持有的。
申请 MDL 锁的操作会形成一个队列,队列中写锁获取优先级高于读锁,一旦出现 MDL 写锁等待(线程申请不到 MDL 写锁),会阻塞后续该表的所有 CRUD 操作(MDL读锁)。
- 所以为了能安全的对表结构进行变更,在对表结构变更前,先要看看数据库中的长事务,是否有事务已经对表加上了 MDL 读锁,如果可以考虑 kill 掉这个长事务,然后再做表结构的变更。
-
意向锁
意向锁的目的是快速判断表里是否有记录被加锁。
意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S锁)
意向排他锁(intention exclusive lock, IX):事务有意向对表中的某些行加排他锁(X锁)
普通的SELECT语句利用MVCC实现一致性读,是无锁的,但是可以使用以下方式加锁:
//先在表上加上意向共享锁,然后对读取的记录加共享锁 select ... lock in share mode;//先表上加上意向独占锁,然后对读取的记录加独占锁 select ... for update;
意向锁之间不冲突,也不会和行级的共享锁和独占锁发生冲突,只会和共享表锁(lock tables … read)或独占表锁(lock tables … write)发生冲突。
-
AUTO-INC 锁(自动增长)
表里的主键通常都会设置成自增的,这是通过对主键字段声明 AUTO_INCREMENT 属性实现的。
在插入数据时,会加一个表级别的 AUTO-INC 锁,然后为被
AUTO_INCREMENT
修饰的字段赋值递增的值,等插入语句执行完成后,才会把 AUTO-INC 锁释放掉。- InnoDB 存储引擎提供了一种轻量级的锁来实现自增。只是在赋值完成后,就把该锁释放。
行级锁
对于表锁和行锁,满足读读共享、读写互斥、写写互斥的。
不同隔离级别下,行级锁的种类不同。
-
在读已提交隔离级别下,行级锁的种类只有记录锁,也就是仅仅把一条记录锁上。
-
在可重复读隔离级别下,行级锁的种类除了有记录锁,还有间隙锁(目的是为了避免幻读)。
行级锁的类型主要有三类:
-
记录锁(Record Lock),也就是仅仅把一条记录锁上;记录锁是有 S 锁和 X 锁之分的。
- 共享锁(S锁)指的就是对于多个不同的事务,对同一个资源共享同一个锁。 相当于对于同一把门,它拥有多个钥匙一样。
- 独占锁(X锁)也叫排他锁,是指该锁一次只能被一个线程所持有。
共享锁(S锁)满足读读共享,读写互斥;独占锁(X锁)满足写写互斥、读写互斥。
-
间隙锁(Gap Lock),锁定一个范围,但是不包含记录本身;只存在于可重复读隔离级别,目的是为了解决可重复读隔离级别下幻读的现象。
- 间隙锁之间是兼容的,即两个事务可以同时持有包含共同间隙范围的间隙锁,并不存在互斥关系,因为间隙锁仅仅是为了防止插入幻影记录而提出的。
-
临键锁(Next-Key Lock),Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。next-key lock 即能保护记录,又能阻止其他事务将新纪录插入到被保护记录前面的间隙中。
- next-key lock 是包含间隙锁+记录锁的,如果一个事务获取了 X 型的 next-key lock,那么另外一个事务在获取相同范围的 X 型的 next-key lock 时,是会被阻塞的。
-
插入意向锁:插入意向锁名字虽然有意向锁,但是它并不是意向锁,它是一种特殊的间隙锁,属于行级别锁。存在间隙锁时,执行Insert语句时会用到。
- 插入意向锁是一种特殊的间隙锁,但不同于间隙锁的是,该锁只用于并发插入操作。如果说间隙锁锁住的是一个区间,那么「插入意向锁」锁住的就是一个点。因而从这个角度来说,插入意向锁确实是一种特殊的间隙锁。
5.2 MySQL是怎么加锁的?
- 从语句角度来看
普通的SELECT默认是不加锁的,属于快照读,是使用MVCC的方式实现的。但是可以在查询时对记录加行级锁,查询会加锁的语句称为锁定读。锁定读的语句必须在事务中,因为当事务提交了,锁就会被释放。而update 和 delete 操作都会加行级锁,且锁的类型都是独占锁(X型锁)。
//对读取的记录加共享锁(S型锁)
select ... lock in share mode;//对读取的记录加独占锁(X型锁)
select ... for update;
而Insert 语句在正常执行时是不会生成锁结构的,它是靠聚簇索引记录自带的 trx_id 隐藏列来作为隐式锁来保护记录的。但此时记录之间加有间隙锁,隐式锁会转换为显示锁。
如果已加间隙锁,此时会生成一个插入意向锁,然后锁的状态设置为等待状态,现象就是Insert语句被阻塞。
- 因为插入意向锁与间隙锁是冲突的,所以当其它事务持有该间隙的间隙锁时,需要等待其它事务释放间隙锁之后,才能获取到插入意向锁。
如果记录之间加有间隙锁,为了避免幻读,此时是不能插入记录的,因为插入意向锁会被设置为等待状态;
如果 Insert 的记录和已有记录存在唯一键冲突,此时也不能插入记录,会对这条记录加上S型的锁;
- 至于是记录锁,还是 next-key 锁,跟是「主键冲突」还是「唯一二级索引冲突」有关系。
- 如果主键冲突:给已存在的主键索引记录添加S型记录锁。
- 如果唯一二级索引冲突:给已存在的二级索引记录添加S型next-key锁。
- 从MySQL角度来看
MySQL加锁的对象是索引,加锁的基本单位是 next-key lock。
- next-key lock 是前开后闭区间,而间隙锁是前开后开区间。在能使用记录锁或者间隙锁就能避免幻读现象的场景下, next-key lock 就会退化成退化成记录锁或间隙锁。
唯一索引等值查询,加锁情况分析:(主键索引为例)
- 当查询的记录是存在的,在索引树上定位到这一条记录后,该记录的索引中的 next-key lock 会退化成「记录锁」。
- 等值查询唯一索引,只需要加锁一条记录,并且加记录锁就可以避免幻读。
- 当查询的记录是不存在的,在索引树找到第一条大于该查询记录的记录后,将该记录的索引中的 next-key lock 会退化成「间隙锁」,因为仅靠间隙锁就可以避免幻读。
唯一索引范围查询,加锁情况分析:
-
首先会对每一个扫描到的索引加 next-key 锁,如果遇到下面这些情况,会退化成记录锁或者间隙锁:
-
对大于的范围查询,next-key锁不会退化。
select * from user where id > 15 for update;
-
对大于等于的范围查询,如果“等于”的等值查询的记录是存在于表中,那么该记录的索引中的 next-key 锁会退化成记录锁。
select * from user where id >= 15 for update;
-
对小于/小于等于的范围查询,扫描到终止范围查询的记录时,next-key锁就会退化为间隙锁。小于等于时,等值查询的记录在表中,next-key不会退化,因为next-key本就是左开右闭,避免幻读。
select * from user where id < 6 for update;
-
-
非唯一索引等值查询
-
当查询的记录存在时,扫描到的二级索引记录加的是next-key lock,扫描到的第一个不符合条件的二级索引记录,next-key 锁会退化成间隙锁。同时,在符合查询条件的记录的主键索引上加记录锁。
select * from user where age = 22 for update;
-
当查询的记录不存在时,扫描到第一条不符合条件的二级索引记录, next-key 锁会退化成间隙锁。因为不存在满足查询条件的记录,所以不会对主键索引加锁。
select * from user where age = 25 for update;
-
-
非唯一索引范围查询
- 对扫描到的二级索引记录加锁都是加 next-key 锁,主键索引加记录锁。
-
没有加索引的查询
- 在线上在执行 update、delete、select … for update 等具有加锁性质的语句,一定要检查语句是否走了索引,如果是全表扫描的话,会对每一个索引加 next-key 锁,相当于把整个表锁住了。
5.3 update没加索引会锁全表?
当我们执行 update 语句时,实际上是会对记录加独占锁(X 锁)的,此时其他事务对持有独占锁的记录进行修改时是会被阻塞的。另外,这个锁并不是执行完 update 语句就会释放的,而是会等事务结束时才会释放。
- 在 update 语句的 where 条件没有使用索引,就会全表扫描,于是就会对所有记录加上 next-key 锁(记录锁 + 间隙锁),相当于把整个表锁住了。
- 即使where条件使用了索引,还得看这条语句在执行过程中,优化器最终选择的是索引扫描,还是全表扫描,如果走了全表扫描,就会对全表的记录加锁了。
5.4 MySQL死锁了,怎么办?
RR隔离级别下,会存在幻读的问题,InnoDB为了解决可重复读隔离级别下的幻读问题,就引出了next-key 锁,是记录锁和间隙锁的组合。
我们可以执行 select * from performance_schema.data_locks\G;
语句 ,确定事务加了什么类型的锁。
-
为什么会出现死锁?
-
建了一张订单表,其中 id 字段为主键索引,order_no 字段普通索引,也就是非唯一索引(二级索引)
# 插入六条记录,id 1-6 、order_on 1001-1006
-
事务A要插入1007订单记录:在插入之前,给订单做幂等性校验,目的是为了保证不会出现重复的订单。
SELECT id FROM t_order WHERE `order_no` = 1007 for UPDATE; # 需要对订单做幂等性校验,所以两个事务先要查询该订单是否存在,不存在才插入记录
执行该语句,事务A在二级索引加了X型next-key锁,范围是(1006 , +∞)。
-
事务B也做幂等性校验:
SELECT id FROM t_order WHERE `order_no` = 1008 for UPDATE;
事务B在二级索引加了X型next-key锁,范围也是(1006 , +∞)。
-
事务A、B执行insert语句,插入1007、1008。
Insert into t_order (order_no, create_date) values (1007, now()); Insert into t_order (order_no, create_date) values (1008, now());
此时两个事务都陷入了等待状态,也就是发生了死锁,因为都在相互等待对方释放锁。
-
因为当我们执行insert语句时,会在插入间隙上获取插入意向锁,而插入意向锁与间隙锁是冲突的,所以当其它事务持有间隙锁时,需要等待其它事务释放间隙锁之后,才能获取到插入意向锁。
而间隙锁与间隙锁之间是兼容的,并且两个事务中
select ... for update
语句并不会相互影响。- 因为间隙锁的意义只在于阻止区间被插入,一个事务获取的间隙锁不会阻止另一个事务获取同一个间隙范围的间隙锁,共享和排他的间隙锁是没有区别的,他们相互不冲突,且功能相同,即两个事务可以同时持有包含共同间隙的间隙锁。
- next-key lock 是包含间隙锁+记录锁的,如果一个事务获取了 X 型的 next-key lock,那么另外一个事务再获取相同范围的 X 型的 next-key lock 时,是会被阻塞的。但是,对于这种范围为 (1006, +∞] 的 next-key lock,两个事务是可以同时持有的,不会冲突。因为 +∞ 并不是一个真实的记录,自然就不需要考虑 X 型与 S 型关系。
-
-
-
如何避免死锁?
死锁的四个必要条件:互斥、占有且等待、不可强占用、循环等待。只要系统发生死锁,这些条件必然成立,但是只要破坏任意一个条件就死锁就不会成立。
在数据库层面,有两种策略通过「打破循环等待条件」来解除死锁状态:
-
设置事务等待锁的超时时间。当一个事务的等待时间超过该值后,就对这个事务进行回滚,于是锁就释放了,另一个事务就可以继续执行了。在 InnoDB 中,参数
innodb_lock_wait_timeout
是用来设置超时时间的,默认值时 50 秒。 -
开启主动死锁检测。主动死锁检测在发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数
innodb_deadlock_detect
设置为 on,表示开启这个逻辑,默认就开启。
-
5.5 字节面试: 加了什么锁,导致死锁的?

创建一张学生表:其中id为主键索引,其他都是普通字段。
事务 A 和 事务 B 都在执行 insert 语句后,都陷入了等待状态,也就是发生了死锁,因为都在相互等待对方释放锁。

- Time1阶段:此时事务 A 在主键索引(INDEX_NAME : PRIMARY)上加的是间隙锁,锁范围是
(20, 30)
。(唯一索引等值查询,查询id不在索引中,退化成间隙锁) - Time2阶段:此时事务B在主键索引上加的是也是间隙锁,和事务A相同。
- Time3阶段:事务 A 的状态为等待状态(LOCK_STATUS: WAITING),因为向事务 B 生成的间隙锁(范围
(20, 30)
)中插入了一条记录,所以事务 A 的插入操作生成了一个插入意向锁(LOCK_MODE:INSERT_INTENTION
)。 - Time4阶段:与Time3阶段相同。
本次案例中,事务 A 和事务 B 在执行完后 update 语句后都持有范围为(20, 30)
的间隙锁,而接下来的插入操作为了获取到插入意向锁,都在等待对方事务的间隙锁释放,于是就造成了循环等待,满足了死锁的四个条件:互斥、占有且等待、不可强占用、循环等待,因此发生了死锁。
整理自:小林Coding
相关文章:

面试官:说一下MySQL中的锁机制吧
5. 1MySQL有哪些锁? 为保证数据的一致性,需要对并发操作进行控制,因此产生了锁。同时锁机制也为实现MySQL的各个隔离级别提供了保证。 锁冲突 也是影响数据库并发访问性能的一个重要因素。所以锁对数据库而言显得尤其重要,也更加…...

STL库中list的迭代器实现痛点分析
前文本篇文章准备换个模式,之前都是先详解模拟实现,但是模拟实现的基本逻辑大多数老铁都是明白的,所以我们这次主要讲解STL库中list的独特性,也就是模拟实现中的重难点文末有模拟实现的源码一,list实现的特殊类list实现…...

字符编码对比(GBK、Unicode、UTF-8)
摘要我们在网上能看到各种文字和符号,那么它们是怎么存储和转化的,还有我们常常提及的UTF-8,为什么都要设置这种编码方式,这里就探讨下。字符集字符集:就是各国文字、符号、数字的集合。常见的字符集有:ASC…...

【百面成神】Redis基础11问,你能坚持到第几问
前 言 🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端 ☕专栏简介:纯手打总结面试题,自用备用 🌰 文章简介:Redis最基础、重要的11道面试题 文章目录…...

十大排序算法极简汇总篇
说明 十大排序算法可以说是每个程序员都必须得掌握的了,如果你们像从 0 详细学习每一篇,那么你们可以看前面的文章。 但是呢,有些人可能已经学过,想要快速复习一下,看看代码怎么写的,那么可以看这篇十大排…...

数据结构笔记
文章目录第一章:数据结构与算法第二章:稀疏数组和队列一 、稀疏sparsearray 数组(一)案例需求(二)稀疏数组介绍(三)应用实列(四)代码实现二、队列(…...

web前端框架——Vue的特性
目录 前言: 一.vue 二.特性 1.轻量级 2.数据绑定 3.指令 4.插件 三.比较Angular 、React 、Vue 框架之间的比较 1. Angular Angular的优点: 2. React React 的优点: 3.vue 3.Vue的优点: 前言: 本篇文章…...

提权工具推荐(PEASS-ng、linpeas_linux_amd64、winPEASany_ofs)
介绍 在这里,您可以找到适用于Windows、Linux/Unix*和MacOS的权限提升工具。 这些工具搜索您可以利用的可能的本地权限提升路径,并用漂亮的颜色打印给您,这样您就可以很容易地识别错误配置。 查看book.hacktricks.xyz中的本地Windows权限提升检查表WinPEAS-Windows本地权限…...

Spark - 继承 FileOutputFormat 实现向 HDFS 地址追加文件
目录 一.引言 二.源码浅析 1.RDD.saveAsTextFile 2.TextOutputFormat 3.FileOutputFormat 三.源码修改 1.修改文件生成逻辑 - getRecordWriter 2.允许目录存在 - checkoutputSpecs 3.全部代码 - TextOutputFormatV2 四.追加存储代码实战 五.总结 一.引言 Output d…...

树莓派编程控制继电器及继电器组
目录 一,继电器说明 ● 继电器接口说明 ① 继电器输入端: ② 继电器输出端: 二,树莓派控制继电器 三,树莓派控制继电器组 一,继电器说明 通俗点讲,可以把继电器理解成是一些功能设备的控制开关。 ● LOW&#…...
oracle和mysql的区别
Oracle与MySQL的区别以及优缺点 MySQL的特点 1、性能卓越,服务稳定,很少出现异常宕机; 2、开放源代码无版本制约,自主性及使用成本低; 3、历史悠久,社区和用户非常活跃,遇到问题及时寻求帮助…...

<Linux开发> linux应用开发-之-uart通信开发例程
一、简介 串口全称叫做串行接口,串行接口指的是数据一个一个的按顺序传输,通信线路简单。使用两条线即可. 实现双向通信,一条用于发送,一条用于接收。串口通信距离远,但是速度相对会低,串口是一种很常用的工…...

基于深度学习的安全帽检测系统(YOLOv5清新界面版,Python代码)
摘要:安全帽检测系统用于自动化监测安全帽佩戴情况,在需要佩戴安全帽的场合自动安全提醒,实现图片、视频和摄像头等多种形式监测。在介绍算法原理的同时,给出Python的实现代码、训练数据集,以及PyQt的UI界面。安全帽检…...

Linux - 进程控制(进程替换)
0.引入创建子进程的目的是什么?就是为了让子进程帮我执行特定的任务让子进程执行父进程的一部分代码如果子进程想执行一个全新的程序代码呢? 那么就要使用进程的程序替换为什么要有程序替换?也就是说子进程想执行一个全新的程序代码ÿ…...
Java中 ==和equals的区别是什么?
作用: 基本类型,比较值是否相等引用类型,比较内存地址值是否相等不能比较没有父子关系的两个对象equals()方法的作用: JDK 中的类一般已经重写了 equals(),比较的是内容自定义类如果没有重写 equals(),将…...

Linux(网络基础---网络层)
文章目录0. 前言1. IP协议1-1 基本概念1-2 协议头格式2. 网段划分2-1 基本概念2.2 IP地址分五大类2-3 特殊的IP地址2-4 IP地址的数量限制2-5 私有IP地址和公网IP地址2-6 路由0. 前言 前面我们讲了,应用层、传输层;本章讲网络层。 应用层:我…...

空间信息智能应用团队研究成果介绍及人才引进
目录1、多平台移动测量技术1.1 车载移动测量系统1.2 机载移动测量系统2、数据处理与应用技术研究2.1 点云与影像融合2.2 点云配准与拼接2.3 点云滤波与分类2.4 道路矢量地图提取2.5 道路三维自动建模2.6 道路路面三维病害分析2.7 多期点云三维变形分析2.8 地表覆盖遥感监测分析…...

ChatGPT应用场景与工具推荐
目录 写在前面 一、关于ChatGPT 二、应用实例 1.写文章 2.入门新的知识 3.解决疑难问题 4.生成预演问题 5.文本改写 6.语言翻译 7.思维导图 8.PDF阅读理解 9.操作格式化的数据 10.模拟场景 11.写代码 三、现存局限 写在前面 本文会简单介绍ChatGPT的特点、局限以…...

图像分类卷积神经网络模型综述
图像分类卷积神经网络模型综述遇到问题 图像分类:核心任务是从给定的分类集合中给图像分配一个标签任务。 输入:图片 输出:类别。 数据集MNIST数据集 MNIST数据集是用来识别手写数字,由0~9共10类别组成。 从MNIST数据集的SD-1和…...

艹,终于在8226上把灯点亮了
接上次点文章ESP8266还可以这样玩这次,我终于学会了在ESP8266上面点亮LED灯了现在一个单片机的价格是几块,加上一个晶振,再来一个快递费,十几块钱还是需要的。所以能用这个ESP8266来当单片机玩,还是比较不错的可以在ub…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...