Mastering Go Training

Mastering Go was designed for teams that already have significant programming experience and have a Go project in flight or upcoming that needs to quickly master the Go programming language. It will start with the fundamentals, and quickly move into the more advanced topics and patterns that surround the Go programming ecosystem.

Length

10 days. Each day is 4 hours long including a 15 minute break.

Class Size

10 - 25 students. Need a larger or smaller class, just contact us for a custom quote.

Target Audience

  • You have little to no Go experience.
  • You have a current or upcoming project that will be written in Go.
  • You are an experienced developer that has a strong grasp of other programming languages.
  • You are looking to learn advanced concurrency patterns.
  • You want to learn more advanced Go testing patterns, such as asynchronous testing, mocking, stubbing, etc.
  • You want to learn how to profile your Go code and improve performance.
  • You want to learn how to create Web API's in Go

Prerequisites

  • Familiarity and comfort navigating and basic file manipulation at the command line.
  • Familiarity and comfort with a modern code editor, including creating and modifying files and projects.
  • You have at least 3-5 years of experience with other modern development languages such as Java, C#, Swift, JavaScript, Python, Rust, etc.
  • Familiarity with basic programming concepts and structures such as variables, loops, conditionals, etc.
  • Computers should be capable of modern software development, such as access to install and run binaries, install a code editor, etc. Full instructions referenced here: preparing your environment for Go development. It may be necessary for them to have root/admin access to their computer.

Recommended Preparation

  • Install and configure an editor for Go.
  • Have a functioning Go environment installed with Go 1.13 or later.
  • Sign up for a Github account if you don't already have one.
  • Install GraphViz (needed for generating Go profiles).

Suggested Followup Learning

Expected Outcomes

  • Students will be able read and understand Go syntax.
  • Students will be able to spot common coding pitfalls in Go and correct them.
  • Students will understand the internals of Slices and how to use them properly.
  • Students will understand how to write idiomatic Go using core principles such as embedding and interfaces.
  • Students will have a strong understanding of concurrency and how to apply it to their projects.
  • Students will understand how to create proper tests, including table tests.
  • Students will be able understand and create advanced concurrent Go patterns.
  • Students will understand how to create tests for asynchronous (concurrent) code.
  • Students will be able to stub out Go structures for better unit testing.
  • Students will understand the Go test ecosystem, as well as how to configure and run their Go tests efficiently.
  • Students will be able to profile and improve performance of Go code.
  • Students will learn about the structures in the standard library needed to create Web API's.
  • Students will be able to create robust API's in Go.
  • Students will understand the proper patterns needed to create testable, reusable code for Web API's in Go.
  • Students will learn how to deal with JSON as well as create custom JSON implementations.
  • Students will learn how to create unit tests and integration tests for web API's.

Course Details

Day One

Welcome

This module covers general information about your instructor and course materials.

Syntax And Types

In this chapter we will cover the fundamentals of the Go programming language. We will cover the keywords, operators, and delimiters that make up the language, as well as the proper idioms to declare and structure your code. We will also cover data structures (structs) as well as how Go handles default values (zero value). An overview of how strings work in Go, how UTF-8 is handled, and the different types of string literals will also be covered.

Finally, we will learn how to properly declare variables, constants, and how to use iota in Go.

Arrays And Iteration

Arrays in Go are useful when planning for detailed layout of memory. Using arrays can sometimes help avoid allocation. However, their primary use is for the building blocks of slices.

This chapter will cover the basics of creating, initializing, and indexing an array. It will also cover basic loop constructs and loop control basics.

Break

Tea/Coffee Break.

Slices

Slices wrap arrays in Go, and provide a more general, powerful, and convenient interface to data sequences. In this chapter, you will cover slice basics such as creating, initializing, and iteration. You will also learn how to grow a slice, work with subsets of slices, and slice tricks.

Maps

Maps are a powerful built-in data structure that associates keys and values. In this chapter you will cover basic map creation, initialization, and iteration. You will discover how to determine if values exist in maps and how to update and delete map values.

Day Two

Pointers

A pointer is a type that holds the address to the value of a variable. In this chapter we will learn about the difference between pass by value and pass by reference. We will also learn how to declare pointers, and how to reference values as pointers. The chapter will discuss performance and security and when to use pointers as well.

Break

Tea/Coffee Break.

Functions

Functions in Go are a primitive type. This chapter will cover how to declare and call functions. We will also cover how to send zero or many arguments, as well as receive zero or many arguments. Additionally, concepts such as defer, init, closures, and methods will also be discussed.

Day Three

Interfaces

Interfaces in Go provide a way to specify the behavior of an object: If something can do this, then it can be used here. This chapter will take a look at how to use interfaces to abstract that behavior. Concepts such as the Empty Interface, satisfying multiple interfaces, and asserting for behavior will be covered. Additionally, this chapter will cover the difference between value and pointer receivers and how they affect the ability to satisfy an interface.

Break

Tea/Coffee Break.

Embedding And Composition

Go does not provide the typical type-driven notion of subclassing. However, it does have the ability to “borrow” pieces of an implementation by embedding types within a struct or interface. This chapter will cover how promotion from embedding works as well how collision and overriding are handled. We will also walk through how to embed types to be able to satisfy a specific interface.

Day Four

Errors

