OOPs Interview Questions
OOPs (object-oriented programming) concepts come up in almost every software and developer interview. These are the questions interviewers actually ask, grouped by theme and tagged by experience level, with concise answers you can speak confidently.
145 questions with concise, interview-ready answers.
OOP Fundamentals
1. What is Object-Oriented Programming (OOP)? Fresher
OOP is a programming paradigm that organizes software around objects — self-contained units that bundle data (attributes) and behavior (methods) together. Instead of writing procedures that act on loose data, you model real-world entities as objects that interact. Its four core pillars are encapsulation, abstraction, inheritance, and polymorphism.
2. What are the four pillars of OOP? Fresher
Encapsulation (bundling state with the behaviour that operates on it and controlling access to the internals), Abstraction (exposing what an object does while hiding how), Inheritance (deriving a new type from an existing one to reuse and specialise behaviour), and Polymorphism (one interface serving many underlying types). Interviewers almost always follow up by asking for an example of each from code you have actually written, so prepare one concrete case per pillar rather than reciting definitions.
3. What is the difference between procedural and object-oriented programming? Fresher
Procedural programming structures a program as a sequence of functions operating on data that lives outside them, so in principle any function can touch any data. OOP inverts that: data and the operations on it live together in an object, and access to the data is controlled by the object. The practical difference shows up during change — altering a shared data structure in a procedural program ripples through every function that read it, whereas in OOP the blast radius is bounded by one class.
4. What are the main advantages of OOP? Fresher
Modularity (each class is a unit you can reason about alone), reusability through inheritance and composition, easier maintenance because changes are localised behind interfaces, and extensibility because new types can slot into existing code that programs against an abstraction. It also maps well to domains that are naturally made of entities with state and behaviour, such as banking, e-commerce, or games.
5. What are the disadvantages or common criticisms of OOP? 2–5 yrs
It adds indirection and boilerplate, so small programs can end up larger and slower to read than a procedural equivalent. Deep inheritance hierarchies become fragile and hard to follow, and mutable shared objects make concurrency harder to reason about than immutable, function-oriented designs. Virtual dispatch and object allocation also carry a small runtime cost, which matters in tight loops and embedded work.
6. What is the difference between an object-oriented and an object-based language? Fresher
An object-based language supports objects and encapsulation but lacks full inheritance and subtype polymorphism — classic examples are VBScript and pre-ES6 JavaScript as it was usually described. An object-oriented language supports all four pillars, including class-based inheritance and dynamic dispatch. The distinction is mostly historical, but interviewers use it to check that you know inheritance and polymorphism are not optional extras in the definition.
7. What is meant by an is-a relationship and a has-a relationship? Fresher
An is-a relationship means one type is a specialised kind of another and is expressed with inheritance — a SavingsAccount is an Account. A has-a relationship means one object holds another as a part and is expressed with composition — a Car has an Engine. Choosing the wrong one is the single most common OOP design mistake: if you cannot honestly say "every X is a Y", use composition.
8. What is an abstract data type? Fresher
An abstract data type is a type defined by the operations you can perform on it and the guarantees those operations make, not by how it stores data. A Stack is an ADT: push, pop and peek with last-in-first-out behaviour, whether it is backed by an array or a linked list. Classes are how OOP languages implement ADTs, which is why the interface matters more than the field layout.
9. What is a method signature? Fresher
A method signature is the part of a method declaration the compiler uses to tell one method from another — typically the name and the ordered list of parameter types. In most languages the return type and parameter names are not part of the signature, which is why you cannot overload on return type alone. Overloading changes the signature; overriding keeps it identical.
10. What is the difference between a class, an object, and a reference? Fresher
The class is the definition that exists in source and in the loaded type metadata. The object is the actual block of memory created at runtime holding that instance's field values. The reference (or pointer) is the variable that points at the object — several references can point at one object, which is why two variables can appear to change together and why identity and equality are different questions.
11. What is the difference between a class and a struct? 2–5 yrs
In languages that have both, the usual distinction is semantics and copying: a struct is typically a value type copied on assignment, while a class is a reference type where assignment copies only the reference. Structs also often cannot participate in inheritance. Use a struct for small immutable bundles of data, such as a point or a money amount, and a class when identity, mutation or polymorphism matters.
Classes, Objects and Constructors
12. What is a class and what is an object? Fresher
A class is a blueprint or template that defines the attributes and methods a type of object will have. An object is a concrete instance of that class, created at runtime, with its own actual values for those attributes. For example, "Car" is a class, while a specific red Toyota is an object of that class.
13. What happens in memory when an object is created? 2–5 yrs
The runtime allocates a block of memory large enough for the object's instance fields (on the heap in most managed languages), zero-initialises it, links it to its type information so virtual dispatch can work, then runs the constructor chain from the base class down. The variable you assign holds only a reference to that block. Local variables and the reference itself live on the stack, which is why an object outlives the method that created it if something still points to it.
14. What is a constructor and what are its types? Fresher
A constructor is a special method that runs automatically when an object is created, used to initialize its state, and it shares the name of the class with no return type. Common types are the default (no-argument) constructor, the parameterized constructor that takes arguments, and the copy constructor that creates a new object from an existing one. If you write no constructor, the compiler provides a default one.
15. Can constructors be overloaded? Fresher
Yes — a class can declare several constructors that differ in parameter list, and the compiler picks one by the arguments at the call site, exactly like method overloading. This is how you offer both a minimal and a fully specified way to build an object. Once the number of optional parameters grows past three or four, overloading gets unreadable and the Builder pattern is the better answer.
16. What is constructor chaining? 2–5 yrs
Constructor chaining is one constructor calling another so initialisation logic is written once. Within a class you delegate to a sibling constructor (this(...) in Java and C#), and up the hierarchy you call the parent constructor (super(...) or a base initialiser). Most languages require that call to be the first statement, because the parent's fields must be valid before the subclass touches them.
17. What is a copy constructor and when do you need one? 2–5 yrs
A copy constructor builds a new object initialised from an existing object of the same class. You need to write one yourself when the object owns mutable resources — arrays, collections, file handles — because the compiler-supplied version copies field by field and would leave both objects sharing the same nested state. Deciding what a copy constructor does is really the shallow-versus-deep copy decision.
18. Can a constructor be private, and why would you make one private? 2–5 yrs
Yes. A private constructor prevents outside code from instantiating the class directly, which is how you implement a Singleton, a static utility class that should never be instantiated, and factory-only types where a named static method such as Money.ofCents() reads better than a bare constructor. It also lets you validate or cache instances before handing one out.
19. Can a constructor be abstract, static, or virtual? Senior
No in almost every mainstream language. A constructor cannot be abstract because there would be nothing to run when the object is created; it cannot be static because it operates on a specific new instance; and it cannot be virtual because the object's dynamic type is not fully established until construction finishes. That last point is why calling an overridable method from a constructor is dangerous — the subclass override runs before the subclass fields are initialised.
20. In what order do constructors run when you create a derived object? 2–5 yrs
Base class first, then down the chain to the most derived class. Field initialisers of each class run just before that class's constructor body. The reason is invariants: the derived constructor may depend on base state being valid, but never the other way round, which is exactly why calling a virtual method from a base constructor can observe a half-built subclass.
21. What is a destructor? Fresher
A destructor is a special method invoked when an object is destroyed, used to release resources the object acquired — memory, file handles, sockets, locks. In deterministic languages like C++ it runs at a known point, when the object goes out of scope or is deleted, which makes it reliable enough to build resource management on. Managed languages replace it with garbage collection plus an explicit dispose or close method.
22. What is the difference between a destructor and a finaliser? 2–5 yrs
A destructor is deterministic: you know exactly when it runs. A finaliser is a hook the garbage collector may call at some unspecified time before reclaiming an object, and it may never run at all if the process exits first. That non-determinism is why finalisers cannot be used to release scarce resources and why Java deprecated finalize() in favour of try-with-resources and cleaners.
23. Why is relying on finalisers for cleanup considered bad practice? 2–5 yrs
Because the timing is unpredictable, the ordering between finalisers is undefined, an exception thrown inside one is usually swallowed, and objects with finalisers survive an extra collection cycle, which hurts performance. A file handle released by a finaliser might stay open for minutes. The correct pattern is explicit, scoped release — try-with-resources, using, defer, or RAII — with a finaliser at most as a last-resort safety net.
24. What is the difference between static and instance members? Fresher
A static (class) member belongs to the class itself and is shared by every instance, initialised once when the class is loaded and reachable without creating an object. An instance member belongs to one object and each object gets its own copy. The practical consequence is that mutable static state is shared across the whole program, which makes it a common source of hidden coupling and thread-safety bugs.
25. Can a static method access instance members, and why not? Fresher
No, not directly. A static method is invoked on the class, so there is no current object and therefore no `this` to resolve instance fields against. It can still work with instance data if you pass an object in as a parameter. This is also why static methods cannot be overridden — there is no instance whose dynamic type could select an implementation.
26. What is a static initialiser block? 2–5 yrs
A static block is code that runs once when the class is first loaded, before any instance is created, and is used to set up static state that needs more than a single expression — building a lookup table, loading a native library, reading configuration. It runs in textual order with the static field initialisers. Because it runs at class-load time, an exception thrown there usually surfaces as a confusing class-initialisation error far from the real cause.
27. What is the difference between this and super? Fresher
The "this" keyword refers to the current object instance and is used to access the current class's members or call another constructor of the same class. The "super" keyword refers to the immediate parent class and is used to access the parent's methods, fields, or constructor. In short, "this" points to the current class while "super" points to the superclass.
28. What are access modifiers and what are the common levels? Fresher
Access modifiers control which code may see a member. The common ladder is private (this class only), package or internal (this module or assembly), protected (this class and its subclasses), and public (everyone). The design rule is to start at the most restrictive level that compiles and widen only when a real caller needs it, because every public member becomes a promise you have to keep.
29. What is the difference between protected and private access? 2–5 yrs
Private members are visible only inside the declaring class, so you can change them freely. Protected members are also visible to subclasses, which means they are part of your contract with every future subclass, not an implementation detail. Marking a field protected "so subclasses can get at it" is a quiet way to break encapsulation — prefer a protected method that subclasses can call or override.
30. What is a nested class and when is it useful? 2–5 yrs
A nested class is a class declared inside another. A static nested class is just a namespaced helper; an inner (non-static) class additionally holds a hidden reference to the enclosing instance. Nesting is useful when the helper type is meaningless outside its owner — a Node inside a LinkedList, a Builder inside the class it builds. The pitfall with inner classes is that the hidden outer reference can keep a large object alive longer than expected.
31. What is object lifetime and who decides when an object dies? 2–5 yrs
Object lifetime is the span from construction to destruction. In manually managed languages the programmer decides, with new and delete or scope-based destruction; in managed languages the garbage collector decides, reclaiming objects once they are no longer reachable from any root. The consequence is that in a garbage-collected language you cannot know when cleanup happens, so anything scarce must be released explicitly rather than left to the collector.
Encapsulation and Abstraction
32. What is encapsulation? Fresher
Encapsulation is bundling data and the methods that operate on it inside a single unit (a class) and restricting direct access to the internal state. It is achieved by making fields private and exposing controlled access through public getters and setters. This protects an object's data from accidental or invalid modification and is often called data hiding.
33. What is abstraction? Fresher
Abstraction means hiding complex implementation details and exposing only the essential features of an object to the user. It lets you focus on what an object does rather than how it does it. In code it is achieved using abstract classes and interfaces — for example, you call a car's start() method without needing to know the engine internals.
34. What is the difference between abstraction and encapsulation? Fresher
Abstraction is about hiding complexity — exposing only what an object does and hiding how it does it, solved at the design level using abstract classes and interfaces. Encapsulation is about hiding data — wrapping data and methods together and restricting access, solved at the implementation level using access modifiers. In short, abstraction hides complexity while encapsulation hides data.
35. Why should fields be private by default? Fresher
Because a public field is a permanent promise about your internal representation: every caller can read and write it, so you can never change how the value is stored, validate it, or make it thread-safe without breaking them. Keeping it private leaves you free to change the representation later. It also gives the class a single place to enforce its invariants, such as a balance never going negative.
36. If you add a getter and a setter for every field, are you still encapsulating? 2–5 yrs
Barely. A class with a public accessor pair for every private field exposes the same shape as a public-field class and just adds ceremony — callers still reach in and manipulate state, and the invariants live outside the class. Real encapsulation means exposing behaviour instead of state: account.withdraw(amount) rather than account.setBalance(account.getBalance() - amount). Add accessors when a caller genuinely needs them, not by reflex.
37. What is the difference between data hiding and encapsulation? 2–5 yrs
Encapsulation is the broader idea of keeping data and behaviour together in one unit; data hiding is the specific mechanism of restricting external access to that data with access modifiers. You can encapsulate without hiding — a class with public fields still groups data and behaviour — but the combination is what makes the class safe to change. Interviewers ask this to see whether you treat them as synonyms.
38. What is an abstract method? Fresher
An abstract method declares a name, parameters and return type but no body, leaving the implementation to a subclass. It exists so a base type can define a step in an algorithm without deciding how it is performed. Any class containing an abstract method must itself be abstract and cannot be instantiated, and every concrete subclass must supply an implementation.
39. Give a real-world example of abstraction and encapsulation in the same object. 2–5 yrs
A database connection object is a good one. Abstraction is the interface it presents — execute(query) — which hides sockets, wire protocols and retries. Encapsulation is that the socket, buffer and transaction state are private fields no caller can touch, so the object can reconnect or pool connections without any caller noticing. Abstraction is what the outside sees; encapsulation is what keeps the inside safe to change.
40. What is a leaky abstraction? Senior
A leaky abstraction is one whose implementation details show through and force the caller to know about them anyway. An ORM that hides SQL until you hit an N+1 query problem, or a network file system that behaves like a local one until latency ruins it, are classic examples. The lesson is not to avoid abstraction but to choose boundaries where the hidden details rarely matter, and to document the ones that do.
41. What is an invariant, and what does it have to do with encapsulation? 2–5 yrs
An invariant is a condition about an object's state that must hold true for the object's whole life — a rectangle's width is never negative, a list's size always matches its contents. Encapsulation exists to protect invariants: if state is private and only the class's own methods change it, the class can guarantee the invariant. Once a field is public, no invariant involving it can be enforced.
Inheritance and Composition
42. What is inheritance? Fresher
Inheritance lets one class (the child or subclass) acquire the attributes and methods of another class (the parent or superclass). It promotes code reuse and establishes an "is-a" relationship — a Dog is an Animal. The child class can use the parent's members and also add or override its own behavior.
43. What are the types of inheritance? Fresher
The common types are single (one child, one parent), multilevel (a chain such as A to B to C), hierarchical (multiple children share one parent), and multiple (one child inherits from several parents). Multiple inheritance of classes is restricted in languages like Java and C# due to the diamond problem, though it is supported through interfaces.
44. Why is multiple inheritance restricted in languages like Java? Fresher
Multiple inheritance of classes is restricted mainly to avoid the diamond problem — when a class inherits from two parents that both define the same method, the compiler cannot decide which version to use, causing ambiguity. Java avoids this by allowing a class to extend only one class while still implementing multiple interfaces, which keeps the inheritance hierarchy unambiguous and simpler to maintain.
45. What is the diamond problem? Fresher
The diamond problem arises when class D inherits from B and C, which both inherit from A. If B and C each override a method from A, D has two competing versions and the compiler cannot pick one; worse, D may end up with two copies of A's state. It is called a diamond because of the shape of the inheritance graph. Java and C# sidestep it by allowing only one base class.
46. How do languages that allow multiple inheritance solve the diamond problem? Senior
C++ offers virtual inheritance, which makes the shared base appear only once so there is a single copy of its state, and requires you to disambiguate conflicting members explicitly with the scope operator. Python uses the C3 linearisation to compute a deterministic method resolution order, so a lookup walks a single flattened chain. Java 8 default methods take a third route: when two interfaces supply conflicting defaults, the compiler refuses to guess and forces the class to override.
47. What is the difference between composition and inheritance? 2–5 yrs
Inheritance derives a new type from an existing one and inherits its whole public and protected surface, creating an is-a relationship fixed at compile time. Composition holds another object as a field and forwards the calls it chooses, creating a has-a relationship you can change at runtime by swapping the held object. Inheritance reuses by extending a type; composition reuses by delegating to an instance.
48. Why is composition usually the better default than inheritance? 2–5 yrs
Because inheritance couples you to the parent's implementation, not just its interface: a change in the base class can silently break subclasses, and you inherit every method whether it makes sense or not (the classic Stack extends Vector mistake). Composition exposes only what you delegate, allows swapping the collaborator at runtime, and keeps hierarchies shallow. Reach for inheritance only when the subtype genuinely satisfies the parent's contract everywhere it is used.
49. What is the fragile base class problem? Senior
It is the situation where a seemingly safe change inside a base class breaks subclasses that depended on its internal call pattern. The textbook case is a collection whose addAll() is implemented by calling add() in a loop: a subclass that overrides both to count elements double-counts, and if the base later stops calling add(), the count silently breaks. It is the strongest practical argument for preferring composition and for designing explicitly for inheritance or forbidding it.
50. What is delegation? 2–5 yrs
Delegation is one object handing a request to another object that does the actual work, usually a field it holds. It is the mechanism that makes composition useful: a wrapper implements an interface and forwards most calls to the wrapped instance while intercepting the ones it cares about. Decorator, Proxy and Strategy are all delegation with different intent, and the only real cost is the forwarding boilerplate.
51. What is the difference between extending a class and implementing an interface? Fresher
Extending a class inherits both the contract and the implementation, including state, and most languages allow only one base class. Implementing an interface inherits only the contract, obliging you to supply the behaviour, and a class can implement many. Use extension when you genuinely want to reuse a parent's implementation, and implementation when you want to declare that your type can play a role.
52. Can a subclass access the private members of its parent class? Fresher
No. Private members are visible only inside the declaring class, so a subclass inherits them in the sense that they occupy space in the object, but it cannot reference them by name. If a subclass legitimately needs access, the parent should expose a protected method rather than making the field protected, so the parent keeps control of how the state is read or changed.
53. What is upcasting and downcasting? 2–5 yrs
Upcasting converts a subclass reference to a base-class reference; it is always safe and usually implicit, and it is what makes polymorphism work. Downcasting converts a base reference back to a subclass reference, which the compiler cannot verify, so it fails at runtime if the object is not actually of that type. Guard downcasts with a type test, and treat a chain of type tests as a hint that a polymorphic method belongs on the type instead.
54. What is method hiding and how does it differ from overriding? 2–5 yrs
Method hiding happens when a subclass declares a member — typically static, or non-virtual in languages like C# — with the same name as one in the parent. The call is resolved by the reference type at compile time, so a parent-typed reference runs the parent's version even if the object is a subclass. Overriding is the opposite: resolution happens at runtime by the object's actual type. Hiding is almost always a mistake made by accident.
55. Why would you mark a class final or sealed? 2–5 yrs
To state that the class was not designed for extension. Inheritance is a contract you have to maintain forever, and a class with subclasses cannot freely change its internal call patterns without risking the fragile base class problem. Sealing also lets the compiler or runtime devirtualise calls, and it is essential for immutability, since a subclass could otherwise add mutable state.
56. What is a mixin or a trait? Senior
A mixin is a bundle of behaviour meant to be composed into a class rather than used as a standalone type — logging, comparability, serialisation. Traits in Scala and Rust, modules in Ruby, and interfaces with default methods in Java all serve this role. They give you reuse across unrelated hierarchies without full multiple inheritance of state, which is where most of the ambiguity comes from.
57. Does inheritance break encapsulation? Senior
It weakens it. A subclass sees the protected surface of its parent and, in practice, depends on the parent's internal calling sequence, so the parent can no longer change freely — the encapsulation boundary now includes every subclass. This is why the standard advice is to design and document explicitly for inheritance, or to prohibit it by sealing the class, and to prefer composition where the relationship is not clearly is-a.
58. What is the difference between association, aggregation, and composition? 2–5 yrs
Association is a general relationship where objects know about each other (a Teacher and a Student). Aggregation is a weaker "has-a" relationship where the part can exist independently of the whole — a Department has Professors, but professors survive if the department closes. Composition is a stronger "has-a" where the part cannot exist without the whole — a House has Rooms, and the rooms cease to exist if the house is destroyed.
59. How do you decide between aggregation and composition when modelling? 2–5 yrs
Ask who owns the lifecycle. If destroying the whole must destroy the part, and the part is never shared with another whole, it is composition — an Order and its OrderLines. If the part is created elsewhere, can outlive the whole, or is referenced by several wholes, it is aggregation — a Playlist and its Songs. Getting this wrong shows up as cascade-delete bugs or orphaned rows once the model reaches a database.
Polymorphism and Dispatch
60. What is polymorphism? Fresher
Polymorphism means "many forms" — the ability of the same operation or method name to behave differently depending on the object or context. It comes in two types: compile-time (method overloading) and runtime (method overriding). It lets you write flexible code that works with objects of different types through a common interface.
61. What is the difference between compile-time and runtime polymorphism? Fresher
Compile-time polymorphism (method overloading) is resolved by the compiler based on the method signature — same method name with different parameter lists. Runtime polymorphism (method overriding) is resolved at runtime through dynamic dispatch, where a subclass provides its own implementation of a parent method and the actual object type decides which runs. Overloading is static binding; overriding is dynamic binding.
62. What is the difference between method overloading and method overriding? Fresher
Overloading defines multiple methods with the same name but different parameters within the same class, and is resolved at compile time. Overriding redefines a parent class method in a subclass with the same signature, and is resolved at runtime. Overloading changes the parameter list; overriding keeps the signature identical but changes the implementation.
63. What are the rules for method overriding? 2–5 yrs
The overriding method must have the same name, parameter list, and a compatible return type as the parent method. It cannot reduce the access level of the overridden method (it can widen it), and it cannot throw broader checked exceptions. Static, final, and private methods cannot be overridden, and the method must be inherited to be overridden.
64. What is dynamic method dispatch? 2–5 yrs
Dynamic dispatch is the runtime mechanism that picks which override to run based on the object's actual type rather than the type of the reference holding it. It is what lets a loop over a list of Shape references call the right area() on every element without a single type check. Without it, polymorphism would be a purely compile-time trick and the Open/Closed Principle would be unimplementable.
65. What is a virtual function? Fresher
A virtual function is a method that can be overridden and is resolved by the object's runtime type. In C++ you opt in with the virtual keyword; in Java every non-static, non-final, non-private method is virtual by default; C# requires virtual on the base and override on the derived. If a function is not virtual, a base-typed reference always runs the base version, which surprises people moving from Java to C++ or C#.
66. What is a vtable and how does the runtime use it? Senior
A vtable is a per-class array of function pointers, one slot per virtual method, built by the compiler. Each object of a polymorphic class stores a hidden pointer to its class's vtable, so a virtual call becomes: load the vtable pointer, index the fixed slot for that method, call through it. Because the slot index is fixed at compile time, dispatch costs an extra couple of memory loads and an indirect branch rather than a search.
67. What is a pure virtual function? 2–5 yrs
A pure virtual function is declared in a base class with no implementation and must be overridden by any concrete derived class — the C++ spelling is `= 0`, and it is the same idea as an abstract method elsewhere. A class with at least one pure virtual function is abstract and cannot be instantiated. It is how you define a contract while still keeping shared state and helper methods in the base.
68. What is static binding and dynamic binding? 2–5 yrs
Static (early) binding resolves a call at compile time from the declared types — overloaded methods, static methods, and non-virtual calls. Dynamic (late) binding defers resolution to runtime and uses the object's actual type, which is what overriding relies on. Static binding is faster and lets the compiler inline; dynamic binding is what buys you extensibility.
69. Can you overload a method by changing only its return type? Fresher
No. The return type is not part of the method signature in most languages, so two methods differing only in return type are ambiguous — at a call site that ignores the result, the compiler would have no way to choose. You need a difference in the number, types, or order of parameters, or simply a different method name.
70. What is a covariant return type? Senior
A covariant return type lets an overriding method return a more specific type than the method it overrides — an override of Animal reproduce() may return Dog. It is safe because every caller expecting an Animal still gets one, and it removes casts from client code. Parameters cannot be narrowed the same way: narrowing an input would break substitutability, which is why parameters are contravariant in theory and invariant in most languages.
71. Why can a static method not be overridden? 2–5 yrs
Overriding depends on an object whose runtime type selects the implementation, and a static method is invoked on the class, so there is no such object. Declaring a static method with the same signature in a subclass hides the parent's rather than overriding it, and the call resolves by the reference type at compile time. Calling a static method through an instance reference is legal in some languages and is exactly what makes this bug hard to spot.
72. What is operator overloading and why do some languages leave it out? 2–5 yrs
Operator overloading lets a class define what built-in operators mean for its instances, so a Matrix or a Money type can support + and == naturally. C++, C# and Python support it. Java deliberately omits it (beyond String concatenation) on the grounds that overloaded operators are easy to abuse — an operator whose meaning is not obvious from the symbol makes code harder to read than a named method.
73. What are the different kinds of polymorphism in type theory? Senior
Ad-hoc polymorphism is overloading: the same name with unrelated implementations chosen by argument type. Parametric polymorphism is generics: one implementation that works uniformly for many types. Subtype polymorphism is inheritance and interfaces: a value of a subtype used where the supertype is expected. Most OOP interview answers only cover the third and half of the first, so naming all three signals depth.
74. What does virtual dispatch cost at runtime? Senior
Roughly an extra indirect load and a branch the CPU cannot always predict, and — more importantly — it usually blocks inlining, which in turn blocks the optimisations inlining would have enabled. In most application code this is invisible; in a hot numeric loop it can be a measurable fraction of runtime. Modern JITs claw much of it back with monomorphic inline caches and speculative devirtualisation when a call site only ever sees one type.
75. What is double dispatch? Senior
Double dispatch selects a method based on the runtime types of two objects rather than one. Single dispatch on the receiver plus overloading on the argument does not achieve it, because the argument overload is chosen statically. The Visitor pattern implements it by having the element call visitor.visit(this), so the first virtual call resolves the element type and the overload resolution then resolves the visitor operation.
Interfaces and Abstract Classes
76. What is the difference between an interface and an abstract class? Fresher
An abstract class can have both abstract and concrete methods, instance fields, and constructors, and a class can extend only one. An interface traditionally declares only method signatures (a pure contract), supports multiple inheritance, and its fields are constants. Use an abstract class to share common code among closely related classes, and an interface to define a capability that unrelated classes can implement.
77. What is an interface? Fresher
An interface is a contract: a set of method signatures a type promises to provide, with no state and traditionally no implementation. It names a capability — Comparable, Serializable, PaymentGateway — that classes from completely unrelated hierarchies can adopt. Because callers depend only on the contract, any implementation can be substituted, which is the basis of dependency injection and testability.
78. When should you choose an interface over an abstract class? 2–5 yrs
Choose an interface when you are defining a capability that unrelated types may need, when you expect implementations to already have a base class, or when you want the freedom to substitute implementations for testing. Choose an abstract class when the implementations are genuinely a family sharing state and a partial algorithm, and you want to write that shared part once. A common design is both: a small interface for callers, plus an abstract base offering a convenient default implementation.
79. Can you instantiate an abstract class? Fresher
No — an abstract class is incomplete by definition and cannot be created with new. You instantiate a concrete subclass, or in some languages an anonymous subclass declared at the point of use, which is why code that looks like it instantiates an abstract type usually isn't. The abstract class still has a constructor, but it runs only as part of constructing a subclass.
80. Can an abstract class have a constructor, and why would it? 2–5 yrs
Yes. The constructor is never called to create an abstract instance directly, but it runs whenever a concrete subclass is constructed, and it is where shared fields are initialised and base invariants are established. Making that constructor protected documents the intent that it is only reachable from subclasses. Its existence is one of the clearest differences from an interface, which has no state to initialise.
81. Can an interface contain implemented methods? 2–5 yrs
In modern languages, yes. Java 8 added default and static methods, and C# 8 added default interface implementations, so an interface can ship behaviour that implementers inherit. The purpose was to let library authors add methods to published interfaces without breaking every existing implementation. What interfaces still cannot have is instance state, which remains the real dividing line from abstract classes.
82. What happens if a class implements two interfaces that declare the same method? 2–5 yrs
If both are abstract declarations, there is no conflict — one implementation satisfies both, since the signatures are identical. The conflict only arises when both interfaces provide default implementations; then the compiler refuses to choose and the class must override the method, usually delegating explicitly to one parent's version. This is exactly the diamond problem, resolved by forcing the ambiguity to be settled in source.
83. What is a marker interface? 2–5 yrs
A marker interface declares no methods and exists purely to tag a type with metadata that the runtime or a library checks — Serializable and Cloneable are the classic Java examples. The advantage over a flag is that it is a type, so it can be checked at compile time in method signatures. Annotations and attributes have largely replaced them because they carry parameters and do not pollute the type hierarchy.
84. What does programming to an interface mean? 2–5 yrs
It means declaring variables, parameters and return types in terms of the most general type that does the job — List rather than ArrayList, Repository rather than PostgresRepository. The payoff is substitutability: you can change the implementation, wrap it, or replace it with a fake in tests without touching callers. The failure mode is over-application, creating a one-implementation interface for every class just in case.
85. What is a functional interface? 2–5 yrs
A functional interface is an interface with exactly one abstract method, so a lambda or method reference can stand in for an instance of it — Runnable, Comparator and Function are examples. It is the bridge between object-oriented and functional style: the compiler treats the lambda as an implementation of that single method. Default and static methods do not count towards the one-abstract-method rule.
86. What is duck typing and how does it differ from interface-based polymorphism? 2–5 yrs
Duck typing means an object is acceptable if it has the methods being called, with no declared relationship to any interface — if it quacks, it is a duck. Python, Ruby and JavaScript work this way; the check happens at call time. Interface-based polymorphism requires the type to declare conformance, which the compiler verifies up front. Duck typing buys flexibility and loses the compile-time guarantee and the discoverability of an explicit contract.
87. Can an abstract class have no abstract methods at all? 2–5 yrs
Yes. Declaring a class abstract only means it cannot be instantiated; it does not require any abstract members. This is useful for a base class that is fully functional but meaningless on its own, or as a deliberate signal that callers must pick a concrete subclass. It is also how some frameworks provide an adapter base class that implements a whole interface with empty methods.
SOLID Principles
88. What are the SOLID principles? 2–5 yrs
SOLID is a set of five design principles for maintainable object-oriented code: Single Responsibility (a class should have one reason to change), Open/Closed (open for extension, closed for modification), Liskov Substitution (subtypes must be substitutable for their base types), Interface Segregation (prefer many specific interfaces over one general one), and Dependency Inversion (depend on abstractions, not concrete implementations).
89. What is the Single Responsibility Principle, with a violation example? 2–5 yrs
A class should have one reason to change — one axis of responsibility, usually one stakeholder or concern. The classic violation is an Invoice class that calculates totals, formats itself as PDF, and writes itself to the database: a tax rule change, a layout change, and a schema change all force edits to the same file, and they come from three different teams. The fix is to split calculation, rendering and persistence into separate types that collaborate.
90. What is the Open/Closed Principle, with a violation example? 2–5 yrs
Software entities should be open for extension but closed for modification: you should be able to add behaviour without editing tested code. The violation is a shipping-cost function with a switch over carrier types that you must reopen and edit for every new carrier, risking the existing branches. Replacing the switch with a Carrier interface and one class per carrier means adding a carrier is a new file, not an edit.
91. What is the Liskov Substitution Principle, with a violation example? 2–5 yrs
Any code that works with a base type must keep working when handed a subtype, without knowing the difference. The textbook violation is Square extends Rectangle: setting width and height independently and asserting the area breaks, because Square secretly couples the two. Another is an ImmutableList subclass whose add() throws — it compiles, but it weakens the parent's contract, which is exactly what LSP forbids.
92. What is the Interface Segregation Principle, with a violation example? 2–5 yrs
No client should be forced to depend on methods it does not use. The violation is a fat Worker interface with work(), eat() and sleep(): a RobotWorker must implement eat() and sleep() with empty bodies or exceptions, and every change to the fat interface recompiles clients that never touched those methods. Splitting it into Workable, Feedable and Restable lets each type implement only what it means.
93. What is the Dependency Inversion Principle, with a violation example? Senior
High-level policy should not depend on low-level detail; both should depend on abstractions. The violation is an OrderService that constructs a MySqlOrderRepository inside itself — the business rule now depends on a database driver, cannot be unit tested without MySQL, and cannot move to another store. Inverting it means OrderService depends on an OrderRepository interface it owns, and the MySQL class implements it, so the arrow of dependency points from detail to policy.
94. What is dependency injection and how does it relate to Dependency Inversion? 2–5 yrs
Dependency injection is the technique of passing a collaborator in — through the constructor, a setter, or a method parameter — instead of creating it inside the class. Dependency Inversion is the principle about which direction dependencies should point; injection is one common way to satisfy it. Constructor injection is usually preferred because it makes dependencies explicit and lets the object be fully valid the moment it exists.
95. What is Inversion of Control? Senior
Inversion of Control is the general idea that the flow of control is handed to a framework or container rather than driven by your code — your code supplies pieces and something else decides when to call them, which is why it is described as the Hollywood principle. Dependency injection is one instance of it; template methods, event callbacks and servlet lifecycles are others. The benefit is decoupling; the cost is that control flow becomes harder to follow in a debugger.
96. Can following SOLID make a design worse? Senior
Yes, when the principles are applied mechanically. Splitting every class until each has one method, or adding an interface with a single implementation for every type, produces a codebase where a simple change touches a dozen files and no one can find where the work happens. SOLID exists to make change cheaper; if a particular application of it makes change more expensive, it is being applied to a problem you do not have.
Design Principles and Code Quality
97. What does DRY mean, and when is it taken too far? Fresher
Don't Repeat Yourself: every piece of knowledge should have one authoritative representation, so a rule change is a one-place edit. It is about duplicated knowledge, not duplicated characters. Taken too far it produces the wrong abstraction — two pieces of code that merely look alike get merged, and then every later difference is bolted on as a flag parameter. Duplication is cheaper than the wrong abstraction.
98. What does KISS mean in practice? Fresher
Keep It Simple, Stupid: prefer the most straightforward design that solves the actual problem, because simple code is easier to read, test and change than clever code. In practice it means fewer layers, fewer configuration knobs, and no framework where a function would do. The test is whether a new team member can follow the code without a guided tour.
99. What does YAGNI mean? Fresher
You Aren't Gonna Need It: do not build functionality on speculation about future requirements. Speculative generality costs you the build and test effort now, carries maintenance weight forever, and is usually wrong about what was actually needed. YAGNI is not an argument against good design — keep the code easy to change, then change it when the requirement is real.
100. What is coupling? 2–5 yrs
Coupling is the degree to which one module depends on the internals of another. Loose coupling means a module talks to others only through narrow, stable interfaces, so a change on the other side does not force a change here. Tight coupling — reaching into another object's fields, depending on concrete classes, sharing global mutable state — is what makes a change in one file break three others.
101. What is cohesion? 2–5 yrs
Cohesion is how strongly the parts of a single module belong together. A highly cohesive class does one thing, and all its fields and methods contribute to that thing. Low cohesion looks like a Utils class or a Manager whose methods share nothing but a file, which makes the class hard to name, hard to test, and a magnet for further unrelated code.
102. Why do you want low coupling and high cohesion? 2–5 yrs
Together they determine how expensive change is. High cohesion means a single requirement change lands mostly inside one module; low coupling means that module's change does not propagate outwards. The pair is really one goal seen from two sides — put related things together, keep unrelated things apart — and almost every other design principle, including SOLID, is a specific tactic for reaching it.
103. What is the Law of Demeter? Senior
The Law of Demeter, or principle of least knowledge, says a method should only call methods on itself, its own fields, its parameters, and objects it creates. The symptom of breaking it is a train wreck like order.getCustomer().getAddress().getCity().getName(), which couples the caller to three classes it never asked about. The fix is to ask the immediate collaborator for what you need — order.shippingCity() — so the chain lives behind one boundary.
104. What is separation of concerns? 2–5 yrs
Separation of concerns means each part of a system addresses one concern — persistence, business rules, presentation, transport — and knows as little as possible about the others. It is why layered architectures and MVC exist. The payoff is that you can change the database or swap a web framework without rewriting the business rules, and the usual violation is SQL or HTML embedded inside domain logic.
105. What is a god class and why is it a problem? 2–5 yrs
A god class is one that has accumulated too many responsibilities and too much state — often named Manager, Processor or Helper — and ends up orchestrating most of the system. It is a problem because every feature touches it, so merge conflicts concentrate there, it cannot be unit tested in isolation, and no one can hold it in their head. It is the most visible Single Responsibility violation, and the fix is extracting cohesive collaborators one at a time.
106. What is the difference between a design principle and a design pattern? 2–5 yrs
A principle is a general guideline about what makes a design good — depend on abstractions, keep cohesion high — and it does not prescribe code. A pattern is a named, reusable solution shape for a recurring problem, with a known structure and known trade-offs. Patterns are often concrete ways of honouring principles: Strategy is one way to satisfy Open/Closed. Knowing principles without patterns is vague; knowing patterns without principles leads to over-application.
107. What is an anti-pattern? 2–5 yrs
An anti-pattern is a common solution that looks reasonable but reliably causes more problems than it solves — god classes, singletons used as global state, anaemic domain models that are pure data with all logic elsewhere, and copy-paste inheritance. Naming them matters because they usually arrive gradually rather than by decision. The useful part of the concept is that each anti-pattern comes with a known refactoring out of it.
108. What is the composition root of an application? Senior
The composition root is the single place — typically near the entry point — where the concrete implementations are chosen and wired together into an object graph. Everything below it depends only on abstractions, which is what makes Dependency Inversion practical instead of theoretical. Scattering construction across the codebase, or using a service locator to fetch dependencies on demand, is what dissolves that boundary and hides the real dependency graph.
Design Patterns
109. What is a design pattern, and what are the three main categories? Fresher
A design pattern is a named, reusable solution to a problem that recurs across designs, described in terms of structure, participants and trade-offs rather than code. The Gang of Four grouped them into creational (how objects are made: Singleton, Factory, Builder, Prototype), structural (how objects are composed: Adapter, Decorator, Facade, Proxy, Composite) and behavioural (how objects interact: Strategy, Observer, Command, Template Method, State, Visitor).
110. What is the Singleton pattern and when is it appropriate? 2–5 yrs
Singleton ensures a class has exactly one instance and provides a global access point, usually via a private constructor and a static accessor. It is appropriate when the resource genuinely is unique and stateless enough not to become a hidden channel between components — a logger, a configuration holder, a connection pool. Even then, injecting one shared instance is usually better than a static getter, because it keeps the dependency visible and testable.
111. How do you make a Singleton thread-safe? Senior
The naive lazy version has a race: two threads can both see a null instance and both construct one. Options are eager initialisation (create at class-load time, simplest and usually sufficient), a static holder class that leans on the language's guaranteed-once class initialisation, double-checked locking with the field marked volatile so the partially constructed object cannot be published, or in Java an enum, which the runtime guarantees to be single-instance and serialisation-safe. Double-checked locking without volatile is the classic broken answer.
112. Why is Singleton often called an anti-pattern? Senior
Because it is global mutable state wearing a design-pattern badge. It hides dependencies — a class using a singleton does not declare it, so you cannot tell what it needs from its constructor — it makes unit tests order-dependent since state leaks between them, and it becomes a contention point under concurrency. If you need one instance, create one and inject it; uniqueness is a lifecycle decision, not a property the class should enforce on itself.
113. What is the Factory Method pattern? 2–5 yrs
Factory Method defines an interface for creating an object but lets subclasses decide which concrete class to instantiate, so the creating code depends only on the product abstraction. You use it when the exact type depends on context — a document application whose OpenDocument step creates a Spreadsheet or a Presentation. The benefit is that adding a product type does not require editing the code that consumes it.
114. What is the difference between Factory Method and Abstract Factory? Senior
Factory Method is a single overridable method producing one kind of product, and it uses inheritance — the subclass chooses. Abstract Factory is an object exposing several creation methods that produce a family of related products meant to be used together, and it uses composition — you pass a different factory in. The usual example is a UI toolkit: an Abstract Factory produces a matching Button, Checkbox and Scrollbar for one platform, so you cannot accidentally mix.
115. What is the Builder pattern and when do you reach for it? 2–5 yrs
Builder separates the construction of a complex object from its representation, accumulating parameters through chained calls and producing the finished object in a build() step. You reach for it when a constructor has many parameters, several of them optional, or when several of the same type sit next to each other and are easy to swap by accident. It also lets you validate the whole combination once, at build time, and return an immutable result.
116. What is the Prototype pattern? 2–5 yrs
Prototype creates new objects by copying an existing configured instance rather than constructing one from scratch. It pays off when construction is expensive — an object built from a database read or a parsed template — or when the concrete type is not known statically and you only hold an example to clone. Its central risk is the shallow-versus-deep copy question, since a careless clone shares mutable internals with the original.
117. What is the Observer pattern? 2–5 yrs
Observer defines a one-to-many dependency: a subject maintains a list of observers and notifies them all when its state changes, without knowing anything about them beyond the notification interface. It underpins UI event handling, model-view updates and pub/sub messaging. The trade-offs to mention are memory leaks when observers are never unregistered, and hard-to-follow cascades when a notification triggers further notifications.
118. What is the Strategy pattern? 2–5 yrs
Strategy encapsulates each member of a family of interchangeable algorithms behind a common interface and lets the client select one at runtime. A checkout that accepts several pricing rules, or a sorter parameterised by a comparator, are typical uses. It is the standard cure for a growing switch statement, and it satisfies Open/Closed because a new algorithm is a new class rather than an edit to the caller.
119. What is the difference between the Strategy and State patterns? Senior
They are structurally almost identical — both delegate to an interchangeable object behind an interface — and differ in intent. With Strategy the client chooses the algorithm and the strategies are unaware of each other. With State the object's behaviour changes as its internal state changes, and the state objects usually decide the transitions, handing control to the next state. If the objects know about their successors, you are looking at State.
120. What is the Decorator pattern? 2–5 yrs
Decorator wraps an object in another object that implements the same interface, adding behaviour before or after delegating to the wrapped instance. Because the wrapper is the same type, decorators stack — buffering over compression over a raw stream, which is exactly how java.io is built. It is the composition-based alternative to subclassing for every combination of features, which would otherwise explode combinatorially.
121. What is the Adapter pattern? 2–5 yrs
Adapter converts the interface of an existing class into the one a client expects, so two things that were not designed together can work together. You use it when integrating a third-party library or a legacy component you cannot modify. The adapter holds the adaptee and translates calls; the giveaway that you need one is a mismatch of vocabulary at a boundary rather than a mismatch of behaviour.
122. What is the difference between Adapter, Decorator, and Proxy? Senior
All three wrap an object, and intent separates them. Adapter changes the interface without changing behaviour. Decorator keeps the interface and adds behaviour, and is designed to stack. Proxy keeps the interface and controls access to the subject — lazy loading, caching, remoting, permission checks — usually managing the subject's lifecycle rather than enhancing its result. Naming the intent, not the structure, is what interviewers are listening for.
123. What is the Facade pattern? 2–5 yrs
Facade provides a single simplified entry point to a complicated subsystem, so common tasks need one call instead of orchestrating six objects in the right order. It reduces coupling because clients depend on the facade rather than the internals, and it does not prevent advanced callers from reaching past it. The risk is that the facade grows into a god class if every new subsystem feature gets a method on it.
124. What is the Template Method pattern? 2–5 yrs
Template Method defines the skeleton of an algorithm in a base-class method, deferring specific steps to abstract methods that subclasses implement, while the overall order stays fixed. A data importer that always validates, parses, transforms and saves, but parses differently per format, is a typical use. It relies on inheritance, so the Strategy pattern is often preferred when you want the steps swappable at runtime rather than per subclass.
125. What is the Command pattern? 2–5 yrs
Command turns a request into an object carrying the action and its parameters, so it can be passed around, queued, logged, or executed later. Because each command knows how to perform itself, adding an undo() method gives you undo/redo almost for free, which is why editors and transactional UIs use it. It also decouples the thing that triggers an action (a menu item) from the thing that performs it.
126. What is the Composite pattern? 2–5 yrs
Composite lets you treat individual objects and compositions of objects uniformly by giving both the same interface, so a client can call render() or size() on a leaf or a whole tree without checking which it has. File systems, UI widget trees and nested order lines are the standard examples. The trade-off is that the shared interface either becomes too general or forces leaves to implement child-management methods they do not support.
127. What is the MVC pattern? 2–5 yrs
Model-View-Controller splits an application into the model (data and business rules), the view (presentation), and the controller (which interprets input and coordinates the two). The point is that the model knows nothing about the view, so the same data can be rendered many ways and the rules can be tested with no UI. MVP, MVVM and their relatives are variations that shift how much logic sits in the middle layer and how the view is updated.
128. What is the Repository pattern? 2–5 yrs
Repository puts a collection-like interface in front of persistence, so domain code says orders.findByCustomer(id) instead of writing queries. It keeps storage details out of business logic, makes the domain testable against an in-memory implementation, and gives a single place to change how data is fetched. The common criticism is that a repository which just forwards every method to an ORM adds a layer without adding an abstraction.
Objects in Practice
129. What is the difference between a shallow copy and a deep copy? 2–5 yrs
A shallow copy duplicates the object's own fields, so any reference field still points to the same nested object — mutating that nested object is visible through both copies. A deep copy recursively duplicates the nested objects too, producing a fully independent graph. Shallow is cheap and often correct when the nested objects are immutable; deep is required when they are mutable and the copies must not interfere.
130. What is object cloning and what are its pitfalls? 2–5 yrs
Cloning creates a new object with the same state as an existing one, usually via a clone method or a copy constructor. The pitfalls are that default clone implementations are shallow, that they typically bypass constructors so validation and final-field initialisation are skipped, and that subclasses easily break the contract by returning the wrong type. Most modern advice is to prefer a copy constructor or a static factory, which are explicit about depth and run normal construction.
131. What is an immutable object and why is immutability useful? 2–5 yrs
An immutable object's observable state cannot change after construction; any modifying operation returns a new instance. It is useful because such objects are automatically thread-safe with no locking, they can be shared and cached freely, and they are safe to use as map keys since their hash never drifts. The cost is allocation churn when you change them often, which is why builders and persistent data structures exist.
132. How do you design an immutable class? 2–5 yrs
Make the class final or sealed so no subclass can add mutable state, make every field private and final, set all fields in the constructor, provide no setters or other mutators, and defensively copy any mutable object both on the way in and on the way out. Missing the defensive copy is the usual bug: storing a caller's list directly means the caller can still mutate your state after construction.
133. What is the difference between identity and equality? Fresher
Identity asks whether two references point to the same object in memory; equality asks whether two objects represent the same value. Reference comparison tests identity, and an equals method tests equality. Value types like a Money or a Date should compare by value, while entities with a lifecycle — a specific user account — usually compare by identifier, and mixing the two models is a common source of duplicate-detection bugs.
134. Why must equality and hashing be kept consistent? 2–5 yrs
Hash-based collections locate an object by its hash first and only then compare for equality, so if two equal objects produce different hashes they land in different buckets and the lookup misses. The contract is one-directional: equal objects must hash equally, but unequal objects may collide. The classic bug is overriding equality alone, or mutating a field used in the hash after the object is already in a set.
135. What is serialisation? 2–5 yrs
Serialisation converts an object graph into a byte stream or text format so it can be stored or sent over a network, and deserialisation reconstructs it. The design issues are versioning — old data must still load after the class changes — and security, since deserialising untrusted input can instantiate arbitrary types and has been the root of many remote-code-execution vulnerabilities. Explicit formats like JSON or Protocol Buffers are usually preferred to language-native serialisation for this reason.
136. What are generics or templates, and what problem do they solve? 2–5 yrs
Generics let you write a class or method parameterised by type, so one implementation works for many element types while the compiler still checks each use. Before generics, collections held a universal base type and every read needed a cast that could fail at runtime. Generics move that failure to compile time and remove the casts, which is both a safety and a readability win.
137. What is the difference between type erasure and reified generics? Senior
With erasure, as in Java, the type argument exists only at compile time and is discarded afterwards, so at runtime a list of strings and a list of integers are the same type and you cannot ask an object what its type parameter was. With reified generics, as in C#, the runtime keeps the type argument, so it can be inspected and used to create arrays or instances. Erasure buys backwards compatibility; reification buys runtime type information.
138. What are covariance and contravariance? Senior
Covariance preserves the subtype direction — if Dog is an Animal, a read-only sequence of Dogs can be used as a sequence of Animals. Contravariance reverses it — something that consumes Animals can be used where a consumer of Dogs is expected. The rule of thumb is that producers are covariant and consumers are contravariant, and mutable containers must be invariant, which is why an array of Dogs typed as an array of Animals can throw when you store a Cat into it.
139. How should exceptions be used in object-oriented design? 2–5 yrs
An exception should signal that a method could not fulfil its contract, and it should carry enough context for a caller to decide what to do. Throw at the level that detects the problem, catch at the level that can actually handle it, and let everything in between propagate. The anti-patterns are catching a broad type and swallowing it, using exceptions for ordinary control flow, and letting low-level exception types leak through an abstraction boundary.
140. When should you create a custom exception class? 2–5 yrs
When callers need to distinguish this failure from others in order to react differently, or when the failure carries domain data worth exposing — an InsufficientFundsException with the shortfall amount. A custom type is better than an error code because it cannot be ignored silently and it names the problem in domain terms. Creating one per method, with no extra information and no distinct handling, is just noise.
141. What is RAII, and how do languages without it manage resources? Senior
Resource Acquisition Is Initialisation ties a resource's lifetime to an object's scope: the constructor acquires it and the destructor releases it deterministically when the scope exits, including on an exception path. It is why C++ smart pointers and lock guards are hard to leak. Garbage-collected languages have no deterministic destruction, so they provide scoped constructs instead — try-with-resources, using, with, defer — which call an explicit close on exit.
142. What is reflection and when is it justified? Senior
Reflection lets a program inspect and manipulate types at runtime — enumerate members, read annotations, instantiate a class named in a string, invoke a method dynamically. It is what makes dependency injection containers, ORMs, serialisers and test runners possible. It is not justified in ordinary application code, because it defeats compile-time checking, resists refactoring tools, and is markedly slower than a direct call.
143. What is the difference between a value object and an entity? Senior
An entity has an identity that persists through change — a Customer is the same customer after they move house — so it is compared by identifier and usually mutable. A value object is defined entirely by its attributes — a Money of 500 INR is interchangeable with any other — so it is compared by value and should be immutable. Modelling something with identity as a value, or vice versa, is a frequent cause of duplicate records and confusing equality behaviour.
144. What is a DTO, and why not just pass the domain object? 2–5 yrs
A Data Transfer Object is a flat, behaviour-free structure used to move data across a boundary — an API response, a service call — in one round trip. You keep it separate from the domain object so that the wire contract can stay stable while the domain evolves, so internal fields are not accidentally exposed, and so serialisation concerns do not creep into your model. The cost is mapping code, which is the trade-off people argue about.
145. What is a POJO or plain object? Fresher
A plain old object is an ordinary class with fields and accessors that does not extend or implement anything imposed by a framework and carries no framework annotations in its core. The value is testability and portability: it can be instantiated with new in a unit test and survives a change of framework. The related warning is the anaemic domain model, where every object is plain data and all behaviour has drifted into service classes.
Get these answered live in your real interview
NostrobeAI is a real-time AI interview copilot — it hears the question and drafts a strong answer on your screen, invisible on Zoom, Meet, and Teams. One-time pricing, no subscription.
Try NostrobeAI free