Angel One · Software Engineer
Updated · 2026-10-02

Angel One Software Engineer
Interview Guide

THE 60-SECOND BRIEF

Angel One is a financial services company whose platforms let users manage investments and trade on the stock market. Candidates describe the Software Engineer role as building, maintaining and scaling those platforms. Backend systems that handle large volumes of data, core trading engines and user-facing mobile features are all mentioned, as is day-to-day work alongside product managers and other engineers. For you, that means the assessment code is likely to deal with orders, prices, holdings and transactions, so knowing the vocabulary of trading helps you read a question quickly.

This guide is for candidates applying for a Software Engineer role at Angel One. It covers the one stage candidates report, the Online Assessment, and the five reported questions: a transaction-workflow class structure, a function for real-time market data input, a performance refactor, error handling for high-frequency financial operations, and an extensible class system for trading features. The requirements candidates describe name Java, C++ or Python as example languages, so the examples here stay language-neutral. No later stages are reported, so none are described.

Candidates report a single stage, an Online Assessment, inside a process of about 2-4 weeks. It is described as a check of core programming skills and of implementing classes and functions, with results driven by how many test cases a solution passes.

Programming for Automated TestingCode CorrectnessObject-Oriented Programming (OOP)

29 min read

Browse Software Engineer questions

See the practice prompts

12Practice promptsAcross five skill areas

The five reported questions all start from a short, loosely worded requirement and ask you to turn it into working code. Two ask for class structures (user transaction workflows, and a modular system for extending trading features), one asks for a function over real-time market data input, one asks you to refactor existing logic for performance and lower complexity, and one asks for error handling suited to high-frequency financial operations. Because the wording is open, your first job in practice is to pin each one down: pick concrete inputs and outputs, list the states or operations, and write the edge cases before the code.

Candidates report that the assessment is judged objectively by the number of test cases a solution clears, and that missing empty or invalid input handling is a common reason for failing cases. That shapes your order of work: get a plain correct version passing first, then handle empty, zero, negative, duplicate and out-of-order input, and only then tighten the time and space complexity. A clever version that fails a boundary case scores worse than a clear one that passes every case.

Reported preparation advice stresses data structures, object-oriented design (encapsulation, inheritance, modularity) and readable code. In practice that means being able to write, from memory and quickly, a class with a clear public interface and hidden state, a hash map or heap or deque used for the right reason, and small functions with honest names. Money needs care: use integer minor units or a decimal type rather than binary floats, and say so in a comment.

The domain is light but worth an evening. Know what an order is (side, symbol, quantity, price), the difference between a market and a limit order, what a partial fill is, how an average buy price and a holding are updated, and the difference between realised and unrealised profit. Candidates are also advised to learn basic financial concepts so the problem statements are easy to read. Nothing beyond the assessment is reported, so spend your time on code you can write cleanly under time pressure.

01

Online Assessment

reported

Candidates describe the Online Assessment as the first and only reported stage, an initial check of core programming skills and of the ability to implement classes and functions. They report that it is judged by how many test cases your solution passes, that empty or invalid input is where many candidates lose cases, and that the questions are representative of the technical challenge rather than a fixed list. The reported topics are programming for automated testing, code correctness, object-oriented programming, implementing classes and function implementation. Approach it in layers: write the class or function signature, make the simplest correct version pass, add boundary handling, then improve complexity. Keep functions small so that a hard problem still yields partial progress, and name things the way a reviewer would expect.

What to demonstrate

  • Working code that passes automated test cases, including boundary and invalid input
  • Implementing classes with encapsulation, inheritance and modularity
  • Function implementation with sensible time and space complexity
  • Readable structure and standard naming, which candidates are advised to keep even in an online test

How to prepare

  • Build a transaction class with explicit states and validation, then test illegal transitions, insufficient balance and duplicate transaction ids (the transaction-workflow question).
  • Implement one market data function, such as a rolling maximum with a monotonic deque and an order book with two heaps, and test empty, out-of-order and duplicate ticks (the real-time market data question).
  • Refactor a slow nested-loop function behind tests you wrote first, replacing repeated scans with a hash index, and record the before and after complexity (the refactoring question).
  • Write a small exception hierarchy that separates validation, transient and fatal errors, and make retries safe with an idempotency key (the error-handling question).
Angel One Software Engineer candidate reports ↗

PracHub editorial advice for the preparation topics above.

01

Using floating-point numbers for prices, quantities or balances

