cswork / libraryOpen practice workspace

Interview guides · Ahu Technologies

Ahu Technologies Software Engineer Interview Guide

Ahu Technologies Software Engineer interview guide: 3 reported rounds, .NET and Azure topics, coding, system design, behavioral prep, 7-day plan.

The 60-second brief

Candidates' reports for this role are tagged with .NET, Oracle Cloud ERP, Azure Cloud, Oracle Cloud and IT asset management software. The role description they relay covers designing, coding, testing and deploying applications, including cloud-based applications and work on existing systems, alongside product managers, QA and UX designers. The reports do not name a specific product, so use the tags as a map of the stack and ask in the phone screen which of them your team would touch.

This guide is for candidates interviewing for the Software Engineer position at Ahu Technologies. It covers the three reported stages (a phone screen, technical interviews and behavioral interviews) and the questions candidates report. The page gives worked guidance for the coding, system design, troubleshooting and behavioral questions, and for the general technical questions on languages, code quality, documentation and the development lifecycle.

Candidates report three stages over roughly 3-5 weeks: a phone screen, then technical interviews that can cover coding and system design, then behavioral interviews.

Focus areas

  • .NET
  • Oracle Cloud ERP
  • Azure Cloud

Overview

The reported requirements for this role name Java, Python or C# as the working languages, with Spring and React as example frameworks and Git and Docker as example tools. Cloud experience (AWS or Azure), Agile, DevOps and CI/CD, and basic front-end knowledge appear as extras. The topic tags on the reports lean toward the Microsoft and Oracle ecosystems: .NET, Azure Cloud, Oracle Cloud ERP and Oracle Cloud. If you have shipped C# on Azure, prepare to talk about it in specifics. If your background is Java or Python on another cloud, prepare the equivalent story and say plainly how it maps.

The reported question list is broad rather than puzzle-heavy. The coding questions are classics: reverse a linked list, implement binary search, compare sorting algorithms, and state the time and space complexity of what you wrote. The design questions ask for reasoning you can do at a whiteboard: handling millions of requests, microservices considerations, database design for a large application, and monolith versus distributed trade-offs. Because these are well-known topics, the differentiator is precision: pointer handling in the reversal, the loop invariant in the search, a clear reason to choose one sort over another.

A large share of the list is about how you work: how you keep code maintainable, what you do about a slipping deadline, how you debug a production issue, what you measure to call a project successful, and how you handle conflict, shifting scope and competing priorities. Prepare these as real episodes from your own work with a decision, a trade-off and a result, because generic principles are easy to give and easy to forget.

Plan the weeks around the structure candidates describe. Use the phone screen to confirm which stack and team the loop is aimed at, spend most of your practice time on coding fundamentals and system design reasoning for the technical interviews, and keep six behavioral stories ready for the last stage. The plan below allocates a day to each of those areas and ends with a full run-through.

The Ahu Technologies interview process

Candidates describe three stages in this order, over roughly 3-5 weeks. Treat the format as what candidates report rather than a published schedule, and confirm details with your recruiter.

Phone Screen

Candidates report an opening phone call about your background and your fit for the Software Engineer role. Approach it as a structured pitch: your recent work, the stack you used, and why this role follows from it. It is also the cheapest moment to learn which parts of the stack the team works in, so bring two or three questions of your own.

What to demonstrate

  • How clearly you describe your background and the work you personally did
  • Whether your experience lines up with the role as candidates describe it
  • Basic communication in a call about your background and fit

How to prepare

  • Write a short spoken summary of your career: current work, one project with measurable impact, and the reason you want this role.
  • Decide which of Java, Python or C# you would name as your strongest language and prepare one concrete example of production code you wrote in it, since the first technical question on the reported list asks which languages you prefer and why.
  • Prepare questions about the team, the stack and what the technical interviews will cover, and note the answers for later rounds.

Technical Interviews

Candidates describe several technical interviews that can cover coding and system design. Expect to write working code, explain its complexity, and reason out loud through an architecture problem. Practise with the guide's coding, design and troubleshooting questions, and keep a short example from your own work ready for each general technical question.

What to demonstrate

  • Working code for a standard data-structure or algorithm problem, with complexity stated
  • Ability to structure a design discussion: requirements, components, data model and trade-offs
  • A reasoned method for diagnosing performance problems and production issues
  • Breadth across engineering practice, such as code quality, the development lifecycle and documentation

How to prepare

  • Hand-write reversing a singly linked list (iterative, then recursive) and binary search with a correct loop condition, and say the complexity of each aloud.
  • Rehearse a design answer for handling millions of requests, then a second pass on microservices versus a monolith, and a third on database design: schema, indexes, partitioning and where you accept stale data.
  • Prepare a debugging walk-through for a slow system and for a production incident: what you check first, how you narrow it down, and how you confirm the fix.
  • Prepare concrete answers on code quality (reviews, tests, static analysis, CI) and on how you document designs.

Behavioral Interviews

Candidates report behavioral interviews centred on how you solve problems and how you work alongside others. The reported question list includes behavioral prompts on leading a team through a difficult project, handling conflict, adapting to a change in scope, what motivates you, and prioritizing across projects. Build a small bank of real stories that can answer them and shape each to the prompt rather than reciting one script.

