CodeGym/Blog Java/Random-PL/Przeglądanie pytań i odpowiedzi z rozmowy kwalifikacyjnej...
John Squirrels
Poziom 41
San Francisco

Przeglądanie pytań i odpowiedzi z rozmowy kwalifikacyjnej na stanowisko programisty Java. Część 6

Opublikowano w grupie Random-PL
Witaj świecie! Dla każdego programisty istotne jest, aby nigdy nie przestawać się rozwijać. W końcu, jeśli przestaniesz, ryzykujesz utratą popytu i całkowitym wypadnięciem z rynku pracy. Świat IT stale się rozwija i idzie do przodu – trzeba iść za nim. Ale jednocześnie nie można po prostu zawsze korzystać z najnowszych technologii, aby nie zapomnieć o „klasykach” (klasycznych tematach związanych z tworzeniem oprogramowania). Dzisiaj chcę kontynuować dyskusję na „klasyczne tematy” dla programistów Java. Przeglądanie pytań i odpowiedzi z rozmowy kwalifikacyjnej na stanowisko programisty Java.  Część 6 - 1Zaznaczę, że moje odpowiedzi nie są ostatnim słowem. To tylko mój pogląd na prawidłowe odpowiedzi – z niektórymi z nich możesz się nie zgodzić. To po prostu w porządku, więc możesz podzielić się swoją opinią w komentarzach. Linki do poprzednich części recenzji znajdziesz na końcu artykułu. Przeglądanie pytań i odpowiedzi z rozmowy kwalifikacyjnej na stanowisko programisty Java.  Część 6 - 2

Biblioteki i standardy

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

Aby odpowiedzieć na to pytanie, myślę, że najpierw musimy zrozumieć, czym jest JPA. Jest 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 relacyjne bazy danych (DB) są reprezentowane jako zbiór połączonych ze sobą tabel. JPA to powszechnie przyjęty 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. Przeglądanie pytań i odpowiedzi z rozmowy kwalifikacyjnej na stanowisko programisty Java.  Część 6 - 3Ale Hibernate to specyficzna biblioteka, która implementuje paradygmaty JPA. Innymi słowy, możesz użyć tej biblioteki do pracy z relacyjną bazą danych za pośrednictwem obiektów reprezentujących dane w bazie danych (Entity). Mówi się, że ta biblioteka jest bardzo bliska ideałom WZP. Być może dlatego zyskało popularność. Jak można sobie wyobrazić, jego popularność uzasadniała dalszy rozwój i ulepszenia. Dodatkowo powszechne zastosowanie wynika z ogromnej społeczności, która zbadała już każde możliwe i niemożliwe pytanie związane z tym narzędziem. Hibernate został dokładnie przebadany i, jak się okazuje, jest niezawodny. Istnieje dobry powód, dla którego nawet idealna implementacja JPA na wiosnę zazwyczaj wykorzystuje Hibernate pod maską.

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

Jak powiedziałem wcześniej, komunikacja w Hibernacji odbywa się za pośrednictwem obiektów danych zwanych jednostkami. Podmioty te reprezentują określone tabele w bazie danych i, jak pamiętasz, klasy Java mogą zawierać odniesienia do innych klas. Zależności te znajdują także odzwierciedlenie w bazie danych. Z reguły są to klucze obce (dla relacji OneToOne, OneToMany, ManyToOne) lub tabele pośrednie (dla relacji ManyToMany). Jeśli Twoja encja posiada odniesienia do innych powiązanych encji, nad tymi odniesieniami umieszczane są adnotacje wskazujące typ relacji: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany. Możesz określić typ kaskady dla tej relacji we właściwości kaskady adnotacji. JPA ma specyficzne metody interakcji z jednostkami (utrwalanie, zapisywanie, łączenie ...). Typy kaskadowe służą do pokazania, jak powinny zachowywać się powiązane dane; metody te są stosowane w jednostce docelowej. Jakie są zatem strategie kaskadowe (typy kaskadowe)? Standard JPA przewiduje zastosowanie sześciu typów kaskad:
  • PERSIST — operacje zapisu odbywają się kaskadowo (dla metod save() i Persist() ). Innymi słowy, jeśli zapiszemy encję, która jest powiązana z innymi encjami, to te encje również zostaną zapisane w bazie danych (o ile ich jeszcze tam nie ma)

  • MERGE — operacje aktualizacji odbywają się kaskadowo (dla metody merge() )

  • REMOVE — operacje usuwania odbywają się kaskadowo ( metoda usuwania() )

  • ALL — zawiera trzy operacje kaskadowe na raz — PERSISTMERGEUSUŃ

