Http Listenandserve
Fast recall
Quick revision
Core answer
Whether you understand Http Listenandserve beyond memorized syntax.
Giving a definition without explaining a practical trade-off.
Connect the concept to a small production example and state its complexity or failure mode.
Interview-ready guide
Interview answer
The one-line server:
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}The two arguments: the address (":8080" binds all interfaces; ":0" picks a port), and the handler (nil = http.DefaultServeMux — the global router that HandleFunc registers into).
What happens inside: ListenAndServe creates an http.Server, calls net.Listen("tcp", addr) to bind, then Serve(listener) — the accept loop. Each accepted connection gets a goroutine that reads the request, routes it through the handler, and writes the response. One goroutine per connection — that's Go's concurrency model directly applied to HTTP.
Executed (via httptest — the same machinery without a real port):
mux := http.NewServeMux()
mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello")
})
// GET /hello → 200 "hello" — verifiedWhat ListenAndServe returns: an error — and it's always non-nil (it returns when the server stops: a bind error (port in use), a Close call, or a Serve error. That's why the idiom is log.Fatal(http.ListenAndServe(...)) — the error is the exit.
The production form: http.Server gives you the knobs (timeouts, TLS, graceful shutdown):
srv := &http.Server{
Addr: ":8080",
ReadTimeout: 10 * time.Second,
WriteTimeout: 30 * time.Second,
Handler: mux,
}
srv.ListenAndServe()For tests, http.Server is the same thing with an httptest listener — no port, no network.
Http Listenandserve
Direct Answer
http.ListenAndServe(addr, handler) starts an HTTP server on the address with the given handler (nil = DefaultServeMux). It blocks until the server errors or shuts down.
Deep Dive & Architecture
The Serve loop, one layer down: for { conn := listener.Accept(); go srv.newConn(conn) } — accept, spawn, repeat. Each connection goroutine parses the HTTP (headers, body framing), builds the *http.Request, finds the handler (ServeMux pattern matching), calls it with (ResponseWriter, Request), and closes. The concurrency IS the goroutine-per-connection — no thread pool to size, no event loop to configure.
The nil handler means DefaultServeMux — a package-level global router. HandleFunc registers into it. The global is convenient for small programs and a dependency concern for large ones (any package can register; the route table is global mutable state) — which is why production code creates its own ServeMux and passes it explicitly.
The timeout story interviewers probe: ListenAndServe with no Server sets NO timeouts — a slow client can hold a connection forever (Slowloris-class attacks). The production Server struct's ReadTimeout/WriteTimeout/IdleTimeout are the defense — and the zero-value-usable philosophy means the simple form works until you need the hardening, then the explicit Server is there.
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- When would you use Http Listenandserve in a real project?
- How would you compare Http Listenandserve with an alternative?
- What is a common mistake when using Http Listenandserve?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.