每日一题,从问题出发,透过问题查漏补缺
Go每日一题 (变量定义)
定义一个包内全局字符串变量,下面语法正确的是(多选):
- A. var str string
- B. str := “”
- C. str = “”
- D. var str = “”
答案解析
答案及解析:AD。
B 只支持局部变量声明;C 是赋值,str 必须在这之前已经声明。
Go每日一题 (struct encoding/json 导出)
以下代码输出什么?
1 | package main |
答案解析
正确答案 B
如果值实现了
json.Marshaler
接口并且不是 nil 指针,则 Marshal 函数会调用其 MarshalJSON 方法以生成 JSON。如果不存在 MarshalJSON 方法,但该值实现 encoding.TextMarshaler 接口,则 Marshal 函数调用其 MarshalText 方法并将结果编码为 JSON 字符串。
Go每日一题 (defer)
下面这段代码输出什么?
1 | func hello(i int) { |
答案解析
答案及解析:5。
hello() 函数的参数在执行 defer 语句的时候会保存一份副本,在实际调用 hello() 函数时用,所以是 5.
Go每日一题 (结构体嵌套)
下面这段代码输出什么?
1 | type People struct{} |
答案解析
showA
showB
Teacher 没有自己 ShowA(),所以调用内部类型 People 的同名方法,
需要注意的是第 5 行代码调用的是 People 自己的 ShowB 方法。
Go每日一题 (字符串)
下列选项正确的是?
1 | func main() { |
- A. hello
- B. xello
- C. compilation error
答案解析
C
Go 语言中的字符串是只读的。
Go每日一题 (指针)
下面代码输出什么?
1 | func incr(p *int) int { |
- A. 1
- B. 2
- C. 3
答案解析
B
指针,incr() 函数里的 p 是 *int 类型的指针,指向的是 main() 函数的变量 p 的地址。
第 2 行代码是将该地址的值执行一个自增操作,incr() 返回自增后的结果。
Go每日一题 (可变函数)
对 add() 函数调用正确的是?
1 | func add(args ...int) int { |
- A. add(1, 2)
- B. add(1, 3, 7)
- C. add([]int{1, 2})
- D. add([]int{1, 3, 7}…)
答案解析
答案及解析:ABD。
可变函数
Go每日一题 (channel)
以下代码输出什么?
1 | package main |
- A:5
- B:不能编译
- C:运行时死锁
答案解析
C
<-ch1 先执行再 调起; 运行时死锁
Go每日一题 (array slice)
- 以下代码输出什么?
1 | package main |
- A:编译错误;
- B:[2 1];
- C:[0 0 1];
- D:[0 1]
答案解析: [0 0 1]
- 以下代码输出什么?
1 | package main |
- A:5 66;
- B:5 88;
- C:7 88;
- D:以上都不对
答案解析: 7 88
答案解析
var x = []int{4: 44, 55, 66, 1: 77, 88}
即
var x = []int{4:44, 5:55, 6:66, 1:77, 2:88}
Go每日一题 (nil切片 空切片)
下面代码下划线处可以填入哪个选项?
1 | func main() { |
- A. s1
- B. s2
- C. s1、s2 都可以
答案解析
答案及解析:A。
nil 切片和空切片。nil 切片和 nil 相等,一般用来表示一个不存在的切片;
空切片和 nil 不相等,表示一个空的集合。
答案及解析:C。
题目仅仅是可以填入,并没有说要走第一个分支
都可以填, s2 == nil 返回的是 false, s1 == nil 返回的是 true
Go每日一题 (强制类型转换)
下面这段代码输出什么?
1 | func main() { |
- A. A
- B. 65
- C. compilation error
答案解析
答案及解析:A。
UTF-8 编码中,十进制数字 65 对应的符号是 A。
Go每日一题 (接口)
下面这段代码输出什么?
1 | type A interface { |
答案解析
答案及解析:13 23。
种类型实现多个接口,结构体 Work 分别实现了接口 A、B,
所以接口变量 a、b 调用各自的方法 ShowA() 和 ShowB(),输出 13、23。
Go每日一题 (slice)
切片 a、b、c 的长度和容量分别是多少?
1 | func main() { |
答案解析
a、b、c 的长度和容量分别是 0 3、2 3、1 2
数组或切片的截取操作。
截取操作有带 2 个或者 3 个参数,形如:[i:j] 和 [i:j:k],
假设截取对象的底层数组长度为 l。在操作符 [i:j] 中,如果 i 省略,默认 0,如果 j 省略,默认底层数组的长度,
**截取得到的切片长度和容量计算方法是 j-i
、l-i
**。
操作符 [i:j:k],k 主要是用来限制切片的容量,但是不能大于数组的长度 l,截取得到的切片长度和容量计算方法是 j-i、k-i。
Go每日一题 (map)
下面代码中 A B 两处应该怎么修改才能顺利编译?
1 | func main() { |
答案解析
1 | func main() { |
Go每日一题 (接口的静态类型)
下面代码输出什么?
1 | type A interface { |
- A. 23 13
- B. compilation error
答案解析
答案及解析:B
接口的静态类型。a、b 具有相同的动态类型和动态值,分别是结构体 work 和 {3};a 的静态类型是 A,b 的静态类型是 B,
接口 A 不包括方法 ShowB(),接口 B 也不包括方法 ShowA(),编译报错。
Go每日一题 (Go101)
Go101 发布的一条 twitter。以下代码是否能正常运行,结果是?
1 | package main |
答案解析
-2
https://gitee.com/ilmself010cn/studygolang_daily/blob/master/daily/2023/03/16/README.md
Go每日一题 (类型 类型别名)
有下面 3 行代码:
1 | // 32 位机器 |
它们是否能编译通过?为什么?
如果面试时问这道题,你需要想想面试官想考察你什么。
答案解析
- 01 数字字面量
在 Go 语言中,字面量是无类型(untyped)的。无类型是什么意思?无类型意味着可以赋值给类似类型的变量或常量。
1 | var a int64 = 32.0 |
- 02 不同类型
int 类型在 32 位机器占 4 字节,64 位机器占 8 字节。所以,在 32 位机器上,int32 和 int 的内存占用和内存布局是完全一样的。
但 Go 语言不会做隐式类型转换,int 和 int32 是不同的类型,因此上题中 2)编译不通过。
- 03 类型别名
很显然,rune 是 int32 的别名,因此题目中 3)也能编译通过。
1 | // 32 位机器 |
Go每日一题 (多赋值)
下面代码中,x 已声明,y 没有声明,判断每条语句的对错。
- x, _ := f()
- x, _ = f()
- x, y := f()
- x, y = f()
答案解析
答案及解析:错、对、对、错。
变量的声明。
1.错,x 已经声明,不能使用 :=;
2.对;
3.对,当多值赋值时,:= 左边的变量无论声明与否都可以;
4.错,y 没有声明。
Go每日一题 (defer)
下面代码输出什么?
1 | func increaseA() int { |
- A. 1 1
- B. 0 1
- C. 1 0
- D. 0 0
答案解析
答案及解析:B。
increaseA() 的返回参数是匿名,increaseB() 是具名
Go每日一题 (defer 返回值)
f1()、f2()、f3() 函数分别返回什么?
1 | func f1() (r int) { |
答案解析
答案及解析:1 5 1。
Go每日一题 (闭包)
以下代码输出什么?
1 | package main |
- A:Hi All;
- B:Hi go All;
- C:Hi;
- D:go All
答案解析
A
关于(函数)闭包,有几个关键点:
- 函数是一等公民;
- 闭包所处环境,可以引用环境里的值;
Go每日一题 (defer)
下面代码段输出什么?
1 | type Person struct { |
答案解析
答案及解析:29 29 28。变量 person 是一个指针变量 。
- person.age 此时是将 28 当做 defer 函数的参数,会把 28 缓存在栈中,等到最后执行该 defer 语句的时候取出,即输出 28;
- defer 缓存的是结构体 Person{28} 的地址,最终 Person{28} 的 age 被重新赋值为 29,所以 defer 语句最后执行的时候,依靠缓存的地址取出的 age 便是 29,即输出 29;
- 很简单,闭包引用,输出 29;
又由于 defer 的执行顺序为先进后出,即 3 2 1,所以输出 29 29 28。
1 | 闭包引用输出 29 |
Go每日一题 (defer)
下面这段代码正确的输出是什么?
1 | func f() { |
- A. F M D
- B. D F M
- C. F D M
答案解析
参考答案及解析:C。
被调用函数里的 defer 语句在返回之前就会被执行
Go每日一题 (slice)
下面的两个切片声明中有什么区别?哪个更可取?
- A. var a []int
- B. a := []int{}
答案解析
答案及解析:第一种切片声明不会分配内存,优先选择。
Go每日一题 (interface 指针)
A、B、C、D 哪些选项有语法错误?
1 | type S struct { |
答案解析
答案及解析:BD
函数参数为 interface{} 时可以接收任何类型的参数,包括用户自定义类型等,
即使是接收指针类型也用 interface{},而不是使用 *interface{}。
Go每日一题 (struct 指针)
下面 A、B 两处应该填入什么代码,才能确保顺利打印出结果?
1 | type S struct { |
答案解析
A. &S{“foo”}
B. *f() 或者 f()
B 处,如果填 *f(),则 p 是 S 类型;如果填 f(),则 p 是 *S 类型;不过都可以使用 p.m 取得结构体的成员。
Go每日一题 (常量表达式)
以下代码输出什么?
1 | package main |
- A:不能编译;
- B:45;
- C:45.2;
- D:45.0
答案解析
正确答案:C。
常量表达式是指仅包含常量操作数,且是在编译的时候进行计算的。
Go每日一题 (string)
下面的代码有几处语法问题,各是什么?
1 | package main |
答案解析
golang 的字符串类型是不能赋值 nil 的,也不能跟 nil 比较。
Go每日一题 (defer)
return 之后的 defer 语句会执行吗,下面这段代码输出什么?
1 | var a bool = true |
答案解析
答案及解析:2 1
defer 关键字后面的函数或者方法想要执行必须先注册,return 之后的 defer 是不能注册的, 也就不能执行后面的函数或方法。