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

自己的简历怎么制作网站驱动开发

自己的简历怎么制作网站,驱动开发,找客户的软件有哪些,企业信息网站模板1. 将value定义为struct节省内存 1. 消除指针引用 当 map 的 value 是 struct 类型时#xff0c;数据会直接存储在 map 中#xff0c;而不是通过指针引用。这可以减少内存分配的开销和 GC#xff08;垃圾回收#xff09;的负担。 type User struct {ID intName string…1. 将value定义为struct节省内存 1. 消除指针引用 当 map 的 value 是 struct 类型时数据会直接存储在 map 中而不是通过指针引用。这可以减少内存分配的开销和 GC垃圾回收的负担。 type User struct {ID intName string }m : make(map[string]User) m[user1] User{ID: 1, Name: John}// Example with pointer to struct m2 : make(map[string]*User) m2[user1] User{ID: 1, Name: John}在第二个示例中map 中存储的是指向 User 结构体的指针这意味着除了存储指针本身外还需要额外的内存来存储 User 结构体并且会增加 GC 的负担。 2. 避免内存碎片化 存储指针时由于指针可能指向堆中的不同位置这会导致内存碎片化增加了内存使用的不确定性。而存储 struct 使得数据更紧凑减少了碎片化。 3. 更高的缓存命中率 由于 struct 的数据是紧凑存储的相对于存储指针struct 的数据更可能在相邻的内存位置。这增加了 CPU 缓存的命中率从而提高了性能。 示例节约内存 下面是一个示例展示了如何通过定义 struct 类型来节约内存 package mainimport (fmtruntime )type User struct {ID intName string }func main() {// 使用 struct 作为 valueusers : make(map[string]User)for i : 0; i 1000000; i {users[fmt.Sprintf(user%d, i)] User{ID: i, Name: fmt.Sprintf(Name%d, i)}}printMemUsage(With struct values)// 使用指针作为 valueuserPtrs : make(map[string]*User)for i : 0; i 1000000; i {userPtrs[fmt.Sprintf(user%d, i)] User{ID: i, Name: fmt.Sprintf(Name%d, i)}}printMemUsage(With pointer values) }func printMemUsage(label string) {var m runtime.MemStatsruntime.ReadMemStats(m)fmt.Printf(%s: Alloc %v MiB\n, label, bToMb(m.Alloc)) }func bToMb(b uint64) uint64 {return b / 1024 / 1024 }4. set实现对比 map[int]bool{} 在这种情况下map 的 value 类型是 bool。每个键会占用一个 bool 类型的空间通常是一个字节。 set : make(map[int]bool) set[1] true set[2] truemap[int]struct{}{} 在这种情况下map 的 value 类型是空的 struct。空的 struct 不占用任何内存因此每个键只占用键本身的内存。 set : make(map[int]struct{}) set[1] struct{}{} set[2] struct{}{}内存使用对比 map[int]bool{} 会比 map[int]struct{}{} 使用更多的内存因为 bool 类型需要存储一个字节在实际应用中可能会有额外的内存对齐和管理开销而 struct{} 是空的不会增加任何内存开销。 示例代码对比内存使用 以下是一个示例代码比较这两种 map 类型的内存使用情况 package mainimport (fmtruntime )func main() {// 使用 bool 作为 valueboolMap : make(map[int]bool)for i : 0; i 1000000; i {boolMap[i] true}printMemUsage(With bool values)// 使用 struct 作为 valuestructMap : make(map[int]struct{})for i : 0; i 1000000; i {structMap[i] struct{}{}}printMemUsage(With struct values) }func printMemUsage(label string) {var m runtime.MemStatsruntime.ReadMemStats(m)fmt.Printf(%s: Alloc %v MiB\n, label, bToMb(m.Alloc)) }func bToMb(b uint64) uint64 {return b / 1024 / 1024 }结果 运行上述代码你会发现使用 struct 作为 value 的内存使用量明显小于使用指针作为 value 的内存使用量。这是因为 减少了指针的存储开销。减少了额外的堆内存分配。降低了 GC 的负担因为 struct 的内存管理更简单不涉及指针的追踪和回收。 2. 哈希分桶的结构 1. 哈希计算 当我们向map中插入一个键值对首先对键进行哈希计算。Go内置了哈希函数来计算键的哈希值。哈希值是一个64位的整数。 2. 分桶依据 Go 中的 map 是分成多个桶 (bucket) 来存储的。桶的数量通常是 2 的幂次这样可以方便地通过位运算来定位到具体的桶。哈希值的高八位和低八位分别用于分桶和桶内定位 高八位 (top 8 bits)用于决定哈希表中的桶位置。低八位 (low 8 bits)用于桶内查找。 3. 桶 (Bucket) 结构 每个桶中可以存储 8 个键值对。当某个桶中的元素超过 8 个时Go 会使用溢出桶来存储额外的键值对。桶的结构如下 type bmap struct {tophash [bucketCnt]uint8keys [bucketCnt]keyTypevalues [bucketCnt]valueTypeoverflow *bmap }tophash存储键的哈希值的高八位。 keys存储键。 values存储对应的值。 overflow指向溢出桶的指针。 . 插入过程 当插入一个键值对时过程如下 计算哈希值对键进行哈希计算得到哈希值 hash。定位桶通过 hash (64 - B)B 是桶的数量的对数得到桶的索引 index。桶内查找通过 hash (bucketCnt - 1) 得到桶内索引。然后通过对比 tophash 数组中的值来定位到具体的键值对存储位置。存储键值对将键值对存储到相应的位置如果当前桶已满则分配新的溢出桶来存储额外的键值对。 5. 查找过程 查找的过程与插入类似 计算哈希值对键进行哈希计算得到哈希值 hash。定位桶通过 hash (64 - B) 得到桶的索引 index。桶内查找通过 hash (bucketCnt - 1) 得到桶内索引然后在相应的 bmap 中查找 tophash 和 keys 数组中匹配的键。如果在当前桶中没有找到则继续查找溢出桶。 3. map扩容过程 1. 扩容触发条件 扩容通常在以下两种情况下触发 装载因子过高装载因子load factor是 map 中元素数量与桶数量的比值。Go 语言中的装载因子阈值通常为 6.5当装载因子超过这个值时会触发扩容。溢出桶过多当溢出桶的数量过多时也会触发扩容。 2. 扩容过程的具体步骤 初始化新的桶数组 在需要扩容时Go 会分配一个新的桶数组其大小通常是旧桶数组的两倍并设置相关的元数据以指示 map 正在进行扩容。标记迁移状态 在 map 的内部结构中会有一个标志位rehash index指示当前已经迁移的桶位置。初始值为 0。迁移部分数据 在每次对 map 进行插入或查找操作时会顺便迁移一部分旧桶中的数据到新桶中。每次迁移一个或多个桶具体数量取决于操作的复杂度。更新 rehash index 迁移完成后更新 rehash index以便下次操作继续迁移下一个桶中的数据。完成扩容 当所有旧桶的数据都迁移到新桶后更新 map 的元数据指向新的桶数组并将扩容状态标志位清除。 4. recovermap的panic panic 和 recover 的工作机制 panic panic 用于引发一个恐慌通常在遇到无法恢复的严重错误时使用。当 panic 被调用时程序的正常执行流程会被中断并开始沿着调用栈向上展开逐层调用函数的 defer 语句直到遇到 recover 或者程序崩溃。 recover recover 用于恢复程序的正常执行通常在 defer 函数中调用。如果在 defer 语句中调用了 recover并且当前栈帧处于恐慌状态那么 recover 会捕获这个恐慌停止栈的展开并返回传给 panic 的值。如果不在恐慌状态下调用 recover它会返回 nil不做任何处理。 在 Go 语言中panic 和 recover 是用来处理异常情况和错误恢复的两种机制。理解它们的工作原理对于编写健壮的 Go 代码非常重要。以下是对 panic 和 recover 机制的详细解释以及它们在 map 中的应用。 panic 和 recover 的工作机制 panic panic 用于引发一个恐慌通常在遇到无法恢复的严重错误时使用。当 panic 被调用时程序的正常执行流程会被中断并开始沿着调用栈向上展开逐层调用函数的 defer 语句直到遇到 recover 或者程序崩溃。 recover recover 用于恢复程序的正常执行通常在 defer 函数中调用。如果在 defer 语句中调用了 recover并且当前栈帧处于恐慌状态那么 recover 会捕获这个恐慌停止栈的展开并返回传给 panic 的值。如果不在恐慌状态下调用 recover它会返回 nil不做任何处理。 在 map 中使用 panic 和 recover 在 Go 的 map 中某些操作如并发读写未加锁的 map会引发 panic。这些 panic 可以被 recover 捕获和处理以防止程序崩溃。 package mainimport (fmt )func main() {defer func() {if r : recover(); r ! nil {fmt.Println(Recovered from panic:, r)}}()// 创建一个 mapm : make(map[string]string)// 引发 panic 的操作causePanic(m)fmt.Println(This line will be executed because panic was recovered.) }func causePanic(m map[string]string) {// 这里尝试并发访问 map可能会引发 panic// 模拟并发问题直接引发 panicpanic(simulated map access panic) }5. map是如何检测到自己处于竞争状态 在 Go 语言中map 的竞争状态concurrent access指的是多个 goroutine 同时读写同一个 map 而没有适当的同步保护。Go 内置的 map 类型在并发读写时会引发 panic以防止数据竞争和未定义行为。这种检测主要是通过 Go 编译器和运行时的实现来完成的而不是底层硬件直接支持的功能。 竞争检测机制 编译器插桩 在编译时Go 编译器会在对 map 进行读写操作的代码位置插入特定的检测代码。这些检测代码在运行时检查 map 是否处于并发访问状态。 运行时检查 运行时的检测代码会追踪 map 的访问。当检测到多个 goroutine 同时对 map 进行读写操作时会引发 panic。具体来说Go 运行时会记录每个 map 的访问情况如果检测到并发访问没有通过同步机制如 sync.Mutex就会引发 panic。 package mainimport (fmtsync )func main() {m : make(map[int]int)var wg sync.WaitGroupvar mu sync.Mutex// 启动多个 goroutine 并发写 map未加锁保护会引发 panicfor i : 0; i 10; i {wg.Add(1)go func(i int) {defer wg.Done()// 取消注释以下行查看未加锁保护的并发写操作// m[i] i// 使用互斥锁保护并发写操作mu.Lock()m[i] imu.Unlock()}(i)}wg.Wait()// 打印 map 内容mu.Lock()for k, v : range m {fmt.Printf(key: %d, value: %d\n, k, v)}mu.Unlock() }6. sync.Map和map加锁的区别 使用场景 sync.Map 适用于读多写少的并发场景简单且高效。使用 sync.Mutex 或 sync.RWMutex 保护普通 map 适用于需要复杂并发控制或写操作较多的场景。 性能 sync.Map 在读多写少的情况下性能优越但在写操作频繁时性能可能不如使用互斥锁保护的普通 map。使用 sync.Mutex 或 sync.RWMutex 可以在读写操作间提供更好的性能平衡尤其是在写操作较多时。 复杂性 sync.Map 封装了并发控制使用简单不需要手动加锁。使用 sync.Mutex 或 sync.RWMutex 需要手动加锁解锁代码相对复杂但更灵活。 方法支持 sync.Map 提供了一些特殊的方法如 LoadOrStore、Range方便特定场景下的使用。使用 sync.Mutex 或 sync.RWMutex 保护的普通 map 可以自由定义自己的方法更灵活但需要更多的代码。 最后给大家推荐一个LinuxC/C高级架构系统教程的学习资源与课程可以帮助你有方向、更细致地学习C/C后端开发具体内容请见 https://xxetb.xetslk.com/s/1o04uB
http://www.zqtcl.cn/news/886966/

