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ęść 2

Opublikowano w grupie Random-PL
Witam ponownie wszystkich! Nadal szukamy odpowiedzi na ponad 250 pytań dla młodszych, średnich i starszych programistów. Pytania są dość ciekawe i sam lubię je analizować: w takich momentach można odkryć luki w wiedzy teoretycznej i to w najbardziej nieoczekiwanych miejscach. Analiza pytań i odpowiedzi na rozmowie kwalifikacyjnej.  Część 2 - 1Poprzednią część znajdziesz w tym artykule . Ale zanim zaczniemy, chcę ci przypomnieć, że:
  1. Pominę pytania, które krzyżują się z tą serią artykułów , aby nie powielać ponownie informacji. Polecam przeczytać te materiały, gdyż zawierają one najczęstsze (najpopularniejsze) pytania podczas rozmów kwalifikacyjnych Java Core.
  2. Pytania na temat DOU są zadawane w języku ukraińskim, ale tutaj będę miał wszystko w języku rosyjskim.
  3. Odpowiedzi można by opisać bardziej szczegółowo, ale tego nie zrobię, bo wtedy odpowiedź na każde pytanie zajęłaby cały artykuł. I nie będą cię pytać o takie szczegóły podczas żadnej rozmowy kwalifikacyjnej.
W razie potrzeby zostawię linki do głębszych badań. Lećmy!

11. Nazwij wszystkie metody klasy Object

Klasa Object posiada 11 metod:
  • Class<?> getClass() — pobieranie klasy bieżącego obiektu;
  • int hashCode() — pobranie kodu skrótu bieżącego obiektu;
  • boolean równa się​(Object obj) - porównanie aktualnego obiektu z innym;
  • Object clone() - utworzenie i zwrócenie kopii bieżącego obiektu;
  • String toString() — uzyskanie ciągu znaków reprezentującego obiekt;
  • void notify() — wybudzenie jednego wątku oczekującego na monitorze tego obiektu (wybór wątków jest losowy);
  • void notifyAll() - budzi wszystkie wątki oczekujące na monitorze tego obiektu;
  • void Wait() - przełącza bieżący wątek w tryb gotowości (zamraża go) na bieżącym monitorze, działa tylko w bloku zsynchronizowanym do czasu, aż niektórzy notify lub notifyAll nie wybudzą wątku;
  • void wait(long timeout) - również zawiesza bieżący wątek na bieżącym monitorze (na bieżącym zsynchronizowanym), ale z timerem umożliwiającym wyjście z tego stanu (lub ponownie: do momentu wybudzenia notify lub notifyAll);
  • void wait(long timeout, int nanos) - metoda podobna do opisanej powyżej, ale z bardziej precyzyjnymi timerami wyjścia z zamrażania;
  • void finalize() - przed usunięciem tego obiektu moduł wyrzucający elementy bezużyteczne wywołuje tę metodę (w końcu). Służy do czyszczenia zajętych zasobów.
Aby poprawnie używać metod hashCode , quals , clone , toString i finalize, należy je na nowo zdefiniować, biorąc pod uwagę bieżące zadanie i okoliczności.

12. Jaka jest różnica pomiędzy try-with-resources a try-catch-finally w przypadku zasobów?

Zwykle podczas korzystania z try-catch-final ostatni blok był używany do zamykania zasobów. W Javie 7 wprowadzono nowy typ operatora try-with-resources , odpowiednik try-catch-final do zwalniania zasobów, ale bardziej zwarty i czytelny. Przypomnijmy sobie, jak wygląda try-catch-finale :
String text = "some text......";
BufferedWriter bufferedWriter = null;
try {
   bufferedWriter = new BufferedWriter(new FileWriter("someFileName"));
   bufferedWriter.write(text);
} catch (IOException e) {
   e.printStackTrace();
} finally {
   try {
       bufferedWriter.close();
   } catch (IOException e) {
       e.printStackTrace();
   }
}
Przepiszmy teraz ten kod, ale używając try-with-resources :
String text = "some text......";
try(BufferedWriter bufferedWriter =new BufferedWriter(new FileWriter("someFileName"))) {
   bufferedWriter.write(text);
} catch (IOException e) {
   e.printStackTrace();
}
W jakiś sposób stało się to łatwiejsze, nie sądzisz? Oprócz uproszczenia jest kilka punktów:
  1. W try-with-resources zasoby zadeklarowane w nawiasach (które zostaną zamknięte) muszą implementować interfejs AutoCloseable i jego jedyną metodę, close() .

    Metoda zamykania jest wykonywana w ukrytym bloku final , w przeciwnym razie w jaki sposób program będzie dokładnie wiedział, jak zamknąć dany zasób?

    Ale najprawdopodobniej rzadko będziesz pisać własne implementacje zasobów i sposób ich zamykania.

  2. Kolejność wykonania bloku:

    1. spróbuj zablokować .
    2. W końcu ukryte .
    3. Blok catch przechwytujący wyjątki z poprzednich kroków.
    4. Wreszcie wyraźne .

    Z reguły wyjątki znajdujące się niżej na liście przerywają te, które pojawiają się wyżej.

