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

news2025/1/4 7:05:09

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

34. Golang Slice 的扩容机制,有什么注意点?

Go 语言中的切片(Slice)具有动态扩容的能力。当切片容量不足以容纳更多元素时,就需要扩容。切片的扩容机制是在原切片容量的基础上扩容,一般是容量的 2 倍或者 1.25 倍,具体扩容的倍数由实现算法决定。以下是关于切片扩容的一些注意点:

  1. 切片扩容会重新分配一块连续的内存空间,因此需要将原切片中的元素复制到新的内存空间中,这个过程可能会比较耗时。
  2. 在使用 append() 函数向切片添加元素时,如果添加的元素个数超出了切片的容量,那么就会触发扩容操作。
  3. 切片扩容会导致原切片和新切片指向不同的内存空间,因此原切片的修改不会影响新切片的值。
  4. 切片扩容并不是每次添加元素都会触发,而是当切片容量不足以容纳更多元素时才会触发。
  5. 当切片容量小于 1024 时,扩容时新的容量会翻倍;当容量大于等于 1024 时,新的容量会增加原来容量的 1/4,也就是乘以 1.25。
  6. 由于切片底层是基于数组实现的,因此切片扩容时,如果原数组的容量不足以容纳新的元素,也会触发数组的重新分配和拷贝。

总之,切片的扩容机制需要注意性能和内存问题,特别是在大规模数据处理中,应该尽量减少切片扩容的次数。

35. 扩容前后的 Slice 是否相同?

在 Golang 中,扩容前后的 Slice 是不同的。在进行 Slice 扩容时,会创建一个新的底层数组,并将原来的元素拷贝到新的数组中。因此,扩容前后的 Slice 指向的底层数组是不同的。

原因

Golang 中的 Slice 是基于数组实现的,因此在创建 Slice 时,底层会创建一个数组来存储数据。当 Slice 中的元素个数超过底层数组的容量时,就需要进行扩容。而在 Golang 中,数组的大小是固定的,无法进行扩容,因此需要创建一个新的底层数组,并将原来的元素拷贝到新的数组中。这样就可以实现 Slice 的扩容了。由于扩容后底层数组的地址已经发生了变化,因此扩容前后的 Slice 底层数组是不同的,即扩容前后的 Slice 不再共享底层数组。

36. Go slice 的底层实现原理

切片是基于数组实现的,它的底层是数组,可以理解为对底层数组的抽象。
源码包中 src/runtime/slice.go 定义了 slice 的数据结构:

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}
slice 占用 24 个字节:
- array: 指向底层数组的指针,占用 8 个字节。
- len: 切片的长度,占用 8 个字节。
- cap: 切片的容量,cap 总是大于等于 len 的,占用 8 个字节。
slice 有 4 种初始化方式:
// 初始化方式1:直接声明
var slice1 []int

// 初始化方式2:使用字面量
slice2 := []int{1, 2, 3, 4}

// 初始化方式3:使用make创建slice
slice3 := make([]int, 3, 5)         

// 初始化方式4: 从切片或数组“截取”
slcie4 := arr[1:3]

通过一个简单程序,看下 slice 初始化调用的底层函数。

package main

import "fmt"

func main() {
    slice := make([]int, 0)
    slice = append(slice, 1)
    fmt.Println(slice, len(slice), cap(slice))
}

通过 go tool compile -S test.go | grep CALL 得到汇编代码。

0x0042 00066 (test.go:6)        CALL    runtime.makeslice(SB)
0x006d 00109 (test.go:7)        CALL    runtime.growslice(SB)
0x00a4 00164 (test.go:8)        CALL    runtime.convTslice(SB)
0x00c0 00192 (test.go:8)        CALL    runtime.convT64(SB)
0x00d8 00216 (test.go:8)        CALL    runtime.convT64(SB)
0x0166 00358 ($GOROOT/src/fmt/print.go:274)     CALL    fmt.Fprintln(SB)
0x0180 00384 (test.go:5)        CALL    runtime.morestack_noctxt(SB)
0x0079 00121 (<autogenerated>:1)        CALL    runtime.efaceeq(SB)
0x00a0 00160 (<autogenerated>:1)        CALL    runtime.morestack_noctxt(SB)

