Akraya · Software Engineer
Updated · 2026-10-02

Akraya Software Engineer
Interview Guide

THE 60-SECOND BRIEF

Akraya works with client companies, and candidates describe Software Engineers as embedded in those clients' project teams. The job reported is to take technical requirements from a client, turn them into maintainable code, and get productive in an existing codebase quickly, either to fill a skills gap or to speed up a product effort. Akraya recruiters and technical screeners handle the early vetting, and candidates who advance may then meet the client's own team. The requirements candidates describe name one modern language (Java, Python and C++ are the examples), Git, and solid data structures and algorithms, with AWS, Azure, GCP, Docker, Kubernetes and CI/CD pipelines as extras.

This guide is for engineers interviewing for a Software Engineer position through Akraya. It covers the five reported technical questions (complexity, optimizing for larger data, linked list versus array, production debugging, maintainable and testable code), the client-facing behavioral topics candidates report, and the early stages: recruiter calls, AI-led assessments and take-home assignments. Because the client differs from one opening to the next, it also shows how to confirm the format for your specific role.

The format varies by client and opening. Candidates describe a sequence that starts with recruiter and technical screeners, can include an AI-led assessment or a take-home with a short turnaround, and may move on to interviews with the client's team.

Coding Assignments (Take-home)AI-Based Pre-screeningAI Chatbots in Hiring Workflows

31 min read

Browse Software Engineer questions

See the practice prompts

12Practice promptsAcross five skill areas

The work described for this role is delivery inside someone else's project. You read a client's specification, ask about the parts that are vague, write code other people will maintain, and keep project managers and client technical leads informed about progress. That shapes what to practise: explaining your reasoning aloud matters as much as producing working code, and the reported questions reflect it. Several ask you to justify a choice (why this approach, why a linked list or an array, how you keep code testable) rather than just produce an answer.

The five reported technical questions split into three groups. Complexity, optimizing a function for a larger data set, and linked list versus array are data-structure and efficiency questions: state the cost in time and space, name the operation that dominates, and tie the choice to how the data is accessed. The production-debugging question is about sequence: how you scope impact, find what changed, mitigate, and then prove a cause in a distributed system. The maintainability question is about concrete habits, such as naming, small functions, dependency seams and unit and integration tests, so prepare examples from your own code instead of slogans.

The early stages deserve their own preparation. Candidates report that recruiter calls count as a formal conversation, that an AI-led assessment can arrive early, and that some loops use a take-home assignment with a tight turnaround. For the AI assessment, find a quiet place and practise giving short structured answers aloud. For a take-home, practise writing down scope, assumptions and an estimate before you open an editor. Candidates' topic lists also include AI chatbots in hiring workflows and handling personally identifiable information, so decide in advance what you will share and when. Contact details and your work authorization status are reasonable to give a recruiter early. Items such as a Social Security number, date of birth or ID documents belong after an offer, and only through an official onboarding portal, never by email, chat or a screening form. If a request for personal data arrives, confirm it is genuine by contacting the recruiter through a phone number or address you already trust, not the one in the message. Candidates also report that recruiters and hiring managers match you to client needs from your resume, so be ready to explain your own contribution to every project on it.

Behavioral preparation centers on the client relationship. The reported example is how you respond when a client changes the requirements halfway through development, and the reported topics are stakeholder management and requirement gathering. Prepare two or three real stories where you clarified an ambiguous request, absorbed a change, or pushed back with a trade-off, each with what you did and what happened as a result.

01

Preparation focus

editorial

Candidates describe a progression that depends on the client and the opening. You typically begin with Akraya recruiters and technical screeners, who handle the first vetting. An AI-led assessment may appear early, and some loops include a coding assignment with a short turnaround. Candidates who advance may then interview with the client's team. Ask your recruiter which of these stages apply, whether coding is live or a take-home, and which language you may use. For the screening calls, expect to walk through your resume project by project. For the technical stages, prepare to explain your complexity reasoning aloud, to compare a linked list with an array for a stated scenario, to walk through debugging a production issue in a distributed system, and to describe how you keep code maintainable and testable. For the AI assessment, answer in a structured way from a quiet room.

What to demonstrate

  • Reported topics: Big O reasoning, memory use and the choice of data structure
  • Reported topics: code quality, meaning readable naming, modular structure and unit and integration tests
  • Reported topics: stakeholder management, clarifying requirements and handling a changed scope
  • Reported question: explaining your own contribution to each project on your resume

