Placement Prep

Most Commonly Asked Java Interview Questions, Set 2

ArrayList vs Vector, runtime polymorphism, multiple inheritance via interfaces, servlet lifecycle, and finalize(). Core Java interview Set 2 topics for freshers.

By FACE Prep Team 5 min read
java interview-questions placement-prep oop java-collections servlets

Set 2 of Java placement interview questions covers topics that go one layer deeper than core OOP: collection internals, dynamic dispatch, multiple inheritance mechanics, the servlet model, and object construction order.

The Set 1 Java interview guide covers overloading vs overriding, access modifiers, and the Collections framework overview. This article picks up where that one stops.

ArrayList vs Vector

Both ArrayList and Vector implement the List interface and hold elements in a dynamically-resizing array. The interview question is almost always about their differences, not their similarities.

FeatureArrayListVector
SynchronizationNot synchronizedSynchronized (thread-safe)
Growth when fullGrows by 50% of current capacityDoubles (grows by 100%)
Custom increment sizeNot supportedSet via Vector(int size, int incr) constructor
PerformanceFaster (no lock overhead)Slower
Current recommendationPreferred for single-threaded codeLegacy; use Collections.synchronizedList or CopyOnWriteArrayList

The growth-rate difference matters in memory-sensitive code. An ArrayList with initial capacity 10 grows to 15, then 22, then 33. A Vector with the same starting capacity grows to 20, then 40, then 80. The Oracle Java SE 21 API for ArrayList documents this growth policy precisely.

The practical interview answer: use ArrayList for most cases. If you need a thread-safe List in modern Java, use Collections.synchronizedList(new ArrayList<>()) or CopyOnWriteArrayList, not Vector.

Compile-Time and Runtime Polymorphism

The Oracle Java Tutorial on polymorphism covers the full mechanics; here is what interviewers test at the fresher level.

Compile-Time Polymorphism

Also called static binding or method overloading. The compiler determines which method to call based on the number and types of arguments at compile time.

class Calculator {
    int add(int x, int y) { return x + y; }            // method 1
    double add(double x, double y) { return x + y; }   // method 2
    int add(int x, int y, int z) { return x + y + z; } // method 3
}

The compiler resolves calc.add(2, 3) to method 1 and calc.add(2.5, 3.0) to method 2 before the program runs. No runtime decision is needed.

Runtime Polymorphism

Also called dynamic method dispatch or dynamic binding. The JVM determines which overridden method to call based on the actual runtime type of the object, not the declared type of the reference.

class Animal {
    void sound() { System.out.println("generic sound"); }
}
class Dog extends Animal {
    @Override
    void sound() { System.out.println("bark"); }
}
class Cat extends Animal {
    @Override
    void sound() { System.out.println("meow"); }
}

// In a calling method:
Animal a = new Dog();
a.sound();  // Output: bark  (JVM checks actual type at runtime)
a = new Cat();
a.sound();  // Output: meow (same reference, different runtime object)

The key concept is upcasting: Animal a = new Dog() stores a Dog object in an Animal reference. The compiler only sees the Animal type; the JVM uses the actual object type at runtime to dispatch the correct method. This is the mechanism behind polymorphic collections and dependency injection.

For interview questions on overloading versus overriding side by side, the core Java interview article has a combined comparison table.

Multiple Inheritance Through Interfaces

Java does not permit a class to extend more than one class. The reason is the Diamond Problem: if class D extends both B and C, and both B and C define the same method display(), there is no unambiguous way to decide which version D inherits. C++ addresses this with virtual inheritance, which adds significant language complexity. Java chose simplicity: no multiple class inheritance at all.

Interfaces provide the safe alternative. A class can implement any number of interfaces:

interface Flyable {
    void move();
}
interface Swimmable {
    void move();
}
class Duck implements Flyable, Swimmable {
    public void move() { System.out.println("fly or swim"); }
}

The Duck class provides a single implementation for move(), removing the ambiguity. When two interfaces declare the same method, the implementing class must supply its own body; the compiler enforces this.

Java 8 added default methods to interfaces, which introduces a limited version of the Diamond Problem. If two interfaces both declare default void move(), the implementing class must explicitly override and resolve the conflict with InterfaceName.super.move(). The compiler errors if you leave it unresolved.

Java Servlets: Lifecycle and Role

