[{"data":1,"prerenderedAt":811},["ShallowReactive",2],{"fw-java":3},{"framework":4,"topics":15,"qa":51},{"id":5,"description":6,"extension":7,"icon":8,"meta":9,"name":10,"order":11,"slug":8,"stem":12,"tier":13,"__hash__":14},"frameworks\u002Fframeworks\u002Fjava.yml","Java interview questions on language fundamentals, object-oriented design, the Collections Framework, exception handling and concurrency — a staple of backend and enterprise technical interviews.","yml","java",{},"Java",5,"frameworks\u002Fjava",1,"jcUKEcQDoMZrreMRtZYJIVpkQlB-varlzbuwmzLr7kc",[16,24,33,42],{"id":17,"description":18,"extension":7,"frameworkSlug":8,"meta":19,"name":20,"order":13,"slug":21,"stem":22,"__hash__":23},"topics\u002Ftopics\u002Fjava-fundamentals.yml","Primitives and wrappers, the String pool, pass-by-value semantics and the object model — the language basics every Java interview starts with.",{},"Fundamentals","fundamentals","topics\u002Fjava-fundamentals","I9Cp0oY-rFDDQ4-iChg29zHL5qVFZP30ULk-xU61i5Y",{"id":25,"description":26,"extension":7,"frameworkSlug":8,"meta":27,"name":28,"order":29,"slug":30,"stem":31,"__hash__":32},"topics\u002Ftopics\u002Fjava-collections.yml","Lists, Sets and Maps, their implementations and trade-offs, iteration and ordering — the Collections Framework that powers most Java code.",{},"Collections",2,"collections","topics\u002Fjava-collections","oGTCqx27Fx-UyQr0bYQtu2sxlQYag65E2mZEwzZePmQ",{"id":34,"description":35,"extension":7,"frameworkSlug":8,"meta":36,"name":37,"order":38,"slug":39,"stem":40,"__hash__":41},"topics\u002Ftopics\u002Fjava-exceptions.yml","Checked vs unchecked exceptions, try\u002Fcatch\u002Ffinally, try-with-resources and designing robust error handling in Java.",{},"Exceptions",3,"exceptions","topics\u002Fjava-exceptions","7wdMfBCatvnEmcGFu6579NZ09gM6HXBfmZyHrPAAwaE",{"id":43,"description":44,"extension":7,"frameworkSlug":8,"meta":45,"name":46,"order":47,"slug":48,"stem":49,"__hash__":50},"topics\u002Ftopics\u002Fjava-concurrency.yml","Threads, synchronization, the memory model, executors and the high-level concurrency utilities used to write correct multithreaded Java.",{},"Concurrency",4,"concurrency","topics\u002Fjava-concurrency","m3PKd0A4OZd-vv3VInNyqKEXxsh5992rebNBGM1GqsM",[52,212,367,513,660],{"id":53,"title":54,"body":55,"description":59,"difficulty":61,"extension":62,"framework":10,"frameworkSlug":8,"meta":63,"navigation":64,"order":13,"path":65,"questions":66,"related":205,"seo":206,"seoDescription":207,"stem":208,"subtopic":209,"topic":28,"topicSlug":30,"updated":210,"__hash__":211},"qa\u002Fjava\u002Fcollections\u002Flist-map-set.md","List Map Set",{"type":56,"value":57,"toc":58},"minimark",[],{"title":59,"searchDepth":29,"depth":29,"links":60},"",[],"medium","md",{},true,"\u002Fjava\u002Fcollections\u002Flist-map-set",[67,72,76,80,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181,185,189,193,197,201],{"id":68,"difficulty":69,"q":70,"a":71},"collection-hierarchy","easy","What is the Java Collections Framework?","A unified set of interfaces and implementations for storing groups of objects.\nThe root is `Iterable` -> `Collection`, which branches into:\n\n- **`List`** — ordered, indexed, allows duplicates (`ArrayList`, `LinkedList`).\n- **`Set`** — no duplicates (`HashSet`, `TreeSet`, `LinkedHashSet`).\n- **`Queue`\u002F`Deque`** — ordering for processing (`ArrayDeque`, `PriorityQueue`).\n\n**`Map`** is part of the framework but **not** a `Collection` (it stores\nkey->value pairs, not single elements).\n\n```java\nList\u003CString> list = new ArrayList\u003C>();\nSet\u003CString> set   = new HashSet\u003C>();\nMap\u003CString, Integer> map = new HashMap\u003C>();\n```\n\nProgramming to the interface (`List` not `ArrayList`) lets you swap\nimplementations freely.\n",{"id":73,"difficulty":69,"q":74,"a":75},"list-vs-set-vs-map","What is the difference between List, Set and Map?","- **`List`** — an **ordered, indexed** sequence that **allows duplicates**.\n  Access by position.\n- **`Set`** — an **unordered** collection of **unique** elements (uniqueness\n  defined by `equals`\u002F`hashCode`).\n- **`Map`** — **key->value** pairs with **unique keys**; not a `Collection`.\n\n```java\nList.of(\"a\", \"a\", \"b\");          \u002F\u002F [a, a, b] — duplicates kept\nSet.of(\"a\", \"a\", \"b\");           \u002F\u002F throws — duplicate in Set.of\nnew HashSet\u003C>(List.of(\"a\",\"a\")); \u002F\u002F {a} — duplicate dropped\nMap.of(\"k1\", 1, \"k2\", 2);        \u002F\u002F {k1=1, k2=2}\n```\n\nPick by need: ordered\u002Findexed -> List; uniqueness\u002Fmembership -> Set; lookups by\nkey -> Map.\n",{"id":77,"difficulty":61,"q":78,"a":79},"arraylist-vs-linkedlist","What is the difference between ArrayList and LinkedList?","- **`ArrayList`** — backed by a **resizable array**. O(1) random access by\n  index; O(1) amortized append; O(n) insert\u002Fremove in the middle (shifting).\n  Cache-friendly, lower memory overhead.\n- **`LinkedList`** — a **doubly-linked list**. O(1) insert\u002Fremove at the ends\n  (or at a known node); but O(n) index access (must walk the chain) and higher\n  per-element memory (node pointers).\n\n```java\nList\u003CInteger> a = new ArrayList\u003C>();\na.get(1000);          \u002F\u002F O(1)\nList\u003CInteger> l = new LinkedList\u003C>();\nl.get(1000);          \u002F\u002F O(n) — walks 1000 nodes\n```\n\nIn practice **`ArrayList` wins almost always** — its cache locality beats\n`LinkedList` even for many insert\u002Fremove patterns. Use `LinkedList` mainly as a\n`Deque`\u002Fqueue.\n",{"id":81,"difficulty":82,"q":83,"a":84},"hashmap-internals","hard","How does HashMap work internally?","A `HashMap` is an **array of buckets**. To store a key it computes\n`hashCode()`, spreads the bits, and maps it to a bucket index. Collisions (keys\nlanding in the same bucket) are chained in a **linked list**, which **converts\nto a balanced tree (red-black)** once a bucket exceeds 8 entries (and the table\nis ≥64) — keeping worst-case lookups at O(log n) instead of O(n).\n\n```java\nMap\u003CString, Integer> m = new HashMap\u003C>();\nm.put(\"a\", 1);   \u002F\u002F hash(\"a\") -> bucket -> store entry\nm.get(\"a\");      \u002F\u002F hash(\"a\") -> bucket -> equals() scan -> 1\n```\n\nLookup\u002Finsert are **O(1) average**. When the size exceeds `capacity *\nloadFactor` (default 16 * 0.75 = 12), the table **resizes** (doubles) and\nrehashes. This is why a correct `hashCode`\u002F`equals` pair is essential.\n",{"id":86,"difficulty":82,"q":87,"a":88},"load-factor","What are capacity and load factor in a HashMap?","- **Capacity** — the number of buckets (always a power of two, default 16).\n- **Load factor** — the fullness threshold (default 0.75). When\n  `size > capacity * loadFactor`, the map **resizes** (capacity doubles) and\n  rehashes all entries.\n\n```java\n\u002F\u002F pre-size when you know roughly how many entries to avoid resizes\nMap\u003CString,Integer> m = new HashMap\u003C>(64);\n```\n\nThe 0.75 default trades space vs time: lower load factor = fewer collisions but\nmore memory; higher = denser but slower lookups. Pre-sizing a known-large map\navoids repeated O(n) resizes during population.\n",{"id":90,"difficulty":61,"q":91,"a":92},"hashmap-vs-hashtable","What is the difference between HashMap, Hashtable and ConcurrentHashMap?","- **`HashMap`** — not synchronized, allows **one `null` key** and `null`\n  values, fastest. Use single-threaded or with external synchronization.\n- **`Hashtable`** — legacy, **fully synchronized** (every method locks the whole\n  table), **no `null`** keys\u002Fvalues. Largely obsolete.\n- **`ConcurrentHashMap`** — thread-safe with **fine-grained locking** (per-bin\n  CAS, not a global lock), no `null` keys\u002Fvalues, high concurrency.\n\n```java\nMap\u003CString,Integer> safe = new ConcurrentHashMap\u003C>(); \u002F\u002F modern thread-safe choice\n```\n\nFor concurrent code, prefer **`ConcurrentHashMap`** over `Hashtable` or\n`Collections.synchronizedMap` — it scales far better under contention.\n",{"id":94,"difficulty":61,"q":95,"a":96},"hashset-treeset-linkedhashset","What is the difference between HashSet, LinkedHashSet and TreeSet?","- **`HashSet`** — backed by a `HashMap`; **no ordering**, O(1) add\u002Fcontains.\n- **`LinkedHashSet`** — `HashSet` + a linked list, so it preserves\n  **insertion order**; O(1) with slightly more memory.\n- **`TreeSet`** — a red-black tree; keeps elements in **sorted order**, O(log n)\n  operations, requires `Comparable`\u002F`Comparator`.\n\n```java\nnew HashSet\u003C>(List.of(3,1,2));       \u002F\u002F order undefined, e.g. [1,2,3] or other\nnew LinkedHashSet\u003C>(List.of(3,1,2)); \u002F\u002F [3, 1, 2] — insertion order\nnew TreeSet\u003C>(List.of(3,1,2));       \u002F\u002F [1, 2, 3] — sorted\n```\n\nChoose by requirement: speed -> HashSet; remember order -> LinkedHashSet; sorted\u002F\nrange queries -> TreeSet.\n",{"id":98,"difficulty":61,"q":99,"a":100},"hashmap-treemap-linkedhashmap","How do HashMap, LinkedHashMap and TreeMap differ?","They mirror the Set variants:\n\n- **`HashMap`** — no order, O(1) average.\n- **`LinkedHashMap`** — insertion order (or access order, enabling easy LRU\n  caches), O(1).\n- **`TreeMap`** — keys sorted, O(log n), supports range\u002Fnavigation methods\n  (`firstKey`, `ceilingKey`, `subMap`).\n\n```java\n\u002F\u002F LinkedHashMap as an LRU cache\nvar lru = new LinkedHashMap\u003CString,Integer>(16, 0.75f, true) {\n  protected boolean removeEldestEntry(Map.Entry\u003CString,Integer> e) {\n    return size() > 100;\n  }\n};\n```\n\n`TreeMap`'s navigation API is its superpower; `LinkedHashMap`'s access-order\nmode is the classic LRU trick.\n",{"id":102,"difficulty":82,"q":103,"a":104},"fail-fast","What is a fail-fast iterator and ConcurrentModificationException?","Most collection iterators are **fail-fast**: they track a `modCount`, and if the\ncollection is structurally modified during iteration (other than through the\niterator's own `remove`), they throw **`ConcurrentModificationException`** —\nfailing immediately rather than risking corrupt results.\n\n```java\nfor (String s : list) {\n  if (s.isEmpty()) list.remove(s); \u002F\u002F ConcurrentModificationException\n}\n\nIterator\u003CString> it = list.iterator();\nwhile (it.hasNext()) {\n  if (it.next().isEmpty()) it.remove(); \u002F\u002F safe via the iterator\n}\nlist.removeIf(String::isEmpty);          \u002F\u002F cleanest\n```\n\nFail-fast is **best-effort** (not guaranteed). Concurrent collections like\n`CopyOnWriteArrayList`\u002F`ConcurrentHashMap` are **fail-safe** instead — they\niterate over a snapshot and don't throw.\n",{"id":106,"difficulty":61,"q":107,"a":108},"comparable-vs-comparator","What is the difference between Comparable and Comparator?","- **`Comparable\u003CT>`** — the type's **natural ordering**, implemented *by the\n  class itself* via `compareTo`. One ordering per class.\n- **`Comparator\u003CT>`** — an **external** ordering object via `compare`, so you can\n  define many orderings without touching the class.\n\n```java\nclass User implements Comparable\u003CUser> {\n  int age; String name;\n  public int compareTo(User o) { return Integer.compare(age, o.age); } \u002F\u002F natural\n}\n\u002F\u002F alternate orderings without modifying User:\nusers.sort(Comparator.comparing(u -> u.name));\nusers.sort(Comparator.comparingInt((User u) -> u.age).reversed()\n                     .thenComparing(u -> u.name));\n```\n\nRule of thumb: one obvious default ordering -> `Comparable`; multiple\u002Fcontextual\norderings -> `Comparator` (which also composes nicely with `thenComparing`).\n",{"id":110,"difficulty":61,"q":111,"a":112},"iterator-vs-listiterator","What is the difference between Iterator and ListIterator?","- **`Iterator`** — forward-only traversal of any `Collection`; supports\n  `hasNext`, `next`, and `remove`.\n- **`ListIterator`** — a `List`-only iterator that goes **both directions**\n  (`hasPrevious`\u002F`previous`), exposes indices (`nextIndex`), and can **`add`**\n  and **`set`** elements during iteration.\n\n```java\nListIterator\u003CString> it = list.listIterator();\nwhile (it.hasNext()) {\n  String s = it.next();\n  if (s.isBlank()) it.set(\"(empty)\"); \u002F\u002F replace in place\n}\n```\n\nUse `ListIterator` when you need to walk backward or modify elements while\niterating a list.\n",{"id":114,"difficulty":61,"q":115,"a":116},"arraylist-resize","How does ArrayList grow, and what is amortized O(1)?","An `ArrayList` holds an internal array. When it fills up, it allocates a **larger\narray** (~1.5×) and copies the elements over — an O(n) operation. But because\ngrowth happens **rarely** (geometrically), the *average* cost of `add` over many\ncalls is **O(1) amortized**.\n\n```java\nList\u003CInteger> list = new ArrayList\u003C>(1000); \u002F\u002F pre-size: skip the resizes\nfor (int i = 0; i \u003C 1000; i++) list.add(i);\n```\n\nIf you know the final size, pass an **initial capacity** to avoid the repeated\ncopies. Note `size()` (number of elements) differs from the internal capacity.\n",{"id":118,"difficulty":69,"q":119,"a":120},"generics-why","Why are generics used in collections?","Generics give collections **compile-time type safety** and remove casts. Before\ngenerics, collections held `Object`, so you could insert anything and had to cast\non the way out — risking `ClassCastException` at runtime.\n\n```java\nList\u003CString> names = new ArrayList\u003C>();\nnames.add(\"Ada\");\nString s = names.get(0);   \u002F\u002F no cast; adding an Integer won't compile\n\nList raw = new ArrayList(); \u002F\u002F raw type — unsafe, avoid\nraw.add(42);\nString bad = (String) raw.get(0); \u002F\u002F compiles, ClassCastException at runtime\n```\n\nGenerics catch type errors at **compile time** and make code self-documenting.\n",{"id":122,"difficulty":82,"q":123,"a":124},"type-erasure","What is type erasure?","Java generics are a **compile-time** feature. After type checking, the compiler\n**erases** type parameters — `List\u003CString>` and `List\u003CInteger>` both become raw\n`List` at runtime, with casts inserted automatically. This keeps backward\ncompatibility with pre-generics code.\n\n```java\nList\u003CString> a = new ArrayList\u003C>();\nList\u003CInteger> b = new ArrayList\u003C>();\na.getClass() == b.getClass();  \u002F\u002F true — same runtime class\n\n\u002F\u002F consequences of erasure:\n\u002F\u002F new T[]      -> illegal\n\u002F\u002F x instanceof List\u003CString> -> illegal (only List\u003C?>)\n```\n\nErasure is why you can't do `new T()`, create generic arrays, or check a generic\ntype with `instanceof` — the type info simply isn't there at runtime.\n",{"id":126,"difficulty":82,"q":127,"a":128},"wildcards","What do the ? extends and ? super wildcards mean (PECS)?","Bounded wildcards control what you can read\u002Fwrite through a generic reference:\n\n- **`? extends T`** — an unknown subtype of T; you can **read** Ts out, but\n  **can't add** (the exact type is unknown). A **Producer**.\n- **`? super T`** — an unknown supertype of T; you can **add** Ts, but reads come\n  back as `Object`. A **Consumer**.\n\nThe mnemonic is **PECS — Producer `extends`, Consumer `super`**:\n\n```java\nvoid copy(List\u003C? extends Number> src, List\u003C? super Number> dst) {\n  for (Number n : src) dst.add(n); \u002F\u002F read from producer, write to consumer\n}\n```\n\n`src` produces values (read-only), `dst` consumes them (write-ok). This is how\n`Collections.copy` and friends are typed.\n",{"id":130,"difficulty":61,"q":131,"a":132},"queue-deque","What are Queue and Deque, and which implementations are common?","- **`Queue`** — FIFO processing; `offer`\u002F`poll`\u002F`peek`. `PriorityQueue` orders\n  by priority instead of arrival.\n- **`Deque`** (\"deck\") — double-ended queue; add\u002Fremove at **both ends**. Works\n  as a queue **or** a stack.\n\n```java\nDeque\u003CInteger> stack = new ArrayDeque\u003C>();\nstack.push(1); stack.push(2); stack.pop();  \u002F\u002F LIFO -> 2\n\nQueue\u003CInteger> q = new ArrayDeque\u003C>();\nq.offer(1); q.offer(2); q.poll();           \u002F\u002F FIFO -> 1\n\nQueue\u003CInteger> pq = new PriorityQueue\u003C>();\npq.offer(5); pq.offer(1); pq.peek();        \u002F\u002F 1 (smallest first)\n```\n\nPrefer **`ArrayDeque`** over the legacy `Stack` class (synchronized, extends\n`Vector`) for stack\u002Fqueue needs.\n",{"id":134,"difficulty":61,"q":135,"a":136},"immutable-collections","How do you create immutable collections?","- **`List.of` \u002F `Set.of` \u002F `Map.of`** (Java 9+) — concise, truly immutable,\n  reject `null` and (for Set\u002FMap) duplicates.\n- **`Collections.unmodifiableList(...)`** — an unmodifiable *view* over an\n  existing collection.\n- **`List.copyOf(...)`** — an immutable copy of any collection.\n\n```java\nList\u003CString> a = List.of(\"x\", \"y\");        \u002F\u002F immutable\na.add(\"z\");                                 \u002F\u002F UnsupportedOperationException\n\nList\u003CString> backing = new ArrayList\u003C>(List.of(\"x\"));\nList\u003CString> view = Collections.unmodifiableList(backing);\nbacking.add(\"y\");                           \u002F\u002F view reflects this — it's a VIEW\n```\n\nGotcha: `unmodifiableList` is a **view** — mutating the backing list still shows\nthrough it. `List.of`\u002F`copyOf` are genuinely independent and immutable.\n",{"id":138,"difficulty":61,"q":139,"a":140},"null-handling","Which collections allow null and which do not?","- **`HashMap`** — one `null` key, many `null` values. **`HashSet`** — one\n  `null` element. `ArrayList`\u002F`LinkedList` allow `null`s.\n- **`Hashtable`, `ConcurrentHashMap`, `TreeMap` (keys)** — **no `null`** (TreeMap\n  can't compare null; concurrent maps disallow it to avoid ambiguity).\n- **`List.of`\u002F`Set.of`\u002F`Map.of`** — reject `null` entirely.\n\n```java\nnew HashMap\u003C>().put(null, 1);          \u002F\u002F\nnew ConcurrentHashMap\u003C>().put(null,1); \u002F\u002F NullPointerException\nList.of(\"a\", null);                    \u002F\u002F NullPointerException\n```\n\nAvoiding `null` (using `Optional` or sentinel objects) sidesteps a whole class\nof these errors.\n",{"id":142,"difficulty":69,"q":143,"a":144},"collections-utility","What does the Collections utility class provide?","`java.util.Collections` is a toolbox of static helpers that operate on\ncollections: `sort`, `reverse`, `shuffle`, `min`\u002F`max`, `binarySearch`,\n`frequency`, `unmodifiableXxx`, `synchronizedXxx`, and `emptyList()`\u002F\n`singletonList()`.\n\n```java\nList\u003CInteger> nums = new ArrayList\u003C>(List.of(3, 1, 2));\nCollections.sort(nums);                 \u002F\u002F [1, 2, 3]\nCollections.reverse(nums);              \u002F\u002F [3, 2, 1]\nint max = Collections.max(nums);        \u002F\u002F 3\n```\n\nDon't confuse `Collections` (utility class, plural) with `Collection` (the\ninterface). `Arrays` is its array-focused sibling (`Arrays.sort`,\n`Arrays.asList`).\n",{"id":146,"difficulty":82,"q":147,"a":148},"arrays-aslist","What are the pitfalls of Arrays.asList()?","`Arrays.asList` returns a **fixed-size list backed by the array** — not a normal\n`ArrayList`. You can `set` elements (it writes through to the array) but **can't\n`add`\u002F`remove`** (throws `UnsupportedOperationException`).\n\n```java\nList\u003CInteger> l = Arrays.asList(1, 2, 3);\nl.set(0, 9);   \u002F\u002F writes through to the backing array\nl.add(4);      \u002F\u002F UnsupportedOperationException\n\n\u002F\u002F also: a primitive array gives a 1-element List\u003Cint[]>, not List\u003CInteger>!\nList\u003Cint[]> oops = Arrays.asList(new int[]{1, 2, 3}); \u002F\u002F size 1\n\nList\u003CInteger> real = new ArrayList\u003C>(Arrays.asList(1, 2, 3)); \u002F\u002F mutable copy\n```\n\nWrap it in `new ArrayList\u003C>(...)` for a fully mutable list, and remember\nautoboxing: pass `Integer[]`, not `int[]`.\n",{"id":150,"difficulty":61,"q":151,"a":152},"set-uniqueness","How does a HashSet decide that two elements are duplicates?","A `HashSet` (backed by a `HashMap`) treats two elements as duplicates when their\n**`hashCode()` matches** *and* **`equals()` returns true**. So uniqueness depends\nentirely on a correct `equals`\u002F`hashCode` implementation.\n\n```java\nclass P { int x;\n  \u002F\u002F no equals\u002FhashCode -> identity-based, \"duplicates\" stay\n}\nSet\u003CP> s = new HashSet\u003C>();\ns.add(new P()); s.add(new P());  \u002F\u002F size 2 (different objects)\n```\n\nIf you forget to override them, two logically-equal objects are treated as\ndistinct. If you override `equals` but not `hashCode` (or vice versa), the set\nmay store duplicates or fail to find elements.\n",{"id":154,"difficulty":82,"q":155,"a":156},"mutable-key","What happens if you use a mutable object as a HashMap key?","The map places the key in a bucket based on its **hash at insertion time**. If\nyou then **mutate the key** so its `hashCode` changes, it ends up in the \"wrong\"\nbucket — the map can no longer find it, even with the same reference.\n\n```java\nMap\u003CList\u003CInteger>, String> m = new HashMap\u003C>();\nList\u003CInteger> key = new ArrayList\u003C>(List.of(1));\nm.put(key, \"v\");\nkey.add(2);                 \u002F\u002F mutates the key -> hashCode changes\nm.get(key);                 \u002F\u002F null! lost in the wrong bucket\n```\n\nRule: **use immutable keys** (`String`, `Integer`, records, frozen value\nobjects). It's the same reason Python forbids list keys.\n",{"id":158,"difficulty":61,"q":159,"a":160},"concurrent-modification-map","How do you safely remove entries from a Map while iterating?","Don't call `map.remove` inside an enhanced-for over its entries — that throws\n`ConcurrentModificationException`. Use the **iterator's `remove`**, or the\ncleaner `removeIf`\u002F`entrySet().removeIf`, or `keySet`\u002F`values` views.\n\n```java\n\u002F\u002F iterator\nIterator\u003CMap.Entry\u003CString,Integer>> it = map.entrySet().iterator();\nwhile (it.hasNext()) {\n  if (it.next().getValue() == 0) it.remove();\n}\n\u002F\u002F concise\nmap.values().removeIf(v -> v == 0);\nmap.entrySet().removeIf(e -> e.getValue() == 0);\n```\n\nFor concurrent access from multiple threads, use `ConcurrentHashMap`, whose\niterators are fail-safe.\n",{"id":162,"difficulty":61,"q":163,"a":164},"stack-vector","Why are Vector and Stack discouraged?","`Vector` and its subclass `Stack` are **legacy synchronized** collections from\nJava 1.0. Every method is synchronized, so they pay locking overhead even in\nsingle-threaded code, and that per-method locking doesn't make *compound*\noperations atomic anyway.\n\n```java\nDeque\u003CInteger> stack = new ArrayDeque\u003C>(); \u002F\u002F modern stack\nList\u003CInteger> list = new ArrayList\u003C>();    \u002F\u002F modern list\n```\n\nUse `ArrayList` (unsynchronized list), `ArrayDeque` (stack\u002Fqueue), and pick a\n*concurrent* collection or explicit synchronization when you genuinely need\nthread safety — not `Vector`\u002F`Stack`.\n",{"id":166,"difficulty":61,"q":167,"a":168},"map-getordefault-merge","What do getOrDefault, computeIfAbsent and merge do?","Java 8 added convenience methods that simplify common map idioms:\n\n- **`getOrDefault(k, d)`** — value for `k`, or `d` if absent.\n- **`computeIfAbsent(k, fn)`** — compute and store a value only if `k` is\n  missing; perfect for multimaps.\n- **`merge(k, v, fn)`** — combine an existing value with a new one; perfect for\n  counting.\n\n```java\n\u002F\u002F grouping (multimap)\nmap.computeIfAbsent(key, k -> new ArrayList\u003C>()).add(item);\n\n\u002F\u002F frequency count\ncounts.merge(word, 1, Integer::sum);\n\nint n = counts.getOrDefault(\"x\", 0);\n```\n\nThese replace verbose `if (map.containsKey(...)) ... else ...` blocks and are\natomic on `ConcurrentHashMap`.\n",{"id":170,"difficulty":61,"q":171,"a":172},"priorityqueue","How does a PriorityQueue work?","A `PriorityQueue` is a **binary heap** that always dequeues the **highest-\npriority** element (by natural order or a `Comparator`), not FIFO. `offer`\u002F`poll`\nare O(log n); `peek` is O(1).\n\n```java\n\u002F\u002F min-heap (default): smallest first\nQueue\u003CInteger> min = new PriorityQueue\u003C>();\n\u002F\u002F max-heap: reverse the comparator\nQueue\u003CInteger> max = new PriorityQueue\u003C>(Comparator.reverseOrder());\nmax.offer(1); max.offer(5); max.peek(); \u002F\u002F 5\n```\n\nCaveat: it's only ordered at the **head** — iterating it does *not* yield sorted\norder. It's the go-to for \"top-K\", Dijkstra, and scheduling problems.\n",{"id":174,"difficulty":61,"q":175,"a":176},"synchronized-collections","What is the difference between synchronized and concurrent collections?","- **`Collections.synchronizedList\u002FMap(...)`** — wraps a collection so each method\n  locks the **whole object**. Simple, but compound operations\n  (check-then-act, iteration) still need external synchronization, and there's\n  no concurrency.\n- **Concurrent collections** (`ConcurrentHashMap`, `CopyOnWriteArrayList`,\n  `ConcurrentLinkedQueue`) — designed for concurrency with fine-grained or\n  lock-free strategies; far better throughput.\n\n```java\nList\u003CInteger> s = Collections.synchronizedList(new ArrayList\u003C>());\nsynchronized (s) {                 \u002F\u002F still must lock to iterate safely\n  for (int x : s) { }\n}\nMap\u003CString,Integer> c = new ConcurrentHashMap\u003C>(); \u002F\u002F no external lock needed\n```\n\nPrefer the concurrent collections in new code.\n",{"id":178,"difficulty":82,"q":179,"a":180},"copyonwrite","When would you use CopyOnWriteArrayList?","`CopyOnWriteArrayList` makes a fresh copy of the backing array on **every\nmutation**, so reads and iteration are **lock-free and never throw\n`ConcurrentModificationException`** (iterators see a stable snapshot). The cost:\nwrites are O(n).\n\n```java\nList\u003CListener> listeners = new CopyOnWriteArrayList\u003C>();\nfor (Listener l : listeners) l.onEvent(); \u002F\u002F safe even if another thread adds\n```\n\nIdeal for **read-mostly, write-rarely** scenarios with concurrent iteration —\nclassically event-listener lists. Terrible for write-heavy workloads.\n",{"id":182,"difficulty":61,"q":183,"a":184},"equals-in-collections","Why must equals and hashCode be consistent for collections to work?","Hash-based collections (`HashMap`, `HashSet`) locate elements by **hash first,\nthen `equals`**. If two equal objects have different hash codes, they land in\ndifferent buckets and the collection can't recognize them as the same — you get\nduplicates in a Set or failed lookups in a Map.\n\n```java\nclass Key {\n  int id;\n  Key(int id) { this.id = id; }\n  @Override public boolean equals(Object o) {\n    return o instanceof Key k && k.id == id;\n  }\n  \u002F\u002F forgot hashCode -> equal Keys get different hashes\n}\nMap\u003CKey,String> m = new HashMap\u003C>();\nm.put(new Key(1), \"a\");\nm.get(new Key(1));   \u002F\u002F null — wrong bucket\n```\n\nAlways override **both together**, keeping them based on the same fields.\n",{"id":186,"difficulty":82,"q":187,"a":188},"tree-navigation","What navigation methods do TreeMap and TreeSet provide?","Because they're sorted, `TreeMap`\u002F`TreeSet` (the `NavigableMap`\u002F`NavigableSet`\ninterfaces) offer **range and neighbor queries** that hash structures can't:\n\n- `first()\u002Flast()`, `floor(x)` (≤ x), `ceiling(x)` (≥ x), `lower(x)` (\u003C x),\n  `higher(x)` (> x).\n- `headSet`, `tailSet`, `subSet` \u002F `headMap`, `tailMap`, `subMap` for ranges.\n\n```java\nNavigableSet\u003CInteger> s = new TreeSet\u003C>(List.of(10, 20, 30));\ns.floor(25);    \u002F\u002F 20  (largest ≤ 25)\ns.ceiling(25);  \u002F\u002F 30  (smallest ≥ 25)\ns.subSet(15, 35); \u002F\u002F [20, 30]\n```\n\nThese make `TreeMap`\u002F`TreeSet` the choice for \"nearest value\", ranges, and\nordered iteration — at O(log n) per operation.\n",{"id":190,"difficulty":61,"q":191,"a":192},"enumset-enummap","What are EnumSet and EnumMap and why use them?","Specialized, highly efficient collections for **enum** keys\u002Felements.\n`EnumSet` is internally a **bit vector**; `EnumMap` is backed by a **plain\narray** indexed by `ordinal()`. Both are much faster and smaller than\n`HashSet`\u002F`HashMap` for enums, and iterate in **enum declaration order**.\n\n```java\nenum Day { MON, TUE, WED, THU, FRI, SAT, SUN }\nEnumSet\u003CDay> weekend = EnumSet.of(Day.SAT, Day.SUN);\nEnumMap\u003CDay, String> plans = new EnumMap\u003C>(Day.class);\nplans.put(Day.MON, \"gym\");\n```\n\nWhenever your keys are enum constants, prefer these over the general-purpose\ncollections.\n",{"id":194,"difficulty":61,"q":195,"a":196},"stream-collectors","How do you build collections from a Stream?","Terminal `collect` with the `Collectors` factory turns a stream into a\ncollection or grouped structure:\n\n```java\nList\u003CString> upper = names.stream()\n    .map(String::toUpperCase)\n    .collect(Collectors.toList());        \u002F\u002F or .toList() (Java 16+)\n\nMap\u003CBoolean, List\u003CInteger>> parts = nums.stream()\n    .collect(Collectors.partitioningBy(n -> n % 2 == 0));\n\nMap\u003CDept, List\u003CEmp>> byDept = emps.stream()\n    .collect(Collectors.groupingBy(Emp::dept));\n```\n\n`Collectors` covers `toSet`, `toMap`, `groupingBy`, `partitioningBy`,\n`joining`, and `counting` — declarative replacements for manual loop-and-add.\n",{"id":198,"difficulty":82,"q":199,"a":200},"list-remove-int-trap","What is the trap with List.remove and an int argument?","`List` has two overloads: `remove(int index)` removes **by position**, and\n`remove(Object o)` removes **by value**. With a `List\u003CInteger>`, passing a\nprimitive `int` calls the **index** version — not the value one.\n\n```java\nList\u003CInteger> list = new ArrayList\u003C>(List.of(10, 20, 30));\nlist.remove(1);                 \u002F\u002F removes INDEX 1 -> [10, 30]\nlist.remove(Integer.valueOf(10)); \u002F\u002F removes the VALUE 10 -> [30]\n```\n\nTo remove a value, box it explicitly with `Integer.valueOf(x)` (or cast to\n`(Integer)`). This is one of the most common surprise bugs with integer lists.\n",{"id":202,"difficulty":69,"q":203,"a":204},"choosing-collection","How do you choose the right collection for a task?","Match the data structure to the dominant operation:\n\n- Ordered list, index access, mostly appends -> **`ArrayList`**.\n- Unique elements, fast membership tests -> **`HashSet`**.\n- Key->value lookups -> **`HashMap`**.\n- Need sorted order or range queries -> **`TreeMap`\u002F`TreeSet`**.\n- Preserve insertion order -> **`LinkedHashMap`\u002F`LinkedHashSet`**.\n- FIFO queue \u002F stack -> **`ArrayDeque`**; priority -> **`PriorityQueue`**.\n- Concurrent access -> **`ConcurrentHashMap`**, `CopyOnWriteArrayList`.\n\n```java\nMap\u003CString,Integer> wordCount = new HashMap\u003C>();   \u002F\u002F counting\nSet\u003CString> seen = new HashSet\u003C>();                \u002F\u002F dedupe\n```\n\nStart from the access pattern (lookup? order? uniqueness? concurrency?) and the\nchoice usually falls out.\n",null,{"description":59},"Java Collections Framework interview questions — List vs Set vs Map, ArrayList vs LinkedList, HashMap internals, fail-fast iterators, Comparable vs Comparator, generics and immutable collections.","java\u002Fcollections\u002Flist-map-set","Lists, Maps & Sets","2026-06-18","4nQd1Mi8XVoUVUsO5rEz9BXEiWRC6sSMJZ0skAAkT9g",{"id":213,"title":214,"body":215,"description":59,"difficulty":82,"extension":62,"framework":10,"frameworkSlug":8,"meta":219,"navigation":64,"order":13,"path":220,"questions":221,"related":205,"seo":362,"seoDescription":363,"stem":364,"subtopic":365,"topic":46,"topicSlug":48,"updated":210,"__hash__":366},"qa\u002Fjava\u002Fconcurrency\u002Fthreads.md","Threads",{"type":56,"value":216,"toc":217},[],{"title":59,"searchDepth":29,"depth":29,"links":218},[],{},"\u002Fjava\u002Fconcurrency\u002Fthreads",[222,226,230,234,238,242,246,250,254,258,262,266,270,274,278,282,286,290,294,298,302,306,310,314,318,322,326,330,334,338,342,346,350,354,358],{"id":223,"difficulty":69,"q":224,"a":225},"thread-vs-runnable","What are the ways to create a thread in Java?","Two basic approaches, plus the modern preferred one:\n\n- **Extend `Thread`** and override `run()` — simple, but uses up your single\n  inheritance slot.\n- **Implement `Runnable`** and pass it to a `Thread` — favored, because it\n  separates the task from the thread and works with executors.\n\n```java\n\u002F\u002F Runnable (preferred)\nRunnable task = () -> System.out.println(\"working\");\nnew Thread(task).start();\n\n\u002F\u002F extending Thread\nclass Worker extends Thread { public void run() { } }\n```\n\nIn real code you rarely create threads directly at all — you submit\n`Runnable`\u002F`Callable` tasks to an **`ExecutorService`**, which manages a pool\nfor you.\n",{"id":227,"difficulty":69,"q":228,"a":229},"start-vs-run","What is the difference between start() and run()?","**`start()`** asks the JVM to create a **new thread** and invoke `run()` on it —\nconcurrent execution. Calling **`run()`** directly just executes the method on\nthe **current** thread, like any ordinary call — no concurrency at all.\n\n```java\nThread t = new Thread(() -> System.out.println(Thread.currentThread().getName()));\nt.start();   \u002F\u002F prints \"Thread-0\" — runs on a new thread\nt.run();     \u002F\u002F prints \"main\"    — runs on the caller's thread\n```\n\nAlso, calling `start()` **twice** on the same `Thread` throws\n`IllegalThreadStateException` — a thread can be started only once.\n",{"id":231,"difficulty":61,"q":232,"a":233},"thread-lifecycle","What are the states in a thread's lifecycle?","A `Thread` moves through these `Thread.State` values:\n\n- **NEW** — created but not started.\n- **RUNNABLE** — eligible to run (running or waiting for CPU).\n- **BLOCKED** — waiting to acquire a monitor lock.\n- **WAITING** — waiting indefinitely (`wait()`, `join()`, `park()`).\n- **TIMED_WAITING** — waiting with a timeout (`sleep`, `wait(ms)`).\n- **TERMINATED** — finished or threw.\n\n```java\nThread t = new Thread(task);\nt.getState();  \u002F\u002F NEW\nt.start();\nt.getState();  \u002F\u002F RUNNABLE\n```\n\nTransitions are driven by the scheduler and synchronization calls; you observe\n(not directly set) the state.\n",{"id":235,"difficulty":61,"q":236,"a":237},"race-condition","What is a race condition?","A race condition occurs when **multiple threads access shared mutable state\nconcurrently** and the outcome depends on the **timing** of their interleaving.\nOperations that look atomic (like `count++`) are actually read-modify-write\nsequences that can interleave and lose updates.\n\n```java\nclass Counter {\n  int count;\n  void inc() { count++; } \u002F\u002F read, +1, write — NOT atomic\n}\n\u002F\u002F 1000 threads each calling inc() once -> final count often \u003C 1000\n```\n\nFixes: make the operation atomic (`synchronized`, `AtomicInteger`), or avoid\nshared mutable state. Race conditions are insidious because they're\n**intermittent** and timing-dependent.\n",{"id":239,"difficulty":61,"q":240,"a":241},"synchronized","What does the synchronized keyword do?","`synchronized` enforces **mutual exclusion**: only one thread can hold an\nobject's **monitor lock** at a time, so synchronized code runs serially. It also\nestablishes a **happens-before** relationship, guaranteeing memory visibility of\nchanges made under the lock.\n\n```java\nclass Counter {\n  private int count;\n  synchronized void inc() { count++; }      \u002F\u002F locks on `this`\n  void dec() {\n    synchronized (this) { count--; }        \u002F\u002F synchronized block\n  }\n}\n```\n\nA `synchronized` instance method locks on `this`; a `synchronized` static method\nlocks on the **`Class`** object. Keep critical sections small to limit\ncontention.\n",{"id":243,"difficulty":82,"q":244,"a":245},"volatile","What does volatile do and what does it not do?","`volatile` guarantees **visibility** and **ordering**: writes by one thread are\nimmediately visible to others (no per-thread caching), and it prevents\nreordering around the access. What it does **not** provide is **atomicity** for\ncompound operations.\n\n```java\nvolatile boolean running = true;  \u002F\u002F flag — visibility is enough\nvoid stop() { running = false; }  \u002F\u002F other threads see this promptly\n\nvolatile int count;\ncount++;   \u002F\u002F still a race — read-modify-write isn't atomic\n```\n\nUse `volatile` for **flags\u002Fstate published once** (the classic stop-flag), and\n`synchronized`\u002F`Atomic*` when you need atomic compound updates.\n",{"id":247,"difficulty":82,"q":248,"a":249},"synchronized-vs-volatile","What is the difference between synchronized and volatile?","- **`volatile`** — only **visibility + ordering** for a single variable. No\n  locking, no atomicity for compound ops. Cheap.\n- **`synchronized`** — **mutual exclusion + visibility**. Makes whole code\n  blocks atomic, can guard multiple variables, but threads can block on the\n  lock.\n\n```java\nvolatile boolean flag;       \u002F\u002F visibility only\nsynchronized void transfer() {  \u002F\u002F atomicity across several fields\n  from -= amt; to += amt;\n}\n```\n\nQuick rule: a single flag\u002Freference written-then-read -> `volatile`; a\nmulti-step invariant or counter -> `synchronized` (or an atomic\u002Flock).\n",{"id":251,"difficulty":82,"q":252,"a":253},"deadlock","What is a deadlock and how do you prevent it?","A deadlock is two+ threads each **holding a lock the other needs**, so all wait\nforever. It requires four conditions (Coffman): mutual exclusion, hold-and-wait,\nno preemption, and circular wait.\n\n```java\n\u002F\u002F Thread 1: lock A then B   |   Thread 2: lock B then A  -> deadlock\nsynchronized (a) { synchronized (b) { } }\nsynchronized (b) { synchronized (a) { } }\n```\n\nPrevention: acquire locks in a **consistent global order**, use **timeouts**\n(`tryLock`), reduce lock scope, or avoid multiple locks entirely. Breaking any\none Coffman condition (usually circular wait, via lock ordering) prevents\ndeadlock.\n",{"id":255,"difficulty":82,"q":256,"a":257},"livelock-starvation","What are livelock and starvation?","- **Starvation** — a thread is perpetually denied the resources\u002FCPU it needs\n  (e.g. low-priority threads, or always losing a lock to greedier ones), so it\n  never makes progress.\n- **Livelock** — threads are **actively running** but keep responding to each\n  other in a way that prevents progress (like two people stepping aside in the\n  same direction repeatedly).\n\n```java\n\u002F\u002F livelock sketch: both threads keep \"politely\" backing off\nwhile (other.isActive()) { backOff(); \u002F* never proceeds *\u002F }\n```\n\nUnlike deadlock (threads blocked), livelocked threads consume CPU. Fixes\ninclude randomized back-off, fairness policies, and bounded retries.\n",{"id":259,"difficulty":82,"q":260,"a":261},"wait-notify","How do wait(), notify() and notifyAll() work?","They coordinate threads on an object's monitor and **must be called while\nholding that object's lock** (inside `synchronized`). `wait()` releases the lock\nand suspends the thread until notified; `notify()` wakes one waiter,\n`notifyAll()` wakes all.\n\n```java\nsynchronized (queue) {\n  while (queue.isEmpty()) {   \u002F\u002F ALWAYS loop, never a bare if\n    queue.wait();             \u002F\u002F releases lock, waits\n  }\n  process(queue.remove());\n}\n\u002F\u002F producer:\nsynchronized (queue) { queue.add(item); queue.notifyAll(); }\n```\n\nAlways re-check the condition in a **`while`** loop (spurious wakeups + stale\nconditions). Prefer `notifyAll` unless you're certain one waiter suffices.\n",{"id":263,"difficulty":61,"q":264,"a":265},"sleep-vs-wait","What is the difference between sleep() and wait()?","- **`Thread.sleep(ms)`** — a static method that pauses the **current** thread\n  for a time **without releasing any locks** it holds. For timing\u002Fthrottling.\n- **`Object.wait()`** — an instance method that **releases the object's lock**\n  and waits to be notified; must be called inside `synchronized`. For\n  coordination between threads.\n\n```java\nsynchronized (lock) {\n  Thread.sleep(100);  \u002F\u002F keeps holding `lock` the whole time\n  lock.wait();        \u002F\u002F releases `lock` while waiting\n}\n```\n\nKey distinction: `sleep` keeps the lock, `wait` gives it up. Using `sleep` for\ninter-thread coordination is a classic anti-pattern.\n",{"id":267,"difficulty":61,"q":268,"a":269},"executor-service","What is an ExecutorService and why use a thread pool?","An `ExecutorService` manages a **pool of reusable threads** and a task queue, so\nyou submit work instead of creating threads by hand. This caps the thread count,\nreuses threads (avoiding creation overhead), and decouples task submission from\nexecution.\n\n```java\nExecutorService pool = Executors.newFixedThreadPool(4);\nFuture\u003CInteger> f = pool.submit(() -> compute());\npool.execute(() -> fireAndForget());\npool.shutdown();                 \u002F\u002F stop accepting; finish queued tasks\npool.awaitTermination(1, TimeUnit.MINUTES);\n```\n\nCreating a thread per task doesn't scale — unbounded threads exhaust memory and\nthrash the scheduler. Always `shutdown()` a pool to release its threads.\n",{"id":271,"difficulty":61,"q":272,"a":273},"thread-pool-types","What thread pool types does Executors provide?","- **`newFixedThreadPool(n)`** — fixed number of threads, unbounded queue.\n- **`newCachedThreadPool()`** — grows\u002Fshrinks on demand; reuses idle threads.\n- **`newSingleThreadExecutor()`** — one thread, sequential task processing.\n- **`newScheduledThreadPool(n)`** — for delayed\u002Fperiodic tasks.\n- **`newVirtualThreadPerTaskExecutor()`** (Java 21) — a virtual thread per task.\n\n```java\nvar scheduled = Executors.newScheduledThreadPool(2);\nscheduled.scheduleAtFixedRate(this::poll, 0, 5, TimeUnit.SECONDS);\n```\n\nIn production many teams construct **`ThreadPoolExecutor`** directly to control\nthe queue bounds and rejection policy, since `newFixedThreadPool`'s unbounded\nqueue can hide backpressure problems.\n",{"id":275,"difficulty":61,"q":276,"a":277},"callable-future","What is the difference between Runnable and Callable, and what is a Future?","- **`Runnable`** — `run()` returns **nothing** and can't throw checked\n  exceptions.\n- **`Callable\u003CV>`** — `call()` **returns a value** and may throw checked\n  exceptions.\n- **`Future\u003CV>`** — a handle to a pending result; `get()` blocks until it's\n  ready, `isDone()`\u002F`cancel()` manage it.\n\n```java\nCallable\u003CInteger> task = () -> 6 * 7;\nFuture\u003CInteger> f = pool.submit(task);\nInteger result = f.get();   \u002F\u002F blocks until done -> 42\n```\n\n`Future.get()` is **blocking**, which is its main weakness — addressed by\n`CompletableFuture`'s non-blocking composition.\n",{"id":279,"difficulty":82,"q":280,"a":281},"completablefuture","What is CompletableFuture and how does it improve on Future?","`CompletableFuture` is a `Future` you can **compose and chain\nasynchronously** — attaching callbacks instead of blocking on `get()`, and\ncombining multiple async results.\n\n```java\nCompletableFuture.supplyAsync(() -> fetchUser(id))\n    .thenApply(User::name)                 \u002F\u002F transform when ready\n    .thenCompose(name -> lookupAsync(name)) \u002F\u002F chain another async call\n    .exceptionally(ex -> \"fallback\")        \u002F\u002F handle errors\n    .thenAccept(System.out::println);       \u002F\u002F consume, non-blocking\n\nCompletableFuture.allOf(f1, f2, f3).join();  \u002F\u002F wait for several\n```\n\nIt enables a non-blocking pipeline (`thenApply`\u002F`thenCompose`\u002F`thenCombine`),\nbuilt-in error handling, and easy fan-out\u002Ffan-in — far more flexible than the\nblocking `Future`.\n",{"id":283,"difficulty":61,"q":284,"a":285},"atomic-classes","What are the atomic classes and how do they work?","`java.util.concurrent.atomic` provides lock-free, thread-safe variables —\n`AtomicInteger`, `AtomicLong`, `AtomicReference`, etc. They use **CAS\n(compare-and-swap)** hardware instructions for atomic updates without locking.\n\n```java\nAtomicInteger count = new AtomicInteger();\ncount.incrementAndGet();          \u002F\u002F atomic ++\ncount.compareAndSet(5, 10);       \u002F\u002F set to 10 only if currently 5\nref.updateAndGet(v -> v + delta); \u002F\u002F atomic functional update\n```\n\nAtomics outperform `synchronized` for simple counters\u002Fflags under contention\n(no blocking), though heavy contention can cause CAS retry loops. For high\ncontention prefer `LongAdder`.\n",{"id":287,"difficulty":82,"q":288,"a":289},"cas","What is compare-and-swap (CAS)?","CAS is an atomic CPU instruction: \"if this memory location still holds the\n*expected* value, replace it with the *new* value, atomically; otherwise do\nnothing and report failure.\" It's the foundation of **lock-free** algorithms.\n\n```java\n\u002F\u002F typical lock-free retry loop\nint prev, next;\ndo {\n  prev = atomic.get();\n  next = prev + 1;\n} while (!atomic.compareAndSet(prev, next)); \u002F\u002F retry if another thread changed it\n```\n\nBecause no lock is held, there's no blocking or deadlock — but it can spin under\ncontention, and it has the **ABA problem** (a value changing A->B->A looks\nunchanged), which `AtomicStampedReference` solves with a version stamp.\n",{"id":291,"difficulty":82,"q":292,"a":293},"reentrantlock","What is ReentrantLock and how does it compare to synchronized?","`ReentrantLock` is an explicit lock with the same mutual-exclusion semantics as\n`synchronized` but **more features**: `tryLock()` (with timeout), interruptible\nlocking, **fairness** policy, and multiple **`Condition`** objects.\n\n```java\nReentrantLock lock = new ReentrantLock();\nlock.lock();\ntry { \u002F* critical section *\u002F }\nfinally { lock.unlock(); }   \u002F\u002F MUST unlock in finally\n\nif (lock.tryLock(1, TimeUnit.SECONDS)) { ... }  \u002F\u002F give up after 1s\n```\n\nTrade-off: `synchronized` is simpler and auto-releases on block exit;\n`ReentrantLock` is more powerful but you **must** `unlock()` in `finally` or you\nleak the lock. Use it only when you need its extra capabilities.\n",{"id":295,"difficulty":82,"q":296,"a":297},"read-write-lock","What is a ReadWriteLock?","A `ReadWriteLock` separates a **read lock** (shared — many readers at once) from\na **write lock** (exclusive). It boosts throughput for **read-heavy** data where\nwrites are rare, since concurrent reads don't block each other.\n\n```java\nReadWriteLock rw = new ReentrantReadWriteLock();\nrw.readLock().lock();   try { return cache.get(k); } finally { rw.readLock().unlock(); }\nrw.writeLock().lock();  try { cache.put(k, v); }     finally { rw.writeLock().unlock(); }\n```\n\nOnly one writer runs at a time and it excludes all readers. For very read-heavy\ncases, `StampedLock` (Java 8) adds optimistic reads that are even faster.\n",{"id":299,"difficulty":82,"q":300,"a":301},"threadlocal","What is ThreadLocal and when is it used?","`ThreadLocal\u003CT>` gives **each thread its own independent copy** of a variable,\nso there's no sharing and no synchronization needed. Common for per-thread\ncontext: `SimpleDateFormat` (not thread-safe), user\u002Frequest context, DB\nconnections.\n\n```java\nstatic final ThreadLocal\u003CSimpleDateFormat> FMT =\n    ThreadLocal.withInitial(() -> new SimpleDateFormat(\"yyyy-MM-dd\"));\nString today = FMT.get().format(new Date());  \u002F\u002F safe per-thread instance\n```\n\nCaution in **thread pools**: threads are reused, so you must **`remove()`** the\nvalue after use or it leaks into the next task (and can cause memory leaks).\n",{"id":303,"difficulty":82,"q":304,"a":305},"java-memory-model","What is the Java Memory Model and happens-before?","The Java Memory Model (JMM) defines **when writes by one thread become visible to\nanother** and what reorderings are allowed. The core concept is\n**happens-before**: if action A happens-before B, A's effects are guaranteed\nvisible to B.\n\nHappens-before edges include: program order within a thread; unlocking a monitor\n-> subsequent locking of it; a `volatile` write -> subsequent read; `Thread.start`\n-> the thread's actions; a thread's actions -> another's `join`.\n\n```java\nvolatile boolean ready;\nint data;\n\u002F\u002F Thread A:\ndata = 42; ready = true;          \u002F\u002F volatile write publishes `data`\n\u002F\u002F Thread B:\nif (ready) System.out.println(data); \u002F\u002F sees 42 — happens-before guarantees it\n```\n\nWithout a happens-before relationship, one thread may **never** see another's\nwrites (or see them reordered). This is *why* `volatile`\u002F`synchronized` matter.\n",{"id":307,"difficulty":61,"q":308,"a":309},"thread-safety","What does it mean for code to be thread-safe?","Thread-safe code behaves **correctly when accessed by multiple threads\nconcurrently**, without external synchronization, regardless of timing. You\nachieve it by: avoiding shared mutable state, **immutability**,\n**synchronization**, atomic variables, or thread-confinement (`ThreadLocal`).\n\n```java\n\u002F\u002F thread-safe by immutability — no state can change\nrecord Point(int x, int y) { }\n\u002F\u002F thread-safe by synchronization\nclass SafeCounter { private int n; synchronized void inc() { n++; } }\n```\n\nLevels range from **immutable** (always safe) -> **thread-safe** (handles its own\nsync) -> **conditionally safe** (some ops need external sync) -> **not\nthread-safe** (`ArrayList`, `HashMap`). The cheapest safety is having no shared\nmutable state at all.\n",{"id":311,"difficulty":82,"q":312,"a":313},"producer-consumer","How do you implement the producer-consumer pattern?","Producers add items to a shared buffer, consumers remove them; they must\ncoordinate so producers wait when full and consumers wait when empty. The\nidiomatic modern way is a **`BlockingQueue`**, which handles all the\nwaiting\u002Fnotifying internally.\n\n```java\nBlockingQueue\u003CTask> queue = new LinkedBlockingQueue\u003C>(100);\n\n\u002F\u002F producer\nqueue.put(task);        \u002F\u002F blocks if the queue is full\n\n\u002F\u002F consumer\nTask t = queue.take();  \u002F\u002F blocks if the queue is empty\n```\n\n`put`\u002F`take` block automatically — no manual `wait`\u002F`notify`. `ArrayBlockingQueue`\n(bounded) gives natural backpressure; `LinkedBlockingQueue` can be bounded or\nunbounded.\n",{"id":315,"difficulty":61,"q":316,"a":317},"countdownlatch","What are CountDownLatch and CyclicBarrier?","Both are synchronization aids that make threads wait for each other:\n\n- **`CountDownLatch`** — threads wait until a counter reaches zero; **one-shot**\n  (can't be reset). \"Wait for N tasks to finish.\"\n- **`CyclicBarrier`** — a fixed number of threads wait for **each other** at a\n  barrier point; **reusable** across rounds.\n\n```java\nCountDownLatch latch = new CountDownLatch(3);\nfor (int i = 0; i \u003C 3; i++)\n  pool.submit(() -> { work(); latch.countDown(); });\nlatch.await();   \u002F\u002F main thread blocks until all 3 finish\n```\n\n`CountDownLatch` is for \"main waits for workers\"; `CyclicBarrier` is for \"workers\nsync up repeatedly.\" `Semaphore` is a related tool that limits concurrent access\nto N permits.\n",{"id":319,"difficulty":61,"q":320,"a":321},"daemon-thread","What is a daemon thread?","A daemon thread is a **background thread that does not prevent the JVM from\nexiting**. The JVM shuts down once only daemon threads remain, abruptly stopping\nthem (their `finally` blocks may not run). Used for support tasks like GC,\nhousekeeping, and monitoring.\n\n```java\nThread t = new Thread(this::poll);\nt.setDaemon(true);   \u002F\u002F must be set BEFORE start()\nt.start();\n```\n\nUser (non-daemon) threads, by contrast, **keep the JVM alive** until they finish.\nSet the daemon flag before `start()` — changing it after throws\n`IllegalThreadStateException`. Don't use daemons for work that must complete.\n",{"id":323,"difficulty":82,"q":324,"a":325},"thread-interruption","How does thread interruption work?","Interruption is a **cooperative** signal, not a forced stop. `interrupt()` sets a\nthread's interrupt flag; the thread must **check it** (`isInterrupted()`) or be\nin a blocking call that throws `InterruptedException`. There is no safe way to\nforcibly kill a thread (`Thread.stop()` is deprecated and dangerous).\n\n```java\nwhile (!Thread.currentThread().isInterrupted()) {\n  try {\n    doWork();\n    Thread.sleep(100);\n  } catch (InterruptedException e) {\n    Thread.currentThread().interrupt(); \u002F\u002F restore the flag, then exit\n    break;\n  }\n}\n```\n\nBest practice: when you catch `InterruptedException` and can't propagate it,\n**restore the interrupt status** with `Thread.currentThread().interrupt()` so\ncallers still see it.\n",{"id":327,"difficulty":61,"q":328,"a":329},"synchronized-collections-conc","Why is ConcurrentHashMap preferred over synchronized maps?","`Collections.synchronizedMap` locks the **entire map** for every operation, so\nthreads serialize even on unrelated keys — a bottleneck. `ConcurrentHashMap`\nuses **fine-grained locking \u002F CAS on individual bins**, allowing many threads to\nread and write different buckets concurrently.\n\n```java\nMap\u003CString,Integer> m = new ConcurrentHashMap\u003C>();\nm.merge(word, 1, Integer::sum);     \u002F\u002F atomic compound update, no global lock\nm.computeIfAbsent(k, x -> load(x)); \u002F\u002F atomic\n```\n\nIt also offers **atomic** compound methods (`merge`, `computeIfAbsent`,\n`putIfAbsent`) and fail-safe iteration. The result is dramatically better\nthroughput under concurrency.\n",{"id":331,"difficulty":82,"q":332,"a":333},"false-sharing","What is false sharing?","False sharing is a performance problem (not a correctness bug) where two threads\nmodify **different variables that happen to sit on the same CPU cache line**.\nEach write **invalidates the whole line** in the other core's cache, forcing\nexpensive cache-coherence traffic even though the variables are independent.\n\n```java\n\u002F\u002F a[0] and a[1] may share a cache line; two threads hammering them contend\nlong[] counters = new long[2];\n\u002F\u002F padding or @Contended separates hot fields onto different lines\n```\n\nMitigations: pad hot fields apart, use `@jdk.internal.vm.annotation.Contended`,\nor use `LongAdder`, which internally stripes counters across cells to avoid\ncontention.\n",{"id":335,"difficulty":69,"q":336,"a":337},"thread-priority","How do thread priorities work?","Each thread has a priority from 1 (`MIN_PRIORITY`) to 10 (`MAX_PRIORITY`),\ndefault 5. It's only a **hint** to the OS scheduler about relative importance —\nnot a guarantee. Behavior is platform-dependent and often ignored.\n\n```java\nThread t = new Thread(task);\nt.setPriority(Thread.MAX_PRIORITY);  \u002F\u002F best-effort hint only\n```\n\nDon't build correctness on priorities — they can't ensure ordering and, on some\nplatforms, do almost nothing. For real coordination use explicit synchronization\nor executor configuration.\n",{"id":339,"difficulty":61,"q":340,"a":341},"synchronized-static","What is the difference between a synchronized instance method and a static one?","The difference is **which lock** is acquired:\n\n- A `synchronized` **instance** method locks on **`this`** (the object). Two\n  threads on *different instances* don't contend.\n- A `synchronized` **static** method locks on the **`Class`** object, shared by\n  all instances.\n\n```java\nclass C {\n  synchronized void a() { }          \u002F\u002F locks on this instance\n  static synchronized void b() { }   \u002F\u002F locks on C.class (one global lock)\n}\n```\n\nA subtle bug: `a()` and `b()` use **different locks**, so they can run\nsimultaneously even though both are \"synchronized.\" Mixing instance and static\nsynchronization on shared state doesn't protect it.\n",{"id":343,"difficulty":82,"q":344,"a":345},"double-checked-locking","What is double-checked locking and why does it need volatile?","Double-checked locking lazily initializes a singleton while only locking on the\nfirst call:\n\n```java\nclass Singleton {\n  private static volatile Singleton instance;   \u002F\u002F volatile is essential\n  static Singleton get() {\n    if (instance == null) {                      \u002F\u002F 1st check (no lock)\n      synchronized (Singleton.class) {\n        if (instance == null) {                  \u002F\u002F 2nd check (locked)\n          instance = new Singleton();\n        }\n      }\n    }\n    return instance;\n  }\n}\n```\n\nWithout **`volatile`**, another thread could see a **partially constructed**\nobject: `instance = new Singleton()` isn't atomic (allocate, construct, assign),\nand reordering could publish the reference before construction finishes.\n`volatile` forbids that reordering. (An enum or holder-class singleton avoids the\nwhole issue.)\n",{"id":347,"difficulty":82,"q":348,"a":349},"blocking-vs-nonblocking","What is the difference between blocking and non-blocking algorithms?","- **Blocking** algorithms use locks; a thread that can't proceed is **suspended**\n  (BLOCKED\u002FWAITING) until the lock frees. Simple, but a slow\u002Fdead lock-holder\n  stalls others (and risks deadlock).\n- **Non-blocking** (lock-free) algorithms use **CAS** retry loops; a thread never\n  suspends — it retries until it succeeds. No deadlock, better scalability, but\n  harder to write and can livelock\u002Fspin.\n\n```java\n\u002F\u002F non-blocking counter\nAtomicLong c = new AtomicLong();\nc.incrementAndGet();   \u002F\u002F CAS loop under the hood — never blocks\n```\n\n`java.util.concurrent` provides both: `ReentrantLock`\u002F`BlockingQueue` (blocking)\nand `Atomic*`\u002F`ConcurrentLinkedQueue` (non-blocking).\n",{"id":351,"difficulty":82,"q":352,"a":353},"virtual-threads","What are virtual threads (Project Loom)?","Virtual threads (Java 21) are **lightweight threads managed by the JVM**, not the\nOS. Millions can exist at once because a blocked virtual thread is **unmounted**\nfrom its carrier OS thread, freeing it for other work. This makes the simple\n\"thread-per-request\" blocking style scale like async code.\n\n```java\ntry (var executor = Executors.newVirtualThreadPerTaskExecutor()) {\n  for (var task : tasks) executor.submit(task); \u002F\u002F a virtual thread each\n}\n```\n\nThey're cheap to create and ideal for **I\u002FO-bound** workloads (many tasks\nblocking on network\u002FDB). For CPU-bound work, platform threads sized to the cores\nare still the right tool — virtual threads don't add CPU.\n",{"id":355,"difficulty":61,"q":356,"a":357},"synchronization-overhead","What is lock contention and how do you reduce it?","Lock contention occurs when many threads compete for the **same lock**, so they\nserialize and queue up — throughput collapses as cores sit idle waiting. The fix\nis to reduce how often and how long threads hold shared locks.\n\nStrategies:\n- **Shrink the critical section** — hold the lock for as little code as possible.\n- **Lock striping** — split one lock into many (what `ConcurrentHashMap` does).\n- **Use atomics \u002F lock-free** structures for simple state.\n- **Immutable or thread-local** data to avoid sharing.\n- **Read-write locks** when reads dominate.\n\n```java\n\u002F\u002F whole method locked     \u002F\u002F lock only the shared mutation\nsynchronized void m() {       void m() {\n  var x = expensive();          var x = expensive();\n  shared.add(x);                synchronized (shared) { shared.add(x); }\n}                             }\n```\n",{"id":359,"difficulty":61,"q":360,"a":361},"executor-shutdown","How do you properly shut down an ExecutorService?","Use the standard two-phase shutdown so in-flight tasks finish and threads are\nreleased (a pool's non-daemon threads otherwise keep the JVM alive):\n\n```java\npool.shutdown();                      \u002F\u002F stop accepting new tasks\ntry {\n  if (!pool.awaitTermination(30, TimeUnit.SECONDS)) {\n    pool.shutdownNow();               \u002F\u002F interrupt running tasks\n    pool.awaitTermination(10, TimeUnit.SECONDS);\n  }\n} catch (InterruptedException e) {\n  pool.shutdownNow();\n  Thread.currentThread().interrupt();\n}\n```\n\n`shutdown()` is graceful (finish queued work); `shutdownNow()` interrupts active\ntasks and returns the unstarted ones. Forgetting to shut down a pool is a common\nresource\u002Fthread leak.\n",{"description":59},"Java concurrency interview questions — threads vs Runnable, synchronized, volatile, the memory model, deadlock, wait\u002Fnotify, executors, futures, CompletableFuture and atomic classes.","java\u002Fconcurrency\u002Fthreads","Threads & Synchronization","bB9xo_QxZtFCRbhLK1eQaCAHZBmcvpo3dMNQY89_qMM",{"id":368,"title":369,"body":370,"description":59,"difficulty":61,"extension":62,"framework":10,"frameworkSlug":8,"meta":374,"navigation":64,"order":13,"path":375,"questions":376,"related":205,"seo":509,"seoDescription":510,"stem":511,"subtopic":369,"topic":37,"topicSlug":39,"updated":210,"__hash__":512},"qa\u002Fjava\u002Fexceptions\u002Fexception-handling.md","Exception Handling",{"type":56,"value":371,"toc":372},[],{"title":59,"searchDepth":29,"depth":29,"links":373},[],{},"\u002Fjava\u002Fexceptions\u002Fexception-handling",[377,381,385,389,393,397,401,405,409,413,417,421,425,429,433,437,441,445,449,453,457,461,465,469,473,477,481,485,489,493,497,501,505],{"id":378,"difficulty":69,"q":379,"a":380},"what-is-exception","What is an exception in Java?","An exception is an **object representing an abnormal event** that disrupts\nnormal flow — a division by zero, a missing file, a null dereference. When one\noccurs, the JVM creates an exception object and **propagates it up the call\nstack** until a matching `catch` handles it, or the thread terminates.\n\n```java\ntry {\n  int x = 10 \u002F 0;          \u002F\u002F throws ArithmeticException\n} catch (ArithmeticException e) {\n  System.out.println(\"Caught: \" + e.getMessage()); \u002F\u002F \"\u002F by zero\"\n}\n```\n\nExceptions separate error-handling code from the main logic and carry context\n(message + stack trace) to help diagnose what went wrong.\n",{"id":382,"difficulty":61,"q":383,"a":384},"exception-hierarchy","What does the Java exception hierarchy look like?","Everything throwable descends from **`Throwable`**, which splits into two\nbranches:\n\n- **`Error`** — serious problems the application shouldn't catch\n  (`OutOfMemoryError`, `StackOverflowError`). Unchecked.\n- **`Exception`** — conditions a program may want to handle.\n  - **`RuntimeException`** and its subclasses are **unchecked**.\n  - All other `Exception` subclasses are **checked**.\n\n```\nThrowable\n├── Error              (unchecked — don't catch)\n└── Exception\n    ├── RuntimeException   (unchecked)\n    └── IOException, SQLException... (checked)\n```\n\nSo \"checked vs unchecked\" is purely about whether the class sits under\n`RuntimeException`\u002F`Error` (unchecked) or elsewhere under `Exception` (checked).\n",{"id":386,"difficulty":61,"q":387,"a":388},"checked-vs-unchecked","What is the difference between checked and unchecked exceptions?","- **Checked** exceptions (subclasses of `Exception`, excluding\n  `RuntimeException`) are verified by the **compiler**: a method must either\n  `catch` them or declare `throws`. They represent recoverable, expected\n  conditions (`IOException`, `SQLException`).\n- **Unchecked** exceptions (`RuntimeException`\u002F`Error` subclasses) are **not**\n  compiler-enforced — usually programming bugs (`NullPointerException`,\n  `IllegalArgumentException`, `ArrayIndexOutOfBoundsException`).\n\n```java\nvoid read() throws IOException {     \u002F\u002F checked -> must declare or catch\n  Files.readString(Path.of(\"x\"));\n}\nvoid bug() {\n  String s = null;\n  s.length();                        \u002F\u002F unchecked -> no declaration required\n}\n```\n\nGuideline: checked for conditions callers can reasonably recover from;\nunchecked for bugs and contract violations.\n",{"id":390,"difficulty":61,"q":391,"a":392},"error-vs-exception","What is the difference between Error and Exception?","Both extend `Throwable`, but:\n\n- **`Error`** signals a serious, usually **unrecoverable** JVM\u002Fsystem problem —\n  `OutOfMemoryError`, `StackOverflowError`, `NoClassDefFoundError`. Applications\n  **should not catch** these; there's typically nothing useful to do.\n- **`Exception`** signals an **application-level** condition that code may\n  reasonably handle.\n\n```java\ntry {\n  recurse();                  \u002F\u002F infinite recursion\n} catch (StackOverflowError e) {\n  \u002F\u002F technically possible, but a code smell — don't rely on this\n}\n```\n\nBoth are unchecked (well, `Error` is), but the intent differs: `Error` = \"the\nplatform is broken\"; `Exception` = \"your program hit a handleable situation.\"\n",{"id":394,"difficulty":69,"q":395,"a":396},"try-catch-finally","What are try, catch and finally blocks?","- **`try`** — wraps code that might throw.\n- **`catch`** — handles a specific exception type (you can have several).\n- **`finally`** — runs **always**, whether or not an exception occurred (and\n  even after a `return`) — for cleanup like closing resources.\n\n```java\ntry {\n  risky();\n} catch (IOException e) {\n  log(e);\n} finally {\n  cleanup();   \u002F\u002F runs no matter what\n}\n```\n\nA `try` needs at least one `catch` **or** a `finally`. `catch` blocks are checked\ntop-down, so order **subclasses before superclasses**.\n",{"id":398,"difficulty":82,"q":399,"a":400},"finally-always-runs","Does finally always run? Are there exceptions?","`finally` runs after the `try`\u002F`catch` in virtually all cases — including when\nthe `try` or `catch` executes a `return`, `break`, or `continue`. The **only**\nways to skip it: `System.exit()`, the JVM crashing, an infinite loop\u002Fdeadlock in\nthe `try`, or the thread being killed.\n\n```java\nint f() {\n  try {\n    return 1;     \u002F\u002F evaluated...\n  } finally {\n    System.out.println(\"still runs\"); \u002F\u002F ...but finally runs before returning\n  }\n}\n```\n\nBeware: a `return` (or `throw`) **inside `finally`** overrides the try's return\nand **swallows pending exceptions** — a notorious bug, so never return\u002Fthrow\nfrom `finally`.\n",{"id":402,"difficulty":61,"q":403,"a":404},"try-with-resources","What is try-with-resources?","A `try` with resources declared in parentheses **auto-closes** them when the\nblock exits — normally or via exception — as long as they implement\n`AutoCloseable`. It replaces verbose `finally { x.close(); }` blocks and avoids\nleaks.\n\n```java\ntry (var br = Files.newBufferedReader(path);\n     var conn = dataSource.getConnection()) {\n  return br.readLine();\n}   \u002F\u002F br and conn closed automatically, in reverse order\n```\n\nResources close in **reverse order** of declaration. It also handles the case\nwhere both the body *and* `close()` throw — see suppressed exceptions.\n",{"id":406,"difficulty":61,"q":407,"a":408},"autocloseable","What is AutoCloseable and how do you use it?","`AutoCloseable` is the interface (one method, `close()`) that makes a class\neligible for **try-with-resources**. Implement it for any resource that needs\ndeterministic cleanup — connections, streams, locks.\n\n```java\nclass Connection implements AutoCloseable {\n  Connection() { System.out.println(\"open\"); }\n  public void close() { System.out.println(\"closed\"); }\n}\ntry (Connection c = new Connection()) {\n  \u002F\u002F use c\n} \u002F\u002F close() called automatically\n```\n\n`Closeable` (from `java.io`) extends `AutoCloseable` but narrows `close()` to\nthrow `IOException`. Prefer `AutoCloseable` for general resources.\n",{"id":410,"difficulty":61,"q":411,"a":412},"multi-catch","What is multi-catch and when is it useful?","Multi-catch (Java 7+) handles **several exception types in one `catch`** using\nthe `|` separator, when the handling logic is identical — reducing duplication.\n\n```java\ntry {\n  parseAndStore();\n} catch (IOException | SQLException e) {   \u002F\u002F one handler for both\n  log.error(\"operation failed\", e);\n  throw new ServiceException(e);\n}\n```\n\nRules: the types must **not be subclasses of one another** (redundant), and the\ncaught variable `e` is **implicitly final**. Use it to collapse copy-pasted\ncatch blocks.\n",{"id":414,"difficulty":69,"q":415,"a":416},"throw-vs-throws","What is the difference between throw and throws?","- **`throw`** is a **statement** that actually raises an exception object, now.\n- **`throws`** is a **method declaration** clause announcing which checked\n  exceptions the method may propagate to its caller.\n\n```java\nvoid withdraw(int amt) throws InsufficientFundsException { \u002F\u002F declares\n  if (amt > balance) {\n    throw new InsufficientFundsException(); \u002F\u002F raises\n  }\n}\n```\n\nMnemonic: `throw` *does* it (one object), `throws` *warns about* it (a list of\ntypes). You can `throw` unchecked exceptions without declaring them.\n",{"id":418,"difficulty":61,"q":419,"a":420},"custom-exception","How do you create a custom exception?","Extend `Exception` (for checked) or `RuntimeException` (for unchecked), and\nprovide constructors that pass the message and cause to `super`.\n\n```java\npublic class InsufficientFundsException extends RuntimeException {\n  private final int shortfall;\n  public InsufficientFundsException(int shortfall) {\n    super(\"Short by \" + shortfall + \" cents\");\n    this.shortfall = shortfall;\n  }\n  public int getShortfall() { return shortfall; }\n}\n```\n\nCustom exceptions let you carry **domain-specific data** and let callers\n`catch` precisely. Prefer **unchecked** for programming\u002Fbusiness errors unless\nthe caller can genuinely recover (then checked).\n",{"id":422,"difficulty":61,"q":423,"a":424},"exception-chaining","What is exception chaining (the cause)?","Exception chaining wraps a low-level exception inside a higher-level one while\n**preserving the original as the \"cause\"**, so the full diagnostic trail\nsurvives. Pass the cause to the constructor or `initCause`.\n\n```java\ntry {\n  jdbc.query();\n} catch (SQLException e) {\n  throw new DataAccessException(\"load failed\", e); \u002F\u002F e becomes the cause\n}\n```\n\nThe printed stack trace shows `Caused by: java.sql.SQLException...`. Chaining\nlets you translate exceptions across abstraction layers without losing the root\ncause — far better than catching and re-throwing a bare new exception.\n",{"id":426,"difficulty":82,"q":427,"a":428},"swallowing","What does it mean to \"swallow\" an exception and why is it bad?","Swallowing is catching an exception and **doing nothing** (or only an empty\nblock), hiding the failure so the program continues in a possibly broken state\nand you lose all diagnostic information.\n\n```java\n\u002F\u002F swallowed — silent failure, impossible to debug\ntry { risky(); } catch (Exception e) { }\n\n\u002F\u002F at minimum, log it (and preserve the stack trace)\ntry { risky(); } catch (Exception e) {\n  log.error(\"risky() failed\", e);\n  throw e;                 \u002F\u002F or wrap\u002Frethrow if you can't handle it\n}\n```\n\nRule: never have an empty catch. Either **handle** it meaningfully, **log** it,\nor **rethrow**. Empty catches are one of the most damaging anti-patterns in\nproduction code.\n",{"id":430,"difficulty":61,"q":431,"a":432},"catch-order","Why does catch block order matter?","`catch` blocks are evaluated **top to bottom**, and the first matching type\nwins. So a **more specific** exception must come **before** its superclass —\notherwise the broad catch shadows the specific one and the compiler reports\n\"exception has already been caught.\"\n\n```java\ntry {\n  read();\n} catch (FileNotFoundException e) {  \u002F\u002F specific first\n  \u002F\u002F handle missing file\n} catch (IOException e) {            \u002F\u002F broader after\n  \u002F\u002F handle other I\u002FO errors\n}\n```\n\nReversing them (`IOException` first) is a **compile error**, because\n`FileNotFoundException` could never be reached.\n",{"id":434,"difficulty":69,"q":435,"a":436},"npe-causes","What causes a NullPointerException and how do you prevent it?","An NPE happens when you **dereference `null`** — call a method, access a field,\nindex an array, or unbox a null wrapper.\n\n```java\nString s = map.get(\"missing\"); \u002F\u002F null\ns.length();                    \u002F\u002F NullPointerException\n```\n\nPrevention: validate inputs (`Objects.requireNonNull`), use `Optional` for\nmaybe-absent values, prefer constants on the left of `equals`\n(`\"x\".equals(s)`), use `getOrDefault`, and embrace **Java 14+ helpful NPE\nmessages** which name the exact expression that was null\n(`Cannot invoke \"String.length()\" because \"s\" is null`).\n",{"id":438,"difficulty":61,"q":439,"a":440},"optional","How does Optional help with null handling?","`Optional\u003CT>` is a container that **explicitly represents \"value or absent,\"**\nforcing callers to deal with the empty case instead of risking an NPE on a\nsurprise null.\n\n```java\nOptional\u003CUser> user = repo.findById(id);\nString name = user.map(User::name)\n                  .orElse(\"unknown\");        \u002F\u002F default if absent\nuser.ifPresent(u -> sendEmail(u));           \u002F\u002F act only if present\n```\n\nBest practices: use it as a **return type** for \"might not find one\"; **don't**\nuse it for fields, parameters, or collections (return an empty collection\ninstead); and avoid `.get()` without checking (`isPresent`\u002F`orElseThrow`).\n",{"id":442,"difficulty":69,"q":443,"a":444},"stack-trace","What is a stack trace and how do you read it?","A stack trace is the **snapshot of the call stack** at the moment an exception\nwas created — it lists, top to bottom, the method calls from where the\nexception was thrown back up to the entry point.\n\n```\njava.lang.NullPointerException: ... \"user\" is null\n    at com.app.Service.process(Service.java:42)   \u003C- where it was thrown\n    at com.app.Controller.handle(Controller.java:18)\n    at com.app.Main.main(Main.java:9)\nCaused by: java.sql.SQLException: ...             \u003C- original cause\n```\n\nRead the **top frame** for where it blew up, and follow **`Caused by:`** down to\nthe root cause. Print it with `e.printStackTrace()` or, better, `log.error(msg,\ne)`.\n",{"id":446,"difficulty":82,"q":447,"a":448},"finally-return-trap","What happens when both try and finally have a return?","A `return` in `finally` **overrides** any return or exception from the `try`\u002F\n`catch` — the try's pending result (or thrown exception) is **discarded\nsilently**. This is a subtle, dangerous bug.\n\n```java\nint f() {\n  try {\n    return 1;\n  } finally {\n    return 2;   \u002F\u002F method returns 2; the \"return 1\" is lost\n  }\n}\nint g() {\n  try {\n    throw new RuntimeException();\n  } finally {\n    return 0;   \u002F\u002F swallows the exception entirely\n  }\n}\n```\n\nNever put `return`\u002F`throw`\u002F`break` in `finally`. Use `finally` strictly for\ncleanup, not control flow.\n",{"id":450,"difficulty":82,"q":451,"a":452},"suppressed-exceptions","What are suppressed exceptions?","In try-with-resources, if the **body throws** *and* `close()` also throws, Java\nkeeps the body's exception as primary and attaches the close exception as a\n**suppressed** exception (so neither is lost). You retrieve them via\n`getSuppressed()`.\n\n```java\ntry (AutoCloseable r = () -> { throw new IOException(\"close failed\"); }) {\n  throw new RuntimeException(\"body failed\"); \u002F\u002F primary\n}\n\u002F\u002F RuntimeException propagates; the IOException is in getSuppressed()\n```\n\nBefore try-with-resources, a `close()` exception in a manual `finally` would\n*replace* the original — hiding the real cause. Suppression fixes that. The\nprintout shows `Suppressed:` beneath the main trace.\n",{"id":454,"difficulty":61,"q":455,"a":456},"rethrow","What are the ways to rethrow an exception?","- **Rethrow as-is** — let it propagate after partial handling (log, then\n  `throw e`).\n- **Wrap and rethrow** — translate to a higher-level type, preserving the cause\n  (`throw new ServiceException(e)`).\n- **Rethrow a different type** — only when it improves the abstraction.\n\n```java\ntry {\n  repo.save(order);\n} catch (SQLException e) {\n  metrics.increment(\"save.failure\");\n  throw new PersistenceException(\"could not save order\", e); \u002F\u002F wrap + chain\n}\n```\n\nAlways pass the original as the **cause** when wrapping, so debugging info\nsurvives. Don't catch just to rethrow the *same* type with no added value.\n",{"id":458,"difficulty":61,"q":459,"a":460},"best-practices","What are best practices for exception handling?","- **Catch specific** exceptions, not bare `Exception`\u002F`Throwable`.\n- **Never swallow** — handle, log, or rethrow.\n- **Throw early, catch late** — validate inputs at the boundary; handle where\n  you have context to recover.\n- **Don't use exceptions for control flow** (they're expensive and obscure\n  intent).\n- **Preserve the cause** when wrapping.\n- **Clean up with try-with-resources**, not manual `finally`.\n- Include **useful messages** with context.\n\n```java\n\u002F\u002F specific, contextual, chained\ncatch (IOException e) {\n  throw new ConfigException(\"failed to load \" + path, e);\n}\n```\n",{"id":462,"difficulty":82,"q":463,"a":464},"exception-performance","Why are exceptions expensive, and what is the cost?","The main cost is **capturing the stack trace** when the exception is\nconstructed — the JVM walks the entire call stack and records each frame. The\n`throw`\u002F`catch` mechanism itself is cheap; building the trace is not. So using\nexceptions for ordinary control flow (e.g. loop termination) is slow.\n\n```java\n\u002F\u002F for hot paths where the trace isn't needed, you can disable it:\nclass FastException extends RuntimeException {\n  FastException() { super(null, null, false, false); } \u002F\u002F no stack trace\n}\n```\n\nGuidance: reserve exceptions for **exceptional** conditions; use return values,\n`Optional`, or sentinels for expected outcomes. Don't catch-and-ignore in tight\nloops.\n",{"id":466,"difficulty":61,"q":467,"a":468},"custom-checked-or-unchecked","Should a custom exception be checked or unchecked?","Decide by whether the **caller can reasonably recover**:\n\n- **Checked** (`extends Exception`) — recoverable, expected conditions the\n  caller should be forced to handle (e.g. `FileNotFoundException`-like cases).\n- **Unchecked** (`extends RuntimeException`) — programming errors, contract\n  violations, or failures the caller usually can't fix (validation,\n  configuration, most business-rule violations).\n\n```java\n\u002F\u002F recoverable -> checked\nclass RetryableNetworkException extends Exception { }\n\u002F\u002F bug \u002F unrecoverable -> unchecked\nclass InvalidConfigException extends RuntimeException { }\n```\n\nModern frameworks (Spring, etc.) lean heavily toward **unchecked** to avoid\n`throws` clutter, translating low-level checked exceptions into runtime ones.\n",{"id":470,"difficulty":82,"q":471,"a":472},"catch-throwable","Why should you avoid catching Throwable or Exception broadly?","Catching `Throwable` also catches **`Error`s** (`OutOfMemoryError`,\n`StackOverflowError`) that you can't sensibly recover from and may make things\nworse. Catching `Exception` broadly hides bugs (an unexpected\n`NullPointerException` gets swallowed by a handler meant for I\u002FO errors).\n\n```java\n\u002F\u002F too broad — masks programming bugs and serious errors\ntry { work(); } catch (Throwable t) { \u002F* keep going *\u002F }\n\n\u002F\u002F catch what you can actually handle\ntry { work(); } catch (IOException e) { recover(e); }\n```\n\nCatch the **narrowest** type that you genuinely know how to handle; let\neverything else propagate to a top-level handler.\n",{"id":474,"difficulty":61,"q":475,"a":476},"exception-translation","What is exception translation across layers?","Exception translation means **converting low-level exceptions into ones\nappropriate to the current abstraction layer**, so callers aren't coupled to\nimplementation details (a service shouldn't leak `SQLException`).\n\n```java\n\u002F\u002F persistence layer hides JDBC details from the service layer\ntry {\n  return jdbcTemplate.query(sql);\n} catch (SQLException e) {\n  throw new RepositoryException(\"query failed\", e); \u002F\u002F translate + chain\n}\n```\n\nAlways keep the original as the cause. This is exactly what Spring's\n`DataAccessException` hierarchy does — translating vendor-specific SQL errors\ninto a consistent, unchecked API.\n",{"id":478,"difficulty":61,"q":479,"a":480},"assert","What is the assert keyword and how does it relate to exceptions?","`assert` checks an invariant that should *always* be true; if false it throws an\n`AssertionError`. Assertions are **disabled by default** at runtime (enable with\nthe `-ea` JVM flag), so they're for **catching developer bugs during\ndevelopment\u002Ftesting**, not validating production input.\n\n```java\nassert index >= 0 : \"index must be non-negative, got \" + index;\n```\n\nBecause they can be turned off, **never** use `assert` for argument validation\nor anything with side effects — use `if (...) throw new\nIllegalArgumentException(...)` for real input checks.\n",{"id":482,"difficulty":61,"q":483,"a":484},"nested-try","How do nested try blocks and exception propagation work?","A `try` can contain another `try`. If an inner block doesn't catch an\nexception, it **propagates outward** to the nearest enclosing handler — and\nkeeps unwinding the stack until something catches it or the thread dies.\n\n```java\ntry {\n  try {\n    throw new IllegalStateException(\"inner\");\n  } finally {\n    System.out.println(\"inner finally\"); \u002F\u002F runs during unwind\n  }\n} catch (IllegalStateException e) {\n  System.out.println(\"caught in outer\"); \u002F\u002F handled here\n}\n```\n\nDuring propagation, every `finally` along the way still executes. This unwinding\nis how an exception thrown deep in the call stack reaches a top-level handler.\n",{"id":486,"difficulty":82,"q":487,"a":488},"uncaught-handler","What happens to an uncaught exception in a thread?","If an exception propagates out of a thread's `run`\u002F`main` without being caught,\nthe thread **terminates**, and the JVM hands the exception to that thread's\n**`UncaughtExceptionHandler`** (by default printing the stack trace to\n`System.err`). Other threads keep running; the **whole JVM only exits if it was\nthe last non-daemon thread**.\n\n```java\nThread.setDefaultUncaughtExceptionHandler((t, e) ->\n    log.error(\"Uncaught in \" + t.getName(), e));\n```\n\nSetting a handler is essential for background threads, whose failures would\notherwise vanish silently.\n",{"id":490,"difficulty":61,"q":491,"a":492},"illegalargument-vs-illegalstate","When do you use IllegalArgumentException vs IllegalStateException?","Both are standard unchecked exceptions for **precondition violations**:\n\n- **`IllegalArgumentException`** — a **method argument** is invalid (wrong\n  value\u002Frange).\n- **`IllegalStateException`** — the **object is in the wrong state** for the\n  operation, regardless of the arguments.\n\n```java\nvoid setAge(int age) {\n  if (age \u003C 0) throw new IllegalArgumentException(\"age \u003C 0: \" + age);\n}\nvoid start() {\n  if (running) throw new IllegalStateException(\"already started\");\n}\n```\n\nUse the built-in exceptions (plus `NullPointerException` for null args,\nidiomatically via `Objects.requireNonNull`) rather than inventing custom ones\nfor these common cases.\n",{"id":494,"difficulty":61,"q":495,"a":496},"finally-resource-leak","Why is manual finally cleanup error-prone compared to try-with-resources?","Manual cleanup in `finally` is verbose and easy to get wrong: you must\nnull-check, nest try\u002Fcatch around `close()`, and handle the case where `close()`\nitself throws (which would hide the original exception). Multiple resources\nmultiply the boilerplate.\n\n```java\n\u002F\u002F error-prone manual style\nBufferedReader br = null;\ntry {\n  br = Files.newBufferedReader(path);\n} finally {\n  if (br != null) br.close(); \u002F\u002F close() can throw and mask the real error\n}\n\n\u002F\u002F correct, concise, handles suppression\ntry (var br = Files.newBufferedReader(path)) { }\n```\n\nTry-with-resources closes in the right order, handles nulls, and records\nsuppressed exceptions — strictly better.\n",{"id":498,"difficulty":82,"q":499,"a":500},"rethrow-precise","What is more precise rethrow analysis (Java 7+)?","Since Java 7, the compiler analyzes which checked exceptions can **actually**\nflow out of a `try`, so you can catch a broad type but **rethrow with a\nnarrower `throws`** clause — as long as the caught variable is effectively\nfinal.\n\n```java\nvoid m() throws IOException, SQLException {  \u002F\u002F precise, not \"throws Exception\"\n  try {\n    if (cond) throw new IOException();\n    else throw new SQLException();\n  } catch (Exception e) {   \u002F\u002F catch broadly...\n    log(e);\n    throw e;                \u002F\u002F ...rethrow: compiler knows it's IOException|SQLException\n  }\n}\n```\n\nBefore Java 7 you'd have been forced to declare `throws Exception`. This lets you\nlog centrally while keeping precise method signatures.\n",{"id":502,"difficulty":82,"q":503,"a":504},"exception-in-static-init","What happens if an exception is thrown in a static initializer?","If a `static` initializer (or static field initialization) throws, the JVM wraps\nit in an **`ExceptionInInitializerError`** and the class **fails to initialize**.\nWorse, the class is marked unusable: any later attempt to use it throws\n**`NoClassDefFoundError`**.\n\n```java\nclass Config {\n  static final int VALUE = compute(); \u002F\u002F if compute() throws...\n  static int compute() { throw new RuntimeException(\"boom\"); }\n}\n\u002F\u002F First use -> ExceptionInInitializerError\n\u002F\u002F Subsequent uses -> NoClassDefFoundError\n```\n\nThis is a confusing failure mode in real systems — a misconfigured static\nconstant can make a class permanently unloadable. Keep static initialization\nsimple and defensive.\n",{"id":506,"difficulty":61,"q":507,"a":508},"logging-vs-throwing","Should you log and throw, or just one?","Doing **both** at every level causes \"log spam\" — the same exception printed\nrepeatedly as it propagates. The common rule: **either handle it (and log) OR\npropagate it (and let a higher layer log)** — not both at every level.\n\n```java\n\u002F\u002F log-and-throw at every layer -> duplicated stack traces\ncatch (IOException e) { log.error(\"failed\", e); throw e; }\n\n\u002F\u002F propagate now, log once at the top-level boundary\ncatch (IOException e) { throw new ServiceException(e); }\n\u002F\u002F ... and a single handler at the controller\u002Fedge logs it\n```\n\nLog **once**, at the boundary where the exception is finally handled (e.g. a\ncontroller advice or a top-level `catch`), with full context.\n",{"description":59},"Java exception handling interview questions — checked vs unchecked, the exception hierarchy, try\u002Fcatch\u002Ffinally, try-with-resources, custom exceptions, chaining, and common pitfalls like swallowing exceptions.","java\u002Fexceptions\u002Fexception-handling","wArz93b9NB6yDuB0xDMten2Mp8DtYbRC8psG-wPq3ak",{"id":514,"title":515,"body":516,"description":59,"difficulty":69,"extension":62,"framework":10,"frameworkSlug":8,"meta":520,"navigation":64,"order":13,"path":521,"questions":522,"related":205,"seo":655,"seoDescription":656,"stem":657,"subtopic":658,"topic":20,"topicSlug":21,"updated":210,"__hash__":659},"qa\u002Fjava\u002Ffundamentals\u002Fdata-types-variables.md","Data Types Variables",{"type":56,"value":517,"toc":518},[],{"title":59,"searchDepth":29,"depth":29,"links":519},[],{},"\u002Fjava\u002Ffundamentals\u002Fdata-types-variables",[523,527,531,535,539,543,547,551,555,559,563,567,571,575,579,583,587,591,595,599,603,607,611,615,619,623,627,631,635,639,643,647,651],{"id":524,"difficulty":69,"q":525,"a":526},"primitives-list","What are the eight primitive types in Java?","Java has exactly **eight** primitives, each with a fixed size and no methods:\n\n| Type | Size | Range \u002F notes |\n| ---- | ---- | ------------- |\n| `byte` | 8-bit | −128…127 |\n| `short` | 16-bit | −32,768…32,767 |\n| `int` | 32-bit | ~±2.1 billion (default for integer literals) |\n| `long` | 64-bit | very large; literal suffix `L` |\n| `float` | 32-bit | IEEE-754, suffix `f` |\n| `double` | 64-bit | IEEE-754 (default for decimal literals) |\n| `char` | 16-bit | a single UTF-16 code unit, `0`…`65535` |\n| `boolean` | JVM-defined | `true` \u002F `false` |\n\nPrimitives hold their value **directly** (on the stack or inline in an\nobject), unlike objects which are accessed through references. Everything else\nin Java — `String`, arrays, your classes — is a reference type.\n",{"id":528,"difficulty":69,"q":529,"a":530},"primitive-vs-wrapper","What is the difference between a primitive and its wrapper class?","Every primitive has an **object wrapper** in `java.lang`: `int`->`Integer`,\n`double`->`Double`, `char`->`Character`, `boolean`->`Boolean`, etc. The primitive\nstores a raw value; the wrapper is a full **object** on the heap that *contains*\nthe value plus object overhead (header, identity, can be `null`).\n\n```java\nint a = 5;              \u002F\u002F raw value, can never be null\nInteger b = 5;          \u002F\u002F object reference, can be null\nInteger c = null;       \u002F\u002F legal; int x = c; would throw NullPointerException\n```\n\nYou need wrappers wherever Java requires an object: generics\n(`List\u003CInteger>`, never `List\u003Cint>`), collections, and nullable fields.\nPrimitives are faster and lighter, so prefer them for arithmetic and hot loops.\n",{"id":532,"difficulty":61,"q":533,"a":534},"autoboxing","What are autoboxing and unboxing?","**Autoboxing** is the compiler automatically converting a primitive to its\nwrapper; **unboxing** is the reverse. It lets primitives and wrappers mix\nseamlessly — `Integer.valueOf(...)` \u002F `intValue()` calls are inserted for you.\n\n```java\nList\u003CInteger> nums = new ArrayList\u003C>();\nnums.add(5);            \u002F\u002F autobox: int 5 -> Integer.valueOf(5)\nint first = nums.get(0); \u002F\u002F unbox: Integer -> intValue()\n```\n\nThe hidden cost: unboxing a `null` wrapper throws **`NullPointerException`**,\nand boxing in a tight loop creates throwaway objects (GC pressure). A classic\ntrap is `Integer sum = 0; for (...) sum += x;` which boxes\u002Funboxes every\niteration — use a primitive `int` accumulator instead.\n",{"id":536,"difficulty":82,"q":537,"a":538},"integer-cache","Why does == sometimes return true and sometimes false for equal Integer values?","Because `==` on wrappers compares **references**, and Java **caches** boxed\n`Integer` objects for the range **−128 to 127** (the `IntegerCache`). Values in\nthat range return the *same* cached object; values outside it create new\nobjects each time.\n\n```java\nInteger a = 127, b = 127;\nSystem.out.println(a == b);   \u002F\u002F true  — same cached object\n\nInteger c = 128, d = 128;\nSystem.out.println(c == d);   \u002F\u002F false — two distinct objects\nSystem.out.println(c.equals(d)); \u002F\u002F true — value comparison\n```\n\nThe lesson interviewers want: **always compare wrapper values with\n`.equals()`** (or unbox to primitives), never `==`. The cache exists because\nsmall integers are extremely common, so reusing them saves allocations.\n",{"id":540,"difficulty":69,"q":541,"a":542},"equals-vs-eqeq","What is the difference between == and .equals() in Java?","`==` compares **references** for objects (do both variables point to the *same*\nobject?) and raw **values** for primitives. `.equals()` is a method that\ncompares **logical equality** — what \"equal\" means is defined by the class.\n\n```java\nString a = new String(\"hi\");\nString b = new String(\"hi\");\na == b        \u002F\u002F false — two different objects\na.equals(b)   \u002F\u002F true  — same characters\n\nint x = 5, y = 5;\nx == y        \u002F\u002F true  — primitive value comparison\n```\n\n`Object.equals` defaults to `==` (reference identity), so a class must\n**override** `equals` to get meaningful value comparison — `String`,\n`Integer`, and the collections all do.\n",{"id":544,"difficulty":61,"q":545,"a":546},"string-immutable","Why are Strings immutable in Java?","A `String`'s internal character data is `final` and never changes after\nconstruction; any \"modification\" returns a **new** `String`. Immutability buys\nseveral things: **safe sharing** in the string pool, **thread safety** without\nlocks, usability as **hash keys** (the hash can be cached and never goes\nstale), and **security** (a path\u002FURL can't be mutated after a check).\n\n```java\nString s = \"hello\";\ns.concat(\" world\");      \u002F\u002F creates a new String, discarded here\nSystem.out.println(s);   \u002F\u002F \"hello\" — s itself is unchanged\ns = s.concat(\" world\");  \u002F\u002F reassign the reference to the new String\n```\n\nThe trade-off is that heavy string building creates garbage — which is exactly\nwhy `StringBuilder` exists.\n",{"id":548,"difficulty":61,"q":549,"a":550},"string-pool","What is the String pool (string interning)?","The string pool is a special area where the JVM stores **one shared copy** of\neach distinct string **literal**. Two identical literals refer to the same\npooled object, saving memory. Strings made with `new` are *not* pooled — they\ncreate a fresh heap object — unless you call `.intern()`.\n\n```java\nString a = \"hi\";          \u002F\u002F pooled\nString b = \"hi\";          \u002F\u002F same pooled object\nString c = new String(\"hi\"); \u002F\u002F new heap object, NOT pooled\na == b           \u002F\u002F true\na == c           \u002F\u002F false\na == c.intern()  \u002F\u002F true — intern() returns the pooled copy\n```\n\nThis is why beginners hit bugs comparing strings with `==`: literals seem to\nwork (same pooled object) but `new`\u002Fcomputed strings don't. Always use\n`.equals()`.\n",{"id":552,"difficulty":61,"q":553,"a":554},"stringbuilder","What is the difference between String, StringBuilder and StringBuffer?","- **`String`** — immutable; every concatenation allocates a new object. Fine\n  for a few fixed pieces, wasteful in loops.\n- **`StringBuilder`** — a **mutable**, resizable character buffer. Not\n  synchronized, so it's fast; the right default for building strings.\n- **`StringBuffer`** — same API as `StringBuilder` but **synchronized**\n  (thread-safe), hence slower. Rarely needed today.\n\n```java\n\u002F\u002F O(n²) garbage — a new String each iteration\nString r = \"\";\nfor (String p : parts) r += p;\n\n\u002F\u002F one buffer, amortized O(n)\nStringBuilder sb = new StringBuilder();\nfor (String p : parts) sb.append(p);\nString r2 = sb.toString();\n```\n\nNote the compiler optimizes simple `a + b + c` into `StringBuilder` calls — the\nproblem is concatenation **inside loops**, where it can't.\n",{"id":556,"difficulty":82,"q":557,"a":558},"pass-by-value","Is Java pass-by-value or pass-by-reference?","Java is **always pass-by-value** — no exceptions. The subtlety is that for\nobjects, the *value being copied is the reference* (the pointer), not the\nobject. So a method can **mutate** the object the reference points to, but\n**reassigning** the parameter doesn't affect the caller's variable.\n\n```java\nvoid mutate(int[] arr) { arr[0] = 99; }   \u002F\u002F changes the caller's array\nvoid reassign(int[] arr) { arr = new int[]{0}; } \u002F\u002F no effect on caller\n\nint[] a = {1};\nmutate(a);    \u002F\u002F a is now {99}\nreassign(a);  \u002F\u002F a is still {99} — the copied reference was replaced locally\n```\n\nSay it crisply in an interview: \"Java passes references **by value**.\" The\nreference is copied; both copies point at the same object until one is\nreassigned.\n",{"id":560,"difficulty":69,"q":561,"a":562},"default-values","What are the default values of fields in Java?","**Instance and static fields** are automatically initialized to a zero value:\n`0` for numeric primitives, `false` for `boolean`, `\\u0000` (the null character) for `char`, and\n**`null`** for any reference type.\n\n```java\nclass Box {\n  int n;        \u002F\u002F 0\n  boolean ok;   \u002F\u002F false\n  String name;  \u002F\u002F null\n}\n```\n\nThe crucial exception: **local variables get no default**. The compiler\n*requires* you to assign one before use, or it's a compile error (\"variable\nmight not have been initialized\") — a deliberate guard against reading garbage.\n",{"id":564,"difficulty":61,"q":565,"a":566},"int-overflow","What happens on integer overflow in Java?","Integer arithmetic **wraps around silently** using two's-complement — no\nexception is thrown. Exceeding `Integer.MAX_VALUE` rolls over to\n`Integer.MIN_VALUE`.\n\n```java\nint max = Integer.MAX_VALUE;   \u002F\u002F 2_147_483_647\nSystem.out.println(max + 1);   \u002F\u002F -2147483648  (wraps, no error)\n\n\u002F\u002F common bug: this overflows before being assigned to long\nlong bad = 1_000_000 * 1_000_000;        \u002F\u002F -727379968\nlong good = 1_000_000L * 1_000_000;      \u002F\u002F 1000000000000 (promote first)\n```\n\nMitigations: promote to `long`, use `Math.addExact`\u002F`multiplyExact` (which\n*throw* `ArithmeticException` on overflow), or `BigInteger` for unbounded math.\n",{"id":568,"difficulty":61,"q":569,"a":570},"float-precision","Why is 0.1 + 0.2 not exactly 0.3 in Java?","`float` and `double` are **binary IEEE-754** floating point. Many decimal\nfractions (like `0.1`) have no exact binary representation, so they're stored\nas the nearest approximation and tiny errors accumulate.\n\n```java\nSystem.out.println(0.1 + 0.2);   \u002F\u002F 0.30000000000000004\nSystem.out.println(0.1 + 0.2 == 0.3); \u002F\u002F false\n```\n\nFor money or anything needing exact decimals, use **`BigDecimal`** (and\nconstruct it from a *String*, not a double):\n\n```java\nnew BigDecimal(\"0.1\").add(new BigDecimal(\"0.2\")); \u002F\u002F 0.3 exactly\n```\n\nNever compare floats with `==`; compare within a small epsilon instead.\n",{"id":572,"difficulty":69,"q":573,"a":574},"char-type","What is the char type and how does it relate to int?","`char` is a **16-bit unsigned** integer holding a single UTF-16 code unit\n(`'A'`, `'7'`, `'€'`). Because it's numeric under the hood, it participates in\narithmetic and auto-promotes to `int`.\n\n```java\nchar c = 'A';\nint code = c;            \u002F\u002F 65 (implicit widening)\nchar next = (char) (c + 1); \u002F\u002F 'B' (must cast back, since c+1 is int)\nSystem.out.println('a' + 'b'); \u002F\u002F 195, not \"ab\" — numeric addition!\n```\n\nA frequent gotcha: `'a' + 'b'` adds the code points, while `\"\" + 'a' + 'b'`\nconcatenates. Characters beyond the Basic Multilingual Plane (emoji) need two\nchars (a surrogate pair) or `int` code points.\n",{"id":576,"difficulty":61,"q":577,"a":578},"casting","What is the difference between widening and narrowing conversions?","**Widening** (smaller -> larger type, e.g. `int`->`long`->`double`) is safe and\n**implicit** — no data loss, no cast needed. **Narrowing** (larger -> smaller,\ne.g. `double`->`int`) can lose data, so it requires an **explicit cast** and you\naccept the truncation.\n\n```java\nint i = 100;\nlong l = i;          \u002F\u002F widening — automatic\ndouble d = i;        \u002F\u002F widening — automatic\n\ndouble pi = 3.99;\nint n = (int) pi;    \u002F\u002F narrowing — explicit; truncates to 3 (not rounded)\nbyte b = (byte) 300; \u002F\u002F narrowing — overflows to 44\n```\n\nNarrowing **truncates toward zero** for floating->integer (it doesn't round),\nand wraps for integer overflow — both common interview \"what prints?\" traps.\n",{"id":580,"difficulty":61,"q":581,"a":582},"var-keyword","What is the var keyword and what are its limits?","`var` (Java 10+) is **local variable type inference**: the compiler infers the\nstatic type from the initializer. It's still **statically typed** — `var` is\nnot a dynamic\u002F`Object` type — just less verbose.\n\n```java\nvar list = new ArrayList\u003CString>();  \u002F\u002F inferred ArrayList\u003CString>\nvar count = 10;                      \u002F\u002F int\nfor (var entry : map.entrySet()) { } \u002F\u002F inferred Map.Entry\u003C...>\n```\n\nRestrictions: only for **local variables with an initializer**. You **can't**\nuse `var` for fields, method parameters, return types, or without an\ninitializer (`var x;` is illegal), and `var x = null;` won't compile (no type\nto infer).\n",{"id":584,"difficulty":61,"q":585,"a":586},"final-keyword","What does the final keyword mean for variables?","A `final` variable can be **assigned only once**. For a primitive that fixes\nthe value; for a reference it fixes **which object** the variable points to —\nthe object itself can still be mutated.\n\n```java\nfinal int MAX = 10;     \u002F\u002F MAX = 11; would not compile\nfinal List\u003CString> xs = new ArrayList\u003C>();\nxs.add(\"ok\");           \u002F\u002F mutating the object is allowed\nxs = new ArrayList\u003C>(); \u002F\u002F reassigning the reference is not\n```\n\n`final` also applies to fields (must be set by the end of construction),\nmethod parameters, and is required for variables a lambda\u002Fanonymous class\ncaptures (they must be `final` or *effectively final*).\n",{"id":588,"difficulty":61,"q":589,"a":590},"static-vs-instance","What is the difference between static and instance variables?","A **static** (class) variable belongs to the **class** — there's exactly **one\ncopy** shared by all instances. An **instance** variable belongs to each\n**object** — every `new` gets its own copy.\n\n```java\nclass Counter {\n  static int total;   \u002F\u002F one shared across all Counters\n  int id;             \u002F\u002F one per instance\n  Counter() { id = ++total; }\n}\nnew Counter(); \u002F\u002F id=1, total=1\nnew Counter(); \u002F\u002F id=2, total=2  (total is shared)\n```\n\nAccess statics via the class name (`Counter.total`). Statics are initialized\nwhen the class is loaded and live for the program's lifetime, which is why\nmutable static state is a common source of bugs and memory leaks.\n",{"id":592,"difficulty":69,"q":593,"a":594},"literals","How do numeric literals and underscores work in Java?","Literals default to `int` (integers) and `double` (decimals); suffixes change\nthat: `L`\u002F`l` for `long`, `f`\u002F`F` for `float`, `d`\u002F`D` for `double`. You can\nalso write binary (`0b`), octal (`0`), and hex (`0x`) literals, and use\n**underscores** as digit separators for readability.\n\n```java\nlong big   = 10_000_000_000L;  \u002F\u002F L needed — exceeds int range\nfloat rate = 1.5f;\nint  mask  = 0xFF;             \u002F\u002F 255 in hex\nint  bits  = 0b1010;           \u002F\u002F 10 in binary\nint  million = 1_000_000;      \u002F\u002F underscores ignored by the compiler\n```\n\nForgetting the `L` on a large literal is a classic bug: `10_000_000_000` alone\nwon't compile because it overflows `int`.\n",{"id":596,"difficulty":69,"q":597,"a":598},"ternary","What is the ternary operator and a common pitfall with it?","The ternary `condition ? a : b` is an **expression** that evaluates to `a` when\nthe condition is true, else `b` — a compact `if\u002Felse` that returns a value.\n\n```java\nString label = (n % 2 == 0) ? \"even\" : \"odd\";\nint max = (a > b) ? a : b;\n```\n\nThe subtle trap is **type promotion \u002F unboxing** of the two branches: if one\nbranch is a primitive and the other a wrapper, the result is unboxed, so a\n`null` wrapper branch can throw `NullPointerException`:\n\n```java\nInteger x = null;\nObject o = true ? 0 : x;   \u002F\u002F fine\nint bad  = false ? 0 : x;  \u002F\u002F NPE — both branches unboxed to int\n```\n",{"id":600,"difficulty":69,"q":601,"a":602},"arrays-basics","How are arrays represented in Java?","An array is an **object** on the heap with a fixed length set at creation; the\nvariable holds a reference to it. Elements are stored contiguously and default\nto their zero value (`0`\u002F`false`\u002F`null`).\n\n```java\nint[] a = new int[3];        \u002F\u002F {0, 0, 0}\nint[] b = {1, 2, 3};         \u002F\u002F array initializer\nString[] names = new String[2]; \u002F\u002F {null, null}\nSystem.out.println(a.length);   \u002F\u002F 3 — a field, not a method\n```\n\nKey facts: `length` is a **field** (no parentheses), the size is **immutable**\nonce created (need a bigger array? allocate a new one or use `ArrayList`), and\nout-of-bounds access throws `ArrayIndexOutOfBoundsException`.\n",{"id":604,"difficulty":61,"q":605,"a":606},"multidim-arrays","How do multidimensional and jagged arrays work?","Java has no true 2D arrays — a `int[][]` is an **array of arrays**. That means\nrows can have different lengths (a **jagged** array), and each row is a separate\nheap object.\n\n```java\nint[][] grid = new int[2][3];   \u002F\u002F 2 rows, 3 cols each\ngrid[0][1] = 5;\n\nint[][] jagged = new int[2][];  \u002F\u002F rows allocated separately\njagged[0] = new int[]{1, 2};\njagged[1] = new int[]{3, 4, 5}; \u002F\u002F different length — legal\n```\n\nBecause rows are independent objects, iterating with `row.length` (not a fixed\ncolumn count) is the safe pattern.\n",{"id":608,"difficulty":61,"q":609,"a":610},"type-promotion","How does numeric promotion work in arithmetic expressions?","In arithmetic, operands smaller than `int` (`byte`, `short`, `char`) are first\n**promoted to `int`**, and if any operand is `long`\u002F`float`\u002F`double` the whole\nexpression is promoted to the widest type. This is why byte arithmetic returns\nan `int`.\n\n```java\nbyte a = 10, b = 20;\nbyte c = a + b;        \u002F\u002F won't compile — a + b is int\nbyte d = (byte)(a + b); \u002F\u002F cast back\n\nint i = 5;\ndouble e = i \u002F 2;      \u002F\u002F 2.0 — int division happens FIRST, then widens\ndouble f = i \u002F 2.0;    \u002F\u002F 2.5 — one double operand promotes the division\n```\n\nThe `5 \u002F 2 == 2` integer-division surprise is the most common version of this\nin interviews.\n",{"id":612,"difficulty":69,"q":613,"a":614},"null-keyword","What is null and what can and cannot be null in Java?","`null` is a special literal meaning a reference points to **no object**. Only\n**reference types** can be `null` — primitives cannot. Using a `null` reference\n(calling a method, accessing a field, unboxing) throws **`NullPointerException`**.\n\n```java\nString s = null;\ns.length();          \u002F\u002F NullPointerException\nint[] a = null;\nint n = a.length;    \u002F\u002F NPE\nInteger boxed = null;\nint x = boxed;       \u002F\u002F NPE — unboxing null\n```\n\n`null` is the same regardless of type, and `instanceof` on `null` is always\n`false`. Modern Java offers `Optional` and (Java 14+) **helpful NPE messages**\nthat name the exact variable that was null.\n",{"id":616,"difficulty":61,"q":617,"a":618},"object-class","What methods does every object inherit from Object?","Every class implicitly extends `java.lang.Object`, inheriting:\n\n- `equals(Object)` — logical equality (default: reference identity).\n- `hashCode()` — int hash, must be consistent with `equals`.\n- `toString()` — string form (default: `ClassName@hexHash`).\n- `getClass()` — runtime class object.\n- `clone()` — shallow copy (protected; needs `Cloneable`).\n- `wait()\u002Fnotify()\u002FnotifyAll()` — thread coordination on the object's monitor.\n- `finalize()` — deprecated cleanup hook.\n\n```java\nclass Point {\n  int x, y;\n  @Override public String toString() { return \"(\" + x + \",\" + y + \")\"; }\n}\n```\n\nYou'll most often override `equals`, `hashCode`, and `toString` — and the\nfirst two must be overridden **together** to honor their contract.\n",{"id":620,"difficulty":69,"q":621,"a":622},"scope-block","What is variable scope in Java?","A variable is visible only within the **block (`{ }`) it's declared in**, and\nceases to exist when that block ends. Inner blocks can see outer variables, but\nnot vice versa, and you can't redeclare a name that's already in scope.\n\n```java\nvoid m() {\n  int x = 1;\n  if (x > 0) {\n    int y = 2;        \u002F\u002F visible only inside this if\n    System.out.println(x + y);\n  }\n  \u002F\u002F y is out of scope here\n}\n```\n\nLoop variables (`for (int i ...)`) are scoped to the loop. Unlike fields, local\nvariables have **no default** and must be assigned before use.\n",{"id":624,"difficulty":61,"q":625,"a":626},"implicit-explicit-cast","When do you need an explicit cast for reference types?","Assigning a subclass reference to a superclass variable (**upcasting**) is\nimplicit and always safe. Going the other way (**downcasting**) needs an\nexplicit cast *and* is checked at runtime — a wrong cast throws\n`ClassCastException`.\n\n```java\nObject o = \"hello\";          \u002F\u002F upcast — implicit\nString s = (String) o;       \u002F\u002F downcast — explicit, succeeds\nInteger bad = (Integer) o;   \u002F\u002F compiles, but throws ClassCastException\n\nif (o instanceof String str) \u002F\u002F pattern matching (Java 16+) guards the cast\n    System.out.println(str.length());\n```\n\nGuard downcasts with `instanceof` (ideally the pattern form) to avoid runtime\nfailures.\n",{"id":628,"difficulty":69,"q":629,"a":630},"constants","How do you define a constant in Java?","The idiom is **`static final`** with an UPPER_SNAKE_CASE name. `static` means\none shared copy; `final` means it can't be reassigned. The compiler can inline\n`static final` primitive\u002F`String` constants for efficiency.\n\n```java\npublic class Config {\n  public static final int MAX_RETRIES = 3;\n  public static final String APP_NAME = \"Interviews\";\n}\n```\n\nNote `final` on a reference constant only freezes the reference, not the\nobject — `static final List\u003CString> X = new ArrayList\u003C>()` can still be mutated,\nso use `List.of(...)` or `Collections.unmodifiableList` for a truly constant\ncollection.\n",{"id":632,"difficulty":69,"q":633,"a":634},"wrapper-parsing","How do you convert between Strings and numbers?","Use the wrapper classes' static methods. `parseXxx` returns a **primitive**;\n`valueOf` returns a **wrapper object**. Going the other way, `String.valueOf`\nor concatenation produces text.\n\n```java\nint n      = Integer.parseInt(\"42\");     \u002F\u002F primitive int\nInteger w  = Integer.valueOf(\"42\");       \u002F\u002F Integer object\ndouble d   = Double.parseDouble(\"3.14\");\nString s   = String.valueOf(42);          \u002F\u002F \"42\"\nString s2  = \"\" + 42;                      \u002F\u002F \"42\" (concatenation)\n```\n\nA malformed string throws **`NumberFormatException`**, so wrap parsing of\nuntrusted input in a try\u002Fcatch or validate first.\n",{"id":636,"difficulty":61,"q":637,"a":638},"bitwise","What are the bitwise and shift operators in Java?","Java has `&` (AND), `|` (OR), `^` (XOR), `~` (NOT), and shifts `\u003C\u003C`, `>>`\n(signed\u002Farithmetic right shift), and `>>>` (unsigned\u002Flogical right shift, which\nfills with zeros).\n\n```java\n5 & 3    \u002F\u002F 1   (0101 & 0011)\n5 | 3    \u002F\u002F 7\n5 ^ 3    \u002F\u002F 6\n1 \u003C\u003C 4   \u002F\u002F 16  (multiply by 2^4)\n-8 >> 1  \u002F\u002F -4  (sign-preserving)\n-8 >>> 28 \u002F\u002F 15 (zero-filled — treats bits as unsigned)\n```\n\n`>>>` is unique to Java (no unsigned types) and is the trap: it's the only shift\nthat ignores the sign bit. Bitwise `&`\u002F`|` also work on `boolean` as\nnon-short-circuiting logical operators.\n",{"id":640,"difficulty":69,"q":641,"a":642},"enhanced-for","What is the enhanced for loop and its limitations?","The enhanced for (for-each) iterates any array or `Iterable` without an index,\nreading each element in turn.\n\n```java\nfor (String name : names) {\n  System.out.println(name);\n}\n```\n\nIts limits, often asked about: you **can't get the index**, you can't iterate\ntwo collections in lockstep, and you **can't modify the collection** during\niteration (it uses an iterator under the hood, so adding\u002Fremoving throws\n`ConcurrentModificationException`). Reassigning the loop variable also doesn't\nchange the underlying element — use a classic indexed `for` or an explicit\n`Iterator` for those cases.\n",{"id":644,"difficulty":69,"q":645,"a":646},"ternary-vs-if","What is the difference between an expression and a statement?","An **expression** evaluates to a value (`a + b`, `x > 0`, `obj.method()`); a\n**statement** is a complete instruction that performs an action (`if`, `for`,\nassignments, `return`). Expressions can be nested inside statements.\n\n```java\nint max = (a > b) ? a : b;   \u002F\u002F ternary is an EXPRESSION (has a value)\nif (a > b) { max = a; }      \u002F\u002F if is a STATEMENT (no value)\n```\n\nThis distinction explains why you can write `int x = a > b ? a : b;` but not\n`int x = if (...) ...;` — `if` produces no value. (Java's `switch` gained an\n*expression* form in Java 14 that does yield a value.)\n",{"id":648,"difficulty":69,"q":649,"a":650},"text-blocks","What are text blocks in Java?","Text blocks (Java 15+) are multi-line string literals delimited by triple\nquotes `\"\"\"`. They preserve line breaks and let you write JSON, SQL, or HTML\nwithout escaping quotes or concatenating lines.\n\n```java\nString json = \"\"\"\n    {\n      \"name\": \"Ada\",\n      \"role\": \"engineer\"\n    }\n    \"\"\";\n```\n\nIncidental leading whitespace is stripped based on the closing delimiter's\nindentation, and the result is just a normal `String` — so it still goes\nthrough the pool and supports all `String` methods.\n",{"id":652,"difficulty":69,"q":653,"a":654},"identifier-rules","What are the rules for valid Java identifiers?","An identifier may contain letters, digits, `_`, and `$`, but **can't start with\na digit**, can't be a **reserved keyword** (`class`, `int`, `for`…), and is\n**case-sensitive** (`count` ≠ `Count`). Unicode letters are allowed.\n\n```java\nint count, _total, $price, αβγ;  \u002F\u002F all legal\nint 2fast;   \u002F\u002F can't start with a digit\nint class;   \u002F\u002F reserved keyword\n```\n\nBy convention (not enforced): `camelCase` for variables\u002Fmethods,\n`PascalCase` for types, `UPPER_SNAKE_CASE` for constants, and `$` is left for\ngenerated code.\n",{"description":59},"Java data types and variables interview questions — primitives vs wrappers, autoboxing, Integer caching, String immutability and the pool, pass-by-value, casting and the var keyword.","java\u002Ffundamentals\u002Fdata-types-variables","Data Types & Variables","_N5UicxRw1mn1pojTIjQziRqx6EuAJ7Vz7sfDiCpglY",{"id":661,"title":662,"body":663,"description":59,"difficulty":61,"extension":62,"framework":10,"frameworkSlug":8,"meta":667,"navigation":64,"order":29,"path":668,"questions":669,"related":205,"seo":806,"seoDescription":807,"stem":808,"subtopic":809,"topic":20,"topicSlug":21,"updated":210,"__hash__":810},"qa\u002Fjava\u002Ffundamentals\u002Foop.md","Oop",{"type":56,"value":664,"toc":665},[],{"title":59,"searchDepth":29,"depth":29,"links":666},[],{},"\u002Fjava\u002Ffundamentals\u002Foop",[670,674,678,682,686,690,694,698,702,706,710,714,718,722,726,730,734,738,742,746,750,754,758,762,766,770,774,778,782,786,790,794,798,802],{"id":671,"difficulty":69,"q":672,"a":673},"four-pillars","What are the four pillars of object-oriented programming?","- **Encapsulation** — bundle data with the methods that operate on it and hide\n  internal state behind a public API (private fields + getters\u002Fsetters).\n- **Abstraction** — expose *what* an object does, hide *how*, via interfaces\n  and abstract classes.\n- **Inheritance** — a subclass reuses and extends a superclass's members\n  (`extends`).\n- **Polymorphism** — one reference type, many runtime forms; the actual\n  object's overridden method is called.\n\n```java\nclass Animal { String sound() { return \"...\"; } }\nclass Dog extends Animal { String sound() { return \"Woof\"; } } \u002F\u002F inheritance + override\nAnimal a = new Dog();   \u002F\u002F polymorphism\na.sound();              \u002F\u002F \"Woof\"\n```\n\nA good one-liner: encapsulation hides data, abstraction hides complexity,\ninheritance reuses behavior, polymorphism varies it.\n",{"id":675,"difficulty":69,"q":676,"a":677},"encapsulation","What is encapsulation and why does it matter?","Encapsulation means keeping fields **private** and exposing controlled access\nthrough methods, so an object protects its own invariants and you can change the\ninternals without breaking callers.\n\n```java\nclass Account {\n  private double balance;           \u002F\u002F hidden state\n  public void deposit(double amt) {\n    if (amt \u003C= 0) throw new IllegalArgumentException();\n    balance += amt;                 \u002F\u002F validated mutation\n  }\n  public double getBalance() { return balance; }\n}\n```\n\nBenefits: validation in one place, freedom to refactor representation, easier\ndebugging (state changes go through known methods), and thread-safety hooks. A\npublic mutable field gives up all of these.\n",{"id":679,"difficulty":69,"q":680,"a":681},"abstraction","What is abstraction and how is it achieved in Java?","Abstraction is exposing a **simplified contract** while hiding implementation\ndetail. In Java you achieve it with **interfaces** (pure contract) and\n**abstract classes** (partial implementation). Callers depend on the abstract\ntype, not the concrete class.\n\n```java\ninterface PaymentGateway { void charge(int cents); }\n\nclass StripeGateway implements PaymentGateway {\n  public void charge(int cents) { \u002F* API calls hidden here *\u002F }\n}\n\nPaymentGateway gw = new StripeGateway(); \u002F\u002F code depends only on the contract\n```\n\nThe payoff is decoupling: you can swap `StripeGateway` for `PayPalGateway`\nwithout touching the calling code — the basis of \"program to an interface.\"\n",{"id":683,"difficulty":69,"q":684,"a":685},"inheritance","What is inheritance and what does Java not allow?","Inheritance lets a subclass acquire the fields and methods of a superclass with\n`extends`, modeling an **is-a** relationship and enabling reuse + polymorphism.\n\n```java\nclass Vehicle { void start() { } }\nclass Car extends Vehicle { void honk() { } } \u002F\u002F Car is-a Vehicle\n```\n\nJava allows **single inheritance** of classes only — a class can extend exactly\none superclass (to avoid the \"diamond problem\"). It *can* implement **multiple\ninterfaces**, which is how Java gets multiple-type flexibility without\nmultiple class inheritance. `final` classes can't be extended at all.\n",{"id":687,"difficulty":61,"q":688,"a":689},"polymorphism","What is polymorphism and what are its forms?","Polymorphism = \"many forms.\" Java has two kinds:\n\n- **Runtime (dynamic) polymorphism** — method **overriding**. The JVM picks the\n  method based on the *actual object* at runtime (dynamic dispatch).\n- **Compile-time (static) polymorphism** — method **overloading**. The compiler\n  picks the method based on the *declared argument types*.\n\n```java\nAnimal a = new Dog();\na.sound();   \u002F\u002F runtime: Dog's override is chosen\n\nprint(5);    \u002F\u002F compile-time: print(int)\nprint(\"hi\"); \u002F\u002F compile-time: print(String)\n```\n\n\"Polymorphism\" in interviews usually means the runtime kind — the engine behind\n`List\u003CShape>` calling each shape's own `area()`.\n",{"id":691,"difficulty":61,"q":692,"a":693},"overloading-vs-overriding","What is the difference between overloading and overriding?","| | Overloading | Overriding |\n| --- | --- | --- |\n| What | Same name, **different parameters** | Subclass **replaces** a superclass method |\n| Signature | Must differ (type\u002Fcount) | Must be **identical** |\n| Bound | **Compile time** (static) | **Run time** (dynamic) |\n| Return type | Can differ | Same or covariant |\n\n```java\nclass Calc {\n  int add(int a, int b) { return a + b; }          \u002F\u002F overload 1\n  double add(double a, double b) { return a + b; }  \u002F\u002F overload 2\n}\nclass Base { void greet() { } }\nclass Sub extends Base { @Override void greet() { } } \u002F\u002F override\n```\n\nOverloading is about offering variations of an operation; overriding is about\nspecializing inherited behavior. Use `@Override` so the compiler verifies you\nactually overrode (and didn't accidentally overload).\n",{"id":695,"difficulty":61,"q":696,"a":697},"abstract-vs-interface","What is the difference between an abstract class and an interface?","- **Abstract class** — can have state (fields), constructors, and a mix of\n  concrete and abstract methods. A class extends **one**. Models an\n  *is-a* with shared implementation.\n- **Interface** — a contract; historically only abstract methods, now also\n  `default`\u002F`static`\u002F`private` methods, but **no instance state** (only\n  `public static final` constants). A class implements **many**.\n\n```java\nabstract class Shape {\n  private String name;            \u002F\u002F state allowed\n  abstract double area();         \u002F\u002F subclasses must implement\n  String describe() { return name + \": \" + area(); }\n}\ninterface Drawable { void draw(); default void hide() { } }\n```\n\nRule of thumb: use an **interface** for a capability multiple unrelated classes\ncan have (`Comparable`, `Runnable`); use an **abstract class** when subclasses\nshare state or implementation and form a tight family.\n",{"id":699,"difficulty":82,"q":700,"a":701},"inheritance-vs-composition","When should you favor composition over inheritance?","**Inheritance** (is-a) tightly couples a subclass to its parent's\nimplementation; changes to the base can silently break subclasses (the \"fragile\nbase class\" problem). **Composition** (has-a) builds behavior by *holding*\nother objects and delegating — looser coupling, more flexible.\n\n```java\n\u002F\u002F inheritance misused: a Stack is-a List? leaks all List methods\nclass Stack\u003CT> extends ArrayList\u003CT> { }\n\n\u002F\u002F composition: Stack HAS a list, exposes only stack operations\nclass Stack\u003CT> {\n  private final List\u003CT> items = new ArrayList\u003C>();\n  void push(T t) { items.add(t); }\n  T pop() { return items.remove(items.size() - 1); }\n}\n```\n\nGuideline (\"favor composition over inheritance\"): use inheritance only for a\ntrue is-a with a stable base designed for extension; otherwise compose. It also\nsidesteps single-inheritance limits.\n",{"id":703,"difficulty":61,"q":704,"a":705},"super-keyword","What does the super keyword do?","`super` refers to the **immediate superclass**. It does two jobs: call the\nparent **constructor** (`super(args)`, must be the first statement) and call an\n**overridden** parent method or access a parent field (`super.method()`).\n\n```java\nclass Animal {\n  Animal(String name) { }\n  void describe() { System.out.println(\"an animal\"); }\n}\nclass Dog extends Animal {\n  Dog(String name) {\n    super(name);              \u002F\u002F chain to parent constructor\n  }\n  @Override void describe() {\n    super.describe();         \u002F\u002F reuse parent behavior\n    System.out.println(\"...specifically a dog\");\n  }\n}\n```\n\nIf you don't call `super(...)` explicitly, the compiler inserts a no-arg\n`super()` — which fails to compile if the parent has no no-arg constructor.\n",{"id":707,"difficulty":69,"q":708,"a":709},"this-keyword","What does the this keyword refer to in Java?","`this` is a reference to the **current object**. Uses: disambiguate a field\nfrom a same-named parameter, call another constructor in the same class\n(`this(...)`, constructor chaining), and pass the current instance to other\nmethods.\n\n```java\nclass Point {\n  int x, y;\n  Point(int x, int y) {\n    this.x = x;          \u002F\u002F field vs parameter\n    this.y = y;\n  }\n  Point() { this(0, 0); } \u002F\u002F chain to the other constructor\n}\n```\n\n`this(...)` for constructor chaining, like `super(...)`, must be the first\nstatement — so you can't use both in one constructor.\n",{"id":711,"difficulty":69,"q":712,"a":713},"constructor","What is a constructor and what are its rules?","A constructor initializes a new object. It has the **class's name**, **no\nreturn type**, and runs when you use `new`. If you write none, the compiler\nsupplies a **default no-arg** constructor.\n\n```java\nclass User {\n  String name;\n  User() { this(\"anon\"); }      \u002F\u002F no-arg, chains\n  User(String name) { this.name = name; } \u002F\u002F parameterized\n}\n```\n\nRules interviewers probe: defining *any* constructor removes the free default\none; constructors can be overloaded; they're **not inherited** (but a subclass\nmust call one via `super`); and `private` constructors enable singletons and\nfactory-only construction.\n",{"id":715,"difficulty":61,"q":716,"a":717},"constructor-chaining","What is the order of execution when an object is constructed?","Construction runs **top-down** through the hierarchy:\n\n1. Static fields\u002Fblocks run **once** when the class first loads.\n2. On `new`: the superclass constructor runs first (via `super`), all the way\n   up to `Object`.\n3. Then instance field initializers and instance initializer blocks run.\n4. Then the rest of the subclass constructor body.\n\n```java\nclass A { A() { System.out.println(\"A ctor\"); } }\nclass B extends A {\n  int x = init();\n  int init() { System.out.println(\"B field\"); return 1; }\n  B() { System.out.println(\"B ctor\"); }\n}\n\u002F\u002F new B() prints: A ctor -> B field -> B ctor\n```\n\nA famous trap: calling an **overridable method from a constructor** runs the\nsubclass override *before* the subclass's fields are initialized — so it may see\n`null`\u002F`0`.\n",{"id":719,"difficulty":69,"q":720,"a":721},"access-modifiers","What are the four access modifiers in Java?","From most to least restrictive:\n\n- `private` — same class only.\n- *(default \u002F package-private)* — same package only (no keyword).\n- `protected` — same package **plus** subclasses (even in other packages).\n- `public` — everywhere.\n\n```java\npublic class Api {\n  private int secret;       \u002F\u002F class only\n  int packageScoped;        \u002F\u002F package\n  protected int forSubs;    \u002F\u002F package + subclasses\n  public int open;          \u002F\u002F everyone\n}\n```\n\nDefault the most restrictive that works (usually `private` fields) — it\nminimizes coupling. Note `protected` also grants package access, which surprises\npeople who think it's \"subclasses only.\"\n",{"id":723,"difficulty":61,"q":724,"a":725},"static-keyword","What does static mean for methods, fields and nested classes?","`static` binds a member to the **class** rather than an instance:\n\n- **static field** — one shared copy across all instances.\n- **static method** — called on the class, has **no `this`**, can't access\n  instance members directly (utility methods, factories).\n- **static nested class** — doesn't hold a reference to an outer instance.\n- **static block** — runs once at class load for static setup.\n\n```java\nclass MathUtil {\n  static final double PI = 3.14159;\n  static int square(int n) { return n * n; } \u002F\u002F MathUtil.square(5)\n}\n```\n\nBecause static methods aren't tied to an object, they **can't be overridden**\n(only *hidden*) and don't participate in runtime polymorphism.\n",{"id":727,"difficulty":61,"q":728,"a":729},"final-class-method","What does final mean for classes and methods?","- **`final` class** — cannot be extended (e.g. `String`, `Integer`). Locks the\n  design and lets the JIT optimize.\n- **`final` method** — cannot be overridden by subclasses; preserves critical\n  behavior.\n- **`final` field** — assign-once (constant once set).\n\n```java\nfinal class Constants { }          \u002F\u002F no subclassing\nclass Base {\n  final void critical() { }        \u002F\u002F subclasses can't override\n}\n```\n\nCommon reasons: immutability (a class meant to be immutable is often `final`),\nsecurity\u002Finvariant protection, and clarity of intent. It's the opposite of\n\"open for extension,\" so use it deliberately.\n",{"id":731,"difficulty":82,"q":732,"a":733},"equals-hashcode","What is the equals\u002FhashCode contract?","If you override `equals`, you **must** override `hashCode`, obeying:\n\n1. Equal objects (`a.equals(b)`) **must** have equal hash codes.\n2. `equals` must be reflexive, symmetric, transitive, and consistent.\n3. Unequal objects *may* share a hash code (collisions are allowed).\n\n```java\nclass Point {\n  final int x, y;\n  @Override public boolean equals(Object o) {\n    if (this == o) return true;\n    if (!(o instanceof Point p)) return false;\n    return x == p.x && y == p.y;\n  }\n  @Override public int hashCode() { return Objects.hash(x, y); }\n}\n```\n\nBreak the contract and **hash-based collections silently misbehave**: a\n`HashMap`\u002F`HashSet` may fail to find an object whose `hashCode` doesn't match\nits `equals`. Use `Objects.hash(...)` \u002F `Objects.equals(...)` to implement them.\n",{"id":735,"difficulty":69,"q":736,"a":737},"tostring","Why and how do you override toString?","The default `toString` returns `ClassName@hexHashCode` — useless in logs. Override\nit to return a readable representation, which is automatically used in string\nconcatenation, `println`, and debuggers.\n\n```java\nclass User {\n  String name; int age;\n  @Override public String toString() {\n    return \"User{name=\" + name + \", age=\" + age + \"}\";\n  }\n}\nSystem.out.println(new User()); \u002F\u002F User{name=null, age=0}\n```\n\nIt's purely for human-readable diagnostics — don't parse it programmatically.\nIDEs and `record`s can generate it for you.\n",{"id":739,"difficulty":61,"q":740,"a":741},"interface-default","What are default methods in interfaces and why were they added?","A **default method** provides a body inside an interface using the `default`\nkeyword. They were added in Java 8 so interfaces could **evolve** — e.g. adding\n`forEach` to `Iterable` — **without breaking** every existing implementer.\n\n```java\ninterface Greeter {\n  String name();\n  default String greet() { return \"Hello, \" + name(); } \u002F\u002F optional to override\n}\n```\n\nIf a class inherits conflicting defaults from two interfaces, it **must\noverride** to resolve the ambiguity (it can call `Iface.super.method()`).\nInterfaces can also have `static` and `private` helper methods now — but still\nno instance state.\n",{"id":743,"difficulty":61,"q":744,"a":745},"marker-interface","What is a marker interface?","A marker interface has **no methods** — it just *tags* a class so that code (or\nthe JVM) can detect a capability at runtime via `instanceof`. Classic examples:\n`Serializable`, `Cloneable`, `RandomAccess`.\n\n```java\nclass Config implements Serializable { } \u002F\u002F \"this class may be serialized\"\n```\n\nThe JVM checks `if (obj instanceof Serializable)` before serializing. Modern\nJava often prefers **annotations** for metadata, but marker interfaces still\ngive you compile-time type checking and `instanceof` support that annotations\ndon't.\n",{"id":747,"difficulty":61,"q":748,"a":749},"enum-basics","What are enums and what can they do beyond constants?","An `enum` defines a fixed set of named instances. Unlike `int` constants,\nenums are **type-safe**, can have **fields, constructors, and methods**, and\neach constant can even override behavior.\n\n```java\nenum Planet {\n  EARTH(9.81), MARS(3.71);\n  private final double gravity;\n  Planet(double g) { this.gravity = g; }   \u002F\u002F constructor\n  double weight(double mass) { return mass * gravity; }\n}\nPlanet.MARS.weight(70);  \u002F\u002F type-safe, behavior attached\n```\n\nEnums are implicitly `final` singletons (one instance per constant), work in\n`switch`, provide `values()`\u002F`valueOf()`\u002F`ordinal()`, and are the recommended\nway to implement singletons.\n",{"id":751,"difficulty":61,"q":752,"a":753},"record-class","What are records in Java?","A `record` (Java 16+) is a concise, **immutable** data carrier. From a one-line\ndeclaration the compiler generates a canonical constructor, `private final`\nfields, accessors, and `equals`\u002F`hashCode`\u002F`toString`.\n\n```java\nrecord Point(int x, int y) { }\n\nPoint p = new Point(1, 2);\np.x();                       \u002F\u002F accessor (no \"get\" prefix)\np.equals(new Point(1, 2));   \u002F\u002F true — value-based\n```\n\nThey're for transparent data aggregates (DTOs, value objects). Limits: records\nare `final`, can't extend a class (they implicitly extend `Record`), and all\nstate is in the header — you can still add a **compact constructor** for\nvalidation.\n",{"id":755,"difficulty":82,"q":756,"a":757},"nested-classes","What are the types of nested classes in Java?","- **Static nested class** — declared `static`; no link to an outer instance, a\n  namespaced helper.\n- **Inner (non-static) class** — holds an implicit reference to its enclosing\n  instance; can access its outer fields.\n- **Local class** — declared inside a method.\n- **Anonymous class** — an unnamed inner class created and instantiated at once.\n\n```java\nclass Outer {\n  static class Helper { }            \u002F\u002F static nested\n  class Inner { }                    \u002F\u002F inner — needs an Outer instance\n  Runnable r = new Runnable() {      \u002F\u002F anonymous\n    public void run() { }\n  };\n}\n```\n\nGotcha: a non-static inner class keeps the outer object alive (potential memory\nleak), so prefer `static` nested classes unless you actually need the enclosing\ninstance.\n",{"id":759,"difficulty":61,"q":760,"a":761},"object-equality-identity","What is the difference between identity, equality and equivalence?","- **Identity** — `a == b`: are they the *same object* in memory?\n- **Equality** — `a.equals(b)`: are they *logically the same value*, per the\n  class's definition?\n- Some classes also expose **ordering equivalence** via `compareTo == 0`.\n\n```java\nString a = new String(\"x\"), b = new String(\"x\");\na == b;            \u002F\u002F false (identity)\na.equals(b);       \u002F\u002F true  (equality)\n\nBigDecimal x = new BigDecimal(\"1.0\"), y = new BigDecimal(\"1.00\");\nx.equals(y);       \u002F\u002F false! (scale differs)\nx.compareTo(y) == 0; \u002F\u002F true  (numeric equivalence)\n```\n\n`BigDecimal` is the classic gotcha where `equals` and `compareTo` disagree.\n",{"id":763,"difficulty":82,"q":764,"a":765},"covariant-return","What is a covariant return type?","When overriding, the subclass method may return a **subtype** of the\nsuperclass method's return type — a covariant return. It lets overrides return\nmore specific types without a cast.\n\n```java\nclass Animal { Animal reproduce() { return new Animal(); } }\nclass Dog extends Animal {\n  @Override Dog reproduce() { return new Dog(); } \u002F\u002F narrower return — legal\n}\nDog puppy = new Dog().reproduce(); \u002F\u002F no cast needed\n```\n\nCommon in builder patterns and `clone()` overrides. (Parameters, by contrast,\nare *not* covariant — changing a parameter type makes it an overload, not an\noverride.)\n",{"id":767,"difficulty":82,"q":768,"a":769},"static-vs-dynamic-binding","What is the difference between static and dynamic binding?","**Static binding** is resolved by the compiler from the **declared type** —\nused for `static`, `private`, `final`, and overloaded methods, plus fields.\n**Dynamic binding** is resolved at runtime from the **actual object type** —\nused for overridden instance methods (virtual dispatch).\n\n```java\nclass A { static void s() { } void v() { } int f = 1; }\nclass B extends A { static void s() { } @Override void v() { } int f = 2; }\n\nA x = new B();\nx.v();   \u002F\u002F B.v()  — dynamic binding (overridden)\nx.s();   \u002F\u002F A.s()  — static binding (hidden, by declared type)\nx.f;     \u002F\u002F 1      — fields are static-bound, not polymorphic\n```\n\nKey insight: **fields and static methods are *hidden*, not overridden** — they\nbind to the declared type, which is a classic trick question.\n",{"id":771,"difficulty":82,"q":772,"a":773},"immutable-class","How do you design an immutable class?","Make the state impossible to change after construction:\n\n1. Mark the class `final` (no subclass can add mutability).\n2. Make all fields `private final`.\n3. Set everything in the constructor; provide **no setters**.\n4. **Defensively copy** mutable fields in and out (don't leak internal refs).\n\n```java\nfinal class Range {\n  private final int[] bounds;\n  Range(int[] bounds) { this.bounds = bounds.clone(); } \u002F\u002F copy in\n  int[] bounds() { return bounds.clone(); }             \u002F\u002F copy out\n}\n```\n\nImmutables are inherently **thread-safe**, cacheable, and safe as map keys —\n`String`, `Integer`, and `LocalDate` are all built this way.\n",{"id":775,"difficulty":61,"q":776,"a":777},"this-vs-super-ctor","Can a constructor call both this() and super()?","No. Both `this(...)` (chain to another constructor in the same class) and\n`super(...)` (chain to the parent) must be the **first statement** in a\nconstructor — and there can only be one first statement, so you use **at most\none** of them.\n\n```java\nclass Base { Base(int n) { } }\nclass Sub extends Base {\n  Sub() { this(5); }          \u002F\u002F delegates within Sub...\n  Sub(int n) { super(n); }    \u002F\u002F ...which then reaches super\n}\n```\n\nThe pattern is to funnel overloaded constructors through `this(...)` down to one\n\"primary\" constructor that finally calls `super(...)`.\n",{"id":779,"difficulty":61,"q":780,"a":781},"object-creation","What are the ways to create an object in Java?","- **`new`** — the normal path, invokes a constructor.\n- **Factory method** — e.g. `List.of()`, `Integer.valueOf()`, your own\n  `Builder.build()`.\n- **`Class.getDeclaredConstructor().newInstance()`** — reflection.\n- **`clone()`** — copy an existing object.\n- **Deserialization** — reconstruct from bytes (bypasses constructors).\n\n```java\nUser a = new User();                          \u002F\u002F new\nList\u003CInteger> b = List.of(1, 2);              \u002F\u002F factory\nUser c = User.class.getDeclaredConstructor().newInstance(); \u002F\u002F reflection\n```\n\nNote that reflection and deserialization can create objects **without running a\nconstructor**, which is why immutability\u002Fsingletons sometimes need extra guards.\n",{"id":783,"difficulty":69,"q":784,"a":785},"ducktyping-isa-hasa","What is the difference between an is-a and a has-a relationship?","- **is-a** -> inheritance. A `Car` *is a* `Vehicle` -> `class Car extends\n  Vehicle`.\n- **has-a** -> composition\u002Faggregation. A `Car` *has an* `Engine` -> the `Car`\n  holds an `Engine` field.\n\n```java\nclass Engine { }\nclass Car extends Vehicle {   \u002F\u002F is-a Vehicle\n  private final Engine engine = new Engine(); \u002F\u002F has-a Engine\n}\n```\n\nModeling tip: if you can't truthfully say \"X is a Y,\" don't use inheritance —\nreach for has-a (composition) instead. Misusing is-a (e.g. `Stack extends\nVector`) is a classic design smell.\n",{"id":787,"difficulty":82,"q":788,"a":789},"method-hiding","What is method hiding and how does it differ from overriding?","When a subclass declares a `static` method with the same signature as a parent\n`static` method, it **hides** rather than overrides it. The version called\ndepends on the **declared (compile-time) type**, not the runtime object — the\nopposite of overriding.\n\n```java\nclass A { static String who() { return \"A\"; } }\nclass B extends A { static String who() { return \"B\"; } }\n\nA ref = new B();\nref.who();   \u002F\u002F \"A\"  — static method, resolved by declared type (hiding)\n\u002F\u002F If who() were an instance method, this would be \"B\" (overriding)\n```\n\nBecause of this confusion, call static methods on the **class** (`A.who()`),\nnever through an instance reference.\n",{"id":791,"difficulty":61,"q":792,"a":793},"interface-vs-abstract-when","Can a class implement multiple interfaces with the same method?","Yes. If two interfaces declare the **same abstract** method, one implementation\nsatisfies both. But if they provide **conflicting `default`** methods, the class\n**must override** to break the tie, optionally delegating with\n`Interface.super.method()`.\n\n```java\ninterface A { default String hi() { return \"A\"; } }\ninterface B { default String hi() { return \"B\"; } }\n\nclass C implements A, B {\n  @Override public String hi() {\n    return A.super.hi();   \u002F\u002F explicitly choose A's default\n  }\n}\n```\n\nThis is Java's controlled answer to the multiple-inheritance \"diamond problem\":\nmultiple *types* are allowed, but conflicting *behavior* must be resolved\nexplicitly.\n",{"id":795,"difficulty":61,"q":796,"a":797},"polymorphism-collections","How does polymorphism enable programming to an interface?","By declaring variables and parameters as the **interface\u002Fsupertype**, your code\nworks with *any* implementation — the runtime calls the actual object's\nmethods. This decouples callers from concrete classes.\n\n```java\nvoid process(List\u003CString> items) { }   \u002F\u002F accepts ArrayList, LinkedList, List.of...\nList\u003CString> list = new ArrayList\u003C>();  \u002F\u002F swap impl freely\n\u002F\u002F list = new LinkedList\u003C>();           \u002F\u002F no caller changes needed\n```\n\n\"Program to an interface, not an implementation\" — depend on `List`, `Map`,\n`Collection`, not `ArrayList`\u002F`HashMap`. It makes code testable (inject fakes)\nand flexible (change implementations without ripple effects).\n",{"id":799,"difficulty":61,"q":800,"a":801},"cohesion-coupling","What are cohesion and coupling?","- **Cohesion** — how focused a class is on a single responsibility. **High\n  cohesion is good**: a `UserValidator` that only validates users.\n- **Coupling** — how dependent classes are on each other's internals. **Low\n  coupling is good**: classes interact through small, stable interfaces.\n\n```java\n\u002F\u002F low coupling: depends on an interface, not a concrete logger\nclass OrderService {\n  private final Logger log;            \u002F\u002F injected abstraction\n  OrderService(Logger log) { this.log = log; }\n}\n```\n\nThe goal of good OO design is **high cohesion, low coupling** — classes that do\none thing well and lean on each other as little as possible, which makes systems\neasier to change and test.\n",{"id":803,"difficulty":82,"q":804,"a":805},"solid","What do the SOLID principles stand for?","Five OO design principles for maintainable code:\n\n- **S** — Single Responsibility: a class has one reason to change.\n- **O** — Open\u002FClosed: open for extension, closed for modification.\n- **L** — Liskov Substitution: subtypes must be usable wherever their base is.\n- **I** — Interface Segregation: prefer small, specific interfaces over fat ones.\n- **D** — Dependency Inversion: depend on abstractions, not concretions.\n\n```java\n\u002F\u002F Dependency Inversion: high-level code depends on an interface\ninterface Repository { void save(Order o); }\nclass OrderService {\n  private final Repository repo;       \u002F\u002F not a concrete DB class\n  OrderService(Repository repo) { this.repo = repo; }\n}\n```\n\nLiskov is the one interviewers probe most: a subclass that throws on, or\nweakens, an inherited method (the `Square extends Rectangle` problem) violates\nit.\n",{"description":59},"Java OOP interview questions — the four pillars, inheritance vs composition, abstract classes vs interfaces, overloading vs overriding, polymorphism, the equals\u002FhashCode contract, records and enums.","java\u002Ffundamentals\u002Foop","Object-Oriented Programming","unDNeaf0bQsd2Gz0CAYtw3utDO8XyOVtZREhMpXE9oI",1781808672508]