This course is designed to teach students about Go’s concurrency model, as well as how to profile and optimize Go code. It starts with a deep dive into concurrency primitives and covers several concurrency patterns. It will go over several common mistakes that are also made when designing concurrent software.
Then, a full overview of how the benchmarking and profiling tools are used to measure code performance. After mastering the tools, the students will then be shown different ways to use the profiling tools, as well as the compiler to identify and fix common performance problems in Go code.
Everyone will have a strong understanding of concurrency, as well as how to use benchmarking, pprof (profiling tools), and the compiler. Finally, students will spend time learning how to spot performance issues, as well as how to fix them.
At least one year of production experience with another modern programming language and six months of daily Go development.
This module covers general information about your instructor and course materials.
This chapter covers general environment setup and other resource related
information needed to complete the courses contained within.
Package management is essential in creating repeatable builds in your software.
Learn how to add and remove Modules, troubleshoot package dependencies, and
understand the files that control current dependencies. This chapter will also
cover how to properly handle forward and backwards compatibility for dep, Go
Modules, older versions of Go, and more.
Concurrent programming in many environments is made difficult by the subtleties required to implement correct access to shared variables. Go encourages a different approach in which shared values are passed around on channels and, in fact, never actively shared by separate threads of execution.
This chapter will cover concurrency as it pertains to Go, what goroutines are, as well as a basic overview of the scheduler and terminology used.
Go promotes sharing memory by communicating. This chapter covers goroutines and how to synchronize communication between them. Mechanics for synchronization such as WaitGroups and Mutexes are explored along with the corresponding patterns for each.
Channels are a conduit in Go used to communicate between goroutines. This chapter covers basic channel usage along with the corresponding patterns for each. Find out the difference between a buffered and unbuffered channel, and when to use them. Also discover how to use channels for signaling for concepts such as graceful application shutdown.
Testing in Go is easy, and simple to use. There is a strong emphasis on testing
in Go. The compiler will catch a lot of bugs for you, but it can not ensure
your business logic is sound or bug-free.
While the testing package isn't large, there are a lot of features
that are not properly understood. In this chapter we will cover
the following concepts:
Table driven tests can be used to cover a lot of ground quickly while re-using
common setup and comparison code. Table driven testing is not unique to Go,
however, it is very powerful. In this module we will cover the different ways
to create, run, and isolate table driven tests.
Understanding the different options to run tests can greatly reduce the feedback cycle during development. In this chapter, we will cover:
Go comes with a powerful set of tools for profiling and improving the
performance of your code. Benchmarking is one of those tools, and the first
one most developers start with. In this module we will cover basic
benchmarking, some common benchmarking mistakes, and how to compare benchmarks
to see if performance has improved.
Go ships with a number of profiling tools. This chapter will walk you through how to:
Understanding how to use tools like pprof and writing benchmarks is important, but understanding common coding pitfalls and how to spot them with those tools is the end goal.
In this interactive workshop, you will:
This chapter covers where to get more support on Go, recommends books and
videos, and list the contact information for our instructors.
Go has the ability to build and cross compile with ease. This chapter will
cover the different ways to build your binary and additionally covers concepts
for embedding build information such as version and GitHub SHA-1 hash. See how
build tags are used to conditionally include specific branches of code by
targeting specific platforms or simply using the tags provided.
In the standard library there are two mechanisms for us to use to test web applications.
These are not their "official" names, but we believe they do a good job of describing the styles of testing. In this module, we will cover both styles of testing and how to use them.
It's easy to decouple packages in Go using interfaces. Because of this, testing
can also be much easier. However, you typically want to stub out your
interfaces in tests so that unit testing is much easier. This chapter will
cover how to write a stub for a service to enable easy and precise testing.
Many times you may be testing parts of your code that have service dependency
that run for an unknown amount of time.
Examples of these may be task queues, distributed system calls, etc.
Because you don't know how long they may take to execute, testing them can
present some challenges.
In this module we will learn how to set up tests both effectively and
efficiently for testing async processes.
Note: This module assumes the audience is familiar with concepts such as
There are many tools to assist with testing. This chapter will cover the following topics:
No project is complete without great documentation. Example tests are a great
way to not only document your code, but ensure that the examples you use always
work as they are actually a test in addition to the documentation.
Code coverage is a great tool to show what part of your code is being tested. It will
help identify areas that need more testing, as well as assist in making sure your tests
actually test the part of the code you think it does.
Workflow automation can significantly improve developer productivity. This chapter will
show how to implement some very simple, lightweight automation to automatically
run tests and coverage.