Mastering Go: Leverage Go’s expertise for advanced utilities, empowering you to develop professional software [4 ed.] 9781805127147

Key Features Fully updated with coverage of web services, TCP/IP, REST APIs, Go Generics, and Fuzzy Testing Apply your n

157 76 2MB

English Pages 808 Year 2024

Report DMCA / Copyright

DOWNLOAD EPUB FILE

Table of contents :
Preface
Who this book is for
What this book covers
To get the most out of this book
Get in touch
A Quick Introduction to Go
Introducing Go
The history of Go
The advantages of Go
When to use Go
My personal Go journey
The go doc and godoc utilities
Hello World!
Introducing functions
Introducing packages
Running Go code
Compiling Go code
Using Go like a scripting language
Important formatting and coding rules
What you should know about Go
Defining and using variables
Constants
Global variables
Printing variables
Controlling program flow
Iterating with for loops and range
Getting user input
Reading from standard input
Working with command line arguments
Using error variables to differentiate between input types
Understanding the Go concurrency model
Developing the which(1) utility in Go
Logging information
log.Fatal() and log.Panic()
Writing to a custom log file
Printing line numbers in log entries
Writing to multiple log files
Developing a statistics application
Summary
Exercises
Additional resources
Basic Go Data Types
The error data type
Numeric data types
Avoiding overflows
Non-numeric data types
Strings, characters, and runes
Converting int to string
The unicode package
The strings package
Times and dates
Working with different time zones
Constants
The constant generator iota
Typed and untyped constants
Grouping similar data
Arrays
Slices
About slice length and capacity
Selecting a part of a slice
Byte slices
Deleting an element from a slice
How slices are connected to arrays
Catching out of bounds errors
The copy() function
Sorting slices
Pointers
Converting a slice to an array or an array pointer
Data types and the unsafe package
Generating random numbers
Generating random strings
Generating secure random numbers
Updating the statistics application
Summary
Exercises
Additional resources
Composite Data Types
Maps
How to tell whether a key exists on a map
Storing to a nil map
Iterating over maps
Structures
The type keyword
Defining new structures
Using the new keyword
Slices of structures
Regular expressions and pattern matching
About regexp.Compile and regexp.MustCompile
Go regular expressions
About raw string and interpreted string literals
Matching names and surnames
Matching integers
Improving the statistics application
Working with CSV files
The updated version of the statistics application
Summary
Exercises
Additional resources
Go Generics
An introduction to generics
Hello, generics!
Constraints
Creating constraints
Supporting underlying data types
Supporting slices of any type
Defining new data types with generics
Using generics in Go structures
The cmp package
The slices package
Shallow and deep copies
The maps package
When to use generics
Summary
Exercises
Additional resources
Reflection and Interfaces
Reflection
Understanding the internal structure of a Go structure
Changing structure values using reflection
The three disadvantages of reflection
Type methods
Creating type methods
Value and point receivers
Using type methods
Interfaces
The sort.Interface interface
The empty interface
Type assertions and type switches
The map[string]interface{} map
The error data type
Writing your own interfaces
Using a Go interface
Object-oriented programming in Go
Interfaces versus generics
Reflection versus generics
Updating the statistics application
Summary
Exercises
Additional resources
Go Packages and Functions
Go packages
About go get and go install
Functions
Anonymous functions
Functions that return multiple values
The return values of a function can be named
Functions that accept other functions as parameters
Functions can return other functions
Variadic functions
The defer keyword
Big O complexity
Developing your own packages
The init() function
Order of execution
Using GitHub to store Go packages
A package for working with SQLite
Working with SQLite3 and Go
Storing the Go package
The design of the Go package
The implementation of the Go package
Testing the Go package
Modules
Creating better packages
Generating documentation
Workspaces
Versioning utilities
Summary
Exercises
Additional resources
Telling a UNIX System What to Do
stdin, stdout, and stderr
UNIX processes
File I/O
The io.Reader and io.Writer interfaces
Using and misusing io.Reader and io.Writer
Buffered and unbuffered file I/O
Reading text files
Reading a text file line by line
Reading a text file word by word
Reading a text file character by character
Reading from /dev/random
Reading a specific amount of data from a file
Writing to a file
Working with JSON
Using Marshal() and Unmarshal()
Structures and JSON
Reading and writing JSON data as streams
Pretty printing JSON records
The viper package
Using command line flags
Reading JSON configuration files
The cobra package
A utility with three commands
Adding command line flags
Creating command aliases
Creating subcommands
Important Go features
Embedding files
ReadDir and DirEntry
The io/fs package
Updating the statistics application
The slog package
Sending logs to io.Discard
Using cobra
Storing and loading JSON data
Implementing the list command
Implementing the insert command
Summary
Exercises
Additional resources
Go Concurrency
Processes, threads, and goroutines
The Go scheduler
The GOMAXPROCS environment variable
Concurrency and parallelism
Goroutines
Creating a goroutine
Creating multiple goroutines
Waiting for all goroutines to finish
What if the number of Add() and Done() calls differ?
Creating multiple files with goroutines
Channels
Writing to and reading from a channel
Receiving from a closed channel
Channels as function parameters
Race conditions are bad
The Go race detector
The select keyword
Timing out a goroutine
Timing out a goroutine inside main()
Timing out a goroutine outside main()
Go channels revisited
Buffered channels
nil channels
Worker pools
Signal channels
Specifying the order of execution for your goroutines
Handling UNIX signals
Handling two signals
Shared memory and shared variables
The sync.Mutex type
What happens if you forget to unlock a mutex?
The sync.RWMutex type
The atomic package
Sharing memory using goroutines
Closured variables and the go statement
The context package
About context.WithCancelCause
The semaphore package
Making the statistics application concurrent
Summary
Exercises
Additional resources
Building Web Services
The net/http package
The http.Response type
The http.Request type
The http.Transport type
Creating a web server
Updating the statistics application
Defining the API
Implementing the handlers
Creating a Docker image
Developing web clients
Using http.NewRequest() to improve the client
Using errGroup
Creating a client for the statistics service
Timing out HTTP connections
Using SetDeadline()
Setting the timeout period on the client side
Setting the timeout period on the server side
Summary
Exercises
Additional resources
Working with TCP/IP and WebSocket
TCP/IP
The nc(1) command line utility
The net package
Developing a TCP client
Developing a TCP client with net.Dial()
Developing a TCP client that uses net.DialTCP()
Developing a TCP server
Developing a TCP server with net.Listen()
Developing a TCP server that uses net.ListenTCP()
Developing a UDP client
Developing a UDP server
Developing concurrent TCP servers
Creating a WebSocket server
The implementation of the server
Using websocat
Creating a WebSocket client
Working with RabbitMQ
Running RabbitMQ
Writing to RabbitMQ
Reading from RabbitMQ
How to remove a module
Summary
Exercises
Additional resources
Working with REST APIs
An introduction to REST
Developing RESTful servers and clients
A RESTful server
A RESTful client
Creating a functional RESTful server
The REST API
Using gorilla/mux
The use of subrouters
The Gin HTTP framework
Gin versus Gorilla
Working with the database
Implementing the RESTful server
Testing the RESTful server
Testing GET handlers
Testing POST handlers
Testing the PUT handler
Testing the DELETE handler
Creating a RESTful client
Creating the structure of the command line client
Implementing the RESTful client commands
Using the RESTful client
Working with multiple REST API versions
Summary
Exercises
Additional resources
Code Testing and Profiling
Optimizing code
Rewriting the main() function for better testing
Profiling code
Profiling a command line application
Profiling an HTTP server
The web interface of the Go profiler
The go tool trace utility
Tracing a web server from a client
Visiting all routes of a web server
Testing Go code
Writing tests for ./ch03/intRE.go
Testing UNIX signals
Disabling test caching
The testing.TempDir() function
The Cleanup() function
The testing/quick package
Timing out tests
Testing using testing.T.Fatal() and testing.T.Fatalf()
Table-driven tests
Testing code coverage
Finding unreachable Go code
Testing an HTTP server with a database backend
The govulncheck tool
Installing the tool
Cross-compilation
Using go:generate
Creating example functions
Summary
Exercises
Additional resources
Fuzz Testing and Observability
Fuzz testing
A simple fuzz testing example
An advanced fuzz testing example
Correcting the bug
Observability
The runtime/metrics package
Measuring the execution time of a function
The expvar package
Learning about CPU characteristics
Exposing metrics to Prometheus
Exposing metrics
Creating a Docker image for a Go server
Specifying the metrics to expose
Getting the metrics
Putting the metrics in Prometheus
Visualizing Prometheus metrics in Grafana
Summary
Exercises
Additional resources
Efficiency and Performance
Benchmarking code
A simple benchmark scenario
Benchmarking the number of memory allocations
Initial version
Improving the number of memory allocations
Buffered versus unbuffered file I/O
The benchstat utility
Wrongly defined benchmark functions
Go memory management
Heap and stack
The main elements of the Go memory model
Memory leaks
Slices and memory leaks
Maps and memory leaks
Memory pre-allocation
Working with eBPF
What is eBPF?
About observability and eBPF
Creating an eBPF tool in Go
Summary
Exercises
Additional resources
Changes in Recent Go Versions
About rand.Seed()
What is new in Go 1.21?
The sync.OnceFunc() function
The clear function
What is new in Go 1.22?
Changes in slices
Changes in for loops
The math/rand/v2 package
Summary
Exercises
Additional resources
Appendix: The Go Garbage Collector
Garbage collection
The key characteristics of the Go GC
Learning more about the Go GC
The tri-color algorithm
More about the operation of the Go GC
Maps, slices, and the Go GC
Using slices
Using maps with pointers
Using maps without pointers
Splitting a map
Comparing the performance of the presented techniques
Additional resources
Other Books You May Enjoy
Index

Mastering Go: Leverage Go’s expertise for advanced utilities, empowering you to develop professional software [4 ed.]
 9781805127147

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
Recommend Papers