W czym warto programować w roku 2022? Przegląd najpopularniejszych języków cz. 1 

UDOSTĘPNIJ

Autor: Tomasz Przedziński, architekt oprogramowania

O tym od czego zacząć tworzenie własnej aplikacji już pisaliśmy, jednak wciąż dostajemy wiele pytań o to, w czym tę aplikację webową czy desktopową najlepiej napisać, jakie technologie będą najlepiej oddawały dany koncept i jakich narzędzi użyć, żeby były one jak najbardziej optymalne. O wypowiedź poprosiliśmy jednego z naszych ekspertów, Tomasza Przedzińskiego. Tomek przygotował cykl wpisów na temat najpopularniejszych języków programowania, który naświetli poszczególne technologie, przybliży popularność języków programowania i podpowie, w czym pisać aplikację webową. 

Wielu z nas śledzi od czasu do czasu index TIOBE, wyjątkowo uniwersalny wskaźnik zestawiający najpopularniejsze języki programowania. Jest bardzo użytecznym narzędziem, pokazującym nie tyle trend współczesnego rynku, co jego status quo w zakresie narzędzi i technologii, używanych przez programistów na całym świecie. TIOBE bardzo trafnie wskazuje, jakie języki programowania mają przyszłość, jednocześnie podpowiadając kierunki, w których warto rozwijać swoje umiejętności, ale też pokazuje, czego potrzebuje biznes.

Top 5 języków programowania w indeksie TIOBE, lipiec 2022. Źródło: www.tiobe.com

W rankingu na lipiec 2022 TIOBE zaznacza, że Python, C, C++ i C# są obecnie najlepszymi kandydatami na język roku 2022. Obecność najpopularniejszych języków Java¹, C i C++ w czołówce jest niezmienna od ponad 20 lat, podczas gdy szybko rosnąca popularność Pythona po raz pierwszy w jego karierze umiejscowiła go na pierwszym miejscu rankingu. Popularność języka C# ma swoje wzloty i upadki, jednak w ostatnich latach dość często widać jego obecność w Top 5.  

Dlaczego warto go znać i co wyróżnia C# na tle innych popularnych języków programowania? O tym za chwilę.  

Biznesowe uzasadnienie popularności języków programowania

Nie powinno być zaskoczeniem, że kandydatury wymienione przez TIOBE pokrywają praktycznie cały rynek usług programistycznych, a każda z nich zajmuje kluczowe miejsce w innym sektorze. O tym, który język programowania wybrać, często decyduje typ i przeznaczenie oprogramowania. Język C króluje w najniższych warstwach oprogramowania i w oprogramowaniu wbudowanym. C++ pokrywa szerokie spektrum zastosowań, choć skupia się głównie na backendzie i na rozwiązaniach, w których liczy się wydajność, uwzględniając zastosowania giełdowe, takie jak HFT (ang. High Frequency Trading) i Low-Latency Trading. Python, z kolei, jest nieocenionym narzędziem do szybkiego prototypowania rozwiązań i budowania frameworków testowych. Jest też bardzo popularny wśród osób zajmujących się uczeniem maszynowym. C# w połączeniu z frameworkiem .NET, zwłaszcza po wydaniu .Net Core, jest jedną z najczęściej używanych technologii w szeroko pojętych rozwiązaniach chmurowych, w aplikacjach webowych, mobilnych oraz desktopowych – w szczególności na system operacyjny Windows. Dobrze daje sobie radę w połączeniu z zyskującym coraz większą popularność IoT. Warto wspomnieć, że wszystkie największe silniki gier są napisane w C++, przy czym silnik Unity jest częściowo napisany w C#. Gry pisane na silnik Unity pisane są w C#, co znacząco przyczyniło się do popularyzacji tego języka².

Jak najłatwiej opisać język C#?

Ideą przemawiającą za powstaniem C# było stworzenie wysokopoziomowego języka programowania podobnego w założeniach do Javy, a jednocześnie bliskiego w składni do C++. C# miał uprościć składnię C++ i dostarczyć narzędzia dostępne we współczesnych językach, stawiając na niezawodność i łatwy rozwój projektu. Popularność C# świadczy o tym, że przynajmniej częściowo ten koncept udało się zrealizować.

Program “Hello world!” w C#

