Golang

Ostatnio, słuchając jednego ze swoich ulubionych zespołów – Led Zeppelin – algorytm, wybierający kolejne, podobne piosenki na Youtube, wprowadził mnie w małą konsternację, losując utwór, którego nigdy wcześniej nie słyszałem. Słuchając brzmienia i wokalu, byłem święcie przekonany, że jest to kawałek z jakiejś ukrytej, poddanej nowoczesnemu remasteringowi  płyty Led Zeppelin, która jakimś cudem nigdy przedtem nie trafiła w moje ręce. Jakież było moje zdziwienie, gdy okazało się, że jest to zespół, o wdzięcznej nazwie „Greta van Fleet”, który dopiero niedawno wypłynął na szerokie wody szturmem zdobywając coraz większe rzesze fanów na całym świecie. Słuchając tej piosenki poczułem się jak wtedy, gdy po raz pierwszy usłyszałem coś więcej o języku programowania Go, który przez dłuższy czas umykał mojej uwadze, a który bardzo szybko zdobywał coraz większą popularność wśród programistów na całym świecie. I to właśnie na Go chciałbym skupić się w tym artykule, przybliżając Wam sylwetkę tego „jeszcze nie tak” popularnego u nas języka.

Aż trudno uwierzyć, że motywacją, do powstania tego jednego z najbardziej lubianych przez programistów języka programowania, jest nienawiść – wspólna nienawiść do zawiłości i nieefektywności współczesnych języków programowania. Inżynierowie zatrudnieni w Google mieli dość pracy z językami, które powstały w zupełnie innej erze programowania. W erze, w której było diametralnie inne podejście do procesu tworzenia aplikacji, zupełnie inne możliwości sprzętowe oraz zdecydowanie inne założenia tych języków. We wrześniu 2007 roku narodził się więc pomysł stworzenia nowego języka, który zdecydowanie bardziej będzie pasował do sposobu pracy w nowoczesnym środowisku IT. Osobami odpowiedzialnymi za główne założenia tego projektu były takie gwiazdy świata komputerowego jak Ken Thompson (projektant oraz twórca UNIX-a i C), Rob Pike (współtwórca formatu UTF 8 oraz UNIX-a) oraz Robert Griesemer.  Efekt ich pracy został przekazany do opinii publicznej 10 listopada 2009, kiedy to Go zostało projektem open source. Wersja 1.0 trafiła do użytkowników w marcu 2012 roku, a jego najświeższa wersja to 1.11, wydana w 2018 roku.

Rys. 1 Maskotką języka Go jest ten uroczy niebieski suseł (Gopher).

Rys. 1 Maskotką języka Go jest ten uroczy niebieski suseł (Gopher).

 

Głównymi założeniami twórców tego języka miała być prostota i połączenie wszystkiego co najlepsze ze świata programowania. Dowodem na to, że udało im się dopiąć swojego celu mogą być opinie użytkowników, w których często przewijają się opinie o następujących zaletach Go:

– język jest kompilowany. Gwarantuje to wykrycie błędów składni już w procesie kompilowania, oraz przyspieszenie działania w porównaniu od języków interpretowanych. Warto też zauważyć, że Go kompiluje się niezmiernie szybko w porównaniu do innych języków kompilowanych,

– statyczne typowanie – pozwalające na wykrycie niektórych błędów już w procesie kompilacji,

– bogaty pakiet standardowy, który oferuje wiele rozwiązań do problemów często spotykanych w procesie tworzenia aplikacji takich jak testowanie, profilowanie, programowanie webowe

– wieloparadygmatowość – mimo iż go jest językiem imperatywnym, to pozwala on również na wykorzystywanie elementów programowania obiektowego i funkcyjnego,

– wielowątkowość, łatwą w obsłudze dzięki Goroutines oraz channels,

– dokumentacja – zawierająca szczegółowe informacje na temat działania pakietów wbudowanych,

– prostota języka.

Czynnikiem, który potwierdza wszystkie powyższe plusy jest chociażby bardzo szybko rosnąca popularność tego języka. Na daną chwilę wg. Indeksu TIOBE (czyli miary popularności jezyków), Go znajduje się na 12 miejscu, notując najwyższy wzrost wśród popularności top 20 języków, przeskakując aż osiem miejsc w porównaniu do poprzedniego roku. Warto zauważyć też, że znaczna część dużych zachodnich korporacji używa Go w swoich systemach. Pomijając oczywiście Google, wśród topowych firm korzystających z tego języka znajdują się między innymi Uber,  Bitly, Facebook, Twitter, Docker, Intel… Lista ta ciągnie się w nieskończoność, i można odnieść wrażenie, że praktycznie każdy poważny gracz na rynku stara się wykorzystać przewagę płynącą z możliwości tego języka.

Rys. 2 Język Go został wybrany piątym najbardziej lubianym językiem przez użytkowników Stack Overflow. Czy tysiące programistów może się mylić? ;-)

Rys. 2 Język Go został wybrany piątym najbardziej lubianym językiem przez użytkowników Stack Overflow. Czy tysiące programistów może się mylić? 😉

Jedną z rzeczy, na której chciałbym skupić się w tym artykule jest właśnie wielowątkowość, która w porównaniu z innymi językami wydaje się być znacznie łatwiejsza w wykorzystaniu. Aby nie pozostać gołosłownym, chciałbym dokonać małego porównania z przykładem z tekstu, który pojawił się już na łamach naszego bloga. W tekście o pytaniach na rozmowach kwalifikacyjnych (część 4, dotycząca wielowątkowości), w ramach wytłumaczenia jak działa metoda zsynchronizowana, pojawił się mały program inkrementujący wartość licznika do 10000 w dwóch różnych wątkach. Kod tego programu znajduje się poniżej:

