Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
liufeiyang committed Jun 30, 2022
0 parents commit 94b7711
Show file tree
Hide file tree
Showing 72 changed files with 2,208 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/go-base.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions array/arrayTest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import "fmt"

func main() {
//arr := [...][3]int{{1,1,1},{2,2,2},{3,3,3}}
//for k1, v1 := range arr {
// for k2, v2 := range v1 {
// fmt.Printf("(%d,%d)=%d ",k1,k2,v2)
// }
// fmt.Println()
//}
arr := [5]int{}
printArr(&arr)
fmt.Println(arr)
fmt.Printf("arr: %p\n",&arr)
//arr2 := [...]int{1,2,3,4,5}
//printArr(&arr2)
//fmt.Printf("arr2: %p\n",&arr2)
}

func printArr(arr *[5]int) {
arr[0] = 1100
for k1, v1 := range arr {
fmt.Printf("(%d,%d)",k1,v1)
}
fmt.Printf("arr: %p\n",&arr)
fmt.Println()
}
27 changes: 27 additions & 0 deletions array/sumTest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import "fmt"

func sumArr(arr *[5]int) {
fmt.Printf("arr: %p\n",&arr)
arr[0]=12132
}

func main() {
arr := [5]int{1,2,3,4,5}
//fmt.Printf("arr: %p\n",&arr)
//sumArr(&arr)
//fmt.Println(arr[0])
findArr(5,arr)
}

func findArr(sum int, arr [5]int) {
for i := 0; i < len(arr); i++ {
for j := i+1; j < len(arr); j++ {
target := arr[i] + arr[j]
if target == sum{
fmt.Printf("(%d,%d)\n",i,j)
}
}
}
}
32 changes: 32 additions & 0 deletions chan/channelDemo01.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

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



func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second)
defer cancel()
go doSomethingCool(ctx)
select {
case <-ctx.Done():
fmt.Println("oh no, I've exceeded the deadline")
}
}

func doSomethingCool(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("timed out")
return
default:
fmt.Println("doing something cool")
}
time.Sleep(500 * time.Millisecond)
}
}
28 changes: 28 additions & 0 deletions chan/channelDemo02.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import "fmt"

func myAppend(s []int) []int {
// 这里 s 虽然改变了,但并不会影响外层函数的 s
s = append(s, 100)
return s
}
func myAppendPtr(s *[]int) {
// 会改变外层 s 本身
*s = append(*s, 100)
return
}
func main() {
s := make([]int, 2, 4)
s[0] = 1
s[1] = 1
fmt.Println("len", len(s))
fmt.Println("cap", cap(s))
fmt.Println(&s)
newS := myAppend(s)
fmt.Println(s)
fmt.Println(newS)
s = newS
myAppendPtr(&s)
fmt.Println(s)
}
103 changes: 103 additions & 0 deletions chan/channelDemo03.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package main

import (
"context"
"fmt"
"log"
"net/http"
_ "net/http/pprof"
"time"
)

func setup() {
// 这里面有一些初始化的操作
}

func main() {
setup()

// 用于监听服务退出, 这里使用了两个 goroutine,所以 cap 为2
done := make(chan error, 2)

// 无缓冲的通道,用于控制服务退出,传入同一个 stop,做到只要有一个服务退出了那么另外一个服务也会随之退出
stop := make(chan struct{}, 0)

// for debug
go func() {
// pprof 传递一个 channel
fmt.Println("pprof start...")
done <- pprof(stop)
fmt.Printf("err1:%v\n", done)

}()

// 主服务
go func() {
fmt.Println("app start...")
done <- app(stop)
fmt.Printf("err2:%v\n", done)
}()

// stopped 用于判断当前 stop 的状态
var stopped bool

// 这里循环读取 done 这个 channel
// 只要有一个退出了,我们就关闭 stop channel
for i := 0; i < cap(done); i++ {

// 对于有缓冲的chan, chan中无值会一直处于阻塞状态
// 对于app 服务会一直阻塞状态,不会有 数据写入到done 通道,只有在5s后,模拟的 pprof会有err写入chan,此时才会触发以下逻辑
if err := <-done; err != nil {
log.Printf("server exit err: %+v", err)
}

if !stopped {
stopped = true
// 通过关闭 无缓冲的channel 来通知所有的 读 stop相关的goroutine退出
close(stop)
}
}
}

// http 服务
func app(stop <-chan struct{}) error {
mux := http.NewServeMux()
mux.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("pong"))
})

return server(mux, ":8080", stop)
}

func pprof(stop <-chan struct{}) error {
// 注意这里主要是为了模拟服务意外退出,用于验证一个服务退出,其他服务同时退出的场景
// 因为这里没有返回err, 所以done chan中无法接收到值, 主程序中会一直阻塞住
go func() {
server(http.DefaultServeMux, ":8081", stop)
}()

time.Sleep(5 * time.Second)
// 模拟出错
return fmt.Errorf("mock pprof exit")
}

// 启动一个服务
func server(handler http.Handler, addr string, stop <-chan struct{}) error {

s := http.Server{
Handler: handler,
Addr: addr,
}

// 这个 goroutine 控制退出,因为 stop channel 只要close或者是写入数据,这里就会退出
go func() {
// 无缓冲channel等待,写入或者关闭
<-stop
log.Printf("server will exiting, addr: %s", addr)
// 此时 httpApi 服务就会优雅的退出
s.Shutdown(context.Background())
}()

// 没有触发异常的话,会一直处于阻塞
return s.ListenAndServe()
}
41 changes: 41 additions & 0 deletions chan/channelDemo04.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"fmt"
"time"
)

// DeferRecover defer recover from panic.
func DeferRecover(tag string, handlePanic func(error)) func() {
return func() {
if err := recover(); err != nil {
fmt.Println(tag)
if handlePanic != nil {
handlePanic(fmt.Errorf("%v", err))
}
}
}
}

// WithRecover recover from panic.
func WithRecover(tag string, f func(), handlePanic func(error)) {
defer DeferRecover(tag, handlePanic)()
f()
panic("test")
}

// Go is a wrapper of goroutine with recover.
func Go(name string, f func(), handlePanic func(error)) {
go WithRecover(fmt.Sprintf("goroutine %s", name), f, handlePanic)
}

func main() {
Go("test-final", func() {
fmt.Println("business")

},func(err error){
fmt.Println("recovery:",err)
})

time.Sleep(3*time.Millisecond)
}
26 changes: 26 additions & 0 deletions chan/channelDemo05.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"fmt"
"time"
)

func main(){
tc:= make(chan int, 1)
go func() {
for i := 0; i <10; i++ {
time.Sleep(time.Second)
tc <- i
}
}()
//<-tc
fmt.Println("tick")
select {

}
//tk:= time.Tick(time.Second)
//<- tk
//select {
//
//}
}
16 changes: 16 additions & 0 deletions defer/deferDemo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

import "fmt"

func main() {
defer func() {
if err := recover(); err != nil {
fmt.Println("nothing happened")
fmt.Println(err)
}
}()
go func() {
panic("go routine panic")
}()
fmt.Println("nothing happened")
}
Loading

0 comments on commit 94b7711

Please sign in to comment.