八股总结(go)实时更新!

发布于:2025-03-31 ⋅ 阅读:(15) ⋅ 点赞:(0)

八股总结(go)

  1. gorm底层怎么连接mysql的

    • gorm是一个基于go语言的ORM框架,gorm不直接实现数据库的连接,而是基于Go标准库database/sql来管理数据库连接池;
    • gorm.open()调用sql.open()初始化database/sql.DB;
  2. gin框架优势

    • gin是一个高性能、轻量级的web框架,基于net/http封装;
    • 基于RadixTree(基数树)进行路由分配;
    • 采用jsoniter进行JSON解析;
    • API设计简洁,内置多种HTTP方法,参数解析简洁;
    • 有着强大的中间件机制,支持局部和全局中间件,内置多个常用中间件,例如:
      • CORS(跨域处理)
      • JWT认证
      • 限流
      • 日志记录
      • 错误恢复(recovery,避免程序崩溃,能够自动捕获panic并返回500错误)
    • 内置渲染引擎,支持HTML模板渲染也支持JSON、XML、YAML格式;
  3. 切片的底层原理

    • slice本质是对底层数组的抽象,包含三个字段,指针:指向底层数组的起始地址,长度:切片当前长度,容量:表示切片当前容量;
    • 当切片容量不足时,会创建一个新的底层数组,并将数据拷贝到新的数组中,如果当前容量cap<=1024扩容两倍,如果当前容量>1024,扩容1.25倍左右;
    • 切片的共享机制,切片和数组是共享底层存储的,切片的修改会影响原始数组,slice[i:j]创建的新的切片如果修改数据,原slice仍然也会被修改;
  4. Map的底层原理

    • map采用哈希表(hashtable)结构,底层包含桶数组:存储键值对,哈希函数:用于计算key的哈希值并确定存放的bucket,溢出桶:当桶满时存储额外的数据;
    • go使用链地址法+开放寻址法解决哈希冲突,链地址法:每个桶最多存储8个键值对,如果超过8,会创建溢出桶,开放寻址法:使用额外的哈希计算在多个同种寻找空位存储;
    • map的扩容,当map大于负载因子6.5时触发扩容,创建2倍的桶,并重新计算key的哈希值,重新分配位置,采用渐进式迁移,为了避免一次性的拷贝影响性能;
    • map的删除,不会立即回收内存,只是标记删除,如果删除后桶为空,也不会回收桶的内存,当map进行扩容或更多数据加入时,才会真正释放内存;
  5. 将切片与map传入函数中,对数据进行修改,在函数外部切片与map会改变吗

    • 切片是引用传递,本质上是一个结构体,函数接收到还是这个结构体的副本,但其指向底层数组的指针不变,如果修改其数据会影响函数外的原切片,但若改变切片长度append()触发了扩容机制,则副本指向的底层数组地址发生改变,此时原切片则不会改变。如果切片触发扩容也能修改生效,则需要返回新的切片;
    • map是引用传递,本质上是一个指针,指向底层的哈希表,函数内部的修改会直接影响外部的map,如果在函数内部对map进行重新赋值(make(map[string]int)),入参会指向新的map,但不会影响外部的map;如果想要在函数内的重新赋值,则可以使用指针类型进行传参;
  6. 切片创建方式有哪些

    • 直接声明:var s []int,默认值为nil, 不能通过索引访问,会发生panic报错但可以append;

    • 使用make([]int, 5),创建长度为5容量为5默认数据为0的切片,也可以通过make([]int, 3, 10)指定capacity;

    • 直接初始化,s := []int{1, 2, 3};

    • 可以通过数组或现有切片创建,arr[1:4],共享arr数组或切片的底层存储,len()是数据长度,cap则是其arr[1]到arr末尾的长度,即从主切片中取出指向开头位置的链表地址这个意思;

      s1 := []int{10, 20, 30, 40, 50}
      s2 := s1[1:3] // [20, 30]
      fmt.Println(s2, len(s2), cap(s2)) // [20 30] 2 4
      
    • 赋值切片(copy()),如果想要创建一个独立的新切片,避免共享底层数组,可以使用copy(),

      src := []int{1, 2, 3}
      dst := make([]int, len(src))
      copy(dst, src)