以下是一些常见的 Go 语言基础知识笔试题:
1. 以下两个变量声明哪个是正确的?为什么?
```go
a := 10
b := 10.0
```
2. Go 语言中的指针有什么作用?请举例说明。
3. Go 语言允许多个返回值吗?请举例说明。
4. Go 语言有异常类型吗?如果有,如何使用?
5. 什么是协程(Goroutine)?如何在 Go 语言中使用协程?
6. 如何高效地拼接字符串?请给出示例代码。
7. 什么是 rune 类型?请举例说明。
8. 如何判断 map 中是否包含某个 key?请给出示例代码。
9. Go 支持默认参数或可选参数吗?如果支持,如何使用?
10. defer 的执行顺序是怎样的?请举例说明。
11. 如何交换两个变量的值?请给出示例代码。
12. Go 语言 tag 是用来做什么的?请举例说明。
13. 如何判断两个字符串切片(slice)是否相等?请给出示例代码。
14. 字符串打印时,%v 和 %+v 的区别是什么?请举例说明。
15. Go 语言中如何表示枚举值(enums)?请举例说明。
16. 空 struct{} 的用途是什么?它的实现原理是什么?
17. init() 函数是什么时候执行的?它在程序中的作用是什么?
18. Go 语言的局部变量分配在栈上还是堆上?请简要解释。
19. 简述 Go 语言GC(垃圾回收)的工作原理。
20. 函数返回局部变量的指针是否安全?为什么?
以下是这些问题的答案:
1. a := 10 是正确的声明,而 b := 10.0 是错误的声明。在 Go 语言中,变量声明需要使用 := 运算符,且声明的类型会被自动推断出来。对于 a := 10,由于整数可以隐式地转换为浮点数,因此可以正确声明变量 b 为浮点数类型。而 b := 10.0 则会导致编译错误,因为 10.0 是一个浮点数,不能被隐式地转换为整数类型。
2. Go 语言中的指针可以用来直接操作内存地址,从而可以避免复制数据和避免使用昂贵的内存分配。指针常用于以下情况:
go语言字符串转数组
    * 传递大的数据结构或对象时,可以通过传递指针来避免复制数据。
    * 在函数内部修改函数外部的变量时,可以通过传递指针来操作原始变量的内存地址。
    * 动态分配内存空间时,可以使用指针来引用分配的内存空间。
