1. What does the following code output , Why? 
//make([]T, length, capacity) s1 := []int{1, 2, 3} fmt.Println(s1, " ha-ha ") //[1 
2 3] s2 := s1 fmt.Println(s1, " ha-ha ") //[1 2 3] for i := 0; i < 3; i++ { s2[i] = 
s2[i] + 1 } fmt.Println(s1) //[2 3 4] fmt.Println(s2) //[2 3 4] [1 2 3]  ha-ha  [1 2 
3]  ha-ha  [2 3 4] [2 3 4] 
 notes : The quotation is the same , It's equivalent to an alias , It's just one more name .
  stay Go The types of references in languages are : mapping (map), Array slicing (slice), passageway (channel), Methods and functions .
  integer , character string , Boor , When an array is passed as a parameter , Is the memory address of the delivery replica , That is, value passing .
2. What does the following code output , Why? 
func rmLast(a []int) { fmt.Println("a", a) a = a[:len(a)-1] for i := 0; i < 13;
 i++ { a = append(a, 8) } fmt.Println("rm after a", a) // fmt.Println(len(a)) } func 
updateLast(a []int) { fmt.Println("a", a) for i := 0; i < len(a); i++ { a[i] = a
[i] + 1 } fmt.Println(" After modification a", a) // fmt.Println(len(a)) } func main() { xyz := [
]int{1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Println("xyz", xyz) rmLast(xyz) fmt.Println(
"rm after xyz", xyz) updateLast(xyz) fmt.Println(" After modification xyz", xyz) //[1 2 3 4 5 6 7 8 9] 
} xyz [1 2 3 4 5 6 7 8 9] a [1 2 3 4 5 6 7 8 9] rm after a [1 2 3 4 5 6 7 8 8 8 8 8 8 
8 8 8 8 8 8 8 8] rm after xyz [1 2 3 4 5 6 7 8 8] a [1 2 3 4 5 6 7 8 8]  After modification a [2 3 4 5 
6 7 8 9 9]  After modification xyz [2 3 4 5 6 7 8 9 9] 
 notes : The value of the slice in the function , The outside is visible , The length of the modified slice is not visible outside 
3. What does the following code output , Why? 
//n1 yes n2 The underlying array of  n1 := [3]int{1, 2, 3} n2 := n1[0:3] fmt.Println(" Here's what's going on n1 address  ") for i 
:= 0; i < len(n1); i++ { fmt.Printf("%p\n", &n1[i]) } fmt.Println(n1) fmt.
Println(" Here's what's going on n2 address  ") for i := 0; i < len(n2); i++ { fmt.Printf("%p\n", &n2[i]) } 
fmt.Println(n2) n2 = append(n2, 1) fmt.Println(" Here's what's going on n1 address  ") for i := 0; i < len(
n1); i++ { fmt.Printf("%p\n", &n1[i]) } fmt.Println(n1) fmt.Println(" Here's what's going on n2 address  ") 
for i := 0; i < len(n2); i++ { fmt.Printf("%p\n", &n2[i]) } fmt.Println(n2) 
 Here's what's going on n1 address 0xc000064140 0xc000064148 0xc000064150 [1 2 3]  Here's what's going on n2 address  0xc000064140 
0xc000064148 0xc000064150 [1 2 3]  Here's what's going on n1 address  0xc000064140 0xc000064148 0xc000064150
[1 2 3]  Here's what's going on n2 address  0xc000090030 0xc000090038 0xc000090040 0xc000090048 [1 2 3 1] 
4. What does the following code output , Why? 
func defer_call(y int) { for i := 0; i < 5; i++ { defer fmt.Println(" output y+i", y+
i) fmt.Println(" ha-ha ") defer fmt.Println(" output i ", i) } } func main() { defer_call(5
) }  ha-ha   ha-ha   ha-ha   ha-ha   ha-ha   output i 4  output y+1 9  output i 3  output y+1 8  output i 2  output y+1 7  output i 1  output y+1 6  output i 0
  output y+1 5  notes : Go ahead " ha-ha ",  sign out defer_call When you use this function , Perform the following functions in reverse order  fmt.Println(" output y+i",5) 
fmt.Println("i",0) fmt.Println(" output y+i",6) fmt.Println(....) 
fmt.Println(" output y+i",9) fmt.Println("i",4) 
5. What does the following code output 
func main() { for i := 0; i < 5; i++ { fmt.Println(i, "haha") 
// Anonymous function : Anonymous functions can be called after declarations.  go func() { time.Sleep(3 * time.Second) fmt.Println(i, " Mm-hmm ")
}() } time.Sleep(10 * time.Second) } 0 haha 1 haha 2 haha 3 haha 4 haha 5  Mm-hmm  5 
 Mm-hmm 5  Mm-hmm  5  Mm-hmm  5  Mm-hmm  
