← Back to Interview Prep

Java Troubleshooting Q&A

50 Java scenario-based interview questions with expert answers — covering OOM errors, GC tuning, deadlocks, classloading, JVM profiling, Spring, Hibernate, and Tomcat.

10 Memory & GC10 Concurrency10 Classloading & Exceptions10 JVM Profiling10 Spring & Frameworks
1

Memory & Garbage Collection (OOM & Leaks)

Q1.Your production application crashes with java.lang.OutOfMemoryError: Java heap space. How do you troubleshoot this?

  • Start the JVM with -XX:+HeapDumpOnOutOfMemoryError to automatically generate a heap dump on crash.
  • Load the .hprof file into Eclipse MAT (Memory Analyzer Tool) or VisualVM.
  • Use the "Leak Suspects" report to identify which objects are retaining the most memory and trace them back to GC roots.

Q2.You encounter OutOfMemoryError: Metaspace. What causes this and how is it fixed?

  • Happens when the JVM runs out of space for class metadata (loaded classes).
  • Common in apps that dynamically generate many classes (proxies, reflection, hot-deployments).
  • Fix: increase Metaspace using -XX:MaxMetaspaceSize=256m, or investigate classloader leaks via heap dumps.

Q3.The application logs show OutOfMemoryError: GC overhead limit exceeded. What does this mean?

  • The JVM is spending more than 98% of its time doing Garbage Collection and recovering less than 2% of the heap.
  • Symptom of a severe memory leak or a heap vastly too small for the workload.
  • Analyze a heap dump to find the leak, or increase heap size as a temporary mitigation.

Q4.Your server CPU usage is hovering at 100%, but traffic is very low. How do you confirm if Garbage Collection is the culprit?

  • Run: jstat -gcutil <pid> 1000 to monitor GC activity every second.
  • If Full GC (FGC) count rapidly increases and time in GC (FGCT) dominates, the application is thrashing.
  • Enable GC logging (-Xlog:gc* in Java 9+) for deeper analysis.

Q5.You suspect a memory leak because heap usage steadily grows over a week without dropping after Full GCs. How do you find the leak without crashing the app?

  • Trigger a live heap dump: jcmd <pid> GC.heap_dump /path/dump.hprof
  • Alternatively: jmap -dump:live,format=b,file=dump.hprof <pid>
  • Analyze with Eclipse MAT. Compare two dumps taken hours apart to find which object counts are strictly increasing.

Q6.Your app throws OutOfMemoryError: Direct buffer memory. What is this and how do you fix it?

  • Native memory allocated via ByteBuffer.allocateDirect() (used by NIO frameworks like Netty or Tomcat) is exhausted.
  • Fix: increase the direct memory limit using -XX:MaxDirectMemorySize.
  • Check for unclosed I/O streams or NIO buffers that are never released.

Q7.A developer used ThreadLocal variables but forgot to call .remove(). What is the consequence?

  • Causes a memory leak — especially in web servers (like Tomcat) that use thread pools.
  • The thread does not die when the request ends, so the ThreadLocal object remains referenced and cannot be GC'd.
  • Always call .remove() in a finally block.

Q8.You need to cache images in memory but want to ensure the JVM does not crash if memory gets tight. What Java feature do you use?

  • Use SoftReference — objects wrapped in SoftReference are kept in memory as long as possible.
  • The GC will clear them before throwing an OutOfMemoryError.
  • Note: Guava Cache or Caffeine are preferred in modern applications.

Q9.The JVM crashes but there is no OutOfMemoryError in the logs. The Linux OS shows the process was killed. What happened?

  • The Linux OOM Killer terminated the Java process.
  • Happens when total memory (Heap + Metaspace + Thread Stacks + Native Memory) exceeds physical RAM or container limits (Docker/Kubernetes).
  • Tune container memory limits and JVM -Xmx settings to leave room for native memory.

Q10.You are tuning G1GC and notice latency spikes due to long pause times. How do you instruct G1GC to prioritize shorter pauses?

  • Set the target maximum pause time: -XX:MaxGCPauseMillis=200 (200ms is the target).
  • G1GC will adjust young generation size and mixed GC frequency to attempt to meet this target.
2

Concurrency & Multithreading

Q11.Your application suddenly stops processing requests entirely, but CPU usage is 0%. What is likely happening and how do you prove it?

  • Classic symptom of a Deadlock.
  • Generate a thread dump: jstack <pid> > thread_dump.txt or jcmd <pid> Thread.print
  • Scroll to the bottom — the JVM will explicitly state "Found one Java-level deadlock" and list the threads and locks involved.