3.是的,Go语言允许多个返回值。使用多个值的赋值语句可以同时接收多个返回值。例如:
```go
a, b := f()
```
在这个例子中,函数 f() 返回两个值,分别赋值给变量 a 和 b。
4. Go 语言有异常类型,可以使用内置的 error 类型表示异常。在函数中遇到错误时,通常会返回一个错误值来表示异常情况。调用者可以通过检查返回的错误值来判断是否发生了异常,从而进行相应的处理。
5. 协程(Goroutine)是 Go 语言中轻量级的执行单位,可以与其他协程并发执行。通过使用关键字 go 可以启动一个新的协程。协程的启动和销毁非常轻量级,可以同时启动成千上万个协程而不会对系统产生太大的负担。协程之间可以通过通道(channel)进行通信和同步。
6. 在 Go 语言中,可以使用字符串拼接操作符 + 来高效地拼接字符串。例如:
```go
a := "Hello"
b := "World"
c := a + " " + b
```
也可以使用 fmt 包的 Sprintf 函数来格式化字符串并拼接:
```go
a := "Hello"
b := "World"
c := fmt.Sprintf("%s %s", a, b)
```
7. rune 类型是 Go 语言中用于表示 Unicode 码点(rune)的类型。它是一个整数类型,可以表示任意 Unicode 字符。例如:
```go
ch := '你' // ch 的类型是 rune
```
8. 在 Go 语言中,可以使用 map 的内置函数 ContainsKey 来判断 map 中是否包含某个 key。例如:
```go
m := make(map[string]int)
m["a"] = 1
value, ok := m["a"] // ok 的值为 true,因为 map 中包含 key "a"
if ok {
    fmt.Println(value) // 输出:1
} else {
    fmt.Println("Key not found") // 不输出任何内容,因为 ok 的值为 true
}
```
9. Go 语言通过预编译指令 `//go:noinline` 来表示特定的函数不应该被内联展开。内联展开是指在编译时将函数调用替换为函数体内代码的展开,可以提高执行效率,但会增加代码大小。因此,对于一些小型且频繁调用的函数,可以使用 `//go:noinline` 指令来禁止内联展开,以避免增加代码大小。
10. defer 的执行顺序是“后进先出”(Last In First Out),也就是说,最后一个被延迟执行的函数将最先被执行,而最先被延迟执行的函数将最后被执行。defer 语句通常用于注册函数调用,在程序退出前执行一些清理操作,例如关闭文件、释放资源等。
11. 在 Go 语言中,可以使用多重赋值来交换两个变量的值。例如:
```go
a := 10
b := 20
a, b = b, a // 通过多重赋值,将 a 和 b 的值交换
```
现在,`a` 的值变成了 20,而 `b` 的值变成了 10。
12. Go 语言中的 tag 是用于为结构体字段或类型添加元信息的标识符。tag 可以用来为程序
提供额外的信息或元数据,例如用于数据库或序列化等操作。在结构体字段声明后面使用 `//` 符号加上 tag 内容即可定义 tag。例如:
```go
type Person struct {
    Name string `json:"name"` // tag 可以为字段添加额外的信息,这里为 JSON 格式的字段名
    Age  int    `json:"age"`  // tag 可以为字段添加额外的信息,这里为 JSON 格式的字段名和类型
}
```
可以通过反射等方式来访问和解析 tag。
13. 在 Go 语言中,可以使用 len() 函数来判断两个字符串切片是否相等。如果两个字符串切片长度相等且每个对应位置的字符都相等,则它们被认为是相等的。可以使用循环遍历比较每个对应位置的字符,或者使用 reflect.DeepEqual() 函数进行深度比较。例如:
```go
slice1 := []string{"a", "b", "c"}
slice2 := []string{"a", "b", "c"}
if len(slice1) == len(slice2) && len(slice1) == len(slice2) {
    // 使用 reflect.DeepEqual() 进行深度比较
    if reflect.DeepEqual(slice1, slice2) {
        fmt.Println("切片相等")
    } else {
        fmt.Println("切片不相等")
    }
} else {
    fmt.Println("切片长度不相等")
}
```
14. 在 Go 语言中,%v 是 fmt.Printf() 函数的格式化占位符,用于输出变量的默认值。如果变量是一个字符串,%v 将输出字符串的内容;如果变量是一个数字,%v 将输出该数字的默认值。而 %+v 则是指定输出的格式化字符串包含变量的类型信息。例如:
```go
var x int = 42
var y float64 = 3.14
var z string = "Hello, World!"
fmt.Printf("%v\n", x)    // 输出:42
fmt.Printf("%v\n", y)      // 输出:3.14
fmt.Printf("%v\n", z)      // 输出:"Hello, World!"
fmt.Printf("%+v\n", x)      // 输出:"int 42" 或 "42 int"(取决于实现)
fmt.Printf("%+v\n", y)      // 输出:"float64 3.14" 或 "3.14 float64"(取决于实现)
fmt.Printf("%+v\n", z)      // 输出:"string Hello, World!" 或 "Hello, World! string"(取决于实现)
```
15. Go 语言没有明确的枚举类型,但是可以使用整型常量和字符串常量来模拟枚举。例如,
可以使用常量和自定义类型来定义一组相关的值:
```go
type Color int
const (
    Red Color = iota
    Green
    Blue
)
```
在这个例子中,`Color` 是一个自定义类型,而 `Red`、`Green` 和 `Blue` 是它的常量值。我们可以通过 `Color` 类型来比较和判断变量的值,例如:
```go
func main() {
    var c Color = Red
    switch c {
    case Red:
        fmt.Println("红")
    case Green:
        fmt.Println("绿")
    case Blue:
        fmt.Println("蓝")
    default:
        fmt.Println("未知颜")
    }
}
```
输出结果为:`红`。
16. 空 struct{} 的用途是作为占位符或空值,类似于其他语言的 nil 或 None。它没有任何字段,可以作为函数的返回值类型,表示函数没有返回值。空 struct{} 的实现原理是 Go 语言使用了零值初始化,即在没有显式初始化的情况下,会将变量初始化为零值。对于 struct{} 类型的变量,零值就是空 struct{}。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。