Go Trivia
33 items — interesting facts, gotchas, and deep-dives about Go.
- beginnerhistorygoogle
Born at Google
Go was conceived at Google in September 2007 by Robert Griesemer, Rob Pike, and Ken Thompson. They started designing it while waiting for a C++ build to finish.
- beginnerhistorydesigners
Three Legends
Go was designed by Robert Griesemer (V8, HotSpot JVM), Rob Pike (Plan 9, UTF-8), and Ken Thompson (Unix, B language, UTF-8). All three had decades of systems programming experience.
- intermediatehistorydesignersstrings
Ken Thompson's Legacy
Ken Thompson co-created Unix and the B programming language (a predecessor to C). He and Rob Pike also co-invented the UTF-8 encoding, which Go uses for all strings.
- beginnerhistoryrelease
Public Release — 2009
Go was announced to the public on 10 November 2009. The announcement was made at Google's annual developer day, and the language was open-sourced on the same day.
- beginnerhistoryreleasecompatibility
Go 1.0 — Stability Promise
Go 1.0 was released on 28 March 2012. It introduced the Go 1 compatibility guarantee: code written for Go 1.0 will continue to compile and run correctly with any future Go 1.x release.
- beginnermascotcommunity
The Gopher
Go's beloved Gopher mascot was designed by Renée French, who is also Rob Pike's partner. The design first appeared on a WFMU promotional poster before being adopted as the Go mascot.
- intermediatemascothistory
Gopher's Debut
The Gopher first appeared on a WFMU free-form radio station t-shirt designed by Renée French in 2000, nine years before Go was released. It was repurposed as Go's mascot because of its creator's connection to the language.
- beginnercommunityconference
GopherCon
GopherCon is the largest annual Go conference. The first GopherCon was held in Denver, Colorado, in 2014. It has since spawned regional editions worldwide including GopherCon UK, EU, India, and Brazil.
- beginnermoduleshistory
Go Modules
Go modules were introduced as an experimental feature in Go 1.11 (2018) and became the default in Go 1.16 (2021). They replaced the old GOPATH-based workflow with a proper dependency management system.
- beginnergenericshistorytype-system
Go added generics in version 1.18 (March 2022)
Go 1.18 introduced parametric polymorphism (generics) with type parameters — the most anticipated addition since launch. Type constraints are expressed as interfaces; `any` (alias for `interface{}`) accepts all types, and `comparable` restricts to map-key-eligible types. It also added fuzzing and workspace mode in a single release.
- intermediategoroutinesconcurrencymemory
Goroutines start with a tiny stack
A goroutine starts with only about 2–8 KB of stack space and the stack grows dynamically as needed — up to 1 GB by default. This makes spawning thousands of goroutines inexpensive compared to OS threads, which typically reserve 1–8 MB of stack.
- advancedconcurrencyhistorychannels
Channels and CSP
Go's channels are inspired by Tony Hoare's Communicating Sequential Processes (CSP), first described in 1978. Rob Pike applied CSP ideas in earlier languages (Newsqueak, Alef) before bringing them to Go.
- intermediatechannelsconcurrencytype-system
Channel direction restricts how a channel can be used
Channels can be typed as send-only (`chan<- T`) or receive-only (`<-chan T`). Restricting channel direction in function signatures makes data flow explicit and prevents misuse. A bidirectional `chan T` can be passed where either directional type is required, but not vice versa.
- intermediateselectchannelsconcurrency
A select with a default clause never blocks
Adding a `default` case to a `select` statement makes it non-blocking — if no other case is ready, the default runs immediately. This pattern is used for try-send and try-receive operations. Without default, `select` blocks until at least one case is ready.
- advancedruntimegoroutinesscheduler
M:N Scheduler
The Go runtime uses an M:N scheduler: M goroutines are multiplexed onto N OS threads. The GOMAXPROCS setting (default: number of CPU cores) controls how many threads run simultaneously.
- advancedruntimegcperformance
Concurrent Garbage Collector
Go uses a tricolour mark-and-sweep garbage collector that runs concurrently with the programme. Since Go 1.5, GC pause times have been sub-millisecond for most workloads, making Go suitable for latency-sensitive applications.
- beginnerstringsunicodetypes
A rune is just an alias for int32
In Go, `rune` is an alias for `int32` and represents a Unicode code point. A `string` is a sequence of bytes, not runes. When you range over a string, Go automatically decodes UTF-8 and yields runes, but indexing with `s[i]` gives the raw byte at position i, not the i-th character.
- intermediateslicesmemoryinternals
A slice is a three-word header: pointer, length, capacity
Internally, a slice is a struct with three fields: a pointer to the underlying array, a length, and a capacity. Passing a slice copies this header (not the data). Mutations through the pointer affect the original array, but appending beyond capacity creates a new backing array.
- intermediateconstantslanguage
iota — The Clever Constant
`iota` is a pre-declared identifier in Go that generates a sequence of integers in a `const` block. It resets to 0 at each `const` keyword and increments with each constant specification.
- intermediateinterfacesnilgotchas
A nil interface and an interface holding a nil pointer are different
An interface value is nil only when both its type and value are nil. If you assign a typed nil pointer to an interface, the interface is not nil — it has a concrete type but a nil value. This surprises many newcomers: `var p *MyType = nil; var i error = p; i == nil` evaluates to `false`.
- intermediateinterfacestype-systemidioms
Interface satisfaction is checked implicitly at compile time
Go uses structural typing — a type implements an interface simply by having all the required methods, with no explicit declaration. You can verify this at compile time with the blank assignment idiom: `var _ io.Writer = (*MyWriter)(nil)`. If MyWriter doesn't satisfy io.Writer, this line fails to compile.
- beginnerinterfacesfmtidioms
Implement fmt.Stringer to control how a type prints
If your type has a `String() string` method, the `fmt` package automatically uses it whenever the value is formatted with `%v`, `%s`, or `Println`. This is the idiomatic way to give custom types human-readable representations.
- intermediateerrorserror-handlingstdlib
Use fmt.Errorf with %w to wrap errors for inspection
Since Go 1.13, you can wrap an error with `fmt.Errorf("context: %w", err)` to add context while preserving the original. `errors.Is(err, target)` unwraps the chain to check for a specific error value, and `errors.As(err, &target)` finds the first error of a given type in the chain.
- intermediateerror-handlingdesignidioms
Errors Are Just Values
Rob Pike's famous blog post "Errors are values" (2015) explains that because `error` is an interface, it can be wrapped, composed, and reasoned about like any other value. This philosophy shapes Go's error handling idioms.
- beginnermapsnilgotchas
Reading from a nil map is safe; writing to one panics
A nil map behaves like an empty map for reads — accessing a missing key returns the zero value for the value type without panicking. However, assigning to a nil map causes a runtime panic. Always initialise maps with `make(map[K]V)` or a map literal before writing to them.
- beginnerdefercontrol-flowidioms
Deferred calls execute in LIFO order
Multiple `defer` statements in a function execute in last-in, first-out (stack) order. This mirrors the natural pairing of open/close and lock/unlock operations, ensuring cleanup happens in the reverse order of acquisition.
- beginnersyntaxidiomsvariables
The blank identifier _ discards values without allocation
Using _ on the left side of an assignment tells the compiler to discard the value entirely. Unlike assigning to a named variable, no memory is allocated and the value is never stored. This is idiomatic Go for ignoring unwanted return values or loop variables.
- intermediateinitpackagesexecution-order
A package can have multiple init() functions
Unlike most languages, Go allows multiple `init()` functions in the same file or package. They all run automatically before `main()`, in the order they appear in source files (files are processed in lexicographic order). Use `init()` for package-level setup, but avoid side effects that make testing difficult.
- beginnerdesigninterfacesembedding
No Inheritance
Go deliberately omits class-based inheritance. Instead, it provides composition through struct embedding and polymorphism through interfaces. This design avoids deep inheritance hierarchies that can be brittle and hard to refactor.
- beginnercompilationdesign
Fast Compilation
Go was designed for fast compilation from the start. The designers intentionally limited language features that slow compilers (such as templates and macros). A large Go codebase typically compiles in seconds.
- beginnertoolinggofmtstyle
gofmt enforces a single canonical formatting style
Unlike most languages where style is a matter of preference, Go enforces one official formatting via `gofmt`. This eliminates style debates and makes all Go code immediately familiar. CI pipelines typically fail if `gofmt -l .` reports any unformatted files. Most editors run gofmt automatically on save.
- beginnertoolscommunity
The Go Playground
The Go Playground (go.dev/play) allows you to write, run, and share Go programmes in a browser. It has been available since 2010 and runs a sandboxed, deterministic Go environment.
- beginnerecosystemcloudnotable-projects
Powering the Cloud
Docker, Kubernetes, Prometheus, Terraform, and Hugo are all written in Go. The language's combination of static compilation, concurrency primitives, and fast startup made it the language of choice for cloud-native infrastructure.