C# jest statycznie typowanym językiem wysokiego poziomu. Podobnie jak Java, kompilowany jest do języka pośredniczącego, zwanego CL (Common Language). Do wykonania kodu potrzebna jest odpowiednia infrastruktura, taka jak np. platforma .NET, w ramach której jest on uruchamiany w CLR (Common Language Runtime), czyli maszynie wirtualnej działającej na podobnych zasadach co JVM (Java Virtual Machine). 

Ze względu na swe mocne powiązanie z platformą .NET, bardzo często zamiast mówić, że pisze się w języku C# mówi się, że pisze się dla platformy .NET³. A to dlatego, że z pisaniem na platformę .NET związane jest wykorzystanie całego ekosystemu, który ona w sobie zawiera. Jest to m.in. wspomniane wcześniej środowisko uruchomieniowe, ale również zbiór bibliotek.

A więc C# czy .NET?

Ze środowiskiem .NET wiąże się wiele różnych terminów i detali, a sam proces kompilacji i uruchamiania kodu na tej platformie jest całkiem skomplikowany. Nie trzeba jednak ich znać, by zacząć w nim pracę. Warto zaznaczyć jednak najważniejszy punkt: większość projektów rozwijanych jest na platformę .NET Core albo .NET Framework. Ta pierwsza zorientowana jest na wydajność i multiplatformowość, a jej główne przeznaczenie to aplikacje webowe, mikroserwisy i aplikacje na urządzenia mobilne. .NET Framework ogranicza swoją implementację do platformy MS Windows⁴, w zamian za to umożliwiając łatwy rozwój aplikacji desktopowych i gier. Obu platform można użyć do pisania aplikacji webowych przy użyciu ASP.NET⁵. Te dwie platformy należy traktować odrębnie, gdyż kodu napisanego dla jednej nie da się uruchomić na drugiej. Ich część wspólna zwana jest .NET Standard. 

Platforma .NET w pełni wykorzystuje możliwości, jakie daje uruchomianie kodu pośredniczącego. Mamy zatem: 

  • możliwość podmiany bibliotek w locie, bez konieczności wyłączania działającego systemu,  
  • kompilator JIT (Just-In-Time Compiler), który na bieżąco analizuje, przez które ścieżki kod przechodzi najczęściej i optymalizuje go w locie,  
  • rozbudowaną refleksję, umożliwiającą pełne poznanie pól i metod klas, wliczając klasy, które dopiero co zostały dynamicznie wczytane z zewnętrznej biblioteki,
  • zarządzanie pamięcią przy pomocy mechanizmów odśmiecania pamięci (ang. Garbage Collection, GC) i wysoki poziom izolacji procesów, co daje nam pewne gwarancje bezpieczeństwa.

Najpopularniejsze zastosowania platformy .NET w biznesie

Graficzna edycja okien, na przykład w Visual Studio, znacząco przyspiesza proces budowania aplikacji desktopowych na platformie .NET i sprawia, że jest ona częstym wyborem, gdy przychodzi stworzyć aplikację w sektorze finansowym. Często buduje się w niej też aplikacje mające służyć jako interfejs do zarządzania bazami danych w firmach. Z kolei ASP.NET jest wygodną alternatywą dla PHP czy Node.js do tworzenia serwisów WWW. ASP.NET jest ceniony za swoją niezawodność i skalowalność, dlatego budowane są w niej największe serwisy webowe, takie jak StackOverflow. Łatwość, z jaką projekty można hostować na platformach chmurowych, odciąża nie tylko developerów, ale i managerów od zajmowania się infrastrukturą, w jakiej osadzony jest projekt. 

Microsoft zadbał o to, by platformy .NET można było wygodnie używać w rozwiązaniach chmurowych, a zwłaszcza w Microsoft Azure. Azure posiada szereg narzędzi ułatwiających tworzenie mikroserwisów i, co w mojej ocenie dużo ważniejsze, monitorowanie ich działania i poszukiwanie błędów, wliczając monitorowanie zapytań do baz danych, by ułatwić ich optymalizację.

Co charakteryzuje język C#?

C# jest językiem obiektowym⁶. Posiada wbudowane mechanizmy programowania asynchronicznego, reprezentowane m.in. przez słowa kluczowe async i await. Umożliwiają one efektywne programowanie z wykorzystaniem zarówno podejścia TAP (ang. Task-based Asynchronous Pattern), jak i EAP (ang. Event-based Asynchronous Pattern). 

