go/

directory
Version: v0.0.0-...-86d22a7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2017 License: Apache-2.0

README

Ultimate Go

This is material for any intermediate-level developer who has at least a few months to years of experience writing code in Go. This class provides a very deep knowledge of the programming language with a big push on language mechanics, design philosophies and guidelines. We focus on teaching how to write code with a priority on consistency, integrity, readability and simplicity. We cover a lot about “if performance matters” with a focus on mechanical sympathy, data oriented design, decoupling and writing production software. We close the class with benchmarking, profiling, tracing and debugging. If you want your team to be better Go developers, code reviewers, designers and architects, this is the class they need.

Ultimate Go

Design Guidelines

"An architecture isn't a set of pieces, it's a set of rules about what you can expect of them." - Michael Feathers

You must develop a design philosophy that establishes a set of guidelines. This is more important than developing a set of rules or patterns you apply blindly. Guidelines help to formulate, drive and validate decisions. You can't begin to make the best decisions without understanding the impact of your decisions. Every decision you make, every line of code you write comes with trade-offs.


Prepare Your Mind

Somewhere Along The Line

  • We became impressed with programs that contain large amounts of code.
  • We strived to create large abstractions in our code base.
  • We forgot that the hardware is the platform.
  • We lost the understanding that every decision comes with a cost.

These Days Are Gone

  • We can throw more hardware at the problem.
  • We can throw more developers at the problem.

Aspire To

  • Be a champion for quality, efficiency and simplicity.
  • Have a point of view.
  • Value introspection and self-review.

Open Your Mind

  • Technology changes quickly but people's minds change slowly.
  • Easy to adopt new technology but hard to adopt new ways of thinking.

Legacy Software

Do you care about the legacy you are leaving behind?

"There are two kinds of software projects: those that fail, and those that turn into legacy horrors." - Peter Weinberger (inventor of AWK)

"Legacy software is an unappreciated but serious problem. Legacy code may be the downfall of our civilization." - Chuck Moore (inventor of Forth)


Productivity vs Performance

Productivity and performance both matter, but in the past you couldn’t have both. You needed to choose one over the other. We naturally gravitated to productivity, with the idea or hope that the hardware would resolve our performance problems for free. This movement towards productivity has resulted in the design of programming languages that produce sluggish software that is out pacing the hardware’s ability to make them faster.

By following Go’s idioms and a few guidelines, we can write code that can be reasoned about by anyone who looks at it. We can write software that simplifies, minimizes and reduces the amount of code we need to solve the problems we are working on. We don’t have to choose productivity over performance or performance over productivity anymore. We can have both.

Quotes

"The hope is that the progress in hardware will cure all software ills. However, a critical observer may observe that software manages to outgrow hardware in size and sluggishness. Other observers had noted this for some time before, indeed the trend was becoming obvious as early as 1987." - Niklaus Wirth

"The most amazing achievement of the computer software industry is its continuing cancellation of the steady and staggering gains made by the computer hardware industry." - Henry Petroski (2015)

"The hardware folks will not put more cores into their hardware if the software isn’t going to use them, so, it is this balancing act of each other staring at each other, and we are hoping that Go is going to break through on the software side.” - Rick Hudson (2015)

"C is the best balance I've ever seen between power and expressiveness. You can do almost anything you want to do by programming fairly straightforwardly and you will have a very good mental model of what's going to happen on the machine; you can predict reasonably well how quickly it's going to run, you understand what's going on .... - Brian Kernighan (2000)

"The trend in programming language design has been to create languages that enhance software reliability and programmer productivity. What we should do is develop languages alongside sound software engineering practices so the task of developing reliable programs is distributed throughout the software lifecycle, especially into the early phases of system design." - Al Aho (2009)


Correctness vs Performance

You want to write code that is optimized for correctness. Don't make coding decisions based on what you think might perform better. You must benchmark or profile to know if code is not fast enough. Then and only then should you optimize for performance. This can't be done until you have something working.

Improvement comes from writing code and thinking about the code you write. Then refactoring the code to make it better. This requires the help of other people to also read the code you are writing. Prototype ideas first to validate them. Try different approaches or ask others to attempt a solution. Then compare what you have learned.

Too many developers are not prototyping their ideas first before writing production code. It is through prototyping that you can validate your thoughts, ideas and designs. This is the time when you can break down walls and figure out how things work. Prototype in the concrete and consider contracts after you have a working prototype.

Refactoring must become part of the development cycle. Refactoring is the process of improving the code from the things that you learn on a daily basis. Without time to refactor, code will become impossible to manage and maintain over time. This creates the legacy issues we are seeing today.

Quotes

"The correctness of the implementation is the most important concern, but there is no royal road to correctness. It involves diverse tasks such as thinking of invariants, testing and code reviews. Optimization should be done, but not prematurely." - Al Aho (inventor of AWK)

"The basic ideas of good style, which are fundamental to write clearly and simply, are just as important now as they were 35 years ago. Simple, straightforward code is just plain easier to work with and less likely to have problems. As programs get bigger and more complicated, it's even more important to have clean, simple code." - Brian Kernighan

"Unless the developer has a really good idea of what the software is going to be used for, there's a very high probability that the software will turn out badly. If the developers don't know and understand the application well, then it's crucial to get as much user input and experience as possible." - Brian Kernighan

"The hardest bugs are those where your mental model of the situation is just wrong, so you can't see the problem at all" - Brian Kernighan

"Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?" - Brian Kernighan

Resources:

Prototype your design! - Robert Griesemer


Code Reviews

You can't look at a piece of code, function or algorithm and determine if it smells good or bad without a design philosophy. These four major categories are the basis for code reviews and should be prioritized in this order: Integrity, Readability, Simplicity and then Performance. You must consciously and with great reason be able to explain the category you are choosing.

