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

Golang 并发机制-7:sync.Once实战应用指南

Go的并发模型是其突出的特性之一,但强大的功能也带来了巨大的责任。sync.Once是由Go的sync包提供的同步原语。它的目的是确保一段代码只执行一次,而不管有多少协程试图执行它。这听起来可能很简单,但它改变了并发环境中管理一次性操作的规则。

sync.Once介绍

Go的并发模型是其突出的特性之一,但强大的功能也带来了巨大的责任。sync.Once是由Go的sync包提供的同步原语。它的目的是确保一段代码只执行一次,而不管有多少协程试图执行它。这听起来可能很简单,但它改变了并发环境中管理一次性操作的规则。

  • 定义: sync.Once是一个结构体,只有一个方法Do( f func() )
  • 目的:它保证函数f最多被调用一次,即使Do被并发地调用了多次
  • 线程安全: sync.Once是完全线程安全的,因此非常适合并发程序
    在这里插入图片描述

但是ync.Once与其他同步原语有那些差异?与mutex或channel不同,它们可以重复使用,sync.Once是专门为一次性行为设计的。它是轻量级的,并且针对这一单一目的进行了优化。

同步的常见用例, sync.Once包括:

  • 初始化共享资源
  • 构建单例模式
  • 仅执行单次的昂贵任务
  • 加载配置文件

下面是一个简单示例:

var instance *singleton
var once sync.Oncefunc getInstance() *singleton {once.Do(func() {instance = &singleton{}})return instance
}

在这个代码片段中,我们使用了sync.Once确保我们的单例只初始化一次,即使从多个协程并发调用getInstance() 也是如此。

但我们只是触及了表面!sync.Once有更多的实际应用,我们将在本文中深入探讨。从基本示例到高级用法,我们将涵盖所有内容。所以,系好安全带,让我们深入了解sync.Once的世界。

基本sync.Once示例:单例模式

单例模式是一种经典的软件设计模式,它将类的实例化限制为单个实例。当只需要一个对象来协调跨系统的操作时,它特别有用。在Go中,sync.Once提供了一种优雅且线程安全的方式来实现此模式。

让我们深入了解使用同步的具体示例。sync.Once用于单例实现:

package mainimport ("fmt""sync"
)type Singleton struct {data string
}var instance *Singleton
var once sync.Oncefunc GetInstance() *Singleton {once.Do(func() {fmt.Println("Creating Singleton instance")instance = &Singleton{data: "I'm the only one!"}})return instance
}func main() {for i := 0; i < 5; i++ {go func() {fmt.Printf("%p\n", GetInstance())}()}// Wait for goroutines to finishfmt.Scanln()
}

在本例中,我们使用sync.Once以确保我们的Singleton结构只实例化一次,即使在从多个例程并发调用GetInstance()时也是如此。

让我们来分析一下使用同步的好处。对于这个单例实现:

  1. 线程安全: sync.Once保证初始化函数只调用一次,即使在并发环境中也是如此。这消除了初始化期间的竞争条件。

  2. 延迟初始化:Singleton实例仅在GetInstance()第一次调用时创建,而不是在程序启动时创建。这对资源管理是有益的。

  3. 简单性:与其他线程安全的单例实现(如使用互斥锁)相比,sync.Once在Go中提供了一个更干净、更惯用的解决方案。

  4. 性能:在第一次调用之后,对 once.Do() 的后续调用基本上是无操作的,这使得它非常高效。

值得注意的是,虽然singleton很有用,但它们并不总是最好的解决方案。它们会使单元测试变得更加困难,并且违反单一职责原则。始终考虑是否有更适合您的特定用例的设计模式。

下面是对单例实现的快速比较:

MethodThread-safe?Lazy initialization?Complexity
sync.OnceYesYesLow
MutexYesYesMedium
init() functionYesNoLow
Global variableNoNoVery Low
MethodThread-safe?Lazy initialization?Complexity
sync.OnceYesYesLow
MutexYesYesMedium
init() functionYesNoLow
Global variableNoNoVery Low

