Go常见的语法题目

1、下面代码能运行吗?为什么。

type Param map[string]interface{}type Show struct {Param
}func main1() {s := new(Show)s.Param["RMB"] = 10000
}

解析

共发现两个问题:

  1. main 函数不能加数字。
  2. new 关键字无法初始化 Show 结构体中的 Param 属性,所以直接对 s.Param 操作会出错。

2、请说出下面代码存在什么问题。

type student struct {Name string
}func zhoujielun(v interface{}) {switch msg := v.(type) {case *student, student:msg.Name}
}

解析:

golang中有规定,switch typecase T1,类型列表只有一个,那么v := m.(type)中的v的类型就是T1类型。

如果是case T1, T2,类型列表中有多个,那v的类型还是多对应接口的类型,也就是m的类型。

所以这里msg的类型还是interface{},所以他没有Name这个字段,编译阶段就会报错。具体解释见: https://golang.org/ref/spec#Type_switches

3、写出打印的结果。

type People struct {name string `json:"name"`
}func main() {js := `{"name":"11"}`var p Peopleerr := json.Unmarshal([]byte(js), &p)if err != nil {fmt.Println("err: ", err)return}fmt.Println("people: ", p)
}

解析:

按照 golang 的语法,小写开头的方法、属性或 struct 是私有的,同样,在json 解码或转码的时候也无法上线私有属性的转换。

题目中是无法正常得到Peoplename值的。而且,私有属性name也不应该加json的标签。

4、下面的代码是有问题的,请说明原因。

type People struct {Name string
}func (p *People) String() string {return fmt.Sprintf("print: %v", p)
}func main() {p := &People{}p.String()
}

解析:

在golang中String() string 方法实际上是实现了String的接口的,该接口定义在fmt/print.go 中:

type Stringer interface {String() string
}

在使用 fmt 包中的打印方法时,如果类型实现了这个接口,会直接调用。而题目中打印 p 的时候会直接调用 p 实现的 String() 方法,然后就产生了循环调用。

5、请找出下面代码的问题所在。

func main() {ch := make(chan int, 1000)go func() {for i := 0; i < 10; i++ {ch <- i}}()go func() {for {a, ok := <-chif !ok {fmt.Println("close")return}fmt.Println("a: ", a)}}()close(ch)fmt.Println("ok")time.Sleep(time.Second * 100)
}

解析:

在 golang 中 goroutine 的调度时间是不确定的,在题目中,第一个写 channelgoroutine 可能还未调用,或已调用但没有写完时直接 close 管道,可能导致写失败,既然出现 panic 错误。

6、请说明下面代码书写是否正确。

var value int32func SetValue(delta int32) {for {v := valueif atomic.CompareAndSwapInt32(&value, v, (v+delta)) {break}}
}

解析:

atomic.CompareAndSwapInt32 函数不需要循环调用。

7、下面的程序运行后为什么会爆异常。

type Project struct{}func (p *Project) deferError() {if err := recover(); err != nil {fmt.Println("recover: ", err)}
}func (p *Project) exec(msgchan chan interface{}) {for msg := range msgchan {m := msg.(int)fmt.Println("msg: ", m)}
}func (p *Project) run(msgchan chan interface{}) {for {defer p.deferError()go p.exec(msgchan)time.Sleep(time.Second * 2)}
}func (p *Project) Main() {a := make(chan interface{}, 100)go p.run(a)go func() {for {a <- "1"time.Sleep(time.Second)}}()time.Sleep(time.Second * 100000000000000)
}func main() {p := new(Project)p.Main()
}

解析:

有一下几个问题:

  1. time.Sleep 的参数数值太大,超过了 1<<63 - 1 的限制。
  2. defer p.deferError() 需要在协程开始出调用,否则无法捕获 panic

8、请说出下面代码哪里写错了

func main() {abc := make(chan int, 1000)for i := 0; i < 10; i++ {abc <- i}go func() {for {a := <-abcfmt.Println("a: ", a)}}()close(abc)fmt.Println("close")time.Sleep(time.Second * 100)
}

解析:

协程可能还未启动,管道就关闭了。

9、请说出下面代码,执行时为什么会报错

type Student struct {name string
}func main() {m := map[string]Student{"people": {"zhoujielun"}}m["people"].name = "wuyanzu"
}

解析:

map的value本身是不可寻址的,因为map中的值会在内存中移动,并且旧的指针地址在map改变时会变得无效。故如果需要修改map值,可以将map中的非指针类型value,修改为指针类型,比如使用map[string]*Student.

10、请说出下面的代码存在什么问题?

type query func(string) stringfunc exec(name string, vs ...query) string {ch := make(chan string)fn := func(i int) {ch <- vs[i](name)}for i, _ := range vs {go fn(i)}return <-ch
}func main() {ret := exec("111", func(n string) string {return n + "func1"}, func(n string) string {return n + "func2"}, func(n string) string {return n + "func3"}, func(n string) string {return n + "func4"})fmt.Println(ret)
}

