Golang面试前一夜准备:6-10题

火山方舟向量数据库大模型

picture.image

Golang面试前一夜准备
题号题目
6协程和线程和进程的区别
7Golang的内存模型中为什么小对象多了会造成GC压力
8Go中数据竞争问题怎么解决
9什么是channel,为什么它可以做到线程安全
10Golang垃圾回收算法
  1. 协程和线程和进程的区别

  • 进程

进程是程序的一次执行过程,是程序在执行过程中的分配和管理资源的基本单位,每个进程都有自己的地址空间,进程是系统进行资源分配和调度的一个独立单位。

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

  • 线程

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

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

  • 协程

协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。

协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

  1. Golang的内存模型中为什么小对象多了会造成GC压力

通常小对象过多会导致GC三色法消耗过多的CPU。优化思路是,减少对象分配(内存分配请看往期文章).

  1. Go中数据竞争问题怎么解决

Data Race问题可以使用互斥锁sync.Mutex, 或者也可以通过CAS无锁并发解决.

其中使用同步访问共享数据或者CAS无锁并发是处理数据竞争的一种有效的方法.

golang在1.1之后引入了竞争检测机制,可以使用 go run -race 或者 go build -race来进行静态检测。

其在内部的实现是,开启多个协程执行同一个命令, 并且记录下每个变量的状态.

竞争检测器基于C/C++的ThreadSanitizer运行时库,该库在Google内部代码基地和Chromium找到许多错误。这个技术在2012年九月集成到Go中,从那时开始,它已经在标准库中检测到42个竞争条件。现在,它已经是我们持续构建过程的一部分,当竞争条件出现时,它会继续捕捉到这些错误。

竞争检测器已经完全集成到Go工具链中,仅仅添加-race标志到命令行就使用了检测器。

  
$ go test -race mypkg    // 测试包  
$ go run -race mysrc.go  // 编译和运行程序  
$ go build -race mycmd   // 构建程序  
$ go install -race mypkg // 安装程序  

要想解决数据竞争的问题可以使用互斥锁sync.Mutex,解决数据竞争(Data race),也可以使用管道解决,使用管道的效率要比互斥锁高.

  1. 什么是channel,为什么它可以做到线程安全

Channel是Go中的一个核心类型,可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication),Channel也可以理解是一个先进先出的队列,通过管道进行通信。

Golang的Channel,发送一个数据到Channel和从Channel接收一个数据都是原子性的。

Go的设计思想就是, 不要通过共享内存来通信,而是通过通信来共享内存,前者就是传统的加锁,后者就是Channel。

也就是说,设计Channel的主要目的就是在多任务间传递数据的,本身就是安全的。

  1. Golang垃圾回收算法

Golang 1.5后,采取的是“非分代的、非移动的、并发的、三色的”标记清除垃圾回收算法。

golang 中的 gc 基本上是标记清除的过程:picture.imagegolang 的垃圾回收是基于标记清扫算法,这种算法需要进行 STW(stop the world),这个过程就会导致程序是卡顿的,频繁的 GC 会严重影响程序性能.

golang 在此基础上进行了改进,通过三色标记清扫法与写屏障来减少 STW 的时间.

gc的过程一共分为四个阶段:

  1. 栈扫描(开始时STW),所有对象最开始都是白色.
  2. 从 root开始找到所有可达对象(所有可以找到的对象),标记为灰色,放入待处理队列。
  3. 遍历灰色对象队列,将其引用对象标记为灰色放入待处理队列,自身标记为黑色。
  4. 清除(并发) 循环步骤3直到灰色队列为空为止,此时所有引用对象都被标记为黑色,所有不可达的对象依然为白色,白色的就是需要进行回收的对象。三色标记法相对于普通标记清扫,减少了 STW 时间. 这主要得益于标记过程是 "on-the-fly" 的,在标记过程中是不需要 STW 的,它与程序是并发执行的,这就大大缩短了STW的时间.

Golang gc 优化的核心就是尽量使得 STW(Stop The World) 的时间越来越短。

更加详细的GC我会在后面单独章节拿出来讲解(源码+图解),为了应付面试这些就足够了。

写屏障:

“ 当标记和程序是并发执行的,这就会造成一个问题. 在标记过程中,有新的引用产生,可能会导致误清扫.

“ 清扫开始前,标记为黑色的对象引用了一个新申请的对象,它肯定是白色的,而黑色对象不会被再次扫描,那么这个白色对象无法被扫描变成灰色、黑色,它就会最终被清扫,而实际它不应该被清扫.

“ 这就需要用到屏障技术,golang采用了写屏障,其作用就是为了避免这类误清扫问题. 写屏障即在内存写操作前,维护一个约束,从而确保清扫开始前,黑色的对象不能引用白色对象.

GC的触发条件:

Go中对 GC 的触发时机存在两种形式:

  1. 主动触发(手动触发),通过调用runtime.GC 来触发GC,此调用阻塞式地等待当前GC运行完毕.
  2. 被动触发,分为两种方式:a. 使用系统监控,当超过两分钟没有产生任何GC时,强制触发 GC. b. 使用步调(Pacing)算法,其核心思想是控制内存增长的比例,当前内存分配达到一定比例则触发.
0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
如何利用云原生构建 AIGC 业务基石
AIGC即AI Generated Content,是指利用人工智能技术来生成内容,AIGC也被认为是继UGC、PGC之后的新型内容生产方式,AI绘画、AI写作等都属于AIGC的分支。而 AIGC 业务的部署也面临着异构资源管理、机器学习流程管理等问题,本次分享将和大家分享如何使用云原生技术构建 AIGC 业务。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论