postgres--MVCC
PostgreSQL 的 MVCC(Multi-Version Concurrency Control,多版本并发控制) 是其实现高并发和高性能的核心机制,支持多个事务同时读写数据库而无需加锁阻塞。它的核心思想是通过保留数据的多个版本来避免读写冲突,从而提高并发能力。以下是详细的介绍和官网资源指引:
MVCC 的核心工作原理
PostgreSQL 的 MVCC 通过以下机制实现:
记录版本链
-
每次修改数据时,创建新版本(新行),旧版本保留(通过
事务可见性规则
判断是否可读)。 -
每行包含两个隐藏系统列:
•
xmin
:记录插入该行的事务 ID(表示此行由此事务创建)。•
xmax
:记录删除或更新此行的事务 ID(若为0
表示此行未被删除)。
事务快照(Snapshot)
-
事务开始时获取当前活跃事务的列表,形成一个“快照”,用于判断数据版本对该事务是否可见。
-
通过快照判断:某数据版本是否是本事务自身修改的,或是否在事务开始前已提交。
事务隔离级别
SQL标准定义四种:
READ COMMITTED
(读已提交REPEATABLE READ
(可重复读)SERIALIZABLE
(串行化)READ UNCOMMITTED
(读未提交)
事务隔离级别
事务隔离级别的作用
事务隔离级别用于控制多个并发事务之间的可见性和相互影响,解决以下并发问题:
- 脏读(Dirty Read):读到其他事务未提交的数据。
- 不可重复读(Non-Repeatable Read):同一事务中多次读取同一行,结果不同(因其他事务修改或删除了该行)。
- 幻读(Phantom Read):同一事务中多次查询同一条件,返回的行数不同(因其他事务插入或删除了符合条件的数据)。
- 序列化异常(Serialization Anomaly):并发事务的执行结果与某种串行顺序不一致。
PostgreSQL 支持的隔离级别
注意
:它不实现 READ UNCOMMITTED
(读未提交),因为其 MVCC 机制默认保证事务只能读取已提交的数据。
READ COMMITTED(读已提交)
-
默认级别。
-
行为:
-
事务中的每个语句都基于该语句执行时已提交的最新数据。
-
如果其他事务在本次事务执行期间提交了修改,后续查询会看到这些修改。
- 解决的问题:
- 防止脏读。
- 未解决的问题:
- 不可重复读、幻读。
- 适用场景:
-
大多数 OLTP 场景(如用户注册、商品下单、简单更新操作)。
-
允许非关键数据短暂不一致(如计数器、非财务操作)。
-
高并发且性能优先 的业务。
示例:
-- 事务 A
BEGIN;
SELECT balance FROM account WHERE id = 1; -- 返回 100-- 事务 B 在此期间提交了 UPDATE account SET balance = 200 WHERE id = 1;SELECT balance FROM account WHERE id = 1; -- 返回 200(事务 B 已提交)
COMMIT;
典型应用
-
用户注册:插入新用户记录,无重复性检查。
-
更新用户资料:修改用户邮箱或地址,无并发冲突风险。
-
读取实时数据:展示最新库存、评论等。
代码示例(Go + GORM)
// 默认隔离级别(READ COMMITTED)
err := db.Transaction(func(tx *gorm.DB) error {// 扣减库存(允许其他事务提交的修改被后续查询看到)if err := tx.Model(&Product{}).Where("id = ? AND stock > 0", productID).Update("stock", gorm.Expr("stock - ?", 1)).Error; err != nil {return err}return nil
})
注意事项
• 若业务逻辑依赖多次查询的一致性(如余额检查后再扣款),需结合 显式锁(SELECT ... FOR UPDATE
)防止竞态条件。
REPEATABLE READ(可重复读)
- 行为:
-
事务开始时创建一个快照(Snapshot),所有查询基于此快照。
-
即使其他事务提交修改,本次事务看到的仍是快照数据。
-
PostgreSQL 的可重复读实际上避免了幻读(与 SQL 标准不同)。
- 解决的问题:
- 脏读、不可重复读、幻读。
- 未解决的问题:
- 序列化异常(需通过
SERIALIZABLE
解决)。
- 适用场景:
-
需要多次读取一致性的场景(如
报表生成、数据导出
)。 -
防止中间数据变更影响业务逻辑(如批量处理订单前检查库存总量)。
-
存在幻读风险但无需严格串行化 的场景。
示例:
-- 事务 A
BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT balance FROM account WHERE id = 1; -- 返回 100-- 事务 B 在此期间提交了 UPDATE account SET balance = 200 WHERE id = 1;SELECT balance FROM account WHERE id = 1; -- 仍返回 100(基于快照)
COMMIT;
典型应用
-
生成财务报表:确保统计期间数据不变。
-
批量任务处理:处理前查询符合条件的任务,处理中不被新增任务干扰。
-
数据迁移:导出数据时保持一致性快照。
代码示例(Go + GORM)
err := db.Transaction(func(tx *gorm.DB) error {// 设置隔离级别为 REPEATABLE READtx.Exec("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ")// 1. 查询当前用户余额var balance inttx.Raw("SELECT balance FROM accounts WHERE user_id = ?", userID).Scan(&balance)// 2. 检查余额是否足够(基于同一快照)if balance < 100 {return errors.New("insufficient balance")}// 3. 扣减余额(即使其他事务在此期间修改了余额,此处仍基于快照判断)if err := tx.Exec("UPDATE accounts SET balance = balance - 100 WHERE user_id = ?", userID).Error; err != nil {return err}return nil
}, &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
注意事项
• PostgreSQL 的 REPEATABLE READ
实际已防止幻读(与 SQL 标准不同)。
• 长事务可能导致表膨胀(旧数据版本无法被清理),需定期维护。
SERIALIZABLE(串行化)
- 行为:
-
通过严格的锁和冲突检测机制,确保事务的执行结果与某种串行顺序一致。
-
如果检测到可能导致序列化异常的操作,事务会中止并返回错误(需重试)。
- 解决的问题:
- 所有并发问题(包括脏读、不可重复读、幻读、序列化异常)。
- 缺点:
- 事务失败率较高,需编写重试逻辑。
- 适用场景:
-
严格数据一致性 的金融操作(如转账、交易结算)。
-
防止并发导致业务逻辑异常(如唯一性约束检查、库存超卖)。
-
复杂业务逻辑涉及多表更新,需保证原子性。
示例:
-- 事务 A
BEGIN ISOLATION LEVEL SERIALIZABLE;
SELECT balance FROM account WHERE id = 1; -- 返回 100-- 事务 B 在此期间尝试修改同一行,可能导致事务 A 提交时失败
-- 事务 A 提交时会检测到冲突并回滚,需捕获错误并重试
COMMIT;
典型应用
-
银行转账:A 向 B 转账,需保证 A 扣款和 B 入账的原子性。
-
抢购活动:防止库存超卖(如秒杀场景)。
-
唯一性校验:注册时检查用户名是否唯一,避免并发注册冲突。
代码示例(Go + GORM)
maxRetries := 3
for i := 0; i < maxRetries; i++ {err := db.Transaction(func(tx *gorm.DB) error {// 设置隔离级别为 SERIALIZABLEtx.Exec("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")// 1. 检查用户名是否唯一var count int64tx.Model(&User{}).Where("username = ?", "alice").Count(&count)if count > 0 {return errors.New("username already exists")}// 2. 创建用户if err := tx.Create(&User{Username: "alice"}).Error; err != nil {return err}return nil}, &sql.TxOptions{Isolation: sql.LevelSerializable})if err == nil {break // 成功}// 处理序列化冲突(PostgreSQL 错误码 40001)if isSerializationError(err) {time.Sleep(time.Duration(i*100) * time.Millisecond) // 指数退避continue} else {panic(err)}
}
注意事项
-
必须实现重试逻辑:捕获序列化异常并重试(如 PostgreSQL 的
40001
错误)。 -
避免事务过长:减少锁竞争,提升成功率。
-
结合显式锁优化:使用
SELECT ... FOR UPDATE
提前锁定关键资源。
决策流程:如何选择隔离级别
-
是否需要
绝对数据一致性
?
• 是 → SERIALIZABLE(如金融系统)。• 否 → 进入下一步。
-
是否需要
多次读取一致性
?
• 是 → REPEATABLE READ(如报表生成)。• 否 → READ COMMITTED(如大多数 OLTP 操作)。
-
是否存在
不可接受的性能损耗
?
• 是 → 降低隔离级别,结合 显式锁或乐观锁 解决竞态条件。• 否 → 维持当前隔离级别。
SQL 标准中的事务隔离级别
SQL 标准(ISO/IEC 9075)定义了四个事务隔离级别,解决以下并发问题:
隔离级别 | 脏读(Dirty Read) | 不可重复读(Non-Repeatable Read) | 幻读(Phantom Read) | 序列化异常(Serialization Anomaly) |
---|---|---|---|---|
READ UNCOMMITTED | 可能发生 | 可能发生 | 可能发生 | 可能发生 |
READ COMMITTED | 禁止 | 可能发生 | 可能发生 | 可能发生 |
REPEATABLE READ | 禁止 | 禁止 | 可能发生 | 可能发生 |
SERIALIZABLE | 禁止 | 禁止 | 禁止 | 禁止 |
如何设置隔离级别
在事务开始时指定隔离级别:
BEGIN ISOLATION LEVEL REPEATABLE READ;
-- 或
START TRANSACTION ISOLATION LEVEL SERIALIZABLE;
注意事项
-
MVCC 与快照:
• PostgreSQL 使用 MVCC 实现隔离级别,REPEATABLE READ
和SERIALIZABLE
依赖事务快照
。•
长时间运行的事务可能导致表膨胀
(旧版本数据无法被VACUUM
清理)。 -
序列化失败处理:
• 在SERIALIZABLE
级别,若事务因冲突中止,需捕获错误并重试:DO $$ BEGINLOOPBEGIN-- 执行事务操作COMMIT;EXIT;EXCEPTION WHEN serialization_failure THENROLLBACK;-- 等待后重试PERFORM pg_sleep(0.1);END;END LOOP; END $$;
-
性能权衡:
• 隔离级别越高,并发性能越低。优先使用能满足需求的最低隔离级别。
隔离级别总结
• READ COMMITTED:适合大多数场景,平衡性能与一致性。
• REPEATABLE READ:适合需要多次读取一致性的场景(如报表)。
• SERIALIZABLE:仅用于严格要求数据绝对一致的场景,需配合重试机制。
建议结合业务需求选择隔离级别,并通过测试验证并发行为是否符合预期。
在 GORM + Go 中实现事务隔离级别
GORM 支持通过 Set
方法或在事务中指定隔离级别,以下为具体实现示例。
全局设置隔离级别
在初始化数据库时全局设置隔离级别(影响所有事务):
import ("gorm.io/gorm""gorm.io/driver/postgres"
)func main() {dsn := "host=localhost user=gorm password=gorm dbname=gorm port=5432 sslmode=disable"db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{// 全局设置隔离级别为 REPEATABLE READPrepareStmt: true,})if err != nil {panic(err)}// 通过 Session 配置隔离级别tx := db.Session(&gorm.Session{PrepareStmt: true,// 设置隔离级别(需数据库驱动支持)// 例如 PostgreSQL 使用以下方式:// Transaction: &sql.TxOptions{Isolation: sql.LevelRepeatableRead},})
}
单次事务中设置隔离级别
在事务中显式指定隔离级别(推荐):
// 开启事务并设置隔离级别为 REPEATABLE READ
err := db.Transaction(func(tx *gorm.DB) error {// 设置隔离级别tx.Exec("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ")// 执行数据库操作if err := tx.Create(&User{Name: "Alice"}).Error; err != nil {return err}// 提交事务return nil
}, &sql.TxOptions{Isolation: sql.LevelRepeatableRead, // 设置隔离级别ReadOnly: false,
})
处理 SERIALIZABLE 冲突
在 SERIALIZABLE
级别下,需捕获序列化异常并重试:
maxRetries := 3
for i := 0; i < maxRetries; i++ {err := db.Transaction(func(tx *gorm.DB) error {// 设置隔离级别为 SERIALIZABLEtx.Exec("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")// 业务逻辑var balance inttx.Raw("SELECT balance FROM accounts WHERE user_id = ?", 1).Scan(&balance)if err := tx.Exec("UPDATE accounts SET balance = ? WHERE user_id = ?", balance+100, 1).Error; err != nil {return err}return nil}, &sql.TxOptions{Isolation: sql.LevelSerializable})if err == nil {break // 成功提交}// 处理序列化错误(PostgreSQL 错误码为 40001)if isSerializationError(err) {time.Sleep(100 * time.Millisecond) // 等待后重试continue} else {panic(err) // 其他错误直接终止}
}
检查序列化错误的辅助函数
func isSerializationError(err error) bool {if pgErr, ok := err.(*pq.Error); ok {return pgErr.Code == "40001" // PostgreSQL 序列化异常错误码}return false
}
关键注意事项
-
数据库驱动支持:
• 不同数据库对隔离级别的支持不同(如 MySQL 支持READ UNCOMMITTED
,而 PostgreSQL 不支持)。• 需检查数据库驱动(如
postgres
、mysql
)的文档。 -
GORM 的局限性:
• GORM 的Transaction
方法默认使用READ COMMITTED
。• 部分数据库(如 SQLite)可能不支持高隔离级别。
-
性能与重试:
•SERIALIZABLE
级别事务失败率高,需配合指数退避(Exponential Backoff)重试策略。• 使用
SELECT ... FOR UPDATE
显式加锁可减少冲突。
完整示例代码
以下是一个完整的 Go + GORM 示例,实现 SERIALIZABLE
事务和自动重试:
package mainimport ("database/sql""fmt""time""github.com/lib/pq""gorm.io/driver/postgres""gorm.io/gorm"
)type Account struct {ID uintUserID intBalance int
}func main() {dsn := "host=localhost user=postgres password=postgres dbname=test port=5432 sslmode=disable"db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})if err != nil {panic(err)}// 模拟转账操作(SERIALIZABLE 级别)transferFunds(db, 1, 2, 100, 3) // 从用户 1 转账 100 到用户 2,最多重试 3 次
}func transferFunds(db *gorm.DB, from, to, amount, maxRetries int) {for i := 0; i < maxRetries; i++ {err := db.Transaction(func(tx *gorm.DB) error {tx.Exec("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE")// 查询转出账户余额var fromAccount Accountif err := tx.Where("user_id = ?", from).First(&fromAccount).Error; err != nil {return err}// 检查余额是否足够if fromAccount.Balance < amount {return fmt.Errorf("insufficient balance")}// 更新转出账户if err := tx.Model(&fromAccount).Update("balance", fromAccount.Balance - amount).Error; err != nil {return err}// 更新转入账户var toAccount Accountif err := tx.Where("user_id = ?", to).First(&toAccount).Error; err != nil {return err}if err := tx.Model(&toAccount).Update("balance", toAccount.Balance + amount).Error; err != nil {return err}return nil}, &sql.TxOptions{Isolation: sql.LevelSerializable})if err == nil {fmt.Println("Transfer succeeded")return}// 处理序列化错误if isSerializationError(err) {fmt.Printf("Retrying after serialization failure (attempt %d)\n", i+1)time.Sleep(time.Duration(i*i*100) * time.Millisecond) // 指数退避} else {panic(err)}}panic("transfer failed after max retries")
}func isSerializationError(err error) bool {if pgErr, ok := err.(*pq.Error); ok {return pgErr.Code == "40001"}return false
}
-
SQL 标准:隔离级别由 ISO/IEC 9075 定义,需通过付费文档或数据库实现(如 PostgreSQL)了解细节。
-
GORM 实现:
-
使用
Transaction
方法并指定&sql.TxOptions{Isolation: ...}
。 -
处理
SERIALIZABLE
冲突需结合错误码检测和重试逻辑。
- 实践建议:
-
优先使用
READ COMMITTED
,仅在必要时升级隔离级别。 -
测试不同隔离级别下的并发行为,确保符合业务需求。
实际开发中的最佳实践
优先使用 READ COMMITTED
-
大多数场景下,
READ COMMITTED
在性能和一致性之间取得平衡。 -
示例:用户下单扣库存,允许其他事务短暂看到中间状态,但通过
WHERE stock > 0
保证最终一致性。
用显式锁替代高隔离级别
• 在 READ COMMITTED
级别下,通过 SELECT ... FOR UPDATE
锁定关键资源,避免竞态条件。
db.Transaction(func(tx *gorm.DB) error {// 锁定用户账户var account Accounttx.Clauses(clause.Locking{Strength: "UPDATE"}).Where("user_id = ?", userID).First(&account)// 检查并更新余额if account.Balance < 100 {return errors.New("insufficient balance")}tx.Model(&account).Update("balance", account.Balance - 100)return nil
})
监控长事务和锁竞争
• 使用数据库监控工具(如 PostgreSQL 的 pg_stat_activity
、pg_locks
)识别长事务和锁等待。
• 优化事务逻辑,减少事务持续时间。
测试并发场景
• 使用 Go 的并发测试工具(如 goroutine
+ sync.WaitGroup
)模拟高并发操作。
func TestConcurrentTransfer(t *testing.T) {var wg sync.WaitGroupfor i := 0; i < 100; i++ {wg.Add(1)go func() {defer wg.Done()transferFunds(db, 1, 2, 10, 3) // 模拟 100 次并发转账}()}wg.Wait()
}
常见误区
-
过度使用 SERIALIZABLE
• 导致事务频繁回滚,性能下降。优先通过业务逻辑设计避免冲突。 -
忽略数据库实现的差异
• 不同数据库对隔离级别的支持不同(如 MySQL 的REPEATABLE READ
允许幻读)。 -
依赖隔离级别解决所有并发问题
• 隔离级别无法替代业务逻辑校验(如唯一性检查需结合唯一索引)。
官方文档资源
PostgreSQL 官网对 MVCC 有详细解释,以下是关键章节:
-
并发控制:
• 解释 MVCC 的原理和事务可见性规则。 -
事务隔离:
• 说明不同隔离级别下 MVCC 的行为。 -
VACUUM 机制:
• 清理旧版本数据(避免事务 ID 回卷和空间膨胀)。
MVCC 的优势
-
高并发:
• 读操作不阻塞写操作,写操作不阻塞读操作(基于版本链)。 -
避免锁争用:
• 减少了行级锁的使用,提升多用户场景下的吞吐量。 -
事务隔离灵活:
• 支持不同级别的隔离,适应多样化需求。
MVCC 的缺点
-
空间膨胀:
• 旧版本数据需要保留到所有可能依赖它们的事务完成,可能导致表膨胀。• 解决方案:通过
VACUUM
清理失效版本(自动或手动触发)。 -
事务 ID 回卷(XID Wraparound):
• 事务 ID 是 32 位整数,长时间未清理可能导致回卷错误(触发紧急停机)。• 预防措施:定期运行
VACUUM
或配置autovacuum
。 -
查询性能开销:
• 版本可见性检查可能增加复杂查询的 CPU 开销。
MVCC 的关键配置与操作
自动清理(Autovacuum)
• 默认开启,用于定期清理旧版本数据。
• 配置参数(postgresql.conf
):
autovacuum = on # 开启自动清理
autovacuum_vacuum_threshold = 50 # 表更新超过50行触发清理
autovacuum_analyze_threshold = 50 # 触发统计信息更新
手动清理
VACUUM [FULL] [ANALYZE] [VERBOSE] table_name; -- 清理旧版本并更新统计信息
• VACUUM FULL
:重建表以彻底回收空间(需表级锁,慎用)。
如何查看 MVCC 信息
查询行的系统列
SELECT xmin, xmax, * FROM my_table WHERE id = 1;
• xmin
和 xmax
显示事务 ID。
• ctid
显示行的物理位置(用于版本链追踪)。
监控事务和快照
SELECT pg_current_xact_id(); -- 当前事务 ID(旧版本用 txid_current())
SELECT pg_current_snapshot(); -- 当前活跃事务快照
检测表膨胀
SELECT schemaname, relname, n_dead_tup
FROM pg_stat_all_tables
WHERE n_dead_tup > 0; -- 显示有死元组的表
MVCC 示例场景
场景:事务隔离下的读写
• 事务 A(REPEATABLE READ
)开始后读取数据:
BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT * FROM my_table WHERE id = 1; -- 假设 xmin=100
• 事务 B 更新此行:
UPDATE my_table SET value = 'new' WHERE id = 1; -- xmin=200, xmax=100
• 事务 A 再次读取:
• 仍看到 xmin=100
的旧版本(不可见事务 B 的修改)。
总结
• MVCC 是 PostgreSQL 实现高并发的基石,通过多版本链和事务快照避免锁争用。
• 需要定期维护:使用 VACUUM
或 autovacuum
清理失效数据,避免空间膨胀和事务 ID 回卷。
• 适合高并发场景:如频繁读写混合的 OLTP 系统。
官方文档是深入了解 MVCC 的最佳资源,结合实践经验调整 VACUUM
策略可显著优化性能。
相关文章:
postgres--MVCC
PostgreSQL 的 MVCC(Multi-Version Concurrency Control,多版本并发控制) 是其实现高并发和高性能的核心机制,支持多个事务同时读写数据库而无需加锁阻塞。它的核心思想是通过保留数据的多个版本来避免读写冲突,从而提…...
nanodet配置文件分析
以下是针对 NanoDet-Plus-M-1.5x_416 配置文件的逐模块解析,以及调整参数的作用和影响范围: 1. 模型架构(model) Backbone(骨干网络) backbone:name: ShuffleNetV2model_size: 1.5x # 控制网络宽度&…...
【Linux网络】HTTP
应用层协议 HTTP 前置知识 我们上网的所有行为都是在做IO,(我的数据给别人,别人的数据给我)图片。视频,音频,文本等等,都是资源答复前需要先确认我要的资源在哪台服务器上(网络IP&…...
Unity中AssetBundle使用整理(一)
一、AssetBundle 概述 AssetBundle 是 Unity 用于存储和加载游戏资源(如模型、纹理、预制体、音频等)的一种文件格式。它允许开发者将游戏资源打包成独立的文件,在运行时动态加载,从而实现资源的按需加载、更新以及减小初始安装包…...
CMOS内存的地址空间在主内存空间中吗?
CMOS内存(即CMOS RAM)的地址空间不位于主内存地址空间(如0x00000-0xFFFFF)内,而是通过独立的I/O端口地址进行访问,具体如下: 1. CMOS内存的物理存储与地址机制 CMOS RAM芯片通常集成在主板…...
大模型应用中常说的Rerank是什么技术?
Rerank技术详解 一、定义与基本原理 Rerank(重排序)是一种在信息检索系统中用于优化搜索结果排序的技术,其核心目标是通过二次评估和排序候选文档,提升结果的相关性和准确性。其运作机制通常分为两阶段: 初步检索:使用传统方法(如BM25关键词匹配或Embedding向量检索)…...
Python-MCPInspector调试
Python-MCPInspector调试 使用FastMCP开发MCPServer,熟悉【McpServer编码过程】【MCPInspector调试方法】-> 可以这样理解:只编写一个McpServer,然后使用MCPInspector作为McpClient进行McpServer的调试 1-核心知识点 1-熟悉【McpServer编…...
C 语言数据结构基石:揭开数组名的面纱与计算数组大小
各类资料学习下载合集 https://pan.quark.cn/s/8c91ccb5a474 在前面的文章中,我们已经学习了 C 语言一维数组的定义和初始化。我们知道数组是用来存储一系列相同类型数据的集合,并通过下标来访问每个元素。但是,除了通过下标访问单个元素,数组名本身在 C 语言中也…...
Java高频面试之并发编程-15
hello啊,各位观众姥爷们!!!本baby今天又来报道了!哈哈哈哈哈嗝🐶 面试官:as-if-serial 是什么?单线程的程序一定是顺序执行的吗? as-if-serial 规则 定义: …...
MySQL数据库迁移SQL语句指南
MySQL数据库迁移SQL语句指南 一、基础迁移方法 1. 使用mysqldump进行全量迁移 -- 导出源数据库(在命令行执行) mysqldump -u [源用户名] -p[源密码] --single-transaction --routines --triggers --events --master-data2 [数据库名] > migration…...
Vue:生命周期钩子
深入理解 Vue 的钩子函数(生命周期函数) Vue 的钩子函数(生命周期函数)是 Vue 实例在不同阶段自动调用的函数。可以在 Vue 实例的创建、更新、销毁等阶段插入自己的逻辑。 钩子函数的作用 想象一下,Vue 实例的生命周…...
深入理解设计模式之原型模式(Prototype Pattern)
一、为什么需要原型模式? 在传统对象创建方式中,我们通过new关键字直接调用构造函数创建实例。但当遇到以下场景时: 对象初始化需要消耗大量资源(如数据库连接)需要创建的对象与现有实例高度相似希望屏蔽对象创建的复…...
K8S cgroups详解
以下是 Kubernetes 中 cgroups(Control Groups) 的详细解析,涵盖其核心原理、在 Kubernetes 中的具体应用及实践操作: 一、cgroups 基础概念 1. 是什么? cgroups 是 Linux 内核提供的 资源隔离与控制机制,…...
ARMV8 RK3399 u-boot TPL启动流程分析 --start.S
上电后运行的第一支文件:arch/arm/cpu/armv8/start.S CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK1 #include <asm/arch/boot0.h> 跳转到 arch/arm/include/asm/arch-rockchip/boot0.h CONFIG_SPL_BUILD1 b 1f ROCKCHIP_EARLYRETURN_TO_BROMno TINY_FRAMEWORKno …...
【网络原理】数据链路层
目录 一. 以太网 二. 以太网数据帧 三. MAC地址 四. MTU 五. ARP协议 六. DNS 一. 以太网 以太网是一种基于有线或无线介质的计算机网络技术,定义了物理层和数据链路层的协议,用于在局域网中传输数据帧。 二. 以太网数据帧 1)目标地址 …...
保姆级教程|YOLO11改进】【卷积篇】【4】使用RFAConv感受野注意力卷积,重塑空间特征提取,助力高效提点
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
虚幻引擎5-Unreal Engine笔记之常用核心类的继承关系
虚幻引擎5-Unreal Engine笔记之常用核心类的继承关系 code review! 文章目录 虚幻引擎5-Unreal Engine笔记之常用核心类的继承关系1.UE5中常用核心类的继承关系1.1.简化版1.2.plantuml图1.3.plantuml代码1.4.关于大写字母U和A2.1.组件和类的关系,组件也是类吗&…...
力扣2680题解
记录 2025.5.9 题目: 思路: 1.计算初始或值:首先计算数组中所有元素的按位或结果 allOr,这表示在不进行任何左移操作时数组的或值。 2.计算固定或值:在计算 allOr 的同时,计算一个 fixed 值,…...
搭建基于chrony+OpenSSL(NTS协议)多层级可信时间同步服务
1、时间同步服务的层级概念 在绝大多数IT工程师实际工作过程中,针对于局域网的时间同步,遇到最多的场景是根据实际的需求,搭建一个简单的NTP时间同步服务以时间对局域网中的服务器、网络设备、个人电脑等基础设施实现同步授时功能。虽然这样…...
虚拟内存:深入解析与性能优化
文章目录 虚拟内存的概念虚拟内存的实现方式虚拟内存的页面置换算法虚拟内存的性能影响结论 在现代计算机系统中,虚拟内存(Virtual Memory)是一种至关重要的技术,它极大地提高了系统的多任务处理能力和内存利用率。本文将深入探讨…...
元数据和主数据
元数据和主数据是数据管理中的两个关键概念,其核心区别如下: 1. 定义与本质 元数据(Metadata) “关于数据的数据”,用于描述数据的属性、结构、来源、用途等上下文信息。 示例:数据库表的字段名称、数据类型…...
JavaScript事件处理全解析:从基础到最佳实践
在现代Web开发中,事件处理是构建交互式应用的核心技术。JavaScript提供了多种事件绑定方式,每种方法都有其适用场景和特点。本文将深入探讨7种主流的事件绑定方法,通过代码示例和原理分析,帮助开发者选择最合适的解决方案。 一、…...
高级数据结构:线段树
线段树概述 线段树是一种处理区间问题的优越算法,也是算法竞赛的常客。 线段树的特点是,类似于一棵二叉树,将一个序列分解成多个区间并储存在二叉树上。 例如,把区间 [ 1 , 10 ] [1,10] [1,10]作为树的根节点,然后把…...
精讲C++四大核心特性:内联函数加速原理、auto智能推导、范围for循环与空指针进阶
前引:在C语言长达三十余年的演进历程中,每一次标准更新都在试图平衡性能与抽象、控制与安全之间的微妙关系。从C11引入的"现代C"范式开始,开发者得以在保留底层控制能力的同时,借助语言特性大幅提升代码的可维护性与安全…...
用ffmpeg压缩视频参数建议
注意:代码中的斜杠\可以删除 一、基础压缩命令(画质优先) ffmpeg -i input.mp4 \-c:v libx264 -preset slow -crf 23 \ # H.264编码,平衡速度与质量-c:a aac -b:a 128k \ # 音频压缩-vf "scaleif(gt(a,16/9),1920,-2):if(…...
uni-app学习笔记(二)--vue页面代码的构成和新建页面
vue页面的构成 一.template 模板区,主要放html布局,注意,如果是开发uni-app,模板区不要放div,h1等标签了,用了在小程序和app端起不到作用。具体应该使用哪些组件,可在uni-app官网上查看:组件-…...
机器语言程序、汇编语言程序、硬件描述语言程序、编译程序、解释程序和链接程序
程序类型定义与核心特征处理对象 / 输入输出结果所属领域典型例子 / 作用机器语言程序由二进制指令(0/1 序列)构成,可被 CPU 直接执行,与硬件架构强绑定。无(直接执行)无(直接运行)低…...
智能语音助手的未来:从交互到融合
摘要 随着人工智能技术的不断进步,智能语音助手已经成为我们生活中不可或缺的一部分。从简单的语音指令到复杂的多模态交互,语音助手正在经历一场深刻的变革。本文将探讨智能语音助手的发展历程、当前的技术瓶颈以及未来的发展方向,特别是其在…...
Redis从基础到高阶应用:核心命令解析与延迟队列、事务消息实战设计
Redis基础知识 #切换数据库 bd:0>select 2 "OK" bd:2>dbsize "0" #清空数据库 bd:0>flushdb "OK" #设置值 bd:0>set name "lyt" "OK" #查看所有key bd:0>keys *1) "name" #获取key bd:0>get …...
操作系统原理实验报告
操作系统原理课程的实验报告汇总 实验三:线程的创建与撤销 实验环境:计算机一台,内装有VC、office等软件 实验日期:2024.4.11 实验要求: 1.理解:Windows系统调用的基本概念,进程与线程的基…...
Python爬虫实战:研究nodejs aes加密
1. 引言 1.1 研究背景与意义 在当今数字化时代,Web 数据的价值日益凸显。通过爬虫技术获取公开数据并进行分析,能够为企业决策、学术研究等提供有力支持。然而,为了保护数据安全和隐私,许多网站采用了加密技术对数据进行保护,其中 AES 加密是一种常见且安全的加密算法。…...
线程的一些事(2)
在java中,线程的终止,是一种“软性”操作,必须要对应的线程配合,才能把终止落实下去 然而,系统原生的api其实还提供了,强制终止线程的操作,无论线程执行到哪,都能强行把这个线程干掉…...
基于 PostgreSQL 的 ABP vNext + ShardingCore 分库分表实战
🚀 基于 PostgreSQL 的 ABP vNext ShardingCore 分库分表实战 📑 目录 🚀 基于 PostgreSQL 的 ABP vNext ShardingCore 分库分表实战✨ 背景介绍🧱 技术选型🛠️ 环境准备✅ Docker Compose(多库 & 读…...
御网杯2025 Web,Msic,密码 WP
Web YWB_Web_xff 审计代码,发现需要$cip2.2.2.1 使用burpsuite抓包,添加X-Forwarded-For:2.2.2.1 然后得到flag YWB_Web_未授权访问 更加题目描述知道需要admin登录,但是现在是guest。 使用burpsuite抓包 发现cookie里面存在userÿ…...
tensorflow 1.x
简介 TensorFlow:2015年谷歌,支持python、C,底层是C,主要用python。支持CNN、RNN等算法,分CPU TensorFlow/GPU TensorFlow。 TensorBoard:训练中的可视化。 快捷键:shiftenter执行命令,Tab键进…...
[ERTS2012] 航天器星载软件形式化模型驱动研发 —— 对 Scade 语言本身的影响
在《从ERTS学习SCADE发展》中提到,在 ERTS 会议中,Scade团队会在该会议中介绍与Scade相关的工作。在 ERTS 2012 中,Scade 团队介绍了使用Scade作为主要工具,应用在航天器星载软件开发中的相关话题。原材料可参考 《Formal Model D…...
Spring Boot 集成 Flink CDC 实现 MySQL 到 Kafka 实时同步
Spring Boot 集成 Flink CDC 实现 MySQL 到 Kafka 实时同步 📌 项目背景 在大数据实时处理场景中,数据库变更数据的捕获与传输是关键环节。Flink CDC 提供了从 MySQL 等数据库中实时捕获数据变更的能力,并通过 Apache Flink 引擎实现流式处理。 本项目使用 Spring Boot …...
软件体系结构(Software Architecture)
文章目录 1. 分层架构(Layered Architecture)核心逻辑代码示例(伪代码)典型场景优缺点 2. 客户端-服务器(Client-Server)核心逻辑典型交互流程应用场景代码示例(RESTful API)优缺点 …...
RS485和RS232 通信配置
RS232 目前硬件上支持RS232的有以下板卡: LubanCat-5IO底板(含有RS232x2) 7.1. 引脚定义 具体的引脚定义可以参考背面的丝印 LubanCat-5IO底板 引脚定义图 7.2. 跳帽配置 LubanCat-5IO底板 鲁班买5IO底板上的RS485和RS232是共用同一组…...
【高数上册笔记篇02】:数列与函数极限
【参考资料】 同济大学《高等数学》教材樊顺厚老师B站《高等数学精讲》系列课程 (注:本笔记为个人数学复习资料,旨在通过系统化整理替代厚重教材,便于随时查阅与巩固知识要点) 仅用于个人数学复习,因为课…...
【网络安全】——大端序(Big-Endian)和小端序(Little-Endian)
字节序(Endianness)是计算机系统中多字节数据(如整数、浮点数)在内存中存储或传输时,字节排列顺序的规则。它分为两种类型:大端序(Big-Endian)和小端序…...
机器学习极简入门:从基础概念到行业应用
有监督学习(supervised learning) 让模型学习的数据包含正确答案(标签)的方法,最终模型可以对无标签的数据进行正确处理和预测,可以分为分类与回归两大类 分类问题主要是为了“尽可能分开整个数据而画线”…...
MIT XV6 - 1.5 Lab: Xv6 and Unix utilities - xargs
接上文 MIT XV6 - 1.4 Lab: Xv6 and Unix utilities - find xargs 继续实验,实验介绍和要求如下 (原文链接 译文链接) : Write a simple version of the UNIX xargs program for xv6: its arguments describe a command to run, it reads lines from the standard …...
Springboot整合Swagger3
Springboot整合Swagger3、常用注解解释、访问Swagger地址出现404、403、拒绝访问等问题_swagger3注解-CSDN博客...
经典音乐播放器——完美歌词 Poweramp Music Player 3 build
—————【下 载 地 址】——————— 【本章单下载】:https://drive.uc.cn/s/d6c480bc47604 【百款黑科技】:https://ucnygalh6wle.feishu.cn/wiki/HPQywvPc7iLZu1k0ODFcWMt2n0d?fromfrom_copylink —————【下 载 地 址】——————— 本…...
锚定基础与拥抱融合:C 语言在编程教育与技术社区的破圈之路
引言 在 Python 占据 TIOBE 指数榜首的 2025 年,C 语言以 23.4% 的稳定份额(2025 年 5 月数据)持续稳居前三,这一现象在编程教育领域尤为显著:全球 92% 的计算机科学本科课程仍将 C 语言作为必修基础课,而…...
深度学习入门:从神经网络基础到前向传播全面解析
深度学习入门:从神经网络基础到前向传播全面解析 🔥 重磅干货! 本文是《深度学习基础与核心技术详解》专栏的开篇之作,将系统性地带你走进深度学习的世界!建议收藏+关注,错过可能要找很久哦~ 目录 深度学习概述神经网络基础 2.1 生物神经元与人工神经元2.2 感知机模型2.…...
Lambda表达式能用在哪些场景?
Lambda表达式是Java 8引入的一种强大特性,它允许以简洁的方式表示匿名函数(即没有名字的函数)。Lambda表达式可以用于许多场景,尤其是在与函数式接口、Stream API、并发编程等结合时,能够显著简化代码并提高开发效率。…...
英语听力口语词汇--2.宣传类
1.approach uk /əˈprəʊtʃ/ n.(思考问题的)方式,方法,态度 2.foreign uk /ˈfɒr.ən/ adj.外国的 3.alliance uk /əˈlaɪ.əns/ n.结盟国家(或团体),同盟国家(或团体)&...
『 测试 』测试基础
文章目录 1. 调试与测试的区别2. 开发过程中的需求3. 开发模型3.1 软件的生命周期3.2 瀑布模型3.2.1 瀑布模型的特点/缺点 3.3 螺旋模型3.3.1 螺旋模型的特点/缺点 3.4 增量模型与迭代模型3.5 敏捷模型3.5.1 Scrum模型3.5.2 敏捷模型中的测试 4 测试模型4.1 V模型4.2 W模型(双V…...