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…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...