6. What does the following code output 
func main() { strs := []string{"one", "two", "three"} for _, s := range strs { 
//1. The main thread is almost finished ( The main thread runs to three It's over ), The concurrent threads are just beginning  //2. If the anonymous function does not pass parameters here , It's shared s Your address , So it's all printed out three go
func() { time.Sleep(1 * time.Second) fmt.Printf("%s ", s) }() } time.Sleep(3 * 
time.Second) } three three three 
7. What does the following code output 
func main() { strs := []string{"one", "two", "three"} for _, s := range strs { 
go func(s string) { time.Sleep(1 * time.Second) fmt.Printf("%s ", s) }(s) } time
.Sleep(3 * time.Second) } three one two one two three one three two 
 notes : There are three concurrent threads , It doesn't necessarily end first , So the output is not fixed 
8. What does the following code output 
func main() { x := []string{"ha", "b", "c"} for v := range x { fmt.Print(v) } }
012 
9. What does the following code output 
type Slice []int func NewSlice() Slice { return make(Slice, 0) } func (s *Slice
) Add(elem int) *Slice { *s = append(*s, elem) fmt.Print(elem) return s } func 
main() { s := NewSlice() defer s.Add(1).Add(2) s.Add(3) } 132 
 notes : One defer Only one function can be delayed ,defer s.Add(1).Add(2), Execute the parameters section first , Then delay the call Add(2)
10. What does the following code output 
package main import ( "fmt" ) func main() { defer_call() } func defer_call() { 
defer func() { fmt.Println(" Before printing ") }() defer func() { fmt.Println(" Printing ") }() 
defer func() { fmt.Println(" After printing ") }() panic(" Trigger exception ") } 
 Examination site :defer Execution sequence 
  answer :
 defer  Last in, first out .
 panic  Need to wait defer  It will be passed up after the end .  appear panic Panic time , I'll do it first defer The last in, first out sequence of , It will be implemented in the end panic.
 After printing 
  Printing 
  Before printing 
 panic:  Trigger exception 
11. What does the following code output 
package main import ( "fmt" ) //  Traverse each element of the slice ,  Element access through a given function  func visit(list []int,
 ffunc(int)) { for _, v := range list { f(v) } } func main() { //  Using anonymous functions to print slice contents  
visit([]int{1, 2, 3, 4}, func(v int) { fmt.Println(v) }) } 
1
 2
 3
 4
12. What does the following code output 
package main import ( "fmt" "runtime" "sync" ) func main() { 
//GOMAXPROCS Set the maximum number of simultaneous execution CPU number , And return to the previous settings . //  if  n < 1, It will not change the current settings . Logic of local machine CPU The number can be calculated by  
NumCPU  query . // This function will be removed after the scheduler is optimized . runtime.GOMAXPROCS(1) wg := sync.WaitGroup{} wg.Add
(20) for i := 0; i < 10; i++ { // Main thread  go func() { // Concurrent threads  fmt.Println("A: ", i)
 wg.Done() }() } for i := 0; i < 10; i++ { go func(i int) { fmt.Println("B: ", i
) wg.Done() }(i) } wg.Wait() } 
 Examination site :go Randomness of execution and closure 
  answer :
  No one knows the order of printing after execution , So it's a random number .  however A: All are outputs 10,B: from 0~9 output ( The order is variable ).  first go 
func in i It's the outside for A variable of , The address does not change . After traversal , final i=10.  so go func On execution ,i The value of is always 10.
 the second go func in i Is a function parameter , With the outside world for In i It's two variables .  tail (i) The value copy will occur ,go func Internal point value copy address .
13. What does the following code output 
package main import ( "fmt" "runtime" "sync" ) func main() { 
//GOMAXPROCS Set the maximum number of simultaneous execution CPU number , And return to the previous settings . //  if  n < 1, It will not change the current settings . Local machine of logic CPU The number can be calculated by  
NumCPU  query . // This function will be removed after the scheduler is optimized . runtime.GOMAXPROCS(2) wg := sync.WaitGroup{} wg.Add
(3) for i := 0; i < 10; i++ { // Main thread  go func() { // Concurrent threads  fmt.Println("A: ", i) 
wg.Done() }() } wg.Wait() wg.Add(7) wgg := sync.WaitGroup{} wgg.Add(5) for i := 
0; i < 10; i++ { go func(i int) { fmt.Println("B: ", i) wgg.Done() }(i) } wgg.
Wait() } 
14. Will the following code trigger an exception ? Please elaborate 
package main import ( "fmt" "runtime" ) func main() { runtime.GOMAXPROCS(1) 
int_chan:= make(chan int, 1) string_chan := make(chan string, 1) int_chan <-1 
string_chan<-"hello" select { case value := <-int_chan: fmt.Println(value) case 
value:= <-string_chan: panic(value) } } 
 Examination site :select Randomness 
  answer :
 select One can be selected randomly for receiving and sending operation .  So the code is willing to trigger exceptions , Maybe not .  single chan If there is no buffer , It's going to block . But combining  
select Can be in multiple chan Waiting for execution . There are three principles :
select  Just one of them case can return, Then immediately .
  When there are more than one case All can return Then any one of them is selected in pseudo-random mode .
  If there is not one case can return Can be executed ”default” block .
15. What's wrong with the following code , How to modify 
package main import ( "fmt" "sync" ) type UserAges struct { ages map[string]int
 sync.Mutex } func (ua *UserAges) Add(name string, age int) { ua.Lock() defer ua
.Unlock() ua.ages[name] = age } func (ua *UserAges) Get(name string) int { if 
age, ok := ua.ages[name]; ok { return age } return -1 } func main() { var 
userAges UserAges userAges.Add("lisa", 24) userAges.Get("lisa") fmt.Println(
userAges.ages) } 
panic: assignment to entry in nil map
goroutine 1 [running]:
 main.(*UserAges).Add(0xc0000521c0, 0x4c492f, 0x4, 0x18)
 C:/Users/zyq/go/src/yj/ra.go:17 +0x98
 main.main()
 C:/Users/zyq/go/src/yj/ra.go:28 +0x69
 exit status 2
  After modification :
func (ua *UserAges) Add(name string, age int) { ua.ages = make(map[string]int) 
ua.Lock() defer ua.Unlock() ua.ages[name] = age } 
 Output results :
map[lisa:24] 
16. What does the following code output , Why? 
package main import ( "fmt" "sync" ) type threadSafeSet struct { sync.RWMutex s
[]interface{} } func (set *threadSafeSet) Iter() <-chan interface{} { // ch := 
make(chan interface{}) //  Take a look at the uncomment ! ch := make(chan interface{}, len(set.s)) go 
func() { set.RLock() for _, elem := range set.s { ch <- elem fmt.Println("Iter:"
, elem) } close(ch) set.RUnlock() }() return ch } func main() { th := 
threadSafeSet{ s: []interface{}{"1", "2"}, } v := <-th.Iter() fmt.Println(v) } 
Iter: 1
 Iter: 2
 1
  answer :ch := make(chan interface{}, len(set.s))  A new one is assigned each time channel,v := 
<-th.Iter() Only one value was passed , therefore v It's an array s First of all value
17. What does the following code output ? Why? ?
package main import ( "fmt" ) type People interface { Show() } type Student 
struct{} func (stu *Student) Show() { } func live() People { var stu *Student 
return stu } func main() { if live() == nil { fmt.Println("AAAAAAA") } else { 
fmt.Println("BBBBBBB") } } 
 output :
 BBBBBBB
