-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
liufeiyang
committed
Jun 30, 2022
0 parents
commit 94b7711
Showing
72 changed files
with
2,208 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { | ||
// | ||
//} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
} |
Oops, something went wrong.