Networking Interview Questions: HTTP, TCP, DNS, TLS Explained

Networking fundamentals appear in almost every senior engineering interview. Whether you’re designing a system or debugging production, you need to explain how data moves from browser to server and back. This guide covers the most common networking interview questions with clear explanations and code.

HTTP Protocol Versions

HTTP/1.1 vs HTTP/2 vs HTTP/3

Feature HTTP/1.1 HTTP/2 HTTP/3
Transport TCP TCP QUIC (UDP-based)
Multiplexing No (one req/connection) Yes (streams) Yes (independent streams)
Head-of-line blocking Yes TCP-level only No
Header compression No HPACK QPACK
Server push No Yes Yes
Connection setup 1 RTT (+ TLS) 1 RTT (+ TLS) 0 RTT (resumed)
HTTP_STATUS_CODES = {
    # 2xx Success
    200: "OK — request succeeded",
    201: "Created — new resource created (POST)",
    204: "No Content — success, no body (DELETE/PUT)",
    206: "Partial Content — range request (streaming/resume)",

    # 3xx Redirection
    301: "Moved Permanently — update bookmarks/crawlers",
    302: "Found — temporary redirect (keeps method)",
    304: "Not Modified — use cached version (ETag/If-None-Match)",
    307: "Temporary Redirect — preserves method (POST stays POST)",
    308: "Permanent Redirect — preserves method",

    # 4xx Client Errors
    400: "Bad Request — malformed syntax",
    401: "Unauthorized — authentication required",
    403: "Forbidden — authenticated but not authorized",
    404: "Not Found",
    409: "Conflict — state conflict (duplicate, optimistic lock fail)",
    410: "Gone — permanently deleted (SEO: tell crawlers to deindex)",
    422: "Unprocessable Entity — validation failed",
    429: "Too Many Requests — rate limit hit",

    # 5xx Server Errors
    500: "Internal Server Error",
    502: "Bad Gateway — upstream server error",
    503: "Service Unavailable — overloaded or down",
    504: "Gateway Timeout — upstream timeout",
}

CACHE_CONTROL_PATTERNS = {
    "immutable_asset": "public, max-age=31536000, immutable",  # JS/CSS with hash
    "api_response":    "private, max-age=0, must-revalidate",   # User-specific data
    "public_page":     "public, max-age=3600, stale-while-revalidate=86400",
    "no_cache":        "no-store",                               # Sensitive data
    "cdn_cacheable":   "public, s-maxage=86400, max-age=3600",  # CDN caches longer
}

TCP vs UDP

"""
TCP (Transmission Control Protocol)
- Connection-oriented: 3-way handshake before data
- Reliable: ACKs, retransmission, ordering
- Flow control: receiver advertises window size
- Congestion control: slow start, AIMD
- Use: HTTP, email, file transfer, databases

UDP (User Datagram Protocol)
- Connectionless: fire and forget
- No reliability guarantees — dropped packets are lost
- Lower latency (no handshake, no ordering overhead)
- Use: DNS, video streaming, online gaming, VoIP, QUIC

TCP 3-way handshake:
  Client               Server
    │──── SYN ──────────►│
    │◄─── SYN-ACK ───────│
    │──── ACK ──────────►│
    │   [data flows]     │

TIME_WAIT state (2*MSL ~4 minutes):
  Server socket enters TIME_WAIT after FIN exchange.
  Prevents reuse of the same port/IP combo during packet drain.
  High connection rate? Set net.ipv4.tcp_tw_reuse=1 on Linux.
"""

import socket

def tcp_echo_server(host="127.0.0.1", port=9000):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host, port))
        s.listen(5)
        while True:
            conn, addr = s.accept()
            with conn:
                data = conn.recv(4096)
                conn.sendall(data)  # Echo back

def udp_server(host="127.0.0.1", port=9001):
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
        s.bind((host, port))
        while True:
            data, addr = s.recvfrom(4096)
            s.sendto(data, addr)

DNS Resolution

