Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About TCS hiring for Java roles
Tata Consultancy Services is a Tata Group company and one of the largest IT services and consulting firms in the world. It delivers application development, testing, cloud, data and analytics services to clients in banking, retail, manufacturing and other industries. In India it hires freshers and experienced staff for software testing, data engineering, BI reporting and analytics roles across its delivery centres.
For Java roles, this TCS practice set focuses most on OOP in Java (5), Multithreading and Concurrency (5), Strings and Exception Handling (5), Java 8+ Features and Streams (4). It has 18 easy, 12 medium questions, so you can start easy and work up to the harder ones.
Company type
IT services
Headquarters
Mumbai, India
Main India offices
Mumbai, Chennai, Pune, Bengaluru, Hyderabad
TCS Java interview process
TCS NQT online assessment (aptitude + coding)
Technical interview
Managerial round
HR round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for TCSStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
What is the difference between Collectors.toMap() and groupingBy()?
toMap() creates one entry per element using key and value functions and throws IllegalStateException on duplicate keys unless you give a merge function. groupingBy() collects all elements with the same key into a List by default, or applies a downstream collector like counting or summingInt. Use toMap for unique keys like id and groupingBy for categories like city.
02
Implement the Builder pattern for a User class with many optional fields.
A builder avoids long constructors.
public class User {
private final String name; private final int age;
private User(Builder b) { name = b.name; age = b.age; }
public static class Builder {
private String name; private int age;
public Builder name(String n) { name = n; return this; }
public Builder age(int a) { age = a; return this; }
public User build() { return new User(this); }
}
}
Usage: new User.Builder().name("Asha").age(25).build(). Lombok @Builder generates this.
03
A counter shared between threads shows wrong totals. How do you fix it?
count++ is not atomic; two threads can read the same value and both write the same result, so updates are lost. Use AtomicInteger.incrementAndGet(), which uses CAS, or LongAdder for very high contention, as it spreads updates over cells. A synchronized method also works but is slower. volatile alone does not fix it because it gives visibility, not atomicity.
04
What does the var keyword do and where can it not be used?
var, added in Java 10, lets the compiler infer the type of a local variable from its initializer, for example var list = new ArrayList<String>(). Java stays statically typed. var cannot be used for fields, method parameters or return types, and it needs an initializer that is not null. Use it when the type is obvious to keep code readable.
Strings are immutable so they can be safely shared from the string pool, used as HashMap keys with a cached hash code, passed between threads without locking and trusted in security checks such as file paths and class names. Any change, like concat or replace, creates a new String. For heavy modification use StringBuilder, which changes its internal buffer in place.
finally runs after try and catch in almost every case, including when the try block returns or throws. It does not run if the JVM exits through System.exit(), the process is killed or the thread dies abruptly. Avoid returning from finally, because that silently overrides the try block's return value and swallows exceptions.
07
An API calls three independent downstream services one after another and takes 900 ms. How would you speed it up?
Since the calls are independent, run them in parallel with CompletableFuture.supplyAsync on a dedicated executor or with virtual threads, then join with allOf. Total latency becomes roughly the slowest call, about 300 ms. Add a timeout per call with orTimeout and a fallback for failures so one slow service does not block the whole response. Structured concurrency is another option in newer Java.
08
What is the difference between map() and flatMap()?
map() transforms each element into exactly one new element, so a Stream of orders mapped to totals stays one-to-one. flatMap() transforms each element into a stream and flattens all of them into one stream, which is useful for one-to-many cases, such as turning a list of orders into a single stream of all items with orders.stream().flatMap(o -> o.items().stream()).
09
What are the four pillars of OOP? Explain with Java examples.
Encapsulation hides data behind methods, for example private fields with getters and setters in a BankAccount class. Abstraction exposes only what is needed through abstract classes or interfaces, like a Payment interface. Inheritance lets a class reuse another, such as SavingsAccount extends Account. Polymorphism lets one reference behave differently, like a Payment variable calling pay() on a UpiPayment or CardPayment.
10
Legacy code uses anonymous classes and loops everywhere. How would you modernise it safely?
First add tests around the behaviour. Then refactor in small steps: anonymous Comparators and Runnables become lambdas, simple loops that filter and transform become streams, and null checks around returns become Optional where useful. Keep complex loops with early exits as loops if a stream is less readable. Use IDE refactorings and review each change to avoid altering behaviour.
javac compiles source code into bytecode, not native machine code. Any machine with a compatible JVM can run that same .class file, so the code is written once and run anywhere. The JVM itself is platform specific; there are separate JVM builds for Windows, Linux and macOS, but the bytecode they run is identical.
HashSet is backed by a HashMap. Each element you add becomes a key in that map with a shared dummy object as the value. So uniqueness depends entirely on the element's hashCode() and equals(), and operations are O(1) on average. LinkedHashSet uses a LinkedHashMap to keep insertion order, and TreeSet uses a TreeMap to keep elements sorted.
13
What is the difference between == and equals() in Java?
== compares primitive values, or for objects it checks whether two references point to the same object in memory. equals() checks logical equality and can be overridden, as String, Integer and most value classes do. For example, new String("a") == new String("a") is false, but equals() returns true. Always use equals() to compare object content.
Method references are short forms of lambdas that just call an existing method. Types: static method (Integer::parseInt), instance method of a specific object (System.out::println), instance method of an arbitrary object of a type (String::toUpperCase) and constructor (ArrayList::new). They make stream code clearer when the lambda only forwards its arguments.
15
What are the main steps to connect to a database with JDBC?
Get a Connection from a DataSource (or DriverManager in small programs), create a PreparedStatement with ? placeholders, bind parameters, execute with executeQuery or executeUpdate, read the ResultSet, and close everything with try-with-resources. In real apps a pooled DataSource like HikariCP supplies connections, and frameworks such as Spring JdbcTemplate or JPA remove most boilerplate.
16
What is the difference between ArrayList and LinkedList?
ArrayList is backed by a resizable array, so get(i) is O(1) and appends are amortised O(1), but inserting in the middle shifts elements. LinkedList is a doubly linked list with O(n) random access but O(1) add or remove at the ends or through an iterator. In practice ArrayList is faster for almost all cases because of better CPU cache use; use ArrayDeque for queues.
17
What is the difference between JPA, Hibernate and Spring Data JPA?
JPA, now Jakarta Persistence, is a specification of interfaces and annotations for object relational mapping. Hibernate is the most popular implementation of that specification and adds its own features. Spring Data JPA sits on top and generates repository implementations from interfaces and method names like findByEmail, reducing boilerplate. Your code uses JPA annotations, Hibernate does the work and Spring Data simplifies access.
18
Count the frequency of each character in a string using Java.
A map with merge() is simple; streams also work.
Map<Character, Integer> freq = new LinkedHashMap<>();
for (char c : s.toCharArray()) {
freq.merge(c, 1, Integer::sum);
}
// Streams version
Map<Character, Long> f = s.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(c -> c,
LinkedHashMap::new, Collectors.counting()));
LinkedHashMap keeps first-seen order.
19
A @Transactional method is not rolling back after an exception. What could be wrong?
Check that the exception is unchecked, since checked exceptions do not roll back unless rollbackFor is set. Check that the method is called through the Spring proxy, not from another method in the same class. Make sure the method is public and the exception is not caught and swallowed inside. Also confirm the database engine supports transactions and the right transaction manager is used.
The simplest safe options are an enum or the holder idiom.
public class Config {
private Config() {}
private static class Holder {
static final Config INSTANCE = new Config();
}
public static Config getInstance() {
return Holder.INSTANCE;
}
}
The JVM loads Holder lazily and class initialisation is thread safe. An enum singleton also resists reflection and serialization attacks.
21
How does ExecutorService work and why use a thread pool?
ExecutorService manages a pool of worker threads and a task queue. You submit Runnable or Callable tasks and get Futures, and workers reuse threads instead of creating one per task, which saves creation cost and limits concurrency. Configure core size, max size, queue and rejection policy through ThreadPoolExecutor. Always call shutdown() and awaitTermination() when done.
22
Can you override a static or private method in Java?
No. Private methods are not visible to subclasses, so a method with the same name in a child is a new method. Static methods belong to the class; a static method with the same signature in a child hides the parent one, and which one runs depends on the reference type, not the object. The @Override annotation on such methods gives a compile error.
throw is a statement used inside a method to actually raise an exception object, for example throw new IllegalStateException("closed"). throws is used in a method signature to declare which checked exceptions the method may pass to its caller, for example void read() throws IOException. A method can declare many exceptions with throws but throws one object at a time.
Declare the class final, make all fields private and final, set them only in the constructor, and provide no setters. For mutable fields like a List or Date, make defensive copies in the constructor and in getters, or use List.copyOf. Immutable objects are thread safe and make good map keys. Java records give a concise way to create shallowly immutable data classes.
25
Use CountDownLatch to wait for three worker threads to finish.
The main thread waits until the count reaches zero.
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try { doWork(); }
finally { latch.countDown(); }
}).start();
}
latch.await(30, TimeUnit.SECONDS);
System.out.println("all done");
countDown in finally makes sure the latch is released even on error.
26
Sort a list of employees by department, then by salary descending.
Chain comparators.
employees.sort(
Comparator.comparing(Employee::department)
.thenComparing(Employee::salary,
Comparator.reverseOrder()));
// Streams version returning a new list
List<Employee> sorted = employees.stream()
.sorted(Comparator.comparing(Employee::department)
.thenComparing(Employee::salary, Comparator.reverseOrder()))
.toList();
List.sort is stable, so equal keys keep their order.
volatile guarantees visibility and ordering: a write to a volatile field is immediately visible to other threads, and it prevents reordering around that access under the Java Memory Model. It does not make compound operations like count++ atomic, because that is a read, modify and write. Use it for flags such as a stop signal, and use AtomicInteger or locks for counters.
Text blocks, final in Java 15, are multi-line string literals written between triple double quotes. They keep line breaks, remove common leading indentation and need far fewer escape characters, which makes embedded JSON, SQL and HTML readable. Methods like formatted() can insert values. They are still normal String objects in the pool.
29
How do you prepare for coding rounds as a Java developer?
Situation: I was preparing for product company interviews while working. Task: get strong at DSA in limited time. Action: I solved two problems a day by pattern, such as sliding window and graphs, always in Java with Collections, timed myself and reviewed mistakes every weekend. Result: in three months I solved 250 problems, cleared online tests comfortably and could explain time complexity clearly.
30
Write a simple REST controller in Spring Boot for creating and fetching products.
Use constructor injection and validation.
@RestController
@RequestMapping("/api/products")
class ProductController {
private final ProductService service;
ProductController(ProductService service) { this.service = service; }
@PostMapping
ResponseEntity<Product> create(@Valid @RequestBody ProductRequest req) {
Product p = service.create(req);
return ResponseEntity.created(URI.create("/api/products/" + p.id())).body(p);
}
@GetMapping("/{id}")
Product get(@PathVariable Long id) { return service.get(id); }
}
Tips to crack the TCS Java interview
Practise TCS NQT style numerical, verbal and reasoning sections along with two basic coding problems under strict time limits.
Be ready to explain your final-year project, SQL basics and core concepts like OOP, DBMS and software testing life cycle.
Read about TCS service lines such as BFSI and its iON and Ignio platforms to answer why you want to join.
Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
Practise the hard questions on this page aloud; TCS interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the TCS Java interview?
Candidates usually go through 4 stages: TCS NQT online assessment (aptitude + coding); Technical interview; Managerial round; HR round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.
Which topics should I prepare for the TCS Java interview?
This practice set leans on OOP in Java (5), Multithreading and Concurrency (5), Strings and Exception Handling (5), Java 8+ Features and Streams (4). Revise those first, then practise explaining one or two of your own projects end to end, because most TCS interviewers ask you to walk through real work.
Are these the exact questions asked at TCS?
No. These are curated practice questions that match the skills and difficulty usually tested in it services interviews like TCS's. They are not a leaked or verified list of past questions.
Where does TCS hire Java professionals in India?
TCS has large teams in Mumbai, Chennai, Pune, Bengaluru, Hyderabad. Openings and locations change often, so check the TCS careers page and filter by city and experience.