Go语言里面的各种疑难杂症

2023-11-20

  • 什么是闭包?闭包有什么缺陷?
func AddUpper() func(int)int{
  var n int =10
  return func (x int) int{
    n = n+x
    return n
  }
}

func main(){
  f := AddUpper()
  fmt.Println(f(1))//11
  fmt.Println(f(2))//13
  fmt.Println(f(3))//16
}

(1) AddUpper是一个函数,返回的数据类型是func (int) int
(2)闭包可以这么理解:返回一个匿名函数,但是这个匿名函数引用到了函数外的n,因此这个匿名函数就和n形成一个整体,构成闭包。
(3)也可以理解为:闭包是类,函数是操作,n是字段。函数和它使用到的n构成闭包。
(4)当我们反复调用f函数时,因为n是初始化一次,因此每调用一次就进行一次累计。
(5)搞清楚闭包的关键,就是分析出返回的函数它使用到哪些变量。
缺陷:闭包的缺陷大家可以搜索下,有一堆的缺陷,什么可读性差、性能问题等等。但是,我个人认为最为重要的一点是匿名函数和函数外的变量生命周期不一致这点导致的问题。如果匿名函数的生命周期比外部变量长,那么外部变量便无法被及时回收,导致内存泄漏;反之,如果匿名函数的生命周期比外部变量短,则会出现一个有意思的现象,匿名函数所引用到的外部变量值不一致。

  • 什么情况下会出现栈溢出?
    (1)递归调用层数过深
    (2)无限循环
    (3)大量的函数调用嵌套:在某些情况下,如果函数调用层次过深,每次函数调用都会在栈上分配一些临时变量,当调用层次太多,栈可能会耗尽。
    (4)大规模的局部变量分配:如果一个函数内部有大量的局部变量需要分配,且这些变量占用控件比较大,也有可能导致栈溢出。

  • 什么是不定参数?调用方法时,不定参数可以传入0个值吗?方法内部怎么使用不定参数?
    不定参数是指函数或方法的参数数量是不确定的,并且可以接受任意数量的参数。在Go语言中,可以使用"…“语法来表示不定参数。
    在函数或方法的参数列表中,使用”…"来指定不定参数的类型。例如,func sum(numbers ...int)表示sum函数接受任意数量的int类型参数。
    在调用方法时,不定参数可以传入0个值。如果不定参数传入了0个值,那么在方法内部,不定参数的长度为0,即切片的长度为0。
    对于不定参数,在方法内部可以像操作普通切片一样使用。可以对不定参数进行迭代、切片操作,也可以将其传递给需要切片参数的函数或方法。
    以下是一个示例:

func sum(numbers ...int) int {
 total := 0
    for _, num := range numbers  
          total += num
       return total
}  
func main(){
    fmt.Println(sum(1, 2, 3))        // 输出:6
    fmt.Println(sum(4, 5, 6, 7, 8))  // 输出:30
    fmt.Println(sum())               // 输出:0,传入0个值
}   

在sum函数内部,不定参数numbers会作为一个int类型的切片。使用range关键字迭代不定参数,对每个元素进行累加操作。当传入0个值时,不定参数切片的长度为0,返回0。

  • 什么是defer?解释下defer的运作机制?
    在Go语言中,defer用于注册延迟执行的函数(或方法)调用,即在函数结束之前执行某个操作。defer语句会将要执行的函数压入一个栈中,当外围函数执行完毕时,栈中的函数按照先进后出的顺序执行。
    defer语句使用关键字"defer"加上要延迟执行的函数调用语句。可以在函数内部的任意位置使用defer语句,多个defer语句的执行顺序与声明顺序相反。
    以下是一个示例:
func main() {
 defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")
    fmt.Println("Hello")
}  

输出结果为:

Hello
3
2
1

在上面的示例中,"Hello"会先被打印出来,然后依次执行defer语句中的函数调用,按照逆序打印数字1、2、3。

defer通常用于释放资源、关闭打开的文件、解锁互斥锁等操作。当函数包含多个defer语句时,可以确保资源的释放和清理操作会在函数结束时执行,无论函数是正常返回还是发生异常。

需要注意的是,defer延迟执行的函数调用参数在defer语句出现时就会求值,而不是在函数返回时才求值。因此,在使用defer时要注意传递参数的值是否符合预期。
至于defer的实现机制:大家可以参考这篇博客:https://blog.csdn.net/weixin_41663412/article/details/104914850

  • 一个方法内部的defer能不能超过8个?
    可以,只不过超过8个,就不能使用开放编码机制。

  • defer内部能不能修改返回值?怎么改?
    在Go语言中,defer语句是在函数返回之前执行的。虽然可以在defer语句中修改函数内部局部变量的值,但是无法直接修改函数的返回值。
    但是,如果函数的返回值是通过命名返回值(named return values)方式定义的,那么可以在defer语句中修改返回值。命名返回值允许我们在函数体中为返回值赋值,并且可以在函数体中的任意位置随时修改返回值。
    下面是一个示例代码:

