go中map

文章目录

    • Map简介
      • 哈希表与Map的概念
      • Go语言内建的Map类型
        • Map的声明
        • Map的初始化
        • Map的访问
        • Map的添加和修改
        • Map的删除
        • Map的遍历
    • Map的基本使用
      • Map的声明与初始化
      • Map的访问与操作
      • Map的删除
      • Map的遍历
      • Map的并发问题
      • 实现线程安全的Map
    • 3. Map的访问与操作
      • 3.1 访问Map元素
        • 代码示例:
      • 3.2 修改Map元素
        • 代码示例:
      • 3.3 删除Map元素
        • 代码示例:
      • 3.4 Map遍历
        • 代码示例:
      • 3.5 Map的并发访问问题
      • 3.6 实现线程安全的Map
      • 图表 3-1: Map的并发访问与线程安全实现
    • 4. Map的遍历与注意事项
      • 4.1 遍历Map
        • 代码示例:
      • 4.2 空值与不存在的键
        • 代码示例:
      • 4.3 修改遍历中的Map
      • 4.4 使用Map的条件
      • 4.5 Map的并发读写
      • 图表 4-1: Map遍历与并发访问
    • 5. 实现线程安全的Map类型
      • 5.1 使用`sync.Mutex`或`sync.RWMutex`
        • 代码示例:
      • 5.2 使用`sync.Map`
        • 代码示例:
      • 5.3 分片加锁(Sharded Locking)
        • 代码示例:
      • 5.4 注意事项
      • 图表 5-1: 线程安全的Map实现方法
    • 6. sync.Map 的详细介绍与使用
      • 6.1 sync.Map 概述
      • 6.2 sync.Map 的核心方法
      • 6.3 sync.Map 的使用场景
      • 6.4 sync.Map 的性能考虑
      • 6.5 sync.Map 的实现原理
      • 图表 6-1: sync.Map 的工作原理
      • 6.6 使用 sync.Map 的示例
    • 7. sync.Map 的高级特性与实际应用
      • 7.1 sync.Map 的高级特性
      • 7.2 使用 LoadAndDelete
        • 代码示例:
      • 7.3 使用 LoadOrStore
        • 代码示例:
      • 7.4 sync.Map 的 Range 方法
        • 代码示例:
      • 7.5 sync.Map 的实际应用
      • 7.6 注意事项
      • 图表 7-1: sync.Map 高级特性的流程
    • 8. 对比分析与性能评估
      • 8.1 内建Map与sync.Map的对比
      • 8.2 sync.Map与读写锁的对比
      • 8.3 分片Map的性能
      • 8.4 性能评估
      • 8.5 实际案例分析
      • 图表 8-1: 不同并发数据结构的性能评估
    • 9. 使用建议与最佳实践
      • 9.1 使用 sync.Map 的建议
      • 9.2 sync.Map 的最佳实践
      • 9.3 性能测试
      • 9.4 内存和CPU监控
      • 9.5 替代方案
      • 9.6 代码示例与模式
        • 代码示例:
      • 图表 9-1: sync.Map 使用建议与最佳实践

  1. Map简介

哈希表与Map的概念

哈希表是一种基于哈希函数的数据结构,它提供了快速的数据插入和检索功能。哈希表通过使用哈希函数将键(key)映射到表中的位置来访问数据,这通常使得大多数情况下的查找、插入和删除操作的时间复杂度为O(1)。这种数据结构在多种编程语言中都有广泛的应用。

Go语言内建的Map类型

Go语言中的map是内建的哈希表类型,它实现了键值对(key-value)的存储和快速检索。以下是Go语言中Map的一些基本特性:

  • 动态的:Go的map是动态的,可以根据需要增长和缩小。
  • 无序的:Map中的元素是无序的,这意味着遍历Map时元素的顺序是不确定的,且不保证与插入顺序相同。
  • 并发非安全的:Go的内建Map不是线程安全的,即在并发环境下直接使用Map可能会导致竞态条件。
Map的声明

在Go中,Map的声明语法如下:

go

var mapVariable map[keyType]valueType

这里keyType是键的类型,必须是可比较的(comparable),例如整数、浮点数、字符串或实现了==!=操作符的自定义类型。valueType是值的类型,可以是任何Go类型。

Map的初始化

使用make函数初始化Map:

go

mapVariable := make(map[keyType]valueType)

