SlideShare ist ein Scribd-Unternehmen logo
JAVA UND GO IM VERGLEICH
PROGRAMMIERSPRACHEN FÜR DIE CLOUD
JOHANNES WEIGEND | @JOHANNESWEIGEND | QAWARE GMBH | @QAWARE
Java und Go im Vergleich
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?
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!
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, …
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
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
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.
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!
UNTERSCHIEDE IM
DETAIL
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)
}
...
}
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
}
BEISPIEL BUCHINDEX
Java und Go im Vergleich
// 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
}
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
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
}
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.
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 !!!
INTERFACES
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)
}
// 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)
}
CONCURRENCYDON'T COMMUNICATE BY SHARING MEMORY! SHARE MEMORY BY COMMUNICATING!
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
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
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
}
}
DEMO
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()
}
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
SINGLE BINARYBUILDING MINIMAL DOCKER CONTAINERS WITH GO
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))
}
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)
}
}
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"]
DEMO
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“
BEST OF BREED
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 …
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
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
?
WAS KÖNNEN JAVA
PROGRAMMIERER VON GO LERNEN?
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.
PERFEKTION
IST NICHT DANN ERREICHT, WENN MAN NICHTS
MEHR HINZUFÜGEN, SONDERN WENN MAN NICHTS
MEHR WEGLASSEN KANN Antoine de Saint-Exupéry
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

Weitere ähnliche Inhalte

PDF
Quarkus Quickstart
PDF
Title is loading ... Cache is cold.
PDF
Making the internet faster HTTP/3 und QUIC
PDF
Cloud Native und Java EE: Freund oder Feind?
PDF
MySQL Cluster with Galera Cluster for MySQL
PDF
Infrastructure as code: Cloud-Umgebungen mit Terraform verwalten
PDF
Kubernetes ist so viel mehr als ein Container Orchestrierer
PDF
Quarkus Quickstart
Title is loading ... Cache is cold.
Making the internet faster HTTP/3 und QUIC
Cloud Native und Java EE: Freund oder Feind?
MySQL Cluster with Galera Cluster for MySQL
Infrastructure as code: Cloud-Umgebungen mit Terraform verwalten
Kubernetes ist so viel mehr als ein Container Orchestrierer

Ähnlich wie Java und Go im Vergleich (20)

PDF
Ein Gopher im Netz
PDF
Go - Googles Sprache für skalierbare Systeme
PPTX
Workshop: Besseres C#
PDF
High performance mit PHP
PDF
Inter Prozedurale Zeigeranalyse
PDF
Production-ready Infrastruktur in 3 Wochen
PDF
Infrastructure as Code - BaselOne 17
PDF
Docker und Kubernetes Patterns & Anti-Patterns
PDF
Docker und Kubernetes Patterns & Anti-Patterns
PDF
Geoinformatik-Kolloquium Juni 2012: High Performance Computing Cluster GIS
PDF
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
PDF
Einführung in Puppet und Vagrant
PDF
Hazelcast bei der SBB (jug.ch)
PDF
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
PDF
JsUnconf 2014
PDF
Docker Workbench
PDF
Skalierbare Anwendungen mit Google Go
PDF
Hazelcast
PDF
Schweine latein-vortrag
PDF
Yes zu NoSQL mit MongoDB für .NET-Entwickler
Ein Gopher im Netz
Go - Googles Sprache für skalierbare Systeme
Workshop: Besseres C#
High performance mit PHP
Inter Prozedurale Zeigeranalyse
Production-ready Infrastruktur in 3 Wochen
Infrastructure as Code - BaselOne 17
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
Geoinformatik-Kolloquium Juni 2012: High Performance Computing Cluster GIS
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Einführung in Puppet und Vagrant
Hazelcast bei der SBB (jug.ch)
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
JsUnconf 2014
Docker Workbench
Skalierbare Anwendungen mit Google Go
Hazelcast
Schweine latein-vortrag
Yes zu NoSQL mit MongoDB für .NET-Entwickler
Anzeige

Mehr von QAware GmbH (20)

