当前位置: 首页 > article >正文

【Golang 面试题】每日 3 题(二十七)

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

79. Go defer 关键字是什么?

定义:

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

使用场景:

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

优点:

方便开发者使用。

缺点:

有性能损耗。

80. 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
}

81. Go defer 代码示例

代码示例:

  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
  1. 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
  1. 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
  1. 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.kler.cn/a/503611.html

相关文章:

  • java fastjson2将 map、实体类、list等 类型转换为JSON介绍
  • BUUCTF:web刷题记录(1)
  • Oracle和MySQL的语法有什么区别
  • Spring Boot中的配置文件有哪些类型
  • 【Lua学习之旅】之单行/多行注释
  • 0基础跟德姆(dom)一起学AI 自然语言处理13-注意力机制介绍2
  • 【大数据】机器学习-----模型的评估方法
  • 微服务中引入消息队列的利弊
  • nginx 简单实践:静态资源部署、URL 重写【nginx 实践系列之一】
  • 使用 configparser 读取 INI 配置文件
  • PHP Filesystem
  • conda管理Python库和虚拟环境
  • 数据挖掘实训:天气数据分析与机器学习模型构建
  • 【RAG学习】如何使用大型语言模型?提示工程、RAG、微调或预训练,什么时候需要哪个
  • 面试题:Java中并发的三大特性
  • .Net Core Record 类型
  • 《银行保险机构数据安全管理办法》正式实施,分类分级、安全评估共筑安全防线
  • MVC如何使用任务调度
  • 基于springboot航空售票及管理系统
  • Duke Humanoid:利用被动动力学实现节能双足机器人