CodeGym /Blog Java /Poland /Utknęliście? Najtrudniejsze części nauki języka Java i to...
CodeGym
Poziom 41

Utknęliście? Najtrudniejsze części nauki języka Java i to, jak sobie z nimi poradzić

Opublikowano w grupie Poland
Jak zapewne wiesz, zalecamy początkującym adeptom kodowania rozpoczęcie nauki języków programowania od Javy, a CodeGym ma wszystko, aby uczynić edukację przyswajalną nawet dla najbardziej nieprzygotowanych uczniów. O ile jednak elementy grywalizacji, przystępna fabuła i zabawne postacie ułatwiają ten proces, o tyle nauka podstaw Javy w pełnym zakresie dla większości nowych uczniów rzadko przebiega bez problemów. Utknęliście? Najtrudniejsze części nauki języka Java i to, jak sobie z nimi poradzić - 1Dzisiaj przyjrzymy się niektórym z najtrudniejszych obszarów podstaw programowania w Javie, próbując zrozumieć, dlaczego wiele osób uważa je za trudne i czy można coś z tym zrobić.

1. Typy generyczne

Typy generyczne w Javie to typy, które mają parametr. Podczas tworzenia typu generycznego określa się nie tylko typ, ale także typ danych, z którymi będzie on współpracował. Typy klasy Generics są często wymieniane przez uczniów Javy jako jeden z najtrudniejszych do zrozumienia elementów tego języka. „Moim głównym problemem wciąż jest korzystanie z klasy Generics. Jest o wiele łatwiej, gdy ma się do dyspozycji metody z parametrami, ale staje się zagmatwane, gdy trzeba napisać własne” – powiedział anonimowy uczeń Javy.

Wskazówki i zalecenia

Oto opinia Raviego Reddy'ego, doświadczonego programisty i profesora uniwersyteckiego, na temat typów generycznych w Javie: „Typy klasy Generics w Javie robią jedną rzecz, której nie są w stanie zrobić szablony C++ — implementują bezpieczeństwo typów. Implementacja szablonów w języku C++ jest zwykłą sztuczką preprocesora i nie zapewnia bezpieczeństwa typu. Typy generyczne w Javie są jak szablony w C++, lecz z dodatkowym zabezpieczeniem typu. Moim skromnym zdaniem bezpieczeństwo typów jest podstawową cechą każdego dobrego środowiska programistycznego. I owszem! Mogą one wydawać się skomplikowane ze względu na nasze mentalne przesunięcia między parametrami a typami. Uważam jednak, że warto poświęcić czas na ich opanowanie. Ponieważ po zrozumieniu interfejsów i typów generycznych o wiele lepiej „myślało mi się” w Javie”.

2. Wielowątkowość

Wielowątkowość w Javie to proces jednoczesnego wykonywania dwóch lub więcej wątków w celu osiągnięcia maksymalnego wykorzystania procesora przez aplikację. Wielowątkowość rozwiązuje bardzo ważne zadania i może przyspieszyć działanie naszych programów. Często wielokrotnie. Uważa się jednak, że jest to jeden z tematów, w których wielu świeżo upieczonych adeptów Javy ma tendencję do utknięcia. Wszystko dlatego, że wielowątkowość może również stwarzać problemy, zamiast je rozwiązywać. Istnieją dwa konkretne problemy, które może powodować wielowątkowość: impas i wyścig. Impas (zakleszczenie) to sytuacja, w której wiele wątków czeka na utrzymywane przez siebie zasoby i żaden z nich nie może kontynuować pracy. Wyścig to błąd projektowy w wielowątkowym systemie bądź aplikacji, w którym ich działanie zależy od kolejności wykonywania poszczególnych części kodu.

Wskazówki i zalecenia

Oto dobra rekomendacja, jak radzić sobie z wielowątkowością, autorstwa S. Lotta, architekta oprogramowania i aktywnego użytkownika StackExchange, popularnej strony z pytaniami i odpowiedziami: "Wielowątkowość jest prosta. Zakodowanie aplikacji do pracy wielowątkowej jest bardzo, bardzo proste. Jest na to prosty sposób, a polega on na użyciu dobrze zaprojektowanej kolejki komunikatów (nie należy tworzyć własnej) do przekazywania danych między wątkami. Najtrudniejszą częścią jest próba uaktualnienia w jakiś magiczny sposób obiektu współdzielonego przez wiele wątków. Właśnie wtedy pojawia się ryzyko wystąpienia błędów, ponieważ użytkownicy nie zwracają uwagi na występujący wyścig. Wiele osób nie korzysta z kolejek komunikatów i próbuje aktualizować obiekty współdzielone, stwarzając sobie problemy. Trudne staje się zaprojektowanie algorytmu, który działa dobrze podczas przekazywania danych między kilkoma kolejkami. To jest trudne. Lecz mechanika współistnienia wątków (poprzez kolejki współdzielone) jest prosta.”

3. Problemy związane ze ścieżkami klas

Błędy ścieżki klas są również uważane za jeden z najbardziej uciążliwych problemów, z jakimi borykają się programiści Javy w swojej codziennej pracy. „Problemy ze ścieżkami klas mogą być czasochłonne do usunięcia i zdarzają się w najgorszym możliwym czasie oraz miejscu: przed wydaniem i często w środowiskach, do których zespół programistów ma niewielki lub żaden dostęp. Mogą one również wystąpić na poziomie IDE i stać się źródłem obniżonej wydajności” - mówi Vasco Ferreira, doświadczony programista Java/Javascript i autor poradników dotyczących programowania.

Wskazówki i zalecenia

