├── readme.MD ├── httpserver ├── build.sh ├── httpserver ├── bin │ └── amd64 │ │ └── httpserver ├── Dockerfile ├── Makefile └── main.go ├── examples ├── module3 │ ├── malloc │ │ ├── Makefile │ │ ├── output │ │ │ └── linux │ │ │ │ └── memoryconsumption │ │ ├── malloc.c │ │ └── main.go │ └── busyloop │ │ ├── busyloop │ │ └── main.go ├── module1 │ ├── init │ │ ├── b │ │ │ └── init.go │ │ ├── a │ │ │ └── init.go │ │ └── main.go │ ├── govet │ │ └── main.go │ ├── forloop │ │ └── main.go │ ├── callbacks │ │ ├── main_test.go │ │ └── main.go │ ├── slice │ │ ├── forrange │ │ │ └── main.go │ │ ├── makenew │ │ │ └── main.go │ │ └── main.go │ ├── helloworld │ │ └── main.go │ ├── map │ │ └── main.go │ ├── defer │ │ └── main.go │ ├── structs │ │ └── main.go │ ├── struct │ │ └── main.go │ ├── context │ │ ├── donechannel │ │ │ └── main.go │ │ └── context │ │ │ └── main.go │ ├── pointer │ │ └── main.go │ ├── reflect │ │ └── main.go │ └── interface │ │ └── main.go └── module2 │ ├── cpuprofiling │ └── main.go │ ├── once │ └── main.go │ ├── mutex │ └── main.go │ ├── waitgroup │ └── main.go │ ├── syncmap │ └── main.go │ └── condition │ └── main.go ├── go.mod ├── .github └── workflows │ └── go.yml └── go.sum /readme.MD: -------------------------------------------------------------------------------- 1 | ### go语言基础示例代码 -------------------------------------------------------------------------------- /httpserver/build.sh: -------------------------------------------------------------------------------- 1 | make push -------------------------------------------------------------------------------- /httpserver/httpserver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cncamp/golang/HEAD/httpserver/httpserver -------------------------------------------------------------------------------- /examples/module3/malloc/Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | CGO_ENABLED=1 GOOS=linux CGO_LDFLAGS="-static" go build -------------------------------------------------------------------------------- /httpserver/bin/amd64/httpserver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cncamp/golang/HEAD/httpserver/bin/amd64/httpserver -------------------------------------------------------------------------------- /examples/module3/busyloop/busyloop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cncamp/golang/HEAD/examples/module3/busyloop/busyloop -------------------------------------------------------------------------------- /examples/module1/init/b/init.go: -------------------------------------------------------------------------------- 1 | package b 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func init() { 8 | fmt.Println("init from b") 9 | } 10 | -------------------------------------------------------------------------------- /examples/module3/malloc/output/linux/memoryconsumption: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cncamp/golang/HEAD/examples/module3/malloc/output/linux/memoryconsumption -------------------------------------------------------------------------------- /examples/module3/busyloop/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | go func() { 5 | for { 6 | } 7 | }() 8 | for { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/cncamp/golang 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/golang/glog v0.0.0-20210429001901-424d2337a529 7 | github.com/stretchr/testify v1.7.0 8 | ) 9 | -------------------------------------------------------------------------------- /examples/module1/govet/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | name := "testing" 9 | fmt.Printf("%d\n", name) 10 | fmt.Printf("%s\n", name, name) 11 | } 12 | -------------------------------------------------------------------------------- /examples/module1/init/a/init.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "fmt" 5 | 6 | _ "github.com/cncamp/golang/examples/module1/init/b" 7 | ) 8 | 9 | func init() { 10 | fmt.Println("init from a") 11 | } 12 | -------------------------------------------------------------------------------- /examples/module3/malloc/malloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define BLOCK_SIZE (100*1024*1024) 6 | char* allocMemory() { 7 | char* out = (char*)malloc(BLOCK_SIZE); 8 | memset(out, 'A', BLOCK_SIZE); 9 | return out; 10 | } -------------------------------------------------------------------------------- /httpserver/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | ENV MY_SERVICE_PORT=80 3 | ENV MY_SERVICE_PORT1=80 4 | ENV MY_SERVICE_PORT2=80 5 | ENV MY_SERVICE_PORT3=80 6 | LABEL multi.label1="value1" multi.label2="value2" other="value3" 7 | ADD bin/amd64/httpserver /httpserver 8 | EXPOSE 80 9 | ENTRYPOINT /httpserver -------------------------------------------------------------------------------- /examples/module1/init/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | _ "github.com/cncamp/golang/examples/module1/init/a" 7 | _ "github.com/cncamp/golang/examples/module1/init/b" 8 | ) 9 | 10 | func init() { 11 | fmt.Println("main init") 12 | } 13 | func main() { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /examples/module1/forloop/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | for i := 0; i < 3; i++ { 9 | fmt.Println(i) 10 | } 11 | fullString := "hello world" 12 | fmt.Println(fullString) 13 | for i, c := range fullString { 14 | fmt.Println(i, string(c)) 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /examples/module1/callbacks/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func add(a, b int) int { 10 | return a + b 11 | } 12 | func TestIncrease(t *testing.T) { 13 | t.Log("Start testing") 14 | result := add(1, 2) 15 | assert.Equal(t, result, 3) 16 | } 17 | -------------------------------------------------------------------------------- /examples/module1/slice/forrange/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | mySlice := []int{10, 20, 30, 40, 50} 9 | for _, value := range mySlice { 10 | value *= 2 11 | } 12 | fmt.Printf("mySlice %+v\n", mySlice) 13 | for index, _ := range mySlice { 14 | mySlice[index] *= 2 15 | } 16 | fmt.Printf("mySlice %+v\n", mySlice) 17 | } 18 | -------------------------------------------------------------------------------- /examples/module1/callbacks/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var a *int 5 | *a += 1 6 | // DoOperation(1, increase) 7 | DoOperation(1, decrease) 8 | } 9 | 10 | func increase(a, b int) int { 11 | return a + b 12 | } 13 | 14 | func DoOperation(y int, f func(int, int)) { 15 | f(y, 1) 16 | } 17 | 18 | func decrease(a, b int) { 19 | println("decrease result is:", a-b) 20 | } 21 | -------------------------------------------------------------------------------- /examples/module1/helloworld/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | name := flag.String("name", "world", "specify the name you want to say hi") 11 | flag.Parse() 12 | fmt.Println("os args is:", os.Args) 13 | fmt.Println("input parameter is:", *name) 14 | fullString := fmt.Sprintf("Hello %s from Go\n", *name) 15 | fmt.Println(fullString) 16 | } 17 | -------------------------------------------------------------------------------- /examples/module1/slice/makenew/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | mySlice1 := new([]int) 9 | mySlice2 := make([]int, 0) 10 | mySlice3 := make([]int, 10) 11 | mySlice4 := make([]int, 10, 20) 12 | fmt.Printf("mySlice1 %+v\n", mySlice1) 13 | fmt.Printf("mySlice2 %+v\n", mySlice2) 14 | fmt.Printf("mySlice3 %+v\n", mySlice3) 15 | fmt.Printf("mySlice4 %+v\n", mySlice4) 16 | } 17 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | pull_request: 5 | branches: [ master ] 6 | 7 | jobs: 8 | 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | 14 | - name: Set up Go 15 | uses: actions/setup-go@v2 16 | with: 17 | go-version: 1.17 18 | 19 | - name: Build 20 | run: go build -v ./... 21 | 22 | - name: Test 23 | run: go test -v ./... 24 | -------------------------------------------------------------------------------- /httpserver/Makefile: -------------------------------------------------------------------------------- 1 | export tag=v1.0 2 | root: 3 | export ROOT=github.com/cncamp/golang 4 | 5 | build: 6 | echo "building httpserver binary" 7 | mkdir -p bin/amd64 8 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/amd64 . 9 | 10 | release: build 11 | echo "building httpserver container" 12 | docker build -t cncamp/httpserver:${tag} . 13 | 14 | push: release 15 | echo "pushing cncamp/httpserver" 16 | docker push cncamp/httpserver:v1.0 17 | -------------------------------------------------------------------------------- /examples/module1/slice/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | myArray := [5]int{1, 2, 3, 4, 5} 9 | mySlice := myArray[1:3] 10 | fmt.Printf("mySlice %+v\n", mySlice) 11 | fullSlice := myArray[:] 12 | remove3rdItem := deleteItem(fullSlice, 2) 13 | fmt.Printf("remove3rdItem %+v\n", remove3rdItem) 14 | } 15 | 16 | func deleteItem(slice []int, index int) []int { 17 | return append(slice[:index], slice[index+1:]...) 18 | } 19 | -------------------------------------------------------------------------------- /examples/module1/map/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | myMap := make(map[string]string, 10) 9 | myMap["a"] = "b" 10 | myFuncMap := map[string]func() int{ 11 | "funcA": func() int { return 1 }, 12 | } 13 | fmt.Println(myFuncMap) 14 | f := myFuncMap["funcA"] 15 | fmt.Println(f()) 16 | value, exists := myMap["a"] 17 | if exists { 18 | println(value) 19 | } 20 | for k, v := range myMap { 21 | println(k, v) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/module1/defer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | defer fmt.Println("1") 11 | defer fmt.Println("2") 12 | defer fmt.Println("3") 13 | loopFunc() 14 | time.Sleep(time.Second) 15 | } 16 | 17 | func loopFunc() { 18 | lock := sync.Mutex{} 19 | for i := 0; i < 3; i++ { 20 | // go func(i int) { 21 | lock.Lock() 22 | defer lock.Unlock() 23 | fmt.Println("loopFunc:", i) 24 | // }(i) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/module1/structs/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | type MyType struct { 8 | Name string `json:"name"` 9 | } 10 | 11 | func main() { 12 | mt := MyType{Name: "test"} 13 | myType := reflect.TypeOf(mt) 14 | name := myType.Field(0) 15 | tag := name.Tag.Get("json") 16 | println(tag) 17 | tb := TypeB{P2: "p2", TypeA: TypeA{P1: "p1"}} 18 | //可以直接访问 TypeA.P1 19 | println(tb.P1) 20 | } 21 | 22 | type TypeA struct { 23 | P1 string 24 | } 25 | 26 | type TypeB struct { 27 | P2 string 28 | TypeA 29 | } 30 | -------------------------------------------------------------------------------- /examples/module3/malloc/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //#cgo LDFLAGS: 4 | //char* allocMemory(); 5 | import "C" 6 | import ( 7 | "fmt" 8 | "time" 9 | ) 10 | 11 | func main() { 12 | // only loop 10 times to avoid exhausting the host memory 13 | holder := []*C.char{} 14 | for i := 1; i <= 10; i++ { 15 | fmt.Printf("Allocating %dMb memory, raw memory is %d\n", i*100, i*100*1024*1025) 16 | // hold the memory, otherwise it will be freed by GC 17 | holder = append(holder, (*C.char)(C.allocMemory())) 18 | time.Sleep(time.Minute) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/module2/cpuprofiling/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "os" 7 | "runtime/pprof" 8 | ) 9 | 10 | var cpuprofile = flag.String("cpuprofile", "/tmp/cpuprofile", "write cpu profile to file") 11 | 12 | func main() { 13 | flag.Parse() 14 | f, err := os.Create(*cpuprofile) 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | pprof.StartCPUProfile(f) 19 | defer pprof.StopCPUProfile() 20 | var result int 21 | for i := 0; i < 100000000; i++ { 22 | result += i 23 | } 24 | log.Println("result:", result) 25 | } 26 | -------------------------------------------------------------------------------- /examples/module2/once/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | type SliceNum []int 9 | 10 | func NewSlice() SliceNum { 11 | return make(SliceNum, 0) 12 | 13 | } 14 | 15 | func (s *SliceNum) Add(elem int) *SliceNum { 16 | *s = append(*s, elem) 17 | fmt.Println("add", elem) 18 | fmt.Println("add SliceNum end", s) 19 | return s 20 | } 21 | 22 | func main() { 23 | var once sync.Once 24 | s := NewSlice() 25 | // 看源代码理解once的行为 26 | once.Do(func() { 27 | s.Add(16) 28 | }) 29 | once.Do(func() { 30 | s.Add(16) 31 | }) 32 | once.Do(func() { 33 | s.Add(16) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /examples/module1/struct/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "reflect" 7 | ) 8 | 9 | type MyType struct { 10 | Name string `json:"name"` 11 | Address 12 | } 13 | type Address struct { 14 | City string `json:"city"` 15 | } 16 | func main() { 17 | mt := MyType{Name: "test",Address: Address{City: "shanghai"}} 18 | b, _ := json.Marshal(&mt) 19 | fmt.Println(string(b)) 20 | myType := reflect.TypeOf(mt) 21 | name := myType.Field(0) 22 | tag := name.Tag.Get("json") 23 | println(tag) 24 | tb := TypeB{P2: "p2", TypeA: TypeA{P1: "p1"}} 25 | //可以直接访问 TypeA.P1 26 | println(tb.P1) 27 | } 28 | 29 | type TypeA struct { 30 | P1 string 31 | } 32 | 33 | type TypeB struct { 34 | P2 string 35 | TypeA 36 | } 37 | -------------------------------------------------------------------------------- /examples/module2/mutex/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | go rLock() 11 | go wLock() 12 | go lock() 13 | time.Sleep(5 * time.Second) 14 | } 15 | 16 | func lock() { 17 | lock := sync.Mutex{} 18 | for i := 0; i < 3; i++ { 19 | lock.Lock() 20 | defer lock.Unlock() 21 | fmt.Println("lock:", i) 22 | } 23 | } 24 | 25 | func rLock() { 26 | lock := sync.RWMutex{} 27 | for i := 0; i < 3; i++ { 28 | lock.RLock() 29 | defer lock.RUnlock() 30 | fmt.Println("rLock:", i) 31 | } 32 | } 33 | 34 | func wLock() { 35 | lock := sync.RWMutex{} 36 | for i := 0; i < 3; i++ { 37 | lock.Lock() 38 | defer lock.Unlock() 39 | fmt.Println("wLock:", i) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /examples/module1/context/donechannel/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | messages := make(chan int, 10) 10 | done := make(chan bool) 11 | 12 | defer close(messages) 13 | // consumer 14 | go func() { 15 | ticker := time.NewTicker(1 * time.Second) 16 | for _ = range ticker.C { 17 | select { 18 | case <-done: 19 | fmt.Println("child process interrupt...") 20 | return 21 | default: 22 | fmt.Printf("send message: %d\n", <-messages) 23 | } 24 | } 25 | }() 26 | 27 | // producer 28 | for i := 0; i < 10; i++ { 29 | messages <- i 30 | } 31 | time.Sleep(5 * time.Second) 32 | close(done) 33 | time.Sleep(1 * time.Second) 34 | fmt.Println("main process exit!") 35 | } 36 | -------------------------------------------------------------------------------- /examples/module2/waitgroup/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | waitBySleep() 11 | } 12 | 13 | // 14 | func waitBySleep() { 15 | for i := 0; i < 100; i++ { 16 | go fmt.Println(i) 17 | } 18 | time.Sleep(time.Second) 19 | } 20 | 21 | func waitByChannel() { 22 | c := make(chan bool, 100) 23 | for i := 0; i < 100; i++ { 24 | go func(i int) { 25 | fmt.Println(i) 26 | c <- true 27 | }(i) 28 | } 29 | 30 | for i := 0; i < 100; i++ { 31 | <-c 32 | } 33 | } 34 | 35 | func waitByWG() { 36 | wg := sync.WaitGroup{} 37 | wg.Add(100) 38 | for i := 0; i < 100; i++ { 39 | go func(i int) { 40 | fmt.Println(i) 41 | wg.Done() 42 | }(i) 43 | } 44 | wg.Wait() 45 | } 46 | -------------------------------------------------------------------------------- /examples/module1/pointer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | str := "a string value" 9 | pointer := &str 10 | anotherString := *&str 11 | fmt.Println(str) 12 | fmt.Println(pointer) 13 | fmt.Println(anotherString) 14 | str = "changed string" 15 | fmt.Println(str) 16 | fmt.Println(pointer) 17 | fmt.Println(anotherString) 18 | para := ParameterStruct{Name: "aaa"} 19 | fmt.Println(para) 20 | changeParameter(¶, "bbb") 21 | fmt.Println(para) 22 | cannotChangeParameter(para, "ccc") 23 | fmt.Println(para) 24 | } 25 | 26 | type ParameterStruct struct { 27 | Name string 28 | } 29 | 30 | func changeParameter(para *ParameterStruct, value string) { 31 | para.Name = value 32 | } 33 | 34 | func cannotChangeParameter(para ParameterStruct, value string) { 35 | para.Name = value 36 | } 37 | -------------------------------------------------------------------------------- /examples/module1/reflect/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | func main() { 9 | // basic type 10 | myMap := make(map[string]string, 10) 11 | myMap["a"] = "b" 12 | t := reflect.TypeOf(myMap) 13 | fmt.Println("type:", t) 14 | v := reflect.ValueOf(myMap) 15 | fmt.Println("value:", v) 16 | // struct 17 | myStruct := T{A: "a"} 18 | v1 := reflect.ValueOf(myStruct) 19 | for i := 0; i < v1.NumField(); i++ { 20 | fmt.Printf("Field %d: %v\n", i, v1.Field(i)) 21 | } 22 | for i := 0; i < v1.NumMethod(); i++ { 23 | fmt.Printf("Method %d: %v\n", i, v1.Method(i)) 24 | } 25 | // 需要注意receive是struct还是指针 26 | result := v1.Method(0).Call(nil) 27 | fmt.Println("result:", result) 28 | } 29 | 30 | type T struct { 31 | A string 32 | } 33 | 34 | // 需要注意receive是struct还是指针 35 | func (t T) String() string { 36 | return t.A + "1" 37 | } 38 | -------------------------------------------------------------------------------- /examples/module1/context/context/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | baseCtx := context.Background() 11 | ctx := context.WithValue(baseCtx, "a", "b") 12 | go func(c context.Context) { 13 | fmt.Println(c.Value("a")) 14 | }(ctx) 15 | timeoutCtx, cancel := context.WithTimeout(baseCtx, time.Second) 16 | defer cancel() 17 | go func(ctx context.Context) { 18 | ticker := time.NewTicker(1 * time.Second) 19 | for _ = range ticker.C { 20 | select { 21 | case <-ctx.Done(): 22 | fmt.Println("child process interrupt...") 23 | return 24 | default: 25 | fmt.Println("enter default") 26 | } 27 | } 28 | }(timeoutCtx) 29 | select { 30 | case <-timeoutCtx.Done(): 31 | time.Sleep(1 * time.Second) 32 | fmt.Println("main process exit!") 33 | } 34 | // time.Sleep(time.Second * 5) 35 | } 36 | -------------------------------------------------------------------------------- /examples/module2/syncmap/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sync" 5 | "time" 6 | ) 7 | 8 | func main(){ 9 | unsafeWrite() 10 | safeWrite() 11 | time.Sleep(time.Second) 12 | } 13 | func unsafeWrite() { 14 | conflictMap := map[int]int{} 15 | for i:=0;i<100;i++ { 16 | go func() { 17 | conflictMap[1] = i 18 | }() 19 | } 20 | } 21 | 22 | type SafeMap struct { 23 | safeMap map[int]int 24 | sync.Mutex 25 | } 26 | 27 | func safeWrite() { 28 | s := SafeMap{ 29 | safeMap: map[int]int{}, 30 | Mutex: sync.Mutex{}, 31 | } 32 | for i:=0;i<100;i++ { 33 | go func() { 34 | s.Write(1,1) 35 | }() 36 | } 37 | } 38 | 39 | func (s *SafeMap)Read(k int) (int, bool){ 40 | s.Lock() 41 | defer s.Unlock() 42 | result, ok := s.safeMap[k] 43 | return result, ok 44 | } 45 | 46 | func (s *SafeMap)Write(k,v int){ 47 | s.Lock() 48 | defer s.Unlock() 49 | s.safeMap[k] = v 50 | } 51 | -------------------------------------------------------------------------------- /examples/module2/condition/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | type Queue struct { 10 | queue []string 11 | cond *sync.Cond 12 | } 13 | 14 | func main() { 15 | q := Queue{ 16 | queue: []string{}, 17 | cond: sync.NewCond(&sync.Mutex{}), 18 | } 19 | go func() { 20 | for { 21 | q.Enqueue("a") 22 | time.Sleep(time.Second * 2) 23 | } 24 | }() 25 | for { 26 | q.Dequeue() 27 | time.Sleep(time.Second) 28 | } 29 | } 30 | 31 | func (q *Queue) Enqueue(item string) { 32 | q.cond.L.Lock() 33 | defer q.cond.L.Unlock() 34 | q.queue = append(q.queue, item) 35 | fmt.Printf("putting %s to queue, notify all\n", item) 36 | q.cond.Broadcast() 37 | } 38 | 39 | func (q *Queue) Dequeue() string { 40 | q.cond.L.Lock() 41 | defer q.cond.L.Unlock() 42 | for len(q.queue) == 0 { 43 | fmt.Println("no data available, wait") 44 | q.cond.Wait() 45 | } 46 | result := q.queue[0] 47 | q.queue = q.queue[1:] 48 | return result 49 | } 50 | -------------------------------------------------------------------------------- /examples/module1/interface/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type IF interface { 6 | getName() string 7 | } 8 | 9 | type Human struct { 10 | firstName, lastName string 11 | } 12 | 13 | type Plane struct { 14 | vendor string 15 | model string 16 | } 17 | 18 | func (h *Human) getName() string { 19 | return h.firstName + "," + h.lastName 20 | } 21 | 22 | func (p Plane) getName() string { 23 | return fmt.Sprintf("vendor: %s, model: %s", p.vendor, p.model) 24 | } 25 | 26 | type Car struct { 27 | factory, model string 28 | } 29 | 30 | func (c *Car) getName() string { 31 | return c.factory + "-" + c.model 32 | } 33 | 34 | func main() { 35 | interfaces := []IF{} 36 | h := new(Human) 37 | h.firstName = "first" 38 | h.lastName = "last" 39 | interfaces = append(interfaces, h) 40 | c := new(Car) 41 | c.factory = "benz" 42 | c.model = "s" 43 | interfaces = append(interfaces, c) 44 | for _, f := range interfaces { 45 | fmt.Println(f.getName()) 46 | } 47 | p := Plane{} 48 | p.vendor = "testVendor" 49 | p.model = "testModel" 50 | fmt.Println(p.getName()) 51 | } 52 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/golang/glog v0.0.0-20210429001901-424d2337a529 h1:2voWjNECnrZRbfwXxHB1/j8wa6xdKn85B5NzgVL/pTU= 4 | github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 5 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 8 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 9 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 10 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 11 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 12 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 13 | -------------------------------------------------------------------------------- /httpserver/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net/http" 9 | 10 | _ "net/http/pprof" 11 | 12 | "github.com/golang/glog" 13 | ) 14 | 15 | func main() { 16 | flag.Set("v", "4") 17 | glog.V(2).Info("Starting http server...") 18 | http.HandleFunc("/", rootHandler) 19 | c, python, java := true, false, "no!" 20 | fmt.Println(c, python, java) 21 | err := http.ListenAndServe(":80", nil) 22 | // mux := http.NewServeMux() 23 | // mux.HandleFunc("/", rootHandler) 24 | // mux.HandleFunc("/healthz", healthz) 25 | // mux.HandleFunc("/debug/pprof/", pprof.Index) 26 | // mux.HandleFunc("/debug/pprof/profile", pprof.Profile) 27 | // mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) 28 | // mux.HandleFunc("/debug/pprof/trace", pprof.Trace) 29 | // err := http.ListenAndServe(":80", mux) 30 | if err != nil { 31 | log.Fatal(err) 32 | } 33 | 34 | } 35 | 36 | func healthz(w http.ResponseWriter, r *http.Request) { 37 | io.WriteString(w, "ok\n") 38 | } 39 | 40 | func rootHandler(w http.ResponseWriter, r *http.Request) { 41 | fmt.Println("entering root handler") 42 | user := r.URL.Query().Get("user") 43 | if user != "" { 44 | io.WriteString(w, fmt.Sprintf("hello [%s]\n", user)) 45 | } else { 46 | io.WriteString(w, "hello [stranger]\n") 47 | } 48 | io.WriteString(w, "===================Details of the http request header:============\n") 49 | for k, v := range r.Header { 50 | io.WriteString(w, fmt.Sprintf("%s=%s\n", k, v)) 51 | } 52 | } 53 | --------------------------------------------------------------------------------