GoSuda

5 Designmerkmale der Programmiersprache Go aus der Perspektive der Systemtechnik und des Backend-Engineerings

By Rabbit Princess views ...

Einleitung

Programmiersprachen sind Werkzeuge zur Entwicklung von Produkten. Allein die Wahl einer bestimmten Sprache entscheidet noch nicht über die Fähigkeiten einer Entwicklerin oder eines Entwicklers. Dennoch kann die Wahl einer Sprache und die Art ihres Umgangs einen direkten Einfluss auf die Denkweise und die Entwicklungsrichtung einer Entwicklerin oder eines Entwicklers haben. Insbesondere der Vergleich der derzeit verwendeten Sprache mit anderen Sprachen erweitert den technischen Horizont und fördert ein Gespür für das Wesentliche. In diesem Beitrag möchte ich darlegen, warum ich mich für Go entschieden habe und in welcher Hinsicht die Sprache die Entwicklung von Entwicklerinnen und Entwicklern unterstützt, gegliedert nach fünf Gesichtspunkten.

1. Go ist eine Sprache, die Leistung und Produktivität in Balance bringt.

Es gibt zahlreiche Programmiersprachen, und jede besitzt je nach ihren Eigenschaften Vor- und Nachteile.

  • C bietet hervorragende Leistung und die Möglichkeit einer maschinennahen Steuerung, jedoch muss der Speicher von Entwicklerinnen und Entwicklern selbst verwaltet werden, und aufgrund fehlender höherer Funktionen ist die Produktivität gering und die Wartung schwierig.
  • C++ und Rust unterstützen verschiedene fortgeschrittene Funktionen wie objektorientierte Programmierung, Templates und Metaprogrammierung, doch die Syntax ist komplex, die Lernkurve steil und die langsame Kompilierung macht sie für wiederholte Bereitstellungen ungeeignet.
  • Java und C# bieten Plattformunabhängigkeit und Stabilität und werden daher häufig in groß angelegten Diensten eingesetzt, doch sie laufen auf einer schwergewichtigen virtuellen Maschine, weshalb Bereitstellung und Laufzeitumgebung komplex sind und der Ressourcenbedarf hoch ist.
  • Python und JavaScript eignen sich aufgrund ihrer prägnanten Syntax und des reichhaltigen Ökosystems gut für schnelle Entwicklung, jedoch ist ihre Laufzeitleistung gering und die Verlässlichkeit des Ökosystems niedrig, sodass sich in großen Systemen strukturelle Grenzen zeigen.

Demgegenüber ist Golang eine Sprache, die zwischen Leistung und Produktivität ein hervorragendes Gleichgewicht herstellt. Da Go wie C eine kompilierte Sprache ist, garantiert sie eine hohe Laufzeitleistung und bietet zugleich durch schnelle Kompilierung eine Flexibilität bei der Bereitstellung auf dem Niveau von Interpretersprachen. Das heißt, Go ist eine ausgewogene Sprache, die ohne markante Schwächen in den meisten Umgebungen zuverlässig eingesetzt werden kann.

2. Go verhindert Cargo-Cult-Programmierung.

Während des Zweiten Weltkriegs errichteten die Alliierten zur Unterstützung des Krieges Luftwaffenstützpunkte auf den Inseln des Pazifiks. Die große Menge an Nachschub und die militärische Ausrüstung veränderten das Leben der Soldaten und der Einheimischen erheblich. Die Bewohner sahen zum ersten Mal, wie Flugzeuge Kleidung, Konserven und andere Güter herbeibrachten. Als der Krieg endete, wurde der Stützpunkt aufgegeben, und die Frachtlieferungen blieben aus. Daraufhin ahmten die Inselbewohner die Soldaten nach, kleideten sich wie Fluglotsen, Soldaten und Matrosen, errichteten landebahnähnliche Flächen und sendeten mit Stöcken Landesignale an die Flugzeuge. Sie führten weiterhin Umzüge durch, damit die Fracht per Fallschirm herabgeworfen würde. Doch die Flugzeuge, auf die sie warteten, kamen nicht.

Cargo-Cult-Programmierung bezeichnet eine Entwicklungsgewohnheit, bei der die äußere Form von Code oder Technik nachgeahmt wird, ohne deren Prinzipien zu verstehen. Bei heutigen Entwicklerinnen und Entwicklern, insbesondere im Bereich der Webentwicklung, tritt eine solche Gewohnheit, ohne die Bedeutung zu kennen, häufig auf. Frameworks wie React, Next, Spring und Django haben es ermöglicht, ohne Kenntnis der inneren Struktur zu entwickeln, doch oft fehlt die Fähigkeit, auch auf kleine Fehler angemessen zu reagieren. Hinzu kommt, dass durch aktuelle KI-Werkzeuge zur Codegenerierung eine Entwicklungsweise weiter verbreitet wird, bei der man Ergebnisse lediglich kopiert und einfügt, anstatt Code selbst zu schreiben oder dessen Prinzipien zu verstehen.

