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.
71. How would you diagnose and fix an OutOfMemoryError?Language SpecificHard
i Question Details
Describe the steps you would take to investigate an OutOfMemoryError, identify the root cause, and validate the fix.
Short Interview Answer (30-60 seconds)
I would first preserve the exact error message, stack trace, memory metrics, garbage collection logs, and any available dump before restarting the process. Then I would identify which memory area or resource failed, such as the Java heap, metaspace, direct memory, or native thread capacity. I would find what is retaining or consuming that memory, fix the ownership, limit, sizing, or workload problem, and validate the change under sustained load. I would not treat a larger heap as the default fix because it can hide a leak or reduce native memory.
Detailed Explanation
This error means the program asked for more working space, but the running process could not provide it. It does not always mean that one part of memory is full, and it does not automatically prove that the program has a leak. The cause may be data kept for too long, more work than expected, too many running tasks, or a limit that is set too low. I would save evidence first, locate the exhausted area, find what is using or holding the space, fix that cause, and then repeat the same workload to prove the usage stays stable.
Useful Questions to Ask the Interviewer
What is the complete OutOfMemoryError message and stack trace?
Which JVM, container, and operating system memory limits are configured?
Are heap dumps, garbage collection logs, thread dumps, and memory metrics available?
Did traffic, data size, dependencies, cache settings, or deployment limits recently change?
How to Explain It in an Interview
I would first preserve evidence because a restart may remove important information about the failure. I would collect the full error, JVM and container metrics, garbage collection logs, and a heap dump when the failure concerns heap memory. I would configure HeapDumpOnOutOfMemoryError before the next occurrence when no dump exists. A heap dump can also fail when disk space or process resources are insufficient, so it is not the only evidence.
Next, I would classify the exact failure. Java heap space usually means the JVM could not allocate an object in the configured heap. GC overhead limit exceeded means the JVM spent excessive time collecting while recovering very little memory. Metaspace can indicate excessive class loading or retained class loaders. Direct buffer memory points to off heap buffers and their configured or practical limits. Unable to create native thread usually points to excessive platform threads, insufficient native memory, or operating system resource limits.
For a heap failure, I would inspect the dump with a tool such as Eclipse Memory Analyzer. I would compare object counts, retained size, the dominator tree, and paths to garbage collection roots. Retained size matters because it shows how much memory would become available if an object were no longer reachable. I would also compare multiple dumps or memory charts when possible to separate normal growth from continuing retention.
Typical causes include unbounded caches, maps, queues, listeners, sessions, request data, large query results, excessive buffering, duplicate objects, and class loader retention. I would add bounds, remove entries, release references, stream or divide large work, close resources, reduce concurrency, or correct object ownership. I would increase memory only when measurements show a valid, bounded live data set that genuinely needs more capacity.
Finally, I would repeat the same workload and confirm that the post collection live memory reaches a stable ceiling, allocation rate is acceptable, collection pauses remain acceptable, queues stay bounded, and the error does not return.
Why Interviewers Ask This
Interviewers ask this question to test whether the candidate can diagnose Java memory failures using evidence instead of guessing. It evaluates knowledge of JVM memory areas, garbage collection, object retention, native memory, resource limits, production recovery, and validation. It also shows whether the candidate can distinguish a memory leak from valid capacity growth and choose a fix that addresses the actual cause.
Common interview mistakes
Common mistakes include increasing the heap before identifying the cause, restarting before preserving evidence, and assuming every OutOfMemoryError is a Java heap leak. Other mistakes are checking only shallow object size, ignoring retained size and reachability, failing to inspect container memory limits, and overlooking metaspace, direct buffers, thread stacks, class loaders, native libraries, queues, and caches. Reducing the heap can leave more room for native memory, while increasing it can make a native memory problem worse. Catching OutOfMemoryError and continuing normal processing is also unsafe because the process may be unable to allocate memory needed for recovery. A top level handler may perform minimal emergency reporting, but the normal response is controlled termination and restart after evidence is preserved.
Interview tip
Present the answer in four steps: preserve evidence, classify the exact error, find what owns or retains the memory, and validate the fix under sustained load. Mention several OutOfMemoryError variants to show that you will not assume every failure is a heap leak. End by explaining that more memory is valid only when the required live data is measured, bounded, and correctly sized.
Interviewer may ask next
How would your diagnosis change if the message says unable to create native thread?
I would investigate platform thread count, native memory, blocked work, and operating system limits instead of treating it as a normal heap retention problem. This error means the JVM could not create another native thread. I would inspect thread dumps, executor configuration, thread creation rate, thread stack size, process limits, container limits, and tasks that remain blocked. The fix may be to bound an executor, remove uncontrolled thread creation, reduce blocking, use virtual threads appropriately for high concurrency blocking work, or adjust a justified system limit. Increasing the Java heap may make the failure worse because it can leave less process memory for thread stacks and other native allocations.
When is increasing the maximum heap a valid fix, and when does it only hide the problem?
Increasing the maximum heap is valid when measurements show that the application has a necessary and bounded live data set that does not fit within the current heap. It can also be valid after expected growth in traffic or batch size when memory returns to a stable level after each workload cycle. It only hides the problem when retained memory continues to grow, caches or queues are unbounded, or objects remain reachable after their useful lifetime. The main tradeoff is that a larger heap provides more capacity but uses more process memory and may change garbage collection pause behavior. I would validate it with sustained load, post collection live memory, allocation rate, pause measurements, and container headroom.
72. How would you troubleshoot high CPU usage in a Java service?Language SpecificHard
i Question Details
Describe how you would profile CPU hot spots, identify the cause, and validate the optimization.
Short Interview Answer (30-60 seconds)
I would first confirm that the Java process is responsible for the CPU increase and identify when it happens. Then I would record CPU samples with Java Flight Recorder, inspect the hottest threads and methods, and compare that evidence with repeated thread dumps, garbage collection data, request traffic, container limits, and recent changes. I would fix the measured cause, such as a tight loop, repeated computation, excessive allocation, expensive serialization, or too much parallel work. Finally, I would repeat the same representative load and compare CPU time per request, throughput, latency, errors, allocation, and result correctness.
Detailed Explanation
High CPU usage means the service is spending much more processor time than expected. I would not immediately change the code. I would first find out which work is using the processor, when the problem starts, and whether it affects all requests or only one operation. I would also check whether traffic, input size, settings, or a recent release changed. The goal is to find the exact repeated work, correct it safely, and prove that the service performs better without producing different results.
Useful Questions to Ask the Interviewer
Is the CPU increase constant or caused by a specific request or background task?
Did traffic, input size, configuration, or application code change recently?
Is the problem visible in one Java process or across every service replica?
Are latency, throughput, errors, or garbage collection activity changing at the same time?
How to Explain It in an Interview
I would start by confirming the symptom. I would check the Java process identifier, CPU use per core, container CPU limits, throttling, affected replicas, request rate, latency, and the time the increase began. Higher CPU can be normal when traffic grows, so I would also compare CPU time per request and completed work per second.
Next, I would collect a focused Java Flight Recorder recording with jcmd. Java Flight Recorder is included in the JDK and can sample running methods, thread activity, allocation, garbage collection, locks, and compilation. Recording cost depends on the selected events and settings, so I would keep the recording limited and verify its impact in production.
I would inspect execution samples to find the threads, methods, and call paths that repeatedly use CPU. I would also capture several thread dumps a few seconds apart. A single thread dump is only one moment. Repeated dumps can show whether the same runnable thread remains in a tight loop or repeatedly performs parsing, regular expression matching, serialization, compression, logging, hashing, or task submission.
If garbage collection threads use much of the CPU, I would inspect allocation rate, object lifetime, heap occupancy, and the methods creating objects. Heavy allocation creates collector work even when the service does not run out of memory. Retained objects can also increase tracing and movement work, depending on the collector.
If Java method samples do not explain the process CPU, I would investigate JIT compilation, native libraries, operating system calls, and other native work with suitable system profiling tools.
After identifying the cause, I would make the smallest safe change. I might remove repeated computation, reduce temporary objects, batch work, limit parallelism, or cache an immutable result with a clear size limit. Virtual threads would not make CPU bound computation faster.
I would then repeat the same representative load and compare CPU time per request, throughput, latency percentiles, allocation rate, garbage collection time, errors, and output correctness. I would release the change gradually and watch for regressions.
Why Interviewers Ask This
Interviewers ask this question to test whether a candidate can diagnose a real Java production problem with evidence instead of guessing. It evaluates knowledge of JVM profiling, thread behavior, garbage collection, JIT compilation, application hot spots, allocation pressure, and safe performance validation. It also tests whether the candidate can separate expected CPU growth from inefficient work and choose an optimization that improves capacity without changing correctness.
Common interview mistakes
A common mistake is changing code before collecting evidence. Another is looking only at total CPU percentage without checking traffic, CPU limits, throttling, completed work, or CPU time per request. Developers may trust one thread dump even though it shows only one instant, or treat the hottest leaf method as the root cause without following its call path. Other mistakes include enabling costly profiling settings for too long, ignoring allocation and garbage collection activity, increasing thread counts for CPU bound work, assuming virtual threads increase processor speed, overlooking native code, and validating with a workload different from the one that caused the problem. Lower CPU is not a successful result if throughput, latency, errors, or output correctness become worse.
Interview tip
Explain the investigation in a clear sequence: confirm the symptom, collect JVM evidence, locate the hot call path, connect it to application behavior, make one focused change, and validate under the same load. Mention Java Flight Recorder, repeated thread dumps, allocation and garbage collection data, native work when Java samples are insufficient, and CPU time per request. Do not guess the cause before profiling.
Interviewer may ask next
What would you do if Java Flight Recorder shows garbage collection threads using a large share of CPU?
I would treat high garbage collection CPU as a symptom until allocation and heap data explain it. I would inspect allocation rate, the methods creating the most objects, object lifetime, heap occupancy after collection, collection frequency, and whether the heap or container limit changed. The exact behavior is that frequent allocation creates more collection work, while retained objects can require more tracing and movement depending on the collector. This matters because changing collector settings may hide the symptom without removing wasteful allocation. I would first reduce unnecessary object creation or unintended retention, then test any heap or collector change under the same workload.
Would replacing platform threads with virtual threads reduce high CPU usage?
No, not when the service is limited by CPU bound computation. Virtual threads make it practical to run many blocking tasks because the JVM can suspend a virtual thread while it waits and let carrier threads run other work. They do not reduce the processor instructions required for parsing, encryption, compression, serialization, loops, or other computation. This matters because allowing more CPU bound tasks to run at once can increase contention and saturation. I would use virtual threads for suitable blocking request flows, but I would still limit CPU heavy concurrency and optimize the measured hot method.
73. How do you reduce object allocation and GC pressure in a hot path?Language SpecificHard
i Question Details
Explain how you would measure allocation pressure and reduce unnecessary object creation in performance-critical code.
Short Interview Answer (30-60 seconds)
I first measure the hot path and confirm that allocation is causing meaningful processor cost, garbage collection work, or latency. I use Java Flight Recorder for the real workload and Java Microbenchmark Harness for an isolated method when needed. Then I remove the largest unnecessary allocations, such as boxing, temporary strings, copied arrays, temporary collections, varargs arrays, and avoidable result objects. I reuse buffers only when ownership is clear and size is limited. After each change, I measure allocation per operation, throughput, latency, and garbage collection again.
Detailed Explanation
This question asks how to make a frequently used part of a program create less temporary data. Each temporary value needs memory. When that value is no longer useful, the program must clean it up. If a busy part creates too much temporary data, the program may spend more time cleaning memory and may respond more slowly. The goal is not to remove every new value. The goal is to find waste, remove it safely, and prove that the change helps the real workload without making the code unsafe or difficult to maintain.
Useful Questions to Ask the Interviewer
Which method or request path is the hot path?
Is the main concern latency, processor use, throughput, or memory use?
What input sizes and request rates should the test represent?
Can temporary storage be owned by one call or one thread?
How to Explain It in an Interview
I start with measurement because a new expression is not automatically a performance problem. I record a representative workload with Java Flight Recorder and inspect allocation samples, garbage collection activity, pause time, processor use, and the methods and object types associated with the most allocated memory. Allocation samples identify important sources but are not an exact count of every object. For an isolated method, I can use Java Microbenchmark Harness with its garbage collection profiler. I include warmup, realistic inputs, separate benchmark forks, and consumed results so JVM compilation does not make the test misleading. Java Flight Recorder is designed to collect detailed JVM runtime information, including information useful for performance analysis. ([docs.oracle.com](https://docs.oracle.com/en/java/java-components/jdk-mission-control/9/user-guide/using-jdk-flight-recorder.html?utm_source=chatgpt.com))
I then fix the largest proven source. Common causes include primitive values being boxed into Integer or Long objects, temporary substring results, String.split results, varargs arrays, copied byte arrays, temporary collections, map entry objects, stream pipeline objects, and result objects that exist only to move several values between methods.
Possible changes include keeping values as primitives, using a simple loop in a measured critical section, scanning a CharSequence by index instead of creating temporary strings, writing into a caller owned buffer, setting an initial collection capacity from a reliable estimate, processing data in one pass, or returning a primitive value when a separate object adds no useful meaning.
Reuse requires strict ownership. A shared mutable buffer can cause races and data corruption. A pool can add synchronization, bookkeeping, stale data, and retained memory. ThreadLocal buffers can keep large arrays reachable for as long as their thread remains alive. With many threads, retained storage can become larger than the allocation it was meant to avoid.
Finally, I repeat the same test. A useful change lowers allocated bytes per operation and improves the required latency, throughput, or processor use. Lower allocation alone is not enough if the new code is slower, unsafe, or harder to maintain.
Why Interviewers Ask This
Interviewers ask this to check whether a candidate can find memory creation with evidence instead of guessing. It tests knowledge of Java allocation, garbage collection, hidden temporary objects, JVM optimization, benchmarking, mutable object ownership, and production measurement. It also shows whether the candidate can improve a critical path without introducing shared state bugs or unnecessary complexity.
Common interview mistakes
Common mistakes include optimizing before measuring, assuming every new expression is harmful, and changing many allocation sources at once so the useful change cannot be identified. Other mistakes include using pools for small temporary objects, sharing reusable buffers across concurrent calls, retaining very large arrays in ThreadLocal storage, replacing clear code with complex mutable state, and checking only pause time while ignoring allocation rate and processor cost. Benchmark mistakes include missing warmup, using unrealistic data, failing to consume results, and running only one JVM process. Another mistake is assuming escape analysis will always remove a local allocation.
Interview tip
Explain the answer in five steps: measure, find the largest source, remove safe waste, protect ownership, and measure again. Give two examples of hidden allocation, explain why pooling is not automatically better, and name the production metrics used to prove the result.
Interviewer may ask next
Can escape analysis guarantee that a local object will not be allocated on the heap?
No. Escape analysis is a JVM optimization and is not guaranteed by the Java language. The HotSpot compiler may use scalar replacement when it proves that an object does not escape and can represent its fields without creating the object. HotSpot documentation also explains that this optimization eliminates eligible allocations rather than moving those objects to a guaranteed stack allocation. ([docs.oracle.com](https://docs.oracle.com/en/java/javase/24/vm/java-hotspot-virtual-machine-performance-enhancements.html?utm_source=chatgpt.com)) This matters because compilation decisions can change with code shape, runtime information, and JVM implementation. I would keep the code correct without this optimization and verify the actual allocation with profiling.
Should you use an object pool to reduce garbage collection pressure?
Usually not for small temporary Java objects. A pool can reduce repeated creation only when reuse is cheaper than allocation and reset, but it can also add contention, bookkeeping, stale state, retained memory, and ownership bugs. A pool is more reasonable when creation is genuinely expensive, the object manages an external resource, or it contains a large reusable buffer with strict capacity and lifetime limits. The main tradeoff is lower creation cost against greater complexity and memory retention, so the decision must be proved with the representative workload.
74. What are Java records, and when would you use them?Language SpecificHard
i Question Details
Explain Java records, what problems they solve, and where they are a good fit.
Short Interview Answer (30-60 seconds)
I use a Java record when a type mainly carries a fixed set of values and its meaning comes from those values. Java provides the component fields, accessors, canonical constructor, equals, hashCode, and toString. Records reduce repeated code, but they are only shallowly immutable. I avoid them when I need changing state, identity based behavior, extra instance fields, or class inheritance.
A Java record is useful when several values belong together and describe one simple fact or result. Java creates much of the routine code, so the programmer can focus on what the data means. Records work well for values such as a user summary, a point, an order result, or a settings group. They are less suitable when the object must change over time, has a separate identity, hides additional changing state, or must inherit behavior from another class.
Useful Questions to Ask the Interviewer
Should the record protect mutable values from later changes?
Is validation required when the record is created?
Does any framework require setters or a no argument constructor?
How to Explain It in an Interview
A record is a special kind of class for transparent data carriers. Its header declares the record components. For example, record User(String name, int age) {} declares the components name and age.
For each component, Java declares a private final field and a public accessor with the same name. Java also provides a canonical constructor, equals, hashCode, and toString unless valid explicit declarations replace the generated versions. The generated equals method requires the same record class and compares corresponding component values. Therefore, two User records with equal component values are equal even when they are different objects.
A record is implicitly final, so another class cannot extend it. Every record directly extends java.lang.Record. A record can implement interfaces and declare methods, static members, nested types, compact constructors, and additional constructors. An additional constructor must delegate to another constructor in the same record. A record cannot declare extra instance fields, because its instance state is defined by its components.
Records are shallowly immutable. A component field cannot be reassigned after construction, but an object referenced by that field can still change. A record containing a mutable list can therefore observe changes made through another reference. Use immutable component types or defensive copies when the record must protect its state. A copy of a collection is still shallow because the elements themselves are not copied.
Arrays need special care. Generated equality compares array components using the array object's own equals behavior, which is identity based. Two separate arrays with equal contents therefore do not make two records equal unless equality is customized or a value based collection is used.
Creating a record normally allocates an object just like creating a normal class. Records do not promise lower memory use or faster execution. The cost of generated equality and hashing depends on the number of components and the work performed by each component type.
Code
import java.util.List;
publicclassMain {
recordUser(String name, int age, List<String> roles) {
User {
if (name == null || name.isBlank()) {
thrownewIllegalArgumentException("name is required");
}
if (age < 0) {
thrownewIllegalArgumentException("age must not be negative");
}
if (roles == null) {
thrownewIllegalArgumentException("roles are required");
}
roles = List.copyOf(roles);
}
}
publicstaticvoidmain(String[] args) {
Userfirst=newUser("Maya", 30, List.of("ADMIN"));
Usersecond=newUser("Maya", 30, List.of("ADMIN"));
System.out.println(first.name());
System.out.println(first.equals(second));
System.out.println(first);
}
}
Why Interviewers Ask This
Interviewers ask this question to check whether a candidate understands concise data modeling, generated record members, value based equality, shallow immutability, constructor rules, inheritance limits, and when a record is a better design choice than a normal class.
Common interview mistakes
A common mistake is calling records deeply immutable. Their component fields are final, but a component can still refer to a mutable object. Another mistake is expecting JavaBean accessors such as getName; the generated accessor is name. Candidates may also forget that records are final, cannot extend another class, cannot declare extra instance fields, and are not automatically faster or smaller than equivalent normal classes. Using an array component without considering identity based array equality is another common error.
Interview tip
Start by saying that a record is best for a value centered data carrier. Then name the generated members, explain value based equality, mention shallow immutability, and finish with one suitable use case and one reason to choose a normal class.
Interviewer may ask next
Is a Java record deeply immutable?
No. A record is only shallowly immutable. Each component field is final, so its primitive value or object reference cannot be reassigned after construction. However, an object referenced by a component can still change. This matters for lists, maps, arrays, and other mutable values. Use immutable component types or defensive copies when later changes must not affect the record. Even then, mutable objects inside a copied collection are not deeply copied.
When should you choose a normal class instead of a record?
Choose a normal class when the object needs changing fields, identity based equality, hidden instance state, extra instance fields, inheritance from another class, or framework support that depends on setters or a no argument constructor. The tradeoff is more code, but a normal class gives greater control over representation, lifecycle, inheritance, and behavior.
75. What are sealed classes in Java?Language SpecificHard
i Question Details
Explain sealed classes, permitted subclasses, and how they help control type hierarchies.
Short Interview Answer (30-60 seconds)
Sealed classes let me control which classes may directly extend a class, and sealed interfaces do the same for direct implementing classes and child interfaces. I declare the parent as sealed and identify its permitted direct children, either explicitly or through same source file inference. Each permitted child must then be final, sealed, or use the Java modifier formed from non, a hyphen character, and sealed. This is useful for controlled domain models and exhaustive pattern matching.
Detailed Explanation
Sealed classes let the owner of a Java design decide which named types may directly inherit from a parent type. This is useful when a business idea has a small and known set of forms. For example, a payment result may only be Success, Failure, or Pending. Other code cannot add an unexpected direct form unless the parent allows it. This keeps the model clear, protects important rules, and helps later code handle every allowed form. It is a way to keep extension controlled without closing inheritance completely.
Useful Questions to Ask the Interviewer
Should I explain sealed interfaces as well as sealed classes?
Should I include exhaustive pattern matching with switch?
Should I cover package, module, and runtime enforcement rules?
How to Explain It in an Interview
A sealed class defines a controlled inheritance hierarchy. A sealed interface provides the same control over its direct implementing classes and direct child interfaces. The parent uses the sealed modifier.
The permitted direct children can be written in a permits clause. Java may infer them when they are declared in the same compilation unit as the sealed parent and directly extend or implement it. The permitted set must not be empty.
Every permitted direct child must state how its own branch continues. A final child cannot be extended. A sealed child defines another controlled set of direct children. A child using the modifier formed from non, a hyphen character, and sealed reopens its branch for further inheritance. The original sealed parent controls only its direct children, not every later descendant.
A permitted child must directly extend or implement the sealed parent. In a named module, the sealed parent and its permitted direct children must be in the same module. In an unnamed module, they must be in the same package.
Java records the permitted children in the class file. The compiler rejects an unauthorized direct child when source is compiled. The JVM also enforces the restriction when classes are loaded, so invalid or incompatible class files cannot bypass the rule.
Sealing does not change normal object creation, method dispatch, equality, or mutability. It adds no per object field, copying step, or special allocation. Its main cost is design coupling. Adding a new permitted type may require updates to exhaustive switch expressions and other code that handles every known case.
Use sealed types for controlled domain outcomes, workflow states, commands, or syntax tree nodes. Avoid them for plugin contracts or public extension points where unknown third parties must add implementations.
Why Interviewers Ask This
Interviewers ask this question to check whether the candidate understands controlled inheritance in modern Java. They are evaluating knowledge of permitted direct children, compiler and runtime enforcement, package and module restrictions, exhaustive pattern matching, and the design judgment needed to choose between a closed hierarchy and an open extension point.
Common interview mistakes
A common mistake is treating sealed and final as the same feature. A final class allows no subclasses, while a sealed class allows a selected set of direct subclasses. Another mistake is forgetting that every permitted direct child must declare final, sealed, or the Java modifier formed from non, a hyphen character, and sealed. Developers may also think the permits list controls every descendant, but it controls only direct children. Other mistakes include placing a permitted child in an invalid module or package, assuming any class in the permits list may inherit indirectly, and believing sealing makes objects immutable, thread safe, or faster.
Interview tip
Start with the practical purpose: sealed classes restrict direct inheritance to a known set of types. Then explain permits, same source file inference, and the three choices available to each permitted child. Finish with one production benefit, such as a controlled domain model or exhaustive pattern matching, and one tradeoff, such as reduced extensibility.
Interviewer may ask next
What happens if an unauthorized class tries to extend a sealed class?
The extension is rejected. The Java compiler reports an error when it compiles source that names a sealed parent without being a permitted direct child. The JVM also checks the permitted subclass information when classes are loaded, so incompatible class files can fail with IncompatibleClassChangeError. This matters because the restriction is not only a source code convention. It remains enforced at runtime even when classes were compiled separately.
When should you choose a sealed interface instead of a normal interface?
Choose a sealed interface when all valid direct implementations and child interfaces are intentionally known and controlled. This supports stronger domain rules and can allow an exhaustive pattern matching switch without a user written default case. Choose a normal interface when plugins, customers, frameworks, or external libraries must add implementations freely. The main tradeoff is control versus extensibility. A sealed hierarchy is easier to reason about, but adding a new permitted type may require updates to code that handles every known case.
76. What is pattern matching in newer Java versions?Language SpecificHard
i Question Details
Explain pattern matching features in modern Java and how they simplify type checks and branching.
Short Interview Answer (30-60 seconds)
Pattern matching lets Java test a value and extract useful data in one operation. In Java 21, permanent features include type patterns for instanceof, pattern matching for switch, and record patterns. They remove repeated casts and make data based branching clearer. I still need to handle null, pattern scope, case order, exhaustiveness, generic type erasure, and sealed hierarchy evolution. Java 25 also has primitive patterns as a preview feature, so they require preview options and careful production approval.
Pattern matching helps a program inspect a value, decide what form it has, and immediately use the information inside it. Older Java code often needed one statement to check a value and another statement to convert it before using it. Modern Java can combine those actions. This reduces repeated code and makes each branch easier to read. It is useful when a program receives several related forms of data and must respond differently to each one. The compiler also rejects several unsafe, impossible, or incomplete branches before the program runs.
Useful Questions to Ask the Interviewer
Should I focus on permanent Java 21 features?
Should I also discuss Java 25 preview features?
Should the example include null and sealed types?
How to Explain It in an Interview
Pattern matching combines a condition with variable binding. A type pattern such as value instanceof String text checks the runtime type and creates text only on paths where the match succeeds. A null value does not match an instanceof type pattern.
Java 21 made record patterns and pattern matching for switch permanent. A switch case can match a type, bind variables, and use a when guard for an additional condition. A record pattern can deconstruct a record into its components. For example, case Circle(double radius) reads the radius component and binds it to a local variable. These Java 21 features are permanent language features. ([openjdk.org](https://openjdk.org/jeps/441?utm_source=chatgpt.com))
Java checks case dominance. A broad unguarded pattern cannot appear before a narrower pattern that it would always capture. A guarded pattern normally appears before the matching unguarded pattern. Enhanced switch statements and switch expressions must also be exhaustive. Sealed types help because the compiler knows their permitted implementations. ([docs.oracle.com](https://docs.oracle.com/javase/specs/jls/se21/html/jls-14.html))
Null needs an explicit decision. In a pattern switch over a reference, case null handles null. Without a matching null case, a null selector causes NullPointerException. A type pattern does not silently match null.
Use pattern matching for data based processing, especially with records and sealed hierarchies. Prefer dynamic dispatch when each subtype owns its behavior. Pattern matching does not bypass generic type erasure, so a pattern such as List<String> is not allowed as a reifiable runtime type check.
The language does not require pattern binding or record deconstruction to allocate a new object. It reuses the matched value and binds local variables. Runtime cost is generally similar to the equivalent explicit type checks, casts, accessor calls, and branches, but exact optimization is a JVM implementation detail.
Java 25 primitive patterns are a third preview feature. They require preview options during compilation and execution and should be used in production only under an explicit preview feature policy. ([openjdk.org](https://openjdk.org/jeps/507?utm_source=chatgpt.com))
Interviewers ask this question to check whether a candidate understands modern Java type testing, safe variable binding, record deconstruction, switch exhaustiveness, null behavior, pattern scope, and case dominance. They also want to see whether the candidate can distinguish permanent language features from preview features and choose pattern matching only when it makes production code clearer.
Common interview mistakes
Common mistakes include forgetting that a type pattern does not match null, omitting case null when null is a valid input, placing a broad unguarded case before a narrower case, placing an unguarded pattern before its guarded form, and writing a nonexhaustive enhanced switch. Other mistakes include using a pattern variable outside its valid scope, trying to match a nonreifiable generic type such as List<String>, assuming deconstruction copies a record, and presenting Java 25 primitive patterns as permanent. A production edge case is evolving a sealed hierarchy without recompiling dependent switches. An older exhaustive switch can throw MatchException when it receives a newly permitted subtype that was unknown when the switch was compiled. ([docs.oracle.com](https://docs.oracle.com/javase/specs/jls/se21/html/jls-13.html))
Interview tip
Start with the practical benefit: Java combines checking and extraction. Then name the permanent Java 21 features. Explain null handling, dominance, exhaustiveness, and generic type erasure. Finish by labeling Java 25 primitive patterns as preview and by stating when dynamic dispatch is a better design.
Interviewer may ask next
What happens when a pattern switch receives null or a new sealed subtype?
Null matches only an applicable case null label. Without one, a null selector causes NullPointerException before ordinary type patterns are considered. A separate production edge case occurs when a sealed hierarchy gains a permitted subtype after a dependent exhaustive switch was compiled. If the old switch receives that new subtype without recompilation, it can throw MatchException. This matters because compile time exhaustiveness is based on the hierarchy visible during compilation. ([docs.oracle.com](https://docs.oracle.com/javase/specs/jls/se21/html/jls-14.html))
Does pattern matching improve performance or reduce memory use?
Pattern matching mainly improves clarity and compile time safety, not guaranteed performance. It usually performs the same logical runtime work as explicit type checks, casts, accessor calls, and branches. The language does not require a new object allocation merely to bind a pattern variable or deconstruct a record. The JVM may optimize the code, but production decisions should be based on readability and measured application performance rather than an assumed speed or memory advantage.
77. How do Java modules work in the JPMS?Language SpecificHard
i Question Details
Explain modules, exports, requires, and how JPMS changes packaging and encapsulation.
Short Interview Answer (30-60 seconds)
JPMS groups packages into named modules with explicit dependency and access rules. A module uses requires to declare which other modules it reads, and exports to expose selected packages. A public type is not accessible from another named module unless its package is exported and the consuming module reads the provider. Modular applications normally use the module path, which lets Java resolve the module graph and reject missing or conflicting dependencies before application code runs.
Detailed Explanation
Java modules divide a large program into named parts with clear boundaries. Each part declares which other parts it needs and which packages other parts may use. Packages still organize related classes, but a module groups packages and controls access between them. This helps teams hide implementation code, document dependencies, and find missing parts before normal application work begins. It is most useful for large applications, reusable libraries, and custom Java runtimes where clear boundaries matter.
Useful Questions to Ask the Interviewer
Will every dependency be a named module?
Does the application use frameworks that need deep reflection?
Must the application support older nonmodular JAR files?
How to Explain It in an Interview
A JPMS module is a named group of packages, resources, and a module descriptor. The descriptor declares the module name and its relationships with other modules.
The requires directive creates a readability relationship. For example, if com.example.app requires com.example.service, the application module can read the service module. Reading the module is not enough by itself. The service module must also export the package containing the type, and normal Java access rules still apply.
The exports directive exposes a package for normal compiled access. An unqualified export exposes it to every module that reads the provider. A qualified export exposes it only to named target modules. Packages that are not exported remain strongly encapsulated from normal access, even when they contain public classes.
The opens directive serves a different purpose. It permits deep reflection into a package at runtime. A qualified opens directive limits that permission to selected modules. An open module opens all its packages for deep reflection. Opening a package does not make it available for normal compiled access.
The requires transitive form also lets modules that depend on the current module read the named dependency. It is useful when a public API exposes types from that dependency. The requires static form makes a dependency mandatory during compilation but optional during runtime resolution.
Java resolves a graph from root modules and their dependencies. A missing required module or an invalid graph causes resolution to fail before the main application code runs. JPMS does not select library versions or download artifacts. Maven and Gradle handle those build concerns.
A modular JAR contains a compiled module descriptor and normally runs from the module path. A plain JAR on the module path can become an automatic module. Automatic modules help migration, but their names and broad access rules make them a temporary compatibility tool rather than the best final design.
Why Interviewers Ask This
Interviewers ask this question to check whether a candidate understands module readability, package accessibility, strong encapsulation, dependency resolution, and modular packaging. It also tests whether the candidate can separate JPMS responsibilities from Maven or Gradle dependency management and can handle reflection, legacy libraries, and production migration safely.
Common interview mistakes
A common mistake is assuming that public means accessible everywhere. Across named modules, the provider must export the package and the consumer must read the provider. Another mistake is treating requires as a Maven or Gradle dependency declaration. JPMS does not download artifacts or choose versions. Developers also confuse exports with opens. Exports supports normal access to public types, while opens permits deep reflection at runtime. Other mistakes include exporting implementation packages, opening the whole module without need, relying permanently on automatic module names, placing a modular JAR on the class path and expecting module boundaries to apply, and creating split packages across modules in one resolved configuration.
Interview tip
Start with the two checks: the consumer must read the provider, and the provider must export the package. Then explain that exports controls normal access, opens controls deep reflection, and the module path enables graph resolution. Finish with one production tradeoff, such as migration problems with automatic modules or reflection based frameworks.
Interviewer may ask next
Can one named module access a public class in a package that another named module does not export?
No, normal compiled access is denied. The consuming module must read the providing module, the providing module must export the package to that consumer, and the class itself must satisfy normal Java access rules. This matters because public classes can remain implementation details when their package is not exported. A command line export override can bypass the module boundary for migration or testing, but depending on that override weakens encapsulation and makes deployment configuration part of the application contract.
What is the production tradeoff between JPMS and keeping an application on the class path?
JPMS provides explicit readability, strong package encapsulation, early module graph validation, and support for custom runtime images. The class path is simpler and is often easier for older libraries and reflection heavy frameworks. The main tradeoff is migration and configuration work. Teams may need module descriptors, opens directives, stable module names, and tests for every runtime path. JPMS is most valuable when enforceable component boundaries and controlled packaging justify that added work.
78. What is method overloading?Language SpecificEasy
i Question Details
Explain method overloading and the rules Java uses to choose the correct overload.
Short Interview Answer (30-60 seconds)
Method overloading means declaring multiple methods with the same name but different parameter lists. Java chooses the overload at compile time from the argument expressions, using applicability rules and then selecting the most specific applicable method. A different return type alone does not create an overload. I use overloading when the methods perform the same logical operation for different input forms, but I avoid combinations that make calls ambiguous.
Method overloading lets a Java class use one method name for several closely related operations. Each version accepts a different number, type, or order of input values. When Java compiles a call, it checks which versions can accept the supplied values and chooses the best valid match. This can make an API easier to read because callers use one clear action name. However, overloads with similar input types can confuse both the compiler and developers, so each version should have the same purpose and an obvious selection rule.
Useful Questions to Ask the Interviewer
Should I explain primitive conversion, boxing, and variable argument rules?
Should I include ambiguity examples involving null and unrelated reference types?
How to Explain It in an Interview
Method overloading occurs when methods have the same name but different parameter lists. The parameter lists may differ by parameter count, parameter types, or parameter order. The return type is not enough because Java does not use the expected return value to distinguish ordinary method overloads.
Java resolves an overloaded call at compile time. It first searches in phases. The first phase considers fixed arity methods that work through identity conversion or widening primitive or reference conversion. If none apply, the next phase also permits boxing, unboxing, and the related widening conversions allowed by method invocation. If no fixed arity method applies, Java considers variable arity methods. Within the first successful phase, Java chooses the most specific applicable method. If no single method is more specific, compilation fails because the call is ambiguous.
For example, describe(10) selects describe(int), while describe(10L) selects describe(long). A String argument selects describe(String) instead of describe(Object) because String is more specific. However, if an expression is declared as Object, Java selects describe(Object) even when the referenced object is a String. Overload resolution uses the compile time type of the expression, not the runtime class of the object.
A null literal can match any reference parameter. Between String and Object, String is more specific. Between unrelated types such as String and StringBuilder, neither is more specific, so the call is ambiguous.
Overloading itself adds no special object allocation and no runtime search among overloads. The compiled call already identifies a method descriptor. Boxing or variable arguments may still create wrapper objects or an array when those conversions are used. Existing compiled code keeps calling its original descriptor, but recompiling source after adding an overload can select a different method.
Interviewers ask this question to check whether the candidate understands method signatures, compile time overload resolution, allowed argument conversions, ambiguity, and the difference between overloading and overriding. It also tests whether the candidate can design clear Java APIs without creating overloads that are surprising or difficult to maintain.
Common interview mistakes
A common mistake is changing only the return type and expecting Java to treat the method as a new overload. Another mistake is expecting the runtime class of an object to control overload selection. Java uses the compile time type of each argument expression. Developers also create ambiguous calls by combining null with unrelated reference types or by mixing primitive types, wrapper types, and variable arguments without checking the resolution phases. Another mistake is using one method name for operations that have different meanings.
Interview tip
Begin with the definition, then say that Java resolves overloads at compile time and chooses the most specific applicable method from the first successful resolution phase. Mention that return type alone is not enough. Finish with one simple example and one null ambiguity example.
Interviewer may ask next
What happens when null is passed to overloaded methods with different reference parameter types?
Java selects a method only when one applicable reference parameter type is more specific than the others. Between String and Object, it selects String because every String is also an Object. Between unrelated types such as String and StringBuilder, neither method is more specific, so compilation fails with an ambiguous call. This matters because adding a new reference overload can make a previously valid null call fail when the source is recompiled.
What performance or allocation effects can boxing and variable arguments introduce during overload selection?
Overloading itself does not require a runtime search or special allocation because the compiler records the selected method descriptor. However, a selected overload that requires boxing may create or reuse a wrapper object according to normal boxing rules, and a variable argument call may create an array for the supplied arguments. Fixed arity methods are considered before variable arity methods, so clear fixed arity overloads can avoid some variable argument allocations, but too many overloads can make the API harder to understand.
79. What is method overriding?Language SpecificEasy
i Question Details
Explain method overriding and how dynamic dispatch works when a subclass replaces parent behavior.
Short Interview Answer (30-60 seconds)
Method overriding happens when a subclass provides its own implementation of an inherited instance method with the same signature. When code calls that method through a parent reference, Java runs the most specific override for the actual object at runtime. This is dynamic dispatch. It lets related object types provide different behavior through one common parent type or interface.
Method overriding lets a more specific object replace behavior received from a more general object. For example, a general animal can have a sound action, while a dog provides its own sound. A variable may use the general animal type, but the action still comes from the real dog object stored in it. This allows the same calling code to work with many related object types without checking every type by hand. It keeps each behavior inside the object that owns it and makes a program easier to extend.
Useful Questions to Ask the Interviewer
Should the example use a parent class, an abstract class, or an interface?
Should I also compare overriding with overloading?
Do you want the rules for access, return types, and exceptions?
How to Explain It in an Interview
In Java, method overriding occurs when a subclass declares an instance method that overrides an inherited instance method. The method name and parameter types must match. The return type must be the same type or a compatible subtype. The overriding method cannot use a more restrictive access level. It may declare fewer checked exceptions or narrower checked exceptions, but it cannot add a broader checked exception than the parent method allows.
Dynamic dispatch means Java chooses the implementation at runtime. The reference type controls which methods the compiler allows the code to call. The actual object type controls which overridden instance method runs. If an Animal reference points to a Dog object, calling sound runs the most specific sound override found for Dog.
The Override annotation should be used because the compiler then verifies that the method really overrides another method. Static methods are hidden, not overridden. Private methods are not inherited, so they cannot be overridden. Final methods cannot be overridden. Constructors and fields also do not use method overriding.
Overriding is useful when related classes follow one contract but need different behavior. The subclass should still honor the meaning promised by the parent contract. Avoid inheritance when the types do not have a true substitutable relationship. Composition is often clearer in that case.
An overridden call does not copy the object and does not require a new object allocation. It has a small method selection cost, but the JVM can often optimize stable call targets through runtime compilation and inlining. A dangerous edge case is calling an overridable method from a constructor because the subclass method can run before the subclass is fully initialized.
Interviewers ask this question to check whether the candidate understands inheritance, replacement of inherited behavior, and runtime method selection. It also tests whether the candidate can distinguish overriding from overloading and apply Java rules for method signatures, access levels, return types, exceptions, static methods, private methods, and final methods.
Common interview mistakes
Common mistakes include changing the parameter types and accidentally overloading the method instead of overriding it, reducing the access level, or declaring a broader checked exception. Another mistake is expecting static methods, private methods, constructors, or fields to use dynamic dispatch. Developers may forget the Override annotation and miss a signature error. They may also call an overridable method from a constructor, which can run subclass code before subclass fields are initialized. A broader design mistake is creating deep inheritance where subclasses cannot safely honor the parent contract.
Interview tip
Start with the practical rule that the actual object decides which overridden instance method runs. Then show a parent reference pointing to a subclass object. Briefly explain that the signature must match, recommend the Override annotation, and distinguish overriding from static method hiding and method overloading.
Interviewer may ask next
What happens if a subclass declares a static method with the same signature as a static parent method?
It is method hiding, not method overriding. Java selects a static method using the reference type or class name rather than the actual object type. Dynamic dispatch therefore does not apply. This matters because changing the object stored in a parent reference does not change which hidden static method is selected. Calling static methods through their class names makes the behavior clear.
Does method overriding add significant performance or memory cost in production?
No, method overriding normally adds only a small runtime method selection cost and does not require a new object allocation or object copy for each call. The JVM can often optimize common call targets through runtime compilation and inlining. The main tradeoff is design complexity. Deep inheritance and surprising overrides can make behavior difficult to understand, so production code should use clear contracts and prefer composition when inheritance is not a natural substitutable relationship.
80. What is Big O notation, and why does it matter when comparing Java solutions?NEWCodingEasy
i Question Details
Define Big O notation as a way to describe how an algorithm's time or extra-space use grows as input size grows. Explain O(1), O(log n), O(n), O(n log n), and O(n²) with small Java examples, distinguish worst-case growth from exact runtime, and show how input constraints and data-structure operations guide solution choice.
Short Interview Answer (30-60 seconds)
Big O tells me how an algorithm’s time or extra memory grows as input size n grows. It compares growth, not exact seconds. O(1) stays constant, O(log n) grows slowly, O(n) grows with n, O(n log n) is common for sorting, and O(n²) grows much faster. In the diagram’s one-pass Java example, I visit each element once. That gives O(n) time and O(1) auxiliary space, which scales better than nested loops for large inputs.
This question asks how we compare Java solutions when the input becomes larger. Big O describes how the amount of work or extra memory grows. It does not tell us the exact number of milliseconds a program will take. The diagram compares O(1), O(log n), O(n), O(n log n), and O(n²). Lower growth usually matters more as n becomes large. Its concrete Java example is one pass through an array. Each element is visited once, so the work grows directly with the number of elements.
Useful Questions to Ask the Interviewer
Should I compare both time complexity and auxiliary space complexity?
Should I use worst-case growth unless an operation is specifically average-case, such as HashMap lookup?
What input-size constraints should I consider when choosing between solutions?
How to Explain It in an Interview
1. Start with what Big O means
Big O describes how time or extra memory grows as input size n grows. It describes a growth rate. It is not an exact runtime measurement. Two O(n) Java programs can take different numbers of milliseconds, but their work grows in the same general way as n becomes larger.
2. Compare the five growth rates
O(1) means constant growth. The amount of work does not grow with n. The diagram uses map.get(key) as an average-case HashMap lookup example.
O(log n) means the remaining search space becomes much smaller at each step. The diagram uses binary search on sorted data. For a random-access list such as ArrayList, binary search needs O(log n) comparisons and efficient indexed access.
O(n) means the work grows in direct proportion to n. A one-pass ArrayList or array scan is the diagram’s example.
O(n log n) grows faster than a simple scan but much slower than O(n²). The diagram uses Collections.sort(list), labeled with TimSort, as the Java example.
O(n²) often appears when one loop of up to n iterations is nested inside another loop of up to n iterations. The diagram shows this nested-loop pattern.
3. Walk through the one-pass Java example
The diagram shows for (int x : nums) sum += x;. Before the loop, the running total starts at zero. The loop reads one array element at a time. It adds the current value to sum, then moves to the next element. The state after each iteration is simple: sum contains the total of all values processed so far. Processing stops after the last element.
4. Explain why the one-pass loop is O(n)
If the array has n elements, the loop body runs n times. Each iteration performs a constant amount of work. Doubling n roughly doubles the number of loop iterations. That is why the time complexity is O(n).
5. Explain the auxiliary space
The loop uses only a running total and the current loop value. The number of these variables does not increase as n grows. The input array is not counted as auxiliary space because it already exists before the algorithm starts. The auxiliary space is therefore O(1).
6. Use constraints and Java operation costs to choose a solution
For small inputs, several approaches may be fast enough. For large inputs, the growth rate becomes much more important. An O(n²) solution becomes expensive much faster than O(n) or O(n log n). Java operation costs also guide the choice. HashMap lookup is O(1) on average. Binary search is O(log n) when used with suitable sorted random-access data. A full scan is O(n). Sorting is commonly O(n log n). The diagram therefore shows why input constraints and data-structure operations matter when comparing solutions.
Key Insight / Why This Solution Works
The concrete algorithm in the diagram is a one-pass scan. It processes each element once and updates a running sum. The central invariant is: after each iteration, sum equals the total of all array values processed so far. Each iteration performs constant work, so n elements require O(n) time. Only a fixed number of variables are kept, so auxiliary space is O(1). The wider Big O comparison explains why this linear growth is usually more suitable than O(n²) nested-loop growth when input constraints are large.
Code
publicclassMain {
publicstaticintsum(int[] nums) {
// Start with no values processed, so the running total is zero.intsum=0;
// Visit each element exactly once.// After every iteration, sum contains the total of all values seen so far.for (int x : nums) {
// Add the current array value to the running total.
sum += x;
}
// All elements have now been processed, so return the final total.return sum;
}
publicstaticvoidmain(String[] args) {
// The diagram shows n = 5 as one example input size.// It does not specify the five numeric values, so this array is used only// to execute the same one-pass loop with that visible input size.int[] nums = newint[5];
// Run the exact O(n) one-pass algorithm shown in the diagram.
sum(nums);
}
}
Time & Space Complexity
The one-pass example takes O(n) time. If there are n elements, it visits n elements once. If n roughly doubles, the amount of loop work roughly doubles. It uses O(1) auxiliary space because only a few variables are needed, and that number does not grow with n. Big O describes growth, not exact running time. The diagram also shows HashMap lookup as O(1) on average. That average-case wording is important because constant-time HashMap access is not guaranteed for every possible case.
Where it is used
Big O is useful whenever engineers compare algorithms or Java data structures for inputs that may grow. It helps compare choices such as a HashMap lookup, binary search on suitable sorted data, a linear scan, sorting, or nested loops. The one-pass O(n) pattern shown in the diagram is common for totals, counts, minimums, maximums, and other calculations that can be updated while each element is read once.
Why Interviewers Ask This
The interviewer is checking whether you can compare solutions by how they scale instead of only by code length or one measured runtime. They want you to understand O(1), O(log n), O(n), O(n log n), and O(n²), and to connect those classes to common Java operations. They also want accurate reasoning about average-case HashMap behavior, auxiliary space, input constraints, and why a lower growth rate can matter when n becomes large.
Common interview mistakes
One mistake is treating Big O as an exact runtime in seconds. Another is forgetting that Big O describes growth as n increases. Candidates may also call HashMap lookup guaranteed O(1) instead of O(1) on average. Another mistake is ignoring sorting cost before a later scan. It is also wrong to call two full nested loops O(n) when both can run up to n times, because that pattern is O(n²). Finally, candidates should distinguish the input memory from auxiliary space used by the algorithm.
Interview tip
Explain the growth classes from smaller growth to larger growth, connect each class to the Java examples in the diagram, and then use the one-pass loop to show exactly why one visit per element gives O(n) time and O(1) auxiliary space.
Interviewer may ask next
Why can one O(n) Java solution still run faster than another O(n) solution?
Big O focuses on growth and hides constant factors and lower-order work. Two algorithms can both be O(n) but do different amounts of work for each element. JVM behavior, allocations, cache effects, and the operations inside the loop can also affect exact runtime. They still belong to the same O(n) growth class because their work grows linearly with n.
Why is Java HashMap lookup described as O(1) on average instead of guaranteed O(1)?
HashMap uses a hash value to choose where a key should be stored or found. With a good distribution of keys, lookup is O(1) on average. Hash collisions can place multiple entries in the same bucket, so constant-time lookup is not guaranteed in every case. That is why the diagram correctly labels HashMap lookup as average-case O(1).
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.