PDF
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
PDF
Frontends mit Hilfe von KI entwickeln.pdf
PDF
Mit ChatGPT Dinosaurier besiegen - Möglichkeiten und Grenzen von LLM für die ...
PDF
50 Shades of K8s Autoscaling #JavaLand24.pdf
PDF
Make Agile Great - PM-Erfahrungen aus zwei virtuellen internationalen SAFe-Pr...
PPTX
Fully-managed Cloud-native Databases: The path to indefinite scale @ CNN Mainz
PDF
Down the Ivory Tower towards Agile Architecture
PDF
"Mixed" Scrum-Teams – Die richtige Mischung macht's!
PDF
Make Developers Fly: Principles for Platform Engineering
PDF
Der Tod der Testpyramide? – Frontend-Testing mit Playwright
PDF
Was kommt nach den SPAs
PDF
Cloud Migration mit KI: der Turbo
PDF
Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See...
PDF
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
PDF
Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.
PDF
Kubernetes with Cilium in AWS - Experience Report!
PDF
50 Shades of K8s Autoscaling
PDF
Kontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAP
PDF
Service Mesh Pain & Gain. Experiences from a client project.
PDF
50 Shades of K8s Autoscaling
QAware_Mario-Leander_Reimer_Architecting and Building a K8s-based AI Platform...
Frontends mit Hilfe von KI entwickeln.pdf
Mit ChatGPT Dinosaurier besiegen - Möglichkeiten und Grenzen von LLM für die ...
50 Shades of K8s Autoscaling #JavaLand24.pdf
Make Agile Great - PM-Erfahrungen aus zwei virtuellen internationalen SAFe-Pr...
Fully-managed Cloud-native Databases: The path to indefinite scale @ CNN Mainz
Down the Ivory Tower towards Agile Architecture
"Mixed" Scrum-Teams – Die richtige Mischung macht's!
Make Developers Fly: Principles for Platform Engineering
Der Tod der Testpyramide? – Frontend-Testing mit Playwright
Was kommt nach den SPAs
Cloud Migration mit KI: der Turbo
Migration von stark regulierten Anwendungen in die Cloud: Dem Teufel die See...
Aus blau wird grün! Ansätze und Technologien für nachhaltige Kubernetes-Cluster
Endlich gute API Tests. Boldly Testing APIs Where No One Has Tested Before.
Kubernetes with Cilium in AWS - Experience Report!
50 Shades of K8s Autoscaling
Kontinuierliche Sicherheitstests für APIs mit Testkube und OWASP ZAP
Service Mesh Pain & Gain. Experiences from a client project.
50 Shades of K8s Autoscaling
Anzeige

Java und Go im Vergleich

  • 1. JAVA UND GO IM VERGLEICH PROGRAMMIERSPRACHEN FÜR DIE CLOUD JOHANNES WEIGEND | @JOHANNESWEIGEND | QAWARE GMBH | @QAWARE
  • 3. 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?
  • 4. 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!
  • 5. 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, …
  • 6. 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
  • 7. 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
  • 8. 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.
  • 9. 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!
  • 11. 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) } ... }
  • 12. 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 }
  • 15. // 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 }
  • 16. 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
  • 17. 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 }
  • 18. 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.
  • 19. 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 !!!
  • 21. 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) }
  • 22. // 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) }
  • 23. CONCURRENCYDON'T COMMUNICATE BY SHARING MEMORY! SHARE MEMORY BY COMMUNICATING!
  • 24. 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
  • 25. 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
  • 26. 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 } }
  • 27. DEMO
  • 28. 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() }
  • 29. 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
  • 30. SINGLE BINARYBUILDING MINIMAL DOCKER CONTAINERS WITH GO
  • 31. 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)) }
  • 32. 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) } }
  • 33. 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"]
  • 34. DEMO
  • 35. 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“
  • 37. 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 …
  • 38. 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
  • 39. 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 ?
  • 41. 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.
  • 42. PERFEKTION IST NICHT DANN ERREICHT, WENN MAN NICHTS MEHR HINZUFÜGEN, SONDERN WENN MAN NICHTS MEHR WEGLASSEN KANN Antoine de Saint-Exupéry
  • 43. 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