JPA ma koncepcję jednostki trwałej — jednostki powiązanej ze swoimi danymi w bazie danych i kontrolowanej przez bieżącą sesję (połączenie). Jeżeli dokonasz jego zmiany bez zapisania zmian w bazie danych, dane podmiotu w bazie nadal ulegną zmianie.
  • DETACH — powiązane podmioty nie są zarządzane przez sesję ( metoda detach() ). Oznacza to, że w przypadku zmiany danych podmiotów powiązanych dane w bazie danych nie są automatycznie aktualizowane – są one konwertowane z trwałych na odłączone (tj. podmiot nie jest zarządzany przez JPA)

  • ODŚWIEŻ — za każdym razem, gdy encja jest odświeżana danymi z bazy danych ( odświeżanie() — odświeża odłączone obiekty), odświeżane są także powiązane z nią encje. Przykładowo zmieniłeś w jakiś sposób dane pobrane z bazy danych i chcesz przywrócić oryginalne wartości. W takim przypadku ta operacja będzie przydatna.

Przeglądanie pytań i odpowiedzi z rozmowy kwalifikacyjnej na stanowisko programisty Java.  Część 6 - 4Hibernate obsługuje wszystkie te standardowe operacje kaskadowe, a także wprowadza trzy własne:
  • REPLICATE — stosowany, gdy mamy więcej niż jedno źródło danych i chcemy, aby dane były synchronizowane (metoda replikacji Hibernate). Wszystkie encje muszą posiadać identyfikatory (id), aby mieć pewność, że można je utworzyć bez problemów (aby mieć pewność, że ten sam podmiot nie będzie miał różnych identyfikatorów dla różnych baz danych)

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

  • LOCK — przeciwieństwo operacji DETACHED : konwertuje odłączony obiekt z powrotem do stanu trwałego, tzn. bieżąca sesja będzie ponownie śledzić obiekt

Jeśli nie zostanie wybrany żaden typ kaskady, wówczas operacja na obiekcie nie będzie miała wpływu na inne powiązane z nim podmioty.

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

Zgodnie z rozdziałem 2.1 Klasa encji specyfikacji JPA : „ Jednymi obiektami mogą być zarówno klasy abstrakcyjne, jak i konkretne ”. Zatem odpowiedź brzmi: tak, klasa abstrakcyjna może być bytem i może być oznaczona adnotacją @Entity.

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