"The software business is one of the few places we teach people to write before we teach them to read". - Tom Love (inventor of Objective C)


Integrity

We need to become very serious about reliability.

There are two driving forces behind integrity:

  • Integrity is about every allocation, read and write of memory being accurate, consistent and efficient. The type system is critical to making sure we have this micro level of integrity.
  • Integrity is about every data transformation being accurate, consistent and efficient. Writing less code and error handling is critical to making sure we have this macro level of integrity.

Write Less Code:

There have been studies that have researched the number of bugs you can expect to have in your software. The industry average is around 15 to 50 bugs per 1000 lines of code. One simple way to reduce the number of bugs, and increase the integrity of your software, is to write less code.

Bjarne Stroustrup stated that writing more code than you need results in Ugly, Large and Slow code:

  • Ugly: Leaves places for bugs to hide.
  • Large: Ensures incomplete tests.
  • Slow: Encourages the use of shortcuts and dirty tricks.

Error Handling:

When error handling is treated as an exception and not part of the main code, you can expect the majority of your critical failures to be due to error handling.

48 critical failures were found in a study looking at a couple hundred bugs in Cassandra, HBase, HDFS, MapReduce, and Redis.

  • 92% : Failures from bad error handling
    • 35% : Incorrect handling
      • 25% : Simply ignoring an error
      • 8% : Catching the wrong exception
      • 2% : Incomplete TODOs
    • 57% System specific
      • 23% : Easily detectable
      • 34% : Complex bugs
  • 8% : Failures from latent human errors

Ignorance vs Carelessness:

Anytime we identify an integrity issue we need to ask ourselves why it happened.

                    Not Deliberate               Deliberate
              ------------------------------------------------------
              |                          |                         |
              |                          |                         |
   Ignorance  |  Learning / Prototyping  |    Hacking / Guessing   |
              |                          |                         |
              |                          |                         |
              |-----------------------------------------------------
              |                          |                         |
              |                          |                         |
Carelessness  |        Education         |   Dangerous Situation   |
              |                          |                         |
              |                          |                         |
              ------------------------------------------------------

Resources:

Software Development for Infrastructure - Bjarne Stroustrup
Normalization of Deviance in Software - danluu.com
Lessons learned from reading postmortems - danluu.com
Technical Debt Quadrant - Martin Fowler
Design Philosophy On Integrity - William Kennedy
Ratio of bugs per line of code - Dan Mayer
Masterminds of Programming - Federico Biancuzzi and Shane Warden
Developing Software The Right Way, with Intent and Carefulness - David Gee


Readability

We must structure our systems to be more comprehensible.

This is about writing simple code that is easy to read and understand without the need of mental exhaustion. Just as important, it's about not hiding the cost/impact of the code per line, function, package and the overall ecosystem it runs in.

Example Readability Issue

Real Machine

"A well-designed language has a one-one correlation between source code and object code. It's obvious to the programmer what code will be generated from their source. This provides its own satisfaction, is efficient, and reduces the need for documentation." - Chuck Moore (inventor of Forth)

In Go, the underlying machine is the real machine rather than a single abstract machine. The model of computation is that of the computer. Here is the key, Go gives you direct access to the machine while still providing abstraction mechanisms to allow higher-level ideas to be expressed.

Mental Models

"Let's imagine a project that's going to end up with a million lines of code or more. The probability of those projects being successful in the United States these days is very low - well under 50%. That's debatable. - Tom Love (inventor of Objective C)

100k lines of code fit inside a box of paper. - Tom Love (inventor of Objective C)

How much code in that box do you think you can maintain a mental model of in your head? I believe asking a single developer to maintain a mental model of more than one ream of paper in that box (~10k lines of code) is asking a lot. If you do the math, then it takes a team of 100 people to work on a code base that hits a million lines of code. That is 100 people that need to be coordinated, grouped, tracked and in a constant feedback loop of communication.

Average Developer

"Can you explain it to the median user (developer)? as opposed to will the smartest user (developer) figure it out?" - Peter Weinberger (inventor of AWK)

You must be aware of who you are on your team. When hiring new people, you must be aware of where they fall. The code must be written for the average developer to comprehend. If you are below average, you have the responsibility to come up to speed. If you are the expert, you have the responsbility to reduce being clever.


Simplicity

We must understand that simplicity is hard to design and complicated to build.

This is about hiding complexity. A lot of care and design must go into simplicity because this can cause more problems then good. It can create issues with readability and it can cause issues with performance.

Simple, But Not Simpler

"Everything should be made as simple as possible, but not simpler." - Albert Einstein

Focus on encapsulation and validate that you're not generalizing or even being too concise. You might think you are helping the programmer or the code but validate things are still easy to use, understand, debug and maintain.

Encapsulation

Paraphrasing: "Encapsulation and the separation of concerns are drivers for designing software. This is largely based on how other industries handle complexity. There seems to be a human pattern of using encapsulation to wrestle complexity to the ground." - Brad Cox (inventor of Objective C)

"The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise - Edsger W. Dijkstra

Encapsulation is what we have been trying to figure out as an industry for 40 years. Go is taking a slightly new approach with the package. Brining encapsulation up a level and providing richer support at the language level.

Resources:

Simplicity is Complicated - Rob Pike


Performance

We must compute less to get the results we need.

This is about not wasting effort and achieving execution efficiency. Writing code that is mechanically sympathetic with the runtime, operating system and hardware. Achieving performance by writing less and more efficient code but staying within the idioms and framework of the language.

"Programmers waste enormous amounts of time thinking about, or worrying about, the speed of non-critical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%." — Donald E. Knuth

"I don't trust anything until it runs... In fact, I don't trust anything until it runs twice." - Andrew Gelman (one of the greatest living statisticians at Columbia University).

Rules of Performance:
* Never guess about performance.
* Measurements must be relevant.
* Profile before you decide something is performance critical.
* Test to know you are correct.

