Go面试看这里了~(六)

原文地址:Go面试看这里了~(六)

1、WaitGroup的用法?

WaitGroup用于等待一组协程结束,用法如下:

  1. main通过调用wg.Add(delta int)设置worker协程个数,之后创建worker。

  2. worker结束后需调用wg.Done()。

  3. main调用wg.Wait()且被block,直到所有worker全部执行结束后返回。

2、WaitGroup实现原理?

  1. WaitGroup主要维护2个计数器,一是请求计数器v,一是等待计数器w,二者组成一64bit的值,请求计数器占高32bit,等待计数器占低32bit。

  2. 每次Add执行,请求计数器v+1,Done方法执行,请求计数器v-1,v为0时通过信号唤醒Wait()。

3、sync.Once是什么?

  1. Once可用来执行仅执行一次的动作,常用于单例对象的实例化场景。

    扫描二维码关注公众号,回复: 13241164 查看本文章
  2. Once常用于初始化单例资源,或并发访问只需初始化一次的共享资源,或在测试初始化一次的测试资源。

  3. sync.Once只暴露一个Do方法,可多次调用Do,但只有第一次调用Do时,f参数才会执行,这里的f是无参数返回的函数。

4、原子操作是什么?

一个或多个操作在CPU执行过程中不被中断的特性称为原子性(atomicity),这些操作对外表现为一个不可分割的整体,要么都执行,要么都不执行,外界看不到此操作执行到一半的状态。

现实世界中,CPU不可能不中断的执行一系列操作,但如可实现在执行多个操作时,能让其中间状态对外不可见,就可宣称实现了原子性。

Go普通赋值语句不是原子操作,如32位的机器上写int64类型的变量就会有中间状态,因为此操作会被拆为两次写操作(MOV),分别是写低32位和写高32位。

5、原子操作和锁的区别?

原子操作由底层硬件支持,锁则是由操作系统的调度器实现,锁应当用来保护一段逻辑,对于一个变量的更新的保护,原子操作通常会有更高的效率,并且能提高多核计算机的优势,如要更新的是复合对象,则应当使用atomic.Value封装好的实现。

6、CAS是什么?

CAS(Compare And Share),也就是比较交换,是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,之后原子性的更新某个位置的值,其实现的方式是给予硬件平台的汇编指令,在Intel的CPU中,使用cmpxchg指令,也就是说CAS是靠硬件实现的,从而在硬件层面提升效率。

假设包含三个参数内存位置(V)、预期原值(A)、新值(B),V表示要更新变量的值,E表示预期值,N表示新值,仅当V等于E时,才会将V的值设为N,如V不等于E,说明已有其它线程在做更新,当前线程则会什么都不做,最后CAS返回当前V的真实值。

CAS总是抱着乐观的态度进行的,总认为自己可以成功完成操作,基于此原理,CAS即使没有锁,也可发现其它线程对于当前线程的干扰。

7、sync.Pool的作用?

对于很多需要重复分配、内存回收的地方,sync.Pool是很好的选择。

频繁的分配、内存回收会给gc带来一定的负担,严重的时候会引起CPU的毛刺,而sync.Pool可将暂时不用的对象缓存起来,待下次需要的时候直接使用,而不需再次经过内存分配,从而实现复用对象的内存,减轻gc的压力,提升系统性能。

至此,本次分享就结束了,后期会慢慢补充。

以上仅为个人观点,不一定准确,能帮到各位那是最好的。

好啦,到这里本文就结束了,喜欢的话就来个三连击吧。

扫码关注公众号,获取更多优质内容。

  

猜你喜欢

转载自blog.csdn.net/luyaran/article/details/121392883