1、Mutex 几种状态

  • mutexLocked — 表示互斥锁的锁定状态;

  • mutexWoken — 表示从正常模式被从唤醒;

  • mutexStarving — 当前的互斥锁进入饥饿状态;

  • waitersCount — 当前互斥锁上等待的 Goroutine 个数;

2、Mutex 正常模式和饥饿模式正常模式(非公平锁)

正常模式下,所有等待锁的 goroutine 按照 FIFO(先进先出)顺序等待。唤醒的goroutine 不会直接拥有锁,而是会和新请求锁的 goroutine 竞争锁的拥有。新请求锁的 goroutine 具有优势:它正在 CPU 上执行,而且可能有好几个,所 以刚刚唤醒的 goroutine 有很大可能在锁竞争中失败。在这种情况下,这个被 唤醒的 goroutine 会加入到等待队列的前面。如果一个等待的 goroutine 超过1ms 没有获取锁,那么它将会把锁转变为饥饿模式。

饥饿模式(公平锁)

为了解决了等待 G 队列的长尾问题
饥饿模式下,直接由 unlock 把锁交给等待队列中排在第一位的 G(队头),同 时,饥饿模式下,新进来的 G 不会参与抢锁也不会进入自旋状态,会直接进入 等待队列的尾部,这样很好的解决了老的 g 一直抢不到锁的场景。饥饿模式的触发条件,当一个 G 等待锁时间超过 1 毫秒时,或者当前队列只剩 下一个 g 的时候,Mutex 切换到饥饿模式。

总结

对于两种模式,正常模式下的性能是最好的,goroutine 可以连续多次获取 锁,饥饿模式解决了取锁公平的问题,但是性能会下降,其实是性能和公平的 一个平衡模式。

3、Mutex 允许自旋的条件

1 锁已被占用,并且锁不处于饥饿模式。
2 积累的自旋次数小于最大自旋次数(active_spin=4)。3 cpu 核数大于 1。
4 有空闲的 P。
5 当前 goroutine 所挂载的 P 下,本地待运行队列为空。

4、RWMutex 实现

通过记录 readerCount 读锁的数量来进行控制,当有一个写锁的时候,会将读 锁数量设置为负数 1<<30。目的是让新进入的读锁等待写锁之后释放通知读 锁。同样的写锁也会等等待之前的读锁都释放完毕,才会开始进行后续的操 作。而等写锁释放完之后,会将值重新加上 1<<30, 并通知刚才新进入的读锁(rw.readerSem),两者互相限制。

5、RWMutex 注意事项

  • RWMutex 是单写多读锁,该锁可以加多个读锁或者一个写锁

  • 读锁占用的情况下会阻止写,不会阻止读,多个goroutine 可以同时获取读锁

  • 写锁会阻止其他 goroutine(无论读和写)进来,整个锁由该 goroutine独占

  • 适用于读多写少的场景

  • RWMutex 类型变量的零值是一个未锁定状态的互斥锁。

  • RWMutex 在首次被使用之后就不能再被拷贝。

  • RWMutex 的读锁或写锁在未锁定状态,解锁操作都会引发 panic。

  • RWMutex 的一个写锁 Lock 去锁定临界区的共享资源,如果临界区的共享资源已被(读锁或写锁)锁定,这个写锁操作的 goroutine 将被阻塞直到解锁。

  • RWMutex 的读锁不要用于递归调用,比较容易产生死锁。

  • RWMutex 的锁定状态与特定的 goroutine 没有关联。一个 goroutine 可以 RLock(Lock),另一个 goroutine 可以 RUnlock(Unlock)。

  • 写锁被解锁后,所有因操作锁定读锁而被阻塞的 goroutine 会被唤醒,并都可以成功锁定读锁。

  • 读锁被解锁后,在没有被其他读锁锁定的前提下,所有因操作锁定写锁而被阻塞的 goroutine,其中等待时间最长的一个 goroutine 会被唤醒。

6、Cond 是什么

Cond 实现了一种条件变量,可以使用在多个 Reader 等待共享资源 ready 的场 景(如果只有一读一写,一个锁或者 channel 就搞定了)
每个 Cond 都会关联一个 Lock(*sync.Mutex or *sync.RWMutex),当修改条 件或者调用 Wait 方法时,必须加锁,保护 condition。

7、Broadcast 和 Signal 区别

func (c *Cond) Broadcast()

