2067 字
约 6 分钟
11
Go语言编程面试题
2026-09-25
无标签

Go语言编程面试题 秀才 2025年6月26日 大约 7 分钟 Go golang 代码面试题 此页内容 1. 1.开启100个协程,顺序打印1-1000,且保证协程号1的,打印尾数为1的数字 2. 2.三个goroutinue交替打印abc 10次 3. 3.用不超过10个goroutine不重复的打印slice中的100个元素 4. 4.两个协程交替打印奇偶数 5. 5.用单个channel实现0,1的交替打印 6. 6.sync.Cond实现多生产者多消费者 7. 7.使用go实现1000个并发控制并设置执行超时时间1秒 8. 8.使用两个Goroutine,向标准输出中按顺序按顺序交替打出字母与数字,输出是a1b2c3 9. 9.编写一个程序限制10个goroutine执行,每执行完一个goroutine就放一个新的goroutine进来 1. 1.开启100个协程,顺序打印1-1000,且保证协程号1的,打印尾数为1的数字

// 同时开启100个协程(分别为1号协程 2号协程 ... 100号协程,
// 1号协程只打印尾数为1的数字,2号协程只打印尾数为2的数,
// 以此类推),请顺序打印1-1000整数以及对应的协程号;

func main() {
 s := make(chan struct{})
 //通过map的key来保证协程的顺序
 m := make(map[int]chan int, 100)
 //填充map,初始化channel
 for i := 1; i <= 100; i++ {
 m[i] = make(chan int)
 }
 //开启100个协程,死循环打印
 //go func() { 这个协程不加也可以的
 for i := 1; i <= 100; i++ {
 go func(id int) {
 for {
 num := <-m[id]
 fmt.Println(num)
 s <- struct{}{}
 }
 }(i)
 }
 //}()
 //循环1-1000,并把值传递给匹配的map
 //然后通过s限制循序打印
 for i := 1; i <= 1000; i++ {
 id := i % 100
 if id == 0 {
 id = 100
 }
 m[id] <- i
 //通过s这个来控制打印顺序。每次遍历一次i
 //都通过s阻塞协程的打印,最后打印完毕
 <-s
 }

 time.Sleep(10 * time.Second)
}
  1. 2.三个goroutinue交替打印abc 10次
package main

import (
 "fmt"
 "sync"
)

func main() {
 // 定义3个channel
 ch1 := make(chan struct{})
 ch2 := make(chan struct{})
 ch3 := make(chan struct{})
 var wg sync.WaitGroup
 wg.Add(3)
 // 打印a
 go func() {
 defer wg.Done()
 for i := 0; i < 10; i++ {
 <-ch1
 fmt.Println("a")
 ch2 <- struct{}{}
 }
 // 第10次的时候,打印c的goroutine写入了ch1
 // 为了防止阻塞,要消费以下ch1
 <-ch1
 }()
 // 打印b
 go func() {
 defer wg.Done()
 for i := 0; i < 10; i++ {
 <-ch2
 fmt.Println("b")
 ch3 <- struct{}{}
 }
 }()
 // 打印c
 go func() {
 defer wg.Done()
 for i := 0; i < 10; i++ {
 <-ch3
 fmt.Println("c")
 ch1 <- struct{}{}
 }
 }()
 // 启动
 ch1 <- struct{}{}
 wg.Wait()
 close(ch1)
 close(ch2)
 close(ch3)
 fmt.Println("end")
}
  1. 3.用不超过10个goroutine不重复的打印slice中的100个元素
package main

import (
 "fmt"
 "sync"
)

// 用不超过10个goroutine不重复的打印slice中的100个元素
// 容量为10的有缓冲channel实现
// 每次启动10个,累计启动100个goroutine,且无序打印
func main() {
 var wg sync.WaitGroup
 // 创建切片
 ss := make([]int, 100)
 for i := 0; i < 100; i++ {
 ss[i] = i
 }
 ch := make(chan struct{}, 10)
 for i := 0; i < 100; i++ {
 wg.Add(1)
 ch <- struct{}{}
 // 写10个就阻塞了,此时goroutine中打印
 go func(idx int) {
 defer wg.Done()
 fmt.Printf("val: %d \n", ss[idx])
 // 打印结束,从缓冲channel中删除一个
 <-ch
 }(i)

 }
 wg.Wait()
 // 关闭channel
 close(ch)
 fmt.Println("end")
}