解析:

依据4个goroutine的启动后执行效率,很可能打印111func4,但其他的111func*也可能先执行,exec只会返回一条信息。

11、下面这段代码为什么会卡死?

package mainimport ("fmt""runtime"
)func main() {var i bytego func() {for i = 0; i <= 255; i++ {}}()fmt.Println("Dropping mic")// Yield execution to force executing other goroutinesruntime.Gosched()runtime.GC()fmt.Println("Done")
}

解析:

Golang 中,byte 其实被 alias 到 uint8 上了。所以上面的 for 循环会始终成立,因为 i++ 到 i=255 的时候会溢出,i <= 255 一定成立。

也即是, for 循环永远无法退出,所以上面的代码其实可以等价于这样:

go func() {for {}
}

正在被执行的 goroutine 发生以下情况时让出当前 goroutine 的执行权,并调度后面的 goroutine 执行:

  • IO 操作
  • Channel 阻塞
  • system call
  • 运行较长时间

如果一个 goroutine 执行时间太长,scheduler 会在其 G 对象上打上一个标志( preempt),当这个 goroutine 内部发生函数调用的时候,会先主动检查这个标志,如果为 true 则会让出执行权。

main 函数里启动的 goroutine 其实是一个没有 IO 阻塞、没有 Channel 阻塞、没有 system call、没有函数调用的死循环。

也就是,它无法主动让出自己的执行权,即使已经执行很长时间,scheduler 已经标志了 preempt。

而 golang 的 GC 动作是需要所有正在运行 goroutine 都停止后进行的。因此,程序会卡在 runtime.GC() 等待所有协程退出。

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

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

相关文章

数据结构:栈和队列的练习题1(括号匹配问题)

题目描述&#xff1a; 思路&#xff1a;我们首先可以把出现的情况大致分为以下几类&#xff1a; 因为涉及匹配问题&#xff0c;所以所有的左括号和右括号肯定要分开来整理。如果我们直接去匹配的话&#xff08;像第一行的从左到右独立匹配&#xff09;是行得通的&#xff0c;但…

C/C++|我们为什么应该使用 `std::make_shared` 创建 `std::shared_ptr`

std::make_shared 是 C11 引入的一个工厂函数&#xff0c;用于创建 std::shared_ptr。与直接使用 new 并将其传递给 std::shared_ptr 构造函数相比&#xff0c;std::make_shared 提供了一种更高效、更安全的方法来分配和管理动态内存。 前置知识1&#xff1a; 当我们调用诸如&a…

关于d3js生成节点画布的个人笔记

实现功能 根据鼠标位置生成节点根据节点位置通过鼠标拖拽生成连线实现自定义线段颜色功能删除节点以及连线功能实现单个节点拖动功能实现整条线路的拖动功能 界面如下&#xff1a; 主要模块介绍 绘制连线 const line svg.selectAll(".line").data(links, d >…

【Linux】Git超详细教程:手把手教你(gitee版)--版本管理+远程仓库克隆(初学者必看!!!)

目录 一、前言 二、git 的深度理解 &#x1f95d; 什么是 git ? &#x1f347; git 的历史发展&#xff08;理解 git 的由来&#xff09; &#x1f34b; 感性理解 git 的版本管理 三、git 的安装 ✨Window 终端安装 ✨Linux 安装 四、git 的工作流程 五、如何在 Linux …

音视频开发—视频相关概念:YUV与RGB

文章目录 YUV相关概念组成部分优点常见的 YUV 格式数据量的计算YUV4:2:0 存储格式平面模式&#xff08;planar):打包模式&#xff08;packed&#xff09; RGB 和 YUV 的定义关系与转换RGB 到 YUV 的转换YUV 到 RGB 的转换 使用场景优缺点 YUV相关概念 YUV 是一种颜色编码格式&…

JVM-JAVA-类加载过程

JVM源码 类加载到 JVM 的过程通过 java 命令执行代码的流程 类加载到 JVM 的过程 在运行一个 main 函数启动程序是&#xff0c;首先需要类加载起把主类加载到 JVM 中 通过 java 命令执行代码的流程 loadClass的类加载过程有如下几步&#xff1a; 类被加载到方法区中后主要包…

Maven项目通过maven central 发布到中央仓库 https://repo.maven.apache.org/ 手把手教学 最新教学

一、注册maven central账号 ​ https://central.sonatype.com/publishing/namespaces 我这里直接使用github账号登录 &#xff0c;可以自己注册或者直接使用google账号或者github账号登录 这里github账号登录之后 应该只出现io.github 下面的io.gitee我也验证过 所以这里出…

Java时间类--JDK8

为什么JDK8会又新增时间相关类呢&#xff1f; ① JDK7的时间对象如果需要比较大小的话&#xff0c;必须都先转换成毫秒值&#xff1b;JDK8则不需要&#xff0c;可以直接比较。 ② JDK7的时间对象可以修改&#xff0c;在多线程环境下就会导致数据不安全&#xff1b;JDK8不能修改…