„Problemy związane ze ścieżkami klas nie są tak niskopoziomowe i nieosiągalne, jak mogłoby się wydawać na pierwszy rzut oka. Chodzi o to, że pliki zip (jar) znajdują się/nie znajdują się w pewnych katalogach, jak znaleźć te katalogi i jak debugować ścieżkę klas w środowiskach z ograniczonym dostępem. Dzięki znajomości ograniczonego zestawu pojęć, takich jak Class Loaders, Class Loader Chain oraz tryby Parent First / Parent Last, można skutecznie rozwiązywać te problemy" — wyjaśnia ekspert.

4. Polimorfizm i jego prawidłowe stosowanie

Jeśli chodzi o zasady OOP, wiele osób twierdzi, że trudno im było zrozumieć polimorfizm. Polimorfizm to zdolność programu do traktowania obiektów o tym samym interfejsie w taki sam sposób, bez informacji o konkretnym typie obiektu. Pomimo tego, że polimorfizm jest całkiem podstawowym tematem, jest dość obszerny i stanowi dobrą część fundamentu Javy. Dla wielu uczniów polimorfizm jest pierwszą trudnością w nauce języka Java. Wszystko dlatego, że istnieją różne formy polimorfizmu stosowane w różnych kontekstach, co może być mylące.

Wskazówki i zalecenia

Nie ma innego sposobu radzenia sobie z polimorfizmem niż nauczenie się go. Oto, jak Torben Mogensen, wykładowca programowania na Uniwersytecie Kopenhaskim, wyjaśnia tę koncepcję: „Proste przeciążanie: + może oznaczać zarówno dodawanie liczb całkowitych, dodawanie liczb zmiennoprzecinkowych, jak i (w niektórych językach) konkatenację ciągów znaków. Polimorfizm podtypu: Jeśli B jest podtypem (dziedziczy po) A, to każda wartość typu B może być użyta w kontekście, który oczekuje wartości typu A. Polimorfizm parametryczny: Typ A można sparametryzować za pomocą parametrów typu, dzięki czemu w różnych kontekstach można podawać różne argumenty typu, a więc instancjonować sparametryzowany typ do różnych typów konkretnych. Nazywa się to również „szablonami” lub „typami generycznymi” i jest zwykle określane w językach OO za pomocą nawiasów ostrokątnych (takich jak T<A>). Polimorfizm interfejsu. Jest to w zasadzie mechanizm, który ogranicza polimorfizm podtypów do podtypów implementujących określony interfejs lub polimorfizm parametryczny do parametrów typu, który implementuje określony interfejs”.

5. Refleksja

Refleksja to mechanizm umożliwiający badanie danych o programie w trakcie jego działania. Refleksja umożliwia eksplorację informacji o polach, metodach i konstruktorach klas. Umożliwia także pracę z typami, które nie były obecne w czasie kompilacji, lecz stały się dostępne w czasie wykonywania. Refleksja i logicznie spójny model wydawania informacji o błędach umożliwiają stworzenie poprawnego kodu dynamicznego. Jednak dla wielu osób zrozumienie, jak używać refleksji nie należy do łatwych zadań. Utknęliście? Najtrudniejsze części nauki języka Java i to, jak sobie z nimi poradzić - 2

Wskazówki i zalecenia

„W przypadku refleksji i Javy, refleksja pozwala Javie, która została zaprojektowana jako typ statyczny, na typowanie dynamiczne. Dynamiczne typowanie nie jest z natury złe. Prawda, pozwala to programiście na łamanie pewnych zasad OOP, ale jednocześnie umożliwia korzystanie z wielu potężnych funkcji, takich jak proxy w czasie wykonywania oraz wstrzykiwanie zależności. Tak, Java pozwala strzelać sobie w stopę za pomocą refleksji. Trzeba jednak bardzo wyraźnie wycelować broń w swoją stopę, zdjąć zabezpieczenie i pociągnąć za spust” — wyjaśnia Jayesh Lalwani, doświadczony programista Java i architekt aplikacji.

6. Strumienie wejściowe/wyjściowe

Strumienie umożliwiają pracę z dowolnym źródłem danych: Internetem, systemem plików komputera lub czymś innym. Strumienie są narzędziem uniwersalnym. Dzięki nim program może odbierać dane z dowolnego miejsca (strumienie wejściowe) i wysyłać je w dowolne miejsce (strumienie wyjściowe). Ich zadanie jest takie samo: pobrać dane z jednego miejsca i przesłać je do innego. Istnieją dwa rodzaje strumieni: strumienie wejściowe (służące do odbierania danych) i strumienie wyjściowe (przeznaczone do wysyłania danych). Wielu osobom trudno jest zrozumieć, na czym polega używanie strumieni, ponieważ Java ma wiele klas strumieni we/wy.

Wskazówki i zalecenia

„Java ma tak wiele klas strumieni we/wy głównie z powodu dwóch czynników. Pierwszym z nich jest dziedziczenie. Niektóre klasy pozostały ze względów historycznych i nie zostały wycofane, ponieważ uznawane są za nieszkodliwe. Po drugie, elastyczność. Różne aplikacje mają różne wymagania, dlatego użytkownik ma do wyboru wiele opcji w zależności od swoich potrzeb. Użyteczne abstrakcje zapewniają przejrzystość podczas czytania, a za pomocą kilku linii kodu można wiele osiągnąć” - mówi Jonas Mellin, szwedzki ekspert w dziedzinie Javy. Jakie aspekty języka Java były dla ciebie najtrudniejsze do zrozumienia lub zdarzyło ci się utknąć na nich na jakiś czas? Podziel się swoimi doświadczeniami w komentarzach.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION