目前卷一正在完成中,有些答案没有添加或校验。希望广大gopher可以一同完成....
package main
import (
"fmt"
)
func main() {
defer_call()
}
func defer_call() {
defer func() { fmt.Println("打印前") }()
defer func() { fmt.Println("打印中") }()
defer func() { fmt.Println("打印后") }()
panic("触发异常")
}
type student struct {
Name string
Age int
}
func pase_student() {
m := make(map[string]*student)
stus := []student{
{Name: "zhou", Age: 24},
{Name: "li", Age: 23},
{Name: "wang", Age: 22},
}
for _, stu := range stus {
m[stu.Name] = &stu
}
}
func main() {
runtime.GOMAXPROCS(1)
wg := sync.WaitGroup{}
wg.Add(20)
for i := 0; i < 10; i++ {
go func() {
fmt.Println("i: ", i)
wg.Done()
}()
}
for i := 0; i < 10; i++ {
go func(i int) {
fmt.Println("i: ", i)
wg.Done()
}(i)
}
wg.Wait()
}
type People struct{}
func (p *People) ShowA() {
fmt.Println("showA")
p.ShowB()
}
func (p *People) ShowB() {
fmt.Println("showB")
}
type Teacher struct {
People
}
func (t *Teacher) ShowB() {
fmt.Println("teacher showB")
}
func main() {
t := Teacher{}
t.ShowA()
}
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)
}
}
func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
a := 1
b := 2
defer calc("1", a, calc("10", a, b))
a = 0
defer calc("2", a, calc("20", a, b))
b = 1
}
func main() {
s := make([]int, 5)
s = append(s, 1, 2, 3)
fmt.Println(s)
}
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 (set *threadSafeSet) Iter() <-chan interface{} {
ch := make(chan interface{})
go func() {
set.RLock()
for elem := range set.s {
ch <- elem
}
close(ch)
set.RUnlock()
}()
return ch
}
package main
import (
"fmt"
)
type People interface {
Speak(string) string
}
type Student struct{}
func (stu *Student) Speak(think string) (talk string) {
if think == "bitch" {
talk = "You are a good boy"
} else {
talk = "hi"
}
return
}
func main() {
var peo People = Student{}
think := "bitch"
fmt.Println(peo.Speak(think))
}
考点:defer执行顺序,panic的执行方式
结果:
打印后
打印中
“触发异常”
打印前
解析:“触发异常”可能出现在任何位置。defer是先进后出,逆序执行。 笔者猜测:panic()函数相当与go出去的一个协程,相关资料:https://blog.golang.org/defer-panic-and-recover, 将马上更新
解析:
在range循环中,变量是不会随着遍历过程发生变化的。
因此在代码中stu是不会变化的,变化的是放在&stu地址上的数据,
因此最后m中value都将是最后一个放在&stu中的值
解析:
先说说WaitGroup的用途:它能够一直等到所有的goroutine执行完成,并且阻塞主线程的执行,直到所有的goroutine执行完成。
这里要注意一下,他们的执行结果是没有顺序的,调度器不能保证多个 goroutine 执行次序,且进程退出时不会等待它们结束。
WaitGroup总共有三个方法:Add(delta int),Done(),Wait()。简单的说一下这三个方法的作用。
Add:添加或者减少等待goroutine的数量
Done:相当于Add(-1)
Wait:执行阻塞,直到所有的WaitGroup数量变成0
结果:
showA
showB
解析:
首先明确一点 go中没有继承关系。也不应该提及“继承”这个词,其中Trecher并没有继承Propler,而是嵌套People,
而t.ShowA()是一个语法糖,其实t.ShowA() = t.people.ShowA(),也就是说在嵌套结构中,go会优先调用本身方法,
如果本身没有此方法,就回去调用其所包含结构的方法。
本题中,showA()是Teacher不具有的,但是它所嵌套的People具有,因此回调用People.showA(),People.showA()
中调用了*People 的showB()当然会展示“shwoB”,而不是“teacher showB”
引申一点,
如果嵌套有两个结构,并且两个结构具有相同的方法,如何执行的?
例如:
type People struct{}
func (p *People) ShowA() {
fmt.Println("showA")
p.ShowB()
}
func (p *People) ShowB() {
fmt.Println("showB")
}
type Human struct{}
func (h *Human) ShowA() {
fmt.Println("Human showA")
}
type Teacher struct {
Human
People
}
func (t *Teacher) ShowB() {
fmt.Println("teacher showB")
}
func main() {
t := Teacher{}
t.ShowA()
}
答案是 编译报错,不支持这种情况的。
结果:
10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4
解析:
1、当程序运行到defer函数时,不会执行函数实现,但会将defer函数中的参数代码进行执行。
因此首先执行的是calc("10", a, b)),随后执行的是calc("2", a, calc("20", a, b))
得到第一行和第二行结果。
2、defer的执行结果是先进后出,从函数尾部向函数头部以此执行。因此会首先执行calc("2", a, calc("20", a, b)),
然后执行defer calc("1", a, calc("10", a, b)),相应打印第三行和第四行
结果:
0 0 0 0 0 1 2 3
解析:
make([]int,5)的含义是创建数组,并且数组初始化5个元素,5个元素的值为类型零值。
结果:
编译不过去
解析:
原因是Student并没有继承People,people中有Speak(string)string方法,而Student类型中没有Speak()方法,
代码中的Student方法是*Student类型的,所有 var peo People = Student{}是不符合规范的。