golang
文章平均质量分 53
SSSTing_
这个作者很懒,什么都没留下…
展开
-
Go 语言源码分析——map
哈希表用于存储键值对的映射关系,具有O(1)的读写性能。通过哈希函数可以将不同的键映射到不同索引上,当不同的键映射到同一个索引上时,huich原创 2021-06-14 13:52:20 · 280 阅读 · 0 评论 -
Go 语言源码分析——channel
Go 语言最常提及的设计模式就是:不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。许多主流编程语言中,多个线程传递数据defangshi原创 2021-06-13 13:03:04 · 244 阅读 · 0 评论 -
Go 缓存系列 ——go-cache源码分析
go-cache是基于内存的k/v缓存,类似于mencached,适用于单机应用程序。go-cache是线程安全的,支持并发地存取。虽然go-cache是保存在内存,但可以通过SaveFile()方法将缓存中的数据保存到文件。一、数据结构go-cache的逻辑代码主要是在cache.go文件中,首先来看它的数据结构// 整体缓存type Cache struct { *cache}type cache struct { defaultExpiration time.Durati.原创 2021-05-15 10:31:35 · 694 阅读 · 0 评论 -
Go 语言源码分析——slice 切片
Go的slice与数组类似,能够通过下标进行访问,越界访问时会报错。但slice比数组更加灵活,数组的大小是固定的,而slice可进行自动扩容。一、数据结构type slice struct { array unsafe.Pointer len int cap int}可以看到,slice底层包含了一个指向数组的指针,以及slice的长度和容量,可通过len()和cap()获取二、源码分析1. makeSlice首先看创建一个slicepackage m..原创 2021-04-28 22:41:00 · 162 阅读 · 0 评论 -
Go 字符串——遍历及切片
一、遍历go的遍历有以下两种方式,但是直接打印输出的为数字,与我们想要的结果不同。这是因为在Go里,字符串存储的是类型为byte的字节切片,而byte实际为uint8类型的值,即存储一个字符串时,存储的不是字符,而是字符对应的字节。那为什么两种遍历输出的数值不一样呢,接着往下看。func main() { str := "hello, 世界" fmt.Println("test 1-------") for i := 0; i < len(str); i++ { fmt.P原创 2021-04-17 19:44:57 · 1728 阅读 · 0 评论 -
Go 防缓存击穿 —— singleflight
缓存击穿:缓存在某个时间点过期时,突然在这个时间点出现对这个key的大量并发请求,此时缓存已过期,请求会直接落在DB上,使得DB瞬间请求量增大,压力骤增。singleflight能够在同一时间有大量针对同一key的请求这种情况,只让一个请求执行去获取数据,而其他协程阻塞等待结果的返回一、数据结构type Group struct { mu sync.Mutex // 互斥锁 m map[string]*call // 对于每一个要获取的key有一个对应的call}ty..原创 2021-04-17 16:10:04 · 206 阅读 · 0 评论 -
Go 标准库源码分析 - sync 包的Pool
Pool 实现了对象池的功能,能够保存和复用对象,减轻了垃圾回收的压力,提高了对象的复用率而不必每次都重新分配内存。一、数据结构type Pool struct { noCopy noCopy local unsafe.Pointer // 实际上是poolLocal类型的数组 localSize uintptr // local数组的大小 victim unsafe.Pointer // 存储的是上一个local里的数据,里面的对象随时可能会被回收,.原创 2021-04-03 18:33:06 · 130 阅读 · 0 评论 -
Go 标准库源码分析 - sync 包的 Map
Go 普通的map是线程不安全的,在并发读写时可能会出现脏数据;sync包中的Map是线程安全的,并发读写时无需额外加锁,适用于多读少写的情况。一、数据结构type Map struct { mu Mutex // 互斥锁,用于锁定dirty map read atomic.Value // 优先读map,支持原子操作 dirty map[interface{}]*entry // dirty是当前最新的map,支持读写 misses int // 记录read读不到数据而.原创 2021-04-01 23:46:28 · 229 阅读 · 1 评论 -
Go 标准库源码分析 - sync包的RWMutex
RWMutex 为读写锁,适用于读多写少的场景,可以同时有多个goroutine对临界区加读锁,此时写操作的goroutine被阻塞;同一时刻仅能有一个goroutine获得写锁,此时其他写操作和读操作的goroutine被阻塞。一、数据结构type RWMutex struct { w Mutex // 互斥锁 writerSem uint32 // 写信号量 readerSem uint32 // 读信号量 readerCount int32 // .原创 2021-03-29 23:11:15 · 126 阅读 · 0 评论 -
Go 标准库源码分析 - sync包的Mutex
在并发情况下会涉及到资源的互斥,Go通过Mutex互斥锁来保证临界资源的互斥访问一、Mutex的工作模式正常模式:在该模式下,等待的goroutine以FIFO顺序等待。被唤醒的goroutine不会直接拥有锁,而是与新请求锁的goroutine竞争,并且这些新goroutine由于已经在CPU中执行,并且可能有好几个,而在竞争中更具优势。在这种情况下,被唤醒的goroutine会被放进队头。当一个等待的goroutine超过1ms未获得锁,会转入饥饿模式。 饥饿模式:在该模式下,锁的所有...原创 2021-03-27 18:46:11 · 124 阅读 · 0 评论 -
Go 标准库源码分析 - sync 的 WaitGroup
WaitGroup常用于多个goroutine协作,主要功能是阻塞等待一组goroutine完成。一、数据结构type WaitGroup struct { noCopy noCopy state1 [3]uint32 // 用于存放任务计数器、等待者计数器和信号量}WaitGroup采用64位的值来保存计数器,其中高32位为任务计数器,低32位为等待者计数器,另外用32位的值保存信号量。WaitGroup在使用时需要64位的计数器进行原子操作,这要求计数器的地址是6...原创 2021-03-23 23:32:58 · 92 阅读 · 0 评论 -
Go标准库源码分析 - sync包的Once
Once能保证程序仅执行一次,与init相似,但init在文件包首次加载时执行,且执行一次;而Once在代码运行需要时执行,且只执行一次。一、数据结构type Once struct { done uint32 // 用于标记函数是否已执行 m Mutex // 并发控制}二、使用方法func (o *Once) Do(f func()) { if atomic.LoadUint32(&o.done) == 0 { o.doSlow..原创 2021-03-16 23:51:05 · 86 阅读 · 0 评论 -
Go 标准库源码分析 - sync包的cond
sync包的cond实现了一种条件变量,当共享的资源未准备好时,多个goroutine挂起等待,直到一个master goroutine通知事件发生。一、数据结构type Cond struct { noCopy noCopy // 实现了Locker接口,使得Cond对象在go vet扫描时能够检测出Cond对象是否被复制 L Locker // 实现了Locker接口,通常使用Mutex或RWMutex notify n.原创 2021-03-14 18:02:23 · 98 阅读 · 0 评论 -
Go 标准库 - context 源码解析
context 主要用来在goroutine 之间传递上下文信息,包括取消信号、超时时间、截止时间、k-v等。标准库的许多接口加上了 context 参数,来实现并发控制和超时控制。一、源码解析1. 接口(1)Contexttype Context interface { Deadline() (deadline time.Time, ok bool) Done() <-chan struct{} Err() error Value(key interface{}) i..原创 2021-01-09 19:37:17 · 167 阅读 · 0 评论