go使用踩过什么坑(for range,数据库连接defer close)
1.select是随机的还是顺序的?select的使用场景?
select会随机选择一个可用通道做收发操作.
常用语gorotine的完美退出
golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作
每个case语句里必须是一个IO操作,确切的说,应该是一个面向channel的IO操作
2.Go语言局部变量分配在栈还是堆?深入分析
Go语言编译器会自动决定把一个变量放在栈还是放在堆.
编译器会做逃逸分析,当发现变量的作用域没有跑出函数范围,就可以在栈上,反之则必须分配在堆。
3.简述一下你对Go垃圾回收机制的理解?golang GC
v1.1 STW
v1.3 Mark STW, Sweep 并行
v1.5 三色标记法【白色--> 灰色待处理队列--> 标记为黑色--> STW(sweep黑色)】
v1.8 hybrid write barrier(混合写屏障:优化STW)
4.简述一下golang的协程调度原理?
M(machine): 代表着真正的执行计算资源,可以认为它就是os thread(系统线程)。
P(processor): 表示逻辑processor,是线程M的执行的上下文。
G(goroutine): 调度系统的最基本单位goroutine,存储了goroutine的执行stack信息、goroutine状态以及goroutine的任务函数等。
5.介绍下 golang 的 runtime 机制?深入分析
Runtime 负责管理任务调度,垃圾收集及运行环境。同时,Go提供了一些高级的功能,如goroutine, channel, 以及GG。
这些高级功能需要一个runtime的支持. runtime和用户编译后的代码被linker静态链接起来,形成一个可执行文件。
这个文件从操作系统角度来说是一个user space的独立的可执行文件。
从运行的角度来说,这个文件由2部分组成,一部分是用户的代码,另一部分就是runtime。
runtime通过接口函数调用来管理goroutine, channel及其他一些高级的功能。从用户代码发起的调用操作系统API的调用都会被runtime拦截并处理。
Go runtime的一个重要的组成部分是goroutine scheduler。他负责追踪,调度每个goroutine运行,实际上是从应用程序的process所属的thread pool中分配一个thread来执行这个goroutine。
因此,和java虚拟机中的Java thread和OS thread映射概念类似,每个goroutine只有分配到一个OS thread才能运行。
6.如何获取 go 程序运行时的协程数量, gc时间, 对象数, 堆栈信息?
调用接口runtime.ReadMemStats可以获取以上所有信息, 注意: 调用此接口会触发 STW(Stop The World)
7.介绍下你平时都是怎么调试 golang 的 bug 以及性能问题的?
panic 调用栈
pprof
火焰图(配合压测)
使用go run -race 或者 go build -race 来进行竞争检测
查看系统 磁盘IO/网络IO/内存占用/CPU 占用(配合压测)
8.简单介绍下 golang 中 make 和 new 的区别
new(T)是为一个T类型的新值分配空间, 并将此空间初始化为T的零值, 并返回这块内存空间的地址, 也就是T类型的指针T, 该指针指向T类型值占用的那块内存.
make(T)返回的是初始化之后的T, 且只能用于slice, map, channel三种类型. make(T, args) 返回初始化之后T类型的值, 且此新值并不是T类型的零值, 也不是T类型的指针T, 而是T类型值经过初始化之后的引用.
context包的用途
Context通常被译作上下文,它是一个比较抽象的概念,其本质,是【上下上下】存在上下层的传递,上会把内容传递给下。在Go语言中,程序单元也就指的是Goroutine
主协程如何等其余协程完再操作
使用channel进行通信,context,select
map如何顺序读取
map不能顺序读取,是因为他是无序的,想要有序读取,首先的解决的问题就是,把key变为有序,所以可以把key放入切片,对切片进行排序,遍历切片,通过key取值。
实现set
type inter interface{}
type Set struct {
m map[inter]bool
sync.RWMutex
}
func New() *Set {
return &Set{
m: map[inter]bool{},
}
}
func (s *Set) Add(item inter) {
s.Lock()
defer s.Unlock()
s.m[item] = true
}
25、Slice与数组区别,Slice底层结构
28、Go的反射包怎么找到对应的方法(这里忘记怎么问的,直接说不会,只用了DeepEqual,简单讲了DeepEqual)
55、goroutine调度用了什么系统调用,这个不会,面试官想从go问到操作系统,然后以为*作系统基础不好,就问了操作系统问题
72、 goroutine泄漏有没有处理,设置timeout,select加定时器
77、go的线程,给他讲了跟goroutine调度
95、go的值传递和引用
108、go的锁如何实现,用了什么cpu指令
109、go的runtime如何实现
112、go什么情况下会发生内存泄漏?(他说ctx没有cancel的时候,这个真不知道)
116、用channel实现定时器?(实际上是两个协程同步)
117、go为什么高并发好?讲了go的调度模型
有疑问加站长微信联系(非本文作者)