内存对齐这个事儿只能自己搞明白
高速公路VS内存图1. 可以把内存比作汽车高速公路
图2.
123456789101112131415161718192021package mainimport ( "fmt" "unsafe")type Salary struct { s1 int8 s2 int16}type Salary2 struct { s1 int16 s2 int16}func main() { fmt.Println(unsafe.Sizeof(Salary{})) fmt.Println(unsafe.Sizeof(Salary2{}))}
输出
44
我们可以看到2个struct,size都是4, 2个结构体字段大小不同,但是结构体大小一样。
内存对齐
可以看到第2个int32跨了2个64位的边界,如果你是64位系统,那么CPU每次访问内存,都是拿64位这么多的数据,对于第2个int32跨越2个64位,那么cp ...
紧急下班:修炼内功---内存模型和垃圾回收,不焦虑打工指南
硬件到软件
Go语言每次申请64MB的虚拟内存,称为heapArena
最多可以有2的20次幂个
Go语言mheap内存是由许多heapArena组成
Runtime/mheap.go
123456789101112131415161718192021type heapArena struct { bitmap [heapArenaBitmapBytes]byte spans [pagesPerArena]*mspan pageInUse [pagesPerArena / 8]uint8 pageMarks [pagesPerArena / 8]uint8 pageSpecials [pagesPerArena / 8]uint8 checkmarks *checkmarksMap zeroedBase uintptr}type mheap struct { ... arenas [1 << arenaL1Bits]*[1 << arenaL2Bits]*heapAr ...
Channel,这次换个学法
Channel,这次换个学法12345c := make(chan string)c<-"面向加薪学习"<-c c := make(chan string,10)
1行 新建无缓冲通道
2行 向通道里输入数据
3行 从通道里拿出数据
5行 新建有缓冲通道
有缓冲通道类似快递柜,只要有空间,别人就可以投递,而无缓冲通道则只能双方都在场的情况下,才能让数据成功收发。
下面看一下通道的源代码runtime/chan.go
12345678910111213type hchan struct { qcount uint // total data in the queue dataqsiz uint // size of the circular queue buf unsafe.Pointer // points to an array of dataqsiz elements elemsize uint16 closed uint32 elem ...
学完锁的全部内容,停止你的精神内耗
不使用锁的问题运行下面的代码,你会发现结果x,每次可能都不一样,有时候是正确结果,有时候是错误的。
123456789101112131415161718192021package mainimport ( "fmt" "sync")func main() { x := 0 num := 1000 var wg sync.WaitGroup wg.Add(num) for i := 0; i < num; i++ { go func() { x = x + 1 wg.Done() }() } wg.Wait() fmt.Println(x)}
这里导致问题的原因就是多个协程共同对x赋值操作。
下面我们对他进行改造
1234567891011121314func main() { var x int32 num := 1000 ...
认知觉醒-学习Go语言协程的方法论
认知觉醒-学习Go语言协程的方法论进程
对于注册/注销一家公司,需要的手续和资料是很复杂的,那么这里我们把公司类比计算机中的进程。
线程
每个公司都有各个部门,那么每个部门都可以共享公司的资源,如图中的会议室和茶水间。每个部门类似计算集中的线程。计算机中进程是开辟了一段内存空间,让程序在上面运行应用,而线程会占用一部分内存,线程之间的内存是共享的,他会占据cpu,这里可以假定cpu是老板。
每个部门都要做事,最后都要老板来敲定最后的方案。那线程也一样,每个线程都少不了运行程序代码,假定我们只有一颗cpu,那么每个线程都需要这个cpu,cpu每次执行一小段时间,就要切换出去,执行下一个线程,当然,每个线程也要保持cpu的执行现场,以便下次再次执行到自己的时候,从哪里开始执行,就这样,最终全部线程执行完毕,看起来计算机好像同时在执行多个任务。所以,线程占用资源大,开销大,切换开销大。
协程
同样还是这张图,老板只有1个,但是每次参加各个部门的会议,老板不再记录中间的会议纪要,由各个部门自己记录,在计算机中,我们用1个线程和1颗cpu,去让各个协程轮流执行,但是每个协程自己记录程 ...
真希望你也明白runtime.Map和sync.Map
Map 官方介绍One of the most useful data structures in computer science is the hash table. Many hash table implementations exist with varying properties, but in general they offer fast lookups, adds, and deletes. Go provides a built-in map type that implements a hash table.哈希表是计算机中最有用的数据结构之一。提供快速查找、添加和删除。 Go 提供了一个实现哈希表的内置Map类型。
Hash冲突那对于Hash的一个最重要的问题,就是hash冲突。下面我们看一下常用的解决方案。
开放寻址法开放寻址法想象成一个停车问题。若当前车位已经有车,则继续往前开,直到找到一个空的停车位。
上图,每个方格子,就是一个车位,当一辆车来的时候,会依次查询是否有空位,如果没有,则继续向后面找,如果发现空位置,就会停到空位置中。
下面看一下,我们 ...
底层逻辑-理解Go语言的本质
1.Java VS Go语言Java,从源代码到编译成可运行的代码
上图已经展示了这个过程:从Java的源代码编译成jar包或war包(字节码),最终运行在JVM中。
我们把Java源代码编译后的jar包或war包看成是工程师生产出来的产品,操作系统是一个平台,JVM就是中间商,那程序的整体性能也要受到中间商JVM的因素影响了。
优点:一次编译,到处运行(windows、linux、macos)
缺点:JVM性能损失大。
Go语言,从源代码到编译成可运行的代码
我们把Go语言的源代码编译后,生成二进制文件,直接就可以在操作系统上运行,没有中间商。
优点:
直接编译成二进制
无需进行虚拟机环境,自动执行
一次编写代码,跨平台执行
高性能并发能力
2.为什么Go语言运行-“没有中间商”每种编程语言都有自己的Runtime, 把这个单词拆开来看,Run=运行,Time=时间,简称:运行时。
Go语言的Runtime作用:
内存管理
协程调度
垃圾回收
Go语言的运行时,是和源代码最终编译生成到二进制文件中的。当我们启动二进制文件的时候,运行时也就是一并 ...
能力进阶-如何成为Go语言微服务架构师
《能力进阶——如何成为 Go 语言微服务架构师》 Go 语言是一个出身名门,由谷歌公司开发的,非常优秀的后端编程语言。它有谷歌公司的加持,天生支持高性能,高并发,上手容易。正因如此,受到市场热捧,令更多工程师愿意投身其中,实现自己的价值。
技术领域对人才的需求通常都是 高级> 中级 > 初级,要想得到更高的职位和薪水,我们就要向高级阶段努力。
很多想成为 Go 语言高级工程师或架构师的小伙伴,一般会有如下顾虑:
产品需求多如牛毛,时间紧张,程序设计不足,代码不规范,写的程序代码僵化、无法扩展和维护;
不懂运行机制,不知如何提升,不能解决复杂问题,甚至在线上出问题时束手无策;
日常工作只是开发,不知如何从上层角度思考系统架构和技术选型;
没有系统学习过微服务、分布式的实战经验,缺乏学习路径。
以上问题若能逐一击破,就会让自己变得更强。
下面是我总结的几点建议,希望能给你带来一些启发。
如果你还在犹豫是否要进阶高级工程师或架构师,那就尽快去系统学习一下 Go 语言微服务。这样方能快速成长,以 ...
区块链原理
区块链原理图1.
图2.
图3.
图4.
图5.
图6.
图7.
图8.
图9.
Web3.0如何入门
添加微信
公众号更多内容
Web3进化史
Web3进化史Web3百科统一的身份认证 + 数据确权和授权图1.
图2.
图3.
图4.
图5.
Web3.0如何入门
添加微信
公众号更多内容