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, exclude, retract, tool (1.24), godebug (1.23) and ignore (1.25, directories the go command skips when matching ./...) directives. Since Go 1.17 it lists all transitively needed modules (with // indirect) so the module graph can be pruned.
go.sum is not a lock file. It is a list of cryptographic hashes: one line for each module's zip (h1: hash of the file tree) and one for its go.mod (/go.mod h1:). It guarantees that the bytes you download are the same bytes everyone else got. Version selection is already deterministic because of MVS and the versions pinned in go.mod, so no separate lock file is needed.
module github.com/acme/billing
go 1.23
toolchain go1.23.4
require (
github.com/google/uuid v1.6.0
golang.org/x/sync v0.8.0 // indirect
)
Gotchas: commit both files. It is normal for go.sum to hold entries for versions that are not selected, because MVS needs to read their go.mod files. What the interviewer wants to hear: "go.mod decides which versions; go.sum checks integrity."
More on Modules, Packages & Tooling
- Q408Explain Minimal Version Selection (MVS). How does it differ from npm/Cargo-style resolution?
- Q409What is semantic import versioning, and why must v2+ modules change their import path?
- Q410How do you release v2 of a module? Compare the "major branch" and "major subdirectory" strategies, and explain +incompatible.
- Q411When would you use a replace directive, and why doesn't a dependency's replace affect your build?
- Q412Explain exclude and retract. Who writes each one, and how do they affect version selection?
- Q413What is a pseudo-version, and when does the go command generate one?