Coś, co wyróżnia C# na tle innych popularnych języków programowania, to wbudowany mechanizm tworzenia zapytań – LINQ (ang. Language Integrated Query). LINQ pozwala tworzyć zapytania, które można wykonać zarówno na bazie danych, jak i na kolekcji obiektów. Można przy tym używać płynnego interfejsu (ang. Fluent Interface) albo składni w stylu języka SQL. Zapytania są zoptymalizowane pod wykorzystywane przez projekty bazy danych (lub kolekcje) i pozwalają na leniwą ewaluację. Mogą być również zrównoleglone przy użyciu PLINQ (Parallel LINQ). 

C# unika wielu problemów zaobserwowanych w innych językach. Ogromną zaletą, która mnie osobiście bardzo się podoba, jest przejrzystość błędów kompilacji. Intellisense, działający na przykład jako wtyczka do Visual Studio Code, zgłasza praktycznie każdy możliwy błąd. Naprawiwszy wszystkie, mam prawie stuprocentową pewność, że kod się skompiluje i uruchomi. Coś, czego w pracy z C++ bardzo, ale to bardzo brakuje. 

Jednak wykorzystanie mechanizmu kompilacji do kodu pośredniczącego i wykonanie go przy pomocy środowiska uruchomieniowego, pociąga za sobą narzut w postaci obniżonej wydajności. Zoptymalizowany program w C++ wykona się szybciej od tego napisanego w C#. Z naciskiem na słowo „zoptymalizowany”, bo często ręcznie pisane rozwiązania w C++ są wydajniej zrealizowane w bibliotekach platformy .NET. 

Wyzwania pracy z C# i .NET

Tworzenie aplikacji internetowych i desktopowych z platformą .NET jest wyzwaniem ze względu na poziom jej złożoności. Wiele konceptów wymaga poznania detali działania tej platformy, by uniknąć typowych błędów spowalniających wykonywanie programu. Do niektórych podstawowych mechanizmów trzeba się po prostu przyzwyczaić, bo na przykład działają inaczej niż oczekiwałby programista. 

Dla przykładu – struktury i klasy mają w C# inne przeznaczenie, więc są obsługiwane inaczej. Struktury powinny być używane do przechowywania obiektów typu POD (ang. Plain Old Data), dlatego przypisanie lub przekazanie ich jako argument funkcji tworzy ich kopię. Klasy są traktowane podobnie jak w języku Java – przekazywane są przez referencję. To detal, którego łatwo się nauczyć, ale nieraz potrafi zaskoczyć. Takich wyjątków w zachowaniu C#, w porównaniu do innych języków, jest zdecydowanie więcej. 

Przykład typowego problemu w C# - powyższy kod wypisze ‘10, 20, 20 ,20’, co może zaskoczyć niektórych programistów. ‘Test1’ jest strukturą, więc w linii 14 zostanie wykonana jego kopia, podczas gdy ‘Test2’ jest klasą, więc w linii 23 zostanie stworzona nowa referencja do tej samej instancji klasy. Te różnice łatwo wyłapać, gdy widać definicję ‘Test1’ i ‘Test2’, ale w złożonym projekcie, gdy w grę wchodzą kolekcje różnych typów, trudniej śledzić typy manipulowanych obiektów i łatwo popełnić błąd.

Warto też pamiętać, że podobnie jak w języku Java, projekty napisane w .NET mają tendencję do tworzenia wielu warstw abstrakcji i potrafią być bardzo złożone, czego ze względów wydajnościowych unika się w projektach pisanych w C czy C++⁷. Próg wejścia w istniejący projekt jest dość wysoki i wymaga dużej wiedzy domenowej, zanim będzie można w nim efektywnie pracować.

Ciąg dalszy nastąpi

Zaczęliśmy od końca, ale przejdziemy przez charakterystyki wszystkich kandydatów. Czy wyłonimy własnego zwycięzcę? Stay tuned, a tymczasem zostawiamy Was z krótkim zestawieniem podstawowych cech kandydatów, żeby zobrazować największe różnice między nimi.  

 

C++ 

Python 

C# 

Poziom abstrakcji 

Niski 

Wysoki 

Wysoki 

Wysoki 

Typ języka 

Kompilowany 

Kompilowany 

Interpretowany 

Zarządzany 

Główny paradygmat programowania 

Proceduralny 

Obiektowy 

Proceduralny, funkcyjny, obiektowy (i inne) 

Obiektowy 

Typowanie 

Statyczne 

Statyczne 

Dynamiczne 

Statyczne 

Refleksja 

Brak 

Bardzo ograniczona 

Pełna 

Pełna 

Zarządzanie pamięcią 

Brak 

