Kto jest głównym pomysłodawcą języka
- Rob Pike (Unix, UTF-8)
- Ken Thompson (Unix author, UTF-8, B lang)
- Robert Griesemer (V8, Java Hotspot (Oracle Java), GFS)
lista kontrybutorów https://golang.org/AUTHORS
Dlaczego go zostało stworzone przez Google? Chcieli rozzwiązać problemy z DUŻYMI aplikacjami które mieli napisane w Google:
- przyspieszyć development
- multicore systems
źródła:
- https://golang.org/doc/faq#What_is_the_purpose_of_the_project
- https://talks.golang.org/2012/splash.article
- Statycznie kompilowany (jedna binarka ze wszystkimi zależnościami)
- Garbage Collected
- Silnie typowany
- Funkcyjno - Pseudo obiektowa hybryda
- łatwy deploy aplikacji (kod nie ma zależności - jenda binarka) + statics
- brak wojny o code style
gofmt
- zintegrowany package manager
go get
- zintegrowane sprawdzanie poprawności kodu
go vet
takżegolint
(github.com/golang/lint) gocode
serwer do intellisense - nie musisz miec IDE aby ci podpowiadało możesz pisać w swoim ulubionym edytorze (Sublime, Atom, Vim)- szybkie budowanie binarek
- ciekawa standardowa biblioteka template/html, performant www servers, json, xml streams, io, buffers, first class citizen concurrency
- kompilacja na wiele maszyn (cross-compilation)
- łatwy i przyjemny setup środowiska (edytory, ide, code completition server)
- wbudowane testy
- bardzo niski próg wejścia aby zacząć pisać
- hype w internetach, jeden z większych wzrostów w trendach na githubie oraz google trends (Tiobe kłamie!)
- brak zarządzania wersjami w package managerze (go get only honors URLs?)
3rd party -
godep
- w go 1.5 została dodana flaga która pozwoli na ładowanie w podobny sposób jak godep to robi (istnieje co prawda zarządzanie na poziomie pkg server przykład mongo "gopkg.in/mgo.v2/bson") zmieniamy API podbijamy wersję, API kompatybilne
- często jeszcze młode biblioteki przykład gin i skopany cache w contrib repo
go get github.com/exu/go-workshops
cd $GOPATH/exu/go-workshops
Architektura web aplikacji
- PHP: Reqest - response app
- Go: Serwery aplikacyjne (a'la NodeJs, Ruby, Python)
Typ
- PHP: Skryptowy (z OPCache)
- Go: Kompilowany
Typowanie
- PHP: Dynamiczne (static z dupy w PHP7)
- Go: Statyczne
Zaprojektowany jako:
- PHP: HTML generator
- Go: Łatwo zarządzalny następca C dla większych projektów
Entry level
- PHP: Trochę trzeba się naumieć aby przykrywać niekompetencje frameworków innymi design patternami
- Go: niski dla podstawowych, trzeba zrozumieć concurrency i kilka dziwnych rozwiązań (np: err handling)
Główny paradygmat
- PHP: Pseudo Java OO
- Go: Pseudo-funkcyjny / Pseudo-Obiektowość da się zamodelować na struct'ach
RPSy
- PHP: Req-Response boli, zamodelowanie Event-loop'a kopnie cie w tylek
- Go: "Concurrency as CORE feature" WWW serwer może być wystarczająco szybki
Użycie w świecie:
- PHP: Tu wygrywa bardzo dużo softu, mało ciekawych projektów
- Go: Jak już coś wychodzi o czym słychać to z reguły jest fajne :)
w Go projekty są uporządkowane zgodnie z "github style" - częścią ścieżki jest adres serwera na którym hostowane jest projekt / biblioteka
src/
github.com
exu
mysuperproject
ioki.com.pl
mnmel
nmelinium
bin/
superappbinary
pkg/
compiled packages
Zmienna środowiskowa $GOPATH
decyduje gdzie się znajdują te katalogi w
twoim systemie.
- go test - wbudowane testowanie
- go fmt - code formater - tylko jeden słuszny coding standard (https://golang.org/pkg/fmt/)
- gocode - autocomplete service (https://github.com/nsf/gocode)
- go vet - znajduje błędy (http://godoc.org/golang.org/x/tools/cmd/vet)
- go oracle - wyszukiwanie zależności (http://golang.org/s/oracle-user-manual)
- godoc - generator dokumentacji
-
IntelliJ Go plugin
-
LiteIDE
-
TODO SublimeText
-
TODO Atom
- BRA
- Unit
- Http
- Bdd tools
- Blackbox testing
- Benchmarking
- Chromedriver example
Go nie posiada wbudowanej biblioteki do asercji, istnieje za to wiele projektów open source:
- http://onsi.github.io/gomega/
- https://github.com/assertgo/assert
- https://github.com/stretchr/testify
Storages:
-
Mongo
-
RethinkDB
-
Redis
-
MySQL?
-
Cassandra?
- echo (MUX)
- gin (MUX)
- beego (większy z ORMem)
- vegeta
live app monitoring
ale to jest trochę słabe
##3 Delve
Filmik autora z Gophercona: https://www.youtube.com/watch?v=InG72scKPd4
https://github.com/bradfitz/talk-yapc-asia-2015/blob/master/talk.md
Github style struktura projektu BASICS IMPORTING CODE
w Go projekty są uporządkowane zgodnie z "github style" - częścią ścieżki jest adres serwera na którym hostowane jest projekt / biblioteka
src/
github.com
exu
mysuperproject
ioki.com.pl
mnmel
nmelinium
bin/
superappbinary
pkg/
compiled packages
Zmienna środowiskowa $GOPATH
decyduje gdzie się znajdują te katalogi w
twoim systemie.
W go package jest zbiorem plików z dyrektywą package nazwa
Package default'owo jest importowany po pełnej ścieżce ścieżce
import "github.com/exu/go-workshops/010-basics-importing/sub"
Zmienne BASICS VARIABLES CODE
W go zmienne nie muszą mieć z góry określonego typu, możemy przypisać
zmienną w postaci a := 1
kompilator będzie wiedział że ma doczynienia
z typem int.
Stałe BASICS CONSTANTS CODE
Obsługa standardowa, fajna rzecz iota
(taki autoincrement)
Funkcje BASICS FUNCTIONS CODE
Funkcje w go to "First class citizen".
Pętle BASICS LOOPS CODE
W go istnieje tylko jedna pętla: for
. Wykorzystywana jest jednak w różnych
wariantach, często używana ze słowem kluczowym range
Inicjalzacja package'u BASICS INIT CODE
func init() {}
odpowiada za zainicjowanie paczki, jest wykonywana tylko
przy pierwszym imporcie paczki.
Tablice BASICS ARRAYS CODE
Tablice w Go to niskopoziomowa struktura danych, najczęściej z nich nie korzystasz zamiast tego wykorzystujemy slice'y nakładkę na typy tablicowe znacznie ułatwiającą pracę z nimi
Slices BASICS SLICES CODE
Slice to "nakładka" na tablicę, trzyma do niej referencję jak przypiszesz slice do slice'a to będą wskazywać na tą samą tablicę.
źródła:
- https://blog.golang.org/slices
- https://github.com/golang/go/wiki/SliceTricks
- https://blog.golang.org/go-slices-usage-and-internals
- http://research.swtch.com/godata
- http://blog.golang.org/go-slices-usage-and-internals
- http://www.dotnetperls.com/slice-go
Mapy BASICS MAPS CODE
Mapy są statycznie typowane jak inne struktury w go, jeżeli potrzebujesz
przechowywać różne typy w jednej mapie możesz uzyć interface{}
oznaczjącego
dowolny typ
Struktury BASICS STRUCTS DEFINING CODE
Struktury to podstawowy typ danych w go, większość driverów do storage'u pozwala kodować i dekodować do struktur. są bardzo użyteczne, dzięki nim możemy zamodelować pseudo-obiektowość, często używane do kompzycji oprogramowania.
Struktury - Kompoozycja BASICS STRUCT COMPOSITION CODE
Kompozycja taki pattern chyba znacie ?
Tagi - annotacje BASICS STRUCT TAGS CODE
Struktury w go posiadają możliwość opisywania pól dodatkowymi "tagami" które następnie możemy wykorzystać programistycznie wykorzystywane często przy enkodowaniu i dekodowaniu z formatów danych (JSON, yml) jak i z różnych silników baz danych.
Interface'y BASICS INTERFACES CODE
Go posiada tzw "implicit interfaces", oznacza to że jeżeli dana struktura implementuje metody z interfejsu automatycznie staje się obikektem o typie równym typie intefejsu.
Zarządzanie błędami BASICS ERRORS CODE
W go nie ma exceptionów, błędy są zwracane poprzez wielokrotne wartości lub agregowane w obiektach jeżeli zachodzi taka potrzeba. Preferuje się podejście jak najszybszej obsługi błędów. W Go błąd jest wartością na którą masz reagować.
Źródła:
Panics BASICS PANICS CODE
- Używamy gdy chcemy zatrzymać program.
- Możemy podpiąć sprawdzenie do "defer chain" czy panic wystąpił
Stringi BASICS STRINGS CODE
Podstawowa struktura danych w większości problemów programistycznych tu też jest i ma wszystko czego potrzebujesz.
Go routines BASICS GOROUTINES CODE
Concurrency. Goroutine to lekki "wątek" uruchamiany wewnątrz programu Goroutines są bardzo lekkie więc uruchomienie równolegle wielu tysięcy nie kosztuje nas zbyt wiele zasobów.
Używanie tzw 3rd parties BASICS 3RD PARTY PACKAGES CODE
Go posiada zintegrowany package manager (bez wersjonowania jeszcze niestety)
go get
pozwala nam w łatwy sposób ściągnąć paczki oraz je uruchamiać.
dzięki powyższej komendzie zostaną ściągnięte wszystkie zależności związane
z packagem main
Example project structure BASICS PROJECT STRUCTURE CODE
Streams - Przykłady STDLIB STREAMS CODE
implementują io.Reader
implementują io.Writer
.
koniec.
Podstawowe operacje na IO, Bufory STDLIB IO CODE
Instalacja DATABASES MYSQL CODE
Uruchom
cd docker/mysql
docker-compose start
mysql -uroot -proot -P7701 -h127.0.0.1 < init.sql
mysql -uroot -proot -P7701 -h127.0.0.1
Przykłady MongoDB DATABASES MONGODB CODE
RethinkDB DATABASES RETHINKDB CODE
Jedną z ciekawych funkcjonalności RethinkDB jest możliwość monitorowania zmian na kolekcji
docker run --name some-rethink -v "$PWD:/data" -d rethinkdb
mozemy również zmapować porty do lokalnej maszynki
docker run --name rethink -p 28015:28015 -v "$PWD/data:/data" -d rethinkdb
wtedy instacja kontenera będzie widoczna pod adresem localhost:28015
docker run --name some-app --link some-rethink:rdb -d application-that-uses-rdb
go readline implementation LIBS READLINE CODE
https://github.com/chzyer/readline
Caddy webserver LIBS CADDY CODE
Profilowanie PROFILING CODE
Profilowanie standardowego programu
import (
"runtime/pprof"
)
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
func init() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
}
}
func main() {
defer pprof.StopCPUProfile()
Następnie budujemy binarkę i odpalamy ją z flagą cpuprofile
go build command.go && ./command -cpuprofile=data.prof
po czym możemy włączyć nasz profiler
go tool pprof command data.prof
Możemy do naszego programu dodać memory profile
var memprofile = flag.String("memprofile", "", "write memory profile to this file")
func memProfile() {
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal(err)
}
pprof.WriteHeapProfile(f)
f.Close()
return
}
}
informacje o pamięci zbierane są zbierane na końcu więc dorzucamy do defer list
func main() {
defer memProfile()
Teraz możemy zbierać informacje o obu profilach
go build command.go && ./command -cpuprofile=cpu.prof -memprofile=mem.prof
go tool pprof command cpu.prof
go tool pprof command mem.prof
package main
import (
"fmt"
"net/http"
_ "net/http/pprof"
)
func handler(w http.ResponseWriter, r *http.Request) {
for i := 0; i < 100000000; i++ {
w.Write([]byte(fmt.Sprintf("%d - %d, ", i, i)))
}
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
run in shell:
go tool pprof http://localhost:8080/debug/pprof/profile