Rys. 1 Kod programu napisanego w Javie, którego jedynym celem życiowym jest liczenie w dwóch wątkach. A Ty myślałeś że Twoja praca jest nudna? ;-)

Rys. 1 Kod programu napisanego w Javie, którego jedynym celem życiowym jest liczenie w dwóch wątkach. A Ty myślałeś że Twoja praca jest nudna? 😉

Dla tych mniej zaznajomionych z Javą – w programie tym tworzymy klasę, posiadającą pole counter, o typie int, która jest inkrementowana o jeden przez zsynchronizowaną (słówko kluczowe synchronized) metodę o nazwie increment(). Słówko to jest niezbędne, aby uniknąć tzw. „race condition”, negatywnego zjawiska, które powoduje, że nie możemy być pewni, w jakim stanie znajduje się dzielony pomiędzy różnymi wątkami zasób. W prostych słowach, akcja inkrementacji przeprowadzona przez jeden wątek, może nie zakończyć się przed „pobraniem” zasobu przez drugi wątek, a więc zmiany wprowadzone przez wątek pierwszy mogą być nadpisane przez wątek drugi. Aby wykonać metodę wielowątkowo, tworzymy dwa wątki (new Thread()), do których podajemy obiekt count, w którym jest zawarte powtórzenie funkcji increment() 5000 razy. Następnie rozpoczynamy działanie obydwu wątków przez .start(), a na samym końcu w bloku try{} czekamy na zakończenie pracy obydwu wątków poprzez metodę join(). Teraz porównajmy powyższą implementację z kodem napisanym w Go:

Rys. 2 Ten sam program napisany w Go. Czy Wam również wydaje się nieco łatwiejszy do czytania?

Rys. 2 Ten sam program napisany w Go. Czy Wam również wydaje się nieco łatwiejszy do czytania?

 

Już na pierwszy rzut oka widać, że napisany program jest o wiele bardziej zwarty, znajduje się tutaj znacznie mniej elementów rozpraszających oko. Nawet bez znajomości języka, zdecydowanie łatwiej jest odczytać intencje osoby piszącej ten kod. Możemy zobaczyć, że na samym początku deklarujemy zmienną wg typu WaitGroup, która pozwoli nam  zatrzymać pracę głównego wątku do czasu  wykonania pracy przez wątki poboczne (wg.Wait()). Poprzez wg.Add(2), informujemy, że czekamy na dwa wątki, które sygnalizują wykonanie swoich obowiązków poprzez wg.Done(). Równoległe operacje uruchamiamy poprzez słówko kluczowe go, poprzedzające nazwę funkcji, która ma zostać wykonana. Dodatkowo zabezpieczamy się przed „race condition” poprzez wykorzystanie zmiennej typu Mutex i jej metody Lock() i Unlock().

Kolejnym argumentem, który przemawia za tym językiem, jest łatwość w jego nauce – sama składnia Go jest na tyle prosta, że ludzie z doświadczeniem programistycznym są w stanie przyswoić ją w bardzo krótkim czasie. Dodatkowo w sieci znajduje się bardzo dużo materiałów napisanych w bardzo przystępny sposób. Wystarczy odwiedzić np. takie strony jak tour.golang.org, na której mamy interaktywnego sandboxa, wraz z tutorialem, który krok po kroku zaznajamia nas z możliwościami tego języka. Na Udemy (czy nawet YouTube) znajdują się również kursy wideo, dla wszystkich tych, którym w ten sposób łatwiej przyswaja się wiedzę. Oprócz tego zawsze można wesprzeć się dokumentacją znajdującą się na stronie projektu – mamy tam opisane praktycznie wszystkie zagadnienia dotyczące pakietu standardowego Go.

Aby nie popaść w totalny zachwyt nad tym językiem, sprawiedliwie postaram się również przedstawić wady wymieniane przez użytkowników. Pierwszą wadą na którą warto zwrócić uwagę jest brak wsparcia typów ogólnych (generics), co może uniemożliwiać tworzenie dokładnego, wyraźnego kodu. Warto jednak napomknąć że zespół pracujący nad rozwojem rozważa dodanie wsparcia dla typów ogólnych w przyszłych wersjach. Jako kolejny problem można uznać sposób w jaki radzimy sobie z błędami, funkcje w Go zamiast wyrzucać wyjątek, zwracają często dwie wartości (metody mają możliwość zwracania wielu wartości), z czego jedna jest wynikiem operacji, natomiast druga jest zmienną typu error. Prowadzi to do ciągłego sprawdzania wartości tego błędu, aby móc wykryć nieprawidłowości w działaniu programu. Wielu użytkowników zwraca również uwagę na małą ilość pakietów dostępnych w Go – problem ten jednak będzie się zmniejszał wraz z biegiem czasu i wzrostem ilości osób wykorzystujących ten język.

Golang jest na pewno narzędziem nowej generacji, mającym na celu zwiększenie produktywności programistów, oraz możliwość wykorzystania w jak największym stopniu możliwości sprzętowych dzisiejszych komputerów. Jego popularność stale rośnie i już teraz można powiedzieć że  język ten sporo namieszał w rynku IT. Czy „wygryzie” on inne języki w przyszłości? Raczej wątpliwe, ale na pewno warto poznać się z nim bliżej i zobaczyć co ma do zaoferowania. A jaka jest wasza opinia o Go? Macie z nim jakieś doświadczenie? Czekamy na komentarze! 😊

 

Marek Makuch

 

 

IT-Leaders.pl to pierwsza na rynku platforma łącząca Specjalistów IT bezpośrednio z pracodawcami. Anonimowy, techniczny profil i konkretnie określone oczekiwania finansowe to tylko niektóre z cech wyróżniających platformę. Zarejestruj się i zobacz jak Cię widzi pracodawca.