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

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 的注意点

  1. 必须成对使用 Lock()Unlock(),否则容易导致死锁。
  2. 不要重复 Unlock(),否则会触发 panic。
  3. 不要在 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 的注意点

  1. 读锁 (RLock) 允许多个 Goroutine 并发读取,但写锁 (Lock) 会阻塞所有读操作。
  2. RLock()Lock() 不能混用,否则可能出现死锁。
  3. 适用于 读多写少 的场景,写多时反而可能降低性能。

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.Mutexsync.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 试图获取锁:

  1. 如果锁是空闲的,直接获取,state 置为 1。
  2. 如果锁被占用,会先进行一小段时间的自旋(在 CPU 允许的情况下短时间循环尝试获取锁)。
  3. 如果自旋后仍然获取不到锁,当前 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 并发编程&#xff1a;从入门到精通的锁机制 引言&#xff1a;为什么需要锁&#xff1f; Go 语言以其天生支持并发的特性深受开发者喜爱&#xff0c;但并发带来的问题也不容小觑&#xff0c;比如数据竞争、并发安全等。如果多个 Goroutine 访问同一个变量&#xff0c;没有做…...

JS判断对象是否为空的方法

在 JavaScript 中&#xff0c;判断一个对象是否为空对象&#xff08;即没有自身可枚举属性&#xff09;&#xff0c;可以通过以下方法实现&#xff1a; 方法 1&#xff1a;使用 Object.keys() javascript function isEmptyObject(obj) {// 确保是普通对象&#xff08;排除 n…...

idea导入tomcat的jar

概述 对于老项目&#xff0c;未使用 Maven/Gradle 管理依赖的&#xff0c;在需要编译 Servlet/JSP 代码时&#xff0c;需要手动添加 Tomcat JAR 依赖&#xff08;如 servlet-api.jar&#xff09;方能进行编绎。 步骤&#xff1a; 1、找到 Tomcat 的 JAR 文件 进入 Tomcat 安…...

Linux 下安装和使用 Jupyter Notebook

Jupyter Notebook / Lab 是 Python 开发和数据分析中不可或缺的工具。为了避免环境污染&#xff0c;推荐使用虚拟环境方式安装并启动它。本教程将教你如何&#xff1a; 安装 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&#xff1a; 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&#xff08;Least Recently Used&#xff09;&#xff1a;最近最少使用策略&#xff0c;当缓存空间不足时&#xff0c;淘汰最久未被访问的数据。…...

html中img标签直接使用border-radius时会图片进行了遮挡

前言 该问题是我写完项目之后&#xff0c;UI走查发现的问题&#xff0c;虽然我也发现了问题&#xff0c;但是改起来&#xff0c;不好改&#xff0c;就耽搁了。后面UI还是要求要改。一直找不到解决方案&#xff0c;歪打正着通过MDN官网偶然看到的clip-path属性。 需求 一个图…...

【Keepalived】Keepalived-2.3.3明确结束对CentOS 7的支持

2025年3月30日&#xff0c;官方发布了Keepalived的最新版&#xff0c;版本号&#xff1a;2.3.3 而2024年11月3日发布的2.3.2版本&#xff0c;在CentOS 7.9上编译的时候&#xff0c;就出现了报错&#xff0c;但是在Alma Linux 8.10上&#xff0c;则可以成功编译安装&#xff0c…...

Docker学习--容器生命周期管理相关命令--docker pause/unpause 命令

docker pause 命令的作用&#xff1a; 用于暂停一个或多个容器中的所有进程。 语法&#xff1a; docker pause CONTAINER [CONTAINER…]&#xff08;要操作的容器的名称&#xff0c;可以同时操作多个&#xff09;。 实例&#xff1a; ①暂停一个容器及其所有进程&#xff1a;…...

【Zabbix技术系列文章】第④篇——Zabbix 数据可视化

在当今数字化运维时代&#xff0c;面对海量的监控数据&#xff0c;如何从中快速获取有价值的信息至关重要。Zabbix 的数据可视化功能为我们提供了直观、高效的解决方案&#xff0c;它能将复杂的监控数据转化为清晰易懂的图表和仪表盘&#xff0c;助力运维人员迅速发现问题、分析…...

R CSV 文件处理指南

R CSV 文件处理指南 引言 CSV&#xff08;逗号分隔值&#xff09;文件是一种常见的文件格式&#xff0c;它以纯文本形式存储表格数据。在R语言中&#xff0c;CSV文件处理是非常基础且重要的技能。本文将详细介绍如何在R中读取、处理和导出CSV文件&#xff0c;并探讨一些高级技…...

在Git仓库的Readme上增加目录页

