luxuze.github.io

github pages

View on GitHub

grammer

slice 从一个切片中创建的新切片,两者共享同一个底层数组,如果修改共享部分,另一个切片有感知

func main() {
    a1 := []int{1,2,3,4}
    a2 := a1[0:1]
    a2[0] = 0
    fmt.Println(a1)
    // [0 2 3 4]
}

go struct 能不能比较

defer 执行顺序

func main() {
    for i := 0; i < 4; i++ {
        defer fmt.Print(i)
    }
    panic(4)
}
// 3210panic: 4

select 可以用于什么,常用于 gorotine 的完美退出

  1. golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作
  2. 每个 case 语句里必须是一个 IO 操作,确切的说,应该是一个面向 channel 的 IO 操作

在 go 语言中,new 和 make 的区别

  1. new 的作用是初始化一个指向类型的指针(*T)
  2. new 函数是内建函数,函数定义:func new(Type) *Type
  3. 使用 new 函数来分配空间。传递给 new 函数的是一个类型,不是一个值。返回值是 指向这个新分配的零值的指针。
  4. make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。
  5. make 函数是内建函数,函数定义:func make(Type, size IntegerType) Type
    1. 第一个参数是一个类型,第二个参数是长度
    2. 返回值是一个类型
  6. make(T, args)函数的目的与 new(T)不同。它仅仅用于创建 Slice, Map 和 Channel,并且返回类型是 T(不是 T*)的一个初始化的(不是零值)的实例。

说说 go 语言中,数组与切片的区别

  1. 数组

    1. 数组是具有固定长度且拥有零个或者多个相同数据类型元素的序列。
    2. 数组的长度是数组类型的一部分,所以[3]int 和 [4]int 是两种不同的数组类型。
    3. 数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变 ;
    4. 数组是值传递;
    5. 数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从 0 开始的下标索引访问元素值。在初始后长度是固定的,无法修改其长度。当作为方法的参数传入时将复制一份数组而不是引用同一指针。数组的长度也是类型的一部分,通过内置函数 len(array)获取其长度。
    6. 数组定义:
      1. var array [10]int
      2. var array = [5]int{1,2,3,4,5}
  2. 切片

    1. 切片表示一个拥有相同类型元素的可变长度的序列。
    2. 切片是一种轻量级的数据结构,它有三个属性:指针、长度和容量。
    3. 切片不需要指定大小;
    4. 切片是地址传递;
    5. 切片可以通过数组来初始化,也可以通过内置函数 make()初始化 .初始化时 len=cap,在追加元素时如果容量 cap1. 不足时将按 len 的 2 倍扩容;
    6. 切片定义:var slice []type = make([]type, len)

go 语言中的引用类型包含哪些

go 语言中指针运算有哪些

  1. 可以通过“&”取指针的地址
  2. 可以通过“*”取指针指向的数据

说说 go 语言的 channel 特性

  1. 给一个 nil channel 发送数据,造成 fatal error: all goroutines are asleep - deadlock!
  2. 从一个 nil channel 接收数据,造成永远阻塞
  3. 给一个已经关闭的 channel 发送数据,引起 panic
  4. 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值
  5. 无缓冲的 channel 是同步的,而有缓冲的 channel 是非同步的

说说进程、线程、协程之间的区别

  1. 进程是资源的分配和调度的一个独立单元,而线程是 CPU 调度的基本单元;
  2. 同一个进程中可以包括多个线程;
  3. 进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束;
  4. 线程共享整个进程的资源(寄存器、堆栈、上下文),一个进程至少包括一个线程;
  5. 进程的创建调用 fork 或者 vfork,而线程的创建调用 pthread_create;
  6. 线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源;
  7. 进程是资源分配的单位,线程是操作系统调度的单位
  8. 效率
    1. 进程切换需要的资源很最大,效率很低
    2. 线程切换需要的资源一般,效率一般
    3. 协程切换任务资源很小,效率高
  9. 多进程、多线程根据 cpu 核数不一样可能是并行的 也可能是并发的。协程的本质就是使用当前进程在不同的函数代码中切换执行,可以理解为并行。 协程是一个用户层面的概念,不同协程的模型实现可能是单线程,也可能是多线程。
  10. 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。(全局变量保存在堆中,局部变量及函数保存在栈中)
  11. 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是这样的)。
  12. 协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。
  13. 一个应用程序一般对应一个进程,一个进程一般有一个主线程,还有若干个辅助线程,线程之间是平行运行的,在线程里面可以开启协程,让程序在特定的时间内运行。
  14. 协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多 CPU 的能力。