Ultimate Go Bundle
$419 Regular price $699
9 courses · 123+ hours
Enroll at 40% OffWhat's included:
- Design Philosophies
- Syntax to Tooling
- Microservices
- Concurrency
- Debugging
Black Friday Sale
Self-paced Go, Rust, Docker, and Kubernetes training from Ardan Labs instructors, with a full year of access to every course in your bundle.
50,000+ engineerstrained by Ardan Labs
Trusted by 1,800+ companies worldwide
1-year access · New course updates · Certificate for every course
One language or platform, from beginner to advanced.
$419 Regular price $699
9 courses · 123+ hours
Enroll at 40% OffWhat's included:
What's included:
What's included:
Go or Rust paired with Docker and Kubernetes.
$539 Regular price $899
15 courses · 183+ hours
Enroll at 40% OffWhat's included:
$479 Regular price $799
13 courses · 104+ hours
Enroll at 40% OffWhat's included:
The full Go, Rust, Docker, and Kubernetes catalog.
Most popular!
$599 Regular price $999
22 courses · 227+ hours
Enroll at 40% OffThe full catalog, valued at $1697: Best Value
Team pricing
Group pricing is available for teams of any size, on every bundle above. Tell us how many engineers you're training and a training advisor will follow up with options and pricing.
No commitment. Self-paced bundles for individuals and teams.
Spot the Bug: Go Edition
Three real Go behaviors that trip up experienced engineers. Think it through, then reveal the answer.
| |
This function returns a nil pointer. So why does the program print false?
Think it through before you reveal the answer.
A typed nil inside an interface.
In Go, an interface value holds both a dynamic type and a dynamic value. getUser() returns a nil *User, but once it’s assigned to any, the interface holds:
*UsernilBecause the interface has a dynamic type, the interface itself isn’t nil, so the comparison returns false. This comes up constantly with error handling, where a function returns a typed nil error.
The lesson: Understand what an interface contains before relying on nil comparisons.
| |
This looks simple. Does the goroutine complete its work? What would you change?
Think it through before you reveal the answer.
The send stays blocked until the program exits.
main never receives from ch; it prints Done and returns. When main returns, the program exits without waiting for other goroutines, so the send never completes. One fix is to receive the value:func main() {
ch := make(chan int)
go func() {
ch <- 42
}()
fmt.Println(<-ch)
}
The lesson: Launching concurrent work doesn't guarantee it completes. In production services, blocked goroutines hold resources and complicate shutdown.
Also on sale: live workshops
Building Rust with AI with Herbert Wolverson runs December 9th & 10th, and Practical Development with AI Agents with Miki Tebeka runs December 15th & 16th.
Trusted by engineers
Don't just take our word for it. Here's what engineers say after working through our courses.
“Thanks Ardan Labs for a great Ultimate Go class! Bill is a great teacher and I'm definitely more productive in Go now.”
Steve Francia
Ultimate Go