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

  • 什么是闭包?闭包有什么缺陷?
func AddUpper() func(int)int{var n int =10return func (x int) int{n = n+xreturn n}
}func main(){f := AddUpper()fmt.Println(f(1))//11fmt.Println(f(2))//13fmt.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 := 0for _, num := range numbers  total += numreturn total
}  
func main(){fmt.Println(sum(1, 2, 3))        // 输出:6fmt.Println(sum(4, 5, 6, 7, 8))  // 输出:30fmt.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 mainimport "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

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

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

相关文章

重排链表(C语言)

题目: 示例: 思路: 这题我们将使用栈解决这个问题,利用栈先进后出的特点,从链表的中间位置进行入栈,寻找链表的中间位置参考:删除链表的中间节点,之后从头开始进行连接。 本题使用…

【C++】异常

异常 前言正式开始C语言传统的处理错误的方式C异常概念异常的使用异常的抛出和捕获自定义异常体系实际中的应用异常的重新抛出 异常安全异常规范C标准库的异常体系异常的优缺点 前言 从这篇开始,我后面的几篇可以算是C的收尾了。 本篇讲异常。 正式开始 先说说C…

MyBatis分页插件PageHelper的使用及特殊字符的处理

目录 一、PageHelper简介 1.什么是分页 2.PageHelper是什么 3.使用PageHelper的优点 二、PageHelper插件的使用 原生limit查询 1. 导入pom依赖 2. Mybatis.cfg.xml 配置拦截器 3. 使用PageHelper进行分页 三、特殊字符的处理 1.SQL注入: 2.XML转义&#…

Arduino程序设计(四)按键消抖+按键计数

按键消抖按键计数 前言一、按键消抖二、按键计数1、示例代码2、按键计数实验 参考资料 前言 本文主要介绍两种按键控制LED实验:第一种是采用软件消抖的方法检测按键按下的效果;第二种是根据按键按下次数,四个LED灯呈现不同的流水灯效果。 一…

什么是负载均衡

前提概述 关于负载均衡,我会从四个方面去说 1. 负载均衡产生的背景 2. 负载均衡的实现技术 3. 负载均衡的作用范围 4. 负载均衡的常用算法 负载均衡的诞生背景 在互联网发展早期,由于用户量较少、业务需求也比较简单。对于软件应用,我们只需要…

《Zookeeper》源码分析(二十)之 Follower

目录 Follower创建Follower实例followLeader()findLeader()connectToLeader()registerWithLeader()syncWithLeader() FollowerZooKeeperServer Follower Leader选举结束后,成为Follower的服务器开始进行Follower的工作,过程如下: 与Leader…

计算机终端核心安全配置规范

声明 本文是学习 政务计算机终端核心配置规范. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 范围 本标准提出了政务计算机终端核心配置的基本概念和要求,规定了核心配置的自动化实现方法,规范了核心配置实施流程。 本标准适…

【Terraform学习】使用 Terraform 创建Amazon VPC(Terraform-AWS最佳实战学习)

使用 Terraform 创建Amazon VPC 实验步骤 前提条件 安装 Terraform: 地址 下载仓库代码模版 本实验代码位于 task_vpc 文件夹中。 变量文件 variables.tf 在上面的代码中,您将声明,aws_access_key,aws_secret_key和 区域变量…

Linux搭建SSLVpn

安装http、ssl服务 编辑http配置文件 修改http的136行,276行以及990行 1、136行将监听端口注释 2、276行和990行修改为自己的域名和要访问的端口 修改http文档最后那部分 新添ssl配置信息,将端口修改为443(截图错了server.key应该放在/etc/…

jenkins Linux如何修改jenkins 默认的工作空间workspace

由于jenkins默认存放数据的目录是/var/lib/jenkins,一般这个var目录的磁盘空间很小的,就几十G,所以需要修改jenkins的默认工作空间workspace 环境 jenkins使用yum安装的 centos 7 正题 1 查看jenkins安装路径 [rootlocalhost jenkins_old_data]# rpm…

【80天学习完《深入理解计算机系统》】第九天 3.2 数据传送指令【mov】【栈和堆】【leaq】【一元操作】【二元操作】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)   文章字体风格: 红色文字表示&#…

基于AWS的3D模型搜索服务实现

3D模型广泛应用于计算机游戏、电影、工程、零售业、广告等许多领域。市场上有很多制作3D模型的工具,但几乎没有工具可以直观地搜索3D模型数据库以找到类似的3D模型 因为开发好的 3D 模型搜索工具非常具有挑战性。 它需要复杂的计算和 AI/ML 框架来创建模型描述符并提…

【MySQL系列】Select语句单表查询详解(二)ORDERBY排序

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

C语言:选择+编程(每日一练Day8)

目录 选择题: 题一: 题二: 题三: 题四: 题五: 编程题: 题一:字符个数统计 思路一: 题二:多数元素 思路一: 本人实力有限可能对一些…

k8s 安装 istio(二)

3.3 部署服务网格调用链检测工具 Jaeger 部署 Jaeger 服务 kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.16/samples/addons/jaeger.yaml 创建 jaeger-vs.yaml 文件 apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata…

【面试】一文讲清组合逻辑中的竞争与冒险

竞争的定义:组合逻辑电路中,输入信号的变化传输到电路的各级逻辑门,到达的时间有先后,也就是存在时差,称为竞争。 冒险的定义:当输入信号变化时,由于存在时差,在输出端产生错误&…

使用haproxy搭建web架构

haproxy HAProxy是一个免费的负载均衡软件,可以运行于大部分主流的Linux操作系统上。 HAProxy提供了可以在七层和四层两种负载均衡能力,它可以提供高可用性、负载均衡、及基于TCP和HTTP应用的代理。适用于负载大的Web站点,在运行在硬件上可…

企业工程项目管理系统源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理) em

​ 工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

mysql数据库root密码遗忘后,修改root密码

目录 方式一: 方式二: 2.1 也可以像我这样,普通用户登录进去后 2.2 执行如下命令,将已知的user1的加密密文更新到root中 2.3 查询数据库 2.4 用root用户登录 2.5 登录正常,但这会root登录进去后,无法…

2023深圳智博会,正运动助力智能装备“更快更准”更智能!

■展会名称: 2023 深圳国际智能装备产业博览会暨深圳国际电子装备产业博览会(以下简称“EeIE 智博会”) ■展会日期 2023年8月29日-31日 ■展馆地点 深圳国际会展中心(宝安新馆) ■展位号 3B030 正运动技术,作为国内领先的…