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

news2024/9/20 22:52:54

✍个人博客: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 main

import "fmt"

func add(x, y int) *int {
    res := 0
    res = x + y
    return &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 something
    return
}
func A1(a,b int) {
    //......
}
func A2(m,n string) {
    //......
}

编译后(伪代码):

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

代码示例

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

    package main
    
    import "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 main
    
    import "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 main
    
    import "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 main

import "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.coloradmin.cn/o/1957216.html

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

相关文章

关联映射和缓存机制学习笔记

学习视频:4001 关联映射概述_哔哩哔哩_bilibili~4007 案例:商品的类别_哔哩哔哩_bilibili 目录 1.关联映射概述 1.1关联映射关系 一对一关系 一对多关系 多对多关系 Java对象如何描述事物之间的关系 1.2一对一查询 元素 a.嵌套查询方式 b.嵌套结果方…

Spring Cache常用注解

依赖代码如下&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency> 常用注解详解 1. Cacheable 作用&#xff1a;主要用于配置方法&#xff0c;使其…

第九届全球渲染大赛来了!CG爱好者准备好了吗!

在CG界的日历上&#xff0c;二月和八月总是特别繁忙的月份。这两个月&#xff0c;全球CG艺术界最盛大的赛事——全球渲染大赛&#xff0c;都会开放报名&#xff0c;吸引着世界各地的CG艺术家和爱好者参与。备受期待的第九届全球渲染大赛&#xff0c;已经定于2024年8月3日在美国…

微信私域运营工具分享

解决微信多管理难的问题&#xff0c;多微信工作重复做&#xff0c;效率低的问题&#xff0c;防止飞单、删除客户&#xff0c;解决私域运营的难题

在双碳目标下,如何实现工厂的数字化改造升级

在"双碳"目标下&#xff0c;如何实现工厂的数字化改造升级 在“双碳”目标&#xff0c;即2030年前实现碳达峰、2060年前实现碳中和的宏伟蓝图下&#xff0c;企业作为经济社会活动的主体&#xff0c;其改造升级不仅是响应国家战略的必然要求&#xff0c;也是实现可持…

软件压力测试知识大揭秘,专业软件测评公司推荐

在信息技术迅猛发展的今天&#xff0c;软件已经成为各个行业运作的核心。有助于提升工作效率和管理水平的&#xff0c;软件的稳定性和性能也变得尤为重要。而软件压力测试&#xff0c;作为一种重要的测试手段&#xff0c;逐渐受到了更多企业的重视。 软件压力测试&#xff0c;…

【ROS 最简单教程 001/300】ROS 概念介绍

ROS&#xff1a;Robot Operating System 【适用于机器人的开源元操作系统】 ROS Plumbing Tools Capabilities Ecosystem 通讯 Plumbing ⭐ 实现ROS不同节点之间的交互工具 Tools ⭐ 工具软件包 (ROS中的开发和调试工具)&#xff0c;提供 仿真 功能&#xff1b;功能 Capabi…

图文好物和无人直播实操:定位/涨粉/养号/橱窗/作品/制作/剪辑/开播/等等

1.前言 各位小伙伴大家好&#xff0c;这里是天夏共创&#xff0c;免费分享副业/创业精品项目资源&#xff0c;打破互联网创业/副业信息壁垒&#xff0c;和您一起共享副业/创业项目资源&#xff0c;开启智能化创业/副业新时代&#xff01;致力于每天免费分享全网互联网精品VIP项…

React类组件生命周期与this关键字

类组件生命周期 参考链接 一图胜千言&#xff08;不常用的生命周期函数已隐藏&#xff09; 代码&#xff1a; //CC1.js import { Component } from "react";export default class CC1 extends Component {constructor(props) {super(props);console.log("con…

基于IDEA+Mysql+SpringBoot开发的社区养老服务管理系统

基于IDEAMysqlSpringBoot开发的社区养老服务管理系统 项目介绍&#x1f481;&#x1f3fb; node -version 14.21.3 在当前社会老龄化趋势日益加剧的背景下&#xff0c;构建一个高效、便捷的社区网养老服务管理系统显得尤为重要。本项目基于Spring Boot框架开发&#xff0c;旨…

