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

✍个人博客:Pandaconda-CSDN博客

📣专栏地址:http://t.csdnimg.cn/UWz06

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

46. Go  方法值接收者和指针接收者的区别?

在 Go 中,方法可以定义在结构体类型上。接收者是指在方法定义中声明的函数参数。接收者可以是值接收者,也可以是指针接收者。值接收者在方法调用时会对接收者进行复制,而指针接收者则会使用指针来引用原始接收者。

使用值接收者时,方法中对接收者所做的任何修改都不会影响原始接收者。而使用指针接收者时,方法中对接收者所做的任何修改都将影响原始接收者。

另外,指针接收者的优势在于它可以避免在每次调用方法时复制接收者,从而提高程序的性能。此外,在某些情况下,只有使用指针接收者才能修改接收者的状态,因为值接收者只能修改接收者的副本。

例如,以下代码演示了一个使用值接收者和指针接收者的方法:

type Counter struct {count int
}// 值接收者方法
func (c Counter) increment() {c.count++
}// 指针接收者方法
func (c *Counter) decrement() {c.count--
}func main() {// 值接收者方法不会改变原始接收者的值c1 := Counter{count: 0}c1.increment()fmt.Println(c1.count) // 输出 0// 指针接收者方法会改变原始接收者的值c2 := Counter{count: 0}c2.decrement()fmt.Println(c2.count) // 输出 -1
}

在上面的示例中,increment() 方法使用值接收者,而 decrement() 方法使用指针接收者。在调用 increment() 方法后,原始 Counter 结构体实例的 count 属性保持为零,因为该方法对接收者的修改只影响了接收者的副本。而在调用 decrement() 方法后,原始 Counter 结构体实例的 count 属性减少了一,因为该方法直接修改了原始接收者。

 47. Go 函数返回局部变量的指针是否安全?

一般来说,局部变量在函数返回后被销毁,因此被返回的引用就成为了 "无所指" 的引用,程序会进入未知状态。

但这在 Go 中是安全的,Go 编译器将会对每个局部变量进行逃逸分析。如果发现局部变量的作用域超出该函数,则不会将内存分配在栈上,而是分配在堆上,因为他们不在栈区,即使释放函数,其内容也不会受影响。

package mainimport "fmt"func add(x, y int) *int {res := 0res = x + yreturn &res
}func main() {fmt.Println(add(1, 2))
}

这个例子中,函数 add 局部变量 res 发生了逃逸。res 作为返回值,在 main 函数中继续使用,因此 res 指向的内存不能够分配在栈上,随着函数结束而回收,只能分配在堆上。

编译时可以借助选项 -gcflags=-m,查看变量逃逸的情况。

./main.go:6:2: res escapes to heap:
./main.go:6:2:   flow: ~r2 = &res:
./main.go:6:2:     from &res (address-of) at ./main.go:8:9
./main.go:6:2:     from return &res (return) at ./main.go:8:2
./main.go:6:2: moved to heap: res
./main.go:12:13: ... argument does not escape
0xc0000ae008

res escapes to heap 即表示 res 逃逸到堆上了。

48. def er 的执行顺序是什么? defer的作用和特点是什么?

在 Go 语言中,defer 是一种延迟执行机制,用于在函数退出前执行一些特定的代码,无论是函数正常返回还是发生异常。defer 语句是在函数调用结束后执行的,即使出现错误或 panic 也会执行。defer 可以用于清理资源、处理错误等场景。

defer 语句的执行顺序是 “后进先出” 的,也就是说最后一个被 defer 的语句会最先执行,直到第一个被 defer 的语句执行完毕为止。

例如,下面的代码中,defer 语句的执行顺序是 3、2、1。

func example() {defer fmt.Println("1")defer fmt.Println("2")defer fmt.Println("3")fmt.Println("done")
}

需要注意的是,defer 延迟执行的代码并不是在函数退出前立即执行,而是在函数执行结束后,当函数返回时才会执行。因此,如果在 defer 语句中使用的变量在函数返回前发生了改变,那么最终执行的代码将使用最终值。

49. Go  defer 关键字的实现原理?

定义

defer 能够让我们推迟执行某些函数调用,推迟到当前函数返回前才实际执行。defer 与 panic 和 recover 结合,形成了 Go 语言风格的异常与捕获机制。

