introduction to go
TRANSCRIPT
![Page 1: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/1.jpg)
Introduction to GoGDG Korea DevFair 2014
장재휴Developer, Purpleworks
![Page 2: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/2.jpg)
Simple can be harder than complex
단 순 함 은 복 잡 함 보 다 어 렵 다 . 생 각 을 명 쾌 하 게 해 단 순 하 게 만 드 려 면 굉 장 히 노 력 해 야 한 다 . 하 지 만 결 국 그 럴 가 치 가 있 다 . 일 단 단 순 함 에 도 달 하 면 , 산 을 움 직 일 수 있 기 때 문 이 다 .
![Page 3: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/3.jpg)
Agenda
What is Go
OOP in Go
Concurrency in Go
Real world Go
![Page 4: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/4.jpg)
What is Go
![Page 5: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/5.jpg)
Why Go?
Statically typed languages ➔ Efficient vs Hard to write
Dynamic language ➔ Easy to use vs Slow
Speed vs Safety vs Ease to use
Concurrent programming is hard(thread, lock, mutex)
![Page 6: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/6.jpg)
What is go
A modern, general purpose language.
open source
Statically typed languages
Feel dynamically
concurrents
garbage-collected
efficient
simply
![Page 7: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/7.jpg)
OOP in Go
![Page 8: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/8.jpg)
1. Object via struct and method
No Classes. No "Objects"
But Go is object-based
![Page 9: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/9.jpg)
Object in Go
package main
import "fmt"
// Type Declaration (Struct)type Rect struct { width int height int}
// Declaring a Methodfunc (r *Rect) Area() int {func (r *Rect) Area() int { return r.width * r.height}
// In Actionfunc main() { r := Rect{width: 10, height: 5} fmt.Println("area: ", r.Area())fmt.Println("area: ", r.Area())} Run
![Page 10: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/10.jpg)
Object in Go II
// Type Declaration (built-in type)type Rects []Recttype Rects []Rect
// Declaring a Methodfunc (rs Rects) Area() int {func (rs Rects) Area() int { var a int for _, r := range rs { a += r.Area() } return a}
// In Actionfunc main() { r := Rect{width: 10, height: 5} x := Rect{width: 7, height: 10} rs := Rects{r, x} fmt.Println("r's area: ", r.Area()) fmt.Println("x's area: ", x.Area()) fmt.Println("total area: ", rs.Area())} Run
![Page 11: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/11.jpg)
2. Code reuse
No Inheritance
Composition over inheritance principle
![Page 12: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/12.jpg)
Composition in Go
// Type Declaration (Struct)type Address struct { Number, Street, City, State string}
// Embedding Typestype Person struct { Name string AddressAddress}
func main() { // Declare using Composite Literal p := Person{ Name: "Steve", Address: Address{Number: "13", Street: "Main", City: "Gotham", State: "NY"},Address: Address{Number: "13", Street: "Main", City: "Gotham", State: "NY"}, } fmt.Println(p) fmt.Println(p.Address)} Run
![Page 13: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/13.jpg)
Composition in Go II
// Declaring a Methodfunc (a *Address) String() string { return a.Number + " " + a.Street + "\n" + a.City + ", " + a.State + " " + "\n"}
func (p *Person) String() string { return p.Name + "\n" + p.Address.String()return p.Name + "\n" + p.Address.String()}
func main() { p := Person{ Name: "Steve", Address: Address{Number: "13", Street: "Main", City: "Gotham", State: "NY"}, } fmt.Println(p.String()) fmt.Println(p.Address.String())} Run
![Page 14: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/14.jpg)
3. Polymorphism via interface
Interface is just set of methods
Interface define behavior (duck typing)
"If something can do this, then it can be used here"
![Page 15: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/15.jpg)
Interfaces in Go
type Rect struct { width int height int}type Rects []Rect
func (r Rect) Area() int {func (r Rect) Area() int { return r.width * r.height}
func (rs Rects) Area() int {func (rs Rects) Area() int { var a int for _, r := range rs { a += r.Area() } return a}
// Interface Declarationtype Shaper interface {type Shaper interface { Area() intArea() int}}
![Page 16: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/16.jpg)
Interfaces in Go II
// Interface Declarationtype Shaper interface { Area() int}
// Using Interface as Param Typefunc Describe(s Shaper) {func Describe(s Shaper) { fmt.Println("Area is:", s.Area())fmt.Println("Area is:", s.Area())}}
// In Actionfunc main() { r := Rect{width: 10, height: 5} x := Rect{width: 7, height: 10} rs := Rects{r, x}
Describe(r)Describe(r) Describe(x)Describe(x) Describe(rs)Describe(rs)} Run
![Page 17: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/17.jpg)
The Power of Interface
Writer interface in standard "io" package
// http://godoc.org/io#Writertype Writer interface { Write(p []byte) (n int, err os.Error)}
Fprintln function in standard "fmt" package
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
![Page 18: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/18.jpg)
The Power of Interface
In handle function, just write to io.Writer object
func handle(w io.Writer, msg string) { fmt.Fprintln(w, msg)}
The os.Stdout can be used for io.Writer.
func main() { msg := []string{"hello", "world", "this", "is", "an", "example", "of", "io.Writer"} for _, s := range msg { time.Sleep(100 * time.Millisecond) handle(os.Stdout, s)handle(os.Stdout, s) }} Run
![Page 19: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/19.jpg)
The Power of Interface
The http.ResponseWriter can be used for io.Writer.
localhost:4000/hello-world (http://localhost:4000/hello-world)
localhost:4000/this-is-an-example-of-io.Writer (http://localhost:4000/this-is-an-example-of-io.Writer)
func handle(w io.Writer, msg string) { fmt.Fprintln(w, msg)}
func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { handle(w, r.URL.Path[1:])handle(w, r.URL.Path[1:]) }) fmt.Println("start listening on port 4000") http.ListenAndServe(":4000", nil)} Run
![Page 20: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/20.jpg)
Concurrency in Go
![Page 21: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/21.jpg)
What is concurrency
Composition of independently executing computations.
It is not parallelism.
![Page 22: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/22.jpg)
Go's Concurrency is
Easy to understand.
Easy to use.
You don't need to be an expert!
![Page 23: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/23.jpg)
Go's approach
In UNIX: processes connected by pipes:
find ~/go/src | grep _test.go$ | xargs wc -l
In Go: goroutines connected by channels
![Page 24: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/24.jpg)
Fundamentals #1 - Goroutine
Independently executing function.
The go statement launches a function call as a goroutine
go f()go f(x, y, ...)
It's not a thread
Very lightweight
A goroutine has its own stack
A goroutine runs concurrently
![Page 25: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/25.jpg)
Goroutine example
func f(msg string, delay time.Duration) { for { fmt.Println(msg) time.Sleep(delay) }}
func main() { go f("A--", 300*time.Millisecond) go f("-B-", 500*time.Millisecond) go f("--C", 1100*time.Millisecond) time.Sleep(10 * time.Second)} Run
![Page 26: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/26.jpg)
Fundamentals #2 - Channel-based communication
Channel allow goroutines to exchange information and synchronize.
Define
chan intchan<- string // send-only channel<-chan T // receive-only channel
Create channel
ch = make(chan int)
Use
ch <- 1 // send value 1 on channel chx = <-ch // receive a value from channel ch
![Page 27: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/27.jpg)
Communicating goroutines
func f(msg string, delay time.Duration, ch chan string) { for { ch <- msg time.Sleep(delay) }}
func main() { ch := make(chan string) go f("A--", 300*time.Millisecond, ch) go f("-B-", 500*time.Millisecond, ch) go f("--C", 1100*time.Millisecond, ch)
for i := 0; i < 100; i++ { fmt.Println(i, <-ch) }} Run
![Page 28: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/28.jpg)
Communicating goroutines II
type Ball struct{ hits int }
func main() { table := make(chan *Ball) go player("ping", table) go player("pong", table)
table <- new(Ball) // game on; toss the ball time.Sleep(1 * time.Second) <-table // game over; grab the ball}
func player(name string, table chan *Ball) { for { ball := <-table ball.hits++ fmt.Println(name, ball.hits) time.Sleep(100 * time.Millisecond) table <- ball }} Run
![Page 29: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/29.jpg)
Philosophy
Goroutines give the efficiency of an asynchronous model.
But you can write code in a synchronous style.
"Don’t communicate by sharing memory . Instead, share memory by communicating."
![Page 30: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/30.jpg)
Real world Go
![Page 31: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/31.jpg)
mixquare.com
Microchats for everyone
Instantly create a channel any topic, location or event
![Page 32: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/32.jpg)
Message Flow
![Page 33: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/33.jpg)
Action of message processing worker
1. save message to datastore 2. fetch channel information 3. fetch user information 4. publish
![Page 34: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/34.jpg)
Measure First
ruby version
go version
![Page 35: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/35.jpg)
Concurrency
RPC-bound jobs are very common
Excuting next job while waiting
![Page 36: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/36.jpg)
Concurrency II
Run synchronously
err1 := msg.save()
c, err2 := msg.fetchChannel()msg.setChannel(c)
u, err3 := msg.fetchUser()msg.setUser(u)
if err1 != nil || err2 != nil || err3 != nil { /* ... */}
![Page 37: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/37.jpg)
Concurrency III
Run concurrently
errc := make(chan error)
go func() {go func() { err := msg.save() errc <- errerrc <- err }()
go func() {go func() { c, err := msg.fetchChannel() msg.setChannel(c) errc <- errerrc <- err }()
go func() {go func() { u, err := msg.fetchUser() msg.setUser(u) errc <- errerrc <- err }()
err1, err2, err3 := <-errc, <-errc, <- errcerr1, err2, err3 := <-errc, <-errc, <- errc if err1 != nil || err2 != nil || err3 != nil { /* ... */ }
![Page 38: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/38.jpg)
Result(Concurrency)
baseline
concurrency
![Page 39: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/39.jpg)
Caching
Using SQL can be slow
Using redis is good, but fault tolerance is too hard.
Solution: Timeout waiting
![Page 40: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/40.jpg)
Caching with control variance
func fetchUser(id string) (*User, error) { var u *User var err error
done := make(chan *User) go func() { u, _ := findFromRedis(id)u, _ := findFromRedis(id) done <- u }()
select {select { case u = <-done:case u = <-done: case <-time.After(REDIS_TIMEOUT * time.Millisecond):case <-time.After(REDIS_TIMEOUT * time.Millisecond): }}
if u == nil { u, err = findFromSql(id)u, err = findFromSql(id) if err != nil { return nil, err } saveToRedis(u)saveToRedis(u) } return u, nil}
![Page 41: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/41.jpg)
Result(Caching)
concurrency
caching
![Page 42: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/42.jpg)
Before and After
ruby version
go version
![Page 43: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/43.jpg)
Conclusion
![Page 44: Introduction to go](https://reader034.vdocuments.net/reader034/viewer/2022052602/55a209761a28aba5368b4569/html5/thumbnails/44.jpg)
Go is... not so great
Go is young language