切片的基础知识

在这里插入图片描述

文章目录

    • ● Slice 的底层实现原理?
    • ● array 和 Slice 的区别?
    • ● 拷贝大切片一定比小切片代价大吗?
    • ● Slice 深拷贝和浅拷贝?
    • ● 零切片、空切片、nil切片?
    • ● Slice 的扩容机制?
    • ● Slice 为什么不是线程安全的?如何解决这个问题?
    • ● 参数传递切片和切片指针有什么区别?
    • ● range 遍历切片的时候有什么要注意的?

● Slice 的底层实现原理?

切片是对底层数组的引用,在创建一个切片的时候,Go会自动分配一个底层数组,并维护这个数组的指针、切片的长度和容量。

● array 和 Slice 的区别?

1、数组是固定长度的,不能动态扩容,在编译期就会确定大小,切片是可以自动扩容的。 2、数组是值类型,切片是引用类型,每个切片都引用了一个底层数组,切片本身不能存储任何数据,都是底层数组存储数据,所以修改切片的时候修改的是底层数组中的数据。切片一旦扩容,指向一个新的底层数组,内存地址也就随之改变。

● 拷贝大切片一定比小切片代价大吗?

不一定。切片中的第一个字段是指向切片底层数组的指针,这是切片的存储空间,第二个字段是切片的长度,第三个字段是容量。将一个切片变量分配给另一个变量只会复制三个机器字,大切片跟小切片的区别无非就是 Len 和 Cap的值比小切片的这两个值大一些,如果发生拷贝,本质上就是拷贝上面的三个字段。

● Slice 深拷贝和浅拷贝?

浅拷贝是创建一个新的切片,但这个新切片仍然引用原切片的底层数组。 深拷贝是创建一个新的切片,并复制原来切片的所有元素到新的切片中。

● 零切片、空切片、nil切片?

零切片
我们把切片内部数组的元素都是零值或者底层数组的内容就全是 nil的切片叫做零切片,使用make创建的、长度、容量都不为0的切片就是零值切片:slice := make([]int,5) // 0 0 0 0 0 slice := make([]*int,5) // nil nil nil nil nil
nil切片
nil切片的长度和容量都为0,并且和nil比较的结果为true,采用直接创建切片的方式或new创建切片的方式:var slice []int var slice = *new([]int)
空切片
空切片的长度和容量也都为0,但是和nil的比较结果为false,因为所有的空切片的数据指针都指向同一个地址 0xc42003bda0;使用字面量、make可以创建空切片:var slice = []int{} var slice = make([]int, 0) 05. 切片的扩容策略

● Slice 的扩容机制?

新申请的容量如果大于当前容量的两倍,会将新申请的容量直接作为新的容量,如果新申请的容量小于当前容量的两倍,会有一个阈值,即当前切片容量小于256时,切片会将当前容量的2倍作为新申请的容量,如果大于等于256,每次容量会增加 (旧容量+3*256)/4。

● Slice 为什么不是线程安全的?如何解决这个问题?

切片的底层数据结构体包括一个指向数组的指针,在多个线程同时对 切片进行操作时会导致竞态条件。(并发读写问题、切片扩容问题) 通过使用适当的同步机制如互斥锁、读写锁,确保对切片的并发访问是安全的,从而避免竞态条件和数据破坏。 (竞态条件是指在并发程序中,由于多个线程或goroutine同时访问或修改共享资源,从而导致程序的执行结果依赖于线程或goroutine的调度顺序,可能产生不确定和错误的结果。)

● 参数传递切片和切片指针有什么区别?

当切片作为参数传递时,其实就是一个结构体的传递,因为Go语言参数传递只有值传递,传递一个切片就会浅拷贝原切片,但因为底层数据的地址没有变,所以在函数内对切片的修改,也将会影响到函数外的切片。
在 Go 语言中,切片虽然是引用类型,但在函数中使用 append 操作时,需要注意一些细节。append 函数可能会导致切片底层数组重新分配内存,从而影响切片的引用传递。
具体来说,当 append 导致切片容量不足而需要扩容时,append 操作会创建一个新的底层数组,并返回新的切片引用。
由于你没有将这个新引用返回给原切片,原切片仍然指向旧的底层数组,因此不会体现出引用传递的效果。
参数传递切片指针就很容易理解了,如果你想修改切片中元素的值,并且更改切片的容量和底层数组,则应该按指针传递。

