【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://www.mzph.cn/web/49579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c/c++的内存管理(超详细)

一、c/c的内存分布 这是操作系统中对于内存的划分&#xff1a; 我们重点掌握以下几个区域即可&#xff1a; 1.栈 (调用函数会建立栈帧) 2.堆(动态开辟的空间) 3.数据段(静态区)&#xff1a;存放静态变量以及全局变量 4.代码段 (常量区) 先来看看一个题目&#xff1a; int…

蓝牙耳机百元之内怎么选?四款百元精品爆款蓝牙耳机盘点

在蓝牙耳机的海洋中&#xff0c;百元价位仿佛是一片神秘的绿洲&#xff0c;既诱人又充满未知&#xff0c;如何在众多选项中挑选出真正的精品呢&#xff1f;蓝牙耳机百元之内怎么选&#xff1f;这是许多消费者的共同疑问&#xff0c;带着这个疑问&#xff0c;作为蓝牙耳机发烧党…

【Python机器学习】朴素贝叶斯——条件概率

条件概率 假设现在有一个装了7块石头的罐子&#xff08;3块灰色&#xff0c;4块黑色&#xff09;&#xff0c;如果从中随机取出一块&#xff0c;灰色的可能性就是3/7&#xff0c;黑色的可能性是4/7。我们使用p(gray)来表示取到灰色石头的概率&#xff0c;其概率值可以通过灰色…

1.3 双向链表定义及部分实现

1.定义 单链表的问题&#xff1a;找后继容易&#xff0c; 找前驱难 双向链表&#xff08; Double Linked List &#xff09; &#xff1a;指的是构成链表的每个结点中设立两个指针域&#xff1a; 一个指向其直接前趋的指针域 prior &#xff0c;一个指向其直接后继的指针域 …

Tent混沌人工蜂群与粒子群混合算法遇到问题,具体问题及解决方案如文。

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

谷歌再被OpenAI截胡?训练数学AI拿下IMO银牌,不及SearchGPT放了空响..

昨夜谷歌振臂高呼&#xff1a;我们新的数学AI&#xff0c;能在IMO数学竞赛达到银牌水平&#xff01; 但就在谷歌发文的几个小时后&#xff0c;OpenAI就偷了谷歌的家&#xff1a; 发布新的搜索方式SearchGPT &#xff0c;剑指挑战谷歌的搜索引擎。 谷歌双模型并用攻克数学难题…

2. 卷积神经网络无法绕开的神——LeNet

卷积神经网络无法绕开的大神——LeNet 1. 基本架构2. LeNet 53. LeNet 5 代码 1. 基本架构 特征抽取模块可学习的分类器模块 2. LeNet 5 LeNet 5: 5 表示的是5个核心层&#xff0c;2个卷积层&#xff0c;3个全连接层.核心权重层&#xff1a;卷积层、全连接层、循环层&#xff…

LCD 横屏切换为竖屏-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

LCD 横屏切换为竖屏 横屏显示如何切换为竖屏显示 LCD 屏默认横屏显示 开发板配套的 LCD 屏默认都是横屏显示&#xff0c;如 4.3 寸、7 寸和 10.1 寸的不同分辨率的 RGB LCD 屏 固定坐标体系 &#xff08;以 800*480 分辨率为例&#xff09;横屏模式下的固定坐标&#xff1a;…

快醒醒,别睡了!...讲《数据分析pandas库》了—/—<5>

一、 1、修改替换变量值 本质上是如何直接指定单元格的问题&#xff0c;只要能准确定位单元地址&#xff0c;就能够做到准确替换。 1.1 对应数值的替换 具体用法如下&#xff1a; replace方法&#xff1a; df.replace(to_replace None :将被替换的原数值&#xff0c;所有…

【Python机器学习】决策树的构造——信息增益

