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

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

查看所有标签

猜你喜欢:

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

iOS面试之道

iOS面试之道

故胤道长、唐巧 / 电子工业出版社 / 2018-7 / 59.00元

《iOS面试之道》是作者将多年的工作经验和积累,结合具体面试内容总结而成的。 《iOS面试之道》共分为3部分。第1部分为面试准备,详细介绍求职中遇到的基本问题,作者根据其多年的经验,在面试流程、简历投递、复习准备方面给出了完善的参考意见和建议。第2部分为算法知识。算法几乎是各种水平的程序员都要面对的考查内容。该部分采用Swift语言重新审视了多种数据结构和算法原理,可以说是为iOS开发者量身......一起来看看 《iOS面试之道》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

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

HEX HSV 互换工具