// 用不超过10个goroutine不重复的打印slice中的100个元素
// 创建10个无缓冲channel和10个goroutine
// 固定10个goroutine,且顺序打印
func test9() {
 var wg sync.WaitGroup
 // 创建切片
 ss := make([]int, 100)
 for i := 0; i < 100; i++ {
 ss[i] = i
 }
 // 创建channel和goroutine
 hashMap := make(map[int]chan int)
 sort := make(chan struct{})
 for i := 0; i < 10; i++ {
 hashMap[i] = make(chan int)
 wg.Add(1)
 go func(idx int) {
 defer wg.Done()
 for val := range hashMap[idx] {
 fmt.Printf("go id: %d, val: %d \n", idx, val)
 sort <- struct{}{}
 }
 }(i)
 }
 // 循环切片,对10取模,找到对应channel的key,写入值
 for _, v := range ss {
 id := v % 10
 hashMap[id] <- v
 // 有序
 <-sort
 }
 // 循环结束关闭channel,删除map的key
 for k, _ := range hashMap {
 close(hashMap[k])
 delete(hashMap, k)
 }
 wg.Wait()
 close(sort)
 fmt.Println("end")
}
  1. 4.两个协程交替打印奇偶数
package main

import (
 "fmt"
 "time"
)

func main() {
 //golang交替打印奇偶数
 //交替打印,可以通过channel来实现
 chan1 := make(chan struct{})
 //偶数
 go func() {
 for i := 0; i < 10; i++ {
 chan1 <- struct{}{}
 if i%2 == 0 {
 fmt.Println("打印偶数:", i)
 }
 }
 }()
 //奇数
 go func() {
 for i := 0; i < 10; i++ {
 <-chan1
 if i%2 == 1 {
 fmt.Println("打印奇数数:", i)
 }
 }
 }()
 //阻塞
 select {
 case <-time.After(time.Second * 10):
 }
}
  1. 5.用单个channel实现0,1的交替打印
package main

import (
 "fmt"
 "time"
)

func main() {
 msg := make(chan struct{})
 go func() {
 for {
 <-msg
 fmt.Println("0")
 msg <- struct{}{}
 }
 }()
 go func() {
 for {
 <-msg
 fmt.Println("1")
 msg <- struct{}{}
 }
 }()
 msg <- struct{}{}
 time.Sleep(3 * time.Minute)

}
  1. 6.sync.Cond实现多生产者多消费者
package main

import (
 "context"
 "fmt"
 "math/rand"
 "sync"
 "time"
)

func main() {
 var wg sync.WaitGroup
 var cond sync.Cond
 cond.L = new(sync.Mutex)
 msgCh := make(chan int, 5)
 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
 defer cancel()
 rand.Seed(time.Now().UnixNano())

 // 生产者
 producer := func(ctx context.Context, out chan<- int, idx int) {
 defer wg.Done()
 for {
 select {
 case <-ctx.Done():
 // 每次生产者退出,都唤醒一个消费者处理,防止最后有消费者线程死锁
 // 生产者比消费者多,所以cond.Signal()就可以。不然的话建议Broadcast()
 cond.Broadcast()
 fmt.Println("producer finished")
 return
 default:
 cond.L.Lock()
 for len(msgCh) == 5 {
 cond.Wait()
 }
 num := rand.Intn(500)
 out <- num
 fmt.Printf("producer: %d, msg: %d\n", idx, num)
 cond.Signal()
 cond.L.Unlock()
 }
 }
 }

 // 消费者
 consumer := func(ctx context.Context, in <-chan int, idx int) {
 defer wg.Done()
 for {
 select {
 case <-ctx.Done():
 // 消费者可以选择继续消费直到channel为空
 for len(msgCh) > 0 {
 select {
 case num := <-in:
 fmt.Printf("consumer %d, msg: %d\n", idx, num)
 default:
 // 如果channel已经空了,跳出循环
 break
 }
 }
 fmt.Println("consumer finished")
 return
 default:
 cond.L.Lock()
 for len(msgCh) == 0 {
 cond.Wait()
 }
 num := <-in
 fmt.Printf("consumer %d, msg: %d\n", idx, num)
 cond.Signal()
 cond.L.Unlock()
 }
 }
 }

 // 启动生产者和消费者
 for i := 0; i < 5; i++ {
 wg.Add(1)
 go producer(ctx, msgCh, i+1)
 }
 for i := 0; i < 3; i++ {
 wg.Add(1)
 go consumer(ctx, msgCh, i+1)
 }

 // 模拟程序运行一段时间
 wg.Wait()
 close(msgCh)
 fmt.Println("all finished")
}
  1. 7.使用go实现1000个并发控制并设置执行超时时间1秒