这将创建一个空的Map,准备好存储键值对。

Map的访问

Map的访问通过使用下标语法:

go

value := mapVariable[key]

这将返回键对应的值。如果键不存在,将返回该值类型的零值。

Map的添加和修改

向Map添加新的键值对或修改已存在的键的值:

go

mapVariable[key] = value
Map的删除

删除Map中的键值对使用delete函数:

go

delete(mapVariable, key)
Map的遍历

遍历Map中的所有键值对:

go

for key, value := range mapVariable {
    // 处理key和value
}

请注意,由于Map是无序的,每次遍历的顺序可能会不同。

  1. Map的基本使用

Map的声明与初始化

在Go语言中,Map是一个通过哈希表实现的键值对集合。声明Map时需要指定键和值的类型。键的类型必须是可比较的,以支持==!=操作符。以下是声明Map的基本语法:

go

var mapVariable map[KeyType]ValueType

声明后,使用make函数进行初始化:

go

mapVariable := make(map[KeyType]ValueType)

图表 2-1: Map的声明与初始化示例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Map的访问与操作

访问Map中的元素时,可以使用下标访问操作符[]。如果键不存在,将返回该值类型的零值。

go

value := mapVariable[key]

修改Map中的元素或添加新元素,同样使用下标访问操作符:

go

mapVariable[key] = value

图表 2-2: Map的访问与赋值操作

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Map的删除

使用delete函数可以从Map中删除键值对:

go

delete(mapVariable, key)

Map的遍历

遍历Map时,可以使用range关键字。由于Map是无序的,遍历的顺序是不确定的:

go

for key, value := range mapVariable {
    // 处理key和value
}

图表 2-3: Map的遍历过程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Map的并发问题

Go的内建Map不是线程安全的。在并发环境下,多个goroutine同时读写Map可能会导致竞态条件和数据不一致。

实现线程安全的Map

为了在并发环境下安全使用Map,可以采用以下方法:

  • 使用sync包的RWMutex:通过读写锁来控制对Map的并发访问。
  • 分片加锁:将Map分割成多个部分,每部分使用独立的锁来减少锁竞争。
  • 使用sync.Map:Go 1.9版本引入的线程安全的Map实现。

图表 2-4: 线程安全****的Map实现方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以上就是Go语言Map的基本使用方法和线程安全问题的概述。接下来,我将根据大纲继续编写关于Map的高级特性和实际应用案例。如果您需要更详细的代码示例或有其他问题,请随时告诉我。

3. Map的访问与操作

3.1 访问Map元素

在Go中,访问Map元素是通过使用下标操作符[]来实现的。给定一个Map mapVariable,可以通过mapVariable[key]来获取与键key对应的值。如果键不存在,将返回该值类型的零值。

代码示例:
value := mapVariable[key] // 获取键对应的值,如果键不存在,value将是零值

3.2 修改Map元素

修改Map中的元素也是通过下标操作符[]来完成。当你给一个已存在的键赋新值时,该键对应的值将被更新。

代码示例:
mapVariable[key] = newValue // 更新键对应的值为newValue

3.3 删除Map元素

从Map中删除元素使用的是delete()函数。调用delete(mapVariable, key)将从Map中删除键key及其对应的值。

代码示例:
delete(mapVariable, key) // 删除键key及其对应的值

3.4 Map遍历

遍历Map时,可以使用range关键字。Map是无序的,所以每次遍历的顺序可能会不同。

代码示例:
for key, value := range mapVariable {
    // 可以使用key和value做相关操作
}

3.5 Map的并发访问问题

Go的内建Map类型不是线程安全的。在并发环境下,如果多个goroutine尝试同时读写Map,可能会遇到竞态条件,导致数据竞争和不一致。

3.6 实现线程安全的Map

为了解决并发访问问题,可以采用以下几种方法:

  • 使用**sync.RWMutex**实现读写锁:适用于读多写少的场景,可以提高读取操作的并发性。
  • 分片加锁(Sharded Locking):通过将Map分割成多个部分,每部分使用单独的锁,以减少锁竞争,适用于高并发读写场景。
  • 使用**sync.Map**:Go语言提供的线程安全的Map实现,适用于特定场景,如只增长的缓存系统或不相交键集的场景。

图表 3-1: Map的并发访问与线程安全实现

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4. Map的遍历与注意事项

