Skip to main content

Forward-deployed engineer technical fundamentals interview questions

10 questions on technical fundamentals for forward-deployed engineer candidates. Expect prompts such as “HTTP status codes for common API scenarios” and “INNER vs LEFT vs FULL OUTER JOIN behavior”, each with a worked answer outline and the follow-ups interviewers push on.

Questions

Showing 1 to 10 of 10 technical fundamentals questions.

As asked

What is the correct HTTP status code for each of these: a resource that does not exist, a successful resource creation, a request with a valid format but invalid business logic, and a server error whose cause is unknown?

Sample answer outline

404 for resource not found, 201 for successful creation (with Location header), 422 Unprocessable Entity for syntactically valid but semantically invalid requests (some teams use 400; either is defensible with a reason), and 500 for unknown server error. Strong candidates distinguish 400 (bad input format) from 422 (valid format but fails business validation), and know that 200 on a creation is technically wrong even if widely used.

Expect these follow-ups

  • When would you use 409 Conflict versus 422 Unprocessable Entity?
httpapi-designfundamentalsrest

As asked

Your platform stores all customers in one table and their integration event logs in another. You need a report that lists every customer, their total event count for the past 30 days, and flags customers with zero events as potentially churned. A colleague wrote an INNER JOIN query and is confused why churned customers are missing. What is wrong, which join type fixes it, and how does the join behave differently when a customer has no matching rows?

Sample answer outline

INNER JOIN returns only rows with a match in both tables (90 customers with 200 orders, potentially multiple rows per customer). LEFT JOIN returns all customers including the 10 with no orders (NULLs in order columns). FULL OUTER JOIN returns all rows from both tables with NULLs where there is no match. Choose LEFT JOIN for a report that must show all customers regardless of whether they have orders, e.g., to find customers with zero orders.

Expect these follow-ups

  • How do you count the number of customers who have placed zero orders, using a LEFT JOIN?
sqljoinsfundamentalsdatabasesreporting

As asked

What is async/await syntactic sugar for, and what happens to an unhandled rejection in each of these: a floating Promise (no await, no .catch), and an async function called without await?

Sample answer outline

async/await is syntactic sugar over Promises, making async code read synchronously. A floating promise with no .catch and no await results in an unhandled promise rejection. In Node.js 14 and earlier this was a warning; from Node.js 15 onward the process exits with a non-zero code by default (the same behavior as --unhandled-rejections=throw in earlier versions). An async function called without await returns a Promise that the caller ignores; any rejection inside it is also unhandled. Strong candidates note that async functions always return a Promise and that errors thrown inside them reject that Promise.

Expect these follow-ups

  • How does Promise.allSettled differ from Promise.all in terms of error handling?
javascriptasyncpromisesfundamentalsnodejs

As asked

You are writing an integration that, in response to an inbound webhook, creates a record in your platform's database and then calls an external billing API to charge the customer. Explain why the sequence matters, what happens if the billing call succeeds but the DB write then fails (or vice versa), and what mechanism you would use to keep both systems consistent.

Sample answer outline

Without a transaction, a crash or error between the two statements leaves the database in an inconsistent state: the order exists but inventory was never deducted, or vice versa. A transaction guarantees atomicity (both succeed or both roll back), consistency (constraints checked at commit), isolation (concurrent transactions don't see each other's partial writes), and durability (once committed, the write survives a crash). Strong candidates also note the isolation level matters: READ COMMITTED prevents dirty reads but not non-repeatable reads.

Expect these follow-ups

  • What is a SELECT FOR UPDATE used for, and why would you use it inside this transaction?
databasestransactionsacidpostgresfundamentals

As asked

You have a Postgres table with 50 million rows. Explain when you would choose a B-tree index, a GIN index, and a partial index, and give a concrete example use case for each.

Sample answer outline

B-tree: the default, for equality and range queries on columns like id, created_at, or email. GIN: for full-text search (tsvector), JSONB containment queries (@>), or array overlap (&&). Partial index: when only a subset of rows is queried, e.g., CREATE INDEX ON orders(customer_id) WHERE status = 'pending'; the index is smaller and faster because it only covers pending orders. Strong candidates also mention that indexes add write overhead and should only be created where they are actually used.

