cswork / libraryOpen practice workspace

Interview guides · Alpha Net

Alpha Net Software Engineer Interview Guide

Alpha Net Software Engineer interview guide: recruiter screen, technical rounds on hashing, .NET, DI and GC, team alignment, and a 7-day plan.

The 60-second brief

Candidates describe Alpha Net engineering work as building and maintaining software for external clients as well as internal platforms, mostly enterprise applications and backend services. The requirements candidates describe centre on .NET backend development, a solid grip on data structures, algorithms and object-oriented design, and hands-on experience shipping production applications. Exposure to cloud deployment, automated testing and CI/CD is listed as a bonus, as is client-facing or consulting experience. Some roles sit on an internal product team and others are tied to a client placement, and candidates report that timelines and round structure can differ between the two. Candidates describe the day-to-day work as building backend services, optimising database queries and refactoring legacy code.

This guide is for backend-leaning software engineers preparing for the Alpha Net Software Engineer loop, especially those whose resume lists .NET. It covers the three reported stages and the full set of reported questions: hash map internals and collision handling, complexity analysis, a live algorithmic problem, garbage collection and threading, .NET architecture and dependency injection lifetimes, query tuning under transactional load, error handling and logging across services, a project deep-dive, and five behavioral prompts. Each question gets a concrete answer outline and the follow-ups worth rehearsing.

Candidates report three stages over roughly 3-5 weeks: a Recruiter Screening Call, a set of Technical Evaluation Rounds on coding and theory, and a Team Alignment Discussion on team fit and HR details. Some candidates report the whole process finishing within a week or two of the first screen.

Focus areas

  • Collision Handling Strategies
  • Data Structures (HashMap / Associative Arrays)
  • Hashing

Overview

The reported loops weight hash maps and collision handling heavily. Candidates who shared loops describe repeated questions on hash maps: how buckets work, how collisions are resolved, and why a collision chain does not always degrade to linear time. Around that sit complexity analysis, one standard algorithmic problem solved out loud, and runtime questions on memory management, garbage collection and the thread lifecycle. If your hash table knowledge stops at "average O(1)", that is the first gap to close: be able to explain bucket indexing, load factor and resizing, chaining versus open addressing, and the Java 8 change that turns long chains into balanced trees.

The second block is .NET and backend engineering: core .NET concepts and how you structure an application, the differences between transient, scoped and singleton dependency injection lifetimes, how you keep database queries fast under heavy transactional load, and how you handle errors and logging when a request crosses several services. These are answered best from code you have actually written, so for each topic pick one example from your own projects (a service you split into layers, a query you rewrote, a captive-dependency bug you fixed) and be ready to explain the mechanism underneath it.

Candidates report that technical rounds check whether the projects on a resume are really the candidate's own work, and that a recent project walkthrough with its architectural choices and trade-offs is part of the reported questions. Write down, before the loop, the architecture of your last two projects, what you personally built, and one decision in each that you would make differently now. Anything you list on your resume is fair game for a question about its internals.

Candidates also report that rigour varies a lot by interviewer: some loops are routine, others are intensive drills on theory or live coding, and some interviewers push back or interrupt. Preparation that holds up in both cases is the same: explain your reasoning aloud, state complexity without being asked, and when challenged, restate the objection and answer it with a concrete example instead of repeating yourself.

The Alpha Net interview process

These are the three stages candidates describe for the Alpha Net Software Engineer process. The technical stage is reported as several rounds rather than one, and candidates say timelines and round structure vary by team or client engagement.

Recruiter Screening Call

The process is reported to open with a call from a recruiter that looks at your background and how well you fit the role. Treat it as a chance to line up your experience with what the role asks for: .NET backend work, production applications you helped ship, and how you work with teammates and clients. Use the call to learn what the remaining stages look like, whether the opening is tied to an internal team or an external client placement (candidates report timelines and structure differ between these), and which technical topics the later rounds cover, since the process can move to technical rounds quickly.

What to demonstrate

  • Background and fit for the role, as candidates describe the call
  • Whether your listed experience lines up with the role

How to prepare

  • Write a two-minute walkthrough of your resume that names the .NET (or other backend) stack, the services you built and one measurable result from each recent role.
  • Prepare a one-sentence answer for every technology on your resume, and remove anything you could not explain at the level of its internals.
  • Write down three questions for the recruiter: how many technical rounds follow, whether the role is client-placed or internal, and whether live coding is done in a shared editor or an IDE.
  • Have notice period, location and work-arrangement constraints ready so the HR details do not stall the process.