Store money as integer minor units or a decimal type, compare with exact arithmetic, and round only at the output boundary. A test comparing a balance after many small fills will expose float drift that a short manual example hides.

02

Chasing the optimal solution before a simple one passes

Reported advice favours passing all test cases over untested cleverness. Write the straightforward version first, run your own cases, then replace the slow part (a repeated scan becomes a hash lookup, a repeated sort becomes a heap) and rerun the same tests.

03

Missing empty, zero, negative, duplicate or unknown-symbol input

Keep a checklist next to every function: empty collection, single element, zero or negative quantity, duplicate id, unknown symbol, out-of-order timestamp. Decide for each whether to reject, ignore or handle it, and write one test per line.

04

Building one large class that branches on a type string for every trading feature

Define a small interface for the varying behaviour, such as an order type or fee rule, give each variant its own class, and look variants up in a registry. A new feature should mean adding a class, not editing a long if-else chain in code that already works.

05

Handling errors by catching everything, or retrying an operation that is not safe to repeat

Separate validation errors (never retry), transient errors (retry with a capped backoff) and fatal errors (stop and report). Retry a submit-style operation only when it carries an idempotency key, so a retry cannot apply the same transaction twice.

Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.

9 technical prompts0 include a worked solution

Implement a function to process real-time market data inputs efficiently.

medium
Technical Implementation & Coding

Implement a function to process real-time market data inputs efficiently.

Approach
  1. Pin down the input first: each tick is (symbol, price, quantity, timestamp), and it arrives as a stream. Keep per-symbol state in a hash map so each tick costs O(1) expected time, and store prices as integers (ticks or paise) to avoid floating-point drift.
  2. Keep running aggregates rather than recomputing. VWAP is sum(price*qty) / sum(qty), updated in O(1) per tick. Last price, day high and day low are single comparisons.
  3. For a sliding window (last N ticks or last T seconds), keep a deque and evict expired entries from the front. A monotonic deque gives the window max or min in amortized O(1). Top-k movers across symbols come from a size-k heap in O(n log k).
  4. Handle the input edge cases explicitly: zero quantity (VWAP divides by zero if every quantity is zero), an unseen symbol, duplicate or out-of-order timestamps, and an empty window when a query arrives before any data.
  5. State the cost: one pass over the stream, O(1) amortized work per tick, and memory of O(symbols + window size). Never re-scan history on each query.
Follow-up
  • How would you return the median price over the last N ticks? (Two heaps with lazy deletion, or an ordered multiset, both O(log N) per update.)
  • What changes if one thread receives ticks and another consumes them?
  • Ticks can arrive a few milliseconds out of order. How does your window stay correct?

Refactor existing logic to improve performance and reduce complexity.

medium
Technical Implementation & Coding

Refactor existing logic to improve performance and reduce complexity.

Approach
  1. Lock in the current behaviour before touching anything: write tests that capture today's outputs, including empty input, a single element, duplicates and boundary values. The refactor passes only if those outputs are unchanged.
  2. Find the real hot spot and give its complexity. The usual case is a nested loop doing membership or lookup checks in O(n*m). Build a hash set or hash map once and the work becomes O(n + m) expected time, paid for with O(m) extra memory.
  3. Replace repeated work with precomputation: move invariant calculations out of loops, use prefix sums for repeated range totals, and sort once then binary search in O(log n) instead of scanning linearly on every query.
  4. Reduce complexity in the readability sense too. Use guard clauses instead of deep nesting, a lookup table or map instead of a long if/else chain, and small named functions for each step. In C++, pass large objects by const reference and reserve vector capacity. In Java, build strings in a loop with StringBuilder.
  5. Check what a faster structure can silently change. An unordered set loses input order, deduplication changes counts, and integer overflow can appear once totals are accumulated. Keep the original order when the output depends on it.
Follow-up
  • How do you show that the refactored version returns exactly the same results as the original?
  • When is the O(n^2) version acceptable, and what input size makes it fail?
  • Your hash-based version uses more memory. When would you choose a sort-based approach instead?

Develop a robust error-handling mechanism for high-frequency financial operations.

medium
Technical Implementation & Coding

Develop a robust error-handling mechanism for high-frequency financial operations.

