Czy programista potrzebuje matematyki?
Pytanie o matematykę i programowanie jest jednym z najczęstszych pojawiających się na mojej skrzynce e-mailowej. Dlatego postanowiłem napisać artykuł opisujący zależność pomiędzy nimi. Jeżeli wciąż zastanawiasz się, do czego matematyka jest potrzebna programiście, w tym artykule poznasz mój punkt widzenia na ten temat.
Karol Trybulec. Senior Frontend Developer w Andea. W 2012 roku ukończył technikum informatyczne. W 2018 roku uzyskał tytuł magistra inżyniera na Wydziale Mechanicznym Politechniki Krakowskiej, na kierunku informatyka ze specjalizacją inżynieria oprogramowania. Interesuje się informatyką w pojęciu ogólnym, w szczególności programowaniem (C/C++, C#/.NET oraz elementy Assemblera), tworzeniem aplikacji internetowych (XHTML/HTML, CSS/SASS, SQL, JavaScript, JQuery, Angular2+, ASP.NET MVC, .Net CORE, Node.JS) oraz zabezpieczeniami komputerowymi.
Spis treści
Związek pomiędzy matematyką i informatyką
Już na samym początku trzeba wspomnieć, że informatyka jako dziedzina nauki wywodzi się bezpośrednio z matematyki. Dawniej stanowiła jej część, jednak przez jej niesamowicie szybki i daleko idący rozwój została uznana za osobną dziedzinę nauki. Informatyka z roku na rok ewoluuje, a celem tego procesu jest szybsze osiąganie wyników za pomocą narzędzi, jakie udostępnia.
Gdyby pokusić się o narysowanie piramidy informatyki, z całym przekonaniem jej podstawą byłaby właśnie matematyka. Z samej definicji wynika, że jest to dziedzina nauki wysoce abstrakcyjna, opierająca się na świecie cyfrowym.
Nauka programowania jest jak nauka matematyki
Z moich obserwacji i doświadczeń wynika, że nauka programowania niczym nie różni się od nauki matematyki. Obydwie te nauki, jako że ze sobą bardzo związane, są naukami nienamacalnymi.
Ucząc się matematyki, przechodzimy przez wszystkie klasy szkoły podstawowej, średniej i wyższej. Chyba każdy z nas poznał to uczucie, kiedy poznając podstawy matematyki w szkole podstawowej, miał wrażenie, że nigdy nie będzie w stanie być lepszym i rozwiązywać trudniejszych zadań. Zadania ze studiów wyglądają wtedy jak magia, a uczeń czuje się przytłoczony ogromem materiału.
Mimo tego niekomfortowego wrażenia lata edukacji mijają, a ludzie nie wiedząc kiedy, stają się coraz lepsi. Zaczynając naukę od tabliczki mnożenia, docieramy do wielomianów, funkcji, szeregów, granic, całek, różniczek itd. Małymi krokami wszystko zaczyna się układać.
Tak samo przytłaczająca wydaje się nauka programowania. Zaczynając jego naukę od podstaw, a więc podstawowych konstrukcji programistycznych, całość wydaje się bezsensowna. Programy pobierające i wyświetlające dane na czarnej konsoli wydają się niepotrzebne, a człowiek ma wrażenie, że nigdy nie będzie w stanie napisać skomplikowanego systemu. Tak jak w przypadku matematyki, jest to wrażenie złudne, ponieważ przez te początkowe etapy po prostu trzeba przejść.
Dlatego właśnie warto studiować
Podobieństwo w nauce matematyki i informatyki jest jednym z argumentów, dla których warto iść na studia informatyczne. Na studiach otrzymuje się odpowiednio poukładane porcje materiału, które podawane są w odpowiedniej kolejności. Po 5 latach studiów i wielu pozornie nieprzydatnych przedmiotach znacznie poszerza się nasz horyzont w dziedzinie informatyki. Nie tylko programowanie, nie tylko sieci informatyczne, nie tylko grafika inżynierska, tylko całe fundamenty nauki jaką jest informatyka.
Nie idąc na studia, nauka programowania może być przytłaczająca i ciężka. Nie mówię, że nie da się go nauczyć samemu, jednak przypomina to sytuację chęci nauczenia się matematyki ze studiów, nie umiejąc tabliczki mnożenia ani ułamków. Człowiek pozostawiony sam sobie może mieć problemy z odpowiednim przejściem przez wszystkie etapy nauki, poprzez te najbardziej prymitywne (czyli pętle i wyświetlanie cyferek w czarnej konsoli) aż po bardziej złożone (kolorowe okienka, interfejsy użytkowników, wzorce projektowe, metodyki).
Dlatego programowanie jest trudne
Na koniec warto wspomnieć o interesującym fakcie, dlaczego programowanie wydaje się pozornie tak trudne? Odpowiedź jest oczywista: jego nauka jest jak nauka matematyki, a w Polsce jego nauczanie jest bardzo słabe. Jest to względnie nowa dziedzina nauki, a społeczeństwo nie nadąża z jego wprowadzeniem do szkół. Patrząc na wysokie zarobki programistów, globalną cyfryzację i wielki deficyt na rynku pracy oczywistym wydaje się, że programowanie powinno być przedmiotem szkolnym prowadzonym choćby w minimalnym wymiarze godzin – tak, aby zaszczepić podstawy.
Matematyki uczymy się całe życie, pewnie około 15 lat. Programowania nie uczymy się nigdzie. Dlatego stając nagle przed decyzją „zaczynam uczyć się programowania„ człowiek staje przed ogromnym wyzwaniem opanowania potężnej dziedziny nauki, bez jakichkolwiek podstaw wiedzy. Wtedy nie wiadomo czego się łapać, a poznawanie podstaw wydaje się bezsensowne.
Gdzie ta matematyka w informatyce?
O tym, że informatyka jest powiązana z matematyką, można dyskutować długo. Niektórzy się z tym zgadzają, inni stanowczo zaprzeczają. Jako programista skupię się oczywiście na matematyce w programowaniu. Na samym początku trzeba zrozumieć, że matematyka to nie tylko operacje algebraiczne, nie tylko analiza matematyczna. Wiele osób sądzi, że matematyki w programowaniu nie ma i wtedy zastanawiam się, czy oni chcieliby pisać kod całkami, żeby tę matematykę zobaczyć?
Dla mnie bardzo ciekawymi przedmiotami na studiach informatycznych były matematyka dyskretna i metody optymalizacyjne. Gdybym miał zdefiniować matematykę dyskretną, nazwałbym ją pomostem pomiędzy światem matematyki a programowania. Te dwa przedmioty są tak ściśle powiązane, że w zależności od specjalizacji nauczyciela akademickiego mogą bardziej przypominać zajęcia z programowania lub matematyki. Matma dyskretna jest nauką o zbiorach dyskretnych (nieciągłych). Jej przykładowe poddziały to:
- logika matematyczna – bardzo fajne i przydatne. Poznaliśmy logikę Boolowską i jej prawa, prawa de Morgana, operacje na zdaniach, aksjomaty, tautologie, kwantyfikatory, implikacje, indukcję matematyczną, podstawy teorii mnogości, dopełnienia zbiorów itd. Na kolokwiach musieliśmy np. uprościć skomplikowane zdania, używając praw z logiki Boola. Opiera się na nich cała elektrotechnika, służą między innymi do upraszczania obwodów elektronicznych i znajdują zastosowanie oczywiście w projektowaniu instrukcji warunkowych w programowaniu. Np. zgodnie z prawem zaprzeczenia koniunkcji instrukcję if !(p&&q) można zapisać jako if (!p || !q). Z rachunku logiki Boola korzysta się świadomie lub nieświadomie w całym życiu zawodowym, wykorzystywałem tę wiedzę także podczas programowania mikrokontrolerów AVR.
- kryptografia – czyli jak działa szyfrowanie, jak działają szyfry jednostronne lub dwustronne. Jak to się dzieje, że asymetrycznego algorytmu RSA nie da się złamać i dlaczego są nim zabezpieczane np. komunikacje w grach MMORPG pomiędzy klientem a serwerem. Jak ważną rolę pełni brak wzoru na liczby pierwsze w algorytmach asymetrycznych i dlaczego cała kryptografia obecnie nam znana zawali się w momencie powstania komputerów kwantowych.
- teoria gier – czyli jak program ma podejmować właściwe decyzje, dlaczego gra w kółko krzyżyk jest grą o sumie stałej i dlaczego można za pomocą algorytmu minimax napisać robota komputerowego, który nigdy nie przegra. Dlaczego w szachach nie jest to już tak proste. Dylemat więźnia i problem wyboru obarczony stratą lub zyskiem.
- teoria grafów – w informatyce po prostu magia. Często wykorzystywane tam, gdzie nigdy byś się tego nie spodziewał. M.in. problem znajdowania najkrótszej drogi w grach (algorytm Dijkstry), problem mostów, drzewa, reprezentacja problemów za pomocą grafów, problem najlepszego sąsiada. Nie wiem, czy wszyscy wiedzą, ale dzięki teorii grafów mamy takie portale jak jakDojade.pl.
Czy czytając powyższe punkty jest sens się zastanawiać, czy matematyka jest związana z programowaniem? Opisałem bardzo ogólnie wyłączenie jeden przedmiot, którym jest matematyka dyskretna.
Być może, ktoś czytający ten artykuł chciałby poznać więcej relacji pomiędzy matematyką a programowaniem. Spróbujmy wypisać problemy programistyczne przypisane do działów matematyki:
- operacje algebraiczne/analiza matematyczna – pisanie wszelkiego rodzaju algorytmów, zwracanie uwagi na złożoność obliczeniową, raczej są to dedykowane i wyspecjalizowane aplikacje desktopowe. Może to być choćby program do obliczania maksymalnego naprężenia w prętach, który napisałem na drugim roku studiów jako forma zaliczenia mechaniki. Umiejętność odróżnienia algorytmów O(n^2) od O(ln(n)), rozumienie, które warto optymalizować. Umieć zapisać funkcję matematyczną f(x) = x^2 jako funkcję w programie.
- statystyka – w programowaniu raczej mało, ewentualnie zajmowanie się big data.
- optymalizacja – gdy pierwszy raz zetknąłem się z tym na studiach, byłem zafascynowany. Związane z programowaniem liniowym i matematyką dyskretną. Przykładowo po poznaniu algorytmu optymalizacji liniowej simplex napisałem swój kalkulator dietetyczny dostępny pod adresem www.kalkulator-diety.pl. Jego zadaniem jest dobranie takich ilości produktów które wybiorę, aby odpowiadały mojej osobie (czyli automatyzuje układanie diety żywieniowej). Jest to też temat mojej pracy magisterskiej.
- algorytmy genetyczne – stosunkowo nowość, mają tak szerokie zastosowanie, że aż ciężko wszystko wypisać. Służą do zaprogramowania sztucznej inteligencji, przewidują pogodę, umieją grać na giełdzie forex. Mój współlokator używa ich do pisania aplikacji automatycznie układającej plan zajęć.
- algebra liniowa – dużo tego jest w programowaniu gier komputerowych (nie używając silników graficznych wysokiego poziomu). Trzeba umieć obracać obiekty w przestrzeni, wszystko opiera się na macierzach i przekształceniach trygonometrycznych. Co najważniejsze trzeba robić to optymalnie, a nie metodą prób i błędów. Używane także we wszelkiego rodzaju obróbce grafiki (filtry, rozpoznawanie kształtów, analiza klatek, oprogramowanie do fotoradarów).
W obecnym projekcie używamy maszyny stanów (maszyny Turinga) do definicji stanów dokumentów, też była omawiana na matematyce dyskretnej. Na koniec napiszę krótko: nie chcę mi się więcej wymyślać. Nie ma się co sprzeczać nad tym, że informatyka to matematyka, a w programowaniu też można jej spotkać całkiem sporo. Jeżeli ktoś sądzi, że w programowaniu nie ma matematyki, to zastanówmy się, czego by się spodziewał? Pisania programu ułamkami? Przecież nie tylko na „liczbach” kończy się matematyka.
Jednak rozważmy dalej, czy można programować, nie umiejąc matematyki?
Trzeba programować szybciej
Aby dopełnić ten artykuł i rozwiać wszystkim wszelkie wątpliwości, należy przeanalizować jeszcze jeden ważny aspekt. Trzeba odpowiedzieć sobie na pytanie: dokąd zmierza informatyka a w szczególności programowanie? Programowanie jako ważny podzbiór informatyki rozwija się nieprawdopodobnie szybko. Praktycznie nie da się nadążyć za wszystkimi nowymi językami i platformami programistycznymi. Po co one powstają? Oczywiście po to, aby było szybciej i lepiej.
Przechodząc przez programowanie od najniższej warstwy (tzw. programowanie embedded), polegało ono na operowaniu instrukcjami procesora (czyli język assembler). Później powstał nieobiektowy język C, jeszcze później – jego starszy brat hybrydowy język C++. Mimo, że był bardzo potężny, wytwarzanie oprogramowania ciągle było zbyt wolne. Zaczęły powstać języki wysokiego poziomu, czyli Java i C#. Programowanie stało się teraz ultra szybkie.
Co będzie dalej? W tzw. międzyczasie modny jest JavaScript, ponieważ jest totalnie niezależny od platformy, na jakiej się wykonuje. Do JavaScripta powstało wiele platform takich jak AngularJS, React, Backbone, Knockout.js. Wszystko po to aby było… szybciej! Stworzony został serwer Node wraz z setkami tysięcy gotowych modułów (sławny node_modules, który często ważą 50GB, czyli 1000 razy więcej niż sam projekt).
Wszystkim zależy na czasie, programowanie rozwija się w stronę szybkiego wytwarzania kodu. Programiści są drodzy, a pisanie systemów informatycznych trwa bardzo długo. Pisanie programów „wolno” nie ma sensu, ponieważ zanim powstaną, już stają się przeterminowane. W tym momencie pojawiają się określenia tzw. programisty oraz dewelopera.
Programista a deweloper
Na różnicę pomiędzy programistą a deweloperem nakierował mnie kiedyś wykładowca od mechaniki. Na zajęciach wywiązała się ciekawa dyskusja, na temat różnicy pomiędzy jednym a drugim. Po krótszej chwili doszliśmy do wniosku, że programista to osoba odpowiedzialna typowo za klepanie kodu. Za napisanie algorytmu, który ma działać tak i tak, który ma pobrać jakieś dane i zwrócić wynik. Programista nie zajmuje się niczym więcej. Fajnie, gdyby programista miał wysokie umiejętności matematyczne w momencie, gdy pisze bibliotekę, która będzie odpowiedzialna np. za przeprowadzanie obliczeń numerycznych.
Z drugiej strony deweloper (ang. software developer) jest osobą, na którą trzeba spojrzeć nieco szerzej. Jest on odpowiedzialny za większą koncepcję, ma wymyślić sposób, umieć połączyć kilka technologii lub kilka rozwiązań. Dla programisty z krwi i z kości ważne mogą okazać się umiejętności matematyczne/fizyczne/mechaniczne lub inne, w zależności w jakim projekcie pracuje. Dla dewelopera ważniejsze może się okazać znanie wielu technologii, umiejętność wykorzystania gotowych rozwiązań i bibliotek dostarczonych przez programistów.
Gdzieś kiedyś usłyszałem, że programista opracowuje skomplikowane biblioteki, które mają działać najszybciej jak to możliwe, a deweloper ma umieć z tych bibliotek korzystać. I tak np. pisząc gry deweloperzy korzystają z gotowych silników graficznych, którą są napisanie idealnie pod względem wydajności, i nie jest im do tego potrzebna matematyka. Z drugiej strony, nad silnikiem graficznym musieli pracować programiści, który na pewno nie mięli problemów z algebrą liniową.
Podział na programistę i dewelopera nie jest moim wymysłem. Choć w naszym kraju nie jest ten podział zbytnio respektowany, to jednak odwrotnie jest w USA. Tam stanowisko programisty (ang. programmer), a stanowisko dewelopera (ang. software developer) jest po prostu inaczej definiowane, te osoby odpowiedzialne są za inne rzeczy.
Czy można programować, nie znając matematyki?
Każdy medal ma dwie strony. Mimo że matematyka jest przydatna, oczywiście można programować bez niej. Przede wszystkim matematyka nie jest potrzebna front-endowcom (ang. front-end developer). Tworzenie szablonów, pisanie HTMLa lub reguł CSS nie wymagają żadnych skomplikowanych obliczeń. Głębszy front-end, czyli programowanie w jakimś frameworku JavaScript także nie będzie od nas wymagać matematyki. Tworząc aplikację w Angular, React lub czystym JavaScript potrzebne dane najpewniej zostaną dostarczone przez back-end.
Podsumowując artykuł powiedzmy otwarcie, matematyka niezbędna programiście (deweloperowi) nie jest. Można naprawdę dużo zarabiać i nie używać matematyki. Natomiast nie postrzegajmy matematyki jako tylko i wyłączenie obliczeń algebraicznych, bo ich jest stosunkowo mało. Patrzmy na nią jako zdolność analitycznego i abstrakcyjnego myślenia, która zawsze może przydać się projektując skomplikowane fragmenty systemu. Błyskotliwość, szybkość znajdywania rozwiązań są cechami pożądanymi w naszym zawodzie. Oto kilka ważnych wniosków:
- w informatyce i programowaniu jest bardzo dużo matematyki – jest to po prostu dziedzina związana z matematyką i bazująca na matematyce, jeżeli sądzisz inaczej to jesteś ignorantem,
- matematyka to nie tylko ułamki i całki – szczególnie w kontekście programowania. Doskonałym przykładem jest matematyka dyskretna, która wprowadza w świat pomiędzy matematyką a programowaniem, uczy logicznego myślenia, ukazuje mechanizmy które warto znać i umieć z nich korzystać,
- można być dobrym matematykiem i nie umieć programować – no wiadomo, tak się zdarza, znam realne przypadki (nie znam na to wytłumaczenia),
- można być dobrym deweloperem i nie umieć matematyki – można zajmować się np. aplikacjami internetowymi, nie pakować się w problemy, których nie umiemy rozwiązać (czyli dedykowane aplikacje bazujące na skomplikowanych obliczeniach),
- nie można być dobrym programistą i nie umieć matematyki – ale chyba wszystko zależy od kontekstu, jak rozumiemy różnicę pomiędzy programistą, a deweloperem i czy taką granicę w ogóle uznajemy. No nie oszukujmy się, będąc matematycznym zerem, silnika do gry nie napiszemy, symulacji fizycznej nie napiszemy, biblioteki do obliczeń metodą MES nie napiszemy, biblioteki rozwiązującej całki metodą Newtona-Cotesa nie napiszemy. Możemy co najwyżej, jako deweloper, wykorzystać istniejące biblioteki,
- wielu sławnych programistów, którzy są nieprzeciętnie dobrzy, są z wykształcenia matematykami,
- bardziej potrzebni są deweloperzy niż programiści – jest mało projektów, które wymagają wysokich zdolności matematycznych. Nikt nie zatrudni „matematycznego zera” do pisania takiej aplikacji jak MatLab, jednak powiedzmy sobie szczerze takich stanowisk jest mniej. IT stoi mocno na aplikacjach bankowych, systemach z rodziny ERP służących do zarządzania firmami itp. Tam matematyki nie ma. Jeżeli ktoś mądry napisał bibliotekę do obsługi formatu Mp3 (dźwięk w formacie mp3 zapisany jest w postaci szeregu furiera), to każdy inny program będzie z niej korzystał. Nikt nie wprowadza swoich kodowań audio, tylko korzysta z istniejących i sprawdzonych.
Na sam koniec warto jeszcze dodać, że umiejętności matematyczne mogą przydać się podczas szukania pracy. Wierzcie lub nie, jednak na krakowskim rynku IT są firmy, które na rozmowie rekrutacyjnej dają zadania z czystej matematyki i każą je rozwiązać na kartce. Na szczęście takie firmy to odosobnione przypadki.
Artykuł został pierwotnie opublikowany na p-programowanie.pl. Zdjęcie główne artykułu pochodzi z unsplash.com.