Broadcast 会唤醒所有等待 c 的 goroutine。

调用 Broadcast 的时候,可以加锁,也可以不加锁。

func (c *Cond) Signal()

Signal 只唤醒 1 个等待 c 的 goroutine。
调用 Signal 的时候,可以加锁,也可以不加锁。

8、Cond 中 Wait 使用

func (c *Cond) Wait()

Wait()会自动释放 c.L,并挂起调用者的 goroutine。之后恢复执行,Wait()会 在返回时对 c.L 加锁。
除非被 Signal 或者 Broadcast 唤醒,否则 Wait()不会返回。
由于 Wait()第一次恢复时,C.L 并没有加锁,所以当 Wait 返回时,调用者通常 并不能假设条件为真。

取而代之的是, 调用者应该在循环中调用 Wait。(简单来说,只要想使用condition,就必须加锁。)

for !condition() {c.Wait()
}
... make use of condition ...
c.L.Unlock()
c.L.Lock()

9、WaitGroup 用法

一个 WaitGroup 对象可以等待一组协程结束。使用方法是:
1. main 协程通过调用 wg.Add(delta int) 设置 worker 协程的个数,然后创 建 worker 协程;
2.worker 协程执行结束以后,都要调用 wg.Done();

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

10、WaitGroup 实现原理

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

  • 每次Add执行,请求计数器v加1,Done方法执行,请求计数器减1,v为0 时通过信号量唤醒 Wait()。

11、什么是 sync.Once

  • Once 可以用来执行且仅仅执行一次动作,常常用于单例对象的初始化场 景。

  • Once 常常用来初始化单例资源,或者并发访问只需初始化一次的共享资 源,或者在测试的时候初始化一次测试资源。

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

12、什么操作叫做原子操作

一个或者多个操作在 CPU 执行过程中不被中断的特性,称为原子性(atomicity)。这些操作对外表现成一个不可分割的整体,他们要么都执行,要 么都不执行,外界不会看到他们只执行到一半的状态。而在现实世界中,CPU不可能不中断的执行一系列操作,但如果我们在执行多个操作时,能让他们的 中间状态对外不可见,那我们就可以宣城他们拥有了“不可分割”的原子性。

在 Go 中,一条普通的赋值语句其实不是一个原子操作。列如,在 32 位机器上 写 int64 类型的变量就会有中间状态,因为他会被拆成两次写操作(MOV)——写 低32位和写高32位。

13、原子操作和锁的区别

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

14、什么是 CAS

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

简述过程是这样:

假设包含 3 个参数内存位置(V)、预期原值(A)和新值(B)。V 表示要更新变量的 值,E 表示预期值,N 表示新值。仅当 V 值等于 E 值时,才会将 V 的值设为 N, 如果 V 值和 E 值不同,则说明已经有其他线程在做更新,则当前线程什么都不 做,最后 CAS 返回当前 V 的真实值。CAS 操作时抱着乐观的态度进行的,它总 是认为自己可以成功完成操作。基于这样的原理,CAS 操作即使没有锁,也可 以发现其他线程对于当前线程的干扰。

15、sync.Pool 有什么用

对于很多需要重复分配、回收内存的地方,sync.Pool 是一个很好的选择。频 繁地分配、回收内存会给 GC 带来一定的负担,严重的时候会引起 CPU 的毛 刺,而 sync.Pool 可以将暂时不用的对象缓存起来,待下次需要的时候直接 使用,不用再次经过内存分配,复用对象的内存,减轻 GC 的压力,提升系统 的性能。

最后:

点击下方名片链接,关注 「码农编程进阶笔记 」微信公众号,在微信聊天对话框回复「go语言实战」「goweb编程」或者直接长按左下图海报中的二维码,可获取最新golang电子书和视频资源

