2023Go面试问答_Go基础

2023-11-09

与其他语言相比,使用 Go 有什么好处

  • 与其他作为学术实验开始的语言不同,Go代码的设计是务实的。每个功能和语法决策都旨在让程序员的生活更轻松。

  • Golang 针对并发进行了优化,并且在规模上运行良好。

  • 由于单一的标准代码格式,Golang 通常被认为比其他语言更具可读性。

  • 自动垃圾收集明显比 Java 或 Python 更有效,因为它与程序同时执行。

Golang 使用什么数据类型

Golang 使用以下类型:

  • Method

  • Boolean

  • Numeric

  • String

  • Array

  • Slice

  • Struct

  • Pointer

  • Function

  • Interface

  • Map

  • Channel

Go 程序中的包是什么

包 (pkg) 是 Go 工作区中包含 Go 源文件或其他包的目录。源文件中的每个函数、变量和类型都存储在链接包中。每个 Go 源文件都属于一个包,该包在文件顶部使用以下命令声明:

package < packagename > 

您可以使用以下方法导入和导出包以重用导出的函数或类型:

import <packagename> 

Golang 的标准包是 fmt,其中包含格式化和打印功能,如 Println().

Go 支持什么形式的类型转换

将整数转换为浮点数。 Go 支持显式类型转换以满足其严格的类型要求。

i :=55 //int

什么是 Goroutine

你如何停止它? 一个 Goroutine 是一个函数或方法执行同时旁边其他任何够程采用了特殊的Goroutine 线程。Goroutine 线程比标准线程更轻量级,大多数 Golang 程序 同时使用数千个 g、Goroutine。

要创建 Goroutine,请 go 在函数声明之前添加关键字。

go f(x, y, z) 

您可以通过向 Goroutine 发送一个信号通道来停止它。Goroutines 只能在被告知检查时响应信号,因此您需要在逻辑位置(例如 for 循环顶部)包含检 查。

package main func main() { 
  quit := make(chan bool) 
  go func() { 
    for { 
        select { 
        case <-quit: 
            return 
        default: 
            // … 
        } 
  } 
}() 
// … 
quit <- true 
} 

如何在运行时检查变量类型

类型开关是在运行时检查变量类型的最佳方式。类型开关按类型而不是值来评估变量。每个 Switch 至少包含一个 case,用作条件语句,和一个defaultcase,如果没有一个 case 为真,则执行。

Go 两个接口之间可以存在什么关系

如果两个接口有相同的方法列表,那么他们就是等价的,可以相互赋值。如果接口 A 的方法列表是接口 B 的方法列表的自己,那么接口 B 可以赋值给接口A。接口查询是否成功,要在运行期才能够确定。

Go 当中同步锁有什么特点 作用是什么

当一个 Goroutine(协程)获得了 Mutex 后,其他 Gorouline(协程)就只能乖乖的等待,除非该 gorouline 释放了该 MutexRWMutex 在读锁占用的情况下,会阻止写,但不阻止读 RWMutex 在写锁占用情况下,会阻止任何其他 goroutine(无论读和写)进来,整个锁相当于由该 goroutine 独占 同步锁的作用是保证资源在使用时的独有性,不会因为并发而导致数据错乱, 保证系统的稳定性。

Go 语言当中 Channel(通道)有什么特点,需要注意什么

如果给一个 nil 的 channel 发送数据,会造成永远阻塞如果从一个 nil 的 channel 中接收数据,也会造成永久爱阻塞给一个已经关闭的 channel 发送数据, 会引起 pannic 从一个已经关闭的 channel 接收数据, 如果缓冲区中为 空,则返回一个零值

Go 语言当中 Channel 缓冲有什么特点

无缓冲的 channel 是同步的,而有缓冲的 channel 是非同步的。

Go 语言中 cap 函数可以作用于那些内容

cap 函数在讲引用的问题中已经提到,可以作用于的类型有:

  • array(数组)

  • slice(切片)

  • channel(通道)