一般在编写Readme时想要增加像文章那样的目录&#xff0c;方便快速跳转&#xff0c;但是Markdown语法并没有提供这样的方法&#xff0c;但是可以通过超链接结合锚点的方式来实现&#xff0c;如下图是我之前一个项目里写的Readme&#xff1a; 例如有下面几个Readme内容&#xff…...

[特殊字符]《多商户家政系统技术解析:SpringBoot+MyBatisPlus+UniApp高效实战指南》

&#x1f6e0;️ 引言&#xff1a;多商户家政系统的技术挑战与价值 在数字化时代&#xff0c;家政行业逐渐向线上迁移&#xff0c;从传统的线下预约转向平台化管理。多商户家政系统具备复杂的角色体系&#xff0c;包括&#xff1a; &#x1f6ce;️ 商户端&#xff1a;管理订单…...

请求Header(Request Headers)详解

请求Header&#xff08;Request Headers&#xff09;详解 HTTP请求Header是HTTP请求消息的重要组成部分&#xff0c;用于在客户端和服务器之间传递附加信息。这些信息帮助服务器理解客户端的环境、偏好和请求的具体内容&#xff0c;从而能够返回更合适的响应。以下是对请求Hea…...

深度求索:开源革命下的AI普惠之路

引言&#xff1a;AI领域的破局者 2025年&#xff0c;全球AI领域因一家中国公司的崛起而震动。杭州深度求索&#xff08;DeepSeek&#xff09;推出的V3大模型以6710亿参数、14.8万亿token训练数据量&#xff0c;在数学竞赛、代码生成等专业领域超越多数国际竞品&#xff0c;其每…...

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虽然好&#xff0c;但也给服务器带来很大的内存开销&#xff0c;当系统的业务量&#xff0c;并发量不高时&#xff0c;考虑到服务器和维护成本&#xff0c;可考虑使用Redis实现一个轻量级的消息队列&#xff0c;实现事件监听的效果。下面介绍下…...

13届省赛python A组:10.数的拆分

题目1 数的拆分 给定 T 个正整数 ai&#xff0c;分别问每个 ai 能否表示为 x 1 y 1 ⋅ x 2 y 2 x1^{y1}⋅x2^{y2} x1y1⋅x2y2 的形式&#xff0c;其中 x1,x2 为正整数&#xff0c;y1,y2 为大于等于 2 的正整数。 输入格式 输入第一行包含一个整数 T 表示询问次数。 接下来…...

【Android Studio】下载安装过程(详细)

目录 一、前期准备 JDK下载安装 二、下载安装 下载 安装 启动 一、前期准备 JDK下载安装 详细的安装过程请移步我的另一篇博客jdk17详细安装步骤_jdk17安装教程详细-CSDN博客 cmd打开命令行&#xff0c;输入java -version验证&#xff0c;可以看到此处我安装的是java23。…...

【RAGFlow】ubuntu22部署ragflow(v0.17.2)

按照官方手册部署&#xff1a; https://ragflow.io/docs/v0.17.2/ 部署环境&#xff1a; CPU: 4核memory&#xff1a; 16gGPU: T4(vGPU)Disk: 20g 1. 配置国内docker-ce源 https://mirrors.tuna.tsinghua.edu.cn/help/docker-ce/ 用清华源&#xff0c;要不然下载速度感人 …...

Easysearch 如何短暂维护 Data 节点

之前介绍过如何移除 Data 节点&#xff0c;那么如果只是短暂停止一个 Data 节点进行维护&#xff0c;之后再次加入集群&#xff0c;是否也需要按照移除节点的步骤进行操作呢&#xff1f;我们先梳理下核心原理。 核心原理 我们先看看节点离开集群之后集群是怎样处理的。当节点…...

【cocos creator 3.x】3Dui创建,模型遮挡ui效果

官方文档&#xff1a;https://docs.cocos.com/creator/3.8/manual/zh/ui-system/components/editor/ui-model.html 1、3Dui创建 创建label&#xff0c;默认会添加canvas根节点和2dCamera 将Camera删除&#xff0c;canvas上组建去除cc.Canvas&#xff0c;cc.widget&#xff0…...

UE5学习笔记 FPS游戏制作32 主菜单,暂停游戏,显示鼠标指针

文章目录 一主菜单搭建UI显示主菜单时&#xff0c;暂停游戏&#xff0c;显示鼠标绑定按钮 二 打开主菜单 一主菜单 搭建UI 添加一个MainUi的控件 添加一个返回游戏的按钮和一个退出游戏的按钮 修改一下样式&#xff0c;放中间 显示主菜单时&#xff0c;暂停游戏&#xff0…...

有哪些开源的视频生成模型

