go面试

查看github

https://github.com/lifei6671/interview-go
https://github.com/lifei6671/interview-go/blob/master/base/go-scheduler-base.md

Golang中除了加Mutex锁以外还有哪些方式安全读写共享变量

Golang中Goroutine 可以通过 Channel 进行安全读写共享变量,还可以通过原子性操作进行.

无缓冲Chan的发送和接收是否同步

channel无缓冲时,发送阻塞直到数据被接收,接收阻塞直到读到数据。
channel有缓冲时,当缓冲满时发送阻塞,当缓冲空时接收阻塞

Golang并发机制以及它所使用的CSP并发模型.

在计算机科学中,通信顺序过程(communicating sequential processes,CSP)是一种描述并发系统中交互模式的正式语言,它是并发数学理论家族中的一个成员,被称为过程算法(process algebras),或者说过程计算(process calculate),是基于消息的通道传递的数学理论。

Goroutine 是Golang实际并发执行的实体,它底层是使用协程(coroutine)实现并发,coroutine是一种运行在用户态的用户线程,类似于greenthread,go底层选择使用coroutine的出发点是因为,

它具有以下特点:

  1. 用户空间 避免了内核态和用户态的切换导致的成本.
  2. 可以由语言和框架层进行调度.
  3. 更小的栈空间允许创建大量的实例.

Golang中的Goroutine的特性:

Golang内部有三个对象: P对象(processor) 代表上下文(或者可以认为是cpu),M(work thread)代表工作线程,G对象(goroutine).
https://github.com/lifei6671/interview-go/blob/master/base/go-gpm.md

协程和线程和进程的区别

进程
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。

线程
线程是进程的一个实体,线程是内核态,而且是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。

线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。

协程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。
协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。