O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Java und Go im Vergleich

215 visualizações

Publicada em

Code Days 2019, München: Vortrag von Johannes Weigend (@JohannesWeigend, Technischer Geschäftsführer bei QAware)

=== Dokument bitte herunterladen, falls unscharf! Please download slides if blurred! ===

Abstract:
Programmiersprachen für die Cloud - Java und Go im Vergleich
Java ist nach dem Tiobe Index 2018 unangefochten Platz 1 bei den weltweit eingesetzten Programmiersprachen. Java ist ausgereift, stabil und verfügt über ein immenses Open Source Ökosystem. Was will man mehr? Obwohl Java gerade für die Backend Entwicklung attraktiv ist, hat Google 2008 eine eigene Programmiersprache Open Source gestellt: Golang oder kurz Go. Der Vortrag beleuchtet die Stärken und Schwächen von Go gegenüber Java, gibt Hinweise für welche Projekte Go eine gute Alternative ist, und wie ein Best of Breed Ansatz aussehen kann. Interessant an Go ist, dass die Grundbausteine von Cloud Plattformen wie OpenShift oder die Google Container Plattform mit Go erstellt wurden. Docker, Kubernetes, Helm, Grafana oder Prometheus ‒ alles ist mit Go programmiert. Die Fragen aus der Sicht von Java-Experten sind: Was macht Go für die Cloud so interessant? Gibt es Funktionen, die Java Programmierer kennen sollten, und wenn ja, welche?