How to prepare

  • Message the recruiter for the stages that apply, whether coding is live or a take-home, and which language to use
  • Rehearse the five reported technical questions aloud, giving time and space cost with a one-sentence reason for each choice
  • Write a one-page sheet per resume project: your role, the stack, one trade-off you made and the outcome
  • Practise short structured answers aloud in a quiet room, since an AI-led assessment may come early
PracHub preparation framework ↗

PracHub editorial advice for the preparation topics above.

01

Quoting a Big O figure with no reason behind it

When asked about the complexity of your solution, name the dominant operation, give time and space separately, and say which alternative you rejected and why. For example, say that a hash set trades O(n) extra memory for lookups that avoid a nested loop.

02

Answering the question about optimizing a function for a larger data set with a trick before you know what larger means

Ask what grows: the number of records, record size, or call frequency. Find the dominant cost, then choose between a better algorithm, a better data structure, batching or caching. Say how you would measure before and after.

03

Reciting textbook linked list versus array facts without using the scenario

Ask what the scenario does most: random reads, appends, inserts or deletes in the middle, or iteration. Remember that O(1) linked list insertion needs a reference to the node, that arrays have better cache locality, and that linked list nodes carry pointer overhead.

04

Jumping to a fix when asked to walk through debugging a production issue in a distributed system

Follow a sequence: scope the impact, check what changed recently, mitigate first with a rollback or feature flag, then use logs, metrics and traces tied together by a request id to narrow the cause. Separate the mitigation from the root cause and name the follow-up.

05

Treating the recruiter call, the AI assessment or your own resume as a formality

Candidates report that recruiters act as your advocate and that AI-led assessments can come early. Prepare for both like a live interview, and be able to explain what you personally built on each project listed.

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

Can you describe the time complexity of your solution and why you chose this approach?

medium
Technical Proficiency and Coding

Can you describe the time complexity of your solution and why you chose this approach?

Approach
  1. Name the variables first, then give time and extra space separately: n elements, k distinct keys, m queries. For example, a hash-set pass for pair-sum is O(n) time and O(n) space, while sorting plus two pointers is O(n log n) time and needs only the sort's working memory.
  2. Derive the bound from the code, not from memory. Count the loop nesting and the cost of each call inside it. x in some_list in Python is O(n), so using it inside a loop makes the whole thing O(n^2). x in some_set is O(1) on average and O(n) in the worst case when hashes collide.
  3. Say which case you are quoting. A dynamic-array append is amortized O(1) because the capacity grows by a constant factor (Java's ArrayList grows about 1.5x, CPython's list about 1.125x), but one append can cost O(n). Quicksort averages O(n log n) and degrades to O(n^2) on bad pivots. Hash lookups are O(1) only on average.
  4. Justify the choice against the brute force with a number. With n = 10^5, an O(n^2) pair scan is about 10^10 steps and too slow, while O(n log n) is about 1.7 million. If n is tiny and fixed, say the simpler version is fine and why.
  5. Count the hidden costs. Slicing copies O(k) elements, repeated string concatenation can be O(n^2) in languages with immutable strings, and recursion adds O(depth) stack space, which can overflow on deep inputs.
Follow-up
  • Can you get extra space down to O(1), and what does that cost in time?
  • How does the bound change if the input arrives as a stream or is already sorted?
  • Where would the constant factor matter more than the big-O for this input size?

How would you optimize this function to handle a larger data set?

medium
Technical Proficiency and Coding

How would you optimize this function to handle a larger data set?

Approach
  1. Measure before changing anything. Profile the function (cProfile in Python, a JFR or async-profiler capture in Java) and time it at n and 2n. Time roughly doubling means linear; roughly quadrupling means quadratic, so look for a nested loop or a repeated scan.
  2. Fix the algorithm first. Replace repeated lookups in a list with a hash map or set, which turns O(n*m) into O(n + m). Sort once and binary-search instead of rescanning. Use prefix sums for repeated range totals, and memoize repeated subcalls.
  3. Bound memory once data outgrows RAM. Stream with iterators or generators instead of materialising lists, and process in fixed-size chunks. For top-k, keep a heap of size k: O(n log k) time, O(k) space. For a full ordering beyond memory, use an external merge sort.
  4. Fix I/O before you parallelise. Replace N+1 queries with one batched query, push filters into the database where an index can serve them, and cache results that do not change. Add parallelism only when partitions are independent. CPython threads do not speed up CPU-bound work because of the GIL, so use processes.
  5. Prove it is still correct. Keep the old version as a reference, compare outputs on random and edge-case inputs (empty, duplicates, maximum size), benchmark at the target size, and name the trade-off you accepted, such as more memory for less latency.