go convey 是什么?一般用来做什么

  • go convey 是一个支持 golang 的单元测试框架

  • go convey 能够自动监控文件修改并启动测试,并可以将测试结果实时输出 到 Web 界面

  • go convey 提供了丰富的断言简化测试用例的编写

Go 语言当中 new 和 make 有什么区别吗

new 的作用是初始化一个纸箱类型的指针 new 函数是内建函数,函数定义:

func new(Type) *Type 

  • 使用 new 函数来分配空间

  • 传递给 new 函数的是一个类型,而不是一个值

  • 返回值是指向这个新非配的地址的指针

Go 语言中 make 的作用是什么

make 的作用是为 slice, map or chan 的初始化 然后返回引用 make 函数是内建函数,函数定义:

func make(Type, size IntegerType) Type 

make(T, args)函数的目的和 new(T)不同 仅仅用于创建 slice, map, channel 而且返回类西行是实例

Printf(),Sprintf(),FprintF() 都是格式化输出,有什么不同

虽然这三个函数,都是格式化输出,但是输出的目标不一样。Printf 是标准输出,一般是屏幕,也可以重定向。 Sprintf()是把格式化字符串输出到指定的字符串中。 Fprintf()是吧格式化字符串输出到文件中。

Go 语言当中数组和切片的区别是什么

数组:

数组固定长度数组长度是数组类型的一部分,所以[3]int 和[4]int 是两种不同的数组类型数组需要指定大小,不指定也会根据处初始化对的自动推算出大小,不可改变数组是通过值传递的

切片:

切片可以改变长度切片是轻量级的数据结构,三个属性,指针,长度,容量不需要指定大小切片是地址传递(引用传递)可以通过数组来初始化,也可以通过内置函数 make()来初始化,初始化的时候 len=cap,然后进行扩容。

Go 语言当中值传递和地址传递(引用传递)如何运用 有什么区别 举例说明

  1. 值传递只会把参数的值复制一份放进对应的函数,两个变量的地址不同,不可相互修改。
  2. 地址传递(引用传递)会将变量本身传入对应的函数,在函数中可以对该变量进行值内容的修改。

Go 语言当中数组和切片在传递的时候的区别是什么

数组是值传递
切片是引用传递

Go 语言是如何实现切片扩容的

package main func main() { 
  quit := make(chan bool) 
  go func() { 
    for { 
        select { 
        case <-quit: 
            return 
        default: 
            // … 
        } 
  } 
}() 
// … 
quit <- true 
} 

看下面代码的 defer 的执行顺序是什么? defer的作用和特 点是什么

defer 的作用是:

你只需要在调用普通函数或方法前加上关键字 defer,就完成了 defer 所需要的语法。当 defer 语句被执行时,跟在 defer 后面的函数会被延迟执行。直到包含该 defer 语句的函数执行完毕时,defer 后的函数才会被执行,不论包含 defer 语句的函数是通过 return 正常结束,还是由于 panic 导致的异常结束。你可以在一个函数中执行多条 defer 语句,它们的执行顺序与声明顺序相反。

defer 的常用场景:

  • defer 语句经常被用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。

  • 通过 defer 机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。

  • 释放资源的 defer 应该直接跟在请求资源的语句后。

Golang Slice 的底层实现

切片是基于数组实现的,它的底层是数组,它自己本身非常小,可以理解为对底层数组的抽象。因为基于数组实现,所以它的底层的内存是连续分配的,效率非常高,还可以通过索引获得数据,可以迭代以及垃圾回收优化。 切片本身并不是动态数组或者数组指针。它内部实现的数据结构通过指针引用底层数组,设定相关属性将数据读写操作限定在指定的区域内。切片本身是一 个只读对象,其工作机制类似数组指针的一种封装。

切片对象非常小,是因为它是只有 3 个字段的数据结构:

  • 指向底层数组的指针

  • 切片的长度

  • 切片的容量

Golang Slice 的扩容机制,有什么注意点

