当前位置: 首页 > news >正文

【MySQL04】【 redo 日志】

文章目录

  • 一、前言
  • 二、redo 日志
    • 1. redo 日志格式
    • 2. Mini-Transaction
      • 2.1 以组的形式写入 redo 日志
      • 2.2 Mini-Transaction (MTR)概念
    • 3. redo 日志写入过程
      • 3.1 redo 日志缓冲区
      • 3.3 redo 日志写入 log buffer
    • 4. redo 日志文件
      • 4.1 redo 日志刷盘机制
      • 4.2 redo 日志文件组
      • 4.3 redo 日志文件格式
    • 5. 相关的全局变量
  • 三、Checkpoint
  • 四、补充
    • 1. binlog 和 redo log 的区别
    • 2. redo log 写入的可靠性
  • 五、参考内容

一、前言

最近在读《MySQL 是怎样运行的》、《MySQL技术内幕 InnoDB存储引擎 》,后续会随机将书中部分内容记录下来作为学习笔记,部分内容经过个人删改,因此可能存在错误,如想详细了解相关内容强烈推荐阅读相关书籍


二、redo 日志

事务四大特性 :ACID (原子性、一致性、隔离性、持久性)

  1. 原子性 (atomicity):事务要么成功要么失败,不存在中间状态
  2. 一致性 (consistency):事务将DB 从一种状态转变为另一种一直的状态,在事务开始前和结束后,DB的完整性约束没有被破坏。
  3. 隔离性 (isolation):每个读写事务的对象对其他事物的操作对象能相互分离,即该事务提交前对其他事务都不可见,通常使用锁来实现
  4. 持久性 (durability):事务一旦提交,其结果就是永久性的

其中 D (持久性) 的是由 redo 日志来实现的, redo 日志由两部分组成:一是内存中的重做日志缓冲(redo log buffer),是易失的;而是redo 日志文件(redo log file),是持久的。


InnoDB 是以页为单位来管理存储空间的,我们进行的增删改查操作本质上都是对页的操作,而前面【MySQL03】【 Buffer Pool】 中提到过,InnoDB 在真正访问页面时,会先判断页在 Buffer Pool 中是否存在,如果存在则直接操作 Buffer Pool 中的页,否则将页从磁盘读取到 Buffer Pool 中再操作。而 Buffer Pool 中的页在被修改后并不会立刻刷新到磁盘,此时就会造成 Buffer Pool 中的页与磁盘页的数据并不相同,即脏页。而如果在一个事务提交后,修改数据写到 Buffer Pool 中但是并未刷盘,如果此时系统宕机内存数据全部丢失则会造成数据的不一致。

一个简单的做法是在事务提交前将所有的页面都刷新到磁盘,不过该方案存在如下问题:

  1. 刷新一个完整的页面太浪费了,有时候仅仅修改了页面的一个字节也需要将整个页刷新到磁盘。
  2. 随机IO刷新效率太低。一个事务可能包含很多语句,即使一个语句也可能修改很多页面,并且这些页面可能并不相邻,在将这些页面刷新到磁盘的时候需进行很对随机IO。

因为上述问题,InnoDB 并不是在事务提交时将所有页刷新到磁盘,而是将修改的内容记录下来,在合适的时机刷新到磁盘中。(记录的并不是全量内容,而是增量内容,因此需要 double write 来保证写入的可靠性。),比如某个事务将系统表空间第100号页面中偏移量为 1000 处的变量值从 1 改成2,只需要记录:

将系统表空间第100号页面中偏移量为 1000 处的变量值更新为2

当事务提交后就会将上述内容刷新到磁盘,即使之后系统崩溃了重启之后按照记录内容重新更新数据页即可。上述内容被称为重做日志(redo log),使用重做日志有如下好处:

  1. redo 日志占用空间非常小:在存储表空间ID、页号、偏移量以及需要更新的值时需要的存储空间很小。
  2. redo 日志是顺序写入磁盘的:在事务执行过程中每执行一条语句,就可能产生若干个 redo 日志,这些日志是按照产生的顺序写入磁盘的,即顺序IO。

所以 InnoDB 通过 Force Log at Commit 机制实现事务的持久性,即当事务提交时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务的提交操作完成才算完成。这里的日志指的是 重做日志,其由两部分组成,即 redo log 和 undo log。 redo log 用来保证事务的持久性; undo log 用来帮助事务回滚以及 MVCC 的功能。redo log 基本都是顺序写, 在 DB运行时不需要对 redo log 文件进行读取操作,而 undo log 是需要进行随机读写。

