Use this guide to prepare for Backend Engineer interviews, with a focus on node.js, express, nestjs. Explain your reasoning and connect it to experience you can substantiate.
These preparation themes come from the questions in this role’s bank. They help you organise your examples; individual employers may assess different things.
Node.js
Express
NestJS
Java
Framework selection
Spring Boot
A useful preparation sequence
Choose your experience level and the round you expect.
Answer one question in your own words before opening its guide.
Compare your reasoning, evidence and trade-offs; adapt the answer to your experience.
Practise the follow-up, then revisit one answer you want to improve.
Representative questions and answer guidance
Open any question to read its answer. The complete guidance is included on this page.
Technical · Mid-level
1. Why can a CPU-heavy loop slow unrelated requests in Node.js?
Answer guide
Node runs your JavaScript on a single main thread with one event loop. A tight loop, large JSON parse or heavy hashing keeps that thread busy, so callbacks for other requests wait even though their I/O has finished, and everyone sees latency spikes. Diagnose it by measuring event-loop delay and taking a CPU profile. Fixes include worker threads or a separate service, chunking work so the loop can breathe, or asynchronous versions of blocking calls. Node shines at I/O concurrency, so long CPU jobs do not belong in the request path.
What this question explores
Understanding of Node's single-threaded event loop and practical ways to find and avoid blocking it.
Common mistakes
Believing Node handles CPU-heavy work on many threads automatically.
Adding more async keywords to a CPU-bound function and expecting it to stop blocking.
Practise a follow-up
How would you measure event-loop lag in a running Node service?
When would you use worker threads and when a separate process or queue?
2. How would you structure error handling in an Express API?
Answer guide
Keep route handlers thin: validate input first, then let failures flow to one central error-handling middleware registered last, which decides the status code and response shape. Never send stack traces or internal details to clients; log them with a request ID instead. Remember that asynchronous errors must reach next, and in older versions a rejected promise in an async handler may not be caught automatically, so wrap handlers or check your version. Keep the format the same across endpoints.
What this question explores
Ability to design consistent, safe API error handling rather than scattered try/catch blocks.
Common mistakes
Sending raw error messages or stack traces back to the client.
Handling errors differently in each route so clients get inconsistent status codes and bodies.
Practise a follow-up
How do you make sure a rejected promise in an async handler reaches your error middleware?
What information would you log for an unexpected error, and what would you keep from the client?
3. What is the purpose of a NestJS provider and module boundary?
Answer guide
A provider is a class or value that Nest can create and inject, such as a service or repository, which keeps business logic out of controllers and easy to replace in tests. A module groups related providers and controllers and decides what it exposes to others through exports, so other modules cannot reach into its internals. Together they give clear boundaries and testable code, in the same way as layers in a larger system. Provider scope also matters, since request-scoped providers add cost. I would keep exports small and mock providers in unit tests.
What this question explores
Understanding of dependency injection and module boundaries as a way to keep a NestJS codebase modular and testable.
Common mistakes
Putting business logic in controllers instead of injectable providers.
Making one giant shared module that exports everything, removing real boundaries.
Practise a follow-up
How would you resolve a circular dependency between two Nest modules?
What is the difference between a singleton and a request-scoped provider in Nest?
4. How would a Java service enforce idempotency for a payment request after an HTTP timeout?
Answer guide
The client generates a unique operation key for each payment intent and sends it with every attempt. The service inserts a row for that key under a uniqueness constraint before calling the payment provider, and stores the final outcome against it. A retry finds the existing row and returns the stored result, or waits if the first attempt is still running. If the provider call times out and the result is unknown, I would mark it pending and reconcile by querying the provider with the same key, not charge again. Provider-side idempotency keys add a second safety net.
What this question explores
Whether you can design payment retries with stored keys, uniqueness constraints and reconciliation of unknown outcomes instead of hoping timeouts are rare.
Common mistakes
Checking whether a payment exists and then inserting it, which races when two retries arrive together.
Retrying the provider call after a timeout without knowing whether the first charge went through.
Practise a follow-up
What if the downstream charge succeeded before your transaction committed?
5. How would you decide whether your organisation should standardise on FastAPI versus Django or Flask for new services?
Answer guide
I would start from the needs: type of workloads, team skills, hiring pool, and expected lifespan. FastAPI suits API first services, async input and output heavy workloads and strong typed contracts with generated documentation. Django offers a mature admin, ORM, authentication and conventions, which saves time for data heavy business applications. Flask suits small, flexible services. I would run a time boxed pilot on a real service, compare delivery speed, performance and operability, and assess ecosystem maturity and long term maintenance. Standardising reduces cognitive load, but forcing one tool everywhere is costly, so I would set a default with a clear exception process.
What this question explores
Whether you can make technology choices based on evidence, team capability and total cost rather than trends.
Common mistakes
Choosing a framework because it is popular without piloting it on a real workload.
Mandating one framework for all cases, ignoring workloads where another fits better.
6. Where should a transaction boundary sit in a Spring service?
Answer guide
The boundary belongs around one business operation that must succeed or fail as a unit, which is usually a public service method, rather than on repositories or controllers. Annotating the service method means all its database changes commit together and roll back on failure. Keep it short: do not call slow external services or wait on users inside a transaction, because that holds locks and connections. Read-only transactions help for queries. I would confirm behaviour with an integration test that forces a failure halfway.
What this question explores
Whether you can place transaction boundaries sensibly and know Spring's proxy and rollback pitfalls.
Common mistakes
Placing transactions on every repository method so one business operation is split across several.
Not knowing that self-invocation bypasses the proxy or that checked exceptions do not roll back by default.
Practise a follow-up
Why might a transactional method called from another method in the same class not start a transaction?
What isolation or propagation setting would you change, and in which situation?
7. How do select_related and prefetch_related reduce Django's N+1 query problem?
Answer guide
The N+1 problem happens when you load a list of objects with one query and then trigger one extra query per object to read a related record, giving N+1 queries in total. For a single-valued relation such as a foreign key, select_related fetches the related row in the same query with a join. For collections and many-to-many relations, prefetch_related runs one extra query for all parents and joins the results in Python. I would look at the query count with Django Debug Toolbar or assertNumQueries, and compare timings before and after.
What this question explores
Knowing how Django's ORM causes extra queries and which tool suits which relationship.
Common mistakes
Using prefetch_related or select_related everywhere without checking what the page really needs.
Not knowing the difference between a SQL join and a separate batched query.
Practise a follow-up
How would you detect N+1 queries in a Django view automatically during tests?
When does a prefetch fetch too much data, and what would you use instead?
8. What is the role of a Flask application context?
Answer guide
Flask uses contexts so code can reach things like current_app, g and, during a request, request without passing them around explicitly. The g object is a per-context scratch space, commonly used for a database connection during one request, and it is cleaned up when the context ends. A frequent error is using current_app or g in a background thread or at import time, where no context exists, which raises the familiar 'working outside of application context' error. Use app.app_context in scripts and tests, and pass real objects to threads.
What this question explores
Basic understanding of why Flask has contexts and where code can and cannot rely on them.
Common mistakes
Using current_app or g at import time or in a separate thread and being surprised by the context error.
Treating g as global storage shared between requests.
Practise a follow-up
What is the difference between the application context and the request context?
How do you run code that needs the app outside a request, for example in a script?
9. What does dependency injection give an ASP.NET Core API?
Answer guide
Dependency injection lets classes ask for the services they need through their constructor instead of creating them, so construction is centralised in the container and usage stays simple. This makes code easier to test, since you can replace a real email service with a fake, and easier to change. Each registration has a lifetime: singleton is one instance for the whole app, scoped is one per request, and transient is a new one every time. Choose the shortest lifetime that works, and turn on scope validation in development.
What this question explores
Understanding of DI and service lifetimes, including the captive dependency mistake.
Common mistakes
Registering a stateful or scoped service as a singleton and sharing it across requests.
Treating the container as a service locator and resolving services manually inside methods.
Practise a follow-up
Why is injecting a scoped service into a singleton a problem, and how do you avoid it?
How would you replace a real dependency with a fake in an integration test?
10. How can a GraphQL resolver create an N+1 problem?
Answer guide
In GraphQL each field has its own resolver. If the parent query returns fifty orders and the customer field resolver runs a database call for each order, you get one query for the list plus fifty for customers, which is the N+1 pattern, and nested fields multiply it. Also limit query depth and cost so clients cannot ask for deeply nested data, and watch out for cross-user cache leaks by creating loaders per request. Trade-off: batching adds a small delay and code. Confirm the fix by counting database calls for a nested query in a test.
What this question explores
Whether you can recognise the per-field resolver cost and know batching and request-scoped caching as fixes.
Common mistakes
Fixing it only by adding a database index, which does not reduce the number of queries.
Creating a loader as a global singleton, so cached data leaks between users or requests.
Practise a follow-up
Why should a batching loader be created per request rather than once for the application?
How would you protect a GraphQL API from very deep or expensive queries?
A request is safe to retry when repeating it produces the same final state as running it once, which is called being idempotent. GET, PUT and DELETE are meant to be idempotent, while POST usually is not, so a retried payment POST could charge twice. The rule depends on how the server is built, not only on the verb. Retries should use backoff with jitter and a limit, and only for errors that are likely temporary, such as timeouts or 503. A network timeout is especially risky because the client does not know whether the first request succeeded.
What this question explores
Understanding of idempotency and how to make retries safe for write operations.
Common mistakes
Saying every POST is safe to retry, or that HTTP verbs alone guarantee idempotency.
Retrying immediately and endlessly without backoff or limits.
Practise a follow-up
How would a server implement idempotency keys for a payment endpoint?
Which HTTP status codes would you treat as retryable, and which not?
12. When would you use a ServiceNow Business Rule versus Flow Designer?
Answer guide
A Business Rule runs on the server when a record is inserted, updated, deleted or queried, and it fits narrow logic where timing matters, such as before a save to validate or set a field, or after it to react. For simple field defaults or validation, a Business Rule is lighter; for orchestration across tasks and teams, a flow is easier to maintain. Watch for two automations updating the same record and triggering each other in a loop, and note that hidden scripts are harder to audit. I would pick by who maintains it and how visible the logic must be.
What this question explores
Judgement in choosing the right ServiceNow automation tool for the job and awareness of maintenance and conflict risks.
Common mistakes
Putting long multi-step processes into scattered Business Rules that nobody can follow.
Building both a flow and a Business Rule on the same trigger without checking for loops or conflicts.
Practise a follow-up
What is the difference between a before and an after Business Rule?
How would you stop two automations from repeatedly updating the same record?
Choose one answer containing an example or practical sequence. Explain what you would actually do, what you would check and when you would ask for help. Keep claims about your experience honest.
For technical or regulated work, check current documentation and applicable local requirements alongside this practice material.