1.简述golang中make和new的区别
make用于内建类型(只能用于创建map、slice 和channel)的内存分配。并且返回一个有初始值(非零)的T类型,而不是*T。
new用于各种类型的内存分配。new(T)分配了零值填充的T类型的内存空间,并且返回其地址,即一个T类型的值。用Go的术语说,它返回了一个指针,指向新分配的类型T的零值。有一点非常重要:*new返回指针。
2.简要描述go中的main和init函数的区别 首先,这两个函数应用位置不同,init函数可以应用于所有的package,main只能应用于 package main,需要注意的是虽然一个package中可以写任意多个init,但是无论是从可读性还是可维护性来说,都是不推荐的;
其次,这两个函数定义时都不能有任何的参数和返回值,
最后,个人理解,init函数为初始化操作,main函数为程序入口。 一图胜千言
3.写出下面代码的输出结果
package main
import (
"fmt"
)
type student struct {
Name string
Age int
}
func main() {
m :=pase_map()
for k,v :=range m {
fmt.Printf("key = %s,value =%v\n",k,v)
}
}
func pase_map() map[string]*student{
m :=make(map[string]*student)
stu :=[]student{{"joy",12},{"lei",14}}
for _,v :=range stu{
m[v.Name]=&v
}
return m
}
解题思路:pase_map返回了一个key为string,值为*student的map,遍历结果应为map的key和value,主要误区在m中,value的值都为&{lei 14},这也是我所不能理解的,感觉进了思维误区,求大神指点
4.通道选择器中的panic问题
package main
import "fmt"
var c1 = make(chan int,1)
var c2 = make(chan string,1)
func main() {
c1 <-1
c2 <-"hello"
select {
case v1 := <-c1:
fmt.Println(v1)
case v2 := <-c2:
panic(v2)
}
}
不一定会引起恐慌,可能会打印1,也可能会恐慌
5.协程交替执行,使其能顺序输出1-20的自然数
package main
import (
"fmt"
"time"
)
func main() {
for i:=1;i<=10;i++ {
go func(i int) {
fmt.Println(2*i-1)
}(i)
}
for i:=1;i<=10;i++ {
go func(i int) {
fmt.Println(2*i)
}(i)
}
time.Sleep(3*time.Second)
}
有疑问加站长微信联系(非本文作者))

关于第3题问题,有一个误区:
m[v.Name]=&v
这里是把 for range 中v 的地址赋值给m。而在range迭代中 v是分配的一个地址(每次迭代中的v都是一个变量),然后每一次迭代给v赋不同的值,所以map所有的值都指向了 v的地址,而v在for range 迭代中只保留了最后一次迭代的值&{lei 14}(前面的值都被覆盖了),因此value 都是&{lei 14}下面是证明实验,添加打印了地址语句
实验结果:
第5题这个是随机输出的,这道题怎么解?
你可以百度一下runtime.Gosched()就知道怎么做了
协程交替执行,使其能顺序输出1-20的自然数,应该这样写才合理吧
#############利用单核,通道交互.
第五题 一个channel传值就够了
谢谢,不过感觉下面老哥的答案也挺好的
老哥,稳
我刚才百度了一下runtime.Gosched(),功能是运行到这一行时就会让出时间片,
按理说,运行到1的时候就会让出时间片,紧接着运行下面线程,运行到2时让出时间片再运行到1. 但是事实并非如此,运行结果还是随机的
下面的代码为什么不行,输出经常是错的。不明白,求各位大佬解释一下
这个问题 是go的协程调度器产生的 当主协程往通道里写入数据时,此时子协程1(即会输出1的协程)读出数据1,但没有输出1,就失去了CPU的时间片。 主协程继续创建了子协程2(即会输出2的协程),子协程2读到数据。 在极端情况下,可能连续创建了20个子协程,然后groutine调度器按一定顺序调度这20个协程,自然会出现乱序。 但实际上会在个别协程上出现偶尔的乱序。比如2在1前面输出,实际上是子协程1先于子协程2创建。然后子协程2先于子线程1获得运行 这个问题是比较难以看出的,也很难用语言描述。
你这个不符合题意中的:交替两字。
for循环并没有被阻塞,所以会不停的创建go协程,等待输出
v是这个函数的一个临时变量,函数运行完之后这个地址可能会挪作他用,那么这样访问是有可能出错的吧
}
func main(){ p := make(chan int,1) v := make(chan int,1) ch := make(chan int) p <- 1 go func(){ for i := 0 ; i <= 20 ; i+=2{ <-p fmt.Println("F",i) v<-1 } close(ch) }() go func(){ for i := 1 ; i <= 20 ; i+=2{ <-v fmt.Println("s",i) p<-1 } }()
}
漏了wg.Done()