go接口
- go语言是谷歌开发的一种编程语言
- 它具有内置的垃圾回收机制
- 支持高并发
- 代码可以编译成单个可执行的二进制文件,不需要运行时环境
go泛型所有接口的父接口是一个空类,interface{}替代任意类型
go引用类型go1.7之前的go泛型实现是使用interface{}替代任意类型,需要使用swich做类型断言判断。1.7之后引入了类似java语言的泛型概念,这种反省概念就是模板
,在程序运行时需要copy一份模板生成对应类型的方法并写入内存中,故泛型系统程序运行时复杂性提升。
切片和数组的显著区别切片、map(字典)、channel(管道),接口,指针 这五种在go中是引用类型,其余类型为值类型。引用类型的引用存在内存栈中,值存在堆内存中。go垃圾回收器GC回收的是堆内存中没有引用的空间。也就是说引用类型若要回收时只需要将引用指向nil即可。
在变量传递(函数传参)时,值类型数据是拷贝专递。引用类型是地址传递,在函数传参时,如果是值传递,修改被传递的参数不会影响原有变量,如果是引用传递,函数内部修改会影响外界。
go语言中的列表和字典切片是一个引用类型,数组是一个值类型。数组一旦创建大小是固定的。切片底层也是数据,切片在运行时可以动态增加大小。切片是可以动态双倍扩容的,使用的是数组内置的添加,复制功能。
切片的方法
len() 返回切片中元素的个数
cap() 返回切片的容量
go select
- 列表:list.List ; 声明: var name list.List or name := list.List。列表的底层数据结构是双向链表。
- 字典: map,提供映射关系的容器,其内部是通过散列表实现的
一个协程如何等其余协程执行完成之后再执行select 可以随机选择一条channel没有读写阻塞的case执行。实际上就是找到没有阻塞的channel。
死锁等待组:sync.WaitGroup。在等待预设数量的协程都执行并且结束后,才会向下执行。
waitGroup.add(5) //设置执行的协程数
waitGroup.Done()//一个协程执行完成后减一的动作
waitGroup.wait()//等待协程等待
另一种办法:给一个共用参数(切片)等待携程看这个共用参数信号确定是否执行
go的channel有缓冲和没缓冲的区别死锁:主协程被阻塞
避免方式:
- 不能单个协程自读自写一个没有缓冲能力的channel
- A协程要求B协程先写入自己在读出,B协程要求A协程先读出自己再写入。此时AB死锁
- 在range channel 时,要注意channel的写入关闭,如果不关闭管道,range channel 就永远阻塞
go为啥可以高并发
- 有缓冲的管道:即使没有写入,也能读出若干默认值。即使没有读出,也能写入若干值。
- 无缓冲的管道:只要没有协程写入就读出阻塞。没有协程读出,就写入阻塞。
G-M-P模型
当一个线程运行在某一个cpu的核上,这个线程下可能会有很多个协程(微协程),当前有其中一个协程处于运行状态,其余的在协程队列中排队等待。
实际M(物理线程)之间的调度是在操作系统上完成的,效率低下。go则是一个M(物理态线程)下挂有一个逻辑态的协程队列,其调度是逻辑调度,不在操作系统层面调度。则效率高。