Example Benchmark

Broad Engineering

"When we're computer programmers we're concentrating on the intricate little fascinating details of programming and we don't take a broad engineering point of view about trying to optimize the total system. You try to optimize the bits and bytes." - Tom Kurtz (inventor of BASIC)

Performance is important but it can't be your priority unless the code is not running fast enough. You only know this once you have a working program and you have validated it. We place those who we think know how to write performant code on a pedestal. We need to put those who write code that is optimized for correctness and performs fast enough on those pedestals.


Micro-Optimizations

Micro-Optimizations are about squeezing every ounce of performance as possible. When code is written with this as the priority, it is very difficult to write code that is readable, simple or idiomatic. You are writing clever code that may require the unsafe package or you may need to drop into assembly.

Example Micro Optimization


Data-Oriented Design

Design Philosophy:

  • If you don't understand the data, you don't understand the problem.
  • All problems are unique and specific to the data you are working with.
  • Data transformations are at the heart of solving problems. Each function, method and work-flow must focus on implementing the specific data transformations required to solve the problems.
  • If your data is changing, your problems are changing. When your problems are changing, the data transformations needs to change with it.
  • Uncertainty about the data is not a license to guess but a directive to STOP and learn more.
  • Solving problems you don't have, creates more problems you now do.
  • If performance matters, you must have mechanical sympathy for how the hardware and operating system work.
  • Minimize, simplify and REDUCE the amount of code required to solve each problem. Do less work by not wasting effort.
  • Code that can be reasoned about and does not hide execution costs can be better understood, debugged and performance tuned.
  • Coupling data together and writing code that produces predictable access patterns to the data will be the most performant.
  • Changing data layouts can yield more significant performance improvements than changing just the algorithms.
  • Efficiency is obtained through algorithms but performance is obtained through data structures and layouts.

Resources:

Data-Oriented Design and C++ - Mike Acton
Efficiency with Algorithms, Performance with Data Structures - Chandler Carruth


Interface And Composition Design

Design Philosophy:

  • Interfaces give programs structure.
  • Interfaces encourage design by composition.
  • Interfaces enable and enforce clean divisions between components.
    • The standardization of interfaces can set clear and consistent expectations.
  • Decoupling means reducing the dependencies between components and the types they use.
    • This leads to correctness, quality and performance.
  • Interfaces allow you to group concrete types by what they do.
    • Don't group types by a common DNA but by a common behavior.
    • Everyone can work together when we focus on what we do and not who we are.
  • Interfaces help your code decouple itself from change.
    • You must do your best to understand what could change and use interfaces to decouple.
    • Interfaces with more than one method have more than one reason to change.
    • Uncertainty about change is not a license to guess but a directive to STOP and learn more.
  • You must distinguish between code that:
    • defends against fraud vs protects against accidents

Validation:

Use an interface when:

  • users of the API need to provide an implementation detail.
  • API’s have multiple implementations they need to maintain internally.
  • parts of the API that can change have been identified and require decoupling.

Don't use an interface:

  • for the sake of using an interface.
  • to generalize an algorithm.
  • when users can declare their own interfaces.
  • if it's not clear how the interface makes the code better.

Resources:

Methods, interfaces and Embedding - William Kennedy
Composition with Go - William Kennedy
Reducing type hierarchies - William Kennedy
Interface pollution in Go - Burcu Dogan
Application Focused API Design - William Kennedy
Avoid interface pollution - William Kennedy


Package-Oriented Design

Package Oriented Design allows a developer to identify where a package belongs inside a Go project and the design guidelines the package must respect. It defines what a Go project is and how a Go project is structured. Finally, it improves communication between team members and promotes clean package design and project architecture that is discussable.

Learn More


Concurrent Software Design

Concurrency is about managing multiple things at once. Like one person washing the dishes while they are also cooking dinner. You're making progress on both but you're only ever doing one of those things at the same time. Parallelism is about doing multiple things at once. Like one person cooking and placing dirty dishes in the sink, while another washes the dishes. They are happening at the same time.

Both you and the runtime have a responsibility in managing the concurrency of the application. You are responsible for managing these three things when writing concurrent software:

Design Philosophy:

  • The application must startup and shutdown with integrity.
    • Know how and when every goroutine you create terminates.
    • All goroutines you create should terminate before main returns.
    • Applications should be capable of shutting down on demand, even under load, in a controlled way.
      • You want to stop accepting new requests and finish the requests you have (load shedding).
  • Identify and monitor critical points of back pressure that can exist inside your application.
    • Channels, mutexes and atomic functions can create back pressure when goroutines are required to wait.
    • A little back pressure is good, it means there is a good balance of concerns.
    • A lot of back pressure is bad, it means things are imbalanced.
    • Back pressure that is imbalanced will cause:
      • Failures inside the software and across the entire platform.
      • Your application to collapse, implode or freeze.
    • Measuring back pressure is a way to measure the health of the application.
  • Rate limit to prevent overwhelming back pressure inside your application.
    • Every system has a breaking point, you must know what it is for your application.
    • Applications should reject new requests as early as possible once they are overloaded.
      • Don’t take in more work than you can reasonably work on at a time.
      • Push back when you are at critical mass. Create your own external back pressure.
    • Use an external system for rate limiting when it is reasonable and practical.
  • Use timeouts to release the back pressure inside your application.
    • No request or task is allowed to take forever.
    • Identify how long users are willing to wait.
    • Higher-level calls should tell lower-level calls how long they have to run.
    • At the top level, the user should decide how long they are willing to wait.
    • Use the Context package.
      • Functions that users wait for should take a Context.
        • These functions should select on <-ctx.Done() when they would otherwise block indefinitely.
      • Set a timeout on a Context only when you have good reason to expect that a function's execution has a real time limit.
      • Allow the upstream caller to decide when the Context should be canceled.
      • Cancel a Context whenever the user abandons or explicitly aborts a call.
  • Architect applications to:
    • Identify problems when they are happening.
    • Stop the bleeding.
    • Return the system back to a normal state.

