Techniki Zaawansowane
8 godz. 35 min · Java · Full-stack i Programowanie
Rafał SolarskiW poczatkowych lekcjach przyjrzymy sie pokladowi, na jakim bedziemy uruchamiali nasze programy. Wykorzystamy VisualVM do podgladania parametrów JVM. Zobaczymy równiez jakie zasoby sa tam dostepne oraz dowiesz sie jak monitorowac to, czy dobrze z nich korzystamy. Opowiemy Ci tez miedzy innymi o tym, jak zrobic heap i thread dump, oraz jak wlaczyc logi GC.
Kolejne lekcje kursu zostaly poswiecone wyrazeniom regularnym. Wyrazenia regularne mozemy wykorzystac nie tylko do walidacji danych wprowadzania przez uzytkownika, ale równiez do dzielenia tekstu oraz wyluskiwania wystapien wzorców w duzym tekscie. W tym rozdziale dowiemy sie miedzy innymi tego, jak mozemy wykorzystac ten potencjal z poziomu Javy.
Dzieki typom generycznym jestesmy w stanie osiagnac bezpieczenstwo typów w trakcie kompilacji przy zachowaniu elastycznosci pisanego kodu. W nastepnym rozdziale kursu przyjrzymy sie temu, jak mozemy je wykorzystac, oraz w jaki sposób czasami nalezy z tego bezpieczenstwa zrezygnowac.
Interfejsy funkcyjne to sposób na przeniesienie odrobiny swiata programowania funkcyjnego do Javy. Gdy polaczymy je z wyrazeniami lambda oraz API strumieni pozwola nam pisac te sama logike w duzo bardziej przejrzysty sposób.
Kolekcje, czyli listy, mapy, zbiory i kolejki to jedne z najczesciej wykorzystywanych klas w codziennej pracy. To jak dobrze poznamy ich mozliwosci ma ogromny wplyw na to, w jaki sposób bedziemy podchodzili do rozwiazywania wyzwan na naszej drodze.
System plików to zasób bez którego ciezko sobie poradzic. Pozwalaja nam na dostarczanie konfiguracji, danych wejsciowych i wyjsciowych, a przez to równiez integrowanie ze soba calych systemów.W tym rozdziale nauczymy sie korzystac z tych dobrodziejstw w bezpieczny sposób wykorzystujac m.in. IO Streams.
Trzymanie daty w String to niekoniecznie najwygodniejszy sposób. Juz od pewnego czasu Java dysponuje bardzo wygodnym Date&Time API - zobaczymy, co mozemy w nim znalezc.
Wielowatkowosc nie jest prosta... i dlugo tak jeszcze pozostanie. Nawet jesli korzystamy z frameworków, które próbuja ja przed nami ukryc, to ciagle musimy byc swiadomi problemów jakie sie z nia wiaza. W tym rozdziale poznamy glówne problemy na jakie mozna natrafic programujac wielowatkowo w Javie. Poznamy równiez klasy, które zdecydowanie pomoga nam zapanowac nad ta zlozonoscia.
JDBC to najbardziej podstawowy sposób laczenia sie z baza SQL z poziomu Javy. W wielu systemach/aplikacjach stosuje sie rozwiazania ORM takie jak JPA/Hibernate. Mimo wszystko warto wiedziec jak to pod spodem dziala oraz umiec poradzic sobie w aplikacjach, gdzie wybrano bardziej "lekkie" podejscie niz Hibernate.
Na koniec kursu wykorzystamy zdobyta wiedze, aby stworzyc prosta aplikacje pozwalajaca na przechowywanie danych o wydatkach. Po stworzeniu coreu aplikacji, mozesz spróbowac uzupelnic go za pomoca GUI.
Ten kurs stworzony zostal przede wszystkim z mysla o osobach, które juz poznaly podstawy jezyka, takie jak zmienne, mechanizmy kontroli wykonania, klasy, typy generyczne.Jezeli chcesz poczuc sie swobodnie nie tylko jesli chodzi o mechanizmy jezyka, ale równiez pod wzgledem znajomosci standardowej biblioteki Javy - to kurs w sam raz dla Ciebie. Materialy beda przydatne dla studentów, którzy znaja juz podstawowa skladnie Javy; programistów Javy chcacych poszerzyc lub uporzadkowac swoja wiedze; programistów innych jezyków, którzy chca poznac inny stack technologiczny.
Cześć w tej lekcji kontynuujemy naszą zabawę ze strumieniami z lambdami
oraz częstymi błędami przy ich wykorzystaniu w tym programie tworzymy
sobie strumień zawierający elementy od jednego do 100 i tutaj mapujemy
sobie poszczególne elementy dodajemy je nazywamy te elementy wpadające
jako id i dodajemy sobie jakiś prefiks jakieś e tutaj
małpę i domain name tak czyli generujemy sobie jakieś adresy
mailowe okej i to tutaj działa teraz
zobaczmy jedną rzecz że tutaj wewnątrz tej lambdy wykorzystujemy id
prefiks oraz domain name które są tutaj jakimiś no właśnie zmiennymi
statycznymi tak tej klasy jeżeli chcemy używać
tego w lambdzie to to nam się oczywiście skompiluje zadziała ale
ktoś może nam to zmienić lepszą praktyką jest wykorzystywanie stałych
tutaj tak tutaj tak nie wydaje mi się żebyśmy wewnątrz naszego
programu chcieli zmieniać domain name tak jako jakąś zmienną statyczną tutaj
tak więc dodajemy po prostu public final static tak w tym
miejscu okej i to już jest jak najbardziej taki w porządku fragment
możemy spokojnie sobie tego używać i idźmy dalej tutaj już trochę rozrósł nam
się przykład wyekstrahowaliśmy metodę make adres która skleja ten adres
mamy też metodę sendmail która udaje że wysłała maila po prostu printuje to
na konsolę żeby wysłała i też chcemy jeszcze tutaj zliczyć
liczby wysłanych maili od momentu startu programu tutaj akurat raz tylko
jest taka seria że wysłałam te 100 000 później już nie są wysyłane one się kończą ale
załóżmy że tej klasy można używać z innych klas ona nie powinna
się nazywać main ale powiedzmy teraz jest taki przykład i teraz pytanie czy
takie zliczanie tutaj jeżeli w tej metodzie jest send mail po prostu inkremetujemy to
czy to jest bezpieczne na razie to jest bezpieczne z tego względu że tutaj
ten static jest private tak czyli tylko z tego
miejsca i z tych metod które są w main możemy edytować tak zmieniać
wartość tej zmiennej oraz druga rzecz trochę mi na pierwszy rzut oka
widoczna to to że te metody których używamy wewnątrz
tego strumienia są w tym momencie wykonywane sekwencyjne ponieważ ten strumień
jest sekwencyjny ale jeżeli dodamy tutaj parę tak czyli zamienimy
ten strumień na strumień który jest współbieżny tak
rozproszony no to czy to już nie będziemy mieli tej gwarancji te
elementy metody tutaj które są wykonywane od tego momentu powinny być
thread safety tak czyli powinny być bezpieczne do wykonywania
wielu wątków na raz teraz się przyjrzymy czy są make address tylko
dostaje integera tak jakiś id skleja sobie
stringa i zwraca go tak nie modyfikuje żadnego stanu więc to jest okej
ale jest metoda sendmail która trochę modyfikuje stan zmienia nam tego longa
tutaj teraz jest taki problem że ze względu na to że ten send
mail będzie wykonywany z wielu wątków to możemy dostać pewną anomalię
w tym miejscu odpalmy sobie tutaj tę metodę i zobacz wysłaliśmy
niby 100 000 maili ale nasz counter pokazuje
mniej brakuje tutaj 14 elementów i teraz z czego to wynika
to jest taka anomalia związana z tym że zapis i odczyt tej
zmiennej tutaj nie są atomowe to znaczy może mieć sytuację kiedy dla
najprostszego przykładu dwa wątki na raz spróbuje implementować
send mail tak tego countera jedna sobie wyciąga stan który jest na początku 0
i druga sobie wyciąga zera ale robią to na raz tak i teraz jedna bierze 0
dodaje do niej jedynkę dostaje jedynkę i w tym samym momencie druga też wyciąga
zero dodaje jedynkę i obie zapisują w tym samym momencie jedynkę
no i teraz tak jedna zapisała jedynkę druga nadpisała tę wartość
też jedynką no i mamy w counterze 1 a maili wysłaliśmy 2
to jest taki problem że ten counter który powinniśmy użyć powinien być też
bezpieczny pod względem wątkowości i tak możemy w tym celu
zamiast longa użyć atomic longa w tym więcej się dowiemy już w rozdziale o
wielowątkowości współbieżności atomic long ma taką cechę
że możemy go spokojnie inkrementować z wielu wątków nie zawsze będzie to
super wydajne ale jest to bezpieczne tutaj zamiast przypisywać po prostu
robimy increment get on po prostu poza tym że zwróci ten element
po zinkrementowaniu to bezpiecznie zainkrementuje nam tę wartość możemy
teraz odpalić nasz przykład i już widzimy że mamy 100 000 okej czyli
to już jest ta bezpieczniejsza wersja teraz na potrzeby jeszcze jednej rzeczy wrócimy sobie
do sytuacji kiedy mieliśmy sekwencyjny strumień i tutaj mamy tego
send mail prawda oraz tutaj jeszcze możemy sobie inkrementować
send mail zróbmy inline teraz tej metody send mail z miejsca
żebybyśmy mieli zamiast tej metody po prostu lambdę tutaj okej tak
to wygląda i teraz sprawdźmy co by się stało jeżeli nie
chcemy mieć tego countera tutaj to chciałbym go mieć tutaj zakomentujmy
sobie to na razie tutaj i utwórzmy na poziomie metody main teraz
to co przed chwilą jeszcze działało już teraz nam nie działa dlaczego dlatego
że w javie po wprowadzeniu lambd wprowadzono taki mechanizm
który blokuje nas przed wykorzystaniem wewnątrz lambdy
parametru jakiejś referencji do obiektu który nie jest finalowy
czyli który nie jest stały albo który nie jest efektywnie stały
ale z wyłączeniem że jest musi być to referencja
do obiektu który jest albo parametrem metody tak
czyli w tym momencie mielibyśmy to jako argument albo jest to zmienna lokalna
czyli tak jak tutaj dopóki mieliśmy to na poziomie jakiejś
zmiennej globalnej jakiegoś statica w main'ie to wszystko było
okej wszystko się kompilowało działało ale teraz jeżeli stworzymy to sobie tutaj i tutaj
sobie zainkrementujemy nie musimy nawet inkrementować tego tutaj wewnątrz lambdy
tak ale wystarczy że tutaj już zmienimy send mails plus
plus tak no to już teraz tam to nie działa teraz o co chodzi z
tym że to jest efektywnie final może być albo final czyli mamy parametr który
jest poprzedzony final ale nie musimy tego robić tak tutaj teraz
zadziała pod warunkiem że wartość tej zmiennej tutaj
nie jest nigdy zmieniana w przypadku primitive nie jest zmieniana jego wartość w przypadku
wtedy kiedy to jest referencja na jakiś obiekt to nie jest po prostu pozmieniany po swojemu
to obiekt tutaj może istnieć być coś jakiś obiekt którego zawartość
w środku zmieniamy tak on jest mutowalny ale nigdy nie zmienia
się to co jest pod tym tak co jest pod tą nazwą okej
to jest tak zwane effectivly final okej podsumujmy czego się nauczyliśmy po
pierwsze jeżeli do czegoś referujemy na jakieś statycznej zmiennej
czy powiedzmy do jakiegoś statycznego obiektu no to po pierwsze zadbajmy o to żeby
to był final druga rzecz jeżeli już musimy zmieniać stan tego
czegoś albo wykorzystujemy nie tyle zmienne
statyczne które są dziś poza nami ale na przykład nasze metody korzystając
z jakichś czy to globalnego jakiegoś stanu czy na przykład modyfikują
bazę czy cokolwiek to jeżeli jesteśmy
w środowisku z którego korzysta wiele wątków czyli na przykład masz strumień jest z parallel
to musimy zadbać aby te elementy w mapach i w tych wszystkich
operacjach po kolei wykonywanych były thread safety ostatnią
rzeczą którą się nauczyliśmy jest to że nie do każdego elementu możemy
w ogóle dostać się z poziomu lambdy nie możemy dostać się do
elementów które są nie są final albo które nie są przynajmniej effectively
final tak to tyle na tę lekcję a już w kolejnej
lekcji nauczymy się jak sobie radzić z wyjątkami wewnątrz lambd dzięki wielkie
i do zobaczenia