基础相关
-
var和:=来定义变量有什么不同?new和make初始化变量有什么不同呢?
#var 用来定义单个或者多个变量变量,:=一般用来创建变量并且用来给变量复赋值 var a int a =5 a :=5 #new 用来创建一个指向新分配零值对象的指针,并返回指向该实例的指针,new返回的是指针对象 #make 用来创建切片,通道和映射等内置数据结构,并初始化 p := new(int) slience := make([]int,0,10)
-
defer是做什么用的,如果一个程序里面有多个defer会怎么样?
延迟的函数推送执行,先进先出,一般用来关闭文件资源。第一个defer一般是在整个程序运行结束后第一个执行,然后才到执行下一个
-
切片的底层是怎么实现的?interface的两种用法了解吗?了解interface的底层实现吗?
如上图切片其实是应用类型,有三个字段:1.指向应用数组的指针,长度,和容量。当对某个切片进行slien[1:3]其实是创建了新的切片。
1.类型断言 value, ok := someInterface.(SomeType) 2.类型查询 switch v := someInterface.(type) { case SomeType1: // 处理 SomeType1 类型 case SomeType2: // 处理 SomeType2 类型 default: // 默认处理 }
-
怎么用的map,会有并发问题吗?怎么求一个map的长度(len就可以,害)。sync.Map可以用len来求长度吗?(应该是想要问sync.Map的底层吧)
//make示例 myMap = make(map[string]int) len(map)
go关于并发问题,标准的 Go map 不是并发安全的,也就是说,如果多个 goroutine 同时读写一个 map,可能会导致数据竞争和不确定的结果。为了在并发环境下安全使用 map,你可以使用互斥锁(sync.Mutex)来保护 map,或者使用 sync.Map,后者是 Go 1.9 引入的并发安全的映射类型。 //用互斥锁来保护标准的'map': package main import ( "fmt" "sync" ) func main() { myMap := make(map[string]int) var mu sync.Mutex var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) go func(n int) { defer wg.Done() mu.Lock() myMap["key"] = n mu.Unlock() }(i) } fmt.Println("Waiting for goroutines to finish...") wg.Wait() mu.Lock() fmt.Println("Map:", myMap) mu.Unlock() }
然而,在 sync.Map 中,你不能直接使用 len() 函数来获取长度。sync.Map 不提供获取长度的方法。这是因为 sync.Map 的设计目标是在并发环境下进行读写操作,而不是频繁获取长度等操作。如果你需要跟踪 sync.Map 的长度,可以自己实现一个计数器,在每次插入或删除键值对时进行递增或递减操作来维护长度信息。但要注意,在多个并发操作中,你需要正确地处理计数器的增减,以避免竞态条件。 package main import ( "fmt" "sync" ) func main() { var myMap sync.Map for i := 0; i < 100; i++ { key := fmt.Sprintf("key%d", i) myMap.Store(key, i) } fmt.Println("wating all gonrint down....") myMap.Range(func(key, value interface{}) bool { fmt.Printf("Key: %v, Value: %v\n", key, value) return true }) }
go -
有缓冲和无缓冲channel的区别
无缓冲(<-):表示如果向通道中输入数据,但是该通道没有输出方,则会堵塞,直到双方都准备好 有缓冲:在缓冲值没有满之前可以一直向通道输入数据
-
select中如果没有default会出现什么情况?(select会阻塞,直到有case可以执行)case中的通道被关闭了会出现什么情况?(只有这一个的话会死循环,可以用,ok判断一下)
-
map是有序的吗?map底层实现怎么处理hash碰撞的问题?
-
recover和panic的实现原理
-
是否了解反射
-
普通的map加锁使用与直接用sync.map有什么区别?(分别说了使用上和性能上)
并发相关
- golang协程的调度,聊聊对GMP模型的理解
- 怎么实现并发?
- 怎么让协程等待?
- 聊聊goroutine泄漏?怎么避免和排查goroutine泄漏的问题?
- goroutine的状态机
- 聊聊channel的特性,从nil的channel中取数据会发生什么?
其他
- 哪些情况下会panic?所有的panic都可以recover吗?recover函数的使用过程,是怎么捕获的?
- context是做什么用的?
- 有什么办法可以获得函数调用的链路?
- 怎么处理协程运行的超时问题?
- 怎么优雅地关闭通道?
- 从面向对象的角度聊聊java和golang的区别
- golang的GC
- golang的http路由实现懂吗,可以描述一下吗?
- golang程序hang住了可能是什么原因(说了可能死循环导致无法GC,golang1.13),怎么排查(可以用pprof)
数据结构
- 数组查找的时间复杂度是多少,为什么?
- 了解跳表吗?
- 你知道哪些树结构,各自的优缺点分别是什么?(回答的时候再回答一下应用场景就更好了)
操作系统
- 用过锁吗?读写锁加读锁的时候会阻塞写操作吗?会阻塞读操作吗?(用过,会,不会)
Linux
- 用过ps命令解决过什么问题吗?查询出来的结果各个字段有什么含义?
- 了解僵尸进程吗?怎么避免?
- 怎么根据pid获取父进程的pid(回答说去/proc下面),怎么根据pid找执行路径呢?怎么根据端口号找pid(回答说lsof -i,用netstat也可以但是我不知道,面试官补充的)
数据库
- Redis和MySQL的区别,什么时候用Redis,什么时候用MySQL(这里我说了下我们服务用到的场景)?如果让你设计一个秒杀系统,要怎么设计?(面试官后来提示了一下说redis又一个自增key)
MySQL
- 有几种隔离级别?默认级别是什么?可重复读是怎么解决幻读的?了解mvcc嘛?下面几种mysql哪个会用到联合索引
linked:https://juejin.cn/post/6967618371844046856