Explain Minimal Version Selection (MVS). How does it differ from npm/Cargo-style resolution?
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 never picks "the latest available". Because of this the result is deterministic and reproducible without a lock file, and a new upstream release changes nothing until someone raises a requirement.
main requires A v1.2, B v1.1
A v1.2 requires C v1.3
B v1.1 requires C v1.4
C: latest published is v1.9
Build list: A v1.2, B v1.1, C v1.4 // max(1.3, 1.4), NOT v1.9
SAT-solver style resolvers (npm, Cargo, pip) search for the newest versions that satisfy range constraints. That is NP-hard in general and depends on what exists in the registry right now, which is why they need lock files.
Consequences: an upgrade happens only when you ask for it (go get C@v1.9). A downgrade may also downgrade modules that depend on it. exclude makes MVS skip a version and move to the next higher one. MVS depends on semver compatibility: within a major version a higher version must be backward compatible, which is why breaking changes need a new import path (v2+). Interviewers want "highest minimum, deterministic, no lock file, upgrades are explicit".
More on Modules, Packages & Tooling
- Q407What exactly do go.mod and go.sum contain, and is go.sum a lock file?
- 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?