Here are 10 Go concurrent programming quizzes to see how many questions you can answer correctly.

1 Mutex

package main
import (
	"fmt"
	"sync"
)
var mu sync.Mutex
var chain string
func main() {
	chain = "main"
	A()
	fmt.Println(chain)
}
func A() {
	mu.Lock()
	defer mu.Lock()
	chain = chain + " --> A"
	B()
}
func B() {
	chain = chain + " --> B"
	C()
}
func C() {
	mu.Lock()
	defer mu.Lock()
	chain = chain + " --> C"
}Copy the code
  • A: Can’t compile
  • B: the outputmain --> A --> B --> C
  • C: outputmain
  • D: panic

2 RWMutex

package main
import (
	"fmt"
	"sync"
	"time"
)
var mu sync.RWMutex
var count int
func main() {
	go A()
	time.Sleep(2 * time.Second)
	mu.Lock()
	defer mu.Unlock()
	count++
	fmt.Println(count)
}
func A() {
	mu.RLock()
	defer mu.RUnlock()
	B()
}
func B() {
	time.Sleep(5 * time.Second)
	C()
}
func C() {
	mu.RLock()
	defer mu.RUnlock()
}Copy the code
  • A: Can’t compile
  • B: the output1
  • C: Program hang
  • D: panic

3 Waitgroup

package main
import (
	"sync"
	"time"
)
func main() {
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		time.Sleep(time.Millisecond)
		wg.Done()
		wg.Add(1)
	}()
	wg.Wait()
}Copy the code
  • A: Can’t compile
  • B: No output, exit normally
  • C: Program hang
  • D: panic

4 Double check implements a singleton

package doublecheck
import (
	"sync"
)
type Once struct {
	m    sync.Mutex
	done uint32
}
func (o *Once) Do(f func()) {
	if o.done == 1 {
		return
	}
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 {
		o.done = 1
		f()
	}
}Copy the code
  • A: Can’t compile
  • B: It can compile and implement singletons correctly
  • C: It can compile, there are concurrency issues, and the f function may be executed multiple times
  • D: It can compile, but the program will panic when running

5 Mutex

package main import ( "fmt" "sync" ) type MyMutex struct { count int sync.Mutex } func main() { var mu MyMutex mu.Lock()  var mu2 = mu mu.count++ mu.Unlock() mu2.Lock() mu2.count++ mu2.Unlock() fmt.Println(mu.count, mu2.count) }Copy the code
  • A: Can’t compile
  • B: the output1, 1
  • C: output1, 2
  • D: panic

6 Pool

package main import ( "bytes" "fmt" "runtime" "sync" "time" ) var pool = sync.Pool{New: func() interface{} { return new(bytes.Buffer) }} func main() { go func() { for { processRequest(1 << 28) // 256MiB } }()  for i := 0; i < 1000; i++ { go func() { for { processRequest(1 << 10) // 1KiB } }() } var stats runtime.MemStats for i := 0; ; i++ { runtime.ReadMemStats(&stats) fmt.Printf("Cycle %d: %dB\n", i, stats.Alloc) time.Sleep(time.Second) runtime.GC() } } func processRequest(size int) { b := pool.Get().(*bytes.Buffer) time.Sleep(500 * time.Millisecond) b.Grow(size) pool.Put(b) time.Sleep(1 * time.Millisecond) }Copy the code
  • A: Can’t compile
  • B: It can compile and run normally with stable memory
  • C: It can compile and memory may explode at runtime
  • D: It can be compiled, memory is inflated at runtime, but it will be reclaimed later

7 channel

package main
import (
	"fmt"
	"runtime"
	"time"
)
func main() {
	var ch chan int
	go func() {
		ch = make(chan int, 1)
		ch <- 1
	}()
	go func(ch chan int) {
		time.Sleep(time.Second)
		<-ch
	}(ch)
	c := time.Tick(1 * time.Second)
	for range c {
		fmt.Printf("#goroutines: %d\n", runtime.NumGoroutine())
	}
}Copy the code
  • A: Can’t compile
  • B: Always output after a period of time#goroutines: 1
  • C: Always output after a period of time#goroutines: 2
  • D: panic

8 channel

package main
import "fmt"
func main() {
	var ch chan int
	var count int
	go func() {
		ch <- 1
	}()
	go func() {
		count++
		close(ch)
	}()
	<-ch
	fmt.Println(count)
}Copy the code
  • A: Can’t compile
  • B: the output1
  • C: output0
  • D: panic

9 Map

package main
import (
	"fmt"
	"sync"
)
func main() {
	var m sync.Map
	m.LoadOrStore("a", 1)
	m.Delete("a")
	fmt.Println(m.Len())
}Copy the code
  • A: Can’t compile
  • B: the output1
  • C: output0
  • D: panic

10 happens before

package main
var c = make(chan int)
var a int
func f() {
	a = 1
	<-c
}
func main() {
	go f()
	c <- 0
	print(a)
}Copy the code
  • A: Can’t compile
  • B: the output1
  • C: output0
  • D: panic