Approach
  1. Sort failures into classes before writing handlers. Validation errors (bad amount, unknown instrument) are rejected at once and never retried. Business failures (insufficient margin) are returned as results. Transient failures (timeout, dropped connection) are the only ones you retry.
  2. Retry transient failures with capped exponential backoff plus random jitter and a fixed maximum number of attempts, so many clients do not retry in lockstep. Once the attempts run out, send the operation to a failed or dead-letter queue instead of dropping it.
  3. Make every operation idempotent with a client-supplied key. A timeout is ambiguous because the order may already have executed, so query its status by that key before resubmitting, and never place it twice.
  4. Put a circuit breaker (closed, open, half-open) in front of a failing dependency so the system fails fast instead of piling up blocked threads. Keep multi-step updates atomic, or record a compensating action, so a partial failure never leaves one ledger leg without the other.
  5. Keep the hot path cheap and visible. In C++, return status codes or a result type for expected outcomes and keep exceptions for truly exceptional cases, because throwing is expensive. Never swallow an error silently, and log each failure with a correlation id.
Follow-up
  • The exchange call timed out. How do you find out whether the order went through, and what do you do next?
  • How do you stop a retry storm when the downstream service recovers?
  • How would you test these error paths without a live dependency?

Create a modular class system that allows for easy extension of trading features.

medium
Technical Implementation & Coding

Create a modular class system that allows for easy extension of trading features.

Approach
  1. Design for extension through interfaces. An Order holds the common fields (id, symbol, side, quantity), and each order type (Market, Limit, StopLoss) implements a shared interface such as validate() and shouldExecute(currentPrice). A new type is then a new class, not another branch in a switch.
  2. Register types in a factory or registry that maps the type name to its constructor, so the parsing and execution code never names a concrete class. Adding a feature means one new class plus one registration line.
  3. Prefer composition to deep inheritance. Run risk checks (quantity limits, price bands, available funds) as a chain of independent rule objects, and publish order events (placed, filled, cancelled) to observers for notifications and audit logging.
  4. Get the trading rules right in each strategy. A limit buy executes at or below its limit price and a limit sell at or above it. A sell stop-loss triggers when price falls to or below the stop, and a buy stop triggers when price rises to or above it.
  5. Name the trade-off: every extra layer of abstraction adds indirection, so add an interface only where a second implementation is realistic. Keep each class testable on its own with a mocked price feed.
Follow-up
  • How would you add a trailing stop-loss, whose trigger price moves with the market, to this design?
  • A new feature needs two behaviours from different classes. Do you use inheritance or composition, and why?
  • How do you unit-test a new order type without running the whole execution path?

The plan follows the single reported stage and its five questions: vocabulary and test setup first, then one question type per day, then a mixed timed run with behavioral stories.

Small steps. Visible outcomes.0 / 7 completed
ONE WEEK · YOUR PACE

Prepare, practise & reflect

One practical outcome each day. Spend longer where you need it.

0 / 7 done
01Vocabulary, language and test harness
  • Choose Java, C++ or Python and write a reusable test file with a few assertions and a table of inputs and expected outputs.
  • Write a one-page glossary: order, side, symbol, quantity, limit and market price, fill and partial fill, holding, average buy price, realised and unrealised profit.
  • Write the edge-case checklist you will reuse all week: empty, single element, zero, negative, duplicate, unknown key, out of order.

Deliverable: A language choice, a working test harness, a one-page glossary and an edge-case checklist.

02Class structure for transaction workflows
  • Pick a concrete workflow, such as deposit, buy, sell and withdraw, and list its states and the legal transitions between them.
  • Implement an account and transaction class with private state, validation, an atomic apply that leaves the balance untouched on failure, and a lookup by transaction id.
  • Write at least ten tests covering an illegal transition, insufficient funds, a duplicate transaction id and a failed apply, then compare with the SQL practice question on detecting a concurrent edit.

Deliverable: A working transaction class with ten or more passing tests and a diagram of its states.

Practice prompt ↗Practice prompt ↗
03Functions over real-time market data
  • Implement a rolling maximum and a volume-weighted average price over a stream of (symbol, price, quantity, timestamp) ticks using a monotonic deque and running sums.
  • Implement a small order book with two heaps for best bid and best ask, supporting cancel through lazy deletion, and state the cost of each operation.
  • Test empty input, a single tick, equal timestamps, out-of-order ticks and a very large batch.

Deliverable: Two functions with complexity written in comments and a passing test file that includes the boundary cases.

Practice prompt ↗
04Refactor for performance and lower complexity
  • Write a deliberately slow function, for example nested loops that match orders to holdings by symbol with repeated recomputation, and add characterization tests first.
  • Refactor it using a hash index, precomputed totals, early returns and extracted helper functions, keeping every test green.
  • Time both versions on a large generated input and record the before and after complexity; read the listing-latency practice question for a measuring habit.