18. What does the following code output ? Why? ?
package main func main() { i := GetValue() switch i.(type) { case int: println(
"int") case string: println("string") case interface{}: println("interface") 
default: println("unknown") } } func GetValue() int { return 1 } 
 analysis 
  Examination site :type
 Compilation failed , because type Can only be used in interface
  After modification :
package main func main() { i := GetValue() switch i.(type) { case int: println(
"int") case string: println("string") case interface{}: println("interface") 
default: println("unknown") } } func GetValue() interface{} { return 1 } 
19. What does the following code output ? Why? ?
package main import "fmt" func main() { s1 := []int{1, 2, 3} s2 := []int{4, 5} 
s1= append(s1, s2...) fmt.Println(s1) fmt.Println(s2) var a = []int{1, 2, 3} a =
append([]int{0}, a...) fmt.Println(a) a = append([]int{-3, -2, -1}, a...) fmt.
Println(a) } 
[1 2 3 4 5]
 [4 5]
 [0 1 2 3]
 [-3 -2 -1 0 1 2 3]
  Examination site :
 1. Add a slice ,  The slice needs to be unpacked s1 = append(s1, s2…)
 2. Except at the end of the slice , We can also add elements at the beginning of the slice 
20. What does the following code output ? Why? ?
package main import "fmt" func GetValue(m map[int]string, id int) (string, bool
) { if _, exist := m[id]; exist { return " There is data ", true } return "", false } func 
main() { intmap := map[int]string{ 1: "a", 2: "bb", 3: "ccc", } v, err := 
GetValue(intmap, 3) fmt.Println(v, err) } 
 There is data  true
  Examination site :map Of key Does it exist 
21. What does the following code output ? Why? ?
package main func DeferFunc1(i int) (t int) { t = i defer func() { t += 3 }() 
return t } func DeferFunc2(i int) int { t := i defer func() { t += 3 }() return 
t} func DeferFunc3(i int) (t int) { defer func() { t += i }() return 2 } func 
main() { println(DeferFunc1(1)) println(DeferFunc2(1)) println(DeferFunc3(1)) } 
4
 1
 3
  Examination site :
  The key to this question is whether the return value has a name , If you have a name , Return value is controlled by defer Inside func The impact of , Without a name, it's not affected 
22. What does the following code output ? Why? ?
package main import "fmt" const ( x = iota y z = "zz" k p = iota c d = "111" f 
) func main() { fmt.Println(x, y, z, k, p, c, d, f) } 
0 1 zz zz 4 5 111 111
  Examination site :
  In constant declaration , Pre declared identifier  iota Represents a continuous typeless integer   constant . Its value is the  
 The corresponding ConstSpec Index of , Start from scratch . It can be used to construct a set of related constants :
const(
 c0 = iota // c0 == 0
 c1 = iota // c1 == 1
 c2 = iota // c2 == 2
 )
const(
 a = 1 << iota // a == 1(iota == 0)
 b = 1 << iota // b == 2(iota == 1)
 c = 3 // c == 3(iota == 2, not used )
 d = 1 << iota // d == 8(iota == 3)
 )
const(
 u = iota * 42 // u == 0( Typeless integer constant )
 v float64 = iota * 42 // v == 42.0(float64 constant )
 w = iota * 42 // w == 84( Typeless integer constant )
 )
23. What does the following code output ? Why? 
package main var size = 1024 var max_size = size * 2 func main() { println(size
, max_size) } 
extra expression in var declaration
  Examination site : Variable short pattern 
  Variable short mode limit :
  Define variables and initialize them explicitly at the same time 
  Data type cannot be provided 
  Can only be used inside a function 
var a int var a = 1 a:=1 
24. Can the following code be output ? Why? 
package main import"fmt" func main() { type MyInt1 int type MyInt2 = int var i 
int =9 var i1 MyInt1 = i var i2 MyInt2 = i fmt.Println(i1,i2) } 
cannot use i (type int) as type MyInt1 in assignment
  Examination site :
  Create a new type based on a type , be called defintion; Create an alias based on a type , be called alias. 
