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

政府部网站建设网址和网站的区别

政府部网站建设,网址和网站的区别,沧州外贸网站建设,一手网推项目平台文章目录 Go中map使用以及注意事项map使用时的并发安全问题 Go中map使用以及注意事项 Go语言中map使用简单示例: func main() {var mp map[string]int// mp : map[string]int{}val, ok : mp["one"]if ok {fmt.Println(val)} else {fmt.Println(val)}mp[…

文章目录

  • Go中map使用以及注意事项
  • map使用时的并发安全问题

Go中map使用以及注意事项

Go语言中map使用简单示例:

func main() {var mp map[string]int// mp := map[string]int{}val, ok := mp["one"]if ok {fmt.Println(val)} else {fmt.Println(val)}mp["two"] = 10
}

思考一:Go语言的map的键类型为什么不能是函数类型、字典类型、切片类型

相信学习过其他语言比如Java语言的朋友对于Java中的HashMap都比较熟悉,对于所有键值对元素的数据结构来说,存储过程先计算key的哈希值,随后使用哈希值定位到对应的bucket,将key和value作为元素存储到对应的bucket中。在这个过程中可能会发生哈希碰撞,在Java中对于哈希碰撞常见的解决方案有拉链法,由于哈希碰撞的存在对于哈希表的键的要求,不仅仅能够计算哈希值,同时能够对键进行判等操作(解决哈希碰撞时key重复的问题)。对于Go语言的map的实现仍然如此,需要考虑到哈希碰撞的出现,所以就要求key必须能够进行判等操作
如果go的map的键为上述三种类型,在运行时就会发生panic。

思考二:Go语言中应该优先考虑那些类型作为map的键的类型

只从性能的角度出发,而不考虑上下文时:在map中比较耗时的操作主要出现在连个地方:

  • 把键值转换为哈希值
  • 把要查找的键值与哈希桶中的键值做对比

对于所有的基本类型、指针类型,以及数组类型、结构体类型和接口类型,Go 语言都有一套算法与之对应。这套算法中就包含了哈希和判等

  • 以求哈希的操作为例,宽度越小的类型速度通常越快。对于布尔类型、整数类型、浮点数类型、复数类型和指针类型来说都是如此。对于字符串类型,由于它的宽度是不定的,所以要看它的值的具体长度,长度越短求哈希越快。
  • 类型的宽度是指它的单个值需要占用的字节数。比如,bool、int8和uint8类型的一个值需要占用的字节数都是1,因此这些类型的宽度就都是1。
  • 高级类型如:数组类型的值求哈希实际上是依次求得它的每个元素的哈希值并进行合并,所以速度就取决于它的元素类型以及它的长度。细则同上。
  • 结构体类型:哈希实际上就是对它的所有字段值求哈希并进行合并,关键在于它的各个字段的类型以及字段的数量。

优先选用数值类型和指针类型,通常情况下类型的宽度越小越好。如果非要选择字符串类型的话,最好对键值的长度进行额外的约束。

map使用时的并发安全问题

考虑如下代码:

func main() {m := map[int]string{1: "haha",}go read(m)time.Sleep(time.Second)go write(m)time.Sleep(30 * time.Second)fmt.Println(m)
}
func read(m map[int]string) {for {_ = m[1]time.Sleep(1)}
}
func write(m map[int]string) {for {m[1] = "write"time.Sleep(1)}
}

开启两个协程并发对map进行读写操作,上述代码运行直接报如下错误:

goroutine 6 [running]:
main.read(0x0?)/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:20 +0x2d
created by main.main/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:12 +0xa5goroutine 1 [sleep]:
time.Sleep(0x6fc23ac00)/usr/local/go/src/runtime/time.go:195 +0x135
main.main()/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:15 +0xfbgoroutine 7 [sleep]:
time.Sleep(0x1)/usr/local/go/src/runtime/time.go:195 +0x135
main.write(0x0?)/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:27 +0x25
created by main.main/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:14 +0xecProcess finished with the exit code 2

对于map的读写是非原子性操作,存在资源竞争,不是现成安全的,可以使用如下命令检测:

go run race ...

为了将非并发安全的读取操作更改为并发安全的,可以引入sync.Mutex,在读、写操作前进行加锁操作;操作后进行解锁,保证并发安全。

func main() {m := map[int]string{1: "haha",}var mutex sync.Mutex // 创建一个互斥锁// 启动读协程go read(m, &mutex)// 等待一秒钟,确保读协程已经开始运行time.Sleep(time.Second)// 启动写协程go write(m, &mutex)// 等待足够长的时间,以便读写协程可以运行time.Sleep(30 * time.Second)// 打印最终的mapfmt.Println(m)
}func read(m map[int]string, mutex *sync.Mutex) {for {mutex.Lock() // 在读取之前加锁value := m[1]mutex.Unlock() // 读取完毕后解锁fmt.Println("Read:", value)time.Sleep(1 * time.Second)}
}func write(m map[int]string, mutex *sync.Mutex) {for {mutex.Lock() // 在写入之前加锁m[1] = "write"mutex.Unlock() // 写入完毕后解锁fmt.Println("Write:", m[1])time.Sleep(1 * time.Second)}
}

后续会将sync.Mutex的底层原理进行总结展示。

http://www.tj-hxxt.cn/news/92045.html

相关文章:

  • 餐饮众筹模板网站建设百度sem运营
  • 便民信息发布平台江西seo推广方案
  • 软件开发外包网站搜外网 seo教程
  • 企业网站的建设的功能定位新开网店自己如何推广
  • 建站之星怎么用链接提交工具
  • 茶叶网站flash模板网址和网站的区别
  • 云南7省建设厅网站seo短视频网页入口引流免费
  • 网站建设ps模板百度指数的网址是什么
  • 我自己做的一个网站显示证书错误百度的seo关键词优化怎么弄
  • 用电脑做网站的历史在哪里找个人免费网站申请注册
  • 书店网站建设定位及目标seo推广外包报价表
  • 网站视频插件代码自己做网站如何赚钱
  • asp 公司网站源码自动外链工具
  • 江苏专业做网站的公司哪家好百度首页广告多少钱
  • 团购网站seo外链交易平台
  • 深圳做网站好的公司提高工作效率图片
  • 网站前后端用什么软件做站长之家ip查询
  • 深圳罗湖网站制作公司哪家好免费发帖平台
  • 龙岩做网站开发大概价格邯郸网站优化
  • 男女做暖网站是什么网页设计与制作学什么
  • 毕业室内设计代做网站新泰网站seo
  • 系统开发北京网站建设公众号seo排名
  • 还有哪些网站做产品众筹青岛seo杭州厂商
  • 域名刚到期就被跳转到其他网站seo文章关键词怎么优化
  • 国外自适应网站模版营销推广网站
  • 郑州做网站找哪家好产品推广找哪家公司
  • 网站设计内容清单广东东莞大益队
  • 邢台做网站可信赖企业类网站有哪些例子
  • 设计说明模版大连seo建站
  • 万网网站后台登陆安徽网站推广