Go 中切片扩容的策略是这样的:

  • 首先判断,如果新申请容量大于 2 倍的旧容量,最终容量就是新申请的容 量

  • 否则判断,如果旧切片的长度小于 1024,则最终容量就是旧容量的两倍

  • 否则判断,如果旧切片长度大于等于 1024,则最终容量从旧容量开始循环增加原来的 1/4, 直到最终容量大于等于新申请的容量

  • 如果最终容量计算值溢出,则最终容量就是新申请容量

扩容前后的 slice 是否相同

情况一:

原数组还有容量可以扩容(实际容量没有填充完),这种情况下,扩容以后的数组还是指向原来的数组,对一个切片的操作可能影响多个指针指向相同地址 的 Slice。

情况二:

原来数组的容量已经达到了最大值,再想扩容, Go 默认会先开一片内存区域,把原来的值拷贝过来,然后再执行 append() 操作。这种情况丝毫不影响 原数组。 要复制一个 Slice,最好使用 Copy 函数。

Golang 的参数传递、引用类型

Go 语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。因为拷贝的内容有时候是非引用类型(int、string、struct 等这些),这样就在函数中就无法修改原内容数据;有的是引用类型(指针、map、slice、chan等 这些),这样就可以修改原内容数据。

Golang 的引用类型包括 slice、map 和 channel。它们有复杂的内部结构,除了申请内存外,还需要初始化相关属性。内置函数 new 计算类型大小,为其分配零值内存,返回指针。而 make 会被编译器翻译成具体的创建函数,由其分 配内存和初始化成员结构,返回对象而非指针。

Golang Map 底层实现

Golang 中 map 的底层实现是一个散列表,因此实现 map 的过程实际上就是实现散表的过程。在这个散列表中,主要出现的结构体有两个,一个叫 hmap(a header for a go map),一个叫 bmap(a bucket for a Go map,通常叫其 bucket)。

Golang Map 如何扩容

装载因子:count/2^B

触发条件:

  • 装填因子是否大于 6.5
  • overflow bucket 是否太多

解决方法:

  • 双倍扩容:扩容采取了一种称为“渐进式”地方式,原有的key 并不会一次性搬迁完毕,每次最多只会搬迁 2个bucket
  • 等量扩容:重新排列,极端情况下,重新排列也解决不了,map 成了链表,性能大大降低,此时哈希种子 hash0
    的设置,可以降低此类极端场景的发生

Golang Map 查找

Go 语言中 map 采用的是哈希查找表,由一个 key 通过哈希函数得到哈希值,64位系统中就生成一个 64bit 的哈希值,由这个哈希值将 key 对应到不同的桶(bucket)中,当有多个哈希映射到相同的的桶中时,使用链表解决哈希冲突。key 经过 hash 后共 64 位,根据 hmap 中 B 的值,计算它到底要落在哪个桶时,桶的数量为 2^B,如 B=5,那么用 64 位最后 5 位表示第几号桶,在用 hash 值的高 8 位确定在 bucket 中的存储位置,当前 bmap 中的 bucket 未找到,则查询对应的 overflow bucket,对应位置有数据则对比完整的哈希值,确定是否是要查找的数据。

如果两个不同的 key 落在的同一个桶上,hash 冲突使用链表法接近,遍历 bucket 中的 key 如果当前处于 map 进行了扩容,处于数据搬移状态,则优先从 oldbuckets 查找。

介绍一下 Channel

Go 语言中,不要通过共享内存来通信,而要通过通信来实现内存共享。Go 的CSP(Communicating Sequential Process)并发模型,中文可以叫做通信顺序进程,是通过 goroutine 和 channel 来实现的。

所以 channel 收发遵循先进先出 FIFO,分为有缓存和无缓存,channel 中大致有 buffer(当缓冲区大小部位 0 时,是个 ring buffer)、sendx 和 recvx 收发的位置(ring buffer 记录实现)、sendq、recvq 当前 channel 因为缓冲区不足 而阻塞的队列、使用双向链表存储、还有一个 mutex 锁控制并发、其他原属等。

