切片在 go 的内部结构有一个指向底层数组的指针,当 range 表达式发生复制时,副本的指针依旧指向原底层数组,所以对切片的修改都会反应到底层数组上,所以通过 v 可以获得修改后的数组元素。
73. 下面这段代码输出结果正确正确吗?
答:s2 的输出结果错误
解析:
s2 的输出是 &{C} &{C} &{C},for range 使用短变量声明(:=)的形式迭代变量时,变量 i、value 在每次循环体中都会被重用,而不是重新声明。所以 s2 每次填充的都是临时变量 value 的地址,而在最后一次循环中,value 被赋值为{c}。因此,s2 输出的时候显示出了三个 &{c}。
可行的解决办法如下:
74. 下面代码里的 counter 的输出值?
A. 2
B. 3
C. 2 或 3
答:C
解析:
for range map 是无序的,如果第一次循环到 A,则输出 3;否则输出 2。
75. 关于协程,下面说法正确是()
A. 协程和线程都可以实现程序的并发执行;
B. 线程比协程更轻量级;
C. 协程不存在死锁问题;
D. 通过 channel 来进行协程间的通信;
答:A D
76. 关于循环语句,下面说法正确的有()
A. 循环语句既支持 for 关键字,也支持 while 和 do-while;
B. 关键字 for 的基本使用方法与 C/C++ 中没有任何差异;
C. for 循环支持 continue 和 break 来控制循环,但是它提供了一个更高级的 break,可以选择中断哪一个循环;
D. for 循环不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量;
答:C D
77. 下面代码输出正确的是?
A. s: [Z,B,C]
B. s: [A,Z,C]
答:A
解析:
知识点:多重赋值。
多重赋值分为两个步骤,有先后顺序:
计算等号左边的索引表达式和取址表达式,接着计算等号右边的表达式;
赋值;
所以本例,会先计算 s[i-1],等号右边是两个表达式是常量,所以赋值运算等同于 i, s[0] = 2, "Z"。
78. 关于类型转化,下面选项正确的是?
答:C
解析:
知识点:强制类型转化
79. 关于switch语句,下面说法正确的有?
A. 条件表达式必须为常量或者整数;
B. 单个case中,可以出现多个结果选项;
C. 需要用break来明确退出一个case;
D. 只有在case中明确添加fallthrough关键字,才会继续执行紧跟的下一个case;
答:B D
80. 如果 Add() 函数的调用代码为:
则Add函数定义正确的是()
答:A C
解析:
知识点:类型断言、方法集。
81. 关于 bool 变量 b 的赋值,下面错误的用法是?
A. b = true
B. b = 1
C. b = bool(1)
D. b = (1 == 2)
答:B C
82. 关于变量的自增和自减操作,下面语句正确的是?
答:A D
解析:
知识点:自增自减操作。
i++ 和 i-- 在 Go 语言中是语句,不是表达式,因此不能赋值给另外的变量。此外没有 ++i 和 --i。
83. 关于GetPodAction定义,下面赋值正确的是
A. var fragment Fragment = new(GetPodAction)
B. var fragment Fragment = GetPodAction
C. var fragment Fragment = &GetPodAction{}
D. var fragment Fragment = GetPodAction{}
答:A C D
84. 关于函数声明,下面语法正确的是?
A. func f(a, b int) (value int, err error)
B. func f(a int, b int) (value int, err error)
C. func f(a, b int) (value int, error)
D. func f(a int, b int) (int, int, error)
答:A B D
85. 关于整型切片的初始化,下面正确的是?
A. s := make([]int)
B. s := make([]int, 0)
C. s := make([]int, 5, 10)
D. s := []int{1, 2, 3, 4, 5}
答:B C D
86. 下面代码会触发异常吗?请说明。
解析:
select 会随机选择一个可用通道做收发操作,所以可能触发异常,也可能不会。
87. 关于channel的特性,下面说法正确的是?
A. 给一个 nil channel 发送数据,造成永远阻塞
B. 从一个 nil channel 接收数据,造成永远阻塞
C. 给一个已经关闭的 channel 发送数据,引起 panic
D. 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值
答:A B C D
88. 下面代码有什么问题?
答:编译报错
解析:
编译报错cannot take the address of i。知识点:常量。常量不同于变量的在运行期分配内存,常量通常会被编译器在预处理阶段直接展开,作为指令数据使用,所以常量无法寻址。
89. 下面代码能否编译通过?如果通过,输出什么?
答:不能通过编译
解析:
知识点:函数返回值类型。nil 可以用作 interface、function、pointer、map、slice 和 channel 的“空值”。但是如果不特别指定的话,Go 语言不能识别类型,所以会报错:cannot use nil as type string in return argument
type People interface {
Show()
}
type Student struct{}
func (stu *Student) Show() {
}
func main() {
var s *Student
if s == nil {
fmt.Println("s is nil")
} else {
fmt.Println("s is not nil")
}
var p People = s
if p == nil {
fmt.Println("p is nil")
} else {
fmt.Println("p is not nil")
}
}
type Direction int
const (
North Direction = iota
East
South
West
)
func (d Direction) String() string {
return [...]string{"North", "East", "South", "West"}[d]
}
func main() {
fmt.Println(South)
}
type Math struct {
x, y int
}
var m = map[string]Math{
"foo": Math{2, 3},
}
func main() {
m["foo"].x = 4
fmt.Println(m["foo"].x)
}
type Math struct {
x, y int
}
var m = map[string]Math{
"foo": Math{2, 3},
}
func main() {
tmp := m["foo"]
tmp.x = 4
m["foo"] = tmp
fmt.Println(m["foo"].x)
}
type Math struct {
x, y int
}
var m = map[string]*Math{
"foo": &Math{2, 3},
}
func main() {
m["foo"].x = 4
fmt.Println(m["foo"].x)
fmt.Printf("%#v", m["foo"]) // %#v 格式化输出详细信息
}
func main() {
v := []int{1, 2, 3}
for i := range v {
v = append(v, i)
}
}
func main() {
var m = [...]int{1, 2, 3}
for i, v := range m {
go func() {
fmt.Println(i, v)
}()
}
time.Sleep(time.Second * 3)
}
2 3
2 3
2 3
for i, v := range m {
go func(i,v int) {
fmt.Println(i, v)
}(i,v)
}
for i, v := range m {
i := i // 这里的 := 会重新声明变量,而不是重用
v := v
go func() {
fmt.Println(i, v)
}()
}
func f(n int) (r int) {
defer func() {
r += n
recover()
}()
var f func()
defer f()
f = func() {
r += 2
}
return n + 1
}
func main() {
fmt.Println(f(3))
}
func main() {
var a = [5]int{1, 2, 3, 4, 5}
var r [5]int
for i, v := range a {
if i == 0 {
a[1] = 12
a[2] = 13
}
r[i] = v
}
fmt.Println("r = ", r)
fmt.Println("a = ", a)
}
r = [1 2 3 4 5]
a = [1 12 13 4 5]
for i, v := range b {
if i == 0 {
a[1] = 12
a[2] = 13
}
r[i] = v
}
func main() {
var a = [5]int{1, 2, 3, 4, 5}
var r [5]int
for i, v := range &a {
if i == 0 {
a[1] = 12
a[2] = 13
}
r[i] = v
}
fmt.Println("r = ", r)
fmt.Println("a = ", a)
}
func main() {
var a = []int{1, 2, 3, 4, 5}
var r [5]int
for i, v := range a {
if i == 0 {
a[1] = 12
a[2] = 13
}
r[i] = v
}
fmt.Println("r = ", r)
fmt.Println("a = ", a)
}
r = [1 12 13 4 5]
a = [1 12 13 4 5]
type Foo struct {
bar string
}
func main() {
s1 := []Foo{
{"A"},
{"B"},
{"C"},
}
s2 := make([]*Foo, len(s1))
for i, value := range s1 {
s2[i] = &value
}
fmt.Println(s1[0], s1[1], s1[2])
fmt.Println(s2[0], s2[1], s2[2])
}
输出:
{A} {B} {C}
&{A} &{B} &{C}
for i := range s1 {
s2[i] = &s1[i]
}
func main() {
var m = map[string]int{
"A": 21,
"B": 22,
"C": 23,
}
counter := 0
for k, v := range m {
if counter == 0 {
delete(m, "A")
}
counter++
fmt.Println(k, v)
}
fmt.Println("counter is ", counter)
}
func main() {
i := 1
s := []string{"A", "B", "C"}
i, s[i-1] = 2, "Z"
fmt.Printf("s: %v \n", s)
}
A.
type MyInt int
var i int = 1
var j MyInt = i
B.
type MyInt int
var i int = 1
var j MyInt = (MyInt)i
C.
type MyInt int
var i int = 1
var j MyInt = MyInt(i)
D.
type MyInt int
var i int = 1
var j MyInt = i.(MyInt)
func main() {
var a Integer = 1
var b Integer = 2
var i interface{} = &a
sum := i.(*Integer).Add(b)
fmt.Println(sum)
}
A.
type Integer int
func (a Integer) Add(b Integer) Integer {
return a + b
}
B.
type Integer int
func (a Integer) Add(b *Integer) Integer {
return a + *b
}
C.
type Integer int
func (a *Integer) Add(b Integer) Integer {
return *a + b
}
D.
type Integer int
func (a *Integer) Add(b *Integer) Integer {
return *a + *b
}
A.
i := 1
i++
B.
i := 1
j = i++
C.
i := 1
++i
D.
i := 1
i--
type Fragment interface {
Exec(transInfo *TransInfo) error
}
type GetPodAction struct {
}
func (g GetPodAction) Exec(transInfo *TransInfo) error {
...
return nil
}
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)
}
}
const i = 100
var j = 123
func main() {
fmt.Println(&j, j)
fmt.Println(&i, i)
}