Golang基础常识性知识面试中常见的六大陷阱及应对技巧

一、nil slice & empty slice

1、nil切片与空切片底层

  • nil切片:var nilSlice [] string

    • nil slice的长度len和容量cap都是0

    • nil slice==nil

    • nil slice的pointer是nil

  • 空切片:emptySlice0 := make([]int,0)

    • empty slice的长度是0,容量是由指向底层数组决定

    • empty slice != nil

    • empty slice的pointer是底层数组的地址

  • nil切片和空切片最大的区别在指向的数组引用地址是不一样的

  • nil空切片引用数组指针地址为0(无指向任何实际地址)

图片

  • 空切片的引用数组指针地址是有的,且固定为一个值,所有的空切片指向的数组引用地址都是一样的

图片

2、创建nil slice 和empty slice

package mainimport "fmt"
func main() {  var nilSlice []string  // 创建一个 nil 切片  emptySlice0 := make([]int, 0)  // 方法1:创建一个空切片(零切片)  var emptySlice1 = []string{}   // 方法2:创建一个空切片
  fmt.Printf("\nnilSlice---> Nil:%v Len:%d Capacity:%d", nilSlice == nil, len(nilSlice), cap(nilSlice))  fmt.Printf("\nemptySlice0---> nil:%v Len:%d Capacity:%d", emptySlice0 == nil, len(emptySlice0), cap(emptySlice0))  fmt.Printf("\nemptySlice1---> nil:%v Len:%d Capacity:%d", emptySlice1 == nil, len(emptySlice1), cap(emptySlice1))
  // nil切片和空切片都可以正常 append数据  nilSlice = append(nilSlice, "sss")}/*Nil:true Len:0 Capacity:0nil:false Len:0 Capacity:0nil:false Len:0 Capacity:0[sss] */

二、类型强转产生内存拷贝

1、字符串转数组发送内存拷贝

  • 字符串转成byte数组,会发生内存拷贝吗?

  • 字符串转出切片,会产生拷贝

  • 严格来说,只要是发送类型强转都会发送内存拷贝

  • 那么问题来了,频繁的内存拷贝操作听起来对性能不大友好

  • 有没有什么办法可以在字符串转出切片的时候不用发生拷贝呢?

2、字符串转数组不内存拷贝方法

  • 那么如果想要在底层转换二者,只需要吧StringHeader的地址强转成SliceHeader就行,那么go有个很强的包叫unsafe

  • 1.unsafe.Pointer(&a)方法可以得到变量a的地址。

    • 2.(*reflect.StringHeader)(unsafe.Pointer(&a)) 可以把字符串a转成底层结构的形式。

    • 3.(*[]byte)(unsafe.Pointer(&ssh)) 可以把ssh底层结构体转成byte的切片的指针。

    • 4.再通过 *转为指针指向的实际内容。

package main
import (   "fmt"   "reflect"   "unsafe")
func main() {   a :="aaa"   ssh := *(*reflect.StringHeader)(unsafe.Pointer(&a))   b := *(*[]byte)(unsafe.Pointer(&ssh))   fmt.Printf("%v---%T",b,b)  // [97 97 97]---[]uint8}

三、拷贝大切片一定代价大吗?

  • SliceHeader 是切片在go的底层结构。

    • 第一个字是指向切片底层数组的指针,这是切片的存储空间

    • 第二个字段是切片的长度

    • 第三个字段是容量

type SliceHeader struct {  Data uintptr  Len  int  Cap  int}
  • 大切片跟小切片的区别无非就是 Len 和 Cap的值比小切片的这两个值大一些,如果发生拷贝,本质上就是拷贝上面的三个字段。

  • 所以 拷贝大切片跟小切片的代价应该是一样的

四、map不初始化使用会怎么样

  • 空map和nil map结果是一样的,都为map[]。

  • 所以,这个时候别断定map是空还是nil,而应该通过map == nil来判断。

package main
func main() {  var m1 map[string]string    // 创建一个 nil map  println("m1为nil: ", m1==nil)  // 报错 => panic: assignment to entry in nil map  //m1["name"] = "tom"
  var m2 =  make(map[string]string)  // 创建一个空map  m2["name"] = "jack"                // 空map可以正常  println("m2为nil: ", m2==nil)}

五、map会遍历删除安全吗?

  • map 并不是一个线程安全的数据结构。

  • 同时读写一个 map 是未定义的行为,如果被检测到,会直接 panic。

  • 上面说的是发生在多个协程同时读写同一个 map 的情况下。

  • 如果在同一个协程内边遍历边删除,并不会检测到同时读写,理论上是可以这样做的。

  • sync.Map可以解决多线程读写map问题

    • 一般而言,这可以通过读写锁来解决:sync.RWMutex

    • 读之前调用 RLock() 函数,读完之后调用 RUnlock() 函数解锁;

    • 写之前调用 Lock() 函数,写完之后,调用 Unlock() 解锁。

    • 另外,sync.Map 是线程安全的 map,也可以使用

六、for循环append坑

1、坑1:添加元素变覆盖

  • 不会死循环,for range其实是golang语法糖,在循环开始前会获取切片的长度 len(切片),然后再执行len(切片)次数的循环。

package mainimport "fmt"func main() {  s := []int{1,2,3,4,5}  for _, v:=range s {    s =append(s, v)    fmt.Printf("len(s)=%v\n",len(s))  }}/*len(s)=6len(s)=7len(s)=8len(s)=9len(s)=10 */

2、坑2:值全部一样

  • 每次循转中num的值是正常的,但是由append构造的res中,全是nums的最后一个值。

  • 最终总结出原因是在for range语句中,创建了变量num且只被创建了一次。

  • 即num有自己的空间内存且地址在for循环过程中不变

  • 循环过程中每次将nums中对应的值和num进行值传递

package mainimport "fmt"func main() {  var nums = []int{1, 2, 3, 4, 5}  var res []*int  for _, num := range nums {    res = append(res, &num)    //fmt.Println("num:", num)  }  for _, r := range res {    fmt.Println("res:", *r)  }}/*res: 5res: 5res: 5res: 5res: 5 */

3、解决方法

  • 方法1

    • 不使用for range的形式,直接用索引来对nums取值

package mainimport "fmt"func main() {  var nums = []int{1, 2, 3, 4, 5}  var res []*int  for i := 0; i < len(nums); i++ {    res = append(res, &nums[i])  }  fmt.Println("res:", res)  for _, r := range res {    fmt.Println("res:", *r)  }}
  • 方法2

    • 在for循环中每次再定义一个新的变量num_temp,将num的值传给num_temp,之后append该变量即可。

package mainimport "fmt"func main() {  var nums = []int{1, 2, 3, 4, 5}  var res []*int  for _, num := range nums {    numTemp := num // 创建一个新的临时变量    res = append(res, &numTemp)  }  for _, r := range res {    fmt.Println("res:", *r)  }}/*res: 1res: 2res: 3res: 4res: 5 */

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

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

相关文章

【Story】《程序员面试的“八股文”辩论:技术基础与实际能力的博弈》

目录 程序员面试中的“八股文”&#xff1a;助力还是阻力&#xff1f;1. “八股文”的背景与定义1.1 “八股文”的起源1.2 “八股文”的常见类型 2. “八股文”的作用分析2.1 理论基础的评价2.1.1 助力2.1.2 阻力 3. 实际工作能力的考察3.1 助力3.2 阻力 4. 面试中的背题能力4.…

C# 表达式树的简介与说明

文章目录 1. 表达式树是什么&#xff1f;2. 表达式树的基本组成3. 构建表达式树的步骤4. 表达式树的使用场景5. 示例代码6. 总结 在 C# 编程中&#xff0c;表达式树&#xff08;Expression Tree&#xff09;是一个强大的概念&#xff0c;它允许我们以代码的形式表示运行时的代码…

二分算法及其公式

二分查找 二分查找是大多数人第一个接触到的算法&#xff0c;很多人都认为只有有序的数组可以使用二分查找&#xff0c;但这种思想其实是错误的&#xff0c;二分查找是可以用于拥有二段性的数组&#xff0c;而且二分算法是由模板做参考的&#xff0c;所以只要掌握就可以解决大…

机器学习课程学习周报六

机器学习课程学习周报六 文章目录 机器学习课程学习周报六摘要Abstract一、机器学习部分1.1 循环神经网络概述1.2 循环神经网络架构1.2.1 深层循环神经网络1.2.2 Elman网络和Jordan网络1.2.3 双向循环神经网络 1.3 长短期记忆网络1.4 LSTM原理1.5 RNN的学习方式1.6 RNN中的梯度…

BUG解决(vue3+echart报错):Cannot read properties of undefined (reading ‘type‘)

这是 vue3echart5 遇到的报错&#xff1a;Cannot read properties of undefined (reading ‘type‘) 这个问题需要搞清楚两个关键方法&#xff1a; toRaw&#xff1a; 作用&#xff1a;将一个由reactive生成的响应式对象转为普通对象。 使用场景&#xff1a; 用于读取响应式…

word修改一处全文都变了

在word中修改一处文字&#xff0c;全文都变了&#xff0c;还得重新排版。来来回回、反反复复特别麻烦。主要是因为word的文档用WPS打开&#xff0c;WPS自动做了更改。我们将word中的文字的样式取消自动更新就可以了。 右键“正文1”&#xff0c;选择“修改” 将子等更新的√&am…

我当年自学黑客(网络安全)的一些心得!(内附学习笔记)

前 言 写这篇教程的初衷是很多朋友都想了解如何入门/转行网络安全&#xff0c;实现自己的“黑客梦”。文章的宗旨是&#xff1a;1.指出一些自学的误区 2.提供客观可行的学习表 3.推荐我认为适合小白学习的资源.大佬绕道哈&#xff01;&#xff08;文末有福利&#xff01;&…

什么是网络安全等级保护测评服务?

等保测评 依据国家网络安全等级保护制度规定&#xff0c;按照有关管理规范和技术标准&#xff0c;对非涉及国家秘密的网络安全等级保护状况进行检测评估。定级协助 根据等级保护对象在国家安全、经济建设、社会生活中的重要程度&#xff0c;以及一旦遭到破坏、丧失功能或者数据…

那英夺冠,《歌手2024》爆大瓜之王!

《歌手2024》真是今年的大瓜之王&#xff0c;瓜农们都要发奖金了&#xff01; 节目组邀请过小沈阳参演&#xff0c;却被他婉拒&#xff0c;难道他预判了《歌手2024》的预判。 决赛颁奖现场上&#xff0c;刘欢提前离场&#xff0c;那英凭着极不稳定的发挥&#xff0c;硬是夺下…

大厂linux面试题攻略四之Linux网络服务(二)

五、Linux网络服务-Apache优化 1.请写出工作中常见的Apache优化策略 Apache服务器优化是提升网站响应速度和稳定性的重要手段。在工作中&#xff0c;常见的Apache优化策略包括以下几个方面&#xff1a; 1. 启用压缩技术 Gzip压缩&#xff1a;使用Gzip压缩技术可以减少服务器…

OAK相机扩展NDVI功能检测植物健康情况

什么是NDVI&#xff1f; 首先&#xff0c;NDVI代表归一化差异植被指数。这听起来很花哨&#xff0c;但这实际上只是衡量植物健康的一种高级方法。NDVI摄像机使用可见光和近红外 (NIR) 光捕获图像。健康的植物反射更多的近红外光并吸收更多的可见光&#xff0c;而生病的植物反射…

MSA+抑郁症模型总结(三)(论文复现)

MSA抑郁症模型总结&#xff08;三&#xff09;&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 MSA抑郁症模型总结&#xff08;三&#xff09;&#xff08;论文复现&#xff09;热门研究领域&#xff1a;情感计算的横向发展一、概述二、论…

卷积神经网络(六)---实现 cifar10 分类

cifar10 数据集有60000张图片&#xff0c;每张图片的大小都是 32x32 的三通道的彩色图&#xff0c;一共是10种类别、每种类别有6000张图片&#xff0c;如图4.27所示。 图 4.27 cifar数据集 使用前面讲过的残差结构来处理 cifar10 数据集&#xff0c;可以实现比较高的准确率。 …

springboot在线图库网站-计算机毕业设计源码35597

摘 要 本文基于Spring Boot作为后端框架&#xff0c;Vue作为前端框架&#xff0c;设计并实现了一个功能丰富的在线图库网站。该网站提供了注册、登录、普通用户功能和管理员功能等一系列功能&#xff0c;为用户提供了方便的浏览摄影相关内容和参与活动的途径&#xff0c;同时管…

《从零开始做个摸鱼小网站! · 序》灵感来源

序 大家好呀&#xff0c;我是summo&#xff0c;这次来写写我在上班空闲(摸鱼)的时候做的一个小网站的事。去年阿里云不是推出了个活动嘛&#xff0c;2核2G的云服务器一年只要99块钱&#xff0c;懂行的人应该知道这个价格在业界已经是非常良心了&#xff0c;虽然优惠只有一年&a…

java之学生管理系统优化版本(利用final)

final的意思表示最终的: 被final 修饰的变量叫做常量,而常量的意思就是不可修改的量,也不可以赋值. 被final修饰的方法叫做最终方法,别的类不可以调用. 被fianl修饰的类叫做最终类,别的类不可调用,也不能作为父类继承.public class StudentSysterm {private static final Strin…

【通俗理解】自由能与自由意志的桥梁——从物理到哲学的跨越

【通俗理解】自由能与自由意志的桥梁——从物理到哲学的跨越 自由能与自由意志的类比 你可以把自由能比作一个“能量货币”&#xff0c;它代表着系统能够用来做功的能量。而自由意志则是一个“选择的能力”&#xff0c;它代表着个体在做出决策时的自主性和可能性。 自由能与自由…

校园气象观测站

TH-XQ3校园气象观测站是一种用于进行校园内天气观测和气象数据收集的设施。它通常由一系列的气象仪器和设备组成&#xff0c;包括气温、湿度、风速、风向、气压、降水量等传感器。观测站可以实时监测和记录天气变化&#xff0c;提供有关天气现象和气象数据的信息。 校园气象观…

第09课 Scratch入门篇:小鸡啄米-自制积木实现

小鸡啄米-自制积木 故事背景&#xff1a; 在上一章的案例中&#xff0c;实现了小鸡啄米的动画&#xff0c;但是发现太多的重复代码&#xff0c;是我们编程的时候代码泰国繁琐&#xff0c;我们可以使用自制积木&#xff0c;将相同的代码提取出来制作成一个新的积木&#xff0c;在…

计算机网络-七层协议栈介绍

之前介绍了网络世界的构成&#xff0c;从宏观角度介绍了网络设备和网络架构&#xff0c;链接: link&#xff0c;但是这种认识过于粗糙&#xff0c;过于肤浅。网络本质上是用于主机之间的通信&#xff0c;是端对端的连接通信&#xff0c;两台计算机可能距离很远&#xff0c;主机…