4.1 遍历Map

Map的遍历是通过range关键字实现的,这允许我们迭代Map中的每个键值对。由于Map是无序的,每次遍历Map时元素的顺序可能会不同。

代码示例:
for key, value := range mapVariable {
    // 在这里可以使用key和value
}

4.2 空值与不存在的键

在访问Map时,如果键不存在,将返回该类型的零值。这可能会与实际存储的零值混淆。因此,通常Map的访问会返回两个值:一个是键对应的值,另一个是布尔值,表示键是否存在于Map中。

代码示例:
value, exists := mapVariable[key]
if exists {
    // 键存在,可以使用value
} else {
    // 键不存在,value是零值
}

4.3 修改遍历中的Map

在遍历Map的过程中,直接修改Map(例如添加或删除键值对)可能会导致迭代器的状态与实际Map的状态不一致,从而引发运行时错误。

4.4 使用Map的条件

  • Map的key必须是可比较的类型,即能够使用==!=进行比较。
  • Map的key通常使用内建的基本类型,如整数、字符串等。如果使用结构体作为key,需要保证结构体在逻辑上的不可变性。

4.5 Map的并发读写

Go的内建Map不是线程安全的。在并发环境下,如果多个goroutine尝试同时读写同一个Map,可能会遇到竞态条件。

图表 4-1: Map遍历与并发访问

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上述图表展示了Map遍历的过程,以及在并发访问Map时可能遇到的问题和解决方案。遍历时,我们通常需要检查键是否存在,以区分零值和不存在的键。在并发环境下,我们需要使用锁或sync.Map来保证Map的线程安全。

5. 实现线程安全的Map类型

在Go语言中,由于内建的Map类型不是线程安全的,因此在并发环境下使用时需要采取额外的措施来保证线程安全。以下是几种实现线程安全Map的方法:

5.1 使用sync.Mutexsync.RWMutex

通过在Map操作前加锁,可以保证同一时间只有一个goroutine能修改Map。

代码示例:
var (
    mu sync.Mutex // 或者使用 sync.RWMutex
    m  = make(map[keyType]valueType)
)

func safeSet(key keyType, value valueType) {
    mu.Lock() // 或者使用 mu.RLock() 来提高读取操作的并发性
    defer mu.Unlock()
    m[key] = value
}

func safeGet(key keyType) (valueType, bool) {
    mu.Lock() // 或者使用 mu.RLock()
    defer mu.Unlock()
    value, ok := m[key]
    return value, ok
}

5.2 使用sync.Map

Go 1.9版本引入了sync.Map,这是一个内置的并发安全的Map类型,适用于某些特定场景。

代码示例:
var m = sync.Map{}

// 设置键值对
m.Store(key, value)

// 获取键值对
value, ok := m.Load(key)

// 删除键值对
m.Delete(key)

// 遍历Map
m.Range(func(key, value interface{}) bool {
    // 处理键值对
    return true // 如果返回false,将停止迭代
})

5.3 分片加锁(Sharded Locking)

通过将Map分割成多个部分,每部分使用单独的锁,可以减少锁竞争,提高并发性能。

代码示例:
type ShardedMap struct {
    shards []map[keyType]valueType
    locks  []*sync.Mutex
}

func (m *ShardedMap) Set(key keyType, value valueType) {
    shardIndex := hash(key) % len(m.shards) // 假设hash是键的哈希函数
    m.locks[shardIndex].Lock()
    m.shards[shardIndex][key] = value
    m.locks[shardIndex].Unlock()
}

5.4 注意事项

  • sync.MapLoadStore操作通常不需要加锁,但Delete操作可能需要。
  • sync.Map的迭代器Range在遍历时不会锁定Map,因此其他goroutine可以并发修改Map。
  • sync.Map没有提供获取Map长度的方法,如果需要获取长度,必须使用Range函数遍历并计数。

图表 5-1: 线程安全的Map实现方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以上是实现线程安全的Map类型的几种方法。在实际应用中,应根据具体的并发需求和性能考虑来选择合适的实现方式。

6. sync.Map 的详细介绍与使用

6.1 sync.Map 概述

sync.Map 是 Go 语言提供的一个并发安全的 Map 类型,它在 Go 1.9 版本中引入。与内建的 Map 类型相比,sync.Map 通过内部同步机制,允许多个 goroutine 安全地并发读写,而不需要外部加锁。

