【Golang 面试基础题】每日 5 题(九)

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06

📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

41. Go channel 有什么特点?

channel 有 2 种类型:无缓冲、有缓冲

channe l有 3 种模式:写操作模式(单向通道)、读操作模式(单向通道)、读写操作模式(双向通道)

写操作模式读操作模式读写操作模式
创建make(chan<- int)make(<-chan int)make(chan int)

channel 有 3 种状态:未初始化、正常、关闭

未初始化关闭正常
关闭panicpanic正常关闭
发送永远阻塞导致死锁panic阻塞或者成功发送
接收永远阻塞导致死锁缓冲区为空则为零值,否则可以继续读阻塞或者成功接收

注意点

  1. 一个 channel 不能多次关闭,会导致 painc。

  2. 如果多个 goroutine 都监听同一个 channel,那么 channel 上的数据都可能随机被某一个 goroutine 取走进行消费。

  3. 如果多个 goroutine 监听同一个 channel,如果这个 channel 被关闭,则所有 goroutine 都能收到退出信号。

 42. Go 语言当中 Channel(通道)有什么特点,需要注意什么?

在 Go 语言中,Channel 是一种用于 Goroutine 之间通信和同步的重要机制。Channel 具有以下几个特点:

  1. 线程安全:Channel 可以安全地在多个 Goroutine 之间传递数据,避免了数据竞争和死锁等问题。

  2. 阻塞式:当 Channel 中没有数据时,读取操作会被阻塞,直到 Channel 中有数据可读;同样地,当 Channel 已满时,写入操作会被阻塞,直到 Channel 中有空间可写入。

  3. 有缓冲和无缓冲:Channel 可以带有缓冲或者不带缓冲。不带缓冲的 Channel 可以保证每次写入和读取都是同步的;带缓冲的 Channel 可以在缓冲区未满时进行写入操作而不阻塞,直到缓冲区满时再阻塞写入操作。

  4. 可关闭:Channel 可以被显式地关闭,以通知 Channel 的接收方不再有数据可读,避免接收方被永久地阻塞。

在使用 Channel 时,需要注意以下几个问题:

  1. 避免死锁:当使用 Channel 进行 Goroutine 之间的通信和同步时,需要确保不会出现死锁的情况。一般来说,可以使用 select 语句和超时机制等方式来避免 Channel 的阻塞问题。

  2. 避免竞态条件:当多个 Goroutine 访问同一个 Channel 时,需要注意避免竞态条件的发生。可以使用 Mutex 和 sync 包中提供的其他同步机制来避免并发访问 Channel 导致的问题。

  3. 合理使用缓冲:当使用带缓冲的 Channel 时,需要根据实际需要设置缓冲区的大小,避免缓冲区过大或过小导致的性能问题。同时需要注意,当 Channel 中的数据过多时,会导致内存占用过高,需要及时清理不必要的数据。

  4. 避免 Channel 泄漏:当使用 Channel 时,需要注意避免 Channel 泄漏的问题,即在不需要使用 Channel 时及时关闭 Channel,避免 Channel 占用过多的系统资源。

实例

以下是一个使用同步锁和 Channel 进行并发编程的例子:

package mainimport ("fmt""sync"
)func main() {var wg sync.WaitGroupwg.Add(2)ch := make(chan int, 5)mutex := sync.Mutex{}go func() {defer wg.Done()for i := 0; i < 10; i++ {mutex.Lock()ch <- imutex.Unlock()}}()go func() {defer wg.Done()for i := 0; i < 10; i++ {mutex.Lock()fmt.Println(<-ch)mutex.Unlock()}}()wg.Wait()close(ch)
}

上述代码中,我们创建了一个有缓冲的 Channel,使用一个 Goroutine 向其中写入数据,另一个 Goroutine 从中读取数据,并使用同步锁保证对 Channel 的访问是线程安全的。在主函数中,我们使用 sync.WaitGroup 来等待两个 Goroutine 完成任务,并在任务完成后关闭 Channel。

 43. Go 语言当中 Channel 缓冲有什么特点?

在 Go 语言中,Channel 缓冲是指在创建 Channel 时设置的缓冲区大小。带缓冲的 Channel 可以在缓冲区未满时进行写入操作而不阻塞,直到缓冲区满时再阻塞写入操作。

