5 cech projektowych języka Go z perspektywy inżynierii systemowej i backendowej

Wprowadzenie
Języki programowania są narzędziami do tworzenia produktów. Sam fakt korzystania z określonego języka nie determinuje poziomu umiejętności programisty. Jednak wybór języka oraz sposób, w jaki się go używa, może bezpośrednio wpływać na sposób myślenia programisty i kierunek jego rozwoju. W szczególności porównywanie używanego języka z innymi językami pozwala poszerzyć horyzonty techniczne i wykształcić wyczucie istoty zagadnień. W tym artykule chciałbym opowiedzieć o tym, dlaczego wybrałem Go oraz w jaki sposób wspiera on rozwój programisty, omawiając to z pięciu perspektyw.
1. Go to język, który równoważy wydajność i produktywność.
Istnieje wiele języków programowania, a każdy z nich ma zalety i wady wynikające z jego cech.
- C zapewnia znakomitą wydajność oraz możliwość niskopoziomowej kontroli, jednak programista musi samodzielnie zarządzać pamięcią, a brak wysokopoziomowych funkcji obniża produktywność i utrudnia utrzymanie kodu.
- C++ i Rust oferują różnorodne zaawansowane funkcje, takie jak programowanie obiektowe, szablony czy metaprogramowanie, lecz ich składnia jest złożona, krzywa uczenia się jest stroma, a wolna kompilacja sprawia, że nie nadają się one dobrze do częstych wdrożeń.
- Java i C# zapewniają niezależność od platformy oraz stabilność, dzięki czemu są powszechnie stosowane w dużych usługach, jednak działają na obciążających maszynach wirtualnych, co komplikuje wdrażanie i środowisko uruchomieniowe oraz wymaga znacznych zasobów.
- Python i JavaScript dzięki zwięzłej składni i bogatemu ekosystemowi nadają się do szybkiego tworzenia oprogramowania, jednak ich wydajność w czasie wykonania jest niższa, a wiarygodność ekosystemu jest mniejsza, co w dużych systemach ujawnia ograniczenia strukturalne.
Z kolei Golang jest językiem, który zapewnia doskonałą równowagę między wydajnością a produktywnością. Go, jako język kompilowany podobnie jak C, gwarantuje wysoką wydajność wykonania, a dzięki szybkiej kompilacji oferuje elastyczność wdrażania na poziomie języków interpretowanych. Innymi słowy, Go jest zrównoważonym językiem, który bez wyraźnych wad może być stabilnie wykorzystywany w większości środowisk.
2. Go zapobiega programowaniu typu cargo cult.
Podczas II wojny światowej alianci zbudowali bazę lotniczą na wyspie na Pacyfiku, aby wspierać działania wojenne. Duża ilość zaopatrzenia i sprzętu wojskowego znacząco zmieniła życie żołnierzy oraz mieszkańców wyspy. Tubylcy po raz pierwszy zobaczyli samoloty przywożące ubrania, konserwy i inne przedmioty. Gdy wojna się skończyła, baza została porzucona i ładunki przestały docierać. Mieszkańcy wyspy, chcąc naśladować żołnierzy, ubrali się jak kontrolerzy ruchu lotniczego, żołnierze i marynarze, zbudowali coś przypominającego pas startowy i za pomocą kijów wysyłali sygnały lądowania do samolotów. Kontynuowali również marsz, aby sprawić, by ładunki spadały na spadochronach. Jednak samoloty, na które czekali, nie nadleciały.
Programowanie typu cargo cult oznacza nawyk tworzenia kodu lub stosowania technologii poprzez naśladowanie jedynie ich zewnętrznej formy, bez zrozumienia zasad ich działania. Współcześni programiści, zwłaszcza w obszarze tworzenia aplikacji webowych, często wykazują tego typu nawyk, stosując rozwiązania bez zrozumienia ich znaczenia. Frameworki takie jak React, Next, Spring czy Django umożliwiły rozwój bez znajomości ich wewnętrznej struktury, lecz wielu programistów nie potrafi poradzić sobie nawet z drobnym błędem. Dodatkowo, wraz z pojawieniem się narzędzi do generowania kodu opartych na sztucznej inteligencji, praktyka kopiowania i wklejania wyników, zamiast pisania kodu samodzielnie lub zrozumienia zasad jego działania, staje się coraz bardziej powszechna.
Go fundamentalnie przeciwdziała temu problemowi na poziomie filozofii języka. Go jest językiem zaprojektowanym wokół biblioteki standardowej, a nie frameworków. Programista może zbudować serwer webowy na poziomie produkcyjnym, korzystając wyłącznie z podstawowych bibliotek, takich jak net/http oraz database/sql, a dzięki temu w naturalny sposób rozwija intuicję i zrozumienie struktur niskiego poziomu, takich jak sieć, bazy danych czy operacje wejścia/wyjścia. Taka struktura, pozwalająca opanować podstawy bez polegania na frameworkach, stanowi fundament, dzięki któremu programista może nieustannie się rozwijać, nie tracąc z oczu istoty technologii.
3. Go zapewnia potężny model współbieżności.
Współczesne procesory rozwijają się w kierunku zwiększania wydajności poprzez równoległe wykorzystanie wielu rdzeni, a nie przez przyspieszanie pojedynczego rdzenia. W związku z tym współbieżność, czyli zdolność programu do jednoczesnego przetwarzania wielu zadań, stała się koniecznością, a znaczenie języków umożliwiających jej efektywne projektowanie i implementację stale rośnie. Go jest językiem zoptymalizowanym pod kątem takiego środowiska. Goroutine to lekki wątek dostarczany przez Go, który można utworzyć, używając stosu o wielkości zaledwie kilku KB, a nawet uruchomienie tysięcy goroutine jednocześnie prawie nie obciąża zasobów systemowych. Środowisko uruchomieniowe Go, dzięki własnemu harmonogramowi M:N, efektywnie rozdziela liczne goroutine na wątki systemowe (OS threads), a proces ten jest optymalizowany automatycznie, bez konieczności bezpośredniej ingerencji programisty. Dzięki temu programista może projektować logikę współbieżną w bezpieczny i spójny sposób, bez złożonej logiki synchronizacji i własnego harmonogramowania.
Ponadto Go aktywnie wspiera nowoczesne projektowanie współbieżności, wykorzystując narzędzia synchronizacji, takie jak mutex i waitGroup, a także channel oraz context. Dzięki tej strukturze programista może, bez zagłębiania się w złożoną teorię, w naturalny sposób wypracować praktyczne wyczucie współbieżności i równoległości, osiągając wysoki poziom abstrakcji i zdolności projektowych, które można wykorzystać w praktyce.
4. Go to język stworzony przez wybitnych programistów, którzy zachowali równowagę.
Go powstał z inicjatywy Google, a jego twórcami są legendarni programiści: Robert Griesemer, Rob Pike oraz Ken Thompson. W szczególności są oni współtwórcami systemu Unix oraz języka C, a także mistrzami w dziedzinie kompilatorów i oprogramowania systemowego, co samo w sobie potwierdza techniczną wiarygodność Go. Do tego doszły praktyczne doświadczenia wielu inżynierów Google oraz wiedza z zakresu prowadzenia dużych usług, dzięki czemu Go od początku zmierzał do rozwiązywania realnych problemów i konsekwentnie rozwijał się, zachowując spójną filozofię i kierunek.
Inne języki często wprowadzają zamieszanie wśród społeczności i użytkowników z powodu przerw w kompatybilności, zmian w projekcie, niestabilnych licencji oraz niestandaryzowanego ekosystemu. Na przykład Python przez lata był podzielony na skutek przerwania kompatybilności między wersjami 2 i 3, a Java po przejęciu przez Oracle doświadczyła niestabilnej polityki licencyjnej, co sprawiło, że wiele przedsiębiorstw zaczęło niechętnie ją wdrażać. Ponadto Node.js nadal nie zapewnia spójnego systemu modułów, ponieważ współistnieją w nim CJS i ESM.
Natomiast Go stawia na pierwszym miejscu spójność i stabilność. Zespół Go dba o zachowanie pełnej kompatybilności wstecznej i przy wprowadzaniu nowych funkcji stosuje stopniowe podejście do integracji, dzięki któremu nie dochodzi do konfliktów z istniejącym kodem. Również składnia unika zbędnych słów kluczowych i ogranicza nadmierną abstrakcję, co zapobiega niepotrzebnemu komplikowaniu samego języka. Ponadto spójne oficjalne narzędzia, takie jak go fmt, go mod, go build i go test, sprawiają, że wszystkie projekty w Go mają jednolite środowisko pracy i strukturę, a bogata biblioteka standardowa w pełni obsługuje serwery webowe, przetwarzanie plików, integrację z bazami danych oraz większość funkcji potrzebnych w praktycznym programowaniu, bez konieczności korzystania z dodatkowych frameworków.
5. Gopher jest uroczy.


