Skip to content

Java Fundamentals Flashcards

Java Fundamentals Flashcards

30 interactive flashcards spanning JVM internals to modern Java features. Press Space to flip, rate 1-4.


Additional Flashcard Topics

  • JVM Memory Model: heap (objects), stack (local variables), method area (class data). Garbage collection reclaims heap memory. Young/Old generation generational collection. The JVM uses mark-and-sweep algorithms to identify unreachable objects.

  • Generics: List<String> enforces type safety at compile time. Type erasure removes generic types at runtime. Wildcards: ? extends T (covariant), ? super T (contravariant). PECS: Producer Extends, Consumer Super.

  • Streams API: list.stream().filter(x -> x > 0).map(x -> x * 2).collect(Collectors.toList()). Functional-style operations on collections. Parallel streams use fork-join pool for automatic parallelisation.

  • Records (Java 16+): record Point(int x, int y) — immutable data carriers with auto-generated constructor, accessors, equals, hashCode, toString. Records are implicitly final and extend Record.

  • Sealed Classes (Java 17+): sealed class Shape permits Circle, Rectangle — restricted hierarchies enabling exhaustive pattern matching. Sealed classes restrict which classes can extend them.

  • Pattern Matching (Java 21+): switch (shape) { case Circle c -> ... } — pattern matching for switch eliminates explicit casts and null checks.

Intuition

Java is a class-based, object-oriented language that runs on the JVM — code compiles to platform-independent bytecode. The JVM handles memory management via garbage collection, so you don’t manually free memory. Java’s type system is statically checked at compile time, with single class inheritance but multiple interface implementation. Modern Java (8+) embraces functional programming with lambdas and streams. Java’s “write once, run anywhere” philosophy and massive ecosystem make it a perennial choice for enterprise applications. The JVM’s maturity and optimisation make Java performant for most workloads.

Common Pitfalls

  • equals/hashCode contract: Overriding equals() without overriding hashCode() breaks hash-based collections (HashMap, HashSet) — always override both together. The contract requires that equal objects have equal hash codes.
  • Autoboxing overhead: Java automatically converts between primitives and wrapper types (intInteger) — this creates unnecessary object allocations in loops, hurting performance. Use primitive types in performance-critical code.
  • Finalizer pitfalls: Using finalize() for cleanup is deprecated — it’s slow, unpredictable, and can cause resurrection of objects. Use try-with-resources and AutoCloseable instead.
  • ConcurrentModificationException: Modifying a collection while iterating over it (e.g., for (Item i : list) list.remove(i)) throws CME. Use Iterator.remove() or removeIf().
  • Null vs Optional: Java has both null and Optional<T>. Optional is not serializable and should not be used as fields — use it only for return types to indicate possible absence.

Cross-References