Technical Evaluation Rounds

Candidates report several technical rounds testing coding skill and theoretical knowledge, and say the experience varies: some interactions are smooth and professional, others are intensive drills on theory or live coding. Candidates also report technical rounds checking that the projects on a resume reflect genuine hands-on contribution. The reported questions fall into two groups: computer science fundamentals (hash map internals, collision handling, complexity, a standard algorithmic problem, garbage collection, threads) and .NET backend topics (application architecture, dependency injection lifetimes, query tuning, distributed error handling, a project walkthrough). Approach each answer by stating the mechanism first, then the complexity or trade-off, then an example from your own work.

What to demonstrate

  • Working code for an algorithmic problem, with its reasoning explained step by step
  • Theoretical knowledge of data structures, hashing, complexity and runtime behaviour
  • Practical .NET and backend knowledge
  • Whether the projects on your resume are genuinely your own work, as candidates report

How to prepare

  • Implement a chained hash map from scratch in C# (or your main language) with resize, then explain aloud how Java 8 tree bins change the worst case.
  • Solve five hash-map-based array and string problems out loud, stating brute force, optimised complexity and edge cases for each.
  • Write one-page notes on .NET garbage collection generations, the large object heap, IDisposable, async/await and the three DI lifetimes, each with an example from your own code.
  • Rehearse a recent project walkthrough naming your personal contribution, two architectural trade-offs and one query or error-handling problem you fixed.

Team Alignment Discussion

The last stage is reported as a conversation about how you would fit the team, plus HR matters. The reported behavioral questions (debugging a production issue under time pressure, technical disagreements, ramping up on an unfamiliar stack, competing deliverables, shifting requirements) are the kind of material to have ready for it. Answer with specific stories told in the first person, each with a clear decision you made and a result you can state.

What to demonstrate

  • Team fit and how you collaborate with teammates and stakeholders
  • Communication when describing past decisions and conflicts
  • HR matters for the role

How to prepare

  • Write five STAR stories, one per reported behavioral prompt, each with the decision you personally made and a concrete outcome.
  • Prepare a version of the disagreement and shifting-requirements stories that involves a client or non-technical stakeholder, since some roles are client-placed.
  • List questions for the team: what the first project would be, how code review and deployment work, and whether the work is client-facing.

Where candidates lose points

Answering the hash map questions with "it is O(1) and collisions go in a linked list" and stopping there.

The reported questions go past the average case into collision resolution and why the worst case is not always linear. Be able to explain bucket indexing, load factor and resizing, chaining versus open addressing, Java 8 tree bins (threshold 8, minimum table of 64, O(log n) lookup) and their limit for non-comparable keys. Practise saying it in under two minutes, then implementing a small chained map.

Listing .NET on the resume but being unable to explain DI lifetimes, garbage collection generations or async/await beyond definitions.

Candidates report that resume technologies are questioned at the level of their internals. For each .NET topic prepare one example from your own code: a scoped DbContext and a captive-dependency bug, an IDisposable resource, an async call that replaced a blocking one. Remove any tool from your resume you could not discuss this way.

Describing a recent project in "we" terms and being unable to say which part you built or why a design choice was made.

Candidates report technical rounds checking that resume projects reflect genuine hands-on contribution. Write out your last two projects: the request path, the components you personally wrote, two trade-offs with the rejected alternative, and one thing you would change. Rehearse it in the first person.

Starting to code the algorithmic problem immediately and in silence, then stating no complexity.

The reported coding question asks for step-by-step reasoning. Restate the problem, ask about size, duplicates and empty input, state the brute force and its cost, then the improvement and its time and space complexity, and trace an edge case through the finished code.

Answering the distributed error-handling question with "wrap it in try/catch and log the exception".

Cover the full picture: global exception middleware and ProblemDetails, structured logs with a correlation or trace ID passed between services, timeouts, retries with backoff only for idempotent operations, circuit breakers, idempotency keys and dead-letter queues. Tie at least one point to an incident you handled.

Questions & practice

Why is the worst-case time complexity for collision handling in a hash table not strictly O(n) under certain b

Medium · Technical and Core Computer Science

Why is the worst-case time complexity for collision handling in a hash table not strictly O(n) under certain balancing conditions?

