golang面试:golang基础语法(一)


title: golang基础语法(一)
auther: Russshare
toc: true
date: 2021-07-13 18:56:29
tags: [golang, 面试]
categories: golang面试

最近忙于面试,就顺便把这个更新到blog上面方便随时查看,有些不对的请留意告知,内容大多数来源前辈的文章,因为当时做笔记也搞忘复制链接了,如果有知道的欢迎补充,我会补上链接。

  • 1、基础语法

    • 01 = 和 := 的区别?

      • =就是单纯的赋值
        :=具有声明变量的功能
    • 02 map

      • 01、map如何顺序读取

        • map不能顺序读取,是因为他是无序的,想要有序读取,首先的解决的问题就是,把key变为有序,所以可以把key放入切片,对切片进行排序,遍历切片,通过key取值。
      • 02 如何判断 map 中是否包含某个 key ?

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

      • 作用对象

        • make 只能用于slice,chan,map 对这些对象进行初始化
        • new 用于 golang任意type 自定义类型和 内置数据类型
      • 语义

        • make(T,args) 初始化内置数据结构(slice,chan,map)
        • new(T) 根据传入的类型,分配一片零值的内存空间,并返回指向这片内存空间的指针 value *T ,显示的创建了对象的一个指针,而不必使用&T对获取该对象的地址。
    • 04 切片与数组 slice

      • 数组

        • (1). 数组
          数组是具有固定长度且拥有零个或者多个相同数据类型元素的序列。

        数组的长度是数组类型的一部分,所以[3]int 和 [4]int 是两种不同的数组类型。

        数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变;

        数组是值传递;

        数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值。

        在初始化后长度是固定的,无法修改其长度。当作为方法的参数传入时将复制一份数组而不是引用同一指针。数组的长度也是其类型的一部分,通过内置函数len(array)获取其长度。

          数组定义:var array [10]int
          var array = [5]int{1,2,3,4,5}
        
          	- 切片
        
          		- 切片表示一个拥有相同类型元素的可变长度的序列。
        

        切片是一种轻量级的数据结构,它有三个属性:指针、长度和容量。

        切片不需要指定大小;

        切片是地址传递;

        切片可以通过数组来初始化,也可以通过内置函数make()初始化 .初始化时len=cap,在追加元素时如果容量cap不足时将按len的2倍扩容;

        切片定义:var slice []type = make([]type, len)

      • slice,len,cap,共享,扩容

        • len:切片的长度,访问时间复杂度为O(1),go的slice底层是对数组的引用。
        • cap:切片的容量,扩容是以这个值为标准。默认扩容是2倍,当达到1024的长度后,按1.25倍。
        • 扩容:每次扩容slice底层都将先分配新的容量的内存空间,再将老的数组拷贝到新的内存空间,因为这个操作不是并发安全的。所以并发进行append操作,读到内存中的老数组可能为同一个,最终导致append的数据丢失。
        • 共享:slice的底层是对数组的引用,因此如果两个切片引用了同一个数组片段,就会形成共享底层数组。当sliec发生内存的重新分配(如扩容)时,会对共享进行隔断。详细见下面例子:
    • 05 在go语言中,Printf()、Sprintf()、Fprintf()函数的区别用法是什么

      • Print(),是把格式字符串输出到标准输出(一般是屏幕,可以重定向)。
      • Printf() 是和标准输出文件(stdout)关联的,Fprintf 则没有这个限制.
      • Sprintf(),是把格式字符串输出到指定字符串中,所以参数比printf多一个char*。那就是目标字符串地址。
      • Fprintf(), 是把格式字符串输出到指定文件设备中,所以参数笔printf多一个文件指针FILE*。主要用于文件操作。Fprintf()是格式化输出到一个stream,通常是到文件。
    • 06 解释以下命令的作用?

      • go env:   #用于查看go的环境变量

      • go run:   #用于编译并运行go源码文件

      • go build:  #用于编译源码文件、代码包、依赖包

      • go get:   #用于动态获取远程代码包

      • go install:  #用于编译go文件,并将编译结构安装到bin、pkg目录

      • go clean:  #用于清理工作目录,删除编译和安装遗留的目标文件

      • go version:  #用于查看go的版本信息

    • 07 go语言中没有隐藏的this指针,这句话是什么意思?

    • 08 int与int32

      • Go 语言是强类型语言啊,即使底层结构相同,如果声明的类型不同,就必须要强制转化。类型转化可能会产生精度丢失。故而,Go 的设计原则就是没有隐式类型转化
    • 09 说说go语言的main函数

      • main函数不能带参数
      •   main函数不能定义返回值
        
      •   main函数所在的包必须为main包
        
      •   main函数中可以使用flag包来获取和解析命令行参数
        
    • 10 说说go语言中的init函数?

      • (1)、一个包中,可以包含多个init函数
      • (2)、程序编译时,先执行导入包的init函数,再执行本包内的init函数
    • 11 Go 允许多个返回值吗?

      • Go语言革命性地在静态开发语言阵营中率先提供了多返回值功能。
    • 12 go语言中的引用类型包含哪些?

      • 数组切片、字典(map)、通道(channel)、接口(interface)
    • 13 Go 有异常类型吗?

      • 有 err
    • 14 channel

      • Golang中除了加Mutex锁以外还有哪些方式安全读写共享变量?

        • Golang中Goroutine 可以通过 Channel 进行安全读写共享变量
      • 无缓冲 Chan 的发送和接收是否同步?

      • 特性

        • A. 给一个 nil channel 发送数据,造成永远阻塞
        • B. 从一个 nil channel 接收数据,造成永远阻塞
        • C. 给一个已经关闭的 channel 发送数据,引起 panic
        • D. 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值
        • E. 无缓冲的channel是同步的,而有缓冲的channel是非同步的
    • 15 如何高效地拼接字符串

      • 在已有字符串数组的场合,使用 strings.Join() 能有比较好的性能

      • 在一些性能要求较高的场合,尽量使用 buffer.WriteString() 以获得更好的性能

      • 性能要求不太高的场合,直接使用运算符,代码更简短清晰,能获得比较好的可读性

      • 如果需要拼接的不仅仅是字符串,还有数字之类的其他需求的话,可以考虑 fmt.Sprintf()

    • 16 什么是 rune 类型

      • //int32的别名,几乎在所有方面等同于int32

      • //它用来区分字符值和整数值

      • byte 等同于uint8,常用来处理ascii字符

      • rune 等同于int32,常用来处理unicode或utf-8字符

    • 17 Go 支持默认参数或可选参数吗?

      • Go语言追求显式的表达,避免隐含,这种设计在其面向对象的语法中尤其明显

      • 不支持默认值 语言就是工具,go的语法简单,什么都不支持,就是防止工具被滥用。

    • 18 defer 的执行顺序

      • 你只需要在调用普通函数或方法前加上关键字defer,就完成了defer所需要的语法。

      • 当defer语句被执行时,跟在defer后面的函数会被延迟执行。

      • 直到包含该defer语句的函数执行完毕时,defer后的函数才会被执行,

      • 不论包含defer语句的函数是通过return正常结束,还是由于panic导致的异常结束。

      • 你可以在一个函数中执行多条defer语句,它们的执行顺序与声明顺序相反。

      • defer的常用场景:

          • defer语句经常被用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。
          • 通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。
          • 释放资源的defer应该直接跟在请求资源的语句后。
    • 19 Go 语言 tag 的用处?

      • tag 可以理解为 struct 字段的注解,可以用来定义字段的一个或多个属性。框架/工具可以通过反射获取到某个字段定义的属性,采取相应的处理方式。tag 丰富了代码的语义,增强了灵活性。go与json字符串
    • 20 如何判断 2 个字符串切片(slice) 是相等的?

      • 1、go 语言中可以使用反射 reflect.DeepEqual(a, b) 判断 a、b 两个切片是否相等,但是通常不推荐这么做,使用反射非常影响性能。
      • 2、通常采用的方式如下,遍历比较切片中的每一个元素(注意处理越界的情况)。
    • 21 字符串打印时,%v 和 %+v 的区别

      • %v 和 %+v 都可以用来打印 struct 的值,区别在于 %v 仅打印各个字段的值,%+v 还会打印各个字段的名称。
      • 但如果结构体定义了 String() 方法,%v 和 %+v 都会调用 String() 覆盖默认值。
    • 22 Go 语言中如何表示枚举值(enums)?

    • 23 空 struct{} 的用途

      • 使用空结构体 struct{} 可以节省内存,一般作为占位符使用,表明这里并不需要一个值。

        • 比如使用 map 表示集合时,只关注 key,value 可以使用 struct{} 作为占位符。如果使用其他类型作为占位符,例如 int,bool,不仅浪费了内存,而且容易引起歧义。
        • 声明只包含方法的结构体。
    • 24 interface代替继承多态

      • 接口类型,是一种抽象的类型,它不会暴露它所代表的对象的内部值和对象支持的操作方法。接口只会通过声明方法(行为)来展示它是用来做什么,并不知道它具体是什么。

      • Go不是严格意义上的面向对象编程语言,理解Go的接口、多态和继承的特性和编程思想

      • https://zhuanlan.zhihu.com/p/59749625

      • interface分为两种 1.空接口 2.带方法的接口

    • 25 go struct能不能比较

      • 如果结构体的所有成员变量都是可比较的,那么结构体就可比较
      • 如果结构体中存在不可比较的成员变量,那么结构体就不能比较
      • 结构体之间进行转换需要他们具备完全相同的成员(字段名、字段类型、字段个数)
    • 26 select可以用于什么

      • (1)、select机制用来处理异步IO问题
      • (2)、select机制最大的一条限制就是每个case语句里必须是一个IO操作
      • (3)、golang在语言级别支持select关键字
    • 27 JSON 标准库对 nil slice 和 空 slice 的处理是一致的吗?

      • 首先JSON 标准库对 nil slice 和 空 slice 的处理是不一致.
    • 28 解释一下 go 语言是一门什么类型的语言?有什么特点,主要能用来做什么?

        1. 静态强类型 2. 编译型 3. 并发型 4. 有垃圾回收功能 的编程语言
    • 29 解释一下 go 语言当中的强类型是什么?有何作用?

        1. 静态强类型 2. 编译型 3. 并发型 4. 有垃圾回收功能 的编程语言
        • 静态类型:编译时就确定类型,java/C/C++/golang
        • 动态类型:运行时确定 python/PHP
        • 强类型:类型是定义好的,无法改变它的类型了,但是向C语言,虽然定义了一个short,还是可以当成char来用的,因为可以直接操作内存。
        • 弱类型:类型之间可以自由转换

猜你喜欢

转载自blog.csdn.net/weixin_45264425/article/details/132200012