补充反馈
slice
既然聊到slice,就不得不提它的近亲array,这里不太想提值类型和引用类型的概念(个人觉得其实都是值类型),golang的array其实可以假想为C的struct类型,只是struct通过变量名来访问成员(如xxx.yyy),而array通过下标来访问成员(如xxx[3]),具体内存布局如下图所示:
图 1 golang的array内存布局
显然golang的array灵活性比较差,长度固定,这才有了slice,概念上有点类似于STL的vector,但是具体实现上还是有差距的,具体内存布局如下图所示:
图 2 golang的slice内存布局
slice类型存在len和cap的概念(与vector类似),这里有一点需要澄清:与vector不一样,slice的len并不能无限增长,cap就是它的天花板。比如s := make([]byte, 3, 5),后续不管s如何增长,它的len也不能超过5。
s:= make([]byte, 5)
s= s[2:4]
图 3 s[2:4]内存布局
从上图不难看出,其实slice操作并没有任何内存拷贝动作,仅仅是生成一份新的描述数据(len=2 cap=3);此时,如果执行s = s[:cap(s)],可以将s的len扩张到最大,如下图所示:
图 4 s[:cap(s)]内存布局
在golang里面,如果slice需要扩张到超出cap,只能创建新的slice,然后将现有数据copy过去,再指向新的slice,一般可以借助内置的append函数。
顺带一提,由于slice操作之后,新的对象存在指针指向真实的数据块内存,所以某些场景下,可能会导致大块内存无法被GC回收。
performance
不少tx都提到了深深的性能担忧,其实我本来并不喜欢过于纠结性能问题,毕竟追求极致的单机性能往往意义不大,不过既然提到了,我也上网找了点数据,供有兴趣的读者参考:

本文探讨了Golang在后台开发中的应用,尤其是其并发特性(goroutine)和通信机制(channel)。通过对比C、Java和PHP的性能,展示了Golang的优势。文章还分析了Golang中的slice内存布局,并指出在处理并发场景时,Golang推荐使用消息传递模型(goroutine + channel)来避免共享内存问题。
最低0.47元/天 解锁文章
1204

被折叠的 条评论
为什么被折叠?