● range 遍历切片的时候有什么要注意的?

副本与原始切片: 在range遍历中,实际上会创建每个元素的副本。这意味着你在循环中对副本的修改不会影响原始切片。如果需要修改原始切片,应该使用索引来操作。
只读: 默认情况下,range遍历是只读的,不能修改切片的元素。如果尝试在range循环中修改元素值,会引发编译错误。
索引和值的顺序: 在range循环中,索引总是在前,元素值总是在后。如果只需要索引而不需要元素值,可以使用下划线 _ 来忽略元素值。
切片遍历的性能考虑:尽管使用range遍历切片是非常方便的,但在性能方面可能会有一些影响。每次使用range遍历时,都会创建元素的副本,这可能导致额外的内存开销和性能下降。如果在性能敏感的场景下遇到性能问题,你可以考虑使用索引遍历,以避免创建副本。另外,如果需要在遍历时修改切片的元素,也应该使用索引遍历,以确保修改能够直接影响到原始切片。
切片为空: 如果切片为空,使用range遍历不会执行任何循环体,这可能会导致你的代码出现逻辑问题。在使用range之前,最好先检查切片的长度。
切片为nil: 如果切片为nil,使用range遍历会引发运行时错误。同样,遍历之前应该确保切片不为nil。
遍历数组 vs. 切片: 在数组上使用range遍历和在切片上使用range遍历是不同的。对于数组,range返回索引和元素的副本,而在切片上,range返回索引和元素值的副本。

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

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

相关文章

WCCI 2024开幕,横滨圣地巡礼,畅游动漫与美食的世界

惊喜!WCCI 2024开幕,横滨圣地巡礼!畅游动漫与美食的世界 会议之眼 快讯 会议介绍 IEEE WCCI(World Congress on Computational Intelligence)2024,即2024年IEEE世界计算智能大会,于6月30日至…

windows USB 设备驱动开发-Host端和Device端

Windows 中的 USB 宿主端驱动程序 下图显示了适用于 Windows 的 USB 驱动程序堆栈的体系结构框图。 此图显示了适用于 USB 2.0 和 USB 3.0 的单独 USB 驱动程序堆栈。 当设备连接到 xHCI 控制器时,Windows 加载 USB 3.0 驱动程序堆栈。 Windows 为连接到 EHCI、OHC…

星辰计划01-动态代理