1. 阿里巴巴通义万相2.1&#xff08;WanX 2.1&#xff09; 技术架构&#xff1a;基于Diffusion Transformer&#xff08;DiT&#xff09;架构&#xff0c;结合自研的高效变分自编码器&#xff08;VAE&#xff09;和Flow Matching训练方案&#xff0c;支持时空上下文建模。参数…...

基于Spring Boot的家庭理财系统app的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

SQLAlchemy系列教程:事件驱动的数据库交互

在现代Web应用开发中&#xff0c;数据库交互往往需要超越简单的CRUD操作。当用户注册成功后自动发送欢迎邮件&#xff1f;在订单创建时同步库存数据&#xff1f;这些场景都需要监听数据库状态变化并触发相应逻辑。SQLAlchemy的事件系统为此提供了优雅的解决方案。 本文将深入解…...

linux基本命令(2)--进程命令PS

其实吧, 在linux命令下 输入man ps也可以&#xff0c;一行行拖下去也是看到解析的。退出不看的时候记得按q哦 基本介绍 国际惯例介绍下这个命令的用途。 在Linux下ps命令是用于查看系统上运行的进程的最基本的命令之一。它提供了当前进程的同时&#xff0c;如用户ID&#xf…...

android adb 查看设备传感器

Android ADB 查看设备传感器的使用技巧 在Android开发中&#xff0c;了解设备的传感器是非常重要的一步。不论是开发健康应用、游戏&#xff0c;还是任何需要感知用户环境的应用&#xff0c;传感器的使用都离不开对其数据的获取。Android Debug Bridge&#xff08;ADB&#xf…...

Verilog HDL 100道面试题及参考答案

目录 Verilog HDL 的四种基本逻辑值是什么? 关键字 reg 和 wire 的主要区别是什么? 解释阻塞赋值(=)与非阻塞赋值(<=)的区别,并举例说明。 如何声明一个双向端口(inout)? 位拼接操作符是什么?举例说明其用法。 拼接信号和常量 拼接常量和信号 重复拼接 以…...

Java基础-26-多态-认识多态

在Java编程中&#xff0c;多态&#xff08;Polymorphism&#xff09; 是面向对象编程的核心概念之一。通过多态&#xff0c;我们可以编写更加灵活、可扩展的代码。本文将详细介绍什么是多态、如何实现多态&#xff0c;并通过具体的例子来帮助你更好地理解这一重要概念。 一、什…...

安当CAS密码应用系统:构建企业级固件签名体系的解决方案

在工业互联网与智能设备爆发式增长的今天&#xff0c;固件安全已成为设备安全的"最后一道防线"。据IDC统计&#xff0c;2025年全球68%的固件攻击将利用密钥管理漏洞发起。传统固件签名方案依赖企业自购硬件加密机&#xff08;HSM&#xff09;&#xff0c;不仅面临高额…...

文法 2025/3/3

文法的定义 一个文法G是一个四元组&#xff1a;G(,,S,P) &#xff1a;一个非空有限的终极符号集合。它的每个元素称为终极符号或终极符&#xff0c;一般用小写字母表示。终极符号是一个语言不可再分的基本符号。 &#xff1a;一个非空有限的非终极符号集合。它的每个元素称为…...

论文阅读:Dual Anchor Graph Fuzzy Clustering for Multiview Data

论文地址:Dual Anchor Graph Fuzzy Clustering for Multiview Data | IEEE Journals & Magazine | IEEE Xplore 代码地址&#xff1a;https://github.com/BBKing49/DAG_FC 摘要 多视角锚图聚类近年来成为一个重要的研究领域&#xff0c;催生了多个高效的方法。然而&#…...

【分享】内外网文件摆渡系统:让数据传输更安全更可靠

【分享】Ftrans内外网文件摆渡系统&#xff1a;让数据传输更安全更可靠&#xff01; 随着大数据时代的到来&#xff0c;数据的重要性日渐得到重视&#xff0c;数据作为数字经济时代下的基础性资源和战略性资源&#xff0c;是决定国家经济发展水平和竞争力的核心驱动力。以行业…...

Spring Boot 中的 Aware 接口以及 ApplicationContextAware 的详细说明、使用示例及注意事项

以下是关于 Spring Boot 中的 Aware 接口以及 ApplicationContextAware 的详细说明、使用示例及注意事项&#xff1a; 一、Aware 接口简介 Spring 框架提供了一系列 Aware 接口&#xff0c;用于让 Bean 在初始化时感知并获取 Spring 容器中的特定组件。这些接口通过回调方法&a…...

nginx的自定义日志

正常nginx的报错都会在 想要把日志独立出来需要用到俩个参数 然后创建目录 mkdir /var/log/timingxu.org 最后实验一下 结果实验成功...