Wyobraź sobie sytuację, w której podczas używania try-catch-final otrzymasz wyjątek w swoim try . W związku z tym natychmiast rozpoczyna się wykonywanie określonego bloku catch , w którym piszesz kolejny wyjątek (na przykład z komunikatem bardziej szczegółowo opisującym błąd) i chcesz, aby metoda dalej zgłaszała ten wyjątek. Następnie następuje wykonanie bloku Final i również zostaje w nim zgłoszony wyjątek. Ale to jest coś innego. Który z tych dwóch wyjątków ostatecznie wyrzuci ta metoda? Wyjątek zgłoszony przez blok last ! Ale jest też jeden punkt związany z próbą z zasobami . Przyjrzyjmy się teraz zachowaniu try-with-resources w tej samej sytuacji. Kiedy próbujemy zamknąć zasoby metodą close() , czyli w sposób dorozumiany final , dostajemy wyjątek w bloku try . Który z tych wyjątków zostanie złapany ? Ten, który został wyrzucony przez blok try ! Wyjątek od ukrytej funkcji final (z metody close() ) zostanie zignorowany. To ignorowanie nazywa się także tłumieniem wyjątków.

13. Czym są operacje bitowe?

Operacje bitowe to operacje na ciągach bitowych, które obejmują operacje logiczne i przesunięcia bitowe. Operacje logiczne:
  • bitowe AND - porównuje wartości bitów, przy czym dowolny bit ustawiony na 0 (fałsz) ustawia odpowiadający mu bit w wyniku na 0. Oznacza to, że jeśli w obu porównywanych wartościach bit miał wartość 1 (prawda), wynik będzie również 1.

    Oznaczone jako - AND , &

    Przykład: 10111101 i 01100111 = 00100101

  • bitowe OR jest operacją odwrotną do poprzedniej. Dowolny bit ustawiony na 1 ustawia w wyniku podobny bit na 1. Odpowiednio, jeśli bit miał wartość 0 w obu porównywanych wartościach, bit wynikowy również będzie wynosił 0.

    Oznaczone jako - OR , |

    Przykład: 10100101 | 01100011 = 11100111

  • bitowe NOT - zastosowane do jednej wartości, odwraca (odwraca) bity. Oznacza to, że te bity, które wynosiły 1, staną się 0; a te, które były 0, staną się 1.

    Oznaczone jako - NOT , ~

    Przykład: ~10100101 = 01011010

  • bitowe wyłączne OR - porównuje wartości bitów i jeśli w obu wartościach bit jest równy 1, to wynikiem będzie 0, a jeśli w obu wartościach bit będzie równy 0, wynikiem będzie 0. Czyli: aby wynik był równy 1, tylko jeden z bitów musi być równy 1, a drugi równy 0.

    Oznaczone jako - XOR , ^

    Przykład: 10100101 ^ 01100011 = 11000110

Przesunięcia bitowe - >> lub << przesuwają bity wartości w określonym kierunku, o określoną liczbę. Wolne pozycje są wypełniane zerami. Na przykład:
  1. 01100011 >> 4 = 00000110
  2. 01100011 << 3 = 00011000