Q12.CPU usage is at 100%. You know it is a Java app, but you do not know which thread is causing it. How do you isolate the thread on Linux?

  • Run: top -H -p <pid> to get the native thread ID (NID) consuming the most CPU.
  • Convert that NID from decimal to hexadecimal.
  • Take a jstack dump and search for that hex NID — it points to the exact line of Java code looping endlessly.

Q13.You are iterating over an ArrayList and removing elements. You suddenly get ConcurrentModificationException. Why?

  • You cannot modify a standard Collection directly while iterating with a for-each loop.
  • Fix options: use Iterator and call iterator.remove(), use CopyOnWriteArrayList, or use Java 8+ list.removeIf(condition).

Q14.Multiple threads are updating a shared integer counter. The final count is lower than expected. How do you resolve this?

  • This is a race condition — the ++ operator is not atomic.
  • Fix: use AtomicInteger and its incrementAndGet() method.
  • Alternatively, wrap the increment inside a synchronized block.

Q15.Thread dumps show dozens of threads in BLOCKED state waiting to acquire a monitor on a specific class. What is the design flaw?

  • A synchronized block surrounds a slow or blocking operation (like an HTTP call or DB query).
  • Fix: reduce the synchronized scope to only the shared-state mutation.
  • Or replace with ReentrantLock or asynchronous patterns.

Q16.You submit 1000 tasks to an ExecutorService with a fixed thread pool of 10. The app crashes with RejectedExecutionException. Why?

  • The work queue associated with the thread pool has reached its maximum capacity.
  • Fix: increase the queue size, use CallerRunsPolicy to handle overflow, or increase the number of worker threads.

Q17.What is the difference between a thread in WAITING state and one in BLOCKED state in a thread dump?

  • BLOCKED: thread is trying to enter a synchronized block but another thread holds the monitor lock.
  • WAITING: thread is voluntarily waiting for a signal (e.g., Object.wait(), Thread.join(), or Condition.await()).

Q18.You catch an InterruptedException while a thread is sleeping. What is the best practice for handling it?

  • Never swallow it with an empty catch block.
  • Either re-throw it as-is, or if you must catch it, immediately call Thread.currentThread().interrupt() to restore the interrupted status.
  • This ensures higher-level methods know the thread was requested to stop.

Q19.A background thread writes logs to a file. Sometimes the thread dies silently and logging stops. How do you catch unhandled exceptions in threads?

  • Set an UncaughtExceptionHandler on the Thread or the ThreadFactory.
  • This defines a fallback method that logs the exception and stack trace before the thread terminates.

Q20.Two threads are transferring money between accounts. Thread A locks Account 1, Thread B locks Account 2. They deadlock. How do you prevent this?

  • Enforce a strict lock-ordering strategy.
  • Always lock accounts in a consistent order regardless of transfer direction (e.g., always lock the lower Account ID first).
  • This breaks the circular wait condition required for a deadlock.
3

Classloading & Exceptions

Q21.You encounter ClassNotFoundException vs NoClassDefFoundError. What is the difference?

  • ClassNotFoundException: thrown when explicitly loading a class at runtime via Class.forName() and it is missing from the classpath.
  • NoClassDefFoundError: fatal error — the class was present at compile time but cannot be found (or failed to initialize in a static block) at runtime.

Q22.Your app throws a NullPointerException on a chained call like a.getB().getC().doSomething(). How do you identify which object is null?

  • Java 14+ enables Helpful NullPointerExceptions by default — the message states exactly which method returned null.
  • Example: "Cannot invoke C.doSomething() because the return value of B.getC() is null".
  • Before Java 14: break the chain into multiple lines to isolate the null.

Q23.You deploy a new .jar file and get NoSuchMethodError. The method exists in source code. What is wrong?

  • Classic Dependency Hell — the JVM loaded an older version of the class from another jar on the classpath.
  • Run: mvn dependency:tree to find and exclude the transitive dependency pulling in the old jar.

Q24.A developer wrote a recursive function resulting in a StackOverflowError. How do you troubleshoot and fix it?

  • The stack trace shows the same method repeated — that confirms infinite recursion.
  • Fix: rewrite as an iterative loop using a while loop and a Stack object.
  • If deep recursion is legitimately needed, increase thread stack size: -Xss2m.

