[VLOG #26] PYTHON vs JAVA? Co dalej z VLOGIEM?
Co jest lepsze: Python czy Java?
Czy na tak postawione pytanie istnieje w ogóle jakaś dobra odpowiedź?
Jedną z rzeczy w świecie IT, która zawsze bardzo mnie denerwowała, były wszelkiego rodzaju gównoburze o tym, jaka technologia jest lepsza. Czy wobec tego teraz przykładam kolejną cegiełkę do zjawiska, którym pogardzam? I tak, i nie.
Chcę opowiedzieć Ci, jakie ja mam doświadczenia zarówno z Pythonem, jak i z Javą. Jak mi się z nimi pracowało, do jakich zastosowań jedno jest lepsze od drugiego i czym charakteryzują się społeczności programistów tych języków.
Czy któreś odradzam, a któreś polecam? Odpowiedź znajdziesz w tym właśnie filmie 😉
A poniżej transkrypcja (a właściwie to mój scenariusz) odcinka jeśli wolisz czytać niż oglądać:
Wstęp
Na wstępie chcę podkreślić, że wszystko co tutaj będę dzisiaj mówił, to tylko moje subiektywne opinie. Bardzo możliwe, że to, co powiem na przykład o zastosowaniach Javy i Pythona, albo o tym, czym się charakteryzują społeczności entuzjastów tych języków, nie będzie pokrywać się z Twoimi doświadczeniami. Ja po prostu dzielę się moimi obserwacjami małych wycinków tych rzeczywistości – być może gdzie indziej jest całkowicie odwrotnie. Jeśli tak jest to bardzo chętnie przeczytam w komentarzach jakie są Twoje doświadczenia.
Jeśli znasz moje poprzednie filmy na kanale to pewnie dało się zauważyć, że często przewijał się w nich Python. Był to język programowania, którego używałem zawodowo przez około ostatnie dwa lata.
Dlatego mówiłem trochę o jego podstawach w mini-serii o strukturach danych w Pythonie, pokazywałem jak z jego pomocą automatyzować różne czynności w przeglądarce a także na jego przykładzie mówiłem, jak robić Test-Driven Development.
Co więcej, zrobiłem też krótki dokument o tym, dlaczego Python jest super i warto się go nauczyć.
Biorąc to wszystko pod uwagę, można zapytać…
Dlaczego do cholery wróciłem zawodowo do Javy?!
Po prostu znudziło mi się uganianie za dzikimi wężami i miałem ochotę usiąść na filiżankę pysznego espresso…
Czy cały czas Was oszukiwałem, mówiąc, że Python jest taki super? A teraz będzie: hipokryta! Sprzedał nam tego Pajtona, a sam ucieka do Javy!
A może dopiero teraz przejrzałem na oczy i zdałem sobie sprawę, że Java jest jednak lepsza? A wcześniej sam żyłem w błędzie i Was w niego wprowadzałem?!
Prawdziwe powody są bardziej pragmatyczne. Każdy język ma zastosowania, które są dla niego bardzo naturalne oraz takie, które są bardziej wymuszone lub które w praktyce są bardzo rzadkie. I ja doszedłem po prostu do wniosku, że w obszarach, w których chcę się rozwijać, czyli w dużych systemach o globalnej skali, które bywają rozproszone, z rozbudowaną architekturą – dużo częściej stosuje się Javę lub inne języki JVMowe, niż Pythona.
Czy to oznacza, że już nie tknę Pythona kijem?
Absolutnie nie! Nic się nie zmieniło i cały czas podtrzymuję to wszystko, co mówiłem do tej pory we vlogach czy w PDFie. Python świetnie się nadaje do wielu zastosowań i mega się cieszę, że go znam – bo teraz mam po prostu wybór.
Jeśli do danego problemu lepiej będzie się nadawała Java, to wezmę Javę, a jeśli Python – to wrócę do zaklinania węży 😉
Do czego lepsza jest Java, a do czego Python?
No to przejdźmy do konkretów, kiedy jedno, a kiedy drugie. Jeszcze raz podkreślam, to jest moja subiektywna lista, jak komuś się nie podoba to wyp…. wypiszcie proszę swoje argumenty w komentarzach 😃
Oczywiście pamiętajcie, że to nie są jedyne słuszne dwa wybory. Nie chciałbym dokonywać tutaj jakiejś fałszywej dychotomii i sugerować, że albo Java, albo Python – jest mnóstwo innych języków, ale te dwa są po prostu mnie najbliższe i dlatego je właśnie porównuję.
Python
Jeśli chodzi o Pythona, to bez wątpienia świetnie sprawdzi się do wszelkiego rodzaju skryptów. Mam tu na myśli takie drobne, pomocnicze skrypty, które na przykład wykonują jakieś operacje na plikach. Najczęściej używa się do tego Basha, ale ja osobiście wolę Pythona bo jest dla mnie dużo czytelniejszy.
Są też skrypty automatyzujące, takie jak choćby ten z wysyłaniem pliku do formularza na stronie internetowej, który pokazywałem w jednym z odcinków vloga. Dzięki dynamicznemu typowaniu, zwięzłej składni i wielu dostępnych bibliotekach w ekosystemie Pythona takie narzędzia możemy stworzyć naprawdę szybko.
Obserwuję nieco z boku cały świat Data Science i Machine Learning, ale wydaje się, że tam Python po prostu króluje. Są też tam używane inne języki jak R, czy właśnie Java na przykład we frameworku Apache Spark. Ale jednak najpopularniejsze narzędzia takie jak Tensorflow, Keras czy PyTorch są przeznaczone właśnie dla Pythona i to o nim najczęściej słyszę w kontekście uczenia maszynowego czy przetwarzania danych.
Jest to bardzo ciekawa i dynamicznie rozwijająca się gałąź IT, ale ja po prostu nie jestem nią obecnie zainteresowany. Chcę zajmować się inżynierią oprogramowania, a praca ze zbiorami danych czy trenowanie modeli machine learningowych to zupełnie inna bajka.
No i po trzecie, Python świetnie nadaje się do programowania webowych backendów, co jest mnie osobiście najbliższe ze wszystkich tych zastosowań. Wysyłaliście mi z resztą wiele wiadomości z prośbą o zrobienie wideo o Django czy Flasku. Pracowałem w kilku projektach z Django i mogę powiedzieć, że to naprawdę fajny framework, ale…
No właśnie, jest tutaj jedno, duże ALE. Moim zdaniem Python dobrze się sprawdza w webówce, ale tylko w małych projektach.
Dla mnie źródłem większości problemów jest tutaj dynamiczne typowanie. Jeśli jest to mały projekt, to jest to też mały problem — znamy najczęściej cały albo prawie cały kod i wiemy, która zmienna co oznacza i jakiego jest typu. Gorzej jeśli projekt się rozrasta, wtedy zaczynają się pojawiać problemy. Mnie osobiście bardzo często trudno było się zorientować, z jakim typem danych akurat pracuję w danej metodzie. Musiałem śledzić jej wywołania w całym projekcie, żeby to zrozumieć, a i tak nie zawsze było to wystarczające — czasem musiałem nawet wpiąć się debuggerem.
Co więcej, zauważyłem tendencję, że bardzo często dane w programach Pythonowych są przekazywane nie za pomocą dedykowanych klas transportowych, tzw. DTO, tylko w zwykłych słownikach. Przez to obsługując gdzieś taki słownik nie tylko musimy znać typy wszystkich jego pól, ale też nazwy wszystkich kluczy!
Od wersji 3.5 w Pythonie dostępne są tak zwane „Type Hints”, czyli adnotacje dzięki którym możemy definiować jaki typ mają wartości zwracane przez funkcje. Moim zdaniem jest to bardzo dobry krok naprzód, pozwalający myśleć o wygodnej pracy w większych projektach napisanych w Pythonie. Ale ich użycie nie jest obowiązkowe i nie jest też sprawdzane przez interpreter. Czyli kod bez tych adnotacji lub z błędnymi też się wykona. Jak one w takim razie działają? Są tylko takimi metadanymi dla zewnętrznych narzędzi, jak statyczne analizatory kodu, które często są wbudowane w nasze IDE — one mogą nam tylko „podpowiedzieć”, że coś jest nie tak z typami. Ale niczego nie mogą wymusić, w przeciwieństwie do kompilatorów w statycznie typowanych językach.
No i z tymi Type Hintsami główny problem jest taki, że mało kto je stosuje. Nie widziałem jeszcze żadnego projektu, który stosowałby je wszędzie. Co najwyżej pojawiają się gdzieś tu i ówdzie. Dlatego ciężko mówić tu o wygodzie pracy porównywalnej do języków statycznie typowanych, dopóki projekty nie będą miały narzucone z góry że 100% kodu ma być pokryte adnotacjami Type Hints. A to się nie stanie pewnie nigdy, bo wielu entuzjastów Pythona uwielbia go właśnie za to dynamiczne typowanie i „wolność”, którą ono daje. No cóż, ja mam po prostu inne podejście.
Podsumowując, jakie są moim zdaniem główne zalety Pythona:
- zwięzła składnia
- szybki development na początku projektu, m.in. dzięki dynamicznemu typowaniu
- brak kompilacji – też wpływa na szybkość developmentu
A jakie są dla mnie największe problemy z Pythonem:
- brak silnego typowania (w średnich i dużych projektach )
- są type hints, ale z mojego doświadczenia mało kto używa w całym projekcie
- brak kompilacji – o niektórych błędach dowiemy się dopiero w runtime
- problemy z wielowątkowością (GIL)
- wiele projektów pisanych bardziej proceduralnie, niż obiektowo
- przekazywanie często słowników przez całą aplikację zamiast obiektów z wartościami (@dataclass)
- z mojego doświadczenia: mniej „dobrych praktyk”, stosowanie typowo pythonowych podejść zamiast ogólnie przyjętych norm
- brak powszechnie stosowanych podejść zmniejszających coupling, takich jak odwrócenie sterowania, na przykład poprzez wstrzykiwanie zależności
Java
No dobrze, a jak to jest z tą Javą? Cześć osób ją kocha, część nienawidzi. A największa część po prostu w niej koduje w korporacjach bo dobrze płacą. Jest częstym obiektem memów, a to, że jest wolna, a to, że napisanie w niej Hello Worlda zajmuje 15 linii kodu.
A jak wygląda to w praktyce? Jeśli chodzi o jej zastosowania, to Java historycznie zaczynała od urządzeń wbudowanych, potem była też w przeglądarkach, w aplikacjach desktopowych, w aplikacjach mobilnych na Symbiana, potem na Androida, pisano w niej nawet tak popularne gry jak Minecraft. Obecnie jednak zdecydowanie najpopularniejszym zastosowaniem Javy, z którym pracuje większość jej programistów są duże, webowe backendy.
Dlatego nie będę w ogóle omawiał pozostałych zastosowań, a skupię się właśnie na webówce. Dlaczego Java jest tam tak często wykorzystywana?
Po pierwsze, w przeciwieństwie do Pythona, Java jest statycznie typowana. To oznacza, że pracując w dużym systemie razem z kilkudziesięcioma albo więcej programistami dużo łatwiej jest odnaleźć się w projekcie.
W świecie Javy są też świetne narzędzia do tworzenia projektów webowych, a w szczególności framework Spring. Przez ostatnie kilka, kilkanaście lat bardzo dynamicznie się rozwijał i teraz oferuje już nie tylko kontener IoC, od czego wszystko się zaczęło, ale całą gamę narzędzi pomagającą tworzyć i utrzymywać duże systemy, jak na przykład Spring Cloud dostarczający gotowe rozwiązania do budowania systemów rozproszonych.
Na koniec — wydajność. Memy o Javie jako o powolnym języku są właśnie tym — memami. Nie mają natomiast wiele wspólnego z rzeczywistością. Java działa na maszynie wirtualnej zwanej JVM i faktycznie na początku, w latach 90-tych, ta dodatkowa warstwa między kodem a gołym hardware’m mogła powodować narzut wydajnościowy. Natomiast przez 25 lat istnienia Javy JVM został bardzo dopracowany i zoptymalizowany. Pojawiły się takie feature’y jak JIT (Just-In-Time compiler) czy dopieszczone garbage collectory. Dzięki temu obecnie istnieją benchmarki, według których w kwestii wydajności Java potrafi zostawić w tyle nawet C++. Po prostu po „rozgrzaniu” aplikacji wydajność kodu jest praktycznie taka sama, jak kodu natywnego, a przewaga wynika z optymalniejszego zarządzania pamięcią przez garbage collector niż ręcznie przez programistę w C++.
Poza tym czysta wydajność języka programowania w systemach webowych nie ma tak naprawdę kluczowego znaczenia. Współcześnie w systemach backendowych mamy wiele warstw cache’y i to one głównie decydują o szybkości i responsywności systemu dla użytkowników. A co więcej, wąskim gardłem dużo częściej bywa baza danych, niż wydajność samego kodu aplikacji.
Podsumowując, jakie są moim zdaniem główne plusy Javy?
- silne, statyczne typowanie
- stabilna i przetestowana w boju platforma uruchomieniowa, jaką jest JVM
- ogromny ekosystem, mnogość bibliotek i narzędzi
- dużo świadomych programistów, znający wzorce, dobre praktyki, piszących czysty kod
- potężne i dobrze przemyślane frameworki jak Spring Boot
Minusy:
- często „rozbuchana” składnia
- szczególnie jeśli chodzi o: operacje na kolekcjach, interakcje z systemem plików, pisanie do konsoli
- wyższy próg wejścia niż np. Python czy JavaScript
- ze Springiem łatwo zacząć, ale bardzo ciężko go dobrze opanować
- można trafić na sporo projektów legacy, z przestarzałymi technologiami, konfiguracjami XML-owymi i spaghetti code
Co dalej z vlogiem?
Do tej pory materiały, jakie publikowałem na blogu czy na vlogu były albo agnostyczne względem języka programowania, albo skupiały się na Pythonie.
W związku z tym, że od kilku miesięcy pracuję na codzień w Javie, to się pewnie nieco zmieni. Nie znaczy to, że nigdy przenigdy nie zobaczycie tu ani jednej linijki kodu w Pythonie! Do wielu rzeczy nadaje się on lepiej niż Java i nie będę chciał wszędzie wciskać mojego aktualnego języka.
Ale jednak oba te języki różnią się nie tylko składnią, ale też pewnymi paradygmatami. Możliwości języków są bardzo zbliżone, ale w wyniku pewnych decyzji twórców, a potem historycznych metod wykorzystania przez społeczności wykształciły się takie a nie inne podejścia.
Przykład: w Javie jeśli przekazujemy jakieś dane wewnątrz naszego programu, na przykład dane o użytkowniku, będą one w 99% przypadków zawarte w polach dedykowanej klasy, np User
. W Pythonie natomiast bardzo często w takiej sytuacji nie stworzymy osobnej klasy, tylko takie dane będziemy przekazywać w słowniku (dict
). I to mimo tego, że żadne techniczne przeszkody w stworzeniu dedykowanej klasy nie istnieją.
Dlaczego o tym mówię? Dlatego że w najbliższym czasie we vlogu planuję poruszać tematy związane z architekturą aplikacji, wzorcami projektowymi i dobrych praktykach związanych z programowaniem obiektowym. I już chociażby na tym przykładzie powyżej widać, że w Pythonie tę obiektowość traktuje się często dużo bardziej po macoszemu.
I właśnie dlatego jeśli będę pokazywał jakieś przykłady to pewnie najczęściej będą one w Javie. Nie dlatego, że jest ona do tego lepsza. Tylko dlatego, że w niej te przykłady będą dużo bardziej naturalne. Nie chcę na siłę pokazywać kodu w Pythonie, który rzadko kiedy spotka się w praktyce.
Dlatego jeśli interesują Was te tematy i chcielibyście dowiedzieć się więcej o tym, jak dobrze projektować i tworzyć webowy backend to „stay tuned”, bo takie właśnie materiały będą się tu wkrótce pojawiać.
Zakończenie
Dzięki za przeczytanie tego wpisu. Jeśli masz jakieś uwagi czy komentarze to zachęcam do napisania ich w komentarzach – to dla mnie największa nagroda za tworzenie tych treści – zaangażowanie widzów i czytelników.
Dzięki, pozdrawiam i do zobaczenia!