Interview Patterns — Cheat Sheet
Computer Networks · 5 topics. Download the PDF or the Instagram carousel and share it.
What Happens When You Type a URL
The classic interview question: typing "https://google.com" triggers a precise sequence spanning DNS resolution, TCP connection, TLS handshake, HTTP request, server processing, and browser rendering — touching nearly every layer of the network stack.
- ✓The full sequence: HSTS check → DNS resolve → TCP handshake → TLS handshake → HTTP request → server process → browser render.
- ✓DNS adds latency only on cache miss; TTL controls how long results are cached at each level.
- ✓TCP + TLS 1.3 cost 2 RTTs total for a new connection; HTTP Keep-Alive and multiplexing (HTTP/2) amortise this across requests.
- ✓CDN cache hit skips origin entirely — serves from edge in ~5ms vs 100ms+ to distant origin.
- ✓Browser rendering is blocked by CSS (CSSOM) and synchronous JS — async/defer and preload hints are critical for performance.
// URL parsed into components: // https://www.google.com/search?q=aicancode // └──┬──┘ └──────┬──────┘└──┬──┘└────┬────┘ // scheme host path query // HSTS Preload List check (browser-internal): // Is "google.com" in chrome://net-internals/#hsts ? // YES → force HTTPS regardless of typed scheme // This check happens BEFORE any DNS or TCP — pure in-browser // Default port resolution: // https → 443, http → 80, ftp → 21 // Explicit override: https://example.com:8443/path
TCP Connection Lifecycle
The full TCP connection lifecycle — establishment (3-way handshake), data transfer with sequence numbers and acknowledgements, flow control, and graceful teardown (4-way FIN handshake) — underpins every reliable network communication.
- ✓The 3-way handshake exchanges random ISNs in both directions — randomisation prevents TCP sequence number prediction attacks.
- ✓SACK (Selective Acknowledgement) allows the sender to retransmit only lost segments, not everything from the loss point forward.
- ✓TIME_WAIT (2×MSL ≈ 60s) on the active closer prevents late duplicate segments contaminating a new connection on the same 4-tuple.
- ✓CLOSE_WAIT accumulation on a server indicates the application is not calling close() after the remote side closes — a common bug.
- ✓HTTP Keep-Alive and HTTP/2 multiplexing reduce the TCP handshake tax by reusing connections across multiple requests.
// 3-Way Handshake: // // Client (10.0.0.1:54321) Server (10.0.0.2:443) // │ │ // │── SYN ──────────────────────────▶│ seq=1000, ack=0 // │ "I want to connect, │ Client: SYN_SENT // │ my ISN is 1000" │ Server: LISTEN → SYN_RCVD // │ │ // │◀─ SYN-ACK ───────────────────────│ seq=5000, ack=1001 // │ "OK, my ISN is 5000, │ (ack = client ISN + 1) // │ I received your SYN" │ // │ │ // │── ACK ──────────────────────────▶│ seq=1001, ack=5001 // │ "Got it, connection open" │ Both: ESTABLISHED // // Why random ISNs? // Prevents TCP hijacking: attacker cannot guess seq numbers to inject data
How DNS Resolution Works
DNS resolution converts a human-readable hostname into an IP address through a hierarchy of caches and authoritative nameservers — from browser cache to root nameservers and back in milliseconds.
- ✓A recursive resolver does the heavy lifting — stub resolvers ask it once, and it iterates through root → TLD → authoritative nameservers.
- ✓CNAME cannot coexist with other records at the zone apex — use ALIAS records (Route 53) or ANAME for root domain CDN/LB pointing.
- ✓Lower TTL 48 hours before any planned DNS change; high TTL during normal operation reduces query load.
- ✓DNS-based load balancing (round-robin, latency-based, weighted) routes at the resolver level — before TCP is even opened.
- ✓Route 53 health checks + failover routing provide automatic DNS-level failover when a regional endpoint goes down.
// DNS query path for "api.aicancode.org" (full cache miss): // // Browser → OS stub resolver: "What is api.aicancode.org?" // OS stub resolver → Recursive resolver (8.8.8.8): "Resolve api.aicancode.org" // // Recursive resolver performs ITERATIVE queries: // // Step 1: Ask Root NS (.) // Query: "api.aicancode.org" → Root NS 198.41.0.4 // Answer: "I don't know, ask .org TLD NS at 199.19.56.1" // // Step 2: Ask .org TLD NS // Query: "api.aicancode.org" → 199.19.56.1 // Answer: "I don't know, ask aicancode.org NS at ns1.vercel-dns.com" // // Step 3: Ask aicancode.org Authoritative NS // Query: "api.aicancode.org" → ns1.vercel-dns.com // Answer: "api.aicancode.org A 76.76.21.21 TTL=300" // // Recursive resolver caches the A record for 300s, returns to OS, OS returns to browser // Total time: ~50–100ms on first query; ~0ms on cache hit
Long Polling vs SSE vs WebSocket
Three patterns for pushing real-time data from server to client — long polling (HTTP hack), Server-Sent Events (one-way HTTP stream), and WebSocket (full-duplex TCP channel) — each with distinct trade-offs in complexity, scalability, and browser support.
- ✓Long polling holds the HTTP request open until data arrives, then the client immediately re-requests — works everywhere but doubles latency.
- ✓SSE (EventSource) is a single persistent HTTP stream; the browser auto-reconnects and sends Last-Event-ID for resumability.
- ✓WebSocket provides full-duplex communication over a single TCP connection — lowest overhead, but requires WS-aware proxies and manual reconnection logic.
- ✓SSE is the right default for most server-push use cases (notifications, feeds); WebSocket only when the client also sends frequent messages.
- ✓WebSocket load balancing requires sticky sessions or a shared pub/sub backend (Redis) because the persistent connection must reach the same server.
// Long polling — client side (JavaScript):
async function longPoll() {
while (true) {
try {
const res = await fetch('/api/notifications?lastId=' + lastEventId, {
signal: AbortSignal.timeout(30000) // 30s server timeout
})
const data = await res.json()
if (data.events?.length) {
processEvents(data.events)
lastEventId = data.events.at(-1).id
}
// Immediately reconnect
} catch (e) {
await sleep(1000) // backoff on error
}
}
}
// Server side (Spring Boot):
@GetMapping("/api/notifications")
public DeferredResult<List<Event>> poll(@RequestParam Long lastId) {
DeferredResult<List<Event>> result = new DeferredResult<>(28000L, List.of());
eventBus.subscribe(lastId, events -> result.setResult(events));
return result; // held open until event arrives or 28s timeout
}
// Characteristics:
// ✓ Works through all proxies and firewalls (plain HTTP)
// ✗ Double latency on each event (server must wait, client must reconnect)
// ✗ Server holds many threads/connections openNAT Traversal Patterns
NAT (Network Address Translation) hides private IP addresses behind a single public IP, breaking peer-to-peer connectivity. NAT traversal techniques — STUN, TURN, and ICE — are how WebRTC and VoIP establish direct connections between clients behind NAT.
- ✓NAT breaks P2P because neither peer's private IP is routable from the internet, and NAT tables have no mapping until outbound traffic creates one.
- ✓STUN discovers your public (NAT-translated) IP:port by asking an external server to echo back what it sees.
- ✓UDP hole punching works when both peers send simultaneously — each outbound packet creates a NAT mapping that allows the other's inbound packet.
- ✓TURN provides a relay server that always works — even through symmetric NAT — but adds latency and bandwidth cost.
- ✓ICE orchestrates all of this: gather candidates (host, STUN, TURN), exchange via signalling, try all pairs, pick the best working path.
// NAT mapping example: // Home network: 192.168.1.0/24, public IP: 203.0.113.5 // // Device A (192.168.1.10) opens connection to Google (142.250.80.36:443): // → NAT creates mapping: 192.168.1.10:54321 ↔ 203.0.113.5:45001 // → Packet arrives at Google with src=203.0.113.5:45001 // ← Google replies to 203.0.113.5:45001 → NAT translates → 192.168.1.10:54321 ✓ // Peer-to-Peer problem: // Peer A: 192.168.1.10 (behind NAT: 203.0.113.5) // Peer B: 10.0.0.20 (behind NAT: 198.51.100.7) // // A tries to connect to B directly: // A knows B's private IP (10.0.0.20) → not reachable from internet // A knows B's public IP (198.51.100.7) → but which port? NAT table unknown // B's NAT drops inbound packets from A — no matching outbound mapping exists // // Neither peer can initiate → connection impossible without traversal