Q25.You try to run a compiled .class file and get UnsupportedClassVersionError. What causes this?

  • You compiled with a higher JDK version (e.g., Java 17) but run it on a lower JRE (e.g., Java 11).
  • Fix: upgrade the runtime environment, or compile with --release 11 flag to target the older version.

Q26.Your app communicates with a third-party API and throws SocketTimeoutException. Is the problem on your end or theirs?

  • Usually theirs — SocketTimeoutException means the TCP connection was established but the server took too long to respond (Read Timeout).
  • If you get ConnectException instead, the connection could not be established (firewall, wrong port, server down).

Q27.What causes an IllegalArgumentException when using Java Reflection to invoke a method?

  • Passing wrong number of arguments, wrong argument types, or a null/wrong-class object as the target instance.

Q28.While parsing a large XML or JSON file, you get an OutOfMemoryError. How should you rewrite the parsing logic?

  • You are likely using DOM parsing — it loads the entire document into memory.
  • Switch to SAX or StAX (streaming XML) or Jackson Streaming API (JsonParser) for JSON.
  • These process data token-by-token without loading the full document into memory.

Q29.You cast a generic List from a legacy API and get a ClassCastException at runtime inside a loop. Why did the compiler not catch this?

  • Java uses Type Erasure — generics are enforced at compile time but removed at runtime.
  • If legacy code inserts an Integer into a raw List, and your code assumes List<String>, the compiler allows it.
  • The hidden cast to String during iteration fails at runtime with ClassCastException.

Q30.You encounter java.io.IOException: Connection reset by peer while downloading a file. What does it mean?

  • The external server (or a firewall/load balancer) abruptly closed the TCP connection (sent an RST packet).
  • Causes: server crash, timeout, or slow data consumption.
  • Fix: implement retry logic with exponential backoff in your code.
4

JVM Performance Profiling

Q31.Your Spring Boot application takes 2 minutes to start up. How do you find out why?

  • Enable Spring Boot Startup Actuator endpoint (/actuator/startup) to see a timeline of bean initialization.
  • Profile the startup with VisualVM to detect blocking network calls (DB schema validation, secret fetching) on the main thread.

Q32.A specific API endpoint is very slow. You have no APM tools. How do you profile it natively?

  • Use JFR (Java Flight Recorder): jcmd <pid> JFR.start duration=60s filename=myrecording.jfr
  • Open the .jfr file in JDK Mission Control (JMC) to analyze method hotspots, thread waits, and IO patterns.

Q33.Application performance degrades severely after 24 hours. A restart fixes it temporarily. What are the usual suspects?

  • Resource leak — top suspects: memory leak (gradual heap growth), connection pool leak (DB connections not returned), thread exhaustion.
  • Monitor heap size and thread count over 24 hours to confirm which resource is growing unboundedly.

Q34.Code profiling shows significant time spent in String.split(). What is the performance concern?

  • String.split() compiles a regex under the hood every time it is called.
  • In a tight loop this is very CPU intensive.
  • Fix: pre-compile the regex using Pattern.compile() as a static constant, or use StringTokenizer for simple delimiters.

Q35.Your thread dump shows multiple threads stuck at java.net.SocketInputStream.socketRead0. What is the issue?

  • Threads are waiting indefinitely for a response from an external network call (DB, REST API, etc.).
  • Root cause: missing timeout configuration.
  • Fix: always configure connection and read timeouts on RestTemplate, HttpClient, or JDBC drivers.

Q36.The JVM logs a warning: CodeCache is full. Compiler has been disabled. What does this mean for performance?

  • The CodeCache stores JIT-compiled native code. When full, the JIT compiler shuts down.
  • Java falls back to interpreting bytecode — massively degrading performance.
  • Fix: increase the cache size: -XX:ReservedCodeCacheSize=256m.

Q37.What is "False Sharing" in Java concurrency and how does it impact performance?

  • False sharing occurs when multiple threads modify independent variables on the same CPU cache line.
  • This causes constant cache invalidation and high CPU overhead between cores.
  • Fix: pad variables with @Contended annotation (Java 8+) so they occupy separate cache lines.

Q38.You are reading a massive 5GB file line-by-line. The application slows drastically. How do you optimize disk I/O?

  • Do not use unbuffered FileReader — wrap it in BufferedReader to read chunks at once.
  • Better: use Files.lines() for a memory-efficient Stream.
  • Fastest: use FileChannel with MappedByteBuffer for native OS-level memory-mapped I/O.

