Skip to main content

Top 30 Java Interview Questions & Answers for 3+ yrs Experience at Infosys

Top 30 Java Interview Questions & Answers for Infosys (3+ Years Experience)

Updated for 2026 – Real-world explanations + examples

Infosys interviews emphasize problem-solving, Java fundamentals, collection performance, and multithreading concepts. Below are the top 30 most commonly asked Java questions for 3–5 years experience, each with concise answers + real project examples

Q1. What are the four major OOP concepts in Java?

Answer: The four major object-oriented programming (OOP) concepts are: Encapsulation, Abstraction, Inheritance, Polymorphism

  • Encapsulation: wrapping data (fields) and methods in a class, controlling access via modifiers (private/public).

  • Abstraction: exposing only necessary details, hiding internal implementation.

  • Inheritance: subclassing to reuse code.

  • Polymorphism: objects taking many forms — e.g., method overloading (compile time) or overriding (runtime).
    Example:

class Animal { public void sound() { System.out.println("Some sound"); } } class Dog extends Animal { // inheritance @Override public void sound() { System.out.println("Woof"); } // polymorphism }

Here Dog inherits from Animal. If you have Animal a = new Dog(); a.sound(); you get “Woof” (runtime polymorphism). Encapsulation example: private fields with getters/setters.


Q2. Why is String immutable in Java?

Answer: java.lang.String is immutable because once created, its value cannot be changed. Internal design: final class, internal final char[] (or byte[] in modern Java). Immutability gives benefits: thread-safety, caching (string pool), safe use as keys in collections, avoids bugs from unexpected modification. 
Example:

String s1 = "hello"; String s2 = s1.replace("h","j"); System.out.println(s1); // "hello" System.out.println(s2); // "jello"

Here s1 wasn’t changed; a new String s2 was created. If Strings were mutable, many issues would arise in multi­threaded code or string pooling.


Q3. What is the difference between String, StringBuffer, and StringBuilder?

Answer:

  • String is immutable.

  • StringBuffer is mutable and thread-safe (synchronized).

  • StringBuilder is mutable but not synchronized (so not thread-safe), recommended for single-thread use due to better performance.
    Example:

StringBuilder sb = new StringBuilder("Hi"); sb.append(" there"); System.out.println(sb); // "Hi there" // In multi-threaded scenario you might choose StringBuffer: StringBuffer sbf = new StringBuffer("Hello"); sbf.append(" world");

Q4. Explain difference between compile-time polymorphism vs runtime polymorphism.

Answer:

  • Compile-time polymorphism: method overloading (same method name, different parameters) or operator overloading (not in Java for user types).

  • Runtime polymorphism: method overriding via inheritance and dynamic dispatch (at runtime the JVM decides which method to call).
    Example:

class Parent { void show() { System.out.println("Parent"); } } class Child extends Parent { @Override void show() { System.out.println("Child"); } }
Parent p = new Child(); p.show(); // prints "Child" => runtime polymorphism

Q5. What is the difference between == and .equals() in Java?

Answer:

  • == compares reference identity (whether two references point to same object in memory).

  • .equals() is a method (from Object), meant to compare logical equivalence, and can be overridden (like in String, Integer, custom classes). If not overridden, equals falls back to ==.
    Example:

String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1 == s2); // false (different objects) System.out.println(s1.equals(s2)); // true (same content)

Q6. Is Java pass-by-value or pass-by-reference?

Answer: Java is strictly pass-by-value. For primitive types, the value is copied. For object references, the value of the reference is copied (i.e., a copy of the pointer), but both refer to same object. There is no pass-by-reference in Java (i.e., you cannot change the caller’s reference to point to new object).
Example:

void changeValue(int x) { x = 10; } int a = 5; changeValue(a); System.out.println(a); // still 5 void changeObject(MyObj obj) { obj.field = "new"; obj = new MyObj("fresh"); } MyObj m = new MyObj("orig"); changeObject(m); System.out.println(m.field); // "new" — because obj.field changed // but m still refers to original object, we didn’t change the caller’s reference

Q7. How does garbage collection work in Java? Explain memory structure.

Answer:
Java runtime manages memory automatically via garbage collection (GC). Major memory areas: Heap (objects), Stack (local variables + method frames), Method Area / PermGen or Metaspace (class definitions), PC register / native stacks. Objects no longer referenced become eligible for GC. There are different GC algorithms (Mark & Sweep, Generational GC, etc). 
Example:

