基础相关

  1. var和:=来定义变量有什么不同?new和make初始化变量有什么不同呢?

    #var 用来定义单个或者多个变量变量,:=一般用来创建变量并且用来给变量复赋值
    var a int
    a =5
    a :=5
    
    #new 用来创建一个指向新分配零值对象的指针,并返回指向该实例的指针,new返回的是指针对象
    #make 用来创建切片,通道和映射等内置数据结构,并初始化
    p := new(int)
    slience := make([]int,0,10)
    
  2. defer是做什么用的,如果一个程序里面有多个defer会怎么样?

    延迟的函数推送执行,先进先出,一般用来关闭文件资源。第一个defer一般是在整个程序运行结束后第一个执行,然后才到执行下一个
    
  3. 切片的底层是怎么实现的?interface的两种用法了解吗?了解interface的底层实现吗?

    image-20230928062833352
    如上图切片其实是应用类型,有三个字段:1.指向应用数组的指针,长度,和容量。当对某个切片进行slien[1:3]其实是创建了新的切片。
    
    1.类型断言		
    value, ok := someInterface.(SomeType)
    2.类型查询		
    switch v := someInterface.(type) {
    case SomeType1:
        // 处理 SomeType1 类型
    case SomeType2:
        // 处理 SomeType2 类型
    default:
        // 默认处理
    }
    
  4. 怎么用的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
  5. 有缓冲和无缓冲channel的区别

    无缓冲(<-):表示如果向通道中输入数据,但是该通道没有输出方,则会堵塞,直到双方都准备好
    有缓冲:在缓冲值没有满之前可以一直向通道输入数据
    
  6. select中如果没有default会出现什么情况?(select会阻塞,直到有case可以执行)case中的通道被关闭了会出现什么情况?(只有这一个的话会死循环,可以用,ok判断一下)

  7. map是有序的吗?map底层实现怎么处理hash碰撞的问题?

  8. recover和panic的实现原理

  9. 是否了解反射

  10. 普通的map加锁使用与直接用sync.map有什么区别?(分别说了使用上和性能上)

并发相关

  1. golang协程的调度,聊聊对GMP模型的理解
  2. 怎么实现并发?
  3. 怎么让协程等待?
  4. 聊聊goroutine泄漏?怎么避免和排查goroutine泄漏的问题?
  5. goroutine的状态机
  6. 聊聊channel的特性,从nil的channel中取数据会发生什么?

其他

  1. 哪些情况下会panic?所有的panic都可以recover吗?recover函数的使用过程,是怎么捕获的?
  2. context是做什么用的?
  3. 有什么办法可以获得函数调用的链路?
  4. 怎么处理协程运行的超时问题?
  5. 怎么优雅地关闭通道?
  6. 从面向对象的角度聊聊java和golang的区别
  7. golang的GC
  8. golang的http路由实现懂吗,可以描述一下吗?
  9. golang程序hang住了可能是什么原因(说了可能死循环导致无法GC,golang1.13),怎么排查(可以用pprof)

数据结构

  1. 数组查找的时间复杂度是多少,为什么?
  2. 了解跳表吗?
  3. 你知道哪些树结构,各自的优缺点分别是什么?(回答的时候再回答一下应用场景就更好了)

操作系统

  1. 用过锁吗?读写锁加读锁的时候会阻塞写操作吗?会阻塞读操作吗?(用过,会,不会)

Linux

  1. 用过ps命令解决过什么问题吗?查询出来的结果各个字段有什么含义?
  2. 了解僵尸进程吗?怎么避免?
  3. 怎么根据pid获取父进程的pid(回答说去/proc下面),怎么根据pid找执行路径呢?怎么根据端口号找pid(回答说lsof -i,用netstat也可以但是我不知道,面试官补充的)

数据库

  1. Redis和MySQL的区别,什么时候用Redis,什么时候用MySQL(这里我说了下我们服务用到的场景)?如果让你设计一个秒杀系统,要怎么设计?(面试官后来提示了一下说redis又一个自增key)

MySQL

  1. 有几种隔离级别?默认级别是什么?可重复读是怎么解决幻读的?了解mvcc嘛?下面几种mysql哪个会用到联合索引

linked:https://juejin.cn/post/6967618371844046856