100 Go Mistakes and How to Avoid Them
- Length: 384 pages
- Edition: 1
- Language: English
- Publisher: Manning
- Publication Date: 2022-10-04
- ISBN-10: 1617299596
- ISBN-13: 9781617299599
- Sales Rank: #407529 (See Top 100 Books)
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 introduces dozens of techniques for writing idiomatic, expressive, and efficient Go code that avoids common pitfalls. By reviewing dozens of interesting, readable examples and real-world case studies, you’ll explore mistakes that even experienced Go programmers make. This book is focused on pure Go code, with standards you can apply to any kind of project.
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. Your code speed and quality will enjoy a huge boost when you improve your concurrency skills, deal with error management idiomatically, and increase the quality of your tests.
inside front cover 100 Go Mistakes Copyright dedication contents front matter preface acknowledgments about this book Who should read this book How this book is organized: A roadmap About the code liveBook discussion forum about the author about the cover illustration 1 Go: Simple to learn but hard to master 1.1 Go outline 1.2 Simple doesn’t mean easy 1.3 100 Go mistakes 1.3.1 Bugs 1.3.2 Needless complexity 1.3.3 Weaker readability 1.3.4 Suboptimal or unidiomatic organization 1.3.5 Lack of API convenience 1.3.6 Under-optimized code 1.3.7 Lack of productivity Summary 2 Code and project organization 2.1 #1: Unintended variable shadowing 2.2 #2: Unnecessary nested code 2.3 #3: Misusing init functions 2.3.1 Concepts 2.3.2 When to use init functions 2.4 #4: Overusing getters and setters 2.5 #5: Interface pollution 2.5.1 Concepts 2.5.2 When to use interfaces 2.5.3 Interface pollution 2.6 #6: Interface on the producer side 2.7 #7: Returning interfaces 2.8 #8: any says nothing 2.9 #9: Being confused about when to use generics 2.9.1 Concepts 2.9.2 Common uses and misuses 2.10 #10: Not being aware of the possible problems with type embedding 2.11 #11: Not using the functional options pattern 2.11.1 Config struct 2.11.2 Builder pattern 2.11.3 Functional options pattern 2.12 #12: Project misorganization 2.12.1 Project structure 2.12.2 Package organization 2.13 #13: Creating utility packages 2.14 #14: Ignoring package name collisions 2.15 #15: Missing code documentation 2.16 #16: Not using linters Summary 3 Data types 3.1 #17: Creating confusion with octal literals 3.2 #18: Neglecting integer overflows 3.2.1 Concepts 3.2.2 Detecting integer overflow when incrementing 3.2.3 Detecting integer overflows during addition 3.2.4 Detecting an integer overflow during multiplication 3.3 #19: Not understanding floating points 3.4 #20: Not understanding slice length and capacity 3.5 #21: Inefficient slice initialization 3.6 #22: Being confused about nil vs. empty slices 3.7 #23: Not properly checking if a slice is empty 3.8 #24: Not making slice copies correctly 3.9 #25: Unexpected side effects using slice append 3.10 #26: Slices and memory leaks 3.10.1 Leaking capacity 3.10.2 Slice and pointers 3.11 #27: Inefficient map initialization 3.11.1 Concepts 3.11.2 Initialization 3.12 #28: Maps and memory leaks 3.13 #29: Comparing values incorrectly Summary 4 Control structures 4.1 #30: Ignoring the fact that elements are copied in range loops 4.1.1 Concepts 4.1.2 Value copy 4.2 #31: Ignoring how arguments are evaluated in range loops 4.2.1 Channels 4.2.2 Array 4.3 #32: Ignoring the impact of using pointer elements in range loops 4.4 #33: Making wrong assumptions during map iterations 4.4.1 Ordering 4.4.2 Map insert during iteration 4.5 #34: Ignoring how the break statement works 4.6 #35: Using defer inside a loop Summary 5 Strings 5.1 #36: Not understanding the concept of a rune 5.2 #37: Inaccurate string iteration 5.3 #38: Misusing trim functions 5.4 #39: Under-optimized string concatenation 5.5 #40: Useless string conversions 5.6 #41: Substrings and memory leaks Summary 6 Functions and methods 6.1 #42: Not knowing which type of receiver to use 6.2 #43: Never using named result parameters 6.3 #44: Unintended side effects with named result parameters 6.4 #45: Returning a nil receiver 6.5 #46: Using a filename as a function input 6.6 #47: Ignoring how defer arguments and receivers are evaluated 6.6.1 Argument evaluation 6.6.2 Pointer and value receivers Summary 7 Error management 7.1 #48: Panicking 7.2 #49: Ignoring when to wrap an error 7.3 #50: Checking an error type inaccurately 7.4 #51: Checking an error value inaccurately 7.5 #52: Handling an error twice 7.6 #53: Not handling an error 7.7 #54: Not handling defer errors Summary 8 Concurrency: Foundations 8.1 #55: Mixing up concurrency and parallelism 8.2 #56: Thinking concurrency is always faster 8.2.1 Go scheduling 8.2.2 Parallel merge sort 8.3 #57: Being puzzled about when to use channels or mutexes 8.4 #58: Not understanding race problems 8.4.1 Data races vs. race conditions 8.4.2 The Go memory model 8.5 #59: Not understanding the concurrency impacts of a workload type 8.6 #60: Misunderstanding Go contexts 8.6.1 Deadline 8.6.2 Cancellation signals 8.6.3 Context values 8.6.4 Catching a context cancellation Summary 9 Concurrency: Practice 9.1 #61: Propagating an inappropriate context 9.2 #62: Starting a goroutine without knowing when to stop it 9.3 #63: Not being careful with goroutines and loop variables 9.4 #64: Expecting deterministic behavior using select and channels 9.5 #65: Not using notification channels 9.6 #66: Not using nil channels 9.7 #67: Being puzzled about channel size 9.8 #68: Forgetting about possible side effects with string formatting 9.8.1 etcd data race 9.8.2 Deadlock 9.9 #69: Creating data races with append 9.10 #70: Using mutexes inaccurately with slices and maps 9.11 #71: Misusing sync.WaitGroup 9.12 #72: Forgetting about sync.Cond 9.13 #73: Not using errgroup 9.14 #74: Copying a sync type Summary 10 The standard library 10.1 #75: Providing a wrong time duration 10.2 #76: time.After and memory leaks 10.3 #77: Common JSON-handling mistakes 10.3.1 Unexpected behavior due to type embedding 10.3.2 JSON and the monotonic clock 10.3.3 Map of any 10.4 #78: Common SQL mistakes 10.4.1 Forgetting that sql.Open doesn’t necessarily establish connections to a database 10.4.2 Forgetting about connections pooling 10.4.3 Not using prepared statements 10.4.4 Mishandling null values 10.4.5 Not handling row iteration errors 10.5 #79: Not closing transient resources 10.5.1 HTTP body 10.5.2 sql.Rows 10.5.3 os.File 10.6 #80: Forgetting the return statement after replying to an HTTP request 10.7 #81: Using the default HTTP client and server 10.7.1 HTTP client 10.7.2 HTTP server Summary 11 Testing 11.1 #82: Not categorizing tests 11.1.1 Build tags 11.1.2 Environment variables 11.1.3 Short mode 11.2 #83: Not enabling the -race flag 11.3 #84: Not using test execution modes 11.3.1 The parallel flag 11.3.2 The -shuffle flag 11.4 #85: Not using table-driven tests 11.5 #86: Sleeping in unit tests 11.6 #87: Not dealing with the time API efficiently 11.7 #88: Not using testing utility packages 11.7.1 The httptest package 11.7.2 The iotest package 11.8 #89: Writing inaccurate benchmarks 11.8.1 Not resetting or pausing the timer 11.8.2 Making wrong assumptions about micro-benchmarks 11.8.3 Not being careful about compiler optimizations 11.8.4 Being fooled by the observer effect 11.9 #90: Not exploring all the Go testing features 11.9.1 Code coverage 11.9.2 Testing from a different package 11.9.3 Utility functions 11.9.4 Setup and teardown Summary 12 Optimizations 12.1 #91: Not understanding CPU caches 12.1.1 CPU architecture 12.1.2 Cache line 12.1.3 Slice of structs vs. struct of slices 12.1.4 Predictability 12.1.5 Cache placement policy 12.2 #92: Writing concurrent code that leads to false sharing 12.3 #93: Not taking into account instruction-level parallelism 12.4 #94: Not being aware of data alignment 12.5 #95: Not understanding stack vs. heap 12.5.1 Stack vs. heap 12.5.2 Escape analysis 12.6 #96: Not knowing how to reduce allocations 12.6.1 API changes 12.6.2 Compiler optimizations 12.6.3 sync.Pool 12.7 #97: Not relying on inlining 12.8 #98: Not using Go diagnostics tooling 12.8.1 Profiling 12.8.2 Execution tracer 12.9 #99: Not understanding how the GC works 12.9.1 Concepts 12.9.2 Examples 12.10 #100: Not understanding the impacts of running Go in Docker and Kubernetes Summary Final words index
Donate to keep this site alive
1. Disable the AdBlock plugin. Otherwise, you may not get any links.
2. Solve the CAPTCHA.
3. Click download link.
4. Lead to download server to download.