Go 语言的 Channel 特性

  • 给一个 nil channel 发送数据,造成永远阻塞

  • 从一个 nil channel 接收数据,造成永远阻塞

  • 给一个已经关闭的 channel 发送数据,引起 panic

  • 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值

  • 无缓冲的 channel 是同步的,而有缓冲的 channel 是非同步的

  • 关闭一个 nil channel 将会发生 panic

Channel 的 ring buffer 实现

channel 中使用了 ring buffer(环形缓冲区) 来缓存写入的数据。ring buffer 有很多好处,而且非常适合用来实现 FIFO 式的固定长度队列。 在 channel 中,ring buffer 的实现如下:
在这里插入图片描述

hchan 中有两个与 buffer 相关的变量:recvx 和 sendx。其中 sendx 表示 buffer 中可写的 index,recvx 表示 buffer 中可读的 index。 从 recvx 到 sendx 之间的元素,表示已正常存放入 buffer 中的数据。 我们可以直接使用 buf[recvx]来读取到队列的第一个元素,使用 buf[sendx] = x 来将元素放到队尾。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2023Go面试问答_Go基础 的相关文章

  • JSON - 使用Gson反序列化动态对象

    假设我有一个以下类型的 Java 类 public class MyClass public String par1 public Object par2 然后我有这个 String json par1 val1 par2 subpar1
  • java.lang.NoClassDefFoundError: javax/ws/rs/core/Configuration

    我正在实现轻松的网络服务 并且正在使用 jboss 4 0 但我遇到以下异常 java lang NoClassDefFoundError javax ws rs core Configuration 我的 web xml 是
  • 在 Java 中将系统属性设置为 Null

    在我的单元测试中 我需要将 workingDir 系统属性设置为 Null 但我不能这样做 因为它给了我 NullPointerException System setProperty workingDir null 我该怎么做 您不能将属
  • android-透明RelativeLayout

    我想要制作一个具有可绘制渐变作为背景的活动 并将在其背景顶部显示 4 个面板 相对布局 现在我想让 4 个面板透明 例如 50 以便也可以看到渐变背景 我搜索了谷歌 但我发现只能通过活动而不是布局来做到这一点 如何做我想做的事 您可以创建一
  • 使 TreeMap 比较器容忍 null

    这个定制的 Valuecomarator 按其值对 TreeMap 进行排序 但在搜索 TreeMap 是否具有某个键时 它不能容忍 nullpointException 如何修改比较器来处理零点 import java io IOExce
  • Spring Batch 多线程

    我正在编写一个 Spring Batch 并希望在需要时对其进行扩展 我的 ApplicationContext 看起来像这样 Configuration EnableBatchProcessing EnableTransactionMan
  • 在 Java 和 C 中在运行时调用名为“string”的方法

    我们如何调用名称为的方法string在运行时 谁能告诉我如何在 Java 和 C 中做到这一点 在java中可以通过反射api来完成 看一下Class getMethod String methodName Class parameterT
  • 将对象列表传递给 Freemarker 然后循环

    我已经熟悉了 FreeMarker 一个 Java 模板引擎 我已经能够通过哈希映射将对象传递给模板引擎了 这样就可以了 但是 一旦我尝试将任何类型的多个对象集传递给 FreeMarker 它就会给我一个 freemarker templa
  • Selenium Webdriver 中显式等待 findElements

    登录后 页面重定向到一个页面 我想等待页面加载 我在其中按 tagName 查找元素 By inputArea By tagName input List
  • 内容安全策略:页面设置阻止自行加载资源?

    我有基于 Java 的 Web 应用程序运行在Tomcat http en wikipedia org wiki Apache Tomcat6 我的应用程序在本地主机和端口 9001 上运行 为了使我的应用程序更加安全并降低风险XSS ht
  • 如何在Android Studio中关联.mp3文件

    我想根据列表视图项单击播放 mp3 文件 但是根据我的代码 我运行我的应用程序 出现此窗口 因此由于缺少音频选项 我真的不知道需要选择其中哪一个为了关联我的 mp3 文件 mainList setOnItemClickListener ne
  • 如何更改tomcat jmx密码的文件权限

    我正在尝试保护 Windows 平台上托管的本地 tomcat 实例上的 JMX 访问 我已经创建了访问权限和密码文件 并使用以下 VM 参数插入这些文件 Dcom sun management jmxremote password fil
  • 使用 Spring 注入 Google Guava Hashmultimap

    是否可以提供一个创建示例Multimap
  • Spark toLocalIterator 和迭代器方法之间的区别

    在编写 Spark 程序时我遇到了这个toLocalIterator 方法 之前我只使用iterator method 如果有人曾经使用过这种方法 请点亮 我在使用时遇到foreach and foreachPartitionSpark程序
  • 将 Class 对象转换为字节

    如果我有一个Class http java sun com j2se 1 5 0 docs api java lang Class html在运行时实例 我可以获得它的 byte 表示形式吗 我感兴趣的字节将在类文件格式 http java
  • Spring Data elasticsearch @Query 注解嵌套对象

    我有两节课 Document public class PracticeQuestion private int userId private List
  • Jersey bean 验证 ParameterNameProvider

    我正在阅读关于泽西岛的文档Bean验证 https jersey java net documentation latest bean validation html The ParameterNameProvider示例显示如何定义方法的
  • 警告:无法加载 sqljdbc_auth.dll 原因:java.library.path 中没有 sqljdbc_auth

    我正在使用 Ubuntu 12 05 并尝试连接到 Windows Server 2012 来获取数据库 我的数据库名称是 jobs 电脑的IP地址是192 160 1 33 托管在1433 但是当我尝试连接时出现以下错误 WARNING
  • 如何更改MultipartFile的originalFilename

    我在服务器端有一个 MultipartFile 文件 我想更改该文件的原始文件名 但该类仅支持 getOriginalFilename 谁能帮我这个 PS 上传的是图片文件 多谢 您可以使用 MockMultipartFile 类更改名称
  • 如何获取 EC2 实例的 CloudWatch 指标数据

    我想获取我的 EC2 实例的 Cloudmetrics 数据 以便我可以使用这些数据绘制图表并将其显示在我的 Android 设备上 我怎么做 有相同的示例程序或教程吗 提前致谢 这就是我正在做的 private static void f

