Golang-C1-15

作业

标准库串讲

atomic.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
	"fmt"
	"sync"
)

func main() {
	cnt := 0
	for {
		var n int32 = 0
		wg := new(sync.WaitGroup)
		wg.Add(2)
		var lock sync.Mutex
		go func() {
			lock.Lock()
			defer lock.Unlock()
			n = n + 2
			wg.Done()
		}()

		go func() {
			lock.Lock()
			defer lock.Unlock()
			n = n / 2
			wg.Done()
		}()

		wg.Wait()
		cnt++
		if n != 2 && n != 1 {
			fmt.Println(cnt)
			fmt.Println(n)
			panic("bingo")
		}
	}
}

unsafe

unsafe.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
	"fmt"
	"unsafe"
)

type T struct {
	m int8
	n int8
}

func main() {
	var n int
	var m [2]int8

	fmt.Println(m)

	var p *int
	p = &n
	p = (*int)(unsafe.Pointer(&m[0]))
	*p = 0x1010
	fmt.Println(m)

}

unsafe1.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package main

import (
	"fmt"
	"unsafe"
)

// data pointer
// len int64
// cap int64

type SliceHeader struct {
	Data unsafe.Pointer
	Len  int
	Cap  int
}

type StringHeader struct {
	Data unsafe.Pointer
	Len  int
}

func slice(s []int, b int, len int) []int {
	hdr := SliceHeader{
		Data: unsafe.Pointer(&s[b]),
		Len:  len,
		Cap:  cap(s),
	}

	s1 := *(*[]int)(unsafe.Pointer(&hdr))
	return s1
}

func stringSlice(s string, b int, len int) string {
	hdr := *(*StringHeader)(unsafe.Pointer(&s))
	hdr.Data = unsafe.Pointer(uintptr(hdr.Data) + uintptr(b))
	hdr.Len = len

	s1 := *(*string)(unsafe.Pointer(&hdr))
	return s1
}

func ZeroCopyString(buf []byte) string {
	hdr := &StringHeader{
		Data: unsafe.Pointer(&buf[0]),
		Len:  len(buf),
	}
	return *(*string)(unsafe.Pointer(hdr))
}

func main() {
	s := []int{1, 2, 3}
	fmt.Println(&s[0])

	// hdr := SliceHeader{
	// 	Data: unsafe.Pointer(&s[1]),
	// 	Len:  2,
	// 	Cap:  3,
	// }

	// s1 := *(*[]int)(unsafe.Pointer(&hdr))

	/*
		var p *SliceHeader
		p = (*SliceHeader)(unsafe.Pointer(&s1))
		fmt.Printf("%#v\n", *p)
	*/
	s1 := slice(s, 0, 2)
	fmt.Println(len(s1))
	fmt.Println(cap(s1))
	fmt.Println(s1[0], s1[1])

	str := "hello"
	str1 := stringSlice(str, 0, 2)
	fmt.Println(str1)

	buf := []byte{'h', 'e', 'l', 'l', 'o'}
	str2 := ZeroCopyString(buf)
	buf[0] = 'a'
	fmt.Println(string(buf), str2)
}

反射

reflect.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package main

import (
	"bytes"
	"fmt"
	"reflect"
	"strconv"
)

type Student struct {
	Name string `json:"name"`
	Id   int    `json:"id"`
}

func (s Student) String() string {
	return fmt.Sprintf("name:%s,id:%d", s.Name, s.Id)
}

func marshal(x interface{}) string {
	t := reflect.TypeOf(x).Elem()
	v := reflect.ValueOf(x).Elem()
	buf := new(bytes.Buffer)
	fmt.Fprintf(buf, "{\n")
	for i := 0; i < t.NumField(); i++ {
		fieldt := t.Field(i)
		fieldv := v.Field(i)
		jsonkey := fieldt.Tag.Get("json")
		if jsonkey == "" {
			jsonkey = fieldt.Name
		}

		var jsonvalue string
		switch fieldt.Type.Kind() {
		case reflect.Int:
			jsonvalue = strconv.Itoa(int(fieldv.Int()))
		case reflect.String:
			jsonvalue = `"` + fieldv.String() + `"`
		}
		fmt.Fprintf(buf, "  \"%s\":%s,\n", jsonkey, jsonvalue)
	}
	fmt.Fprintf(buf, "}\n")
	return buf.String()
}

