Go语言面经进阶10问
1.Golang可变参数
函数方法的参数,可以是任意多个,这种我们称之为可以变参数,比如我们常用的fmt.Println()这类函数,可以接收一个可变的参数。可以变参数,可以是任意多个。我们自己也可以定义可以变参数,可变参数的定义,在类型前加上省略号…即可。
func main() {print("1","2","3")
}func print (a ...interface{}){for _,v:=range a{fmt.Print(v)}fmt.Println()
}
例子中我们自己定义了一个接受可变参数的函数,效果和fmt.Println()一样。可变参数本质上是一个数组,所以我们向使用数组一样使用它,比如例子中的 for range 循环。
2.Golang Slice的底层实现
切片是基于数组实现的,它的底层是数组,它自己本身非常小,可以理解为对底层数组的抽象。因为基于数组实现,所以它的底层的内存是连续分配的,效率非常高,还可以通过索引获得数据,可以迭代以及垃圾回收优化。
切片本身并不是动态数组或者数组指针。它内部实现的数据结构通过指针引用底层数组,设定相关属性将数据读写操作限定在指定的区域内。切片本身是一个只读对象,其工作机制类似数组指针的一种封装。
切片对象非常小,是因为它是只有3个字段的数据结构:
- 指向底层数组的指针
- 切片的长度
- 切片的容量
这3个字段,就是Go语言操作底层数组的元数据。
3.Golang Slice的扩容机制,有什么注意点
Go 中切片扩容的策略是这样的:
首先判断,如果新申请容量大于 2 倍的旧容量,最终容量就是新申请的容量。否则判断,如果旧切片的长度小于 1024,则最终容量就是旧容量的两倍。
否则判断,如果旧切片长度大于等于 1024,则最终容量从旧容量开始循环增加原来的 1/4 , 直到最终容量大于等于新申请的容量。如果最终容量计算值溢出,则最终容量就是新申请容量。
情况一:原数组还有容量可以扩容(实际容量没有填充完),这种情况下,扩容以后的数组还是指向原来的数组,对一个切片的操作可能影响多个指针指向相同地址的Slice。
情况二:原来数组的容量已经达到了最大值,再想扩容, Go 默认会先开一片内存区域,把原来的值拷贝过来,然后再执行 append() 操作。这种情况丝毫不影响原数组。
要复制一个Slice,最好使用Copy函数。
4.Golang Map底层实现
Golang 中 map 的底层实现是一个散列表,因此实现 map 的过程实际上就是实现散表的过程。
在这个散列表中,主要出现的结构体有两个,一个叫hmap(a header for a go map),一个叫bmap(a bucket for a Go map,通常叫其bucket)。
hmap如下所示:
图中有很多字段,但是便于理解 map 的架构,你只需要关心的只有一个,就是标红的字段:buckets 数组。Golang 的 map 中用于存储的结构是 bucket数组。而 bucket(即bmap)的结构是怎样的呢? bucket:
相比于 hmap,bucket 的结构显得简单一些,标橙的字段依然是“核心”,我们使用的 map 中的 key 和 value 就存储在这里。
“高位哈希值”数组记录的是当前 bucket 中 key 相关的”索引”,稍后会详细叙述。还有一个字段是一个指向扩容后的 bucket 的指针,使得 bucket 会形成一个链表结构。
整体的结构应该是这样的:
Golang 把求得的哈希值按照用途一分为二:高位和低位。低位用于寻找当前 key属于 hmap 中的哪个 bucket,而高位用于寻找 bucket 中的哪个 key。
需要特别指出的一点是:map中的key/value值都是存到同一个数组中的。这样做的好处是:在key和value的长度不同的时候,可以消除padding带来的空间浪费。
Map 的扩容:当 Go 的 map 长度增长到大于加载因子所需的 map 长度时,Go 语言就会将产生一个新的 bucket 数组,然后把旧的 bucket 数组移到一个属性字段 oldbucket中。
注意:并不是立刻把旧的数组中的元素转义到新的 bucket 当中,而是,只有当访问到具体的某个 bucket 的时候,会把 bucket 中的数据转移到新的 bucket 中。
5. JSON 标准库对 nil slice 和 空 slice 的处理是一致的吗
首先 JSON 标准库对 nil slice 和 空 slice 的处理是不一致。
通常错误的用法,会报数组越界的错误,因为只是声明了slice,却没有给实例化的对象。
var slice []int
slice[1] = 0
此时slice的值是nil,这种情况可以用于需要返回slice的函数,当函数出现异常的时候,保证函数依然会有nil的返回值。
empty slice 是指slice不为nil,但是slice没有值,slice的底层的空间是空的,此时的定义如下
slice := make([]int,0)
slice := []int{}
当我们查询或者处理一个空的列表的时候,这非常有用,它会告诉我们返回的是一个列表,但是列表内没有任何值。总之,nil slice 和 empty slice是不同的东西,需要我们加以区分的。
6.Golang的内存模型,为什么小对象多了会造成gc压力
通常小对象过多会导致 GC 三色法消耗过多的GPU。优化思路是,减少对象分配。
7.Data Race问题怎么解决?能不能不加锁解决这个问题
同步访问共享数据是处理数据竞争的一种有效的方法。
golang在 1.1 之后引入了竞争检测机制,可以使用 go run -race 或者 go build -race来进行静态检测。其在内部的实现是,开启多个协程执行同一个命令, 并且记录下每个变量的状态。
竞争检测器基于C/C++的ThreadSanitizer 运行时库,该库在Google内部代码基地和Chromium找到许多错误。这个技术在2012年九月集成到Go中,从那时开始,它已经在标准库中检测到42个竞争条件。现在,它已经是我们持续构建过程的一部分,当竞争条件出现时,它会继续捕捉到这些错误。
竞争检测器已经完全集成到Go工具链中,仅仅添加-race标志到命令行就使用了检测器。
$ go test -race mypkg // 测试包
$ go run -race mysrc.go // 编译和运行程序 $ go build -race mycmd
// 构建程序 $ go install -race mypkg // 安装程序
要想解决数据竞争的问题可以使用互斥锁sync.Mutex,解决数据竞争(Data race),也可以使用管道解决,使用管道的效率要比互斥锁高。
8.在 range 迭代 slice 时,你怎么修改值的
在 range 迭代中,得到的值其实是元素的一份值拷贝,更新拷贝并不会更改原来的元素,即是拷贝的地址并不是原有元素的地址。
func main() {data := []int{1, 2, 3}for _, v := range data {v *= 10 // data 中原有元素是不会被修改的}fmt.Println("data: ", data) // data: [1 2 3]
}
如果要修改原有元素的值,应该使用索引直接访问。
func main() {data := []int{1, 2, 3}for i, v := range data {data[i] = v * 10 }fmt.Println("data: ", data) // data: [10 20 30]
}
如果你的集合保存的是指向值的指针,需稍作修改。依旧需要使用索引访问元素,不过可以使用 range 出来的元素直接更新原有值。
func main() {data := []*struct{ num int }{{1}, {2}, {3},}for _, v := range data {v.num *= 10 // 直接使用指针更新}fmt.Println(data[0], data[1], data[2]) // &{10} &{20} &{30}
}
9.nil interface 和 nil interface 的区别
虽然 interface 看起来像指针类型,但它不是。interface 类型的变量只有在类型和值均为 nil 时才为 nil如果你的 interface 变量的值是跟随其他变量变化的,与 nil 比较相等时小心。如果你的函数返回值类型是 interface,更要小心这个坑:
func main() {var data *bytevar in interface{}fmt.Println(data, data == nil) // <nil> truefmt.Println(in, in == nil) // <nil> truein = datafmt.Println(in, in == nil) // <nil> false // data 值为 nil,但 in 值不为 nil
}// 正确示例
func main() {doIt := func(arg int) interface{} {var result *struct{} = nilif arg > 0 {result = &struct{}{}} else {return nil // 明确指明返回 nil}return result}if res := doIt(-1); res != nil {fmt.Println("Good result: ", res)} else {fmt.Println("Bad result: ", res) // Bad result: <nil>}
}
10.select可以用于什么
常用于goroutine的完美退出。
golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作每个case语句里必须是一个IO操作,确切的说,应该是一个面向channel的IO操作。
相关文章:
Go语言面经进阶10问
1.Golang可变参数 函数方法的参数,可以是任意多个,这种我们称之为可以变参数,比如我们常用的fmt.Println()这类函数,可以接收一个可变的参数。可以变参数,可以是任意多个。我们自己也可以定义可以变参数,可…...
大厂真题:【DP】米哈游2023秋招-米小游与魔法少女-奇运
题目描述与示例 题目描述 米小游都快保底了还没抽到希儿,好生气哦!只能打会活动再拿点水晶。 米小游和世界第一可爱的魔法少女 TeRiRi 正在打 BOSS,BOSS 的血量为h,当 BOSS 血量小于等于0时,BOSS 死亡。TeRiRi 有一…...
后端面经学习自测(一)
文章目录 1、MySQL-MVCC2、MySQL-原子性怎么实现3、MySQL-持久性怎么实现隔离性怎么实现 4、操作系统-死锁产生手写死锁死锁排查 5、操作系统-避免死锁死锁的四个必要条件预防死锁 6、操作系统-pageCache是什么零拷贝 7、计算机网络-TCP的可靠性和顺序性怎么实现8、计算机网络-…...
win10、win11安装Ubuntu 22.04
目前为止(2023年10月6日),最新的 Ubuntu 版本是 Ubuntu 22.04。你可以按照以下步骤在 Windows 上使用 WSL 安装 Ubuntu 22.04: 检查系统要求: 确保你的操作系统是 Windows 10 或更高版本,并已安装 Windows …...
golang gin框架1——简单案例以及api版本控制
gin框架 gin是golang的一个后台WEB框架 简单案例 package mainimport ("github.com/gin-gonic/gin""net/http" )func main() {r : gin.Default()r.GET("/ping", func(c *gin.Context) {//以json形式输出,还可以xml protobufc.JSON…...
Redisson—分布式对象
每个Redisson对象实例都会有一个与之对应的Redis数据实例,可以通过调用getName方法来取得Redis数据实例的名称(key)。 RMap map redisson.getMap("mymap"); map.getName(); // mymap 所有与Redis key相关的操作都归纳在RKeys这…...
alsa pcm接口之在unix环境的传输方法
在unix环境,数据片段响应被接受通过standard I/O call或事件等待路径(poll或select功能),为完成列表,异步通知响应该被列举出来.ALSA实现那些方法被描述在ALSA transfers部分. 标准I/O传输(Standadrd I/O transfers) 这个标准I/O传输常常使用read和write C语言函数集,对于那些函…...
小谈设计模式(20)—组合模式
小谈设计模式(20)—组合模式 专栏介绍专栏地址专栏介绍 组合模式对象类型叶节点组合节点 核心思想应用场景123 结构图结构图分析 Java语言实现首先,我们需要定义一个抽象的组件类 Component,它包含了组合节点和叶节点的公共操作&a…...
sheng的学习笔记-【中文】【吴恩达课后测验】Course 1 - 神经网络和深度学习 - 第三周测验
课程1_第3周_测验题 目录:目录 第一题 1.以下哪一项是正确的? A. 【 】 a [ 2 ] ( 12 ) a^{[2](12)} a[2](12)是第12层,第2个训练数据的激活向量。 B. 【 】X是一个矩阵,其中每个列都是一个训练示例。 C. 【 】 a 4 […...
一文详解动态链表和静态链表的区别
1、引言 本文主要是对动态链表和静态链表的区别进行原理上的讲解分析,先通过对顺序表和动态链表概念和特点的原理性介绍,进而引申出静态链表的作用,以及其概念。通过这些原理性的概述,最后总结归纳出动态链表和静态链表的区别。本…...
[C国演义] 第十三章
第十三章 三数之和四数之和 三数之和 力扣链接 根据题目要求: 返回的数对应的下标各不相同三个数之和等于0不可包含重复的三元组 – – 即顺序是不做要求的 如: [-1 0 1] 和 [0, 1, -1] 是同一个三元组输出答案顺序不做要求 暴力解法: 排序 3个for循环 去重 — — N^3, …...
<二>Qt斗地主游戏开发:过场动画的实现
1. 过场动画效果 2. 思路分析 过场动画较为简单,只有一个进度条在进行滚动,因此实现起来不需要动画相关处理,仅需要图片和定时器设定,让进度条动起来即可。我们可以创建一个对话框,设定背景图片以及对话框透明无边框&a…...
链式法则(Chain Rule)
定义 链式法则(Chain Rule)是概率论和统计学中的一个基本原理,用于计算联合概率分布或条件概率分布的乘积。它可以用于分解一个复杂的概率分布为多个较简单的条件概率分布的乘积,从而简化概率分析问题。 链式法则有两种常见的形…...
AUTOSAR COM模块框架梳理
框架: COM的功能主要就是两个: 把IPDU内的signal提取出来提供给SWC使用,把SWC发送的signal拷贝到IPDU buffer内 所以,COM的关键字是 signal, signal group, IPDU, IPDU group Signal group 是为了保证 Complex Data Types 的数…...
详细介绍区块链之挖矿
对不起,大家,这篇文章对作者来说实在是太有意义和含金量了,作者想把它设置为关注博主才能见全文,请大家理解!如果觉得还是看不懂,抱歉耽误大家的时间,就请取消关注!!&…...
华为OD机试真题-路灯照明问题(Java/C++/Go/Python)
【华为OD机试真题】路灯照明问题(Java/C++/Go/Python) 题目描述 在一条笔直的公路上安装了N个路灯,从位置0开始安装,路灯之间间距固定为100米。 每个路灯都有自己的照明半径,请计算第一个路灯和最后一个路灯之间,无法照明的区间的长度和。 输入描述 第一行为一个数N…...
嵌入式技术面试基本规则
潜规则1:面试的本质不是考试,而是告诉面试官你会做什么 经验不够的小伙伴特别容易犯的一个错误,不清楚面试官到底想问什么,其实整个面试中面试官并没有想难倒你的意思,只是想通过提问的方式来知道你会什么。 比如stm…...
osg实现自定义插件读取自定义格式的模型文件到场景
目录 1. 前言 2. 预备知识 3. 工具、原料 4. 代码实现 1. 前言 osg提供了很多插件来读取模型文件到场景中,这些插件支持大约70种格式类型的文件,但现实中的文件是各式各样,osg不可能囊括所有类型文件,当osg不支持某种类型格式…...
redis进阶
redis.conf 启动的时候就通过配置文件来启动的! # 这个不是配置的,就是在这儿说明一下 # 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写) # # 1k > 1000 bytes # 1kb > 102…...
(一)正点原子STM32MP135移植——准备
一、简述 使用板卡:正点原子的ATK-DLMP135 V1.2 从i.mx6ull学习完过来,想继续学习一下移植uboot和内核的,但是原子官方没有MP135的移植教程,STM32MP157的移植教程用的又是老版本的代码,ST官方更新后的代码不兼容老版本…...
Kotlin的关键字 lateinit 和 lazy
序、完善一下曾经的草稿。 Kotlin通常要求我们在定义属性后立即对起进行初始化,当我们不知道理想的初始值时,这样做似乎很奇怪,尤其是在生命周期驱动android属性的情况下。 lateinit 简介 lateinit,Kotlin提供的一个可以延迟初…...
阿里云服务器ECS详细介绍_云主机_服务器托管_弹性计算
阿里云服务器ECS英文全程Elastic Compute Service,云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务,阿里云提供多种云服务器ECS实例规格,如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等,阿里云服务器网分享阿…...
12、建立健全人员培训体系
9、大小屏分离与精细化审核 10、质量审核的设立与合并 11、视频分类建议 内容仓为公司其他部门输送了许多人才,既包括有潜力的主管,也有表现突出或者具备某些特殊能力的员工,从内容仓走出的同事,有些已经成为公司重要业务某个方…...
代码随想录算法训练营第五十九天 | 647. 回文子串 516.最长回文子序列
1. 回文子串 647. 回文子串 - 力扣(LeetCode) 一个子串左右两个元素相等,并且中间对称,才是回文子串 即 ij 时,[i1: j-1]对称 dp[i][j]: [i:j] 是否是回文字串 当 子串长度大于2 由 dp[i1][j-1] 推出…...
React Redux
redux是什么 Redux是一个模式和库,用于管理和更新应用程序状态,使用称为“action”的事件。它是需要在整个应用程序中使用的状态的集中存储,规则确保状态只能以可预测的方式更新。 Redux主要有三个功能: 获取当前状态更新状态监…...
StreamingLLM - 处理无限长度的输入
文章目录 关于 StreamingLLM使用关于 StreamingLLM Efficient Streaming Language Models with Attention Sinks GitHub : https://github.com/mit-han-lab/streaming-llm论文:https://arxiv.org/abs/2309.17453在流媒体应用程序(如多轮对话)中 部署大型语言模型(LLM)是迫…...
[Linux 命令] nm 详解
1. nm 命令: 显示关于指定 File 中符号的信息,文件可以是对象文件、可执行文件或对象文件库。如果文件没有包含符号信息,nm 命令报告该情况,但不把它解释为出错条件。 nm 命令缺省情况下报告十进制符号表示法下的数字值。 2. 命…...
好文学作品的鉴赏标准
好文学作品的鉴赏标准 2023年诺贝尔文学奖颁给了挪威剧作家约恩福瑟。由于之前的博彩公司给中国作家残雪开出了最高的赔率,以及诺贝尔官方推特在揭晓奖项前发布了一张泰戈尔99年前访华的老照片,残雪的获奖氛围在国内各类媒体的渲染下被拉至极高。当奖项…...
智慧公厕:将科技融入日常生活的创新之举
智慧公厕是当今社会中一项备受关注的创新项目。通过将科技融入公厕设计和管理中,这些公厕不仅能够提供更便利、更卫生的使用体验,还能够极大地提升城市形象和居民生活质量。本文将以智慧公厕领先厂家广州中期科技有限公司,大量的精品案例项目…...
ROS(0)命令及学习资源汇总
ROS安装命令 参考:Ubuntu20.04.4安装ROS Noetic详细教程 - 知乎 安装C和Python3 sudo apt-get install g sudo apt-get install python3 ROS运行小海龟仿真器 roscore确定ROS是否运行成功rosrun turtlesim turtlesim_node运行小海龟仿真器rosrun turtlesim turtle_…...
近三天发生的国际新闻/seo广告
2019—2020学年度第一学期,在各级领导的关心支持下,全校师生紧紧围绕培养“人人喜欢的人、人人需要的人、人人离不开的人”的目标,高举“严管管严、紧跟跟紧”大旗,励精图治,强化管理,各项工作都取得了显著…...
长春网站建设那家好/郑州seo优化外包顾问阿亮
我为您找到了这些非常酷的jQuery技巧。 它们中的一些提供了非常有趣且使用有趣的怪异效果。 1.图像淡入淡出过渡 将一个图像淡化为另一个图像的基本技巧。 资源: http://jqueryfordesigners.com/image-cross-fade-transition/ 2.背景图像动画 这提供了易于使用…...
布吉做棋牌网站建设/推广引流工具
概述 权限系统提的最多的就是 RBAC(基于角色的访问控制)。 所谓角色,其实就是权限的集合,某个角色就是某几个权限的结合。其目的是为了简化授权和鉴权的过程。 基于角色的权限控制用在简单的权限环境下没有问题,如果在…...
建设简单企业网站/流量平台有哪些
转自:https://www.jianshu.com/p/fef2d215b91d 1. argparse介绍 是python的一个命令行解析包,非常编写可读性非常好的程序 2. 基本用法 prog.py是我在linux下测试argparse的文件,放在/tmp目录下,其内容如下: #!/usr/bi…...
wordpress主题页脚/网址大全
注意:本方法会下载整个项目,但是,最后出现在本地项目文件下里只有需要的那个文件夹存在。类似先下载,再过滤。 有时候因为需要我们只想gitclone 下仓库的单个或多个文件夹,而不是全部的仓库内容,这样就很省…...
网站项目策划方案/深圳网络推广服务是什么
2019年10月底,运营商正式启动5G商用仪式,并纷纷制定了规模可观的5G建设投资计划。中国信息通信研究院副院长、中国泰尔实验室执行主任何桂立在APC协会和亨通集团联合主办的2019年全球光纤光缆大会上发表《5G应用促进光纤协同发展》演讲报告,他…...