随机推荐

  • 从零开始的Docker详解(六)

    Docker仓库 docker仓库是集中存放镜像的地方 类似maven的仓库集中存放依赖 Docker Hub Docker Hub是由Docker官方维护的公共仓库 包含官方镜像和个人上传的镜像 大部分镜像都可以在上面找到 注 非官方的镜
  • CentOS7.3 安装

    选择Install CentOS Linux 7 选择语言 点击软件选择 选择基本环境 点击安装位置 选择我要配置分区 点击完成 根据需要选择分区方案 点击 根据需要添加挂载点 添加完所有挂载点后点击完成 在弹出的页面中选择接受更改 点击开
  • java基础知识点

    java中有四大修饰符 分别为private default protected public 下面主要是四者之间的区别 private 私有的 private可以修饰成员变量 成员方法 构造方法 不能修饰类 此刻指的是外部类 内部类不加以
  • 【mybatis-plus】学习笔记

    官方地址 https mp baomidou com 自动化工具 JPA tk imapper MybatisPlus 简介 MyBatis Plus 简称 MP 是一个 MyBatis 的增强工具 在 MyBatis 的基础上只做增强不做
  • 将Android项目打包成Library

    最近在弄一个SDK 考虑把项目做成 Library 类库的形式 方便调用 顺便在此分享给大家 首先 先创建一个普通的android项目 这个项目可以起任何你想要的名称 想要的包名等 步骤如下 在Package Explorer中 鼠标右键项
  • .NET Word模板引擎--MiniWord,继MiniExcel后又一开源作品

    目录 Part1简介 Part2特点 Part3安装 Part4使用 文本生成 图片生成 列表生成 表格生成 Part5总结 Part1简介 MiniWord 是 NET Word模板引擎 由Word模板和数据 简单 快速生成文件 Part
  • 启动模式,BOOT0和BOOT1详解

    原文链接 http blog csdn net daunxx article details 40148945 在画STM32的电路图的时候 关于STM32的启动方式纠结了一下 现有的参考设计都是在STM32的启动选择引脚BOOT0和BOO
  • 通过Java构建树形结构

    通过Java构建树形结构所需要的数据 实体类Test 主键 private String id 父类ID private String parentId 子节点 private List
  • matplotlib - 确保 0 在 RdBu 颜色条中变为白色

    matplotlib 确保 0 在 RdBu 颜色条中变为白色 matplotlib 确保 0 在 RdBu 颜色条中变为白色 IT工具网 标签 matplotlib colormap 我使用以下代码段创建了一个热图 span style
  • 丢手帕问题

    package Task author 链表解决丢手帕问题 约瑟夫问题 public class CycLink public static void main String args CycLinkModel cycLink new Cy
  • Vue3.x 中 vue.config 配置 Webpack-dev-server的proxy 实现代理跨域

    前言 如果你有单独的后端开发服务器 API 并且希望在同域名下发送 API 请求 那么代理某些 URL 会很有用 解决开发环境的跨域问题 不用在去配置nginx和host 爽歪歪 在webpack config js中配置 下面简单介绍一下
  • MySQL锁系列(八)之 死锁

    能学到什么 什么是死锁 死锁有什么危害 典型的死锁案例剖析 如何避免死锁 一 什么是死锁 1 必须满足的条件 1 2 1 必须有两个或者两个以上的事务 2 不同事务之间都持有对方需要的锁资源 A事务需要B的资源 B事务需要A的资源 这就是典
  • Protobuf(二)proto3语法格式

    proto文件有两种语法标准 proto2和proto3 我们以proto3为例 其语法格式如下 message
  • 什么是软件测试?

    什么是软件测试 软件测试的定义 在一定条件下对软件进行操作 发现软件的问题 提高软件的质量 软件测试在开发中的有着重要地位 软件测试在各阶段的完成相应的任务 需求测试 架构测试 详细测试等 随着测试的发展 测试技术有了新的支持和扩充CMMI
  • Spline interpolation and Savitzki-Golay smoothing

    转自 http octave 1599824 n4 nabble com Spline interpolation and Savitzki Golay smoothing td1675136 html natural cubic spli
  • QT---窗口、按钮的基本设置

    目录 一 窗口相关的设置及中文编译错误设置 1 在源文件widget cpp中进行修改数据 并创建有关界面 2 如遇中文编译错误 即标题中文显示乱码 可如下设置 3 窗口界面及标题设置 窗口是否拉伸 二 创建按钮的相关设置 1 添加头文件
  • mybatis使用resultMap自定义映射处理,处理多对一的映射关系:

    1 级联方式处理
  • UML 中九种图

    UML 中九种图 1 用例图 说明 由参与者 actor 用例 User Case 以及他们之间的关系构成 用来描述系统功能 作用 可视化表达系统需求 更直观 规范 客服纯文字说明不足 图示 2 类图 说明 类 Class 封装了数据和行为
  • 数据结构 线性表的顺序存储和链式存储,以及基本操作、单链表例题

    一 线性表的存储表示 1 顺序表 线性表的顺序表示又称为顺序表 顺序表的静态分配存储表示 线性表的静态分配顺序存储结构 typedef int ElemType typedef struct 顺序表的定义 ElemType elem LIS
  • 2023Go面试问答_Go基础

    与其他语言相比 使用 Go 有什么好处 与其他作为学术实验开始的语言不同 Go代码的设计是务实的 每个功能和语法决策都旨在让程序员的生活更轻松 Golang 针对并发进行了优化 并且在规模上运行良好 由于单一的标准代码格式 Golang 通