网站打不开怎么办,收藏以备不时之需

DNS设置示范教程 部分地区有使用移动网络的小伙伴们吐槽无法访问部分网站的情况&#xff0c;同样的网站&#xff0c;使用电信和联通的用户就能正常访问。 这其实有很大几率是由于运营商的网络问题导致的&#xff0c;容易出现网站打不开的结果。 要解决移动网络无法访问的情况…

【React Hooks原理 - useTransition】

概述 在上一篇中我们介绍了useDeferredValue的基本原理&#xff0c;本文主要介绍一下useTransition这个Hook&#xff0c;之所以在这里提到useDeferredValue&#xff0c;是因为这两个Hook都是在React18引入的进行渲染优化的Hooks&#xff0c;在某些功能上是重叠的&#xff0c;主…

YOLO入门教程(一)——训练自己的模型【含教程源码 + 故障排查】

目录 引言前期准备Step1 打标训练Step2 格式转换Step3 整理训练集Step4 训练数据集4.1创建yaml文件4.2训练4.3故障排查4.3.1OpenCV版本故障&#xff0c;把OpenCV版本升级到4.0以上4.3.2NumPy版本故障&#xff0c;把NumPy降低版本到1.26.44.3.3没有安装ultralytics模块4.3.4Aria…

自闭症儿童上学指南:帮助孩子适应校园生活

在自闭症儿童成长的道路上&#xff0c;校园生活是他们融入社会、学习新知、发展社交技能的重要一步。作为星启帆自闭症儿童康复机构&#xff0c;我们深知这一过程对于孩子及其家庭而言既充满挑战也极具意义。 一、前期准备&#xff1a;建立坚实的支持体系 1. 深入了解孩子需求 …

【机器学习】梯度下降函数如何判断其收敛、学习率的调整以及特征缩放的Z-分数标准化

#引言 在机器学习中&#xff0c;特征缩放和学习率是两个非常重要的概念&#xff0c;它们对模型的性能和训练速度有显著影响。 特征缩放是指将数据集中的特征值缩放到一个固定的范围内&#xff0c;通常是在0到1之间或者标准化到均值为0、方差为1。特征缩放对于模型的训练至关重要…

Vmware安装openstack

安装虚拟机 创建完成后&#xff0c;点击开启虚拟机 稍等执行成功后 上传压缩包到指定目录。将yoga_patch.tar.gz包上传至/root目录下&#xff0c;将stack3_without_data.tar.gz包使用WinSCP上传至/opt目录下 vim run_yoga.sh #/bin/bash cd /root sudo apt-get update tar -xzv…

java面向对象总结

java面向对象篇到这里就已经结束了&#xff0c;有什么不懂的地方可以逐一进行重新观看。希望大家能够从入门到起飞。 Java面向对象基础篇综合训练&#xff08;附带全套源代码及逐语句分析&#xff09;-&#xff1e;基于javabeen Java面向对象进阶篇综合训练&#xff08;附带全…

如何跨专业通过软件设计师考试

链接&#xff1a;如何跨专业通过软件设计师-软件中级职称考试 (qq.com)

经济下行,企业还在“裁员至上”?

最近小红书、B站崩溃&#xff0c;又延伸到某云服务厂商问题频发&#xff0c;让人忍不住戏谑&#xff1a;“这算不算裁员裁到大动脉&#xff1f;” 在阿道看来&#xff0c;各大企业的裁员动作&#xff0c;绕不开的依旧是“人月神话”&#xff1a;盲目加人带来的是成本的倍增和效…

STKMATLAB 卫星编队覆盖分析纯代码实现

任务描述 设置卫星编队&#xff08;沿航迹编队&#xff0c;大斜视角&#xff0c;幅宽100km&#xff0c;下视角30&#xff0c;斜视角26&#xff09;&#xff0c;设置分析区域&#xff08;中国全境&#xff09;&#xff0c;设置FigureOfMerit&#xff08;展示覆盖率&#xff09;…