package main

import "fmt"

func example() (result int) {
	defer func() {
		result = 100 // 在defer语句中修改返回值
	}()

	result = 10 // 正常的返回值赋值

	return result // 返回值为修改后的值
}

func main() {
	fmt.Println(example()) // 输出结果为100
}

在上述示例中,我们在defer语句中修改了返回值result的值,并且最终的返回结果被修改为了100。这是因为defer语句会在函数返回之前执行,所以最后的返回值会受到defer语句的影响。

  • 数组和切片有什么区别?
    数组和切片是Go语言中常用的数据结构,它们有以下几点区别:
  1. 长度固定 vs. 长度可变:数组的长度是固定的,定义时需要指定长度,并且无法修改。而切片的长度是可变的,可以根据需要进行动态扩容或裁剪。

  2. 数据存储方式:数组的元素在内存中是连续存储的,而切片则是一个对数组的引用,并包含了指向底层数组的指针、长度和容量等信息。

  3. 传递方式:通过值传递 vs. 通过引用传递:在函数间传递数组时,实际上是进行值传递,即将整个数组的副本传递给函数。而传递切片时,只是将切片的引用(指针)传递给函数,因此不会复制整个切片的内容,函数内部对切片进行的修改会反映到原始切片中。

  4. 使用方式:数组通常用于表示具有固定长度的集合,而切片则更适合处理动态变化的集合。切片提供了丰富的内置函数,如追加元素、裁剪切片、复制切片等,这些操作在数组上通常无法直接进行。

总的来说,数组适合用于长度固定,不需要频繁修改的情况;而切片则更具灵活性,适合处理长度变化、需要频繁操作的集合。
在这里插入图片描述

  • 切片怎么扩容?
    在这里插入图片描述
    扩容系数:当容量小于256(新版,旧版为1024)的时候,2倍扩容;否则按照1.25倍扩容。
    一开始是2倍扩容主要是为了提高内存的利用率和减少扩容的次数。当容器中的元素数量超过当前容量时,需要对容器进行扩容。通过将容量扩大到原来的2倍,可以在一定程度上减少扩容次数,因为每次扩容都需要重新分配更大的内存空间,并将原有数据复制到新的内存中,这个过程是比较耗时的。
    而后面改为1.25倍扩容是为了避免在容器元素数量较大时,扩容过程占用过多的内存空间。当容器的元素数量较大时,每次扩容后容量增加的幅度相对较小,这样可以更加灵活地利用内存,并且减少不必要的内存浪费。
    综上所述,一开始是2倍扩容可以提高内存利用率和减少扩容次数,后面改为1.25倍扩容可以减少内存占用和内存浪费。

切片的扩容与缩容:https://blog.csdn.net/qq_20867981/article/details/86467539

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go语言里面的各种疑难杂症 的相关文章