6.2 sync.Map 的核心方法

  • Store: 存储键值对,如果键已存在,则会更新其值。
  • Load: 加载键对应的值,如果键不存在,则返回该类型的零值和一个 false 标志。
  • Delete: 删除键值对。
  • Range: 遍历 Map 中的所有键值对,但遍历过程中不保证其他 goroutine 的修改会立即反映出来。

6.3 sync.Map 的使用场景

sync.Map 适用于以下两种场景:

  1. 只写入一次的键: 一个键只被写入一次,之后可能会被多次读取。
  2. 不相交的键集: 多个 goroutine 操作不相交的键集,即每个 goroutine 只读写自己的键。

6.4 sync.Map 的性能考虑

  • sync.Map 相对于内建 Map 加入了一些额外的内存和计算开销,以提供并发安全性。
  • 在高并发读写的场景下,sync.Map 可以提供比使用读写锁(sync.RWMutex)更好的性能。

6.5 sync.Map 的实现原理

sync.Map 的实现涉及以下几个关键点:

  • 空间换时间: 使用两个字段 readdirty 来存储键值对,read 是只读的,dirty 是可写的。
  • 延迟删除: 删除操作只是将条目标记为删除,实际的内存清理会在之后进行。
  • 双检查: 在 LoadDelete 操作中,先尝试无锁访问 read,如果需要访问 dirty,则加锁并再次检查 read

图表 6-1: sync.Map 的工作原理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上述图表展示了 sync.Map 的工作原理,包括其内部的 readdirty 字段,以及核心方法 StoreLoadDelete 的操作流程。

6.6 使用 sync.Map 的示例

var m sync.Map

// 存储键值对
m.Store("key", "value")

// 读取键值对
if val, ok := m.Load("key"); ok {
    fmt.Println(val)
}

// 删除键值对
m.Delete("key")

// 遍历 Map
m.Range(func(key, value interface{}) bool {
    fmt.Printf("%v: %v\n", key, value)
    return true
})

在实际使用中,sync.Map 提供了一种简便的方式来处理并发环境下的 Map 操作,而无需手动管理锁。然而,它也带来了一些限制和性能开销,因此在某些场景下可能需要仔细评估是否使用 sync.Map

7. sync.Map 的高级特性与实际应用

7.1 sync.Map 的高级特性

sync.Map 除了基本的 StoreLoadDelete 操作外,还提供了一些高级特性,以支持更复杂的并发场景:

  • LoadAndDelete: 原子地从键加载并删除条目。
  • LoadOrStore: 如果键存在,则加载其值;如果不存在,则存储提供的值。
  • Range: 遍历 Map 中的所有键值对,但要注意,遍历过程中的修改可能不会反映在迭代器中。

7.2 使用 LoadAndDelete

LoadAndDelete 方法可以在单次原子操作中删除键并返回其值,这在某些需要清理资源的场景下非常有用。

代码示例:
value, loaded := m.LoadAndDelete(key)
if loaded {
    // 键存在,value 是其对应的值
    // 现在键已经被删除
}

7.3 使用 LoadOrStore

LoadOrStore 方法允许你在键不存在时存储一个新值,如果键存在,则返回其现有值,这减少了检查键是否存在的需要。

代码示例:
value, loaded := m.LoadOrStore(key, newValue)
if loaded {
    // 键已存在,value 是其对应的值
} else {
    // 键不存在,newValue 已被存储
}

7.4 sync.Map 的 Range 方法

Range 方法允许你遍历 Map 中的所有键值对。这个方法在每次调用时的行为类似于只读的迭代器。

代码示例:
m.Range(func(key, value interface{}) bool {
    // 处理 key 和 value
    // 如果返回 false,则停止迭代
    return true
})

7.5 sync.Map 的实际应用

sync.Map 可以在多种并发场景下使用,例如:

  • 缓存系统: 作为并发缓存存储,其中键是缓存的索引,值是缓存的数据。
  • 计数器: 作为并发安全的计数器,每个键代表一个特定的计数项。
  • 注册表: 存储和管理一组并发访问的注册项。

7.6 注意事项

  • sync.MapRange 函数不保证在遍历过程中对 Map 的修改会立即反映出来,如果需要反映修改,可以在 Range 调用结束后再次调用。
  • sync.Map 没有提供直接获取 Map 大小的方法,如果需要,可以在 Range 中计数。

