【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.tpcf.cn/web/49579.html

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

相关文章

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

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

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

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

为什么Spring不推荐@Autowired用于字段注入

背景 Spring是Java程序员常用的框架之一。官方从Spring 4.0开始不推荐使用Autowired进行字段注入。 Spring注入方式 基于构造器注入&#xff1a;在构造器上使用Autowired。 优点&#xff1a;可以声明字段为final&#xff0c;确保字段在构造时被初始化。 基于setter方法注入&…

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

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

【SpringBoot】参数传递之RequestBody接收JSON数据

4.3.3 RequestBody接收Json数据 PostMapping(path "/save2") public String save2(RequestBody Student student){ String firstName student.getFirstName; String lastName student.getLastName; return firstName"" "lastName; }

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…

C语言系统调用linux文件系统

在C语言中&#xff0c;open、write和read函数是系统调用&#xff08;system calls&#xff09;&#xff0c;它们直接由操作系统提供&#xff0c;用于底层的文件操作。这些函数是UNIX和类UNIX系统&#xff08;如Linux&#xff09;中的标准接口&#xff0c;不同于C标准库中的文件…

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

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

SRTOD

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

SLAM面试题

常见的slam面试问题如下&#xff0c;在文章末尾有《自动驾驶100问》的视频内容&#xff0c;可以去看看&#xff1a; 1.重定位和回环检测的区别是什么&#xff1f; 2.单应矩阵H和基础矩阵F的区别是什么&#xff1f; 3.视觉SLAM方法的分类和对应的特点分析。 4.关键帧的作用是…