Infosys Java Developer Interview Experience — 2
Interview of a candidate with 7+ years of Experience
Infosys Java Developer Interview Experience — 2
Interview of a candidate with 7+ years of Experience

If you are not a paid member of Medium, please use my friend link to read the entire article: Friend Link
I, recently, appeared for the Infosys interview for Java Lead role. For context, I have over 7.5 years of experience in Java, SQL, Spring Boot, Microservices, and related technologies.
I’ll break this down in 2 parts:
- Interview Process
- Interview Questions
This is how it went:
1. Interview Process:
The process was smooth and as follows:
- I got an email from Infosys Talent Acquisition team regarding hiring in Infosys.
- I shared the requested details in a survey form.
- After sharing the details, the first technical round was setup.
On the day of the interview:
- The interviewer joined the call on time.
- We exchanged pleasantries and got straight into technical questions.
- The interviewer were professional and courteous throughout.
2. Interview Questions:
Below are some of the technical questions I was asked. I’ve merged similar questions and follow-up queries for clarity.
I’ll include textbook explanations for all the answers to help anyone preparing for interviews.
Q1. What are the benefits of OOPs?
Below are the benefits of OOPs:
- Modularity (Code Reusability):
- OOP allows breaking down a complex problem into smaller objects.
- Each class can be reused across different projects without rewriting code.
class MathUtils {
public int add(int a, int b) {
return a + b;
}
}
// Reuse MathUtils anywhere
MathUtils util = new MathUtils();
System.out.println(util.add(5, 10)); // Output: 15
2. Encapsulation (Data Hiding & Security):
- Internal details of an object are hidden, and only necessary functionality is exposed via methods.
- This protects data and improves code maintainability.
class BankAccount {
private double balance; // hidden from outside
public void deposit(double amount) {
balance += amount;
}
public double getBalance() {
return balance;
}
}
BankAccount account = new BankAccount();
account.deposit(5000);
System.out.println(account.getBalance()); // 5000
3. Inheritance (Code Reuse & Extensibility):
- Existing classes can be extended to create new ones.
- Promotes code reusability and reduces redundancy.
class Vehicle {
void start() { System.out.println("Vehicle starts"); }
}
class Car extends Vehicle {
void honk() { System.out.println("Car honks"); }
}
Car c = new Car();
c.start(); // Inherited method
c.honk(); // Car specific
4. Polymorphism (Flexibility & Scalability):
- Same function/method can behave differently depending on the object.
class Animal {
void sound() { System.out.println("Some sound"); }
}
class Dog extends Animal {
void sound() { System.out.println("Bark"); }
}
class Cat extends Animal {
void sound() { System.out.println("Meow"); }
}
Animal a1 = new Dog();
Animal a2 = new Cat();
a1.sound(); // Bark
a2.sound(); // Meow
5. Abstraction (Focus on What, Not How):
- Hides implementation details and shows only essential features.
abstract class Payment {
abstract void pay(double amount);
}
class CreditCardPayment extends Payment {
void pay(double amount) {
System.out.println("Paid " + amount + " using Credit Card");
}
}
Payment p = new CreditCardPayment();
p.pay(1000); // Paid 1000 using Credit Card
6. Maintainability & Scalability:
- Since code is modular, changes in one class don’t heavily affect others.
- Easy to extend the system as requirements grow.
7. Real-World Modeling:
- OOP models real-world entities (like Car, Employee, BankAccount) making systems intuitive.
class Employee {
private String name;
private double salary;
Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public void showDetails() {
System.out.println(name + " earns " + salary);
}
}
Employee e = new Employee("Shivam", 90000);
e.showDetails(); // Shivam earns 90000
Q2. What are the benefits of Functional Programming?
Functional Programming (FP) emphasizes writing pure functions, immutability, and stateless code. It’s widely used in Java 8 (Streams, Lambdas, Optional), Scala, Kotlin, etc.
Below are some of it’s benefits:
1. Immutability → Safer Code:
- Data is immutable (cannot be changed once created).
- Prevents accidental changes and side effects.
- Makes code thread-safe by default.
List<String> names = Arrays.asList("Shivam", "Rahul", "Amit");
// Create a new list (no mutation)
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upperNames); // [SHIVAM, RAHUL, AMIT]
2. Pure Functions → Predictable & Testable:
- Pure functions always produce the same output for the same input.
- No hidden dependencies → easier to test and debug.
// Pure function
int square(int x) {
return x * x;
}
// Always predictable
System.out.println(square(4)); // 16
System.out.println(square(4)); // 16
3. Concise & Expressive Code:
- FP (with Lambdas & Streams) reduces boilerplate code.
- Easier to read and maintain.
// Imperative style
List<String> result = new ArrayList<>();
for(String s : names) {
if(s.startsWith("S")) {
result.add(s);
}
}
// Functional style
List<String> resultFP = names.stream()
.filter(s -> s.startsWith("S"))
.collect(Collectors.toList());
System.out.println(resultFP); // [Shivam]
4. Easier Parallelism & Concurrency:
- Since data is immutable and functions are stateless, parallel processing is safer and easier.
int sum = IntStream.range(1, 1000)
.parallel() // Safe parallel execution
.sum();
System.out.println(sum);
5. Higher-Order Functions → Reusability:
- Functions can be passed as parameters, returned as results, or stored in variables.
- Increases reusability and flexibility.
Function<Integer, Integer> squareFn = x -> x * x;
Function<Integer, Integer> doubleFn = x -> x * 2;
// Compose functions
Function<Integer, Integer> squareThenDouble = squareFn.andThen(doubleFn);
System.out.println(squareThenDouble.apply(5)); //(5*5)=25 → (25*2)=50
6. Declarative Programming → Focus on What, Not How:
- Instead of writing loops and managing states, you declare what you want.
// Find sum of even numbers
int sum = IntStream.rangeClosed(1, 10)
.filter(n -> n % 2 == 0)
.sum();
System.out.println(sum); // 30
Q3. What are Design Patterns and its Types in Java?
Design Patterns are proven, reusable solutions to common problems in software design.
They are not code, but templates / guidelines on how to structure classes and objects to solve recurring issues.
They improve readability, maintainability, reusability, and make code easier for teams to understand.
Think of them as best practices for object-oriented design.
Types of Design Patterns in Java
According to the Gang of Four (GoF), there are 23 design patterns, grouped into 3 categories:
1. Creational Patterns:
These deal with how objects are created while hiding the creation logic from the client.
Instead of instantiating objects directly using new, creational patterns give more flexibility.
Key Idea:
- Control what objects are created, how, and when.
- Makes the system independent of object creation.
Common Patterns:
- Singleton → Only one instance exists in the entire JVM.
- Factory Method → A method that decides which subclass to instantiate.
- Abstract Factory → Factory of factories (returns factories, not objects directly).
- Builder → Step-by-step object construction (great for complex objects).
- Prototype → Clone existing objects instead of creating new ones.
Use Case: When object creation is complex, costly, or needs control (e.g., database connections, configurations).
// Singleton Example
class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
System.out.println(obj1 == obj2); // true
2. Structural Patterns:
These deal with how classes and objects are combined to form larger structures. They simplify the design by ensuring that system parts fit together efficiently.
Key Idea:
- Focus on composition (object relationships) rather than inheritance.
- Provide flexibility and scalability in system architecture.
Common Patterns:
- Adapter → Makes two incompatible interfaces work together (like a power plug adapter).
- Decorator → Add new functionality to an object dynamically without altering its structure.
- Composite → Treat individual objects and groups of objects uniformly (tree-like structures).
- Proxy → Provide a placeholder to control access to another object (e.g., Virtual Proxy, Security Proxy).
- Facade → Provide a simplified interface to a complex subsystem.
- Bridge → Decouple abstraction from implementation so both can vary independently.
- Flyweight → Reuse objects instead of creating new ones to save memory.
Use Case: When you want to extend structures, improve code reuse, or hide complexities from clients.
// Adapter Example
interface MediaPlayer {
void play(String fileName);
}
class Mp3Player implements MediaPlayer {
public void play(String fileName) {
System.out.println("Playing mp3: " + fileName);
}
}
class Mp4Player {
void playMp4(String fileName) {
System.out.println("Playing mp4: " + fileName);
}
}
// Adapter to make Mp4Player compatible
class MediaAdapter implements MediaPlayer {
private Mp4Player mp4Player = new Mp4Player();
public void play(String fileName) {
mp4Player.playMp4(fileName);
}
}
MediaPlayer player = new MediaAdapter();
player.play("movie.mp4");
3. Behavioral Patterns:
These deal with how objects interact and communicate. They focus on responsibilities, delegation, and control flow between objects.
Key Idea:
- Defines how responsibilities are distributed among objects.
- Encapsulates algorithms, communication, and workflow.
Common Patterns:
- Strategy → Encapsulates algorithms; client can switch algorithms at runtime.
- Observer → One-to-many dependency; when one object changes, others are notified (e.g., Event Listeners).
- Command → Encapsulates a request as an object (useful for undo/redo).
- Chain of Responsibility → Pass request along a chain of handlers until one handles it.
- Iterator → Sequentially access elements of a collection without exposing its internals.
- State → Change object behavior when internal state changes.
- Template Method → Define the algorithm’s structure, but let subclasses define specific steps.
- Visitor → Add operations to objects without changing their classes.
- Mediator → Defines a central mediator object to reduce direct communication between classes.
- Memento → Save and restore the state of an object without exposing its internals.
Use Case: When you need flexibility in communication, separation of concerns, or to handle complex workflows cleanly.
// Strategy Example
interface PaymentStrategy {
void pay(int amount);
}
class CreditCardPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card");
}
}
class PayPalPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal");
}
}
class ShoppingCart {
private PaymentStrategy paymentStrategy;
ShoppingCart(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
void checkout(int amount) {
paymentStrategy.pay(amount);
}
}
ShoppingCart cart = new ShoppingCart(new CreditCardPayment());
cart.checkout(500); // Paid 500 using Credit Card
Q4. Explain Chain-of-Responsibility (CoR) Design Pattern
The Chain of Responsibility pattern allows a request to be passed along a chain of handlers, where each handler decides either to process the request or pass it to the next handler in the chain.
It decouples the sender and receiver:
- The sender doesn’t know which object will handle the request.
- Multiple handlers get a chance to process the request.
Characteristics:
- Follows the “pass the request along the chain” principle.
- Promotes loose coupling between sender and receiver.
- Used when multiple objects can handle a request, but the handler isn’t known in advance.
Real-World Analogy:
Think of customer support escalation:
- Level 1 support tries to solve your issue.
- If they can’t, it goes to Level 2.
- If not resolved, escalates to Level 3 manager.
You (the sender) don’t know who will fix it, but someone in the chain will.
Java Example (CoR Pattern):
// Step 1: Handler interface
abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(String request);
}
// Step 2: Concrete Handlers
class Manager extends Handler {
public void handleRequest(String request) {
if (request.equals("LeaveApproval")) {
System.out.println("Manager approved the leave request.");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
class Director extends Handler {
public void handleRequest(String request) {
if (request.equals("BudgetApproval")) {
System.out.println("Director approved the budget request.");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
class CEO extends Handler {
public void handleRequest(String request) {
if (request.equals("CompanyAcquisition")) {
System.out.println("CEO approved the company acquisition.");
} else {
System.out.println("Request could not be handled.");
}
}
}
// Step 3: Client
public class ChainOfResponsibilityDemo {
public static void main(String[] args) {
Handler manager = new Manager();
Handler director = new Director();
Handler ceo = new CEO();
// Build chain: Manager -> Director -> CEO
manager.setNextHandler(director);
director.setNextHandler(ceo);
// Send requests
manager.handleRequest("LeaveApproval"); // Manager handles
manager.handleRequest("BudgetApproval"); // Director handles
manager.handleRequest("CompanyAcquisition"); // CEO handles
manager.handleRequest("UnknownRequest"); // Nobody handles
}
}
Output:
Manager approved the leave request.
Director approved the budget request.
CEO approved the company acquisition.
Request could not be handled.
When to Use Chain of Responsibility:
- When multiple objects can handle a request, but you don’t want to specify the handler explicitly.
- When requests should be handled in a flexible, dynamic order.
- Common in logging, authentication, validation, and request filtering.
Q5. Explain S.O.L.I.D principles in detail.
I have already written an extremely detailed article on SOLID principles. I request you to please go through the same:
[embed]S.O.L.I.D Principles in Java: Deep Dive with Interview Questions A Complete Guidemedium.com
Q6. Design an Employee Details Portal REST API with these rules:
- Employee data fields: Employee Id, Name, Email Id, Salary
- Employee can search other employees by Name, Email Id, Employee Id
- Employee can view his/her own salary only (Employee A cannot view Employee B’s salary)
We need a REST API that manages employee details. Requirements:
- Fields: Employee Id, Name, Email Id, Salary.
- Search: Employees can be searched by Id, Name, Email Id.
- Salary Visibility Rule:
- An employee can see only their own salary.
- If they search other employees, they should see all details except salary.
To enforce this, we’ll:
- Use a Spring Boot REST Controller.
- Store employees in an in-memory
List<Employee>for simplicity. - Implement a DTO (Data Transfer Object) to hide salary for non-owners.
- Add a service layer for business logic.
- Simulate “logged-in employee” with a
loggedInEmployeeId(in real world → use Spring Security/JWT).
Code:
// Employee.java (Model)
public class Employee {
private int id;
private String name;
private String email;
private double salary;
// Constructors
public Employee(int id, String name, String email, double salary) {
this.id = id;
this.name = name;
this.email = email;
this.salary = salary;
}
// Getters
public int getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
public double getSalary() { return salary; }
}
// EmployeeDTO.java (For hiding salary if not self)
public class EmployeeDTO {
private int id;
private String name;
private String email;
private Double salary; // Nullable (hidden for others)
public EmployeeDTO(Employee employee, boolean includeSalary) {
this.id = employee.getId();
this.name = employee.getName();
this.email = employee.getEmail();
this.salary = includeSalary ? employee.getSalary() : null;
}
// Getters
public int getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
public Double getSalary() { return salary; }
}
// EmployeeService.java (Business Logic)
import java.util.*;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
@Service
public class EmployeeService {
private List<Employee> employees = new ArrayList<>();
// Dummy logged-in employee (In real-world → JWT or session user)
private int loggedInEmployeeId = 101;
public EmployeeService() {
employees.add(new Employee(101, "Shivam", "shivam@example.com", 500000));
employees.add(new Employee(102, "Ram", "ram@example.com", 60000));
employees.add(new Employee(103, "Amit", "amit@example.com", 70000));
}
public List<EmployeeDTO> searchEmployees(String name, String email, Integer id) {
return employees.stream()
.filter(emp -> (name == null || emp.getName().equalsIgnoreCase(name)) &&
(email == null || emp.getEmail().equalsIgnoreCase(email)) &&
(id == null || emp.getId() == id))
.map(emp -> new EmployeeDTO(emp, emp.getId() == loggedInEmployeeId))
.collect(Collectors.toList());
}
}
// EmployeeController.java (REST API Layer)
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {
private final EmployeeService employeeService;
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
// Search API
@GetMapping("/search")
public List<EmployeeDTO> searchEmployees(
@RequestParam(required = false) String name,
@RequestParam(required = false) String email,
@RequestParam(required = false) Integer id) {
return employeeService.searchEmployees(name, email, id);
}
}
Example API Usage
Request:
GET /api/employees/search?name=Shivam
Response (Shivam is logged-in employee):
[
{
"id": 101,
"name": "Shivam",
"email": "shivam@example.com",
"salary": 500000
}
]
Request:
GET /api/employees/search?name=Ram
Response (Salary hidden for others):
[
{
"id": 102,
"name": "Ram",
"email": "ram@example.com",
"salary": null
}
]
What we achieved:
- Employees can search others by Id, Name, Email.
- Employees can view their own salary but not others’ salary.
- Code follows proper layers (Model, DTO, Service, Controller).
- This is interview-level code and not prod ready code.
Final Thoughts:
The interview lasted around 35–40 minutes, and I cleared it without much difficulty.
This was followed by an offline Techno-Managerial round, where I was asked about design principles and technical use cases related to my project. After clearing that, an offline HR round was scheduled.
In the HR discussion, however, things took a turn. I was told that my current CTC was the maximum they could offer.
This was despite the fact that, prior to the managerial round, I was assured over a call that there were no budget constraints for this role and that my expected CTC had been duly noted.
Instead, I was told, “We are redirecting your CV to another HR unit who will set up your HR round and get back to you.”
If you’ve spent some time in corporate life, you know what that really means: we’re not moving forward with your profile.
So, in the end, it turned out to be a bit of a waste of time. But on the bright side, at least I got an article out of it.
If you or someone you know recently had an interview or if you’d like me to explain any topic, feel free to reach out to me via email. I’ll write an detailed article on the same.
If you need help with interview preparation, or need consultation in general. Please reach out to me over the email.
Email: shivamsrivastava.iec@gmail.com
If you found my work helpful and want to show your support:
Buy Shivam a Coffee
For collaboration or clarifications please connect with me on:
Email: shivamsrivastava.iec@gmail.com
Quora: Shivam Srivastava
X.com (Twitter): Shivam on X
Buy Me a Coffee: Shivam Srivastava
If you liked this article, you’ll also enjoy my below list of articles:
[embed]Interview Experiences and Learnings Edit descriptionmedium.com
메타데이터
- post_id
- 53966e8af079
- slug
- infosys-java-developer-interview-experience-2-53966e8af079
- url
- https://medium.com/coding-odyssey/infosys-java-developer-interview-experience-2-53966e8af079
- canonical_url
- https://medium.com/coding-odyssey/infosys-java-developer-interview-experience-2-53966e8af079
- author_url
- https://medium.com/@shivamsrivastava.iec
- status
- ok
- fetched_at
- 2026-06-12 18:14:10