gophercon2018 心得整理

紀錄一些我覺得不錯的重點

From https://github.com/duffn/gophercon2018


Design Guidelines

Interface And Composition Design

Design Philosophy:

Validation:

Use an interface when:

Don’t use an interface:

Resources:

Methods, interfaces and Embedding - William Kennedy
Composition with Go - William Kennedy
Reducing type hierarchies - William Kennedy
Interface pollution in Go - Burcu Dogan
Application Focused API Design - William Kennedy
Avoid interface pollution - William Kennedy

Concurrent Software Design

Concurrency is about managing multiple things at once. Like one person washing the dishes while they are also cooking dinner. You’re making progress on both but you’re only ever doing one of those things at the same time. Parallelism is about doing multiple things at once. Like one person cooking and placing dirty dishes in the sink, while another washes the dishes. They are happening at the same time.

Both you and the runtime have a responsibility in managing the concurrency of the application. You are responsible for managing these three things when writing concurrent software:

Design Philosophy:

Channel Design

Channels allow goroutines to communicate with each other through the use of signaling semantics. Channels accomplish this signaling through the use of sending/receiving data or by identifying state changes on individual channels. Don’t architect software with the idea of channels being a queue, focus on signaling and the semantics that simplify the orchestration required.

Language Mechanics:

Design Philosophy:

Depending on the problem you are solving, you may require different channel semantics. Depending on the semantics you need, different architectural choices must be taken.

From: https://github.com/ardanlabs/gotraining/blob/master/topics/go/README.md


Scheduler

切換時機

key point

thread spinning

limitations

From: https://speakerdeck.com/kavya719/the-scheduler-saga


Patterns

DONT use callback:

1
2
3
4
5
6
func Fetch(name string, f func(string)) {
	go func() {
		...
		f(s)
	} ()
}

DO use Future:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func Fetch(name string) <-chan string {
	ch := make(chan string, 1)
	go func() {
		...
		c <- s
	} ()
	return c
}

func main() {
	a := Fetch("a")
	b := Fetch("b")
	consume(<-a, <-b)
}

DO use producer-consumer queue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func Glob(pat string) <-chan string {
	ch := make(chan string)
	go func() {
		defer close(ch)
		for ... {
			...
			ch <- s
		}
	}
	return ch
}

func main() {
	for s := range Glob("a*") {
		...
	}
}

From: https://drive.google.com/file/d/1nPdvhB0PutEJzdCq5ms6UI58dp50fcAN/view


Allocation

curl localhost:6060/debug/pprof/trace?seconds=5 > trace.out
go tool trace trace.out

memory allocation analysis
https://github.com/loov/view-annotated-file

reduce allocation times because we need to do on every allocation:

recycle allocation: sync.Pool

From: https://speakerdeck.com/emfree/allocator-wrestling