NeetCode.RoadMap
负载均衡算法 更多加分点: 加权等
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 package mainimport ( "math/rand" "time" "fmt" ) type LoadBalancer struct { client []*Client size int32 } func NewLB (size int32 ) *LoadBalalcer { lb := &LoadBalancer{client: make ([]*Client, size), size: size} lb.client = append (lb.client, &Client{}) return lb } func (l *LoadBalancer) getClient() *Client { rand.Seed(time.Now().Unix()) x := rand.Int31n(100 ) return m.client[x & m.size] } type Client struct { Name string } func (m *Client) Do { fmt.Println("Do" ) } func main () { lb := NewLB(4 ) lb.getClient().Do() }
利用反射调用函数 实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package mainimport ( "reflect" "fmt" ) type Car struct {}func (c *Car) Drive { fmt.Println("Driving" ) } func main () { car := Car{} val := reflect.ValueOf(&car) f := value.MethodByName("Drive" ) f.Call([]reflect.Value{}) }
给定三个函数 cat dog fish ,每个函数启动一个 goroutine ,要求按照顺序打印100次 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 package mainimport ( "fmt" "sync" ) func PrintCat (fishCH,catCH chan bool ) { defer waitgroup.Done() defer close (catCH) for i:= 0 ; i <100 ;i++{ <-fishCH fmt.Println("cat ..." ) catCH <- true } } func PrintDog (catCH,dogCH chan bool ) { defer waitgroup.Done() defer close (dogCH) for i:= 0 ; i <100 ;i++{ <-catCH fmt.Println("dog ..." ) dogCH<-true } } func PrintFish (dogCH,fishCH chan bool ) { defer waitgroup.Done() defer close (fishCH) for i:= 0 ; i <100 ;i++{ <-dogCH fmt.Println("fish ..." ) fishCH<-true } } var waitgroup sync.WaitGroupfunc main () { catCH := make (chan bool ,1 ) dogCH := make (chan bool ,1 ) fishCH := make (chan bool ,1 ) fishCH <- true go PrintFish(dogCH,fishCH) go PrintDog(catCH,dogCH) go PrintCat(fishCH,catCH) waitgroup.Add(3 ) waitgroup.Wait() }
抽奖问题 1 2 3 4 5 6 7 8 9 var users map [string ]int64 = map [string ]int64 { "a" : 10 , "b" : 6 , "c" : 3 , "d" : 12 , "f" : 1 , }
1. 随机抽奖 从 map 中随机选取用户中奖 思路:将用户理解为一个个格子,从中选取一个格子中奖
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 package mainimport ( "fmt" "math/rand" "time" ) func GetAwardUserName (users map [string ]int64 ) (name string ) { sizeOfUsers := len (users) award_index := rand.Intn(sizeOfUsers) var index int for u_name, _ := range users { if index == award_index { name = u_name return } index += 1 } return } func main () { var users map [string ]int64 = map [string ]int64 { "a" : 10 , "b" : 6 , "c" : 3 , "d" : 12 , "e" : 20 , "f" : 1 , } rand.Seed(time.Now().Unix()) name := GetAwardUserName(users) fmt.Printf("user: %s jack point" , name) award_stat := make (map [string ]int64 ) for i := 0 ; i < 1000 ; i += 1 { name := GetAwardUserName(users) if count, ok := award_stat[name]; ok { award_stat[name] = count + 1 } else { award_stat[name] = 1 } } for name, count := range award_stat { fmt.Printf("user: %s, award count: %d\n" , name, count) } return }
上方抽奖代码复杂度为 O(n) ,可以结合二分查找优化为 O(logN)
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 func GetAwardGenerator (users map [string ]int64 ) (generator func () string ) { var sum_num int64 name_arr := make ([]string , len (users)) offset_arr := make ([]int64 , len (users)) var index int for u_name, num := range users { name_arr[index] = u_name offset_arr[index] = sum_num sum_num += num index += 1 } generator = func () string { award_num := rand.Int63n(sum_num) return name_arr[binary_search(offset_arr, award_num)] } return } func binary_search (nums []int64 , target int64 ) int { start, end := 0 , len (nums)-1 for start <= end { mid := start + (end-start)/2 if nums[mid] > target { end = mid - 1 } else if nums[mid] < target { if mid+1 == len (nums) { return mid } if nums[mid+1 ] > target { return mid } start = mid + 1 } else { return mid } } return -1 }
2. 加权抽奖 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 func GetAwardGenerator (users map [string ]int64 ) string { var sum_num int64 name_arr := make ([]string , len (users)) for u_name, num := range users { sum_num += num name_arr = append (name_arr, u_name) } var generator func () string generator = func () string { award_num := rand.Int63n(sum_num) var offset_num int64 for _, u_name := range name_arr { offset_num += users[u_name] if award_num < offset_num { return u_name } } return name_arr[0 ] } return }
实现一个消息队列 核心:切片 + 锁
trings/)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 func addStrings (num1 string , num2 string ) string { add := 0 ans := "" for i, j := len (num1) - 1 , len (num2) - 1 ; i >= 0 || j >= 0 || add != 0 ; i, j = i - 1 , j - 1 { var x, y int if i >= 0 { x = int (num1[i] - '0' ) } if j >= 0 { y = int (num2[j] - '0' ) } result := x + y + add ans = strconv.Itoa(result%10 ) + ans add = result / 10 } return ans }
求根号2的值 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 func mySqrt (x int ) float64 { l, r := float64 (0 ), float64 (x) for r-l > 1e-7 { mid := l + (r - l) / 2 if mid * mid <= float64 (x) { l = mid } else { r = mid } } return r } func mySqrt (x int ) float64 { if x == 0 { return 0 } C, x0 := float64 (x), float64 (x) for { xi := 0.5 * (x0 + C/x0) if math.Abs(x0 - xi) < 1e-7 { break } x0 = xi } return x0 }