C# coding questions frequently asked
in MNC interviews
l
pa
ep
1️⃣ Remove duplicates without using LINQ Distinct()
de
an
What interviewers test
/s
● Hashing fundamentals
/in
● Time vs memory trade-offs
m
● Whether you understand why Distinct() works
co
n.
Real-world scenario
di
ke
You are processing millions of user IDs coming from logs or Kafka messages.
You must remove duplicates fast and predictably.
lin
Optimized approach (HashSet)
w.
public static List<int> RemoveDuplicates(int[] input)
w
{
//w
var seen = new HashSet<int>();
var result = new List<int>();
s:
tp
foreach (var item in input)
ht
{
if ([Link](item)) // Add returns false if already exists
{
[Link](item);
}
}
return result;
}
Complexity
Aspect Value
Time O(n)
l
pa
Space O(n) (hash storage)
ep
Why this is better than naive loops
de
● Nested loops = O(n²) ❌
an
● HashSet = constant-time lookup ✅
/s
Interview Tip:
/in
m
Say “I prefer HashSet because it gives O(1) average lookup and preserves intent clearly.”
co
n.
2️⃣ Explain async / await with a real production
di
ke
scenario
lin
What interviewers test
w.
● Thread utilization
w
//w
● Scalability thinking
s:
● Non-blocking I/O knowledge
tp
ht
Real-world scenario
API calls:
● Database
● Payment gateway
● Email service
Blocking threads = server collapse under load
Bad (Blocking)
public string GetUser()
{
var response = [Link](url).Result; // Blocks thread
❌
return [Link]().Result;
}
l
pa
ep
Good (Async, scalable)
public async Task<string> GetUserAsync()
de
{
an
var response = await [Link](url);
return await [Link]();
/s
}
/in
m
Why async/await matters
co
● Thread is released during I/O wait
n.
di
● [Link] can serve more concurrent requests
ke
● No thread starvation
lin
w.
Key interview line
w
“Async doesn’t make code faster; it makes servers scalable.”
//w
s:
tp
3️⃣ IEnumerable vs ICollection vs IList
ht
What interviewers test
● Execution pipeline understanding
● Abstraction knowledge
Hierarchy
IEnumerable
└── ICollection
└── IList
IEnumerable<T>
● Read-only iteration
● Lazy execution
l
pa
ep
IEnumerable<int> numbers = GetNumbers();
foreach (var n in numbers) { }
de
✅ Best for streaming, read-only, deferred execution
an
/s
/in
ICollection<T>
m
co
● Adds count + add/remove
n.
ICollection<int> list = new List<int>();
di
[Link](1);
ke
✅ When modifying collection without index access
lin
w.
w
//w
IList<T>
s:
● Index-based access
tp
ht
IList<int> list = new List<int>();
int first = list[0];
✅ When order & index matter
Interview rule of thumb
“Expose the least powerful interface required.”
4️⃣ First non-repeating character in a string
What interviewers test
● Hashing
● Single-pass logic
l
pa
● Clean thinking
ep
Optimized solution
de
public static char? FirstUniqueChar(string input)
an
{
var frequency = new Dictionary<char, int>();
/s
/in
foreach (var ch in input)
frequency[ch] = [Link](ch) + 1;
m
co
foreach (var ch in input)
if (frequency[ch] == 1)
n.
return ch;
di
ke
return null;
lin
}
w.
w
Complexity
//w
s:
Time O(n)
tp
Spac O(k) (unique chars)
ht
Why two loops?
● First: count
● Second: preserve order
5️⃣ Handle millions of records efficiently
What interviewers test
● Memory pressure awareness
● Streaming & batching
l
❌ Bad (Loads everything)
pa
ep
var users = [Link](); // Memory explosion
de
✅ Streaming (Best)
an
await foreach (var user in [Link]())
/s
{
Process(user);
/in
}
m
co
✅ Batching
n.
const int batchSize = 1000;
di
for (int i = 0; i < total; i += batchSize)
ke
{
lin
var batch = GetBatch(i, batchSize);
ProcessBatch(batch);
w.
}
w
//w
Key principles
s:
● Never load everything
tp
ht
● Prefer streams
● Control memory explicitly
6️⃣ Dependency Injection without any framework
What interviewers test
● SOLID
● Architecture fundamentals
Step 1: Abstraction
public interface IMessageService
{
l
pa
void Send(string message);
}
ep
de
Step 2: Implementation
an
public class EmailService : IMessageService
{
/s
public void Send(string message)
{
/in
[Link]("Email: " + message);
m
}
co
}
n.
di
Step 3: Injection
ke
public class Notification
lin
{
private readonly IMessageService _service;
w.
w
public Notification(IMessageService service)
//w
{
_service = service;
s:
}
tp
ht
public void Notify(string msg)
{
_service.Send(msg);
}
}
Why this matters
● Loose coupling
● Testable code
● Swappable implementations
7️⃣ struct vs class (real-world)
l
pa
What interviewers test
ep
● Memory & performance awareness
de
an
Use struct when:
/s
● Small
/in
● Immutable
m
co
● Value-type behavior
n.
di
public readonly struct Point
{
ke
public int X { get; }
lin
public int Y { get; }
}
w.
w
//w
Use class when:
s:
● Large
tp
● Mutable
ht
● Shared references
public class User
{
public string Name { get; set; }
}
Interview statement
“Structs live on stack or inline, classes live on heap with GC cost.”
8️⃣ Design a rate limiter
What interviewers test
l
● Concurrency
pa
ep
● Thread safety
de
● System design
an
Token bucket (simple)
/s
public class RateLimiter/in
{
m
private readonly int _limit;
private int _count;
co
private DateTime _windowStart = [Link];
n.
private readonly object _lock = new();
di
public RateLimiter(int limit)
ke
{
lin
_limit = limit;
}
w.
w
public bool Allow()
//w
{
lock (_lock)
s:
{
tp
if (([Link] - _windowStart).TotalSeconds >= 1)
ht
{
_count = 0;
_windowStart = [Link];
}
if (_count < _limit)
{
_count++;
return true;
}
return false;
}
}
}
Used in
l
pa
● APIs
ep
● Login attempts
de
an
● OTP systems
/s
/in
m
9️⃣ LINQ vs IQueryable
co
What interviewers test
n.
di
● Deferred execution
ke
● DB performance
lin
w.
LINQ (IEnumerable)
w
var data = [Link](x => [Link] > 30).ToList();
//w
s:
● Executes in memory
tp
ht
IQueryable
var data = [Link](x => [Link] > 30);
● Translates to SQL
● Executes in DB
Interview line
“IQueryable builds expressions; IEnumerable executes them.”
🔟 Write clean, production-ready C# code
What interviewers test
l
pa
● Professional maturity
ep
Principles
de
● Small methods
an
● Clear naming
/s
● No magic values /in
m
● Proper exceptions
co
n.
public class OrderService
{
di
public void PlaceOrder(Order order)
ke
{
lin
if (order == null)
throw new ArgumentNullException(nameof(order));
w.
w
Validate(order);
//w
Save(order);
}
s:
tp
private void Validate(Order order)
ht
{
if ([Link] <= 0)
throw new InvalidOperationException("Invalid total");
}
private void Save(Order order)
{
// persistence logic
}
}
ht
tp
s:
//w
w
w.
lin
ke
di
n.
co
m
/in
/s
an
de
ep
pa
l