Golang 常见面试题
Feb 26, 2022
Golang 常见面试题
Golang 中的 GPM 调度器是什么
很多人都听说过 golang 天然支持高并发,原因是因为其内部都 goroutine 加持,可以在一个进程里面启动陈成千上万的协程。
GPM 调度模型分别代表了三个角色:
- G,Goroutine,就是常用使用 go 关键字创建的执行体
- M,Machine,表示操作系统的线程
- P,Processor,表示处理器,有了它才能建立 G、M 之间的关系
GO 中的锁有哪些
- 互斥锁,sync.Mutex
- 读写锁,sync.RWMutex
- sync.Map ,sync.Map
go 中自带的 map 是线程不安全的,如果有多个协程同时修改 map 变量,就会出现异常。
sync.Map 是线程安全的
Go 中的 Chan 的发送和接受是否同步
ch := make(chan int) // 无缓冲,发送和接受同步
ch2 := make(chan int,2) // 有缓冲,缓冲大小为2,不要求发送和接受是同步的
- channel 如果没有缓冲,发送时会阻塞,直到数据被接受,接受数据时也会阻塞,直到数据被发送
- channel 如果有缓冲,当缓冲容量满了的时候,发送和接受都阻塞,当缓冲空闲时,接受是阻塞的
进程、线程、协程的区别是什么
- 进程
进程是系统进行资源分配和调度的一个独立的单位。
每个进程都有自己独立的空间,有自己的独立内存,所以上下文进程切换的开销也比较大,但相对比较安全。
- 线程
线程是进程的一个实体,线程是内核态,而且是 CPU 调度和分配的基本单位,线程基本自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可以与同一个进程的其他线程,共享进程的全部资源
- 协程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制,协程拥有自己的寄存器上下文和栈。
什么是 Channel,为什么它可以做到线程安全
Channel 是 go 中的一个核心类型,我把它看成一个管道,通过它并发核心单位就可以进行发送或者接受数据进行通信。
从一个数据发送到 channel、从 channel 中接受数据,都是原子性的。
go 的设计思想是,不要通过共享内存来通信,而是通过通信来共享内存,前者就是传统的加锁,后者就是 channel
也就是说,设计 channel 的主要目的,就是在多任务中传递数据,本身就是安全的