Giter VIP home page Giter VIP logo

go42's Issues

23.1 同步锁示例中G1解锁后,G2和G3中一个加锁后另一个需要等待锁释放后才能加锁

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	wg := sync.WaitGroup{}

	var mutex sync.Mutex
	fmt.Println("Locking  (G0)")
	mutex.Lock()
	fmt.Println("locked (G0)")
	wg.Add(3)

	for i := 1; i < 4; i++ {
		go func(i int) {
			fmt.Printf("Locking (G%d)\n", i)
			mutex.Lock()
			fmt.Printf("locked (G%d)\n", i)

			time.Sleep(time.Second * 2)
			mutex.Unlock()
			fmt.Printf("unlocked (G%d)\n", i)
			wg.Done()
		}(i)
	}

	time.Sleep(time.Second * 5)
	fmt.Println("ready unlock (G0)")
	mutex.Unlock()
	fmt.Println("unlocked (G0)")

	wg.Wait()
}

程序输出:
Locking (G0)
locked (G0)
Locking (G1)
Locking (G3)
Locking (G2)
ready unlock (G0)
unlocked (G0)
locked (G1)
unlocked (G1)
locked (G3)
unlocked (G3)
locked (G2)
unlocked (G2)

关于23.1 同步锁代码示例的错误

下面代码通过3个goroutine来体现sync.Mutex 对资源的访问控制特征:


package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    wg := sync.WaitGroup{}

    var mutex sync.Mutex
    fmt.Println("Locking  (G0)")
    mutex.Lock()
    fmt.Println("locked (G0)")
    wg.Add(3)

    for i := 1; i < 4; i++ {
        go func(i int) {
            fmt.Printf("Locking (G%d)\n", i)
            mutex.Lock()
            fmt.Printf("locked (G%d)\n", i)

            time.Sleep(time.Second * 2)
            mutex.Unlock()
            fmt.Printf("unlocked (G%d)\n", i)
            wg.Done()
        }(i)
    }

    time.Sleep(time.Second * 5)
    fmt.Println("ready unlock (G0)")
    mutex.Unlock()
    fmt.Println("unlocked (G0)")

    wg.Wait()
}
程序输出:
Locking  (G0)
locked (G0)
Locking (G1)
Locking (G3)
Locking (G2)
ready unlock (G0)
unlocked (G0)
locked (G1)
unlocked (G1)
locked (G3)
locked (G2)
unlocked (G3)
unlocked (G2)

这里的程序输出应该是不对的,在unlocked (G3)输出之前,G2还没有取到锁,不可能输出locked (G2)。

Go slice 不是指针,而是包含指针的结构体

第12章,slice的介绍基本是错的。

绝对不要用指针指向 slice,切片本身已经是一个引用类型,所以它本身就是一个指针!

package main

import "fmt"

func main() {
	x := []int{0, 0, 0}
	test(x)
	fmt.Println(x)
}

func test(i []int) {
	i = []int{1, 2, 3}
}

输出 [0 0 0],如果按照作者的理论 slice 是指针的话,结果应该是 [1 2 3]

错太多了,建议作者再读读 https://blog.golang.org/go-slices-usage-and-internals

35.2节错误未处理

35.2节方法err未处理
func tHandler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("layout.html.tmpl", "index.html.tmpl")
t.ExecuteTemplate(w, "layout", "Hello World!")
}

模板章节的疑问

格式化这块有些小问题

结果介绍里面是下面这种输出。这里应该是格式化字符串用错了,不是合理的example.

const templ = ` 
{{range .}}----------------------------------------
Name:   {{.Name}}
Price:  {{.Price | printf "%4s"}} // 这块的模板函数不合理
{{end}}`
程序输出:
----------------------------------------
Name:   《三国演义》
Price:  %!s(float64=19.82)
----------------------------------------
Name:   《儒林外史》
Price:  %!s(float64=99.09)
----------------------------------------
Name:   《史记》
Price:  %!s(float64=26.89)

第十章关于strings.Join和strings.Builder效率比较的问题

参考源码,Join本身就是调用了套了一个Builder来存新字符串,所以这两个效率应该是一样的?
go1.15.2 darwin/amd6

func Join(elems []string, sep string) string {
	switch len(elems) {
	case 0:
		return ""
	case 1:
		return elems[0]
	}
	n := len(sep) * (len(elems) - 1)
	for i := 0; i < len(elems); i++ {
		n += len(elems[i])
	}

	var b Builder
	b.Grow(n)
	b.WriteString(elems[0])
	for _, s := range elems[1:] {
		b.WriteString(sep)
		b.WriteString(s)
	}
	return b.String()
}

