勤学如春起之苗,不见其增日有所长;辍学如磨刀之石,不见其损日有所亏。

本文的重点:逃逸分析、延迟语句、散列表、通道、接口。

1.逃逸分析

逃逸分析是Go语言中的一项重要优化技术,可以帮助程序减少内存分配和垃圾回收的开销,从而提高程序的性能。下面是一道涉及逃逸分析的面试题及其详解。

问题描述:

有如下Go代码:

func foo() *int {
x := 1
return &x
} func main() {
p := foo()
fmt.Println(*p)
}

请问上面的代码中,变量x是否会发生逃逸?

答案解析:

在上面的代码中,变量x只在函数foo()中被定义和初始化,然后其地址被返回给了主函数main()。因为返回值是指针类型,需要在堆上分配内存,所以变量x会发生逃逸。所谓逃逸,就是指变量的生命周期不仅限于函数栈帧,而是超出了函数的范围,需要在堆上分配内存。

如果变量x没有发生逃逸,那么它会被分配在函数栈帧中,随着函数的返回而被自动销毁。而如果发生了逃逸,变量x就需要在堆上分配内存,并由垃圾回收器负责回收。在实际的程序中,大量的逃逸会导致内存分配和垃圾回收的开销增加,从而影响程序的性能。

逃逸分析是Go语言的一项优化技术,可以在编译期间分析代码,确定变量的生命周期和分配位置,从而避免不必要的内存分配和垃圾回收。通过逃逸分析的优化,可以有效地提高程序的性能和可靠性。

更多逃逸分析的内容,可以阅读我之前分享的文章:内存分配和逃逸分析详解

2.延迟语句

defer语句是Go语言中的一项重要特性,可以用于在函数返回前执行一些清理或收尾工作,例如释放资源、关闭连接等。下面是一道涉及defer语句的面试题及其详解。

问题描述:

有如下Go代码:

func main() {
defer func() {
fmt.Println("defer 1")
}()
defer func() {
fmt.Println("defer 2")
}()
fmt.Println("main")
}

请问上面的代码中,输出的顺序是什么?

答案解析:

在上面的代码中,我们定义了两个defer语句,它们分别输出"defer 1"和"defer 2"。这两个defer语句的执行顺序是先进后出的,也就是说后定义的defer语句先执行,先定义的defer语句后执行。因此,输出的顺序应该是"main"、"defer 2"、"defer 1"。

这个例子也展示了defer语句的另一个特性,即在函数返回前执行。在main函数返回前,两个defer语句分别执行了它们的函数体,输出了相应的内容。这种特性可以用于释放资源、关闭连接等操作,在函数返回前保证它们被执行。

需要注意的是,defer语句并不是一种异步操作,它只是将被延迟执行的函数加入到一个栈中,在函数返回前按照后进先出的顺序执行。因此,在defer语句中的函数应该是轻量级的,避免影响程序的性能。同时,也需要注意defer语句的执行顺序和函数返回时的状态,避免出现不符合预期的结果。

3.散列表Map

Go语言中的map是一种非常有用的数据结构,可以用于存储键值对。下面是一道涉及map的面试题及其详解。

问题描述:

有如下Go代码:

func main() {
m := make(map[int]string)
m[1] = "a"
m[2] = "b"
fmt.Println(m[1], m[2])
delete(m, 2)
fmt.Println(m[2])
}

请问上面的代码中,输出的结果是什么?

答案解析:

在上面的代码中,我们使用make函数创建了一个map,然后向其中添加了两个键值对,分别是1:"a"和2:"b"。接着,我们输出了这两个键对应的值,分别是"a"和"b"。

接下来,我们使用delete函数从map中删除了键为2的元素。然后,我们尝试输出键为2的值,但是输出为空。这是因为我们已经从map中删除了键为2的元素,所以它对应的值已经不存在了。

需要注意的是,当我们从map中访问一个不存在的键时,它会返回该值类型的零值。在本例中,值的类型是string,它的零值是""。所以,当我们尝试输出键为2的值时,它返回的是空字符串。

需要提醒的是,map是一种引用类型的数据结构,它的底层实现是一个哈希表。在使用map时,需要注意以下几点:

  1. map是无序的,即元素的顺序不固定。
  2. map的键必须是可以进行相等性比较的类型,如int、string、指针等。(通俗来说就是可以用==和!=来比较的,除了slice、map、function这几个类型都可以)
  3. map的值可以是任意类型,包括函数、结构体等。
  4. 在多个goroutine之间使用map时需要进行加锁,避免并发访问导致的竞态问题。

4.通道Channel

