Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About TCS hiring for .NET Full Stack 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 .NET Full Stack roles, this TCS practice set focuses most on C# Fundamentals (5), Entity Framework Core (5), SQL Server and T-SQL (5), LINQ, Collections and Generics (4). It has 11 easy, 19 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 .NET Full Stack 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 are the four pillars of object-oriented programming?
Encapsulation hides internal state behind methods and properties. Abstraction exposes only what the caller needs, using abstract classes and interfaces. Inheritance lets a class reuse and extend another class. Polymorphism lets one interface have many implementations, so code calls Pay() without knowing whether it is a card or UPI payment. Together they make code easier to change, test and reuse.
02
What are signals in Angular and why were they introduced?
Signals are reactive values: count = signal(0) holds state, computed() derives values and effect() runs side effects when dependencies change. Angular knows exactly which parts of the view read which signal, so it updates only those parts instead of checking the whole component tree. This enables zoneless change detection, which became the default for new apps in Angular 21, and gives simpler state handling than RxJS for local UI state.
03
Write a switch expression using pattern matching to calculate shipping cost.
dotnet tool install --global dotnet-ef
# create a migration from model changes
dotnet ef migrations add AddOrderStatus
# apply pending migrations to the database
dotnet ef database update
# undo the last unapplied migration
dotnet ef migrations remove
# generate an idempotent SQL script for production
dotnet ef migrations script --idempotent -o deploy.sql
In Visual Studio the Package Manager Console equivalents are Add-Migration and Update-Database.
05
Show the newer LINQ methods Chunk, DistinctBy and MaxBy.
// split 1,000 ids into batches of 100 for bulk API calls
foreach (int[] batch in ids.Chunk(100))
await SendBatchAsync(batch);
// unique customers by email
var unique = customers.DistinctBy(c => c.Email).ToList();
// highest-paid employee object, not just the salary
Employee? top = employees.MaxBy(e => e.Salary);
These were added in .NET 6 and remove the need for custom helpers or third-party libraries like MoreLINQ.
public async IAsyncEnumerable<Order> GetOrdersAsync(
[EnumeratorCancellation] CancellationToken ct = default)
{
await foreach (var o in _db.Orders.AsNoTracking().AsAsyncEnumerable().WithCancellation(ct))
yield return o;
}
// consumer
await foreach (var order in service.GetOrdersAsync())
Console.WriteLine(order.Id);
Items are produced and consumed one at a time asynchronously. ASP.NET Core can stream an IAsyncEnumerable result as JSON without buffering the whole list.
07
How do you use an explicit transaction in EF Core across multiple SaveChanges calls?
await using var tx = await db.Database.BeginTransactionAsync();
try
{
db.Orders.Add(order);
await db.SaveChangesAsync();
var stock = await db.Stocks.SingleAsync(s => s.ProductId == order.ProductId);
stock.Quantity -= order.Quantity;
await db.SaveChangesAsync();
await tx.CommitAsync();
}
catch
{
await tx.RollbackAsync();
throw;
}
A single SaveChanges is already transactional; explicit transactions are needed when you combine several saves or raw SQL into one unit.
08
What is the difference between a clustered and a non-clustered index?
A clustered index defines the physical order of the table's data, so the leaf level is the data itself, and a table can have only one. A non-clustered index is a separate structure with key values and a pointer back to the row, and a table can have many. Range queries on the clustered key are fast. Non-clustered indexes speed up searches on other columns but add cost to inserts and updates.
09
How do model binding and validation work in ASP.NET Core Web API?
Model binding maps request data into action parameters from the route, query string, headers or body, using [FromRoute], [FromQuery] and [FromBody]. Validation uses data annotations like [Required], [StringLength] and [Range] on DTOs. With [ApiController], invalid models automatically return 400 Bad Request with ProblemDetails listing the errors, so you do not need to check ModelState manually. FluentValidation is popular for complex rules.
10
What is the difference between authentication and authorization in ASP.NET Core?
Authentication answers who you are: middleware reads a cookie or JWT, validates it and builds a ClaimsPrincipal for HttpContext.User. Authorization answers what you may do: it checks that user against rules such as [Authorize(Roles = "Admin")] or a policy like requiring an Employee claim with a certain department. A missing or invalid identity gives 401 Unauthorized, while a valid user without permission gets 403 Forbidden.
11
Explain eager, lazy and explicit loading in EF Core.
Eager loading fetches related data in the same query using Include and ThenInclude, for example orders with their items. Lazy loading loads a navigation property automatically the first time you access it, requiring proxies and virtual properties; it is convenient but easily causes N+1 queries. Explicit loading loads a navigation on demand with Entry(order).Collection(o => o.Items).LoadAsync(). Projection with Select is often better than all three.
Most LINQ operators such as Where and Select do not run when you write them; they build a query that executes only when you enumerate it with foreach, ToList, Count or First. This means the query sees the latest data at enumeration time and can be composed step by step. The catch is that enumerating the same query twice runs it twice, which can mean two database calls. Call ToList to materialise once.
13
Show a class using a primary constructor with dependency injection.
public class OrderService(IOrderRepository repo, ILogger<OrderService> logger)
{
public async Task<Order?> GetAsync(int id)
{
logger.LogInformation("Fetching order {Id}", id);
return await repo.FindAsync(id);
}
}
Primary constructors on classes arrived in C# 12. Parameters are captured and usable in all members, removing boilerplate fields. They are not readonly, so assign to a readonly field if immutability matters.
A view is a saved SELECT query that acts like a virtual table; it simplifies complex joins and can restrict which columns users see, but by default it stores no data. An indexed view has a unique clustered index, so SQL Server physically stores and maintains its results, which speeds up heavy aggregations. The cost is slower writes on base tables, and it requires SCHEMABINDING and deterministic expressions.
15
Using LINQ, group employees by department and get the count and average salary.
var report = employees
.GroupBy(e => e.Department)
.Select(g => new
{
Department = g.Key,
Count = g.Count(),
AvgSalary = g.Average(e => e.Salary)
})
.OrderByDescending(x => x.AvgSalary)
.ToList();
GroupBy returns groups with a Key, and aggregate methods run per group. With EF Core this translates to SQL GROUP BY.
Generics let you write classes and methods with a type parameter, such as List<T> or Repository<T>, that work with any type while staying type-safe. Benefits are compile-time checking instead of casts, no boxing for value types, and code reuse. For example, one generic Result<T> type can wrap any API response. The CLR creates specialised code for value types and shares code for reference types.
The Common Language Runtime is the execution engine of .NET. It loads compiled IL code, converts it to machine code with the JIT compiler, manages memory through the garbage collector, enforces type safety, handles exceptions and manages threads. Because every .NET language compiles to the same IL, C#, F# and VB.NET code can run on the same CLR and call each other.
In five years I want to be a senior full stack engineer who can design a complete .NET system, from database and APIs to front end and cloud deployment, and guide newer developers. In the near term I want to master ASP.NET Core, EF Core and SQL Server performance, then grow into Azure and system design. I would like to grow inside one company where I can take on bigger modules over time.
19
What is the difference between method overloading and method overriding?
Overloading means several methods with the same name but different parameter lists in the same class, resolved at compile time, for example Add(int, int) and Add(double, double). Overriding means a derived class provides a new implementation of a virtual or abstract base method with the same signature, resolved at runtime based on the actual object type. Overloading is compile-time polymorphism; overriding is runtime polymorphism.
20
What is the difference between compile-time and runtime polymorphism?
Compile-time, or static, polymorphism is resolved by the compiler, mainly through method overloading and operator overloading, and through generics. Runtime, or dynamic, polymorphism is resolved when the program runs, through virtual methods and interfaces: a Shape reference may call Circle.Area or Square.Area depending on the actual object. Runtime polymorphism is what makes plugin designs and dependency injection possible.
An async void method cannot be awaited, so the caller does not know when it finishes. Exceptions thrown inside it cannot be caught by the caller; they go to the synchronization context and can crash the process. It is also hard to unit test. Use async Task instead. The only accepted use of async void is for event handlers, such as button click handlers in desktop apps, where the signature is fixed.
22
What is the difference between reactive forms and template-driven forms in Angular?
Template-driven forms are defined mainly in HTML with ngModel and directives; they are quick for simple forms but harder to test. Reactive forms are defined in TypeScript with FormGroup, FormControl and Validators, giving explicit, strongly typed models, easy dynamic fields, custom and async validators, and straightforward unit testing. For enterprise apps such as loan application or KYC forms, reactive forms are the usual choice.
23
What is the difference between DELETE, TRUNCATE and DROP?
DELETE removes rows one by one, supports WHERE, fires triggers and is fully logged, so it is slower on big tables. TRUNCATE removes all rows by deallocating pages, is minimally logged, resets identity values and cannot have WHERE; it fails if foreign keys reference the table. DROP removes the whole table including structure, indexes and permissions. In SQL Server, both DELETE and TRUNCATE can be rolled back inside a transaction.
24
What is the difference between a primary key and a unique key in SQL Server?
Both enforce uniqueness. A table can have only one primary key, it cannot contain NULLs, and by default SQL Server creates a clustered index for it. A table can have many unique constraints, each allowing a single NULL in SQL Server, and they create non-clustered indexes by default. Use the primary key for row identity, such as EmployeeId, and unique keys for business rules like a unique email or PAN.
ref passes a variable by reference; it must be initialised before the call and the method can read and change it. out also passes by reference but need not be initialised, and the method must assign it before returning, as in int.TryParse. in passes by reference as read-only, which avoids copying large structs while preventing changes. Overusing ref and out makes code harder to read, so tuples are often cleaner.
public async Task<PagedResult<ProductDto>> GetPageAsync(int page, int size)
{
var query = db.Products.AsNoTracking().OrderBy(p => p.Id);
int total = await query.CountAsync();
var items = await query
.Skip((page - 1) * size)
.Take(size)
.Select(p => new ProductDto(p.Id, p.Name, p.Price))
.ToListAsync();
return new PagedResult<ProductDto>(items, total, page, size);
}
Always order before Skip and Take. For very deep pages, keyset paging with Where(p => p.Id > lastId) is faster than large offsets.
27
What are DbContext and DbSet, and what lifetime should DbContext have?
DbContext represents a session with the database: it holds configuration, the change tracker and connection handling. Each DbSet<T> property represents a table you can query and add to. DbContext is lightweight and not thread-safe, so it should be short-lived; in ASP.NET Core it is registered as scoped, one per request, via AddDbContext. For background services or Blazor, use IDbContextFactory to create contexts on demand.
lock ensures that only one thread at a time executes a block of code for a given lock object, preventing race conditions on shared data. It compiles to Monitor.Enter and Monitor.Exit inside try-finally. Lock on a private readonly object, never on this or a string. Since .NET 9 there is a dedicated System.Threading.Lock type that is faster. You cannot await inside a lock; use SemaphoreSlim for async code.
29
What are services and dependency injection in Angular?
A service is a class, marked @Injectable, that holds logic or data shared across components, such as API calls, authentication or a cart. Angular's DI creates the service and provides it to components that request it in the constructor or with the inject() function. With providedIn: 'root', one shared instance exists for the whole app. This keeps components focused on UI and makes logic easy to test.
30
What is the difference between const, readonly and static readonly?
const is a compile-time constant, implicitly static, and its value is copied into calling assemblies, so changing it requires recompiling them. readonly fields are set at declaration or in the constructor and can differ per instance. static readonly is set once per type at runtime, so it can hold values like DateTime.Now or a new object. Use const only for values that will never change, such as Math.PI.
Tips to crack the TCS .NET Full Stack 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 .NET Full Stack 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 .NET Full Stack interview?
This practice set leans on C# Fundamentals (5), Entity Framework Core (5), SQL Server and T-SQL (5), LINQ, Collections and Generics (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 .NET Full Stack 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.