Code Monkey home page Code Monkey logo

100-go-mistakes's Introduction

100 Go Mistakes and How to Avoid Them

Source code and community space of πŸ“– 100 Go Mistakes and How to Avoid Them, published by Manning in August 2022.

Read online: 100go.co.

100-go-mistakes's People

Contributors

aaraney avatar allmtz avatar bawfen avatar c0dehu1k avatar christowolf avatar fbnfgc avatar hitzhangjie avatar jushutch avatar nikzayn avatar peaacechoi avatar pellared avatar rustinwelter avatar stefafafan avatar teivah avatar vmellos avatar wureny avatar zvanyang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

100-go-mistakes's Issues

Mistake #22 "nil vs empty slices" regarding memory allocation of empty slices

Item 22 says:

One of the main differences between a nil and an empty slice regards allocations. Initializing a nil slice doesn’t require any allocation, which isn’t the case for an empty slice.

Correct me if I am wrong, but AFAIK both slices will have no memory allocations.

Slices are represented in memory as 3 words, defined by the slice header:

type slice struct {
	array unsafe.Pointer
	len   int
	cap   int
}

A nil slice is actually a zero value of the slice header:

slice {
	array: nil,
	len:   0,
	cap:   0,
}

An empty slice is just a slice with len and cap equal to 0 and an array pointing to 'zero-sized' array:

slice {
	array: unsafe.Pointer(&zerobase),
	len:   0,
	cap:   0,
}

The value of the array is the address of the runtime.zerobase, the base address for all 0-byte allocations

Mention linters

It would be useful if at the end of each mistake you listed which Go linters help catch the mistake (if any exist).

P.S. thanks for this project! I'm loving this book so far.

A possible contradicting statement in `#54: Not handling defer errors`

  • The book is a delightful read, can be put into action easily, so thanks for it.
  • Considering below statements

which we will implement, is to return the rows.Scan error but log the rows.Close error

vs

so we decide to log "err" and return the existing error.

  • shouldn't above be so we decide to log "closeErr" and return the existing error.
  • first statement seems to be correct, however the code snippet follows second statement
    func getBalance3(db *sql.DB, clientID string) (balance float32, err error) {
    rows, err := db.Query(query, clientID)
    if err != nil {
    return 0, err
    }
    defer func() {
    closeErr := rows.Close()
    if err != nil {
    if closeErr != nil {
    log.Printf("failed to close rows: %v", err)
    }
    return
    }
    err = closeErr
    }()
    // Use rows
    return 0, nil
    }
  • I believe in line 41 it should be log.Printf("failed to close rows: %v", closeErr)
  • I know it's a small typo, however thought of reporting it due to contradicting statements

Thanks.

spell mistake

hello, i find one spell mistake in 100-go-mistakes at chapter 9 #63 - Not being careful with goroutines and loop variable.

in the code, use fmt.Print :

s := []int{1, 2, 3}

for _, i := range s {
        go func() {
                fmt.Print(i)
        }()
}

in the description, use fmt.Println:

it prints the value of i at the time fmt.Println is executed

Higher granularity is equivalent to higher rate

On page 340, section Heap Profiling, high granularity means high rate, but instead it says:

We can change this rate, but we shouldn't be too granular because the more we decrease the rate, the more effort heap profiling will require to collect data.

Add Fuzz test for #90

Not considering Fuzz test

Since go 1.18, this kind of tests may help us to find out missing edge case.

Solution

Use it ;) .

Probably an incomplete statement in `#61: Propagating an inappropriate context`

  • First three different conditions are mentioned which can cancel HTTP Request
  • An issue was identified with third condition
  • It was fixed by providing & explaining a solution, however the fix doesn't seem to satisfy first two conditions
  • IOW, if we are using a detached context doesn't publish get executed even though if one of first two conditions are met?
  • Probably adding a statement stating the intention it's only to get values might be good πŸ€”
  • Pardon & disregard the issue if my understating is incorrect
package main

import (
	"context"
	"fmt"
	"time"
)

type detach struct{ ctx context.Context }

func (d detach) Deadline() (time.Time, bool) { return time.Time{}, false }
func (d detach) Done() <-chan struct{}       { return nil }
func (d detach) Err() error                  { return nil }
func (d detach) Value(key any) any           { return d.ctx.Value(key) }

func publish(ctx context.Context) {
	select {
	case <-ctx.Done():
		fmt.Println(ctx.Err())
	case <-time.After(100 * time.Millisecond):
		fmt.Println("published")
	}
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(50*time.Millisecond))
	defer cancel()
	ctx = context.WithValue(ctx, "key", "value")
	publish(detach{ctx: ctx}) // prints "published" even if the client timed out
}

Thanks.

Add benchmark tests for Predicatability

Describe the mistake

Please add benchmark tests for 12-optimizations/91-cpu-caches/predictability

Solution