What to demonstrate

  • Your own role and decisions in past team projects
  • How you communicate and resolve disagreement with colleagues
  • How you respond when scope, deadlines or priorities shift

How to prepare

  • Write six stories in a situation, action, result outline: leading a difficult project, a conflict, a scope change, a prioritization choice, your motivation and a cloud project.
  • Mark in each story what you personally decided, what it cost and what you would change, and replace every unexplained 'we' with the specific thing you did.
  • Practise each story aloud until it fits a short answer, then practise reshaping it for a different prompt.

Where candidates lose points

Writing a reverse-linked-list or binary-search solution that fails on edge cases

Test your own code on an empty list, a single node and two nodes, and for binary search on an empty array, one element and a target past either end. Check that the loop condition and midpoint update cannot spin forever or overflow, then state the complexity unprompted.

Answering a design question such as handling millions of requests by naming technologies without requirements

Start by fixing the scope: callers, read versus write ratio and failure expectations. Then lay out components, the data model and the first bottleneck, and say where you would accept stale data. Compare monolith and distributed options on team size, deploy independence and operational cost, not on fashion.

Describing code quality and the development lifecycle as slogans

Give mechanics from your own projects: how reviews ran, what tests gated a merge, what the CI pipeline checked, how a design was documented and where it lived, and what you personally owned at each lifecycle stage.

Giving behavioral answers in 'we' with no personal decision, or reusing one story for every prompt

Prepare six separate stories: leading a difficult project, a conflict, a scope change, a prioritization choice, your motivation and a cloud project. In each, state the decision you made, the trade-off, and the result, and keep the difficulty honest.

Claiming Azure, .NET or Oracle Cloud ERP experience you cannot support, or ignoring that those tags appear on the role

State precisely what you have used, then name the nearest equivalent and what you would learn first. A specific, accurate account of adjacent cloud or enterprise-application work holds up under follow-up questions better than a vague claim.

Questions & practice

Write a function to reverse a linked list.

Medium · Coding / Algorithms

