JavaRush /Blog Java /Random-PL /Analiza pytań i odpowiedzi z rozmów kwalifikacyjnych dla ...

Analiza pytań i odpowiedzi z rozmów kwalifikacyjnych dla programisty Java. Część 6

Opublikowano w grupie Random-PL
Witaj świecie! Ciągły rozwój jest bardzo ważny dla każdego programisty. W końcu, jeśli przestaniesz, istnieje ryzyko, że zostaniesz nieodebrany i całkowicie wylecisz z rynku: świat IT stale się rozwija i posuwa do przodu, a Ty musisz iść z nim. Ale jednocześnie nie można skupiać się wyłącznie na nowych i świeżych technologiach, aby nie zapomnieć, że tak powiem, o klasyce (tematy klasyczne). Dzisiaj chcę kontynuować analizę pytań dotyczących „klasycznych” tematów dla programisty Java. Analiza pytań i odpowiedzi z rozmów kwalifikacyjnych dla programisty Java.  Część 6 - 1Zaznaczam, że moje odpowiedzi nie są ostatecznym autorytetem – tak po prostu widzę prawidłowe odpowiedzi na te pytania i z częścią z nich możesz się nie zgodzić. Będzie to całkiem normalne, więc nie wahaj się podzielić swoją opinią w komentarzach. Linki do części analizy znajdują się na końcu artykułu.Analiza pytań i odpowiedzi z rozmów kwalifikacyjnych dla programisty Java.  Część 6 - 2

Biblioteki i standardy

52. Co to jest hibernacja? Jaka jest różnica między JPA a Hibernacją?

Myślę, że aby odpowiedzieć na to pytanie, najpierw musimy zrozumieć, czym jest JPA . JPA to specyfikacja opisująca obiektowo-relacyjne mapowanie prostych obiektów Java i udostępniająca interfejs API do przechowywania, pobierania i manipulowania takimi obiektami. Oznacza to, że jak pamiętamy, relacyjne bazy danych (DB) prezentowane są w postaci wielu połączonych ze sobą tabel. JPA to powszechnie akceptowany standard opisujący sposób, w jaki obiekty mogą wchodzić w interakcję z relacyjnymi bazami danych . Jak widać, JPA jest czymś abstrakcyjnym i nieuchwytnym. Podobnie jak sam pomysł, podejście. Analiza pytań i odpowiedzi z rozmów kwalifikacyjnych dla programisty Java.  Część 6 - 3Jednocześnie Hibernate jest specyficzną biblioteką implementującą paradygmaty JPA . Oznacza to, że za pomocą tej biblioteki można pracować z relacyjną bazą danych poprzez obiekty reprezentujące dane z bazy danych (Entity). Jak mówią, biblioteka ta jest bardzo bliska ideałom WZP i być może dlatego stała się popularna. A jak rozumiesz, popularność użytkowania jest dobrym argumentem za dalszym rozwojem i ulepszeniami. Dodatkowo za jego częstym używaniem stoi ogromna społeczność, która już uporała się ze wszystkimi możliwymi i niemożliwymi pytaniami związanymi z tym narzędziem. Oto przykład książki , która szczegółowo bada wszystkie ciemne zakątki tej technologii. Oznacza to, że Hibernate został zbadany tak bardzo, jak to możliwe i, jak się okazuje, jest niezawodny. Właściwie nie bez powodu nawet idealna implementacja JPA po stronie Springa zwykle wykorzystuje Hibernate pod maską.

53. Co to jest kaskadowanie? Jak jest używany w Hibernacji?

