My First Week with Go: What I Learned Coming from Java

Week 1 of Learning Go
I set aside this week to learn Go properly. I have a strong interest in cloud native projects, and since Go is the language that ecosystem runs on, it made sense to start here. Coming from a Java/Spring Boot background, a lot of the ideas mapped over, but Go's approach to a few things — errors, concurrency, deployment — was a genuine shift in how I think.
This is a quick log of what I covered and the resources I used, in case it helps anyone else starting out.
What I covered
- Variables, types, and zero values
- Functions and Go's multiple-return / error pattern
- Structs, methods, interfaces, and pointers
- Error handling (Go has no exceptions — worth understanding why)
- Packages and modules (
go mod) - Goroutines, channels, and
select - Build tooling (
go build,run,test,fmt,vet) - Memory management and garbage collection
To make the concurrency piece stick, I built a small program: a set of fake API calls, each running in its own goroutine, with the results collected over a channel and a select-based timeout so slow calls don't hang everything. Writing it myself taught me more than any amount of reading — especially why you pass data through channels instead of sharing variables.
Resources I used
For understanding how Go differs from other backend languages, this comparison was a solid starting point: https://talent500.com/blog/backend-2025-nodejs-python-go-java-comparison/
For the core language — types, functions, structs, interfaces, error handling, packages — I stuck to the official documentation, which is excellent: https://go.dev/doc/
For goroutines, channels, and the select statement, this video was clear and practical:
https://www.youtube.com/watch?v=qyM8Pi1KiiM&t=1829s
Reflections
The biggest mental shift from Java was how much Go prefers to be explicit — no implicit type conversion, errors returned as values instead of thrown, and cleanup handled with defer. The other standout was concurrency: goroutines feel a lot like Java's virtual threads, and passing data through channels rather than locking shared state is a cleaner way to reason about concurrent code.