"""
DNS Resolution Chain for "www.techinterview.org":

Browser cache → OS cache → Recursive resolver (ISP/8.8.8.8)
    → Root nameserver (.) → TLD nameserver (.org)
    → Authoritative nameserver (techinterview.org NS records)
    → Returns A/AAAA record → cached at each level per TTL

Record types:
  A     → IPv4 address
  AAAA  → IPv6 address
  CNAME → Canonical name (alias)
  MX    → Mail exchanger
  TXT   → Arbitrary text (SPF, DKIM, domain verification)
  NS    → Nameserver delegation
  SOA   → Start of authority (zone metadata)
  PTR   → Reverse DNS (IP → hostname)

TTL considerations:
  Low TTL (60s): fast failover, high resolver load, slower lookups
  High TTL (86400s): cached everywhere, slow to propagate changes
  Strategy: lower TTL before planned migration, raise after
"""

import dns.resolver  # dnspython library

def lookup_dns(domain: str):
    resolver = dns.resolver.Resolver()
    resolver.nameservers = ["8.8.8.8", "1.1.1.1"]

    for record_type in ["A", "AAAA", "MX", "TXT"]:
        try:
            answers = resolver.resolve(domain, record_type)
            for ans in answers:
                print(f"{record_type}: {ans}")
        except dns.resolver.NoAnswer:
            pass

TLS 1.3 Handshake

"""
TLS 1.3 Handshake (1 RTT, vs 2 RTT for TLS 1.2):

Client                              Server
  │── ClientHello ─────────────────►│
  │   (supported ciphers, key share) │
  │◄─ ServerHello + Certificate ────│
  │   + CertificateVerify + Finished│
  │── Finished ────────────────────►│
  │   [Encrypted data flows]        │

Key improvements in TLS 1.3 vs 1.2:
  - Removed weak algorithms: RSA key exchange, RC4, 3DES, SHA-1
  - Forward secrecy mandatory (ephemeral Diffie-Hellman)
  - 0-RTT resumption: client sends data with first packet
    (risk: replay attacks — only use for idempotent requests)
  - Handshake encrypted sooner (hides certificate from passive observer)

Common vulnerabilities and mitigations:
  BEAST  → Fixed in TLS 1.2+ (CBC IV chaining)
  POODLE → Disable SSL 3.0/TLS 1.0
  BEAST  → Mitigated by 1/n-1 record splitting
  CRIME  → Disable TLS compression
  HSTS   → Force HTTPS, prevent downgrade attacks
"""

import ssl, socket

def check_tls(hostname: str, port: int = 443):
    context = ssl.create_default_context()
    with socket.create_connection((hostname, port)) as raw:
        with context.wrap_socket(raw, server_hostname=hostname) as tls:
            cert = tls.getpeercert()
            print(f"Protocol: {tls.version()}")
            print(f"Cipher:   {tls.cipher()}")
            print(f"Subject:  {dict(x[0] for x in cert['subject'])}")
            print(f"Expires:  {cert['notAfter']}")

Load Balancing Algorithms

import random
import time
from collections import defaultdict
from typing import List, Optional

class Backend:
    def __init__(self, host: str, weight: int = 1):
        self.host = host
        self.weight = weight
        self.active_connections = 0
        self.healthy = True
        self.response_times: List[float] = []

class LoadBalancer:
    def __init__(self, backends: List[Backend]):
        self.backends = backends
        self._rr_index = 0

    def healthy_backends(self) -> List[Backend]:
        return [b for b in self.backends if b.healthy]

    def round_robin(self) -> Optional[Backend]:
        healthy = self.healthy_backends()
        if not healthy:
            return None
        backend = healthy[self._rr_index % len(healthy)]
        self._rr_index += 1
        return backend

    def least_connections(self) -> Optional[Backend]:
        healthy = self.healthy_backends()
        if not healthy:
            return None
        return min(healthy, key=lambda b: b.active_connections)

    def weighted_round_robin(self) -> Optional[Backend]:
        """Servers with higher weight get proportionally more requests."""
        healthy = self.healthy_backends()
        if not healthy:
            return None
        pool = []
        for b in healthy:
            pool.extend([b] * b.weight)
        return pool[self._rr_index % len(pool)]

    def ip_hash(self, client_ip: str) -> Optional[Backend]:
        """Same client IP always routes to same backend (sticky sessions)."""
        healthy = self.healthy_backends()
        if not healthy:
            return None
        idx = hash(client_ip) % len(healthy)
        return healthy[idx]

    def p2c_least_latency(self) -> Optional[Backend]:
        """Power of Two Choices — pick 2 random, choose lower latency."""
        healthy = self.healthy_backends()
        if len(healthy) < 2:
            return healthy[0] if healthy else None
        a, b = random.sample(healthy, 2)
        avg_a = sum(a.response_times[-10:]) / max(len(a.response_times[-10:]), 1)
        avg_b = sum(b.response_times[-10:]) / max(len(b.response_times[-10:]), 1)
        return a if avg_a <= avg_b else b