Istnieje również wyjątek, gdy przesuwa się w prawo liczbę ujemną. Jak pamiętacie, za znak odpowiada pierwszy bit i jeśli ten bit jest równy 1, to liczba jest ujemna. Jeśli przesuniesz liczbę ujemną, zwolnione pozycje nie będą już wypełniane zerami, ale jedynkami, ponieważ konieczne jest zachowanie bitu znaku. Na przykład: 10100010 >> 2 = 11101000 Jednocześnie w Javie istnieje dodatkowy operator przesunięcia w prawo bez znaku >>> Ten operator jest analogiem >>, podczas przesuwania wolne pozycje są wypełniane 0, niezależnie od tego, czy liczba jest ujemna lub dodatnia. Na przykład: 10100010 >>> 2 = 00101000 Przeczytaj więcej o operacjach bitowych tutaj . Analiza pytań i odpowiedzi na rozmowie kwalifikacyjnej.  Część 2 - 2Jako przykłady użycia przesunięć bitowych w Javie można przytoczyć metodę hash() mapy HashMap, która służy do określenia specjalnego wewnętrznego kodu skrótu dla klucza: Analiza pytań i odpowiedzi na rozmowie kwalifikacyjnej.  Część 2 - 3Ta metoda umożliwia równomierną dystrybucję danych w HashMap w celu zminimalizowania ilość kolizji.

14. Jakimi standardowymi klasami niezmiennymi są obiekty w Javie?

Niezmienny to obiekt, który nie pozwala na zmianę jego pierwotnych parametrów. Może posiadać metody zwracające nowe obiekty danego typu, z parametrami, które chciałeś zmienić. Niektóre standardowe obiekty niezmienne:
  • Zdecydowanie najbardziej znanym niezmiennym obiektem w Javie jest String;
  • instancje klas opakowań, które otaczają standardowe typy: Boolean, Character, Byte, Short, Integer, Long, Double, Float;
  • obiekty, które są zwykle używane dla szczególnie DUŻYCH liczb - BigInteger i BigDecimal;
  • obiekt będący jednostką w śladach stosu (na przykład w śladzie stosu wyjątku) StackTraceElement;
  • obiekt klasy File - może zmieniać pliki, ale jednocześnie sam jest niezmienny;
  • UUID – często używany jako unikalny identyfikator elementów;
  • wszystkie obiekty klas pakietu java.time;
  • Ustawienia regionalne — używane do określenia regionu geograficznego, politycznego lub kulturowego.

15. Jakie są zalety obiektu niezmiennego w porównaniu z obiektami zwykłymi?

  1. Takie obiekty są bezpieczne, gdy są używane w środowisku wielowątkowym . Korzystając z nich, nie musisz się martwić o utratę danych z powodu wyścigu wątków. W przeciwieństwie do pracy ze zwykłymi obiektami: w tym przypadku będziesz musiał bardzo dokładnie przemyśleć i opracować mechanizmy korzystania z obiektu w środowisku równoległym.
  2. Obiekty niezmienne są dobrymi kluczami na mapie, ponieważ jeśli użyjesz obiektu zmiennego, a następnie obiekt zmieni swój stan, użycie HashMap może stać się mylące: obiekt będzie nadal obecny, a jeśli użyjesz funkcji includeKey() może nie być znalezionym.
  3. Obiekty niezmienne doskonale nadają się do przechowywania niezmiennych (stałych) danych, których nigdy nie należy zmieniać podczas działania programu.
  4. „Atomiczność do awarii” – jeśli niezmienny obiekt zgłosi wyjątek, nadal nie pozostanie w niepożądanym (zepsutym) stanie.
  5. Klasy te są łatwe do przetestowania.
  6. Dodatkowe mechanizmy, takie jak konstruktor kopiujący i implementacja klonowania, nie są potrzebne.

Pytania dotyczące OOP

Analiza pytań i odpowiedzi na rozmowie kwalifikacyjnej.  Część 2 - 4

16. Jakie są ogólne zalety OOP w porównaniu z programowaniem proceduralnym?

A więc zalety OOP:
  1. Złożone aplikacje są łatwiejsze do napisania niż programowanie proceduralne, ponieważ wszystko jest rozbite na małe moduły – obiekty, które na siebie oddziałują – w efekcie programowanie sprowadza się do relacji pomiędzy obiektami.
  2. Aplikacje napisane przy użyciu OOP są znacznie łatwiejsze do modyfikacji (o ile przestrzegane są koncepcje projektowe).
  3. Ponieważ dane i operacje na nich tworzą jedną całość, nie są rozmazane w całej aplikacji (co często ma miejsce w programowaniu proceduralnym).
  4. Hermetyzacja informacji chroni najważniejsze dane przed użytkownikiem.
  5. Możliwe jest ponowne wykorzystanie tego samego kodu z różnymi danymi, ponieważ klasy pozwalają na utworzenie wielu obiektów, z których każdy posiada własne wartości atrybutów.
  6. Dziedziczenie i polimorfizm pozwalają także na ponowne wykorzystanie i rozszerzenie istniejącego kodu (zamiast powielania podobnej funkcjonalności).
  7. Łatwiejsza rozszerzalność aplikacji niż w przypadku podejścia proceduralnego.
  8. Podejście OOP pozwala na abstrakcję od szczegółów implementacji.