Follow-up
  • The data no longer fits on one machine. How do you partition it, and what happens to keys that span partitions?
  • If you could improve only one of memory or latency here, which would you pick and why?
  • How would you stop a later change from bringing the regression back?

What are the trade-offs between using a linked list versus an array in this specific scenario?

medium
Technical Proficiency and Coding

What are the trade-offs between using a linked list versus an array in this specific scenario?

Approach
  1. Access: an array reaches index i in O(1) because the address is computed. A linked list must walk i nodes, so it is O(n), and binary search on it gains nothing.
  2. Insert and delete: in a linked list these are O(1) once you hold the node (a singly linked list also needs the predecessor to delete), but finding the position is O(n). In an array, a middle insert or delete shifts elements in O(n). Appending to a dynamic array is amortized O(1), with an O(n) copy when it resizes.
  3. Memory and cache: an array is contiguous, so scans are cache- and prefetch-friendly. Each list node pays for one or two pointers (8 bytes each on a 64-bit system) plus its own allocation, and following pointers causes cache misses. That is why arrays often win in practice even with some middle inserts.
  4. Tie the answer to the scenario. Random access, sorting or binary search point to an array. A queue points to a ring buffer or deque. For O(1) move-to-front and eviction, as in an LRU cache, use a doubly linked list paired with a hash map. If references must stay valid while elements are inserted, use a list, because resizing a C++ vector invalidates its iterators.
  5. Cover the edge cases in code: an empty structure, updating head and tail when the first or last node changes, a single-element list, and the off-by-one when shifting array elements.
Follow-up
  • Implement an LRU cache with O(1) get and put. Which structures would you use?
  • Why can a vector beat a linked list on middle insertions in benchmarks, despite the worse big-O?
  • How would you detect a cycle in a linked list without extra memory?

How do you ensure your code is maintainable and testable for other team members?

medium
Technical Proficiency and Coding

How do you ensure your code is maintainable and testable for other team members?

Approach
  1. Separate logic from side effects. Keep the core computation in small pure functions, and pass the database client, HTTP client and clock in through constructors or parameters (dependency injection). Tests can then use fakes instead of real network calls or the system time.
  2. Test in layers. Write many fast unit tests on the logic, including the edge cases (empty input, null, boundary values, duplicates), and fewer integration tests at the database and API boundaries. Make tests deterministic with a fixed clock, seeded randomness and no shared state, and name each test after the behaviour it checks.
  3. Make the code readable without its author. Use names that state intent, functions that do one thing, and comments that explain why rather than what. Document public interfaces with their inputs, outputs and errors. Let a formatter and linter (Black and Ruff, ESLint, Checkstyle) settle style so reviews focus on design.
  4. Enforce it through the workflow. Keep pull requests small, run tests and lint in CI on every push before merge, and require review. Treat coverage as a way to spot untested branches, not a number to hit.
  5. Back it with one concrete example: a function with a hidden dependency (a direct database call or datetime.now()) that you refactored to take that dependency as a parameter, the test that became possible, and the bug it caught.
Follow-up
  • How do you test code that calls an external API you do not control?
  • How would you add tests to a legacy module that has none before changing it?
  • When is a mock the wrong tool, and what would you use instead?

The plan follows the reported topics in order: format and resume first, then complexity and optimization with a timed session on unseen problems, data-structure trade-offs, production debugging, maintainable code with Git habits and take-home scoping, client-facing stories, and a full dry run. PracHub practice questions on outages, deadlines and estimation support the later days.

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
01Confirm the format and inventory your resume
  • Write to your recruiter asking which stages apply (recruiter call, AI-led assessment, take-home, client interview), whether coding is live, and which language you may use.
  • For every project on your resume, write what you personally built, the stack, one trade-off you made and the result.
  • Write a short spoken summary of your background and what kind of client work you want.

Deliverable: A list of format questions sent to your recruiter, plus one project sheet per resume entry.

