What exactly do go.mod and go.sum contain, and is go.sum a lock file?
go.mod declares the module path, the minimum Go version ( go line), an optional toolchain , and minimum required versions of dependencies ( require ), plus replace ,…
36 Go interview questions on modules, packages & tooling, with detailed answers and code.
go.mod declares the module path, the minimum Go version ( go line), an optional toolchain , and minimum required versions of dependencies ( require ), plus replace ,…
MVS builds the requirement graph starting from the main module. For each module path it picks the highest of the minimum versions that anything in the graph requires. It…
The import compatibility rule says: if an old package and a new package have the same import path, the new one must be backward compatible with the old one. A major…
Major branch (the common choice): on main, or on a v2 branch, change the go.mod line to module example.com/lib/v2 , update every internal import to the /v2 path, then…
replace swaps the content of a module version for another version, another module path (a fork), or a local directory. Typical uses: testing a local fix before it goes…
exclude is written by a consumer in the main module. It forbids one specific version. If something requires an excluded version, MVS moves up to the next higher…
A pseudo-version stands for an untagged commit . It has the form vX.Y.Z-yyyymmddhhmmss-abcdefabcdef , made of a base version, the UTC commit time, and a 12-character…
Workspaces (Go 1.18) let you build several local modules together as if they were all main modules, without editing any go.mod. They are the standard answer for "I'm…
go mod vendor copies the packages needed to build and test the main module into vendor/ and writes vendor/modules.txt . Since Go 1.14, if vendor/ exists and go.mod says…
The compiler enforces this rule: a package whose path contains an internal element can be imported only by code rooted at the parent of that internal directory . It is…
By default GOPROXY=https://proxy.golang.org,direct and GOSUMDB=sum.golang.org . The public proxy cannot see private repos, and the checksum database would reject, or at…
sum.golang.org is an append-only, Merkle-tree transparency log (Trillian) of go.sum lines for every public module version. The first time anyone in the world downloads…
Since Go 1.21, go 1.22.0 is a strict minimum requirement (it used to be advisory). An older toolchain refuses to build the module, or downloads a newer one. The line…
// go.mod: go 1.21 package main import "fmt" func main() { var fns []func() for i := 0; i < 3; i++ { fns = append(fns, func() { fmt.Print(i, " ") }) } for _, f := range…
Before 1.24 the convention was a tools.go file with //go:build tools and blank imports, used to pin versions of developer tools (stringer, mockgen, sqlc) in go.mod. Go…
Since Go 1.17/1.18 the jobs are separate: go get only changes dependency requirements in the current module's go.mod and go.sum. It no longer builds or installs…
Build constraints decide whether a file is part of a package for a given build. There are two mechanisms. 1. //go:build expressions (Go 1.17+). These are boolean…
Put a custom tag on the integration test files, then opt in when running tests: //go:build integration package store_test import "testing" func TestPostgresRoundTrip(t…
go generate scans source files for //go:generate command args lines (no space after // ) and runs the commands with the package directory as the working directory. It is…
"cgo is not Go." The costs: Call overhead : each Go-to-C call switches to the system stack and tells the scheduler. That is tens of nanoseconds, versus about 1 ns for a…
The GC may move goroutine stacks and must be able to see every Go pointer. The rules, enforced at runtime when GODEBUG=cgocheck=1 (the default): Go may pass a Go pointer…
The Go toolchain can cross-compile to every supported target: set GOOS / GOARCH (and GOARM / GOAMD64 for micro-architecture levels). cgo is disabled by default when…
package main import "fmt" const commit = "none" var version = "dev" var built = defaultBuilt() func defaultBuilt() string { return "unknown" } func main() {…
Since Go 1.18 every binary embeds its module path, dependency versions and hashes, build settings (GOOS, GOARCH, CGO_ENABLED, -tags , -ldflags ), and VCS information (…
package main import ( "context" "fmt" "sync" "time" ) type Counter struct { mu sync.Mutex n int } func (c Counter) Inc() { c.mu.Lock(); c.n++; c.mu.Unlock() } // (1)…
go vet is conservative and ships with the toolchain. staticcheck (Dominik Honnef) covers much more, with about 150 checks in several families: SA : bugs, e.g. SA4006…
//go:embed (Go 1.16) compiles files into the binary at build time. The directive goes immediately above a package-level variable of type string , []byte , or embed.FS .…
When a pattern names a directory , files whose names start with . or _ are excluded recursively. So //go:embed dist silently drops dist/.well-known/ , _app/ (SvelteKit…
package main import "fmt" var a = b + 1 var b = f() func f() int { fmt.Println("f"); return 1 } func init() { fmt.Println("init1", a, b) } func init() {…
The compiler rejects cycles ( import cycle not allowed ) because package initialization and compilation units must form a DAG. A cycle usually signals a design problem:…
The commands used for dependency forensics: govulncheck ./... # is the vulnerable symbol actually reachable? go mod why -m golang.org/x/net # shortest import chain from…
PGO became generally available in Go 1.21. The compiler uses a CPU profile from representative production load to make better decisions: inlining hot call sites more…
// go.mod: go 1.20 (built with a Go 1.24 toolchain) package main import "fmt" func main() { defer func() { fmt.Printf("%T\n", recover()) }() panic(nil) } Answer: with go…
Before 1.17 the go command had to load the go.mod of every module in the transitive graph, including modules that provide no package you actually build. From go 1.17…
There are two separate caches: Module cache ( GOMODCACHE , default $GOPATH/pkg/mod ): extracted, read-only module source plus the downloaded zips and go.mod files in…
//go:linkname localname importpath.name tells the compiler to use importpath.name as the object-file symbol for localname . It needs import _ "unsafe" . It comes in two…