121-150

121. 下面代码输出什么?

func main() {
    var ch chan int
    select {
    case v, ok := <-ch:
        println(v, ok)
    default:
        println("default") 
    }
}

答:default

解析:

ch 为 nil,读写都会阻塞。

122. 下面这段代码输出什么?

type People struct {
    name string `json:"name"`
}

func main() {
    js := `{
        "name":"seekload"
    }`
    var p People
    err := json.Unmarshal([]byte(js), &p)
    if err != nil {
        fmt.Println("err: ", err)
        return
    }
    fmt.Println(p)
}

答:输出 {}

解析:

知识点:结构体访问控制,因为 name 首字母是小写,导致其他包不能访问,所以输出为空结构体。

修复代码:

123. 下面这段代码输出什么?

  • A. 1

  • B. 100

  • C. compilation error

答:输出 B

解析:

调用 foo() 函数时虽然是传值,但 foo() 函数中,字段 ls 依旧可以看成是指向底层数组的指针。

124. 下面代码输出什么?

答:false true

解析:

Go 语言的 switch 语句虽然没有"break",但如果 case 完成程序会默认 break,可以在 case 语句后面加上关键字 fallthrough,这样就会接着走下一个 case 语句(不用匹配后续条件表达式)。或者,利用 case 可以匹配多个值的特性。

修复代码:

125. 下面的代码能否正确输出?

答:编译错误

解析:

函数只能与 nil 比较。

126. 下面代码输出什么?

  • A. 1

  • B. compilation error

答:B

解析:

map[key]struct 中 struct 是不可寻址的,所以无法直接赋值。

修复代码:

127. 下面的代码有什么问题?

答:X{} 是不可寻址的,不能直接调用方法

解析:

知识点:在方法中,指针类型的接收者必须是合法指针(包括 nil),或能获取实例地址。

修复代码:

128. 下面代码有什么不规范的地方吗?

解析:

检查 map 是否含有某一元素,直接判断元素的值并不是一种合适的方式。最可靠的操作是使用访问 map 时返回的第二个值。

修复代码如下:

129. 关于 channel 下面描述正确的是?

  • A. 向已关闭的通道发送数据会引发 panic;

  • B. 从已关闭的缓冲通道接收数据,返回已缓冲数据或者零值;

  • C. 无论接收还是接收,nil 通道都会阻塞;

答:A B C

130. 下面的代码有几处问题?请详细说明。

答:有两处问题

解析:

  • 1.直接返回的 T{} 不可寻址;

  • 2.不可寻址的结构体不能调用带结构体指针接收者的方法;

修复代码:

131. 下面的代码有什么问题?

答:编译错误

解析:

不能使用多级指针调用方法。

132. 下面的代码输出什么?

答:10 11 12

解析:

知识点:方法表达式。

通过类型引用的方法表达式会被还原成普通函数样式,接收者是第一个参数,调用时显示传参。类型可以是 T 或 *T,只要目标方法存在于该类型的方法集中就可以。

还可以直接使用方法表达式调用:

133. 关于 channel 下面描述正确的是?

  • A. close() 可以用于只接收通道;

  • B. 单向通道可以转换为双向通道;

  • C. 不能在单向通道上做逆向操作(例如:只发送通道用于接收);

答:C

134. 下面的代码有什么问题?

答:编译错误

解析:

直接返回的 T{} 无法寻址,不可直接赋值。

修复代码:

135. 下面的代码有什么问题?

答:代码没问题,输出 3 4

解析:

从一个基础切片派生出的子切片的长度可能大于基础切片的长度。假设基础切片是 baseSlice,使用操作符 [low,high],有如下规则:0 <= low <= high <= cap(baseSlice),只要上述满足这个关系,下标 low 和 high 都可以大于 len(baseSlice)。

136. 下面代码输出什么?

答:13 11 12

解析:

知识点:方法值。

当指针值赋值给变量或者作为函数参数传递时,会立即计算并复制该方法执行所需的接收者对象,与其绑定,以便在稍后执行时,能隐式第传入接收者参数。

137. 下面哪一行代码会 panic,请说明原因?

答:第 8 行

解析:

因为两个比较值的动态类型为同一个不可比较类型。

138. 下面的代码输出什么?

答:321

解析:

第一次循环,写操作已经准备好,执行 o(3),输出 3;

第二次,读操作准备好,执行 o(2),输出 2 并将 c 赋值为 nil;

第三次,由于 c 为 nil,走的是 default 分支,输出 1。

139. 下面的代码输出什么?

答:10

解析:

知识点:运算符优先级。

如下规则:递增运算符 ++ 和递减运算符 -- 的优先级低于解引用运算符 * 和取址运算符 &,解引用运算符和取址运算符的优先级低于选择器 . 中的属性选择操作符。

140. 下面哪一行代码会 panic,请说明原因?

答:第 6 行

解析:

第 6 行,截取符号 [i:j],如果 j 省略,默认是原切片或者数组的长度,x 的长度是 2,小于起始下标 6 ,所以 panic。

141. 下面的代码输出什么?

答:13 13 13

解析:

知识点:方法值。

当目标方法的接收者是指针类型时,那么被复制的就是指针。

142. 下面哪一行代码会 panic,请说明原因?

答:第 12 行

解析:

因为左侧的 s[0] 中的 s 为 nil。

143. 下面哪一行代码会 panic,请说明原因?

答:第 19 行

解析:

因为 s.bar 将被展开为 (*s.T).bar,而 s.T 是个空指针,解引用会 panic。

可以使用下面代码输出 s:

144. 下面的代码有什么问题?

答:锁失效

解析:

将 Mutex 作为匿名字段时,相关的方法必须使用指针接收者,否则会导致锁机制失效。

修复代码:

或者可以通过嵌入 *Mutex 来避免复制的问题,但需要初始化。

145. 下面这段代码输出什么?

答:4

解析:

知识点:多重赋值。

多重赋值分为两个步骤,有先后顺序:

  • 计算等号左边的索引表达式和取址表达式,接着计算等号右边的表达式;

  • 赋值;

所以本例,会先计算 s[k],等号右边是两个表达式是常量,所以赋值运算等同于 k, s[1] = 0, 3

146. 下面代码输出什么?

答:932

147. 下面哪一行代码会 panic,请说明。

答:第 4 行

解析:

当前作用域中,预定义的 nil 被覆盖,此时 nil 是 int 类型值,不能赋值给 map 类型。

148. 下面代码输出什么?

答:-128

解析:

溢出

149. 下面选项正确的是?

  • A. 类型可以声明的函数体内;

  • B. Go 语言支持 ++i 或者 --i 操作;

  • C. nil 是关键字;

  • D. 匿名函数可以直接赋值给一个变量或者直接执行;

答:A D

150. 下面的代码输出什么?

答:768

解析:

知识点:匿名函数defer()

defer() 后面的函数如果带参数,会优先计算参数,并将结果存储在栈中,到真正执行 defer() 的时候取出。

最后更新于