如你所见,sync.Once在线程安全性、延迟初始化和低复杂性之间提供了很好的平衡。

请记住,虽然这个示例演示了sync.Once的基本用法。曾经,它的应用远远超出了单例模式。在接下来的部分中,我们将探索更高级的用法和最佳实践。

高级sync.Once用法:延迟初始化

延迟初始化是一种设计模式,在这种模式中,我们将对象的创建、值的计算或其他一些代价高昂的过程延迟到第一次需要的时候。这种策略可以显著提高性能和资源使用,特别是对于初始化成本高的应用程序。在Go中,同步。Once为实现线程安全的延迟初始化提供了一种优秀的机制。

让我们用一个更复杂的例子来探索这个概念:

package mainimport ("database/sql""fmt""log""sync"_ "github.com/lib/pq"
)type DatabaseConnection struct {db *sql.DB
}var (dbConn *DatabaseConnectiononce   sync.Once
)func GetDatabaseConnection() (*DatabaseConnection, error) {var initError erroronce.Do(func() {fmt.Println("Initializing database connection...")db, err := sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")if err != nil {initError = fmt.Errorf("failed to open database: %v", err)return}if err = db.Ping(); err != nil {initError = fmt.Errorf("failed to ping database: %v", err)return}dbConn = &DatabaseConnection{db: db}})if initError != nil {return nil, initError}return dbConn, nil
}func main() {// Simulate multiple goroutines trying to get the database connectionvar wg sync.WaitGroupfor i := 0; i < 5; i++ {wg.Add(1)go func(id int) {defer wg.Done()conn, err := GetDatabaseConnection()if err != nil {log.Printf("Goroutine %d: Error getting connection: %v\n", id, err)return}log.Printf("Goroutine %d: Got connection %p\n", id, conn)}(i)}wg.Wait()
}

这个例子演示了几个高级概念:

  1. 资源密集型初始化:创建数据库连接的成本通常很高。通过使用sync.Once确保这个昂贵的操作只发生一次,而不管有多少协程请求连接。

  2. 错误处理:我们已经将错误处理合并到惰性初始化中。如果在初始化期间发生错误,则捕获错误并将其返回给所有调用者。

  3. 并发管理:该示例模拟了数据库连接的多个并发请求,展示了如何sync.Once有效地管理了这个场景。

  4. 实际用例:此模式在实际应用程序中通常用于管理共享资源,如数据库连接、配置加载或缓存初始化。

让我们来分析一下使用sync.Once实现延迟初始化的好处:

  • 效率:资源只在实际需要时才分配,这可以显著减少启动时间和内存使用。
  • 线程安全:sync.Once确保即使多个程序试图同时初始化资源,初始化也只发生一次。
  • 简单性:与手动锁定机制相比,sync.Once提供了一种更干净、更不容易出错的方法。
  • 关注点分离:初始化逻辑被封装在once.Do()函数中,使代码更模块化,更易于维护。

下面是不同初始化策略的比较:

StrategyProsCons
Eager InitializationSimple, predictablePotentially wasteful if resource isn’t used
Lazy Initialization (without sync)EfficientNot thread-safe
Lazy Initialization (with sync.Once)Efficient, thread-safeSlightly more complex than eager initialization
Lazy Initialization (with mutex)Flexible, allows re-initializationMore complex, potentially less performant

特别提醒:sync.Once是强大的,它并不总是最好的解决方案。例如,如果需要重新初始化资源的能力(例如,在连接丢失后重新连接到数据库),你可能需要使用其他同步原语,如mutex.。

在下一节中,我们将探讨使用sync.Once时的常见缺陷和最佳实践,确保您可以在Go程序中有效地利用这个强大的工具。

sync.Once的实际应用

虽然我们已经介绍了同步的一些基本和高级示例。现在,让我们深入了解一些实际应用程序,在这些应用程序中,同步原语真正发挥了作用。这些示例将演示如何sync.Once可以用来解决Go编程中的常见问题,特别是在并发和分布式系统中。

  1. 数据库连接池

连接池是一种用于提高数据库性能的技术。不是为每个操作打开和关闭连接,而是维护可重用连接池。

import ("database/sql""sync"_ "github.com/lib/pq"
)var (dbPool *sql.DBpoolOnce sync.Once
)func GetDBPool() (*sql.DB, error) {var err errorpoolOnce.Do(func() {dbPool, err = sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")if err != nil {return}dbPool.SetMaxOpenConns(25)dbPool.SetMaxIdleConns(25)dbPool.SetConnMaxLifetime(5 * time.Minute)})if err != nil {return nil, err}return dbPool, nil
}

这种方法确保数据库连接池只初始化一次,而不管有多少协程调用GetDBPool(),它既高效又线程安全。

  1. 配置加载场景

加载配置文件是sync.Once的另一个常见用例。通常希望在启动时只加载一次,但首次需要惰性加载。

import ("encoding/json""os""sync"
)type Config struct {APIKey string `json:"api_key"`Debug bool `json:"debug"`
}var (config *ConfigconfigOnce sync.Once
)func GetConfig() (*Config, error) {var err errorconfigOnce.Do(func() {file, err := os.Open("config.json")if err != nil {return}defer file.Close()config = &Config{}err = json.NewDecoder(file).Decode(config)})if err != nil {return nil, err}return config, nil
}

此模式确保读取和解析配置文件的潜在昂贵操作只发生一次,即使应用程序的多个部分同时请求配置。

  1. 模块化Go应用中插件初始化

对于插件架构的应用程序, sync.Once可以用来确保每个插件只初始化一次,即使有多个组件试图使用它:

type Plugin struct {Name stringinitialized boolinitOnce sync.Once
}func (p *Plugin) Initialize() error {var err errorp.initOnce.Do(func() {// Simulate complex initializationtime.Sleep(2 * time.Second)if p.Name == "BadPlugin" {err = fmt.Errorf("failed to initialize plugin: %s", p.Name)}p.initialized = truefmt.Printf("Plugin %s initialized\n", p.Name)})return err
}func UsePlugin(name string) error {plugin := &Plugin{Name: name}if err := plugin.Initialize(); err != nil {return err}// Use the plugin...return nil
}

这种方法允许延迟加载插件,并确保即使多个线程试图同时使用同一个插件,初始化也只发生一次。

  • 几种方式优缺点比较
Use CaseBenefits of sync.OncePotential Drawbacks
DB Connection PoolingEnsures single pool creation, thread-safeMay delay error detection until first use
Config LoadingLazy loading, consistent config across appMight complicate dynamic config updates
Plugin InitializationEfficient for rarely used pluginsCould increase complexity in plugin management

这些实际应用程序展示了 sync.Once 的多功能性。解决常见的并发编程挑战。通过理解这些模式,你可以适时、高效使用sync.Once,让应用更高效和健壮的代码。

最后总结

本文介绍了Golang sync.Once的最佳实践,从基本示例到高级应用程序。记住,sync.Once是你在并发Go程序中“执行一次且仅执行一次”场景的首选工具。它很简单,但功能强大——就像go本身一样。因此,下次遇到一次性初始化挑战时,你将确切地知道应该使用什么方法。

相关文章:

Golang 并发机制-7:sync.Once实战应用指南

Go的并发模型是其突出的特性之一&#xff0c;但强大的功能也带来了巨大的责任。sync.Once是由Go的sync包提供的同步原语。它的目的是确保一段代码只执行一次&#xff0c;而不管有多少协程试图执行它。这听起来可能很简单&#xff0c;但它改变了并发环境中管理一次性操作的规则。…...

java nio 底层使用的是select 、poll还是epoll

在 Java NIO 中&#xff0c;底层使用的 I/O 多路复用机制取决于操作系统和 JDK 的实现。 &#x1f680; Java NIO 底层使用机制概述 操作系统默认多路复用机制系统调用Linuxepollepoll_create、epoll_ctl、epoll_waitWindowsselect 或 WSAPollselect() 或 WSAPoll()macOS / B…...

Kotlin协程详解——协程取消与超时

目录 一、协程取消 1.取消协程的执行 2.使计算代码可取消 3.在finally中释放资源 4.运行不能取消的代码块 二、协程超时 异步超时与资源管理 一、协程取消 1.取消协程的执行 在一个长时间运行的应用程序中&#xff0c;你也许需要对你的后台协程进行细粒度的控制。 比如…...

双向链表、内核链表和gdb(20250208)

单向链表 节点 数据域 指针域&#xff08;后继节点&#xff09; 双向链表 相比于单项指针&#xff0c;双向指针存有前驱节点的地址&#xff0c;使链表的灵活性更高。 内核链表 在内核中 offsetof&#xff1a;获取结构体某个成员到结构体开头的偏移量container_of:根据结…...

全程Kali linux---CTFshow misc入门(38-50)

第三十八题&#xff1a; ctfshow{48b722b570c603ef58cc0b83bbf7680d} 第三十九题&#xff1a; 37换成1&#xff0c;36换成0&#xff0c;就得到长度为287的二进制字符串&#xff0c;因为不能被8整除所以&#xff0c;考虑每7位转换一个字符&#xff0c;得到flag。 ctfshow{5281…...

MySQL 8.0.41安装教程(2025年2月8号)

下载网址&#xff1a;https://www.mysql.com/cn/downloads/ 点击 我选择的是第二个离线安装 点击之后&#xff0c;选择直接下载&#xff1a; 下载完成双击&#xff1a; 我选择的是自定义安装&#xff1a; 右边默认已经存在我选择的8.0.41 点击红框中的&#xff0c;自定义安装路…...

【自学笔记】Deepseek的基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Deepseek知识点总览一、Deepseek简介二、Deepseek的三大适用模式1. 基础模型&#xff08;V3&#xff09;2. 深度思考&#xff08;R1&#xff09;3. 联网搜索模式 三…...

10N10-ASEMI中低压N沟道MOS管10N10

编辑&#xff1a;ll 10N10-ASEMI中低压N沟道MOS管10N10 型号&#xff1a;10N10 品牌&#xff1a;ASEMI 封装&#xff1a;TO-252 最大漏源电流&#xff1a;10A 漏源击穿电压&#xff1a;100V 批号&#xff1a;最新 RDS&#xff08;ON&#xff09;Max&#xff1a;135mΩ …...

2025年2月8日(Adafruit_PCA9685详细使用)

Adafruit_PCA9685 是一个 Python 模块&#xff0c;用于与 PCA9685 驱动芯片进行通信&#xff0c;该芯片常用于控制多个伺服电机。PCA9685 是一个 16 通道的 PWM&#xff08;脉宽调制&#xff09;驱动器&#xff0c;常用于需要精确控制多个伺服电机的应用。 以下是详细的使用方…...

MR30分布式IO模块:驱动智能制造工厂的工业互联与高效控制新范式

在工业4.0与智能制造浪潮的推动下&#xff0c;传统制造业正经历着从“机械驱动”向“数据驱动”的深刻转型。作为工业数据连接领域的领军者&#xff0c;明达技术凭借其自主研发的MR30分布式IO模块&#xff0c;以创新的技术架构与卓越的性能表现&#xff0c;为全球制造企业构建了…...

Reqable使用实践

一、背景 日常开发中&#xff0c;难免要抓取请求数据&#xff0c;查看接口数据&#xff0c;从而更好定位问题&#xff0c;基于这个原因&#xff0c;查找了一些抓包工具&#xff0c;例如&#xff1a; HttpCanary、 Steam 、Fiddler等&#xff0c;不是要钱&#xff0c;就是只对苹…...

数据可视化基本套路总结

首先从维基百科上搬出数据可视化的概念&#xff1a; 数据可视化是关于数据之视觉表现形式的研究&#xff1b;其中&#xff0c;这种数据的视觉表现形式被定义为一种以某种概要形式抽提出来的信息&#xff0c;包括相应信息单位的各种属性和变量。 用人话简单来说&#xff0c;数据…...

TensorFlow域对抗训练DANN神经网络分析MNIST与Blobs数据集梯度反转层提升目标域适应能力可视化...

全文链接&#xff1a;https://tecdat.cn/?p39656 本文围绕基于TensorFlow实现的神经网络对抗训练域适应方法展开研究。详细介绍了梯度反转层的原理与实现&#xff0c;通过MNIST和Blobs等数据集进行实验&#xff0c;对比了不同训练方式&#xff08;仅源域训练、域对抗训练等&am…...

DNS劫持和HTTPDNS

DNS 劫持是一种网络攻击手段&#xff0c;攻击者通过篡改域名系统&#xff08;DNS&#xff09;解析过程&#xff0c;将用户请求的域名重定向到恶意网站或其他不正确的地址。这种攻击可以用于多种目的&#xff0c;例如窃取用户数据、传播恶意软件或进行钓鱼攻击。 举个例子 假设…...

云原生微服务

能够认识到云原生微服务对应用程序设计的影响&#xff0c;描述无状态微服务&#xff0c;并比较单体和微服务架构。要充分利用运营模式&#xff0c;您需要以不同的方式思考应用程序设计。您需要考虑云原生微服务。此图像显示了一个应用程序&#xff0c;该应用程序被设计为小型微…...

【deepSeek R1】Ollama 更改模型安装位置 以及应用安装位置

【deepSeek R1】Ollama 更改模型安装位置 以及应用安装位置 本地版部署deepSeek R1 可以参考文章 3分钟教你搭建属于自己的本地大模型 DeepSeek R1 Ollama 是一个开源工具&#xff0c;旨在帮助用户轻松在本地计算机上运行、部署和管理大型语言模型&#xff08;LLMs&#xff09;…...

windows + visual studio 2019 使用cmake 编译构建静、动态库并调用详解

环境 windows visual studio 2019 visual studio 2019创建cmake工程 1. 静态库.lib 1.1 静态库编译生成 以下是我创建的cmake工程文件结构&#xff0c;只关注高亮文件夹部分 libout 存放编译生成的.lib文件libsrc 存放编译用的源代码和头文件CMakeLists.txt 此次编译CMak…...

使用Feign代替RestTemplet

Feign RestTemplet存在的问题 String url "http: //userservice/user/" order.getUserId(); User user restTemplate.getFor0bject(url, User.class);可读性差参数复杂URL难以维护 Feign声明式的Http客户端&#xff0c;官方地址&#xff1a;https://github.com…...

苹果笔记本安装jmeter

下载并安装jmeter即可&#xff0c;jmeter官网下载地址&#xff1a;Apache JMeter - Download Apache JMeter 参考以下文章&#xff1a;“https://blog.csdn.net/weixin_51664828/article/details/145008755”...

设备通过国标GB28181接入EasyCVR,显示在线但视频无法播放的原因排查

安防监控EasyCVR平台支持多种视频源接入&#xff0c;包括但不限于IP摄像头、NVR、编码器、流媒体服务器等。平台采用高效的视频流接入技术&#xff0c;支持大规模视频流的并发接入&#xff0c;确保视频流的稳定性和流畅性。 有用户反馈&#xff0c;项目现场使用国标GB28181接入…...

为什么我喜欢在 CSS 中使用 RegEx

说到正则&#xff08;RegEx&#xff09;&#xff0c;我们第一反应往往是“在编程中用来匹配或验证字符串”&#xff0c;比如做表单验证。但其实在 CSS 中&#xff0c;也能用到与正则类似的选择器特性&#xff0c;为我们的样式管理带来诸多便利。别怀疑&#xff0c;以下就是如何…...

深度剖析 Redisson 分布式锁:原理、实现与应用实践

文章目录 写在文章开头详解Redisson 分布式锁使用和实现前置准备工作分布式锁的基本使用公平锁的使用联锁的使用读写锁基本使用常见问题Redisson和Jedis有什么区别redisson如何实现分布式锁redisson如何实现分布式锁的可重入redisson如何实现公平锁Redisson的watchdog机制是什么…...

今日AI和商界事件(2025-02-08)

今日AI领域的重大事件主要包括以下几个方面&#xff1a; 一、DeepSeek引发的行业震动 事件概述&#xff1a;DeepSeek作为近期崛起的AI模型&#xff0c;以其低成本、高性能的推理能力引发了广泛关注。其开源策略、独特的出身以及强大的算力表现&#xff0c;使得微软、英伟达等…...

Mac 基于Ollama 本地部署DeepSeek离线模型

最近节日期间最火的除了《哪吒》就是deepseek了&#xff0c;毕竟又让西方各个层面都瑟瑟发抖的产品。DeepSeek凭借其强大的AI能力真的是在全球多个领域展现出强大的影响力。由于受到外部势力的恶意攻击倒是deepseek官方服务不稳定&#xff0c;国内其他厂家的适配版本也不是很稳…...

Python截图轻量化工具

这是用Python做到截图工具&#xff0c;不过由于使用了ctypes调用了Windows的API, 同时访问了Windows中"C:/Windows/Cursors/"中的.cur光标样式文件, 这个工具只适用于Windows环境&#xff1b; 如果要提升其跨平台性的话&#xff0c;需要考虑替换ctypes的一些专属于W…...

怎麼在Chrome中設置代理伺服器?

出於隱私、安全或者訪問特定網路資源的需求&#xff0c;設置代理伺服器顯得尤為重要。本文將詳細介紹如何在Chrome流覽器中進行代理伺服器的設置。 代理伺服器是介於電腦和互聯網之間的一道“中間牆”。幫助間接訪問互聯網資源&#xff0c;這樣實際的IP地址被代理伺服器的IP地…...

【数据结构中链表常用的方法实现过程】

线性表 线性表包括:顺序表、链表、栈&#xff0c;队列等&#xff0c;本节我们先学习顺序表。 顺序表 利用新的数据类型——顺序表&#xff0c;操作数组 顺序表的本质就是对数组的增删改查。 /*** 打印顺序表中的所有元素*/Overridepublic void display() {for (int i 0; i…...

语言月赛 202308【小粉兔处理题解审核志愿者轮换】题解(AC)

》》》点我查看「视频」详解》》》 [语言月赛 202308] 小粉兔处理题解审核志愿者轮换 题目背景 又到了一周的周日&#xff0c;扶苏又像催命一样开始催促小粉兔处理题解审核志愿者的轮换。但是懒狗小粉兔总是把这项工作拖到第二天凌晨。 【这里有一张内部群聊图&#xff0c;…...

第二十二章:游戏结缘与现实的相遇

“终于结束了……” 小冷的手微微颤抖&#xff0c;笔在纸上划过&#xff0c;签下放弃 985 高校研究生入学资格的名字&#xff0c;那一刻&#xff0c;数月来压在心头沉甸甸的巨石轰然崩塌&#xff0c;扬起的尘埃渐渐消散。曾经&#xff0c;学术巅峰犹如夜空中遥不可及却又熠熠生…...

(ICLR=2025)生成的表征对齐:训练扩散Transformer比你想象的更简单

生成的表征对齐&#xff1a;训练扩散Transformer比你想象的更简单 paper是KAIST发表在ICLR 2025的工作 paper title:REPRESENTATION ALIGNMENT FOR GENERATION: TRAINING DIFFUSION TRANSFORMERS IS EASIER THAN YOU THINK Code&#xff1a;链接 ABSTRACT 最近的研究表明&…...

保姆级教程--DeepSeek部署

以DeepSeek-R1或其他类似模型为例&#xff0c;涵盖环境配置、代码部署和运行测试的全流程&#xff1a; 准备工作 1. 注册 Cloud Studio - 访问 [Cloud Studio 官网](https://cloudstudio.net/)&#xff0c;使用腾讯云账号登录。 - 完成实名认证&#xff08;如需长期使用…...

[css] 黑白主题切换

link动态引入 类名切换 css滤镜 var 类名切换 v-bind css预处理器mixin类名切换 【前端知识分享】CSS主题切换方案...

C语言练习题

文章目录 1. 递归实现将字符串str中的元素逆序2. 对数组arr进行冒泡排序&#xff08;升序&#xff09;3. 对数组从下标low到下标hihg区间内的元素进行快速排序&#xff08;升序&#xff09;4. 在数组中利用二分查找(折半查找)目标关键字5. 求n的阶乘6. 判断year是否为闰年7. 求…...

Lambda 表达式

一、Lambda 表达式简介 Lambda 表达式是一种简洁的函数式编程方式&#xff0c;用于实现只有一个方法的接口&#xff08;例如函数式接口&#xff09;。 基本语法 (parameters) -> expression (parameters) -> { statements; } 参数&#xff1a;可以有零个或多个参数。…...

Vue 鼠标事件合集,关于鼠标右键的处理方法(改写鼠标右键方法、自定义鼠标右键)

鼠标事件使用 mousedown"canvasDown($event)"按下事件合集 click 点击某个对象时触发 mousedown 鼠标按钮被按下时触发 mouseup 鼠标按钮被松开时触发 mouseleave 当鼠标指针移出元素时触发 dblclick 双击时触发 mousemove 鼠标移动时触发&#xff0c…...

go语言中的接口

接口简介 现实生活中的接口 现实生活中手机、相机、U 盘都可以和电脑的 USB 接口建立连接。我们不需要关注 usb 卡槽大小是否一样&#xff0c;因为所有的 USB 接口都是按照统一的标准来设计的。 Golang 中的接口&#xff08;interface&#xff09; Golang 中的接口是一种抽象…...

如何在Android Studio中开发一个简单的Android应用?

Android Studio是开发Android应用的官方集成开发环境&#xff08;IDE&#xff09;&#xff0c;它提供了许多强大的功能&#xff0c;使得开发者能够高效地创建Android应用。如果你是Android开发的初学者&#xff0c;本文将引导你如何在Android Studio中开发一个简单的Android应用…...

启明星辰发布MAF大模型应用防火墙产品,提升DeepSeek类企业用户安全

2月7日&#xff0c;启明星辰面向DeepSeek等企业级大模型业务服务者提供的安全防护产品——天清MAF&#xff08;Model Application Firewall&#xff09;大模型应用防火墙产品正式发布。 一个新赛道将被开启…… DeepSeek的低成本引爆赛道规模 随着DeepSeek成为当前最热的现象级…...

开箱即用的.NET MAUI组件库 V-Control 发布了!

之前写过挺多的MAUI Sample&#xff0c;其中有很多代码可以打包成组件&#xff0c;当组件完善到一定程度&#xff0c;我会把控件封装起来放到控件库中。 今天&#xff0c;在这个仓库建立一年零八个月后&#xff0c;我觉得可以考虑将其作为开源库发布。 有很多网友在观望.NET …...

android skia渲染介绍

Android AOSP 的渲染系统主要使用 Skia 图形库。Skia 是一个开源的 2D 图形库&#xff0c;它被广泛应用于 Android 的图形渲染中&#xff0c;负责绘制 UI 元素、文本、图像以及其他 2D 图形内容。 以下是 Android AOSP 中 Skia 的作用和它在渲染系统中的位置&#xff1a; 1. 什…...

MySQL的底层原理与架构

前言 了解MySQL的架构和原理对于很多的后续很多的操作会有很大的帮助与理解。并且很多知识都与底层架构相关联。 了解MySQL架构 通过上面的架构图可以得知&#xff0c;Server层中主要由 连接器、查询缓存、解析器/分析器、优化器、执行器 几部分组成的&#xff0c;下面将主要…...

GB/T 43698-2024 《网络安全技术 软件供应链安全要求》标准解读

一、43698-2024标准图解 https://mmbiz.qpic.cn/sz_mmbiz_png/rwcfRwCticvgeBPR8TWIPywUP8nGp4IMFwwrxAHMZ9Enfp3wibNxnfichT5zs7rh2FxTZWMxz0je9TZSqQ0lNZ7lQ/640?wx_fmtpng&fromappmsg 标准在线预览&#xff1a; 国家标准|GB/T 43698-2024 相关标准&#xff1a; &a…...

Vue(4)

一.组件的三大组成部分-注意点说明 &#xff08;1&#xff09;scoped样式冲突 默认情况&#xff1a;写在组件中的样式会全局生效 → 因此很容易造成多个组件之间的样式冲突 ①全局样式&#xff1a;默认组件中的样式会作用到全局 ②局部样式&#xff1a;可以给组件加上scoped属…...

实验3 词法分析(二)

实验3 词法分析(二) [实验目的]&#xff1a; 1 . 熟悉给定的词法分析程序&#xff1b; 2 . 改进词法分析程序。 [实验内容]&#xff1a; 1.尝试多方面改进TEST语言的文法&#xff0c;参考教材附录B词法分析程序TESTscan.c&#xff0c;在此词法分析程序的基础上改进程序&#x…...

MYSQL第四次

目录 题目分析 代码实现 一、修改 Student 表中年龄&#xff08;sage&#xff09;字段属性&#xff0c;数据类型由 int 改变为 smallint 二、为 Course 表中 Cno 字段设置索引&#xff0c;并查看索引 三、为 SC 表建立按学号&#xff08;sno&#xff09;和课程号&#xff…...

CentOS 7配置samba服务设置文件共享

CentOS 7配置samba服务设置文件共享 一、生成另一个Linux系统&#xff0c;名为Linux-client&#xff0c;作为测试系统。 [rootliunx-client ~]# hostnamectl set-hostname Liunx-client二、如果没有则安装Samba服务&#xff0c;如果已经安装则省略此步。 yum install samba…...

分布式微服务系统架构第91集:系统性能指标总结

加群联系作者vx&#xff1a;xiaoda0423 仓库地址&#xff1a;https://webvueblog.github.io/JavaPlusDoc/ 系统性能指标总结 系统性能指标包括哪些&#xff1f; 业务指标、资源指标、中间件指标、数据库指标、前端指标、稳定性指标、批量处理指标、可扩展性指标、可靠性指标。 …...

【算法】动态规划专题⑦ —— 多重背包问题 + 二进制分解优化 python

目录 前置知识进入正题优化方法&#xff1a;二进制分解实战演练 前置知识 【算法】动态规划专题⑤ —— 0-1背包问题 滚动数组优化 python 【算法】动态规划专题⑥ —— 完全背包问题 python 进入正题 多重背包问题I https://www.acwing.com/problem/content/4/ 题目描述 有…...

Node.js学习指南

一、模块化规范 nodejs使用的模块化规范 叫做 common.js 规范: 每一个模块都有独立的作用域 代码在各自模块中执行 不会造成全局污染 每一个模块都是一个独立的文件&#xff08;module对象&#xff09; 模块可以被多次加载&#xff08;module.exports 属性&#xff09; 但是仅…...

Mybatis篇

1&#xff0c;什么是Mybatis &#xff08; 1 &#xff09;Mybatis 是一个半 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它内部封装了 JDBC&#xff0c;开发时只需要关注 SQL 语句本身&#xff0c;不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁…...