会话1: 什么是动态代理? 👧 什么是代理啊?👨来来来,听我细细来说 代理这个词在不同的上下文中有不同的含义,主要可以归纳为以下几类解释: 计算机网络中的代理服务器(Proxy Server&#xff0…

跨平台Ribbon UI组件QtitanRibbon全新发布v6.7.0——支持Qt 6.6.3

没有Microsoft在其办公解决方案中提供的界面,就无法想象现代应用程序,这个概念称为Ribbon UI,目前它是使应用程序与时俱进的主要属性。QtitanRibbon是一款遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件,QtitanRibb…

Linux_生产消费模型_Block_Queue

目录 一、互斥锁 1.1 错误的抢票 1.1.1 类的成员函数与构造 1.1.2 start 函数 1.1.3 线程的回调函数 1.1.4 main 函数 1.1.5 结果 1.2 概念 1.3 相关系统调用 1.3.1 锁的创建 1.3.2 锁的初始化 1.3.2.1 动态初始化 1.3.2.2 静态初始化 1.3.3 锁的销毁 1.3.4…

看不懂懂车大爆炸,你就错过了国产小车的王炸!

咦?咋的啦?咱中国自己的汽车品牌前几天在汽车工业协会公布的数据里一跃而起,真的是威风凛凛啊!2023年咱们自家的乘用车品牌市场份额硬生生地占了个56%,这可是半壁江山啊!特别是那些10万块钱以下的家用小车&…

32.哀家要长脑子了!

1.299. 猜数字游戏 - 力扣(LeetCode) 公牛还是挺好数的,奶牛。。。妈呀,一朝打回解放前 抓本质抓本质,有多少位非公牛数可以通过重新排列转换公牛数字,意思就是,当这个数不是公牛数字时&#x…

C++多态~~的两个特殊情况

目录 1.多态的概念 2.简单认识 (1)一个案例 (2)多态的两个满足条件 (3)虚函数的重写 (4)两个特殊情况 1.多态的概念 (1)多态就是多种形态; …

SQL 29 计算用户的平均次日留存率题解

问题截图如下: SQL建表代码: drop table if exists user_profile; drop table if exists question_practice_detail; drop table if exists question_detail; CREATE TABLE user_profile ( id int NOT NULL, device_id int NOT NULL, gender varchar…

小白也能懂:逆向分析某网站加速乐Cookie参数流程详解

加速乐作为一种常见的反爬虫技术,在网络上已有大量详尽深入的教程可供参考。然而,对于那些初次接触的人来说,直接面对它可能仍会感到困惑。 声明 本文仅用于学习交流,学习探讨逆向知识,欢迎私信共享学习心得。如有侵权…

【区块链+基础设施】珠三角征信链 | FISCO BCOS应用案例

“珠三角征信链”是中国人民银行广州分行、中国人民银行深圳市中心支行按照中国人民银行总行工作部署,积 极贯彻珠三角一体化发展、粤港澳大湾区建设等国家战略而建设的跨区域征信一体化数据中心枢纽,以 FISCO BCOS 为底链构建应用平台,并由微…

springboot接口防抖【防重复提交】

什么是防抖 所谓防抖,一是防用户手抖,二是防网络抖动。在Web系统中,表单提交是一个非常常见的功能,如果不加控制,容易因为用户的误操作或网络延迟导致同一请求被发送多次,进而生成重复的数据记录。要针对用…

Docker 镜像导出和导入

docker 镜像导出 # 导出 docker 镜像到本地文件 docker save -o [输出文件名.tar] [镜像名称[:标签]] # 示例 docker save -o minio.tar minio/minio:latest-o 或 --output:指定导出文件的路径和名称[镜像名称[:标签]]:导出镜像名称以及可选的标签 dock…

【Python画图-驯化01】一文叫你搭建python画图最优环境配置

【Python画图-循环01】一文叫你搭建python画图最优环境配置 本次修炼方法请往下查看 🌈 欢迎莅临我的个人主页 👈这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合,智慧小天地! 🎇 免费获取相关内容文档关注&#…

Windows/Linux/Mac 系统局域网服务发现协议及传输速度比较

简介 分析 / 验证对比常见局域网服务发现协议在 Windows/Linux/Mac 等不同系统下的支持和表现 在使用不同系统的智能硬件时,如常见的树莓派 / Openwrt 路由器 / Debian/Fedora/Windows/Mac 等系统是,系统间相互发现以及网络共享本应是系统的基础服务&a…

探秘 Django 专业之道

一、Django项目开发 1.web框架底层 1.1 网络通信 注意:局域网 个人一般写程序,想要让别人访问:阿里云、腾讯云。 去云平台租服务器(含公网IP)程序放在云服务器 先以局域网为例 我的电脑【服务端】 import sock…

Linux下SUID提权学习 - 从原理到使用

目录 1. 文件权限介绍1.1 suid权限1.2 sgid权限1.3 sticky权限 2. SUID权限3. 设置SUID权限4. SUID提权原理5. SUID提权步骤6. 常用指令的提权方法6.1 nmap6.2 find6.3 vim6.4 bash6.5 less6.6 more6.7 其他命令的提权方法 1. 文件权限介绍 linux的文件有普通权限和特殊权限&a…

计算机毕业设计Python深度学习美食推荐系统 美食可视化 美食数据分析大屏 美食爬虫 美团爬虫 机器学习 大数据毕业设计 Django Vue.js

Python美食推荐系统开题报告 一、项目背景与意义 随着互联网和移动技术的飞速发展,人们的生活方式发生了巨大变化,尤其是餐饮行业。在线美食平台如雨后春笋般涌现,为用户提供了丰富的美食选择。然而,如何在海量的餐饮信息中快速…

(1)Jupyter Notebook 下载及安装

目录 1. Jupyter Notebook是什么?2. Jupyter Notebook特征3. 应用3. 利用Google Colab安装Jupyter Notebook3.1 什么是 Colab?3.2 访问 Google Colab 1. Jupyter Notebook是什么? 百度百科: Jupyter Notebook(此前被称为 IPython …

Unity Shader 软粒子

Unity Shader 软粒子 前言项目Shader连连看项目渲染管线设置 鸣谢 前言 当场景有点单调的时候,就需要一些粒子点缀,此时软粒子就可以发挥作用了。 使用软粒子与未使用软粒子对比图 项目 Shader连连看 这里插播一点,可以用Vertex Color与…