1 2 1
NerdHND
Feb 24, 2025 1
拿我得指出哥们候选人真的有问题吧, 这, 这不是完全不会嘛...
2
hingle
Feb 24, 2025 3
薪资给多少?薪资低那就 “门当户对” 了,挺好的。
3
kandaakihito
Feb 24, 2025 12
看了一下,上周那个 “一面出 LRU 算法题算难吗” 的帖子也是你发的。老哥你负责面的到底是什么类型岗位呀?怎么题目差距好像有点儿大。 而且说实话,如果给你投简历的人里面,有 80%连 chan 的基础都用不清楚。。。那么你这个岗位面试的时候应该不适合问 LRU 。
4
nomagick
Feb 24, 2025 2
你也别有莫名的优越感然后老来收铜币; 先用务实标准筛选一下吧,统招本科四六级,3 年经验之类的
6
clemente
Feb 24, 2025
如果说从通过率分布的角度来定义 题的难度的话 90% 应该算 hard
7
fruitmonster
Feb 24, 2025
虽然知道应该使用 waitgroup ,但是, "time sleep " 没解决没执行完就退出这个问题么?
9
xuanbg
Feb 24, 2025
你这个不叫 go 基础,就是个编程基础。
10
jworg
Feb 24, 2025
可以用第三方库不,我脑子已经被 conc 惯坏了,只记得起 conc 的 WaitGroup , 系统的 WaitGroup 好像属于 sync 包。
11
langhuishan
Feb 24, 2025 1
golang 的精髓不就是并发吗?这都没掌握,等于没学
12
cooooing
Feb 24, 2025 via Android
@
fruitmonster time sleep 只是降低出现这个问题的概率,并没有解决问题。如果操作是请求 api 或者其他耗时操作,要 sleep 多久?这种方式不好的,还是得 wait group 或者其他方式来同步
13
Vegetable
Feb 24, 2025
这种情况至少说明完全没做过需要 graceful shutdown 的程序,不能说判死刑,但至少对 go 不太了解吧
14
freemoon
Feb 24, 2025
可以说说招聘岗位要求几年经验,给多少薪资
15
zljklang Feb 24, 2025
package main import "fmt" func main() { // 创建无缓冲通道 ch := make(chan int) // 发送方 goroutine go func() { for i := 0; i < 5; i++ { ch <- i // 顺序发送数字 } close(ch) // 发送完成后关闭通道[1,7](@ref) }() // 接收方 goroutine for num := range ch { fmt.Println("Received:", num) } } 这个对吗
16
givenge
Feb 24, 2025 2
天天发这些,不会是想转自媒体吧
17
opengps
Feb 24, 2025 1
对于你的状态来考他们不合格,那反过来他们提问题考验你你有信心通过吗? 单个问题并不能说明人的整体能力
18
hunterster
Feb 24, 2025
package main import ( "fmt" "sync" ) func writeData(c chan int, i int) { c <- i } func readData(c chan int) { for i := 0; i < 5; i++ { fmt.Println("The data is:", <-c) } } func main() { var wg sync.WaitGroup wg.Add(5) var c = make(chan int) for k := 1; k <= 5; k++ { go func() { defer wg.Done() writeData(c, k) }() } go readData(c) wg.Wait() close(c) }
19
codersdp1
Feb 24, 2025
这个确实属于 go 基础了,没掌握这些写并发功能肯定会出问题的。
20
voidmnwzp
Feb 24, 2025
```go func Test2(t *testing.T) { s := make(chan int) go func() { for i := range s { fmt.Println("recv:",i) } }() for i := 0; i < 5; i++ { s <- i } close(s) } ``` 不是这和 1+。。100 求和有啥区别 很难吗
22
expy
Feb 24, 2025
正常,卷是真的卷,但是水平差的人也大量存在。
25
bv
Feb 24, 2025
@
SingeeKing 真的假的?都几年经验?这种人招进去也是边学边做吧,甚至还会拖队友后腿。
26
main1234
Feb 24, 2025 1
package main import ( "fmt" "sync" ) func main() { sw := sync.WaitGroup{} sw.Add(1) ch := make(chan int) go func() { for i := 0; i < 5; i++ { ch <- i } close(ch) }() go func() { defer sw.Done() for i := range ch { fmt.Println(i) } }() sw.Wait() fmt.Println("done") }
27
voidmnwzp
Feb 24, 2025
@
phpcyy range channel 的话 如果 channel 关闭了会退出的 你可以试试
28
yuanyao Feb 24, 2025
@
lasuar 三年左右,薪资我不清楚,我自己 22 年三年经验进来的时候给了 32k*14 ,不知道现在多少了
29
yiqiao
Feb 24, 2025
@
zljklang 你这个方法如果主 goroutine 发送完后立刻退出接收方还在运行导致提前终止吧 ,你可以试着调大循环可以看出来
还是要引入 WaitGroup
31
Licsber
Feb 24, 2025
笑死 最近写了个转发助手 和你这个题完全重叠
写出来加双端调试 部署上线测试总共两天吧
来看看我这水平能开多少(
```go
// listener 省略
func handleConnection(conn net.Conn) {
s := &Session{
Cmd: link_start,
Remote: remote,
ServerSideRemote: conn.RemoteAddr().String(),
ClientID: clientID,
}
ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout)
sessionManager.Set(s.ServerSideRemote, conn)
sessionManager.Bind(s.ServerSideRemote, cancel)
send, _ := json.Marshal(s)
token := mqttClient.Publish(controlTopic, defaultQOS, false, send)
if token.Wait() && token.Error() != nil {
slog.Error("Publish control packet failed:", "err", token.Error())
sessionManager.Remove(s.ServerSideRemote)
return
}
<-ctx.Done()
switch ctx.Err() {
case context.Canceled:
slog.Info ("Link confirmed successfully:", "serversideremote", s.ServerSideRemote)
case context.DeadlineExceeded:
slog.Warn("Confirmation timeout after 5s:", "serversideremote", s.ServerSideRemote)
sessionManager.Remove(s.ServerSideRemote)
}
}
func runServerForwarding(s *Session) {
conn, ok := sessionManager.Get(s.ServerSideRemote)
if !ok {
slog.Error("Connection not found:", "connID", s.ServerSideRemote)
return
}
defer conn.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
topic := topicPrefix + s.ClientSideLocal
token := mqttClient.Subscribe(topic, defaultQOS, func(c mqtt.Client, m mqtt.Message) {
select {
case <-ctx.Done():
return
default:
slog.Debug("Recv client down:", "recv", m.Payload())
recv, err := hex.DecodeString(string(m.Payload()))
if err != nil {
slog.Error("HEX decode error:", "err", err)
cancel()
return
}
_, err = conn.Write(recv)
if err != nil {
slog.Warn("TCP write error:", "err", err)
cancel()
}
}
})
if token.Wait() && token.Error() != nil {
slog.Error("Subscribe client down error:", "err", token.Error())
return
}
buf := make([]byte, defaultBufSize)
for {
select {
case <-ctx.Done():
return
default:
conn.SetReadDeadline(time.Now().Add(readTimeout))
n, err := conn.Read(buf)
if err != nil {
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
slog.Debug("TCP read timeout:", "connID", s.ServerSideRemote)
continue
}
slog.Warn("TCP read error:", "err", err)
return
}
send := hex.EncodeToString(buf[:n])
slog.Debug("Send up:", "send", send)
topic := topicPrefix + s.ServerSideRemote
token := mqttClient.Publish(topic, defaultQOS, false, send)
if token.Wait() && token.Error() != nil {
slog.Error("Publish up error:", "err", token.Error())
return
}
}
}
}
```
32
yuanyao Feb 24, 2025 via iPhone
@
zljklang 要求是新开两个 goroutine ,我没说清楚。你这个也没问题
39
leehaoze98
Feb 24, 2025
面外包或者校招会问两个协程交替打印,一个打印 A~Z ,一个打印 1~100 。 1. 有的人手打从'A'~'Z'的数组 2. 有的人 goroutine 没启动,主进程就退出了 3. 有的人只会处理两个协程打印数量一致的情况,一个打印 26 个,另一个打印 100 个,好多人会死锁。
40
phpcyy
Feb 24, 2025
@
voidmnwzp 试了下,直接用 main 函数,不使用单元测试文件,即使是 5 也有概率到 3 就退出
41
voidmnwzp
Feb 24, 2025
@
phpcyy #40 func Test2(t *testing.T) {
s := make(chan int)
wg:=sync.WaitGroup{}
wg.Add(1)
go func() {
for i := range s {
fmt.Println("go2:",i)
}
fmt.Println("done")
wg.Done()
}()
for i := 0; i < 5; i++ {
s <- i
}
close(s)
wg.Wait()
}
42
smallparking
Feb 24, 2025
``` package main import ( "fmt" "sync" ) func send(ch1 chan int) { for i := range 5 { ch1 <- i fmt.Printf("send i: %d\n", i) } close(ch1) } func recv(wg *sync.WaitGroup, ch1 chan int) { // wait receive all data and done for i := range ch1 { fmt.Printf("receive i: %d\n", i) } wg.Done() } func main() { var wg sync.WaitGroup ch1 := make(chan int) wg.Add(1) go send(ch1) go recv(&wg, ch1) wg.Wait() } ``` 确实有点难度,一般不会启两个 goroutine, 所以确实不是一下子写出来的
43
phpcyy
Feb 24, 2025
@
voidmnwzp 这个没问题。楼上有例子,你把生产者放 goroutine 先,然后消费者放到 main 函数里,,是最简单的实现
44
ChatGOP
Feb 24, 2025
Gobyexample 大把例子。
45
xiangxiangxiang
Feb 24, 2025
写了快两年 go 。。。确实基本没用过 channel ,只有看 b 站学 go 语言的时候用过 WaitGroup 倒是工作中经常用
46
k9982874
Feb 24, 2025
这个不提前复习一下直接上手没 ai 辅助真写不出一次全对
47
vhwwls
Feb 24, 2025
运维路过,这个我觉得应该是贵司的简历筛选出了问题,一楼说的对。
49
ChatGOP
Feb 24, 2025
@
daimazha 是的, 八股文。 而且哥觉得凡是八股文,AI/Google 能做的都不算是真正的能力
50
Nazz
Feb 24, 2025
我用 chan 从来不 close
51
zhengfan2016
Feb 24, 2025 10
只能说 op 招聘错方向了,你招的 985 ,211 都是市场里不缺面试机会的那一批。如果不是特别热爱代码的,也不会去钻研这些东西,反正 curd 就能轻松把钱拿,下班了打游戏不香吗。
倒是那些学历低人一等的大专和普本,有少部分人为了在竞争中脱颖而出,可能真会去钻研这种东西,而聪明的 op 已经把这种可能性过滤掉了。
至此,面试者百分之 90%不会不是很正常吗
52
hunterster
Feb 24, 2025
@
yuanyao 这个是看到要求随手写的,没注意到只要两个协程,我改一下
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func init() {
wg.Add(5)
}
func writeData(c chan int, count int) {
fmt.Println("Write rountine is executed.")
for k := 0; k < count; k++ {
defer wg.Done()
c <- k
}
}
func readData(c chan int, count int) {
fmt.Println("Read rountine is executed.")
for i := 0; i < count; i++ {
fmt.Println("The data is:", <-c)
}
}
func main() {
var c = make(chan int)
go writeData(c, 5)
go readData(c, 5)
wg.Wait()
close(c)
}
54
birdhk
Feb 24, 2025
package main import "sync" func main() { var wg sync.WaitGroup ch := make(chan int) wg.Add(2) go func() { defer wg.Done() for i := 0; i < 10000; i++ { ch <- i } close(ch) }() go func() { defer wg.Done() for i := range ch { println(i) } }() wg.Wait() } 我感觉我这样应该没问题,有大哥们 review 一下吗
56
ForkNMB
Feb 24, 2025
刚开始学 go 也以为是八股文看看得了 不上手试试 写的也是简单版本(因为没有具体复杂的场景 写出来当然简单)等真用 go 开发写服务 多个协程下 服务优雅关闭 资源合理释放 生产者消费者怎么稳定的转起来 还是踩了很多坑的= = 面试这个确实能筛人
57
PUR4uF5Oq0z0YN9r
Feb 24, 2025
这个还好, 我之前出的面试题是: 用两个 channel 循环打印水分子(H2O), 分子顺序不要求, 但是每一行必须是 2 个 H 加 1 个 O 的组合
58
ChatGOP
Feb 24, 2025 2
@
ForkNMB 其实招人的, 如果自己没有看过这题没有准备, 拿这题考他自己, 也会被筛出局。
60
Jinnrry
Feb 24, 2025 via iPhone 2
我面试也问这个题目。感觉和 hr 相关,很多 hr 只看背景,不懂技术,找一堆人过来就 90%都写不出来。 我现在这里 hr 比较专业,基本上一半的人能写出来的。 想来也是搞笑,这些连个协程通信都写不明白的人,讲起垃圾回收,数组扩容,乐观锁悲观锁却能头头是道
61
guanhui07
Feb 24, 2025
也是八股文的一种 不过如果他能知道 waitGroup 我就让他过
62
seakee
Feb 24, 2025
``` func main() { num := make(chan int, 5) done := make(chan struct{}) go func() { for n := range num { fmt.Println(n) } close(done) }() go func() { for i := 0; i < 5; i++ { num <- i } close(num) }() <-done } ```
63
Trim21
Feb 24, 2025
这还八股啊,这不是 go 并发编程的基础知识吗 ...
64
kalista
Feb 24, 2025
我有个问题,你们面试写代码允许用 cursor 吗
65
prosgtsr
Feb 24, 2025
多线程的题是挺难答的。如果不经常复习的话。一段时间就忘了。甚至就连 juc 自带的几个工具叫啥都忘了。。
68
bitfly
Feb 24, 2025 via Android
虽然我也不熟 但是真写过这玩意儿 在网络上并发处理随机遍历数组且不重复就需要用到这玩意 网络的不稳定性和结果返回的不确定性 的确很多 panic 修修补补不少时间配合 gpt 大法 Go 的并发网络遍历还是挺无敌的
69
harryge
Feb 24, 2025
package main import ( "time" "fmt" ) func main() { ch := make(chan int) go sender(ch, 5) go receiver(ch) time.Sleep(1 * time.Second) fmt.Println("done") } func receiver(ch chan int) { for { i, ok := <- ch if !ok { fmt.Println("Chan closed") break } fmt.Println("received ", i) } } func sender(ch chan int, n int) { for i := 0; i < n; i++ { fmt.Println("sent ", i) ch <- i } close(ch) }
70
voidmnwzp
Feb 24, 2025
@
leehaoze98 func Test2(t *testing.T) {
s := make(chan int)
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
var i int
for {
if i>=90{
break
}
i=<-s
if i>=90{
break
}
i++
fmt.Printf("go1: %c\n",i)
s<-i
}
fmt.Println("done")
wg.Done()
}()
i := 65
fmt.Printf("main: %c\n",i)
s <- i
for {
if i>=90{
break
}
i = <-s
if i >= 90 {
break
}
i++
fmt.Printf("main: %c\n",i)
s <- i
}
wg.Wait()
close(s)
}
72
bbao
Feb 24, 2025
生产者消费者再业务开发中是非常常见的场景,考察代码能力挺好的,只是题目中有一个点会让人很奇怪,waitgroup 通常用于多个 goroutine 并发执行且等待所有 goroutine 返回结果使用。比如同时请求 HTTP 、GRPC 等请求下由多个业务接口。 [两个 goroutine 用 channel 通信] channel 原则由生产者来控制关闭。消费者直接消费,通常 v,ok:=chan 来做个逻辑判断是否关闭。 channel 另一个特点是对于已关闭的 channel 进行读时会默认返回 0 ,由第二个返回变量来判断是否关闭。所以通常消费者无需关心做额外的业务处理。 此题如果等待两个 goroutine 都结束,输出预期结果,务必需要一定的等待时间,原因在于生产者如果关闭了 channel ,则 channel 不会再有阻塞的能力。 例如: c := make(chan int, 5) go func{xxxxxx; close(c) } go func(xxxxxx;} <-c (此处不会进行任何阻塞,所以启动程序即服务进行运行结束。) waitgroup 可以,sleep 可以,context.WithTimeout 也可以。只是这三个用在这个场景中,在真实的业务里会很奇怪。一般业务也很难遇见这样的场景吧。 楼主想根据一个场景设计题同时考察 channel 、waitgroup 或 context.Withtimeout 用法之外。还是要贴合一下实际场景好一些。 比如特性特点,使用场景能很熟悉即可。是不是要用 sleep 、context.Withtimeout 、waitgroup 并不是那么重要。原因在业务代码中,如果这样出现这样的代码逻辑,是在 codreview 时打回的。
73
body007
Feb 24, 2025
@
ericcen goland 自带功能哦,你也可以用那个代码检查的工具,也可以检查出循环里面的 defer
74
Sezxy
Feb 24, 2025 via Android
@
Trim21 我见过说问算法也说是八股,反正基础知识问了都是八股
75
lixikei
Feb 24, 2025
是不是这样子的 ```go package main import ( "fmt" "sync" ) func main() { wg := sync.WaitGroup{} ch := make(chan int) wg.Add(2) go func() { defer wg.Done() defer close(ch) for i := 0; i < 5; i++ { ch <- i } }() go func() { defer wg.Done() for v := range ch { fmt.Printf("i: %d\n", v) } }() wg.Wait() } ```
76
zhangfuguan
Feb 25, 2025
package main import ( "fmt" "sync" ) var wg sync.WaitGroup func main() { wg.Add(2) ch := make(chan int32, 1) go send(ch) go read(ch) wg.Wait() fmt.Println("done") } func read(ch <-chan int32) { for { select { case msg := <-ch: fmt.Println(msg) if msg == 10 { wg.Done() } } } } func send(ch chan<- int32) { for i := int32(1); i <= 10; i++ { ch <- i } close(ch) wg.Done() } 这样?
77
CyJaySong
Feb 25, 2025
帮陪朋友发的 ```go package main import ( "fmt" ) func main() { ch := make(chan int) down := make(chan struct{}) go func() { for i := 0; i < 5; i++ { i := i ch <- i } close(ch) }() go func() { for num := range ch { fmt.Println("Received:", num) } down <- struct{}{} }() <-down } ```
78
guanzhangzhang
Feb 25, 2025
我们同事写 python 的,也只有 web 框架限制了他们写代码用错误 raise ,写非 web 场景全部是糊屎,从不用抛出错误,单独得加一个布尔返回值来上层接收函数内报错了没。基本没看到使用 class 而是写几百行 if else ,少数前人留下的 class 里又在__init 里加 os.exit 的
79
zxjxzj9
Feb 25, 2025
这个确实还挺有水平的,因为一般人不写这种玩具小程序,用 goroutine 都是在 http 框架的处理器里写,确实不会在意这个退出的问题。 不过其实解决方法也很简单,就是每个 goroutine 开始前塞一个 wg.add(),运行完了塞一个 wg.done()就可以了
80
Huelse
Feb 25, 2025
这个水平要求没啥问题,但实际上你们最后还是会选薪资要的低的
81
phenixc
Feb 25, 2025
package main import ( "fmt" "sync" ) func senddata(out chan <- int, wg *sync.WaitGroup) { defer wg.Done() for i := range 5 { out <- i } close(out) } func receivedata(in <- chan int, wg *sync.WaitGroup) { defer wg.Done() for i := range in { fmt.Println(i) } } func main() { var wg sync.WaitGroup ch := make(chan int) wg.Add(2) go senddata(ch, &wg) go receivedata(ch, &wg) wg.Wait() }
82
capgrey
Feb 25, 2025
我比较好奇,为什么你懂,候选者不懂。是你们学习用的阅读材料的差异吗? op 看哪个文档的,Effective Go 吗?
83
caicaiwoshishui
Feb 25, 2025
func main() { ch := make(chan int, 1) wg := sync.WaitGroup{} count := 5 wg.Add(1) // Add 1 to the WaitGroup before starting the producer goroutine go func(wg *sync.WaitGroup, ch chan int, count int) { defer wg.Done() for i := 0; i <= count; i++ { ch <- i } }(&wg, ch, count) go func() { for { select { case v, ok := <-ch: if !ok { // Check if the channel is closed return } fmt.Println(v) } } }() wg.Wait() close(ch) fmt.Println("end") }
86
duty
Feb 25, 2025
只能说感谢楼主,本来是一个 Go 开发,来到这家公司除了第一个项目后面全是写 python ,看到这个题的时候打开编辑器,基础语法都错了五六次,虽然最后实现了,但还是该反思自己把基础知识都整忘了,该重新抓起来了,也该开始计划换工作了,这样下去,感觉以后的路也会被糟蹋了
88
mayli
Feb 25, 2025
正常吧,go 基础,没写过的很容易挂
89
Rehtt
Feb 25, 2025 via Android
也就两个 goroutine ,生产者和消费者都只有一个 goroutine 根本不需要 waitgroup ,两个 channel 就可以了,一个负载消息一个用来退出阻塞就行了
90
loginv2
Feb 25, 2025
v2 是回复里面不支持 md 语法么 怎么这么多人都发的没缩进了
91
UN2758
Feb 25, 2025
@
harryge 你这个 time.sleep 真是把我干沉默了,假如如果我是面试官,你没有主动解释这样思路不规范的写法的话,评分不会很好
92
UN2758
Feb 25, 2025
``` package main import ( "fmt" "sync" ) func producer(c chan int, wg *sync.WaitGroup) { for i := 0; i < 10000; i++ { c <- i } close(c) } func consumer(c chan int, wg *sync.WaitGroup) { for i := range c { fmt.Println("consumer", i) } wg.Done() } func main() { c := make(chan int) wg := sync.WaitGroup{} wg.Add(1) go producer(c, &wg) go consumer(c, &wg) wg.Wait() } ```
93
buffzty
Feb 25, 2025
用不着 waitgroup ,context ,done channel 这些啊 for 循环就行了,关闭了循环就退出了 package main import "log" var ( jobs = make(chan int) ) func t2() { for v := range jobs { log.Println(v) } } func t1() { for i := 0; i < 5; i++ { jobs <- i } close(jobs) } func main() { go t1() t2() }
94
angeni
Feb 25, 2025
平台决定的候选人素质
95
lesismal
Feb 25, 2025 1
> 2. 有的 channel 不知道由生产者关闭,直接在主程序生产者还未发送结束就关闭结果 panic ; 这种面试题用一个 chan 可以,但但就这个面试题的功能的话似乎就没必要俩协程了,不需要用俩协程也就不需要用 chan 了。 所以这种题如果出给我、只是纸面作答、我是不知道怎么答只能空着,因为需求不合理。 很多基础场景生产者不是唯一的,可能会是并发多协程会生产,所以通常是应该把用于发送的和用于关闭的分开两个 chan 、用于 close 的 chan 再配个 atomic compareandswap ,避免用单个 chan 、某个地方关闭后、其他协程还在给 chan 发数据直接就 panic 了,一些粗暴的实现直接 recover 这种 panic 虽然也问题不大但毕竟它不是个好的处理方式、比如还得纠结 panic recover 是否再给调用者一个 ErrClosed 返回,还是两个 chan 好些。 另外,如果不需要清理 chan 内遗留的数,chan 本身用完之后是不需要 close 的。
96
gaifanking
Feb 25, 2025
类似生产者消费者、状态机这种比较典型的场景/思路都有哪些呢?
97
sampeng
Feb 25, 2025 via iPhone
说实话,我面试的时候也被问过这个类似的问题。没答上来,得到的评价是不会 golang 。这妨碍我能开发 golang 完整的项目吗?我当时回答的思路基本是自己撸一个 waitgroup ,因为当时一瞬间压根没想到 waitgroup 现成的。但我知道要有类似 waitgroup 的极致。实际开发不管是问 AI 还是 google 搜索,只要我思路有了,这也不费事。所以之后我在面试基本不会卡关键词,重点是有没思路。思路是不是自己想的和经验得来的…
98
Steaven
Feb 25, 2025
怎么跟我面试差不多,上周四下班后面试的
99
Steaven
Feb 25, 2025
两种方法,第一种: package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup initial := make(chan struct{}) ch := make(chan int) prev := initial for i := 1; i <= 100; i++ { wg.Add(1) next := make(chan struct{}) go func(i int, prev, next chan struct{}) { <-prev ch <- i close(prev) if i < 100 { next <- struct{}{} } }(i, prev, next) prev = next } initial <- struct{}{} go func() { for i := range ch { wg.Done() fmt.Println(i) } }() wg.Wait() } 第二种(使用锁): package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup var mu sync.Mutex ch := make(chan int) cond := sync.NewCond(&mu) current := 1 for i := 1; i <= 100; i++ { wg.Add(1) go func(num int) { mu.Lock() for current != num { cond.Wait() } ch <- i current++ cond.Broadcast() mu.Unlock() }(i) } go func() { for i := range ch { wg.Done() fmt.Println(i) } }() wg.Wait() }
100
tuxz
Feb 26, 2025
```go func main() { ch := make(chan int) doneCh := make(chan struct{}) go func(ch chan<- int) { for i := 0; i < 5; i++ { ch <- i } close(ch) }(ch) go func(ch <-chan int) { for v := range ch { fmt.Println(v) } close(doneCh) }(ch) <-doneCh } ```
ubao
msn
snddm
index
pchome
yahoo
rakuten
mypaper
meadowduck
bidyahoo
youbao
zxmzxm
asda
bnvcg
cvbfg
dfscv
mmhjk
xxddc
yybgb
zznbn
ccubao
uaitu
acv
GXCV
ET
GDG
YH
FG
BCVB
FJFH
CBRE
CBC
GDG
ET54
WRWR
RWER
WREW
WRWER
RWER
SDG
EW
SF
DSFSF
fbbs
ubao
fhd
dfg
ewr
dg
df
ewwr
ewwr
et
ruyut
utut
dfg
fgd
gdfgt
etg
dfgt
dfgd
ert4
gd
fgg
wr
235
wer3
we
vsdf
sdf
gdf
ert
xcv
sdf
rwer
hfd
dfg
cvb
rwf
afb
dfh
jgh
bmn
lgh
rty
gfds
cxv
xcv
xcs
vdas
fdf
fgd
cv
sdf
tert
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
sdf
shasha9178
shasha9178
shasha9178
shasha9178
shasha9178
liflif2
liflif2
liflif2
liflif2
liflif2
liblib3
liblib3
liblib3
liblib3
liblib3
zhazha444
zhazha444
zhazha444
zhazha444
zhazha444
dende5
dende
denden
denden2
denden21
fenfen9
fenf619
fen619
fenfe9
fe619
sdf
sdf
sdf
sdf
sdf
zhazh90
zhazh0
zhaa50
zha90
zh590
zho
zhoz
zhozh
zhozho
zhozho2
lislis
lls95
lili95
lils5
liss9
sdf0ty987
sdft876
sdft9876
sdf09876
sd0t9876
sdf0ty98
sdf0976
sdf0ty986
sdf0ty96
sdf0t76
sdf0876
df0ty98
sf0t876
sd0ty76
sdy76
sdf76
sdf0t76
sdf0ty9
sdf0ty98
sdf0ty987
sdf0ty98
sdf6676
sdf876
sd876
sd876
sdf6
sdf6
sdf9876
sdf0t
sdf06
sdf0ty9776
sdf0ty9776
sdf0ty76
sdf8876
sdf0t
sd6
sdf06
s688876
sd688
sdf86