100 Go Mistakes and How to Avoid Them

100 Go Mistakes and How to Avoid Them

by Teiva Harsanyi
100 Go Mistakes and How to Avoid Them

100 Go Mistakes and How to Avoid Them

by Teiva Harsanyi

Paperback

$69.99 
  • SHIP THIS ITEM
    Qualifies for Free Shipping
  • PICK UP IN STORE
    Check Availability at Nearby Stores

Related collections and offers


Overview

Spot errors in your Go code you didn’t even know you were making and boost your productivity by avoiding common mistakes and pitfalls.

100 Go Mistakes and How to Avoid Them shows you how to:

Dodge the most common mistakes made by Go developers
Structure and organize your Go application
Handle data and control structures efficiently
Deal with errors in an idiomatic manner
Improve your concurrency skills
Optimize your code
Make your application production-ready and improve testing quality

100 Go Mistakes and How to Avoid Them puts a spotlight on common errors in Go code you might not even know you’re making. You’ll explore key areas of the language such as concurrency, testing, data structures, and more—and learn how to avoid and fix mistakes in your own projects. As you go, you’ll navigate the tricky bits of handling JSON data and HTTP services, discover best practices for Go code organization, and learn how to use slices efficiently.

Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications.

About the technology
Understanding mistakes is the best way to improve the quality of your code. This unique book examines 100 bugs and inefficiencies common to Go applications, along with tips and techniques to avoid making them in your own projects.

About the book
100 Go Mistakes and How to Avoid Them shows you how to replace common programming problems in Go with idiomatic, expressive code. In it, you’ll explore dozens of interesting examples and case studies as you learn to spot mistakes that might appear in your own applications. Expert author Teiva Harsanyi organizes the error avoidance techniques into convenient categories, ranging from types and strings to concurrency and testing.

What's inside

Identify and squash code-level bugs
Avoid problems with application structure and design
Perfect your data and control structures
Optimize your code by eliminating inefficiencies

About the reader
For developers proficient with Go programming and syntax.

About the author
Teiva Harsanyi is a senior software engineer at Docker with experience in various domains, including safety-critical industries like air traffic management.

Table of Contents
1 Go: Simple to learn but hard to master
2 Code and project organization
3 Data types
4 Control structures
5 Strings
6 Functions and methods
7 Error management
8 Concurrency: Foundations
9 Concurrency: Practice
10 The standard library
11 Testing
12 Optimizations

Product Details

ISBN-13: 9781617299599
Publisher: Manning
Publication date: 10/04/2022
Pages: 384
Sales rank: 507,382
Product dimensions: 7.38(w) x 9.25(h) x 0.70(d)

About the Author

Teiva Harsanyi is a senior software engineer with experience in different programming languages such as Go, Rust, Java, and Scala. He has worked in various domains across insurance, transportation, and safety-critical industries like air traffic management. Today, he works as a freelance engineer coding in Go. He also blogs and mentors newcomers to the language.

Table of Contents

Preface xii

Acknowledgments xiii

About this book xiv

About the author xvii

About the cover illustration xviii

1 Go: Simple to learn but hard to master 1

1.1 Go outline 2

1.2 Simple doesn't mean easy 3

1.3 100 Go mistakes 4

Bugs 4

Needless complexity 5

Weaker readability 5

Suboptimal or unidiomatic organization 5

Lack of API convenience 6

Under-optimized code 6

Lack of productivity 6

2 Code and project organization 7

2.1 #1: Unintended variable shadowing 7

2.2 #2: Unnecessary nested code 9

2.3 #3: Misusing init functions 12

Concepts 12

When to use init functions 15

2.4 #4: Overusing getters and setters 17

2.5 #5: Interface pollution 18

Concepts 18

When to use interfaces 21

Interface pollution 24

2.6 #6: Interface on the producer side 25

2.7 #7: Returning interfaces 27

2.8 #8: any says nothing 28

2.9 #9: Being confused about when to use generics 31

Concepts 31

Common uses and misuses 34

2.10 #10: Not being aware of the possible problems with type embedding 36

2.11 #11: Not using the functional options pattern 40

Config struct 41

Builder pattern 42

Functional options pattern 44

2.12 #12: Project misorganization 46

Project structure 46

Package organization 47

2.13 #13: Creating utility packages 48

2.14 #14: Ignoring package name collisions 50

2.15 #15: Missing code documentation 51

2.16 #16: Not using linters 53

3 Data types 56

3.1 #17: Creating confusion with octal literals 56

3.2 #18: Neglecting integer overflows 57

Concepts 58

Detecting integer overflow when incrementing 59

Detecting integer overflows during addition 60

Detecting an integer overflow during multiplication 60

3.3 #19: Not understanding floating points 61

3.4 #20: Not understanding slice length and capacity 64

3.5 #21: Inefficient slice initialization 68

3.6 #22: Being confused about nil vs. empty slices 71

3.7 #23: Not properly checking if a slice is empty 74

3.8 #24: Not making slice copies correctly 76

3.9 #25: Unexpected side effects using slice append 77

3.10 #26: Slices and memory leaks 80

Leaking capacity 80

Slice and pointers 81

3.11 #27: Inefficient map initialization 84

Concepts 84

Initialization 86

3.12 #28: Maps and memory leaks 87

3.13 #29: Comparing values incorrectly 90

4 Control structures 95

4.1 #30: Ignoring the fact that elements are copied in range loops 95

Concepts 96

Value copy 96

4.2 #31: Ignoring how arguments are evaluated in range loops 98

