Golang的面试50问(一)?

数据类型

  1. go的数据类型有几种,分别都是哪些?
    14种,分别是
    基本数据类型:整型,浮点型、复数形,布尔、字符串、字符(byte、rune)
    复合数据类型:数组、切片、映射、函数、结构体、通道、接口、指针
  2. 整型数据类型的范围
    有符号类型是 负的(2的N-1)次方到正的(2的N-1次方-1) 如 int8:-128 127 负2的7次方-正的2的7次方减1
    无符号类型是 正的2的N次方-1 uint8: 0~255
    3.什么是字符串字面量
    双引号书写字符串呗成为字符串字面量,这种字面量不能跨行(string literal)
    4.字符byte和rune?
    字符串中的每一个元素叫“字符”,byte 1字节 rune 4字节(表示单个unicode字符,int32的别名类型)
    5.iota是用来干什么的?
    iota,特殊常量值,是一个系统定义的可以被编译器修改的常量值。iota只能被用在常量的赋值中,每个const关键字出现时,被重置为0,然后每出现一个常量,iota所代表的数值会自动加1
    6.位运算符号按位异或、左移、右移的意义
    (^):两个bit位不同为1,相同为0
    (<<)按照二进制把所有的数字向左移动对应的位数,高位舍弃,低位补0,数学意义就是乘以2的n次方
    (>>)按照二进制把所有的数字向右移动对应的位数,低位舍弃,高位补0,数学意义就是除以2的n次方

函数与指针

  1. 局部变量和全局变量
    在函数体内声明的变量为局部,函数体外声明的叫全局,全局变量的声明周期同main(),他们名字可以相同,局部变量会被优先考虑
    8.函数变量
    type caseFunc func(string) string 声明了一个函数类型。
  2. 闭包
    闭包是由函数和其他的引用环境组合而成的实体。
    函数是编译器静态的概念,闭包是运行期动态的概念
    优点:加强模块化、较好的抽象能力、简化代码
    10.可变参数
    通过...的方式来实现
    11.指针
    指针是存储另一个变量的内存地址的变量。用&符号来获取变量的地址。在golang语言里指针不能运算
    var ptr int 指向整型的指针
    获取指针指向的变量值用
    号 *ptr
    空指针:指针被定义后没有分配到任何变量时,它的值为nil,也就是空指针。
    指针数组:就是元素为指针类型的数组
    指针的指针:一个指针变量存放的又是另一个指针变量的地址,则这个指针变量为指向指针的指针。
    var ptr **int
    12.函数的参数传递
    值传递:调用函数时将实际参数复制一份。
    引用传递:调用函数时将实际参数的地址传递到函数中
    go的slice和map、chan类型的实现机制都类似指针
    go语言中所有的传参都是值传递,都是一个副本。副本的内容有的值类型
    int string bool array struct 属于值类型
    pointer、slice、map、chan 属于引用类型

内置容器

  1. 数组函数
    数组是相同类型的一组结构构成的长度固定的序列
    var 变量名 [数组长度] 数据类型
    数组的长度,len(array)
    数组是值类型,不是引用类型

  2. 切片
    切片是可变长度的序列,序列中每个元素都是相同的类型。
    var identifier []type
    make([]type,len,capacity)
    len()获取长度,cap()方法获取容量、append()追加新元素,copy()复制切片元素。
    切片是引用类型

  3. map
    map是由Hash表实现的,所以对map的读取顺序不固定,也就是说map是无序的,key必须保证唯一。map也是引用类型
    var 变量名 map[key类型]value 类型
    make(map[key类型]value类型)
    判断key是否存在
    value,ok := map[key]
    函数 delete()删除集合中的元素,清空map 重新make一个新的map

  4. 常用的内置包?
    字符串:按字符串和字符遍历
    常用函数:contains(s,substr string)bool 判断字符串s是否包含substr字符串
    count(s,sep string)int 返回字符串s包含字符串sep的个数
    index(s,sep string) int 返回字符串s中字符串sep首次出现的位置
    lastIndex(s,sep string) int 返回字符串s中sep最后一次出现的位置
    分割:
    fields(s string)[]string 以空白字符串分割 返回一个切片
    split(s,sep string)[]string 以sep为分隔符分割,分割后字符最后去掉sep
    splitAfter(s,sep string)[]string 以sep为分隔符分割,分割后字符最后附加sep
    大小写:
    title() 首字母大写
    tolower()小写
    toupper()大写
    其他:
    修剪 trim() 比较compare()

  5. 正则表达式
    ^a 以a为开头
    . 除\n以外的任何单个字符
    $ 匹配输入字符串的结数位置
    x|y 代表x或者y (g|f)ood 匹配good 和food

    • 匹配前面的子表达式0次或多次,相当于{0,}
    • 匹配前面的子表达式1次或多次,等价于{1,}
      ? 0次或一次
      [xyz] 匹配所包含的任意一个字符,如[abc]可以匹配plain中的a
      [^xyz] 匹配未包含的任意一个字符,如[abc]可以匹配plain中的p
      \d 匹配一个数字,等价[0-9]
      \D 匹配一个非数字,等价于[^0-9]
  6. time 包
    now() 当前本地时间
    before() t在u之前,返回true
    after() t在u之后,返回true

面向对象编程

面向对象:关注的是对象,构成问题的事务分解成各个对象。
面向过程:关注的是过程,分析出解决问题的步骤,然后用函数实现每一个步骤。
  1. 结构体:
    值类型
    属性必须唯一
    统一个包内部能重复,
    同类型的成员属性可以写一行。
    当实例,才分配内存,只有先实例化才能使用结构体。
    值类型
    深拷贝就是为新的对象分配了内存
    浅拷贝:
    只是复制了对象的指针
    结构体嵌套:
    将一个结构体作为另一个结构体的属性(字段),这种结构就是结构体嵌套
    聚合关系:一个类作为另一个类的属性
    继承关系:一个类作为另一个类的子类
    实例化:根据结构体的定义的格式创建一份与格式一致的内存区域。
    结构体实例化后形成指针类型的结构体,new()函数会分配内存,第一个参数是类型,返回的值是指向该类型重新分配的零值的指针。

  2. 方法:
    作用于特定类型变量的函数。这种特定类型变量叫做接受者,类似于其他语言的this或者self。
    函数:一段具有独立功能的代码,可以被反复多次调用。
    区别:函数不可以重名,方法可以重名;方法有接受者,而函数无接受者。

    go为什么有方法和函数?
    1 实现类似于类的行为
    2 相同名称的方法可以在不同的类型定义,而相同名称的函数时不允许的。

  3. 接口
    面向对象语言中,接口用于定义对象的行为。当某个类型为接口中的所有方法提供了具体的实现细节,这个类型就被称为实现了该接口。
    type Phone interface{
    call()
    }
    什么是鸭子模型:
    走路像鸭子,叫声像鸭子,就归类为鸭子。
    duck typing 编程语言往往被归为动态类型语言,
    缺点:静态类型语言的编译时候就能发现错误,而动态语言需要运行时才能发现。
    go的折中:
    结构体类型T不需要显示的声明它实现了接口I,只要类型T实现了接口I规定的所有方法,它就自动实现了接口I
    将结构体类型的变量显式或者隐式转换为接口I类型的变量i,这样就可以在奇台讲台类型语言一样,在编译时检查参数的合法性。
    多态:多态就是事务的多种形态,几个相似而不完全相同的对象,要求向他们发出同一个消息时,反应各不相同,执行不同的操作。

  4. 空接口
    空接口中没有任何方法,任意类型都可以实现该接口:interface{},
    场景:
    1 println的参数就是空接口
    2 定义个map:key是string,value是任意数据类型
    3 定义一个切片,其中存储任意类型的数据

异常处理

  1. error 本质上是一个接口类型,其中包含一个Error()方法,错误值可以存储在变量中,通过函数返回。
    type error interface{
    Error()string
    }
    处理方式是跟nil比较

  2. 用于延迟一个函数或者方法的执行的关键字是什么?
    defer,只能出现在函数或者方法的内部
    defer 是按照逆序执行的,报错的时候也会执行。因为是放在堆栈中,按照先进后出的顺序执行。
    使用场景:处理成对的操作,打开-关闭,链接-断开连接,加锁-释放锁,特别是在执行打开资源操作时,遇到错误需要提前返回,返回前需要关闭相应的资源,不然很容易造成资源泄露。
    defer的参数在执行延迟语句时被执行,而不是在执行实际的函数调用时执行。

  3. panic作用是什么?
    让当前程序进入恐慌,中断程序的执行,panic()是一个内建函数,可以中断原有的控制流程。不应该通过调用panic()函数来报告普通的错误,而应该只把它作为报告致命错误的一种方式。

  4. recover是干什么的?
    recover 可以让进入恐慌的流程的goroutine,恢复过来并重新获得流程控制权。recover可以捕获panic()的输入值,使程序恢复正常运行。必须在延迟函数中进行。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注