Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Introduction à Go
Novembre 2016
Sylvain Wallez
Software Engineer, Elastic Cloud
Elastic.co
Au menu
A propos...
Origines de Go, qui l'utilise ?
Comparaison de Go et Java
Exemples
Programmation concurrente
La boîte ...
About me...
Origines de Go
"Go is an open source programming language that makes it easy to build simple, reliable,
and efficient softwa...
Les créateurs
Robert Griesemer : V8, Java HotSpot
Rob Pike : Unix team, créateur de UTF-8
Ken Thompson : inventeur du lang...
Utilisations de Go chez Google
Des milliers de développeurs, des millions de lignes de code.
Exemples publics :
Proxy SPDY...
Qui utilise Go ?
golang.org/wiki/GoUsers(http://golang.org/wiki/GoUsers)
Apcera, Bitbucket, bitly, Canonical, CloudFlare, ...
Qui utilise Go ?
OVH (job précédent):
- nouvelle génération de services internes
- outils de déploiement (Docker & co)
- K...
Comparaison de Go et Java
Beaucoup de points communs
Descendance de C (langage impératif, accolades)
Typage statique
Garbage collected
Memory safe (...
Go est (évidemment) différent
Compilation en exécutable natif. Pas de VM
Link statique, exécutable autosuffisant
Contrôle sur...
Beaucoup d'omissions volontaires
Pas de classes (mais des interfaces)
Pas de constructeurs
Pas d'héritage (mais compositio...
Pourquoi Go fait ces omissions ?
Volonté des créateurs du langage :
La clarté du code est primordiale.
En lisant du code, ...
Exemples
Go, une syntaxe familière quand on vient de C ou Java
Main.java
public class Main {
public static void main(String[] args)...
Hello, web server
Les types viennent après les noms.
Les noms Capitalisés sont publics. Les autres noms sont privés (packa...
Exemple : recherche sur Google
func main() {
http.HandleFunc("/search", handleSearch)
fmt.Println("serving on http://local...
Valider la requête
func handleSearch(w http.ResponseWriter, req *http.Request) {
log.Println("serving", req.URL)
// Check ...
Collecter les résultats
// Run the Google search.
start := time.Now()
results, err := Search(query)
elapsed := time.Since(...
Afficher les résultats
// Render the results.
type templateData struct {
Results []Result
Elapsed time.Duration
}
err = resu...
Les templates HTML
Dans librairie standard, similaire à Mustache
Paramètres : maps et objets Go
// A Result contains the t...
Envoyer une requête à l'API Google Search
func Search(query string) ([]Result, error) {
// Prepare the Google Search API r...
Parser la réponse JSON dans une structure Go
// https://developers.google.com/web-search/docs/#fonje
var jsonResponse stru...
Terminé pour le front-end !
Nous n'avons utilisé que la librairie standard :
import (
"encoding/json"
"fmt"
"html/template...
L'exécution concurrente en Go
Communicating Sequential Processes (Tony Hoare, 1978)
Les programmes concurrents sont structurés en :
processus indépendan...
Goroutines
Les goroutines sont comme des threads légers.
Elles démarrent avec des petites piles (stack) qui sont retaillée...
Channels
Le canal de communication entre les goroutines.
c := make(chan string)
// goroutine 1
go func() {
c <- "hello!"
}...
Select
Un select bloque jusqu'à ce que envoi ou réception soient possibles.
select {
case n := <-in:
fmt.Println("received...
Exemple : Recherche Google (côté serveur)
A partir de mots-clés, renvoyer une page de résultats :
faire une recherche sur ...
Un Google fake en 6 lignes
On simule une recherche par un délai aléatoire de 100 ms maximum.
var (
Web = fakeSearch("web")...
Google Search : le main()
func main() {
start := time.Now()
results := GoogleSearch("golang")
elapsed := time.Since(start)...
Google Search (séquentiel)
La fonction GoogleSearch prend une chaîne de recherche, et renvoie une slice de Results
(des st...
Google Search (parallèle)
On lance les recherches en parallèle, et on attend tous les résultats.
Les func anonymes sont de...
Google Search (parallèle + timeout)
On n'attend pas les serveurs qui traînent.
Pas de lock, pas de synchronized, pas de ca...
Les outils
Go : l'outillage
La commande 'go' :
go fmt(http://play.golang.org/p/GPqra77cBK): formatage selon les règles canoniques
go ...
Quelques liens
Tutoriel interactif
tour.golang.org(http://tour.golang.org)
Effective Go : un must read pour aller plus loin...
Thank you
Sylvain Wallez
Software Engineer, Elastic Cloud
Elastic.co
@bluxte(http://twitter.com/bluxte)
sylvain@bluxte.net...
Introduction au langage Go
Prochain SlideShare
Chargement dans…5
×

Introduction au langage Go

556 vues

Publié le

Introduction au langage Go, avec comparaisons à Java
Présentation donnée dans différents meetups et conférences en 2015 et 2016.

Sources : https://github.com/swallez/golang-talks/

Publié dans : Logiciels
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Introduction au langage Go

  1. 1. Introduction à Go Novembre 2016 Sylvain Wallez Software Engineer, Elastic Cloud Elastic.co
  2. 2. Au menu A propos... Origines de Go, qui l'utilise ? Comparaison de Go et Java Exemples Programmation concurrente La boîte à outils de Go Adapté de "Go for Java Programmers(http://talks.golang.org/2015/go-for-java-programmers.slide)" de Sameer Ajmani
  3. 3. About me...
  4. 4. Origines de Go "Go is an open source programming language that makes it easy to build simple, reliable, and efficient software." -- golang.org(http://golang.org) Créé par Google à partir de 2007 pour des besoins internes : logiciels serveurs, architectures massivement distribuées (10⁶⁺ machines) adapté à des grands projets (5000+ développeurs) Open source depuis 2009 avec une communauté très active Langage stable depuis la version 1 début 2012 Actuellement : Go 1.7.3
  5. 5. Les créateurs Robert Griesemer : V8, Java HotSpot Rob Pike : Unix team, créateur de UTF-8 Ken Thompson : inventeur du langage B, ancètre du C
  6. 6. Utilisations de Go chez Google Des milliers de développeurs, des millions de lignes de code. Exemples publics : Proxy SPDY pour Chrome sur les mobiles Serveur de téléchargement pour Chrome, ChromeOS, Android SDK, Earth, etc. Load balancer Vitess pour MySQL (YouTube) Kubernetes, orchestrateur de cluster Docker La cible initiale est les services réseaux, mais c'est un langage généraliste.
  7. 7. Qui utilise Go ? golang.org/wiki/GoUsers(http://golang.org/wiki/GoUsers) Apcera, Bitbucket, bitly, Canonical, CloudFlare, Core OS, Digital Ocean, Docker, Dropbox, Facebook, Getty Images, GitHub, Hashicorp, Heroku, InfluxDB, Iron.io, Kubernetes, Medium, MongoDB services, Mozilla services, New York Times, pool.ntp.org, SmugMug, SoundCloud, Stripe, Square, Thomson Reuters, Tumblr...
  8. 8. Qui utilise Go ? OVH (job précédent): - nouvelle génération de services internes - outils de déploiement (Docker & co) - Kafka as a Service, Time Series as a Service Elastic (job actuel): - les Beats, agents de collectes de métrique
  9. 9. Comparaison de Go et Java
  10. 10. Beaucoup de points communs Descendance de C (langage impératif, accolades) Typage statique Garbage collected Memory safe (références nulles, contrôle des bornes à l'exécution) Les variables sont toujours initialisées (zero/nil/false) Méthodes Interfaces Assertions sur les types (instanceof) Reflection et introspection
  11. 11. Go est (évidemment) différent Compilation en exécutable natif. Pas de VM Link statique, exécutable autosuffisant Contrôle sur l'organisation mémoire Les fonctions sont des valeurs String est un type primitif, représenté en UTF-8 Maps et array/slices : types primitifs Goroutines et channels : concurrence définie dans le langage
  12. 12. Beaucoup d'omissions volontaires Pas de classes (mais des interfaces) Pas de constructeurs Pas d'héritage (mais composition) Pas de final Pas d'exceptions Pas de types génériques
  13. 13. Pourquoi Go fait ces omissions ? Volonté des créateurs du langage : La clarté du code est primordiale. En lisant du code, comprendre ce qu'il fait doit être clair immédiatement. En écrivant du code, savoir comment l'écrire doit être clair immédiatement. Un peu de redondance vaut parfois mieux qu'une factorisation obscure. Pour plus d'infos : Less is exponentially more (Pike, 2012)(http://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html) Go at Google: Language Design in the Service of Software Engineering (Pike, 2012) (http://talks.golang.org/2012/splash.article)
  14. 14. Exemples
  15. 15. Go, une syntaxe familière quand on vient de C ou Java Main.java public class Main { public static void main(String[] args) { System.out.println("Hello, world!"); } } hello.go package main import "fmt" func main() { fmt.Println("Hello, world!") } Run
  16. 16. Hello, web server Les types viennent après les noms. Les noms Capitalisés sont publics. Les autres noms sont privés (package). Il y a des types pointeurs. package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/hello", handleHello) fmt.Println("serving on http://localhost:7777/hello") log.Fatal(http.ListenAndServe("localhost:7777", nil)) } func handleHello(w http.ResponseWriter, req *http.Request) { log.Println("serving", req.URL) fmt.Fprintln(w, "Hello, world!") } Run
  17. 17. Exemple : recherche sur Google func main() { http.HandleFunc("/search", handleSearch) fmt.Println("serving on http://localhost:8080/search") log.Fatal(http.ListenAndServe("localhost:8080", nil)) } // handleSearch handles URLs like "/search?q=golang" by running a // Google search for "golang" and writing the results as HTML to w. func handleSearch(w http.ResponseWriter, req *http.Request) { Run
  18. 18. Valider la requête func handleSearch(w http.ResponseWriter, req *http.Request) { log.Println("serving", req.URL) // Check the search query. query := req.FormValue("q") if query == "" { http.Error(w, `missing "q" URL parameter`, http.StatusBadRequest) return } query := req.FormValue("q") initialise une nouvelle variable query du type de l'expression (string). FormValue est une méthode sur le type *http.Request : package http type Request struct {...} func (r *Request) FormValue(key string) string {...}
  19. 19. Collecter les résultats // Run the Google search. start := time.Now() results, err := Search(query) elapsed := time.Since(start) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } Search renvoie 2 valeurs : une "slice" de résultats, et une erreur. func Search(query string) ([]Result, error) {...} Les résultats sont valides uniquement si l'erreur est nil type error interface { Error() string // a useful human-readable error message } Les erreurs peuvent contenir des infos complémentaires, accessibles via des cast ("type assertion").
  20. 20. Afficher les résultats // Render the results. type templateData struct { Results []Result Elapsed time.Duration } err = resultsTemplate.Execute(w, templateData{ Results: results, Elapsed: elapsed, }); if err != nil { log.Print(err) return } resultsTemplate.Execute produit du HTML et l'écrit dans un io.Writer : type Writer interface { Write(p []byte) (n int, err error) } http.ResponseWriter implémente l'interface io.Writer.
  21. 21. Les templates HTML Dans librairie standard, similaire à Mustache Paramètres : maps et objets Go // A Result contains the title and URL of a search result. type Result struct { Title, URL string } var resultsTemplate = template.Must(template.New("results").Parse(` <html> <head/> <body> <ol> {{range .Results}} <li>{{.Title}} - <a href="{{.URL}}">{{.URL}}</a></li> {{end}} </ol> <p>{{len .Results}} results in {{.Elapsed}}</p> </body> </html> `)) Run
  22. 22. Envoyer une requête à l'API Google Search func Search(query string) ([]Result, error) { // Prepare the Google Search API request. u, err := url.Parse("https://ajax.googleapis.com/ajax/services/search/web?v=1.0") if err != nil { return nil, err } q := u.Query() q.Set("q", query) u.RawQuery = q.Encode() // Issue the HTTP request and handle the response. resp, err := http.Get(u.String()) if err != nil { return nil, err } defer resp.Body.Close() L'instruction defer resp.Body.Close est équivalente au finally Java
  23. 23. Parser la réponse JSON dans une structure Go // https://developers.google.com/web-search/docs/#fonje var jsonResponse struct { // anonymous structure ResponseData struct { Results []struct { TitleNoFormatting, URL string } } } if err := json.NewDecoder(resp.Body).Decode(&jsonResponse); err != nil { return nil, err } // Extract the Results from jsonResponse and return them. var results []Result for _, r := range jsonResponse.ResponseData.Results { results = append(results, Result{Title: r.TitleNoFormatting, URL: r.URL}) } return results, nil }
  24. 24. Terminé pour le front-end ! Nous n'avons utilisé que la librairie standard : import ( "encoding/json" "fmt" "html/template" "log" "net/http" "net/url" "time" ) Les serveurs Go tiennent la charge : chaque requête tourne dans une goroutine séparée. Goroutine ?
  25. 25. L'exécution concurrente en Go
  26. 26. Communicating Sequential Processes (Tony Hoare, 1978) Les programmes concurrents sont structurés en : processus indépendants qui s'exécutent séquentiellement et communiquent en échangeant des messages. L'exécution séquentielle est facile à comprendre. Pas les callbacks ! Les primitives Go : goroutines, channels, et l'instruction select.
  27. 27. Goroutines Les goroutines sont comme des threads légers. Elles démarrent avec des petites piles (stack) qui sont retaillées selon les besoins. Un programme Go peut avoir des milliers de goroutines actives. On démarre une goroutine avec l'instruction go : doSomething() go doSomethingElse(arg1, arg2) // Forked in a separate goroutine doAnotherThing() Le runtime Go ordonnance les goroutines sur des threads de l'OS Une goroutine bloquée ne bloque pas un thread !
  28. 28. Channels Le canal de communication entre les goroutines. c := make(chan string) // goroutine 1 go func() { c <- "hello!" }() // goroutine 2 go func() { s := <-c fmt.Println(s) // "hello!" }()
  29. 29. Select Un select bloque jusqu'à ce que envoi ou réception soient possibles. select { case n := <-in: fmt.Println("received", n) case out <- v: fmt.Println("sent", v) } Le default permet de ne pas bloquer. select { case out <- v: fmt.Println("sent", v) default: fmt.Println("No message, moving on") }
  30. 30. Exemple : Recherche Google (côté serveur) A partir de mots-clés, renvoyer une page de résultats : faire une recherche sur le Web faire une recherche sur Youtube faire une recherche sur Google Maps faire une recherche dans les News, etc sélectionner des pubs (faut bien vivre !) assembler les résultats (et les pubs)
  31. 31. Un Google fake en 6 lignes On simule une recherche par un délai aléatoire de 100 ms maximum. var ( Web = fakeSearch("web") Image = fakeSearch("image") Video = fakeSearch("video") // ... other sources ) type Result string type Search func(query string) Result func fakeSearch(kind string) Search { return func(query string) Result { time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) return Result(fmt.Sprintf("%s result for %qn", kind, query)) } } fakeSearch est une fonction qui retourne une fonction
  32. 32. Google Search : le main() func main() { start := time.Now() results := GoogleSearch("golang") elapsed := time.Since(start) fmt.Println(results) fmt.Println(elapsed) } Run
  33. 33. Google Search (séquentiel) La fonction GoogleSearch prend une chaîne de recherche, et renvoie une slice de Results (des string). Lance sequentiellement les recherches Web, Image, et Video, et ajoute leurs résultats à la slice de résultats. Temps total = somme des temps individuels func GoogleSearch(query string) (results []Result) { results = append(results, Web(query)) results = append(results, Image(query)) results = append(results, Video(query)) return } Run
  34. 34. Google Search (parallèle) On lance les recherches en parallèle, et on attend tous les résultats. Les func anonymes sont des closures sur query and c. Temps total = temps de la requête la plus longue func Google(query string) (results []Result) { c := make(chan Result) go func() { c <- Web(query) }() go func() { c <- Image(query) }() go func() { c <- Video(query) }() for i := 0; i < 3; i++ { result := <-c results = append(results, result) } return } Run
  35. 35. Google Search (parallèle + timeout) On n'attend pas les serveurs qui traînent. Pas de lock, pas de synchronized, pas de callbacks ! c := make(chan Result, 3) go func() { c <- Web(query) }() go func() { c <- Image(query) }() go func() { c <- Video(query) }() timeout := time.After(80 * time.Millisecond) for i := 0; i < 3; i++ { select { case result := <-c: results = append(results, result) case <-timeout: fmt.Println("timed out") return } } return Run
  36. 36. Les outils
  37. 37. Go : l'outillage La commande 'go' : go fmt(http://play.golang.org/p/GPqra77cBK): formatage selon les règles canoniques go vet : "checkstyle" par les devs de Go go doc : javadoc-like. Tout le Go open source sur godoc.org(http://godoc.org) go get : téléchargement/installation de packages IDE : plugins IntelliJ, Eclipse, Sublime, Vim... Compilation cross-platform (Yay Raspberry Pi !) Compilation pour mobiles (applis ou librairies Android et iOS)
  38. 38. Quelques liens Tutoriel interactif tour.golang.org(http://tour.golang.org) Effective Go : un must read pour aller plus loin golang.org/doc/effective_go.html(https://golang.org/doc/effective_go.html) Collection de liens, de trucs et astuces, etc. golang.org/wiki/Learn(http://golang.org/wiki/Learn) Cette présentation github.com/swallez/golang-talks/(https://github.com/swallez/golang-talks/)
  39. 39. Thank you Sylvain Wallez Software Engineer, Elastic Cloud Elastic.co @bluxte(http://twitter.com/bluxte) sylvain@bluxte.net(mailto:sylvain@bluxte.net)

×