Channels 100

Array 100

4.3 #32: Ignoring the impact of using pointer elements in range loops 102

4.4 #33: Making wrong assumptions during map iterations 105

Ordering 105

Map insert during iteration 107

4.5 #34: Ignoring how the break statement works 108

4.6 #35: Using defer inside a loop 110

5 Strings 113

5.1 #36: Not understanding the concept of a rune 114

5.2 #37: Inaccurate string iteration 115

5.3 #38: Misusing trim functions 118

5.4 #39: Under-optimized string concatenation 119

5.5 #40: Useless string conversions 121

5.6 #41: Substrings and memory leaks 123

6 Functions and methods 126

6.1 #42: Not knowing which type of receiver to use 127

6.2 #43: Never using named result parameters 129

6.3 #44: Unintended side effects with named result parameters 132

6.4 #45: Returning a nil receiver 133

6.5 #46: Using a filename as a function input 136

6.6 #47: Ignoring how defer arguments and receivers are evaluated 138

Argument evaluation 138

Pointer and value receivers 141

7 Error management 143

7.1 #48: Panicking 143

7.2 #49: Ignoring when to wrap an error 146

7.3 #50: Checking an error type inaccurately 149

7.4 #51: Checking an error value inaccurately 152

7.5 #52: Handling an error twice 154

7.6 #53: Not handling an error 156

7.7 #54: Not handling defer errors 158

8 Concurrency: Foundations 162

8.1 #55: Mixing up concurrency and parallelism 163

8.2 #56: Thinking concurrency is always faster 166

Go scheduling 166

Parallel merge sort 169

8.3 #57: Being puzzled about when to use channels or mutexes 173

8.4 #58: Not understanding race problems 174

Data races vs. race conditions 174

The Go memory model 179

8.5 #59: Not understanding the concurrency impacts of a workload type 181

8.6 #60: Misunderstanding Go contexts 186

Deadline 186

Cancellation signals 187

Context values 188

Catching a context cancellation 190

9 Concurrency: Practice 193

9.1 #61: Propagating an inappropriate context 193

9.2 #62: Starting a goroutine without knowing when to stop it 196

9.3 #63: Not being careful with goroutines and loop variables 198

9.4 #54: Expecting deterministic behavior using select and channels 200

9.5 #65: Not using notification channels 204

9.6 #66: Not using nil channels 205

9.7 #67: Being puzzled about channel size 211

9.8 #68: Forgetting about possible side effects with string formatting 213

Etcd data race 213

Deadlock 214

9.9 #69: Creating data races with append 216

9.10 #70: Using mutexes inaccurately with slices and maps 218

9.11 #71: Misusing sync.WaitGroup 221

9.12 #72: Forgetting about sync.Cond 223

9.13 #73: Not using errgroup 228

9.14 #74: Copying a sync type 231

10 The standard library 234

10.1 #75: Providing a wrong time duration 235

10.2 #76: time.After and memory leaks 235

10.3 #77: Common JSON-handling mistakes 238

Unexpected behavior due to type embedding 238

JSON and the monotonic clock 240

Map of any 243

10.4 #78: Common SQL mistakes 244

Forgetting that sql. Open doesn't necessarily establish connections to a database 244

Forgetting about connections pooling 245

Not using prepared statements 246

Mishandling null values 247

Not handling row iteration errors 248

10.5 #79: Not closing transient resources 249

HTTP body 250

Sql.Rows 252

Os.File 253

10.6 #80: Forgetting the return statement after replying to an HTTP request 255

10.7 #81: Using the default HTTP client and server 256

HTTP client 256

HTTP server 259

11 Testing 262

11.1 #82: Not categorizing tests 262

Build tags 263

Environment variables 264

Short mode 265

11.2 #83: Not enabling the -race flag 266

11.3 #84: Not using test execution modes 268

The parallel flag 269

The-shuffle flag 270

11.4 #85: Not using table-driven tests 271

11.5 #86: Sleeping in unit tests 274

11.6 #87: Not dealing with the time API efficiently 278

11.7 #88: Not using testing utility packages 281

The httptest package 281

The iotest package 283

11.8 #89: Writing inaccurate benchmarks 285

Not resetting or pausing the timer 286

Making wrong assumptions about micro-benchmarks 287

Not being careful about compiler optimizations 289

Being fooled by the observer effect 291

11.9 #90: Not exploring all the Go testing features 294

Code coverage 294

Testing from a different package 295

Utility functions 295

Setup and teardown 296

12 Optimizations 299

12.1 #91: Not understanding CPU caches 300

CPU architecture 300

Cache line 301

Slice of structs vs. struct of slices 304

Predictability 305

Cache placement policy 307

12.2 #92: Writing concurrent code that leads to false sharing 312

12.3 #93: Not taking into account instruction-level parallelism 315

12.4 #94: Not being aware of data alignment 321

12.5 #95: Not understanding stack vs. heap 324

Stack vs. heap 324

Escape analysis 329

12.6 #96: Not knowing how to reduce allocations 331

API changes 331

Compiler optimizations 332

Sync.Pool 332

12.7 #97: Not relying on inlining 334

12.8 #98: Not using Go diagnostics tooling 337

Profiling 337

Execution tracer 344

12.9 #99: Not understanding how the GC works 347

Concepts 347

Examples 349

12.10 #100: Not understanding the impacts of running Go in Docker and Kubernetes 352

Final words 355

Index 357

From the B&N Reads Blog

Customer Reviews