Skip to content
tezvyn:

⚙️Backend Dev

Backend engineering, APIs, and databases

265 bites

Test yourself: Top 30 intermediate Backend Dev concepts questionsMultiple choice, with the correct answer and why it is correct on every question. Free, no sign-in.

Intermediate concepts in Backend Dev, page 3

Promise .catch(): Handling Rejections
intermediate2 min read

Promise .catch(): Handling Rejections

.catch() is the try...catch for promises, intercepting errors (rejections) in a chain. Use it at the end of a promise chain to handle failures from preceding steps, like a failed API call. The footgun: placing it mid-chain can swallow errors.

intermediate2 min read

Node.js util.promisify: From Callbacks to Promises

util.promisify converts callback-based functions into Promise-based ones, letting you use async/await with older Node.js APIs. It's a bridge for legacy code following the standard (err, value) callback pattern. The footgun: it fails on non-standard signatures.

intermediate2 min read

Rust Slices (&[T]): Views Without Ownership

A Rust slice is a borrowed view into a contiguous sequence of data, like an array or Vec, without taking ownership. Use it to write functions that operate on parts of a collection efficiently. The footgun: a slice cannot outlive the data it points to.

intermediate2 min read

Two-Phase Locking (2PL): Preventing Database Race Conditions

2PL is a database's pessimistic strategy for safe concurrency. A transaction acquires all necessary locks before releasing any, ensuring operations don't clash. It's used to guarantee consistency.

Nested Pydantic Models: Composing Complex Data
intermediate2 min read

Nested Pydantic Models: Composing Complex Data

Use a Pydantic model as a field type inside another to build complex, nested structures. This is essential for modeling JSON with sub-objects, like a user with an address.

Async/Await: Write Non-Blocking Code That Reads Synchronously
intermediate2 min read

Async/Await: Write Non-Blocking Code That Reads Synchronously

async/await lets you write non-blocking code that reads like simple, synchronous logic. It's used for network requests or database queries without freezing your app. The biggest footgun is using await inside a function you forgot to declare as async.

intermediate2 min read

Rust's Two String Types: String vs. &str

Think of String as an owned, growable text buffer on the heap, while &str is a borrowed, fixed-size view into string data. This distinction is key to Rust's memory safety. Functions often take &str to flexibly accept both types.

Database Deadlock: The Two-Way Standoff
intermediate2 min read

Database Deadlock: The Two-Way Standoff

A deadlock is a 'Mexican standoff' where two transactions can't finish because each is waiting for a resource the other has locked. This happens in systems with concurrent writes. The database will kill one transaction, forcing your app to handle the retry.

Pydantic's Data Coercion: From Raw Data to Python Types
intermediate2 min read

Pydantic's Data Coercion: From Raw Data to Python Types

Pydantic automatically converts raw data, like strings from a JSON request, into the Python types you declare. It's how FastAPI turns a JSON body into a typed Python object.

intermediate2 min read

Rust Enums: Attaching Data Directly to Variants

A Rust enum variant can carry its own data, acting like a mini-struct. This is perfect for modeling states with different payloads, like a Result that holds either a value or an error. The footgun is using a separate struct to pair an enum with.

MVCC: Read and Write Data Without Blocking Each Other
intermediate2 min read

MVCC: Read and Write Data Without Blocking Each Other

MVCC avoids slow, traditional locks by giving each transaction its own consistent data snapshot. This allows readers and writers to work at the same time without blocking each other, boosting performance in databases like PostgreSQL.

Pydantic: Configuring Models with `model_config`
intermediate2 min read

Pydantic: Configuring Models with `model_config`

Think of model_config as the settings panel for your Pydantic models, letting you change validation rules like string length or immutability. Use it to enforce global constraints or make models immutable. The footgun is using the old class Config: from V1.

Promise.all(): Wait for Multiple Promises at Once
intermediate2 min read

Promise.all(): Wait for Multiple Promises at Once

Promise.all() runs multiple promises in parallel, resolving only when all have succeeded. It's for when you need data from several API endpoints to render a single component.

intermediate2 min read

Strict Two-Phase Locking (S2PL): Safety Over Speed

Strict Two-Phase Locking (S2PL) forces a transaction to hold all its locks until it fully commits or aborts. This prevents cascading aborts in databases but at the cost of concurrency, as other transactions are blocked for longer periods.

intermediate2 min read

The Query Optimizer: Your Database's Internal GPS

A query optimizer is your database's internal GPS, turning your SQL "what" into the fastest "how." It chooses the best execution plan—like join order or index usage—for every query. The footgun: stale statistics can trick it into picking a slow route.

intermediate2 min read

Rust Item Visibility: Private by Default

In Rust, all items are private by default. Think of modules as locked rooms; you need the pub keyword to unlock the door. This is crucial for creating a public API or letting modules interact.

intermediate2 min read

FastAPI: Use UploadFile for Efficient File Uploads

FastAPI handles file uploads as 'form data', giving you a streamable UploadFile object instead of a raw byte blob. Use this for endpoints like image or document submissions. The footgun is reading large files into memory instead of streaming them.

intermediate2 min read

path.join() vs. path.resolve(): Concatenation vs. Calculation

path.join() glues path segments together, while path.resolve() calculates an absolute path. Think string building vs. cd commands. Use join for relative paths and resolve for absolute ones.

intermediate2 min read

Composite Indexes: One Index for Multiple Columns

A composite index is like a phone book sorted by last name, then first name. It's for queries filtering on multiple columns, like finding a specific person. The footgun is creating separate indexes, which is far less efficient than a single composite one.

intermediate2 min read

Rust Methods: Attaching Behavior to Data

Rust methods are functions attached to your data structures, defined in an impl block. Instead of do_thing(my_struct), you call my_struct.do_thing(). The key footgun: instance.name() calls a method, but instance.name accesses a field.

We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.

See open roles