目录

一、什么是隔离级别

1.1、为什么复合操作需要事务?

1.2、事务的 ACID 特性如何保障操作可靠性?

1.3、隔离性通过隔离级别来控制

二、为什么用多级隔离级别

2.1、事务并发执行时可能引发以下问题

2.1.1、脏读(Dirty Read)- 读未提交

2.1.2、不可重复读(Non-Repeatable Read)-  读已更新

2.1.3、幻读(Phantom Read)-  读已新增已删除

2.2、SQL 标准定义的四级隔离级别(从低到高)

三、Mysql-innodb RC隔离级别解决幻读底层流程揭秘

3.1、模拟RC和RR隔离的事务情况

3.2、MVCC实现揭秘

3.2.1、数据版本链结构化表格(从新到旧排序)基于UNDO_LOG

3.2.2、版本链核心机制解析

3.2.2.1、版本链如何形成?

3.2.2.2、版本链的核心作用:支撑 MVCC 并发读

3.2.2.3、版本链的生命周期(undo log 回收)

3.2.3、如何根据undo_log中的版本链进行定位确定读取哪个版本数据呢?

3.2.3.1、核心概念定义

3.2.3.2、核心分工 

3.2.3.3、当前读与快照读的本质区别

3.2.3.4、ReadView:可见性判断的 “裁判”

3.3、拿上述模拟RC与RR的事务例子进行说明

3.3.1、例子

3.3.2、RC隔离级别 ReadView 以及规则判断

3.3.3、RR隔离级别 ReadView 以及规则判断 

 3.3.4、RR存在幻读的特例


一、什么是隔离级别

        在 MySQL 中,当需要执行多条 SQL 语句(例如 “先查询数据状态再进行更新”、“跨表关联修改数据” 等场景)时,单条 SQL 的独立执行无法保证整体操作的可靠性。此时需引入事务机制,通过 ACID 特性屏蔽并发业务的干扰,确保操作的原子性与完整性:

1.1、为什么复合操作需要事务?

假设业务场景为 “查询账户余额后进行转账”,若不使用事务:

  1. 事务 A 查询余额为 1000 元,准备转账 500 元;
  2. 此时事务 B 同时修改该账户余额为 0 并提交;
  3. 事务 A 继续执行转账操作,最终余额变为 - 500 元,导致数据错误。

事务的作用:将多条 SQL 语句封装为一个不可分割的整体,要么全部成功,要么全部回滚,避免中间状态被其他业务干扰。MySQL 的事务机制通过 ACID 特性,为多条 SQL 的复合操作提供了 “原子性保护罩”:既屏蔽了并发业务的干扰,又确保了数据在复杂操作中的一致性,是解决 “查询 - 修改” 类业务场景可靠性问题的核心方案。

1.2、事务的 ACID 特性如何保障操作可靠性?

特性含义及作用示例场景
原子性(Atomicity)事务中的操作要么全部完成,要么全部回滚,不存在部分成功的状态。转账操作中,扣款与到账必须同时成功,否则回滚至初始状态。
一致性(Consistency)事务执行前后,数据从一个合法状态变为另一个合法状态,避免逻辑错误。转账后,转出账户减少的金额必须等于转入账户增加的金额,总余额不变。
隔离性(Isolation)多个事务并发执行时,相互之间不可见、不干扰,通过隔离级别避免脏读、幻读等问题。事务 A 查询余额时,不受事务 B 未提交的修改影响,确保读取的数据是已提交的合法版本。
持久性(Durability)事务提交后,数据修改永久保存,即使数据库崩溃也能恢复。转账成功后,即使服务器断电,重启后数据依然有效。

1.3、隔离性通过隔离级别来控制

隔离性(Isolation) 正是通过设置多级隔离级别来控制不同事务之间的干扰程度。多级隔离级别的设计本质是在 “数据一致性” 和 “并发性能” 之间寻找平衡,不同级别对应不同的并发控制策略,同时来针对解决脏读、幻读等问题。

二、为什么用多级隔离级别

2.1、事务并发执行时可能引发以下问题

2.1.1、脏读(Dirty Read)- 读未提交