图表 7-1: sync.Map 高级特性的流程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以上是 sync.Map 的高级特性和实际应用的概述。这些特性使得 sync.Map 成为处理并发数据存储的强大工具。

8. 对比分析与性能评估

8.1 内建Map与sync.Map的对比

内建Map和sync.Map在并发安全性、性能和使用场景上有所不同:

  • 并发安全性: 内建Map不是线程安全的,而sync.Map是为并发访问设计的。
  • 性能: 在高并发读写的场景下,sync.Map可能提供更好的性能,因为它减少了锁的争用。
  • 使用场景: 内建Map适用于单线程环境或可以通过外部同步控制并发的场景;sync.Map适用于需要多个goroutine并发读写的场景。

8.2 sync.Map与读写锁的对比

使用sync.RWMutex保护的内建Map和sync.Map在读写操作的锁策略上不同:

  • 锁策略: sync.RWMutex允许多个读操作同时进行,写操作是排他的;sync.Map通过内部机制允许更高的并发性。
  • 性能: 在读多写少的场景下,使用sync.RWMutex可能更有优势;在写操作较多或读写相当的场景下,sync.Map可能更优。

8.3 分片Map的性能

分片Map通过将数据分散到多个Map上,每个Map由一个锁保护,从而减少锁竞争:

  • 并发性: 分片Map可以提供非常高的并发性,特别是在写操作分散均匀的情况下。
  • 实现复杂性: 分片Map的实现比sync.Map复杂,需要合理地设计分片数量和散列函数。

8.4 性能评估

性能评估是选择合适并发数据结构的关键。以下是性能评估的一些要点:

  • 基准测试: 使用Go的基准测试工具对不同的Map实现进行性能测试。
  • 场景模拟: 模拟实际应用场景,测试在不同并发级别下的性能表现。
  • 资源监控: 监控内存使用、CPU使用等资源指标,评估性能开销。

8.5 实际案例分析

在实际应用中,选择哪种Map实现应基于具体需求和性能测试结果:

  • 缓存系统: 如果缓存的读写非常频繁,sync.Map可能是一个好选择。
  • 配置管理: 如果配置信息的更新不频繁,但读取操作很多,使用sync.RWMutex保护的Map可能更合适。
  • 分布式****系统: 在分布式系统中,分片Map可以提供高效的数据局部性,减少跨节点通信。

图表 8-1: 不同并发数据结构的性能评估

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以上是内建Map、sync.Map和分片Map的对比分析以及性能评估的概述。在实际开发中,选择哪种数据结构应基于对性能、并发性和实现复杂性的综合考量。

9. 使用建议与最佳实践

9.1 使用 sync.Map 的建议

以下是在使用 sync.Map 时应考虑的一些建议:

  • 评估并发需求: 在选择使用 sync.Map 之前,评估应用的并发访问模式是否符合 sync.Map 的适用场景。
  • 避免过度使用: 由于 sync.Map 的实现复杂性,它可能带来额外的性能开销,因此仅在需要时使用。
  • 谨慎使用 Range: 使用 Range 遍历时,要注意它不会锁定Map,因此在遍历过程中Map的结构可能会变化。

9.2 sync.Map 的最佳实践

以下是一些使用 sync.Map 的最佳实践:

  • 使用 LoadAndDelete: 当需要原子地加载并删除键值对时,使用 LoadAndDelete 方法。
  • 使用 LoadOrStore: 当需要根据键的存在与否来决定加载或存储值时,使用 LoadOrStore 方法。
  • 避免在 Range 中修改: 不要在 Range 函数的迭代过程中修改Map,这可能会导致竞态条件。

9.3 性能测试

  • 基准测试: 对 sync.Map 的操作进行基准测试,以了解其性能特性。
  • 并发场景模拟: 模拟实际的并发访问模式,评估 sync.Map 在不同场景下的表现。

9.4 内存和CPU监控

  • 监控内存使用: 使用工具监控 sync.Map 在高并发下的内存使用情况。
  • 监控CPU使用: 监控 sync.Map 在高负载下的CPU使用率,确保性能开销在可接受范围内。

9.5 替代方案

  • 考虑其他数据结构: 在某些情况下,可能需要考虑其他数据结构或第三方库提供的并发安全的Map实现。
  • 使用读写锁: 对于读多写少的场景,使用 sync.RWMutex 保护的内建Map可能更合适。