Brak 

GC 

GC 

Obsługa wyjątków 

Brak 

Jest (można wyłączyć) 

Jest 

Jest 

Wsparcie dla programowania wielowątkowego 

Brak 

TAP, EAP, inne 

TAP, EAP, inne 

TAP, EAP, inne 

Najpopularniejszy manager pakietów 

Brak 

Conan 

pip 

NuGet 

Najpopularniejsze narzędzie do budowania projektu 

make, CMake 

CMake 

(Niepotrzebne) 

dotnet, mono 

Trudność nauczenia się języka 

Łatwy 

Trudny 

Bardzo łatwy 

Średni 

Praca w złożonych projektach 

Bardzo trudna 

Trudna 

Średnio trudna 

Średnio trudna 

Poszukiwanie błędów 

Szalenie trudne 

Trudne 

Trudne 

Średnio trudne 


Zestawienie kluczowych różnic pomiędzy językami C, C++, Python i C#. 

Ostatnie dwie pozycje mocno zależą od sposobu organizacji projektu. Zawsze możemy trafić na taki, w którym poziomy trudności są odwrócone.

Masz pomysł na aplikację mobilną, webową lub własny system i szukasz doświadczonego partnera technologicznego? Obejrzyj projekty, które zrealizowaliśmy z klientami, którzy potrzebowali oprogramowania na zamówienie

Jeśli masz gotowy plan działania i opis aplikacji, będziemy w stanie przygotować wycenę nawet w 24 godziny od przesłania specyfikacji. Jeśli nie – nic nie szkodzi. Skontaktuj się z nami i umów na bezpłatną konsultację, aby wspólnie opracować dalsze kroki.

Tomasz Przedziński, rocznik 86, skończył studia magisterskie z Informatyki Stosowanej na Uniwersytecie Jagiellońskim w Krakowie i obronił doktorat z inżynierii oprogramowania na AGH. Specjalizuje się w C++, ale mocno polubił się ze środowiskami embedded. Nie ukrywa sympatii do algorytmiki i optymalizacji rozwiązań. W pracy zawodowej stawia na jakość, budując zaawansowane środowiska testowe lub rozbudowując istniejące.

¹ - Język Java nie jest omawiany w tym artykule nie tylko dlatego, że nie został przez TIOBE uznany za kandydata na język roku 2022. Artykuł opisuje praktyczne aspekty języków programowania, bazując na moim doświadczeniu, a w Javie nie napisałem nawet linijki kodu od ponad 15 lat. Nie czuję się kompetentny pisać o tym języku.

² - Dawniej, do prostszych silników gier używało się języka C, ale ze względu na złożoność współczesnych silników obecnie nie praktykuje się takich rozwiązań. W języku Python można pisać gry, ale ze względu na niską wydajność tego silnika są to głównie niewymagające sprzętowo produkcje 2D. Dobrym przykładem jest silnik RenPy, który jest popularnym silnikiem do tworzenia gier typu Visual Novel.

³ - To rozróżnienie jest o tyle istotne, że na platformę .NET można pisać obecnie w ponad dwudziestu językach. Jednak najpopularniejsze dwa to właśnie C# i Visual Basic .NET (skracany do VB.NET), który w indeksie TIOBE zajmuje szóste miejsce, zaraz za C#.

⁴ - Sam .NET Framework został napisany tak, by można było go zaimplementować na każdej platformie, jednak w pełni zaimplementowany jest tylko na platformę MS Windows. Kod .NET Core jest Open Source, podczas gdy tylko niektóre moduły kody .NET Framework są dostępne jako Open Source.

⁵ - Do niedawna framework do aplikacji webowych ASP.NET dostępny był tylko dla .NET Framework. Obecnie istnieje też wersja ASP.NET Core.

⁶ - Platforma .NET umożliwia programowanie funkcyjne, np. przy użyciu języka F#, ale znaczna większość wspieranych języków jest jednak językami obiektowymi.

⁷ - Projekty pisane w C++ nadal mogą mieć wiele warstw abstrakcji, jednak dużo rozwiązań tworzy się na szablonach. Szablony zwiększają ilość kodu, co spowalnia jego wykonanie na bardzo niskiej warstwie (związanej z lokalnością kodu i zarządzaniem pamięcią instrukcji), ale to spowolnienie jest znacząco mniejsze niż korzystanie z wirtualnych funkcji i interfejsów, wymagające nakładu pracy w trakcie działania programu.

Najnowsze wpisy na blogu