Channel Design

Channels allow goroutines to communicate with each other through the use of signaling semantics. Channels accomplish this signaling through the use of sending/receiving data or by identifying state changes on individual channels. Don't architect software with the idea of channels being a queue, focus on signaling and the semantics that simplify the orchestration required.

Language Mechanics:

  • Use channels to orchestrate and coordinate goroutines.
    • Focus on the signaling semantics and not the sharing of data.
    • Signaling with data or without data.
    • Question their use for synchronizing access to shared state.
      • There are cases where channels can be simpler for this but initially question.
  • Unbuffered channels:
    • Receive happens before the Send.
    • Benefit: 100% guarentee the signal has been received.
    • Cost: Unknown latency on when the signal will be received.
  • Buffered channels:
    • Send happens before the Receive.
    • Benefit: Reduce blocking latency between signaling.
    • Cost: No guarentee when the signal has been received.
      • The larger the buffer, the less guarentee.
      • Buffer of 1 can give you one delayed send of guarentee.
  • Closing channels:
    • Close happens before the Receive. (like Buffered)
    • Signaling without data.
    • Perfect for signaling cancellations and deadlines.
  • NIL channels:
    • Send and Receive block.
    • Turn off signaling
    • Perfect for rate limiting or short term stoppages.

Design Philosophy:

Depending on the problem you are solving, you may require different channel semantics. Depending on the semantics you need, different architectural choices must be taken.

  • If any given Send on a channel CAN cause the sending goroutine to block:
    • Not allowed to use a Buffered channel larger than 1.
      • Buffers larger than 1 must have reason/measurements.
    • Must know what happens when the sending goroutine blocks.
  • If any given Send on a channel WON'T cause the sending goroutine to block:
    • You have the exact number of buffers for each send.
      • Fan Out pattern
    • You have the buffer measured for max capacity.
      • Drop pattern
  • Less is more with buffers.
    • Don’t think about performance when thinking about buffers.
    • Buffers can help to reduce blocking latency between signaling.
      • Reducing blocking latency towards zero does not necessarily mean better throughput.
      • If a buffer of one is giving you good enough throughput then keep it.
      • Question buffers that are larger than one and measure for size.
      • Find the smallest buffer possible that provides good enough throughput.

Directories