Deliverable: Before and after code, identical passing tests and a short table of complexity and measured timings.

Practice prompt ↗Practice prompt ↗
05Error handling for high-frequency operations
  • Define an exception hierarchy that separates validation, transient and fatal errors, and return a structured result so callers can act on the category.
  • Implement a retry helper with capped exponential backoff and jitter that retries only idempotent calls, and add an idempotency key to a submit-style operation.
  • Test with a fake dependency that fails twice then succeeds, and prove that the transaction is applied exactly once; compare with the failure-taxonomy practice question.

Deliverable: An error-handling module with tests showing a retried operation applies once and non-retryable errors fail immediately.

Practice prompt ↗Practice prompt ↗
06Modular trading features and a portfolio class
  • Design an order-type interface with separate classes for market and limit orders, plus a registry, then add a third order type by adding one class and no edits to existing ones.
  • Build a portfolio class with dynamic updates: apply a fill, update quantity and average price, handle a sell that closes a position, and return an immutable snapshot.
  • Write a short note on where you used encapsulation, inheritance or composition and why.

Deliverable: An extensible class system, a portfolio class with tests, and a diff showing a new feature added without editing old code.

Practice prompt ↗
07Timed mock and behavioral stories
  • Take two of the five questions you chose blind, give yourself a fixed time budget, and work in layers: baseline passing, edge cases, then optimization.
  • Review your own failures and list the three edge cases you missed most often.
  • Write two short stories, one about a setback and one about explaining a technical choice, using the behavioral practice questions as prompts.

Deliverable: Two timed solutions with a pass and fail table, a list of three missed edge cases and two written stories.

Practice prompt ↗Practice prompt ↗Practice prompt ↗Practice prompt ↗Practice prompt ↗Practice prompt ↗Practice prompt ↗

Expand any day for tasks and deliverables. Your progress is saved on this device.

The only stage candidates report is a coding assessment, and what they say about the behavioral side is general: be ready to describe your problem-solving process, how you handle setbacks, how you collaborate and how you explain technical reasoning. No specific behavioral questions are reported, so prepare stories that show your own decisions and what you changed afterwards. Keep each story concrete, with the situation, your action and the result you can measure.

Unblock an engineer without taking the keyboard

easy
mentoringleasesat-least-once

A teammate has spent two days on a job handler that occasionally writes duplicate rows. They are certain the queue is delivering twice by mistake. You suspect a lease expiring under a slow handler, so the job is running concurrently with itself. Describe how you have unblocked someone in this position: what you asked before offering a hypothesis, what you showed them rather than told them, and what you left them owning. Then say what you would do if their theory turned out to be the right one.

Approach
  1. Ask before diagnosing, and ask for things answerable from data they already have: the attempt count on the job rows that produced duplicates, the handler's observed duration against its lease expiry, and whether the duplicate rows share a natural key that a unique constraint could have caught.
  2. Teach the shape rather than the answer. A lease cannot distinguish a dead worker from a slow one, so a handler that outruns its lease is running twice by design, and deploys deliver the other half by killing handlers mid-run on every rollout. Both of their candidate theories produce identical duplicate rows, which is why the evidence has to come from timings rather than from argument.
  3. Hand over a checklist they execute: a natural key on every write the handler performs so the second copy collides rather than appends, the record of intent written before any external effect, a lease heartbeat while running, and the metric that shows it working.
  4. Keep ownership with them deliberately. Pair on the first write, then step back; if you finish it yourself you have closed one ticket and left the same person stuck on the next redelivery.
Follow-up
  • How would you distinguish a genuine double-delivery from a lease expiry using only the data already stored?
  • Their handler calls an external endpoint before recording that it did. What do you tell them to change first?

Argue against a design, lose, and commit anyway

medium
disagreementservice boundariesdecision records

Describe a design you argued against and lost. State the failure you predicted as a named mechanism, not a feeling about complexity: two services that would need one transaction, a projection with no rebuild path, a write path with no idempotency key. Say what evidence you brought, what the decision maker weighed instead, and what you did after the decision was made: what you instrumented, what you wrote down, and whether the prediction came true. Five minutes.