02Complexity and optimizing for larger data
  • Take three problems you have solved in Java, Python or C++. For each, write the brute-force version and an improved one, with time and space cost and a one-sentence reason for the choice.
  • Take a function with a nested loop, such as finding duplicates. Time it on a small input and one that is 100 times larger, then rewrite it with a hash set or a sort.
  • Run a timed session on two problems you have not seen, 25 minutes each, narrating your approach aloud as you code. When each is done, state its time and space cost and one trade-off.
  • Say your answers aloud as you would explain them to a client technical lead.

Deliverable: Three complexity statements with reasons, one before-and-after timing, and notes on how the two unseen problems went.

Practice prompt ↗Practice prompt ↗
03Linked list versus array, scenario by scenario
  • Implement a singly linked list (insert at head, delete by value, reverse) and use a dynamic array in the same language.
  • Measure traversal and middle insertion on a large input for both, and note the effect of memory layout.
  • Write a four-row table of scenarios (queue, random lookup, frequent head inserts, a cache with eviction) with the structure you would pick and the reason.

Deliverable: Benchmark numbers for both structures and the scenario table with a one-line justification per row.

Practice prompt ↗
04Debugging a production issue in a distributed system
  • Write a short debugging sequence: scope impact, check recent changes, mitigate, then use logs, metrics and traces correlated by request id to find the cause.
  • Walk through a scenario aloud, such as intermittent timeouts after a deploy across several services, and state what each check rules out.
  • Practise telling one real outage story using the PracHub outage practice question as a structure.

Deliverable: A one-page debugging checklist and a recorded spoken walkthrough of one scenario.

Practice prompt ↗Practice prompt ↗
05Maintainable, testable code, Git habits and take-home scoping
  • Take a messy function of thirty lines or more. Split it into small pure functions, inject its dependencies, and write unit tests for its edge cases plus one integration test.
  • Make that refactor on a branch as a sequence of small commits with clear messages. Be ready to explain how you would resolve a merge conflict, and how you would use git bisect to find the commit that introduced a regression.
  • Write a scope note for an imagined take-home: assumptions, what is in and out, and an estimate with its main unknowns.
  • Rehearse the explanation of why your changes make the code easier for a teammate to maintain.

Deliverable: The refactored function with its tests, a branch with a readable commit history, and a one-paragraph scope and estimate note.

Practice prompt ↗Practice prompt ↗
06Client-facing stories
  • Write a story for the reported prompt on a client changing requirements midway through development: what you clarified, what you traded off, how you communicated it, and the result.
  • Write a second story about conflicting feedback or requirements from two stakeholders and how you resolved it.
  • List five clarifying questions you would ask about an ambiguous requirement before starting work, and practise the deadline story from the PracHub practice set.

Deliverable: Two written stories and a list of five clarifying questions.

Practice prompt ↗
07Full dry run
  • Record yourself in a quiet room answering the five reported technical questions aloud in structured form.
  • Replay it and note any answer that lacked a stated reason, a trade-off or an edge case.
  • Run a final recruiter-call rehearsal: your background, your resume projects and the questions you would ask about the client role.

Deliverable: One full recording with self-review notes and a final list of questions for the recruiter.

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

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

Candidates report that the behavioral side of Akraya loops covers stakeholder management, such as handling conflicting requirements or feedback, and requirement gathering, such as clarifying expectations before a project starts. For a client-embedded role, build each story around what you asked, what you decided, how you told people, and what happened next.

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?

Narrate an outage you owned from page to postmortem

hard
incident responseblast radiuspostmortems

Pick an incident you personally drove, ideally one where writes were affected rather than reads. In six to eight minutes: state the symptom as it first appeared on a dashboard, the blast radius you established before you knew the cause, the mitigation you applied and when, the mechanism you eventually proved, and the follow-up that would prevent a repeat. Bring numbers: error rate, tenants affected, minutes to mitigate, minutes to resolve. If you cannot name what you measured, choose a different incident.

Approach
  1. Open on the signal rather than the cause: which metric at which percentile moved, on which service, at what time, so the listener follows the same evidence you had rather than a conclusion you already reached.
  2. Separate mitigation from diagnosis out loud. State what you did to stop the bleeding (flag off, shed traffic, drain a lease, roll back a deploy) and say plainly that you did it before the mechanism was known, because those are two jobs with different deadlines.
  3. Establish blast radius in countable terms: how many tenants, how many writes, and crucially whether the effect was loss or only delay. An append-only revision table or a pending outbox row means the change survived and the projection was merely behind, which is a repair rather than a data-loss incident.
  4. Prove the mechanism instead of asserting it. Name the trace span that grew, the plan that flipped to a sequential scan, the lease that expired, plus one alternative you ruled out and the signal that stayed flat while you ruled it out.
