golang -- 面试题

代码输出问题

1. defer 栈结构

package main

import (
	"fmt"
)

func main() {
	DeferCall()
}
func DeferCall() {
	defer func() {fmt.Println("A")}()
	defer func() {fmt.Println("B")}()
	defer func() {fmt.Println("C")}()
	
	panic("error")
}

输出结果
这里写图片描述

解释:
defer注册是方法是保存在栈中,后入先出。
panic触发后,defer方法仍然执行。但panic后面的代码不执行。

2. go启动goroutine时传入参数

package main

import (
	"fmt"
	"runtime"
	"sync"
)

func main() {
	runtime.GOMAXPROCS(1)
	wg := sync.WaitGroup{}
	wg.Add(20)
	for i := 0; i < 10; i++ {
		go func() {
			fmt.Println("A: ", i)
			wg.Done()
		}()  // 这里不传入参数
	}
	for i := 0; i < 10; i++ {
		go func(i int) {
			fmt.Println("B: ", i)
			wg.Done()
		}(i)  // 这里传入i
	}
	wg.Wait()
}

运行结果:一共10个10
这里写图片描述

解释:
传入i时,go func 会一直保存i这个变量的引用,当i在外层循环变成了10, go func 保存的i也都是10.

3. 继承方法

package main

import (
	"fmt"
)
type People struct{}

func (p *People) ShowA() {
	fmt.Println("showA")
	p.ShowB()
}
func (p *People) ShowB() {
	fmt.Println("showB")
}

type Teacher struct {
	People
}

func (t *Teacher) ShowB() {
	fmt.Println("teacher showB")
}

func main() {
	t := Teacher{}
	t.ShowA()

	t.ShowB()
}

运行结果:
这里写图片描述

解释:
Teacher覆盖了ShowB方法,调用ShowA方法时,ShowA属于People,所以ShowA里面调用的仍然是People的ShowB方法.

4. 切片

package main

import (
	"fmt"
)
func main() {
	s := make([]int, 5)
	s = append(s, 1, 2, 3)
	fmt.Println(s)
}

运行结果:
这里写图片描述

解释:
make([]int, 5) 之后,这个list就变成[0, 0, 0, 0, 0] 了,默认0填充。

5. 接口

package main

import (
    "fmt"
)

type People interface {
    Show()
}

type Student struct{}

func (stu *Student) Show() {

}

func main() {

    var s *Student
    fmt.Println(s == nil) // true

    var p People = s
    fmt.Println(p == nil) // false
}

解释:
在底层,interface作为两个成员来实现,一个类型和一个值, 只有当类型未设置, 值也没有设置的时候,interface才是nil.

#代码存在问题

1. for循环

package main

import (
	"fmt"
)
type student struct {
	Name string
	Age  int
}

func PaseStudent() {
	m := make(map[string]*student)
	stus := []student{
		{Name: "zhou", Age: 24},
		{Name: "li", Age: 23},
		{Name: "wang", Age: 22},
	}
	for _, stu := range stus {
		m[stu.Name] = &stu  // 这里的会把stu这个变量的地址赋值给map
		fmt.Printf("%p \n", &stu)  // for循环的变量, 不会每次都被新建
	}

	// 显示m中的内容
	for k, v := range m {
		fmt.Println(k, *v)
	}
}

func main() {
	PaseStudent()
}

运行结果:
这里写图片描述

错误:
for 循环不会每次循环的时候都新建循环变量stu, 所以将stu变量的地址赋值给map后,循环结束后,map中所以值还是指向stu地址。

改正:

	for _, stu := range stus {
		s := stu  // 这里新建一个变量
		m[stu.Name] = &s  
		fmt.Printf("%p \n", &stu)
	}

2. type使用

package main

func main() {
	i := GetValue()

	switch i.(type) {
	case int:
		println("int")
	case string:
		println("string")
	case interface{}:
		println("interface")
	default:
		println("unknown")
	}

}

func GetValue() int {
	return 1
}

运行结果:
这里写图片描述
解释:type只能用在interface上, 把func GetValue返回值从int改为interface {} 就可以了。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值