Go面试基础(纯理论)

      • 数据类型

        • 数据类型是编程语言中用来定义数据的属性和操作的分类。它决定了数据在内存中的存储方式和可以进行的操作。不同的数据类型具有不同的特性和限制。数据类型就像是一个容器
      • 泛型

        • 函数上简单使用泛型,提高下基础类库的开发效率
        • 需要使用slice, map, channel类型,但是slice, map, channel里的元素类型可能有多种
        • 通用的数据结构,比如链表,二叉树等。
        • 只是单纯调用实参的方法时,不要用泛型
        • 当函数或者方法或者具体的实现逻辑,对于不同类型不一样时,不要用泛型。比如encoding/json这个包使用了reflect,如果用泛型反而不合适
          • 当函数或者方法或者具体的实现逻辑,对于不同类型不一样时,不要用泛型。比如encoding/json这个包使用了reflect,如果用泛型反而不合适
        • 当你发现针对不同类型,会写出同样的代码逻辑时,才去使用泛型。
      • map

        • 遍历
          • 遍历键值对:使用for循环和range关键字遍历map时,range会返回键值对
      • 反射

        • 使用
          • 获取类型信息:可以使用reflect.TypeOf()函数获取一个值的类型信息,返回一个reflect.Type类型的对象。可以通过Type对象获取类型的名称、种类(如结构体、指针、函数等)、字段信息等。
          • 获取值信息:可以使用reflect.ValueOf()函数获取一个值的反射值,返回一个reflect.Value类型的对象。可以通过Value对象获取值的类型、获取和设置字段的值、调用方法等。
          • 类型转换:可以使用reflect.Value对象的Interface()方法将反射值转换为普通的接口类型,以便进行类型断言和类型转换。
          • 动态调用方法:可以使用reflect.Value对象的MethodByName()方法获取指定名称的方法,并通过Call()方法动态调用方法
          • 反射在一些特定的场景下非常有用,例如编写通用的库、处理配置文件、实现序列化和反序列化等。但在大多数情况下,应优先考虑使用静态类型和接口来实现代码逻辑,以获得更好的性能和可读性。
      • 死锁

        • 如何避免死锁和解决死锁问题
          • 避免嵌套锁:避免在一个锁的临界区内再次获取同一个锁,这可能导致死锁。如果确实需要在一个锁的临界区内获取另一个锁,可以考虑使用互斥锁的TryLock方法来尝试获取锁,避免阻塞
          • 避免循环依赖:当多个goroutine之间存在循环依赖时,容易导致死锁。可以通过调整锁的获取顺序,破坏循环依赖关系,避免死锁的发生。
          • 使用超时机制:在获取锁的操作中,可以使用带有超时机制的方式,避免长时间等待锁而导致死锁。可以使用time.After()函数或context.WithTimeout()函数来设置超时时间。
          • 使用互斥锁和条件变量:在使用锁的时候,可以结合条件变量(Cond)来实现更复杂的同步逻辑。条件变量可以用于在满足特定条件之前等待,以避免死锁。
          • 使用并发安全的数据结构:Go语言提供了一些并发安全的数据结构,如sync.Map、atomic包中的原子操作等。使用这些数据结构可以避免手动加锁导致的死锁问题
      • channel

        • 阻塞发生的情况
          • 发送阻塞:当向一个无缓冲的channel发送数据时,如果没有goroutine在等待接收数据,发送操作会阻塞,直到有其他goroutine接收数据为止
          • 接收阻塞:当从一个无缓冲的channel接收数据时,如果没有goroutine在发送数据,接收操作会阻塞  直到有其他goroutine发送数据为止
          • 缓冲区满阻塞:当向一个有缓冲的channel发送数据时,如果缓冲区已满,发送操作会阻塞,直到有其他goroutine从channel中接收数据,腾出缓冲区空间
          • 缓冲区空阻塞:当从一个有缓冲的channel接收数据时,如果缓冲区为空,接收操作会阻塞,直到有其他goroutine向channel中发送数据
          • 向nil的channel读写数据会导致程序永久地阻塞
        • panic

          • 向已关闭的channel发送数据:当向一个已经关闭的channel发送数据时,会导致panic。关闭的channel不能再进行发送操作,否则会引发panic。
          • 从已关闭的channel接收数据:当从一个已经关闭的channel接收数据时,如果缓冲区中没有数据,会返回一个零值,并且不会发生panic。但如果缓冲区中已经没有数据,而且channel已经关闭,继续接收操作会导致panic。
          • 关闭一个nil的channel会panic
          • 当发生panic时,会触发panic机制,当前goroutine的执行会被中断,然后会沿着调用栈向上查找defer语句,并执行相应的defer函数。如果没有恢复panic,程序会终止并打印panic信息。
          • 关闭一个已经关闭的channel
      • 逃逸分析

        • 悬挂指针

          • 避免返回指向局部变量的指针:在函数中创建的局部变量在函数返回后会被销毁,因此不应返回指向局部变量的指针。
          • 避免将指针存储在全局变量中:全局变量的生命周期很长,如果将指针存储在全局变量中,可能导致指针指向的对象在不再需要时仍然被引用
          • 结构体指针做返回值:因为局部变量保存在栈上,函数调用结束后,栈帧释放,局部变量的地址上,不在收系统保护,随时可能分配给其他程序。
        • 规则

          • 栈上分配:如果一个变量在函数内部创建,并且在函数结束后不再被引用,那么可以将其分配在栈上。这样的变量不会逃逸到堆上,可以通过栈的自动释放来回收内存。
          • 堆上分配:如果一个变量在函数内部创建,并且在函数结束后仍然被引用(如返回指针或存储在全局变量中),那么会将其分配在堆上。这样的变量会逃逸到堆上,需要通过垃圾回收来释放内存。
        • 作用

          • 优化内存分配和减少垃圾回收的压力。如果一个变量在函数结束后不再被引用,那么可以将其分配在栈上,而不是在堆上进行内存分配。这样可以减少垃圾回收的工作量,提高程序的性能。
          • 逃逸分析的结果可以帮助优化内存分配和减少垃圾回收的压力,提高程序的性能。
          • 减少程序员心智负担
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值