Approach
  1. State the prediction in falsifiable form up front: the mechanism, the condition that triggers it, and the observable outcome. A prediction that cannot be checked also cannot be credited to you later.
  2. Show the evidence you had at the time and label each piece honestly as measured, analogous, or intuition. Keeping the intuition is fine; disguising it as data is the thing that erodes your standing in the next argument.
  3. Represent the opposing case at full strength, including the constraint you did not control: a fixed date, a team boundary, or the fact that the decision was cheap to reverse and yours was not.
  4. Make disagree-and-commit concrete. Name the artefact you left behind so the prediction could be settled without you: the alert and its threshold, the counter on the dashboard, the decision note that recorded the trade-off and the condition that would revisit it.
Follow-up
  • What threshold on that alert would have proved you right, and did anyone ever look at it?
  • If the same proposal arrived tomorrow with the same deadline, would you argue it the same way?

Ship under a deadline and bound the debt you chose

medium
paginationtechnical debttradeoffs

You have four days to ship a tenant-facing listing endpoint. The version you would defend uses keyset pagination over (tenant_id, status, updated_at DESC, resource_id DESC); the version you can finish uses LIMIT/OFFSET with no matching index. Describe a deadline call you actually made of this shape: what you shipped, what you knowingly deferred, how you bounded the damage with a mechanism rather than an intention, and the specific numeric condition that would force the follow-up. Name who you told and where you wrote it down.

Approach
  1. Name the deferred failure precisely instead of calling it slow. OFFSET n makes the database produce and discard n rows, so cost grows with page depth; without an index matching the sort, every matching row is read and sorted before the limit applies; and rows inserted between two page fetches shift across the boundary so items are skipped or repeated with nothing in the response to signal it.
  2. Bound the blast radius with something mechanical rather than a promise: cap maximum page depth, cap page size, restrict the endpoint to one internal caller, or keep it behind a flag. State which failure each cap removes and which it leaves standing.
  3. Attach a number to the trigger and wire it to an alarm: the first tenant crossing N resources, or the endpoint's p99 crossing its share of the 400 ms budget, so the debt announces itself instead of waiting to be remembered.
  4. Write it where the next engineer looks, which is the code and the ticket, not a chat message: what was deferred, why, the cap, and the trigger.
Follow-up
  • At what page depth does the offset version breach your latency budget, given your page size and row counts?
  • What breaks first when you switch to keyset pagination later, and what does a client holding an old page token see?
  • 01

    Walk me through how you break down a problem you have never seen before, from the first read to the final test.

  • 02

    Tell me about a setback on a project: what went wrong, what you did next and what you changed afterwards.

  • 03

    Describe a time you explained a technical decision to a product manager or teammate who disagreed with it.

  • 04

    Describe a bug that reached users because of an unhandled edge case. How was it found, and which test now guards against it?

  • 05

    Tell me about code you refactored. What did you measure before and after, and how did you know behaviour had not changed?

PracHub preparation framework ↗
How should I prepare for the Angel One coding assessment?

Practice designing classes and implementing functions from a short requirement, because that is what the reported questions ask. Write your own tests first, cover empty and invalid input, and optimize only after a simple version passes. Candidates describe the result as depending on how many test cases pass, so correctness and boundary handling come first.

Angel One Software Engineer candidate reports ↗
How many rounds are there and how long does the process take?

Candidates report one stage, an Online Assessment, within a process of about 2-4 weeks. What follows after it is not reported, so avoid planning around specific later rounds and treat the assessment as the part to prepare thoroughly.

Angel One Software Engineer candidate reports ↗
What should I prepare for the behavioral part?

Candidates report that you should be ready to describe your problem-solving process and how you handle setbacks, and to explain your technical reasoning clearly. Prepare two or three stories with a clear decision, an action and a result, and rehearse explaining a design choice aloud in plain language.

Angel One Software Engineer candidate reports ↗
Which programming language should I use?

The requirements candidates describe list Java, C++ or Python as examples of a major language. Whether the assessment limits your choice is not reported, so read the instructions when you receive them. Choose the language in which you write classes, hash maps, heaps and deques fastest, and practice in it all week.

PracHub Software Engineer practice ↗
Do I need finance knowledge?

Candidates are advised to learn basic financial concepts, and familiarity with financial systems is listed as a nice-to-have rather than a requirement. Learn the words that appear in the reported questions: order, side, quantity, price, fill, holding, average price and profit. That is enough to read a trading-flavoured problem without confusion.

Angel One Software Engineer candidate reports ↗
What if I cannot finish a problem?

Split it into small functions so each piece can pass its own cases, and submit a working simpler version rather than an unfinished optimal one. Handle empty and invalid input in the simple version, since those are the cases reported as most often missed.

PracHub Software Engineer practice ↗
Sources & methodology 3 sources ↗

No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.