Skip to main content
Ai

MERN + Gen AI Engineer Interview Prep: 200 Deep Conceptual Questions (Node.js, Postgres, PostgreSQL & React) | Ahmed's Debug Diary

  MERN + Gen AI Engineer — Deep Conceptual Interview Prep 50 Questions Each: React | Node.js | PostgreSQL | AI/Agents 1. REACT — 50 Deep Conceptual Questions What is the Virtual DOM and why doe...

Tech Ahmed
July 11, 2026
43 min read
MERN + Gen AI Engineer Interview Prep: 200 Deep Conceptual Questions (Node.js, Postgres, PostgreSQL & React) | Ahmed's Debug Diary
Share:

 


MERN + Gen AI Engineer — Deep Conceptual Interview Prep

50 Questions Each: React | Node.js | PostgreSQL | AI/Agents


1. REACT — 50 Deep Conceptual Questions

  1. What is the Virtual DOM and why does it help performance? A lightweight JS representation of the real DOM. React diffs the new tree against the previous one (reconciliation) and only applies minimal real-DOM mutations, avoiding expensive full re-renders.

  2. Explain the Fiber architecture. Fiber is React's reconciliation engine (since React 16) that breaks rendering work into units, allowing React to pause, abort, reuse, or prioritize work — enabling concurrent rendering and time-slicing.

  3. What actually happens during "reconciliation"? React compares (diffs) old and new element trees level by level, using type + key to decide whether to update, replace, or unmount/remount a node.

  4. Why do list items need a stable key, and what breaks if you use array index? Keys let React match elements between renders. Using index as key causes incorrect state/DOM reuse when items are reordered, inserted, or removed — leading to stale UI or lost input state.

  5. How does useState preserve state across re-renders if the function component re-runs every time? State is stored outside the function component, in the Fiber node, tied to hook call order — not in the function's local scope.

  6. Why must hooks not be called conditionally? React matches hooks to state by call order, not by name. Conditional hooks shift the order across renders and corrupt state association.

  7. Explain the stale closure problem with useEffect/useCallback. A callback captures variables from the render it was created in. If dependencies aren't correctly listed, the callback keeps referencing outdated values even after state changes.

  8. Difference between useMemo and useCallback. useMemo memoizes a computed value; useCallback memoizes a function reference. useCallback(fn, deps) is equivalent to useMemo(() => fn, deps).

  9. When does useEffect run relative to paint? How is useLayoutEffect different? useEffect runs asynchronously after the browser paints. useLayoutEffect runs synchronously before paint — used when you need to measure/mutate the DOM before the user sees a flash.

  10. What is batching, and how did React 18 change it? Batching groups multiple setState calls into a single re-render. Before React 18, batching only happened inside React event handlers. React 18 introduced automatic batching everywhere — including promises, timeouts, and native event handlers.

  11. What problem does React.memo solve, and when can it backfire? It skips re-rendering a component if props are shallow-equal. It backfires when props are new object/array/function references每 render (common without useMemo/useCallback), making the memoization useless while adding comparison overhead.

  12. Explain Context API re-render behavior. Every component consuming a Context re-renders whenever the Provider's value changes — even if the consumer only cares about part of it. Split contexts or memoize the value to avoid unnecessary re-renders.

  13. Why is Context not a full replacement for Redux/Zustand? Context has no built-in mechanism for selective subscription, middleware, devtools, or performance optimization for high-frequency updates — it's a dependency injection tool, not a state manager.

  14. What are Server Components, and how do they differ from SSR? Server Components render on the server and send a serialized description (not HTML) to the client, with zero client-side JS for that component. SSR renders full HTML on the server but still hydrates/ships JS for interactivity.

  15. What is hydration, and what causes hydration mismatches? Hydration attaches event listeners/state to server-rendered HTML instead of re-rendering from scratch. Mismatches occur when server and client render different output (e.g., using Date.now(), window, or non-deterministic data).

  16. Controlled vs uncontrolled components — tradeoffs? Controlled: React state is the single source of truth (predictable, easier validation, more re-renders). Uncontrolled: DOM holds the value via refs (better perf for large forms, less code, harder to validate live).

  17. What are Error Boundaries, and what do they NOT catch? Class components implementing componentDidCatch/getDerivedStateFromError that catch render-time errors in children. They do not catch errors in event handlers, async code, SSR, or in the boundary itself.

  18. Explain code-splitting with React.lazy and Suspense. React.lazy dynamically imports a component, and Suspense shows a fallback UI until the chunk loads — reducing initial bundle size.

  19. What problem does Suspense for data fetching solve? It lets components "wait" for async data declaratively, without manual loading-state juggling, unifying the loading pattern for code and data.

  20. Explain the difference between useRef and useState for tracking values. useRef persists a mutable value across renders without triggering re-renders; useState persists a value and triggers a re-render when updated.

  21. How does React decide whether to unmount/remount vs update a component on a conditional render? If the element type changes at the same position in the tree, React unmounts the old subtree and mounts a new one, resetting state. Same type = update in place.

  22. What is Prop Drilling and how do you avoid it besides Context? Passing props through many intermediate components that don't need them. Alternatives: composition (passing children/render props), state management libraries, or colocating state closer to where it's used.

  23. Higher-Order Components vs custom Hooks — why did the ecosystem shift to hooks? HOCs wrap components (causing wrapper hell, prop naming collisions, harder debugging). Hooks share logic without adding component layers, are more composable, and keep code flatter.

  24. What is the Rules of Hooks and why do they exist (mechanically)? Hooks must be called at the top level, in the same order every render, and only from React functions — because React tracks hook state via a linked list matched to call order in that Fiber.

  25. Explain reconciliation's use of type and key together. React first compares element type. If types match, it reuses the DOM node and updates props/children. key is then used to match children of the same type inside lists.

  26. What is React's Concurrent Rendering and how does it differ from the old synchronous model? Concurrent rendering lets React interrupt, pause, or discard in-progress renders to prioritize urgent updates (like typing) over less urgent ones (like a large list re-render), improving perceived responsiveness.

  27. What is startTransition used for? Marks state updates as non-urgent so React can render them at low priority, keeping the UI responsive during expensive updates (e.g., filtering a large list while typing in a search box).

  28. Why can useEffect cause infinite loops, and how do you debug it? Usually because the effect updates state that's also in its dependency array without a stable reference (new object/array on every render). Debug by checking dependency identity, and use useMemo/useCallback to stabilize references.

  29. Explain React Portals and a real use case. Portals render children into a DOM node outside the parent hierarchy while preserving React's event bubbling. Common for modals, tooltips, and dropdowns that need to escape overflow:hidden containers.

  30. What is forwardRef and why is it needed? Function components don't receive ref as a normal prop by default. forwardRef lets a parent get a ref to an underlying DOM node or imperative handle inside a child component.

  31. What does useImperativeHandle do? Customizes the instance value exposed to parent components when using ref, letting you expose only specific methods instead of the whole DOM node.

  32. What is React Strict Mode actually doing under the hood? In development, it intentionally double-invokes certain functions (component body, some hooks, reducers) to surface side effects and impure rendering logic — no effect in production builds.

  33. CSR vs SSR vs SSG vs ISR — when would you pick each? CSR: highly interactive apps, SEO not critical. SSR: dynamic, SEO-sensitive content generated per request. SSG: static content known at build time (blogs, docs). ISR: static pages that need periodic regeneration without full rebuilds.

  34. How does React's diffing algorithm achieve O(n) instead of O(n³) tree diff? By using heuristics: comparing only same-level siblings (not cross-level), and using type+key to shortcut identity checks instead of doing a full tree edit-distance comparison.

  35. What's the difference between state colocated in a component vs lifted state? Colocated state stays local to where it's used (better performance, less re-render blast radius). Lifted state moves to a common ancestor when multiple children need to share/sync it.

  36. How do you prevent unnecessary re-renders in a large list? React.memo on list items, stable keys, virtualization (react-window/react-virtualized), and avoiding inline function/object props passed to each item.

  37. What is the "waterfall" problem in data fetching, and how does Suspense/React Query help? Sequential fetches (fetch A, then B depends on A) that could've run in parallel, delaying render. Prefetching, parallel queries, and Suspense-based fetching help avoid unnecessary sequential dependencies.

  38. Explain useReducer and when it's preferable to multiple useState calls. useReducer centralizes state transition logic via a pure reducer function — better for complex state with multiple sub-values or when the next state depends on the previous one in non-trivial ways.

  39. What's the difference between React.Fragment and returning an array? Fragments group children without adding extra DOM nodes and don't require keys (unless mapped). Returning an array requires explicit keys on each element.

  40. How do you handle race conditions in data fetching inside useEffect? Use a cleanup flag/AbortController: cancel or ignore the response if the effect re-runs (component unmounts or dependencies change) before the fetch resolves.

  41. What's the difference between shallow and deep comparison, and where does React use which? Shallow compares top-level references only (used in React.memo, PureComponent). Deep compares nested values recursively (not built into React by default — must implement manually or use libraries).

  42. Explain how React's event system (SyntheticEvent) differs from native DOM events. React uses a single delegated listener (attached at the root in React 17+) that normalizes events across browsers into SyntheticEvent objects, improving performance and consistency vs attaching listeners per node.

  43. What's a render prop pattern, and why is it less common now? A component takes a function as a prop to determine what to render, enabling logic sharing. Largely replaced by hooks, which achieve the same reuse without the nested "callback hell" render props can create.

  44. How would you test a component that uses hooks with side effects? Use React Testing Library — render the component, simulate user interaction, and assert on the resulting DOM/behavior rather than testing hook internals directly (test behavior, not implementation).

  45. What's the danger of using array/object literals directly as JSX props? They create a new reference on every render, breaking memoization (React.memo) for child components and potentially causing unnecessary re-renders or effect re-runs.

  46. How does React handle keys when you have nested lists (list of lists)? Each level's mapped elements need their own unique key within their own sibling list; keys don't need to be globally unique, only unique among siblings at that level.

  47. What is the significance of the children prop in composition patterns? It lets a parent component render arbitrary content passed by its caller, enabling flexible composition (e.g., layout components, modals, providers) without prop drilling specific content types.

  48. Explain double-rendering behavior with useState initializer functions vs direct values. useState(expensiveCompute()) runs the expensive function on every render even though only the first result matters. useState(() => expensiveCompute()) (lazy initializer) runs it only once.

  49. What's the tradeoff of deeply nested component trees for performance? Deeper trees mean more work during reconciliation traversal and increase the "blast radius" of state changes near the root, since re-renders propagate downward through all children unless memoized.

  50. How do you decide between local component state, Context, and a global store (Redux/Zustand)? Local state: isolated UI concerns. Context: low-frequency, broadly shared data (theme, auth). Global store: high-frequency updates, complex cross-cutting state, or when you need devtools/time-travel/middleware.


2. NODE.JS — 50 Deep Conceptual Questions

  1. Explain the Node.js Event Loop phases in order. Timers → Pending callbacks → Idle/prepare → Poll → Check (setImmediate) → Close callbacks — with microtasks (Promises, process.nextTick) flushed between each phase.

  2. Difference between process.nextTick() and setImmediate(). process.nextTick runs before the event loop continues to the next phase (highest priority microtask). setImmediate runs in the Check phase, after I/O callbacks in the current loop iteration.

  3. How is Node.js single-threaded yet capable of handling concurrent I/O? JS execution is single-threaded, but I/O operations are offloaded to the OS kernel (async I/O) or libuv's thread pool, with results delivered back to the event loop via callbacks.

  4. What is libuv and what role does it play? A C library providing the event loop, async I/O, thread pool (for fs, DNS, crypto, zlib), and cross-platform abstractions — the actual engine behind Node's async behavior.

  5. Explain microtasks vs macrotasks in Node's queue model. Microtasks (Promise callbacks, queueMicrotask) run immediately after the current operation, before the event loop proceeds. Macrotasks (setTimeout, setImmediate, I/O callbacks) run in their designated event loop phase.

  6. What is backpressure in Streams, and how do you handle it? When a writable stream can't consume data as fast as it's produced. write() returns false when the internal buffer is full — you should pause the readable stream until 'drain' fires, or use .pipe() which handles this automatically.

  7. Explain the four types of Node.js Streams. Readable (source of data), Writable (destination), Duplex (both, e.g., TCP sockets), Transform (duplex that modifies data, e.g., gzip).

  8. What's the difference between Buffer and String in Node.js? Buffer is a fixed-size raw binary data allocation outside the V8 heap; String is immutable UTF-16 encoded text. Buffers are used for binary/streaming data (files, network) before/without encoding to a string.

  9. How does the cluster module achieve scaling on multi-core machines? It forks multiple worker processes (each with its own event loop) sharing the same server port via the OS, letting the OS load-balance incoming connections across workers.

  10. Cluster vs Worker Threads — when do you use which? Cluster: scaling I/O-bound apps horizontally across CPU cores (each worker is a separate process, no shared memory). Worker Threads: CPU-bound tasks needing parallelism within one process, with optional shared memory via SharedArrayBuffer.

  11. How does Node.js handle uncaught exceptions vs unhandled promise rejections? uncaughtException fires for synchronous errors not caught anywhere; unhandledRejection fires for rejected Promises with no .catch(). Both should be logged, and the process should typically restart gracefully rather than continuing in an unknown state.

  12. CommonJS vs ES Modules — key runtime differences. CJS is synchronous, uses require/module.exports, resolved at runtime. ESM is asynchronous, static (import/export analyzed at parse time enabling tree-shaking), and top-level await is supported.

  13. What causes memory leaks in long-running Node servers? Common causes: global variable accumulation, unbounded caches, forgotten timers/intervals, event listeners not removed, closures retaining large objects, and unresolved Promises holding references.

  14. How does V8's garbage collector work (generational GC)? Objects start in the "young generation" (Scavenge, fast, frequent). Objects surviving multiple collections get promoted to the "old generation" (Mark-Sweep-Compact, slower, less frequent) — optimizing for the fact most objects die young.

  15. What is the difference between module.exports and exports? exports is a reference to module.exports. Reassigning exports = {...} breaks the reference (doesn't affect what's actually exported); you must mutate it or use module.exports = {...} directly.

  16. Explain middleware pattern in Express and how next() works. Middleware functions run sequentially in registration order, each receiving (req, res, next). Calling next() passes control to the next middleware; not calling it hangs the request; calling next(err) skips to error-handling middleware.

  17. How do you handle errors in async Express route handlers? Since Express doesn't natively catch rejected Promises in async handlers (pre-Express 5), wrap handlers in a try/catch or a helper (e.g., express-async-handler) that forwards errors to next(err).

  18. What's the difference between authentication via JWT and server-side sessions? JWT: stateless, self-contained token verified via signature, no server storage needed but harder to revoke. Sessions: server stores session state (in-memory/Redis/DB), referenced by a session ID cookie — easy to revoke, but requires shared storage for scaling.

  19. How do you scale WebSocket connections across multiple Node instances? Use a shared pub/sub layer (Redis adapter for Socket.io) so messages broadcast on one instance reach clients connected to other instances, since WebSocket connections are sticky to a single process.

  20. What is the N+1 query problem and how do ORMs solve it? Fetching a list, then querying related data per item in a loop (N extra queries). Solved via eager loading (include/join) or batching with a DataLoader pattern.

  21. Explain connection pooling and why it matters for database performance. Reusing a fixed set of open DB connections instead of opening/closing per request — avoids the overhead of TCP/auth handshake per query and prevents exhausting the DB's max connection limit under load.

  22. What is a race condition in async Node code, and give a practical example. When the outcome depends on timing of concurrent operations. E.g., two requests reading a counter, both incrementing based on a stale read, causing lost updates — mitigated with DB-level atomic operations or locks.

  23. How does async/await handle error propagation compared to raw Promises? await on a rejected Promise throws synchronously inside the async function, so standard try/catch works — cleaner than chaining .catch() on every .then().

  24. What is the thread pool size default in libuv, and how do you change it? Default is 4 threads, used for fs, DNS lookups (dns.lookup), crypto, and zlib. Configurable via the UV_THREADPOOL_SIZE environment variable.

  25. How do you prevent an Express app from crashing on a single bad request? Centralized error-handling middleware, input validation, try/catch around async logic, and process-level safety nets (though a true crash from unhandled exceptions should still restart the process via a process manager).

  26. Explain how require() caching works and its implications. Modules are cached by resolved file path after first load — subsequent require() calls return the same cached instance (singleton-like), so mutable state in a module persists across imports within a process.

  27. What is the difference between horizontal and vertical scaling for a Node API? Vertical: bigger machine (more CPU/RAM) for the same process. Horizontal: more instances/machines behind a load balancer — Node's single-threaded nature makes horizontal scaling (with cluster/containers) typically more effective.

  28. How would you implement rate limiting in a Node API? Token bucket or sliding window algorithm, often backed by Redis for distributed consistency (e.g., express-rate-limit with a Redis store) so limits apply across all instances, not per-process.

  29. What's the danger of blocking the event loop, and how do you detect it? A CPU-heavy synchronous operation (e.g., large JSON.parse, sync crypto, tight loops) blocks all other requests since there's one thread. Detect via event loop lag monitoring (perf_hooks, toobusy-js) or APM tools.

  30. Explain how environment-based configuration should be handled securely. Secrets via environment variables or a secrets manager (not committed to source), validated at startup (e.g., with zod/joi), and never logged or exposed in error responses.

  31. What's the purpose of helmet and cors middleware? helmet sets secure HTTP headers (CSP, HSTS, X-Frame-Options) to mitigate common attacks. cors controls which origins can make cross-origin requests to your API.

  32. How does Node.js handle child processes, and what are the main methods? spawn (streams data, good for large output), exec/execFile (buffers output, good for small commands), and fork (spawns a new Node process with an IPC channel for message passing) — each for different use cases.

  33. What's the difference between REST and GraphQL from a Node backend perspective? REST: multiple fixed endpoints, potential over/under-fetching. GraphQL: single endpoint, client specifies exact fields needed, but requires careful resolver design to avoid N+1 issues and enforce query complexity limits.

  34. How do you implement graceful shutdown in a Node server? Listen for SIGTERM/SIGINT, stop accepting new connections (server.close()), let in-flight requests finish, close DB/Redis connections, then exit — important for zero-downtime deploys in orchestrated environments (Kubernetes).

  35. What is idempotency and why does it matter for API design (e.g., payments)? An idempotent operation produces the same result no matter how many times it's called. Critical for retried requests (network failures) — implemented via idempotency keys stored server-side to detect duplicate submissions.

  36. How do Promises handle chaining errors across multiple .then() calls? An error/rejection at any point in the chain skips subsequent .then() handlers and jumps to the nearest .catch() — similar to exception propagation in synchronous code.

  37. What's the difference between process.env and a .env file? .env is just a file convention (loaded via dotenv) that populates process.env at startup; Node itself doesn't read .env natively — it's a developer convenience layer, not a runtime feature.

  38. Explain how to structure a Node app for testability (dependency injection). Decouple business logic from framework/db specifics by injecting dependencies (DB clients, external services) rather than importing them directly, enabling mocking in unit tests.

  39. What is a common caching strategy using Redis in a Node API, and what invalidation issues arise? Cache-aside: check Redis first, fall back to DB, populate cache on miss. Invalidation issues include stale reads after writes — mitigated with TTLs, write-through caching, or explicit invalidation on updates.

  40. How does Node handle DNS resolution differences (dns.lookup vs dns.resolve)? dns.lookup uses the OS resolver (via libuv thread pool, respects /etc/hosts). dns.resolve* queries DNS servers directly over the network (async, doesn't use thread pool), bypassing OS-level caching/hosts file.

  41. What's the purpose of a message queue (RabbitMQ/SQS/Kafka) in a Node microservices architecture? Decouples services, buffers load spikes, enables async processing and retries, and improves resilience since producers and consumers don't need to be online simultaneously.

  42. How would you debug a memory leak in production Node app? Take heap snapshots (--inspect, Chrome DevTools, or heapdump), compare snapshots over time to find growing retained objects, and check for common culprits like unbounded caches or listener leaks.

  43. What's the difference between Object.freeze and const regarding immutability? const prevents reassignment of the variable binding only. Object.freeze prevents mutation of the object's own properties (shallow) — you can still have a const object whose properties are mutable unless frozen.

  44. Explain how logging should differ between development and production Node apps. Dev: verbose, human-readable (console). Production: structured JSON logs (for aggregation via ELK/Datadog), appropriate log levels, and avoiding logging sensitive data (PII, secrets).

  45. What's the role of a reverse proxy (Nginx) in front of a Node app? Handles TLS termination, load balancing, static file serving, request buffering, and compression — offloading work Node isn't optimized for and adding a security layer.

  46. How does PM2 help manage Node processes in production? Process manager providing clustering, automatic restarts on crash, zero-downtime reloads, log management, and monitoring — without manually scripting process supervision.

  47. What is the difference between optimistic and pessimistic locking in a Node+DB context? Optimistic: assume no conflict, check a version/timestamp before committing, retry on conflict (better for low-contention). Pessimistic: lock the row/resource during the transaction, blocking others (better for high-contention, at the cost of throughput).

  48. How do you handle circular dependencies between Node modules? Node returns a partial (possibly incomplete) module.exports when a circular require is detected mid-load. Fix by restructuring (extract shared code to a third module) or deferring the require inside a function.

  49. What's the tradeoff between using an ORM (Prisma/Sequelize) vs raw SQL queries? ORM: faster development, type safety, migrations, less SQL injection risk. Raw SQL: full control over complex/optimized queries, less abstraction overhead — many teams use both (ORM for CRUD, raw SQL for reporting/complex joins).

  50. How would you design a health-check endpoint for a Node service in Kubernetes? Separate /liveness (is the process running/responsive) from /readiness (can it serve traffic — DB connected, dependencies healthy) so Kubernetes doesn't kill a pod that's just temporarily busy but restarts one that's truly stuck.


3. POSTGRESQL — 50 Deep Conceptual Questions

  1. Explain ACID properties with a practical example. Atomicity (all-or-nothing), Consistency (valid state transitions), Isolation (concurrent transactions don't interfere), Durability (committed data survives crashes) — e.g., a bank transfer debiting one account and crediting another must be all-or-nothing (atomicity) and survive a crash right after commit (durability).

  2. What is MVCC (Multi-Version Concurrency Control) and why does Postgres use it? Instead of locking rows for reads, Postgres keeps multiple versions of a row so readers see a consistent snapshot while writers create new versions — allowing high read concurrency without blocking.

  3. Explain the four transaction isolation levels and Postgres defaults. Read Uncommitted (not really implemented separately in PG), Read Committed (default — sees committed data as of each statement), Repeatable Read (consistent snapshot for the whole transaction), Serializable (strictest, prevents all anomalies via conflict detection).

  4. What is a "dirty read", "non-repeatable read", and "phantom read"? Dirty read: seeing uncommitted data from another transaction. Non-repeatable read: re-reading a row gives different data within the same transaction. Phantom read: re-running a query returns different rows (new inserts matching the filter).

  5. How does Postgres implement row versioning under MVCC (xmin/xmax)? Every row has hidden xmin (creating transaction ID) and xmax (deleting/updating transaction ID) columns. Updates create a new row version rather than overwriting in place; old versions are cleaned up by VACUUM.

  6. What is VACUUM, and why is it necessary? Reclaims space from dead row versions (left by updates/deletes under MVCC) and updates statistics for the query planner. Without regular vacuuming, table bloat grows and performance degrades.

  7. Difference between VACUUM, VACUUM FULL, and autovacuum. VACUUM: reclaims space for reuse without locking the table exclusively. VACUUM FULL: rewrites the entire table to reclaim space to the OS, requiring an exclusive lock (blocking). Autovacuum: background process automatically triggering VACUUM/ANALYZE based on thresholds.

  8. What's the difference between a B-tree, GIN, GiST, and Hash index? B-tree: default, good for equality/range queries and sorting. GIN: good for composite values like arrays, JSONB, full-text search (multiple values per row). GiST: good for geometric data, nearest-neighbor search. Hash: equality-only lookups, rarely preferred over B-tree.

  9. How do you read an EXPLAIN ANALYZE output to diagnose a slow query? Look for sequential scans on large tables (missing index), high "actual time" vs "estimated rows" mismatches (stale statistics), nested loop joins on large datasets, and sort/hash operations spilling to disk.

  10. What is the difference between a Nested Loop, Hash Join, and Merge Join? Nested Loop: good for small outer tables/indexed inner lookups. Hash Join: builds a hash table on one side, good for larger unsorted datasets without useful indexes. Merge Join: requires both inputs sorted, efficient for pre-sorted large datasets.

  11. Explain the difference between a VIEW and a MATERIALIZED VIEW. A VIEW is a stored query executed fresh every time it's referenced (always current, no storage). A MATERIALIZED VIEW stores the result physically, needing manual/scheduled REFRESH to stay up to date, but reads are much faster.

  12. What are Window Functions, and how do they differ from GROUP BY? Window functions (ROW_NUMBER(), RANK(), SUM() OVER(...)) compute values across a set of rows related to the current row without collapsing rows into groups, unlike GROUP BY which aggregates and reduces row count.

  13. Explain a recursive CTE and a real-world use case. A WITH RECURSIVE query that references itself to traverse hierarchical/graph data — e.g., building an org chart tree or category hierarchy from a self-referencing parent_id column.

  14. What is table partitioning, and when is it beneficial? Splitting one logical table into multiple physical tables (by range, list, or hash) so queries touching only recent/relevant partitions scan less data — beneficial for very large time-series or log tables.

  15. Difference between horizontal partitioning (sharding) and partitioning within a single Postgres instance. Native partitioning splits data within one Postgres server across child tables. Sharding distributes data across multiple separate database servers/instances, requiring application- or middleware-level routing logic.

  16. How does Postgres handle deadlocks? Postgres automatically detects deadlocks (via a wait-for graph check) and aborts one of the transactions with a deadlock_detected error, allowing the other to proceed.

  17. Explain optimistic locking implemented via a version column in Postgres. Each row has a version integer; updates include WHERE version = :expected and increment it — if no rows match (someone else updated first), the application detects the conflict and retries or fails gracefully.

  18. What's the difference between DELETE, TRUNCATE, and DROP? DELETE: row-by-row, logged, can be rolled back, triggers fire, WHERE clause supported. TRUNCATE: fast, deallocates pages directly, minimal logging, resets identity columns, can't filter rows. DROP: removes the entire table structure and data.

  19. What are foreign key constraints doing at the storage/enforcement level? Postgres checks referential integrity on insert/update/delete via triggers internally, ensuring a referenced row exists (or cascades/restricts per the defined ON DELETE/ON UPDATE behavior).

  20. Explain ON DELETE CASCADE vs ON DELETE SET NULL vs ON DELETE RESTRICT. CASCADE: deletes dependent rows automatically. SET NULL: sets the foreign key column to NULL on dependent rows. RESTRICT (default-like behavior): blocks the delete if dependent rows exist.

  21. What is normalization, and what problem does 3NF solve? Organizing data to reduce redundancy and avoid update/insert/delete anomalies. 3NF specifically removes transitive dependencies (non-key columns depending on other non-key columns) so facts are stored in exactly one place.

  22. When would you intentionally denormalize a schema? For read-heavy workloads where join costs are too expensive at scale — trading some redundancy/consistency risk for query performance (e.g., storing a computed total instead of always summing line items).

  23. What is the difference between a clustered and non-clustered index concept in Postgres (since PG doesn't have true clustered indexes by default)? Postgres tables are heap-organized by default (no inherent physical order). CLUSTER can physically reorder table rows to match an index once, but new inserts don't maintain that order automatically — unlike databases with true clustered indexes (e.g., SQL Server).

  24. Explain connection pooling tools like PgBouncer and why the app-level pool isn't always enough. PgBouncer sits between the app and Postgres, multiplexing many client connections onto fewer actual DB connections — critical because Postgres connections are relatively expensive (each spawns a backend process), and app-level pools alone don't help across multiple app instances.

  25. What is the JSONB type, and how does it differ from JSON? JSONB stores data in a decomposed binary format (allows indexing via GIN, faster to query, slightly slower to insert), while JSON stores an exact text copy (preserves whitespace/key order, faster to insert, no indexing without functional indexes).

  26. How does full-text search work in Postgres (tsvector/tsquery)? Text is converted to tsvector (normalized lexemes with position info), and searched against a tsquery. A GIN index on the tsvector column makes searches fast, supporting ranking, stemming, and stop-word removal.

  27. What is a composite index, and when does column order matter? An index on multiple columns together. Order matters because Postgres can efficiently use a leading prefix of the index (e.g., index on (a,b) helps queries filtering on a or a AND b, but not on b alone).

  28. Explain the difference between INNER JOIN, LEFT JOIN, and FULL OUTER JOIN. INNER: only matching rows from both tables. LEFT: all rows from the left table plus matches from the right (NULLs where no match). FULL OUTER: all rows from both tables, NULLs where no match on either side.

  29. What causes table bloat, and how do you monitor it? Frequent updates/deletes leave dead tuples that autovacuum hasn't cleaned yet, inflating table/index size on disk. Monitored via pg_stat_user_tables (dead tuple counts) or extensions like pgstattuple.

  30. What is the purpose of ANALYZE, separate from VACUUM? Updates the query planner's statistics (row counts, value distributions) so it can choose efficient query plans — stale statistics lead to poor plan choices even if data itself is fine.

  31. How do row-level locks differ from table-level locks in Postgres? Row-level locks (from UPDATE/SELECT FOR UPDATE) block concurrent modification of specific rows only, allowing high concurrency. Table-level locks (from DDL, LOCK TABLE) block broader operations and can significantly reduce concurrency.

  32. Explain SELECT FOR UPDATE and its use case. Locks selected rows against concurrent modification until the transaction commits/rolls back — used to safely read-then-update a value (e.g., decrementing inventory) without race conditions.

  33. What is the N+1 query problem from a database perspective, and how do indexes/joins fix it? Running one query to fetch a list, then one query per item for related data — instead, a single JOIN or WHERE id IN (...) query fetches everything at once, drastically reducing round trips.

  34. Explain logical replication vs streaming (physical) replication in Postgres. Physical replication copies WAL (write-ahead log) at the byte level to create an identical replica (used for HA/failover). Logical replication replicates specific tables/changes at the row level, allowing replication between different Postgres versions or selective table sync.

  35. What is the Write-Ahead Log (WAL), and why is it central to durability? Every change is first written to a sequential log before being applied to data files — if Postgres crashes, it replays the WAL on restart to recover to a consistent state, ensuring durability without requiring every write to hit the data files immediately.

  36. How does Postgres achieve high availability (HA)? Typically via streaming replication to standby servers, with tools like Patroni or repmgr managing automatic failover, plus WAL archiving for point-in-time recovery.

  37. What's the difference between a Primary Key and a Unique constraint? Primary Key: implies NOT NULL + uniqueness, only one per table, typically used for the row's identity and as the target of foreign keys. Unique: allows NULLs (multiple NULLs allowed unless otherwise restricted), can have multiple per table.

  38. Explain how EXPLAIN (ANALYZE, BUFFERS) helps diagnose I/O-bound query issues. Shows actual buffer hits vs reads from disk — a high number of disk reads (vs cache hits) indicates the working set doesn't fit in memory (shared_buffers), pointing to memory tuning or query optimization needs.

  39. What is a covering index, and how does it enable index-only scans? An index that includes all columns needed by a query (via INCLUDE or composite key), letting Postgres answer the query directly from the index without visiting the heap table — much faster.

  40. How would you design a schema for soft deletes, and what tradeoffs come with it? Add a deleted_at timestamp column instead of physically deleting rows; queries must filter WHERE deleted_at IS NULL. Tradeoffs: table grows unbounded, unique constraints get tricky (need partial indexes), and every query needs the filter (easy to forget).

  41. What is a partial index, and when would you use one? An index built only on rows matching a condition (e.g., WHERE deleted_at IS NULL) — smaller, faster, and specifically optimized for the common query pattern rather than indexing the entire table.

  42. Explain the difference between TEXT, VARCHAR(n), and CHAR(n) in Postgres. Functionally near-identical performance-wise in Postgres. VARCHAR(n) enforces a length limit, CHAR(n) pads with spaces to fixed length (rarely useful), TEXT is unlimited length — Postgres docs generally recommend TEXT unless a specific length constraint is meaningful.

  43. How does Postgres handle NULL in indexes, uniqueness, and comparisons? NULL is never equal to NULL in comparisons (NULL = NULL is unknown/false), multiple NULLs are allowed in a unique column (each treated as distinct), and B-tree indexes do store NULLs (retrievable via IS NULL queries).

  44. What's the purpose of database migrations, and what risks come with running them on a live production table? Migrations version-control schema changes. Risks: adding a NOT NULL column or index on a huge table can lock it for a long time — mitigated with CONCURRENTLY for index creation and multi-step migrations (add nullable, backfill, then add constraint).

  45. Explain CREATE INDEX CONCURRENTLY and why it matters in production. Builds an index without holding a long-lived exclusive lock that blocks writes, at the cost of taking longer and requiring two table scans — critical for adding indexes to large, actively-written production tables.

  46. What is a database transaction's "read your own writes" behavior mean in Read Committed isolation? Within the same transaction, you always see your own uncommitted changes, even though other transactions can't see them until commit — this is separate from cross-transaction visibility rules.

  47. How do you prevent SQL injection at the database/query layer regardless of ORM? Always use parameterized queries/prepared statements (never string-concatenate user input into SQL), which Postgres treats as data, not executable SQL syntax.

  48. What's the difference between COUNT(*), COUNT(1), and COUNT(column)? COUNT(*) and COUNT(1) are functionally identical (count all rows) and equally optimized by the planner. COUNT(column) counts only non-NULL values in that column — meaningfully different if NULLs are possible.

  49. How does Postgres query planning use statistics to choose Sequential Scan vs Index Scan? The planner estimates the cost of each based on table size, index selectivity, and cached statistics (from ANALYZE) — for queries returning a large percentage of rows, a sequential scan can actually be cheaper than random-access index lookups.

  50. What are common causes of "too many connections" errors, and how do you fix them structurally? Each app instance opening its own pool without limits, connection leaks (not releasing back to pool), or serverless functions each opening new connections — fixed via connection pooling (PgBouncer), lowering per-instance pool size, or using serverless-friendly drivers.


4. AI / AGENTS / GEN AI ENGINEERING — 50 Deep Conceptual Questions

  1. What is a token, and why does tokenization matter for cost/latency? A token is a sub-word unit (not always a full word) the model processes. Cost and context limits are measured in tokens, so tokenization efficiency directly affects both pricing and how much text fits in a context window.

  2. Explain the difference between embeddings and raw text for search. Embeddings are dense vector representations capturing semantic meaning, allowing similarity search ("meaning-close" matches) rather than exact keyword matching — enabling search that understands paraphrases and synonyms.

  3. What is RAG (Retrieval-Augmented Generation), and what problem does it solve? Combines a retrieval step (fetching relevant documents from a knowledge base) with generation, letting an LLM answer using up-to-date or private data it wasn't trained on — reducing hallucination and enabling grounded, citable answers.

  4. When would you choose fine-tuning over RAG, and vice versa? Fine-tuning: teaching a model a style, format, or behavior pattern consistently. RAG: injecting fresh or proprietary factual knowledge without retraining. Many production systems use RAG for facts and light fine-tuning/prompting for tone/format.

  5. What is chunking in a RAG pipeline, and why does chunk size matter? Splitting documents into smaller pieces before embedding/indexing. Too large: retrieval imprecise, wastes context. Too small: loses surrounding context needed for coherent answers. Overlapping chunks help preserve context across boundaries.

  6. Explain cosine similarity vs Euclidean distance for vector search. Cosine similarity measures the angle between vectors (direction, ignoring magnitude) — good for semantic similarity regardless of text length. Euclidean distance measures straight-line distance, sensitive to vector magnitude, often less ideal for normalized embeddings.

  7. What is an ANN (Approximate Nearest Neighbor) index like HNSW, and why not use exact search? Exact nearest-neighbor search is O(n) per query — too slow at scale. HNSW builds a graph-based index enabling sub-linear approximate search, trading a small accuracy loss for massive speed gains on millions of vectors.

  8. What is the context window, and what happens when you exceed it? The maximum number of tokens (input + output) a model can process in one call. Exceeding it truncates or errors out — requiring chunking, summarization, or retrieval strategies to fit relevant info within the limit.

  9. Explain hallucination and why RAG doesn't fully eliminate it. The model generating plausible-sounding but false/unsupported content. RAG reduces it by grounding answers in retrieved context, but the model can still misinterpret, over-generalize, or blend retrieved facts incorrectly — grounding isn't a guarantee.

  10. What is the difference between zero-shot, few-shot, and chain-of-thought prompting? Zero-shot: no examples, just instructions. Few-shot: a handful of examples included in the prompt to demonstrate the pattern. Chain-of-thought: explicitly prompting the model to reason step-by-step before answering, improving performance on multi-step problems.

  11. Explain function calling / tool use in LLMs at a mechanical level. The model is given tool schemas (name, description, parameters). Based on the prompt, it outputs a structured call (name + arguments) instead of free text; your code executes the actual function and feeds the result back into the conversation for the model to use.

  12. What is the ReAct pattern for agents? Interleaving Reasoning (thinking through the next step) and Acting (calling a tool), then observing the result and repeating — letting the model plan dynamically rather than in one shot.

  13. How does an agent decide which tool to call among several available? The model is given each tool's name, description, and parameter schema; it uses its own reasoning (guided by the system prompt and conversation context) to pick the best-matching tool based on the semantic fit to the current sub-task.

  14. What is "agentic memory", and what are the common types? Short-term/working memory (current conversation context), long-term memory (persisted facts/preferences across sessions, often in a vector store or key-value store), and episodic memory (past interaction summaries) — used to give agents continuity beyond a single context window.

  15. Explain the difference between a single-agent and multi-agent system. Single-agent: one model handles reasoning and tool use end-to-end. Multi-agent: specialized agents (e.g., planner, researcher, coder, critic) collaborate, each with a narrower role, often coordinated by an orchestrator agent.

  16. What is orchestration in an agentic system, and why is it needed? Managing the flow of control between multiple steps/agents/tools — deciding what runs next, handling errors/retries, and aggregating results — since raw LLM calls alone don't have built-in workflow control.

  17. What is prompt injection, and how do you mitigate it in an agent with tool access? Malicious content (in user input or retrieved documents) tricking the model into ignoring its instructions or taking unintended actions. Mitigations: input/output sanitization, strict tool permission scoping, human-in-the-loop for sensitive actions, and treating retrieved content as data, not instructions.

  18. What are guardrails in an LLM application, and where do they sit in the pipeline? Validation/filtering layers applied to input (blocking harmful prompts) and output (checking for PII leaks, toxic content, format compliance) — can be rule-based, classifier-based, or a second LLM call reviewing the first's output.

  19. Explain the tradeoff between temperature and top-p sampling. Temperature scales the probability distribution before sampling (higher = more random/creative). Top-p (nucleus sampling) restricts sampling to the smallest set of tokens whose cumulative probability exceeds p — both control randomness but via different mechanisms; they're often tuned together.

  20. What is structured output / JSON mode, and why is it useful for agents? Constraining the model's output to a defined schema (JSON) so downstream code can reliably parse it without brittle regex/string parsing — critical when an agent's output feeds directly into another system or tool call.

  21. How do you evaluate an LLM application beyond "it looks right"? Automated eval sets with golden answers (exact match, semantic similarity, or LLM-as-judge scoring), human review sampling, tracking hallucination rate, retrieval precision/recall (for RAG), and latency/cost metrics — ideally as a repeatable regression suite.

  22. What is "LLM-as-judge" evaluation, and what's a known weakness of it? Using another (often stronger) LLM to score outputs against a rubric. Weakness: it can be biased toward verbose, confident-sounding, or stylistically similar answers rather than truly correct ones, and can inherit the same blind spots as the model being judged.

  23. Explain semantic caching in an LLM application. Caching responses keyed by the semantic similarity of the query (via embeddings) rather than exact string match — so paraphrased but equivalent queries can reuse a cached answer, cutting cost and latency.

  24. What is the difference between a vector database and a traditional relational database for this use case? Vector DBs (Pinecone, Weaviate, pgvector) are optimized for high-dimensional similarity search (ANN indexing) rather than exact-match/relational queries — many production systems use both together (metadata in relational tables, embeddings in a vector index, sometimes combined via pgvector in Postgres itself).

  25. How would you reduce hallucination in a RAG system beyond just retrieving more documents? Improve retrieval quality (better chunking/embeddings), add citation requirements forcing the model to ground claims in retrieved text, use a smaller/stricter system prompt scope, and add a post-hoc verification step (e.g., a second pass checking claims against sources).

  26. What is the "lost in the middle" problem with long context windows? LLMs tend to attend less reliably to information placed in the middle of a very long context compared to the beginning or end — meaning simply stuffing more retrieved documents into context doesn't guarantee the model will use the most relevant ones effectively.

  27. Explain the difference between MCP (Model Context Protocol) and traditional function calling. Function calling defines tools per-application, tightly coupled to that app's code. MCP standardizes how models/agents discover and connect to external tools/data sources via a common protocol, so the same tool server can be reused across different agent clients/apps.

  28. What's the difference between a planning agent and a reactive agent? A planning agent generates a multi-step plan upfront (then executes, possibly re-planning on failure). A reactive agent decides the next single action based only on the current state/observation, without an explicit upfront plan — simpler but can be less efficient for complex multi-step tasks.

  29. How do you handle tool call failures gracefully in an agent loop? Catch errors and feed them back to the model as an observation (so it can retry with corrected arguments or try a different tool), set a max retry/step limit to avoid infinite loops, and fall back to a human-in-the-loop or graceful failure message.

  30. What is self-reflection / self-critique in agent design? Having the model (or a separate critic call) evaluate its own intermediate output against the goal before finalizing — catching errors or incomplete reasoning before the result is returned to the user or acted upon.

  31. Explain the cost/latency tradeoff of using a large vs small model in an agent pipeline. Larger models: better reasoning, fewer errors on complex tasks, but slower and more expensive per call. Smaller models: cheaper/faster, good for simple sub-tasks (routing, extraction) — many production systems mix model sizes based on task complexity ("model routing").

  32. What is prompt caching, and how does it reduce cost in multi-turn agent conversations? Reusing the computed key-value cache for a repeated prefix (e.g., a long system prompt or tool schema that doesn't change between calls), so the model doesn't reprocess identical tokens from scratch each turn — cutting latency and cost on long conversations.

  33. How would you design an agent to safely execute code (e.g., a coding agent)? Sandbox execution (isolated container/VM, no network or restricted network), resource/time limits, explicit allow-lists for file system access, and never executing agent-generated code with elevated system privileges.

  34. What's the difference between LangChain, LlamaIndex, and building agent logic from scratch? LangChain: general-purpose framework for chains/agents/tool orchestration. LlamaIndex: focused heavily on data ingestion/indexing for RAG. From scratch: more control and fewer abstraction leaks/debugging headaches, often preferred once you understand the underlying patterns well, at the cost of more boilerplate.

  35. Explain LangGraph's approach to agent state vs a simple linear chain. LangGraph models agent workflows as a graph with explicit state passed between nodes (allowing branches, loops, and cycles), rather than a fixed linear sequence — better suited for agents that need to loop, retry, or conditionally branch based on intermediate results.

  36. What is the "context rot" or context window degradation problem in long agent runs? As an agent's conversation/context grows very long (many tool calls, retrieved documents), relevant early instructions or facts can get diluted or "forgotten" in practice, degrading output quality — mitigated via periodic summarization or context pruning.

  37. How do you decide the right chunk overlap strategy for RAG documents? Balance between redundancy (too much overlap wastes storage/retrieval slots) and context loss (too little overlap cuts sentences/ideas at chunk boundaries) — commonly 10-20% overlap, tuned based on document structure (e.g., preserving whole paragraphs/sections).

  38. What's the difference between dense retrieval and hybrid search (dense + BM25/keyword)? Dense retrieval uses embeddings for semantic similarity but can miss exact terms (product codes, names). Hybrid search combines it with traditional keyword/BM25 scoring, often giving better precision for queries with specific literal terms alongside semantic ones.

  39. How would you implement guardrails against an agent taking a destructive action (e.g., deleting data)? Explicit allow-lists of permitted actions/tools, requiring human confirmation for irreversible operations, dry-run/preview modes, and audit logging of every tool call the agent makes.

  40. What is the role of a system prompt in agent behavior, and what are its limits? Sets persistent instructions/persona/constraints for the model across the conversation. Limits: it's not a hard security boundary (can potentially be overridden by sufficiently crafted user/injected input), so critical restrictions should also be enforced at the application/tool-permission layer, not the prompt alone.

  41. Explain streaming responses and why they matter for perceived latency in agent UIs. Tokens are sent to the client as they're generated rather than waiting for the full response — dramatically improves perceived responsiveness even though total generation time is similar.

  42. What's the difference between an embedding model and a generative (chat) model, and can you reuse one API key/model for both purposes? Embedding models output a fixed-size numeric vector representing meaning (used for search/similarity); generative models produce text/tokens autoregressively. They're typically separate models optimized for different objectives, though some providers offer both under one API.

  43. How would you handle multi-turn conversation memory in an agent without blowing the context window? Summarize older turns periodically, retrieve only relevant past turns via embedding similarity (rather than including the full history), or use a rolling window combined with persisted long-term memory in a separate store.

  44. What's the difference between "grounding" and "citation" in a RAG-based answer? Grounding means the answer's claims are actually derived from retrieved content (reducing hallucination). Citation means explicitly showing the user which source supports which claim — you can have grounding without citation, but citation without true grounding is misleading (fabricated citations).

  45. Explain the concept of tool schema design and why vague descriptions hurt agent performance. The model selects and calls tools based on their name/description/parameter docs — vague or overlapping descriptions cause the model to pick the wrong tool or pass malformed arguments; clear, distinct, example-rich schemas materially improve agent reliability.

  46. What is a common failure mode of agents doing multi-step tasks (compounding errors)? Small reasoning or retrieval errors early in a multi-step chain compound as later steps build on a flawed intermediate result — mitigated with verification/checkpoint steps and the ability to backtrack or re-plan rather than blindly proceeding.

  47. How do you handle rate limits and retries when calling an LLM API in production? Exponential backoff with jitter on 429/5xx errors, request queuing, and possibly a fallback to a secondary model/provider — while being careful not to silently retry non-idempotent side-effecting tool calls.

  48. What's the difference between evaluating retrieval quality vs generation quality in a RAG system? Retrieval quality: are the right documents being fetched (precision/recall against a labeled set). Generation quality: given good retrieval, is the model's answer accurate, complete, and well-grounded — these need to be evaluated and debugged separately since a bad answer can stem from either stage.

  49. Explain the concept of "least privilege" as applied to agent tool permissions. Give an agent only the specific tools/scopes it needs for its task (e.g., read-only DB access instead of full write access) so a reasoning error or prompt injection has limited blast radius rather than full system access.

  50. How would you architect a production agent system for observability/debugging? Log every prompt, tool call, arguments, and response (tracing per conversation/session ID), track latency and token usage per step, use a tracing tool (e.g., LangSmith or a custom structured logger), and version-control prompts/tool schemas so regressions are traceable to specific changes.


Suggested Study Approach

  • Day 1-2: React + Node.js (these overlap heavily in MERN interviews — expect combined questions like "how does SSR work with Express + React?")
  • Day 3: PostgreSQL — practice writing EXPLAIN ANALYZE on a few real queries against a local DB, not just reading answers
  • Day 4: AI/Agents — be ready to walk through a RAG or agent architecture on a whiteboard/verbally end-to-end
  • Day 5: Mock interview — pick 10 random questions from each section and answer out loud, timing yourself to ~90 seconds per question

Good luck this week — this positions you well alongside the portfolio and assessments you've already put in.

Second Heading

  • Unordered lists, and:
    1. One
    2. Two
    3. Three
  • More

Blockquote

And bold, italics, and even italics and later bold. Even strikethrough. A link to somewhere.

And code highlighting:

var foo = 'bar';

function baz(s) {
   return foo + ':' + s;
}

Or inline code like var foo = 'bar';.

Or an image of bears

bears

The end ...

Tech Ahmed

Tech Ahmed

Related Articles