package main
import (
"context"
"errors"
"fmt"
"time"
)
func main() {
ctx, cancle := context.WithTimeout(context.Background(), time.Second*5)
defer cancle()
fmt.Println("<<<<<<<<<<<<<<<<", T2(ctx))
}
func T(ctx context.Context) []int {
c := make(chan int)
go func() {
for i := 0; i < 10; i++ {
c <- i
time.Sleep(1 * time.Second)
}
close(c)
}()
result := make([]int, 0)
for {
var (
ok bool
x int
)
select {
case x, ok = <-c:
fmt.Println(">>>>>>>>>>>", x)
result = append(result, x)
case <-ctx.Done():
fmt.Println(">>>>>>>>>timeout")
}
if !ok {
break
}
}
return result
}
func T2(ctx context.Context) []int {
c := make(chan error)
result := make([]int, 0)
go func() {
defer close(c)
for i := 0; i < 10; i++ {
result = append(result, i)
c <- errors.New("hahahah")
time.Sleep(1 * time.Second)
}
}()
for {
select {
case x, ok := <-c:
fmt.Println(">>>>>>>", x)
if !ok {
return result
}
case <-ctx.Done():
fmt.Println(">>>>>>>>>timeout")
return result
}
}
}
func T3() []int {
c := make(chan error)
result := make([]int, 0)
go func() {
defer close(c)
for i := 0; i < 10; i++ {
result = append(result, i)
c <- errors.New("hahahah")
time.Sleep(1 * time.Second)
}
}()
for {
select {
case x, ok := <-c:
fmt.Println(">>>>>>>", x)
if !ok {
return result
}
case <-time.After(time.Second * 5):
fmt.Println(">>>>>>>>>timeout")
return result
}
}
}
func T4() []int {
c := make(chan error)
result := make([]int, 0)
go func() {
defer close(c)
for i := 0; i < 10; i++ {
result = append(result, i)
c <- errors.New("hahahah")
time.Sleep(6 * time.Second)
}
}()
for {
select {
case x, ok := <-c:
fmt.Println(">>>>>>>", x)
if !ok {
return result
}
case <-time.After(time.Second * 5):
fmt.Println(">>>>>>>>>timeout")
return result
}
}
}
func T5() []int {
c := make(chan error)
result := make([]int, 0)
go func() {
defer close(c)
for i := 0; i < 10; i++ {
result = append(result, i)
c <- errors.New("hahahah")
time.Sleep(6 * time.Second)
}
}()
for timeOut := time.After(time.Second * 20); ; {
select {
case x, ok := <-c:
fmt.Println(">>>>>>>", x)
if !ok {
return result
}
case <-timeOut:
fmt.Println(">>>>>>>>>timeout")
return result
}
}
}
延迟运行func中的指针问题
# package main
import "fmt"
func main() {
origin := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s := func(i int) func() {
return func() {
fmt.Println(">>>>>>>>>>>>>", i)
}
}(origin[9])
origin[9] = 10
s() // output: >>>>>>>>>>>>> 9
origin = append([]int{-1}, origin...)
s() // output: >>>>>>>>>>>>> 9
s2 := func(i *int) func() {
return func() {
fmt.Println(">>>>>>>>>>>>>>", *i)
}
}(&(origin[9]))
s2() // output: >>>>>>>>>>>>> 8
origin[9] = 9
s2() // output: >>>>>>>>>>>>> 9
}
六大原则
- 职责单一原则
- 里式替换原则
- 依赖倒置原则
- 接口隔离原则
- 迪米特原则
- 开闭原则
高可用
衡量一个系统架构设计是否满足高可用的目标,就是假设系统中任何一台或者多台服务器宂机时,以及出现各种不可预期的问题时,系统整体是否依然可用
伸缩性
所谓伸缩性时指通过不断向集群中加入服务器的手段来缓解不断上升的用户并发访问压力和不断增长的数据存储需求
衡量架构伸缩性的主要标准就是是否可以用多台服务器构建集群,是否容易向集群中添加新的服务器,加入新的服务器后是否可以提供和原来的服务器无差别的服务,集群中可容纳的总的服务器数量是否有限制
拓展性
衡量网站架构拓展性好坏的主要标准就是在网站增加新的业务产品时,是否可以实现对现有产品透明无影响,不需要任何改动或者很少改动既有业务功能就可以上线新产品。不同产品之间是否很少耦合,一个产品改动对其他产品无影响,其他产品和功能不需要受牵连进行改动
矩阵空间压缩方法
在动态规划里,如果只是得到结果而非过程,实际可以不记录整个矩阵,可以压缩为min(m,n)
在最短路径问题里,如果只是要得出最短路径和的话,可以用到这个技巧
实现数组倒序
package main
import (
"fmt"
"sort"
"strings"
)
func main() {
god := []string{"g", "o", "d"}
sort.SliceStable(god, func(i, j int) bool { return i > j })
fmt.Printf("god is %s", strings.Join(god,""))
}
output is : god is dog