为了确保每次日志都写入重做日志文件,在每次将重做日志缓冲写入 redo log 后, InnoDB 都需要调用一次 fsync 来刷新文件缓冲区数据到磁盘中。InnoDB 允许设置非持久性的情况,即当事务提交时,日志不写入重做日志文件,而是等待一个时间周期后再执行 fsync 操作,借此可以提高DB性能,但是宕机后可能会存在最新数据丢失。

1. redo 日志格式

在这里插入图片描述

具体字段如下:

字段解释
typeredo 日志的类型, 占用 1 个字节
space ID表空间ID
page number页号
dataredo 日志的具体内容

在将一条记录插入到一个页面时,需要更改的地方非常多,如:

  1. 表中有多少个索引,一条Insert 语句就需要可能更新多少棵 B+Tree
  2. 针对某一棵B+Tree,即可能更新叶子节点页面,也可能更新内存节点页面,还可能创建新页面(如页分裂
  3. 可能更新 Page Directory 中的槽信息
  4. 可能更新 Page Header 中各种页面统计信息
  5. 等等

所以可能出现如下情况:在数据页修改的过程中,可能会出现很多不连续的修改,如下图:

InnoDB 设计了多种 redo 日志类型用于处理这种情况,这部分不做过多介绍,如有需要可以参考书中内容。

在这里插入图片描述


2. Mini-Transaction

2.1 以组的形式写入 redo 日志

在执行语句的过程中产生的 redo 日志,被 InnoDB 划分为了若干个不可分割的组。比如:

  1. 更新 Max Row ID 属性时产生的 redo 日志为一组,是不可分割的。
  2. 向聚簇索引对应的 B+Tree 的页面中插入一条记录时产生的 redo 日志为一组,是不可分割的。
  3. 向某个二级索引对应的 B+Tree 的页面中插入一条记录时产生的 redo 日志是一组,是不可分割的。
    InnoDB 规定执行需要保证原子性的操作时,所以必须以组的形式来记录 redo 日志;在进行恢复时,针对某个组中的 redo log ,要么把全部的日志都恢复,要么一条也不恢复。即 redo log 也存在自身的原子性。

这里存在两种情况:

  1. 有些需要保证原子性的操作生成了多条 redo log
    InnoDB 会在一组的最后一条 redo log 后面加上一条特殊类型的redo 日志,该类型的reod 日志名为 MLOG_MULTI_REC_END,结构只有一个 type 字段,对应十进制的数字31。在系统崩溃恢复的时候,只有解析到类型为 MLOG_MULTI_REC_END 的 redo 日志时,才认为解析到一组完整的redo 日志,才会进行恢复,否则直接放弃前面解析到的 redo 日志。

  2. 有些需要保证原子性的操作只生成一条 redo log
    这种情况虽然也可以在 redo log 后面追加一条 MLOG_MULTI_REC_END 日志,但是 InnoDB 设计的更加节约一些,在上面的 redo log 通用日志格式的时候介绍过 redo log 第一个字段是 type, 表示 redo 日志的类型,而这个字段实际占用 1 字节,但实际上, redo log 日志的类型并没有那么多种,所以其实使用 7位足以表示,因此 type 字段的第一位可以用来表示是否是单一日志,如下:
    在这里插入图片描述

2.2 Mini-Transaction (MTR)概念

InnoDB 将对底层页面进行一次原子访问的过程称为一个 Mini-Transaction (MTR)。即一个 MTR 可以包含一组 redo 日志,在进行崩溃恢复时,需要把这一组 redo 日志作为一个不可分割的整体来处理。

即:一个事务可以包含多个语句,一个语句可以包含多个 MTR,一个 MTR 可以包含多条 redo log。

3. redo 日志写入过程

InnoDB 将 MTR 生成的 redo 日志放在了大小为 512 字节的页中(由于 redo log block的大小和磁盘扇区大小一样,都是512 字节,因此重做日志的写入可以保证原子性,不需要 double writer 技术),这里的redo 日志页跟之前提到表空间中的数据页并不相同,为了方便区分我们将 redo 日志 写入的页称为 block。真正存储redo日志的部分是 log block body,log block header 和 log block trailer 存储的是一些管理信息。一个 redo log block 示意图如下:

在这里插入图片描述

3.1 redo 日志缓冲区

在【MySQL03】【 Buffer Pool】 中提到过 Buffer Pool 的概念。同理在写入 redo 日志时也不能直接写入到磁盘中,实际上在服务器启动的时候就向操作系统申请了一片连续的内存空间用于作为 redo log buffer (redo 日志缓冲区), 也可以称为 log buffer,这片连续的内存空间被划分为若干个连续的 redo log block ,如下图:
在这里插入图片描述

3.3 redo 日志写入 log buffer

向 log buffer 中写入redo 日志的过程是顺序写入的,也就是先往前面的 block 中写,当该 block 没有空闲空间后再写入下一个 block 中,因此当 log buffer 写入 redo 日志时,就需要一个全局变量 log_free 记录应该从哪个 block 的哪个偏移量写入,如下:
在这里插入图片描述

一个 MTR 执行过程中可能产生若干条 redo 日志,这些redo 日志是一个不可分割的组,所以并不是每生成一条 redo 日志就将其插入到 log buffer 中,而是将每个 MTR 运行过程中产生的日志先暂存到一个地方,当 MTR 结束后再将过程中产生的一组 redo 日志全部复制到 log buffer中。

另外需要注意的是:因为事务是可以并发执行的,每当一个 MTR 完成就会将该MTR 生成的 redo 日志复制到 log buffer 中,因此对于不同事务的 MTR 对应的 redo 日志可能是交替写入 log buffer 的。

4. redo 日志文件

4.1 redo 日志刷盘机制

redo 日志会先被写入到 内存中的 log buffer 中,在合适的时机再将 log buffer 中的数据刷新到磁盘中,刷盘时机如下:

  1. log buffer 空间不足,log buffer 大小通过 innodb_log_buffer_size 指定,当 log buffer 使用量超过50% 时,会触发刷盘机制
  2. 事务提交时会触发刷盘。
  3. 将脏页刷新到磁盘前,会先保证将该脏页对应的 redo 日志刷新到磁盘中,由于 redo 日志是顺序写入的,所以将某个脏页对应的redo 日志刷新到磁盘时,也会保证将其之前产生的 redo 日志刷新到磁盘
  4. 后台线程,大约每秒一次将log buffer 刷新到磁盘
  5. 正常关闭服务器时
  6. checkpoint 时。

4.2 redo 日志文件组

redo 日志文件组是一个逻辑上的概念,并没有一个实际存储的物理文件来表示 redo 日志文件组(log group)。InnoDB 默认情况下是存在多个 redo 日志文件的(默认为 ib_logfile0 和 ib_logfile1 两个文件),这多个 redo 日志文件,被称为 redo 日志文件组。当一个 redo log 写满后会选择下一个 redo 日志文件(如果循环写入可能会造成"追尾"的情况, InnoDB 通过 Checkpoint 机制来处理这种清理),如下:
在这里插入图片描述

4.3 redo 日志文件格式

redo 日志文件本质就是将 log buffer 刷新到磁盘文件中,因此redo 日志文件也是由若干个 512 字节大小 block 组成。在 redo 日志文件组中,每个文件的大小、格式都一样:

  1. 前 2048 个字节即 2KB(前4个block)用来存储一些管理信息
  2. 2048 个字节往后存储 log buffer 中的镜像。

redo 日志文件前2KB存储的的内容如下:

名称大小(字节)解释
log file header512记录该 redo 日志文件的一些整体属性
checkpoint1512记录checkpoint信息
512未使用
checkpoint2512记录checkpoint信息

需要注意的是:

  1. 对于上述这些信息,仅 redo 日志文件组的中的第一个 redo 日志文件保存这些信息,其余的文件仅仅保留上述空间而不保留文件信息,同时因为保存了上述信息,所以 redo 日志文件的写入并非是完全有序的。
    如下图:在同一个redo 日志文件组,由于 ib_logfile01 是日志文件组中的第一个文件,所以其前2KB 存储相关信息, 而 ib_logfile1 前2KB 仅仅保留空间而不保存文件信息
    在这里插入图片描述

5. 相关的全局变量

  1. log sequence number : InnoDB 中存在一个名为 log sequence number (lsn) 的全局变量,用来记录当前已经写入的 redo 日志量,其初始值是8704(初始值没有什么意义,仅仅就是一个数字),单位是字节,也就是说每写入1字节的 redo 日志,lsn 就会加1。每一组 MTR 生成的 redo 日志都有唯一的 lsn 值与其对应;lsn 值越小说明 redo 日志产生的越早。

    在MTR 结束时还会将MTR 执行过程中修改过的页面加入到 Buffer Pool 的 flush 链表中:当第一次修改某个已经加载到 Buffer Pool 中的页面时,就会把这个页面对应的控制块插入到 flush 链表的头部;之后在修改该页时如果页面已经存在在 flush 链表中则不会再次插入,也就是说,flush 链表中的脏页是按照页面第一次修改时间进行排序的,在这个过程中会在缓冲页对应的控制块中记录两个关于页面何时修改的属性:

    1. oldest_modification : 第一希修改 buffer pool 中某个缓冲页时,就将修改该页面的MTR开始时对应的lsn 值写入这个属性
    2. newest_modification : 每修改一次页面就会将该修改页面的 MTR结束时对应的值写入这个属性。也就是说该属性表示页面最近一次修改后对应的 lsn 的值。

    总的来说flush 链表中的脏页是按照页面第一次修改时间进行排序的,也就是按照 oldest_modification 属性 代表的lsn 的值进行排序;被多次更新的页面不会插入到 flush 链表中但是会更新 newest_modification 属性的值

  2. buf_next_to_write : redo 日志是先写入到 log buffer 中,之后才会被刷新到磁盘的 redo 日志文件中(并且由于 redo log block的大小和磁盘扇区大小一样,都是512 字节,因此重做日志的写入可以保证原子性,不需要 double writer 技术。),InnoDB 中存在一个buf_next_to_write 的全局变量用来标记当前 log_buffer 中已经有哪些日志被刷新到磁盘了。

  3. flushed_to_disk_lsn : lsn 表示系统写入的redo 日志量,这包括了写入到 log buffer 但是没有刷新到磁盘的redo 日志。因此 InnoDB还存在一个 flushed_to_disk_lsn 的全局变量用来记录刷新到磁盘的 redo 日志量。在系统启动时,flushed_to_disk_lsn 和 lsn 的初始值都是8704,在系统运行过程中由于部分 log buffer 没有刷新到磁盘会导致二者差异化。

三、Checkpoint

由于 redo 日志文件组的容量是有限的,所以不得不循环使用 redo 日志文件组的文件,但这需要判断redo 日志文件组中的哪些内容没有存在的必要:redo 日志只是为了在系统崩溃后恢复脏页用的,因此判断 redo 日志占用磁盘是否可以被覆盖的一句就是它对应的脏页是否已经被刷新到磁盘中。

InnoDB 存在一个全局变量 checkpoint_lsn 用来表示当前系统中可以被覆盖的 redo 日志的总览是多少,该变量的初始值也为 8704。当 脏页被刷新到磁盘上,就可以执行一个增加 checkpoint_lsn 的操作,这个过程称为执行一次 checkpoint。

InnoDB 中存在后台线程将脏页刷新到磁盘,这里的 刷新到磁盘 和 执行一次 chekcpoint 是两回事,一般来说,脏页的刷新和 执行一次 checkpoint 是在不同线程上执行的,并不是说每次有脏页刷新就要去执行一次 checkpoint。

执行一次 checkpoint 可以分为两个步骤:

  1. 计算当前系统中可以被覆盖的redo 日志对应的 lsn 值最大是多少

    redo 日志可以覆盖的前提是他对应的脏页被刷新到磁盘中,因此只要我们计算出当前系统最早修改的脏页对应的 oldest_modification 值,那么凡是系统在 lsn 值小于该节点的 oldest_modification 值时产生的redo 日志都可以被覆盖掉。我们把该脏页的 oldest_modification 赋值给 checkpoint_lsn。
    flush 链表的尾节点就是 系统中最早修改的脏页,其 oldest_modification 的值可以获取并赋值给 checkpoint_lsn,如果 redo 日志对应的 lsn 值小于 checkpoint_lsn 时就可以被覆盖掉。

  2. 将 checkpoint_lsn 与对应的 redo 日志文件组偏移量以及此次 checkpoint 的编号写到日志文件的管理信息(checkpoint1 和 checkpoint2, 当 checkpoint_no 是奇数时写入到 checkpoint2,是偶数时写入到 checkpoint1)中。

    InnoDB 维护了一个 checkpoint_no 变量用来统计系统执行了多少次 checkpoint;每执行一次 checkpoint,该变量的值就加1

注意:一般情况下都是后台线程对 LRU 链表和 flush 链表进行刷盘操作,因为刷盘操作比较慢,不想影响用户线程的处理请求。但是如果当前系统修改页面的操作过于频繁就会导致写 redo 日志的操作十分频繁,系统 lsn 值增长过快。如果后台线程的刷盘操作不能将脏页快速刷出,系统将无法执行 checkpoint ,可能就需要用户线程从 flush 链表中把那些最早修改的脏页同步刷新到磁盘。这样这些脏页对应的 redo 日志就没用了,就可以执行 checkpoint。

四、补充

1. binlog 和 redo log 的区别

  1. 二进制日志记录所有与 Mysql DB有关的日志记录,不管是什么存储引擎,而 重做日志是 InnoDB 特有的,仅记录 InnoDB 存储引擎的事务日志。
  2. 二进制日志记录的是关于一个事务的具体操作内容,即逻辑日志,而 重做日志记录的是每个页的更改的物理情况
  3. 二进制日志文件仅在事务提交前进行提交,即只写入磁盘一次,无论事务多大。而在事务进行过程中,重做日志条目会不断写入到重做日志文件中。
  4. 二进制日志写入后不会删除,会一直存放在磁盘上,用于主从同步或者数据恢复,因此可能会存在磁盘被而二进制日志占满的情况。而 redo log 目的是为了保证数据写入的可靠性以及效率提高,重做日志文件是可复用的,因此不会存在磁盘占用过多的情况

2. redo log 写入的可靠性

由于 redo log block 的大小和磁盘扇区大小一样,都是512 字节,因为扇区是写入的最小单位,所以可以保证写入是必定成功的。因此在重做日志的写入过程中不需要有 doublewrite

五、参考内容

书籍:《MySQL是怎样运行的——从根儿上理解MySQL》、《MySQL技术内幕 InnoDB存储引擎 》

如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正

相关文章:

【MySQL04】【 redo 日志】

文章目录 一、前言二、redo 日志1. redo 日志格式2. Mini-Transaction2.1 以组的形式写入 redo 日志2.2 Mini-Transaction (MTR)概念 3. redo 日志写入过程3.1 redo 日志缓冲区3.3 redo 日志写入 log buffer 4. redo 日志文件4.1 redo 日志刷盘机制4.2 r…...

Android线性布局的概念与属性

线性布局(LinearLayout)是Android中最简单的布局方式,线性布局方式会使得所有在其内部的控件或子布局按一条水平或垂直的线排列。如图所示,图a是纵向线性布局示意图,图b是横向线性布局示意图。 a)纵向线性布局示意图 …...

