Software Engineering Fundamentals

How a click becomes a rendered page — networking, HTTP, backend architecture, and auth. Written at junior-dev / interview level.

1 · How machines find and talk to each other

Before any HTTP happens, two computers must (a) locate each other and (b) open a reliable channel. That's what the network stack does.

The layers you're expected to know

LayerJobUnitExamples
ApplicationWhat the data meansMessageHTTP, DNS, SMTP, WebSocket, gRPC
TransportDeliver to the right process, reliably or notSegmentTCP, UDP, QUIC
NetworkRoute across networks to the right machinePacketIP, ICMP, BGP
LinkMove bits to the next hop on the wireFrameEthernet, Wi‑Fi, ARP
Mental model: IP gets the envelope to the building. TCP makes sure every page arrives, in order, and to the right apartment (the port). HTTP is the language written inside the letter.

Addressing: IP, ports, DNS

IP address

Identifies a machine/interface. 142.250.72.14 (IPv4) or 2607:f8b0::200e (IPv6). Private ranges like 10.x, 192.168.x are LAN-only and get translated by NAT.

Port

16-bit number identifying a process on that machine. 80 HTTP, 443 HTTPS, 22 SSH, 5432 Postgres. An IP + port pair is a socket.

DNS

The phone book: turns api.example.com into an IP. Runs on UDP/53 (TCP for big answers). Answers are cached per the record's TTL.

What a DNS lookup actually does

Browser cachealready know it?
OS cache / hostsstub resolver
Recursive resolverISP, 1.1.1.1, 8.8.8.8
Root → TLD → Authoritative. → .com → example.com

Record types worth knowing: A IPv4 · AAAA IPv6 · CNAME alias · MX mail · TXT verification/SPF · NS nameservers.

TCP vs UDP

TCP — connection-oriented

  • 3-way handshake: SYNSYN-ACKACK
  • Guarantees delivery + ordering (sequence numbers, ACKs, retransmits)
  • Flow control + congestion control
  • Costs one full round trip before any data moves
  • Used by: HTTP/1.1 & /2, SSH, SMTP, databases

UDP — fire and forget

  • No handshake, no ordering, no retransmit
  • Tiny header, minimal latency
  • App must handle loss itself if it cares
  • Used by: DNS, video/voice, gaming, QUIC → HTTP/3

TLS: how HTTPS gets secure

TLS sits between TCP and HTTP. After the TCP handshake, the TLS handshake:

  1. ClientHello — supported TLS versions, cipher suites, SNI (which hostname), key share.
  2. ServerHello + Certificate — chosen cipher, the server's X.509 cert chain, its key share.
  3. Verify — client checks the cert chains up to a trusted CA, isn't expired, and matches the hostname.
  4. Derive keys — both sides compute the same symmetric session key (ECDHE) without ever sending it. This gives forward secrecy.
  5. Finished — everything after this is encrypted with fast symmetric crypto (AES-GCM/ChaCha20).

