This interview guide is for educational and informational purposes only. It is designed to help readers prepare, but it does not guarantee any interview result, hiring decision, offer, or outcome. Interview questions, hiring criteria, and preferred answers can vary by employer, interviewer, industry, location, and time. The examples and explanations reflect the authors' research and judgment, are provided without warranties of any kind, and should not be treated as the only correct approach. Diagrams are simplified illustrations intended to highlight the main components and their interactions; actual systems and implementations may be more complex. Alternative approaches may be equally valid or better suited to a particular question, context, or interviewer. To the fullest extent permitted by applicable law, the author, contributors, and publisher are not liable for decisions made, actions taken, or losses incurred based on this guide.
Identity, Image, and Privacy Notice
To respect individual privacy, some names, profile photographs, avatars, biographical details, and other identifying information displayed in this guide may be replaced with pseudonyms, licensed stock images, illustrative avatars, composite images, or representative descriptions. Unless a person is expressly identified as an actual contributor, a displayed name, image, or profile should not be understood as depicting or identifying a specific candidate, interviewer, employee, or other real individual. These representations are provided for editorial and illustrative purposes only and do not imply endorsement, employment, participation, or affiliation with this guide or any company mentioned in it. Any resemblance to an actual person is coincidental.
Company Notice
This guide is an independent educational resource and is not affiliated with, endorsed by, sponsored by, or approved by the company named in this guide. Company names are used only to identify interview experiences commonly reported by candidates. Interview practices can change without notice, and inclusion of company-specific content does not mean these questions are official, complete, or guaranteed to be asked. To the fullest extent permitted by law, the author, contributors, and publisher are not responsible for outcomes related to use of this material.
Questions or comments?
Contact us for general questions, or share feedback, technical corrections, and comments with the community.
21. What are access modifiers?Language SpecificEasy
i Question Details
Explain public, protected, default, and private access modifiers and what each one allows.
Short Interview Answer (30-60 seconds)
Access modifiers control where a Java class, constructor, field, method, or nested type can be used. Public gives the widest access. Protected allows access from the same package and from subclasses, with a special rule for subclasses in another package. Writing no modifier gives package access. Private limits access to the enclosing top level class or interface. In production code, I start with private and widen access only when the design requires it.
Detailed Explanation
Access modifiers are visibility rules. They decide which parts of a program may use another part. These rules help developers show only what other code needs and hide details that should remain internal. This makes programs safer to change because fewer places can depend on hidden details. Java provides four access levels. Each level allows a different group of code to use the declared item. The correct choice depends on whether the item should be available everywhere, within one package, through inheritance, or only inside its owner.
Useful Questions to Ask the Interviewer
Should I explain access for top level types as well as their members?
Should I include access between different packages?
Should I explain the special protected rule for subclasses in another package?
How to Explain It in an Interview
Java has four access levels: public, protected, package access, and private. Package access is selected by writing no access modifier.
Public gives the widest Java language access. A public member may be used from another class only when the declaring type is also accessible. In a named module, the package may also need to be exported to the module containing the caller.
Protected allows access from every class in the same package. It also allows access from a subclass in another package. In that second case, access is granted through inheritance. The subclass cannot freely access the protected member through an arbitrary object whose type is the parent class.
Package access allows use only by code in the same package. It is useful for helper types and members that several classes in one package share but outside code should not use.
Private is the narrowest level. A private member is accessible only within the body of the top level class or interface that encloses its declaration. This includes its nested types. Java compilers and the JVM support this access without requiring the developer to expose the member publicly.
A top level class or interface can be public or have package access. It cannot be protected or private. Members and nested types may use all four access levels.
The modifier itself does not allocate objects, copy values, or change asymptotic performance. Its purpose is access control. A strong production rule is to choose the narrowest level that still supports the required collaboration.
Why Interviewers Ask This
Interviewers ask this question to check whether a candidate understands how Java controls access between classes, packages, and subclasses. It also tests whether the candidate can protect implementation details, expose a clear interface, and choose the narrowest access level that supports the design.
Common interview mistakes
Common mistakes include calling package access an explicit modifier even though it is created by writing no modifier. Another mistake is assuming protected means subclasses only, because every class in the same package also receives access. Candidates may also assume that a subclass in another package can access a protected member through any parent object. Java does not allow that. Other mistakes include declaring a top level type as protected or private, making every member public, and assuming a public member is usable when its declaring type or package is not accessible.
Interview tip
Explain the four levels from widest to narrowest. Then mention that protected includes same package access and has a special inheritance rule across packages. Finish by stating that production code should use the narrowest access level that supports the required design.
Interviewer may ask next
Can a subclass in another package access a protected member through any object of the parent class?
No. A subclass in another package receives protected access through inheritance. Inside that subclass, the protected member may be accessed through the current object or through an expression whose type is that subclass or one of its subclasses. It cannot be accessed through an arbitrary parent class object. This matters because protected does not create general access outside the declaring package.
What is the tradeoff between public access and narrower access in production code?
Public access makes a type or member available to more callers and may be necessary for a supported interface. The tradeoff is that callers can depend on it, which increases coupling and makes future changes harder. Private or package access preserves implementation freedom but may require a deliberate public method or interface when another component has a valid need.
22. What does the final keyword do in Java?Language SpecificEasy
i Question Details
Explain how final affects variables, methods, and classes.
Short Interview Answer (30-60 seconds)
The final keyword prevents a variable from being assigned again, prevents a method from being overridden, and prevents a class from being extended. For an object reference, final stops the reference from pointing to another object, but it does not stop changes inside a mutable object. I use final when a value, reference, method implementation, or class design should not be replaced.
The final keyword tells Java that a variable, method, or class has a restriction that later code cannot remove. For a variable, it stops another assignment after the first valid assignment. For a method, it stops a child class from replacing the inherited implementation. For a class, it stops another class from extending it. This makes the intended design clearer and prevents some accidental changes. However, final does not always make data completely unchangeable. Its exact effect depends on whether it is applied to a primitive value, an object reference, a parameter, a method, or a class.
Useful Questions to Ask the Interviewer
Should I explain final local variables, fields, and parameters?
Should I compare a final reference with an immutable object?
Should I include the rules for final methods and final classes?
How to Explain It in an Interview
The final keyword creates a Java language restriction.
A final variable can be assigned only once. A final local variable may receive its value when declared or later, but Java must prove that every use happens after one definite assignment and that no second assignment occurs. A final parameter receives its value when the method is called and cannot be assigned again inside that method.
A final instance field may have a field initializer, an instance initializer, or an assignment in every constructor path. A final static field may have a field initializer or an assignment in a static initializer.
For a primitive variable, final prevents replacing the primitive value. For an object reference, final prevents assigning a different reference. It does not make the object immutable. A final ArrayList reference can still be used to add or remove elements because the list itself remains mutable.
A final method may be inherited, but a subclass cannot override it. The method may still be overloaded with a different parameter list. A final class cannot be extended.
Final normally adds no separate object allocation, copying, or meaningful memory cost. It is mainly a compile time language rule. Final instance fields also receive special initialization visibility guarantees under the Java Memory Model when the object is constructed correctly and does not escape during construction. This does not make a mutable object thread safe.
Use final to communicate stable assignments, protect required method behavior, and prevent unsupported inheritance. Do not use it as a substitute for immutability, synchronization, or careful class design.
Interviewers ask this question to check whether a candidate understands reassignment, inheritance, and object mutability in Java. They also want to see whether the candidate can distinguish a final reference from an immutable object and use final for clear and safe production design.
Common interview mistakes
A common mistake is saying that a final object cannot change. Final protects the variable that stores the reference, not the mutable object behind it. Another mistake is saying that every final variable must be assigned on its declaration line. A blank final variable may be assigned later when Java can prove that it is assigned exactly once. Developers may also confuse final with finally or finalize, which have different meanings. Final does not automatically provide deep immutability, thread safety, or a performance improvement. A private method cannot be overridden because it is not inherited, so final adds no useful overriding protection to that method.
Interview tip
Explain final in three parts. A final variable cannot be assigned again, a final method cannot be overridden, and a final class cannot be extended. Then state the key limitation that a final reference does not make a mutable object immutable.
Interviewer may ask next
Can an object change when the variable that refers to it is final?
Yes. Final prevents the reference variable from being assigned a different object, but it does not freeze the referenced object. A final ArrayList can still add, remove, or replace elements because ArrayList is mutable. This matters because reference stability and object immutability are different guarantees. Use an immutable type or a carefully designed unmodifiable view when the contents must not change.
Does final improve performance or reduce memory use?
No general performance or memory improvement is guaranteed. Final normally does not allocate another object, copy the referenced object, or reduce its memory size. It mainly enforces a language restriction and communicates design intent. The compiler or JVM may use final information during optimization, but production code should use final for correctness, clarity, and controlled inheritance rather than depend on a measurable speed improvement.
23. What does the static keyword do in Java?Language SpecificEasy
i Question Details
Explain how static members belong to the class rather than an instance.
Short Interview Answer (30-60 seconds)
The static keyword makes a member belong to the class instead of to each object. A static field has one shared value for each loaded copy of the class, and a static method can be called with the class name without creating an object. A static method has no current object, so it cannot directly use this, instance fields, or instance methods.
The static keyword is useful when a value or action should be shared by all objects of one class. Java keeps one shared value instead of giving every object a separate copy. For example, each user can have a different name, while one shared number records how many users were created. A shared action can also run without first creating an object. This is helpful for common values, simple helper actions, and information that describes the whole group rather than one item. It should be used carefully when the shared value can change.
Useful Questions to Ask the Interviewer
Should I explain static fields, static methods, static initialization, and method hiding?
Should I include thread safety and class loader behavior for shared static state?
How to Explain It in an Interview
A static member belongs to the class rather than to an individual object. It is normally accessed with the class name, such as User.getCount(). An object does not need to be created before a static method or field can be accessed, although the class must be initialized before its static members are used as required by Java initialization rules.
A static field has one value for each loaded Class object. Every instance using that same loaded class sees the same field. This is useful for constants, shared counters, cached metadata, and values that describe the class as a whole. A constant is commonly declared static and final because it belongs to the class and cannot be reassigned after initialization.
A static method also belongs to the class. It has no current object, so it cannot directly access this, instance fields, or instance methods. It can directly access static members. An instance method can access both instance members and static members because it has a current object.
Static methods are hidden rather than overridden. When a parent class and child class declare static methods with the same signature, the selected method depends on the declared reference type or class name, not on the runtime object type.
Mutable static state requires care in production. Threads using the same loaded class share the field, so compound updates such as count plus plus are not automatically safe. Synchronization, locks, or atomic classes may be needed. Static references can also keep objects reachable for the lifetime of the class loader. Separate class loaders and separate Java processes have separate static state.
Interviewers ask this question to check whether a candidate understands the difference between members that belong to a class and members that belong to each object. It also tests whether the candidate understands shared state, method access rules, method hiding, class loading, thread safety, memory retention, and when class level design is appropriate in production code.
Common interview mistakes
A common mistake is thinking that every object receives its own static field. Objects using the same loaded class share that field. Another mistake is calling a static method through an object reference. Java allows this, but the call is still resolved as a class method and the syntax hides its real ownership. Developers may also expect a static method to access this or instance data directly, but no current object exists. Other mistakes include treating hidden static methods as overridden methods, using mutable static state without thread safety, and assuming static state is shared across class loaders or Java processes.
Interview tip
Start by saying that static means the member belongs to the class. Then explain fields and methods separately. Mention that static methods have no current object, static methods are hidden rather than overridden, and mutable static fields require careful thread safety and lifecycle management.
Interviewer may ask next
Is a static field always shared across the entire Java application?
No. A static field belongs to one loaded Class object, so there is normally one copy per class loader. Another class loader can load the same class name and create a separate static field. A separate Java process also has separate memory and separate static state. This matters in application servers, plugin systems, test environments, and distributed deployments because static does not mean one value across every loader, process, or replica.
When should a static method be used instead of an instance method?
Use a static method when the operation does not depend on the state of a particular object and logically belongs to the class, such as a factory method or a calculation based only on its arguments. Use an instance method when behavior depends on object fields or should participate in normal runtime overriding. A static method avoids requiring an object only for the call, but excessive static design can increase coupling and make dependency replacement, testing, and extension harder.
24. What do this and super mean in Java?Language SpecificEasy
i Question Details
Explain how this and super are used to refer to the current object and parent members.
Short Interview Answer (30-60 seconds)
The main difference is that this refers to the current object, while super selects members and constructors from the direct superclass. I use this to access current object fields and methods or to call another constructor in the same class. I use super to access an inherited visible field, call the superclass version of an overridden method, or invoke a superclass constructor. Neither keyword can be used to access the current object from a static context.
The keyword this means the object whose constructor or instance method is currently running. The keyword super tells Java to use a visible field, method, or constructor from the direct parent class. These keywords are useful when a class and its parent use the same names. They also help constructors initialize an object in the required order. This does not create a new object, and super does not represent a separate parent object. Both keywords work with the one object that is being used or created.
Useful Questions to Ask the Interviewer
Should I explain fields and overridden methods?
Should I include constructor chaining?
Should I compare the Java 21 and Java 25 constructor rules?
How to Explain It in an Interview
Inside an instance method or constructor, this refers to the current object. For example, this.name selects the name field of that object. It is often used when a parameter hides a field name, as in this.name = name. The left side is the object field, and the right side is the parameter.
A call such as this.describe() invokes a method on the current object. Normal dynamic method selection still applies. Therefore, Java can run an overriding method based on the actual object type.
Super is not a separate object reference that can be stored or passed around. It is a keyword that selects the direct superclass context. Super.name accesses an inherited visible field when a child field hides it. Super.describe() calls the direct superclass implementation instead of the overriding implementation in the child. Super cannot directly access a private superclass member.
In a constructor, this(...) invokes another constructor in the same class. Super(...) invokes a constructor of the direct superclass. A constructor can contain only one explicit constructor invocation, and constructor chains must eventually reach a superclass constructor. A recursive this(...) chain is a compile time error.
In Java 21, this(...) or super(...) must be the first constructor statement. Java 25 finalized flexible constructor bodies, so permitted statements may appear before that invocation. Code in this early construction section cannot read the object being constructed or call its instance methods. If no explicit invocation is written, Java implicitly invokes super() when allowed. Compilation fails if the direct superclass has no accessible constructor with no arguments.
These keywords perform selection and invocation. They do not copy or allocate another object. Their direct memory cost is zero, and their direct performance cost is negligible beyond the normal field access, method call, or constructor call being performed.
Interviewers ask this question to check whether the candidate understands the current object, inheritance, field hiding, method overriding, and constructor chaining. It also tests whether the candidate knows how Java selects a current class member or a direct superclass member when names overlap.
Common interview mistakes
Common mistakes include treating super as a separate parent object, trying to store or pass super as a value, and using this or super for current object access in a static context. Another mistake is assuming super can directly access private superclass members. Candidates may also confuse field hiding with method overriding. Fields are selected using the declared context of the access, while overridden instance methods normally use dynamic method selection. A super method call explicitly selects the direct superclass implementation. It is also incorrect to state that a constructor invocation must always be the first statement in Java 25, because Java 25 permits a restricted early construction section.
Interview tip
Start with one clear sentence: this refers to the current object, while super selects the direct superclass context. Then explain one field example, one overridden method example, and constructor chaining. Mention that Java 21 requires the constructor invocation first, while Java 25 permits restricted statements before it.
Interviewer may ask next
Can statements appear before this(...) or super(...) in a constructor?
Yes in Java 25, but not under the standard Java 21 rules. Java 25 finalized flexible constructor bodies and permits a restricted early construction section before this(...) or super(...). That section may perform tasks such as argument validation, but it cannot read the object being constructed or call its instance methods. This matters because Java can allow useful preparation while still preventing access to incompletely initialized object state.
Should an overriding method always call super.method()?
No. Super.method() should be used only when the overriding method intentionally needs the direct superclass implementation. The call bypasses normal dynamic selection for that specific invocation and selects the superclass method body. This can reuse stable behavior, but it also couples the child to superclass implementation details. In production code, frequent super calls may indicate that composition would provide clearer and more flexible behavior.
25. What is the difference between an array and an ArrayList?Language SpecificEasy
i Question Details
Compare arrays and ArrayList in terms of size, flexibility, and usage.
Short Interview Answer (30-60 seconds)
An array has a fixed length after creation, while an ArrayList can grow or shrink as elements are added or removed. Arrays can store primitive values or object references. An ArrayList stores object references, so primitive values use wrapper types such as Integer. I use an array when the number of items is known and stable, and an ArrayList when the size can change or List methods make the code easier to maintain.
The practical choice depends on whether the number of values can change. An array is like a row of numbered spaces created with a fixed count. After creation, that count cannot change, although the values inside the spaces can change. An ArrayList is a flexible group of values. It can grow when new values arrive and become smaller when values are removed. Both keep values in order and let you reach a value by its position. The main decision is whether you need a stable size or easy changes to the group.
Useful Questions to Ask the Interviewer
Is the number of values known in advance?
Will values often be added or removed?
Do we need to store primitive values directly?
How to Explain It in an Interview
An array has a fixed length. For example, new int[3] always has three positions. You can replace values in those positions, but you cannot add a fourth position. To use a different length, you must create another array and copy the required values into it.
An ArrayList is a class from the Java collections library. It stores its elements in an internal array. When that internal array has no free capacity and another element is added, the ArrayList allocates a larger internal array and copies the existing element references into it. This growth is automatic, but the addition that triggers it costs more time and memory than a normal addition.
Arrays can store primitives directly, such as int, double, and boolean. They can also store object references. An ArrayList stores object references and uses generic types, such as ArrayList<Integer>. Java often converts between int and Integer automatically, but wrapper objects can require more memory than primitive values.
Both arrays and ArrayList provide constant time access by index. Replacing an existing element by index is also constant time. Adding to the end of an ArrayList is constant time on average across many additions. Adding or removing near the beginning or middle takes linear time because later elements must shift.
Reference arrays and ArrayList can contain null. Primitive arrays cannot. Neither type is automatically thread safe.
Use an array when the size is known, direct primitive storage matters, or an API requires an array. Use an ArrayList when the size changes and methods such as add, remove, contains, and clear improve readability and maintenance.
Interviewers ask this question to check whether the candidate understands two common Java containers and can choose between them based on size changes, stored value types, available operations, performance, memory use, and production needs.
Common interview mistakes
A common mistake is saying that an array is immutable. Its length is fixed, but its elements can usually be changed. Another mistake is saying that ArrayList stores primitives directly. It stores object references, so primitive values use wrapper types. Candidates also forget that ArrayList growth can allocate another internal array and copy existing references. Another mistake is using remove(1) on an ArrayList<Integer> while intending to remove the value one. That call removes the element at index one. Using remove(Integer.valueOf(1)) removes the first matching value. It is also incorrect to assume that either type is automatically thread safe.
Interview tip
Start with fixed length versus flexible size. Then mention primitive storage, index access, automatic resizing, shifting costs, and the practical rule for choosing between them.
Interviewer may ask next
What happens when an ArrayList has no free capacity and another element is added?
The ArrayList allocates a larger internal array, copies its existing element references into that array, and then stores the new element. This matters because the addition that triggers resizing takes linear time and temporarily requires another array allocation, even though adding at the end takes constant time on average across many additions.
When would you choose an array instead of an ArrayList in production code?
I would choose an array when the size is known and stable, when primitive values should be stored directly, or when an API requires an array. Arrays avoid collection overhead and can avoid wrapper objects for primitive data. The tradeoff is that changing the length requires creating another array and copying values, and arrays provide fewer convenience operations.
26. What is the Java Collections Framework?NEWLanguage SpecificEasy
i Question Details
Define the Java Collections Framework and explain the roles of Iterable, Collection, List, Set, Queue, Deque, and Map. Give simple examples of ArrayList, HashSet, HashMap, and ArrayDeque, and explain that choosing a collection depends on ordering, duplicates, lookup needs, mutation, concurrency, and expected data size.
Short Interview Answer (30-60 seconds)
The Java Collections Framework is the standard JDK set of interfaces and classes for storing and working with groups of objects. Iterable supports iteration. Collection is the main interface for groups of elements, with List, Set, Queue, and Deque below it. Map is separate because it stores key and value pairs. I choose a collection based on whether I need ordering, duplicates, fast lookup, queue behavior, mutation, thread safety, and the expected amount of data.
In Java, we often need to keep many values together and perform common actions such as adding, removing, finding, or visiting them. Java provides a standard group of ready made tools for this job. Different tools have different rules. Some keep items in a specific order. Some prevent repeated items. Some connect one value to another value for quick finding. Some are designed for processing items from one end or both ends. The main skill is choosing the tool whose behavior matches the problem instead of using the same tool everywhere.
Useful Questions to Ask the Interviewer
Should I explain the main interfaces as well as common implementations?
Would you like me to compare their ordering, duplicate, and lookup behavior?
How to Explain It in an Interview
The Java Collections Framework is a set of JDK interfaces, implementations, and algorithms for working with groups of objects.
Iterable is the basic interface for something that can provide an Iterator, which lets code visit elements one at a time. Collection extends Iterable and represents a group of elements.
List keeps elements in sequence and allows duplicates. ArrayList is a common implementation. It gives fast indexed access and is usually a good choice when reads are common and inserts in the middle are not frequent.
Set represents unique elements. HashSet is a common implementation. It uses hashing and normally gives fast add, remove, and contains operations. It does not promise iteration order.
Queue represents elements waiting to be processed. Deque extends Queue and supports adding or removing from both ends. ArrayDeque is a common choice for a queue or stack. It does not allow null elements.
Map is part of the framework but does not extend Collection. It stores key and value pairs. HashMap is a common implementation. Each key is unique, while values can repeat. It allows one null key and null values.
The correct choice depends on ordering, duplicates, lookup needs, how often data changes, concurrency needs, and expected data size. Standard ArrayList, HashSet, HashMap, and ArrayDeque are not generally safe for unsynchronized concurrent modification by multiple threads.
Code
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
publicclassMain {
publicstaticvoidmain(String[] args) {
// Keep names in insertion sequence and allow repeated values.
List<String> names = newArrayList<>();
names.add("Ana");
names.add("Ben");
names.add("Ana");
System.out.println(names);
// Keep unique values according to equality and hashing.
Set<String> uniqueNames = newHashSet<>(names);
System.out.println(uniqueNames.contains("Ana"));
// Associate each unique key with a value for direct lookup.
Map<Integer, String> usersById = newHashMap<>();
usersById.put(101, "Ana");
usersById.put(102, "Ben");
System.out.println(usersById.get(101));
// Process work in first in first out order using both ends of the deque.
ArrayDeque<String> tasks = newArrayDeque<>();
tasks.addLast("Task A");
tasks.addLast("Task B");
System.out.println(tasks.removeFirst());
}
}
Why Interviewers Ask This
Interviewers ask this to check whether the candidate understands the main Java collection interfaces, can choose a suitable implementation for a real problem, and understands important behavior such as ordering, duplicates, lookup cost, mutation, and thread safety.
Common interview mistakes
A common mistake is saying that Map extends Collection. It does not. Another mistake is assuming HashSet or HashMap keeps insertion order. Their iteration order is not guaranteed. Candidates may also assume every collection allows null, but ArrayDeque does not. Another mistake is choosing ArrayList for frequent insertion near the front without considering element movement. It is also incorrect to assume ordinary ArrayList, HashSet, HashMap, or ArrayDeque automatically makes concurrent modification by multiple threads safe.
Interview tip
Start with the purpose of the framework, then explain the interface relationships in a simple order. Mention that Map is separate from Collection. Give one practical example for ArrayList, HashSet, HashMap, and ArrayDeque. Finish by saying that the right choice depends on ordering, duplicates, lookup needs, mutation, concurrency, and data size.
Interviewer may ask next
What happens if two objects in a HashSet are equal according to equals but have inconsistent hashCode values?
That violates the equals and hashCode contract and can make HashSet behave incorrectly. If two objects are equal according to equals, they must return the same hashCode. HashSet uses the hash value to narrow where it searches and then uses equality to identify a matching element. If equal objects produce different hash values, a logically equal value may not be found where expected and duplicate looking entries can appear. This matters because correct uniqueness and lookup behavior depend on a valid equals and hashCode implementation.
How would you choose between ArrayList, HashSet, HashMap, and ArrayDeque in production code?
I would choose based on the behavior the application needs. ArrayList is suitable for an ordered sequence with indexed access and duplicates. HashSet is suitable for unique elements and fast membership checks. HashMap is suitable for looking up values by unique keys. ArrayDeque is suitable for queue or stack operations at the ends. The main tradeoff depends on ordering guarantees, duplicate rules, lookup patterns, mutation patterns, memory use, concurrency requirements, and expected data size.
27. What is the difference between ArrayList and LinkedList?Language SpecificMedium
i Question Details
Compare ArrayList and LinkedList in terms of memory, access patterns, inserts, deletes, and common use cases.
Short Interview Answer (30-60 seconds)
I would choose ArrayList for most applications because it gives constant time indexed access, usually uses less memory, and normally iterates efficiently. LinkedList stores every element in a separate node with references to the previous and next nodes. Indexed access is therefore linear time. LinkedList can add or remove an element in constant time when the required node is already known, but finding that node can still take linear time.
Detailed Explanation
Both classes keep items in order and let the program add, read, replace, or remove them. The main difference is how they arrange those items in memory. ArrayList keeps item references together in one growing container. LinkedList gives every item its own holder and connects the holders. This changes how quickly the program can reach an item, move items, and change the beginning or middle of the collection. It also changes how much extra memory is used. The best choice depends on which operations the program performs most often.
Useful Questions to Ask the Interviewer
Will the code frequently read or replace an element by its position?
Will additions and removals happen mainly at the end, beginning, or middle?
Will the code already have an Iterator positioned at the element being changed?
Are memory use and iteration speed important?
How to Explain It in an Interview
ArrayList stores element references in a resizable array. Because an array supports direct indexed access, get and set are O(1). Adding at the end is amortized O(1). Most additions are fast, but an addition that exceeds the current capacity can allocate a larger array and copy the existing references, making that individual operation O(n). Inserting or removing near the beginning or middle is O(n) because later references must shift.
LinkedList is a doubly linked list. Each node stores an element reference plus references to the previous and next nodes. Getting an element by index is O(n) because the implementation must walk from the nearer end. Adding or removing at either end is O(1). Inserting or removing through a ListIterator at an already reached position is also O(1), but reaching that position may require O(n) work.
ArrayList usually uses less memory. It stores one array of references, although the array may contain unused capacity. LinkedList allocates one node per element and keeps two additional node references. Those separate allocations also usually make iteration less friendly to processor caches, so LinkedList is not automatically faster for frequent changes.
Both classes preserve insertion order, allow duplicate elements, and allow null. Neither class is thread safe. Their iterators are fail fast on a best effort basis and must not be treated as a concurrency guarantee.
ArrayList is the normal production default. LinkedList is useful only when its constant time end operations or changes through an already positioned iterator match the workload. For a queue or stack, ArrayDeque is usually a better choice.
Why Interviewers Ask This
Interviewers ask this question to check whether a candidate understands how two common Java List implementations store elements and how that storage affects access time, updates, iteration, allocation, and memory use. It also tests whether the candidate can choose a collection from the actual workload instead of repeating complexity values without considering the cost of locating an element.
Common interview mistakes
A common mistake is saying that every middle insertion or removal in LinkedList is O(1). The link change is O(1) only after the target node has been reached. Calling add with an index, remove with an index, or searching for a value still requires a traversal and is O(n). Another mistake is assuming LinkedList uses less memory. It normally uses more because each element requires a node and two additional node references. Candidates also forget that ArrayList growth occasionally copies references, confuse fail fast iteration with thread safety, or choose LinkedList for a queue when ArrayDeque is usually more suitable.
Interview tip
Begin with the practical choice that ArrayList is the usual default. Then explain that ArrayList uses a resizable array while LinkedList uses connected nodes. Compare indexed access, end operations, middle changes, memory, and iteration. Clearly qualify that LinkedList gives constant time insertion or removal only after the required node has already been reached.
Interviewer may ask next
Is removing an element from the middle of a LinkedList always O(1)?
No. Reconnecting the neighboring nodes is O(1) only when the target node has already been reached, such as through a ListIterator. Calling remove with an index or first searching for a value requires a traversal, which is O(n). This matters because the traversal cost often removes the expected performance advantage.
Which collection would you normally choose for queue operations in production?
I would normally choose ArrayDeque instead of LinkedList. ArrayDeque provides amortized O(1) additions and removals at both ends, avoids one node allocation for every element, and usually has better memory locality. The important limitation is that ArrayDeque does not allow null elements, while LinkedList does.
28. What is the difference between HashSet and TreeSet?Language SpecificMedium
i Question Details
Compare HashSet and TreeSet in ordering, lookup behavior, and performance.
Short Interview Answer (30-60 seconds)
I use HashSet when I need fast membership checks and do not need sorted iteration. Its basic operations have expected O(1) time when hash values are distributed well, but it does not guarantee iteration order. I use TreeSet when elements must remain sorted or when I need navigation and range operations. Its basic operations take O(log n) time. HashSet permits one null element. TreeSet can accept null only when its Comparator explicitly supports null values.
Both classes store unique values, but they organize those values differently. HashSet is usually the better choice when the order does not matter and the program mainly needs to check whether a value exists. TreeSet is useful when values must remain sorted or when the program must find values near a given value. This choice affects lookup speed, iteration order, null handling, memory use, and the rules used to decide whether two values are duplicates.
Useful Questions to Ask the Interviewer
Must the values be returned in sorted order?
Does the code need range or nearest value searches?
Can the collection contain null?
Is faster average lookup more important than sorted access?
How to Explain It in an Interview
HashSet implements Set and is backed by a HashMap. It uses hashCode to select a storage location and equals to determine whether an equal element is already present. The add, contains, and remove operations have expected O(1) time when hash values are distributed well. The API does not guarantee constant time for every possible input.
HashSet does not guarantee iteration order. Its order can change when the set changes or when the program runs in a different environment. It permits one null element because its backing HashMap permits a null key.
TreeSet implements NavigableSet and is backed by a TreeMap. It keeps elements sorted by their natural ordering or by a Comparator supplied when the set is created. Its add, contains, and remove operations have guaranteed O(log n) time.
TreeSet provides navigation methods such as lower, higher, floor, and ceiling. It also provides range views through headSet, tailSet, and subSet. These operations are useful when the application needs sorted traversal, nearest values, or values within a boundary.
TreeSet decides that two elements are duplicates when compareTo or the Comparator returns zero. This can differ from equals, so the ordering should normally be consistent with equals. A TreeSet using natural ordering rejects null. A TreeSet with a Comparator can accept null only when that Comparator supports comparing null values.
Neither collection is thread safe. Objects stored in either set should not change fields used by equals, hashCode, compareTo, or the Comparator while they remain in the set.
Interviewers ask this question to check whether a candidate understands Java set behavior, ordering, equality, lookup cost, and collection selection. It also tests whether the candidate knows that HashSet and TreeSet both store unique elements but use different rules to locate elements and decide whether an element is already present.
Common interview mistakes
A common mistake is assuming that HashSet preserves insertion order. LinkedHashSet is the usual choice when predictable encounter order is required. Another mistake is expecting TreeSet to use equals for duplicate detection. TreeSet uses compareTo or its Comparator, and a comparison result of zero means the values are duplicates. Developers also sometimes change an object after insertion in a way that changes its hash or ordering. This can make contains or remove fail and can break the logical structure of the set. Another mistake is assuming that TreeSet always rejects null. A Comparator that explicitly supports null can allow it, while natural ordering cannot. Neither collection should be modified concurrently without suitable coordination.
Interview tip
Start with the decision rule. Say HashSet is for fast expected membership checks without sorted order, while TreeSet is for sorted values, navigation, and range operations. Then compare expected O(1) with guaranteed O(log n), explain null handling, and mention that TreeSet treats a comparison result of zero as a duplicate.
Interviewer may ask next
What happens if a TreeSet Comparator returns zero for two objects that are not equal according to equals?
TreeSet treats the second object as a duplicate and does not add it as a separate element. TreeSet determines uniqueness through compareTo or the supplied Comparator, so a result of zero means the objects occupy the same logical position. This matters because the set can behave differently from code that uses equals. The ordering should normally be consistent with equals unless the application deliberately defines uniqueness through another property.
When is LinkedHashSet a better choice than HashSet or TreeSet?
LinkedHashSet is better when elements must remain unique and iteration must follow a predictable encounter order. It provides expected O(1) basic operations like HashSet, but it maintains additional links to preserve order. It does not sort elements and does not provide TreeSet navigation or range operations. The main tradeoff is additional memory compared with HashSet in exchange for predictable iteration order.
29. What is the difference between HashMap and Hashtable?Language SpecificMedium
i Question Details
Explain the differences between HashMap and Hashtable, including synchronization and legacy behavior.
Short Interview Answer (30-60 seconds)
I normally use HashMap when the map is confined to one thread or when access is coordinated elsewhere. Hashtable is a legacy class whose main map operations synchronize on the Hashtable instance. That protects individual operations, but it does not automatically make a sequence of operations atomic. HashMap allows one null key and multiple null values, while Hashtable allows neither. For a map shared by many threads, ConcurrentHashMap is usually the better modern choice.
Detailed Explanation
These two choices both store information so a value can be found by a matching name or object. The practical difference is safety when several parts of a program use the same data at once. The older choice protects each basic action by itself, but that does not protect a longer group of actions. The newer common choice does not add that protection automatically. They also treat missing references differently. One accepts them, while the older one rejects them. In modern programs, another shared data option is usually better when many workers update the data together.
Useful Questions to Ask the Interviewer
Will several threads read and update the same map?
Must the map accept null keys or null values?
Must several map operations happen as one atomic action?
How to Explain It in an Interview
HashMap and Hashtable both implement Map and store key and value pairs by using each key's hashCode and equals methods.
HashMap is the normal general purpose choice. It does not synchronize its operations. Multiple threads may read an unchanged HashMap after it has been published safely, but concurrent structural changes require external coordination. Without that coordination, behavior is not safe or predictable.
Hashtable is a legacy class. Its main map operations synchronize on the Hashtable instance. Only one thread at a time can execute those synchronized operations on the same instance. This adds lock contention. It also protects only one method call at a time. A sequence such as checking for a key and then inserting a value is not automatically atomic. The caller must lock the complete sequence on the same Hashtable instance, or use an atomic operation from a suitable concurrent map.
HashMap permits one null key and multiple null values. Hashtable throws NullPointerException when given a null key or null value.
Both maps normally provide constant time lookup, insertion, and removal when keys have well distributed hash codes. Poor hash distribution can make operations slower. HashMap and Hashtable both use memory proportional to the number of entries. They store references to keys and values rather than copying those objects. Resizing allocates a larger bucket array and redistributes stored entries.
HashMap iterators are fail fast on a best effort basis. Hashtable collection view iterators have similar behavior. Hashtable also provides the older Enumeration API, which is not fail fast.
For modern shared access, ConcurrentHashMap is usually preferred because it supports safe concurrent operations with better scalability than one instance wide lock. Hashtable is mainly useful when maintaining an older API that specifically requires it.
Why Interviewers Ask This
Interviewers ask this question to check whether a candidate understands Java map behavior, synchronization, thread safety, null handling, iteration behavior, performance tradeoffs, and the difference between a modern collection and a legacy class. It also tests whether the candidate can choose an appropriate map for production code instead of assuming that synchronized individual operations make every workflow safe.
Common interview mistakes
A common mistake is saying that Hashtable makes every use of the map thread safe. Its synchronization protects individual method calls, not a sequence such as check then insert. Another mistake is choosing Hashtable whenever several threads exist without considering ConcurrentHashMap. Candidates also forget that Hashtable rejects both null keys and null values, while HashMap permits one null key and multiple null values. It is also incorrect to treat fail fast iteration as a guaranteed way to detect every concurrent modification.
Interview tip
Start with the practical choice. Say that HashMap is the normal modern map, Hashtable is a synchronized legacy class, and ConcurrentHashMap is usually preferred for shared concurrent access. Then explain null handling and why synchronized individual methods do not make compound actions atomic.
Interviewer may ask next
Does Hashtable make a check then insert sequence atomic?
No. Hashtable synchronizes each relevant method call separately, so a check followed by an insertion is still two operations. Another thread can change the table between them. This matters when only one value must be created for a key. The caller can synchronize the complete sequence on the same Hashtable instance, but a modern concurrent map operation such as ConcurrentHashMap computeIfAbsent is usually clearer and more scalable.
Why is ConcurrentHashMap usually preferred over Hashtable in production?
ConcurrentHashMap is usually preferred because it supports safe concurrent access without using one instance wide lock for every ordinary operation. This allows more threads to work on different parts of the map at the same time. It also provides atomic operations such as putIfAbsent, compute, and computeIfAbsent. The tradeoff is that it rejects null keys and null values, and callers must understand the exact atomic guarantee of the operation they choose.
30. What is the difference between HashMap and ConcurrentHashMap?Language SpecificMedium
i Question Details
Compare HashMap and ConcurrentHashMap for thread safety, concurrency, and performance.
Short Interview Answer (30-60 seconds)
HashMap is not thread safe, so I use it when one thread owns the map or when all access is protected by external synchronization. ConcurrentHashMap is designed for safe access by multiple threads and allows reads and updates with much less contention than locking one entire map. HashMap allows one null key and null values, while ConcurrentHashMap allows neither. For shared state, I use atomic methods such as putIfAbsent, compute, or merge instead of separate check and update calls.
The practical choice depends on whether several workers can use and change the same collection at the same time. A regular map is simpler when one worker owns it. A concurrent map is safer when many workers share it. It prevents overlapping changes from damaging the collection or producing unsafe access. It also provides operations that perform a check and an update as one action. This matters because another worker could otherwise change the data between those two steps and cause a lost or incorrect update.
Useful Questions to Ask the Interviewer
Will multiple threads read or update the same map?
Must a check and an update happen as one atomic operation?
Does the application need null keys or null values?
Can iteration happen while other threads update the map?
How to Explain It in an Interview
HashMap is not thread safe. Multiple threads may read the same HashMap only when no thread modifies it and the map has been safely published. Unsynchronized concurrent updates can cause lost updates, stale observations, or inconsistent behavior.
ConcurrentHashMap is thread safe for its documented operations. Retrieval operations normally do not block. Updates use internal coordination only where needed instead of locking the entire map for every operation. The exact mechanism is a JDK implementation detail, so code should rely on the API guarantees rather than assumptions about internal locks.
Both maps normally provide average O(1) get and put performance when keys have suitable hash values. ConcurrentHashMap pays extra coordination cost for thread safety. A HashMap is therefore usually the simpler and lower cost choice for thread confined data. Under real shared access, ConcurrentHashMap usually scales better than protecting one HashMap with one large lock.
HashMap permits one null key and multiple null values. ConcurrentHashMap rejects null keys and null values. This lets a null result from get clearly indicate that no value is currently mapped to the key.
HashMap iterators are fail fast on a best effort basis and may throw ConcurrentModificationException after an unsupported structural change. ConcurrentHashMap iterators are weakly consistent. They do not throw that exception because of concurrent updates, but they are not fixed snapshots and may observe some updates while iteration is running.
Methods such as putIfAbsent, computeIfAbsent, compute, and merge provide atomic map operations. A separate containsKey followed by put is not atomic. ConcurrentHashMap protects one map instance inside one JVM. It does not coordinate separate application processes or replicas.
Interviewers ask this question to check whether the candidate understands shared mutable data, safe access from multiple threads, atomic map operations, null handling, iteration behavior, and the performance and memory tradeoffs of choosing a regular map or a concurrent map in production.
Common interview mistakes
A common mistake is assuming that a final HashMap reference makes the map thread safe. Final prevents reassignment of the reference, but it does not protect changes to the map. Another mistake is using containsKey followed by put on ConcurrentHashMap and assuming the pair is atomic. Each call is safe by itself, but another thread can act between them. Developers may also assume that a ConcurrentHashMap iterator is a fixed snapshot. It is weakly consistent and may observe some concurrent changes. Another mistake is expecting thread safety of the map to make a larger business operation atomic. Several related map calls may still require explicit coordination. ConcurrentHashMap may also use more memory than HashMap because concurrency support can require additional bookkeeping. The exact difference is implementation and workload dependent.
Interview tip
Start with the decision rule. Use HashMap for thread confined data or data protected by external synchronization. Use ConcurrentHashMap for shared concurrent access. Then compare atomic operations, null handling, iteration behavior, performance, memory cost, and the fact that thread safe individual methods do not make every sequence of calls atomic.
Interviewer may ask next
Is containsKey followed by put atomic on ConcurrentHashMap?
No. Each method call is thread safe, but the two call sequence is not atomic. Another thread can insert, remove, or replace the mapping between the calls. This matters for create when missing logic because work may run more than once or one value may replace another unexpectedly. Use putIfAbsent or computeIfAbsent for insertion, and use compute or merge when the existing value must be updated atomically.
Should ConcurrentHashMap always replace HashMap in production because it is thread safe?
No. ConcurrentHashMap is appropriate when the same map instance is genuinely shared across threads. It adds coordination cost, may require more memory, rejects null keys and values, and provides weakly consistent iteration rather than a fixed snapshot. HashMap is simpler for local or thread confined data. If several related operations or several collections must change as one unit, ConcurrentHashMap alone is not enough and the application may need explicit locking or a different state design.
More questions load as you scroll
Disclaimer: This interview guide is for educational and informational purposes only. It is designed to help readers prepare, but it does not guarantee any interview result, hiring decision, offer, or outcome. Interview questions, hiring criteria, and preferred answers can vary by employer, interviewer, industry, location, and time. The examples and explanations reflect the authors' research and judgment, are provided without warranties of any kind, and should not be treated as the only correct approach. Diagrams are simplified illustrations intended to highlight the main components and their interactions; actual systems and implementations may be more complex. Alternative approaches may be equally valid or better suited to a particular question, context, or interviewer. To the fullest extent permitted by applicable law, the author, contributors, and publisher are not liable for decisions made, actions taken, or losses incurred based on this guide.