2021-02-22


本文摘自网络,作者,侵删。

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的调度模型


本文来自:简书

感谢作者:voidFan

查看原文:2021-02-22

相关阅读 >>

Go语言的依赖管理

test

Go实战--使用Golang开发windows gui桌面程序(lxn/walk)

tools easily execute sql against structured text like csv or tsv

Golang 协程+channel+select 实现最简单的斐波那契数列

手撸Golang 行为型设计模式 责任链模式

devops ci/cd 分析(四)之编写k8s yaml模版

优雅的实现 Golang rest api 架构

手撸Golang 架构设计原则 里氏替换原则

Golang 创建型设计模式 抽象工厂

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...