What Go actually is
Go is a statically typed, garbage-collected language that compiles to one static binary with a scheduler inside it. This lesson sets out the runtime you are buying, the release cadence you are committing to, and the three things about Go that most annoy people arriving from a bigger language.
On this page
What you will be able to do
- Describe what a Go build produces and what it does not need at run time
- Explain the goroutine scheduler and garbage collector at the level a caller needs
- State the current supported Go releases and the support policy that decides them
- Predict which habits from TypeScript or Java will not transfer
go build writes one file. That file holds your code, every library it imports, the garbage
collector, the scheduler and the rest of the runtime, and it runs on a machine with nothing
installed on it. No interpreter to match, no JVM to size, no node_modules sitting beside it. The
artefact is the whole product, and that single fact reshapes deployment, containers, CI and how you
argue about dependencies.
Measure it rather than take it on faith. On your own machine:
mkdir hello && cd hello
go mod init example.com/hello
cat > main.go <<'EOF'
package main
import "fmt"
func main() {
fmt.Println("hello")
}
EOF
go build -o hello .
ls -l hello
file hello
Expect a couple of megabytes for a program that prints one line, because the runtime is in there. Then build it the way you would ship it, with debugging information dropped:
CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o hello-small .
ls -l hello-small
Read the numbers your own machine prints. The order of magnitude is the point: a few megabytes at
rest, and nothing to install on the target. One caveat while you are looking at file: cgo is
enabled by default, and a program that imports net or os/user
can acquire a dependency on the system C library, so a native build is not automatically a
static binary.
CGO_ENABLED=0 selects the pure Go implementations instead, which on Linux is what makes the file
static in the sense people mean by the word. Elsewhere the word does not apply: a macOS or Windows
binary always links the platform's own system library.
The runtime you are buying
Three parts matter to a caller, and nothing else does yet.
A scheduler. Goroutines are multiplexed onto a small number of operating system threads, and when one blocks on a system call the scheduler moves the others elsewhere. You do not size a thread pool and you do not colour your functions. Coming from TypeScript, the habit to unlearn is the single-threaded event loop and the fear of blocking it: in Go, blocking is a normal thing for one goroutine to do, and it is cheap. Coming from Java, the closest thing you know is virtual threads, except that here it was never optional and there is no platform-thread version of the Application Programming Interface (API) to choose between. How to actually use any of this is module 4, and the answer is smaller than you expect.
A garbage collector, on by default, with almost no dials. Go 1.26 ships the Green Tea collector
by default, and its release notes say they expect a reduction of 10-40% in garbage collection
overhead for programs that lean on the collector. That is the Go team's claim rather than a
measurement made here, so treat it as a reason not to worry rather than a number to quote in a
capacity plan. The tuning surface is GOGC, which sets how much new allocation triggers the next
cycle, and GOMEMLIMIT, a soft ceiling that makes the collector work harder as you approach it.
There is no generational-versus-concurrent choice to make, no collector to select on the command
line, and no ergonomics arms race to follow.
A processor count that is not the machine's.
- GOMAXPROCS
The number of goroutines Go will run simultaneously, which is effectively how many cores your program will use. Since Go 1.25 the default is derived from the number of logical CPUs, the process's CPU affinity mask and, on Linux, the cgroup CPU quota, whichever is smallest, and the runtime re-derives it as those change while the program runs.
This is the fact a Java reader should sit up for, because it is the container problem you already
know from heap sizing, solved the other way round. Under a quota, runtime.NumCPU still reports
every logical CPU it can see. GOMAXPROCS follows the share you were actually given.
The documented floor is 2, so a tiny quota does not leave the program running one goroutine at a
time, and a module declaring language version 1.24 or lower keeps the old behaviour even on a 1.26
toolchain.
That gating by declared language version is a pattern you will meet repeatedly, and
the next lesson explains the line
in go.mod that controls it.
Which Go you are running
Stable is go1.26.5, released on 7 July 2026 according to the release history page at go.dev/doc/devel/release, and the other supported line is go1.25.12. Both were read there on 13 August 2026. Major releases land every six months, in February and August, and Go 1.26.0 landed on 10 February 2026. The support policy is one sentence: each major Go release is supported until there are two newer major releases. Two lines are live at any moment, so a major release gets roughly a year of security and correctness fixes and then stops, quietly.
Three things that will annoy you first
They are all deliberate, and this course resolves each rather than defending it.
There are no exceptions. A function that can fail returns an error as its last value, and you check it at the call site. The result is more lines and a signature that tells the truth about what can go wrong, and it is module 3. The Go team settled the question in 2025: there is no new error syntax coming, so build the habit rather than waiting.
There is no inheritance. No classes, no extends, no super, and no virtual dispatch through
an embedded type. Composition and interfaces do the work, and interfaces are satisfied implicitly,
so nothing declares that it implements anything. That combination is the single largest structural
difference from Java and it is
module 2.
The standard library expects you to write the loop. There is no streams API and no lodash. The
slices and maps packages cover sorting, searching, cloning and keys, and past that you write a
for loop and it is three lines and everyone reading it agrees on what it does. Reviewers here
prefer the loop; that judgement is
module 2 as well.
Check your understanding
Sign in to take this check
4 questions on this lesson, one at a time, with the reasoning for every option as soon as you answer. Each answer is marked on the server and stored against your account.
An account is free. There is no paid plan, no tier and nothing to buy.