9.6 代码示例与模式

  • 存储和加载: 始终使用 StoreLoad 方法来保证操作的原子性。
  • 条件加载或存储: 使用 LoadOrStore 来减少条件检查的需要。
代码示例:
var m sync.Map

// 安全地存储键值对
m.Store(key, value)

// 安全地加载键值对
if val, ok := m.Load(key); ok {
    // 使用 val
} else {
    // 键不存在
}

// 条件存储
if val, loaded := m.LoadOrStore(key, value); !loaded {
    // value 是新存储的
}

图表 9-1: sync.Map 使用建议与最佳实践

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以上是关于 sync.Map 的使用建议和最佳实践的概述。在实际开发中,应根据具体情况选择最合适的并发数据结构,并遵循最佳实践以确保代码的健壳性和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/843414.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序 button样式设置为图片的方法

微信小程序 button样式设置为图片的方法 background-image background-size与background-repeat与border:none;是button必须的 <view style" position: relative;"><button class"customer-service-btn" style"background-image: url(./st…

新华三H3CNE网络工程师认证—VLAN使用场景与原理

通过华三的技术原理与VLAN配置来学习&#xff0c;首先介绍VLAN&#xff0c;然后介绍VLAN的基本原理&#xff0c;最后介绍VLAN的基本配置。 文章目录 一、传统以太网问题1、广播域范围过大2、分割广播域 二、如何实现VLAN1、VLAN技术达到的效果2、VLAN数值的编号范围3、仿真&am…

这届打工人,快把单休卷成职场用工标配了……

最近&#xff0c;小柴有个朋友跟小柴吐槽&#xff0c;自己被「灵活就业」大半年了&#xff0c;有点扛不住&#xff0c;就准备去送外卖&#xff0c;结果第一天赚了38&#xff0c;反手电瓶车罚了50…… 心灰意冷的他&#xff0c;最终还是在某BOSS上充个值&#xff0c;没日没夜的投…

手持式气象站:便携科技,掌握微观气象的利器

手持式气象站&#xff0c;顾名思义&#xff0c;是一种可以随身携带的气象监测设备。它小巧轻便&#xff0c;通常配备有温度、湿度、风速、风向、气压等多种传感器&#xff0c;能够实时测量并显示各种气象参数。不仅如此&#xff0c;它还具有数据存储、数据传输、远程控制等多种…

搭建博客系统#Golang

WANLI 博客系统 项目介绍 基于vue3和gin框架开发的前后端分离个人博客系统&#xff0c;包含md格式的文本编辑展示&#xff0c;点赞评论收藏&#xff0c;新闻热点&#xff0c;匿名聊天室&#xff0c;文章搜索等功能。 点击跳转&#xff1a;Github 项目开源地址 功能展示 B 站…

实战篇(十):使用Processing创建可爱花朵:实现随机位置、大小和颜色的花朵

使用Processing创建可爱花朵 0.效果预览1. 引言2. 设置Processing环境3. 创建花朵类4. 实现花瓣绘制5. 绘制可爱的笑脸6. 鼠标点击生成花朵7. 完整代码8. 总结与扩展0.效果预览 在本教程中,我们将使用Processing编程语言来创建一个可爱的花朵生成器。通过封装花朵为一个类,并…

使用shedlock实现分布式互斥执行

前言 前序章节&#xff1a;springboot基础(82):分布式定时任务解决方案shedlock 如果你不清楚shedlock&#xff0c;建议先阅读前序章节&#xff0c;再来查看本文。 如果我们不在spring环境下&#xff0c;如何使用shedlock实现分布式互斥执行&#xff1f; 我们可以使用shedl…

Elasticsearch 7.x入门学习-Java API操作

1 创建项目 在idea开发工具中创建Maven项目 修改 pom 文件&#xff0c;增加 Maven 依赖关系 <dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</versi…

ubuntu2204配置anacondacuda4090nvidia驱动

背景 某个机房的几台机器前段时间通过dnat暴露至公网后被入侵挖矿&#xff0c;为避免一些安全隐患将这几台机器执行重装系统操作&#xff1b; 这里主要记录配置nvidia驱动及cuda&anaconda。 步骤 大概分为几个步骤 禁用nouveau配置grub显示菜单install nvidia-driveri…