Approach

  1. Clarify: singly linked list, reverse in place, return the new head; handle an empty list and a single node.
  2. Iterative solution with three pointers: prev = null, curr = head; while curr is not null: next = curr.next, curr.next = prev, prev = curr, curr = next; return prev. O(n) time, O(1) extra space.
  3. Recursive alternative: reverse the rest of the list, then set head.next.next = head and head.next = null. Still O(n) time, but O(n) call-stack space, so a long list can overflow the stack (CPython's default recursion limit is 1000).
  4. Test aloud: empty, one node, two nodes, odd and even lengths, and check that the old head now points to null so the result has no cycle.

Follow-up

  • Reverse only the nodes between positions m and n in one pass.
  • Reverse the list in groups of k nodes.
  • How would you reverse a doubly linked list?

How would you implement a binary search algorithm?

Medium · Coding / Algorithms

Approach

  1. State the precondition: the array is sorted and supports random access. Binary search runs in O(log n) time and O(1) space when written iteratively.
  2. Keep a clear invariant: lo = 0, hi = n - 1, loop while lo <= hi, mid = lo + (hi - lo) / 2 to avoid integer overflow in Java or C#, then move lo = mid + 1 or hi = mid - 1, and return -1 when the loop ends.
  3. Know the variants: lower bound (first index where a[i] >= target) using a half-open range with hi = mid; first and last occurrence when there are duplicates; and binary search on the answer when a predicate is monotone.
  4. Know the library behaviour: Java's Arrays.binarySearch returns -(insertion point) - 1 when the key is missing and gives no guarantee which duplicate it finds; C#'s Array.BinarySearch returns the bitwise complement of the insertion index; Python has bisect_left and bisect_right.
  5. Test edge cases: empty array, one element, target below the minimum or above the maximum, and duplicates; check that every update shrinks the range so the loop cannot run forever.

Follow-up

  • Search for a target in a rotated sorted array.
  • Find the first and last positions of a target in a sorted array with duplicates.
  • Why write lo + (hi - lo) / 2, and in which languages does it matter?

Discuss the time and space complexity of your solutions.

Medium · Coding / Algorithms

Approach

  1. Name the variables explicitly (n, m, V and E, k) and give time and auxiliary space separately, for example O(n + m) time and O(n) space.
  2. Derive it from the code: nested loops multiply, consecutive loops add, halving the range gives log n, and a recurrence covers recursion (merge sort's T(n) = 2T(n/2) + O(n) solves to O(n log n)); recursion depth counts as space.
  3. Call out hidden costs: hash-map operations are O(1) on average but O(n) in the worst case; building a string with += in a loop in Java or C# copies it each time, giving O(n^2) total work, so use StringBuilder; Python's list.pop(0) is O(n), so use collections.deque; appending to a dynamic array is amortised O(1).
  4. Connect the bound to the constraints: with n = 10^5, an O(n^2) solution is about 10^10 operations and too slow, while O(n log n) is fine. Say explicitly when you trade memory for time (memoisation, a hash set).

Follow-up

  • Why is appending to a dynamic array amortised O(1)?
  • Your solution is O(n log n); can it be faster, and what lower bound applies?
  • How much memory would your solution need for 10 million inputs?

Can you explain the differences between different sorting algorithms?

Medium · Coding / Algorithms

Approach

  1. Quicksort: O(n log n) on average, O(n^2) in the worst case with bad pivots (for example, first-element pivots on already sorted input); sorts in place with O(log n) expected stack space; not stable. Random or median-of-three pivots reduce the risk.
  2. Merge sort: O(n log n) in the worst case, stable, needs O(n) extra memory on arrays; a natural fit for linked lists and external sorting of data larger than memory. Heapsort: O(n log n) in the worst case with O(1) extra memory, but not stable and has poor cache locality.
  3. Insertion sort: O(n^2) in the worst case but O(n) on nearly sorted input, and stable, which is why hybrid sorts use it on small subarrays. Counting and radix sort avoid comparisons: O(n + k) and O(d(n + k)) for bounded integer keys.
  4. Know what the standard libraries do: Python's sort is Timsort-based and stable; Java's Arrays.sort uses dual-pivot quicksort for primitives and stable TimSort for objects; .NET's Array.Sort uses unstable introsort, while LINQ OrderBy is stable.
  5. Choose by the properties that matter: whether you need stability, the memory budget, worst-case guarantees, whether the input is nearly sorted, and whether the data fits in memory.

Follow-up

  • How would you sort a 100 GB file with 4 GB of memory?
  • Why does stability matter when you sort by a second key?
  • Which algorithm would you use for an array that is almost sorted, and why?

Solve a coding problem on a whiteboard or online coding platform during the interview.

Medium · Coding / Algorithms

Approach

  1. Clarify the input types, output, size limits and edge cases, and write two or three examples, including one edge case, before coding.
  2. State the brute-force solution and its complexity, then improve it by naming a pattern: a hash map for constant-time lookups, two pointers on sorted data, a sliding window for contiguous ranges, BFS for shortest paths in unweighted graphs, a heap for top-k in O(n log k), dynamic programming for overlapping subproblems.
  3. Code in the language you know best (the requirements candidates describe list Java, Python or C#), use clear names, and say the loop invariant out loud as you write.
  4. Trace one example by hand, then check edge cases: empty input, a single element, duplicates, negative numbers, integer overflow. Finish by stating the final time and space complexity.
  5. On an online platform, write code that compiles and run the given tests plus your own; on a whiteboard, keep the syntax close enough to compile.

Follow-up

  • Your solution passes the examples; what input would break it?
  • Can you reduce the extra space to O(1)?
  • How would the solution change if the input arrived as a stream?

Explain why the owner filter ignores the listing index

Medium · composite index · query plans · sort elimination

The only index on resource is (tenant_id, status, updated_at DESC, resource_id DESC). A new endpoint returns one user's resources across all statuses, newest created first: WHERE tenant_id = $1 AND owner_user_id = $2 ORDER BY created_at DESC LIMIT 20. On a tenant with 2M rows it takes 900 ms and EXPLAIN shows a sort above a large scan. Explain precisely why the existing index cannot serve it, give the index that can, and state which of these the new index still will not help: owner_user_id alone across tenants; the same query ordered by updated_at. PostgreSQL 16.

Approach

  1. Separate the two jobs an index does. For filtering, a composite btree is seekable only on a left prefix, so with no predicate on status the scan can at best range over tenant_id and test owner_user_id per row; PostgreSQL 16 has no btree skip scan to jump the unconstrained column.
  2. For ordering, the index is sorted by (status, updated_at) within a tenant and not by created_at, so the LIMIT cannot stop early: every matching row is read and then sorted. That is the 'Sort Method: top-N heapsort' line, and it is why the plan reads 2M rows to answer with 20.
  3. Derive the replacement from the access path — equality, equality, then the ordering column: CREATE INDEX CONCURRENTLY ON resource (tenant_id, owner_user_id, created_at DESC). The scan seeks to the (tenant, owner) range and walks 20 entries in order, so the Sort node disappears along with the row-read.
  4. Treat INCLUDE (title, status) as conditional, not free. An index-only scan still visits the heap for any row whose page is not marked all-visible, so on a table taking 1.2k writes/second the win depends on autovacuum keeping the visibility map current, and the wider index costs more on every insert.

Follow-up

  • 90% of rows are status='active'. Would a partial index WHERE status = 'active' change your answer, and for which of the three queries?
  • A dashboard runs this for 40 owners in one page load. What changes about the design?

Hold a per-tenant active cap against concurrent creates

Hard · write skew · isolation levels · constraints

A tenant on the standard plan may hold at most 50 resources with status='active'. The create handler runs SELECT count(*) FROM resource WHERE tenant_id = $1 AND status = 'active', compares to 50, then inserts. Two creates arrive 3 ms apart on different instances and the tenant lands at 51. Name the anomaly, say whether PostgreSQL 16 READ COMMITTED or REPEATABLE READ prevents it and why, then give an implementation that holds the cap at READ COMMITTED with the exact statements. Finally, say what changes when the cap is 'at most one running export per tenant' on job_run.

Approach

  1. Name it: write skew. The two transactions read an overlapping set and write disjoint rows, so there is no row-level conflict for the engine to detect and each commit is individually legal.
  2. Rule out the levels precisely. READ COMMITTED takes a fresh snapshot per statement and takes no lock on the counted rows, so both see 49. PostgreSQL's REPEATABLE READ is snapshot isolation: it removes non-repeatable reads and phantoms within the snapshot but still admits write skew, because the anomaly is not a re-read of a changed row, it is a read of a set that a concurrent transaction invalidates. Only SERIALIZABLE closes it, by tracking the read dependency and aborting one transaction with SQLSTATE 40001 — a guarantee that exists only if the application re-runs the whole transaction from the read.
  3. Convert the set predicate into a single-row conflict: keep tenant.active_resource_count and run UPDATE tenant SET active_resource_count = active_resource_count + 1 WHERE tenant_id = $1 AND active_resource_count < 50 in the same transaction as the INSERT. Zero affected rows is the cap, returned as 409. The row lock serialises the decision at any isolation level, and contention is bounded to one tenant's row — which is also the fair-scheduling unit, unlike a global counter that would convoy every tenant behind one row.
  4. State the cost you just took on: a counter is a second source of truth that can drift, so every path that changes status must adjust it inside the same transaction, and a periodic reconciliation has to exist, with resource_revision as the authority for what the count should have been.

Follow-up

  • A resource moves from archived back to active. Which statements change, and what breaks if the counter update and the status change land in different transactions?
  • The cap becomes plan-dependent and a plan can change mid-month. Where does the number 50 live, and who reads it?

What programming languages are you most comfortable with, and why?

Medium · Technical / Domain Questions

Approach

  1. Name one or two languages you have shipped production code in, and for each say what you built, which version, and which runtime (JVM, .NET CLR, CPython). The requirements candidates describe for this role list Java, Python or C#, so if you know one of those well, lead with it.
  2. Give reasons that come from the language itself, not just taste: static typing and compile-time checks in Java and C#, managed memory with a garbage collector, mature frameworks (Spring, ASP.NET Core), and Python's speed of iteration for scripting and data work.
  3. Prove depth with one detail a casual user would miss: LINQ queries in C# run lazily and execute again each time you enumerate them; in Java, overriding equals without hashCode breaks HashMap lookups; Python evaluates a mutable default argument once, when the function is defined.
  4. Be honest about a limit and how you work around it, for example that standard CPython builds have a GIL, so I use processes or async I/O rather than threads for CPU-bound work.

Follow-up

  • What feature of that language would you change, and why?
  • How does memory management work in that runtime, and when has garbage collection affected a service you ran?
  • If the team worked mainly in a language you use less, what would you learn first to be productive?

Describe a challenging technical problem you solved and the approach you took.

Medium · Technical / Domain Questions

Approach

  1. Pick a problem whose technical root cause you found yourself (a memory leak, a deadlock, a slow query, a race condition), and open with the symptom in numbers: error rate, p99 latency, how many users or jobs were affected.
  2. Walk the diagnosis as a chain of hypotheses and the evidence that ruled each one out: profiler output, query execution plan, thread dump, logs, a minimal reproduction.
  3. Explain the fix and at least one alternative you rejected, with the trade-off that decided it (risk, effort, performance, time to ship).
  4. Finish with a measured result and the guardrail you added so it cannot recur silently: a regression test, an alert, a runbook entry.

Follow-up

  • How did you confirm your fix caused the improvement, rather than a drop in traffic or another change?
  • What did you get wrong along the way, and what did it cost?
  • What would you have done if the right fix had been too risky to ship that week?

How do you ensure code quality and maintainability in your projects?

Medium · Technical / Domain Questions

Approach

  1. Describe layered automated checks: unit tests for logic, integration tests at database and HTTP boundaries, a small number of end-to-end tests, all run in CI on every pull request, with a failing build blocking the merge.
  2. Let tools enforce style and catch common bugs so review time goes to design: a formatter plus linters or analyzers (Roslyn analyzers for C#, Checkstyle or SpotBugs for Java, ruff and mypy for Python).
  3. Keep pull requests small and review for correctness, naming, error handling and test coverage of the change, not for whitespace.
  4. Design for change: clear module boundaries, dependency injection so code can be tested in isolation, no abstraction until a second use case exists, and short decision records explaining why a design was chosen.
  5. Track signals rather than vanity numbers: escaped defects, change failure rate, flaky-test count. Coverage percentage is a hint, not a goal.

Follow-up

  • You must change a legacy module with no tests; how do you do it safely?
  • What would you block a pull request for, and what would you let go?
  • How do you stop a test suite from becoming slow or flaky as it grows?

Explain the software development lifecycle and your role in it.

Medium · Technical / Domain Questions

Approach

  1. Name the phases: requirements, design, implementation, testing, deployment, then operation and maintenance. Explain that iterative models such as Scrum run the same activities in short cycles, while waterfall runs each phase once in sequence.
  2. For each phase, say what you personally did: clarified acceptance criteria with product, wrote or reviewed design notes, implemented with tests, reviewed peers' code, owned the CI pipeline, monitored after release.
  3. Describe the path from merge to production: CI builds and tests every commit, artifacts are versioned (for example Docker images), and deployment uses a rolling, blue-green or canary strategy with a tested rollback.
  4. Show where you move checks earlier: design review before coding, static analysis and tests in CI, feature flags so incomplete work can be merged without being exposed to users.

Follow-up

  • When is a more sequential, up-front design process the right choice?
  • Walk through exactly what happened between merging a pull request and it reaching production on your last team.
  • How do you handle a requirement that changes in the middle of a sprint?

How would you design a system to handle millions of user requests?

Medium · System Design / Architecture

Approach

  1. Pin the load first: one million requests a day is about 12 per second on average (1,000,000 / 86,400), while one million per second needs a very different design. Ask for peak-to-average ratio, read/write ratio, latency target and data size.
  2. Make the app tier stateless behind a load balancer so it scales horizontally with autoscaling; keep sessions in a shared store such as Redis or in signed tokens; serve static assets from a CDN.
  3. Protect the database: cache-aside reads with a TTL, read replicas for read-heavy paths (accepting replication lag), connection pooling, and sharding by a key such as user id once one primary cannot absorb the writes.
  4. Move slow or bursty work to a queue (Kafka, SQS, Azure Service Bus) with idempotent consumers, because delivery is usually at-least-once.
  5. Add resilience and visibility: timeouts, retries with exponential backoff and jitter, circuit breakers, per-client rate limiting (token bucket), deployment across availability zones, and p50/p95/p99 latency and error-rate dashboards backed by load tests.

Follow-up

  • After a deploy the cache is empty and every request hits the database; what happens, and how do you prevent a stampede?
  • How would you shard the user data, and which query becomes expensive as a result?
  • What changes if writes must be strongly consistent across two regions?

Describe the considerations you would make when designing a microservices architecture.

Medium · System Design / Architecture

Approach

  1. Draw service boundaries around business capabilities, and give each service ownership of its own data store; a shared database couples deployments through the schema.
  2. Choose the communication style per interaction: synchronous REST or gRPC when the caller needs an answer now, asynchronous events through a broker when it does not. Every remote call gets a timeout, retries only for idempotent operations, and a circuit breaker.
  3. Handle consistency without distributed transactions: sagas with compensating actions, the transactional outbox pattern to publish an event atomically with the database write, and idempotency keys because consumers will see duplicates.
  4. Plan the operational cost: independent CI/CD pipelines, containers and an orchestrator, service discovery, an API gateway, centralised logs, distributed tracing with propagated correlation ids (for example OpenTelemetry), and versioned API contracts.
  5. State the trade-off: network latency, partial failure and more infrastructure in exchange for independent deploys and scaling. For a small team, a modular monolith is often the better starting point.

Follow-up

  • An order service and a payment service must both succeed or both be undone; walk through the saga and its failure cases.
  • How do you change an API contract without breaking consumers that deploy on their own schedule?
  • A request is slow only when it passes through four services; how do you find the slow hop?

What tools and methodologies do you use for system design and documentation?

Medium · System Design / Architecture

Approach

  1. Start from written requirements: functional needs, non-functional targets (availability, latency, throughput), constraints, and back-of-the-envelope estimates of traffic and storage.
  2. Diagram at more than one zoom level, for example with the C4 model (context, containers, components, code), plus sequence diagrams for the flows that matter most. Prefer diagrams as code (Mermaid, PlantUML, Structurizr) stored in the repository so they are reviewed with the code.
  3. Write a design document that lists alternatives and why they were rejected, and record lasting choices as Architecture Decision Records: context, decision, consequences, superseded by a new record rather than edited.
  4. Make interfaces explicit: OpenAPI specifications for REST endpoints, and versioned schema migrations (Flyway, Liquibase or EF Core migrations).
  5. Keep documentation alive: give each document an owner, update it in the same pull request as the change, and delete what is stale; add runbooks for on-call tasks.

Follow-up

  • Describe on one page how you would document the last system you built.
  • How do you stop design documents from going stale after launch?
  • When is a design document not worth writing?

Explain how you would approach database design for a large application.

Medium · System Design / Architecture

Approach

  1. Start from access patterns and volumes: the top queries, read/write ratio, expected growth and retention. Choose a relational database (PostgreSQL, SQL Server, Oracle) when you need transactions, joins and constraints; use a document or key-value store only for access patterns it serves better.
  2. Normalise transactional tables to roughly third normal form to avoid update anomalies, and denormalise selectively for hot read paths with a stated way to keep copies in sync. Enforce invariants in the database with primary keys, foreign keys, unique and check constraints.
  3. Index for the queries you listed: B-tree indexes on filter, join and sort columns, with composite indexes ordered for the leftmost-prefix rule (equality columns before range columns). Every index costs write time and storage, so confirm each with EXPLAIN.
  4. Plan scale: connection pooling, read replicas, range partitioning by date for time-series data so old partitions can be dropped cheaply, and sharding by tenant or user once a single primary is not enough.
  5. Plan operations: backward-compatible migrations (expand, migrate, contract), backups with regularly tested restores, and a deliberate choice of transaction isolation level.

Follow-up

  • A query filtering on status and a created-at range is slow; which index would you add, and in what column order?
  • How would you add a NOT NULL column to a table with hundreds of millions of rows without downtime?
  • When would you choose a document store over a relational database for part of this application?

Discuss the trade-offs between monolithic and distributed architectures.

Medium · System Design / Architecture

Approach

  1. Monolith strengths: one deployable, in-process calls with no network failure modes, a single database with ACID transactions, and simple local debugging. Costs: every change redeploys everything, the whole application scales as one unit, and coupling grows without enforced boundaries.
  2. Distributed strengths: independent deploys and scaling per component, fault isolation, and teams owning their services. Costs: network latency, partial failures, eventual consistency between data stores, and heavier tooling for tracing, deployment and monitoring.
  3. Name the middle ground: a modular monolith with enforced module boundaries, and extracting a service only along a seam where scaling needs, release cadence or ownership really differ, using the strangler fig pattern to move traffic gradually.
  4. Tie the choice to context: team size, how well the domain boundaries are understood, and whether CI/CD and observability are mature enough to run many services. Mention the fallacies of distributed computing, such as assuming the network is reliable or latency is zero.

Follow-up

  • Which part of a monolith you have worked on would you extract first, and how would you migrate traffic to it?
  • How do you keep data consistent once one transaction's data is split across two services?
  • What signs tell you a move to microservices was premature?

How would you approach a situation where a deadline is imminent but the project is behind schedule?

Medium · Problem-Solving / Case Studies

Approach

  1. Quantify the gap first: break the remaining work into tasks with estimates, compare that with the days left, and identify the critical path rather than reporting a vague feeling of being late.
  2. Lay out the real levers: cut scope (for example MoSCoW: must, should, could, won't), move the date, or add people, noting Brooks's law that adding people to a late software project tends to make it later. Say explicitly what you would not trade, such as tests on the core paths.
  3. Tell stakeholders early with options and their consequences, not just bad news, and get a named person to make the decision.
  4. Execute visibly: track progress daily, clear blockers, stop new requests from entering the sprint, and use feature flags so partial work can ship safely.
  5. Afterwards, run a retrospective on why the estimate was wrong and what early signal was missed.

Follow-up

  • The stakeholder refuses both a scope cut and a new date; what do you do?
  • Which corners would you never cut under deadline pressure, and why?
  • How could the slip have been spotted earlier?

Describe a complex problem you encountered and how you structured your solution.

Medium · Problem-Solving / Case Studies

Approach

  1. Pick a problem with several interacting parts, and state the constraints and the success criterion at the start so the listener can judge the result.
  2. Show the decomposition: the sub-problems, the unknowns, and the riskiest assumption you tested first with a spike or prototype.
  3. Explain the options you compared and the trade-off that decided it, for example consistency versus latency, or build versus buy.
  4. Describe incremental delivery: milestones that could each be verified with tests or metrics, so a wrong turn was caught early.
  5. Close with a measured outcome and what you would structure differently next time.

Follow-up

  • Which part of your decomposition turned out to be wrong, and how did you find out?
  • How did you get others to agree on the approach?
  • What would you simplify if you did it again?

What metrics would you use to measure the success of a software project?

Medium · Problem-Solving / Case Studies

Approach

  1. Separate the layers. Outcome: adoption, task completion, retention, support-ticket volume, time or cost saved. Delivery: the four DORA metrics (deployment frequency, lead time for changes, change failure rate, time to restore service). Reliability: SLOs on availability, p95 latency and error rate, plus escaped defects.
  2. Also report schedule and budget against plan, but do not equate shipping on time with success if nobody uses the result.
  3. Set a baseline and a target before launch, and pair leading indicators (activation in week one) with lagging ones (retention after a quarter).
  4. Guard against gaming (Goodhart's law): avoid lines of code, velocity compared across teams, or coverage percentage as targets.
  5. Fit the metrics to the project type: for an internal tool, time saved per task and active users; for a migration, unchanged error rates and a decommissioned old system.

Follow-up

  • The project shipped on time but adoption is low; was it a success?
  • How would you measure success for a migration that users should not notice at all?
  • Which of these metrics would you report weekly, and which quarterly?

Given a scenario where a system is experiencing performance issues, how would you troubleshoot it?

Medium · Problem-Solving / Case Studies

Approach

  1. Define the symptom with data before forming theories: which endpoint or job, which percentile (p99 versus average), throughput, error rate, and since when. Line that up against deploys, configuration changes and traffic spikes.
  2. Check every resource systematically, for example with the USE method (utilization, saturation, errors) for CPU, memory, disk, network, thread pools and connection pools, and the RED metrics (rate, errors, duration) per service.
  3. Narrow down the layer on the tagged .NET and Azure stack: Application Insights or Azure Monitor shows end-to-end traces and how long each dependency call (SQL, HTTP, queue) took; dotnet-counters shows thread-pool queue length, GC heap size and time in GC live; dotnet-trace captures a CPU profile or the stacks behind thread-pool starvation, often sync-over-async blocking.
  4. In the database, Azure SQL Query Store shows the slowest queries and plans that regressed after a change; then check missing indexes, lock waits and ORM N+1 patterns before moving on to external dependencies.
  5. Change one variable at a time and verify with the same metric under comparable load, then leave behind a dashboard or alert that would have caught it earlier.

Follow-up

  • Average latency is flat but p99 has tripled; what does that suggest?
  • CPU is low but requests are slow; where do you look next?
  • How would you confirm a suspected N+1 query coming from an ORM?

Explain how you would approach debugging a critical production issue.

Medium · Problem-Solving / Case Studies

Approach

  1. Mitigate before you diagnose: assess impact (how many users, is data being corrupted), open an incident with clear roles, and roll back the latest deploy or switch off a feature flag if the timing matches. Restoring service comes before finding the root cause.
  2. Gather evidence: dashboards, error logs, traces, and a timeline of recent changes (deploys, configuration, infrastructure, dependency status pages). On a .NET service on Azure, search Application Insights by operation id to join the failing request with its dependency calls and exceptions, and compare failure rates before and after the deploy in Azure Monitor.
  3. Test the cheapest, most informative hypothesis first, change one thing at a time, and reproduce in a staging environment with production-like data when that is safe. If the database is implicated, check Azure SQL Query Store for a plan that changed when the incident began; if the process is hung, take a dotnet-counters reading and a dotnet-trace or dump before restarting it.
  4. Handle data damage explicitly: identify affected records and plan a verified backfill or correction.
  5. Afterwards, write a blameless postmortem with timeline, root cause, contributing factors and owned action items such as a regression test or a new alert, and keep stakeholders updated throughout.

Follow-up

  • The rollback did not fix it; what do you do next?
  • The failure hits 1% of requests and you cannot reproduce it locally; how do you get more information?
  • How do you decide between a hotfix and a rollback?

Suggested practice checklist

The plan follows the reported loop: the first day sets up the phone screen and stack, the middle days cover coding, system design, general engineering, an ERP integration design and troubleshooting for the technical interviews, and the last days build and rehearse behavioral stories.

Day 1 — Phone screen pitch and stack map

  • Write a short spoken career summary and a one-paragraph answer to why this role, using one project with a concrete result.
  • List the stack tags reported for the role (.NET, Azure Cloud, Oracle Cloud, Oracle Cloud ERP) and, for each, write what you have done with it and the nearest equivalent you have used.
  • Write three questions to ask the recruiter about the team, the stack and what the technical interviews cover.

Deliverable: A written pitch, a stack map marking gaps, and three questions for the recruiter.

Day 2 — Coding fundamentals by hand

  • Write reverse-a-linked-list iteratively and recursively, and test on empty, single-node and two-node lists.
  • Write binary search with a half-open interval and again with an inclusive one, and trace both on arrays where the target is missing and at either end.
  • Write a short comparison of insertion, merge, quick and heap sort covering time, extra space, stability and nearly-sorted input.
  • Solve one unseen problem on a whiteboard or an online editor and state its time and space complexity.

Deliverable: Two correct hand-written solutions with tested edge cases, a sorting comparison sheet, and one timed unseen problem with complexity stated.

Day 3 — System design and data modelling

  • Outline a design for a service handling millions of requests: load balancing, stateless app tier, caching, queueing and database scaling, and name the first bottleneck.
  • Write a table of monolith versus microservices trade-offs and the considerations for splitting a service: boundaries, data ownership, deployment, failure handling.
  • Design a schema for a large application, choosing indexes and a partitioning or sharding key, and say which queries it makes expensive.

Deliverable: Three design outlines (high-scale service, microservices split, database schema) and notes from the two SQL practice questions.

Day 4 — Engineering practice, cloud and an ERP sync design

  • Write out your answers on programming languages, code quality and maintainability, the development lifecycle and your role in it, and how you document designs, each with an example from your own projects and one real diagram or decision record.
  • Write your challenging technical problem story: the symptom in numbers, the hypotheses you ruled out and the evidence for each, the fix with one rejected alternative, and the measured result.
  • Prepare your cloud project story: workload, services chosen and why, deployment pipeline, secrets and cost, framed for Azure if you have used it.
  • Because Oracle Cloud ERP and IT asset management software appear as topic tags, outline an asset inventory sync service on Azure that exchanges records with Oracle Cloud ERP: REST APIs versus bulk file import, idempotent upserts keyed on an external id, reconciliation of mismatched records, retries with backoff, and an audit trail of every change.

Deliverable: Five prepared answers (languages, a challenging problem, code quality, the development lifecycle, design documentation), one cloud project outline and one asset-sync design outline, each backed by a real example or a stated trade-off.

Day 5 — Troubleshooting and project delivery

  • Write a step-by-step method for a slow .NET service on Azure: define the symptom, check recent changes, read traces and dependency timings in Application Insights, check thread-pool and GC behaviour with dotnet-counters, and look for regressed queries in Azure SQL Query Store, testing one hypothesis at a time.
  • Write a production-incident outline covering mitigation first (rollback, feature flag, scaling), then root cause, then a follow-up fix and communication.
  • Prepare answers on handling a behind-schedule project with an imminent deadline, a complex problem you structured, and the metrics you would use to judge a software project.

Deliverable: A performance-troubleshooting checklist, an incident outline and three prepared answers with metrics.

Day 6 — Behavioral story bank

  • Write six stories in a situation, action, result outline: leading a difficult project, a conflict, a scope change, a prioritization choice, your motivation and a cloud project (reuse the one from day 4).
  • Mark each story with your specific decision, the trade-off and a result you can state.
  • Say each story aloud and shorten it, then practise answering a different prompt from the same story.

Deliverable: Six rehearsed stories with decisions and results written next to each, and a map of which story answers which prompt.

Day 7 — Full run-through

  • Do a mock phone screen using your day 1 pitch and questions.
  • Do a mock technical session: one coding problem, one design prompt, and one troubleshooting scenario, answered aloud.
  • Do a mock behavioral session with a friend or a recording, and list the three weakest answers to rework.

Deliverable: A short list of the three weakest answers with a revised version of each, and a final one-page checklist for each round.

Behavioral stories for the final stage

Candidates describe the last stage as interviews about how you solve problems and how you work with others. For a Software Engineer role that means stories with your own decisions in them: leading or steering work, resolving a disagreement, absorbing a change in scope, and choosing between competing tasks. Rehearse each as a short story you can shape to the prompt.

  1. Discuss a time when you had to learn a new technology quickly to meet project demands.

Discuss your experience with cloud technologies and their application in software development.

Medium · Technical / Domain Questions

Approach

  1. Pick one real cloud project and state the workload first: what the application did, who used it and what it needed from the platform (compute, storage, database, messaging, identity).
  2. Name the services you actually used and the decision behind each, for example a managed database versus running your own, or a queue to decouple a slow job. A list of service names without a decision shows nothing.
  3. Cover the operating side: how you deployed (CI/CD pipeline, infrastructure as code or portal clicks), how you managed secrets and per-environment configuration, and how you watched cost and health.
  4. State a result you can defend, such as a deploy that became repeatable, a bill that dropped, or an outage you avoided. Be honest about the provider: if your experience is on a different cloud than the one tagged for this role (Azure, Oracle Cloud), say so and map the concepts across.

Follow-up

  • Why did you choose that service over the alternative, and what would make you reverse the choice?
  • What went wrong in that deployment, and what did you change afterwards?
  • How did you handle secrets, environments and rollbacks?

Describe a time when you had to lead a team through a difficult project. What was your approach?

Medium · Behavioral / Leadership

Approach

  1. Choose a project where you set direction or unblocked others, even without a manager title. State in two sentences why it was difficult: unclear requirements, a hard deadline, a risky migration or a stretched team.
  2. Show the leading actions as your own: how you broke the work into pieces, who you assigned what and why, how you tracked progress, and what decision you made when plans slipped.
  3. Include a moment of friction with a person or a trade-off, and how you handled it, because a story with no difficulty does not answer the question.
  4. Close with the outcome and a number if you have one (delivery date met, defects after release, time saved), then one thing you would change. The common mistake is narrating the team's achievement in 'we' with no visible decision of yours.

Follow-up

  • How did you handle a teammate who was falling behind?
  • What did you cut or defer, and who agreed to that?
  • What would you do differently if you led it again?

How do you handle conflict within a team?

Medium · Behavioral / Leadership

Approach

  1. Use a genuine disagreement with a colleague, ideally technical (design choice, review feedback, release timing), not a personality clash you won.
  2. Describe how you found out what the other person actually cared about: their constraint or risk, not just their position. Say that you asked questions and restated their view before arguing yours.
  3. Show how it was resolved with evidence rather than volume: a small prototype, a benchmark, a written comparison of options, or an escalation for a decision with both views fairly stated.
  4. Report the result and the relationship afterwards, including the case where you were wrong or the decision went against you and you committed to it anyway. Avoid casting the other person as the villain.

Follow-up

  • What would you have done if the other person had been more senior and stayed unconvinced?
  • Describe a time you changed your mind in a disagreement.
  • When do you escalate rather than keep working it out?

Share an experience where you had to adapt to a significant change in project scope.

Medium · Behavioral / Leadership

Approach

  1. Pick a change that really altered the work: a feature added late, a requirement reversed, or a dependency that moved. State what was planned and what changed.
  2. Show your first response: you re-estimated, identified what was affected (code, tests, QA, design) and made the cost of the change visible to the product manager or stakeholder rather than absorbing it silently.
  3. Describe the trade-off you negotiated: what moved out, what moved later, what was simplified, and how you protected testing and quality while doing it.
  4. Close with the delivered outcome and what you now do up front to make scope changes cheaper, such as smaller increments or a written assumptions list. The sinking mistake is a story about working longer hours with no decision in it.

Follow-up

  • How did you re-estimate, and how accurate was the new estimate?
  • How did you decide what to cut?
  • What would you do if the change arrived after the work was already in testing?

What motivates you to perform well in your role?

Medium · Behavioral / Leadership

Approach

  1. Answer with one or two specific drivers, not a list of virtues, and back each with something you did: for example, owning a service until it ran reliably, or shortening a slow build that annoyed everyone.
  2. Tie the drivers to the work the role involves as candidates describe it: designing, coding, testing and deploying software, reviewing code and working with product, QA and UX. Do not claim to know what the company values.
  3. Give a short example of motivation turning into action when no one asked you to, and its result.
  4. Be ready to say what drains you and how you handle it. A single answer built around pay or titles, or one that could be recited at any employer, tells the interviewer nothing.

Follow-up

  • Tell me about a period when your motivation was low, and what you did.
  • What kind of work would you least want to own?
  • What would you want to learn in your first year in this role?

How do you prioritize tasks when working on multiple projects?

Medium · Behavioral / Leadership

Approach

  1. Open with the method, then prove it with one real episode. A workable method: list every commitment, estimate the effort, rank by impact and deadline, check which items block other people, and pick the order with the smallest cost of delay.
  2. Describe how you made the ranking visible: a shared board, a short message to stakeholders, or a conversation where you asked them to choose between two items rather than promising both.
  3. Include what you dropped or deferred and how you told the people affected, because showing a sacrifice is more convincing than claiming you did it all.
  4. Add how you handle interruptions, such as a production issue arriving mid-sprint, and when you re-plan. The mistake is answering 'I just work harder' or 'everything is a priority'.

Follow-up

  • What do you do when two managers give you conflicting priorities?
  • A production issue lands in the middle of a deadline week. What happens to your plan?
  • How do you track tasks so nothing silently slips?