Go vermeidet dieses Problem auf der Ebene der Sprachphilosophie grundlegend. Go ist eine Sprache, die nicht auf Frameworks, sondern auf der Standardbibliothek basiert. Entwicklerinnen und Entwickler können allein mit grundlegenden Bibliotheken wie net/http und database/sql einen Webserver auf dem Niveau eines produktiven Dienstes aufbauen, und dabei entwickeln sie auf natürliche Weise ein Verständnis und Gespür für Netzwerke, Datenbanken, E/A und andere tiefere Strukturen. Eine Struktur, die es ermöglicht, ohne Abhängigkeit von Frameworks die Grundlagen von Grund auf solide zu erlernen, bildet somit die Basis dafür, dass Entwicklerinnen und Entwickler das Wesen der Technik nicht aus den Augen verlieren und kontinuierlich wachsen können.

3. Go bietet ein leistungsfähiges Nebenläufigkeitsmodell.

Moderne CPUs entwickeln sich eher dahin, die Leistung durch die parallele Nutzung mehrerer Kerne zu steigern, als die Geschwindigkeit eines einzelnen Kerns zu erhöhen. Dadurch ist Nebenläufigkeit, also die Fähigkeit eines Programms, mehrere Aufgaben gleichzeitig zu bearbeiten, unverzichtbar geworden, und die Bedeutung von Sprachen, mit denen sich diese effizient entwerfen und umsetzen lassen, wächst zunehmend. Go ist eine Sprache, die für dieses Umfeld optimiert ist. Eine Goroutine ist ein von Go bereitgestellter leichtgewichtiger Thread, der sich mit einem Stack von nur wenigen KB erzeugen lässt und selbst bei gleichzeitiger Ausführung Tausender Goroutinen kaum Systemressourcen verbraucht. Die Go-Laufzeitumgebung verteilt über einen eigenen M:N-Scheduler zahlreiche Goroutinen effizient auf OS-Threads, und dieser Vorgang wird automatisch optimiert, ohne dass Entwicklerinnen und Entwickler direkt eingreifen müssen. Dadurch können Entwicklerinnen und Entwickler Nebenläufigkeitslogik auf sichere und konsistente Weise entwerfen, ohne komplexe Synchronisationslogik oder eigenes Scheduling implementieren zu müssen.

Außerdem unterstützt Go aktiv ein modernes Nebenläufigkeitsdesign mit Synchronisationswerkzeugen wie Mutex und WaitGroup sowie mit Channel und Context. Aufgrund dieser Struktur können Entwicklerinnen und Entwickler ein praktisches Gespür für Nebenläufigkeit und Parallelität entwickeln, ohne sich in komplexer Theorie zu verlieren, und ein hohes Maß an Abstraktions- und Entwurfsfähigkeit erreichen, das sich aus dem Nichts heraus praktisch nutzen lässt.

4. Go ist eine Sprache, die von hervorragenden Entwicklerinnen und Entwicklern mit klarer Ausrichtung geschaffen wurde.

Go ist eine Sprache, die unter der Leitung legendärer Entwickler wie Robert Griesemer, Rob Pike und Ken Thompson bei Google entstanden ist. Insbesondere sind sie die Schöpfer von Unix und C sowie Meister auf den Gebieten der Compiler und der Systemsoftware, wodurch sie selbst die technische Glaubwürdigkeit von Go belegen. Hinzu kommt, dass die praktische Erfahrung zahlreicher Google-Ingenieure und ihr Know-how im Betrieb großer Dienste eingeflossen sind. Dadurch hat sich Go von Anfang an auf die Lösung realer Probleme ausgerichtet und sich mit einer kohärenten Philosophie und Richtung weiterentwickelt.

Andere Sprachen verursachen durch Kompatibilitätsbrüche, Designänderungen, unbeständige Lizenzen und nicht standardisierte Ökosysteme oft Verwirrung bei Communities und Anwenderinnen und Anwendern. Beispielsweise war das Python-Ökosystem durch den Kompatibilitätsbruch zwischen Version 2 und 3 jahrelang gespalten, und bei Java führten nach der Übernahme durch Oracle instabile Lizenzbedingungen dazu, dass Unternehmen zunehmend zögerten, es einzuführen. Außerdem koexistieren bei Node.js weiterhin CJS und ESM, weshalb bis heute kein einheitliches Modulsystem bereitgestellt wird.

Demgegenüber ist Go eine Sprache, die Konsistenz und Stabilität als oberste Werte betrachtet. Das Go-Team bewahrt die Abwärtskompatibilität konsequent und verfolgt auch bei der Einführung neuer Funktionen einen schrittweisen Integrationsansatz, damit es nicht zu Konflikten mit bestehendem Code kommt. Auch bei der Syntax werden unnötige Schlüsselwörter vermieden und übermäßige Abstraktion begrenzt, um zu verhindern, dass die Sprache selbst unnötig komplex wird. Zudem fördern einheitliche offizielle Werkzeuge wie go fmt, go mod, go build und go test, dass alle Go-Projekte dieselbe Entwicklungsumgebung und Struktur besitzen. Die leistungsfähige und praxisnahe Standardbibliothek unterstützt zuverlässig die meisten für die reale Entwicklung notwendigen Funktionen, etwa Webserver, Dateiverarbeitung und Datenbankanbindung, ganz ohne zusätzliche Frameworks.

5. Der Gopher ist niedlich.

Gopher1

Gopher2

Gopher3