Approach

  1. Start from the baseline: with separate chaining, if n keys land in one bucket the chain is a linked list and lookup is O(n).
  2. Explain the balancing condition: since Java 8, HashMap converts a bucket into a red-black tree once its chain exceeds 8 nodes (TREEIFY_THRESHOLD) and the table has at least 64 buckets (below that it resizes instead), and turns it back into a list at 6. Lookup in that bin is O(log n).
  3. State the caveat precisely: the tree is ordered by hash, then by compareTo when keys implement Comparable. For non-comparable keys with identical hashes, lookup may have to search both subtrees, so the guarantee really holds for Comparable keys.
  4. Mention why it matters: deliberate collisions (hash flooding) can turn a web server's request-parameter map into an O(n^2) workload. Treeification is one defence; randomised string hashing is another, and .NET Core's Dictionary switches to a randomised string comparer after too many collisions.
  5. Name alternatives with stronger worst-case lookup, such as cuckoo hashing (O(1) worst-case lookup, expensive inserts), to show you know balanced bins are one option among several.

Follow-up

  • Why is the threshold 8 and not 2? (Under a good hash and 0.75 load, a bin of 8 is vanishingly rare, and tree nodes cost about twice the memory.)
  • What is the amortised cost of insert once resizing is included?
  • How would you write a hashCode for a composite key so collisions stay rare?

Walk through the solution to a standard algorithmic coding problem while sharing your step-by-step reasoning.

Medium · Technical and Core Computer Science

Approach

  1. Restate the problem and pin down constraints before coding: input size, value ranges, duplicates, empty input, whether the input is sorted, and whether you return indices or values.
  2. Say the brute-force solution and its complexity, then name the bottleneck. Candidates do not name a specific problem, but the reported emphasis on hashing makes hash-map problems a likely type. For many array and string problems, the usual improvement is a hash map or set that turns a nested O(n^2) scan into one O(n) pass (two-sum, first non-repeating character, grouping anagrams by a sorted or counted key).
  3. Code in small steps while narrating, choose clear names, and keep the main loop free of special cases by handling empty or single-element input first.
  4. Trace one normal example and one edge case by hand through the code, then state time and space complexity, including the extra O(n) space the hash map costs.
  5. If time allows, offer a variant: a sorted input allows two pointers in O(1) extra space. A reported scenario asks you to process a data stream and optimise it for minimal memory overhead, so be ready to say what a bounded map, counter or sliding window keeps and what it drops.

Follow-up

  • Can you reduce the extra memory, and what do you give up?
  • How does the solution change if the input arrives as a stream too large for memory?
  • What test cases would you write for this function?

Discuss how memory management and garbage collection function in your primary programming language.

Medium · Technical and Core Computer Science

Approach

  1. Pick your primary language and be explicit. For .NET: the CLR allocates reference types on the managed heap by bumping a pointer; value types live inline (on the stack for locals, inside the object for fields), and boxing copies a value type onto the heap.
  2. Describe the generational GC: gen0, gen1 and gen2, based on the observation that most objects die young; a mark-and-compact collection of gen0 is cheap, and survivors are promoted. Objects of 85,000 bytes or more go to the large object heap, collected with gen2 and not compacted by default, so it can fragment.
  3. Separate managed memory from unmanaged resources: GC reclaims memory but not file handles or connections, so use IDisposable with using; finalizers are a safety net that delay collection by at least one extra GC, which is why Dispose calls GC.SuppressFinalize.
  4. Mention the modes and tuning levers: workstation versus server GC, background GC, and allocation reduction with Span<T>, ArrayPool<T> and avoiding boxing in hot loops.
  5. Cover managed memory leaks: references kept alive by event handlers that are never unsubscribed, static collections, and unbounded caches. Diagnose with dotnet-counters (heap size, gen2 count), then a heap snapshot (dotnet-gcdump or dotnet-dump) compared over time to find the root holding the objects.

Follow-up

  • How would you debug a memory leak in a high-throughput backend service?
  • What is the difference between Dispose and a finalizer, and when do you need both?
  • Why might calling GC.Collect manually make performance worse?

Explain the lifecycle of a thread and how concurrency is managed in high-throughput applications.

Medium · Technical and Core Computer Science