相关文章:

  • 营业执照咋做网等网站遂宁网站建设公司哪家好
  • 湖南平台网站建设找哪家重庆网站建设营销
  • wordpress搭建企业网站小型网络架构
  • 淘宝联盟链接的网站怎么做培训网站排名
  • 上海高端网站建设定制大连开发区邮编
  • 手机网站公司免费crm软件下载
  • 家居企业网站建设平台周口seo
  • 扁平化网站建设公司广告推广方案
  • 高端企业网站 程序北京做网站费用
  • net做网站遇到的问题搜索引擎优化方法
  • 专业的设计网站有哪些网站数据库做好了 怎么做网页
  • 鄂州网站建设公司网站制作过程教程
  • 网站建设课程小结二建证考试需要什么条件
  • 比较好的商城网站设计品牌策划案
  • 自适应科技公司网站模板做网站的公司深
  • 网站怎么吸引流量用淘宝做公司网站
  • asp做的网站后台怎么进去老河口城乡建设局网站
  • 中铁建设集团有限公司官方网站wordpress质感
  • 那个网站点击率高pc网站自动生成app
  • 东莞营销型网站建站淘金企业网站建设
  • 怎么用模板做网站手机python编程软件
  • 做视频网站都需要什么软件下载广东网站建设哪家专业
  • 开淘宝的店铺网站怎么做网页设计需要学什么书
  • 如何做收费网站微信小程序开发教程详解
  • 软件下载网站如何履行安全管理义务网站合同书
  • 普宁17网站一起做淘宝网站建设 丽水
  • 网站注册需要多少钱wordpress缓存失败
  • 西安h5响应式网站施工企业安全生产管理规范最新版
  • 电商平台网站建设如何安装网站模版
  • wordpress攻击跳转seo营销软件