Linux云计算 |【第一阶段】ENGINEER-DAY3

主要内容&#xff1a; LVM逻辑卷管理、VDO、RAID磁盘阵列、进程管理 一、新建逻辑卷 1、什么是逻辑卷 逻辑卷&#xff08;Logical Volume&#xff09;是逻辑卷管理&#xff08;Logical Volume Management&#xff0c;LVM&#xff09;系统中的一个概念。LVM是一种用于磁盘管理…

SpringBoot集成MQTT实现交互服务通信

引言 本文是springboot集成mqtt的一个实战案例。 gitee代码库地址&#xff1a;源码地址 一、什么是MQTT MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;&#xff0c;是一种基于发布/订阅&#xff08;publish/subscribe&…

[Armbian] 部署Docker版Home Assistent,安装HACS并连接米家设备

title: [Armbian] 部署Docker版Home Assistent&#xff0c;安装HACS并连接米家设备 date: 2024-07-21T10:51:23Z lastmod: 2024-07-21T11:40:39Z [Armbian] 部署Docker版Home Assistent&#xff0c;安装HACS并连接米家设备 官网&#xff1a;Home Assistant (home-assistant.i…

sql常见50道查询练习题

sql常见50道查询练习题 1. 表创建1.1 表创建1.2 数据插入 2. 简单查询例题(3题&#xff09;2.1 查询"李"姓老师的数量2.2 查询男生、女生人数2.3 查询名字中含有"风"字的学生信息 3. 日期相关例题(6题&#xff09;3.1 查询各学生的年龄3.2 查询本周过生日的…

Yolo-World网络模型结构及原理分析(一)——YOLO检测器

文章目录 概要一、整体架构分析二、详细结构分析YOLO检测器1. Backbone2. Head3.各模块的过程和作用Conv卷积模块C2F模块BottleNeck模块SPPF模块Upsampling模块Concat模块 概要 尽管YOLO&#xff08;You Only Look Once&#xff09;系列的对象检测器在效率和实用性方面表现出色…

【GraphRAG】微软 graphrag 效果实测

GraphRAG 本文将基于以下来源&#xff0c;对Microsoft GraphRAG分析优缺点、以及示例实测分析。 1. Source 代码仓库&#xff1a; Welcome to GraphRAGhttps://microsoft.github.io/graphrag/ 微软文章1&#xff08;2024.2.13&#xff09;&#xff1a;GraphRAG: Unlocking…

通过albumentation对目标检测进行数据增强(简单直接)

albumentation官方文档看不懂&#xff1f;xml文件不知道如何操作&#xff1f;下面只需要修改部分代码即可上手使用 要使用这个方法之前需要按照albumentation这个库还有一些辅助库,自己看着来安装就行 pip install albumentation pip install opencv-python pip install json…

阿尔泰科技利用485模块搭建自动灌溉系统实现远程控制

自动灌溉系统又叫土壤墒情监控系统&#xff0c;土壤墒情监控系统主要实现固定站无人值守情况下的土壤墒情数据的自动采集和无线传输&#xff0c;数据在监控中心自动接收入库&#xff1b;可以实现24小时连续在线监控并将监控数据通过有线、无线等传输方式实时传输到监控中心生成…

破解反爬虫策略 /_guard/auto.js(二)实战

这次我们用上篇文章讲到的方法来真正破解一下反爬虫策略&#xff0c;这两个案例是两个不同的网站&#xff0c;一个用的是 /_guard/auto.js&#xff0c;另一个用的是/_guard/delay_jump.js。经过解析发现这两个网站用的反爬虫策略基本是一模一样&#xff0c;只不过在js混淆和生成…

FOG Project 文件名命令注入漏洞复现(CVE-2024-39914)

0x01 产品简介 FOG是一个开源的计算机镜像解决方案,旨在帮助管理员轻松地部署、维护和克隆大量计算机。FOG Project 提供了一套功能强大的工具,使用户能够快速部署操作系统、软件和配置设置到多台计算机上,从而节省时间和精力。该项目支持基于网络的 PXE 启动、镜像创建和还…

Python | Leetcode Python题解之第240题搜索二维矩阵II

题目&#xff1a; 题解&#xff1a; class Solution:def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:m, n len(matrix), len(matrix[0])x, y 0, n - 1while x < m and y > 0:if matrix[x][y] target:return Trueif matrix[x][y] > tar…