Channel 缓冲的特点如下:

  1. 可以提高并发性能:使用带缓冲的 Channel 可以提高并发程序的性能,因为缓冲区可以暂时存储数据,避免了每次数据传输时都需要阻塞等待的情况。这种方式特别适用于生产者-消费者模式,其中生产者的产生速度快于消费者的处理速度,缓冲区可以暂时存储一定量的数据,使得生产者和消费者的速度可以适度地解耦。

  2. 缓冲区大小需要合理设置:Channel 缓冲区大小的设置需要根据实际应用场景进行合理的选择,过小的缓冲区可能会导致生产者被阻塞,过大的缓冲区可能会导致内存占用过高。一般来说,需要根据实际情况进行调整,以达到最优的性能表现。

  3. 带缓冲的 Channel 可能会出现死锁问题:当使用带缓冲的 Channel 进行 Goroutine 之间的通信和同步时,需要注意避免死锁的问题。因为带缓冲的 Channel 可以在缓冲区未满时进行写入操作,如果生产者写入数据的速度过快,可能会导致缓冲区已满而阻塞生产者,此时如果消费者已经不再消费数据,整个程序就会进入死锁状态。

  4. 可以使用 close() 函数关闭 Channel:当使用带缓冲的 Channel 时,需要注意及时清理缓冲区中的数据,可以使用 close() 函数来显式地关闭 Channel。关闭 Channel 会使得 Channel 中未被读取的数据被丢弃,并且后续的写入操作会导致 panic 异常。

实例

举个例子,假设有一个生产者-消费者模式的场景,生产者不断地向 Channel 中写入数据,而消费者则以固定的速度从 Channel 中读取数据进行处理。如果使用带缓冲的 Channel,可以设置缓冲区大小为一定的值,比如 10,这样生产者可以连续向 Channel 中写入 10 个数据,只有当 Channel 中已经存储了 10 个数据时才会阻塞。而消费者则可以按照自己的处理速度从 Channel 中读取数据,只有当 Channel 中的数据被消费完时才会阻塞等待新的数据。这样可以提高程序的并发性能,避免频繁地阻塞等待。

package mainimport ("fmt""time"
)func producer(ch chan<- int) {for i := 1; i <= 10; i++ {ch <- ifmt.Printf("Producer: %d\n", i)}close(ch)
}func consumer(ch <-chan int) {for {data, ok := <-chif !ok {break}fmt.Printf("Consumer: %d\n", data)time.Sleep(time.Second)}
}func main() {ch := make(chan int, 5)go producer(ch)consumer(ch)
}

44. C hannel 的 ring buffer 实现

在 Go 语言中,channel 是一种用于在 goroutine 之间进行通信的机制。通常情况下,channel 会被实现为一个 FIFO 的队列。当向 channel 发送数据时,数据会被添加到队列的末尾;当从 channel 接收数据时,数据会被从队列的头部取出。

在 Go 1.3 版本中,新增了一种基于环形缓冲区(ring buffer)的 channel 实现方式,可以用于提高 channel 的性能。具体来说,当创建一个缓冲区大小为 n 的 channel 时,Go 语言会为其分配一个大小为 n 的环形缓冲区,而不是一个简单的队列。

使用环形缓冲区实现 channel 有以下几个好处:

  1. 避免动态内存分配:在缓冲区大小确定的情况下,环形缓冲区可以在创建时一次性分配所需的内存,避免了频繁的动态内存分配和释放操作,从而提高了性能。

  2. 提高缓存命中率:环形缓冲区会将元素放置在连续的内存块中,这样可以提高缓存命中率,从而减少缓存访问延迟,提高了通信的效率。

  3. 支持无锁访问:由于 channel 是在多个 goroutine 之间进行通信的,因此通常会涉及到并发访问的问题。环形缓冲区的实现可以采用无锁算法,从而避免了锁竞争带来的开销,提高了并发访问的效率。

需要注意的是,使用环形缓冲区实现 channel 也有一些限制和注意事项。例如,缓冲区大小必须是 2 的幂次方,否则可能会导致缓冲区溢出或者浪费内存等问题。同时,对于特殊的 channel 操作,如 close、select 和带缓冲区的 channel 等,也需要注意环形缓冲区的使用方式。

  

 45. Go 方法与函数的区别?

在 Go 语言中,方法(method)是一个包含接收者参数的函数,用于为接收者类型提供一些行为。而函数(function)则是一段代码,可被调用并可接收参数和返回值。

方法需要被绑定到一个类型上,它们通过使用接收者参数来实现这一点。接收者可以是值类型或指针类型。值类型的接收者在方法执行时会将调用者的值复制一份,而指针类型的接收者则直接操作调用者的值,因此可以修改调用者的状态。