数据库open报ORA-600 kcratr_scan_lastbwr故障处理---惜分飞

由于断电&#xff0c;导致数据库正常open报ORA-600 kcratr_scan_lastbwr错误 Wed Jan 17 18:23:26 2024 ALTER DATABASE MOUNT Successful mount of redo thread 1, with mount id 1028618590 Database mounted in Exclusive Mode Lost write protection disabled Completed:…

【Git】在错误分支上开发了怎么办

情况一&#xff1a;还未提交 git add . 『暂存修改的代码』git stash 『把暂存的文件提交到git的暂存栈』git checkout 『本该提交代码的分支』git stash pop 『取出暂存栈中的代码』 情况二&#xff1a;已提交 git checkout 『不该提交代码提交了代码的分支』git reset HEA…

输入3个字符串,要求将字母按由小到大顺序输出

对于将3个整数按由小到大顺序输出&#xff0c;是很容易处理的。可以按照同样的算法来处理将3个字符串按大小顺序输出。可以直接写出程序。 编写程序&#xff1a; 运行结果&#xff1a; 这个程序是很好理解的。在程序中对字符串变量用关系运算符进行比较&#xff0c;如同对数值…

【Git 版本管理】合并 + 变更,看懂Git

看懂 Git 合并操作分离 HEAD分离 HEAD 测试 相对引用(^ || ~)操作符 ^相对引用 ^ 测试操作符 ~相对引用 ~ 测试 撤销变更Git ResetGit Revert撤销变更 测试 整理提交记录Git Cherry-pick测试 交互式 rebase交互式 rebase 测试 合并操作 关键字&#xff1a;commit、branch、merg…

Minio篇:初识MinIO

1. MinIO快速入门 1.1.MinIO核心概念 下面介绍MinIO中的几个核心概念&#xff0c;这些概念在所有的对象存储服务中也都是通用的。 对象&#xff08;Object&#xff09; 对象是实际的数据单元&#xff0c;例如我们上传的一个图片。 存储桶&#xff08;Bucket&#xff09; 存储…

基于单片机的机械臂的研究

摘要 &#xff1a; 工业机器人是现代科学技术的融合下的产物&#xff0c;属于机电自动化设备的一种。机械臂作为工业机器人的核心&#xff0c;在提高工业生产效率的同时&#xff0c;也保障了工作人员的身心安全。本文以某款基于单片机的机械臂为例&#xff0c;对机械臂的设计方…

【JAVA SE】多态

✨✨欢迎大家来到Celia的博客✨✨ &#x1f389;&#x1f389;创作不易&#xff0c;请点赞关注&#xff0c;多多支持哦&#x1f389;&#x1f389; 所属专栏&#xff1a;JAVA 个人主页&#xff1a;Celias blog~ 目录 引言 一、多态 1.1 多态的概念 1.2 多态的实现条件 1.3…

AI未来预测

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经成为了当今世界的热门话题。从自动驾驶汽车到智能家居&#xff0c;从虚拟助手到机器人&#xff0c;AI的应用已经渗透到了我们生活的方方面面。在未来&#xff0c;AI将会继续改变我们的生活方式&#xff0…

深入探讨 Android 的 View 显示过程与源码分析

文章目录 1. 探讨 Android 的 View 显示过程1.1. onFinishInflate1.2. onAttachedToWindow1.3. onMeasure1.4. onSizeChanged1.5. onLayout1.6. onDraw 2. 系统代码分析1.1. onFinishInflate1.2. onAttachedToWindow1.3. onMeasure1.4. onSizeChanged1.5. onLayout1.6. onDraw …

【Spring Boot】SpringBoot 下在 yml 中的 logging 日志配置

文章目录 前言输出日志的级别日志输出的位置日志输出的格式日志文件的存储路径日志文件是否输出到控制台配置Logback 配置日志分组配置日志细粒度配置【logger】 前言 logging 配置主要用于控制应用程序的日志输出行为&#xff0c;可以通过配置定制日志的格式、级别、输出位置…

数字化浪潮中的TPM革新:打造高效生产新范式

在数字化浪潮席卷全球的今天&#xff0c;传统生产管理模式正面临前所未有的挑战与机遇。TPM&#xff08;全面生产维护&#xff09;作为一种先进的生产管理理念&#xff0c;如何在数字化驱动下焕发新的活力&#xff0c;成为制造业转型升级的关键一环。 数字化技术为TPM带来了前…

Ubuntu禁止内核自动更新

查看当前内核版本 uname -v #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 7 09:00:52 UTC 2 uname -a Linux GKJ 6.5.0-35-generic #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 7 09:00:52 UTC 2 x86_64 x86_64 x86_64 GNU/Linux uname -r 6.5.0-35-generic 方法1&am…