golang(2023) 面试常问问题总结

01 -- defer问题

package main

import "fmt"

/**
 总结
	1 如果有返回值 或者返回值为引用类型 defer里面的值会影响返回值
	2 如果没有返回值 defer里面的值操作 不影响返回值
 */

func b() (i int) {
	defer func() {
		i++
		fmt.Println("defer2:", i)
	}()
	defer func() {
		i++
		fmt.Println("defer1:", i)
	}()
	return i //或者直接写成return
}


func d() *int {
	var i int
	defer func() {
		i++
		fmt.Println("defer2:", i)
	}()
	defer func() {
		i++
		fmt.Println("defer1:", i)
	}()
	return &i
}

func c() int {
	var i int
	defer func() {
		i++
		fmt.Println("defer2:", i)
	}()
	defer func() {
		i++
		fmt.Println("defer1:", i)
	}()
	return i
}
func main() {
	fmt.Println("return b :", b())  //影响
	fmt.Println("return d :", *d()) //影响
	fmt.Println("return c :", c())  //不影响
}




打印结果如下

defer1: 1
defer2: 2
return b : 2
defer1: 1
defer2: 2
return c : 0
defer1: 1
defer2: 2
return d : 2
Exiting.

02--值传递和引用传递问题

package main

import (
	"fmt"
)

/**
	golang中都是采用值传递,即拷贝传递,也就是深拷贝。没有引用传递。
	之所有有些看起来像是引用传递的场景,是因为Golang中存在着引用类型,
		如slice、map、channel、function、pointer这些天生就是指针的类型,在传递的时候是复制的地址。
		引用类型作为参数时,称为浅拷贝,形参改变,实参数跟随变化。因为传递的是地址,形参和实参都指向同一块地址
 */

type User struct {
	name string
	age int
}

func a(u *User) {
	u.name = "sss"
	u.age = 20
	//fmt.Println("aa == " , u)
}

func ss(a []string) {
	a[0] = "M"
	a = append(a , "c") //这里注意 不会影响外面的切片
	a = append(a , "d")
	fmt.Println("slice == " , a)
}

func main() {

	u := User{
		name: "syn",
		age: 18,
	}

	fmt.Println("11" , u)
	a(&u)
	fmt.Println("22" , u)

	slc := []string{
		"a","b",
	}

	fmt.Println("11" , slc)
	ss(slc)
	fmt.Println("33" , slc)
}

03 -- 反射tag

package main

import (
	"fmt"
	"reflect"
)


type User1 struct {
	name string `json:name-field`
	age  int
}
func (u *User1)Sss() {
	fmt.Println("user == sssss")
}

func getStructTag(f reflect.StructField) string {
	fmt.Println("ss")
	return string(f.Tag)
}

func main() {

	user := &User1{"John Doe The Fourth", 20}

	/*field, ok := reflect.TypeOf(user).Elem().FieldByName("name")
	if !ok {
		panic("Field not found")
	}
	fmt.Println(getStructTag(field))*/

	vof := reflect.ValueOf(user)
	var arr []reflect.Value
	vof.MethodByName("Sss").Call(arr)

}


04 -- map 的 key 可以是什么

package main

import "fmt"

/**
 golang 中 map 的 key 必须是可比较的,再简单点是可以使用 == 运算符进行比较。
 很显然 slice,map,function 不可以,
 所以 数字、string、bool、array、channel、指针可以,以及 包含前面类型的 struct
 */


func main () {
	//可以
	 var mstr map[string]string
	 fmt.Println(mstr)
	//可以
	var mbool map[bool]string
	fmt.Println(mbool)
	//可以
	var marr map[[1]int]string
	fmt.Println(marr)


	 //不可以
	var mslice map[[]int]string
	fmt.Println(mslice)
}

05--gc垃圾回收

https://www.bilibili.com/video/BV1wz4y1y7Kd?p=4&vd_source=d65523a41f0dbf6ab62927eaf750baa2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值