package main

import (
 "context"
 "fmt"
 "sync"
 "time"
)

func main() {
 // 创建 1000 个协程,并且进行打印
 // 总共超时时间 1s,1s 没执行完就超时,使用 ctx 进行控制

 // 定义任务 channel
 tasks := make(chan int, 1000)
 // 定义 ctx
 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
 defer cancel()
 var wg sync.WaitGroup

 // 启动 1000 个协程
 for i := 0; i < 1000; i++ {
 wg.Add(1)
 tasks <- i
 go func(id int) {
 defer wg.Done()
 select {
 case <-ctx.Done():
 return
 default:
 fmt.Printf("goroutine id: %d\n", id)
 }
 }(i)
 }

 <-ctx.Done()
 fmt.Println("exec done")
 close(tasks)
 wg.Wait()
 fmt.Println("finish")
}
  1. 8.使用两个Goroutine,向标准输出中按顺序按顺序交替打出字母与数字,输出是a1b2c3
package main

import (
 "fmt"
 "sync"
)

func main() {
 // 定义两个channel,一个打印数字,一个打印字母
 numCh := make(chan struct{})
 strCh := make(chan struct{})
 var wg sync.WaitGroup
 wg.Add(2)
 // 打印字符
 go func() {
 defer wg.Done()
 for i := 'a'; i <= 'z'; i++ {
 fmt.Println(string(i))
 // 通知打印数字
 numCh <- struct{}{}
 // 阻塞等待打印字母
 <-strCh
 }
 }()
 // 打印字母
 go func() {
 defer wg.Done()
 for i := 1; i <= 26; i++ {
 <-numCh
 fmt.Println(i)
 // 通知打印字母
 strCh <- struct{}{}
 }
 }()
 wg.Wait()
 fmt.Println("finished")
}
  1. 9.编写一个程序限制10个goroutine执行,每执行完一个goroutine就放一个新的goroutine进来
package main

import (
 "fmt"
 "sync"
)

// 编写一个程序限制10个goroutine执行,每执行完一个goroutine就放一个新的goroutine进来
func main() {
 var wg sync.WaitGroup
 ch := make(chan struct{}, 10)
 for i := 0; i < 20; i++ {
 wg.Add(1)
 ch <- struct{}{}
 go func(id int) {
 defer wg.Done()
 fmt.Println("id: %d", id)
 <-ch
 }(i)
 }
 wg.Wait()

}

关注秀才公众号: IT杨秀才 ,领取精品学习资料 公众号后台回复: Go面试 ,领取Go面试题库PDF 公众号后台回复: Go学习 ,领取Go必看书籍 公众号后台回复: 大模型 ,领取大模型学习资料 公众号后台回复: 111 ,领取架构学习资料 公众号后台回复: 26届秋招 ,领取26届秋招企业汇总表

🔥 配套实战项目,拆得开、跑得起、能写进简历 多 Agent 编排 + RAG 混合检索 · 31 篇深度教程 + 50+ 面试题 点击查看 DevSupport AI 实战项目 → 在 GitHub 上编辑此页 上次编辑于: 2026/6/24 23:41:22 贡献者: Percygu , Your Name , gupeng

Go语言编程面试题
https://clxhxhhr.top/posts/3633/
作者
clxstart
发布于
2026-09-25
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。