面试题答案
一键面试发送操作
- 缓冲区为空:
- 当缓冲区为空时,发送操作会立即将数据放入缓冲区,而不会阻塞。例如:
package main
import "fmt"
func main() {
ch := make(chan int, 5)
ch <- 1
fmt.Println("Data sent to channel when buffer was empty")
}
- 缓冲区未满:
- 只要缓冲区未满,发送操作都能立即完成,将数据放入缓冲区。例如:
package main
import "fmt"
func main() {
ch := make(chan int, 5)
for i := 0; i < 3; i++ {
ch <- i
}
fmt.Println("Data sent to channel when buffer was not full")
}
- 缓冲区满:
- 当缓冲区满时,发送操作会阻塞,直到有其他 goroutine 从 Channel 中接收数据,腾出空间。例如:
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 5)
for i := 0; i < 5; i++ {
ch <- i
}
go func() {
time.Sleep(2 * time.Second)
<-ch
fmt.Println("Receiver removed data, unblocking sender")
}()
ch <- 6
fmt.Println("Data sent after receiver made space")
}
接收操作
- 缓冲区为空:
- 接收操作会阻塞,直到有数据被发送到 Channel 中。例如:
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int, 5)
go func() {
time.Sleep(2 * time.Second)
ch <- 1
fmt.Println("Data sent to channel, unblocking receiver")
}()
data := <-ch
fmt.Println("Received data:", data)
}
- 缓冲区未满:
- 接收操作会从缓冲区中取出数据,不会阻塞。例如:
package main
import "fmt"
func main() {
ch := make(chan int, 5)
ch <- 1
data := <-ch
fmt.Println("Received data from non - full buffer:", data)
}
- 缓冲区满:
- 接收操作同样会从缓冲区中取出数据,不会阻塞,并且取出数据后,缓冲区会腾出空间,可用于后续的发送操作。例如:
package main
import "fmt"
func main() {
ch := make(chan int, 5)
for i := 0; i < 5; i++ {
ch <- i
}
data := <-ch
fmt.Println("Received data from full buffer:", data)
}
综上所述,缓冲区大小为5的 Channel 在通信时,发送操作在缓冲区未满时不会阻塞,满时阻塞;接收操作在缓冲区为空时阻塞,非空时不阻塞。这种机制使得多个 goroutine 之间的数据传递更加灵活和高效,同时也需要开发者谨慎处理以避免死锁等问题。