Golang经典面试题

栏目: Go · 发布时间: 6年前

1. 下面代码能运行吗?为什么

运行结果:

panic: assignment to entry in nil mapgoroutine 1 [running]:main.main()

如上所示,运行过程中会发生异常,原因是因为字典Param的默认值为nil,当给字典nil增加键值对是就会发生运行时错误panic: assignment to entry in nil map。

正确的修改方案如下:

package main

import "fmt"

type Param map[string]interface{}

type Show struct {

Param

}

func main() {

// 创建Show结构体对象    s := new(Show)

// 为字典Param赋初始值    s.Param = Param{}

// 修改键值对    s.Param["RMB"] = 10000    fmt.Println(s)

}

运行结果如下:

&{map[RMB:10000]}

Process finished with exit code 0

2. 请说出下面代码存在什么问题

type student struct {

Name string

}

func f( v interface{}) {

switch msg := v.(type) {

case student, student:

msg.Name

}

}

有两个问题:

问题一:interface{}是一个没有声明任何方法的接口。

问题二:Name是一个属性,而不是方法,interface{}类型的变量无法调用属性。

3. 写出打印的结果。

type People struct {

name string json:"name"

}

func main() {

js := {

"name":"11"

}

var p People

err := json.Unmarshal([]byte(js), &p)

if err != nil {

fmt.Println("err: ", err)

return

}

fmt.Println("people: ", p)

}

输出内容如下:

people:  {}

运行结果如下:

people:  {11}Process finished with exit code 0

4. 下面的代码是有问题的,请说明原因。

package main

import "fmt"

type People struct {

Name string

}

func (p People) String() string {

return fmt.Sprintf("print: %v", p)

}

func main() {

p := &People{}

p.String()

}

运行结果如下:

runtime: goroutine stack exceeds 1000000000-byte limit

fatal error: stack overflow

runtime stack:

runtime.throw(0x10c122b, 0xe)

如下所示,上面的代码出现了栈溢出,原因是因为%v格式化字符串是本身会调用String()方法,上面的栈溢出是因为无限递归所致。

5. 请找出下面代码的问题所在。

package main

import ("fmt"    "time")

func main() {

ch := make(chan int, 1000)

go func() {

for i := 0; i < 10; i++ {

ch <- i

}

}()

go func() {

for {

a, ok := <-ch

if !ok {

fmt.Println("close")

return            }

fmt.Println("a: ", a)

}

}()

close(ch)

fmt.Println("ok")

time.Sleep(time.Second  100)

}

运行结果如下:

panic: send on closed channelok

goroutine 5 [running]:

main.main.func1(0xc420098000)

解析:出现上面错误的原因是因为提前关闭通道所致。

正确代码如下:

package main

import ( "fmt"    "time")

func main() {

// 创建一个缓冲通道

ch := make(chan int, 1000)

go func() {

for i := 0; i < 10; i++ {

ch <- i

}

}()

go func() {

for i := 0; i < 10; i++ {

a, ok := <-ch

if !ok {

fmt.Println("close")

close(ch)

return            }

fmt.Println("a: ", a)

}

}()

fmt.Println("ok")

time.Sleep(time.Second)

}

运行结果如下:

ok

a:  0a:  1a:  2a:  3a:  4a:  5a:  6a:  7a:  8a:  9

6. 请说明下面代码书写是否正确。

var value int32

func SetValue(delta int32) {

for {

v := value

if atomic.CompareAndSwapInt32(&value, v(v+delta)) {

break

}

}

}

atomic.CompareAndSwapInt32里面一共三个参数,上面的书写错误,正确的书写是:atomic.CompareAndSwapInt32(&value, v,v+delta)

func CompareAndSwapInt32(addr int32, old, new int32) (swapped bool)

第一个参数的值应该是指向被操作值的指针值。该值的类型即为int32。

后两个参数的类型都是int32类型。它们的值应该分别代表被操作值的旧值和新值