17. Powiedz nam, jakie braki występują w OOP

Niestety, są też:
  1. OOP wymaga dużej wiedzy teoretycznej, którą należy opanować, zanim będziesz mógł cokolwiek napisać.Analiza pytań i odpowiedzi na rozmowie kwalifikacyjnej.  Część 2 - 5
  2. Idee OOP nie są tak łatwe do zrozumienia i zastosowania w praktyce (trzeba mieć w głębi serca trochę filozofa).
  3. Podczas korzystania z OOP wydajność oprogramowania jest nieco zmniejszona ze względu na bardziej złożoną organizację systemu.
  4. Podejście OOP wymaga więcej pamięci, ponieważ wszystko składa się z klas, interfejsów, metod, które zajmują znacznie więcej pamięci niż zwykłe zmienne.
  5. Czas potrzebny na analizę wstępną jest dłuższy niż w przypadku analizy proceduralnej.

18. Co to jest polimorfizm statyczny i dynamiczny

Polimorfizm pozwala obiektom zachowywać się inaczej dla tej samej klasy lub interfejsu. Istnieją dwa typy polimorfizmu, znane również jako wczesne i późne wiązanie . Polimorfizm statyczny, czyli wcześniejsze wiązanie:
  • występuje w czasie kompilacji (na początku cyklu życia programu);
  • decyduje, którą metodę wykonać w czasie kompilacji;
  • Przeciążanie metod jest przykładem polimorfizmu statycznego;
  • wczesne wiązanie obejmuje metody prywatne, statyczne i terminalowe;
  • dziedziczenie nie jest związane z wczesnym wiązaniem;
  • Polimorfizm statyczny nie dotyczy konkretnych obiektów, ale informację o klasie, której typ jest reprezentowany po lewej stronie nazwy zmiennej.
Dynamiczny polimorfizm lub późne wiązanie:
  • występuje w czasie wykonywania (kiedy program jest uruchomiony);
  • dynamiczny polimorfizm decyduje, jaką konkretną implementację będzie miała metoda w czasie wykonywania;
  • nadpisywanie metod jest przykładem polimorfizmu dynamicznego;
  • późne wiązanie to przypisanie konkretnego obiektu, odniesienie do jego typu lub jego nadklasy;
  • dziedziczenie jest związane z dynamicznym polimorfizmem.
Więcej o różnicach pomiędzy wczesnym i późnym wiązaniem możesz przeczytać w tym artykule .

19. Zdefiniuj zasadę abstrakcji w OOP

Abstrakcja w OOP to sposób na uwydatnienie zestawu istotnych cech obiektu, z wyłączeniem nieistotnych szczegółów. Oznacza to, że projektując program z podejściem OOP, skupiasz się na modelach w ogóle, bez zagłębiania się w szczegóły ich realizacji. W Javie za abstrakcję odpowiedzialne są interfejsy . Na przykład masz maszynę i to będzie interfejs. I różne interakcje z nim – np. uruchomienie silnika, obsługa skrzyni biegów – to funkcje, z których korzystamy bez wchodzenia w szczegóły implementacyjne. Przecież w momencie prowadzenia samochodu nie zastanawiasz się, jak dokładnie skrzynia biegów spełnia swoje zadanie, jak kluczykiem uruchamia silnik, czy dokładnie jak kierownica obraca koła. I nawet jeśli zostanie wymieniona implementacja jednej z tych funkcjonalności (na przykład silnika), możesz tego nie zauważyć. To nie ma dla Ciebie znaczenia: nie wdajesz się w szczegóły implementacji. Ważne jest dla Ciebie, aby akcja została zrealizowana. Właściwie jest to abstrakcja od szczegółów implementacji. Na tym dzisiaj się zatrzymamy: ciąg dalszy!Analiza pytań i odpowiedzi na rozmowie kwalifikacyjnej.  Część 2 - 6
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION