Golang相关面试题

Golang

(63条消息) go/golang面试中的高频八股文问题_光哥2020的博客-CSDN博客_golang八股文

1.go的profile工具?

profile就是定时采样,收集cpu,内存等信息,进而给出性能优化指导。golang目前提供了3中profile,分别是 cpu profile, memery profile, blocking profile。

2.能否同时建立大量协程?可以建立,但是后果严重。

考虑到后果:回答不能 ,会造成内存挤压。即go进程分配资源给协程,当这些协程回收之后,go进程仍然占有着协程的资源。系统会为go进程预留空间以免它会再次分配协程。这块实际未使用的内存不会回收。

3.拷贝大切片一定比拷贝小切片代价大吗?
type SliceHeader struct {
 Data uintptr
 Len  int
 Cap  int
}

切片中的第一个字段是 指向切片底层数组的指针,这是切片的存储空间,第二个字段是切片的长度,第三个字段是容量。将一个切片变量分配给另一个变量只会复制三个机器字,大切片跟小切片的区别无非就是 LenCap的值比小切片的这两个值大一些,如果发生拷贝,本质上就是拷贝上面的三个字段。

小于1024 变为原来的两倍 大于1024 变为原来的1.25倍

4.切片的深浅拷贝

深浅拷贝都是进行复制,区别在于复制出来的新对象与原来的对象在它们发生改变时,是否会相互影响,本质区别就是复制出来的对象与原对象是否会指向同一个地址。在Go语言,切片拷贝有三种方式:

  • 使用=操作符拷贝切片,这种就是浅拷贝
  • 使用[:]下标的方式复制切片,这种也是浅拷贝
  • 使用Go语言的内置函数copy()进行切片拷贝,这种就是深拷贝
5.设计模式

快来,这里有23种设计模式的Go语言实现 - 知乎 (zhihu.com)

6.go调试工具

delve

pprof有两个包:

net/http/pprof 和 runtime/pprof

其实net/http/pprof中只是使用runtime/pprof包来进行封装了一下,并在http端口上暴露出来

7.golang性能分析

[golang]7种 Go 程序性能分析方法 - landv - 博客园 (cnblogs.com)

**方法1:**time。包含:shell内置的time、GNU实现的time、*BSD、macOS 的 time、go tool 中的 -toolexec 参数。

**方法2:**GODUBUG

**方法3:**pprof

pprof 源自 Google Performance Tools 工具集。Go runtime 中内置了 pprof 的性能分析功能。这包含了两部分:

方法4:/debug/pprof

方法5: pref

**方法6:**火焰图 Flame Graph

pprof trans

8.golang map底层原理 什么时候进行扩容? 什么时候进行rehash?

map 的实现原理 | Go 程序员面试笔试宝典 (golang.design)

有两种扩容方式:

1.增量扩容

触发 map 扩容的时机:在向 map 插入新 key 的时候,会进行条件检测,符合下面这 2 个条件,就会触发扩容:

1.负载因子超过阈值,源码里定义的阈值是 6.5负载因子: loadFactor := count / (2^B) count 就是 map 的元素个数,2^B 表示 bucket 数量。

2.overflow 的 bucket (溢出桶)数量过多,这有两种情况:(1)当 B 大于15时,也就是 bucket 总数大于 2^15 时,如果overflow的bucket数量大于215,就触发扩容。(2)当B小于15时,如果overflow的bucket数量大于2B 也会触发扩容。

如何扩容:由于 map 扩容需要将原有的 key/value 重新搬迁到新的内存地址,如果有大量的 key/value 需要搬迁,在搬迁过程中map会阻塞,非常影响性能。因此 Go map 的扩容采取了一种称为 “渐进式” 的方式,原有的 key 并不会一次性搬迁完毕,每次最多只会搬迁 2 个bucket。

首先分配新的buckets,并且将老的buckets挂到新的map的oldbucket字段上。在插入或修改、删除 key 的时候,都会尝试进行搬迁 buckets 的工作。

2.等量扩容 也要创建新的桶 不是原地扩容

此时桶内元素分布非常稀疏,重新做一遍类似增量扩容的搬迁动作,将稀疏的键值对重新排列一次,让桶利用率更高,保证更快地存取。

如果在搬迁的时候进行查询,首先查询新的map里面有没有,如果没有就去oldbucket中查找。如果没有就是没有。

9.malloc分配的内存是物理内存还是虚拟内存?

分配虚拟内存,当要访问该数据的时候才分配物理内存。

10.go有哪些优点?

出生名门,来自谷歌公司。

语法简单。

相较于 Java 和 C++呆滞的编译速度,Go 的快速编译时间是一个主要的效率优势。Go拥有接近C的运行效率。

Go语言支持当前所有的编程范式,包括过程式编程、面向对象编程、面向接口编程、函数式编程。

强大的标准库。

部署方便:二进制文件,Copy部署

创新的地方:有Goroutine 和 Channel,并发简单。并且支持高并发。

很稳定:有很强大的编译检查、严格的编码规范和完整的软件生命周期工具。go tool、gofmt、go test等。

11.牛客网上的代码上传到服务器,服务器如何判定?

首先服务器接收到go文件之后,与服务器本地测试文件结合,在本地测试文件里面调用一个test函数,调用了go文件里的函数,然后执行go run,得出来的结果用 assert + 布尔表达式判定。

12.数组和切片的区别?

先说数据结构

切片是指针类型,数组是值类型。

数组的长度是固定的,而切片不是(切片可以看成动态的数组)。

切片比数组多一个容量(cap)属性。

切片的底层是数组。

13.协程同步的方式,waitgroup和contex的区别?

(23条消息) golang并发控制之WaitGroup与Context_alwaysrun的博客-CSDN博客_waitgroup和context区别

在go中有三种方式实现并发控制(主协程等待子协程完成):

  • Channel:通过channel控制子协程;
  • WaitGroup:使用信号量控制子协程;子协程数动态可调整;
  • Context:使用上下文控制子协程;可进一步控制孙子协程;

Waitgroup结构:

 WaitGroup结构

包含状态计数器 和 一个信号量:

  • counter:还未执行完成的协程数量;
  • waiter count:多少个等待者;
  • semaphore:信号量;

当信号量>0时,表示资源可用;获取信号量时信号量减一;

当信号量==0时,表示资源不可用;获取信号量时,当前线程进入睡眠,当信号量为正时被唤醒。

对外提供接口

Add(delta int): counter增加delta(delta可以为负,若counter=0,根据waiter数量释放等量的信号量;若counter为负数,则panic。;

Wait(): waiter递增一,并阻塞等待信号量.

Done():counter减一,并按照waiter数释放相应次数信号量,实际上是调用Add(-1);

Context:相比WaitGroup,Context对于派生协程有更强的控制力,可控制多级协程。主要看下面的链接。

(23条消息) golang并发控制之WaitGroup与Context_alwaysrun的博客-CSDN博客_waitgroup和context区别

Go并发控制简

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值