Expect these follow-ups

  • What is a covering index, and when is it worth using?
postgresindexesdatabasesfundamentalsperformance

As asked

A customer wants to build a custom analytics dashboard that queries many different combinations of your data. They ask whether they should use your REST API or your GraphQL API. Walk me through the tradeoffs.

Sample answer outline

REST is simpler to cache (HTTP caching at the URL level), easier to understand for less experienced developers, and has predictable response shapes. GraphQL lets the client specify exactly what fields it needs (avoiding over-fetching), compose data from multiple resources in one request, and iterate quickly without new endpoints. For a dashboard with many variable queries, GraphQL reduces both the number of requests and the response payload size. Downsides of GraphQL: N+1 query risk, harder to cache, more complex to implement securely.

Expect these follow-ups

  • How would you handle authentication and rate limiting differently between REST and GraphQL endpoints?
api-designrestgraphqlfundamentalstradeoffs

As asked

A customer complains that their integration is fetching stale data from your API even after you pushed an update. You suspect a caching issue. Explain Cache-Control, ETag, and how you would diagnose which layer is caching the stale response.

Sample answer outline

Cache-Control: max-age=300 tells any cache (browser, CDN, or proxy) to reuse the response for 5 minutes without revalidating. ETag is a validator: the server returns an opaque token with the response; the client sends If-None-Match on the next request and gets 304 Not Modified if unchanged. Diagnosis: check the Cache-Control header in the live response (curl -I), check if a CDN is in front (X-Cache hit headers), and compare the response age header vs. when the update was published.

Expect these follow-ups

  • When would you set Cache-Control: no-store versus no-cache?
httpcachingapi-designfundamentalsdebugging

As asked

Your schema stores arbitrary customer metadata in a Postgres column. Should it be JSON or JSONB? What are the actual differences, and when does the choice matter?

Sample answer outline

JSONB is stored as a binary decomposed format: it deduplicates keys, does not preserve key order or whitespace, and supports GIN indexing for fast containment and key-existence queries. JSON is stored as plain text and preserves exact input (including key order and duplicate keys). For almost all use cases, JSONB is the right choice because it supports indexing and operators (@>, ?, etc.). JSON is only preferable if you need to preserve exact text encoding or audit the raw input.

Expect these follow-ups

  • How do you index a specific nested key inside a JSONB column, and what is the query that would use that index?
postgresjsonjsonbdatabasesfundamentals

As asked

A customer asks whether they should use OAuth2 or an API key to authenticate their integration with your platform. What are the concrete tradeoffs, and which do you recommend for each scenario?

Sample answer outline

API keys: simple, long-lived, easy to implement, good for server-to-server where the key can be kept secret. Downside: no user-level scope, hard to rotate without disrupting the integration. OAuth2: grants scoped, revocable tokens on behalf of a specific user or org, short-lived access tokens with refresh tokens, industry standard for third-party access. Use OAuth2 when the integration acts on behalf of a user (their data), API keys when it is a machine-to-machine system integration.

Expect these follow-ups

  • What is the risk of issuing a long-lived OAuth2 access token instead of using short-lived tokens with refresh?
authenticationoauth2api-keyssecurityfundamentals

As asked

A bug only appears in production, not in staging, and the code is identical. What are the most common reasons for staging/production divergence, and how do you structure environments to minimize this?

Sample answer outline

Common causes: staging uses a different (smaller) dataset that doesn't trigger the edge case; environment variables or config differ (connection pool size, timeouts, feature flags); staging uses a different version of a third-party API sandbox that behaves differently from live; infrastructure differences (single node vs. multi-node, different PostgreSQL version). Reduce divergence by: using production-like data volumes in staging (anonymized), infrastructure-as-code so both use the same config, and running smoke tests against production after each deploy rather than trusting staging exclusively.

Expect these follow-ups

  • How do you safely use production-like data in staging without violating GDPR?
devopsenvironmentsstagingfundamentalsdebugging