CORS and Security Headers

SECURITY_HEADERS = {
    # Prevent MIME-type sniffing
    "X-Content-Type-Options": "nosniff",

    # Clickjacking protection
    "X-Frame-Options": "DENY",  # or SAMEORIGIN

    # Force HTTPS for 1 year, include subdomains
    "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",

    # Control referrer info
    "Referrer-Policy": "strict-origin-when-cross-origin",

    # Content Security Policy — whitelist allowed sources
    "Content-Security-Policy": (
        "default-src 'self'; "
        "script-src 'self' 'unsafe-inline' https://cdn.example.com; "
        "style-src 'self' https://fonts.googleapis.com; "
        "img-src 'self' data: https:; "
        "connect-src 'self' https://api.example.com"
    ),

    # Permissions Policy (formerly Feature-Policy)
    "Permissions-Policy": "camera=(), microphone=(), geolocation=(self)",
}

CORS_HEADERS = {
    "Access-Control-Allow-Origin":  "https://app.example.com",  # Never * for credentialed
    "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
    "Access-Control-Allow-Headers": "Authorization, Content-Type, X-Request-ID",
    "Access-Control-Max-Age":       "86400",   # Cache preflight for 24h
    "Access-Control-Allow-Credentials": "true",
}

Frequently Asked Questions

What is the difference between HTTP/2 and HTTP/3?

HTTP/2 runs over TCP with multiplexed streams (no head-of-line blocking at HTTP layer, but TCP-level blocking remains). HTTP/3 runs over QUIC (built on UDP), eliminating TCP head-of-line blocking entirely. HTTP/3 also supports 0-RTT connection resumption for returning clients, reducing latency. QUIC handles connection migration (switching IPs without reconnecting).

What happens when you type a URL in a browser?

The browser checks DNS cache, then OS cache, then queries the recursive resolver. The resolver walks the DNS tree (root → TLD → authoritative nameserver) to find the A/AAAA record. The browser establishes a TCP connection (3-way handshake), performs TLS handshake (1 RTT for TLS 1.3), sends an HTTP GET request, receives the response, and renders the page.

What is the difference between TCP and UDP?

TCP is connection-oriented with guaranteed delivery, ordering, and flow control. UDP is connectionless with no delivery guarantee — packets may be lost, duplicated, or reordered. TCP suits HTTP, databases, and file transfers. UDP suits DNS, video streaming, online gaming, and VoIP where low latency matters more than perfect reliability.

{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “What is the difference between HTTP/2 and HTTP/3?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “HTTP/2 runs over TCP with multiplexed streams (no head-of-line blocking at HTTP layer, but TCP-level blocking remains). HTTP/3 runs over QUIC (built on UDP), eliminating TCP head-of-line blocking entirely. HTTP/3 also supports 0-RTT connection resumption for returning clients, reducing latency. QUIC handles connection migration (switching IPs without reconnecting).”
}
},
{
“@type”: “Question”,
“name”: “What happens when you type a URL in a browser?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “The browser checks DNS cache, then OS cache, then queries the recursive resolver. The resolver walks the DNS tree (root → TLD → authoritative nameserver) to find the A/AAAA record. The browser establishes a TCP connection (3-way handshake), performs TLS handshake (1 RTT for TLS 1.3), sends an HTTP GET request, receives the response, and renders the page.”
}
},
{
“@type”: “Question”,
“name”: “What is the difference between TCP and UDP?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “TCP is connection-oriented with guaranteed delivery, ordering, and flow control. UDP is connectionless with no delivery guarantee — packets may be lost, duplicated, or reordered. TCP suits HTTP, databases, and file transfers. UDP suits DNS, video streaming, online gaming, and VoIP where low latency matters more than perfect reliability.”
}
}
]
}

Scroll to Top