func print(x interface{}) {
	t := reflect.TypeOf(x)
	fmt.Println(t.Kind())
	t = t.Elem()
	fmt.Println(t.Name())
	fmt.Println(t.PkgPath())
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		fmt.Println(field)
		fmt.Println("jsonkey:", field.Tag.Get("json"))
	}

	field, _ := t.FieldByName("Name")
	fmt.Printf("%#v\n", field)

	for i := 0; i < t.NumMethod(); i++ {
		method := t.Method(i)
		fmt.Println(method.Name)
	}

	v := reflect.ValueOf(x).Elem()
	vfiled := v.FieldByName("Name")
	fmt.Println(vfiled.String())

	method := v.MethodByName("String")
	ret := method.Call(nil)
	fmt.Println(ret[0].String())
}

func main() {
	s := &Student{
		Name: "binggan",
		Id:   1,
	}
	print(s)

	fmt.Println(marshal(s))

	s1 := []string{"hello", "world"}
	s2 := s1
	fmt.Println(reflect.DeepEqual(s1, s2))
}

正则表达式

reg.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import (
	"fmt"
	"regexp"
)

var (
	reg = regexp.MustCompile("[a-z]+.*+?")
)

func main() {
	ok := reg.MatchString("abc12345")
	fmt.Println(ok)
	fmt.Println(reg.FindString("abc12345"))
}

标准库rpc

tree

1
2
3
4
5
6
7
rpc
├── client
│   └── main.go
├── common
│   └── proto.go
└── server
    └── main.go

protobuf

grpc

tree

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
grpc
├── bench
│   └── encode_test.go
├── checklist
├── cli
│   ├── cmd
│   │   ├── add.go
│   │   ├── dump.go
│   │   ├── query.go
│   │   ├── root.go
│   │   └── rpc.go
│   ├── LICENSE
│   └── main.go
├── client
│   └── main.go
├── decode.go
├── myproto
│   ├── addressbook.pb.go
│   ├── addressbook.proto
│   └── compile.sh
├── proto.go
└── server
    └── main.go

cobra命令行工具

mail和context

mail.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main

import (
	"bytes"
	"fmt"
	"log"
	"os/exec"
	"text/template"
)

var (
	tpl = template.Must(template.New("alarm").Parse(`From: <bingan@reboot.com>
To: <{{.To}}>
Subject: {{.Subject}}
Content-Type: text/html;charset=utf8

{{.Body}}
`))
)

type mailDesc struct {
	To      string
	Subject string
	Body    string
}

func sendmail(m *mailDesc) error {
	buf := new(bytes.Buffer)
	tpl.Execute(buf, m)

	cmd := exec.Command("sendmail", "-t")
	cmd.Stdin = buf
	out, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("%s:%s", err, out)
	}

	return nil
}

func main() {
	m := &mailDesc{
		To:      "y1053419035@qq.com",
		Subject: "炸弹",
		Body:    "<h1>呵呵</h1>",
	}
	log.Print(sendmail(m))
}

ctx.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package main

import (
	"context"
	"net"
	"net/http"
	"time"
)

func callRedis(ctx context.Context) {
	dialer := new(net.Dialer)
	conn, err := dialer.DialContext(ctx, "tcp", "")
	deadline, ok := ctx.Deadline()
	conn.SetDeadline(deadline)

	req := http.NewRequest("GET", "", nil)
	req = req.WithContext(ctx)

}

func callMySql(ctx context.Context) {

}

func callApi(ctx context.Context) {

}

func main() {
	ctx, cancel := context.WithTimeout(context.TODO(), 10*time.Second)
	defer cancel()
	go callRedis(ctx)
	go callMySql(ctx)
	go callApi(ctx)

	user := make(chan bool)
	select {
	case <-ctx.Done():
	case <-user:
		cancel()
	}

}

杂谈

homework