yoklainterview sim

Backend Java Memory Jvm Interview Questions

75 verified Backend Java Memory Jvm interview questions — solve with answers, learn from explanations, test yourself in a real simulation.

Try the real simulation →

Sample questions

Java Memory JvmDifficulty 1
public class Demo {
    public static void main(String[] args) {
        int x = 5;
        Point p = new Point(1, 2);
    }
}

class Point {
    int x, y;
    Point(int x, int y) { this.x = x; this.y = y; }
}

Where do the local variable x and the Point object referenced by p live in the JVM's memory areas?
  • aBoth x and the Point object live on the heap; only p itself lives in the stack frame
  • bx and p sit in the stack frame; only the Point object lives on the heap
  • cBoth x and the Point object live inside main's stack frame
  • dx lives on the heap, while the Point object and p both live on the stack
Explanation:Each thread has its own stack made up of frames, one per active method call. Primitive local variables like x are stored directly inside the current frame. Reference variables like p are also stored in the frame, but the object they point to -- here, the Point instance created by new -- is allocated on the shared heap, which all threads can reach. When main returns, the frame (and x, p) disappear, but the Point object only goes away once nothing references it anymore and the garbage collector reclaims it.
Java Memory JvmDifficulty 2
String a = "hello";
String b = "hello";
System.out.println(a == b);

What does this print, and why?
  • afalse, because == always compares object identity and string literals are never shared
  • bfalse, because every String literal allocates a new object on the heap
  • ctrue, but only because the JIT compiler happens to optimize this specific pattern away
  • dtrue, because both literals are interned into the same entry in the string pool
Explanation:String literals are automatically interned by the JVM: when the class is loaded, "hello" is placed once into the string pool, and any other occurrence of the identical literal in the same or another class reuses that same pooled String object instead of allocating a new one. Since a and b both refer to that one pooled object, == (identity comparison) returns true. This is a JVM-level guarantee for literals, not a JIT optimization, and it's exactly why == is unreliable for comparing strings built at runtime instead of literals.
Java Memory JvmDifficulty 2
String a = "hello";
String b = new String("hello");
System.out.println(a == b);
System.out.println(a.equals(b));

What is printed, in order?
  • afalse then true
  • btrue then true
  • cfalse then false
  • dtrue then false
Explanation:new String("hello") explicitly forces allocation of a brand-new String object on the heap, even though its characters are copied from the pooled literal -- it is never automatically added to the string pool. So a (the pooled literal) and b (the freshly allocated copy) are different objects, making a == b false. equals compares character content rather than identity, and both strings hold the same characters, so a.equals(b) is true. This pair of lines is the classic illustration of why identity comparison and value comparison for String are not interchangeable.
Java Memory JvmDifficulty 1
A Java program crashes with StackOverflowError. Which best describes what actually ran out?
  • aThe heap ran out of space to allocate new objects
  • bThe JVM ran out of native operating-system threads
  • cA thread's call stack outgrew its fixed size from deep recursion
  • dThe garbage collector could not free enough unreachable objects in time
Explanation:StackOverflowError specifically means a single thread's call stack -- the region holding one frame per active method invocation -- grew past its configured size, almost always because of runaway or excessively deep recursion (each recursive call pushes another frame without returning). This is a distinct memory area and failure mode from the heap: OutOfMemoryError: Java heap space means the heap itself is full of objects that can't be collected, which is a different problem with a different fix.
Java Memory JvmDifficulty 2
String s = "a";
for (int i = 0; i < 3; i++) {
    s += i;
}
System.out.println(s);

Each time s += i executes inside the loop, what happens to the String object in memory, and why?
  • aThe existing String object referenced by s is mutated in place to append the new character; only one String object ever exists
  • bBecause String is immutable, s += i creates a brand-new String object each iteration (the old contents concatenated with i), and the previous object referenced by s becomes unreachable garbage; after the loop, several discarded intermediate String objects have been created along the way
  • cThe JVM always rewrites this loop to use a single StringBuilder call across all iterations, so no matter how many times the loop runs, at most one intermediate object is ever created
  • ds += i only allocates a new object the first time the loop runs; later iterations reuse the same underlying character array since Java arrays can be resized
Explanation:Java String objects are immutable -- no method on String can change the characters it already holds. Compilers commonly translate a single + expression into an internal buffer-based call for efficiency, but that optimization applies per concatenation expression; it does not merge separate loop iterations into one accumulator, because s is reassigned to a new reference on every iteration. So each s += i produces a new String object holding the combined characters, and the object s previously pointed to becomes eligible for garbage collection. For repeated concatenation across many iterations, using a single StringBuilder and calling .append() avoids creating and discarding all these intermediate objects.
Java Memory JvmDifficulty 3
A junior developer relies on overriding finalize() to close a file handle when an object is garbage collected, instead of using try-with-resources. What is the core problem with this approach?
  • aGC decides if and when finalize() runs, so cleanup timing is unpredictable
  • bfinalize() is called synchronously the instant a reference goes out of scope, which can block the calling thread
  • cfinalize() can only be used on classes that also implement AutoCloseable
  • dObjects that override finalize() are automatically ineligible for garbage collection
Explanation:Relying on finalize() for resource cleanup is unreliable because the JVM makes no promise about when -- or even whether -- finalize() runs; it depends entirely on when (or if) the garbage collector decides an object is unreachable and schedules finalization, which could be long after the resource should have been released, or never if the JVM exits first. Try-with-resources, in contrast, calls close() deterministically the moment the block exits, which is why it's the recommended pattern for anything holding an OS-level resource like a file handle or socket.

Test yourself against the 3300-question Backend bank.

Start interview