Tech Notes #1: Teaching myself Golang
Rome wasn’t built in a day. Neither can you pick up a language; unless your day has 10000 hours (or ~2 days on Planet Venus).
I came into this learning out of necessity. Here’s what I did to learn and hopefully this helps you as well. I’m curious to know what worked for you as you picked up something new.
Why Golang?
The origin story is undoubtedly from Google.
The goals of the Go project were to eliminate the slowness and clumsiness of software development at Google, and thereby to make the process more productive and scalable. The language was designed by and for people who write—and read and debug and maintain—large software systems.
While I did read typical documentation, I also referred to real-world use cases to understand why a company would make a choice to pick a technology. I read 2 cases that helped me understand the impact of Golang: Stream and Dropbox. Dropbox also mentions a lot more nitty-gritty in their migration to gRPC as well.
Some highlights that I can list:
It’s fast. Benchmarks here.
The way it handles concurrency via goroutines. Goroutines vs Green threads.
Statically typed, compiled language.
In-built testing support without an extra dependency.
Decent package management
While it has its benefits, not every language is the perfect choice for every organization.
Pick a language if the team is familiar with it and has/can build tooling around it. Starting a company/project in an unfamiliar language can waste time.
Does the language do what you want it to do and is it easy to do that thing? If yes, do it.
If you are in a language ecosystem, build common libraries, templates, auto-formatting, and code-generation tooling to improve your ecosystem. Do this regardless of language - it helps in developer productivity.
Learning the basics
It wasn’t the easiest language to learn. I’ll admit I found it quirky. I taught myself Scala, so how harder could it be.
The IDE of choice for me is Intellij Goland.
I started here, the standard documentation. “hello world” happened! Yeah, a foray into a new language. Hardly teaches you anything, but a start, nonetheless.
tree -a
.
├── go.mod
└── hello.go
That poor hello.go held all my basic learning. I mean all of the random things I tried.
// Array creation and printing
names := []string{"john", "joe", "james"}
for _, name := range names {
formatter.Println(name)
}
// Creating a map
mymap := map[string]string{"name": "john", "city": "dublin"}
// Anonymous func
func anonFunc() {
one := func() int {
return 1
}
formatter.Println(one())
}
Although that helped get the really basic stuff in place, the real learning came from Learn Go with Tests.
I’ve never done a tutorial like this before and it helped hit home all the necessary concepts one need with a testing-first approach. It was iterative, and helped you correct and fix code, while also telling you the right way to test and check assumptions.
I had a bunch of these files in a random repo while I learned this.
├── concurrency_test.go
├── context_test.go
├── dependency_injection.go
├── dictionary_test.go
├── go.mod
├── go.sum
Learning to build in Go
While the tutorial did wonders to cement my basic knowledge, it isn’t the real world where you build things and see things break. Basic tutorials can’t cover everything (they shouldn’t either), so there needs to be another learning technique.
Learning by trying and building maybe? But, do you just build a dummy REST API, or do you go full service? I did the latter which had elements of almost everything I needed to learn.
I ran into this post: Go, RabbitMQ, and gRPC Clean Architecture microservice.
This had everything. Informative, took some time to grasp, but all-in-all valuable.
// directory structure
.
├── cmd
├── config
├── docker
├── internal
├── migrations
├── pgdata
├── pkg
└── vendor
To learn, I went ahead to rebuild it from zero by referring to this repository. Some things I managed to learn:
Structuring a go project in a clean way
Error handling
Passing context information
Concepts around async messages (rabbit), open tracing, metrics, and logging.
Building a functional service with tests, mocks, and documentation.
Dealing with goroutines
Configuration management
Data access
gRPC tooling
Some metrics from my experiments with the code (post rewriting). I slammed it with scripts to make a noticeable dent.
Writing an actual service
Iteration is great, but gotta deploy someday right? Writing production-grade code versus random test apps is not even in the same league, so it takes some effort to find that finesse.
While I can’t share specifics of the systems I’ve written, I can tell you it was driven and powered by the learnings in the previous sections. In addition to this, I learned a lot from some prior art and existing best practices.
I’ll share what I learned here though:
Accurately mapping requirements and logic into Go.
Structure the code well with interfaces and clear separation
This helps in cleaner code contracts
Helps in unit testing so you can test individual pieces independently.
Make sure error handling is meaningful and traceable.
Add telemetry wherever possible.
Make sure you follow patterns (repository) to separate your app logic from the data store logic.
Refactor and refactor some more if needed - aim for clarity, DRY, and KISS.
Automate your debug cycle - helps you debug quickly and test changes without much manual intervention.
Use these steps to learn
If you are ever in my position where you need to start learning a language, follow these steps:
Start reading the high level and begin with the initial setup, etc. It will help get you into the ecosystem and start slow.
Learn basics. Function declaration, primitives, basic syntax.
Jump to building some applications. I haven’t tried them out but Gophercises looks promising.
Build a service - emulate or start from scratch and Google away. It’s going to be slow. Maybe go a step ahead and let someone review this code too. Or compare with open-source projects?
Go to prod. Start building stuff that works and solves business problems.
What lies ahead?
I’m never going to be done learning. Can one ever be an expert? I still see people on Twitter claiming to have expertise in a language, only to be corrected by someone else.
10000 hours may give you that base, but expertise takes years and I’m barely anywhere close to reaching that. But, what I want you to take away from this endeavor of mine is that learning by doing helps a lot.
I am going to continue to work on building my skills in Go. And if I ever jump into another language, I’m going to approach it similarly. I’m staring at you Rust.
Until the next post, thanks for reading.
Stay encouraged.