【蓝桥杯速成】| 17.完全背包(一维easy版)

题目一&#xff1a;爬楼梯 问题描述 57. 爬楼梯&#xff08;第八期模拟笔试&#xff09; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬至多m (1 < m < n)个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 注意&#xff1a;给定 n 是一个正整…...

算法导论(动态规划)——路径问题

算法思路&#xff08;62&#xff09; 状态表示&#xff1a; 在解决“路径类”问题时&#xff0c;常见的状态表示形式有两种&#xff1a; 形式一&#xff1a;从位置 [i,j] 出发的路径计数。形式二&#xff1a;从起始位置到达位置 [i,j] 的路径计数。 本文选择第二种形式来定义状…...

Python Flask并发demo(http并发与锁)独占接口、monkey功能还不太确定

文章目录 Flask 并发接口实现示例代码示例关键并发支持特性解析1. **Gevent monkey patching**&#xff1a;2. **线程锁控制**&#xff1a;3. **协程服务器**&#xff1a;4. **状态标志与异常处理**&#xff1a;5. **接口差异化处理**&#xff1a; 使用场景- 需要处理高并发请求…...

stm32第十天外部中断和NVIC讲解

一&#xff1a;外部中断基础知识 1.STM32外部中断框架 中断的概念&#xff1a;在主程序运行过程中&#xff0c;出现了特点的中断触发条件&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行 1&…...

音视频 ColorSpace色彩空间详解

前言 基于前篇介绍YUV格式,本文继续介绍另一个重要概念颜色空间,又叫色彩空间;主要用于在音视频开发中的色彩空间转换。 色彩空间Color Space 色彩空间由色彩模型和色域共同定义。当色彩模型与特定的描述相关联以后,就称为色彩空间。 色彩模型Color Model 色彩模型Col…...

通义万相2.1 你的视频创作之路

通义万相2.1的全面介绍 一、核心功能与技术特点 通义万相2.1是阿里巴巴达摩院研发的多模态生成式AI模型&#xff0c;以视频生成为核心&#xff0c;同时支持图像、3D内容及中英文文字特效生成。其核心能力包括&#xff1a; 复杂动作与物理规律建模 能够稳定生成包含人体旋转、…...

动态规划学习——背包问题

一&#xff0c;开心的金明 题目链接&#xff1a;P1060 [NOIP 2006 普及组] 开心的金明 - 洛谷 本题是一道经典的01背包问题&#xff0c;状态表示和状态定义可以仿照01背包的来。 01背包传送门&#xff1a;【背包问题 】01背包_01背包算法题链接-CSDN博客 dp[i][j]表示从前i个物…...

oracle数据泵操作

源库操作 查询目录对象是否已定义 plsql执行 select * from dba_directories t where t.directory_name MYDIR;先创建一个d盘databack文件夹上边语句查询,无返回数据&#xff0c;则创建&#xff0c;若提示权限不足&#xff0c;请授权 plsql执行 create directory mydir as …...

flutter框架中文文档,android智能手机编程答案

RecyclerView优化全攻略&#xff1a;从数据处理到性能提升 字节跳动四面有三面都问了这个问题&#xff0c;在此做了整理&#xff0c;希望可以帮助到大家&#xff0c;欢迎查漏补缺。 数据处理和视图加载分离 我们知道&#xff0c;从远端拉取数据肯定是要放在异步的&#xff0…...

Sourcetree安装教程及配合Gitee的使用

零、SourceTree介绍 SourceTree 是一款由 Atlassian 公司开发的免费图形化版本控制工具&#xff0c;支持 Git 和 Mercurial 两大版本控制系统。它通过直观的界面简化了代码管理操作&#xff0c;适合开发者和团队高效管理项目代码。 核心功能 可视化操作 无需记忆命令行&#x…...

.net farmework 4.8 类库中添加 wpf 窗体

一般正常情况下&#xff0c;在 .net farmework 4.8 类库中是无法添加 wpf 窗体的&#xff0c;如下图 但是可以添加 winform 窗体&#xff0c;如果想添加 wpf 窗体&#xff0c;需要一些更改 1.添加库 在程序集这里添加库&#xff0c;直接搜索名字即可 需要添加下面库&#xff1…...

某合约任意提取BNB漏洞

1背景描述 合约是一个在满足特定条件时在区块链上执行代码的程序&#xff0c;各方以数字签署合同的方式准许并维护它的其运行。这些代码可以是向朋友汇款、买卖 NFT 虚拟商品等一系列复杂的内容。 存在漏洞的目标合约是一个结合Meme文化病毒式传播与去中心化金融&#xff08;D…...