初始化 slice 调用的是 runtime.makeslice,makeslice 函数的工作主要就是计算 slice 所需内存大小,然后调用 mallocgc 进行内存的分配。

所需内存大小 = 切片中元素大小 * 切片的容量

func makeslice(et *_type, len, cap int) unsafe.Pointer {
    mem, overflow := math.MulUintptr(et.size, uintptr(cap))
    if overflow || mem > maxAlloc || len < 0 || len > cap {
        // NOTE: Produce a len out of range error instead of a
        // cap out of range error when someone does make([]T, bignumber).
        // cap out of range is true too, but since the cap is only being
        // supplied implicitly, saying len is clearer.
        // See golang.org/issue/4085.
        mem, overflow := math.MulUintptr(et.size, uintptr(len))
        if overflow || mem > maxAlloc || len < 0 {
            panicmakeslicelen()
        }
        panicmakeslicecap()
    }

    return mallocgc(mem, et, true)
}

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

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

相关文章

npm ERR! ECONNRESET 解决方法

问题&#xff1a;npm 命令遇到的错误是 ECONNRESET&#xff0c;这通常与网络连接问题相关。设置代理解决问题。 一、查看当前代理设置 npm config get proxy npm config get https-proxy二、设置代理 npm config set proxy http://your-proxy-address:port npm config set h…

单元测试3.0+ @RunWith(JMockit.class)+mock+Expectations

Jmockit使用笔记_基本功能使用Tested_Injectable_Mocked_Expectations_jmockit.class-CSDN博客 测试框架Jmockit集合junit使用 RunWith(JMockit.class) 写在测试案例类上的注解 Tested 在测试案例中,写在我们要测试的类上面, 一般用实现类 Injectable 在测试案例中声明…

网络渗透测试实验二:网络嗅探与身份认证

1.实验目的和要求 1、通过使用Wireshark软件掌握Sniffer&#xff08;嗅探器&#xff09;工具的使用方法&#xff0c;实现捕捉HTTP等协议的数据包&#xff0c;以理解TCP/IP协议中多种协议的数据结构、通过实验了解HTTP等协议明文传输的特性。 2、研究交换环境下的网络嗅探实现…

mqtt连接onenet云平台

密码 version2018-10-31&resproducts%2FlzNd7drwE2%2Fdevices%2Flocation_1&et1756617761&methodmd5&sign52jsIUhK7i2zXjlEtkwDhQ%3D%3D 设备名称&#xff1a;temperatureAndHumidity 设备密钥&#xff1a;bE5OSHBlTHU3TDNSUUVoTmY0WWZqbThDVzNjOUJ3Y1Y 产品i…

Neo4j GDS 2.0 安装与配置

Neo4j GDS 2.0 安装与配置 GDS插件安装&#xff1a;Neo4j官方文档 1. GDS简介 Neo4j Graph Data Science (GDS) 库作为 Neo4j Graph Database 的插件提供。该插件需要安装到数据库中并在 Neo4j 配置中列入白名单。有两种主要方法可以实现这一点&#xff0c;我们将在本章中详…

艾体宝方案丨全面提升API安全:AccuKnox 接口漏洞预防与修复

一、API 安全&#xff1a;现代企业的必修课 在现代技术生态中&#xff0c;应用程序编程接口&#xff08;API&#xff09;扮演着不可或缺的角色。从数据共享到跨平台集成&#xff0c;API 成为连接企业系统与外部服务的桥梁。然而&#xff0c;伴随云计算的普及与微服务架构的流行…

使用JMeter对Linux生产服务器进行压力测试

安装 JMeter wget https://downloads.apache.org/jmeter/binaries/apache-jmeter-5.4.1.tgz tar -xzf apache-jmeter-5.4.1.tgz cd apache-jmeter-5.4.1创建 JMeter 脚本 设置中文 选择Options—>Choose Language—>选择其他语言&#xff08;例如&#xff1a;Chinese&am…

位置编码--RPE