决策树是最经常使用的数据挖掘算法。它之所以如此流行&#xff0c;一个很重要的原因就是不需要了解机器学习的知识&#xff0c;就能搞明白决策树是如何工作的。 决策树的优缺点&#xff1a; 优点&#xff1a;计算复杂度不高&#xff0c;输出结果易于理解&#xff0c;对中间值的…

linux集群架构--高可用--keepalived(13985字详解)

linux架构高可用 a.概述 高可用&#xff1a;HA HighAvailablity —>Keepalived生成VIP&#xff0c;DNS解析到这个IP地址即可 b.原理 keepalived 是基于VRRP协议实现高可用VRRP虚拟路由器冗余协议&#xff0c;最开始是给网络设备实现高可用&#xff0c;目前keepalive实现v…

项目实战1(30小时精通C++和外挂实战)

项目实战1&#xff08;30小时精通C和外挂实战&#xff09; 01-MFC1-图标02-MFC2-按钮、调试、打开网页05-MFC5-checkbox及按钮绑定对象06--文件格式、OD序列号08-暴力破解09-CE10-秒杀僵尸 01-MFC1-图标 这个外挂只针对植物大战僵尸游戏 开发这个外挂&#xff0c;首先要将界面…

GUL图形化界面操作(下部)

目录 ​编辑 前言 Swing 窗口 注意点 新增的组件 进度条组件 开关按钮 多面板和分割面板 多面板 分割面板 ​编辑 选项窗口 对话框带三个选项是&#xff0c;否&#xff0c;取消。 对话框提示输入文本: 前言 修炼中&#xff0c;该篇文章为俺很久前的学习笔记 Swi…

2024钉钉杯A题思路详解

文章目录 一、问题一1.1 问题1.2 模型1.3 目标1.4 思路1.4.1 样本探究1.4.2 数据集特性探究&#xff1a;1.4.3 数据预处理1.4.4 数据趋势可视化1.4.5 ARIMA和LSTM两种预测模型1.4.6 参数调整 二、问题二2.1 问题2.2 模型2.3 目标2.4 思路2.4.1 样本探究2.4.2 数据集特性探究2.4…

Radon(拉当) 变换:超详细讲解(附MATLAB,Python 代码)

Radon 变换 Radon 变换是数学上用于函数或图像的一种积分变换&#xff0c;广泛应用于图像处理领域&#xff0c;尤其是在计算机断层成像 (CT) 中。本文档将详细介绍 Radon 变换的数学含义及其在图像处理中的应用。 数学定义 Radon 变换的数学定义是将二维函数 f ( x , y ) f…

SRTOD

文章目录 AbstractMethodoverviewinnovationsolve Experiment link Abstract 本文主要探讨了在目标检测领域中&#xff0c;如何解决微小物体检测的问题。传统的通用检测器在处理微小物体时性能下降严重&#xff0c;主要是因为难以提取有效的特征。为了解决这个问题&#xff0c…

STL-string(使用和部分模拟实现)

1.string basic_string<char> 是 C 标准库中定义的一个模板类型,用于表示一个字符串。这个模板类接收一个字符类型作为模板参数。typedef basic_string<char> string&#xff1a;string类是basic_string类模板的实例化&#xff0c;它使用 char作为其字符类型。 2.…

狗都能看懂的Actor-Critic强化学习算法讲解

Review Policy Gradient 上面的公式是Policy Gradient的更新函数&#xff0c;这个式子是指在 s t s_t st​时刻采取了 a t a_t at​&#xff0c;计算出对应发生的概率 p θ p_\theta pθ​&#xff0c;然后计算在采取了这个 a t a_t at​之后&#xff0c;所得到的reward有多大。…

优化算法|自适应大邻域搜索算法及MATLAB代码实现

回来填坑了&#xff0c;本篇推文将详细讲解ALNS算法求解VRP问题及MATLAB代码实现。 算法介绍 节约算法构造初始解 function routessaving_init(DistMatrix, Demand, Cap) C_EPS1e-1;Nsize(DistMatrix,1); routescell(numel(2:N),1); for i1:numel(routes) % 每个节点单独一条…