interviewpath
  • 0day streak
  • 10total XP
  • Level 1

Focus mode

Java essentials

Read alongside

Dev.java: Learn Java: The Collections Framework

Collection interfaces and implementations; continue with the Type Erasure, Records and Virtual Threads tutorials listed under this resource.

Objectives

  • Choose among ArrayList, ArrayDeque, HashMap, LinkedHashMap, TreeMap and PriorityQueue for a task and state the cost of the operations used.
  • Implement equals and hashCode consistently, or use a record, and explain what breaks when a key is mutated after insertion into a HashMap.
  • Explain type erasure and its consequences: no runtime generic type tests, no generic array creation, and the role of bounded wildcards.
  • Use ExecutorService, CompletableFuture, ConcurrentHashMap and atomic classes instead of raw threads, and explain what volatile does and does not guarantee.
  • Describe heap versus stack, generational garbage collection and how memory leaks arise in a garbage-collected language.

Why it matters

Choosing Java for an interview signals that you write production-style Java. The common failures are semantic rather than syntactic: a HashMap key whose hash changes after insertion, a counter made "thread-safe" with volatile, a generic method that assumes type information exists at runtime, or a cache that leaks because its entries stay reachable.

Core ideas

  • Collections. Program to interfaces (List, Map, Deque). ArrayList gives O(1) indexed access; ArrayDeque is the usual stack and queue; HashMap has expected O(1) operations and no order; LinkedHashMap keeps insertion or access order, which makes a simple LRU cache; TreeMap keeps keys sorted with O(log n) operations and range queries; PriorityQueue is a binary heap ordered by natural order or a comparator. Iterators of the general-purpose implementations are fail-fast on a best-effort basis: a structural change during iteration usually throws ConcurrentModificationException.
  • equals and hashCode. Equal objects must have equal hash codes, and both should depend only on fields that do not change while the object sits in a hash-based collection. == compares references, so compare boxed numbers and strings with equals. Records generate consistent equals, hashCode and toString from their components.
  • Generics and erasure. Type arguments exist only at compile time; at runtime List<String> and List<Integer> share one class. You cannot test instanceof List<String>, create new T[n], or overload methods that differ only in type arguments. Use ? extends T for parameters you only read from and ? super T for parameters you only write to.
  • Immutability. final stops reassignment of a field, not mutation of the object it refers to. Immutable classes (final fields, no setters, defensive copies, or records with immutable components) are easy to share between threads. List.of builds an unmodifiable list; Collections.unmodifiableList is a read-only view of a list that can still change underneath.
  • Concurrency. Prefer executors to hand-managed threads, CompletableFuture for composing asynchronous results, and ConcurrentHashMap, AtomicLong or LongAdder for shared state. Since Java 21, virtual threads make thread-per-task code cheap for blocking I/O. volatile guarantees visibility and ordering of individual reads and writes but does not make count++ atomic; synchronized and the java.util.concurrent locks provide mutual exclusion plus happens-before edges.
  • JVM memory. Objects live on the garbage-collected heap; each thread's stack holds frames with local primitives and references. HotSpot's collectors are generational because most objects die young, and G1 is selected by default on most configurations. A Java leak is an object that stays reachable but is no longer needed, such as entries in a static map or listeners never removed.

Common misconceptions

  • "volatile makes increments thread-safe." Each read and write is visible, but count++ is still a read-modify-write race; use an atomic class or a lock.
  • "final means immutable." It fixes the reference, not the state of the referenced object.
  • "Generic types are checked at runtime." They are erased; raw types and unchecked casts can put a wrong element into a collection, which then fails with a ClassCastException far from the cause.
  • "Garbage collection prevents memory leaks." It reclaims only unreachable objects; reachable but useless objects accumulate.

How to approach it

Write small programs that demonstrate each failure (a mutated HashMap key, a lost update under volatile) and then fix them. Mid-level and senior backend conversations may extend into thread-pool sizing, CompletableFuture error handling and garbage-collection pauses.

Self-check before you finish

  1. When would you choose TreeMap over HashMap?
  2. What goes wrong if two equal objects have different hash codes?
  3. Why can you not write new T[10] in a generic class?
  4. What does ? super T allow you to do with a parameter?
  5. Is a final List<String> field immutable?
  6. What makes an object eligible for garbage collection?