与方法不同,函数没有接收者参数,因此它们无法直接修改调用者的状态。函数在 Go 语言中是一等公民,可以像任何其他类型的值一样被传递和赋值。函数还可以是匿名的,或者被作为闭包使用,以便在不同的作用域中进行操作。

实例

在 Go 语言中,函数是一段代码块,可以独立调用,接受参数和返回结果,它没有任何属于对象的概念。而方法是和对象相关联的函数,它属于对象的一部分,可以调用对象的属性和方法。

例如,下面是一个函数和一个方法的示例:

// 函数
func add(x int, y int) int {return x + y
}// 方法
type Person struct {Name stringAge  int
}func (p *Person) sayHello() {fmt.Printf("Hello, my name is %s and I'm %d years old.\n", p.Name, p.Age)
}

可以看到,函数 add 只是一个独立的代码块,而方法 sayHello 则是一个属于 Person 结构体对象的一部分。在调用方法时,需要先创建一个 Person 对象,然后通过这个对象调用方法,例如:

p := Person{Name: "Alice", Age: 30}
p.sayHello() // 输出:Hello, my name is Alice and I'm 30 years old.

总的来说,Go 语言中的方法与函数的区别在于方法需要绑定到一个类型上,并且可以直接修改调用者的状态,而函数则没有这些限制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3270246.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【Android】Fragment与Activity间通信知识总结

文章目录 一、Activity向Fragment通信1.1 通过方法1.1.1 构造方法1.1.1 普通public方法 1.2 通过setArguments方法1.3 通过接口 二、Fragment向Activity通信2.1 通过getActivity2.2 通过接口 三、Fragment之间传递数据通过Activity中转 一、Activity向Fragment通信 1.1 通过方…

聊聊基于Alink库的主成分分析(PCA)

概述 主成分分析&#xff08;Principal Component Analysis&#xff0c;PCA&#xff09;是一种常用的数据降维和特征提取技术&#xff0c;用于将高维数据转换为低维的特征空间。其目标是通过线性变换将原始特征转化为一组新的互相无关的变量&#xff0c;这些新变量称为主成分&…

关于链表、顺序表、栈和队列的一些总结

关于链表、顺序表、栈和堆的一些总结 1.顺序表2.链表2.1 单向链表2.1 带哨兵位双向循环链表 3.栈4.队列 1.顺序表 2.链表 2.1 单向链表 2.1 带哨兵位双向循环链表 3.栈 4.队列

【Matlab】绘图时使用字母控制线型和颜色(内含多图对比示例)

概要 测试了英文字母a-z不同输入下线条的颜色和线型&#xff0c;供参考选择。 语法 plot(x, y, 颜色); 如 plot(x, y, b); 测试 以下测试设置线宽为1.5&#xff0c;代码 x 0: 0.01: 2*pi; y sin(x); plot(x, y, b, LineWidth, 1.5);修改时把 b 改成不同字母即可 ‘a’…

基于关联规则的分类算法(CBA) | 项集、频繁项集、关联规则 | arulesCBA库

基于关联规则的分类算法 目前使用较多且较为简洁的关联规则分类算法是基于关联规则的分类算法&#xff08;Classification Based on Association, CBA&#xff09;&#xff0c;下面将从该算法的相关概念开始介绍。 这部分笔记参考论文&#xff1a;孙菡悦.基于多因素交互效应的…

Linux第五节课(权限02)

1、Linux下的用户分类 root&#xff1a;超级用户普通用户&#xff1a;通过root新建的用户&#xff0c;adduser root不受权限约束&#xff1b;普通用户受权限约束&#xff1b; Linux系统中&#xff0c;所有用户都需要有密码&#xff0c;无论是root还是其他&#xff0c;即便是…

MySQL内如何改变编码格式

查找数据库的编码格式&#xff1a; show variables like character%;具体内容时这些 在创建表时设定编码格式&#xff1a; create database <要创建的数据库的名字> charset utf8; 修改数据库默认编码&#xff1a; set character_set_databaseutf8mb4; character_…

大模型算法备案流程最详细说明【流程+附件】

文章目录 一、语料安全评估 二、黑盒测试 三、模型安全措施评估 四、性能评估 五、性能评估 六、安全性评估 七、可解释性评估 八、法律和合规性评估 九、应急管理措施 十、材料准备 十一、【线下流程】大模型备案线下详细步骤说明 十二、【线上流程】算法备案填报…

【二分查找 数论】2513. 最小化两个数组中的最大值

