Go 语言笔试面试题(并发编程)

2023-11-18

Q1 无缓冲的 channel 和 有缓冲的 channel 的区别?

答案:对于无缓冲的 channel,发送方将阻塞该信道,直到接收方从该信道接收到数据为止,而接收方也将阻塞该信道,直到发送方将数据发送到该信道中为止。

对于有缓存的 channel,发送方在没有空插槽(缓冲区使用完)的情况下阻塞,而接收方在信道为空的情况下阻塞。

例如:

func main() {
    st := time.Now()
    ch := make(chan bool)
    go func ()  {
        time.Sleep(time.Second * 2)
        <-ch
    }()
    ch <- true  // 无缓冲,发送方阻塞直到接收方接收到数据。
    fmt.Printf("cost %.1f s\n", time.Now().Sub(st).Seconds())
    time.Sleep(time.Second * 5)
}
func main() {
    st := time.Now()
    ch := make(chan bool, 2)
    go func ()  {
        time.Sleep(time.Second * 2)
        <-ch
    }()
    ch <- true
    ch <- true // 缓冲区为 2,发送方不阻塞,继续往下执行
    fmt.Printf("cost %.1f s\n", time.Now().Sub(st).Seconds()) // cost 0.0 s
    ch <- true // 缓冲区使用完,发送方阻塞,2s 后接收方接收到数据,释放一个插槽,继续往下执行
    fmt.Printf("cost %.1f s\n", time.Now().Sub(st).Seconds()) // cost 2.0 s
    time.Sleep(time.Second * 5)
}

Q2 什么是协程泄露(Goroutine Leak)?

协程泄露是指协程创建后,长时间得不到释放,并且还在不断地创建新的协程,最终导致内存耗尽,程序崩溃。常见的导致协程泄露的场景有以下几种:

缺少接收器,导致发送阻塞

这个例子中,每执行一次 query,则启动1000个协程向信道 ch 发送数字 0,但只接收了一次,导致 999 个协程被阻塞,不能退出。

func query() int {
    ch := make(chan int)
    for i := 0; i < 1000; i++ {
        go func() { ch <- 0 }()
    }
    return <-ch
}

func main() {
    for i := 0; i < 4; i++ {
        query()
        fmt.Printf("goroutines: %d\n", runtime.NumGoroutine())
    }
}
// goroutines: 1001
// goroutines: 2000
// goroutines: 2999
// goroutines: 3998

缺少发送器,导致接收阻塞

那同样的,如果启动 1000 个协程接收信道的信息,但信道并不会发送那么多次的信息,也会导致接收协程被阻塞,不能退出。

死锁(dead lock)

两个或两个以上的协程在执行过程中,由于竞争资源或者由于彼此通信而造成阻塞,这种情况下,也会导致协程被阻塞,不能退出。

无限循环(infinite loops)

这个例子中,为了避免网络等问题,采用了无限重试的方式,发送 HTTP 请求,直到获取到数据。那如果 HTTP 服务宕机,永远不可达,导致协程不能退出,发生泄漏。

func request(url string, wg *sync.WaitGroup) {
    i := 0
    for {
        if _, err := http.Get(url); err == nil {
            // write to db
            break
        }
        i++
        if i >= 3 {
            break
        }
        time.Sleep(time.Second)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go request(fmt.Sprintf("https://127.0.0.1:8080/%d", i), &wg)
    }
    wg.Wait()
}

Q3 Go 可以限制运行时操作系统线程的数量吗?

答案:

The GOMAXPROCS variable limits the number of operating system threads that can execute user-level Go code simultaneously. There is no limit to the number of threads that can be blocked in system calls on behalf of Go code; those do not count against the GOMAXPROCS limit.

可以使用环境变量 GOMAXPROCS 或 runtime.GOMAXPROCS(num int) 设置,例如:

runtime.GOMAXPROCS(1) // 限制同时执行Go代码的操作系统线程数为 1

从官方文档的解释可以看到,GOMAXPROCS 限制的是同时执行用户态 Go 代码的操作系统线程的数量,但是对于被系统调用阻塞的线程数量是没有限制的。GOMAXPROCS 的默认值等于 CPU 的逻辑核数,同一时间,一个核只能绑定一个线程,然后运行被调度的协程。因此对于 CPU 密集型的任务,若该值过大,例如设置为 CPU 逻辑核数的 2 倍,会增加线程切换的开销,降低性能。对于 I/O 密集型应用,适当地调大该值,可以提高 I/O 吞吐率。

往期精彩

Go 语言笔试面试题(实现原理)

Go 语言笔试面试题(基础语法)

腾讯PHP/GO工程师面试经历

字节跳动Go 语言面试会问哪些问题?

【精选】2022年全新GO工程师面试题

欢迎分享给需要的朋友,求一键三连:分享朋友圈、点赞、在看

335515069bb123ac19d4f421aa532c05.png

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go 语言笔试面试题(并发编程) 的相关文章

随机推荐

  • OLED透明屏轻量化设计:提升便携性与用户体验的新方向

    随着科技的不断进步 OLED透明屏作为一种新兴的显示技术正逐渐走入人们的视野 除了在视觉效果上的优势 OLED透明屏在重量方面的设计也备受关注 对此 尼伽将深入探讨OLED透明屏轻量化设计的重要性 策略以及应用案例 希望看后对您有所启发 一
  • 面试机试题目,使用Spring + SpringMVC +Mybatis + html + css实现员工管理系统

    文章目录 机试挑战 需求分析 简介 访问地址 http 39 99 237 90 8080 employee http 39 99 237 90 8080 employee 源码 https github com Listen Y Java
  • Visual C++中函数的覆盖和函数的隐藏

    我是荔园微风 作为一名在IT界整整25年的老兵 今天来聊聊Visual C 中函数的覆盖和函数的隐藏 Visual C 中函数的覆盖和函数的隐藏与JAVA有很大不同 有些容易搞错的点和概念 我们要特别注意 首先 先满足一下急性子的同学 因为
  • 思科模拟器:nat地址转换-静态转换-动态转换-pat转换

    我么需要的环境 sw1为公司出口 192开头的网段为内网也就是公司内部 1动态 缺点 只能外网访问内网 内网无法访问外网 2静态 缺点 比如有两个公网ip如果在有两个人上网的时候 第三个人无法上网 由于使用设备不固定所以 外网无法访问内网
  • https证书过期处理方案及相关问题

    证书过期处理 1 替换证书操作 2 问题及处理 1 替换证书操作 证书由甲方提供 也可以去阿里云进行申请 前往nginx安装目录下的 conf cert替换旧的证书 目录 nginx conf cert 重启nginx操作 https bl
  • Android 开发中的权限申请

    一 权限动态申请 我们都知道 从 Android 6 0 开始 部分危险权限在 xml 注册的同时 还需要动态申请 1 需要动态申请的权限 Manifest permission CONTACTS 联系人 Manifest permissi
  • Pytorch 学习(三)sigmoid 逻辑回归预测

    1 数据预处理 处理多特征样本 import pandas as pd data pd read csv csv 划分数据 iloc 第一个参数 行 第二个参数 列 X data iloc 1 标签为 1 1 讲 1 替换为 0 Y dat
  • Shell中的幽灵王者—JAVAWEB 内存马 【认知篇】

    Goby社区第 21 篇技术分享文章 全文共 6700 字 预计阅读时间 17 分钟 自我介绍 大家好 我是 su18 无论是个人博客还是社区 已经很久没写技术文章了 原因有很多 时间 精力 心态等等 但在开源社区也算比较活跃 由于工作需要
  • JSONUtil.toJsonStr 时间变成了时间戳

    问题描述 我的接口是以Date来接收日期的 然后我在拿到这个对象参数后 通过hutool当中的JSONUtil toJsonStr将其序列化成json字符串 然后存储到数据库 然后存储到数据库当中发现这个字段是时间戳 DateTimeFor
  • 在Spring Boot使用Undertow服务

    1 undertow简介 Undertow是RedHAT红帽公司开源的产品 采用JAVA开发 是一款灵活 高性能的web服务器 提供了NIO的阻塞 非阻塞API 也是Wildfly的默认Web容器 在javaweb容器的世界里 Tomcat
  • mysql数据库三大引擎优缺点

    1 MyISAM 特性 不支持事务 表级锁定 并发性能大大降低 读写互相阻塞 适用场景 不支持事务 并发相对较低 表锁定 执行大量select语句操作的表 count 操作较快 不支持外键 注 查询速度快的原因 a MyISAM存储的直接是
  • sqlserver自动定时备份数据库并按日期命名

    sqlserver自动定时备份数据库并按日期命名 备份数据库是很有必要的 在维护软件和站点的时候关系到我们数据的安全和完整性 数据库为我们提供了自动备份功能 定时自动备份 SqlServerde 的维护计划中自带了备份数据库任务 并不是自动
  • Python 各种画图

    文章目录 Part I 基础知识 Chap I 快应用 Chap II 常用语句 Part II 画图样例 Chap I 散点图 Chap II 柱状图 Chap III 折线图 Chap IV 概率分布直方图 Chap V 累计概率分布曲
  • 用Python自动化处理Excel表格详解

    Excel表格基础知识 Excel表格可以帮助用户创建 编辑 格式化和计算数据 并生成各种图表和报表 Excel表格通常用于商业 金融 科学 教育等领域 Excel表格的常用操作 Excel表格的常用操作包括插入 删除 移动 复制 粘贴 排
  • ZYNQ LINUX 下 PL中断PS记录

    最近ZYNQ的项目需要 调试了PL中断PS的部分 下面将其中了解到信息记录下来 以防遗忘 如图一 图二所示 PL到PS的中断分为16个共享中断 SPI 和4个私有中断 PPI 本文用到了共享中断 着重介绍SPI中断 图一 图二 PL 侧16
  • 贝wa儿歌(安卓)

    本次贝wa儿歌为大家提供的是特殊版本的 软件需要注册登录才能才能使用VIP权限 安装好后 打开如果提示更新请点击取消 一定不要更新哦 贝瓦儿歌不仅只是儿歌 其实有很多分类的 包括有国学 动画 英语 故事 思维 情商 习惯等等 寓教于乐让小朋
  • java项目:基于springboot的商城系统(springBoot+mybatis+layui+jquery)1003

    项目描述 爱购商城 分为前端和后端两部分 主要功能包括 用户管理 轮播图管理 商品分类管理 商品品牌管理 商品管理 等功能 运行环境 jdk8 mysql IntelliJ IDEA maven 项目技术 springBoot mybati
  • 【C++11】 线程库的使用

    文章目录 1 线程库的基本使用 1 1 thread 1 2 this thread 1 3 线程函数参数 2 mutex 2 1 mutex的基本使用 2 2 mutex系列锁 2 3 lock guard与unique lock 3 原
  • 字符“&”在XML文件中需要被转义

    今天弄Mybatis的配置文件时 因为这样一条语句
  • Go 语言笔试面试题(并发编程)

    Q1 无缓冲的 channel 和 有缓冲的 channel 的区别 答案 对于无缓冲的 channel 发送方将阻塞该信道 直到接收方从该信道接收到数据为止 而接收方也将阻塞该信道 直到发送方将数据发送到该信道中为止 对于有缓存的 cha