事务 A 读取到事务 B 未提交的修改,若 B 回滚,A 读取的数据即为无效。

核心逻辑

  1. 事务 B 的更新未提交时,事务 A 若能读到这个 “临时数据”,就会引发脏读
  2. 事务 B 回滚后,事务 A 之前读的 “李四” 实际不存在,数据一致性被破坏
时间点事务 A 操作事务 B 操作stu 表(id=1)数据状态关键问题(脏读风险)
T1-(未开始查询)-(未开始更新)name='李牛牛'-
T2-(等待)update stu set name='李四' where id=1(执行更新,但未提交)name='李四'(事务 B 未提交的临时状态)事务 B 修改了数据,但还没确认(未提交)
T3select * from stu where id=1(查询数据)-(等待)读事务 B 未提交的name='李四'脏读发生事务 A 读到了事务 B 未提交的临时数据
T4-(等待)rollback(回滚事务,撤销 T2 的修改)回滚为name='李牛牛'事务 B 的修改被撤销,事务 A 之前读的数据 “无效” 了
T5-(后续查询 / 业务逻辑)-(结束)name='李牛牛'若事务 A 基于 T3 的脏数据做业务,会出问题

2.1.2、不可重复读(Non-Repeatable Read)-  读已更新

事务 A 多次读取同一数据时,事务 B 在期间提交了修改,导致 A 前后读取结果不一致。

核心逻辑

  1. 事务 A 在同一事务内,先读李牛牛,后读李四
  2. 差异源于事务 B 在事务 A 执行期间提交了修改,破坏了 “同一事务内数据可重复读” 的预期。
时间点事务 A 操作事务 B 操作stu 表(id=1)数据状态关键现象(不可重复读)
T1-(未开始)-(未开始)name='李牛牛'-
T2select * from stu where id=1(第一次查询)-(等待)name='李牛牛'事务 A 拿到初始数据
T3处理其他数据(耗时操作)-(等待)name='李牛牛'数据暂时未变
T4-(等待)update stu set name='李四' where id=1(执行更新)name='李四'(事务 B 修改后)事务 B 修改了数据,但未提交
T5-(等待)commit(提交事务 B)name='李四'(已提交)事务 B 的修改生效,数据永久改变
T6select * from stu where id=1(第二次查询)-(结束)name='李四'不可重复读发生同事务内两次查询结果不同

2.1.3、幻读(Phantom Read)-  读已新增已删除

事务 A 按条件查询数据时,事务 B 插入了符合条件的新数据,导致 A 再次查询时结果集 “幻觉” 般新增记录。

核心逻辑

        1.事务 A 先查询 “无数据”→执行删除→再查询 “有数据(李牛牛)”;

        2.差异源于事务 B 在事务 A 执行期间插入并提交了新数据,让事务 A 产生 “数据幻觉”。