java反射介绍

Java反射API允许你在运行时检查和修改程序的行为。这意味着你可以动态地创建对象、查看类的字段、方法和构造函数,甚至调用它们。这是一个强大的特性,但也应该谨慎使用,因为它可以破坏封装性。 以下是使用Java反射的一些常见用途:…...

Spring中@Transactional的实现和原理

这篇文章写的很详细了,引自脚本之家 Java中SpringBoot的Transactional原理_java_脚本之家...

华为仓颉可以取代 Java 吗?

大家好,我是君哥。 在最近的华为开发者大会上,华为亮相了仓颉编程语言,这是华为历经 5 年,投入大量研发成本沉淀的一门编程语言。 1 仓颉简介 按照官方报告,仓颉编程语言是一款面向全场景智能的新一代编程语言&#…...

性能测试相关理解(一)

根据学习全栈测试博主的课程做的笔记 一、说明 若未特别说明,涉及术语都是jmeter来说,线程数,就是jmeter线程组中的线程数 二、软件性能是什么 1、用户关注:响应时间 2、业务/产品关注:响应时间、支持多少并发数、…...

缓存-分布式锁-原理和基本使用

分布式锁原理和使用 自旋 public Map<String, List<Catelog2Vo>> getCatalogJsonFromDBWithRedisLock() {Boolean b redisTemplate.opsForValue().setIfAbsent(Lock, Lock, Duration.ofMinutes(1));if (!b) {int i 10;while (i > 0) {Object result redisTe…...

判断国内ip

php代码 //是否国内ip function isChinaIP($ip) {saveLog("---isChinaIP----------");$url "https://searchplugin.csdn.net/api/v1/ip/get?ip".$ip;// 发送HTTP请求$response file_get_contents($url);$utf8String mb_convert_encoding($response, &…...

linux修改内核实现禁止被ping(随手记)

概述 Linux默认允许被ping。其主要决定因素为&#xff1a; 内核参数防火墙&#xff08;iptables/firewall&#xff09; 以上的决定因素是与的关系&#xff0c;即需要均满足。 因此&#xff0c;修改linux禁被ping有以上两种方法可以实现。 修改内核文件使禁ping 1. 临时生…...

mac M1安装 VSCode

最近在学黑马程序员Java最新AI若依框架项目开发&#xff0c;里面前端用的是Visual Studio Code 所以我也就下载安装了一下&#xff0c;系统是M1芯片的&#xff0c;安装过程还是有点坑的写下来大家注意一下 1.在appstore中下载 2.在系统终端中输入 clang 显示如下图 那么在终端输…...

代码随想录算法训练营第二十七天 |56. 合并区间 738.单调递增的数字 968.监控二叉树 (可跳过)

56. 合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;in…...

网络基础:IS-IS协议

IS-IS&#xff08;Intermediate System to Intermediate System&#xff09;是一种链路状态路由协议&#xff0c;最初由 ISO&#xff08;International Organization for Standardization&#xff09;为 CLNS&#xff08;Connectionless Network Service&#xff09;网络设计。…...

Java面试八股之如何提高MySQL的insert性能

如何提高MySQL的insert性能 提高MySQL的INSERT性能可以通过多种策略实现&#xff0c;以下是一些常见的优化技巧&#xff1a; 批量插入&#xff1a; 而不是逐条插入&#xff0c;可以使用单个INSERT语句插入多行数据。例如&#xff1a; INSERT INTO table_name (col1, col2) V…...

【密码学】什么是密码?什么是密码学?

一、密码的定义 根据《中华人民共和国密码法》对密码的定义如下&#xff1a; 密码是指采用特定变换的方法对信息等进行加密保护、安全认证的技术、产品和服务。 二、密码学的定义 密码学是研究编制密码和破译密码的技术科学。由定义可以知道密码学分为两个主要分支&#x…...

k8s record 20240703

1. containerd 它不用于直接和开发人员互动&#xff0c;在这方面不和docker竞争 containerd的用时最短&#xff0c;性能最好。 containerd 是容器的生命周期管理&#xff0c;容器的网络管理等等&#xff0c;真正让容器运行需要runC containerd 是一个独立的容器运行时&am…...

Ansible常用模块

华子目录 Ansible四个命令模块1.组成2.特点3.区别3.1command、shell模块3.2raw模块 4.command模块4.1参数表4.2free_form参数 5.shell模块5.1作用5.2例如 6.script模块6.1示例 7.raw模块7.1参数7.2示例 文件操作模块1.file模块1.1参数1.2示例 2.copy模块2.1参数 Ansible四个命令…...

【JavaScript脚本宇宙】提升用户体验:探索 JavaScript 库中的浏览器特性支持检测

深入探讨JavaScript库&#xff1a;功能、配置与应用场景 前言 在现代的Web开发中&#xff0c;JavaScript库扮演着至关重要的角色&#xff0c;帮助开发人员简化代码、提高效率、实现更好的用户体验。本文将探讨几个常用的JavaScript库&#xff0c;包括模块加载库、数据绑定库和…...

深度学习:C++和Python如何对大图进行小目标检测

最近在医美和工业两条线来回穿梭&#xff0c;甚是疲倦&#xff0c;一会儿搞搞医美的人像美容&#xff0c;一会儿搞搞工业的检测&#xff0c;最近新接的一个项目&#xff0c;关于瑕疵检测的&#xff0c;目标图像也并不是很大吧&#xff0c;需要放大后&#xff0c;才能看见细小的…...

Eureka从入门到精通面试题及答案参考

什么是Eureka?它在微服务架构中扮演什么角色? Eureka是Netflix开源的一款基于REST的服务发现组件,它主要应用于构建分布式系统中的服务注册与发现。在微服务架构中,Eureka扮演着至关重要的角色,它让微服务架构中的各个服务实例能够互相发现、相互调用,从而实现了服务之间…...

io流 多线程

目录 一、io流 1.什么是io流 2.流的方向 i.输入流 ii.输出流 3.操作文件的类型 i.字节流 1.拷贝 ii.字符流 ​3.字符流输出流出数据 4.字节流和字符流的使用场景 5.练习 6.缓冲流 1.字节缓冲流拷贝文件 2.字符缓冲流特有的方法 1.方法 2.总结 7.转换流基本用法…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...