Company Questions in Java
Introduction
Technical interviews at top tech companies (often referred to as FAANG or MAANG) require a deep understanding of Java internals, memory management, and concurrency. Interviewers don't just want to know if you can write code; they want to know if you understand how the JVM executes your code.
This guide covers some of the most frequently asked Java-specific company interview questions, complete with expected answers and deep dives into the underlying architecture.
1. The String Pool and Immutability
Question: Why are Strings immutable in Java, and how does the String Pool work?
Answer: Strings are immutable in Java for several reasons:
- Security: Strings are widely used as parameters for network connections, database URLs, and file paths. If they were mutable, a hacker could change the path after authentication.
- Thread Safety: Because they cannot be changed, immutable objects are inherently thread-safe and can be shared across multiple threads without synchronization.
- Caching (The String Pool): To save memory, the JVM maintains a special memory region called the String Pool. When you create a String literal (e.g.,
String s = "hello";), the JVM checks if "hello" already exists in the pool. If it does, it returns the existing reference. This is only possible because Strings are immutable; if one reference changed the value, it would affect all other references pointing to the same literal.
String s1 = "Java";
String s2 = "Java";
String s3 = new String("Java");
System.out.println(s1 == s2); // true (same reference in String Pool)
System.out.println(s1 == s3); // false (s3 is a new object on the heap)
2. HashMap vs. ConcurrentHashMap
Question: How does a HashMap work internally, and why is ConcurrentHashMap better for multi-threaded environments?
Answer:
A HashMap stores data in an array of "buckets." Each bucket is a linked list (or a balanced tree in Java 8+ if collisions are high) of nodes containing key-value pairs. When put(key, value) is called, the key's hashCode() determines the array index.
However, HashMap is not thread-safe. If multiple threads resize the array simultaneously, it can lead to infinite loops (especially in Java 7 and older) or data corruption.
ConcurrentHashMap is designed for concurrency:
- In Java 7, it used Segment Locking (locking only a fraction of the map at a time).
- In Java 8+, it uses a Compare-And-Swap (CAS) mechanism and synchronizes only the specific node/bucket being updated, rather than locking the entire map. This allows multiple threads to read and write simultaneously with extremely high throughput.
3. Abstract Classes vs. Interfaces
Question: When would you choose an Abstract Class over an Interface in modern Java?
Answer: Historically (pre-Java 8), interfaces could only have abstract methods, while abstract classes could have state (instance variables) and concrete methods.
Since Java 8 introduced default methods in interfaces, the line has blurred, but the core differences remain:
- State: Abstract classes can hold instance variables (state). Interfaces can only have
public static finalconstants. - Multiple Inheritance: A class can implement multiple interfaces but can only extend one abstract class.
- Constructors: Abstract classes can have constructors; interfaces cannot.
When to use: Use an interface to define a contract or capability (e.g., Runnable, Serializable). Use an abstract class to provide a base foundation for closely related classes that share common state and logic (e.g., an abstract Vehicle class that manages an engineState variable).
4. Garbage Collection and Memory Leaks
Question: Can memory leaks happen in Java despite the Garbage Collector (GC)? How?
Answer: Yes, memory leaks can and do occur in Java. A memory leak in Java happens when objects are no longer needed by the application but are still referenced by something else, preventing the GC from reclaiming them.
Common causes include:
- Static Collections: A
static ListorMapthat continually grows over the application's lifecycle without elements being removed. - Unclosed Resources: Failing to close database connections or file streams.
- Inner Classes: Anonymous inner classes hold an implicit reference to their outer class. If the inner class is long-lived, the outer class cannot be garbage collected.
- ThreadLocal Variables: Using
ThreadLocalin thread pools (like Tomcat) without calling.remove(), causing old objects to persist across web requests.
5. The volatile Keyword
Question: What does the volatile keyword do, and how is it different from synchronized?
Answer:
In multi-threaded Java applications, each thread may cache variables in CPU registers or local memory for performance. The volatile keyword tells the JVM that a variable's value will be modified by different threads and should always be read from and written directly to main memory. This guarantees visibility.
However, volatile does not guarantee atomicity. For example, count++ is actually three operations (read, increment, write). If two threads do this simultaneously on a volatile variable, data can still be lost.
- Use
volatilefor simple flags (e.g.,boolean isRunning = true;). - Use
synchronizedorjava.util.concurrent.atomicclasses (likeAtomicInteger) when performing compound operations or when the new value depends on the old value.
Summary
Technical interviews test your foundational knowledge of how Java operates underneath the syntax. By understanding memory management, threading, and data structure internals, you can confidently answer the most difficult questions asked by top tech companies.