C# Advanced - Interview Questions
FAANG & product company questions. Spot the bug, explain the fix, prove you're senior.
10 Interview Questions with Code
public ActionResult GetUser() {
var user = GetUserAsync().Result; // Kunal wrote this
return View(user);
}
Answer: Sync-over-async deadlock. .Result blocks the ASP.NET request thread. await inside GetUserAsync tries to resume on that same thread. Thread is blocked, so it can't resume. Deadlock.
Fix: await GetUserAsync() all the way. Make controller async Task<ActionResult>.
public async void SaveDataAsync() {
await db.SaveAsync(); // Prerna's API method
}
Answer: Two problems. 1. Caller can't await it, so can't catch exceptions. 2. If db.SaveAsync() throws, exception goes unhandled and crashes the process. Only use async void for event handlers.
Fix: public async Task SaveDataAsync(). Let caller await and handle errors.
var users = db.Users.ToList();
foreach(var u in users) {
u.Orders = db.Orders.Where(o => o.UserId == u.Id).ToList(); // Kaushal's code
}
Answer: N+1 query problem. 1 query for users + 100 queries for orders = 101 DB hits. DB round trips kill performance.
Fix: Eager load: db.Users.Include(u => u.Orders).ToList(). 1 query with JOIN.
public T Create<T>() {
return new T(); // Sanju's generic factory
}
Answer: Compiler doesn't know if T has a parameterless constructor. T could be an interface or class without default ctor.
Fix: Add constraint: public T Create<T>() where T : new()
List<T>.class PizzaTracker {
public PizzaTracker(OrderService svc) {
svc.PizzaReady += OnPizzaReady; // Karan subscribes
}
void OnPizzaReady() { }
} // PizzaTracker instances never GC'd
Answer: OrderService holds reference to PizzaTracker via delegate. Even if UI releases PizzaTracker, service keeps it alive. Memory leak.
Fix: Unsubscribe: svc.PizzaReady -= OnPizzaReady; in Dispose. Or use WeakEvent pattern.
Answer: List<int> stores ints directly: 4 bytes each. ArrayList boxes each int to object: 24 bytes object header + 4 bytes data + 8 byte reference = 36 bytes. Plus GC pressure from 1M heap objects.
Math: 1M ints = List<int>: 4MB. ArrayList: 36MB.
var data = await http.GetAsync(url).ConfigureAwait(false);
Answer: Tells await NOT to capture SynchronizationContext. Resumes on any thread pool thread, not UI thread. Avoids deadlock in library code.
Use in: Library code that doesn't touch UI. Don't use in: UI code that updates labels after await.
Answer: Covariance. IEnumerable<out T> has out keyword. Means T only comes out, never goes in. Since all strings are objects, treating IEnumerable<string> as IEnumerable<object> is safe.
Contrast: List<string> to List<object> fails. List has Add(T) so it's invariant.
string log = File.ReadAllText("huge.log"); // Kashvee's log parser
Answer: Loads entire file into string. 2GB ASCII becomes 4GB UTF-16 string. Exceeds max string size or RAM. OutOfMemoryException.
Fix: using var reader = new StreamReader("huge.log"); Read line by line. Memory = O(1).
public event Action OnComplete;
OnComplete(); // Kiaan raises event
Answer: If no subscribers, OnComplete is null. Invoking null throws NullReferenceException.
Fix: OnComplete?.Invoke(); Null-conditional prevents crash.
No comments yet. Be the first to share your thoughts!