另外似乎strings.Builder是个改写版的迷你bytes.Buffer

关于28.2 指针运算代码示例的错误

但是对于v.j来说,怎么来得到它在内存中的地址呢?其实我们可以获取它相对于v的偏移量(unsafe.Sizeof可以为我们做这个事),但上面的代码并没有这样去实现。各位别急,一步步来。
var j *int64 = (*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + uintptr(unsafe.Sizeof(int64(0)))))
其实我们已经知道v是有两个成员的,包括i和j,并且在定义中,i位于j的前面,而i是int32类型,也就是说i占4个字节。所以j是相对于v偏移了4个字节。您可以用uintptr(4)或uintptr(unsafe.Sizeof(int64(0)))来做这个事。unsafe.Sizeof方法用来得到一个值应该占用多少个字节空间。注意这里跟C的用法不一样,C是直接传入类型,而Go 语言是传入值。

以上这一段表述中将uintptr(4)等同于uintptr(unsafe.Sizeof(int64(0))),但其实uintptr(unsafe.Sizeof(int64(0)))==uintptr(8),但是这里var j *int64 = (*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + uintptr(unsafe.Sizeof(int64(0)))))是可以正确取到j的值,是因为这里发生了对齐,除了i本身占用4字节,还有4个字节由编译器进行填充,导致unsafe.Offsetof(v.j)和uintptr(unsafe.Sizeof(int64(0)))在64位机器上,值都是8。原文说j是相对于v偏移了4个字节,实际上是错误的,而且也没有说清楚为什么使用uintptr(unsafe.Sizeof(int64(0)))。

27.1 反射(reflect)

x 被定义为:var x float64 = 3.4,那么 reflect.TypeOf(x) 返回 float64,reflect.ValueOf(x) 返回 。
漏了reflect.ValueOf(x) 返回值

defer可以再补充点

如果defer的代码块放在了函数退出代码的后面,那么defer中的代码块也是是无法执行到的

2.3 复数

复数使用 re+imI 来表示,其中 re 代表实数部分,im 代表虚数部分,I 代表根号负 1
I是小写的

关于31.4 bufio包代码示例的错误

本小节最后的示例代码如下:

package main

import (
    "bufio"
    "fmt"
    "strings"
)

func main() {
    sr := strings.NewReader("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
    buf := bufio.NewReaderSize(sr, 0) //默认16
    b := make([]byte, 10)

    fmt.Println("==", buf.Buffered()) // 0
    S, _ := buf.Peek(5)
    fmt.Printf("%d ==  %q\n", buf.Buffered(), s) // 
    nn, er := buf.Discard(3)
    fmt.Println(nn, er)

    for n, err := 0, error(nil); err == nil; {
        fmt.Printf("Buffered:%d ==Size:%d== n:%d==  b[:n] %q ==  err:%v\n", buf.Buffered(), buf.Size(), n, b[:n], err)
        n, err = buf.Read(b)
        fmt.Printf("Buffered:%d ==Size:%d== n:%d==  b[:n] %q ==  err: %v == s: %s\n", buf.Buffered(), buf.Size(), n, b[:n], err, s)
    }

    fmt.Printf("%d ==  %q\n", buf.Buffered(), s)
}

其中第16行S应该为s。

README.md typo

首先感谢输出的文章,README中有一个 typo,虽然不影响理解,修改一下应该更好。

- 第一章到第二十六章
+ 第一章到第十六章 +

可能有吹毛求疵的嫌疑:smile:

article title and sequence

could you rename the title as
42_1_xxx => 42_01_xxx
42_2_xxx => 42_02_xxx
then the article's sequence looks would be more nice

第二十三章 同步与锁 程序输出是否有误?

原版:

程序输出:
Locking  (G0)
locked (G0)
Locking (G1)
Locking (G3)
Locking (G2)
ready unlock (G0)
unlocked (G0)
locked (G1)
unlocked (G1)
locked (G3)
locked (G2)
unlocked (G3)
unlocked (G2)

输出不应该是locked g3,unlock g3,再去locked g2么?

string转[]byte的陷阱

在string转[]byte中,有个非常典型的例子。有同学可以解释下为什么吗?
package main
import "fmt"
func main() {
s := []byte("")
s1 := append(s, 'a')
s2 := append(s, 'b')
//fmt.Println(s1, "==========", s2)
fmt.Println(string(s1), "==========", string(s2))
}
// 注释时候输出是 b ========== b
// 取消注释输出是 [97] ========== [98] a ========== b
// 如果s不是空字符串又不一样。

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.