Path Synopsis
concurrency
channels/advanced/example1
Sample program to show the order of channel communication for unbuffered, buffered and closing channels based on the specification.
Sample program to show the order of channel communication for unbuffered, buffered and closing channels based on the specification.
channels/example1
This sample program demonstrates the basic channel mechanics for goroutine signaling.
This sample program demonstrates the basic channel mechanics for goroutine signaling.
channels/example2
Sample program to show how to use an unbuffered channel to simulate a game of tennis between two goroutines.
Sample program to show how to use an unbuffered channel to simulate a game of tennis between two goroutines.
channels/example3
Sample program to show how to use an unbuffered channel to simulate a relay race between four goroutines.
Sample program to show how to use an unbuffered channel to simulate a relay race between four goroutines.
channels/example4
This sample program demonstrates how to use a buffered channel to receive results from other goroutines in a guaranteed way.
This sample program demonstrates how to use a buffered channel to receive results from other goroutines in a guaranteed way.
channels/example5
This sample program demonstrates how to use a channel to monitor the amount of time the program is running and terminate the program if it runs too long.
This sample program demonstrates how to use a channel to monitor the amount of time the program is running and terminate the program if it runs too long.
channels/exercises/exercise1
Write a program where two goroutines pass an integer back and forth ten times.
Write a program where two goroutines pass an integer back and forth ten times.
channels/exercises/exercise2
Write a program that uses a fan out pattern to generate 100 random numbers concurrently.
Write a program that uses a fan out pattern to generate 100 random numbers concurrently.
channels/exercises/template1
Write a program where two goroutines pass an integer back and forth ten times.
Write a program where two goroutines pass an integer back and forth ten times.
channels/exercises/template2
Write a program that uses a fan out pattern to generate 100 random numbers concurrently.
Write a program that uses a fan out pattern to generate 100 random numbers concurrently.
data_race/advanced/example1
Sample program to show a more complicated race condition using an interface value.
Sample program to show a more complicated race condition using an interface value.
data_race/example1
Sample program to show how to create race conditions in our programs.
Sample program to show how to create race conditions in our programs.
data_race/example2
Sample program to show how to use the atomic package to provide safe access to numeric types.
Sample program to show how to use the atomic package to provide safe access to numeric types.
data_race/example3
Sample program to show how to use a mutex to define critical sections of code that need synchronous access.
Sample program to show how to use a mutex to define critical sections of code that need synchronous access.
data_race/example4
Sample program to show how to use a read/write mutex to define critical sections of code that needs synchronous access.
Sample program to show how to use a read/write mutex to define critical sections of code that needs synchronous access.
data_race/exercises/exercise1
Answer for exercise 1 of Race Conditions.
Answer for exercise 1 of Race Conditions.
data_race/exercises/template1
Fix the race condition in this program.
Fix the race condition in this program.
goroutines/example1
Sample program to show how to create goroutines and how the scheduler behaves.
Sample program to show how to create goroutines and how the scheduler behaves.
goroutines/example2
Sample program to show how the goroutine scheduler will time slice goroutines on a single thread.
Sample program to show how the goroutine scheduler will time slice goroutines on a single thread.
goroutines/example3
Sample program to show how to create goroutines and how the goroutine scheduler behaves with two contexts.
Sample program to show how to create goroutines and how the goroutine scheduler behaves with two contexts.
goroutines/exercises/exercise1
Create a program that declares two anonymous functions.
Create a program that declares two anonymous functions.
goroutines/exercises/template1
Create a program that declares two anonymous functions.
Create a program that declares two anonymous functions.
patterns/chat
Package chat implements a basic chat room.
Package chat implements a basic chat room.
patterns/chat/main
This sample program demonstrates how to create a simple chat system.
This sample program demonstrates how to create a simple chat system.
patterns/logger
Package logger shows a pattern of using a buffer to handle log write continuity by dealing with write latencies by throwing away log data.
Package logger shows a pattern of using a buffer to handle log write continuity by dealing with write latencies by throwing away log data.
patterns/logger/main
This sample program demonstrates how the logger package works.
This sample program demonstrates how the logger package works.
patterns/pool
Package pool manages a user defined set of resources.
Package pool manages a user defined set of resources.
patterns/pool/main
This sample program demonstrates how to use the pool package to share a simulated set of database connections.
This sample program demonstrates how to use the pool package to share a simulated set of database connections.
patterns/task
Package task provides a pool of goroutines to perform tasks.
Package task provides a pool of goroutines to perform tasks.
patterns/task/main
This sample program demonstrates how to use the work package to use a pool of goroutines to get work done.
This sample program demonstrates how to use the work package to use a pool of goroutines to get work done.
design
composition/assertions/example1
Sample program demonstrating when implicit interface conversions are provided by the compiler.
Sample program demonstrating when implicit interface conversions are provided by the compiler.
composition/assertions/example2
Sample program demonstrating that type assertions are a runtime and not compile time construct.
Sample program demonstrating that type assertions are a runtime and not compile time construct.
composition/decoupling/example1
Sample program demonstrating struct composition.
Sample program demonstrating struct composition.
composition/decoupling/example2
Sample program demonstrating decoupling with interfaces.
Sample program demonstrating decoupling with interfaces.
composition/decoupling/example3
Sample program demonstrating interface composition.
Sample program demonstrating interface composition.
composition/decoupling/example4
Sample program demonstrating decoupling with interface composition.
Sample program demonstrating decoupling with interface composition.
composition/decoupling/example5
Sample program demonstrating removing interface pollution.
Sample program demonstrating removing interface pollution.
composition/exercises/exercise1
Using the template, declare a set of concrete types that implement the set of predefined interface types.
Using the template, declare a set of concrete types that implement the set of predefined interface types.
composition/grouping/example1
This is an example of using type hierarchies with a OOP pattern.
This is an example of using type hierarchies with a OOP pattern.
composition/grouping/example2
This is an example of using composition and interfaces.
This is an example of using composition and interfaces.
composition/mocking/example1
Sample program to show how you can personally mock concrete types when you need to for your own packages or tests.
Sample program to show how you can personally mock concrete types when you need to for your own packages or tests.
composition/mocking/example1/pubsub
Package pubsub simulates a package that provides publication/subscription type services.
Package pubsub simulates a package that provides publication/subscription type services.
composition/pollution/example1
This is an example that creates interface pollution by improperly using an interface when one is not needed.
This is an example that creates interface pollution by improperly using an interface when one is not needed.
composition/pollution/example2
This is an example that removes the interface pollution by removing the interface and using the concrete type directly.
This is an example that removes the interface pollution by removing the interface and using the concrete type directly.
error_handling/example1
Sample program to show how the default error type is implemented.
Sample program to show how the default error type is implemented.
error_handling/example2
Sample program to show how to use error variables to help the caller determine the exact error being returned.
Sample program to show how to use error variables to help the caller determine the exact error being returned.
error_handling/example3
http://golang.org/src/pkg/encoding/json/decode.go Sample program to show how to implement a custom error type based on the json package in the standard library.
http://golang.org/src/pkg/encoding/json/decode.go Sample program to show how to implement a custom error type based on the json package in the standard library.
error_handling/example4
Package example5 provides code to show how to implement behavior as context.
Package example5 provides code to show how to implement behavior as context.
error_handling/example5
Sample program to show see if the class can find the bug.
Sample program to show see if the class can find the bug.
error_handling/example5/reason
Sample program to show see if the class can find the bug.
Sample program to show see if the class can find the bug.
error_handling/example6
Sample program to show how wrapping errors work.
Sample program to show how wrapping errors work.
error_handling/exercises/exercise1
Create two error variables, one called ErrInvalidValue and the other called ErrAmountTooLarge.
Create two error variables, one called ErrInvalidValue and the other called ErrAmountTooLarge.
error_handling/exercises/exercise2
Create a custom error type called appError that contains three fields, err error, message string and code int.
Create a custom error type called appError that contains three fields, err error, message string and code int.
error_handling/exercises/template1
Create two error variables, one called ErrInvalidValue and the other called ErrAmountTooLarge.
Create two error variables, one called ErrInvalidValue and the other called ErrAmountTooLarge.
error_handling/exercises/template2
Create a custom error type called appError that contains three fields, err error, message string and code int.
Create a custom error type called appError that contains three fields, err error, message string and code int.
language
arrays/example1
Sample program to show how to declare and iterate over arrays of different types.
Sample program to show how to declare and iterate over arrays of different types.
arrays/example2
Sample program to show how arrays of different sizes are not of the same type.
Sample program to show how arrays of different sizes are not of the same type.
arrays/example3
Sample program to show how the behavior of the for range and how memory for an array is contiguous.
Sample program to show how the behavior of the for range and how memory for an array is contiguous.
arrays/example4
Sample program to show how the for range has both value and pointer semantics.
Sample program to show how the for range has both value and pointer semantics.
arrays/exercises/exercise1
Declare an array of 5 strings with each element initialized to its zero value.
Declare an array of 5 strings with each element initialized to its zero value.
arrays/exercises/template1
Declare an array of 5 strings with each element initialized to its zero value.
Declare an array of 5 strings with each element initialized to its zero value.
constants/example1
Sample program to show how to declare constants and their implementation in Go.
Sample program to show how to declare constants and their implementation in Go.
constants/example2
Sample program to show how constants do have a parallel type system.
Sample program to show how constants do have a parallel type system.
constants/example3
Sample program to show how iota works.
Sample program to show how iota works.
constants/example4
Sample program to show how literal, constant and variables work within the scope of implicit conversion.
Sample program to show how literal, constant and variables work within the scope of implicit conversion.
constants/exercises/exercise1
Declare an untyped and typed constant and display their values.
Declare an untyped and typed constant and display their values.
constants/exercises/template1
Declare an untyped and typed constant and display their values.
Declare an untyped and typed constant and display their values.
embedding/example1
Sample program to show how what we are doing is NOT embedding a type but just using a type as a field.
Sample program to show how what we are doing is NOT embedding a type but just using a type as a field.
embedding/example2
Sample program to show how to embed a type into another type and the relationship between the inner and outer type.
Sample program to show how to embed a type into another type and the relationship between the inner and outer type.
embedding/example3
Sample program to show how embedded types work with interfaces.
Sample program to show how embedded types work with interfaces.
embedding/example4
Sample program to show what happens when the outer and inner type implement the same interface.
Sample program to show what happens when the outer and inner type implement the same interface.
embedding/exercises/exercise1
Copy the code from the template.
Copy the code from the template.
embedding/exercises/template1
Copy the code from the template.
Copy the code from the template.
exporting/example1
Sample program to show how to access an exported identifier.
Sample program to show how to access an exported identifier.
exporting/example1/counters
Package counters provides alert counter support.
Package counters provides alert counter support.
exporting/example2
Sample program to show how the program can't access an unexported identifier from another package.
Sample program to show how the program can't access an unexported identifier from another package.
exporting/example2/counters
Package counters provides alert counter support.
Package counters provides alert counter support.
exporting/example3
Sample program to show how the program can access a value of an unexported identifier from another package.
Sample program to show how the program can access a value of an unexported identifier from another package.
exporting/example3/counters
Package counters provides alert counter support.
Package counters provides alert counter support.
exporting/example4
Sample program to show how unexported fields from an exported struct type can't be accessed directly.
Sample program to show how unexported fields from an exported struct type can't be accessed directly.
exporting/example4/users
Package users provides support for user management.
Package users provides support for user management.
exporting/example5
Sample program to show how to create values from exported types with embedded unexported types.
Sample program to show how to create values from exported types with embedded unexported types.
exporting/example5/users
Package users provides support for user management.
Package users provides support for user management.
exporting/exercises/exercise1
Create a package named toy with a single exported struct type named Toy.
Create a package named toy with a single exported struct type named Toy.
exporting/exercises/exercise1/toy
Package toy contains support for managing toy inventory.
Package toy contains support for managing toy inventory.
exporting/exercises/template1
Create a package named toy with a single exported struct type named Toy.
Create a package named toy with a single exported struct type named Toy.
exporting/exercises/template1/toy
Package toy contains support for managing toy inventory.
Package toy contains support for managing toy inventory.
functions/advanced/example1
Sample program to show how to recover from panics.
Sample program to show how to recover from panics.
functions/example1
Sample program to show how functions can return multiple values while using named and struct types.
Sample program to show how functions can return multiple values while using named and struct types.
functions/example2
Sample program to show how we can use the blank identifier to ignore return values.
Sample program to show how we can use the blank identifier to ignore return values.
functions/example3
Sample program to show some of the mechanics behind the short variable declaration operator redeclares.
Sample program to show some of the mechanics behind the short variable declaration operator redeclares.
functions/example4
Sample program to show how anonymous functions and closures work.
Sample program to show how anonymous functions and closures work.
functions/exercises/exercise1
Declare a struct type to maintain information about a user.
Declare a struct type to maintain information about a user.
functions/exercises/template1
Declare a struct type to maintain information about a user.
Declare a struct type to maintain information about a user.
interfaces/advanced/example1
Sample program that explores how interface assignments work when values are stored inside the interface.
Sample program that explores how interface assignments work when values are stored inside the interface.
interfaces/example1
Sample program to show how polymorphic behavior with interfaces.
Sample program to show how polymorphic behavior with interfaces.
interfaces/example2
Sample program to show how to understand method sets.
Sample program to show how to understand method sets.
interfaces/example3
Sample program to show how you can't always get the address of a value.
Sample program to show how you can't always get the address of a value.
interfaces/example4
Sample program to show how method sets can affect behavior.
Sample program to show how method sets can affect behavior.
interfaces/example5
Sample program to show how the concrete value assigned to the interface is what is stored inside the interface.
Sample program to show how the concrete value assigned to the interface is what is stored inside the interface.
interfaces/exercises/exercise1
Declare an interface named speaker with a method named speak.
Declare an interface named speaker with a method named speak.
interfaces/exercises/template1
Declare an interface named speaker with a method named speak.
Declare an interface named speaker with a method named speak.
maps/example1
Sample program to show how to declare, initialize and iterate over a map.
Sample program to show how to declare, initialize and iterate over a map.
maps/example2
Sample program to show how to declare and initialize a map using a map literal and delete a key.
Sample program to show how to declare and initialize a map using a map literal and delete a key.
maps/example3
Sample program to show how only types that can have equality defined on them can be a map key.
Sample program to show how only types that can have equality defined on them can be a map key.
maps/exercises/exercise1
Declare and make a map of integer values with a string as the key.
Declare and make a map of integer values with a string as the key.
maps/exercises/template1
Declare and make a map of integer values with a string as the key.
Declare and make a map of integer values with a string as the key.
methods/example1
Sample program to show how to declare methods and how the Go compiler supports them.
Sample program to show how to declare methods and how the Go compiler supports them.
methods/example2
Sample program to show how to declare methods against a named type.
Sample program to show how to declare methods against a named type.
methods/example3
Sample program to show how to declare function variables.
Sample program to show how to declare function variables.
methods/example4
Sample program to show how to declare and use function types.
Sample program to show how to declare and use function types.
methods/exercises/exercise1
Declare a struct that represents a baseball player.
Declare a struct that represents a baseball player.
methods/exercises/template1
Declare a struct that represents a baseball player.
Declare a struct that represents a baseball player.
pointers/example1
Sample program to show the basic concept of pass by value.
Sample program to show the basic concept of pass by value.
pointers/example2
Sample program to show the basic concept of using a pointer to share data.
Sample program to show the basic concept of using a pointer to share data.
pointers/example3
Sample program to show the basic concept of using a pointer to share data.
Sample program to show the basic concept of using a pointer to share data.
pointers/example4
Sample program to teach the mechanics of escape analysis.
Sample program to teach the mechanics of escape analysis.
pointers/example5
Sample program to show how stacks grow/change.
Sample program to show how stacks grow/change.
pointers/exercises/exercise1
Declare and initialize a variable of type int with the value of 20.
Declare and initialize a variable of type int with the value of 20.
pointers/exercises/exercise2
Declare a struct type and create a value of this type.
Declare a struct type and create a value of this type.
pointers/exercises/template1
Declare and initialize a variable of type int with the value of 20.
Declare and initialize a variable of type int with the value of 20.
pointers/exercises/template2
Declare a struct type and create a value of this type.
Declare a struct type and create a value of this type.
slices/advanced/example1
Sample program to show how to use a third index slice.
Sample program to show how to use a third index slice.
slices/example1
Sample program to show how the capacity of the slice is not available for use.
Sample program to show how the capacity of the slice is not available for use.
slices/example2
Sample program to show the components of a slice.
Sample program to show the components of a slice.
slices/example3
Sample program to show how to takes slices of slices to create different views of and make changes to the underlying array.
Sample program to show how to takes slices of slices to create different views of and make changes to the underlying array.
slices/example4
Sample program to show how to grow a slice using the built-in function append and how append grows the capacity of the underlying array.
Sample program to show how to grow a slice using the built-in function append and how append grows the capacity of the underlying array.
slices/example5
Sample program to show how one needs to be careful when appending to a slice when you have a reference to an element.
Sample program to show how one needs to be careful when appending to a slice when you have a reference to an element.
slices/example6
Sample program to show how strings have a UTF-8 encoded byte array.
Sample program to show how strings have a UTF-8 encoded byte array.
slices/example7
Sample program to show how to declare and use variadic functions.
Sample program to show how to declare and use variadic functions.
slices/example8
Sample program to show how the for range has both value and pointer semantics.
Sample program to show how the for range has both value and pointer semantics.
slices/exercises/exercise1
Declare a nil slice of integers.
Declare a nil slice of integers.
slices/exercises/template1
Declare a nil slice of integers.
Declare a nil slice of integers.
struct_types/advanced/example1
Sample program to show how struct types align on boundaries.
Sample program to show how struct types align on boundaries.
struct_types/example1
Sample program to show how to declare and initialize struct types.
Sample program to show how to declare and initialize struct types.
struct_types/example2
Sample program to show how to declare and initialize anonymous struct types.
Sample program to show how to declare and initialize anonymous struct types.
struct_types/example3
Sample program to show how variables of an unnamed type can be assigned to variables of a named type, when they are identical.
Sample program to show how variables of an unnamed type can be assigned to variables of a named type, when they are identical.
struct_types/exercises/exercise1
Declare a struct type to maintain information about a user (name, email and age).
Declare a struct type to maintain information about a user (name, email and age).
struct_types/exercises/template1
Declare a struct type to maintain information about a user (name, email and age).
Declare a struct type to maintain information about a user (name, email and age).
variables/example1
Sample program to show how to declare variables.
Sample program to show how to declare variables.
variables/exercises/exercise1
Declare three variables that are initialized to their zero value and three declared with a literal value.
Declare three variables that are initialized to their zero value and three declared with a literal value.
variables/exercises/template1
Declare three variables that are initialized to their zero value and three declared with a literal value.
Declare three variables that are initialized to their zero value and three declared with a literal value.
packages
context/example1
Sample program to show how to store and retrieve values from a context.
Sample program to show how to store and retrieve values from a context.
context/example2
Sample program to show how to use the WithCancel function.
Sample program to show how to use the WithCancel function.
context/example3
Sample program to show how to use the WithDeadline function.
Sample program to show how to use the WithDeadline function.
context/example4
Sample program to show how to use the WithTimeout function of the Context package.
Sample program to show how to use the WithTimeout function of the Context package.
context/example5
Sample program that implements a web request with a context that is used to timeout the request if it takes too long.
Sample program that implements a web request with a context that is used to timeout the request if it takes too long.
context/exercises/exercise1
Sample program that implements a simple web service using the context to handle timeouts and pass context into the request.
Sample program that implements a simple web service using the context to handle timeouts and pass context into the request.
encoding/example1
Sample program to show how to unmarshal a JSON document into a user defined struct type.
Sample program to show how to unmarshal a JSON document into a user defined struct type.
encoding/example2
Sample program to show how to unmarshal a JSON document into a user defined struct type from a file.
Sample program to show how to unmarshal a JSON document into a user defined struct type from a file.
encoding/example3
Sample program to show how to marshal a user defined struct type into a string.
Sample program to show how to marshal a user defined struct type into a string.
encoding/example4
Sample program to show how write a custom Unmarshal and Marshal functions.
Sample program to show how write a custom Unmarshal and Marshal functions.
encoding/exercises/exercise1
Create a file with an array of JSON documents that contain a user name and email address.
Create a file with an array of JSON documents that contain a user name and email address.
encoding/exercises/template1
Create a file with an array of JSON documents that contain a user name and email address.
Create a file with an array of JSON documents that contain a user name and email address.
io/advanced/example1
Sample program to show how io.Writes can be embedded within other Writer calls to perform complex writes.
Sample program to show how io.Writes can be embedded within other Writer calls to perform complex writes.
io/advanced/example2
Sample program that adds a few more features.
Sample program that adds a few more features.
io/example1
Sample program to show how different functions from the standard library use the io.Writer interface.
Sample program to show how different functions from the standard library use the io.Writer interface.
io/example2
Sample program to show how to write a simple version of curl using the io.Reader and io.Writer interface support.
Sample program to show how to write a simple version of curl using the io.Reader and io.Writer interface support.
io/example3
Sample program to show how to use a MultiWriter to perform writes to multiple devices with one write call.
Sample program to show how to use a MultiWriter to perform writes to multiple devices with one write call.
io/example4
Sample program that takes a stream of bytes and looks for the bytes “elvis” and when they are found, replace them with “Elvis”.
Sample program that takes a stream of bytes and looks for the bytes “elvis” and when they are found, replace them with “Elvis”.
io/exercises/exercise1
Download any document from the web and display the content in the terminal and write it to a file at the same time.
Download any document from the web and display the content in the terminal and write it to a file at the same time.
io/exercises/template1
Download any document from the web and display the content in the terminal and write it to a file at the same time.
Download any document from the web and display the content in the terminal and write it to a file at the same time.
logging/example1
Sample program to show how to use the log package from the standard library.
Sample program to show how to use the log package from the standard library.
logging/example2
Sample program to show how to extend the log package from the standard library.
Sample program to show how to extend the log package from the standard library.
logging/exercises/exercise1
Setup a new program to use the log package.
Setup a new program to use the log package.
logging/exercises/template1
Setup a new program to use the log package.
Setup a new program to use the log package.
reflection/exercises/exercise1
Declare a struct type that represents a request for a customer invoice.
Declare a struct type that represents a request for a customer invoice.
reflection/exercises/template1
Declare a struct type that represents a request for a customer invoice.
Declare a struct type that represents a request for a customer invoice.
reflection/inspect/integer
Example shows how to use reflection to decode an integer.
Example shows how to use reflection to decode an integer.
reflection/inspect/struct
Example shows how to inspect a structs fields and display the field name, type and value.
Example shows how to inspect a structs fields and display the field name, type and value.
reflection/interface/map
Example shows how to reflect over a map of struct type values that are stored inside an interface value.
Example shows how to reflect over a map of struct type values that are stored inside an interface value.
reflection/interface/pointer
Example shows how to reflect over a struct type pointer that is stored inside an interface value.
Example shows how to reflect over a struct type pointer that is stored inside an interface value.
reflection/interface/slice
Example shows how to reflect over a slice of struct type values that are stored inside an interface value.
Example shows how to reflect over a slice of struct type values that are stored inside an interface value.
reflection/interface/struct
Example shows how to reflect over a struct type value that is stored inside an interface value.
Example shows how to reflect over a struct type value that is stored inside an interface value.
reflection/tag
Example shows how to reflect on a struct type with tags.
Example shows how to reflect on a struct type with tags.
profiling
godebug
Sample program that implements a simple web service that will allow us to explore how to use the GODEBUG variable.
Sample program that implements a simple web service that will allow us to explore how to use the GODEBUG variable.
http_trace/example1
Sample program to show how the httptrace package provides a number of hooks to gather information during an HTTP round trip about a variety of events.
Sample program to show how the httptrace package provides a number of hooks to gather information during an HTTP round trip about a variety of events.
http_trace/example2
Sample program to show how to use the http trace with a unique Client and Transport.
Sample program to show how to use the http trace with a unique Client and Transport.
memcpu
Sample program that takes a stream of bytes and looks for the bytes “elvis” and when they are found, replace them with “Elvis”.
Sample program that takes a stream of bytes and looks for the bytes “elvis” and when they are found, replace them with “Elvis”.
pprof
Sample program that implements a simple web service that will allow us to explore how to use the http/pprof tooling.
Sample program that implements a simple web service that will allow us to explore how to use the http/pprof tooling.
project
This program provides a sample web service that uses concurrency and channels to perform a coordinated set of asynchronous searches.
This program provides a sample web service that uses concurrency and channels to perform a coordinated set of asynchronous searches.
project/search
Package search manages the searching of results against different news feeds.
Package search manages the searching of results against different news feeds.
project/service
Package service maintains the logic for the web service.
Package service maintains the logic for the web service.
stack_trace/example1
Sample program to show how to read a stack trace.
Sample program to show how to read a stack trace.
stack_trace/example2
Sample program to show how to read a stack trace when it packs values.
Sample program to show how to read a stack trace when it packs values.
stack_trace/example3
Sample program that implements a simple web service that will allow us to explore how to look at core dumps.
Sample program that implements a simple web service that will allow us to explore how to look at core dumps.
trace
Sample program that performs a series of I/O related tasks to better understand tracing in Go.
Sample program that performs a series of I/O related tasks to better understand tracing in Go.
testing
benchmarks/caching
Package caching provides code to show why Data Oriented Design matters.
Package caching provides code to show why Data Oriented Design matters.
fuzzing/example1
Package api provides an example on how to use go-fuzz.
Package api provides an example on how to use go-fuzz.
fuzzing/exercises/exercise1
Package fuzzprot provides the ability to unpack user values from our binary protocol.
Package fuzzprot provides the ability to unpack user values from our binary protocol.
tests/example4
Sample program that implements a simple web service.
Sample program that implements a simple web service.
tests/example4/handlers
Package handlers provides the endpoints for the web service.
Package handlers provides the endpoints for the web service.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL