Go 语言面试题(一):基础语法

文章目录

    • Q1 = 和 := 的区别?
    • Q2 指针的作用?
    • Q3 Go 允许多个返回值吗?
    • Q4 Go 有异常类型吗?
    • Q5 什么是协程(Goroutine)
    • Q6 如何高效地拼接字符串
    • Q7 什么是 rune 类型
    • Q8 如何判断 map 中是否包含某个 key ?
    • Q9 Go 支持默认参数或可选参数吗?
    • Q10 defer 的执行顺序
    • Q11 如何交换 2 个变量的值?
    • Q12 Go 语言 tag 的用处?
    • Q13 如何判断 2 个字符串切片(slice) 是相等的?
    • Q14 字符串打印时,%v 和 %+v 的区别
    • Q15 Go 语言中如何表示枚举值(enums)
    • Q16 空 struct{} 的用途

Q1 = 和 := 的区别?

:= 声明+赋值

= 仅赋值

var foo int
foo = 10
// 等价于
foo := 10

Q2 指针的作用?

指针用来保存变量的地址。

例如

var x =  5
var p *int = &x
fmt.Printf("x = %d",  *p) // x 可以用 *p 访问
  • 运算符,也称为解引用运算符,用于访问地址中的值。
    &运算符,也称为地址运算符,用于返回变量的地址。

Q3 Go 允许多个返回值吗?

允许

func swap(x, y string) (string, string) {
   return y, x
}

func main() {
   a, b := swap("A", "B")
   fmt.Println(a, b) // B A
}

Q4 Go 有异常类型吗?

Go 没有异常类型,只有错误类型(Error),通常使用返回值来表示异常状态。

f, err := os.Open("test.txt")
if err != nil {
    log.Fatal(err)
}

Q5 什么是协程(Goroutine)

Goroutine 是与其他函数或方法同时运行的函数或方法。 Goroutines 可以被认为是轻量级的线程。 与线程相比,创建 Goroutine 的开销很小。 Go应用程序同时运行数千个 Goroutine 是非常常见的做法。

Q6 如何高效地拼接字符串

Go 语言中,字符串是只读的,也就意味着每次修改操作都会创建一个新的字符串。如果需要拼接多次,应使用 strings.Builder,最小化内存拷贝次数。

var str strings.Builder
for i := 0; i < 1000; i++ {
    str.WriteString("a")
}
fmt.Println(str.String())

Q7 什么是 rune 类型

ASCII 码只需要 7 bit 就可以完整地表示,但只能表示英文字母在内的128个字符,为了表示世界上大部分的文字系统,发明了 Unicode, 它是ASCII的超集,包含世界上书写系统中存在的所有字符,并为每个代码分配一个标准编号(称为Unicode CodePoint),在 Go 语言中称之为 rune,是 int32 类型的别名。

Go 语言中,字符串的底层表示是 byte (8 bit) 序列,而非 rune (32 bit) 序列。例如下面的例子中 语 和 言 使用 UTF-8 编码后各占 3 个 byte,因此 len(“Go语言”) 等于 8,当然我们也可以将字符串转换为 rune 序列。

fmt.Println(len("Go语言")) // 8
fmt.Println(len([]rune("Go语言"))) // 4

Q8 如何判断 map 中是否包含某个 key ?

if val, ok := dict["foo"]; ok {
    //do something here
}

dict[“foo”] 有 2 个返回值,val 和 ok,如果 ok 等于 true,则说明 dict 包含 key “foo”,val 将被赋予 “foo” 对应的值。
在这里插入图片描述

Q9 Go 支持默认参数或可选参数吗?

Go 语言不支持可选参数(python 支持),也不支持方法重载(java支持)。

Q10 defer 的执行顺序

多个 defer 语句,遵从后进先出(Last In First Out,LIFO)的原则,最后声明的 defer 语句,最先得到执行。
defer 在 return 语句之后执行,但在函数退出之前,defer 可以修改返回值。
例如:

func test() int {
	i := 0
	defer func() {
		fmt.Println("defer1")
	}()
	defer func() {
		i += 1
		fmt.Println("defer2")
	}()
	return i
}