Q39.You use + to concatenate Strings inside a loop with 10,000 iterations. GC spikes occur. Why?

  • Strings are immutable — + creates a new StringBuilder and a new String object per iteration.
  • This floods the young generation heap with short-lived objects, triggering frequent minor GCs.
  • Fix: create a single StringBuilder outside the loop and use .append() inside it.

Q40.How do you identify if poor database performance is the cause of your Java application slowness?

  • Check HikariCP metrics via JMX or Micrometer — if the pool is maxed out, DB queries are too slow.
  • In thread dumps, look for threads waiting inside JDBC ResultSet.next() or PreparedStatement.execute().
  • Enable slow query logging in your database to identify the offending queries.
5

Frameworks & Ecosystem (Spring, Hibernate, Tomcat)

Q41.Spring Boot fails to start with ApplicationContextException mentioning a Circular Dependency. How do you resolve it?

  • Service A depends on Service B and Service B depends on Service A — Spring cannot initialize them.
  • Best fix: redesign the architecture and extract shared logic to a third Service C.
  • Quick fix (avoid in production): annotate one of the injected dependencies with @Lazy.

Q42.You query an entity via Hibernate and get LazyInitializationException when accessing a nested collection in the view layer. Why?

  • The Hibernate Session (transaction) was closed before the lazily loaded collection was accessed.
  • Fix: use JOIN FETCH in your JPQL query to load the collection eagerly.
  • Or, access the collection before the @Transactional boundary ends.

Q43.Tomcat crashes with java.net.SocketException: Too many open files. How do you troubleshoot?

  • In Linux, every socket and file descriptor counts against the OS open-file limit.
  • Check for unclosed InputStream, OutputStream, or HTTP connections in code.
  • Fix: increase OS limit via ulimit -n or /etc/security/limits.conf.

Q44.A Spring @Transactional method throws an Exception, but database changes are NOT rolled back. Why?

  • By default, Spring only rolls back for unchecked exceptions (RuntimeExceptions).
  • Checked exceptions (like IOException) do not trigger rollback by default.
  • Fix: use @Transactional(rollbackFor = Exception.class) — or ensure the exception is not swallowed inside the method.

Q45.You get SSLHandshakeException: PKIX path building failed when calling an HTTPS API via RestTemplate. What is the fix?

  • The JVM does not trust the SSL certificate of the external server (self-signed or missing intermediate CA).
  • Fix: download the server certificate and import it into the JDK truststore:
  • keytool -import -alias myserver -file cert.cer -keystore $JAVA_HOME/lib/security/cacerts

Q46.Your Spring Boot application throws UnrecognizedPropertyException when parsing a JSON request using Jackson. How do you handle this gracefully?

  • The client sent a JSON field not mapped in your Java DTO.
  • Fix globally: spring.jackson.deserialization.fail-on-unknown-properties=false in application.properties.
  • Fix per class: annotate the DTO with @JsonIgnoreProperties(ignoreUnknown = true).

Q47.You add a method to a Spring Repository interface and get IllegalArgumentException: Failed to create query for method on startup.

  • Spring Data JPA could not map the method name to an entity property.
  • Example: entity has firstName but method is findByFirstname() — lowercase n breaks the mapping.
  • Fix: match the method name exactly to the entity field name casing: findByFirstName().

Q48.HikariCP logs show Connection is not available, request timed out after 30000ms. What are the steps to diagnose?

  • All connections in the pool are checked out and not being returned.
  • Look for: missing @Transactional, unclosed custom JDBC connections, or slow queries holding the connection.
  • Enable HikariCP leak detection (leakDetectionThreshold) to log stack traces of unreturned connections.

Q49.You hot-deploy a WAR file to Tomcat repeatedly during development and eventually get OutOfMemoryError (Metaspace). Why?

  • This is a Classloader leak.
  • On redeployment, the old WebAppClassLoader should be GC'd.
  • If a background thread or ThreadLocal retains a reference to the old classloader, all its loaded classes stay in Metaspace permanently.

Q50.An application uses SLF4J and Logback, but suddenly no logs are printed to the file — only to console. What should you check?

  • Check for multiple SLF4J bindings on the classpath.
  • A dependency may have pulled in slf4j-simple or log4j-slf4j-impl alongside logback-classic.
  • Fix: exclude the conflicting logging dependency in pom.xml or build.gradle.

☕ Pro Tip for Java Interviews

Always back your answers with the exact JVM flag, command, or tool name. Interviewers test depth — saying "I would use jcmd and Eclipse MAT" is far stronger than "I would check the memory".

← Back to All Interview Guides