Go语言中的通道(channel)是一种非常有用的特性,用于在不同的goroutine之间传递数据。下面是一道涉及通道的面试题及其详解。

问题描述:

有如下Go代码:

func main() {
ch := make(chan int)
go func() {
ch <- 1
ch <- 2
ch <- 3
close(ch)
}()
for {
n, ok := <-ch
if !ok {
break
}
fmt.Println(n)
}
fmt.Println("done")
}

请问上面的代码中,输出的结果是什么?

答案解析:

在上面的代码中,我们使用make函数创建了一个整型通道ch。然后,我们启动了一个goroutine,向通道中写入了三个整数1、2和3,并在最后使用close函数关闭了通道。

接着,在主函数中,我们使用for循环不断从通道中读取数据,直到通道被关闭。每次从通道中读取到一个整数后,我们将它输出。最后输出"done",表示所有的数据已经读取完毕。

因为通道是一种同步的数据传输方式,写入和读取会阻塞直到对方准备好,所以输出的结果应该是:

需要注意的是:在通道被关闭后,读取操作仍然可以从通道中读取到之前写入的数据。这是因为通道中的数据并没有立即消失,而是在读取完毕后被垃圾回收器回收。因此,在使用通道时,需要根据实际情况判断何时关闭通道,以避免出现不必要的竞态和内存泄漏。

5.接口

Go语言中的接口(interface)是一种非常重要的特性,用于定义一组方法。下面是一道涉及接口的面试题及其详解。

问题描述:

有如下Go代码:

type Animal interface {
Speak() string
} type Dog struct{} func (d *Dog) Speak() string {
return "Woof!"
} type Cat struct{} func (c *Cat) Speak() string {
return "Meow!"
} func main() {
animals := []Animal{&Dog{}, &Cat{}}
for _, animal := range animals {
fmt.Println(animal.Speak())
}
}

请问上面的代码中,输出的结果是什么?

答案解析:

在上面的代码中,我们定义了一个Animal接口,它有一个Speak方法。然后,我们定义了Dog和Cat两个结构体,分别实现了Animal接口的Speak方法。

接着,在main函数中,我们创建了一个Animal类型的切片,其中包含了一个Dog对象和一个Cat对象。然后,我们使用for循环遍历这个切片,调用每个对象的Speak方法,并输出它们返回的字符串。

因为Dog和Cat都实现了Animal接口的Speak方法,所以它们都是Animal类型的对象,可以被放入Animal类型的切片中。在遍历切片时,我们调用每个对象的Speak方法,它们分别返回"Woof!"和"Meow!",然后被输出。

因此,输出的结果应该是:



需要注意的是,接口是一种动态类型,它可以包含任何实现了它所定义的方法集的类型。在使用接口时,需要注意以下几点:

  1. 接口是一种引用类型的数据结构,它的值可以为nil。
  2. 实现接口的类型必须实现接口中所有的方法,否则会编译错误。
  3. 接口的值可以赋给实现接口的类型的变量,反之亦然。
  4. 在实现接口的类型的方法中,可以通过类型断言来判断接口值的实际类型和值。

总结

这篇文章总结了5个知识点的面试题:逃逸分析、延迟语句defer、散列表map、通道Channel、接口interface

下一篇文章计划分享的5个知识点是:unsafe、context、错误处理、计时器、反射。

欢迎大家三连支持一波,你的点赞、分享,是我更文的最大动力。

公众号:程序员升职加薪之旅

