MySQL的日志--Redo Log【学习笔记】
MySQL的日志--Redo Log
知识来源:
- 《MySQL是怎样运行的》--- 小孩子4919
MySQL的事务四大特性之一就是持久性(Durability)。但是底层是如何实现的呢?这就需要我们的Redo Log(重做日志)闪亮登场了。它记录着事务的所有操作,等到MySQL崩溃之后,哪怕修改的脏页生前还在
Buffer Pool
中遨游,此时也可以读取Redo Log
中的信息,将这些脏页生前的样貌刻在磁盘上。有关于
Buffer Pool
的知识可以查看mysql的Buffer Pool【学习笔记】-CSDN博客。
为什么持久化需要Redo Log?
最直接的方法,可以是等事务执行完成之后,立刻进行持久化操作。那为什么还需要Redo Log?
-
直接持久化的弊端
-
如果事务执行完成之后直接持久化,那么可能会进行大量的随机IO刷盘脏页数据。这时候,性能损耗很大,用户会觉得MySQL慢慢的。
-
并且直接持久化的空窗期较大,如果在这个时候断电,那么可能会出现事务部分操作成功,部分失败的情况。
-
-
Redo Log的好处
-
Redo Log记录的是MySQL执行语句需要的必要信息,比如:插入一条记录,那么Redo Log日志就会记录字段数量,插入页面的偏移量等等信息。相较于刷脏页的16KB,这短短的几十上百字节显得微不足道。并且Redo Log是顺序IO,也就是怼着Redo Log文件追加记录。持久化的空窗期就很小,持久化的效率很高!丝毫不影响用户体验。
-
Redo Log的格式
Redo Log的通用格式
根据type的不同,对应的data内部的格式和内容也会不同。这个通用格式比作一辆车,那么type就是车的型号,型号不同,那车的样子也会不同。
-
type:Redo Log的类型,MySQL5.7.22中共有53种不同的类型。
-
space ID:表空间ID。不知道表空间的可以看InnoDB的表空间【学习笔记】-CSDN博客。
-
page number:页号。也在表空间的文章中有说明。
-
data:根据type的不同而不同。
简单的Redo Log
如果该Redo Log中记录的是修改某页中的某个字段。如:修改系统表空间页号为7的页面中Max Row ID属性。MySQL在启动时,会将这个属性读取到内存赋值给一个全局变量中,用于赋值给那些有隐藏列row_id的新插入记录,随机自增1。等到这个值为256的倍数时,就会将该值持久化。此时会先在Buffer Pool中该页对应的缓冲页中修改该值,然后再记录Redo Log。等下次系统启动时,会读取Max Row ID属性增加256后(可能重启前,该值为257,需要保证这个值大于重启前的值),再赋值给内存中的全局变量。
-
对于这种只要将修改页面中某个偏移量开始的几个字节的值持久化的情况。只需要很简单的Redo Log便可以,这种Redo Log被称为物理日志。具体类型如下:
-
MLOG_1BYTE(type字段值为1):表示页面某个偏移量处写入1个字节。
-
MLOG_2BYTE(type字段值为2):表示页面某个偏移量处写入2个字节。
-
MLOG_4BYTE(type字段值为4):表示页面某个偏移量处写入4个字节。
-
MLOG_8BYTE(type字段值为8):表示页面某个偏移量处写入8个字节。
-
MLOG_WRITE_STRING(type字段值为30):表示页面某个偏移量处写入1个字节序列。
-
复杂的Redo Log格式
对于修改一个页面的一个字段来说,简单的Redo Log已经足够了。但是如果你需要插入一条记录(如果页面剩余空间不够,可能还需要进行页分裂)。并且被修改页面中的Page Header、Page Directory中都有值需要修改。例如:Page Directoy中的槽信息,Page Header中的PAGE_N_DIR_SLOTS(槽数量)。。
这时候简单的Redo Log格式已经不够用了。需要更加抽象,上层的记录方式,比如记录插入语句的必要信息,等数据恢复的时候,执行插入语句,而不是将对应修改的字段更新。
-
这些对应的type分别是:
-
MLOG_REC_INSERT(type的值为9):表示插入一条非紧凑行格式(REDUNDANT)
-
MLOG_COMP_REC_INSERT(type的值为38):表示插入一条紧凑行格式记录(COMPACT、DYNAMIC、COMPRESSED)
-
MLOG_COMP_REC_DELETE(type的值为58):表示删除一条紧凑行格式记录(COMPACT、DYNAMIC、COMPRESSED)
-
MLOG_COMP_LIST_START_DELETE(type的值为44):表示从给定的某条记录开始删除一系列紧凑型行格式记录
-
MLOG_COMP_LIST_END_DELETE(type的值为43):与MLOG_COMP_LIST_START_DELETE相呼应,表示删除一系列紧凑型行格式记录,直到MLOG_COMP_LIST_END_DELETE记录的行格式为止
-
-
这些Redo Log的data中的内容都是逻辑语句,而不是物理层面具体的偏移量处的值。
-
这边以MLOG_COMP_REC_INSERT举例子。
-
n_uniques:表示需要n_uniques个字段才能保证记录唯一。比如:对于聚簇索引来说,就是主键列数,对于二级索引来说,就是索引列+主键列数(无论记录对应的索引列是否为NULL)。
-
field1_len~fieldn_len:若干个字段存储空间大小。无论固定长度类型(INT)还是可变长度类型(VARCHAR)。
-
offset:前一条记录在页面中的偏移量,用于恢复时更新该记录记录头中的next_record属性为新插入记录真实数据开始的偏移量。
-
end_seg_len:可以转换成该记录占用存储空间的总大小。具体转换方式不展开。
-
Mini-Transaction(MTR)
-
首先提出一个最重要的问题--有了
Transaction
为什么还需要Mini-Transaction
?-
Tansaction
包含一系列数据库操作,每个操作对应一条数据库语句。 -
而每条数据库语句底层MySQL会执行很多动作分别是一条
redo log
,比如:向满的页面插入一条记录,MySQL就会执行页分裂:开辟新页、根据主键平分原来的数据(不考虑90-10划分机制)、插入新数据、新增目录项。(当然还有更新二级索引、系统页什么的。。这边就省略了) -
这个时候如果中途崩溃了,也就是说,只记录到"新数据插入"这条
redo log
,后面的日志没了。等到时候开始恢复数据,MySQL执行这一系列记载下来的redo log
,但是目录项没有生成,那这个B+树不就出问题了? -
所以这时候需要将对底层页面的操作划分成一个一个组,每个组被称为MTR,保证原子性,一组的redo log要不全部记录,要不全部不记录。如:对聚簇索引的操作划分成一个不可分割的组,这个组内的操作需要保证原子性。
-
-
如何划分
-
如果一个语句生成多个
redo log
-
那么在这一系列
redo log
后面再加上type为MLOG_MULTI_REC_END
的redo log
(里面有且仅有type这个字段),在解析redo log
的时候,如果没有读到这个类型的redo log
,那么就会将之前解析的redo log全部丢弃,一句也不执行。
-
-
如果一个语句生成一个
redo log
-
当然按照上面的方法也可以,但是有更好的方法节省一个字节。上面提到
redo log
最多也就53中类型,那么type
的第一位就可以拿出来标记为1,代表这个需要保证原子性的操作只产生了一条单一的redo log
。(其实上面也可以采用这种方法,比如10001
,那轻易可以划分成1|0001
,但是可能考虑兼容性吧。。。)
-
-
-
Mini-Transaction在事务中的层次
-
当然不同事务是可以并发持久化的,并且持久化单元就是MTR。
-
Redo Log写入过程
存储结构---Redo Log Block
-
每个Redo Log Block占512字节。有点类似于表空间中的页,有头有尾,中间部分存放记录。一条Redo Log可以被称为Redo Log记录。
-
log block header
-
LOG_BLOCK_HDR_NO
:每个block都有编号。就像页面有页号。-
计算公式是
((lsn/512)&0x3FFFFFFF)+1
,这个lsn后面会讲到。-
此时可以看到
LOG_BLOCK_HDR_NO
最大为1G(2^30),最多存在1G个block,所以Redo Log File
最多也就512GB -
LOG_BLOCK_HDR_NO
第一位是flush bit
,该值为1,则表示本block是在将Redo Log Buffer
中的block落盘操作中,第一个被刷入的block
-
-
-
LOG_BLOCK_HDR_DATA_LEN
:表示block使用的字节数。初始值为12字节,全部使用完则为512字节,否则则为redo log大小+12字节。 -
LOG_BLOCK_FIRST_REC_GROUP
:表示该block中第一个MTR中的第一个redo log记录偏移量。 -
LOG_BLOCK_CHECKPOINT_NO
:表示checkpoint的序号。
-
-
log block trailer
-
LOG_BLOCK_CHECKSUM
:校验和。
-
-
内存中---Redo Log Buffer
类似于缓冲页的Buffer Pool,块也有缓冲,叫做Redo Log Buffer,简称log buffer。在MySQl启动的时候向操作系统申请的连续内存空间,可以通过启动选项innodb_log_buffer_size来指定大小,默认16MB。
-
向
log buffer
中写入redo log
记录是顺序写入的,并且通过全局变量buf_free
指针来标记后续redo log
记录该从哪里开始写。 -
buf_next_to_write
指针标记后续redo log
记录从哪里开始刷入磁盘。 -
redo log
写入是以MTR为单位的,并且不同事务的MTR可以交替写入。比如:-
事务T1的两个MTR分别称为mtr_t1_1和mtr_t1_2;
-
事务T2的两个MTR分别称为mtr_t2_1和mtr_t2_2;
-
磁盘中---Redo Log File
-
Redo Log Buffer
刷盘到Redo Log File
的时机-
当
Redo Log Buffer
使用容量超过50%左右,就开始将缓存落盘。 -
默认情况下,事务提交时会立即将缓存落盘。可以通过
innodb_flush_log_at_trx_commit
系统变量设置,默认值为1。-
0:事务提交后,不立即将缓存落盘。缓存落盘的任务交给了后台线程。
-
1:事务提交后,立即将缓存落盘。(其实是先写到操作系统
page cache
中,然后调用fsync()系统调用,立即将page cache
中的数据写到磁盘中) -
2:事务提交后,立即将缓存写到操作系统的
page cache
中,具体何时写到磁盘,完全根据操作系统安排。
-
-
后台线程每秒一次,将缓存落盘。
-
正常关闭服务器
-
做checkpoint
-
-
Redo Log File
默认存放在MySQL的数据目录中,可以通过innodb_log_group_home_dir
设置。默认有两个文件--ib_logfile1
和ib_logfile2
,可以通过innodb_log_files_in_group
设置数量,文件的命名采用ib_logfile[n],n=0,1,2...。每个文件大小默认48MB,可以通过innodb_log_file_size
设置。-
书写顺序是从
ib_logfile0
开始写,写满则写ib_logfile1
,不断延续。如果全部都被写满了,则从ib_logfile0
重新开始写。 -
Redo Log File的总大小是
innodb_log_files_in_group * innodb_log_file_size
-
-
Redo Log File
的格式-
由两部分组成前四个block+后续存储Redo Log的block
-
前四个block的结构
-
log file header:描述该redo log file的整体信息
-
-
checkpoint1
-
-
checkpoint2:和checkpoint1一致
-
-
-
Log Sequence Number(LSN)
-
lsn
是MySQL
的一个全局遍历,用来标注系统中写入的Redo Log
量(包括刷入磁盘的、和存在Redo Log Buffer
中的)-
初始值为8704,后续增加多少
Redo Log
量,则增加相应的值(还包括block的头尾所占的字节)-
此时
mtr_1
为200字节,mtr_2
为1000字节,那么计算当前lsn
则为8704+200+1000+12*3+4*2=9948字节
。
-
-
-
而还有一个全局变量
flushed_to_disk_lsn
,则用来标注系统刷入磁盘的Redo Log
量。这个变量的计算方式同lsn
。 -
flush
链表(存在于Buffer Pool,专门用于记录脏页的控制块)中的lsn
-
控制块中有两个变量
oldest_modification
和newest_modification
。oldest_modification
记录第一次修改该缓冲页前的MTR
所对应的lsn
(只要该脏页的控制块存在于链表中,那么这个变量就只会赋值一次,并且按照这个值从大到小排序);newest_modification
记录最近一次修改脏页后的MTR
的lsn
值。举个例子:-
原来的链表样子
-
MTR3
修改了页b和页d,修改前的lsn
为9948,修改后的lsn为10000
-
-
checkpoint
如果脏页落盘,那么记录修改对应脏页的Redo Log也就没有存在的必要了,可以被后面新的Redo Log覆盖了,checkpoint这个机制便是判断redo log file是否可以覆盖的保证。串联了flush中的lsn和Redo Log File前四个block中LOG_HEADER_START_LSN和LOG_CHECKPOINT_LSN这两个属性。请看下面的例子:
-
现在MySQL中
Buffer Pool
、Redo Log Buffer
和Redo Log File
的样子-
在执行了
mtr_1
、mtr_2
、mtr_3
后的样子,并且除了mtr_3
,其余mtr都完成了持久化
-
-
随后
mtr_1
对应的脏页a完成了持久化,那么此时mtr_1
中的Redo Log
都失去了作用。-
此时会将该脏页的
newest_modification
赋值给磁盘中对应页File Header
中FILE_PAGE_LSN
字段(后续用于快速恢复,不知道页结构的可以看mysql如何将数据组织起来的,索引(自底向上,以innodb存储引擎为例)【学习笔记】-CSDN博客)
-
-
异步线程就会执行一次
checkpoint
,来设置Redo Log File
头部的那两个属性。(脏页落盘和执行checkpoint
虽然是有明显的先后顺序,但并不是一次脏页落盘,就执行一次checkpoint
)-
内存中有一个全局变量
checkpoint_lsn
来记录当前可以覆盖的Redo Log
总量大小,初始化为8704 -
将当前MySQL中最早修改的脏页对应的的控制块中的
oldest_modification
赋值给checkpoint_lsn
,由于脏页a已经落盘,那么最早修改的脏页就成为了脏页c,为8916。 -
内存中有一个全局变量
checkpoint_no
来记录当前checkpoint
的编号。每次执行完checkpoint
后会赋值给LOG_CHECKPOINT_NO
,随后自增1。-
当
checkpoint_no
的值是偶数时,就写到checkpoint1
中;是奇数时,就写checkpoint2
中。
-
-
将
checkpoint_lsn
赋值给LOG_CHECKPOINT_LSN
,并通过checkpoint_lsn
计算出对应Redo Log File
中的offset
赋值给LOG_CHECKPOINT_OFFSET
。 -
checkpoint完成后,各个lsn的值
-
可以通过
show engine innodb status\G
查看各个lsn
-
-
崩溃恢复
-
确定起点:首先通过比较两个
checkpoint block
的LOG_CHECKPOINT_LSN
,选出较大的checkpoint block
。并且通过其LOG_CHECKPOINT_OFFSET
获得到Redo Log File
对应的偏移量,这个便是恢复的起点。(从前面可知,lsn小于LOG_CHECKPOINT_LSN
的Redo Log
所对应的脏页已经成功落盘了。至于大于等于lsn
的Redo Log
记录无法确定是否落盘,因为脏页落盘和checkpoint
是异步的,在两者间的空窗期,发生崩溃的话,就无法通过LOG_CHECKPOINT_LSN
确定哪些脏页已经落盘了) -
确定终点:从起点开始,一路向后遍历,直到遍历到
log block header
中LOG_BLOCK_HDR_DATA_LEN
不为512字节的(如果为512字节,则表示该block全部写满Redo Log记录) -
快速恢复手段:
-
使用hash结构:将需要恢复的Redo Log记录中的表空间ID和页号作为key,Redo Log记录作为value存入hash结构,对于修改同一页面的Redo Log用链表串起来,一起执行。
-
使用磁盘页中
File Header
中的FILE_PAGE_LSN
字段:前面提到这个字段记录脏页的控制块中newest_modification
的值,也就是说如果这个值大于LOG_CHECKPOINT_LSN
,那么该脏页一定是在执行最后一次checkpoint后落盘的,那么该页相关的lsn
小于FILE_PAGE_LSN
的Redo Log
就不需要被用于恢复了(也就是直接掠过这些Redo Log
记录)
-
TIPS:此时有一个巨大的问题,也就是说,如果有一个事务执行到一半,并且前半个事务的sql语句都被记录到Redo Log中并且持久化了(innodb_flush_log_at_trx_commit设置为0,并且这个事务执行时间超过1秒)。这个时候恢复不就不能保证该事务的原子性了吗。非也,这个时候Undo Log熠熠生辉。
相关文章:
MySQL的日志--Redo Log【学习笔记】
MySQL的日志--Redo Log 知识来源: 《MySQL是怎样运行的》--- 小孩子4919 MySQL的事务四大特性之一就是持久性(Durability)。但是底层是如何实现的呢?这就需要我们的Redo Log(重做日志)闪亮登场了。它记录着…...
《系统分析师-第三阶段—总结(五)》
背景 采用三遍读书法进行阅读,此阶段是第三遍。 过程 第9章 总结 在这个过程中,对导图的规范越来越清楚,开始结构化,找关系,找联系。...
【LangChain4j】AI 第二弹:项目中接入 LangChain4j
普通接入方式 参考文档: Get Started https://docs.langchain4j.dev/get-started 1.添加依赖 <!-- 基于open-ai的langchain4j接口:ChatGPT、deepseek都是open-ai标准下的大模型 --> <dependency><groupId>dev.langchain4j</grou…...
测试基础笔记第十天
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、查询语句1.基本查询2.条件查询3.模糊查询4.范围查询5.判断空 二、其他复杂查询1.排序2.聚合函数3.分组4.分页查询 一、查询语句 1.基本查询 – 需求1: 准备商…...
代理模式:控制对象访问的中间层设计
代理模式:控制对象访问的中间层设计 一、模式核心:通过代理对象控制对目标对象的访问 在软件开发中,有时需要为对象添加一个 “代理” 来控制对它的访问,例如: 远程代理:访问远程对象时(如 R…...
Python类和对象二(十一)
构造函数: 重写: 通过类名访问类里面的方法的做法,称为调用未绑定的父类方法,他有时候会产生钻石继承问题: 发现A重复初始化了两次,类c同事继承类B1和B2,类B1和B2又是继承类A的,当c…...
大模型在代码安全检测中的应用
大模型在代码安全检测领域的应用近年来取得显著进展,尤其在代码审查(Code Review, CR)场景中展现出高效性与准确性。以下是其核心优势、技术路径、挑战及实践案例的总结: 一、技术优势与核心能力 语义理解与上下文分析 大模型通过…...
Python实现图片浏览器
Python实现图片浏览器 支持浏览多种常见图片格式:JPG, JPEG, PNG, GIF, BMP, TIFF, WEBP 通过"打开文件夹"按钮选择任何包含图片的文件夹 灵活的排序选项: 按时间排序(新→旧或旧→新) 按文件名排序(A→…...
网页设计规范:从布局到交互的全方位指南
网页设计规范看似繁杂,但其实都是为了给用户提供更好的体验。只有遵循这些规范,才能设计出既美观又实用的网页,让用户在浏览网页时感到舒适、愉悦。 一、用户体验至上 用户体验(UX)是网页设计的核心原则之一。设计师…...
哪些心电图表现无缘事业编体检呢?
根据《公务员录用体检通用标准》心血管系统条款及事业单位体检实施细则,心电图不合格主要涉及以下类型及处置方案: 一、心律失常类 早搏:包括房性早搏、室性早搏和交界性早搏。如果每分钟早搏次数较多(如超过5次)&…...
Java基础系列-HashMap源码解析1-BST树
文章目录 序二叉搜索树(BST)引入查找5插入9极端情况删除删除叶节点 10删除节点只有左子树或只有右子树删除节点既有左子树又有右子树为什么这么代替? 序 提到HashMap,就不得不提红黑树(HashMap1.8之后)&am…...
生物计算安全攻防战:从DNA存储破译到碳基芯片防御体系重构
随着碳基生物芯片突破冯诺依曼架构限制,DNA数据存储密度达到1EB/克量级,合成生物学与信息技术的融合正引发新一轮安全革命。本文深入解析碳基芯片逆向工程路径,揭示酶驱动DNA数据解码的技术突破,预警合成生物回路潜在的数据泄露风…...
【金仓数据库征文】从Oracle到KingbaseES的语法兼容与迁移
随着“信创”战略的深入推进,国产数据库逐渐成为IT系统的重要组成部分。KingbaseES(金仓数据库)凭借其良好的Oracle兼容性和日益完善的生态,成为金融、政务等核心行业国产化替代的重要选项。本文将从语法兼容性分析出发࿰…...
MATLAB 下载安装教程
## 一、下载MATLAB 1. 访问 MathWorks 官方网站:https://www.mathworks.com/ 2. 点击右上角的"登录"按钮 - 如果没有账号,需要先注册一个 MathWorks 账号 - 学生可以使用教育邮箱注册,获得教育版授权 3. 登录后,点击&…...
Android kotlin通知功能完整实现指南:从基础到高级功能
本文将详细介绍如何在Android应用中实现通知功能,包括基础通知、动作按钮和内联回复等高级特性。 一、基础通知实现 1. 基本通知发送方法 fun sendBasicNotification(context: Context, title: String, message: String) {// 1. 创建通知渠道(Android 8.0必需)va…...
Javase 基础入门 —— 04 继承
本系列为笔者学习Javase的课堂笔记,视频资源为B站黑马程序员出品的《黑马程序员JavaAI智能辅助编程全套视频教程,java零基础入门到大牛一套通关》,章节分布参考视频教程,为同样学习Javase系列课程的同学们提供参考。 01 什么是继…...
2.4/Q2,Charls最新文章解读
文章题目:The impact of hearing ability on depression among retired middle-aged and elderly individuals in China: the chain mediating role of self-rated health and life satisfaction DOI:10.1186/s41043-025-00791-9 中文标题:中…...
对流对象的理解
在c里,“流”可以理解为数据传输与操作的“介质”。 从输入输出角度来看,有输入流(比如cin)和输出流(cout)。对于输入流,数据通过它从外部设备(例如键盘)“流入”程序内…...
RBAC权限-笔记
1. RBAC模型简介 1.1. RBAC三要素 RBAC权限模型(Role-Based Access Control:基于角色的访问控制)有3个基础组成部分,分别是:用户、角色和权限。它们之间的关系如下图所示: 用户(User)…...
stm32之GPIO函数详解和上机实验
目录 1.LED和蜂鸣器1.1 LED1.2 蜂鸣器 2.实验2.1 库函数:RCC和GPIO2.1.1 RCC函数1. RCC_AHBPeriphClockCmd2. RCC_APB2PeriphClockCmd3. RCC_APB1PeriphClockCmd 2.1.2 GPIO函数1. GPIO_DeInit2. GPIO_AFIODeInit3. GPIO_Init4. GPIO_StructInit5. GPIO_ReadInputDa…...
MsQuick编译和使用
MsQuick编译和使用 编译克隆代码使用cmakevs2022编译 使用示例 编译 克隆代码 git clone --recurse-submodules https://github.com/microsoft/msquic.git使用cmakevs2022编译 然后直接configure之后Generate然后打开vs工程编译即可生成动态库 使用示例 #include <s…...
01 ubuntu中wps桌面快捷键无法使用
文章目录 1. 问题描述:2. 解决方法:3. 结果展示4. 参考 1. 问题描述: 2. 解决方法: 添加权限 chmod 755 ./wps-office-prometheus.desktop 右键选择允许运行 3. 结果展示 修改前 修改后 4. 参考 参考1...
云原生后端架构:重塑后端开发的新范式
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:后端开发的新时代正在到来 传统的后端开发常常面临如下挑战:部署流程复杂、环境不一致、系统难以扩展、监控能力薄弱、上线流程缓慢。在企业数字化转型、业务快速迭代的大背景下,这些问题暴露得…...
Linux命令-tcpdump
tcpdump 是一个功能强大的网络数据包捕获和分析工具。以下是 tcpdump 命令的完整参数列表及说明: 参数 -a 将网络地址和广播地址转换为名字 tcpdump -a -i eth0-A 以 ASCII 格式打印所有分组,最小化链路层头部信息 tcpdump -A-b 在数据链路层上选择协议…...
分糖果——牛客
链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 幼儿园准备了nnn包糖果,每包糖果里有111、222或333颗美味的糖果。现在需要将这些这些糖果平分给两个表现优异的小朋友以作奖励,为了公平公正,需要…...
L0、L2和L∞范数这三种范数的区别
目录 一、解释 1. L0范数:数一数你有多少件行李 2. L2范数:别把行李塞得太满 3. L∞范数:别带任何超重的东西 一句话总结 二、作用 1. L0范数的作用:做减法,只留最重要的…...
[实战]zynq7000设备树自动导出GPIO
目录 zynq7000设备树自动导出GPIO添加设备树节点验证实验 结论 zynq7000设备树自动导出GPIO 今天无聊,掏出我82年产的microzed玩一玩。玩啥好呢,要不点个灯吧。于是,三下五除二,通过linux sys接口以及echo,很快就点亮…...
java六人打分
import java.util.Scanner;public class HelloWorld {public static void main(String[] args) {//打分平均分System.out.println("请输入六个评分");Scanner sc new Scanner(System.in);double[] score new double[6];for(int i0;i<score.length;i){System.ou…...
量子计算浪潮下的安全应对之法
量子计算凭借其强大的计算能力,被传言能够在极短时间内秒级破解传统计算机需耗时漫长岁月(以万年算)才能解开的密码,成为了近年来人们讨论的热点。这看似高深的科技名词在网络安全中又扮演着何种角色?我们应从当前人们…...
Windows Server 2022 常见问题解答
一、安装与部署 1.1 系统要求 硬件配置:最低需要 1.4 GHz 64 位处理器、512 MB 内存、32 GB 硬盘空间。但在实际生产环境中,为确保系统流畅运行,建议使用 2.0 GHz 以上处理器、8 GB 以上内存和 100 GB 以上硬盘。软件兼容性:与大多数基于 Windows 的企业级应用兼容,但在安…...
项目组合管理PPM
项目组合管理(Project Portfolio Management, PPM)详述 一、定义与核心目标 定义 项目组合管理是通过系统化的方法,对组织的所有项目和项目集进行识别、选择、优先级排序、资源配置和动态监控,以确保其与战略目标一致,并最大化投资回报(ROI)的管理过程。 核心目标 战略…...
自建开源远程协助服务RustDesk —— 筑梦之路
开源项目 # 服务端https://github.com/rustdesk/rustdesk-server.git# 客户端https://github.com/rustdesk/rustdesk.git 搭建服务端 需要使用的端口、协议 hbbs - RustDesk ID 注册服务器 hbbr - RustDesk 中继服务器默认情况下,hbbs 监听 21115(tcp) , 21…...
【android bluetooth 协议分析 11】【AVDTP详解 2】【avdtp 初始化阶段主要回调关系梳理】
在车机中 a2dp 通常情况下作为 sink. 本篇来帮助各位 朋友梳理一下,这部分的初始化流程。 我们着重梳理 native 层的逻辑, framework - java 侧一般比较容易看明白, 暂时不做梳理。 如果需要笨叔梳理的可以在博客评论。 出专门的章节来梳理。…...
C++回顾 day3
宏定义的数据是在预处理发生了替换 const类型的数据是在编译阶段发生的替换 命名空间 namespace 空间名{int a;void func_print(){printf("func_print");}struct Stu{int x;char *y;};//或者其他命名空间 } Space::x 20; cout << Space::x;using Space::x;…...
机器学习算法-分类决策树
分类决策树算法-python实现 数据集 具体方法是:从根结点开始,对结点计算所有可能的特征的信息增益,选择信息增益最大的特征作为结点的特征,由该特征的不同取值建立子节点;再对子结点递归地调用以上方法,构…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(9): 意向形
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(9): 意向形 1、前言(1)情况说明(2)工程师的信仰 2、知识点(1)「~てしまう」=「~ちゃう…...
kotlin与MVVM结合使用总结(一)
一、Kotlin 与 MVVM 结合的核心优势 代码简洁性 数据类(data class)简化 Model 层定义,自动生成equals/hashCode/toString扩展函数简化 View 层逻辑(如点击事件扩展)lateinit/by lazy优化 ViewModel 属性初始化 异步处…...
达妙电机CAN通信及实验
项目进一步往下做的时候,要上实物了,需要用到达妙电机,虽然有说明书和例程,但是STM32控制电机的具体时间还是花了些时间,我的板子和例程的有些区别,中间很多地方都需要进行修改完善,而且还补充了…...
语音合成之四基于LLM的语音合成
基于LLM的语音合成 1.技术架构1.1 LlaSA1.2 CosyVoice (和 CosyVoice2)1.3 SparkTTS 2 特性对比2.1 零样本语音克隆2.2 多语种支持2.3 可控语音生成2.4 计算效率和模型大小 总结 当前,在大型语言模型(Large Language Models,LLMs)…...
Docker Python 官方镜像使用说明(TAG说明)
Docker Python 官方镜像使用说明(TAG说明) 本文将以python的3.12版本,详细讲解官方 Python 镜像 的TAGS含义 官方文档:https://github.com/tuonioooo/docker 🧭 一张图先看懂(最常见 Tag) py…...
Node.js 开发用户登录功能(使用mysql实现)
在 Web 开发中,用户登录功能是一个基础且重要的部分。、 一、环境搭建 在开始开发之前,我们需要搭建好相应的开发环境。以下是所需的工具和库: Node.js:作为 JavaScript 的运行环境,为我们的项目提供支持。mysql2&am…...
程序员学英文之Shipment Claim 运输和索赔
Time is precious , don’t waste your time, you should spend your time on something valuable . 时间很宝贵,不要浪费时间,你应该把时间用在有 价值的事情上。 Dia-1: Shipment by Voyage Charter 租船装运 1. May I know when your bo…...
python实战项目64:selenium采集软科中国大学排名数据
python实战项目64:selenium采集软科中国大学排名数据 一、项目需求二、流程分析三、完整代码一、项目需求 本项目的需求是使用selenium采集软科中国大学排名的数据。网站首页如下: 抓取此网页数据一般有两种方式,一种是直接发requests请求,我们这里采用的是使用selenium控…...
Linux服务器:在ufw防火墙设置这套规则sudo ufw allow from 172.0.0.0/8,为什么容器就可以访问宿主机的服务了?
在 Docker 环境中,容器默认使用 桥接网络(bridge),宿主机和容器之间的通信会受到防火墙(如 ufw)的限制。当你执行 sudo ufw allow from 172.0.0.0/8 后,容器可以访问宿主机上的服务,原因如下: 1. Docker 默认使用 172.x.x.x 网段 Docker 默认会创建一个 docker0 网桥…...
Google搜索技巧
谷歌搜索 1. 使用双引号 (" ") 精确匹配短语 ● 例子:"人工智能的定义" ● 作用:确保搜索结果中包含完全匹配的短语,而不是单独的单词。 2. 使用减号 (-) 排除特定词语 ● 例子:苹果 -水果 ● 作用&…...
Reactor编程模型介绍
Reactor 模型是一种基于事件驱动的编程模型,广泛应用于高并发网络服务器的设计中。它通过事件循环和回调机制,将事件的处理逻辑从主线程中解耦出来,从而实现高效的异步 I/O 操作。Reactor 模型的核心思想是利用一个或多个事件分发器(Reactor)来监听各种事件(如 I/O 事件、…...
C++笔记-stack_queue(含deque,priority_queue,仿函数的讲解)
一.stack和queue的基本使用 stack和queue就是我们之前所学的栈和队列,这两个和之前学的vector,list不太一样: 这是vector和list的,注意第一行中写的containers,代表这两个都是容器,但是: stac…...
意见反馈留言二维码制作
意见反馈对于工作整改具有重要作用,在工作中一味埋头苦干不如抬头多听听反馈声音。而传统的反馈内容投递后,因为繁琐性和时效性的枷锁,往往石沉大海,不知何时才能得到回应,这就导致反馈信息的延迟,一些时效…...
扣子智能体平台深度解读:功能剖析与全流程工作流详解
在上一篇文章中,我们已经带大家了解了“智能体”这一概念的内涵,并通过扣子智能体平台的各大模块做了初步介绍,同时用一个简单的示例演示了如何构建和部署第一个智能体。那篇文章打好了基础,让大家对智能体的基本组成与工作方式有…...
C语言五子棋项目
头文件与宏定义 #include <graphics.h> #include <conio.h> graphics.h:EasyX 图形库,提供图形绘制功能(画线、画圆、显示文字等)。 conio.h:提供控制台输入输出函数(这里只是为了兼容性&…...