Przede wszystkim chciałbym zauważyć, że EntityManager jest kluczowym elementem JPA . Służy do interakcji podmiotów z bazą danych. Ogólnie metody interakcji encji z bazą danych wywoływane są na encji (utrwalanie, łączenie, usuwanie, odłączanie)... Ale zauważam też, że ten komponent zwykle nie jest singletonem dla całej aplikacji. Często jest lekki, jeden jest usuwany i tworzony jest nowy przy użyciu EntityManagerFactory . Jeśli narysujemy porównanie z JDBC , gdzie EntityManagerFactory jest analogiczne do DataSource , wówczas EntityManager jest analogiczne do Connection . Wcześniej wspomniałem, że byt trwały to byt zarządzany przez bieżące połączenie. Encja ta jest zarządzana przez EntityManager , który jest ściśle powiązany z bieżącym połączeniem, oraz TransactionManager , który odpowiada za otwieranie/zamykanie transakcji. Na poniższym rysunku możesz zobaczyć cykl życia encji: Przeglądanie pytań i odpowiedzi z rozmowy kwalifikacyjnej na stanowisko programisty Java.  Część 6 - 5EntityManager zarządza encją, gdy znajduje się ona na etapie Zarządzany (kiedy jest trwała, ponieważ ma połączenie z EntityManager ) . Oznacza to, że nie jest nowy i nie jest również usunięty. Kiedy encja jest nowa lub usunięta, można powiedzieć, że jest również odłączona, ponieważ EntityManager nią nie zarządza. Istnieją różne strategie dla EntityManager . Możesz mieć singleton EntityManager dla całej aplikacji lub tworzyć nowy za każdym razem dla każdego połączenia. Jeśli używasz Springa, tworzenie/usuwanie EntityManagera jest zarządzane automatycznie pod maską (ale to nie znaczy, że nie możesz go dostosować do własnych potrzeb ^^). Muszę wspomnieć, że jeden lub więcej EntityManager tworzy kontekst trwałości . Kontekst trwałości to środowisko, w którym instancje jednostek są synchronizowane z podobnymi jednostkami w bazie danych (jak powiedziałem, działa to tylko w przypadku jednostek trwałych). Jeśli zagłębisz się w JPA (co gorąco polecam), bardzo często spotkasz się z tą koncepcją.

56. Co to jest klasa Assert? Dlaczego jest używany?

Nie słyszałem o takiej klasie w JPA , więc założę, że to pytanie odnosi się do klasy znalezionej w bibliotece JUnit, która jest używana do testów jednostkowych. W tej bibliotece klasa Assert służy do sprawdzania wyników wykonania kodu (tutaj Assert oznacza potwierdzenie, że masz określony stan/dane w określonym miejscu w kodzie). Załóżmy na przykład, że testujesz metodę, która ma stworzyć kota. Uruchamiasz metodę i otrzymujesz wynik:

Cat resultOfTest = createCat();
Ale trzeba mieć pewność, że został stworzony poprawnie, prawda? Zatem ręcznie tworzysz konkretnego kota ( oczekiwanyCat ) z dokładnie takimi parametrami, jakie spodziewasz się u kota uzyskanego 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 błąd AssertionError , który mówi nam, że nie uzyskaliśmy oczekiwanych rezultatów. Klasa Assert posiada wiele różnych metod obejmujących różnorodne operacje pomocne w weryfikacji oczekiwanych wyników. Oto kilka z nich:
  • AssertTrue(<boolean>) — oczekuje się, że wartość przekazana jako argument będzie prawdziwa

  • AssertFalse(<boolean>) — oczekuje się, że wartość przekazana jako argument będzie fałszywa

  • AssertNotEquals(<object1>, <object2>) — obiekty przekazane jako argumenty muszą się różnić przy porównywaniu przy użyciu równości ( false )

  • AssertThrows(<ClassNameOfException>.class, <exceptionObject>) — oczekuje się, że drugi argument będzie wyjątkiem zgłoszonym przez pierwszy argument (tj. drugi argument jest zwykle wywołaniem metody, które powinno zgłosić wyjątek wymaganego typu)

Strunowy

57. Opisz klasę String w Javie

String to standardowa klasa Java odpowiedzialna za przechowywanie i manipulowanie wartościami ciągów (sekwencji znaków). Jest to klasa niezmienna (o immutable pisałem wcześniej tutaj ), tzn. danych obiektów tej klasy nie da się zmienić po ich utworzeniu. Od razu zaznaczę, że klasy StringBuilder i StringBuffer są w zasadzie identyczne — jedyną różnicą jest to, że jedna z nich jest przeznaczona do użytku w środowisku wielowątkowym ( StringBuffer ). Klasy te są podobne do String , ale różnią się tym, że można je modyfikować . Nawet po ich utworzeniu pozwalają modyfikować ciągi, które reprezentują, bez tworzenia nowego obiektu. Ich metody różnią się od standardowych metod String i są przeznaczone do manipulacji ciągami (nie bez powodu nazywają to konstruktorem).

