各位老铁,这几个Golang Go语言面试问题怎么回答(回答的圆满不)?

各位老铁,这几个Golang Go语言面试问题怎么回答(回答的圆满不)?

如果从一个 map 里随机抽取 3 个 key,概率保持一样,要怎么做

  • 把 key 放到 slice 里,随机获取 3 个 key

channel,2 个 goroutine 同时发送和接收,会发生什么?

  • 对于无缓存的,发送端会短暂的阻塞
  • 对于有缓存的, 看缓存是否已满,如果满了就和无缓存一样

map 里的元素被 delete 后,map 的内存的体积会不会立即减小

  • 不会,gc 不会立即执行

一个 work server,每次收到一个请求,就创建一个协程去处理这个请求,里面有大量的 slice,append 这种情况,短时间请求特别多,这个服务器会发生什么情况

  • 内存暴涨?

更多关于各位老铁,这几个Golang Go语言面试问题怎么回答(回答的圆满不)?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

25 回复

map 就是随机的,直接 for 循环取前三个就行吧

更多关于各位老铁,这几个Golang Go语言面试问题怎么回答(回答的圆满不)?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在数量不大的情况下,好像并不是很随机

我觉得想问的还是 runtime 实现,但好像回答没有怎么涉及。特别是那个 map 删除键值的,确实不会立即减小,但原因不是 gc 而是 map 的内存结构

不过感谢分享面试题

第二个问题,对于 channel 两个协程进行收发,你的短暂的阻塞的说法是错误的。

一个协程给 channel 发消息,一个协程从 channel 接收,要求是这两个协程都准备好,才能完成收发操作。

形象一点的例子就是,快递员给你送快递,你要去拿快递,通过沟通约定了时间地点,快递员得带着快递过去,你得过去拿,这样才能完成这个流程。

而对于有缓冲的 channel,是不需要收发同步的,但是队列满了之后就和无缓冲的一样了。

所以,同时收发会直接完成这一次消息传递。非同时收发,那么发送端会被阻塞,接收端也会被阻塞。

体积那题不是考察 gc , 哈希表有装填因子,大于或小于的时候才会执行 resize

感谢

关于 map 中的 key 被删除之后 gc 的问题,不是特别好回答。印象中这个问题很早就有人在 github 提出 issues 过,刚刚找出来了。

https://github.com/golang/go/issues/20135

可以去看看进展

1.没理解
2.channel 内部有锁实现线程安全,剩下的就是 goroutine 阻塞唤醒等流程
3.不会,map 没有缩容机制,内存占用只会越扩越多
4.大量的 slice append 操作会导致大量的 内存拷贝,应该是考的这个吧

以上是根据 1.13 版本源码的理解,现在可能不准确

我也刚刚看到这个了

如果是我回答的话。1,4
把 map 的值 copy 到 slice 。然后使用 Fisher-Yates 算法保持概率一样。

第 4 个需要问 slice 的大小。机器的 total memory 。是否使用 sync.Pool 。综合考虑多个变量。最后看增加和消费的速度,可能有两种情况。可能爆生成者 > 消费者(内存回收),可能生成者==消费者平衡(内存回收),就是不加不减。(如果不引入速度的话,这题描述的有 bug)。(还有一种概率小的情况生成者 < 消费者(内少回收) 基本不可能发生)。

我记得 go 的 map 内存占用不会随着元素的 Delete 而出发 resize 的,例如 原来 map 中有 100 个元素,这时 map 占用内存 10M 现在把 map 的元素删除 90 个, map 还是占用 10M 内存, 当然,元素会被 gc 回收掉.

我没有研究过源码, 只是看别人的分析文章了解的,不正确还请指正

go 的好像确实是不会,我的有问题,我是按照一般的 map 回答的

最后的那个应该是 cpu 会暴涨吧,说到 append,应该是要问 append 扩容

当然内存也涨的。。

查了一下 java 的 hashmap 也不缩容…目前就只在哈希表学习时和 redis 哈希表里见到过缩容操作,可能是缩容的性价比确实不高吧


第一题我觉得是考察随机采样算法,最常见的蓄水池算法就可以处理。

虽然不懂 go,但现代系统确实不再流行缩容,因为现在最贵的硬件资源是 CPU 。

这个概念在学 nosql 的时候被反复提及,以前流行关系数据库是因为它可以节约存储空间(以前最贵的硬件资源),代价就是数据用的时候需要临时组装,耗费 CPU 资源。但现在 CPU 成了最贵的硬件资源,所以就把数据按读取时需要的格式存储,冗余也没问题,只要能尽量减少临时组装数据。

所以,除非过大的哈希表影响了整体速度,否则不缩

我觉得前三个回答得都可以。

第四个问题,如果请求太多,每个都开一个 goroutine 显的很失控。特别是 goroutine 里对内存有明显压力。你可以 channel request 先。

第二题更具体点:
无缓存,同时发送和接收时,发送端会阻塞,接收端完成接收,发送端解阻塞完成发送;
有缓冲,发送端阻塞到复制值到缓冲区完成,缓冲区满一直阻塞,接收端阻塞到从缓冲区取值完成,缓冲区空一直阻塞

3 这个 delete map[key]. map 的容量和 gc 应该没关系?

第三个问题,题目就是每个请求都开一个 goroutine, 是想问你这个服务器会有什么表现,比较开放,这个问题

go 面试也开始内卷了

针对您提出的Golang(Go语言)面试问题的圆满回答,可以从以下几个方面着手,确保回答既专业又全面:

  1. 并发编程:强调Go语言的goroutines和channels特性,如何高效地进行并发编程,以及使用sync包管理并发资源。可以提及使用select语句处理多个channel的读写。

  2. 内存管理:说明Go语言的垃圾回收机制(GC),包括GC的工作原理、触发条件及调优策略。同时,可以提到逃逸分析(escape analysis)和如何编写GC友好的代码。

  3. 接口与实现:解释Go语言的接口(interface)是隐式实现的,无需显式声明。讨论接口的多态性、空接口(interface{})的用途以及如何通过接口实现解耦和扩展性。

  4. 错误处理:强调Go语言中的错误处理模式,如使用error类型返回错误,以及defer、panic和recover机制在异常处理中的应用。

  5. 性能优化:提及Go语言的性能调优技巧,如使用profile工具分析性能瓶颈,优化算法和数据结构,以及减少不必要的内存分配和复制。

  6. 版本控制:如果使用Go Modules进行依赖管理,可以介绍其工作原理和优势。同时,提及使用go fmt、go lint等工具保持代码风格和质量。

在回答时,尽量结合具体代码示例或项目经验,使回答更加生动和有说服力。同时,保持语言清晰、逻辑连贯,展现出您对Go语言的深入理解和实践经验。

回到顶部