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

news2024/12/25 12:14:43
  • 什么是闭包?闭包有什么缺陷?
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

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

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

相关文章

Three.js 实现模型材质分解,拆分,拆解效果

原理:通过修改模型材质的 x,y,z 轴坐标 positon.set( x,y,z) 来实现拆解,分解的效果。 注意:支持模型材质position 修改的材质类型为 type“Mesh” ,其他类型的材质修改了position 可能没有实际效果 在上一篇 Three.js加载外部glb,fbx,gltf…

小研究 - Android 字节码动态分析分布式框架(二)

安卓平台是个多进程同时运行的系统,它还缺少合适的动态分析接口。因此,在安卓平台上进行全面的动态分析具有高难度和挑战性。已有的研究大多是针对一些安全问题的分析方法或者框架,无法为实现更加灵活、通用的动态分析工具的开发提供支持。此…

代码生成综述

代码生成大模型属于LLM模型的一个子类,理论来讲也是属于语言模型的一种特例。代码本身其实也是一种特殊的语言表示,所以代码模型的实现应该是具备通用自然语言和代码两部分的能力。实际的代码模型也是有两条路径来实现,让训练好的NLP LLM模型…

IPv4,IPv6,TCP,路由

主要回顾一下TCP/IP的传输过程,在这个过程中,做了什么事情 ip : 网际协议,IP协议能让世界上任意两台计算机之间进行通信。 IP协议的三大功能: 寻址和路由传递服务:不可靠(尽最大努力交付传输数据包&…

数据仓库一分钟

数据分层 一、数据运营层:ODS(Operational Data Store) “面向主题的”数据运营层,也叫ODS层,是最接近数据源中数据的一层,数据源中的数据,经过抽取、洗净、传输,也就说传说中的 ETL…

模板方法模式(十六)

相信自己,请一定要相信自己 上一章简单介绍了代理模式(十五), 如果没有看过, 请观看上一章 一. 模板模式 引用 菜鸟教程里面的 模板模式介绍: https://www.runoob.com/design-pattern/template-pattern.html 在模板模式(Template Pattern)…

什么是PPS和TOD时序?授时防护设备是什么?

介绍 PPS和TOD PPS和TOD是两种用于精确时间同步的技术,它们在许多领域都有广泛的应用,总的来说,PPS和TOD被广泛应用于各种需要高度精确时间同步的领域,包括通信、测量、测试、系统集成和计算机网络等。 一、PPS PPS&#xff08…

Zookeeper集群单节点启动成功但未同步其他节点数据

首先排查节点启动是否正常: 在zookeeper的bin目录下执行:sh zkServer.sh status 判断当前节点数据leader 还是follower 节点都启动正常,但某一个zookeeper集群节点(下面简称“异常节点”)不同步其他节点数据&#xf…

redis高级----------主从复制

redis的四种模式:单例模式;主从模式;哨兵模式,集群模式 一、主从模式 单例模式虽然操作简单,但是不具备高可用 缺点: 单点的宕机引来的服务的灾难、数据丢失单点服务器内存瓶颈,无法无限纵向扩…

flink sql checkpoint 调优配置

- execution.checkpointing.interval: 检查点之间的时间间隔(以毫秒为单位)。在此间隔内,系统将生成新的检查点 SET execution.checkpointing.interval 6000; - execution.checkpointing.tolerable-failed-checkpoints: 允许的连续失败检查…

大数据与移动应用开发技术综合实训室建设方案

一 、系统概述 大数据与移动应用开发技术综合作为新一代信息技术的重点和促进信息消费的核心产业,已成为我国转变信息服务业的发展新热点:成为信息通信领域发展最快、市场潜力最大的业务领域。互联网尤其是移动互联网,以其巨大的信息交换能力…

bh002- Blazor hybrid / Maui 使用ORM和数据库快速教程

接上篇 bh002- Blazor hybrid / Maui 保存设置快速教程 源码 10. 添加引用 Index.razor.cs 添加引用 using FreeSql.DataAnnotations; #if WINDOWS using Windows.Storage; #endif 11. 简单使用freesql ORM 初始化数据,添加数据 public partial class Index {[DisplayNam…

2022年06月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:制作蛋糕 小A擅长制作香蕉蛋糕和巧克力蛋糕。制作一个香蕉蛋糕需要2个单位的香蕉,250个单位的面粉,75个单位的糖,100个单位的黄油。制作一个巧克力蛋糕需要75个单位的可可粉,200个单位的面粉,150个单位的糖,150个单位的黄油。一个香蕉蛋糕可以卖出400元,而一个巧…

Matlab论文插图绘制模板第108期—特征渲染的标签散点图

在之前的文章中,分享了Matlab标签散点图的绘制模板: 进一步,再来分享一下特征渲染的标签散点图的绘制模板,以便再添加一个维度的信息。 先来看一下成品效果: 特别提示:本期内容『数据代码』已上传资源群中…

蓝凌OA custom.jsp 任意文件读取

​曾子曰:“慎终追远,民德归厚矣。” 漏洞复现 访问漏洞url: 出现漏洞的文件为 custom.jsp,构造payload: /sys/ui/extend/varkind/custom.jsp var{"body":{"file":"file:///etc/passwd&q…

ESP32-新建工程

目录 本文简介 实验平台 正文 一、安装开发环境 1、安装内容 2、启动 ESP-IDF 环境 二、开始创建工程 三、配置工程 四、编译工程 五、烧录到设备 六、监视输出 七、在工程中创建自己的文件夹 本文简介 idf.py 命令行工具提供了一个前端,可以帮助您轻松…

在Windows下安装PIP+Phantomjs+Selenium

最近准备深入学习Python相关的爬虫知识了,如果说在使用Python爬取相对正规的网页使用"urllib2 BeautifulSoup 正则表达式"就能搞定的话;那么动态生成的信息页面,如Ajax、JavaScript等就需要通过"Phantomjs CasperJS Selen…

DP读书:鲲鹏处理器 架构与编程(八)3.1鲲鹏处理器片上系统与Taishan处理器内核架构

鲲鹏处理器片上系统架构 一、鲲鹏处理器片上系统与Taishan处理器内核架构1. 鲲鹏处理器片上系统概况a. 鲲鹏处理器片上系统与鲲鹏芯片家族b. 鲲鹏920处理器片上系统的组成部件c. 鲲鹏920处理器片上系统的特征d. 鲲鹏920处理器片上系统的逻辑结构 2. Taishan V110 处理器内核微架…

greenplum gpfdist外部表(只读)的实现---理论

经过项目的验证测试以及初步商用化,本篇将进一步讲解greenplum外部表的实现原理,包括设计原则、交互协议与实现流程。gpfdist工具的简介与使用见回顾greenplum gpfdist工具。 1 设计原则 greenplum作为分布式分析型数据库,其每个节点都是独立…

使用ChatGPT-4优化编程效率:高效查询代码示例和解决方案

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…