58. Jakie są sposoby na utworzenie obiektu String? Gdzie jest tworzony?

Najczęstszym sposobem tworzenia ciągu jest określenie żądanej wartości w podwójnym cudzysłowie:

String str = "Hello World!";
Możesz to również zrobić jawnie, używając new :

String str = new String("Hello World!");
Możesz także utworzyć ciąg znaków z tablicy znaków:

char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
Możemy to zrobić wywołując metodę toString na jakimś obiekcie:

String str = someObject.toString();
Możemy to zrobić wywołując dowolną inną metodę zwracającą ciąg znaków. Przykład:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str = reader.readLine();
Rozumiesz, że może być wiele, wiele sposobów na utworzenie ciągu. Kiedy tworzony jest obiekt String , jest on przechowywany w puli ciągów , co omówimy bardziej szczegółowo w jednym z poniższych pytań.

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

Java używa podwójnego znaku równości ( == ) do wykonywania porównań. Jeśli będziemy musieli porównać proste wartości, takie jak int, użyjemy go. Ale ta metoda nie nadaje się do porównywania pełnoprawnych obiektów. Porówna jedynie odniesienia, tj. to, czy odniesienia wskazują na ten sam obiekt, czy nie. Oznacza to, że jeśli porównamy dwa obiekty z tymi samymi wartościami pól za pomocą == , otrzymamy false . Pola mają te same wartości, ale same obiekty zajmują różne miejsca w pamięci. Obiekty typu string , pomimo swojej zwodniczej prostoty, nadal są obiektami. Porównywanie ich za pomocą == również nie jest właściwe (pomimo obecności puli ciągów). Właściwym rozwiązaniem jest standardowa metoda równości klasy Object , którą należy nadpisać, aby działała poprawnie (domyślnie do porównań używana jest metoda == ). Klasa String zastępuje ją, więc po prostu używamy jej implementacji:

String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);
Przeglądanie pytań i odpowiedzi z rozmowy kwalifikacyjnej na stanowisko programisty Java.  Część 6 - 6Mówiliśmy o porównaniach równości. Teraz wymyślimy porównania dotyczące sortowania. W końcu, jeśli mamy coś posortować, musimy wiedzieć, jakiej zasady będziemy używać do sortowania. Aby to zrobić, możesz użyć TreeSet , standardowego posortowanego zestawu. Ta struktura danych opiera się na algorytmie 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. Aby przypisać metodę porównania do sortowania, użyj komparatorów . Zwykle musisz je zaimplementować dla klas, które chcesz posortować, ale w przypadku String są one już zaimplementowane. W związku z tym po prostu dodajemy nasze ciągi do TreeSet , a on je za nas posortuje:

TreeSet<String> sortedSet = new TreeSet<>();
sortedSet.add("B");
sortedSet.add("C");
sortedSet.add("A");
sortedSet.forEach(System.out::println);
Wyjście konsoli:
ABC

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

Jak powiedziałem wcześniej, obiekty String mają 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, do których możemy odwoływać się za pomocą indeksu:

char firstChar = charArr[0]; // H

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

Klasa String posiada metodę getBytes , która jest podobna do metody toCharArray i zwraca ciąg znaków w postaci tablicy bajtów:

String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
Doszliśmy do logicznego wniosku z naszej dzisiejszej recenzji. Dziękuje za przeczytanie!
Komentarze
  • Popularne
  • Najnowsze
  • Najstarsze
Musisz się zalogować, aby dodać komentarz
Ta strona nie ma jeszcze żadnych komentarzy