Jak powiedziałem wcześniej, w Hibernacji komunikacja odbywa się poprzez obiekty danych zwane jednostkami . Encje te reprezentują pewne konkretne tabele w bazie danych, a jak pamiętasz, w Javie klasy mogą zawierać odniesienia do innych klas. Zależności te znajdują odzwierciedlenie w bazie danych. W bazie danych są to z reguły klucze obce (dla OneToOne, OneToMany, ManyToOne) lub tabele pośrednie (dla ManyToMany).Więcej o relacjach pomiędzy encjami przeczytasz w tym artykule . Gdy Twój podmiot posiada linki do innych powiązanych podmiotów, nad tymi linkami umieszczane są adnotacje wskazujące rodzaj połączenia: @OneToOne, @OneToMany, @ManyToOne, @ManyToMane, w których parametrach możesz określić wartość właściwości - kaskada - rodzaj kaskady dla tego połączenia. JPA ma specyficzne metody interakcji z jednostkami (utrwalanie, zapisywanie, łączenie...) . Typy kaskadowe są dokładnie używane do pokazania, jak powinny zachowywać się powiązane dane, gdy te metody są używane w encji docelowej. Jakie są zatem strategie kaskadowe (rodzaje kaskadowania)? Standard JPA zakłada zastosowanie sześciu typów kaskadowania:
  • PERSIST - operacje zapisu będą wykonywane kaskadowo (dla metod save() i Persist() ). Oznacza to, że jeśli zapiszemy podmiot powiązany z innymi podmiotami, to one również zostaną zapisane w bazie danych (o ile ich jeszcze tam nie ma)

  • MERGE - operacje aktualizacji będą wykonywane kaskadowo (dla metody merge() )

  • REMOVE - operacje usuwania wykonywane są kaskadowo ( metoda usuwania() )

  • WSZYSTKIE - zawiera trzy operacje kaskadowe na raz - TRZYMAJ - POŁĄCZ - USUŃ

JPA ma koncepcję jednostki trwałej jednostki powiązanej z jej danymi w bazie danych, która jest kontrolowana przez bieżącą sesję (połączenie) . Jeśli go zmienisz, ale nie zapiszesz zmian w bazie danych, jego dane w bazie nadal ulegną zmianie.
  • DETACH – powiązane podmioty nie będą zarządzane przez sesję ( metoda detach() ). Oznacza to, że gdy ulegną zmianie, nie nastąpi automatyczna zmiana ich danych w bazie - zostaną przeniesione ze stanu trwałości do stanu odłączonego (podmiot nie zarządzany przez JPA)

  • ODŚWIEŻ - za każdym razem, gdy encja jest aktualizowana danymi z bazy danych ( odświeżanie () - aktualizuje odłączone obiekty), powiązane encje są aktualizowane w ten sam sposób. Na przykład w jakiś sposób zmieniłeś dane pobrane z bazy danych i chcesz zwrócić ich pierwotne wartości. W takim przypadku ta operacja będzie dla Ciebie przydatna.

Analiza pytań i odpowiedzi z rozmów kwalifikacyjnych dla programisty Java.  Część 6 - 4Hibernate obsługuje wszystkie te standardowe operacje kaskadowe, ale wprowadza także trzy własne:
  • REPLICATE - Używane, gdy mamy więcej niż jedno źródło danych i chcemy, aby dane były synchronizowane (metoda Hibernate - replikacja). Wszystkie podmioty muszą posiadać identyfikatory (id), aby nie było problemów z ich wygenerowaniem (aby ten sam podmiot nie miał różnych identyfikatorów dla różnych baz danych)

  • SAVE_UPDATE - kaskadowe zapisywanie/usuwanie (dla metody Hibernate - saveOrUpdate )

  • LOCK jest operacją odwrotną do DETACHED : przenosi odłączoną jednostkę z powrotem do stanu trwałości , tj. obiekt będzie ponownie śledzony w bieżącej sesji

Jeśli nie zostanie wybrany typ kaskadowy, żadna operacja na elemencie nie będzie miała żadnego wpływu na inne powiązane z nim encje.

54. Czy klasa Entity może być abstrakcyjna?

W specyfikacji JPA w paragrafie 2.1 Klasa encji znajduje się wiersz: „ Jednymi jednostkami mogą być zarówno klasy abstrakcyjne, jak i konkretne ”. Odpowiedź brzmi: tak, klasa abstrakcyjna może być jednostką i można ją opatrzyć adnotacją @Entity.

55. Kim jest menadżer podmiotu? Za co jest odpowiedzialny?