相对位置编码 (Relative Position Encoding, RPE) 1. 相对位置编码 相对位置编码是 Transformer 中的一种改进位置编码方式&#xff0c;它的主要目的是通过直接建模序列中元素之间的相对位置&#xff0c;而不是绝对位置&#xff0c;从而更好地捕捉序列元素之间的依赖关系&#…

《代码随想录》Day21打卡!

写在前面&#xff1a;祝大家新年快乐&#xff01;&#xff01;&#xff01;2025年快乐&#xff0c;2024年拜拜~~~ 《代码随想录》二叉树&#xff1a;修剪二叉搜索树 本题的完整题目如下&#xff1a; 本题的完整思路如下&#xff1a; 1.本题使用递归进行求解&#xff0c;所以分…

【mysql】linux安装mysql客户端

参考文章&#xff1a; MySQL系列之如何在Linux只安装客户端 linux下安装mysql客户端client MySQL Community Downloads 查看linux版本方法&#xff1a; lsb_release -a cat /proc/version下载文件&#xff1a; rpm -ivh mysql-community-*可以删除错误的包&#xff1a; RP…

HTML——26.像素单位

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>像素</title></head><body><!--像素&#xff1a;1.指设备屏幕上的一个点&#xff0c;单位px&#xff0c;如led屏上的小灯朱2.当屏幕分辨率固定时&…

一键闪测仪:MLCC尺寸测量解决方案

MLCC是电子行业中常用的陶瓷电容器&#xff0c;其尺寸影响物理占用空间、电气性能和可靠性等&#xff0c;因此MLCC尺寸管控对产品质量至关重要。 在此&#xff0c;小优博士给各位介绍MLCC的概况以及MLCC尺寸快速测量解决方案。 一、MLCC概述 MLCC&#xff08;Multi-layer Cer…

Spring API 接口加密/解密

API 接口加密/解密 为了安全性需要对接口的数据进行加密处理&#xff0c;不能明文暴露数据。为此应该对接口进行加密/解密处理&#xff0c;对于接口的行为&#xff0c;分别有&#xff1a; 入参&#xff0c;对传过来的加密参数解密。接口处理客户端提交的参数时候&#xff0c;…

学习threejs,导入pdb格式的模型

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.PDBLoader pdb模型加…

Frontend - 分页(针对 python / Django )

目录 一、同个文件内&#xff08;方式一&#xff09; 1. 前端 html 2. 定义分页界面 3. 获取分页数据 4.后端根据前端分页需求&#xff0c;整理分页数据 5.显示情况 6. JsonResponse 相关知识 二、不同文件内依旧有效&#xff08;方式二&#xff0c;更优化&#xff09;…

[2474].第04节:Activiti官方画流程图方式

我的后端学习大纲 Activiti大纲 1.安装位置&#xff1a; 2.启动&#xff1a;

按照乘法分解10点结构

在行列可自由变换的平面上9点结构有1430个&#xff0c;10点结构有3908个。其中可被分解为2*5的有102个&#xff0c; 5a1*2a110a28 5a1*2a210a689 5a1*2a310a1722 5a2*2a110a172 5a2*2a210a1081 5a2*2a310a2006 5a3*2a110a275 5a3*2a210a1561 5a3*2a310a2381 5a4*2a110…

JVM实战—6.频繁YGC和频繁FGC的后果

大纲 1.JVM GC导致系统突然卡死无法访问 2.什么是Young GC什么是Full GC 3.Young GC、Old GC和Full GC的发生情况 4.频繁YGC的案例(G1解决大内存YGC过慢) 5.频繁FGC的案例(YGC存活对象S区放不下) 6.问题汇总 1.JVM GC导致系统突然卡死无法访问 (1)基于JVM运行的系统最怕…

word运行时错误‘-2147221164(80040154)’ 没有注册类的解决办法

目录 问题描述解决方案 问题描述 解决方案 打开C盘找到路径C:\Users\Administrator\AppData\Roaming\Microsoft\Word\STARTUP或者在everything中搜索“Microsoft\Word\STARTUP”删除NEWebWordAddin.dotm文件即可正确打开word。