MyInt1 Call it defintion, Although the underlying type is int type , But it cannot be assigned directly , It needs to be forced ; MyInt2 be called alias, It can be assigned directly .
25. Can the following code be output ? Why? 
package main import "fmt" type User struct { } type MyUser1 User type MyUser2 =
 Userfunc (i MyUser1) m1() { fmt.Println("MyUser1.m1") } func (i User) m2() { 
fmt.Println("User.m2") } func main() { var i1 MyUser1 var i2 MyUser2 i1.m1() i2.
m2() i1.m2() } 
 output :
 MyUser1.m1
 User.m2
 i1.m2() It can't be carried out , because MyUser1 The method is not defined .
  Examination site :
  because MyUser2 Completely equivalent to User, So it has all its methods , And one of them added a new method , There will be another one .
26. use WaitGroup Concurrent calculation of the sum of two groups of data 
package main import ( "fmt" "sync" ) func main() { wg := sync.WaitGroup{} var 
xValueint var iValue int wg.Add(2) // Start two processes  go func() { for x := 0; x <= 50; x++ 
{ xValue += x } fmt.Println("xValue: ", xValue) wg.Done() 
// Put it in the process at the end , Make sure the process is finished, and the counter will be subtracted by one  }() //wg.Done()  If done Put it here , We can't confirm whether the above process has done or not , It's going to be one less  go 
func() { for i := 51; i <= 100; i++ { iValue += i } fmt.Println("iValue: ", 
iValue) wg.Done() }() wg.Wait() fmt.Println("sumValue", xValue+iValue) } 
iValue: 3775
 xValue: 1275
 sumValue 5050
27. Using channel to calculate the sum of two groups of data 
package main import ( "fmt" ) func main() { c := make(chan int, 2) go func() { 
var xValue int for x := 0; x <= 50; x++ { xValue += x } c <- xValue }() go func(
) { var iValue int for i := 51; i <= 100; i++ { iValue += i } c <- iValue }() x,
 y:= <-c, <-c fmt.Println("sumValue", x+y) } 
