Java and OOP Fundamentals

Question 1: Why use private fields with public getters/setters?

Encapsulation hides internal state and enforces controlled access. Getters/setters let objects manage their own data while enabling validation, formatting, or side effects when data is accessed or modified.

Question 2: Abstract Class vs Interface

Abstract classes allow partial implementation and are used when there’s a strong hierarchical “is-a” relationship.

Interfaces define a contract that classes agree to implement, supporting multiple inheritance of behavior.

Use an interface when behavior is shared but classes aren’t tightly related.

Question 3: What is Polymorphism?

Polymorphism allows objects to take many forms. It supports:

  • Overloading: same method name, different parameters (compile time)
  • Overriding: subclass redefines behavior of parent method (runtime)
  • Dynamic dispatch: correct method is chosen at runtime based on actual object type

Question 4: equals() and hashCode()

If you override equals(), always override hashCode().

equals() checks logical state, while hashCode() enables efficient lookup in hash-based structures like HashMap or HashSet.

Failing to override both can cause incorrect behavior in collections.

Question 5: final Keyword

  • final variable: cannot be reassigned
  • final method: cannot be overridden
  • final class: cannot be subclassed

Question 6: Composition vs Inheritance

Use composition when one object “has-a” relationship with another (e.g., a Car has an Engine).

Use inheritance for an “is-a” relationship (e.g., Car is a Vehicle).

Composition promotes flexibility and loose coupling.

Question 7: this Keyword

this refers to the current instance. It is used to disambiguate between fields and parameters or pass the current object to another method or constructor.

Question 8: == vs .equals()

  • == compares references (memory addresses)
  • .equals() compares content/state (when overridden)

For objects like String, use .equals() for value comparison.

Question 9: Checked vs Unchecked Exceptions

  • Checked (e.g., IOException): must be caught or declared
  • Unchecked (e.g., NullPointerException): runtime-only, optional to catch

Checked exceptions represent recoverable errors; unchecked indicate programming bugs.

Question 10: static Keyword

static means the member belongs to the class, not an instance.
Used for shared constants, utility methods, or static inner classes.

Top-level classes cannot be static.

Question 11: Library System Design (Example)

Use a Library class to manage a List<Book> or Map<String, List<Book>> to support:

  • Adding/removing books
  • Searching by title (case-insensitive)
  • Handling duplicate titles by grouping them under the same key

Normalize titles to lowercase for consistent lookups.

Question 12: What is Immutability?

An immutable class cannot have its internal state changed after creation.

To create one:

  • Use final fields
  • Make class final
  • No setters
  • Initialize via constructor
  • Return defensive copies of mutable fields

Java’s String class is immutable to support thread safety, caching, and security.

Question 13: Access Modifiers

ModifierSame ClassSame PackageSubclass (different package)Everywhere
publicYesYesYesYes
protectedYesYesYesNo
defaultYesYesNoNo
privateYesNoNoNo

Question 14: Reflection

Reflection allows runtime inspection and manipulation of classes, methods, fields, and constructors.

Useful for frameworks (e.g., Spring), serialization, and testing, but can break encapsulation and impact performance.

Question 15: Streams

Streams provide a declarative, functional-style API to process collections.

Support operations like filter, map, sorted, and collect.

  • Intermediate ops (lazy): map(), filter(), limit()
  • Terminal ops: collect(), forEach(), count(), findFirst()

Question 16: Lazy Evaluation

Stream operations are lazily evaluated. They’re only executed when a terminal operation triggers the pipeline.

This improves efficiency, enables short-circuiting, and avoids unnecessary work.

Question 17: Terminal Operations

Terminal operations are methods like collect(), findFirst(), and forEach() that trigger stream processing and return a result or cause a side effect.

Question 18: Optional Class

Optional<T> is a container that may or may not hold a non-null value. It’s used to avoid null checks and reduce NullPointerException risk.

Common methods:

  • isPresent()
  • ifPresent(Consumer)
  • orElse(), orElseGet(), orElseThrow()

Question 19: Functional Interfaces and Lambdas

A functional interface has a single abstract method.

Common examples:

  • Runnable
  • Callable
  • Comparator
  • Consumer
  • Function

Can be used with lambda expressions:

list.forEach(item -> System.out.println(item));

Question 20: Method References

A method reference is a shorthand for a lambda expression calling a method:

list.forEach(System.out::println);

Useful for cleaner code with known methods.

Question 21: try-with-resources

Introduced in Java 7.
Automatically closes resources like InputStreams and Readers that implement AutoCloseable:

try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    String line = br.readLine();
}

Question 22: Varargs

Allows methods to accept zero or more arguments of a specified type:

public void printAll(String... messages)

Treats varargs as an array internally.

Question 23: Enums

Enums represent a fixed set of constants. They can include fields, constructors, and methods.

Example:

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY
}

Question 24: Collections vs Arrays

  • Arrays have fixed size, store homogeneous elements
  • Collections (List, Set, Map) are resizable and flexible

Use List for ordering, Set for uniqueness, Map for key-value pairs.

Question 25: Generics

Allow classes and methods to operate on objects of various types:

List<String> list = new ArrayList<>();

Enhance type safety and eliminate casting.

Question 26: Common Java APIs

  • java.util: collections, date/time, utilities
  • java.io / java.nio: input/output and file handling
  • java.net: networking
  • java.lang: core language features

Question 27: Classloaders

ClassLoaders load Java classes into memory. Custom classloaders can define alternative loading behavior. Important in frameworks, containers, and modular apps.

Question 28: Garbage Collection

Java manages memory automatically using garbage collection. Objects without references are eligible for GC. You can suggest GC using System.gc(), but it is not guaranteed.

Question 29: Serialization

Serialization converts an object to a byte stream for storage/transmission. The class must implement Serializable. Use transient to exclude fields.

Question 30: Threading Basics

  • Thread creation via Thread or Runnable
  • Synchronization prevents race conditions
  • Executors provide thread pools
  • Use synchronized, volatile, and Lock for control
Thread t = new Thread(() -> {
    System.out.println("Hello from a thread");
});
t.start();