Follow-up
  • What would you do differently in the first five minutes, given the same dashboard and no more information?
  • Which follow-up action did you deliberately not take, and why was dropping it the right call?

Estimate work you have never done and defend the range

hard
estimationbackfillsexpand-contract

You are asked to estimate a change you have never attempted: add a column to a 100-million-row table, populate it, move reads across, and drop the old shape. Give a range with the assumptions that generate it, including batch size, the signal your backfill throttles on, and wall-clock hours, and name the three unknowns that would move the number most. Then describe a real estimate you gave under comparable ignorance: how you expressed its uncertainty, what you committed to, and how wrong you turned out to be.

Approach
  1. Decompose into independently deployable steps before estimating anything: add the column nullable, write both shapes, backfill in batches, verify, move reads, stop writing the old shape, drop it. That is four deploys spread over days, and the calendar estimate is dominated by them rather than by the loop's runtime.
  2. Do the arithmetic aloud for the part that has arithmetic in it: batch size times number of batches times per-batch duration, at a write rate the primary can absorb alongside roughly 1.2k writes per second of production traffic. The loop is throttled by replication lag and lock waits, not by how fast it can issue statements.
  3. Price the schema step by its lock rather than its statement duration. In PostgreSQL an ALTER TABLE taking ACCESS EXCLUSIVE waits for every open transaction on that table while later queries queue behind it, so a millisecond change issued during a thirty-second analytics query stalls that table for thirty seconds. Adding a nullable column with a non-volatile default avoids a rewrite from version 11; a new index wants CREATE INDEX CONCURRENTLY, which cannot run inside a transaction block and leaves an invalid index behind if it fails.
  4. Express the answer as a range whose endpoints each trace to a stated assumption, then name the cheapest experiment that collapses it, which is almost always running one real batch against the real table and multiplying.
Follow-up
  • How do you verify the backfill genuinely finished, given rows written by production traffic while it ran?
  • Where does the backfill resume from after a worker is killed mid-batch, and what makes that resume point trustworthy?
  • 01

    How do you respond when a client changes the project requirements halfway through development?

  • 02

    Describe a time two stakeholders gave you conflicting requirements or feedback, and how you resolved it.

  • 03

    Tell me about a project where the request was ambiguous. What did you ask before you started, and how did the answers change your plan?

  • 04

    Walk me through a project on your resume and say exactly which parts you built.

  • 05

    Describe a time you had a very short turnaround on an assignment. How did you scope it and what did you cut?

PracHub preparation framework ↗
How difficult are the technical interviews?

Candidates describe them as fairly straightforward, centered on computer science fundamentals and problem solving. Clear explanation of your logic is reported to matter more than clever tricks, so practise saying each answer aloud with its complexity, trade-off and edge cases.

Akraya Software Engineer candidate reports ↗
How long does the process take?

Candidates report a fast-paced process that often takes a few weeks, though it varies with how urgently the client is hiring. Confirm the stages and your availability with your recruiter early.

Akraya Software Engineer candidate reports ↗
Will I be interviewed by the client or by Akraya staff?

Both can be involved. The loop description above covers the reported order: Akraya's side comes first, and the client's team may follow if you advance. Ask your recruiter who will be on each call so you can prepare for the right audience.

Akraya Software Engineer candidate reports ↗
What is the AI-led assessment and how should I prepare?

Candidates report that an AI-led assessment can appear early in the process. Take it as seriously as a live interview: find a quiet space and practise giving structured answers to the five reported technical questions and the client-change question.

PracHub Software Engineer practice ↗
Will there be a take-home assignment?

Candidates mention coding assignments in some loops. A take-home may come with a deadline, so ask the recruiter how long you have before you commit. Before you start, write down the scope, your assumptions and an estimate, and ask about anything ambiguous.

PracHub Software Engineer practice ↗
Which languages and tools should I know?

The requirements candidates describe name at least one modern language, with Java, Python and C++ as examples, plus Git and data structures and algorithms. Cloud platforms (AWS, Azure, GCP), Docker, Kubernetes and CI/CD are reported as extras. Pick the language you are strongest in and make sure you can write tests in it, and practise working with Git in small, well-described commits.

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.