sumValue 5050
28. What does the following code output , Why? 
package main func main() { done := make(chan struct{}) // end event  c := make(chan 
string) // Data transmission channel  go func() { s := <-c // Accept the message  println(s) close(done) 
// Close the channel , As closing notice  }() c <- "hi!" // send message  <-done // block , Until all data or pipes are closed  } 
hi!
29. What does the following code output , Why? 
package main import ( "sync" "time" ) func main() { var wg sync.WaitGroup ready
:= make(chan struct{}) for i := 0; i < 3; i++ { wg.Add(1) go func(id int) { 
defer wg.Done() println(id, ":ready.") <-ready // Because I can't get it , So it's blocked  println(id, ": 
running...") }(i) } time.Sleep(time.Second) println("ready?Go!") close(ready) 
//close after , Close the channel and unblock it  wg.Wait() } 
0 :ready.
 1 :ready.
 2 :ready.
 ready?Go!
 2 : running…
 1 : running…
 0 : running…
30. What does the following code output , Why? 
package main func main() { done := make(chan struct{}) // Used to end an event  c := make(chan 
int) // Data transmission channel  go func() { defer close(done) // Notice to close  for x := range c { 
// Cycle through the message until the channel is closed  println(x) } }() c <- 1 c <- 2 c <- 3 close(c) // Channel closed to unblock  <-done
// block , Until there is data or notification to close  } 
1
 2
 3
31. What does the following code output , Why? 
package main func main() { done := make(chan struct{}) // Used to end an event  c := make(chan 
int) // Data transmission channel  go func() { defer close(done) // Notice to close  for { x, ok := <-c if !ok { 
// According to this, judge whether the channel is closed or not  return } println(x) } // Channel closed , End of cycle  }() c <- 1 c <- 2 c <- 3 close(c
) // Channel closed to unblock  <-done // block , Until there is data or notification to close  } 
1
 2
 3
32. What does the following code output , Why? 
package main func main() { c := make(chan int, 3) // Data transmission channel  c <- 10 c <- 20 
close(c) for i := 0; i < cap(c)+1; i++ { x, ok := <-c println(i, ":", ok, x) } }
0 : true 10
 1 : true 20
 2 : false 0
 3 : false 0
33. What does the following code output , Why? 
  If multiple channels are processed at the same time , Optional select sentence , He will randomly select an available channel for receiving and transmitting 
package main import "sync" func main() { var wg sync.WaitGroup wg.Add(2) a, b 
:= make(chan int), make(chan int) go func() { // receiving end  defer wg.Done() for { var ( 
namestring x int ok bool ) select { // Random selection available channel receive data   case x, ok = <-a: name =
"a" case x, ok = <-b: name = "b" } if !ok { return // If any channel is closed , Then the reception is terminated  } println(
name, x) // Output received data information  } }() go func() { // Sender  defer wg.Done() defer close(a) 
defer close(b) for i := 0; i < 10; i++ { select { // Randomly selected to send channel case a <- i: 
case b <- i * 10: } } }() wg.Wait() } 
 Output one 
 C:\Users\zyq\go\src\LearnGoLang\learn>go run hello.go
 b 0
 a 1
 a 2
 a 3
 b 40
 b 50
 b 60
 a 7
 a 8
 a 9
  Output 2 
 C:\Users\zyq\go\src\LearnGoLang\learn>go run hello.go
 a 0
 b 10
 b 20
 b 30
 a 4
 a 5
 b 60
 b 70
 b 80
 a 9
  output …
34. What does the following code output , Why? 
  The channel is bidirectional by default , There is no distinction between sender and receiver , But sometimes we can restrict the direction of the receive and send operation to get more rigorous operation logic .
  Type conversion is usually used to get one-way channels , And give the two sides of the operation .
package main import "sync" func main() { var wg sync.WaitGroup wg.Add(2) c := 
make(chan int) var send chan<- int = c // Send only  var recv <-chan int = c // Receive only  go 
func() { // receiving end  defer wg.Done() for x := range recv { println(x) } }() go func() 
{ // Sender  defer wg.Done() defer close(c) for i := 0; i < 3; i++ { send <- i } }() 
wg.Wait() } 
0
 1
 2
  be careful :
 1. Reverse operation cannot be done on unidirectional communication 
 2.close() Cannot be used for receiving end 
 3. Unable to convert one-way channel back 
35. What does the following code output , Why? 
  problem : Channel energy transfer slice Is that right 
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup wg.Add
(2) a, b := make(chan []int), make(chan []int) go func() { // receiving end  defer wg.Done()
for { var ( name string x []int ok bool ) select { // Random selection available channel receive data   case x, 
ok= <-a: name = "a" case x, ok = <-b: name = "b" } if !ok { return 
// If any channel is closed , Then the reception is terminated  } x[0] = 99 fmt.Println(name, x) // Output received data information  } }() i := []int{1
, 2, 3, 4} go func() { // Sender  defer wg.Done() defer close(a) defer close(b) fmt.
Println(i) select { // Randomly selected to send channel case a <- i: } }() wg.Wait() fmt.Println(i)
} 
[1 2 3 4]
 a [99 2 3 4]
 [99 2 3 4]
36. The third 33 How to solve the problem , Wait for the end of all channel message processing , Instead of terminating reception when any channel is closed 
  Tips : If you want to wait for the end of all channel message processing , The completed channel can be set to nil, So it gets blocked , No more select Select .
package main import "sync" func main() { var wg sync.WaitGroup wg.Add(3) a, b 
:= make(chan int), make(chan int) go func() { // receiving end  defer wg.Done() for { select
{ // Random selection available channel receive data   case x, ok := <-a: if !ok { a = nil break 
// Used to jump out of a loop in a loop statement , And start executing the statement after the loop . //break  stay  switch( Switch statement ) In the implementation of a  case  The function of jumping out after a sentence . } 
println("a", x) case x, ok := <-b: if !ok { b = nil break } println("b", x) } if
 a== nil && b == nil { // It's all over , Exit loop  return } } }() go func() { // Sender a defer wg.
Done() defer close(a) for i := 0; i < 3; i++ { a <- i } }() go func() { // Sender b 
defer wg.Done() defer close(b) for i := 0; i < 3; i++ { b <- i * 10 } }() wg.
Wait() } 
a 0
 b 0
 b 10
 a 1
 a 2
 b 20
37. What does the following code output , Why? 
  If it's the same channel , It's also a random choice case implement 
package main import "sync" func main() { var wg sync.WaitGroup wg.Add(2) c := 
make(chan int) go func() { // receiving end  defer wg.Done() for { var ( v int ok bool ) 
select { // Random selection available channel receive data   case v, ok = <-c: println("a1:", v) case v, ok = <-
c: println("a2:", v) } if !ok { return // If any channel is closed , Then the reception is terminated  } } }() go func() { 
// Sender  defer wg.Done() defer close(c) for i := 0; i < 10; i++ { select { 
// Randomly selected to send channel case c <- i: case c <- i * 10: } } }() wg.Wait() } 
a1: 0
 a2: 10
 a1: 20
 a1: 30
 a1: 40
 a1: 5
 a1: 6
 a2: 70
 a1: 80
 a1: 9
 a2: 0
38. What does the following code output , Why? 
package main func main() { done := make(chan struct{}) data := []chan int{ make
(chan int, 3), // Data buffer  } go func() { defer close(done)// Close the channel , End blocking  for i := 0; i 
< 10; i++ { select { case data[len(data)-1] <- i: dafault: data = append(data, 
make(chan int, 3)) } } }() <-done// block  for i := 0; i < len(data); i++ { c := data
[i] close(c) for x := range c { println(x) } } } 
39. What does the following code output , Why? 
  The factory method is usually used to goroutine Bind to channel 
package main import "sync" type receiver struct { sync.WaitGroup data chan int 
} func newReceiver() *receiver { r := &receiver{ data: make(chan int), } r.Add(1
) go func() { // receiving end  defer r.Done() for x := range r.data { // Receive the message until the channel is closed  println
("recv:", x) } }() return r } func main() { r := newReceiver() r.data <- 1 // Sender 
 r.data <- 2 close(r.data) // Close the channel , Give notice of termination  r.Wait() // Wait for the end of receiver processing  } 
recv: 1
 recv: 2
40. What does the following code output , Why? 
  Using channel to realize semaphore 
package main import ( "fmt" "sync" "runtime" "time" ) func main(){ runtime.
GOMAXPROCS(4) var wg sync.WaitGroup sem:=make(chan struct{},2)// A maximum of two concurrent execution is allowed  for
 i:=0;i<5;i++{ wg.Add(1) go func(id int){ defer wg.Done() sem<-struct{}{}
//acquire: Get the signal  defer func(){<-sem}()//release: Release the signal  time.Sleep(time.Second*2) fmt
.Println(id,time.Now().Unix()) }(i) } wg.Wait() } 
0 1599985509
 4 1599985509
 2 1599985511
 1 1599985511
 3 1599985513
41. What does the following code output , Why? 
  Standard library time Provided timeout and tick channel realization 
package main import ( "fmt" "time" "os" ) func main(){ go func(){ for{ select{ 
case <-time.After(time.Second*5): //func After(d Duration) <-chan Time 
//After A period of time passes in another thread d The time when the backward return value is sent . Equivalent to NewTimer(d).C. fmt.Println("timeout...") os.
Exit(0) // Exit Let the current program use the given status code code sign out . generally speaking , // Status code 0 Show success , wrong 0 Indicates an error . The program will terminate immediately ,defer The function for is not executed .
} } }() go func(){ tick:=time.Tick(time.Second) for{ select{ case <-tick: fmt.
Println(time.Now().Unix()) } } }() <-(chan struct{})(nil)// Direct use nil channel Blocking process  } 
42. What does the following code output , Why? 
  Channels are not used to replace locks , They have different use scenarios . Channel tends to solve the concurrent processing architecture of logical level , The lock is used to protect local data security .
package main import ( "sync" "time" ) type data struct { sync.Mutex } func (d 
data) test(s string) { d.Lock() defer d.Unlock() for i := 0; i < 5; i++ { 
println(s, i) time.Sleep(time.Second) } } func main() { var wg sync.WaitGroup wg
.Add(2) var d data go func() { defer wg.Done() d.test("read") }() go func() { 
defer wg.Done() d.test("write") }() wg.Wait() } 
write 0
 read 0
 read 1
 write 1
 read 2
 write 2
 read 3
 write 3
 read 4
 write 4
Technology