时间点事务 A 操作事务 B 操作stu 表数据状态关键现象(幻读)
T1-(未开始)-(未开始)空表(假设初始无数据)-
T2select * from stu(第一次查询)-(等待)空表事务 A 看到 “没有数据”
T3delete from stu(删除操作,实际无数据可删)-(等待)空表逻辑上 “删除所有数据”,但无实际效果
T4-(等待)insert into stu value(2, '李牛牛')(插入数据)插入后:id=2, name='李牛牛'(事务 B 未提交)事务 B 新增数据,但未提交
T5-(等待)commit(提交事务 B)数据变为:id=2, name='李牛牛'(已提交)事务 B 的插入生效,数据永久存在
T6select * from stu(第二次查询)-(结束)id=2, name='李牛牛'幻读发生同事务内前后查询数据量 / 内容突变

    多级隔离级别的存在,正是为了通过不同策略解决上述问题,同时避免过度锁定导致性能下降。

    2.2、SQL 标准定义的四级隔离级别(从低到高)

    隔离级别解决的问题并发性能影响MySQL 默认级别(InnoDB)
    读未提交(Read Uncommitted)不解决任何问题,可能出现脏读、不可重复读、幻读最高(几乎无锁定)一般不使用
    读已提交(Read Committed, RC)解决脏读,仍可能出现不可重复读、幻读较高(行级锁,提交后释放)是(大多数业务场景)
    可重复读(Repeatable Read, RR)解决脏读、不可重复读,仍可能出现幻读(Innodb除外)中等(行级锁 + 间隙锁,防止数据修改)可配置使用
    可串行化(Serializable)解决所有并发问题(脏读、不可重复读、幻读)最低(完全串行化执行)仅特殊场景使用

    三、Mysql-innodb RC隔离级别解决幻读底层流程揭秘

    在 MySQL 的 InnoDB 存储引擎里,RC(读已提交)和 RR(可重复读)这两种隔离级别,借助 MVCC(多版本并发控制)机制来处理并发事务。

    3.1、模拟RC和RR隔离的事务情况

    时间点事务 A(trx_id=1)事务 B(trx_id=2)事务 C(trx_id=3)事务 D(查询事务)stu 表(id=1)数据版本变化关键现象(RR vs RC)
    T1begin
    update name=' 李牛牛' where id = 1
    -(未开始)-(未开始)-(未开始)事务 A 修改后:版本 1(trx_id=1,name=' 李牛牛 ')-
    T2commit-(未开始)-(未开始)-(未开始)版本 1 提交,成为 “已提交版本”-
    T3-(结束)begin
    update name=' 李四' where id = 1
    -(未开始)-(未开始)事务 B 修改后:版本 2(trx_id=2,name=' 李四 ')版本 2 未提交,仅事务 B 可见
    T4-(结束)处理其他数据(耗时操作)-(未开始)select * from stu where id = 1RR和RC读版本1(李牛牛
    T5-(结束)commit-(未开始)处理其他数据(耗时操作)版本 2 提交,覆盖版本 1,成为新 “已提交版本”-
    T6-(结束)-(结束)begin
    update name=' 王五' where id = 1
    处理其他数据(耗时操作)事务 C 修改后:版本 3(trx_id=3,name=' 王五 ')版本 3 未提交,仅事务 C 可见
    T7-(结束)-(结束)处理其他数据(耗时操作)select * from stu where id = 1(第二次查询)

    RC读版本2(李四

    RR读版本1(李牛牛)-解决不可重复度

    T8-(结束)-(结束)commit(等待)版本 3 提交,覆盖版本 2,成为最新 “已提交版本”
    T8-(结束)-(结束)-(结束)(等待)无新修改,版本 3 仍为最新

    3.2、MVCC实现揭秘

    MVCC 的核心逻辑是通过维护数据的多个版本,让不同事务在并发访问时,能基于各自可见的版本读写数据,以此在保证一定数据一致性的同时,提升并发性能 ,平衡了数据一致性需求与系统并发处理能力。InnoDB 的数据版本链使用的是回滚日志(UNDO_LOG)是 MVCC 的底层支撑,通过TRX_IDDB_ROLL_PTR串联历史版本,让读写操作在并发时互不阻塞;而 隔离级别的差异 本质是 “读操作遍历版本链时的规则不同”(快照是否固定、遍历范围如何),最终导致 “可重复读” 或 “不可重复读” 的结果。

    3.2.1、数据版本链结构化表格(从新到旧排序)基于UNDO_LOG

    版本层级

    (新→旧)

    id姓名

    TRX_ID

    (修改事务 ID)

    DB_ROLL_PTR

    (回滚指针,指向上一版本)

    版本来源

    版本 3

    (最新)

    1王五30x6446123(指向版本 2)事务 3 修改并提交
    版本 21李四20x6346413(指向版本 1)事务 2 修改并提交
    版本 11李牛牛10x77108a12(指向版本 0)事务 1 修改并提交

    版本 0

    (最旧)

    1李牛牛nullnull初始数据(无事务修改)
    3.2.2、版本链核心机制解析
    3.2.2.1、版本链如何形成?
    • 每次事务修改数据时,InnoDB 会:
      ① 复制当前行的旧版本到 undo log(回滚日志);
      ② 生成新版本,记录自身TRX_ID(修改事务的 ID);
      ③ 通过DB_ROLL_PTR将新版本与旧版本串联,形成单向链表

    • 示例中,数据从 “李牛牛”→“李牛牛”→“李四”→“王五” 的演变,对应版本 0→1→2→3 的链式结构。

    3.2.2.2、版本链的核心作用:支撑 MVCC 并发读

    InnoDB 的 MVCC(多版本并发控制) 通过版本链实现 “读不阻塞写,写不阻塞读”:

    • 读操作(SELECT):根据当前事务的隔离级别一致性快照,从版本链的最新版本开始,向前遍历,跳过以下版本:
              ✖️ 事务未提交的版本(TRX_ID对应事务未提交);
              ✖️ 事务 ID 大于当前快照可见范围的版本(仅 RR 级别会严格校验)。
    • 写操作(UPDATE/DELETE):直接生成新的版本,追加到版本链末端(旧版本保留在 undo log,供回滚或 MVCC 读使用)。
    3.2.2.3、版本链的生命周期(undo log 回收)
    • 版本链中的旧版本不会永久保留,InnoDB 会通过 purge 线程 回收 “不再被任何事务需要的旧版本”(如:当所有活跃事务的快照都不包含某旧版本时,该版本会被清理)。
    • 这解释了为什么长事务会导致 undo log 膨胀(长事务的快照保留时间长,旧版本无法及时回收)。
    3.2.3、如何根据undo_log中的版本链进行定位确定读取哪个版本数据呢?

    在 MySQL 的 InnoDB 存储引擎中,MVCC 通过 版本链(undo log) 和 ReadView 机制 实现高并发下的数据一致性。当事务执行 快照读(如普通 SELECT)时,会根据 隔离级别 生成 ReadView(RC 级别每次查询生成新 ReadView,RR 级别事务启动时生成一次),并按规则遍历版本链,直至找到可见版本或链尾。而 当前读(如 SELECT ... FOR UPDATE)则直接读取最新版本并加锁,不依赖 ReadView。通过这种方式,MVCC 将数据可见性判断转化为高效的内存操作,既避免了锁冲突,又通过隔离级别灵活控制一致性,实现了性能与正确性的平衡。

    3.2.3.1、核心概念定义
    概念本质典型操作示例核心特点
    当前读读取数据的最新版本,并对数据加锁(共享锁 / 排他锁),保证并发一致性。SELECT ... FOR UPDATE(排他锁)
    SELECT ... LOCK IN SHARE MODE(共享锁)
    INSERT/UPDATE/DELETE(隐式加锁)
    ① 读最新数据;② 加锁,阻塞其他事务修改
    快照读读取数据的历史版本(通过 MVCC 的版本链),无需加锁(逻辑无锁)。普通 SELECT * FROM table(未加锁时)① 读历史版本;② 无锁,高并发友好
    ReadView一个 “可见性视图”,用于判断哪个历史版本对当前事务可见的规则集合。由 InnoDB 自动生成(随事务 / 查询启动)包含活跃事务 ID、版本范围等元数据
    3.2.3.2、核心分工 
    概念作用依赖关系
    MVCC多版本并发控制,通过维护数据的历史版本链(undo log),实现读写并发无锁化。是快照读的底层支撑,当前读也依赖其版本链(但行为不同)。
    快照读读取历史版本(非最新数据),无锁,高并发友好。必须依赖 ReadView 判断哪个历史版本可见。负责高并发场景。
    当前读读取最新版本,并加锁(共享 / 排他锁),保证写操作原子性。不依赖 ReadView(加锁,直接读最新),直接访问最新数据并加锁。负责强一致场景(如写操作、临界资源读取)。
    ReadView一个 “可见性规则集合”,记录生成时刻的活跃事务 ID 等信息,指导快照读选择历史版本。是快照读的可见性判断依据,决定从版本链中选哪个版本。
    3.2.3.3、当前读与快照读的本质区别
    特性快照读(Snapshot Read)当前读(Current Read)
    依赖 ReadView✅ 必须通过 ReadView 选择历史版本❌ 直接读取最新版本(忽略 ReadView)
    加锁机制❌ 无锁(MVCC 实现读 - 写并发)✅ 加锁(S/X 锁,阻塞其他事务修改)
    典型操作SELECT * FROM table(无锁查询)SELECT ... FOR UPDATE
    INSERT/UPDATE/DELETE
    一致性保证由 ReadView 和隔离级别控制(RC/RR 的差异)强一致性(读取时锁定最新数据)
    3.2.3.4、ReadView:可见性判断的 “裁判”

    ReadView 是一个动态生成的内存结构,包含四个核心字段:

    • m_ids:当前活跃事务 ID 集合(未提交的事务);
    • min_trx_idm_ids中的最小事务 ID;
    • max_trx_id:下一个待分配的事务 ID(未来事务的起始 ID);
    • creator_trx_id:当前事务自身的 ID。

    当事务执行快照读时,InnoDB 会按以下步骤遍历版本链:

    获取当前 ReadView(根据隔离级别生成,RC 每次查询生成,RR 事务启动时生成);

    从最新版本开始,检查每个版本的trx_id是否满足以下条件:

    条件结果
    trx_id < min_trx_id✅ 版本可见(事务已提交)
    trx_id ≥ max_trx_id❌ 版本不可见(事务在 ReadView 生成后启动)
    min_trx_id ≤ trx_id < max_trx_id 且 trx_id ∈ m_ids❌ 版本不可见(事务未提交)
    min_trx_id ≤ trx_id < max_trx_id 且 trx_id ∉ m_ids✅ 版本可见(事务已提交)

    递归检查:若当前版本不可见,则通过DB_ROLL_PTR回溯到上一版本,重复上述判断,直到找到可见版本或遍历到链尾。

    3.3、拿上述模拟RC与RR的事务例子进行说明

    我们把上面的例子挪下来。

    3.3.1、例子
    时间点事务 A(trx_id=1)事务 B(trx_id=2)事务 C(trx_id=3)事务 D(查询事务)stu 表(id=1)数据版本变化关键现象(RR vs RC)
    T1begin
    update name=' 李牛牛' where id = 1
    -(未开始)-(未开始)-(未开始)事务 A 修改后:版本 1(trx_id=1,name=' 李牛牛 ')-
    T2commit-(未开始)-(未开始)-(未开始)版本 1 提交,成为 “已提交版本”-
    T3-(结束)begin
    update name=' 李四' where id = 1
    -(未开始)-(未开始)事务 B 修改后:版本 2(trx_id=2,name=' 李四 ')版本 2 未提交,仅事务 B 可见
    T4-(结束)处理其他数据(耗时操作)-(未开始)select * from stu where id = 1RR和RC读版本1(李牛牛
    T5-(结束)commit-(未开始)处理其他数据(耗时操作)版本 2 提交,覆盖版本 1,成为新 “已提交版本”-
    T6-(结束)-(结束)begin
    update name=' 王五' where id = 1
    处理其他数据(耗时操作)事务 C 修改后:版本 3(trx_id=3,name=' 王五 ')版本 3 未提交,仅事务 C 可见
    T7-(结束)-(结束)处理其他数据(耗时操作)select * from stu where id = 1(第二次查询)

    RC读版本2(李四

    RR读版本1(李牛牛)-解决不可重复度

    T8-(结束)-(结束)commit(等待)版本 3 提交,覆盖版本 2,成为最新 “已提交版本”
    T8-(结束)-(结束)-(结束)(等待)无新修改,版本 3 仍为最新
    3.3.2、RC隔离级别 ReadView 以及规则判断

    在读已提交(RC)隔离级别下,每一次执行快照读(select语句)时,都会生成一个ReadView,在上述例子中事务4,在事务3与事务2提交过程中 进行了2次查询,也就是生成了2次ReadView。

    快照读时机ReadView的值

    版本链数据访问规则

    (每一个版本进行遍历判断找到对应版本)

    第一次快照读,是事务2还未提交

    m_ids=[2,3,4](当前活跃事务 ID 集合(未提交的事务)

    min_trx_id =2(m_ids中的最小事务 ID)

    max_trx_id = 5(下一个待分配的事务 ID(未来事务的起始 ID)

    creator_trx_id =4(当前事务自身的 ID)

    1、当前事务id == creator_trx_id(4)?

    (成立说明数据就是自己这个事务更改的)

    2、trx_id<min_trx_id(2)?

    (成立说明数据已经提交了,可以访问,只有版本链中的1满足,其他不满足)

    3、trx_id>max_trx_id(5)?

    (成立、并判断版本是否在m_ids中,如果在说明事务没有提交)

    4、min_trx_id(2)<=trx_id<=max_trx_id(5)

    (如果成立,说明这个版本事务没有被提交不能访问,不存在可以访问)

    (满足一个即可返回,顺序互斥判断)综上判断最终找到版本1,返回李牛牛

    第二次快照读,是事务2已提交,事务3未提交

    m_ids=[3,4](当前活跃事务 ID 集合(未提交的事务)

    min_trx_id =3(m_ids中的最小事务 ID)

    max_trx_id = 5(下一个待分配的事务 ID(未来事务的起始 ID)

    creator_trx_id =4(当前事务自身的 ID)

    1、当前事务id == creator_trx_id(4)?

    (成立说明数据就是自己这个事务更改的)

    2、trx_id<min_trx_id(3)?

    (成立说明数据已经提交了,可以访问,遍历到版本链中的2满足)

    3、trx_id>max_trx_id(5)?

    (成立说明该事务是在ReadView生成以后才开始,不容许访问。不成立,可以访问)

    4、min_trx_id(3)<=trx_id<=max_trx_id(5)

    (如果成立,说明这个版本事务没有被提交不能访问,不存在可以访问)

    (满足一个即可返回,顺序互斥判断)综上判断最终找到版本2,返回李四

    3.3.3、RR隔离级别 ReadView 以及规则判断 

    在可重复读(RR)隔离级别下,仅在第一次执行快照读(select语句)时,都会生成一个ReadView,后面快照读复用,在上述例子中事务4,在事务3与事务2提交过程中 进行了2次查询,也就是生成了1次ReadView。

    快照读时机ReadView的值

    版本链数据访问规则

    (每一个版本进行遍历判断找到对应版本)

    第一次快照读,是事务2还未提交

    m_ids=[2,3,4](当前活跃事务 ID 集合(未提交的事务)

    min_trx_id =2(m_ids中的最小事务 ID)

    max_trx_id = 5(下一个待分配的事务 ID(未来事务的起始 ID)

    creator_trx_id =4(当前事务自身的 ID)

    1、当前事务id == creator_trx_id(4)?

    (成立说明数据就是自己这个事务更改的)

    2、trx_id<min_trx_id(2)?

    (成立说明数据已经提交了,可以访问,只有版本链中的1满足,其他不满足)

    3、trx_id>max_trx_id(5)?

    (成立、并判断版本是否在m_ids中,如果在说明事务没有提交)

    4、min_trx_id(2)<=trx_id<=max_trx_id(5)

    (如果成立,说明这个版本事务没有被提交不能访问,不存在可以访问)

    (满足一个即可返回,顺序互斥判断)综上判断最终找到版本1,返回李牛牛

    第二次快照读,是事务2已提交,事务3未提交

    复用第一的快照读

    1、当前事务id == creator_trx_id(4)?

    (成立说明数据就是自己这个事务更改的)

    2、trx_id<min_trx_id(2)?

    (成立说明数据已经提交了,可以访问,只有版本链中的1满足,其他不满足)

    3、trx_id>max_trx_id(5)?

    (成立、并判断版本是否在m_ids中,如果在说明事务没有提交)

    4、min_trx_id(2)<=trx_id<=max_trx_id(5)

    (如果成立,说明这个版本事务没有被提交不能访问,不存在可以访问)

    (满足一个即可返回,顺序互斥判断)综上判断最终找到版本1,返回李牛牛

     3.3.4、RR存在幻读的特例

    在可重复读(RR)隔离级别下,仅在第一次执行快照读(select语句)时,都会生成一个ReadView,后面快照读复用。因为复用了 所以没有幻读的问题。

    特例:当两次快照读之间存在当前读(也就是说加了锁) ,ReadView会从新生成,导致产生幻读。

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

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

    相关文章

    odoo17 警示: selection attribute will be ignored as the field is related

    在 Odoo 17 中&#xff0c;当使用 related 字段时&#xff0c;直接在 fields.Selection 中指定选择列表会被忽略&#xff08;因为选择项会从关联字段继承&#xff09;。wtd_fuwlx fields.Selection(服务类型 , relatedwtd_id.fuwlx, storeTrue)遇到了一个警告&#xff0c;提示…

    gemma-3n-E2B多模态模型使用案例:支持文本、图像、语音输入

    参考&#xff1a; https://developers.googleblog.com/en/introducing-gemma-3n-developer-guide/下载&#xff1a; https://modelscope.cn/models/google/gemma-3n-E2B-it 模型下载 运行代码&#xff1a; https://github.com/huggingface/huggingface-gemma-recipes 微调&…

    计算机网络实验——互联网安全实验

    实验1. OSPF路由项欺骗攻击和防御实验一、实验目的验证路由器OSPF配置过程。验证OSPF建立动态路由项过程。验证OSPF路由项欺骗攻击过程。验证OSPF源端鉴别功能的配置过程。验证OSPF防路由项欺骗攻击功能的实现过程。二、实验任务使用自己的语言简述该实验原理。如图1所示的网络…

    Pytorch中torch.where()函数详解和实战示例

    torch.where() 是 PyTorch 中非常常用的一个函数&#xff0c;功能类似于 NumPy 的 where&#xff0c;用于条件筛选或三元选择操作。在深度学习训练、掩码操作、损失函数处理等场景中非常常见。一、基本语法 torch.where(condition, x, y)condition&#xff1a;一个布尔张量&…

    基于Hadoop的公共自行车数据分布式存储和计算平台的设计与实现

    文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍&#xff1a;基于Hadoop的公共自行车数据分布式存储与计算平台设计与实现数据介绍数据预处理 Hadoop 集群的几个主要节点介绍1. NameNode&#xff08;主节点&#xff09;2. DataNod…

    Java项目:基于SSM框架实现的程序设计课程可视化教学系统【ssm+B/S架构+源码+数据库+毕业论文】

    摘 要 使用旧方法对程序设计课程可视化教学信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在程序设计课程可视化教学信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题…

    Unity 实现 NPC 随机漫游行为的完整指南

    在游戏开发中&#xff0c;NPC&#xff08;非玩家角色&#xff09;的行为逻辑对于营造真实、沉浸式的游戏世界至关重要。一个常见但又极具表现力的需求是&#xff1a;让 NPC 在场景中自然地随机移动&#xff0c;仿佛它们有自己的意识和目的地。 本文将详细介绍如何使用 Unity 的…

    重新学习Vue中的按键监听和鼠标监听

    文章目录按键事件1. 使用 keyup.enter 修饰符2. 使用 v-on 监听键盘事件3. 在组件上监听原生事件Vue 2Vue 34. 全局监听键盘事件注意事项鼠标事件1. 基本鼠标事件监听常用鼠标事件2. 事件修饰符3. 鼠标按键检测4. 鼠标位置信息5. 自定义指令监听鼠标事件6. 组合鼠标事件7. 性能…

    vue2启动问题以及解决方案

    vue2启动时&#xff1a;ERROR Invalid options in vue.config.js: "typescript.validate.enable" is not allowed如果需要在 VSCode 中控制 TypeScript 验证&#xff1a;在项目根目录创建 .vscode/settings.json 文件&#xff08;如不存在&#xff09;添加以下配置&a…

    Vue响应式系统:从原理到核心API全解析

    响应式原理 响应式机制的主要功能就是&#xff0c;可以把普通的JavaScript对象封装成为响应式对象&#xff0c;拦截数据的读取和设置操作&#xff0c;实现依赖数据的自动化更新。 Q: 如何才能让JavaScript对象变成响应式对象&#xff1f; 首先需要认识响应式数据和副作用函数…

    水下目标检测:突破与创新

    水下目标检测技术背景 水下环境带来独特挑战&#xff1a;光线衰减导致对比度降低&#xff0c;散射引发图像模糊&#xff0c;色偏使颜色失真。动态水流造成目标形变&#xff0c;小目标&#xff08;如1010像素海胆&#xff09;检测困难。声呐与光学数据融合可提升精度&#xff0…

    高通SG882G平台(移远):2、使用docker镜像编译

    其实之前已经编译过了。今日搜索时发现&#xff0c;只有当时解决问题的汇总&#xff0c;没有操作步骤。于是记录下来。 建议使用Ubuntu20 LTS。 安装docker $ sudo apt update $ sudo apt install docker.io $ sudo docker -v Docker version 27.5.1, build 27.5.1-0ubuntu3…

    轻松上手:使用Nginx实现高效负载均衡

    接上一篇《轻松上手&#xff1a;Nginx服务器反向代理配置指南》后&#xff0c;我们来探讨一下如何使用Nginx实现高效负载均衡。 在当今高并发、大流量的互联网环境下&#xff0c;单台服务器早已无法满足业务需求。想象一下&#xff1a;一次电商平台的秒杀活动、一个热门应用的…

    身份证号码+姓名认证接口-身份证二要素核验

    身份证号实名认证服务接口采用身份证号码、姓名二要素核验的方式&#xff0c;能够快速确认用户身份。无论是新用户注册&#xff0c;还是老用户重要操作的身份复核&#xff0c;只需输入姓名及身份证号&#xff0c;瞬间即可得到 “一致” 或 “不一致” 的核验结果。这一过程高效…

    自动驾驶基本概念

    目录 自动驾驶汽车&#xff08;Autonomous Vehicles &#xff09; 单车智能 车联网 智能网联&#xff08;单车智能车联网&#xff09; 自动驾驶关键技术 环境感知与定位 车辆运动感知 车辆运动感知 路径规划与决策 自动驾驶发展历程 自动驾驶应用场景 自动驾驶路测…

    提示词框架(10)--COAST

    目前&#xff0c;有很多提示词框架都叫COAST&#xff0c;但是每个的解释都不同&#xff0c;出现很了很多解释和演化版本&#xff0c;不要在意这些小事&#xff0c;我们都是殊途同归--让AI更好的完成任务COAST框架&#xff0c;比较适合需要详细背景和技术支持的任务&#xff0c;…

    基于selenium实现大麦网自动抢票脚本教程

    闲来无事&#xff0c;打开大麦网发现现在大多数演唱票都需要手机端才能抢票&#xff0c;仅有很少一部分支持pc端用网页去抢票&#xff0c;但正所谓&#xff1a;道高一尺&#xff0c;魔高一丈&#xff0c;解决这个反爬问题&#xff0c;我们可以采用Airtest连接仿真机来模拟手机端…

    2048小游戏实现

    2048小游戏实现 将创建一个完整的2048小游戏&#xff0c;包含游戏核心逻辑和美观的用户界面。设计思路 4x4网格布局响应式设计&#xff0c;适配不同设备分数显示和最高分记录键盘控制&#xff08;方向键&#xff09;和触摸滑动支持游戏状态提示&#xff08;胜利/失败&#xff0…

    Windows VMWare Centos Docker部署Springboot + mybatis + MySql应用

    前置文章 Windows VMWare Centos环境下安装Docker并配置MySqlhttps://blog.csdn.net/u013224722/article/details/148928081 Windows VMWare Centos Docker部署Springboot应用https://blog.csdn.net/u013224722/article/details/148958480 Windows VMWare Centos Docker部署…

    【科普】Cygwin与wsl与ssh连接ubuntu有什么区别?DIY机器人工房

    Cygwin、WSL&#xff08;Windows Subsystem for Linux&#xff09;和通过 SSH 连接 Ubuntu 是三种在 Windows 环境下与类 Unix/Linux 系统交互的工具&#xff0c;但它们的本质、运行环境、功能范围有显著区别。以下从核心定义、关键差异和适用场景三个维度详细说明&#xff1a;…