func main() {
	fmt.Println("return", test())
}
// defer2
// defer1
// return 0

这个例子中,可以看到 defer 的执行顺序:后进先出。但是返回值并没有被修改,这是由于 Go 的返回机制决定的,执行 return 语句后,Go 会创建一个临时变量保存返回值,因此,defer 语句修改了局部变量 i,并没有修改返回值。那如果是有名的返回值呢?

func test() (i int) {
	i = 0
	defer func() {
		i += 1
		fmt.Println("defer2")
	}()
	return i
}

func main() {
	fmt.Println("return", test())
}
// defer2
// return 1

这个例子中,返回值被修改了。对于有名返回值的函数,执行 return 语句时,并不会再创建临时变量保存,因此,defer 语句修改了 i,即对返回值产生了影响。

Q11 如何交换 2 个变量的值?

a, b := "A", "B"
a, b = b, a
fmt.Println(a, b) // B A

Q12 Go 语言 tag 的用处?

tag 可以理解为 struct 字段的注解,可以用来定义字段的一个或多个属性。框架/工具可以通过反射获取到某个字段定义的属性,采取相应的处理方式。tag 丰富了代码的语义,增强了灵活性。

例如:

package main

import "fmt"
import "encoding/json"

type Stu struct {
	Name string `json:"stu_name"`
	ID   string `json:"stu_id"`
	Age  int    `json:"-"`
}

func main() {
	buf, _ := json.Marshal(Stu{"Tom", "t001", 18})
	fmt.Printf("%s\n", buf)
}

这个例子使用 tag 定义了结构体字段与 json 字段的转换关系,Name -> stu_name, ID -> stu_id,忽略 Age 字段。很方便地实现了 Go 结构体与不同规范的 json 文本之间的转换。

Q13 如何判断 2 个字符串切片(slice) 是相等的?

go 语言中可以使用反射 reflect.DeepEqual(a, b) 判断 a、b 两个切片是否相等,但是通常不推荐这么做,使用反射非常影响性能。

通常采用的方式如下,遍历比较切片中的每一个元素(注意处理越界的情况)。

func StringSliceEqualBCE(a, b []string) bool {
    if len(a) != len(b) {
        return false
    }

    if (a == nil) != (b == nil) {
        return false
    }

    b = b[:len(a)]
    for i, v := range a {
        if v != b[i] {
            return false
        }
    }

    return true
}

Q14 字符串打印时,%v 和 %+v 的区别

%v 和 %+v 都可以用来打印 struct 的值,区别在于 %v 仅打印各个字段的值,%+v 还会打印各个字段的名称。

type Stu struct {
	Name string
}

func main() {
	fmt.Printf("%v\n", Stu{"Tom"}) // {Tom}
	fmt.Printf("%+v\n", Stu{"Tom"}) // {Name:Tom}
}

但如果结构体定义了 String() 方法,%v 和 %+v 都会调用 String() 覆盖默认值。

Q15 Go 语言中如何表示枚举值(enums)

通常使用常量(const) 来表示枚举值。

type StuType int32

const (
	Type1 StuType = iota
	Type2
	Type3
	Type4
)

func main() {
	fmt.Println(Type1, Type2, Type3, Type4) // 0, 1, 2, 3
}

参考 What is an idiomatic way of representing enums in Go? - StackOverflow

Q16 空 struct{} 的用途

使用空结构体 struct{} 可以节省内存,一般作为占位符使用,表明这里并不需要一个值。

fmt.Println(unsafe.Sizeof(struct{}{})) // 0

比如使用 map 表示集合时,只关注 key,value 可以使用 struct{} 作为占位符。如果使用其他类型作为占位符,例如 int,bool,不仅浪费了内存,而且容易引起歧义。

type Set map[string]struct{}

func main() {
	set := make(Set)

	for _, item := range []string{"A", "A", "B", "C"} {
		set[item] = struct{}{}
	}
	fmt.Println(len(set)) // 3
	if _, ok := set["A"]; ok {
		fmt.Println("A exists") // A exists
	}
}