Approach

  1. Give the lifecycle states: in Java NEW, RUNNABLE, BLOCKED (waiting for a monitor), WAITING, TIMED_WAITING and TERMINATED; in .NET a Thread moves from Unstarted to Running, may sit in WaitSleepJoin, and ends Stopped. Say what moves a thread between states (start, lock contention, wait/sleep/join, completion).
  2. Explain why high-throughput services avoid a thread per request: threads cost memory for their stacks and context switches. Use a thread pool, and in .NET use async/await for I/O so no thread is held while waiting on the network or database.
  3. Name the synchronisation tools and when each fits: lock/Monitor for short critical sections, SemaphoreSlim (with WaitAsync) to limit concurrency in async code, Interlocked for single counters, ConcurrentDictionary and Channel<T> for producer-consumer pipelines.
  4. Cover the failure modes: race conditions on shared mutable state, deadlock from inconsistent lock ordering (fix with a global order or timeouts), and thread-pool starvation from sync-over-async calls such as .Result or .Wait() on a Task.
  5. Close with design choices that reduce locking: immutable data, per-request state instead of shared state, and partitioning work so each partition has one owner.

Follow-up

  • What is the difference between Task.Run and an async database call in terms of threads used?
  • How would you recognise thread-pool starvation in a running service?
  • What are the four conditions for deadlock, and which one do you usually break?

Stop tag and share joins from fanning out a page

Medium · join fan-out · semi-joins · many-to-many

resource_tag is (resource_id, tag_id) with PK (resource_id, tag_id); resource_share is (resource_id, shared_with_user_id, permission). The tagged-and-shared listing inner-joins resource to both, filters tenant_id, tag_id = ANY($2) and shared_with_user_id = $3, orders by updated_at DESC and takes 50. Pages come back with fewer than 50 distinct resources and the total in the header is far too high. Explain the row multiplication, rewrite both the page query and the count query so each is correct, and name the index each one needs. PostgreSQL 16.

Approach

  1. Do the arithmetic against the predicates that are actually there. An inner join emits one row per matching child row, and both joins are filtered: tag_id = ANY($2) admits only the requested tags, shared_with_user_id = $3 admits one user's share rows. So a resource holding three of the requested tags and shared with $3 once yields three rows, not one — the multiplier is its count of matching tags times its share rows for that single user, and that second factor is 1 unless the table admits duplicate (resource_id, shared_with_user_id) pairs. LIMIT 50 then limits rows rather than resources, and COUNT(*) counts pairs — the header is the product, not the population.
  2. Reject DISTINCT as the fix. It deduplicates after the product has been built, so the planner must materialise and sort the fanned-out set before the LIMIT can apply, and it leaves any SUM or AVG in the same select list wrong.
  3. Rewrite both filters as semi-joins, keeping resource as the only row source: AND EXISTS (SELECT 1 FROM resource_tag rt WHERE rt.resource_id = r.resource_id AND rt.tag_id = ANY($2)) and the same shape against resource_share. A semi-join stops at the first match per resource and preserves the driving index order, so ORDER BY updated_at DESC, resource_id DESC LIMIT 50 still stops after 50 rows.
  4. Count with the same predicates and no join at all: SELECT count(*) FROM resource r WHERE r.tenant_id = $1 AND r.status = 'active' AND EXISTS (...) AND EXISTS (...). Nothing multiplies a resource, so the number is the population.

Follow-up

  • The filter changes from 'any of these tags' to 'all of these tags'. Rewrite it and state what it costs relative to the ANY form.
  • A resource can be shared with the same user twice under different permissions. Does your count change, and should it?

Write the update path that detects a concurrent edit

Medium · optimistic concurrency · transactional outbox · audit history

resource carries version INT NOT NULL DEFAULT 1. resource_revision holds revision_id, resource_id, version, actor_user_id, change_kind, patch JSONB, request_id, created_at with UNIQUE (resource_id, version). outbox_event holds aggregate_type, aggregate_id, aggregate_version, event_type, payload, status. A PUT carries the version the client read. Write the exact statements for the single transaction that applies the edit, records the revision and enqueues 'resource.updated', and give the handler's branch on zero affected rows. Then say what PostgreSQL 16 does under READ COMMITTED when two of these updates hit one row at once.

