Easy Questions (Conceptual Basics)
General Core Java
1. What is the JDK, JRE, and JVM?
• JVM (Java Virtual Machine) is the runtime engine. It's responsible for
running the compiled Java bytecode. This is what makes Java "Write Once,
Run Anywhere," as the JVM is specific to the operating system.
• JRE (Java Runtime Environment) is what you need to run a Java
application. It contains the JVM plus the core Java libraries (like [Link],
[Link], etc.).
• JDK (Java Development Kit) is what you need to develop Java
applications. It includes everything in the JRE, plus the compiler (javac),
debugger, and other development tools.
2. What are the main principles of Object-Oriented Programming (OOP)?
There are four main principles:
1. Encapsulation: Binding data (variables) and the methods that act on that
data together as a single unit (a class). Data is kept private, and access is
controlled through public methods (getters/setters).
2. Inheritance: A mechanism where one class (subclass) acquires the
properties and behaviors of another class (superclass). It promotes code
reuse.
3. Polymorphism: The ability of an object to take on many forms. A parent
class reference can point to a child class object. This allows a single action,
like a method call, to be performed in different ways (method overriding).
4. Abstraction: Hiding complex implementation details and showing only the
essential features of an object. This is achieved using abstract classes and
interfaces.
3. What is the difference between an int and an Integer?
• int is a primitive data type. It's not an object, it stores the actual binary
value, and it cannot be null. It's more memory-efficient.
• Integer is a wrapper class (an object). It wraps the int value into an object.
This allows it to be used in contexts that require objects, like in Collections
(ArrayList<Integer>), and it can be null.
4. What is a static variable in Java?
A static variable is a class-level variable. It is shared among all instances
(objects) of that class. There is only one copy of a static variable, no matter how
many objects are created from that class.
5. What is the difference between == and the .equals() method?
• == is an operator. For primitives (like int), it compares the values. For
objects, it compares the memory addresses (i.e., it checks if two references
point to the exact same object).
• .equals() is a method from the Object class. Its default behavior is the same
as ==. However, classes like String and Integer override it to compare the
contents or state of the objects.
6. What is method overloading vs. method overriding?
• Overloading is in the same class. It's when two or more methods have the
same name but different parameters (different type, number, or order of
parameters). This is resolved at compile-time.
• Overriding is in a subclass. It's when a subclass provides a specific
implementation for a method that is already defined in its superclass. The
method signature (name and parameters) must be the same. This is resolved
at runtime.
7. What is an interface?
An interface is a blueprint for a class. It defines a contract of abstract methods
that a class must implement. It's used to achieve 100% abstraction and multiple
inheritance of type. Since Java 8, interfaces can also contain default and static
methods.
8. What is an abstract class?
An abstract class is a class that cannot be instantiated on its own. It's designed to
be subclassed. It can contain both abstract methods (methods without a body) and
concrete methods (methods with a body). It's used to provide a common base for
related subclasses.
9. Can you have an abstract class without any abstract methods?
Yes. You can declare a class abstract even if it has no abstract methods. This is
done to prevent the class from being instantiated directly, forcing developers to
use one of its subclasses.
10. What is the final keyword used for?
The final keyword can be used in three ways:
• final variable: Its value cannot be changed once assigned. It's a constant.
• final method: It cannot be overridden by a subclass.
• final class: It cannot be extended or subclassed.
Exception Handling (Easy)
11. What is an exception?
An exception is an event that occurs during program execution that disrupts the
normal flow of instructions. It's an object that represents an error condition,
which can be "thrown" by a method and "caught" and handled by another.
12. What is the difference between an Error and an Exception?
Both are subclasses of Throwable.
• An Error represents a serious, unrecoverable problem that an application
should not try to catch, like OutOfMemoryError or StackOverflowError.
These are usually caused by the JVM itself.
• An Exception represents a condition that an application can and should try
to catch and handle, like FileNotFoundException or NullPointerException.
13. What is the purpose of the try, catch, and finally keywords?
• try: This block surrounds the code that might throw an exception.
• catch: This block "catches" and handles a specific type of exception if one
is thrown in the try block.
• finally: This block always executes, whether an exception was thrown or
not. It's used for cleanup code, like closing a file or a database connection,
to ensure resources are released.
14. What is the Throwable class?
The Throwable class is the root class of Java's exception hierarchy. Only objects
that are instances of this class (or its subclasses, Error and Exception) can be
thrown by the JVM or by a throw statement.
15. What is the difference between checked and unchecked exceptions?
• Checked Exceptions: These are exceptions that the compiler checks at
compile-time. You must handle them with a try-catch block or declare them
with the throws keyword. They represent external conditions (e.g.,
IOException).
• Unchecked Exceptions: These are exceptions that the compiler does not
check at compile-time. They occur at runtime and typically represent
programming errors (e.g., NullPointerException,
ArrayIndexOutOfBoundsException). They all inherit from
RuntimeException.
16. Give an example of a checked exception.
IOException, SQLException, or FileNotFoundException.
17. Give an example of an unchecked exception.
NullPointerException, ArithmeticException (like divide-by-zero), or
ArrayIndexOutOfBoundsException.
18. What does the throws keyword do?
The throws keyword is used in a method signature. It declares that the method
might throw one or more checked exceptions, passing the responsibility of
handling them to the calling method.
19. What does the throw keyword do?
The throw keyword is used inside a method to explicitly create and throw an
exception object. For example: throw new RuntimeException("This is an
error");.
20. Can a try block exist without a catch block?
Yes, but it must have a finally block. A try block must be followed by either at
least one catch block or one finally block (or both).
Collection Framework (Easy)
21. What is the Collection framework in Java?
It's a unified architecture for storing and manipulating groups of objects. It
provides a set of interfaces (like List, Set, Map) and concrete implementation
classes (like ArrayList, HashSet, HashMap) to handle data efficiently.
22. What is the root interface of the Collection framework?
The root interface for most collections is the Collection interface. (Note: Map is
considered part of the framework but does not extend Collection.)
23. What is the difference between Collection and Collections?
• Collection (with an 'o-n') is an interface. It's the root interface for data
structures like List and Set.
• Collections (with an 's') is a utility class. It provides static helper methods
for operating on collections, such as [Link](),
[Link](), or [Link]().
24. What are the main interfaces in the Collection framework?
The three main interfaces are:
• List: An ordered collection that allows duplicate elements.
• Set: An unordered collection that does not allow duplicate elements.
• Map: An object that maps unique keys to values (not a true Collection).
25. What is an ArrayList?
It's the resizable array implementation of the List interface. It's fast for random
access (getting an element by index) but slower for adding or removing elements
from the middle.
26. What is a LinkedList?
It's the doubly-linked list implementation of the List interface. It's fast for adding
and removing elements from the beginning or end, but slow for random access.
27. What is a HashSet?
It's the implementation of the Set interface that uses a HashMap internally. It
provides constant-time performance for add and contains operations and does not
allow duplicates. It makes no guarantees about the order of elements.
28. What is a HashMap?
It's the implementation of the Map interface that stores key-value pairs using a
hash table. It provides very fast (constant-time) put and get operations. It allows
one null key and multiple null values, and it does not guarantee order.
29. Does a List allow duplicate elements?
Yes.
30. Does a Set allow duplicate elements?
No.
31. What is an Iterator?
An Iterator is an object used to traverse (loop through) the elements in a
collection, one by one. It provides methods like hasNext(), next(), and remove().
32. What is the difference between an Array and an ArrayList?
• Array: Is fixed-size. Its size cannot be changed after creation. It can store
both primitives and objects.
• ArrayList: Is dynamic and resizable. It can grow and shrink at runtime. It
can only store objects (it uses wrapper classes for primitives, like Integer
for int).
Moderate Questions (Practical Application)
General Core Java
33. Explain the public static void main(String[] args) method signature.
• public: It's an access modifier, making the method visible to the JVM so it
can start the program.
• static: It means the method belongs to the class, not an object. The JVM can
call this method without creating an instance of the class first.
• void: This is the return type. It means the main method doesn't return any
value.
• main: This is the name of the method, which the JVM specifically looks for
as the entry point.
• String[] args: This is the parameter. It's an array of String objects that
allows you to pass command-line arguments to your program.
34. What is the difference between String, StringBuilder, and StringBuffer?
• String: Is immutable. Every time you modify it (like concatenating), a
new String object is created. This is inefficient for many modifications.
• StringBuilder: Is mutable. It allows you to modify the string without
creating a new object each time. It is not thread-safe, making it the fastest
option for string manipulation in a single thread.
• StringBuffer: Is mutable and thread-safe. Its methods are synchronized.
This makes it slower than StringBuilder but safe to use in a multi-threaded
environment.
35. Why is the String class immutable in Java?
There are several key reasons:
1. String Pool: Java stores string literals in a "String Pool." If multiple
references point to the same string ("Hello"), immutability ensures that one
reference can't change the value for all the others.
2. Security: Immutable strings are safe to use as parameters for sensitive
operations like file paths, database connections, or network URLs. A
method cannot change the original value.
3. Hashing: Because strings are immutable, their hash code can be calculated
once, cached, and reused. This makes them very efficient as keys in a
HashMap.
36. What is the this keyword?
The this keyword is a reference to the current object—the instance on which the
method was called. It's typically used to disambiguate between instance variables
and local parameters (e.g., [Link] = name;).
37. What is the super keyword?
The super keyword is a reference to the parent class (superclass) object. It's
used to call a superclass's constructor (e.g., super(name);) or to call a superclass's
overridden method (e.g., [Link]();).
38. What is the default value of local variables?
Local variables (variables declared inside a method) do not have a default
value. You must explicitly initialize them before using them, or the code will not
compile. (Instance variables, on the other hand, do get default values like 0, false,
or null).
39. Explain the contract between hashCode() and equals().
This contract is crucial for collections like HashMap and HashSet.
1. If two objects are equal according to the equals() method, then they must
have the same hashCode().
2. If two objects have the same hashCode(), they are not required to be equal.
(This is a hash collision).
Simply put: If [Link](b) is true, then [Link]() == [Link]() must
also be true.
Exception Handling (Moderate)
40. What happens if an exception is thrown in a try block and there is no
matching catch block?
The finally block (if present) is executed. Then, the exception is propagated up
the call stack to the calling method. If it's not caught there, it continues up the
stack. If it reaches the main method and isn't caught, the program terminates and
prints the stack trace.
41. Will the finally block always execute? Name a situation where it might
not.
The finally block will almost always execute. The only common situations where
it won't execute are:
1. If the JVM is terminated by a call to [Link]().
2. If the JVM crashes due to a fatal, unrecoverable Error (like a
StackOverflowError so deep it can't even run the finally block).
42. What is exception propagation?
This is the process where an unhandled exception "bubbles up" the call stack
from the method where it was thrown to the method that called it, and so on, until
a matching catch block is found or the program terminates.
43. How do you create a custom exception?
You create a custom exception by extending one of the existing exception
classes.
• Extend Exception to create a checked exception.
• Extend RuntimeException to create an unchecked exception.
You just need to provide a constructor that calls the super(message) constructor.
Java
class InvalidAgeException extends RuntimeException {
public InvalidAgeException(String message) {
super(message);
}
}
44. What is the difference between throw and throws?
• throw: This is an action. It is used inside a method to explicitly throw an
instance of an exception.
• throws: This is a declaration. It is used in the method signature to declare
that the method might throw a checked exception.
45. What is the try-with-resources statement? What interface must a
resource implement to be used with it?
This statement (from Java 7) automatically closes resources after the try block is
finished. It eliminates the need for a finally block just to call [Link]().
Any resource used in a try-with-resources statement must implement the
AutoCloseable interface.
46. Can you have a return statement in a catch block? What happens to the
finally block?
Yes, you can. The finally block will still execute after the catch block decides
what value to return, but before the method actually returns that value.
47. What is exception chaining?
This is the practice of catching an exception, wrapping it in a new, more specific
or relevant exception, and then throwing the new exception. The original
exception is passed as the "cause" to the new exception's constructor. This is
great for adding context to an error.
48. What is the difference between final, finally, and finalize()?
• final: A keyword used to make a variable a constant, a method un-
overridable, or a class un-inheritable.
• finally: A block used in exception handling. It always executes and is used
for cleanup code.
• finalize(): A method from the Object class. It is called by the Garbage
Collector before an object is destroyed. Its use is strongly discouraged and
it has been deprecated; it's unreliable.
49. What happens if you have a return statement in both the try and finally
blocks?
The value from the finally block will be returned. The finally block's return
statement overwrites any return value from the try or catch block. This is
considered very bad practice as it can also suppress exceptions.
50. Can you re-throw an exception from a catch block?
Yes. You can catch an exception, perform some action (like logging), and then re-
throw the same exception using throw e; to let it propagate up the call stack for
further handling.
Collection Framework (Moderate)
51. Explain the hierarchy of the Collection framework.
• At the top is the Iterable interface.
• Collection extends Iterable.
• List, Set, and Queue are the three main interfaces that extend Collection.
• Map is a separate interface and does not extend Collection.
52. What is the difference between ArrayList and LinkedList? When would
you use each?
• ArrayList uses a dynamic array. It's fast for random access (O(1) for
get(index)). It's slow for inserts/deletes in the middle (O(n)) because it has
to shift elements.
• LinkedList uses a doubly-linked list. It's slow for random access (O(n)).
It's fast for inserts/deletes at the beginning, end, or middle (O(1)) if you
already have a reference to the node.
• Use ArrayList when you have more read/search operations than writes.
• Use LinkedList when you have a high number of inserts and deletes,
especially at the start or end of the list.
53. What is the difference between HashSet and TreeSet?
• Ordering: HashSet is unordered. TreeSet is sorted in natural order (or by
a Comparator).
• Performance: HashSet is faster (O(1) average for add/contains) because it
uses a hash table. TreeSet is slower (O(log n)) because it uses a Red-Black
Tree.
• null values: HashSet allows one null element. TreeSet does not allow null
elements because it needs to compare them, which would cause a
NullPointerException.
54. How does a HashSet store elements and ensure uniqueness?
A HashSet is backed by a HashMap internally.
1. When you call [Link](element), it calculates the hashCode() of the
element.
2. It uses this hash to find a "bucket" in the HashMap.
3. If a collision occurs (other elements are in that bucket), it uses the equals()
method to check if the element already exists.
4. If equals() returns false for all elements in that bucket, it adds the new
element. This hashCode/equals combination is how it guarantees
uniqueness.
55. What is the difference between HashMap and Hashtable?
• Thread-Safety: HashMap is not synchronized (not thread-safe).
Hashtable is synchronized (all its methods are thread-safe).
• null values: HashMap allows one null key and multiple null values.
Hashtable allows no null keys or null values.
• Performance: HashMap is faster. Hashtable is slower due to
synchronization overhead.
• Usage: Hashtable is a legacy class and should be avoided. If thread-safety
is needed, ConcurrentHashMap is the modern, high-performance
alternative.
56. What is the difference between Iterator and ListIterator?
• Scope: Iterator can be used on any Collection (Set, List, Queue).
ListIterator can only be used with Lists.
• Direction: Iterator only moves forward. ListIterator is bidirectional; it can
move forward (next()) and backward (previous()).
• Operations: ListIterator can also add() and set() (replace) elements during
iteration.
57. What is the difference between fail-fast and fail-safe iterators?
• Fail-fast: These iterators throw a ConcurrentModificationException if the
underlying collection is modified structurally (add/remove) by any means
other than the iterator's own remove() method. Iterators for ArrayList and
HashMap are fail-fast.
• Fail-safe: These iterators work on a snapshot or a clone of the collection.
They do not throw this exception because they are iterating over a copy.
Iterators for CopyOnWriteArrayList and ConcurrentHashMap are fail-safe.
58. What is the Comparable interface?
The Comparable interface is used to define the natural ordering for a class. The
class itself implements this interface and defines the compareTo() method. For
example, String implements Comparable to sort alphabetically.
59. What is the Comparator interface?
The Comparator interface is used to define a custom or external ordering. You
create a separate class that implements Comparator and defines the compare(o1,
o2) method. This is used when you want to sort objects in different ways (e.g.,
sort Employee by name, then by salary).
60. How would you sort an ArrayList of custom objects?
Two ways:
1. Have the custom object (e.g., Employee) implement the Comparable
interface and define compareTo(). Then just call [Link](list).
2. Create a separate Comparator class (e.g., SortEmployeeByName). Then,
pass an instance of it to the sort method: [Link](list, new
SortEmployeeByName()). (In Java 8+, you'd use a lambda expression).
61. How does a HashMap work internally? (Explain put() and get())
• put(key, value):
1. It calculates the [Link]() and uses it to find an index ("bucket")
in its internal array.
2. If the bucket is empty, it stores the new (key, value) pair as a Node.
3. If the bucket is not empty (a collision), it iterates through the Nodes
in that bucket (which are stored as a linked list or, since Java 8, a
balanced tree).
4. It uses equals() to check if the key already exists. If yes, it overwrites
the old value. If no, it adds the new (key, value) pair to the end of the
list/tree.
• get(key):
1. It calculates the hashCode() to find the correct bucket.
2. It iterates the list/tree in that bucket, using equals() to find the Node
with the matching key.
3. If found, it returns the value. If not found, it returns null.
62. What is a hash collision in HashMap, and how is it handled?
A hash collision is when two different keys produce the same hash code, or their
hash codes map to the same array index.
HashMap handles this using separate chaining. It stores all the colliding key-
value pairs in a data structure at that single array index. This starts as a linked
list. Since Java 8, if this linked list grows too long (beyond 8), it converts into a
Red-Black Tree to improve performance from O(n) to O(log n) for lookups in
that bucket.
63. Can you add a null key or null value to a HashMap?
Yes. HashMap allows one null key and multiple null values.
64. Can you add a null element to a TreeSet or TreeMap?
No. TreeSet and TreeMap store elements in sorted order. To do this, they must
compare elements. If you try to add null, they will try to call compareTo() on it,
which results in a NullPointerException.
65. What is the load factor of a HashMap, and what is its default value?
The load factor is a measure of how full the HashMap is allowed to get before its
capacity is automatically increased (this is called "rehashing").
• The default load factor is 0.75 (or 75%).
• This means when the number of entries exceeds 75% of the capacity, the
HashMap will create a new, larger array (usually double the size) and re-
hash all existing entries.
66. What is the difference between Set and Map?
• A Set is a collection of unique values (e.g., {"apple", "banana"}).
• A Map is a collection of key-value pairs (e.g., {"fruit": "apple", "color":
"red"}).
• You can think of a Set as just the "key" part of a Map.
67. What is a PriorityQueue?
It's a queue that orders elements based on their natural ordering or a Comparator.
When you poll() an element, you always get the smallest element (or "highest
priority" element) according to that order, not necessarily the one that was added
first.
68. What is the Queue interface? Name one implementation.
The Queue interface represents a collection for holding elements prior to
processing, typically in a FIFO (First-In, First-Out) order. A common
implementation is LinkedList (which also implements List).
69. What is the Deque interface?
Deque stands for "Double-Ended Queue." It's a queue that allows you to add or
remove elements from both the head (front) and the tail (end). LinkedList and
ArrayDeque are common implementations.
70. How can you make a collection read-only?
You can use the utility methods in the Collections class, such as
[Link](myList), [Link](mySet), or
[Link](myMap). These return a read-only "view" of the
collection. Any attempt to modify it will throw an
UnsupportedOperationException.
Difficult Questions (Advanced & Tricky)
General Core Java
71. What is the Java Memory Model (JMM)?
The JMM defines the rules and guarantees for how threads interact with main
memory. It specifies when and how changes made by one thread (in its local
cache) become visible to other threads. It ensures memory consistency across
different hardware and defines the behavior of keywords like volatile,
synchronized, and final.
72. Explain Garbage Collection (GC) in Java.
GC is Java's automatic memory management. The Garbage Collector is a
background process that reclaims memory from objects that are no longer
"reachable"—meaning there are no active references pointing to them. This
prevents most memory leaks and frees developers from manual memory
deallocation.
73. What is the difference between a shallow copy and a deep copy?
• Shallow Copy: Copies only the top-level object. If the object contains
references to other objects, only the references are copied, not the objects
themselves. Both the original and the copy will point to the same nested
objects.
• Deep Copy: Creates a copy of the object and recursively copies all objects
it references. The copy is completely independent of the original.
74. What is a volatile variable?
The volatile keyword guarantees visibility. It ensures that any read of that
variable will see the most recent write to it by any thread, and any write is
flushed to main memory immediately. It does not guarantee atomicity (e.g., i++
is not thread-safe even if i is volatile).
75. What is the transient keyword?
The transient keyword is used during Serialization. When you mark a variable as
transient, you are telling the Java serialization mechanism to skip this variable.
Its value will not be saved and will be restored as its default (e.g., null or 0)
during deserialization. It's used for sensitive data or fields that can be
recalculated.
Exception Handling (Difficult)
76. What happens if an exception is thrown inside a finally block?
If an exception was already thrown in the try or catch block and is pending, that
original exception is discarded. The new exception from the finally block is the
one that propagates up the call stack. This is dangerous because it hides the
original root cause.
77. What is a "suppressed" exception?
This was introduced in Java 7 with try-with-resources to solve the problem of
exceptions in finally blocks.
If an exception is thrown in the try block, the close() method is still called. If
close() also throws an exception, this second exception does not overwrite the
first. Instead, it is "suppressed" and attached to the original exception. You can
retrieve it by calling [Link]().
78. What is the difference between ClassNotFoundException and
NoClassDefFoundError?
• ClassNotFoundException (an Exception): This is a checked exception.
It's thrown at runtime when you explicitly try to load a class by name using
[Link](), but the class file cannot be found on the classpath.
• NoClassDefFoundError (an Error): This is an Error. It's thrown by the
JVM when a class was present during compilation, but the JVM cannot find
it at runtime. This often happens because of a missing JAR, or if the class's
static initializer block threw an exception, making the class un-loadable.
79. What is an OutOfMemoryError? Is it an Exception or an Error? How
would you handle it?
It is an Error. It's thrown by the JVM when it cannot allocate any more memory.
You should not try to catch it, as the application is in an unstable state. The only
"handling" is to let the application crash, analyze the heap dump to find the
memory leak, and fix the code, or increase the heap size (-Xmx).
80. What is a StackOverflowError? How can you cause one?
This is also an Error. It's thrown when a thread's call stack becomes too deep.
The most common cause is infinite recursion—a method that calls itself
endlessly without a proper base case.
81. If a method in a superclass declares throws IOException, can the
overriding method in the subclass declare throws Exception? What about
throws FileNotFoundException?
• throws Exception? No. An overriding method cannot throw a broader or
new checked exception than the superclass method.
• throws FileNotFoundException? Yes. An overriding method can throw a
narrower (subclass) checked exception, or no checked exception at all.
(FileNotFoundException is a subclass of IOException).
82. Explain the "unreachable catch block" compiler error.
This is a compile-time error. It occurs when you order catch blocks from
general to specific. Java requires you to catch exceptions from most specific to
most general. If you put catch (Exception e) before catch (IOException e), the
IOException block is "unreachable" because the Exception block already caught
it.
Collection Framework (Difficult)
83. Why does the Map interface not extend the Collection interface?
The Collection interface's contract is built around a "bag" of single elements
(add(E element)). The Map interface's contract is fundamentally different; it's
built around key-value pairs (put(K key, V value)). A Map is not a collection of
elements; it's a mapping. Making it extend Collection would have been a
confusing and "lossy" API design.
84. What is a ConcurrentHashMap, and how does it provide thread-safety?
It's a high-performance, thread-safe Map. Instead of using a single lock for the
entire map (like Hashtable), it uses a technique called lock striping. It divides
the map into internal segments or "buckets," and each bucket has its own lock.
One thread writing to one bucket only locks that bucket, allowing other threads
to read and write to other buckets simultaneously. Read operations (get()) are
generally non-locking and very fast.
85. How is ConcurrentHashMap different from
[Link](new HashMap())?
• Locking: synchronizedMap wraps the HashMap in a single lock. Only one
thread can access it at a time for any operation (read or write).
ConcurrentHashMap uses finer-grained lock striping, allowing many
threads to operate at once.
• Performance: ConcurrentHashMap has vastly superior performance and
concurrency. synchronizedMap becomes a major bottleneck in multi-
threaded applications.
86. What is a CopyOnWriteArrayList? When is it useful, and what are its
drawbacks?
It's a thread-safe List that achieves thread-safety by creating a new copy of the
underlying array every time a modification (add, set, remove) occurs.
• Use Case: It is extremely useful when reads are very frequent and writes
are very rare.
• Benefits: Reads are lock-free and very fast. Its iterator is fail-safe.
• Drawbacks: It is very expensive for writes. A single add has to copy the
entire array, which is O(n).
87. What is a BlockingQueue? Explain a use case.
It's a thread-safe Queue that blocks when the queue is in a certain state.
• put(E element): Adds an element, but if the queue is full, the thread waits.
• take(): Removes an element, but if the queue is empty, the thread waits.
• Use Case: It's the perfect data structure for the Producer-Consumer
problem. One thread (Producer) puts items, and another thread (Consumer)
takes them. The queue handles all the synchronization.
88. What is a WeakHashMap? How is it different from a HashMap?
In a normal HashMap, the map holds a strong reference to its keys, meaning they
will never be garbage collected.
In a WeakHashMap, the keys are stored as WeakReferences. If a key object is no
longer referenced anywhere else in the application, it becomes eligible for
garbage collection. The WeakHashMap will then automatically remove that
entry. It's used for caching or storing metadata that should be automatically
cleaned up when the main object is GC'd.
89. If you don't override hashCode() for a custom object used as a key in a
HashMap, what will happen?
The default [Link]() method will be used, which is based on the
object's memory address. This means that even if two objects are logically equal
according to your .equals() method (e.g., two Employee objects with the same
ID), they will have different hash codes. As a result, you won't be able to retrieve
the value using a new, "equal" key. The HashMap will not work correctly.
90. If two objects are .equals(), must their hashCode() be the same?
Yes, absolutely. This is the first rule of the hashCode/equals contract.
91. If two objects have the same hashCode(), must they be .equals()?
No, not necessarily. This is a hash collision. Two different objects can happen to
have the same hash code. This is why HashMap also uses equals() to confirm the
key is a true match.
92. How does the remove() method work in a HashMap?
It works just like get(). It calculates the hashCode() to find the correct bucket,
then iterates the list/tree in that bucket, using equals() to find the matching key. If
it finds a Node where the key is equal, it removes that Node from the list/tree and
returns the associated value.
93. What is an EnumSet?
It's a specialized Set implementation designed exclusively for enum types.
Internally, it's represented as a bit vector (a long). Each bit corresponds to one
enum constant. This makes it extremely fast and memory-efficient.
94. How is the TreeSet backed internally?
A TreeSet is backed by a TreeMap. When you call [Link](element), it's actually
calling [Link](element, DUMMY_VALUE). The TreeMap is what stores the
elements as keys in a sorted Red-Black Tree.
95. What is generics in the Collection framework? What is type erasure?
• Generics: (e.g., List<String>) They provide compile-time type safety.
They allow the compiler to check that you are only adding the correct type
of object to a collection, preventing ClassCastExceptions at runtime.
• Type Erasure: This is how generics are implemented. The type information
(like <String>) is erased from the bytecode after compilation. At runtime,
the JVM only sees a raw List. The compiler inserts the necessary type casts
for you automatically. This was done to ensure backward compatibility.
96. What is a ReentrantLock? How is it different from a synchronized
block?
Both provide thread-safety and are "reentrant" (a thread can re-acquire a lock it
already holds).
• synchronized is a keyword built into the language. It's simple, and the lock
is automatically released.
• ReentrantLock is a class. It's more flexible. It allows you to tryLock()
(acquire with a timeout), check if a lock is held, and create "fair" locks
(granting the lock to the longest-waiting thread). You must manually
unlock() in a finally block.
97. What is [Link]()? How is it different from new
ArrayList<>()?
• new ArrayList<>(): Creates a new, mutable ArrayList object. You can add
elements to it.
• [Link](): Returns a singleton, immutable empty list. Every
call returns the same static object. You cannot add elements to it. It's more
memory-efficient when you need to return an empty list from a method.
98. What is the Stream API (Java 8)? How does it relate to collections?
A Stream is a sequence of elements that supports aggregate operations.
• It is not a data structure; it's a "pipeline" that processes data from a source
(like a Collection).
• Operations are lazy (like filter() or map()) and don't run until a "terminal"
operation (like collect()) is called.
• Collections are the most common source for streams. You call
[Link]() to get a stream, process it, and then collect it back into a
new collection.
99. Explain the difference between forEach as a loop and the
[Link]() method.
• for-each loop: This is external iteration. You control the iteration, pulling
one element at a time. It is inherently sequential. for (String s : myList) { ...
}
• [Link](): This is internal iteration. You pass it a lambda (a
block of code), and the stream controls how and when to apply that code.
This internal control is what allows the stream to be processed in parallel.
100. How would you design a data structure that supports insert, delete,
search, and getRandom in O(1) time?
You need to combine two data structures:
1. An ArrayList to store the values. This gives O(1) getRandom (using
[Link](randomIndex)) and O(1) average-time insert (at the end).
2. A HashMap<V, Integer> that maps the value to its index in the ArrayList.
This gives O(1) average-time search.
The tricky part is delete(value), which must also be O(1):
1. Get the index of the value to delete from the map.
2. Get the last element from the list.
3. Move the last element to the index of the element you're deleting:
[Link](index, lastElement).
4. Update the map for the element you just moved: [Link](lastElement,
index).
5. Remove the original value from the map.
6. Remove the last element from the list (which is now a duplicate).
This avoids shifting elements in the ArrayList, making the delete operation O(1).