字节跳动Go 语言面试会问哪些问题?相关推荐

  1. 面试字节跳动,被面试官的源码问题问到怀疑人生

    面试字节跳动,被面试官的源码问题问到怀疑人生 最近,我的一位朋友在找工作,已经拿到了美团.快手等公司的Offer,准备选择其中一家入职了. 后来他又接到了字节跳动的电话,通知他去参加三面.从二面到三面 ...

  2. (99)利用任务task实现单字节乘法功能,面试必问(二十三)(第20天)

    (99)利用任务task实现单字节乘法功能,面试必问(二十三)(第20天) 1 文章目录 1)文章目录 2)FPGA初级课程介绍 3)FPGA初级课程架构 4)利用任务task实现单字节乘法功能,面试 ...

  3. (98)利用函数function实现半字节加法功能,面试必问(二十二)(第20天)

    (98)利用函数function实现半字节加法功能,面试必问(二十二)(第20天) 1 文章目录 1)文章目录 2)FPGA初级课程介绍 3)FPGA初级课程架构 4)利用函数function实现半字 ...

  4. 为什么字节跳动的前端面试需要那么难的算法题?

    首先我来辟个谣: 随便打开一个招聘网站,你会发现前端工程师的岗位需求依旧庞大,大厂人才奇缺,就业薪资起点高,无行业限制. (数据来源:职友集) 前端开发的行业大环境 行业升级,如果说以前只会HTML. ...

  5. 【本人秃顶程序员】作为字节跳动的研发面试官,有些话我不得不说!

    今天看到了一篇关于如何准备面试的文章,分享给大家.尽管很多人都讨厌 "面试造航母,工作螺丝钉"的局面,但又不得不收起脾气假笑面对.谁让谁僧多粥少呢? 正文开始 2019春招过半,面 ...

  6. 字节跳动Java后端面试真题,看完你学会了吗,「附面试福利」

    前言; 之前有好多朋友给我留言说想去字节跳动,今天就给大家分享几道字节跳动的面试真题给大家,文末有福利哦. 一. 谈谈你对Java平台的理解? "Java 是解释执行",这句话正确 ...

  7. 4月跳槽进字节跳动了,面试真简单...

    前言: 最近金三银四跳槽季,相信很多小伙伴都在面试找工作, 怎样才能拿到大厂的offer,没有掌握绝对的技术,那么就要不断的学习,没有绝对的天才,只有持续不断的付出.对于我们每一个平凡人来说,改变命运 ...

  8. 2021年字节跳动+京东+美团面试总结!专题解析

    前言 很多人聊起移动端适配都是懵逼状态,都想口吐芬芳.难道移动端还要适配,直接px写死,其他自适应不就完了吗?其实不然,要求严格的公司会要求缩放比例完全相同,简单说就是,在每个手机上的每一行的字数都要 ...

  9. 字节跳动Android实习面试凉凉经,震撼来袭免费下载!

    开头 最近,程序员这个圈子可谓热闹非凡,前不久,一个神奇的开源项目996.ICU诞生,几天时间就有超过10w+ star 和 1w+ fork ,可谓是Github上star增长最快的项目.996.i ...

最新文章

  1. gdal java shp_【GDAL/OGR】利用GDAL/OGR读取shp文件并转换为json文件(Java版)
  2. Linux vsftp服务
  3. as3 访问远程计算机,Flash AS3中数据发送与接收
  4. Redis性能问题排查解决手册(值得收藏)
  5. 程序图片运行效果存在偏差问题
  6. (王道408考研操作系统)第四章文件管理-第二节3:减少延迟时间的方法
  7. 两个for做数据插入_冒泡排序、选择排序、插入排序
  8. 容器入门(8) - 镜像签名
  9. 小程序进阶学习02--安装webstorm
  10. 九度oj 题目1028:继续畅通工程
  11. 开源hr系统 java_微人事-前后端分离的人力资源管理系统-江南一点雨
  12. Win10系统隐藏磁盘
  13. html简介百度百科,outerHTML
  14. uboot_v2016 版本中fw_printenv的编译问题
  15. 【ROM制作工具】华为UPDATE.APP固件一键解包打包教程
  16. CSS画出半圆,四分之一圆,三角等图形
  17. apicloud打开地图导航
  18. SQL SERVER 连乘写法
  19. android handler的机制和原理_Android完整知识体系路线(菜鸟-资深-大牛必进之路)
  20. 二值图像blob分析

热门文章

  1. AVM环视:系统搭建整体流程
  2. 望京,承包了帝都码农圈的魔幻
  3. win10中文字符乱码解决方案
  4. B. Sereja and Mirroring
  5. excel 域 邮件合并_如何获得免费的电子邮件域(5种快速简便的方法)
  6. 在UC浏览器投放广告的优势、效果!
  7. Spring中的AOP以及切入点表达式和各种通知
  8. foxmail清除无法清除的未读邮件
  9. 【二叉搜索树】(三) 小结
  10. 我用 python 做了款可开淘宝店赚钱的工具!