Go并发编程小测验: 你能答对几道题?

栏目: Go · 发布时间: 5年前

内容简介:以下是10个Go并发编程的小测验,看看你能答对几道题?

以下是10个 Go 并发编程的小测验,看看你能答对几道题?

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"
}
main --> A --> B --> C
main

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()
}

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()
}
  • A: 不能编译
  • B: 无输出,正常退出
  • C: 程序hang住
  • D: panic

4 双检查实现单例

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()
	}
}
  • A: 不能编译
  • B: 可以编译,正确实现了单例
  • C: 可以编译,有并发问题,f函数可能会被执行多次
  • D: 可以编译,但是程序运行会panic

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)
}
1, 1
1, 2

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)
}
  • A: 不能编译
  • B: 可以编译,运行时正常,内存稳定
  • C: 可以编译,运行时内存可能暴涨
  • D: 可以编译,运行时内存先暴涨,但是过一会会回收掉

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())
	}
}
#goroutines: 1
#goroutines: 2

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)
}

9 Map

package main

import (
	"fmt"
	"sync"
)

func main() {
	var m sync.Map
	m.LoadOrStore("a",1)
	m.Delete("a")

	fmt.Println(m.Len())
}

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)
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Algorithms on Strings, Trees and Sequences

Algorithms on Strings, Trees and Sequences

Dan Gusfield / Cambridge University Press / 1997-5-28 / USD 99.99

String algorithms are a traditional area of study in computer science. In recent years their importance has grown dramatically with the huge increase of electronically stored text and of molecular seq......一起来看看 《Algorithms on Strings, Trees and Sequences》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具