Rozmowa kwalifikacyjna z Javy? Żaden problem! – cz. I (String)

A więc wybierasz się na rozmowę kwalifikacyjną z Javy? Na pewno od jakiegoś czasu przeszukujesz Google szukając przykładowych pytań, które mogą się pojawić podczas rozmowy na stanowisko developera w Javie. Są pytania, które pojawiają się bardzo często – dlatego dobrze jest zawczasu sprawdzić odpowiedzi i odświeżyć swoją teoretyczną wiedzę, w końcu nawet najbardziej doświadczony programista może zapomnieć pewnych technicznych niuansów występujących w danym języku. Postanowiliśmy Wam ułatwić zadanie i postarać się tematycznie zebrać najczęściej pojawiające się pytania na rozmowach wraz z odpowiedziami i wytłumaczeniem. Niezależnie od tego czy przygotowujesz się do rozmowy o swoją pierwszą prace, czy jesteś już weteranem, który na tym języku zjadł własne zęby, mamy nadzieję, że dowiesz się czegoś nowego i z nieco mniejszym stresem udasz się na rozmowę.

Aby ułatwić poszukiwania konkretnych pytań, podzielimy je na bloki tematyczne, w których postaramy się zawrzeć jak najwięcej problematycznych zagadnień z danego tematu. Tym samym dostarczymy Wam szereg artykułów zawierających odpowiedzi na najbardziej popularne pytania. Na pierwszy ogień pójdzie tematyka ciągów literowych (String) i zagadnienia z nim związane. W tym artykule nie spotkacie zadań programistycznych – cały ten tekst poświęcony problemom teoretycznym z nim związanym. Na zadania programistyczne poświęcimy inny artykuł – dzięki temu łatwiej będzie Wam w przyszłości wrócić do konkretnego zagadnienia! A więc, czy jesteście gotowi? Zaczynamy!

Zacznijmy od samej definicji String’a, spoglądając do oficjalnej dokumentacji Javy, możemy przeczytać, iż String jest klasą, która reprezentuje ciąg znaków. String jest stały – jego wartość nie może zostać zmieniona po tym jak został stworzony. Ponieważ typ String jest niezmienny może być dzielony. Tak więc mamy już odpowiedź na pierwsze podstawowe pytanie:

  1. Czym jest String w Javie?

String jest to klasa, która została zdefiniowana w pakiecie java.lang. Warto też zauważyć, iż nie jest to prymitywny typ danych (prymitywy zaczynają się z małej litery). Jest niezmienny oraz (zazwyczaj) przechowywany w puli ciągów znaków (String pool).

Tutaj u niektórych z Was mogą pojawić się dwa pytania (nie tylko u Was – są to też częste pytania na rozmowach kwalifikacyjnych):

  1. Dlaczego String jest niezmienny?

Po pierwsze, jest to spowodowane:

  • Bezpieczeństwem – jeżeli w aplikacji występują połączenia (przedstawiane za pomocą Stringa), dane użytkowników (nazwy użytkowników, hasła), połączenia z bazami danych, to w przypadku gdy String mógłby być modyfikowany łatwość zmiany tych parametrów stanowiłaby zagrożenie bezpieczeństwa.
  • Synchronizacja (w programowaniu wielowątkowym) – skoro String jest niezmienny to automatycznie rozwiązuje to problem z synchronizacją.
  • Zarządzanie Pamięcią – kompilator widzi kiedy dwa obiekty typu String posiadają tą samą wartość. Dzięki temu możliwa jest optymalizacja – wystarczy jeden obiekt aby reprezentować dwie zmienne.
  1. Co to jest String Pool?

String pool jest specjalnym miejscem w pamięci, w którym przechowywana jest pula wszystkich Stringów. Lądują tam wszystkie obiekty typu String, które zostały zainicjowane przy użyciu cudzysłowu – obiekty, które zostały zainicjowane przy pomocy słówka new lądują w pamięci lokalnej, poza pulą ciągów znaków. Warto pamiętać, że taka inicjalizacja ciągów znaków może spowodować mniejszą optymalizację kodu.

 

Rys.  1 Wizualizacja puli. Warto zauważyć że s1 == s2 daje true, s1 == s4 zwraca false, natomiast s1.equals(s4) zwraca true.

 

  1. Jak porównywać dwa obiekty typu String?

To pytanie bezpośrednio nawiązuje do pytania trzeciego. Otóż, jeżeli chcemy porównać zawartość obiektu (tj. ciąg znaków) powinniśmy używać metody, w którą zaopatrzony jest ten obiekt – s1.equals().  Jeżeli do porównywania używamy dwóch znaków równości to możemy spodziewać się niejednoznacznym wyników. Znak „==” sprawdza czy obiekty są identyczne, więc jeżeli inny obiekt będzie miał tą samą zawartość tekstową, ale przykładowo inny hashcode, to takie porównanie zwróci nam wynik „false”. Funkcja .equals() porównuje to co jest w niej zapisane do porównywania – w przypadku Stringa jest to zawartość tekstowa.

 

Rys.  2 Porównywanie obiektów klasy String.

 

  1. Jaka jest różnica pomiędzy klasą String, StringBuffer oraz StringBuilder?

Podczas manipulacji Stringiem w czasie wykonywania programu za każdym razem gdy go zmieniamy tworzymy obiekt. Aby więc nie marnować pamięci na ciągłe tworzenie nowych ciągów znaków java udostępnia nam dwie klasy, które pozwalają na manipulację ciągami znaków, bez zużywania zbędnej pamięci – czyli StringBuffer oraz StringBuilder. Różnice są zawarte w tabelce poniżej:

 

Rys.  3 Tabelka która porównuje właściwości klas String, StringBuffer oraz StringBuilder.

  1. Jakie są metody inicjowania obiektów klasy String?

Istnieją dwie metody inicjowania obiektów klasy String:

 

Rys.  4 Dwie metody inicjowania obiektów klasy String

Ważne jest, iż metody te nie są sobie równoważne (przynajmniej nie w każdym aspekcie). Metoda pierwsza powoduje, iż utworzony String trafia do puli obiektów klasy String (String pool), natomiast metoda druga lokuje obiekt w pamięci lokalnej. Dzięki metodzie pierwszej w przypadku powtórzenia danego ciągu znaków kompilator odwoła się do obiektów klasy String zawartych w puli – czego skutkiem będzie wyższa wydajność programu.

  1. String w odróżnieniu od prymitywów (primitive classes) jest pochodną klasą (derived class). Czym różni się String od innych pochodnych klas?

Po pierwsze – String posiada swoją specjalną pulę, w którym jest on przechowywane. Spowodowane jest to tym, iż jest on jedną z najczęściej wykorzystywanych klas (na dodatek bez możliwości modyfikacji) i dzięki temu możliwy jest wzrost wydajności programów. Ponadto z powodu powszechnego występowania, String posiada również możliwość deklarowania obiektów w sposób niedostępny dla innych klas – bez słówka kluczowego „new”, przy pomocy tzw. „String literals” (mała uwaga – wyjątkiem są klasy typu Wrapper np. Long, Integer czy Float). Jest to również preferowany sposób, dzięki temu nasze obiekty lądują w puli obiektów typu String. Ostatnią rzeczą, która jest wyjątkowa w tej klasie, jest operator „+” umożliwiający łatwe łączenie teog typu obiektów.

  1. String, StringBuffer i StringBuilder – która z tych trzech klas typu final?

To pytanie jest pułapką – wszystkie z tych klas są zadeklarowane jako final. Warto pamiętać, że zadeklarowanie klasy jako final nie stanowi o jej zmienności. Słówko final stanowi o tym, że klasa nie może być dziedziczona przez inne klasy!

  1. Czym jest „String Intern”?

To pytanie odnosi się do puli obiektów typu String (String Pool). „String Intern” jest to obiekt składowany w puli. Użycie metody .intern() na ciągu obiektów String spowoduje, że będziemy mogli być pewni, iż wszystkie obiekty o tej samej zawartości mają jedno miejsce w pamięci w puli.

  1. Czy w obiekcie klasy String można przechowywać dane wrażliwe? Dlaczego?

W obiektach klasy String nie powinniśmy przechowywać danych wrażliwych np. haseł. Spowodowane jest to tym, iż String jest niezmienny (immutable) a więc nie ma sposobu aby pozbyć się zawartości danego obiektu. Dodatkowo przez to, że obiekty typu String są przechowywane w puli (String Pool) mają one trochę dłuższą żywotność niż obiekty w pamięci lokalnej (heap), co stanowi ryzyko, iż jakikolwiek użytkownik, który ma dostęp do pamięci Javy może mieć dostęp do tych danych. Hasła i inne wrażliwe dane powinny być przechowywane w tablicy znaków – char[].

  1. Ile obiektów będzie stworzonych przez ten kod? (To pytanie występuje w dwóch wariantach)

String s1 = „abc”;

    String s2 = „abc”;

W tym przypadku tworzony jest jeden obiekt. Pierwszy obiekt s1 tworzony jest w pamięci lokalnej w puli obiektów typu String, natomiast drugi obiekt s2, poprzez referencję będzie odwoływał się do tej samej wartości.

 

String s1 = „abc”;

String s2 = new String(„abc”);

W drugim przypadku tworzone są dwa obiekty. Pierwszy z nich ląduje podobnie jak w poprzednim przykładzie w puli, natomiast drugi poprzez użycie słówka „new” tworzony jest w pamięci lokalnej.

 

I to by chyba było na tyle – postaraliśmy się zebrać dla Was najciekawsze i najczęściej przejawiające się pytania odnośnie klasy String w Javie. Mamy nadzieję, że dzięki wiedzy zawartej we wszystkich pytaniach uda Wam się chociaż trochę zredukować stres przed nadchodzącymi rozmowami kwalifikacyjnymi. W następnych częściach postaramy się rozwiać wątpliwości w zakresie innych dziedzin związanych z Javą – również tych czysto programistycznych. Czekamy również na Wasze ciekawe pytania, które przytrafiły się Wam podczas rozmów. Do zobaczenia!

 

IT-Leaders.pl to pierwsza na rynku platforma łącząca Specjalistów IT bezpośrednio z pracodawcami. Anonimowy, techniczny profil i konkretnie określone oczekiwania finansowe to tylko niektóre z cech wyróżniających platformę. Zarejestruj się i zobacz jak Cię widzi pracodawca.

 

Może Ci się również spodoba

1 Odpowiedź

  1. Sierpień 18, 2017

    […] w kolejnym artykule z serii „Rozmowa kwalifikacyjna z Javy? Żaden problem!”. W poprzednim artykule omawialiśmy pytania z rozmów kwalifikacyjnych odnoszące się do jednej z najważniejszych klas […]