TLS 1.3 needs 1 round trip (0-RTT on resumption); TLS 1.2 needed 2. TLS gives you three things: confidentiality (encrypted), integrity (tamper-evident), and authenticity (you're talking to the real server).

Interview trap: HTTPS encrypts the URL path, headers, and body — but not the destination IP or the hostname in SNI (unless Encrypted Client Hello is used). An observer sees that you visited a site, not what you did there.

2 · What happens when you hit Enter on a URL

This is the single most common systems interview question. Click each step.

1
Parse the URLBreak it into its pieces
https://api.example.com:443/v1/users/42?fields=name#bio
└scheme┘   └──── host ────┘ └port┘└── path ──┘└── query ──┘└frag┘
  • scheme → which protocol + default port (https→443)
  • host → what to resolve via DNS
  • path + query → sent to the server
  • fragment (#bio) → never sent to the server; browser-only

The browser also checks its HSTS list and may upgrade http:// to https:// before doing anything.

2
Resolve DNSHostname → IP address

Browser cache → OS cache → recursive resolver → root/TLD/authoritative. Result is cached for the record's TTL. Big sites return an IP near you via GeoDNS / anycast so you hit a nearby CDN edge.

3
Open a TCP connectionThree-way handshake
client ──── SYN ────────▶ server
client ◀─── SYN-ACK ──── server
client ──── ACK ───────▶ server   (connection established)

One full round trip. This is why latency (RTT) matters more than bandwidth for page load, and why connections are kept alive and reused.

4
TLS handshakeNegotiate encryption (HTTPS only)

ClientHello → ServerHello + certificate → validate chain → derive session keys. ALPN inside the handshake also decides whether you'll speak HTTP/1.1 or HTTP/2.

5
Send the HTTP requestMethod, path, headers, maybe a body
GET /v1/users/42 HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0 ...
Accept: application/json
Authorization: Bearer eyJhbGciOi...
Cookie: session=abc123
(blank line ends headers; body would follow)
6
The request crosses the infrastructureCDN → LB → app server
CDN edgestatic? serve now
Load balancerpick a healthy server
App serverroute → middleware → handler
Cache / DBRedis, Postgres

Inside the app: routing matches the path → middleware runs (auth, logging, rate limiting, body parsing) → the handler executes business logic → it reads/writes the database → it serializes a response.

7
Server sends the responseStatus line, headers, body
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 74
Cache-Control: private, max-age=60
ETag: "a3f9c1"

{"id":42,"name":"Ada Lovelace","email":"ada@example.com"}
8
Browser rendersParse → DOM/CSSOM → layout → paint
HTML → DOMtokenize + parse
CSS → CSSOMrender-blocking
Layoutcompute geometry
Paint + Compositepixels on screen

Sub-resources (CSS, JS, images, fonts) each trigger their own request — often reusing the same connection. Synchronous <script> blocks parsing; defer/async don't.

Say it in one breath: parse URL → DNS → TCP → TLS → HTTP request → CDN/LB → app server → DB → response → parse & render. Then mention caching happens at every layer.

3 · HTTP essentials

HTTP is a stateless, text-based request/response protocol. Stateless means the server remembers nothing between requests — that's why cookies and tokens exist.

Methods

MethodPurposeSafe?Idempotent?Body?
GETRead a resourceYesYesNo
POSTCreate / trigger an actionNoNoYes
PUTReplace a resource wholesaleNoYesYes
PATCHPartial updateNoNot necessarilyYes
DELETERemove a resourceNoYesOptional
HEADLike GET, headers onlyYesYesNo
OPTIONSAsk what's allowed (CORS preflight)YesYesNo

Safe = doesn't change state. Idempotent = doing it 5 times leaves the same state as doing it once. This is why a retried PUT is fine but a retried POST may double-charge a card — hence idempotency keys.

Status codes — click one

Pick a status code above.

The classes: 1xx informational · 2xx success · 3xx redirect · 4xx you messed up · 5xx the server messed up.

Headers that matter

Request headers

  • Host — which site (required in 1.1; enables virtual hosting)
  • Accept — formats the client wants
  • AuthorizationBearer <token> or Basic ...
  • Cookie — stored cookies for this origin
  • Content-Type — what the body is
  • If-None-Match — conditional GET using an ETag
  • Origin / Referer — where the request came from

Response headers

  • Content-Type — e.g. application/json
  • Cache-Controlno-store, max-age=3600, private
  • ETag / Last-Modified — validators for caching
  • Set-Cookie — create/update a cookie
  • Location — where a 3xx points
  • Access-Control-Allow-Origin — CORS
  • Strict-Transport-Security — force HTTPS (HSTS)

Caching, concretely

# First request
GET /logo.png            →  200 OK
                              Cache-Control: max-age=86400
                              ETag: "v3"

# Within 24h: no request at all — served from local cache

# After expiry: revalidate cheaply
GET /logo.png
If-None-Match: "v3"       →  304 Not Modified  (no body, tiny)

Cookies

Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=1209600

REST in one screen

GET    /users          list
POST   /users          create        → 201 + Location: /users/42
GET    /users/42       read          → 200 or 404
PUT    /users/42       full replace
PATCH  /users/42       partial update
DELETE /users/42       remove        → 204
GET    /users/42/posts nested resource

Principles: nouns not verbs, plural collections, statelessness, correct status codes, use the query string for filtering/sorting/pagination (?page=2&limit=20&sort=-created_at).

HTTP versions

VersionTransportKey change
HTTP/1.1TCPText; keep-alive; head-of-line blocking — one slow response stalls the connection, so browsers open ~6 per origin
HTTP/2TCP + TLSBinary framing, multiplexed streams on one connection, header compression (HPACK), server push (now deprecated)
HTTP/3QUIC over UDPRemoves TCP-level head-of-line blocking, 0/1-RTT handshake, connection survives network switches (Wi-Fi→cellular)

When request/response isn't enough

Polling

Client asks every N seconds. Simple, wasteful, laggy.

SSE

text/event-stream. One-way server→client push over plain HTTP. Great for feeds and notifications.

WebSocket

HTTP Upgrade → persistent full-duplex socket. Chat, live collaboration, games.

4 · Backend architecture

The standard shape of a web system

Clientbrowser, mobile
DNS + CDNedge cache, TLS termination
Load balancerhealth checks, routing
App serversstateless, N replicas
CacheRedis / Memcached
·
Databaseprimary + read replicas
·
Queue + workersKafka, SQS, Celery
·
Object storageS3 for files

Each piece, and why it exists

Load balancer

Spreads traffic across replicas (round-robin, least-connections, hash). Removes unhealthy instances. Often terminates TLS. Gives you horizontal scaling and zero-downtime deploys.

Stateless app servers

No per-user state in memory — session data lives in Redis or a signed token. That's what makes any server able to handle any request, and lets you add/remove instances freely.

Cache

Repeated reads are the bulk of traffic. Cache-aside is the common pattern: check Redis → miss → query DB → write to Redis with a TTL. The hard part is invalidation.

Queue + workers

Anything slow (email, video encode, report generation) is pushed to a queue so the request returns fast. Buys you retries, backpressure, and smoothing of traffic spikes.

CDN

Copies of static assets in hundreds of cities. Cuts latency (physics — distance costs milliseconds) and offloads origin traffic.

Database replicas

Writes go to the primary; reads fan out to replicas. Replication lag means a read right after a write may be stale — eventual consistency.

Scaling: vertical vs horizontal

Vertical (scale up)Horizontal (scale out)
HowBigger machineMore machines
LimitHardware ceilingEffectively none
ComplexityLow — no code changeHigher — needs statelessness, LB, distributed data
FailureSingle point of failureRedundant by design

SQL vs NoSQL

Relational (Postgres, MySQL)

Fixed schema, joins, ACID transactions, strong consistency. Default choice for anything with relationships and correctness requirements — money, orders, users.

ACID = Atomicity, Consistency, Isolation, Durability

Non-relational (Mongo, DynamoDB, Cassandra)

Flexible documents or wide columns, easy horizontal partitioning, often eventual consistency. Good for huge volume, denormalized reads, unstructured or rapidly-changing shapes.

Indexes: the single highest-leverage database concept. An index is a B-tree that turns an O(n) table scan into O(log n) — at the cost of extra storage and slower writes. "Why is this query slow?" almost always ends in EXPLAIN and a missing index.

CAP theorem

When a network Partition happens, a distributed system must choose:

Since partitions will happen, in practice CAP is a choice between consistency and availability.

Monolith vs microservices

Monolith

One deployable. Simple to run, test, and reason about; in-process calls; single transaction boundary. Downside: one codebase, coupled deploys, whole-app scaling.

Microservices

Independent deploys, per-service scaling, team autonomy, tech diversity. Cost: network calls that fail, distributed transactions, tracing/observability burden, operational overhead.

The expected answer: start with a well-modularized monolith; extract services when a specific team, scaling, or reliability boundary demands it. Microservices trade code complexity for operational complexity.

Reliability vocabulary

5 · Authentication, authorization, and security

Authentication = who are you. Authorization = what are you allowed to do. Different problems; don't conflate them (401 vs 403).

Sessions vs JWTs

Server sessionsJWT (stateless tokens)
Where state livesServer (Redis/DB); client holds an opaque IDIn the token itself, signed
RevocationInstant — delete the rowHard — valid until expiry unless you keep a denylist
ScalingNeeds a shared session storeNo lookup; any server can verify
Best forClassic web apps, anything needing instant logoutAPIs, mobile, service-to-service
// A JWT is three base64url parts joined by dots:
header.payload.signature

{"alg":"HS256","typ":"JWT"}                // header
{"sub":"42","role":"admin","exp":1790000000} // payload — readable by anyone!
HMACSHA256(base64(header)+"."+base64(payload), secret) // signature
Critical: a JWT payload is encoded, not encrypted. Anyone can read it. The signature only proves it wasn't tampered with. Never put secrets in it. Also: always pin the expected alg server-side — accepting alg: none or a swapped algorithm is a classic vulnerability.

Common pattern: short-lived access token (5–15 min) + long-lived refresh token stored in an HttpOnly cookie, rotated on each use.

OAuth 2.0 + OIDC ("Sign in with Google")

1. Redirectapp → Google with client_id, scope, state
2. Consentuser logs in at Google, approves
3. Coderedirect back with a one-time code
4. Exchangebackend swaps code for tokens

Key points: the app never sees the user's Google password. OAuth 2.0 = authorization (delegated access to an API); OpenID Connect layers authentication on top by adding an id_token (a JWT describing the user). Public clients (SPAs, mobile) must use PKCE. The state parameter prevents CSRF on the callback.

Password storage

Attacks you should be able to name

SQL injection

User input concatenated into a query. Fix: parameterized queries / prepared statements. Never string-build SQL.

// bad
"SELECT * FROM u WHERE id=" + id
// good
"SELECT * FROM u WHERE id=$1", [id]

XSS (cross-site scripting)

Attacker-supplied script runs in another user's page. Fix: escape on output, use a templating engine that escapes by default, set a Content-Security-Policy, mark cookies HttpOnly.

CSRF

A malicious site makes the browser send an authenticated request to yours using its cookies. Fix: SameSite cookies, anti-CSRF tokens, check Origin.

IDOR / broken access control

/orders/1002 returns someone else's order. Fix: authorize every object access server-side. The #1 item on the OWASP Top 10.

MITM

Traffic intercepted in transit. Fix: HTTPS everywhere, HSTS, valid certs, no mixed content.

Secrets in source

API keys committed to git. Fix: env vars, a secrets manager, rotation, and pre-commit scanning.

CORS — why the browser blocks your fetch

The same-origin policy stops JavaScript on a.com from reading responses from b.com. An origin = scheme + host + port; all three must match. CORS is the server's way of opting in:

# Browser preflight for a non-simple request
OPTIONS /api/data
Origin: https://app.example.com
Access-Control-Request-Method: PUT

# Server permits it
204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, PUT, POST
Access-Control-Allow-Credentials: true
Two things people get wrong: (1) CORS is enforced by the browser, not the server — curl and your backend ignore it entirely, so it is not a security control for your API. (2) The request often does reach your server; the browser just refuses to hand the response to your JS.

6 · Check yourself

Nine questions covering the material. Click an answer.

Score

0 / 9 answered