Publicada em: Software
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Java und Go im Vergleich

  1. 1. JAVA UND GO IM VERGLEICH PROGRAMMIERSPRACHEN FÜR DIE CLOUD JOHANNES WEIGEND | @JOHANNESWEIGEND | QAWARE GMBH | @QAWARE
  2. 2. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH AGENDA ▸ Warum Go? / Go im Überblick! ▸ Stärken von Java ▸ Stärken von Go ▸ Go vs. Java an Beispielen ▸ Go Konzepte, die ein Java Programmierer kennen sollte ▸ Best of Breed - Für welche Programme macht Go Sinn?
  3. 3. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH WARUM GO? ▸ Go wurde als C++ Alternative zur systemnahen Programmierung entwickelt ▸ Designziele • Einfachheit • Schnelle Kompilierung • Automatische und sichere Speicherverwaltung • Laufzeitunterstützung • Unterstützung von Nebenläufigkeit und Parallelität • Einfache Anbindung von C/C++ Code • Sprachfeatures aus modernen, dynamischen Sprachen ▸ Systemnahes Programmieren soll Spaß machen!
  4. 4. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH GO IST DIE WESENTLICHE SPRACHE IM CLOUD NATIVE STACK ▸ Alle wesentlichen Komponenten sind in Go geschrieben • Container Platform: (Docker), rkt, ContainerD • Cluster Orchestrator: Kubernetes, OpenShift • Cross Cutting: Prometheus, Jaeger, …
  5. 5. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH APPLICATIONS CLOUD PLATFORM OS GO C/C++ JAVA EINSATZGEBIETE VON JAVA UND GO - DER SWEET SPOT ANALYTICS WEBAPPS MICROSERVICES UTILITIES CROSS CUTTING DEVOPS AI SCALING SECURITY RESOURCEMGMT DRIVER OS EXTENSION
  6. 6. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH STÄRKEN VON JAVA ▸ Verbreitungsgrad ▸ Community ▸ Standards (JavaEE …) ▸ Open Source ▸ Open Source Ökosystem ▸ Multi Purpose - Multi Platform ▸ Tools 13 Mio JARs auf Maven Central Platz 1 im TIOBE Index
  7. 7. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH WARUM VERWENDEN CLOUD PLATTFORMEN GO? (SCHWÄCHEN VON JAVA) ▸ Memory und CPU • Java Anwendungen haben einen hohen Grundbedarf an Ressourcen (RAM, CPU - lange Startzeit verursacht durch Class Loading und Classpath Scanning (Spring/CDI)). ▸ Container • Java Anwendungen benötigen eine JVM. Aufgrund der JVM Abhängigkeiten enthalten viele Container ein komplettes OS Filesystem Image. ▸ Footprint • Ein Java Werkzeug benötigt aufgrund transitiver Abhängigkeiten schnell > 100 MB (z.B. Hadoop Client). Aufgrund der dynamischen Class Loader Architektur kann erst zur Laufzeit entschieden werden, welche Klassen wirklich benötigt werden. Oft ist das nur ein kleiner Prozentsatz des vorhandenen Codes.
  8. 8. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH WARUM VERWENDEN CLOUD PLATTFORMEN GO? (SCHWÄCHEN VON JAVA) ▸ Concurrency ▸ Parallelprogrammierung mit Java basiert auf Threads und Synchronisation (Mutex/Lock). Erst mit Java7 kamen Erweiterungen für asynchrones Programmieren (CompletableFuture) ▸ Threads sind schwergewichtige Betriebssystem Ressourcen. Ein Thread belegt ca. 1 MB an Ressourcen. ▸ ⇨ Thread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führen können, falls mehr Anfragen bearbeitet werden müssen als Threads im Pool zur Verfügung stehen. ▸ Komplexität ▸ Java ist einfach gestartet und hat sich über die Jahre zu einer sehr komplexen Programmiersprache entwickelt. Wenige Programmierer überblicken alle Sprachmittel im JDK und bei JavaEE ▸ Es macht Sinn sich Go genauer anzusehen!
  9. 9. UNTERSCHIEDE IM DETAIL
  10. 10. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH OOP IN JAVA - JAVA KENNT CODE NUR INNERHALB VON KLASSEN // Rational represents a rational number numerator/denominator. public class Rational { final private int numerator; final private int denominator; public Rational(int numerator, int denominator) { if (denominator == 0) { throw new RuntimeException("division by zero"); } int divisor = gcd(numerator, denominator); this.numerator = numerator / divisor; this.denominator = denominator / divisor; } public Rational Multiply(Rational y) { return new Rational(numerator * y.numerator, denominator * y.denominator) } ... }
  11. 11. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH GO KENNT KEINE KLASSEN UND TRENNT DATEN UND FUNKTIONEN! // Rational represents a rational number numerator/denominator. type Rational struct { numerator int denominator int } // Multiply method for rational numbers (x1/x2 * y1/y2) func (x Rational) Multiply(y Rational) Rational { return NewRational(x.numerator*y.numerator, x.denominator*y.denominator) } // NewRational constructor function func NewRational(numerator int, denominator int) Rational { if denominator == 0 { panic("division by zero") } r := Rational{} divisor := gcd(numerator, denominator) r.numerator = numerator / divisor r.denominator = denominator / divisor return r }
  12. 12. BEISPIEL BUCHINDEX
  13. 13. // Page contains an array of words. type Page []string // Book is an array of pages. type Book []Page // Index contains a list of pages for each word in a book. type Index map[string][]int // MakeIndex generates an index structure func MakeIndex(book Book) Index { idx := make(Index) for i, page := range book { for _, word := range page { pages := idx[word] idx[word] = append(pages, i) } } return idx }
  14. 14. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH WARUM KEINE KLASSEN? ▸ Weniger Code ▸ Geringere Schachtelung ▸ Keine No-Op Anweisungen „public static void“ ▸ Freiheitsgrade bei der Implementierung von Interfaces ▸ Embedding (=Aggregation) statt Vererbung ▸ Interfaces statt Klassenhierarchien
  15. 15. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH GO KENNT POINTER ▸ Pointer werden wie auch Werte per Kopie übergeben ▸ Es gibt keine Pointer Arithmetik (p++) wie in C/C++ ▸ Pointer sind automatisch mit nil initialisiert func swap1(x, y int) { x, y = y, x } func swap2(x *int, y *int) { *x, *y = *y, *x } func swap3(x **int, y **int) { *x, *y = *y, *x }
  16. 16. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH GO KENNT POINTER func main() { var a, b = 1, 2 fmt.Printf("a=%d, b=%dn", a, b) swap1(a, b) fmt.Printf("swap1(a,b) : a=%d, b=%dn", a, b) swap2(&a, &b) fmt.Printf("swap2(&a,&b) : a=%d, b=%dn", a, b) pa, pb := &a, &b swap3(&pa, &pb) fmt.Printf("swap3(&pa, &pb): a=%d, b=%dn", a, b) } a=1, b=2 swap1(a,b) : a=1, b=2 swap2(&a,&b) : a=2, b=1 swap3(&pa, &pb): a=2, b=1 Program exited.
  17. 17. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH GO KENNT POINTER - WARUM? ▸ Einfache Anbindung von C-Code ohne Adapter (Java JNI) ▸ Unterscheidung zwischen Pointer und Value ▸ Kontrolle über das Speicherlayout von Strukturen (Java: Project Valhalla) ▸ Call by Value und Call by Reference für komplexe Datentypen type Point struct { x, y, z int} type Triangle struct { a, b, c Point } type Triangles [] Triangle // flach !!!
  18. 18. INTERFACES
  19. 19. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH INTERFACES LIEFERN POLYMORPHISMUS ▸ Alle Typen in Go implementieren das leere Interface {} // Stack is a generic LIFO container for untyped objects. type Stack struct { data []interface{} } // NewStack constructs an empty stack. func NewStack() *Stack { return new(Stack) } // Push pushes a value on the stack. func (s *Stack) Push(value interface{}) { s.data = append(s.data, value) }
  20. 20. // Node is the interface to eval an abstract syntax tree (AST) type Node interface {     // Eval evaluates the AST. The variables of the expression are set to true or false in the vars map.     // Missing vars (there are no key in the map) are evaluated to false.     Eval(vars map[string]bool) bool } // Or is the logical OR Operator in an AST type Or struct {     lhs Node     rhs Node } // Eval implements the Node interface func (o Or) Eval(vars map[string]bool) bool {     return o.lhs.Eval(vars) || o.rhs.Eval(vars) } PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH INTERFACES AND POLYMORPHISM: ABSTRACT SYNTAX TREE // And is the logical AND Operator in an AST type And struct {     lhs Node     rhs Node } // Eval implements the Node interface func (a And) Eval(vars map[string]bool) bool {     return a.rhs.Eval(vars) && a.rhs.Eval(vars) }
  21. 21. CONCURRENCYDON'T COMMUNICATE BY SHARING MEMORY! SHARE MEMORY BY COMMUNICATING!
  22. 22. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH GO ROUTINEN SIND KEINE THREADS! ▸ Eine Go Routine ist eine nebenläufige Funktion im gleichen Adressraum ▸ Go verwendet einen internen Thread Pool für die Ausführung ▸ Die Go Routinen laufen abschnittsweise auf den Threads ▸ Go Routinen werden kooperativ unterbrochen (z.B. bei fmt.Println()) -> Kooperatives Multitasking f("hello", "world") // f runs; we wait go f("hello", "world") // f starts running g() // does not wait for f to return
  23. 23. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH CHANNELS ERMÖGLICHEN SICHERE SYNCHRONISATION ZWISCHEN GO ROUTINEN ▸ Erzeugen ▸ Senden ▸ Empfangen c1 := make(chan int) // buffer size = 0 c2 := make(chan int, 10) // buffer size = 10 c1 <- 1 // blocks until receiver reads c2 <- 2 // blocks when buffer is full x = <- c1 // blocks until sender sends y = <- c2 // blocks when buffer is empty
  24. 24. SYNCHRONISATION ÜBER CHANNELS - PING / PONG PING PONG// Ball contains the number of hits. 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 } }
  25. 25. DEMO
  26. 26. ANALOG ZU JAVA KENNT GO LOW LEVEL LOCKS // BlockingQueue is a FIFO container with a fixed capacity. // It blocks a reader when it is empty and a writer when it is full. type BlockingQueue struct { m sync.Mutex c sync.Cond data []interface{} capacity int } // Put puts an item in the queue and blocks it the queue is full. func (q *BlockingQueue) Put(item interface{}) { q.c.L.Lock() defer q.c.L.Unlock() for q.isFull() { q.c.Wait() } q.data = append(q.data, item) q.c.Signal() }
  27. 27. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH ZUSAMMENFASSUNG ▸ Go Routinen sind eine Abstraktion über Threads und skalieren sehr gut ▸ Mit Go Channels können die meisten Synchronisationsprobleme sehr elegant gelöst werden ▸ Channels basieren auf Message Passing anstelle von Blockaden ▸ Go hat auch eine Low Level Api mit Locks für klassische Synchronisationsprobleme ▸ Klassen aus java.util.concurrent können damit einfach portiert werden
  28. 28. SINGLE BINARYBUILDING MINIMAL DOCKER CONTAINERS WITH GO
  29. 29. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH EIN EINFACHER RESTFUL SERVICE package main import ( "log" "net/http" "github.com/gorilla/mux" ) func main() { router := mux.NewRouter().StrictSlash(true) router.HandleFunc("/customer/{customerId}", getCustomerByID) router.HandleFunc("/customer", getAllCustomers) log.Println("CustomerServer: Listening on http://localhost:8080/customer ...") log.Fatal(http.ListenAndServe(":8080", router)) }
  30. 30. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH EIN EINFACHER RESTFUL SERVICE // Customer type type Customer struct { Name string `json:"name"` Address string `json:"address"` Tel string `json:"telephone"` } // Simple static customer data. var customers = []Customer{ Customer{„Ken Thompson“, „US", "+11 170 12345678"}, Customer{„Rob Pike", "US", "+11 169 87654321"}, } func getAllCustomers(w http.ResponseWriter, r *http.Request) { if err := json.NewEncoder(w).Encode(customers); err != nil { panic(err) } }
  31. 31. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH DOCKERFILE / DAS BUILDER PATTERN ▸ Der Container "builder" enthält die komplette Go Compiler Suite + Tools ▸ Der generierte Container enthält ausschließlich das von Go generierte Programm ▸ Das Programm ist statisch gelinkt und hat keine weiteren Abhängigkeiten ▸ Der finale Container ist nur wenige MB groß!!! # Build FROM golang:alpine as builder RUN mkdir /build ADD . /build/ WORKDIR /build RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o main . # Repackage FROM scratch COPY --from=builder /build/main /app/ WORKDIR /app CMD ["./main"]
  32. 32. DEMO
  33. 33. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH DER GO WERKZEUGZEUGKASTEN GEHT ÜBER JAVA HINAUS ▸ Compile, Build, Run von Anwendungen aus vielen Packages / Quelldateien ohne Buildskript mit „go build / go run“ ▸ Unit Testing mit Test Coverage „go test / go tool cover“ ▸ Profiling mit pprof (CPU und Memory) -> Flamegraphs (Brendan Gegg) ▸ Formatierung von Quelldateien mit „go fmt“ ▸ Quellcode Style Checker mit „go vet“ ▸ Slideshows mit ausführbarem Go Code im Browser mit „present“
  34. 34. BEST OF BREED
  35. 35. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH FÜR WELCHE ANWENDUNGEN EIGNET SICH GO PERFEKT? ▸ Hilfsprozesse wie Sidecar Container auf Cloud Plattformen (Kubernetes, OpenShift) ▸ Systemnahe Infrastrukturdienste wie Reverse Proxies, Authentication Proxies ▸ Automationsfunktionalität in der Cloud wie Elastic Scaling Automation ▸ Aggregator für Microservices (z.B. Backend for Frontend, gRPC auf RESTful Adapter) ▸ Querschnitts-Dienste (Crosscutting) wie Monitoring, Logging …
  36. 36. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH FÜR WELCHE ANWENDUNGEN SOLLTE MAN EHER JAVA WÄHLEN? ▸ Anwendungen mit komplexen Schnittstellen (legacy, proprietary) ▸ Enterprise Anwendungen mit langer Lebensdauer (Standards !) ▸ Anwendungen mit einem hohen Wiederverwendungspotential durch vorhandene Open Source Projekte ▸ Anwendungen mit engen Schnittstellen zu anderen Java Anwendungen
  37. 37. PROGRAMMIERSPRACHEN FÜR DIE CLOUD - JAVA UND GO IM VERGLEICH DIE GRAUZONE HÄNGT VON DEN ENTWICKLERN UND STRATEGIE AB ▸ Entwickler, die bisher C++ und Java programmiert haben, werden Go mögen und schnell produktiv sein ▸ Entwickler, die bisher nur Java programmiert haben, sollten mit Go eher vorsichtig sein ▸ Firmen, die sich stark in Richtung Cloud Nativer Entwicklung orientieren, sollten mit Go mutiger sein und Go auch für Teile der Anwendungsentwicklung nutzen ?
  38. 38. WAS KÖNNEN JAVA PROGRAMMIERER VON GO LERNEN?
  39. 39. WAS SOLLTEN JAVA PROGRAMMIERER VON GO LERNEN? ▸ Message Passing ist mit Java auch ohne native Channels und Go Routinen möglich. Hier kann man von Go und der Einfachheit der Nutzung lernen. ▸ KISS ist relevant. In Java ist es inzwischen möglich ähnlich komplexen Code zu schreiben wie früher in C++. Guter Java Code beschränkt sich auf das wesentliche. Es ist nicht zielführend jedes Java Feature in eine Anwendung einzubauen! ▸ Semantik Versioning und Minimal Version Detection sind Konzepte, die sich auch mit Java Tools umsetzen lassen. ▸ Es lassen sich mit ein wenig Erfahrung auch kleine, cloudfähige Java Container bauen. Hier kann man sich an Go orientieren. ▸ Man sollte sich im Projekt überlegen, was man aus Java alles weglassen kann ohne an Produktivität und Spaß zu verlieren.
  40. 40. PERFEKTION IST NICHT DANN ERREICHT, WENN MAN NICHTS MEHR HINZUFÜGEN, SONDERN WENN MAN NICHTS MEHR WEGLASSEN KANN Antoine de Saint-Exupéry
  41. 41. CODEDAYS 2019 JOHANNES WEIGEND / QAWARE GMBH @JOHANNESWEIGEND @QAWARE SIEHE AUCH HTTPS://WWW.QAWARE.DE/FILEADMIN/USER_UPLOAD/SONDERDRUCK-JAVASPEKTRUM-05-2018-JAVA-VS-GO-WEB.PDF WEITERE QAWARE TALKS MITTWOCH, 23.01.2019 | 09:55 - 10:40 UHR KMI 4.2 | CLOUD COMPUTING CRON IN DER CLOUD - DIE TOP 10 HITPARADE | ALEX KRAUSE MITTWOCH, 23.01.2019 | 11:00 - 11:45 UHR MI 4.2 (OOP) | SCHNELLIGKEIT UND AUSDAUER IN SOFTWARE-PROJEKTEN | MICHAEL ROHLEDER

×