《GO语言实战》语言学习笔记
- go语言编写的包易于分享,代码复用,多核利用,并发模型,编译器,类型,并发,通道,测试。
- 内置并发机制
- 快速的编译构建
- 自带垃圾回收
- 简单的语法和类型
- go语言只会关心直接依赖的库(什么是关心哈?)
- go没有类型安全保护机制,需要用go vet测试来确保不会出现类型错误
- goroutine协程比线程占用更少的内存
- 协程使用一个内置数据结构channel进行同步通信,通信的消息是具有类型的。
- 一个线程可以执行多个协程
- 通道并不提供跨 goroutine 的数据访问保护机制。
- go不用继承而采用组合,对于模型的抽象采用接口,不需要接口声明。
- go的类和struct很相似
- 不需要声明接口是因为运行时会根据实现的方法来自动检测类的实现的接口,这个特点叫做鸭子类型(怎么解决二义性问题)。
- go为了方便组合,所有接口都采用轻量设计(不设计包含很多方法的接口)
- play.golang.org试用go.
- go有基于web和基于网络的标准库
- 所有变量会被默认初始化为0值,比如指针的0值就是nil,字符串的0值就是空串。
- go也有函数式编程的匿名函数,但却是静态类型的语言
- go可以返回切片实现返回多个值,不同类型的值可以放在一个切片里(切片是一种特殊数组)
- waitGroup相当于CycleBarrier
- struct可以声明json的映射关系。
- defer可以定义finally动作。
- struct内部没有方法,需要在外部定义方法的时候约束方法的调用者或者说方法的接收者。
- go语言有传值和传引用的区别。
- chan的定义有点类似范型需要指定传输的数据结构
- 每个包都有单独的目录,不能把多个包放在一个目录下。
- 不能把一个包的文件拆分到不同目录中。
- 一个目录下的go文件只能用一个包名,所以包名通常是目录名。
- main都会有一个main()作为程序入口
- godoc可以查看文档
- 如果导入路径包含域名,那么程序会使用go get获取包
- 每个包可以有多个init函数,并且会在main之前执行
- go vet可以检测类型编译是否有错误
- go fmt可以格式化代码
- godep 依赖版本管理工具
- gb 版本依赖更优雅,工程上src是本地代码,vender是第三方代码。gb修改了go工具链的元信息,使得用户可以不需要修改源码的情况下实现依赖版本控制。
- gb与go默认工具链,如go get等不兼容。
- 数组是切片和map的底层数据结构
- go数组跟c语言的数组一样
- go语言有指针类型,对数组的传递如果采用值传递会copy内存,所以通常采用指针传递。
- go语言的切片有容量和长度的概念,长度是逻辑上的,容量是数组的物理内存大小。
array := [3]int{10, 20, 30}
- 切片指针到可以寻址的长度为容量。如下:
![go语言实战-切片共享数组.png](https://i-blog.csdnimg.cn/blog_migrate/da20405ae30e292aeb248e17b98c68ba.png)
- append如果能够插入就会修改原来的底层数组,如果不行就会创建新的数组,并扩容100%,如果输了打到1000,则扩容因子会变成25%。
- append可能会造成切片共享底层数组,为了不让其共享底层数组可以采用append进行copy并扩容。只需要将切片的长度做限制就可以了,可以通过原数组[begin:end(不包含):size-end(不包含)]第3个参数和第二个参数一样就可以了。
- range会创建副本。
- map底层采用哈希值的低8位和高8位实现桶分段算法。
- map只有引用传递,没有值传递
- go是一种静态类型的语言
- go的继承采用组合,封装采用struct,多态采用接口的调用者约束实现。
- 包内成员默认是私有的,而方法默认是共有的,所以可以通过工厂模式实现开放封闭原则。
- go类型分为内置类型,引用类型,结构类型。
- Go 语言的并发同步模型来自一个叫作通信顺序进程(Communicating Sequential Processes,CSP) 的范型(paradigm)。CSP 是一种消息传递模型,通过在 goroutine 之间传递数据来传递消息,而不是 对数据进行加锁来实现同步访问。
- 物理处理器CPU只会隶属于某一个逻辑处理器,每一个逻辑处理器只会和一个Thread绑定。相当于每个Thread拥有多个物理CPU,但只拥有一个逻辑CPU,而且是用完就马上解绑的。一个协程隶属一个线程。
- 协程阻塞时线程会与逻辑处理器解绑。
- 线程和物理CPU时物理概念,而协程和逻辑处理器时逻辑概念。
- go提高了原则函数来保证原子操作,类似java CAS。以及采用了mutex来实现临界区。
- 无缓存通道类似synctronizedQueue只有一个空间的阻塞队列。
- 带缓存的通道类似listedblockedqueue。
- work类似cachedThreadExecutedPool,内存采用无缓存的通道和协程工作。
- pool类似fixedThreadExecutedPool,会有执行延迟。
- runner类似调度线程池。采用优先级队列和懒定时计数器实现定时任务。
- 单元测试用go test