Approach

  1. One transaction, three writes, no network call inside it: UPDATE resource SET title = $3, version = version + 1, updated_at = now() WHERE resource_id = $1 AND tenant_id = $4 AND version = $2; then INSERT the resource_revision row at version $2 + 1; then INSERT the outbox_event row at the same aggregate_version. The event goes to a table rather than a broker because no transaction spans both.
  2. Branch on the affected-row count before doing anything else. Zero has three causes — stale version, wrong tenant, row gone — so re-read once and map to 409 carrying the current version, or 404 for an id outside the caller's tenant, which also stops the endpoint confirming that another tenant's id exists.
  3. State the engine behaviour instead of assuming it. Under READ COMMITTED the second UPDATE blocks on the row lock, and when the first commits PostgreSQL re-evaluates the WHERE clause against the newly committed row, so the version predicate now fails and the statement reports zero rows. Under REPEATABLE READ the identical collision raises SQLSTATE 40001 instead, so the handler must fold both shapes into one conflict response.
  4. Keep UNIQUE (resource_id, version) even though the predicate already serialises writers. It is what makes a lost update unwritable if any other path ever reaches the revision table, and it converts a logic bug into 23505 rather than into a silently missing history row.

Follow-up

  • A client sends the version it read ten minutes ago and the resource has moved three versions. What is in your 409 so it can resolve the conflict without a full re-fetch?
  • Two editors, two disjoint fields, no overlap. Does your answer still refuse the second write, and should it?

Explain the internal workings of a HashMap and how hash collisions are handled.

Medium · Technical and Core Computer Science

Approach

  1. Start with the layout: an array of buckets; the key's hash code is mixed and reduced to an index. Java's HashMap uses a power-of-two table and computes (n - 1) & (h ^ (h >>> 16)); .NET's Dictionary keeps an int[] of bucket heads plus an Entry[] array chained by a next index, sized to primes.
  2. Explain collision resolution: separate chaining (each bucket holds a list of entries, as in Java and .NET) versus open addressing (linear or quadratic probing, double hashing, Robin Hood). The trade-off: probing is cache-friendly but degrades sharply at high load, and deletion needs tombstones or backward-shift deletion (the latter is used with linear probing and Robin Hood).
  3. Cover load factor and resizing: Java resizes at 0.75 of capacity by doubling and redistributing entries; .NET Dictionary grows to a prime at least double the size when its entries array fills. Resizing is O(n) but amortised O(1) per insert.
  4. State the equality contract: lookup compares hash first, then equals/Equals. Equal objects must have equal hash codes, and a key mutated after insertion becomes unreachable.
  5. Give complexity: average O(1) for get/put/remove, worst case O(n) for a plain chain when every key collides, O(log n) for a Java 8 tree bin.

Follow-up

  • What happens if every key returns the same hashCode, and how would you detect it in production?
  • How do ConcurrentHashMap or ConcurrentDictionary avoid locking the whole table?
  • Why does Java use a power-of-two table while .NET uses prime sizes?

What are the core concepts and architectural best practices when developing applications in.net?