package main

import "testing"

const n = 1_000_000

var global int64

func BenchmarkLinkedList(b *testing.B) {
	var local int64
	for i := 0; i < b.N; i++ {
		b.StopTimer()
		nodes := make([]node, n)
		for i := 0; i < n-1; i++ {
			nodes[i].next = &nodes[i+1]
		}
		b.StartTimer()
		local = linkedList(&nodes[0])
	}
	global = local
}

func BenchmarkSum2(b *testing.B) {
	var local int64
	for i := 0; i < b.N; i++ {
		b.StopTimer()
		s := make([]int64, n)
		b.StartTimer()
		local = sum2(s)
	}
	global = local
}

Mistake #11 - Builder pattern part

Func NewServer is defined as:
func NewServer(addr string, config Config) (*http.Server, error)
... you can't pass nil as a config param right?
You said this:

However, we still need to pass a
config struct that can be empty if a client wants to use the default configuration:
server, err := httplib.NewServer("localhost", nil)

To stop ticker explicitly

10.1 #75 Providing a wrong time duration should stop ticker, or cause leaks

ticker := time.NewTicker(1000) // should stop defer
for {
    select {
    case <-ticker.C:
        // Do something
    }
}
ticker := time.NewTicker(1000)
defer ticker.Stop()
for {
    select {
    case <-ticker.C:
        // Do something
    }
}

Typo on page 115

There is a typo in the second to last sentence at the end of mistake 36:
Having these concepts in mind is essential because runes as are everywhere in Go. Let's see a concrete application of this knowledge involving a common mistake related to string iteration.

Update golang.org links/references

Any mentions of golang.org should be changed to go.dev to align with the ongoing site merge.
E.g. there is an occurrence on page 179.

Mistakes summary

As you may have noticed, I've been enriching the repo with much more content these past weeks. See https://100go.co.

I only had a TL;DR in the past, and now I want it to be as helpful as possible for people who can't afford to buy the book, for example.

It remains about one-third of the mistakes to summarize. Also, any suggestions or improvements to the existing system are more than welcome. The file to be modified is here: https://github.com/teivah/100-go-mistakes/blob/master/docs/index.md.

If you're up for it, feel free to open a PR (a PR could contain multiple mistakes summary). Let's keep track of the remaining work:

  • Mistake 67
  • Mistake 68
  • Mistake 69
  • Mistake 70
  • Mistake 71
  • Mistake 72
  • Mistake 73
  • Mistake 74
  • Mistake 75
  • Mistake 76
  • Mistake 77
  • Mistake 78
  • Mistake 79
  • Mistake 80
  • Mistake 81
  • Mistake 82
  • Mistake 83
  • Mistake 84
  • Mistake 85
  • Mistake 86
  • Mistake 87
  • Mistake 88
  • Mistake 89
  • Mistake 90
  • Mistake 91
  • Mistake 92
  • Mistake 93
  • Mistake 94
  • Mistake 95
  • Mistake 96
  • Mistake 97
  • Mistake 98
  • Mistake 99
  • Mistake 100

Does range operator really copy the iterable?

Hello, first of all, please accept many thanks for the great book you wrote! It's awesome to have all those gotchas collected in one place and so well explained :)

I would like to ask for a further explanation of the statement in the book that made me a bit confused though. It says that the range operator copies the slice/array/channel being iterated over (ie the range clause) on its first (and only) evaluation just before the iteration. I cannot find that in the relevant part of the Golang spec. My understanding was, on the other hand, the for-range behaves that way because it's the v (the local iterator variable) that is a copy of the slice element (not that the whole iterable thing gets copied). Please see the following snippet: https://go.dev/play/p/tEE8fW6Jxrk.

Referring to the code samples in this repo here, such a statement can be found in the book as the comment eg. to this one (or a couple of other snippets in the 4.2.x chapter):

func listing1() {
a := [3]int{0, 1, 2}
for i, v := range a {
a[2] = 10
if i == 2 {
fmt.Println(v)
}
}
}

Potentially mistakenly included tag markers

First off, thanks for creating and releasing this content, @teivah! Ive thoroughly enjoyed everything ive read thus far! Can't wait for my hard copy of your book to arrive.

I wasn't sure if these tag like markers (i.e. <1>) were mistakenly included or not? I did not see them mentioned in text as if they were reference points, so I thought it was best to ask. Im happy to submit a PR to remove them if that is the case. JLMK.

func getKeys[K comparable, V any](m map[K]V) []K { <1>
var keys []K <2>

Item #64

Describe the book error

Item #64 says: "disconnectCh is a buffered channel", but it isn't.

README: Chinese translation πŸ‡¨πŸ‡³

Knowing there will be a Chinese translation (release date unknown yet), I would very much like this repo to offer a Chinese version of the README.

If you're interested, feel free to open a PR, even if it's only one part of it :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.