golang常见面试题
1. go语言有哪些优点、特性?
语法简便,容易上手。
支持高并发,go有独特的协程概念,一般语言最小的执行单位是线程,go语言支持多开协程,协程是用户态线程,协程的占用内存更少,协程只独有自己的栈等一些资源。其他都是共享线程的。调度时可以极大减少上下文切换。
2. go的包管理
golang在1.11版本之前用的是GOPATH,项目代码要放在GOPATH/src目录下才可运行。但是GOPATH存在弊端,没有版本控制概念,go get的外部库,自己都不知道下载的什么版本,再多人协作开发时无法确定大家的外部库版本是否一致,会出大问题。
golang1.11后推荐使用go mod 管理,go env 下设置 GO111MODULE = on 打开。支持依赖升降级。
3. make和new 的一些区别
new 可以初始化声明所有类型,返回的是一个指针类型。对应的是该类型的空值
make 只能用来初始化 map slice channel 的,返回的就是这个类型。对应的是该类型的零值
new的用法不常见,一般使用 var 或 :=
4. channel 是可以被 close 的,之后还可以读写吗?
不管是有无缓冲channel。关闭后都可以读,读的是channel 传输类型的 零值。
不管是有无缓冲channel,关闭后都不可以写,写会panic
5. channel有什么用
channel 用来做协程之间的通信。go语言提倡不要用共享内存来通信,要用通信的方式来共享内存。channel就是利用通信的方式实现对资源的访问。
无缓冲channel可以用来做协程间的同步
有缓冲channel可以用来做消息队列
6. channel的底层结构?接收、发送消息的过程?
channel底层是一个结构体,里面包含一个环形缓冲区,还有接收等待队列和发送等待队列。分别存放等待写消息的协程队列和读消息的协程队列,还有一个互斥锁,用来保证channel的线程安全,防止多个协程并发读写。
当一个协程向channel写数据,如果是无缓冲通道,会将其加入到消息等待发送队列中,等待一个协程向channel读数据
读数据时,会先看缓冲区,如果没有再唤醒消息等待发送队列的第一个协程拿到信息,如果没有加入到消息等待接收队列,等待一个协程向channel写数据
7. channel 并发安全吗?
channel并发安全,底层结构体中有一个互斥锁,在并发环境下可以自动实现加锁解锁操作。
8. 怎么样输出一个有序的map
用slice存放map的key值,对slice进行排序,然后按照slice顺序查找map key value
用golang的数据结构 list来实现,list是一个链表。map[key]value value存放链表节点,写入map的时候同时按照顺序写入list中,顺序遍历时,只需要遍历链表即可。可以达到有序效果。
9. map在传参时的类型
golang传参都是值传递,只是对于map chan 等类型,他们在进行值拷贝的时候,调用的makechan 和 makemap 方法返回的都是指针类型的变量。导致操作的其实是同一个内存。
10. 可以直接对map取地址吗?
对map可以取址,但是对于map的key value不能取址,map不支持这种操作,当某种条件达到后,map会做增量扩容或者等量扩容操作。这时候每个key 的地址都可能发生变化。因此获取map key value地址的操作是无意义的。
11. map底层结构
map底层是一个结构体,hmap,hmap中包含 元素的个数,桶的个数,以及指向桶数组的指针,每一个桶是一个bucket,bucket在go中用的是 bmap结构体,每个bucket可以存放 8个键值对,哈希值低八位相同的键存入bucket时会将高八位存储在tophash数组里。data 区域存放的key-value数据是按照 keykeykey valuevaluevalue存放的,overflow指针指向下一个bucket桶,通过链表将所有冲突的键连接起来。
12. 哪些数据类型不能作为map里面的key,哪些可以,有没有什么评判标准?
无法比较的数据类型都不能作为map里面的key。
基本数据类型都可作为key,指针也可以,因为指针比较的是地址。 数组也可以,结构体也可以
不可比较 map slice function
13. map是并发安全的吗?怎么实现并发安全?
map不是并发安全的,底层结构体没有用互斥锁进行加锁解锁操作。
如何实现并发安全,1.map+读写锁 (推荐) 2.用sync.Map
14. sync.Map如何解决并发问题?
sync.Map底层结构体中嵌入了一个互斥锁。。。。
15. gmp模型(局部饥饿、全局饥饿、全局缓存队列等)
最开始的时候,大多用线程池,开一定量的线程,当有工作任务到来时,会拿出一个线程处理,但当因为发生系统调用而阻塞时,线程池中可工作的线程就少了,线程池的性能就降低了。于是有了GMP模型。
G是协程,用户态线程
本地队列:每个P都有本地队列,本地队列中存放的是G
全局队列:当本地队列都满了,新来的G会优先加入本地队列中,本地队列满了会把本地队列的一半加入到全局队列
M是工作线程,用来处理协程的
P是处理器,默认数量是内核数,M通过获取P来处理P中的G
15. go有了协程之后,那它的线程是怎么调度的?(GMP模型)M最多多少个?
有调度策略:线程正常情况下会和P绑定,处理P中的本地队列G,但当处理G时,由于系统调用导致阻塞时,会触发hand off,M会和 P 解绑,把P转移给其他的空闲M,如果没有就创建一个新的M处理。如果M将P中的队列G处理完了,就会从其他P的本地队列中偷取一半协程来运行,如果其他都没有,就会从全局队列中选择一批来处理。
M最多10000个,在初始化运行时会设置最大值。但因为M需要获取到P才能处理G,P的数量是很有限的,所以M不会很多。
16. 线程数量和什么有关系?线程数量是无限大的吗?
线程数量和程序运行时,设置的最大M有关,默认是10000,并且跟P有关系,因为M必须要拿到P才能处理G。而且如果线程处理的阻塞的G完成后,可能会被销毁。不能无限大
16. slice深度拷贝
copy方法时,或者append触发扩容机制时都是深度拷贝。拷贝的是数据本身,新创建的对象和源对象不共享内存,会另开辟一个新的内存地址,值修改时不会影响源对象值。
17. slice和数组有什么区别?
slice 结构体中包含了 一个指向底层数组的指针还有slice的长度及容量
数组无法扩容,切片可以动态追加
数组声明时需要指定长度,切片不需要
数组是值类型的,切片是引用类型的
18. slice如何扩容?
1.18版本之前,当切片容量1024之前,每次扩容都是原来数组的二倍,当切片容量到1024之后,每次扩容都是原数组1.25倍
1.18版本,觉得扩容比例一下从2变成1.25有些不平滑,于是调整扩容机制,在容量小于256时,是2倍扩容,当容量大于256时,增加 (原来容量+3*256)/4。逐渐接近1.25倍,更平滑
19. interface{}怎么用
interface{}可以用来实现多态和符合设计模式的原则 依赖倒转 面向接口编程。 写一个接口,里面有要实现的方法,定义一个结构体,实现接口中的方法,然后初始化时,声明一个接口对象并指向具体的结构体,这样实现了面向接口编程,解耦。
也可以用来做强制类型转换,断言。interface.(type)
20. 说一下go的继承
go中的继承是通过结构体嵌套实现的,子结构体嵌套父结构体。初始化子结构体后,就可以用父结构体的方法。
21. go中哪些变量是不能比较的
map slice function
22. golang强类型,弱类型?
golang是强类型语言,不会隐式的进行数据类型的转换。在速度上可能略逊弱类型语言,但是严谨性又避免了不必要的错误
23. golang并发控制?
可以用 Sync.WaitGroup实现 WaitGroup有三个方法,Add,Done,Wait。用来控制计数器数量。
可以用channel实现,goroutine之间通过channel通信,如果多个goroutine都写入channel,这时候通过缓冲区就可以实现并发控制,当缓冲区满时,后面的goroutine的写操作会被阻塞。
24. 一个go-routine最小占多大内存空间?
2kb
25. context类型有哪些?Context的作用是什么?context如何实现cancel的?
context主要用来在协程间传递关闭信号、信息的。可以控制多级协程
空context、cancelCtx、valueCtx、timerCtx。cancelCtx可以用来做协程的断开操作。
27. 正常模式和饥饿模式?
针对于互斥锁的,Mutex。正常模式下请求锁的协程要按照先入先出顺序排队,以此被唤醒,唤醒后还要与新请求锁的协程进行竞争,因为新请求的协程有优势,他们正在CPU上运行或者数量比较多。新唤醒的协程很难获取到锁,于是又会加到队列头部,如果一个等待的协程超过1ms仍未获取到锁,就会进入到饥饿模式。
饥饿模式下,互斥锁所有权会直接从解锁的协程转移到队首的协程,并且新到达的协程不会尝试获取锁而是加到队列尾部。如果一个等待协程获取到锁并且满足下面两个条件只一,就会回到正常模式。是队列的最后一个协程,等待时间小于1ms。
正常模式有更好的性能,饥饿模式可以避免尾部延迟这种情况
28. 用Go实现一个死锁
死锁存在四个条件,互斥,占有且等待,循环等待,不可强占用
func main() {ch1 := make(chan int)ch2 := make(chan int)var x sync.WaitGroupx.Add(2)go func() {ch2 <- 1fmt.Println(<-ch1)x.Done()}()go func() {fmt.Println(<-ch2)ch1 <- 1x.Done()}()x.Wait()
}
29. gc的了解
gc是垃圾回收机制,为了对堆栈上使用完的对象及时回收。防止内存溢出。最初1.3版本之前使用的是标记清除法,GC时会暂停程序进行标记清楚操作。STW时间很长。为了优化STW,1.3版本后缩短了一些STW时间,回收对象的操作放在STW时间之外。1.5版本时为了降低STW的时间,使用三色标记法+插入/删除屏障实现。三色标记法是在GC开始时,从根节点开始遍历所有可达对象,第一次遍历到的对象置灰,第二次遍历到的对象置黑。当没有灰色对象是开始回收对象。但是这样存在问题,当新创建了一个白色对象时,被一个黑色对象引用了,此时会造成刚创建的对象也被回收。还有当删除一个对象时,但是后面的对象还想要使用,但是断掉后后面的对象也会被回收。针对这两种情况提出了两个设计原则,强三色不变式和弱三色不变式,强三色强调黑色对象不能引用白色对象。弱三色不变式强调当黑色对象引用白色对象是,要保证还有一个灰色对象引用白色对象。针对这两个原则,产出了插入屏障和删除屏障,插入屏障实现的是强三色不变式,当黑色对象引用白色对象时,会将白色对象变为灰色对象。删除屏障实现的是弱三色不变式,当删除灰色后面的白色对象,会把删除的白色对象置灰。当扫描完没有灰色对象后,会将栈对象置白,启用STW,从新扫描一遍栈上的可达节点,最终删掉白色对象。插入屏障仍然需要re-scan栈上的节点。删除屏障,删除效率低,这次要删除的对象要等下次才能删掉。于是1.8版本后,采用三色标记法+混合写屏障。混合写屏障结合了插入和删除屏障的优点,栈上的对象不启用GC,扫描时会将所有栈上对象和新建对象置黑,针对堆上对象,所有创建和删除的对象都置灰。体现的是变形的弱三色不变式。1.8版本极大减少了STW时间,但并不是完全没有,因为在GC三色标记法之前还要STW,开启辅助GC和写屏障,统计根对象的任务数量等。
30. 什么时候会触发 golang GC 呢?
手动触发:调用runtime.GC来手动触发
定期触发:最长两分钟触发一次GC
内存达到一定值:每当内存扩大一倍时启用GC
31. 内存泄漏
创建的资源没有正常释放造成内存一直占用。也无法被GC回收。内存泄漏一般是程序员申请资源后没有手动去释放资源,关闭通道,解锁等。
通过pprof工具排查
32. go里面声明一个变量,它是放在栈上还是堆上?
内存逃逸,局部变量从栈上逃逸到堆上发生了内存逃逸。
对于指针类型,因为分配内存时不知道是否存在外部引用,于是就将内存分配在堆中,防止函数结束后局部变量被回收。
如果数据量太大,栈放不下就会逃逸到堆中
interface类型上调用方法,编译时不知道是如何实现的,就会放到堆中。
33. 子goroutine的panic会不会被父g捕获
panic只能捕获本协程内部的错误,无法捕获子协程的错误
34. defer的先后顺序
defer满足栈的结构,先入后出。
35. defer什么情况下可以修改函数的返回值?
defer和return知识,return分为两步操作,第一步先将返回值赋给return,在准备返回之前要执行defer函数,执行完后才将结果返回。 如果定义了具名返回值,并且在defer时对这个变量进行了处理。那return 这个变量时就会修改。
36. golang 如何做超时控制?
1.timeAfter 这个函数会返回一个通道,并且过一段时间后会自动向通道发送一个数据。
2.context 的 withTimeout 和 withDeadline 方法,当到规定时间或超过某一时间后,会调用cancel方法来关闭channel。可以做超时控制
37. select 一般使用在什么场景
select一般与通道连用,用来监听多个通道的状态。
可以在多个通道中选择一个可用的操作来执行,如果没有一个通道准备就绪,select会执行defaule语句或者继续等待。
38.go程序运行顺序?
从main包开始执行,首先会导入引用的包,如果这个包里有init函数,会先执行这个包的init函数。
如果在main包定义了init函数,Go运行会在包导入后,全局变量初始化之前调用init函数。
调用之后会进行全局变量初始化操作,最终进入到main函数,是整个程序入口点。main函数执行后,程序会按照调用函数顺序依次执行其他函数。
相关文章:
golang常见面试题
1. go语言有哪些优点、特性? 语法简便,容易上手。 支持高并发,go有独特的协程概念,一般语言最小的执行单位是线程,go语言支持多开协程,协程是用户态线程,协程的占用内存更少,协程只…...
探索Python编程世界:从入门到精通
一.Python 从入门到精通 随着计算机科学的发展,编程已经成为了一种必备的技能。而 Python 作为一种简单易学、功能强大的编程语言,越来越受到人们的喜爱。本文将为初学者介绍 Python 编程的基础知识,帮助他们踏入 Python 编程的大门…...
Spark Shuffle Tracking 原理分析
Shuffle Tracking Shuffle Tracking 是 Spark 在没有 ESS(External Shuffle Service)情况,并且开启 Dynamic Allocation 的重要功能。如在 K8S 上运行 spark 没有 ESS。本文档所有的前提都是基于以上条件的。 如果开启了 ESS,那么 Executor 计算完后&a…...
Docker 干货系列 (持续更新)
dive 直接用本地镜像名称来启动,不需要走 hub dive.sh IMAGE_NAME"${1}" TMP_FILE/tmp/dive-tmp-image.tar docker save "$IMAGE_NAME" > $TMP_FILE && dive $TMP_FILE --sourcedocker-archive && rm $TMP_FILE示例&#…...
一.jwt token 前后端的逻辑
摘要 jwt token 前后端的交互逻辑,此部分只描述了一些交互逻辑,不涉及到真实应用的开发。 token的格式 tokenheader‘.’payload‘.’sign 第一次登陆的时候 判断http请求头中是否包含Authorization不包含则提示用户未登录当用户登录后,…...
day12_oop_抽象和接口
今日内容 零、 复习昨日 一、作业 二、抽象 三、接口 零、 复习昨日 final的作用 修饰类,类不能被继承修饰方法,方法不能重写[重点]修饰变量/属性,变成常量,不能更改 static修饰方法的特点 static修饰的方法,可以通过类名调用 static修饰的属性特点 在内存只有一份,被该类的所有…...
linux 将 api_key设置环境变量里
vi ~/.bashrc在最后添加api_key的环境变量 export GEMINI_API_KEYAIza**********WvpX7FwbdM刷新配置 source ~/.bashrc使用python 读取环境变量 import os gemini_api_key os.getenv(GEMINI_API_KEY) print(gemini_api_key)...
java八股文复习-----2024/03/03
1.接口和抽象类的区别 相似点: (1)接口和抽象类都不能被实例化 (2)实现接口或继承抽象类的普通子类都必须实现这些抽象方法 不同点: (1)抽象类可以包含普通方法和代码块&#x…...
UE4 Niagara 关卡3.4官方案例解析
Texture sampling is only supported on the GPU at the moment.(纹理采样目前仅在GPU上受支持) 效果:textures can be referenced within GPU particle systems。this demo maps a texture to a grid of particles(纹理可以在GPU粒子系统中被引用这个演…...
C# Onnx segment-anything 分割万物 一键抠图
目录 介绍 效果 模型信息 sam_vit_b_decoder.onnx sam_vit_b_encoder.onnx 项目 代码 下载 C# Onnx segment-anything 分割万物 一键抠图 介绍 github地址:GitHub - facebookresearch/segment-anything: The repository provides code for running infere…...
Linux配置网卡功能
提示:工具下载链接在文章最后 目录 一.network功能介绍二.配置network功能2.1 network_ip配置检查 2.2 network_br配置2.2.1 配置的网桥原先不存在检查2.2.2 配置的网桥已存在-修改网桥IP检查2.2.3 配置的网桥已存在-只添加网卡到网桥里检查 2.3 network_bond配置检查 2.4 netw…...
【C++】十大排序算法之 归并排序 快速排序
本次介绍内容参考自:十大经典排序算法(C实现) - fengMisaka - 博客园 (cnblogs.com) 排序算法是《数据结构与算法》中最基本的算法之一。 十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序…...
x-pack的破解方式和免费jar包!!可直接用!!
原理介绍 我们平时为es安装x-pack组件,用elasticsearch-plugin install x-pack ,安装成功后。 1.cd $es目录/pulgins/x-pack 里面有一个x-pack-5.6.2.jar ,将jar包反编译,然后将里面的licence的程序改下。再编译成jar包。 2…...
最新版本,Midjourney保姆级教程!
一、认识Midjourney 1.1、MidJourney是什么? 随着ChatGPT的横空出世,人类正式迈入AI元年,其中MidJourney便是AI绘图工具,它能根据用户输入的文字描述(提示词)生成绘画作品,不管是灵动的人物&a…...
Android中的几种定位方式调用详解
目前,移动端大致通过三种方式来进行设备定位:GPS、基站、wifi。本文就详细的讲解一下这几种定位方式和实现方法。 前言 android中我们一般使用LocationManager来获取位置信息,这里面有四中provider: public static final Strin…...
【软件测试】接口调不通排查分析+常遇面试题总结
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、接口调不通&am…...
c++基础学习第三天(指针,结构体)
c基础学习第三天(指针,结构体) 文章目录 1、指针1.1、指针的基本概念1.2、指针变量的定义和使用1.3、 指针所占内存空间1.4、空指针和野指针1.5、 const修饰指针1.5.1、const修饰指针-常量指针1.5.2、const修饰常量-指针常量1.5.3、const即修…...
【数仓】zookeeper软件安装及集群配置
相关文章 【数仓】基本概念、知识普及、核心技术【数仓】数据分层概念以及相关逻辑【数仓】Hadoop软件安装及使用(集群配置)【数仓】Hadoop集群配置常用参数说明 一、环境准备 准备3台虚拟机 Hadoop131:192.168.56.131Hadoop132ÿ…...
Qt 实现橡皮擦拭显示图片
1.简介 在一些游戏中看见类似解密破案的效果,使用手触摸去擦拭图片上的灰尘,然后显示最终的图片,所以也想试试Qt实现的效果。大家有自己想做的效果,都可以尝试。 以下是效果展示图。 可以控制橡皮擦的大小,进行擦拭…...
Vue3+Element-Plus中ELMessage样式丢失处理
Vu3Element-Plus项目中,element-plus使用按需引入有时会出现样式失效和在vscode中使用会报错[找不到名称“ElMessage”。ts(2304)]错误 ELMessage弹框样式丢失处理方法 使用按需引入就不能手动再引入 import { ElMessage } from "element-plus";ElMessage.success…...
C#图像金字塔:3个关键技巧,让图像识别从“卡顿“变“闪电“!
🔥关注墨瑾轩,带你探索编程的奥秘!🚀 🔥超萌技术攻略,轻松晋级编程高手🚀 🔥技术宝库已备好,就等你来挖掘🚀 🔥订阅墨瑾轩,智趣学习不…...
otp:Go语言一次性密码库入门指南 - 5分钟快速上手双因素认证
otp:Go语言一次性密码库入门指南 - 5分钟快速上手双因素认证 【免费下载链接】otp TOTP library for Go 项目地址: https://gitcode.com/gh_mirrors/otp/otp 在当今网络安全威胁日益严峻的环境下,一次性密码(OTP)已成为保护…...
大一C语言期末必考|程序结构+流程控制(详解+例题+易错点)一
🔥个人主页:北极的代码(欢迎来访) 🎬作者简介:java后端学习者 ❄️个人专栏:苍穹外卖日记,SSM框架深入,JavaWeb ✨命运的结局尽可永在,不屈的挑战却不可须臾或…...
OpenClaw模型微调:优化千问3.5-35B-A3B-FP8在特定任务的表现
OpenClaw模型微调:优化千问3.5-35B-A3B-FP8在特定任务的表现 1. 为什么需要微调千问模型? 当我第一次尝试用OpenClaw自动化处理财务报告时,发现千问3.5-35B-A3B-FP8虽然能理解基本指令,但在处理表格数据提取和金额计算时频繁出错…...
杰理之开mic关mic复位问题处理【篇】
开PC模式...
论文降重降AI难?自带双功能黑科技的实用工具盘点
论文降重和消除AI生成痕迹是很多创作者面临的双重难题,选对工具能节省大量时间精力。下面整理了几款自带降AIGC率功能的实用工具,覆盖中文、英文、应急、轻量优化等不同使用场景,附实际使用效果与核心特点,帮你快速找到适配需求的…...
基于YOLOv10深度学习的植物叶片病害识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目+模型)
一、项目介绍 本项目基于先进的YOLOv10目标检测算法,开发了一套智能植物叶片病害识别检测系统。系统能够实现对38种不同植物叶片健康状况的实时检测与分类,包括多种常见病害及健康叶片。通过图形用户界面,用户可以方便地上传图片、视频或调用…...
Python脚本:一键将图片按顺序合成PDF
📌 前言在日常工作和学习中,我们经常需要将多张图片(如扫描件、截图、照片)合并成一个PDF文件。虽然有很多现成的工具可以实现,但用Python自己写一个脚本不仅灵活,还能避免上传到第三方网站带来的隐私风险。…...
【3步修复】华硕游戏本色彩配置文件丢失解决方案
【3步修复】华硕游戏本色彩配置文件丢失解决方案 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar, and other mo…...
做对这三步,拥有一个聪明的智能问数与分析Agent
这两年,智能问数与分析,几乎已经成了 ToB Agent 里最容易出圈的“爆款场景”。原因不难理解。相比很多还停留在演示层、流程层的 AI 应用,智能问数更接近企业管理者最直接的需求:我有问题,系统能不能立刻给我答案&…...