Na wstępie chciałbym zaznaczyć, że EntityManager to jeden z kluczowych komponentów JPA , który służy do interakcji podmiotów z bazą danych. Generalnie wywołuje metody interakcji podmiotu z bazą danych (utrwalanie, łączenie, usuwanie, odłączanie)... Ale zaznaczę też, że ten komponent z reguły nie jest jeden dla całej aplikacji: najczęściej jest lekki i często jest usuwany, a nowy jest tworzony przy użyciu EntityManagerFactory . Jeśli narysujemy analogię z JDBC , gdzie EntityManagerFactory będzie odpowiednikiem DataSource , to z kolei EntityManager będzie odpowiednikiem Connection . Wcześniej wspomniałem o encji trwałości , jako o encji kontrolowanej przez bieżące połączenie. A więc: tą encją zarządza dokładnie EntityManager , który jest ściśle powiązany z bieżącym połączeniem oraz TransactionManager , który odpowiada za otwieranie/zamykanie transakcji. W dalszej części rysunku poniżej możesz zobaczyć cykl życia encji: Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6 - 5EntityManager zarządza encją gdy jest na etapie Zarządzany (w tym momencie jest trwały, ponieważ ma połączenie z EntityManagerem). Oznacza to, że nie jest już nowy i nie został jeszcze usunięty. Można powiedzieć, że gdy byt jest nowy lub usunięty, jest również odłączony, ponieważ nie jest zarządzany przez EntityManager. Istnieją różne strategie dla EntityManager. Oznacza to, że może istnieć jeden singleton EntityManager dla całej aplikacji lub za każdym razem można tworzyć nowy dla każdego połączenia. Jeśli używasz Springa, tworzenie/usuwanie EntityManagera jest kontrolowane automatycznie pod maską (ale to nie znaczy, że nie możesz go dostosować ^^). Warto powiedzieć, że jeden lub więcej EntityManagerów tworzy kontekst trwałości . Kontekst trwałości to środowisko, w którym instancje encji są synchronizowane z podobnymi encjami w bazie danych (jak powiedziałem, działa to tylko w przypadku encji trwałych). Jeśli zagłębisz się w JPA (co gorąco polecam), natkniesz się na te koncepcje bardzo, bardzo często.

56. Co to jest klasa Assert? Dlaczego go używać?

Nie słyszałem o takiej klasie w JPA , więc przyjmę, że odnosi się to do klasy JUnit biblioteki, która służy do jednostkowych testów kodu. Klasa tej biblioteki, Assert , służy do sprawdzania wyników wykonania kodu ( assert to stwierdzenie, że masz określony stan/dane w określonym miejscu). Na przykład testujesz metodę, która powinna stworzyć kota. Uruchamiasz metodę i otrzymujesz wynik:
Cat resultOfTest = createCat();
Ale trzeba mieć pewność, że został stworzony poprawnie, prawda? Dlatego też wcześniej utworzyłeś ręcznie określonego kota - oczekiwanego Kota - z dokładnie takimi parametrami, jakich oczekujesz od kota, uzyskanymi za pomocą metody createCat() . Następnie użyj klasy Assert , aby zweryfikować wyniki:
Assert.assertEquals(resultOfTest, expectedCat);
Jeśli koty są różne, zostanie zgłoszony wyjątek AssertionError , który informuje nas, że oczekiwane wyniki nie są zbieżne. Klasa Assert posiada wiele różnych metod, które obejmują wiele zadań związanych z weryfikacją oczekiwanych wyników. Tutaj jest kilka z nich:
  • AssertTrue(<boolean>) - oczekiwana wartość otrzymana jako argument musi być prawdziwa

  • AssertFalse(<boolean>) - oczekiwana wartość otrzymana jako argument powinna być fałszywa

  • AsserNotEquals(<object1>, <object2>) - obiekty otrzymane jako argumenty muszą być różne przy porównywaniu przy użyciu równości ( false )

  • AssertThrows(<ClassNameOfException>.class, <exceptionObject>) - oczekuje się, że drugi argument będzie wyjątkiem klasy określonej przez pierwszy argument (czyli z reguły w miejsce drugiego argumentu wywoływana jest metoda, która powinna zgłosić wyjątek wymaganego typu)

Strunowy

57. Scharakteryzuj ciąg w Javie

String to standardowa klasa w Javie, odpowiedzialna za przechowywanie i manipulowanie wartościami stringów (ciągów znaków), jest klasą niezmienną ( o immutable pisałem wcześniej ), tj. Dane obiektów tej klasy nie mogą zostać zmienione po utworzeniu. Od razu zaznaczę, że klasy StringBuilder i StringBuffer to dwie praktycznie identyczne klasy, z tą tylko różnicą, że jedna z nich jest przeznaczona do użycia w środowisku wielowątkowym (StringBuffer). Klasy te są analogiczne do String , ale w przeciwieństwie do nich można je modyfikować . Oznacza to, że raz utworzone obiekty umożliwiają modyfikację ciągu, który reprezentują, bez tworzenia nowego obiektu. Właściwie metody te różnią się od standardowych metod String i mają na celu zaspokojenie potrzeb zmiany ciągu znaków (nie bez powodu nazywane są budowniczymi). Przeczytaj więcej o String , StringBuffer i StringBuilder w tym artykule .

