Getting Started with Go Basics
Welcome to Go Basics — a collection of in-depth articles on Go internals and best practices.
Each article dives deep into a specific Go topic — from goroutine scheduling to GC internals — with interactive code examples you can run right in the browser.
Interactive Go Code
Every article includes runnable Go code powered by Codapi. Click Run to execute:
package main
import "fmt"
func main() {
fmt.Println("Hello from Go Basics!")
}
Goroutine Scheduling Overview
Go uses a work-stealing scheduler built around three core abstractions:
- G (Goroutine): a lightweight thread managed by the Go runtime
- M (Machine): an OS thread
- P (Processor): a logical processor that mediates between G and M
GOMAXPROCS controls the number of Ps, not the number of OS threads.
Value vs Pointer Receivers
- Value Receiver
- Pointer Receiver
package main
import "fmt"
type Point struct {
X, Y int
}
func (p Point) Translate(dx, dy int) Point {
return Point{p.X + dx, p.Y + dy}
}
func main() {
p := Point{1, 2}
p2 := p.Translate(3, 4)
fmt.Println(p, "→", p2)
}
Value receivers get a copy of the struct. The original is never modified.
package main
import "fmt"
type Point struct {
X, Y int
}
func (p *Point) Translate(dx, dy int) {
p.X += dx
p.Y += dy
}
func main() {
p := Point{1, 2}
p.Translate(3, 4)
fmt.Println(p)
}
Pointer receivers modify the original struct in place.
If any method on a type uses a pointer receiver, consider using pointer receivers for all methods on that type. Mixing can lead to subtle bugs with interface satisfaction.
What's Next?
Explore the articles in the sidebar — each one covers a topic from the curated list of Go topics with the same depth and interactive examples shown here.