Network Programming And Protocols
Asked of: Software Engineer
Last updated
What's being tested
Interviewers are probing your practical fluency with building robust, low-latency networked services: how you pick transports, manage concurrency, reason about latency vs throughput, and design protocols that handle partial failures (retries, timeouts, idempotency). They expect concrete tradeoffs (e.g., blocking threads vs non-blocking I/O) and the right low-level knobs (TCP_NODELAY, buffer sizes, framing) a Software Engineer must use to meet performance and correctness targets.
Core knowledge
-
TCP vs UDP semantics: TCP = reliable, ordered, congestion-controlled; UDP = unreliable, unordered, lower latency. Use UDP for multicast/real‑time with application-level recovery.
-
Socket API essentials:
socket,bind,listen,accept,connect,send,recv, nonblockingEAGAINbehavior; handle partialsend/recvandSIGPIPE. -
Non-blocking I/O and readiness APIs:
select/poll(O(n) with limits), epoll/kqueue(scales to 10k+ fds), use edge-triggered vs level-triggered semantics deliberately. -
Bandwidth-Delay Product (BDP): BDP = bandwidth * RTT; set send/recv buffers to ~BDP to avoid sender/receiver starvation for high-throughput, high-RTT links.
-
Framing strategies: length-prefixed framing versus delimiter-based; use length-prefix + size cap to avoid message-splitting and injection attacks.
-
Nagle and delayed ACKs: Nagle's algorithm can increase latency; disable with
TCP_NODELAYfor small latency-sensitive messages, but consider increased packet count and bandwidth. -
Head-of-line blocking: TCP enforces ordering; multiplexing protocols (e.g.,
HTTP/2streams) or UDP-based designs avoid HOL blocking; trade reliability vs complexity. -
Timeouts, retries, idempotency: choose client-side timeouts << overall SLA; implement exponential backoff with jitter; design idempotent RPCs (idempotency keys) so retries are safe.
-
TLS cost and session resumption: TLS handshake adds CPU + latency; reuse sessions, enable session tickets, or terminate TLS at trusted endpoints if acceptable.
-
Serialization cost: binary formats (
protobuf) are more compact and faster to parse thanJSON; measure (CPU vs wire savings) before choosing. -
MTU & fragmentation: typical
MTU=1500bytes; avoid UDP fragmentation; enable Path MTU Discovery or send smaller datagrams to avoid reassembly penalties. -
Monitoring & SLOs: track
p50,p99, and tail-latency; instrumentconnect/handshake/send/recvlatencies and queue lengths to detect queuing-induced tail spikes.
Worked example
Design a non-blocking TCP server to handle 10k concurrent client connections. First 30 seconds: ask clarifying questions—expected request rate per connection, message size distribution, latency SLOs (p99 target), and whether messages are request/response or streaming. Skeleton answer pillars: (1) use non-blocking I/O with epoll (edge-triggered) and a fixed-size thread pool for processing; (2) implement a small per-connection state machine with length-prefixed framing and a bounded write buffer to handle EAGAIN; (3) apply backpressure so overload drops or rejects new requests early; (4) operational controls: SO_SNDBUF/SO_RCVBUF tuned to BDP, TCP_NODELAY depending on small-message latency need. Tradeoff flagged: edge-triggered epoll requires careful loop to drain sockets or you'll miss events—simpler level-triggered is safer but slightly less efficient. Close: mention metrics to expose (active_connections, send_queue_len, handler_latency), and "if I had more time" you'd add connection pooling, adaptive thread sizing, and stress tests with synthetic traffic to tune buffer sizes.
A second angle
Consider designing a retry and idempotency scheme for RPCs over TLS with strict correctness requirements. The same core concepts apply, but constraints change: TLS increases handshake cost so keep connections pooled and long-lived; retries must consider whether the server processed the request before the connection dropped—use idempotency keys or explicit at-most-once semantics with server-side deduplication. Framing stays length-prefixed, but you must authenticate and authorize each message; add per-RPC unique IDs and persistent logs for dedup checks. Here, latency SLOs push you to choose smaller timeouts and conservative retry counts; additionally, prefer application-level ACKs to know when it’s safe to retry versus assuming retransmission.
Common pitfalls
Pitfall: conflating packet loss with application-level failure.
Many engineers treat a timeout as a permanent failure without distinguishing transient packet loss, server crash, or slow processing; always design retries with increasing backoff and idempotency.
Pitfall: assuming blocking calls are okay at any scale.
Proposing a thread-per-connection model for 10k connections is tempting, but it fails on memory and context-switch costs; explain why event-driven or async I/O scales better.
Pitfall: neglecting framing and partial reads/writes.
Returning a naiverecv()loop that assumes onerecv()== one message is wrong; always implement buffering and handle partial messages, oversized lengths, and malicious inputs.
Connections
Interviewers may pivot to performance profiling (where to measure CPU vs network stalls) or security (threat model for TLS, certificate rotation, MITM mitigations). They may also ask about distributed-systems reliability patterns like circuit breakers, leader election, or consensus if the protocol needs stronger guarantees.
Further reading
-
[TCP/IP Illustrated, Volume 1 — W. Richard Stevens] — classic, deep grounding in TCP/IP behavior and edge cases.
-
[High Performance Browser Networking — Ilya Grigorik] — excellent practical coverage of latency, BDP, MTU, and TLS effects on performance.
Related concepts
- Robust Networking, REST, And Concurrency ControlSystem Design
- Real-Time Systems, WebSockets, and Long-Lived Connections
- Auctions, Ticketing, And Real-Time MessagingSystem Design
- Low-Level System Design For High-Throughput C++ Services
- Real-Time Notifications And WebSockets For Banking
- Production System Design TradeoffsSystem Design