58. Jakie są różne sposoby tworzenia obiektu String? Gdzie jest tworzony?

Najczęstszym sposobem utworzenia ciągu jest po prostu podanie potrzebnej wartości w podwójnych nawiasach:
String str = "Hello World!";
Możesz to również zrobić bezpośrednio poprzez new :
String str = new String("Hello World!");
Możesz utworzyć ciąg znaków zaczynając od tablicy znaków:
char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
W wyniku działania metody toString na jakimś obiekcie:
String str = someObject.toString();
Podobnie jak wynik każdej innej metody, zwraca reprezentację ciągu znaków. Na przykład:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str =  reader.readLine();
Jak rozumiesz, istnieje bardzo, bardzo wiele sposobów na utworzenie ciągu. Kiedy tworzony jest obiekt String , jest on przechowywany w puli ciągów , o czym porozmawiamy bardziej szczegółowo w jednym z poniższych pytań.

59. Jak porównać dwa ciągi znaków w Javie i jak je posortować?

Aby porównać wartości w Javie, używany jest podwójny znak równości == . Gdybyśmy musieli porównać niektóre proste wartości, takie jak int , użylibyśmy tego. Ale ta metoda nie ma zastosowania do porównywania pełnoprawnych obiektów. W tym przypadku będzie to jedynie porównanie odniesień – czy wskazują na ten sam obiekt, czy nie. Oznacza to, że porównując dwa obiekty o dokładnie takich samych wartościach pól wewnętrznych, porównanie poprzez == da wynik fałszywy : pomimo identycznych pól obiektów same obiekty zajmują różne komórki pamięci. A obiekty klasy String , pomimo swojej zwodniczej prostoty, nadal są obiektami. Porównanie za pomocą == również nie ma dla nich zastosowania (nawet pomimo obecności puli ciągów). Tutaj w grę wchodzi standardowa metoda klasy Object - równa się , którą należy przesłonić w klasie, aby działała poprawnie (w przeciwnym razie domyślnie porównuje za pomocą == ). Jest on zastępowany w klasie String , więc po prostu go bierzemy i używamy:
String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6 - 6Mówiliśmy o porównaniach dopasowujących, teraz spójrzmy na porównania sortujące. W końcu, aby coś posortować, musimy wiedzieć, według jakiej zasady sortować. Aby to zrobić, możesz użyć standardowego zestawu posortowanego - TreeSet . Więcej o różnych kolekcjach w Javie możesz przeczytać w tym artykule . Lista ta działa w oparciu o algorytm drzewa czerwono-czarnego i sortuje zbiór zgodnie z określoną zasadą sortowania. Jak powiedziałem wcześniej, musisz zrozumieć, jak sortować obiekty określonego typu. Komparatory służą do ustawiania metody porównywania podczas sortowania . Zazwyczaj należy je zaimplementować dla klas, które chcesz sortować, ale w przypadku String są już zaimplementowane. Dlatego po prostu dodajemy potrzebne wiersze do TreeSet , a on je posortuje:
TreeSet<String> sortedSet = new TreeSet<>();
sortedSet.add("B");
sortedSet.add("C");
sortedSet.add("A");
sortedSet.forEach(System.out::println);
Wyjście konsoli:
A B C

60. Podaj algorytm konwersji ciągu znaków na znak. Napisz odpowiedni kod

Jak powiedziałem wcześniej, obiekty klasy String posiadają wiele różnych, przydatnych metod. Jednym z nich jest toCharArray . Ta metoda konwertuje ciąg znaków na tablicę znaków:
String str = "Hello world";
char[] charArr = str.toCharArray();
Następnie mamy tablicę znaków, które możemy wywołać według indeksu:
char firstChar = charArr[0]; // H

61. Jak przekonwertować ciąg znaków na tablicę bajtów i odwrotnie? Napisz odpowiedni kod

Podobnie jak metoda toCharArray , klasa String posiada metodę getBytes , która zwraca tablicę bajtów ciągu:
String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
Dzisiejsza część analizy dobiegła logicznego końca. Dziękuję za uwagę!Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 6 - 7
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION