Java
Baza pytań rekrutacyjnych i wiedzy. Filtruj, szukaj i sprawdzaj swoją wiedzę.
easyooppolymorphismjava+1
Odpowiedź
Polimorfizm pozwala traktować różne obiekty przez ten sam interfejs lub klasę bazową. Wywołując metodę nadpisaną na referencji typu bazowego, Java wybiera implementację w czasie działania (dynamic dispatch); przeciążanie metod daje polimorfizm czasu kompilacji.
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.sound(); // Output: Dog barks
}
}mediumexceptionerror-handlingjava
Odpowiedź
Wyjątki checked muszą być obsłużone lub zadeklarowane w throws (np. IOException) i zwykle oznaczają sytuacje możliwe do obsłużenia. Wyjątki unchecked dziedziczą po RuntimeException (np. NullPointerException) i najczęściej wskazują błąd programisty; ich obsługa jest opcjonalna.
mediumoopinterfaceabstract-class+2
Odpowiedź
Interfejs definiuje kontrakt; klasa może implementować wiele interfejsów, a interfejs może mieć metody domyślne/statyczne, ale nie ma stanu instancji. Klasa abstrakcyjna może zawierać pola, konstruktory i częściową implementację, ale dziedziczyć można tylko po jednej klasie. Interfejsy stosuj do „zdolności”, a abstrakcyjne do wspólnej logiki bazowej.
easystringimmutabilitymemory+1
Odpowiedź
String jest niemutowalny, aby można go było bezpiecznie współdzielić między wątkami, buforować i internować w puli Stringów oraz używać jako klucz w kolekcjach hashujących (stały hashCode). Zwiększa to też bezpieczeństwo, bo np. nazwy klas czy ścieżki nie mogą zostać zmienione po utworzeniu.
mediummemorystackheap+2
Odpowiedź
Stack to pamięć per‑wątek przechowująca ramki wywołań, lokalne prymitywy i referencje; jest alokowana/zwalniana przy wejściu/wyjściu z metody i działa bardzo szybko. Heap to współdzielona pamięć, gdzie znajdują się obiekty i tablice; zarządza nią GC i obiekty zwykle żyją dłużej niż jedno wywołanie metody.
easyequalsreferencestring
Odpowiedź
`==` dla obiektów porównuje referencje (czy to ta sama instancja), a `.equals()` porównuje równość logiczną zdefiniowaną przez klasę (np. `String` porównuje treść). Dla typów prostych `==` porównuje wartości.
String a = new String("hi");
String b = new String("hi");
System.out.println(a == b); // false
System.out.println(a.equals(b)); // trueeasyfinalinheritancejava-basics
Odpowiedź
`final` zmienna nie może być ponownie przypisana, `final` metoda nie może być nadpisana, a `final` klasa nie może być dziedziczona. (To nie czyni obiektu automatycznie niemutowalnym.)
easystringstringbuilderperformance
Odpowiedź
`String` jest niemutowalny, więc wielokrotne konkatenacje tworzą dużo obiektów. `StringBuilder` jest mutowalny i szybki do składania tekstu w jednym wątku; `StringBuffer` jest podobny, ale zsynchronizowany (dziś rzadko potrzebny).
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 3; i++) {
sb.append(i).append(",");
}
System.out.println(sb.toString());mediumexceptionscheckedruntimeexception
Odpowiedź
Checked exceptions muszą być obsłużone lub zadeklarowane w sygnaturze (dziedziczą po `Exception`, ale nie po `RuntimeException`). Unchecked (`RuntimeException`) nie wymagają tego i zwykle oznaczają błąd programistyczny lub niepoprawny stan.
mediumautoboxingwrappernpe
Odpowiedź
Autoboxing zamienia prymitywy na wrappery (np. `int`→`Integer`), a unboxing odwrotnie. Pułapki: unboxing `null` daje NPE, cache’owanie `Integer` może mylić przy `==`, a dodatkowe alokacje potrafią zaboleć wydajnościowo.
Integer x = null;
// int y = x; // NullPointerException due to unboxing
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true (Integer cache)
Integer c = 1000;
Integer d = 1000;
System.out.println(c == d); // falsemediumhashmapconcurrencyconcurrenthashmap
Odpowiedź
`HashMap` nie jest thread-safe; równoległe zapisy mogą go uszkodzić. `ConcurrentHashMap` wspiera bezpieczny dostęp współbieżny z dobrą wydajnością (i nie pozwala na null jako klucz/wartość). Użyj, gdy wiele wątków czyta/zapisuje bez zewnętrznej blokady.
hardequalshashcodehashmap
Odpowiedź
Jeśli dwa obiekty są równe wg `equals()`, muszą mieć ten sam `hashCode()`. Kolekcje haszujące (HashMap/HashSet) na tym polegają; złamanie kontraktu powoduje „znikające” wpisy i trudne bugi.
final class User {
private final String email;
User(String email) {
this.email = email;
}
@Override public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
return email.equals(((User) o).email);
}
@Override public int hashCode() {
return email.hashCode();
}
}hardconcurrencyvolatilesynchronized
Odpowiedź
`volatile` gwarantuje widoczność (i porządek) zmiennej między wątkami, ale nie robi atomowości dla operacji złożonych. `synchronized` daje wzajemne wykluczanie i jednocześnie zapewnia happens-before (widoczność) dla chronionego fragmentu.
class StopFlag {
private volatile boolean stop = false;
void requestStop() {
stop = true;
}
void runLoop() {
while (!stop) {
// do work
}
}
}Odpowiedź
Heap jest zwykle podzielony na młodą i starą generację: większość obiektów szybko umiera, więc sprzątanie young gen jest częste i tanie (minor GC). Obiekty żyjące dłużej są promowane; czyszczenie old gen jest rzadsze i zwykle droższe.
hardcompletablefutureasyncconcurrency
Odpowiedź
To reprezentacja asynchronicznego obliczenia, które możesz składać (`thenApply/thenCompose`) bez blokowania. Typowa pułapka to zbyt wczesne `get()/join()` (zamiana na kod blokujący) albo brak obsługi wyjątków (`exceptionally/handle`).
CompletableFuture<Integer> result = CompletableFuture
.supplyAsync(() -> 40)
.thenApply(x -> x + 2)
.exceptionally(e -> 0);
System.out.println(result.join());easystaticclassoop
Odpowiedź
`static` oznacza, że element należy do klasy, a nie do konkretnej instancji. Pole statyczne jest współdzielone przez wszystkie obiekty, a metodę statyczną można wywołać bez tworzenia instancji (ale nie ma ona bezpośredniego dostępu do pól instancji).
mediumsethashsettreeset+2
Odpowiedź
HashSet jest zwykle szybszy dla add/contains (średnio O(1)), bo jest oparty o hash. TreeSet trzyma elementy posortowane (zbalansowane drzewo), więc operacje są O(log n), ale dostajesz kolejność i zapytania zakresowe.
mediumoptionalnull-safetyapi
Odpowiedź
`Optional` reprezentuje wartość, która może być obecna albo nie, i wymusza obsłużenie przypadku pustego. Typowe nadużycie to trzymanie `Optional` jako pola w encjach/DTO wszędzie; najczęściej jest przeznaczony dla wartości zwracanych, a nie pól do serializacji czy persystencji.
Optional<User> user = repo.findById(id);
String name = user.map(User::getName).orElse("unknown");hardmemory-leakgcreferences+1
Odpowiedź
GC zwalnia tylko obiekty nieosiągalne. Jeśli przez błąd trzymasz referencje (np. rosnąca statyczna lista/mapa, cache bez eviction, listenery nieusuwane), obiekty pozostają osiągalne i pamięć rośnie.
hardconcurrencyarraylistthread-safety+1
Odpowiedź
`ArrayList` nie ma synchronizacji, więc równoległe zapisy mogą uszkodzić stan wewnętrzny albo dać niespójne odczyty. Rozwiązania: zewnętrzny lock, `Collections.synchronizedList`, `CopyOnWriteArrayList` (gdy głównie czytasz) albo inne kolekcje współbieżne zależnie od przypadku.
easyinterfaceabstract-classoop
Odpowiedź
Interfejs definiuje kontrakt (jakie metody istnieją) i wspiera wielokrotne dziedziczenie typu. Klasa abstrakcyjna może współdzielić stan i implementację, ale możesz dziedziczyć tylko po jednej klasie. Interfejs jest dla „umiejętności”, a abstrakcyjna dla wspólnej bazy zachowania.
mediumhashmaplinkedhashmapcollections
Odpowiedź
HashMap nie gwarantuje kolejności iteracji. LinkedHashMap utrzymuje kolejność dodania (albo kolejność dostępu, jeśli tak ustawisz), co daje przewidywalną iterację i pozwala budować cache typu LRU.
mediumtry-with-resourcesautocloseableio
Odpowiedź
Automatycznie zamyka zasoby implementujące `AutoCloseable` (pliki, streamy, JDBC) nawet gdy poleci wyjątek. Zapobiega wyciekom i upraszcza, a jednocześnie uwiarygadnia sprzątanie zasobów.
try (var in = Files.newInputStream(path)) {
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
}hardjmmhappens-beforeconcurrency+1
Odpowiedź
Happens-before to reguła gwarantująca widoczność i porządek między wątkami. Jeśli A happens-before B, to B musi zobaczyć efekty A (np. przez `synchronized`, `volatile` albo start/join wątku).
hardweakreferenceweakhashmapgc+1
Odpowiedź
Weak reference nie blokuje GC: jeśli obiekt ma tylko słabe referencje, może zostać zebrany. Przydaje się w cache’ach wrażliwych na pamięć (np. WeakHashMap), gdzie lepiej „zgubić” wpis niż leakować pamięć.
easyjvmjrejdk+1
Odpowiedź
JVM uruchamia bytecode Javy. JRE to środowisko uruchomieniowe (JVM + biblioteki standardowe) potrzebne do odpalania aplikacji. JDK to zestaw deweloperski (JRE + kompilator i narzędzia) potrzebny do budowania aplikacji.
mediumrecordsdtoimmutability+1
Odpowiedź
Record to zwięzła składnia dla niezmiennego nośnika danych. Generuje final pola, konstruktor oraz `equals/hashCode/toString`. Jest dobry do DTO, wiadomości i obiektów “wartościowych” — nie do encji z rozbudowanym, mutowalnym cyklem życia.
mediumstreamscollectionsside-effects+1
Odpowiedź
Kolekcja przechowuje dane; stream opisuje potok operacji (filter/map/reduce), który produkuje wynik. Streamy są zwykle jednorazowe, a częsty błąd to efekty uboczne (mutowanie zewnętrznego stanu) w `map/forEach`, co utrudnia myślenie o kodzie.
List<String> activeNames = users.stream()
.filter(User::isActive)
.map(User::getName)
.toList();hardthreadlocalconcurrencythread-pool+1
Odpowiedź
`ThreadLocal` przechowuje osobną wartość na wątek (często jako kontekst requestu). Częsty problem to pule wątków: wątki są recyklingowane, więc wartości mogą “przeciekać” między requestami, jeśli ich nie wyczyścisz (`remove()` w `finally`).
hardconcurrencylockssynchronized+1
Odpowiedź
`synchronized` jest prostsze i używa monitorów JVM, dając wzajemne wykluczenie oraz jasne happens-before. `ReentrantLock` jest bardziej elastyczny: `tryLock()`, timeouty, opcje fairness i wiele `Condition` — ale musisz zawsze robić `unlock()` w `finally`.
easyclasspathjvmjar+1
Odpowiedź
Classpath to lista miejsc, w których JVM szuka klas i zasobów (katalogi i pliki JAR). Jeśli czegoś nie ma na classpath, możesz dostać `ClassNotFoundException` / `NoClassDefFoundError`. Ustawiasz go przez build tool, IDE albo opcję `-cp` przy uruchamianiu Javy.
mediumjavavartype-inference+1
Odpowiedź
`var` daje inferencję typu dla zmiennych lokalnych: kompilator wywnioskuje statyczny typ z inicjalizatora. To NIE robi z Javy języka dynamicznego. `var` działa tylko dla zmiennych lokalnych z inicjalizatorem (nie dla pól, parametrów metod ani bez przypisania).
mediumjavacollectionsimmutability+1
Odpowiedź
`List.of(...)` tworzy listę niemodyfikowalną (unmodifiable). Próba add/remove skończy się `UnsupportedOperationException`. Częsty gotcha: nie pozwala też na elementy null (rzuci `NullPointerException` już przy tworzeniu).
List<String> xs = List.of("a", "b");
// xs.add("c"); // throws UnsupportedOperationExceptionhardjavastreamsparallel+2
Odpowiedź
Parallel streamy mogą pomóc przy pracy CPU-bound na dużych kolekcjach, gdy elementy są niezależne, a praca jest na tyle ciężka, żeby opłacił się narzut. Pułapki: domyślnie używają `ForkJoinPool.commonPool`, mogą być wolniejsze dla małych zadań, są złe dla blokującego I/O, a efekty uboczne i współdzielony stan łatwo prowadzą do race condition.
hardjavaclassloaderjvm+1
Odpowiedź
ClassLoader ładuje klasy i zasoby. W Javie typ jest identyfikowany przez (nazwa klasy + ClassLoader, który ją załadował). To znaczy, że “ta sama” nazwa klasy załadowana przez dwa różne classloadery jest traktowana jako dwa różne typy, co potrafi dać `ClassCastException` w setupach typu pluginy albo app-serwery.
mediumjavagenericstype-erasure+1
Odpowiedź
Type erasure oznacza, że informacja o typach generycznych jest usuwana w runtime. W efekcie nie zrobisz `new T()`, `T.class` ani `instanceof T`, a część sprawdzeń działa tylko w czasie kompilacji. W runtime widzisz typy „surowe”.
easyjavarecorddto+1
Odpowiedź
`record` to zwięzły nośnik danych. Generuje prywatne finalne pola, kanoniczny konstruktor, akcesory, `equals`, `hashCode` i `toString`. Sprawdza się jako DTO/obiekt wartości, gdzie równość wynika z danych, ale nie czyni zagnieżdżonych obiektów niemutowalnymi.
mediumjavasealedinheritance+1
Odpowiedź
Sealed class ogranicza, które klasy mogą ją dziedziczyć/implementować (`permits`). Dzięki temu hierarchia jest jawna i można pisać wyczerpujące `switch`. To przydatne do modelowania zamkniętych zestawów wariantów.
mediumjavaconcurrencylocks+1
Odpowiedź
`synchronized` używa wbudowanych monitorów i automatycznie zwalnia blokadę. `ReentrantLock` to jawny lock z funkcjami typu `tryLock`, polityką fairness i możliwością przerwania oczekiwania — ale musisz go zwolnić w `finally`. Oba są reentrant.
easyjavaexceptionsresources+1
Odpowiedź
Wymaga zasobów implementujących `AutoCloseable`. Zasób jest zamykany automatycznie (nawet przy wyjątku), co zmniejsza boilerplate i zapobiega wyciekom. Jest bezpieczniejsze niż ręczne `finally`.
try (var in = Files.newInputStream(path)) {
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
}easyjavastringperformance+1
Odpowiedź
StringBuilder nie jest synchronizowany i jest szybszy w kodzie jednowątkowym. StringBuffer jest synchronizowany (thread‑safe), ale zwykle wolniejszy. Oba są mutowalnymi alternatywami dla `String`.
mediumjavacollectionsconcurrency+1
Odpowiedź
HashMap nie jest thread‑safe i najlepiej używać go w kodzie jednowątkowym lub zewnętrznie synchronizowanym. ConcurrentHashMap wspiera bezpieczne współbieżne odczyty/zapisy z lepszą skalowalnością; nie pozwala na null key/value. Używaj, gdy wiele wątków korzysta z mapy bez dodatkowych locków.
mediumjavagcjvm+2
Odpowiedź
Większość obiektów szybko umiera. JVM wykorzystuje to, często sprzątając young generation (szybkie minor GC) i promując długo żyjące obiekty do old generation, które sprząta rzadziej. To poprawia throughput i czasy pauz.
mediumjavajitperformance+1
Odpowiedź
JVM startuje od interpretacji bytecode, a potem JIT kompiluje „gorące” metody do kodu natywnego na podstawie profilowania. Na początku bywa wolniej; po rozgrzaniu działa szybciej dzięki zoptymalizowanemu kodowi maszynowemu.
mediumjavanested-classinner-class+1
Odpowiedź
Statyczna klasa zagnieżdżona nie trzyma ukrytej referencji do obiektu zewnętrznego i można ją tworzyć bez instancji klasy zewnętrznej. Inner class ma referencję do obiektu zewnętrznego, co zwiększa zużycie pamięci i może prowadzić do leaków.