go中锁的入门到进阶使用
Go 并发编程:从入门到精通的锁机制
引言:为什么需要锁?
Go 语言以其天生支持并发的特性深受开发者喜爱,但并发带来的问题也不容小觑,比如数据竞争、并发安全等。如果多个 Goroutine 访问同一个变量,没有做好同步,就可能导致数据错误甚至程序崩溃。
比如下面的例子:
var counter intfunc main() {for i := 0; i < 1000; i++ {go func() {counter++}()}time.Sleep(time.Second)fmt.Println("Counter:", counter) // 结果可能小于 1000
}
多个 Goroutine 竞争 counter
,但没有同步保护,导致最终结果不可预测。这就是数据竞争问题。
本篇文章,我们就来聊聊 Go 里的锁机制,帮助你掌握如何在高并发环境下写出稳定、高效的代码。
1. 互斥锁(Mutex)
互斥锁(sync.Mutex
)是最基础的锁,它保证同一时刻只有一个 Goroutine 可以执行临界区代码。
示例:使用 Mutex 保护共享资源
package mainimport ("fmt""sync""time"
)var (counter intmu sync.Mutex
)func main() {for i := 0; i < 1000; i++ {go func() {mu.Lock()counter++mu.Unlock()}()}time.Sleep(time.Second)fmt.Println("Counter:", counter) // 保证结果是 1000
}
Mutex 的注意点
- 必须成对使用
Lock()
和Unlock()
,否则容易导致死锁。 - 不要重复 Unlock(),否则会触发 panic。
- 不要在
defer
里解锁耗时操作的 Mutex,避免阻塞其他 Goroutine。(意思是尽量只锁住必要操作)
2. 读写锁(RWMutex)
当读操作远多于写操作时,sync.RWMutex
允许多个 Goroutine 并发读取,而写操作依然是独占的。
示例:读多写少的场景
package mainimport ("fmt""sync""time"
)var (counter intrwMu sync.RWMutex
)func read() {rwMu.RLock()fmt.Println("Read Counter:", counter)rwMu.RUnlock()
}func write() {rwMu.Lock()counter++rwMu.Unlock()
}func main() {for i := 0; i < 100; i++ {go read()}for i := 0; i < 10; i++ {go write()}time.Sleep(time.Second)
}
RWMutex 的注意点
- 读锁 (
RLock
) 允许多个 Goroutine 并发读取,但写锁 (Lock
) 会阻塞所有读操作。 RLock()
和Lock()
不能混用,否则可能出现死锁。- 适用于 读多写少 的场景,写多时反而可能降低性能。
3. sync.Once:确保只执行一次
sync.Once
用于确保某段代码只执行一次,比如初始化配置、数据库连接等。
var once sync.Oncefunc initDB() {fmt.Println("Initializing Database...")
}func main() {for i := 0; i < 10; i++ {go once.Do(initDB)}time.Sleep(time.Second)
}
注意:
sync.Once
只保证 代码执行一次,但并不保证多个 Goroutine 调用时的先后顺序。
4. sync.Map:并发安全的 map
Go 1.9 引入 sync.Map
,它是并发安全的 map,适用于高并发读写的场景。
var m sync.Mapfunc main() {m.Store("name", "Go")value, ok := m.Load("name")if ok {fmt.Println("Value:", value)}
}
适用场景:
- 读写频繁的场景
- 需要高效遍历的情况(比
sync.RWMutex
保护的普通 map 更快)
5. 自旋锁与 atomic 操作
Go 也支持 CAS(Compare And Swap) 操作,适用于极端高并发的场景,比如计数器。
package mainimport ("fmt""sync/atomic"
)var counter int64func main() {for i := 0; i < 1000; i++ {go func() {atomic.AddInt64(&counter, 1)}()}time.Sleep(1 * time.Second)fmt.Println("Counter:", counter)
}
相比 Mutex,atomic
避免了线程阻塞,但只适用于简单变量操作。
6. 锁的使用误区与优化
1. 避免死锁:
死锁通常是多个 Goroutine 交叉持有多个锁导致的。
mu1.Lock()
mu2.Lock()
mu2.Unlock()
mu1.Unlock()
优化: 保证加锁顺序一致,避免交叉加锁。
2. 缩小锁的粒度:
mu.Lock()
expensiveOperation() // 避免在锁内执行耗时操作
mu.Unlock()
优化方式:
- 锁定时长尽量短
- 读写分离(RWMutex)
- 使用 atomic 代替 Mutex(适用于计数器等简单操作)
基础总结
- Mutex:适用于写多读少
- RWMutex:适用于读多写少
- sync.Once:保证代码执行一次
- sync.Map:适用于高并发 map 读写
- atomic:适用于简单计数操作,避免 Mutex 阻塞
掌握这些锁机制,能让你的 Go 并发程序更稳定、更高效!
进阶:深入 Go 并发锁底层原理、易错点与实践
如果你已经掌握了 sync.Mutex
、sync.RWMutex
这些基础用法,那恭喜你,已经入门了 Go 并发编程。但在企业级开发中,光会用锁还远远不够,我们还需要了解锁的底层实现、易错点、性能影响,甚至在特定场景下如何替代锁,以避免潜在的性能瓶颈。
本篇文章,我们将从 Go 锁的底层机制出发,结合实际开发中的经验,探讨如何更高效地使用锁,避免踩坑!
1. Go 里的锁底层实现:Mutex 深度解析
1.1 Mutex 的底层结构
Go 的 sync.Mutex
并不是一个简单的布尔锁,而是一个自旋锁 + 休眠锁的组合。来看一下 sync.Mutex
的底层结构(基于 Go 1.21 源码):
// Go runtime 的 Mutex 结构
// runtime/sema.gotype Mutex struct {state int32 // 记录当前锁的状态sema uint32 // 信号量,阻塞 Goroutine 使用
}
其中 state
变量存储了锁的状态,核心机制如下:
- 低 3 位:存储锁状态(如是否被持有,是否有等待者)。
- 高 29 位:存储等待 Goroutine 的个数。
- sema:用于信号量,支持 Goroutine 阻塞和唤醒。
1.2 自旋 + 休眠:性能优化策略
当一个 Goroutine 试图获取锁:
- 如果锁是空闲的,直接获取,
state
置为 1。 - 如果锁被占用,会先进行一小段时间的自旋(在 CPU 允许的情况下短时间循环尝试获取锁)。
- 如果自旋后仍然获取不到锁,当前 Goroutine 会进入休眠(阻塞),等待持有锁的 Goroutine 释放锁后唤醒自己。
自旋的好处:减少线程切换开销,提高并发性能,适用于短时间持有锁的场景。
1.3 为什么 Mutex 不能递归加锁?
在 Go 里,sync.Mutex
不支持递归加锁,也就是说,如果一个 Goroutine 两次 mu.Lock()
,第二次调用会直接死锁。
mu.Lock()
mu.Lock() // 死锁!
为什么?因为 Mutex
只是一个简单的状态标志,它并不会记录是哪一个 Goroutine 持有了它。因此,同一个 Goroutine 再次 Lock()
时,就会自己阻塞自己,导致死锁。
解决方案:使用
sync.RWMutex
,或者用sync.Once
保障某段代码只执行一次。
2. 实际开发应用中的锁优化策略
2.1 缩小锁的粒度
锁的粒度越大,竞争就越激烈,导致程序整体性能下降。推荐的做法是缩小锁的作用范围。
错误示例(锁粒度太大,影响性能):
var mu sync.Mutex
var users = make(map[string]int)func updateUser(name string, score int) {mu.Lock()defer mu.Unlock()users[name] = score//其他代码段
}
改进方案(只锁定必要的部分):
func updateUser(name string, score int) {mu.Lock()users[name] = scoremu.Unlock()
}
或者使用 sync.Map
代替普通 map
,避免手动加锁:
var users sync.Map
func updateUser(name string, score int) {users.Store(name, score)
}
2.2 读多写少时,RWMutex 也可能带来问题
通常 sync.RWMutex
适用于读多写少的情况,但如果 Goroutine 竞争激烈,RWMutex
可能会导致 写操作饥饿。写锁会一直等待所有的读锁释放,而新的读锁又不断进来,导致写锁一直无法获取。
优化方案:使用 channel 进行并发控制,或者考虑分段锁(Sharding Lock)降低竞争。
2.3 高并发下,什么时候用 Atomic 替代 Mutex?
对于简单的计数器累加操作,使用 sync.Mutex
可能会引入额外的性能开销,而 sync/atomic
通过 CAS(Compare-And-Swap) 操作可以提升性能。
var counter int64
atomic.AddInt64(&counter, 1)
适用场景:
- 计数器
- ID 生成器
- 轻量级状态标志
3. 易错点与 Debug 技巧
3.1 如何避免死锁?
死锁通常发生在多个 Goroutine 交叉持有多个锁时。
错误示例(交叉加锁,导致死锁):
var mu1, mu2 sync.Mutex
func f1() {mu1.Lock()defer mu1.Unlock()time.Sleep(time.Millisecond * 100) // 模拟一些操作mu2.Lock() // 这里可能死锁defer mu2.Unlock()
}
func f2() {mu2.Lock()defer mu2.Unlock()time.Sleep(time.Millisecond * 100) // 模拟一些操作mu1.Lock() // 这里可能死锁defer mu1.Unlock()
}
问题分析:
f1()
先锁mu1
,然后锁mu2
。f2()
先锁mu2
,然后锁mu1
。- 如果
f1()
和f2()
同时运行,可能会发生f1()
拿到了mu1
,但f2()
拿到了mu2
,两者都在等待对方释放锁,造成死锁。
解决方案:始终保证加锁顺序一致。
func f1() {mu1.Lock()mu2.Lock() // 加锁顺序一致mu2.Unlock()mu1.Unlock()
}func f2() {mu1.Lock() // 确保加锁顺序和 f1 一致mu2.Lock()mu2.Unlock()mu1.Unlock()
}
3.2 如何检测数据竞争?
使用 -race
选项可以让 Go 运行时检测数据竞争。
go run -race main.go
如果程序存在数据竞争,Go 会给出详细的 Goroutine 访问日志,帮助排查问题。
简单总结一下:
- Mutex 的底层实现 采用 自旋 + 休眠 机制优化性能。
- Mutex 不能递归加锁,避免死锁的方法是保证加锁顺序一致。
- 缩小锁的粒度,避免锁住不必要的代码。
- RWMutex 在读多写少时表现优越,但也可能造成写锁饥饿。
- 高并发计数操作,优先考虑
sync/atomic
代替 Mutex。 - 使用
-race
进行数据竞争检测,避免并发 Bug。
之后会深入源码,讲一下sync.map等是如何保证并发安全的,可以关注我学习更多it知识。
相关文章:
go中锁的入门到进阶使用
Go 并发编程:从入门到精通的锁机制 引言:为什么需要锁? Go 语言以其天生支持并发的特性深受开发者喜爱,但并发带来的问题也不容小觑,比如数据竞争、并发安全等。如果多个 Goroutine 访问同一个变量,没有做…...
JS判断对象是否为空的方法
在 JavaScript 中,判断一个对象是否为空对象(即没有自身可枚举属性),可以通过以下方法实现: 方法 1:使用 Object.keys() javascript function isEmptyObject(obj) {// 确保是普通对象(排除 n…...
idea导入tomcat的jar
概述 对于老项目,未使用 Maven/Gradle 管理依赖的,在需要编译 Servlet/JSP 代码时,需要手动添加 Tomcat JAR 依赖(如 servlet-api.jar)方能进行编绎。 步骤: 1、找到 Tomcat 的 JAR 文件 进入 Tomcat 安…...
Linux 下安装和使用 Jupyter Notebook
Jupyter Notebook / Lab 是 Python 开发和数据分析中不可或缺的工具。为了避免环境污染,推荐使用虚拟环境方式安装并启动它。本教程将教你如何: 安装 Python、pip、venv使用虚拟环境安装 Jupyter汉化安装实用插件设置登录密码启动并远程访问编写一个一键…...
【Ubuntu常用命令】
1.将本地服务器文件或文件夹传输到远程服务器 文件 scp /data/a.txt administrator10.60.51.20:/home/administrator/ 文件夹 scp -r /data/ administrator10.60.51.20:/home/administrator/ 2.从远程服务器传输文件到本地服务器 scp administrator10.60.51.20:/data/a.txt /h…...
UR机械臂sim2real推荐包
推荐一个和ur机械臂配套的interface: ur_rtde Universal Robots RTDE C Interface — ur_rtde 1.6.0 documentation 也欢迎大家提供新想法和bug...
HTTP协议深度解析详解
HTTP协议深度解析详解 一、HTTP协议基础架构 1.1 请求响应模型 #mermaid-svg-pAGwQipduFJRm11I {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-pAGwQipduFJRm11I .error-icon{fill:#552222;}#mermaid-svg-pAGwQipd…...
算法学习第十七天:LRU缓存与布隆过滤器
LRU缓存与布隆过滤器 目录 LRU缓存 基本概念实现原理C代码实现 布隆过滤器 基本概念实现原理C代码实现 LRU缓存 基本概念 LRU(Least Recently Used):最近最少使用策略,当缓存空间不足时,淘汰最久未被访问的数据。…...
html中img标签直接使用border-radius时会图片进行了遮挡
前言 该问题是我写完项目之后,UI走查发现的问题,虽然我也发现了问题,但是改起来,不好改,就耽搁了。后面UI还是要求要改。一直找不到解决方案,歪打正着通过MDN官网偶然看到的clip-path属性。 需求 一个图…...
【Keepalived】Keepalived-2.3.3明确结束对CentOS 7的支持
2025年3月30日,官方发布了Keepalived的最新版,版本号:2.3.3 而2024年11月3日发布的2.3.2版本,在CentOS 7.9上编译的时候,就出现了报错,但是在Alma Linux 8.10上,则可以成功编译安装,…...
Docker学习--容器生命周期管理相关命令--docker pause/unpause 命令
docker pause 命令的作用: 用于暂停一个或多个容器中的所有进程。 语法: docker pause CONTAINER [CONTAINER…](要操作的容器的名称,可以同时操作多个)。 实例: ①暂停一个容器及其所有进程:…...
【Zabbix技术系列文章】第④篇——Zabbix 数据可视化
在当今数字化运维时代,面对海量的监控数据,如何从中快速获取有价值的信息至关重要。Zabbix 的数据可视化功能为我们提供了直观、高效的解决方案,它能将复杂的监控数据转化为清晰易懂的图表和仪表盘,助力运维人员迅速发现问题、分析…...
R CSV 文件处理指南
R CSV 文件处理指南 引言 CSV(逗号分隔值)文件是一种常见的文件格式,它以纯文本形式存储表格数据。在R语言中,CSV文件处理是非常基础且重要的技能。本文将详细介绍如何在R中读取、处理和导出CSV文件,并探讨一些高级技…...
在Git仓库的Readme上增加目录页
一般在编写Readme时想要增加像文章那样的目录,方便快速跳转,但是Markdown语法并没有提供这样的方法,但是可以通过超链接结合锚点的方式来实现,如下图是我之前一个项目里写的Readme: 例如有下面几个Readme内容ÿ…...
[特殊字符]《多商户家政系统技术解析:SpringBoot+MyBatisPlus+UniApp高效实战指南》
🛠️ 引言:多商户家政系统的技术挑战与价值 在数字化时代,家政行业逐渐向线上迁移,从传统的线下预约转向平台化管理。多商户家政系统具备复杂的角色体系,包括: 🛎️ 商户端:管理订单…...
请求Header(Request Headers)详解
请求Header(Request Headers)详解 HTTP请求Header是HTTP请求消息的重要组成部分,用于在客户端和服务器之间传递附加信息。这些信息帮助服务器理解客户端的环境、偏好和请求的具体内容,从而能够返回更合适的响应。以下是对请求Hea…...
深度求索:开源革命下的AI普惠之路
引言:AI领域的破局者 2025年,全球AI领域因一家中国公司的崛起而震动。杭州深度求索(DeepSeek)推出的V3大模型以6710亿参数、14.8万亿token训练数据量,在数学竞赛、代码生成等专业领域超越多数国际竞品,其每…...
XSS 攻击(详细)
目录 引言 一、XSS 攻击简介 二、XSS 攻击类型 1.反射型 XSS 2.存储型 XSS 3.基于 DOM 的 XSS 4.Self - XSS 三、XSS 攻击技巧 1.基本变形 2.事件处理程序 3.JS 伪协议 4.编码绕过 5.绕过长度限制 6.使用标签 四、XSS 攻击工具与平台 1.XSS 攻击平台 2.BEEF 五…...
使用Redis实现轻量级消息队列
使用消息中间件如RabbitMQ或kafka虽然好,但也给服务器带来很大的内存开销,当系统的业务量,并发量不高时,考虑到服务器和维护成本,可考虑使用Redis实现一个轻量级的消息队列,实现事件监听的效果。下面介绍下…...
13届省赛python A组:10.数的拆分
题目1 数的拆分 给定 T 个正整数 ai,分别问每个 ai 能否表示为 x 1 y 1 ⋅ x 2 y 2 x1^{y1}⋅x2^{y2} x1y1⋅x2y2 的形式,其中 x1,x2 为正整数,y1,y2 为大于等于 2 的正整数。 输入格式 输入第一行包含一个整数 T 表示询问次数。 接下来…...
【Android Studio】下载安装过程(详细)
目录 一、前期准备 JDK下载安装 二、下载安装 下载 安装 启动 一、前期准备 JDK下载安装 详细的安装过程请移步我的另一篇博客jdk17详细安装步骤_jdk17安装教程详细-CSDN博客 cmd打开命令行,输入java -version验证,可以看到此处我安装的是java23。…...
【RAGFlow】ubuntu22部署ragflow(v0.17.2)
按照官方手册部署: https://ragflow.io/docs/v0.17.2/ 部署环境: CPU: 4核memory: 16gGPU: T4(vGPU)Disk: 20g 1. 配置国内docker-ce源 https://mirrors.tuna.tsinghua.edu.cn/help/docker-ce/ 用清华源,要不然下载速度感人 …...
Easysearch 如何短暂维护 Data 节点
之前介绍过如何移除 Data 节点,那么如果只是短暂停止一个 Data 节点进行维护,之后再次加入集群,是否也需要按照移除节点的步骤进行操作呢?我们先梳理下核心原理。 核心原理 我们先看看节点离开集群之后集群是怎样处理的。当节点…...
【cocos creator 3.x】3Dui创建,模型遮挡ui效果
官方文档:https://docs.cocos.com/creator/3.8/manual/zh/ui-system/components/editor/ui-model.html 1、3Dui创建 创建label,默认会添加canvas根节点和2dCamera 将Camera删除,canvas上组建去除cc.Canvas,cc.widget࿰…...
UE5学习笔记 FPS游戏制作32 主菜单,暂停游戏,显示鼠标指针
文章目录 一主菜单搭建UI显示主菜单时,暂停游戏,显示鼠标绑定按钮 二 打开主菜单 一主菜单 搭建UI 添加一个MainUi的控件 添加一个返回游戏的按钮和一个退出游戏的按钮 修改一下样式,放中间 显示主菜单时,暂停游戏࿰…...
有哪些开源的视频生成模型
1. 阿里巴巴通义万相2.1(WanX 2.1) 技术架构:基于Diffusion Transformer(DiT)架构,结合自研的高效变分自编码器(VAE)和Flow Matching训练方案,支持时空上下文建模。参数…...
基于Spring Boot的家庭理财系统app的设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
SQLAlchemy系列教程:事件驱动的数据库交互
在现代Web应用开发中,数据库交互往往需要超越简单的CRUD操作。当用户注册成功后自动发送欢迎邮件?在订单创建时同步库存数据?这些场景都需要监听数据库状态变化并触发相应逻辑。SQLAlchemy的事件系统为此提供了优雅的解决方案。 本文将深入解…...
linux基本命令(2)--进程命令PS
其实吧, 在linux命令下 输入man ps也可以,一行行拖下去也是看到解析的。退出不看的时候记得按q哦 基本介绍 国际惯例介绍下这个命令的用途。 在Linux下ps命令是用于查看系统上运行的进程的最基本的命令之一。它提供了当前进程的同时,如用户ID…...
android adb 查看设备传感器
Android ADB 查看设备传感器的使用技巧 在Android开发中,了解设备的传感器是非常重要的一步。不论是开发健康应用、游戏,还是任何需要感知用户环境的应用,传感器的使用都离不开对其数据的获取。Android Debug Bridge(ADB…...
Verilog HDL 100道面试题及参考答案
目录 Verilog HDL 的四种基本逻辑值是什么? 关键字 reg 和 wire 的主要区别是什么? 解释阻塞赋值(=)与非阻塞赋值(<=)的区别,并举例说明。 如何声明一个双向端口(inout)? 位拼接操作符是什么?举例说明其用法。 拼接信号和常量 拼接常量和信号 重复拼接 以…...
Java基础-26-多态-认识多态
在Java编程中,多态(Polymorphism) 是面向对象编程的核心概念之一。通过多态,我们可以编写更加灵活、可扩展的代码。本文将详细介绍什么是多态、如何实现多态,并通过具体的例子来帮助你更好地理解这一重要概念。 一、什…...
安当CAS密码应用系统:构建企业级固件签名体系的解决方案
在工业互联网与智能设备爆发式增长的今天,固件安全已成为设备安全的"最后一道防线"。据IDC统计,2025年全球68%的固件攻击将利用密钥管理漏洞发起。传统固件签名方案依赖企业自购硬件加密机(HSM),不仅面临高额…...
文法 2025/3/3
文法的定义 一个文法G是一个四元组:G(,,S,P) :一个非空有限的终极符号集合。它的每个元素称为终极符号或终极符,一般用小写字母表示。终极符号是一个语言不可再分的基本符号。 :一个非空有限的非终极符号集合。它的每个元素称为…...
论文阅读:Dual Anchor Graph Fuzzy Clustering for Multiview Data
论文地址:Dual Anchor Graph Fuzzy Clustering for Multiview Data | IEEE Journals & Magazine | IEEE Xplore 代码地址:https://github.com/BBKing49/DAG_FC 摘要 多视角锚图聚类近年来成为一个重要的研究领域,催生了多个高效的方法。然而&#…...
【分享】内外网文件摆渡系统:让数据传输更安全更可靠
【分享】Ftrans内外网文件摆渡系统:让数据传输更安全更可靠! 随着大数据时代的到来,数据的重要性日渐得到重视,数据作为数字经济时代下的基础性资源和战略性资源,是决定国家经济发展水平和竞争力的核心驱动力。以行业…...
Spring Boot 中的 Aware 接口以及 ApplicationContextAware 的详细说明、使用示例及注意事项
以下是关于 Spring Boot 中的 Aware 接口以及 ApplicationContextAware 的详细说明、使用示例及注意事项: 一、Aware 接口简介 Spring 框架提供了一系列 Aware 接口,用于让 Bean 在初始化时感知并获取 Spring 容器中的特定组件。这些接口通过回调方法&a…...
nginx的自定义日志
正常nginx的报错都会在 想要把日志独立出来需要用到俩个参数 然后创建目录 mkdir /var/log/timingxu.org 最后实验一下 结果实验成功...
【蓝桥杯速成】| 17.完全背包(一维easy版)
题目一:爬楼梯 问题描述 57. 爬楼梯(第八期模拟笔试) 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬至多m (1 < m < n)个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整…...
算法导论(动态规划)——路径问题
算法思路(62) 状态表示: 在解决“路径类”问题时,常见的状态表示形式有两种: 形式一:从位置 [i,j] 出发的路径计数。形式二:从起始位置到达位置 [i,j] 的路径计数。 本文选择第二种形式来定义状…...
Python Flask并发demo(http并发与锁)独占接口、monkey功能还不太确定
文章目录 Flask 并发接口实现示例代码示例关键并发支持特性解析1. **Gevent monkey patching**:2. **线程锁控制**:3. **协程服务器**:4. **状态标志与异常处理**:5. **接口差异化处理**: 使用场景- 需要处理高并发请求…...
stm32第十天外部中断和NVIC讲解
一:外部中断基础知识 1.STM32外部中断框架 中断的概念:在主程序运行过程中,出现了特点的中断触发条件,使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行 1&…...
音视频 ColorSpace色彩空间详解
前言 基于前篇介绍YUV格式,本文继续介绍另一个重要概念颜色空间,又叫色彩空间;主要用于在音视频开发中的色彩空间转换。 色彩空间Color Space 色彩空间由色彩模型和色域共同定义。当色彩模型与特定的描述相关联以后,就称为色彩空间。 色彩模型Color Model 色彩模型Col…...
通义万相2.1 你的视频创作之路
通义万相2.1的全面介绍 一、核心功能与技术特点 通义万相2.1是阿里巴巴达摩院研发的多模态生成式AI模型,以视频生成为核心,同时支持图像、3D内容及中英文文字特效生成。其核心能力包括: 复杂动作与物理规律建模 能够稳定生成包含人体旋转、…...
动态规划学习——背包问题
一,开心的金明 题目链接:P1060 [NOIP 2006 普及组] 开心的金明 - 洛谷 本题是一道经典的01背包问题,状态表示和状态定义可以仿照01背包的来。 01背包传送门:【背包问题 】01背包_01背包算法题链接-CSDN博客 dp[i][j]表示从前i个物…...
oracle数据泵操作
源库操作 查询目录对象是否已定义 plsql执行 select * from dba_directories t where t.directory_name MYDIR;先创建一个d盘databack文件夹上边语句查询,无返回数据,则创建,若提示权限不足,请授权 plsql执行 create directory mydir as …...
flutter框架中文文档,android智能手机编程答案
RecyclerView优化全攻略:从数据处理到性能提升 字节跳动四面有三面都问了这个问题,在此做了整理,希望可以帮助到大家,欢迎查漏补缺。 数据处理和视图加载分离 我们知道,从远端拉取数据肯定是要放在异步的࿰…...
Sourcetree安装教程及配合Gitee的使用
零、SourceTree介绍 SourceTree 是一款由 Atlassian 公司开发的免费图形化版本控制工具,支持 Git 和 Mercurial 两大版本控制系统。它通过直观的界面简化了代码管理操作,适合开发者和团队高效管理项目代码。 核心功能 可视化操作 无需记忆命令行&#x…...
.net farmework 4.8 类库中添加 wpf 窗体
一般正常情况下,在 .net farmework 4.8 类库中是无法添加 wpf 窗体的,如下图 但是可以添加 winform 窗体,如果想添加 wpf 窗体,需要一些更改 1.添加库 在程序集这里添加库,直接搜索名字即可 需要添加下面库࿱…...
某合约任意提取BNB漏洞
1背景描述 合约是一个在满足特定条件时在区块链上执行代码的程序,各方以数字签署合同的方式准许并维护它的其运行。这些代码可以是向朋友汇款、买卖 NFT 虚拟商品等一系列复杂的内容。 存在漏洞的目标合约是一个结合Meme文化病毒式传播与去中心化金融(D…...