CompareAndSwapInt32·函数在被调用之后会先判断参数addr指向的被操作值与参数old`的值是否相等。

仅当此判断得到肯定的结果之后,该函数才会用参数new代表的新值替换掉原先的旧值。否则,后面的替换操作就会被忽略。

完整代码如下:

package main

import ( "sync/atomic"    "fmt")

var value int32

func SetValue(delta int32) {

for {

v := value

// 比较并交换

if atomic.CompareAndSwapInt32(&value, v,v+delta) {

fmt.Println(value)

break

}

}

}

func main()  {

SetValue(100)

}

运行结果为100.

7. 下面的程序运行后为什么会爆异常。

package main

import ( "fmt"    "time")

type Project struct{}

func (p Project) deferError() {

if err := recover(); err != nil {

fmt.Println("recover: ", err)

}

}

func (p Project) exec(msgchan chan interface{}) {

for msg := range msgchan {

m := msg.(int)

fmt.Println("msg: ", m)

}

}

func (p Project) run(msgchan chan interface{}) {

for {

defer p.deferError()

go p.exec(msgchan)

time.Sleep(time.Second  2)

}

}

func (p Project) Main() {

a := make(chan interface{}, 100)

go p.run(a)

go func() {

for {

a <- "1"            time.Sleep(time.Second)

}

}()

time.Sleep(time.Second  100)

}

func main() {

p := new(Project)

p.Main()

}

运行结果如下:

panic: interface conversion: interface {} is string, not intgoroutine 17 [running]:

main.(Project).exec(0x1157c08, 0xc420068060)

出现异常的原因是因为写入到管道的数据类型为string,而m := msg.(int)这句代码里面却使用了int,修改方法,将int修改为string即可。

完整正确代码如下:

package main

import ("fmt"    "time")

type Project struct{}

func (p Project) deferError() {

if err := recover(); err != nil {

fmt.Println("recover: ", err)

}

}

func (p Project) exec(msgchan chan interface{}) {

for msg := range msgchan {

m := msg.(string)

fmt.Println("msg: ", m)

}

}

func (p Project) run(msgchan chan interface{}) {

for {

defer p.deferError()

go p.exec(msgchan)

time.Sleep(time.Second  2)

}

}

func (p Project) Main() {

a := make(chan interface{}, 100)

go p.run(a)

go func() {

for {

a <- "1"            time.Sleep(time.Second)

}

}()

time.Sleep(time.Second  100)

}

func main() {

p := new(Project)

p.Main()

}

运行结果如下:

msg:  1msg:  1msg:  1.

.

.msg:  1msg:  1msg:  1msg:  1msg:  1

8. 请说出下面代码哪里写错了。

func main() {

abc := make(chan int, 1000)

for i := 0; i < 10; i++ {

abc <- i

}

go func() {

for {

a := <-abc

fmt.Println("a: ", a)

}

}()

close(abc)

fmt.Println("close")

time.Sleep(time.Second  100)

}

go中的for循环是死循环,应该设置出口。正确代码如下:

package main

import (

"fmt"    "time")func main() {

abc := make(chan int, 1000)

for i := 0; i < 10; i++ {

abc <- i

}

go func() {

for {

a,ok := <-abc

if !ok {

fmt.Println("结束!")

return            }

fmt.Println("a: ", a)

}

}()

close(abc)

fmt.Println("close")

time.Sleep(time.Second  100)

}

运行结果为:

closea:  0a:  1a:  2a:  3a:  4a:  5a:  6a:  7a:  8a:  9结束!

9. 请说出下面代码,执行时为什么会报错

type Student struct {

name string

}

func main() {

m := map[string]Student{"people": {"liyuechun"}}

m["people"].name = "wuyanzu"

}

答案:报错的原因是因为不能修改字典中value为结构体的属性值。

代码作如下修改方可运行:

package main

import "fmt"

type Student struct {

name string}func main() {

m := map[string]Student{"people": {"liyuechun"}}

fmt.Println(m)

fmt.Println(m["people"])

// 不能修改字典中结构体属性的值    //m["people"].name = "wuyanzu"    var s Student = m["people"] //深拷贝    s.name = "xietingfeng"    fmt.Println(m)

fmt.Println(s)

}

运行结果如下:

map[people:{liyuechun}]

{liyuechun}

map[people:{liyuechun}]

{wuyanzu}

10. 请说出下面的代码存在什么问题

type query func(string) string

func exec(name string, vs ...query) string {

ch := make(chan string)

fn := func(i int) {

ch <- vsi}

for i, _ := range vs {

go fn(i)

}

return <-ch

}

func main() {

ret := exec("111", func(n string) string {

return n + "func1"    }, func(n string) string {

return n + "func2"    }, func(n string) string {

return n + "func3"    }, func(n string) string {

return n + "func4"    })

fmt.Println(ret)

}

return <-ch 止执行一次,所以不管传入多少query函数,都只是读取最先执行完的query。


以上所述就是小编给大家介绍的《Golang经典面试题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

How to Build a Billion Dollar App

How to Build a Billion Dollar App

George Berkowski / Little, Brown Book Group / 2015-4-1 / USD 24.95

Apps have changed the way we communicate, shop, play, interact and travel and their phenomenal popularity has presented possibly the biggest business opportunity in history. In How to Build a Billi......一起来看看 《How to Build a Billion Dollar App》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换