1. golang协程为什么比线程轻量?
1. go协程调用跟切换比线程效率高。
线程是内核对外提供的服务,应用程序可以通过系统调用让内核启动线程,由内核来负责线程调度和切换。线程在等待IO操作时线程变为unrunnable状态会触发上下文切换。现代操作系统一般都采用抢占式调度,上下文切换一般发生在时钟中断和系统调用返回前,调度器计算当前线程的时间片,如果需要切换就从运行队列中选出一个目标线程,保存当前线程的环境,并且恢复目标线程的运行环境,最典型的就是切换ESP指向目标线程内核堆栈,将EIP指向目标线程上次被调度出时的指令地址。
2. go协程占用内存少。
执行go协程只需要极少的栈内存(大概是4~5KB),默认情况下,而线程栈的大小为1MB。goroutine就是一段代码,一个函数入口,以及在堆上为其分配的一个堆栈。所以它非常廉价,我们可以很轻松的创建上万个goroutine,但它们并不是被操作系统所调度执行。
2. 数组与切片比较
数组:
1. 数组是具有固定长度的且拥有0个或者多个相同元素的数据类型。
2. 数组的长度是数组类型的一部分,比如[3]int 和 [4]int是两种不同类型的数组,可以通过内置函数len(array)来获取数组的长度。
3. 数组需要指定大小,如果不指定会根据初始化来自动推算出大小,在初始化之后不可改变,无法修改其长度。
4. 数组是值传递。
5. 数组是内置(build-in)类型,是一组同一类型数据的集合,它是值类型。
6. 和php等语言一样,go数组从0开始的下标索引来访问数组元素。
切片:
1. 切片表示一个拥有相同类型的可变长度的序列。它对底层的数组(内部是通过数组保存数据的)进行了抽象,并提供相关的操作方法。
2. 切片是一种轻量级的数据结构,它有三个属性:指针,长度,容量。这些属性是 Golang 需要操作底层数组的元数据:
切片数据结构的定义:
type slice struct { array unsafe.Pointer len int cap int }
上面结构体里的3 个字段分别是指向底层数组的指针、切片访问的元素的个数(即长度)和切片允许增长到的元素个数(即容量)。
3. 切片不需要指定大小。
4. 切片是地址传递。
5. 切片可以痛殴数组来初始化,也可以通过内置函数make()来初始化。初始化时候len = cap,在append等追加元素时候容量不够(cap不足)时候将len扩容2倍。