Channel是Go语言中用于协程之间通信的重要机制。它的底层实现原理相对简单,通过分析源码可以更好地理解其工作原理。
gotype hchan struct {
//channel分为无缓冲和有缓冲两种。
//对于有缓冲的channel存储数据,借助的是如下循环数组的结构
qcount uint // 循环数组中的元素数量
dataqsiz uint // 循环数组的长度
buf unsafe.Pointer // 指向底层循环数组的指针
elemsize uint16 //能够收发元素的大小
closed uint32 //channel是否关闭的标志
elemtype *_type //channel中的元素类型
//有缓冲channel内的缓冲数组会被作为一个“环型”来使用。
//当下标超过数组容量后会回到第一个位置,所以需要有两个字段记录当前读和写的下标位置
sendx uint // 下一次发送数据的下标位置
recvx uint // 下一次读取数据的下标位置
//当循环数组中没有数据时,收到了接收请求,那么接收数据的变量地址将会写入读等待队列
//当循环数组中数据已满时,收到了发送请求,那么发送数据的变量地址将写入写等待队列
recvq waitq // 读等待队列
sendq waitq // 写等待队列
lock mutex //互斥锁,保证读写channel时不存在并发竞争问题
}

JVM的预热是指在应用启动之初,为了保障第一次请求的快速响应,采取特定的策略来处理第一次的预加载逻辑。这是因为JVM的懒加载和JIT(即时编译)机制会导致第一次调用的耗时较长。
JVM进程启动时,ClassLoader会将需要的所有类加载到内存。ClassLoader主要分为以下三步: