【Golang 面试 - 进阶题】每日 3 题(十九)

✍个人博客:Pandaconda-CSDN博客

📣专栏地址:http://t.csdnimg.cn/UWz06

📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

 55. Go channel 发送和接收什么情况下会死锁?

在 Go 中,channel 发送和接收操作可能会导致死锁的情况,一般来说,有以下几种情况容易引起死锁:

  1. 发送者和接收者数量不一致:如果发送者的数量不等于接收者的数量,那么可能会导致发送者或接收者被阻塞,进而导致死锁。

  2. 单向 channel 的使用不当:如果使用了单向 channel 并且发送者和接收者之间出现了交叉,那么可能会导致死锁。比如,一个只允许发送数据的 channel 被多个 goroutine 接收,或者一个只允许接收数据的 channel 被多个 goroutine 发送。

  3. 循环等待:当多个 goroutine 彼此等待对方释放资源时,就会发生循环等待的情况,从而导致死锁。这种情况在 channel 中也可能出现,例如,一个 goroutine 在发送数据时,另一个 goroutine 在接收数据之前需要释放某些资源,而这个资源的释放需要等待第一个 goroutine 发送完数据。

  4. channel 缓冲区已满或为空:当一个非缓冲的 channel 中没有数据可以被读取或者缓冲区已满时,发送和接收操作都会被阻塞,从而导致死锁。

为了避免以上情况的发生,我们可以在编写代码时注意使用 channel,确保发送者和接收者数量一致,使用单向 channel 时注意正确的使用方式,避免循环等待的情况,以及正确地使用 channel 的缓冲区。此外,我们还可以使用 Go 语言提供的一些工具来检测死锁的情况,例如 go vetgo test -race 等。

 56. Go channel 有无缓冲的区别?

无缓冲:一个送信人去你家送信,你不在家他不走,你一定要接下信,他才会走。

有缓冲:一个送信人去你家送信,扔到你家的信箱转身就走,除非你的信箱满了,他必须等信箱有多余空间才会走。

无缓冲有缓冲
创建方式make(chan TYPE)make(chan TYPE, SIZE)
发送阻塞数据接收前发送阻塞缓冲满时发送阻塞
接收阻塞数据发送前接收阻塞缓冲空时接收阻塞

非缓冲 channel

package main
import (
    "fmt"
    "time"
)
func loop(ch chan int) {
    for {
        select {
        case i := <-ch:
            fmt.Println("this value of unbuffer channel", i)
        }
    }
}
func main() {
    ch := make(chan int)
    ch <- 1
    go loop(ch)
    time.Sleep(1 * time.Millisecond)
}

这里会报错 fatal error: all goroutines are asleep - deadlock! 就是因为 ch <- 1 发送了,但是同时没有接收者,所以就发生了阻塞

但如果我们把 ch <- 1 放到 go loop(ch) 下面,程序就会正常运行

缓冲 channel

package main
import (
    "fmt"
    "time"
)
func loop(ch chan int) {
    for {
        select {
        case i := <-ch:
            fmt.Println("this  value of unbuffer channel", i)
        }
    }
}
func main() {
    ch := make(chan int,3)
    ch <- 1
    ch <- 2
    ch <- 3
    ch <- 4
    go loop(ch)
    time.Sleep(1 * time.Millisecond)
}

这里也会报 fatal error: all goroutines are asleep - deadlock! ,这是因为 channel 的大小为 3 ,而我们要往里面塞 4 个数据,所以就会阻塞住,解决的办法有两个:

  1. 把 channel 长度调大一点

  2. 把 channel 的信息发送者 ch <- 1 这些代码移动到 go loop(ch) 下面 ,让 channel 实时消费就不会导致阻塞了

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值