Error handling in Go can feel a bit tedious at first. However, this chapter will cover the benefits of how Go's error model results in more reliable code. This chapter will also cover how to handle basic errors and return errors as an interface that satisfies the error type. Concepts such as custom error types, panics, recovering from panics, and sentinel errors are also covered.

Concurrency

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.

Break

Tea/Coffee Break.

Concurrency With The Sync Package

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. Additionallywe will cover how to spot common concurrency bugs and tools used to debug them.

Concurrency With Channels

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. Finally, learn how to spot common concurrency pitfalls and how to properly structure your concurrent code for to avoid them.

Day Five

Context

Package context defines the Context type, which carries deadlines, cancelation signals, and other request-scoped values across API boundaries and between processes. Context is used for controlling concurrent subsystems in your application. This chapter will cover the different kinds of behavior with contexts including canceling, timeouts, and values.

Modules And Packages

Package management is essential in creating repeatable builds in your software. In this chapter we will learn how to add and remove Modules, troubleshoot package dependencies, and understand the files that control current dependencies. This chapter will also cover what packages are, and some common approaches for structuring packages in your Go project.

Break

Tea/Coffee Break.

Building And Compiling Go Applications

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.

Tooling

Go ships with a strong suite of built in tools. This chapter will go over the most common tools and how to use them in your daily development workflow. In addition to the tools that ship with Go, there are a set of very important linters and vetters that can catch runtime bugs as well as significantly improve code quality and performance. This chapter shows what those tools are and how to use them.

Testing Basics

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 some features that are not properly understood. In this chapter we will cover the following concepts:

  • *testing.T
  • Error vs. Fatal
  • Failure Messages
  • Helpers
  • Testing Packages

Table Driven Testing

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.

Day Six

Running Tests

Understanding the different options to run tests can greatly reduce the feedback cycle during development. In this chapter, we will cover:

  • Running Specific Tests
  • Verbose Output
  • Failing Fast
  • Parallel Options
  • Short Testing
  • Timing Out Tests
  • Race Conditions

Code Coverage

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.

Break

Tea/Coffee Break.

Example Tests

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.

Stubbing & Mocking Tests

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.

Testing Net/HTTP

In the standard library there are two mechanisms for us to use to test web applications.

  • Unit Style Testing
  • Integration Style Testing

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.

Day Seven

Testing Asynchronous Tasks

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

  • httptest package
  • concurrency primitives such as channels and goroutines

Testing Tooling

There are many tools to assist with testing. This chapter will cover the following topics:

  • Comparing complex structures with go-cmp
  • How to use the testing/quick package
  • Fuzzing your API

Workflow Automation

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.

Break

Tea/Coffee Break.

Testing With IO

Many times the software we design relies on reading and writing data, either to disk, network connections, etc. This chapter will show you how to properly architect your software so that it is easily testable without the need to create temporary files as well as show how to use the io interfaces in your tests.

Benchmarking

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.

Day Eight

Welcome

This module covers general information about your instructor and course materials.

Introduction To Go Web Development

This chapter will cover some basic concepts of web development in Go. We'll cover how to create handlers, set up routing, and launch a basic web server.

HTTP Handlers

Understanding how Go web applications work means understanding the HTTP.Handler interface. This module will cover how Handler, HandlerFunc and ServeHTTP all work together to create the basic building blocks of a Go web service. We will also cover how to create and implement middleware, such as a basic logger and authentication.

Break

Tea/Coffee Break.

Routing And Muxing

Routing in Go requires the use of a "muxer". In this module, we'll explore how to properly set up a muxer to route traffic properly in your web application.

HTML Templates

This module will cover HTML templating with the standard library as well as other popular libraries.

Day Nine

Encoding JSON

Working with JSON in Go can present many challenges. This chapter will cover basic encoding/decoding, how to handle JSON that isn't consistent, as well as mapping JSON to structs.

Production Ready Web Services

This module will go beyond the basics, and introduce concepts for production ready, well behaved, web application and services. This module will talk about how to secure your service, introduce middleware and tracing, as well as show how to organize your code so that testing, mocking, and injection are easily accomplished.

Break

Tea/Coffee Break.

Testing Net/HTTP

In the standard library there are two mechanisms for us to use to test web applications.

  • Unit Style Testing
  • Integration Style Testing

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.

Finalize

This chapter covers where to get more support on Go, recommends books and videos, and list the contact information for our instructors.

Day Ten

Profiling

Go ships with a number of profiling tools. This chapter will walk you through how to:

  • Use interactive pprof with a cpu profile
  • Use interactive pprof with different types of memory profiles
  • Generate profiles from benchmarks
  • Generate profiles from live/running applications
  • Generate torch graphs from benchmarks or live/running applications

Optimizing Go Services

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:

  • Learn several compiler tricks to spot areas for improvement
  • Learn how to properly buffer readers and writers
  • Find and remove unnecessary memory allocations
  • Use flame graphs to identify redundant calls

Break

Tea/Coffee Break.

Tracing

The execution trace captures a wide range of execution events such as goroutine creation/blocking/unblocking, syscall enter/exit/block, GC-related events, changes of heap size, processor start/stop, etc. A precise nanosecond-precision timestamp and a stack trace is captured for most events. The generated trace can be interpreted using go tool trace.

This chapter will walk through how to enable tracing, use the trace tool, and spot performance issues.

Finalize

This chapter covers where to get more support on Go, recommends books and videos, and list the contact information for our instructors.

Subscribe to our newsletter