使用场景

defer 语句经常被用于处理成对的操作,如文件句柄关闭、连接关闭、释放锁。

优点:

方便开发者使用。

缺点:

有性能损耗。

实现原理

Go1.14 中编译器会将 defer 函数直接插入到函数的尾部,无需链表和栈上参数拷贝,性能大幅提升。把 defer 函数在当前函数内展开并直接调用,这种方式被称为 open coded defer。

源代码:

func A(i int) {defer A1(i, 2*i)if(i > 1) {defer A2("Hello", "eggo")}// code to do somethingreturn
}
func A1(a,b int) {//......
}
func A2(m,n string) {//......
}

编译后(伪代码):

func A(i int) {// code to do somethingif(i > 1){A2("Hello", "eggo")}A1(i, 2*i)return
}

代码示例

  1. 函数退出前,按照先进后出的顺序,执行 defer 函数

    package mainimport "fmt"// defer:延迟函数执行,先进后出
    func main() {defer fmt.Println("defer1")defer fmt.Println("defer2")defer fmt.Println("defer3")defer fmt.Println("defer4")fmt.Println("11111")
    }// 11111
    // defer4
    // defer3
    // defer2
    // defer1

    wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

  2. panic 后的 defer 函数不会被执行(遇到 panic,如果没有捕获错误,函数会立刻终止)

    package mainimport "fmt"// panic后的defer函数不会被执行
    func main() {defer fmt.Println("panic before")panic("发生panic")defer func() {fmt.Println("panic after")}()
    }// panic before
    // panic: 发生panic

    wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

  3. panic 没有被 recover 时,抛出的 panic 到当前 goroutine 最上层函数时,最上层程序直接异常终止。

    package mainimport "fmt"func F() {defer func() {fmt.Println("b")}()panic("a")
    }// 子函数抛出的panic没有recover时,上层函数时,程序直接异常终止
    func main() {defer func() {fmt.Println("c")}()F()fmt.Println("继续执行")
    }// b
    // c
    // panic: a

    wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

  4. panic 有被 recover 时,当前 goroutine 最上层函数正常执行。 

package mainimport "fmt"func F() {defer func() {if err := recover(); err != nil {fmt.Println("捕获异常:", err)}fmt.Println("b")}()panic("a")
}func main() {defer func() {fmt.Println("c")}()F()fmt.Println("继续执行")
}// 捕获异常: a
// b
// 继续执行
// c

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

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

相关文章

YOLOV8-人员越界识别

原文:YOLOV8-人员越界识别 - 知乎 (zhihu.com) 一、人员越界识别背景描述 实际生活中某些场景下需要配合摄像头自动识别危险区域,并在发现有人员闯入危险区域(禁止进入区域)时进行报警。翻越围墙监测预警系统对监控区域内的护栏、围墙设定警戒围墙区域,一旦有可疑人员靠…

springboot电子产品销售系统-计算机毕业设计源码80294

摘 要 电子商务行业在全球范围内迅速发展,随之而来的是电子产品销售市场的快速增长和消费者对在线购物体验的需求提升,因此,电子产品销售系统应运而生。该系统旨在满足电子产品市场的需求,提供全面的购物功能和高效的管理操作。 …

高级及架构师高频面试题-基础型

1、设计模式有哪些原则(待解释的更直白) 单一职责原则:一个类或方法应只负责一项职责,避免一个类因为多个变化原因而改变。开闭原则:软件实体应对扩展开放,对修改封闭。比如要增加用户类别的时候可以新增一…

校车购票小程序的设计

管理员账户功能包括:系统首页,个人中心,学生管理,我的乘车信息管理,车辆信息管理,座位管理,系统管理 微信端账号功能包括:系统首页,车辆信息,我的 开发系统…

【项目管理】高手项目经理都在用的6个SOP

SOP(Standard Operating Procedure)流程是一种标准化的操作指南,旨在确保组织或团队在各种情况下都能高效、一致地完成任务。SOP流程通常包括详细的步骤、关键控制点和责任分配,以确保质量和安全。SOP流程涉及从日常运营到危机管理…

28.x86游戏实战-初探XXX发包

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 工具下载: 链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

GPT-4o mini小型模型具备卓越的文本智能和多模态推理能力