Medium · Framework and Domain Knowledge (.NET and

Approach

  1. Cover the platform layer briefly: C# compiles to IL, the CLR JIT-compiles it and manages memory through the GC, and code is packaged in assemblies. Be clear about .NET Framework versus modern cross-platform .NET.
  2. Describe how an ASP.NET Core application is put together: the hosting model, the middleware pipeline (order matters: exception handling first, then routing, authentication, authorisation, endpoints), built-in dependency injection, configuration with the options pattern, and ILogger-based logging.
  3. Give an architecture you have used: thin controllers or endpoints, a service layer holding business rules, and data access through EF Core or Dapper behind interfaces, with dependencies pointing inward so the business layer can be unit tested without a database.
  4. State the practices and the reason for each: async all the way down for I/O, validation at the boundary, DTOs instead of exposing entities, small focused services (single responsibility), and automated tests with xUnit or NUnit plus mocks.
  5. Name a trade-off you have actually faced, such as whether a repository layer over EF Core earns its extra code, or when a layered monolith is simpler than splitting services.

Follow-up

  • What happens if authentication middleware is registered after the endpoint middleware?
  • How would you structure a solution so business logic can be tested without a database?
  • What changed for you moving from .NET Framework to modern .NET?

How do you structure and optimize database queries for applications handling heavy transactional loads?

Medium · Framework and Domain Knowledge (.NET and

Approach

  1. Start from measurement: find the slow or high-frequency queries from the database's query statistics or APM traces, then read the execution plan for scans, key lookups and bad row estimates before changing anything.
  2. Index for the access pattern: composite indexes ordered by equality columns then range or sort columns, covering indexes with included columns for hot reads, and a stated write cost for every index you add on a transactional table.
  3. Fix the application side: remove N+1 patterns (eager loading or projection to only the needed columns in EF Core), use parameterised queries for plan reuse and safety, batch writes, and use keyset pagination instead of large OFFSET values.
  4. Keep transactions short and choose isolation deliberately: do no network calls inside a transaction, consider snapshot or read-committed-snapshot isolation to stop readers blocking writers, and use optimistic concurrency (a rowversion column checked in the UPDATE's WHERE clause) to detect concurrent edits.
  5. Mention the scale-out options and their costs: connection pooling, caching read-heavy reference data, read replicas with their replication lag, and archiving or partitioning very large tables.

Follow-up

  • A query is fast in testing but slow in production with the same SQL. What do you check? (Parameter sniffing, statistics, data skew.)
  • How do you diagnose and reduce deadlocks between two transactions?
  • When does adding an index make overall throughput worse?

Explain the differences between various dependency injection lifetimes in modern application frameworks.

Medium · Framework and Domain Knowledge (.NET and

Approach

  1. Define the three lifetimes in Microsoft.Extensions.DependencyInjection: Transient creates a new instance per resolution, Scoped creates one per scope (one per HTTP request in ASP.NET Core), Singleton creates one for the application's lifetime.
  2. Map each to typical services: stateless lightweight helpers as transient, DbContext and unit-of-work objects as scoped (DbContext is not thread safe), and caches, configuration and thread-safe clients as singleton.
  3. Explain the captive dependency bug: a singleton that takes a scoped service holds one DbContext forever, sharing it across requests and threads. ASP.NET Core's scope validation (ValidateScopes and ValidateOnBuild) throws on this, but it is on by default only in the Development environment; the fix is to inject IServiceScopeFactory and create a scope per unit of work.
  4. Cover disposal: the container disposes IDisposable services it created at the end of their scope; transient disposables resolved from the root provider are not released until shutdown, which looks like a leak.
  5. Give a practical example: a BackgroundService is a singleton, so it creates a scope per iteration to get a fresh DbContext; HttpClient should come from IHttpClientFactory rather than a new instance per call or one static instance that ignores DNS changes.

Follow-up

  • How do you use a scoped service inside a hosted background service?
  • Why is injecting IServiceProvider everywhere considered a service-locator smell?
  • What goes wrong if a singleton holds mutable state accessed by concurrent requests?

Walk through a recent project you built, highlighting the specific architectural choices and trade-offs you ma

Medium · Framework and Domain Knowledge (.NET and

Walk through a recent project you built, highlighting the specific architectural choices and trade-offs you made.

Approach

  1. Open with context in two sentences: what the system did, who used it, and the scale (requests, data size or users) as you actually measured it.
  2. Describe the architecture as a request path: entry point, services, data stores, queues or external calls, so the listener can picture it without a diagram.
  3. Pick two or three decisions and give each the same shape: the options you considered, what you chose, why, and what it cost (for example a layered monolith over microservices, EF Core over raw SQL for most queries with Dapper for one hot path, or synchronous calls replaced with a queue).
  4. Say plainly what you personally built, in the first person, and keep it separate from what the team did. Candidates report technical rounds checking that resume projects are genuinely the candidate's own, so expect detail questions on any component you claim.
  5. End with what you would change now and why, backed by something that happened in production.

Follow-up

  • Which part of that system did you write yourself, and how did you test it?
  • What would break first if traffic grew ten times?
  • Why did you not choose the alternative you rejected?

How do you ensure robust error handling and logging across distributed backend services?

Medium · Framework and Domain Knowledge (.NET and

Approach

  1. Split errors by type: validation and business errors returned to the caller as clear 4xx responses (ProblemDetails in ASP.NET Core), transient infrastructure errors that are safe to retry, and unexpected faults caught by global exception-handling middleware that logs once and returns a generic 500.
  2. Make failures traceable across services: structured logging with ILogger message templates or Serilog, a correlation or trace ID propagated in headers (W3C traceparent through OpenTelemetry), and the same ID included in every log line and error response.
  3. Handle transient failures deliberately: timeouts on every outbound call, retries with exponential backoff and jitter only for idempotent operations, a circuit breaker (for example with Polly) to stop hammering a failing dependency, and idempotency keys so a retried write is applied once.
  4. For asynchronous flows, use dead-letter queues for messages that keep failing, with alerts and a replay path.
  5. Keep logs useful: consistent levels, no secrets or personal data, sampling for noisy paths, and alerts driven by metrics such as error rate and latency instead of individual log lines.

Follow-up

  • A retry caused a duplicate payment or record. How do you prevent that?
  • How would you find the cause of one failed request that crossed five services?
  • Where do you catch exceptions, and where do you let them propagate?

Describe a time when you had to debug a critical production issue under tight time constraints.

Medium · Behavioral and Professional Alignment

Approach

  1. Choose a real incident where you were hands-on, and open with the impact: what broke, for whom, and why time mattered.
  2. Show the order of operations: stabilise first (roll back, disable a feature flag, scale out), then diagnose by asking what changed and when, reading logs, metrics and traces, reproducing if possible, and narrowing the cause with checks that rule out half the candidates each time.
  3. State the root cause precisely and separate it from the trigger (for example a deploy exposed a missing index or an unbounded cache), then the fix and how you verified it in production.
  4. Finish with prevention: the alert, test or runbook you added, and what you communicated to stakeholders during and after.
  5. Avoid a hero story with no evidence; the answer sinks if you cannot say how you confirmed the fix worked.

Follow-up

  • How did you know your fix was the cause of the recovery and not a coincidence?
  • What monitoring would have caught this earlier?
  • What would you do differently if it happened again?

Suggested practice checklist

The seven days follow the reported question groups: hashing and complexity first, then runtime internals, .NET architecture, database and distributed backend topics, your own project story, and finally the behavioral prompts and the team alignment stage.

Day 1 — Hash map internals and collision handling

  • Write a chained hash map in C# or your main language with put, get, remove and resize at a set load factor, and test it with keys that deliberately collide.
  • Write a one-page comparison of separate chaining and open addressing (linear probing, double hashing, tombstones or backward-shift deletion).
  • Explain aloud, in under two minutes, why the worst-case lookup in a Java 8 HashMap bin is O(log n) for comparable keys, including the treeify and untreeify thresholds.

Deliverable: A working, tested hash map implementation, a one-page chaining versus probing comparison, and a recorded two-minute explanation of tree bins.

Day 2 — Algorithmic problem solving out loud

  • Solve five hash-map-based problems (two-sum, group anagrams, first unique character, longest substring without repeats, subarray sum equals k) while narrating, stating brute force first.
  • For each, write the time and space complexity and two edge-case tests.
  • Redo the hardest one from a blank editor under a self-set limit, speaking throughout.

Deliverable: Five solved problems with complexity notes and edge-case tests, plus one clean narrated repeat of the hardest.

Day 3 — Memory, garbage collection and threads

  • Write notes on .NET GC generations, the large object heap, finalizers versus Dispose, and the two leak patterns you would check first (event handlers, static caches).
  • Write a small producer-consumer program with Channel<T> or a BlockingCollection, then add a deliberate race on a shared counter and fix it with Interlocked or a lock.
  • Explain aloud the thread lifecycle states and why .Result on a Task can starve the thread pool.

Deliverable: A GC and leak-diagnosis note sheet, a producer-consumer program with its race condition fixed, and a spoken thread-lifecycle explanation.

Day 4 — .NET architecture and dependency injection

  • Build a minimal ASP.NET Core API with controller, service and data-access layers, registering one transient, one scoped and one singleton service.
  • Inject a scoped service into a singleton and observe the scope-validation error, then fix it with IServiceScopeFactory. The error appears only when ValidateScopes or ValidateOnBuild is on, which is the default only in the Development environment, so enable it explicitly if you run in Production mode.
  • Write five practices you follow when structuring a .NET application, each with the reason and an example from your work.

Deliverable: A layered sample API demonstrating all three DI lifetimes, a reproduced and fixed captive-dependency error, and a list of five justified .NET practices.

Day 5 — Queries under load and distributed error handling

  • Take one slow query from a past project or a sample database, read its execution plan, add a covering index and measure the change; note the write cost.
  • Write an UPDATE that detects a concurrent edit with a rowversion or version column, and rewrite one join that fans out rows.
  • Outline error handling for a request crossing three services: middleware, correlation IDs, timeouts, retries with backoff, circuit breaker and idempotency keys.

Deliverable: A before-and-after query plan with measurements, an optimistic-concurrency UPDATE and a corrected join, and a one-page error-handling outline for a three-service request.

Day 6 — Your project and your production incident

  • Write the walkthrough of your most recent project: request path, your personal contribution, two trade-offs with rejected alternatives, and one change you would make now.
  • Write the production-debugging story in STAR form with the stabilise, diagnose, fix, verify and prevent steps.
  • Have a friend interrupt both stories with "why not X?" questions and practise answering without losing the thread.

Deliverable: A written project walkthrough, a written incident story, and notes on the interruptions you struggled with.

Day 7 — Behavioral stories and the final stages

  • Write STAR stories for disagreement, ramping up on a new stack, competing deliverables and shifting requirements, each with a decision you made and a result.
  • Prepare a client-facing variant of the disagreement and shifting-requirements stories.
  • Write your two-minute recruiter introduction and the questions you will ask about rounds, team and client placement.

Deliverable: Four STAR stories with client-facing variants, a two-minute introduction, and a list of questions for the recruiter and team.

Behavioural preparation

The behavioral questions candidates report for this role centre on production pressure, disagreement, learning a new stack, competing priorities and changing requirements. Since some Alpha Net roles are tied to client placements and candidates report a closing discussion on team fit, prepare stories that show how you work with teammates and non-technical stakeholders, told in the first person with a clear decision and a measurable result.

  1. Describe a time when you had to debug a critical production issue under tight time constraints.

How do you handle technical disagreements with team members or project stakeholders?

Medium · Behavioral and Professional Alignment

Approach

  1. Pick a disagreement about something substantive (a design, a library choice, a deadline versus quality trade-off) where both sides had a reasonable case.
  2. Show how you understood the other position first, then agreed on the deciding criteria with the other person (performance, cost, delivery date, maintainability).
  3. Describe the evidence you gathered, such as a small prototype, a benchmark or a list of risks, and how the decision was made, including the case where it went against you and you committed to it.
  4. If the role may involve clients, include a version with a non-technical stakeholder where you translated the technical trade-off into time, cost or risk.
  5. The answer sinks if the story is that you were right and the other person was wrong; show the relationship stayed intact and what you learned.

Follow-up

  • Tell me about a time you were the one who turned out to be wrong.
  • What do you do when a client insists on an approach you think is risky?
  • How do you escalate when a disagreement cannot be resolved between peers?

Walk through a project where you had to quickly ramp up on an unfamiliar technology stack.

Medium · Behavioral and Professional Alignment

Approach

  1. Set the scene: what the unfamiliar stack was, why you needed it, and the deadline you were working against.
  2. Show a deliberate learning method: scoped what you needed first, read official docs and ran samples, read the existing codebase and its tests, paired with someone experienced, and shipped a small real change early to get feedback.
  3. Show how you checked quality while new: code review, following the stack's idioms instead of writing your old language in new syntax, and tests around anything you were unsure of.
  4. Give the result with a concrete marker (a feature delivered, a timeframe, a bug rate) and what you now do the same way when you start on anything new.
  5. Avoid a story that is only about reading tutorials; it needs a delivered result.

Follow-up

  • How did you know your code was idiomatic for that stack and not a translation?
  • What did you get wrong early on, and how did you find out?
  • How would you ramp up on a client's existing codebase in your first two weeks?

How do you prioritize your tasks when managing multiple competing deliverables?

Medium · Behavioral and Professional Alignment

Approach

  1. Describe a real period with competing deliverables, naming them and who wanted each.
  2. Explain your method: rank by impact, deadline and dependencies, and unblock others first, since work that blocks a teammate costs more than its own size.
  3. Show communication: you made the trade-off visible to the people affected, agreed on what would slip or shrink, and confirmed it in writing.
  4. Give the outcome and what you would change, for example breaking large tasks down sooner or raising a conflict earlier.
  5. The answer sinks if the method is just working longer hours; the point is choosing and communicating.

Follow-up

  • Two stakeholders both say their task is the top priority. What do you do?
  • Tell me about something you deprioritised that later turned out to matter.
  • How do you handle an urgent production issue that lands in the middle of planned work?

Describe a situation where project requirements shifted mid-development and how you adapted your code.

Medium · Behavioral and Professional Alignment

Approach

  1. Describe what changed, when it changed relative to your progress, and why the change happened.
  2. Explain how you assessed impact before reacting: which code, tests and timelines were affected, and what could be kept.
  3. Show the technical adaptation: the seams that helped or the lack of them that hurt (interfaces, configuration, feature flags, tests that let you refactor safely), and the rework you actually did.
  4. Show how you reset expectations with stakeholders on scope or dates, and the result.
  5. Close with the lesson in code terms, for example isolating the volatile business rules behind an interface, without claiming you now over-engineer everything for change.

Follow-up

  • How do you design for likely change without over-engineering?
  • Which tests made the change safe, or which missing tests made it painful?
  • When would you push back on a requirement change instead of absorbing it?