随机推荐

  • 单级和串级pid原理分析以及pid应用与小车的技巧

    这篇文章主要是帮助理解和使用pid 不会讲复杂的代码公式 重点在最后 一定要看到最后 pid可以看作是一种控制器 用来控制某个变量达到你想要的地步 单级pid 这里我举个例子来理解一下 假设有一个水缸 最终的控制目的是要保证水缸里的水位永远
  • 一文讲透彻!RobotFramwork测试框架教程(全能)

    Robot Framwork在业界早已名声大振 有很多刚学自动化测试的伙伴问我 有没有不需要编程就可以玩自动化的方法 有吗 有的 Robot Framwork 我们今天就一篇文章 把它讲得明明白白 一 Robot Framwork简述 Ro
  • 软件外包开发的测试用例

    软件测试用例是一组详细的步骤 输入数据 预期结果和实际结果 用于验证软件是否满足特定需求或功能 编写测试用例的目的是确保软件的质量和性能 今天和大家分享编写软件测试用例的一般步骤 希望对大家有所帮助 北京木奇移动技术有限公司 专业的软件外包
  • 使用web3和infura开发以太坊ethereum区块链

    web3 Github https github com ethereum web3 js web3 js是以太坊提供的一个Javascript库 它封装了以太坊的RPC通信API 提供了一系列与区块链交互方法 使js与以太坊交互变得简单
  • Netty网络框架

    buffer 缓冲区 S2 Channel的flush方法 发送缓冲区中的数据并清空 gt buffer 缓冲区 buffer 发送 gt S3 SocketChannel write 将数据写入到缓冲区 flush 发送缓冲区中的数据并进
  • db2实现两个数相减_DB2 日期相减

    标签 简单方法 使用 days 字符型的日期 2012 01 01 2012 01 11 values days date 2012 01 11 days date 2012 01 01 10 错误示例 sql Append LEFT JO
  • ARM developer suit v1.2免安装教程

    博主按照网上的步骤安装了不下10遍ads 很生气 一次都没成功过 然后卸载后 继续安装 总是出现modify repait unistall那个界面 以为没有卸干净 然后按照网上的删注册表记录的方法 电脑第二天就开不了机了 当然还是没装成功
  • 路由器简单认识

    路由器 是一个三层设备 可以解析到三层 第一层是比特流 电压 电信号 第二层是数据帧 从比特流到数据帧的过程也叫格式化 可以看到MAC地址 第三层是数据包 IP地址 网络层 交换机 网桥 二层设备 区别 1 交换机基于硬件处理 网桥基于软件
  • 简单介绍十几款常用的画架构图流程图的软件

    简单介绍十几款常用的画架构图流程图的软件 draw io draw io是开源免费的在线画图工具 还提供桌面版本 特性 实时协作 支持在线离线版本 存储支持多种方式 Google Drive OneDrive GitHub GitLab D
  • 非常优秀的网站设计案例,设计师必备

    厚积才能薄发 一个优秀的设计师的天性一定是想要获得更多网站设计灵感 擅于为新项目寻找创意切入点 搜索设计参考资源 最新的设计趋势 今天为大家带来了一组免费可商用的网站设计案例 通过这些网站设计案例 你可以获得 寻找不同风格的网站灵感 配色
  • 硬件工程师-三极管

    目录 一 机械开关 二 三极管的种类 三 NPN型三极管 N型三极管 四 PNP型三极管 编辑 五 三极管公式 NPN型三极管 PNP型三极管 六 NPN管的继续讲解 三极管的导通电压 PNP管也是一样 三极管的三种状态 判断三极管是放大还
  • 抖音SEO矩阵系统源码开发部署(二)技术搭建+二次开发

    抖音SEO矩阵系统源码开发 是一项技术密集型工作 需要对大数据处理 人工智能等领域有深入了解 该系统开发过程中需要用到多种编程语言 如Java Python等 同时 需要使用一些框架和技术 如Hadoop Spark PyTorch等 以提
  • 文件搜索工具(Python实现)

    文章目录 文件搜索工具介绍 代码实现 实现思路 os walk函数 os path join函数 代码整体编写 打包成exe程序 效果展示 文件搜索工具介绍 文件搜索工具能够基于名称快速定位匹配的文件和文件夹位置 比如Everything就
  • 原来实现GCP用客户端登录这么简单啊

    充满活力的一天开始了 GCP 就是谷歌的一个云服务 进入VM实例列表通过 SSH 点击 在浏览器窗口打开 进入VPS服务器 下图 切换到管理员用户 sudo i 编辑sshd config文件 vi etc ssh sshd config
  • 一个jq投票,无论成功与否3秒后自动关闭提示框

    原文地址 http blog csdn net zjb574 article details 7759447
  • 超详细的Vue-router (路由)

    由于Vue在 开发时对路由支持的不足 于是官方补充了vue router插件 vue的单页面应用是基于路由和组件的 路由用于设定访问路径 并将路径和组件映射起 来 传统的页面应用 是用一些超链接来实现页面切换和跳转的 在vue router
  • 解决vCharts不兼容Echarts5+版本问题

    背景 在实际开发项目中 发现老项目里同时用到了vCharts和Echarts 此时的Echarts是低版本 并不会出现问题 但在漏洞扫描中Echarts需升级 此时项目开始报错 v charts 不能和echarts5 版本同时存在 当时的
  • 如何快速构建CMBD系统-glpi

    脚本后续更新及迭代将由kkitDeploy项目代替 https github com luckman666 kkitdeploy server 请大家持续关注kkitDeploy 一 CMBD系统构建步骤 起初 开发这套CMBD系统是为了帮
  • 华为OD机试真题-最大平分数组【2023Q1】

    题目描述 给定一个数组nums 可以将元素分为若干个组 使得每组和相等 求出满足条件的所有分组中 最大的平分组个数 输入描述 第一行输入 m 接着输入m个数 表示此数组 数据范围 1 lt M lt 50 1 lt nums i lt 50
  • Go语言里面的各种疑难杂症

    什么是闭包 闭包有什么缺陷 func AddUpper func int int var n int 10 return func x int int n n x return n func main f AddUpper fmt Prin