GPT-4o mini 是首个应用OpenAI 指令层次结构方法的模型,这有助于增强模型抵抗越狱、提示注入和系统提示提取的能力。这使得模型的响应更加可靠,并有助于在大规模应用中更安全地使用。 GPT-4o mini 在学术基准测试中,无论是在文本智能还是多模…

微信小游戏之三消(二)主要游戏控制方法

设计一个 game class。负责了游戏的核心控制逻辑,包括游戏状态管理、方块和道具的生成与效果处理,以及游戏的重新开始和复活流程。通过这些方法,脚本实现了游戏的基本玩法和用户交互。 主要游戏控制方法 gameStart():开始游戏&am…

Java学习Day16:基础篇6

1.静态和非静态 2.调用静态和非静态的过程 注:在Java中,同类中,确实可以使用类的对象来调用静态方法,尽管这不是推荐的做法。静态方法属于类本身,而不是类的任何特定实例。因此,理论上讲,你应该…

【iOS】—— KVO与KVC

KVO与KVC 1. KVOKVO底层实现分析如何验证上面的说法:NSKVONotifyin_Person内部结构didChangeValueForKey:内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法 回答问题: 2. KVC简介:key和keyPath的区别key&#xff1a…

探索 Electron:如何进行网址收藏并无缝收录网页图片内容?

Electron是一个开源的桌面应用程序开发框架,它允许开发者使用Web技术(如 HTML、CSS 和 JavaScript)构建跨平台的桌面应用程序,它的出现极大地简化了桌面应用程序的开发流程,让更多的开发者能够利用已有的 Web 开发技能…

EtherNet/IP转CAN协议转化网关(功能与配置)

怎么样把EtherNet/IP和CAN两个协议连接起来?有很多朋友想要了解这个问题,那么作者在这里统一说明一下。其实有一个不错的设备产品可以很轻易地解决这个问题,名为JM-EIP-ECAT网关。接下来作者就从该设备的功能及配置详细说明一下。 一,设备主…

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

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

TinyMCE一些问题

1.element 在el-dialog中使用tinymce导致富文本弹窗在el-dialog后面的问题 原因是富文本的弹窗层级太低了 在APP.vue中添加样式即可解决 /* 富文本菜单 */ .tox-tinymce-aux {z-index: 9999 !important; }2.element 在el-dialog中点击富文本的功能栏报错 由于 aria-hidden 属…

Midjourney、Sora和硅谷机密-《分析模式》漫谈15

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的Preface(前言)有这么一句: Kent Beck, Ward Cunningham, and Jim Coplein encouraged me to get involved with the commu…

虚假的互联网信息?不妨从IT的角度理解【景观社会】

博主前言:“我思故我在”,笛卡尔的这一哲学命题,大抵上次还比较熟络的时光还是高中亦或复习考研政治的岁月里。这是一个光怪陆离的社会——或者说网络社会,形形色色的消息充斥在脑海之时,你是否还能认识真正的自己&…

YOLOV8-源码解读-SPP-SPPF

先给出YOLOV8中一键三连卷积模块 def autopad(k, pNone, d1): # kernel, padding, dilation"""Pad to same shape outputs."""if d > 1:k d * (k - 1) 1 if isinstance(k, int) else [d * (x - 1) 1 for x in k] # actual kernel-sizeif…

分布式事务解决方案(一) 2PC、3PC、TCC、Sega

目录 1.绪论 2.2PC 2.1 基本原理 2.1.1 组成 2.1.2 步骤 1.prepare阶段 2.commit阶段 2.2 2PC 存在的问题 2.2.1 阻塞问题 2.2.2 单点故障问题 1. 事务协调器宕机 2.部分数据不一致问题 2.资源管理器宕机 3. 事务协调器和资源管理管理器同时宕机 2.2 实现 2.2.1…

怎么将几个pdf合成为一个pdf?pdf合成为一个的常用方法

在现代的职场和学术环境中,如何将多个独立的PDF文档合并成一个统一的文件已经成为提高工作效率、优化文档管理和促进信息共享的重要手段。PDF格式以其卓越的跨平台兼容性、强大的数据保护能力以及清晰易读的版面设计,在全球范围内得到了广泛的应用和认可…