再比如,使用信道(channel)控制并发时,我们只是需要一个信号,但并不需要传递值,这个时候,也可以使用 struct{} 代替。

func main() {
	ch := make(chan struct{}, 1)
	go func() {
		<-ch
		// do something
	}()
	ch <- struct{}{}
	// ...
}

再比如,声明只包含方法的结构体。

type Lamp struct{}

func (l Lamp) On() {
        println("On")

}
func (l Lamp) Off() {
        println("Off")
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python高阶技巧 正则表达式

正则表达式&#xff0c;又称规则表达式&#xff08;Regular Expression&#xff09;&#xff0c;是使用单个字符串来描述、匹配某个句法规则的字符串&#xff0c;常被用来检索、替换那些符合某个模式&#xff08;规则&#xff09;的文本。 简单来说&#xff0c;正则表达式就是使…

Prometheus + Grafana安装

Prometheus是一款基于时序数据库的开源监控告警系统&#xff0c;非常适合Kubernetes集群的监控。Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态&#xff0c;任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的集成过程。这样做非常适合做…

Ceph入门到精通-远程开发Windows下使用SSH密钥实现免密登陆Linux服务器

工具&#xff1a; win10、WinSCP 服务器生成ssh密钥&#xff1a; 打开终端&#xff0c;使账号密码登录&#xff0c;输入命令 ssh-keygen -t rsa Winscp下载 Downloading WinSCP-6.1.1-Setup.exe :: WinSCP window 生成密钥 打开powershell ssh-keygen -t rsa 注意路径 …

Day10-NodeJS和NPM配置

Day10-NodeJS和NPM 一 Nodejs 1 简介 Nodejs学习中文网:https://www.nodeapp.cn/synopsis.html Nodejs的官网:https://nodejs.org/ 概念:Nodejs是JavaScript的服务端运行环境.Nodejs不是框架,也不是编程语言,就是一个运行环境. Nodejs是基于chrome V8引擎开发的一套js代码…

【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台2

吃完快餐粥&#xff0c;除了粥的味道不错之外&#xff0c;我对个快餐盒的圆盖子产生了兴趣&#xff0c;能否做个极低成本的简易机器人呢&#xff1f;也许只需要二十元左右 知识点&#xff1a;轮子&#xff08;wheel&#xff09; 中国词语。是用不同材料制成的圆形滚动物体。简…

Python以及Pycharm保姆级的下载安装教程,看完就懂

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Python的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Python的安装 1.下载地址 2.下载步骤…

Netty+springboot开发即时通讯系统笔记(一)

业务部分从sql开始&#xff1a; /*Navicat Premium Data TransferSource Server : localhostSource Server Type : MySQLSource Server Version : 50740Source Host : localhost:3306Source Schema : im-coreTarget Server Type : MySQLTarge…

微信小程序的自定义TabBar及Vant的使用

一、安装Vant 1、在 资源管理器 空白位置&#xff0c;点右键打开 在外部终端窗口打开 2、初始化NPM npm init -y 3、安装命令 npm i vant/weapp1.3.3 -S --production 4、构建NPM包 在 工具 里选择构建NPM包 5、删除style:v2 在app.json里&#xff0c;删除"style"…

SpringBoot中使用Swagger详解

在Spring Boot中规范的使用Swagger进行接口测试 文章目录 Swagger是什么&#xff1f;为什么要用Swagger&#xff1f;准备工作创建项目编写接口验证 高级配置文档注释接口过滤自定义响应 SwaggerUI的使用遇到的问题&#xff1a; Swagger是什么&#xff1f; Swagger是一套基于Op…

黑马大数据学习笔记4-Hive部署和基本操作

目录 思考规划安装MySQL数据库修改root用户密码配置Hadoop下载解压Hive提供MySQL Driver包配置Hive初始化元数据库启动Hive&#xff08;使用Hadoop用户&#xff09;Hive体验HiveServer2HiveServer2服务启动 Beeline p48、51、52 https://www.bilibili.com/video/BV1WY4y197g7/?…

机器学习——SMO算法推导与实践

一、 硬间隔-SMO算法推导 明天再说&#xff0c;啊。。。。感觉天空明朗了很多&#xff0c;即使现在已经很晚了 还是要打开柯南&#xff0c;看看电视&#xff0c;等待天气预报所说的台风天吧&#xff01; 一时之间&#xff0c;忽然失去了用markdown语法写下推导过程的勇气。。。…

【Docker】Docker+Zipkin+Elasticsearch+Kibana部署分布式链路追踪

文章目录 1. 组件介绍2. 服务整合2.1. 前提&#xff1a;安装好Elaticsearch和Kibana2.2. 再整合Zipkin 点击跳转&#xff1a;Docker安装MySQL、Redis、RabbitMQ、Elasticsearch、Nacos等常见服务全套&#xff08;质量有保证&#xff0c;内容详情&#xff09; 本文主要讨论在Ela…

Typescript 枚举类型

枚举是用来表示一组明确的可选值列表 // enum是枚举类型的关键字 //枚举如果不设置值&#xff0c;默认从0开始 enum Direction {Up, // 0 Down, // 1 Left, // 2Right // 3} //如果给第一个值赋值为100&#xff0c;则第二、第三第四个都会在第一个的基础上1 分别是101,102…

算法通过村第二关-链表黄金笔记|K个一组反转

文章目录 前言链表反转|K个一组翻转链表解题方法&#xff1a;头插法处理&#xff1a;穿针引线法处理&#xff1a; 总结 前言 提示&#xff1a;没有人天生就喜欢一种气味而讨厌另一种气味。文明的暗示而已。 链表反转|K个一组翻转链表 给你链表的头节点 head &#xff0c;每 k…

基于自组织竞争网络的患者癌症发病预测(matlab代码)

1.案例背景 1.1自组织竞争网络概述 前面案例中讲述的都是在训练过程中采用有导师监督学习方式的神经网络模型。这种学习方式在训练过程中,需要预先给网络提供期望输出,根据期望输出来调整网络的权重,使得实际输出和期望输出尽可能地接近。但是在很多情况下,在人们认知的过程中…

Redis安装以及配置隧道连接(centOs)

目录 1.centOs安装Redis 2. Redis 启动和停⽌ 3. 操作Redis 2.Xshell配置隧道 1.centOs安装Redis #使⽤yum安装Redis yum -y install redis 2. Redis 启动和停⽌ #查看是否启动 ps -ef|grep redis#启动redis: redis-server /etc/redis.conf &#停⽌Redis redis-cli sh…

TabR:检索增强能否让深度学习在表格数据上超过梯度增强模型?

这是一篇7月新发布的论文&#xff0c;他提出了使用自然语言处理的检索增强Retrieval Augmented技术&#xff0c;目的是让深度学习在表格数据上超过梯度增强模型。 检索增强一直是NLP中研究的一个方向&#xff0c;但是引入了检索增强的表格深度学习模型在当前实现与非基于检索的…

Docker入门——保姆级

Docker概述 ​ —— Notes from WAX through KuangShen 准确来说&#xff0c;这是一篇学习笔记&#xff01;&#xff01;&#xff01; Docker为什么出现 一款产品&#xff1a;开发—上线 两套环境&#xff01;应用环境如何铜鼓&#xff1f; 开发 – 运维。避免“在我的电脑…

QGraphicsView实现简易地图3『局部加载-地图缩放』

前文链接&#xff1a;QGraphicsView实现简易地图2『瓦片经纬度』 第一篇文章提到过&#xff0c;当地图层级较大时&#xff0c;暴力全加载地图会造成程序卡顿&#xff0c;因此需要实现地图的局部加载。 实现思路&#xff1a;以地图窗口&#xff08;以下称为视口&#xff09;为地…

如何搭建WordPress博客网站,并且发布至公网上?

如何搭建WordPress博客网站&#xff0c;并且发布至公网上&#xff1f; 文章目录 如何搭建WordPress博客网站&#xff0c;并且发布至公网上&#xff1f;概述前置准备1 安装数据库管理工具1.1 安装图形图数据库管理工具&#xff0c;SQL_Front 2 创建一个新数据库2.1 创建数据库2.…