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