「刷起来」Go必看的进阶面试题详解的更多相关文章

  1. 「万字图文」史上最姨母级Java继承详解

    摘要:继承是面向对象软件技术中的一个概念.它使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用. 本文分享自华为云社区<「万字图文」史上最姨母级Java继承详解丨[奔跑吧!JAVA] ...

  2. 「SAP技术」SAP 如何看序列号被包在哪些HU里?

    「SAP技术」SAP 如何看序列号被包在哪些HU里? 事务代码SE16 ,表名OBJK, 输入物料号,序列号,HeadTable 输入值SER06, 查询结果如下, 根据objlist, 去表ser0 ...

  3. 「建议心心」要就来15道多线程面试题一次爽到底(1.1w字用心整理)

    . 本文是给**「建议收藏」200MB大厂面试文档,整理总结2020年最强面试题库「CoreJava篇」**写的答案,所有相关文章已经收录在码云仓库:https://gitee.com/bingqil ...

  4. 「刷题」Color 群论

    这道题乍一看挺水的,直接$ Ploya $就可以了,可是再看看数据范围:n<=1e9 那就是有1e9种置换,这不歇比了. 于是考虑式子的优化. 首先证明,转i次的置换的每个循环结大小是 $ gc ...

  5. 「刷题」THUPC泛做

    刷了一下,写一下. T1. 天天爱射击 可以这样想. 我们二分一下每一块木板在什么时刻被击碎. 然后直接用主席树维护的话是\(O(nlog^2n)\)的. 会\(T\),而且是一分不给那种... 那么 ...

  6. 「LibreOJ#516」DP 一般看规律

    首先对于序列上一点,它对答案的贡献只有与它的前驱和后驱(前提颜色相同)构成的点对, 于是想到用set维护每个颜色,修改操作就是将2个set暴力合并(小的向大的合并),每次插入时更新答案即可 颜色数要离 ...

  7. 「刷题」JZPKIL

    这道反演题,真牛逼. 以下用$B$代表伯努利数,$l*g=f$代表狄利克雷卷积,先推式子. 对于给出的$n,x,y$求一百组数据的$ans$ $\begin{array}{rcl} ans & ...

  8. 「刷题」GERALD07加强版

    是LCT了. 首先我们不知道联通块怎么数. 然后颓标签知道了是LCT. 那么考虑一下怎么LCT搞. 有一个很普遍的思路大家也应该都知道,就是如何求一个区间中某种颜色的个数. 这个可以很简单的用主席树来 ...

  9. 「刷题」Triple

    正解是普通型母函数+FFT. 才学了多项式,做了一道比较好的题了. 首先有三个斧子被偷了. 我们考虑构造一种普通型母函数. 就是说一种多项式吧,我的理解. 系数是方案,下标,也就是所谓的元指数代表的是 ...

  10. 「刷题」xor

    说实话这道题没有A掉,不过所有的思路都是我自己想的,我觉得这个思路真的很棒很棒很棒的. 首先这个题的题面描述告诉我这种运算有封闭性,满足结合律和交换率,那么其实这个东西是个群运算了,而且这个群有单位元 ...

随机推荐

  1. 常用的CSS效果(1)

    单行省略 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; 多行省略 display:-webkit-box; overf ...

  2. 微服务注册到Nacos上的Ip错误,是内网ip不是公网ip

    spring.cloud.nacos.discovery.ip = 本机公网IP spring.cloud.nacos.discovery.port = 服务端口

  3. 狐漠漠养成日记 Cp.00001 开始养成计划

    开始养成计划 今天是我开始这个"狐漠漠养成计划"的第一天(划掉). 看来是昨天出门前忘记保存了,昨天写的几百字内容全都没有了,今天其实已经是计划开始的第二天了. 因为昨天晚上出去喝 ...

  4. WPF VB.NET 代码实现界面动画效果

    WPF VB.NET 代码实现界面动画效果 Imports System.Windows.Media.Animation 例子: Dim result As New Storyboard Dim an ...

  5. C语言初级阶段7——指针1

    C语言初级阶段7--指针1 地址与指针 1.地址:数据在内存中的存储位置编号,是一个常量. 2.指针:指针的本质就是地址. 指针变量的定义和声明 1.指针变量:存储的数据是地址. 2.定义方法:类型* ...

  6. 探测域名解析依赖关系(运行问题解决No module named 'DNS')

    探测域名解析依赖关系 最近很懒,今天晚上才开始这个任务,然后发现我原来能跑起来的程序跑不起来了. 一直报错 ModuleNotFoundError: No module named 'DNS' 这个应 ...

  7. IT工具知识-11:一种安卓投屏到Win10失败的解决方法

    软硬件平台 电脑:WIN10 LTSC 手机:红米K30Pro/MIUI 11.0.26 投屏软件:安卓端-自带投屏,WIN10-自带投屏(连接) 故障描述 之前还能用的,但是在换了个路由器之后就不能 ...

  8. DevExpress 模块注入框架

    参考地址 模块注入框架(MIF)是一组帮助MVVM应用程序的类.它提供以下功能 将ViewModel连接到视图 页面之间导航 保存和恢复应用程序的可视和逻辑状态 单元测试 模块 模块是应用程序的功能单 ...

  9. Float浮动、 CSS定位(position)

    Float浮动. CSS定位(position)1.CSS定位机制(1)普通流(标准流)-默认状态,元素自动从左往右,从上往下的排列(2)浮动-会使元素向左或向右移动,只能左右,不能上下-浮动元素碰到 ...

  10. Servlet's characters of get and post

    Tomcat默认是使用ISO8859-1来解码的,ISO8859-1是不支持中文的. 1.post请求解决乱码原因: 服务器不知道按哪种编码来处理HTML等文件来响应给浏览器的,所以处理post请求时 ...