A Java servlet is a server-side class that handles HTTP requests and generates responses. Before REST APIs and frameworks like Spring Boot became dominant, servlets were the standard building block for Java web applications.

The servlet container (Tomcat, Jetty, or similar) owns the lifecycle:

  • init(): Called once when the container first loads the servlet. Expensive setup goes here: opening a database pool, loading configuration. Not called again for subsequent requests.
  • service(): Called once per incoming HTTP request. The container creates a request and response object, passes them to service(), which routes to doGet(), doPost(), etc., depending on the HTTP method.
  • destroy(): Called once before the container removes the servlet. Resource cleanup goes here: closing connections, flushing output.

The interview question usually asks you to name the three methods in order and explain the trigger for each.

finalize() and Object Construction

The finalize() Method

Java’s garbage collector reclaims memory from objects that are no longer reachable. Unlike C++, which requires explicit destructors, Java handles this automatically. The finalize() method, declared in Object, gives objects a last-call opportunity before their memory is freed.

The typical use case: an object holding a non-Java resource (a file handle, a database connection, a native socket) overrides finalize() to release that resource if the application code failed to do so.

class ResourceHolder {
    protected void finalize() throws Throwable {
        // release file handles, connections, etc.
        super.finalize();
    }
}

Java 9 deprecated finalize(). Modern Java uses AutoCloseable with try-with-resources, which is deterministic and does not depend on GC timing. For placement interviews, know both: what finalize() does, and why it was deprecated.

Object Construction Order

When new MyClass() runs, Java follows a fixed four-step sequence:

  • Step 1: Memory is allocated from the heap for all instance variables plus implementation-specific data (type pointer, GC metadata).
  • Step 2: Instance variables are initialized to type defaults: 0 for numeric types, false for boolean, null for references.
  • Step 3: The constructor chain fires. Java calls the most-derived class constructor, which immediately calls the superclass constructor (super(), explicit or implicit), all the way up to Object. The superclass constructors finish first; the most-derived constructor’s body runs last.
  • Step 4: Within each constructor, instance initializers and initialization blocks run before the constructor body.

The practical consequence: a superclass constructor may call a method overridden in the subclass, but the subclass instance variables are still at their default values at that point. This is a classic Java gotcha that interviewers probe.

Dell’s technical interview rounds cover exactly this class of Java OOP question. The Dell fresher interview guide has the full question set for CSE and IT tracks.

What These Patterns Look Like in Production

The interface-based multiple inheritance design from the section above is the same pattern Python’s LLM libraries use. LangChain’s BaseChatModel, LlamaIndex’s BaseLLM, and the OpenAI client’s protocol all define abstract contracts that different provider implementations override at runtime. If you understand Java’s interface dispatch, reading those Python abstractions takes minutes, not hours.

TinkerLLM lets you build against those live APIs at ₹499, which is a practical way to test how the interface and dynamic dispatch patterns from this article translate into real code.

Primary sources

Frequently asked questions

What is the main difference between ArrayList and Vector in Java?

ArrayList is not synchronized and grows by 50% when full; Vector is synchronized (thread-safe) and doubles in size when full. ArrayList is faster for single-threaded use; prefer Collections.synchronizedList or CopyOnWriteArrayList for thread-safe alternatives.

What is runtime polymorphism in Java?

Runtime polymorphism is when the JVM decides at runtime which overridden method to call, based on the actual object type rather than the reference type. It requires method overriding and an upcast reference: Animal a = new Dog(); a.speak() calls Dog's speak() method.

Why does Java not support multiple inheritance through classes?

Multiple class inheritance creates ambiguity when two parent classes define the same method. This is the Diamond Problem from C++. Java solves it by disallowing multiple class inheritance while allowing a class to implement multiple interfaces.

What does the finalize() method do in Java?

finalize() is called by the garbage collector on an object just before reclaiming its memory. It is used to release non-Java resources like file handles or database connections. Java 9 deprecated it; modern Java uses try-with-resources instead.

What are the three lifecycle methods of a Java Servlet?

A servlet's lifecycle runs through init() (called once when first loaded by the container), service() (called for each incoming HTTP request), and destroy() (called when the container removes the servlet).

In what order does Java initialize an object?

Java initializes objects in four steps: memory is allocated from the heap, instance variables are set to defaults (0, false, null), the superclass constructor chain runs (most-derived last), then instance initializers and the class constructor body execute.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹499)
Free AI Roadmap PDF