public void demo() { MyObj o = new MyObj(); o = null; // object becomes eligible for GC (assuming no other refs) }

In reality you don’t force GC; you trust JVM to reclaim memory.


Q8. What is the difference between ArrayList and LinkedList in Java?

Answer:

  • ArrayList is backed by a dynamic array: good for random access (get by index) O(1), slower for insertion/removal in the middle (shifting).

  • LinkedList is a doubly linked list: good for insertion/removal at head/tail/middle (if you have reference) but slower for random access (O(n)).
    Also, LinkedList implements List and Deque interfaces (so you can use it as queue).
    Example:

List<String> list1 = new ArrayList<>(); list1.add("a"); list1.add("b"); String x = list1.get(1); // quick List<String> list2 = new LinkedList<>(); list2.add("a"); list2.add("b"); String y = list2.get(1); // slower than ArrayList

Q9. What is the difference between List, Set and Map in Java Collections?

Answer:

  • List is an ordered collection, allows duplicates, index-based access.

  • Set is a collection that does not allow duplicates, may be ordered or unordered depending on implementation (HashSet, TreeSet).

  • Map is a collection of key→value pairs; keys must be unique, values may duplicate; not a subtype of Collection. 
    Example:

List<String> list = new ArrayList<>(); list.add("apple"); list.add("apple"); // allowed Set<String> set = new HashSet<>(); set.add("apple"); set.add("apple"); // second add ignored Map<String, Integer> map = new HashMap<>(); map.put("apple", 1); map.put("apple", 2); // replaces value 1 with 2

Q10. Explain HashMap internal working in Java.

Answer:
HashMap works by using a hash table where keys are hashed to hashed-buckets (an array of Node<K,V>). Steps: compute hashCode of key, then map to bucket via index (hash & (capacity-1)). If collision (same bucket), chain via linked list or tree (since Java 8). On insertion: if load factor threshold exceeded, resize (rehash). Retrieval: compute hash, go to bucket, traverse chain comparing key equals until match.
Example:

Map<String, Integer> map = new HashMap<>(); map.put("apple", 1); map.put("banana", 2); int val = map.get("apple"); // hash("apple") → bucket → value 1

If you insert keys whose hash map to same bucket repeatedly, performance may degrade without treeifying.


Q11. What is fail-fast vs fail-safe iterator in Java Collections?

Answer:

  • A fail-fast iterator (e.g., on ArrayList, HashMap’s keySet) checks a modification count and throws ConcurrentModificationException if collection modified structurally after iterator created.

  • A fail-safe iterator (e.g., on CopyOnWriteArrayList, ConcurrentHashMap) works on a snapshot of the collection or uses internal locking so modifications don’t cause exceptions in the iteration thread.
    Example:

List<String> list = new ArrayList<>(List.of("a","b","c")); for (String s : list) { list.add("d"); // during iteration → ConcurrentModificationException }

Contrast with CopyOnWriteArrayList which permits such modification although new element may not appear in iteration.


Q12. What is multithreading in Java? How do you create threads?

Answer:
Multithreading means executing multiple threads concurrently within a process. In Java you can create threads by:

  • Extending Thread class and overriding run(), then start().

  • Implementing Runnable interface (or Callable<V>) and passing to Thread (or using executor).
    You also use concurrency utilities in java.util.concurrent.
    Example:

class MyTask implements Runnable { public void run() { System.out.println("Task running " + Thread.currentThread().getName()); } } Thread t = new Thread(new MyTask()); t.start();

Q13. What is the difference between synchronized and volatile in Java?

Answer:

  • synchronized ensures mutual exclusion and visibility: only one thread at a time can execute a synchronized block/object; it also ensures memory visibility (locks flush caches).

  • volatile ensures visibility of changes across threads (reads/writes go to main memory) but does not provide atomicity or locking for compound actions. So volatile is good for simple flags/shared variables; for compound state changes you need synchronization or other concurrency constructs.
    Example:

volatile boolean flag = false; void writer() { flag = true; } void reader() { if (flag) { System.out.println("Flag is true"); } }

If you needed to increment a counter, volatile alone wouldn’t suffice for atomic increment (use AtomicInteger or synchronized).


Q14. What is a deadlock? How can it be prevented?

Answer:
Deadlock is a situation where two or more threads are blocked forever, each waiting for a resource held by the other. In Java this can happen when Thread-A holds Lock-1 and waits for Lock-2, while Thread-B holds Lock-2 and waits for Lock-1.
Prevention strategies:

  • Acquire locks in a fixed global order.

  • Use tryLock() with timeout.

  • Use less fine-grained locking or avoid nested locks.
    Example:

Object lock1 = new Object(); Object lock2 = new Object(); Thread t1 = new Thread(() -> { synchronized(lock1) { synchronized(lock2) { // do work } } }); Thread t2 = new Thread(() -> { synchronized(lock2) { synchronized(lock1) { // do work } } }); t1.start(); t2.start(); // possible deadlock if t1 holds lock1, t2 holds lock2

Q15. What are lambda expressions and functional interfaces in Java 8?

Answer:

  • A functional interface is an interface with exactly one abstract method (e.g., Runnable, Comparator, Consumer<T>). You can annotate with @FunctionalInterface.

  • A lambda expression provides a concise way to implement a functional interface: (parameters) -> expression/body. Java 8 introduced this. Lambdas allow treating functions as first-class citizens.
    Example:

List<String> names = List.of("Alice","Bob","Charlie"); names.forEach(name -> System.out.println(name)); // lambda

Here forEach takes a Consumer<String> functional interface.


Q16. Explain the Stream API in Java 8. What is the difference between intermediate and terminal operations?

Answer:
The Stream API allows functional‐style operations on collections (and other data sources) like map/filter/reduce. Streams are lazy: you build a pipeline of operations, and execution happens when a terminal operation is called.

  • Intermediate operations return a new stream (e.g., filter(), map(), sorted()), and are lazy.

  • Terminal operations produce a result or side-effect (e.g., collect(), forEach(), reduce(), count()), and trigger the pipeline.
    Example:

List<Integer> nums = List.of(1,2,3,4,5); int sum = nums.stream() .filter(n -> n % 2 == 0) // intermediate .map(n -> n * n) // intermediate .reduce(0, Integer::sum); // terminal System.out.println(sum); // 4*4 + 2*2 = 20

Q17. What is the Optional class in Java 8? Why use it?

Answer:
java.util.Optional<T> is a container object which may or may not contain a non-null value. It helps to avoid NullPointerExceptions and makes API contracts explicit: e.g., a method returns Optional<String> instead of possibly returning null. It encourages handling absence of value.
Example:

Optional<String> maybeName = Optional.ofNullable(getName()); maybeName.ifPresent(name -> System.out.println("Name is " + name)); String name2 = maybeName.orElse("Unknown");

Q18. Explain method overloading vs method overriding in Java.

Answer:

  • Method overloading (compile time): same method name, different parameter list (type/number) within same class or subclass.

  • Method overriding (runtime polymorphism): subclass provides a specific implementation for a method declared in superclass (same name + signature).
    Example:

class A { void f(int x) { System.out.println("A: "+x); } // overloaded void f(int x, int y) { System.out.println("A: "+x+y);} } class B extends A { @Override void f(int x) { System.out.println("B: "+x); } // overriding }

Q19. What is the difference between abstract class and interface in Java (pre Java 8 vs post Java 8)?

Answer:

  • Abstract class: can have concrete methods, fields, constructors, and may hold state. A class extends only one abstract class (single inheritance).

  • Interface: initially (pre Java 8) only abstract methods; Java 8 introduced default & static methods; Java 9 added private methods; allows multiple inheritance of types (a class can implement many interfaces).
    Use interface when you want to define contract, and abstract class when you want shared code/state plus derived classes.
    Example:

interface Flyable { void fly(); default void land() { System.out.println("Landing"); } } abstract class Bird { String color; Bird(String c){ color = c; } abstract void fly(); void printColor(){ System.out.println(color); } } class Sparrow extends Bird implements Flyable { Sparrow(){ super("brown"); } @Override void fly(){ System.out.println("Sparrow flying"); } @Override public void fly() { System.out.println("Sparrow flies high"); } }

Q20. What are the new features in Java 8 (besides lambdas and streams)?

Answer: Some of the key features include: default and static methods in interfaces, method references, Optional, new Date/Time API (java.time.*), CompletableFuture, ParallelStream, Collectors utilities, StringJoiner, enhancements to Collection interface (forEach, removeIf), and more. 
Example:

List<String> l = List.of("a","b","c"); l.forEach(System.out::println); // method reference

or:

LocalDate date = LocalDate.now().plusDays(5);

Q21. Explain the difference between Array and ArrayList.

Answer:

  • Array: fixed size once created (new int[5]). Can hold primitives or objects.

  • ArrayList: resizable dynamic array (part of Java Collections), cannot hold primitives directly (use wrapper types), offers methods (add, remove, etc), size dynamically changes.
    Example:

int[] arr = new int[3]; arr[0] = 1; List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.remove(0);

Q22. What is the difference between == vs equals() for custom objects? How do you override equals() and hashCode()?

Answer:
As earlier, == checks reference equality, equals() checks logical equality. For custom objects you should override equals() and hashCode() so that objects used as keys in hash-based collections behave correctly (contract: equal objects must equal hashCode).
Example:

class Person { String name; int age; @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Person)) return false; Person p = (Person)o; return age == p.age && Objects.equals(name, p.name); } @Override public int hashCode() { return Objects.hash(name, age); } }

Q23. What is a classloader in Java? How does the JVM load classes?

Answer:
A classloader is a part of the JVM that loads class files (binary) into the runtime. Three main types: Bootstrap, Extension, Application (or System) classloader. The loading process: loading → linking (verification, preparation, resolution) → initialization (static blocks executed). Custom classloaders can be used.
Example:

Class<?> cls = Class.forName("com.myapp.MyClass");

This triggers the classloader to load the class (if not already), link it, then initialize it.


Q24. What is reflection in Java? When do you use it?

Answer:
Reflection (in java.lang.reflect) is the ability of a program to inspect and modify runtime behavior: inspect classes, methods, fields, call methods dynamically, even if private (via setAccessible). Useful for frameworks (ORMs, DI), serialization, testing. But it has overhead and breaks encapsulation.
Example:

Method m = MyClass.class.getDeclaredMethod("process", String.class); m.setAccessible(true); m.invoke(myInstance, "inputValue");

Q25. What is serialization in Java? Why and how is it done?

Answer:
Serialization is the process of converting an object into a stream of bytes (so it can be written to file/network) and deserialization is the reverse. In Java you implement java.io.Serializable (marker interface). You can use ObjectOutputStream and ObjectInputStream. It is used for caching, transmitting objects, deep cloning, etc.
Example:

class Employee implements Serializable { private static final long serialVersionUID = 1L; String name; int id; }

Then:

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("emp.ser")); oos.writeObject(new Employee("John", 101));

Q26. What is the difference between shallow copy vs deep copy in Java?

Answer:

  • Shallow copy: copies the object but not the objects it refers to (i.e., references inside the object still point to original).

  • Deep copy: copies the object and recursively copies all objects it references, so the clone is independent of the original.
    Example:

class Address { String city; } class Person implements Cloneable { String name; Address addr; public Person clone() throws CloneNotSupportedException { return (Person) super.clone(); // shallow copy } }

Here addr is same in clone & original. For deep copy you’d clone the Address as well.


Q27. What is thread-safety? Give an example of a thread-safe collection.

Answer:
Thread-safety means that a class or collection can be safely used by multiple threads simultaneously without causing inconsistent state or race conditions. Example of thread-safe collection: java.util.concurrent.ConcurrentHashMap, CopyOnWriteArrayList, Vector (legacy), Hashtable.
Example:

ConcurrentHashMap<String, Integer> cmap = new ConcurrentHashMap<>(); cmap.put("apple", 1); cmap.computeIfAbsent("banana", k -> 2); // multiple threads can safely work with cmap

Q28. What is the difference between HashMap and ConcurrentHashMap?

Answer:

  • HashMap is not thread‐safe; if accessed concurrently with modifications without proper synchronization, behavior is undefined.

  • ConcurrentHashMap is thread‐safe and uses internal locking mechanics (or lock‐free in parts) to allow concurrent reads/writes with better scalability. It does not lock entire map for modifications, uses segment or bin‐level locks (Java 8 uses internal table + CAS). Also null keys/values are not allowed in ConcurrentHashMap (unlike HashMap).
    Example:

Map<String, Integer> map = new HashMap<>(); // unsafe if multiple threads doing map.put(...) concurrently Map<String, Integer> cmap = new ConcurrentHashMap<>(); // safe for concurrent operations

Q29. What is the difference between checked vs unchecked exceptions in Java?

Answer:

  • Checked exceptions extend Exception (but not RuntimeException) and must be either caught or declared to be thrown by the method signature.

  • Unchecked exceptions extend RuntimeException (or Error) and need not be declared or caught explicitly; they usually indicate programming errors (null pointer, array out of bounds).
    Example:

void readFile() throws IOException { // IOException is checked // ... } void process() { String s = null; s.length(); // NullPointerException is unchecked }

Q30. What are default methods in interfaces (Java 8)? Why were they introduced?

Answer:
Default methods let you add concrete methods (with implementation) in interfaces by using the keyword default. They were introduced in Java 8 to support backward compatibility: to add new methods to existing interfaces (like Collection, Iterable) without breaking existing implementations. They also allow interfaces to provide some common behavior.
Example:

interface MyInterface { void doWork(); default void log(String msg) { System.out.println("Log: " + msg); } } class MyImpl implements MyInterface { public void doWork() { log("Doing work"); } }

⭐ Conclusion

These 30 Java interview questions represent the most commonly asked topics at Infosys for 3+ years experience—with a strong focus on:

✔ Collections
✔ Multithreading
✔ Lambda & Streams
✔ Memory management
✔ OOP & Core Java fundamentals

Comments

Popular posts from this blog

25+ Spring Data JPA Interview Questions with Answers, Explanations & Use Cases

  📘 Spring Data JPA Interview Questions (with Answers, Explanations & Use Cases) 1. What is JPA and how is it related to Spring Data JPA? Answer: JPA (Java Persistence API) is a Java specification for managing relational data. Spring Data JPA is a part of Spring Data that simplifies JPA usage by reducing boilerplate code. Use Case: Persisting Java objects (like User ) to a relational database without writing SQL. 2. What are the key annotations used in JPA? Answer: @Entity , @Table , @Id , @GeneratedValue , @Column , @ManyToOne , @OneToMany , etc. Explanation: These annotations map Java objects to database tables and relationships. Use Case: Creating a User entity with an auto-generated ID and fields mapped to table columns. 3. What is the difference between JPA and Hibernate? Answer: JPA is a specification; Hibernate is an implementation of that specification. Use Case: Using Hibernate as the default JPA provider in Spring Boot. 4. How do you define a p...

How to Send Emails in Spring Boot Using SMTP (With and Without Attachments)

Sending emails is a common requirement in modern web applications — for things like user registration, password resets, or notifications. In this tutorial, we’ll walk through how to send emails in a Spring Boot application using SMTP , specifically with Gmail’s SMTP server , and demonstrate how to send both plain emails and emails with attachments . 📺 Video Demo If you prefer watching over reading, here’s a full demo of this tutorial in action: 📁 GitHub Repo  Want the complete working code? Clone the GitHub link provided below which contains all the source code. Source Code GitHub Link: https://github.com/TheDipDeveloper/Spring-Boot-Sending-Email 🧰 Prerequisites Java 17 or above Maven Spring Boot 3.x A Gmail account  🚀 Step 1: Add Spring Boot Mail Dependency First, add all the required dependency on pom.xml file < dependencies > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring...

Create a Real-World Banking System with Spring Boot 3, JPA, MySQL & Postman

Are you looking to build a real-world project using Spring Boot and MySQL? In this tutorial, we'll walk you through creating a complete Banking Service REST API that supports full CRUD operations, money transfers, deposits, and withdrawals. Whether you're preparing for interviews or enhancing your portfolio, this hands-on project will give you practical experience with Spring Boot 3, Spring Data JPA, and RESTful API design. In this post, you'll learn how to build a Banking Service REST API using: ✅ Spring Boot 3.x ✅ Java 17 ✅ MySQL ✅ Postman for API testing ✅ IntelliJ IDEA ✅ GitHub Repo : https://github.com/TheDipDeveloper/Banking-Service-Application-REST-Api By the end, you'll have a complete backend application that supports: Creating bank accounts Fetching account data Deposits and withdrawals Transferring funds between accounts Deleting accounts 🛠️ Tech Stack Java 17 Spring Boot 3.x Spring Data JPA MySQL Lombok ...