本文涉及知识 二分查找算法合集 质数、最大公约数、菲蜀定理 LeetCode2513. 最小化两个数组中的最大值 给你两个数组 arr1 和 arr2 &#xff0c;它们一开始都是空的。你需要往它们中添加正整数&#xff0c;使它们满足以下条件&#xff1a; arr1 包含 uniqueCnt1 个 互不相同…

栈和队列<数据结构 C版>

目录 栈&#xff08;Stack&#xff09; 栈的结构体 初始化 销毁 入栈 判空 出栈 取栈顶元素 获取栈个数 测试&#xff1a; 队列&#xff08;Queue&#xff09; 队列的结构体 单个结点 队列 初始化 销毁 入队列&#xff0c;队尾 判空 出队列&#xff0c;队头 …

贪心算法.

哈夫曼树 哈夫曼树&#xff08;Huffman Tree&#xff09;&#xff0c;又称为霍夫曼树或最优二叉树&#xff0c;是一种带权路径长度最短的二叉树&#xff0c;常用于数据压缩。 定义&#xff1a;给定N个权值作为N个叶子结点&#xff0c;构造一棵二叉树&#xff0c;若该树…

大话成像公众号文章阅读学习(一)

系列文章目录 文章目录 系列文章目录前言一、扫射拍摄二、索尼Alpha 9 III2.1. 视频果冻效应2.2 闪光灯同步速度2.3 其他功能 三 A9III 局限性总结 前言 大话成像是一个专注成像的公众号&#xff0c;文章都很好。 今天看的这篇是 特朗普遭枪击后“大片”出自它 文章地址 htt…

Python | Leetcode Python题解之第284题窥视迭代器

题目&#xff1a; 题解&#xff1a; class PeekingIterator:def __init__(self, iterator):self.iterator iteratorself._next iterator.next()self._hasNext iterator.hasNext()def peek(self):return self._nextdef next(self):ret self._nextself._hasNext self.itera…

SGLang 大模型推理框架 qwen2部署使用案例;openai接口调用、requests调用

参考: https://github.com/sgl-project/sglang 纯python写,号称比vllm、tensorRT还快 暂时支持模型 安装 可以pip、源码、docker安装,这里用的pip 注意flashinfer安装最新版,不然会可能出错误ImportError: cannot import name ‘top_k_top_p_sampling_from_probs’ fr…

万物互联,触手可及“2024南京智慧城市,物联网,大数据展会”

在金秋送爽的11月&#xff0c;南京这座历史悠久而又充满活力的城市&#xff0c;即将迎来一场科技盛宴——2024南京智慧城市、物联网、大数据展会。这不仅是一场技术的集会&#xff0c;更是未来生活蓝图的预览&#xff0c;它汇聚了全球顶尖的科技企业、创新者及行业精英&#xf…

1.2 单链表定义及操作实现(链式结构)

1.单链表定义 链式存储&#xff1a;用一组任意的存储单元存储线性表中的数据元素。用这种方法存储的线性 表简称线性链表。 为了正确表示结点间的逻辑关系&#xff0c;在存储每个结点值的同时&#xff0c;还必须存储指示其直接 后继结点的地址&#xff08;或位置&#xff09;…

04-Charles中的Map Remote和Map Local介绍

Charles提供了Map Remote和Map Local两个功能。 Map Remote是将指定的网络请求重定向到另一个网址。Map Local是将指定的网络请求重定向到本地文件。 一、Map Remote 假设代码中调用了接口A&#xff0c;但是接口A的响应结果不能满足需求&#xff1b;此时&#xff0c;有另一个…

第15周 Zookeeper分布式锁与变种多级缓存

Zookeeper **************************************************************

heic怎么转换成jpg?heic转jpg,分享6款图片格式转换器免费汇总!

众所周知&#xff0c;在与非苹果手机设备用户&#xff08;如安卓手机或Windows台式机用户&#xff09;分享照片之前&#xff0c;通常需要将iphone的heic格式转换为jpg。由于这些操作系统的旧版本不原生支持heic图片格式&#xff0c;因此需要额外的第三方工具来查看这些图像。因…

0727,学什么学,周六就应该休息!!!!!

周六就应该休息&#xff0c;一天就忙了两小时也不是我的错喵 目录 UDP的小总结 01&#xff1a;使用select实现一个基于UDP的一对一即时聊天程序。 1.0 复读机服务器和树洞客户端 2.0 byby不了一点的敬业服务器&#xff01;&#xff01;&#xff01; 今天到此为止&#x…