①★GO语言面试之数据格式舒适版♥√
Posted 行走的皮卡丘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了①★GO语言面试之数据格式舒适版♥√相关的知识,希望对你有一定的参考价值。
①★GO语言面试之数据格式👈 |
1、🐹数组和切片
1.1 ☀️有如下代码,请说明两个切片的不同
msg := []int{1,2,3,4,5,6,7,8,9};
sli1 := msg[2:3:4]
sli2 := msg[2:3]
答:
考点: 切⽚容量
⾥⾯的数据⼀样,但是两个切⽚的容量不⼀样
容量 = max - low
1.2 ❄️写出下面程序运行的结果
func main(){
abc := make([]int,2)
abc = append(abc,1,2,3)
fmt.Println(abc)
}
答:
考点: 切⽚追加
结果:[0 0 0 0 0 0 0 0 0 0 1 2 3]
1.3 🐱下面代码输出什么?
package main
import "fmt"
func main(){
arr:=[]int{1,2,3,4,5,6,7,8}
s1:=arr[2:6]
s2:=s1[3:6]
fmt.Println("s1==",s1)
fmt.Println("s2==",s2)
}
答:
考点:切⽚截取
结果:
s1== [3 4 5 6]
s2== [6 7 8]
1.4 🐹是否可以编译通过?如果通过,输出什么?
package main
import "fmt"
func main() {
s1 := []int{1, 2, 3}
s2 := []int{4, 5}
s1 = append(s1, s2)
fmt.Println(s1)
}
答:
考点:append追加不定参
append切⽚时候别漏了’…’
结果:编译失败。
1.5 🐮解释Slice和Array的区别
答:
考点:数组和切⽚
结果:
array是固定⻓度的数组,使⽤前必须确定数组⻓度。
slice是⼀个引⽤类型,是⼀个动态的指向数组切⽚的指针。
slice是⼀个不定⻓的,总是指向底层的数组array的数据结构。
数组是值类型,把⼀个数组赋予给另⼀个数组时是发⽣值拷⻉,⽽切⽚是指针类型,拷⻉的是指针。
所以在golang的⽅法中即使是值传递切⽚,其实也是传递的指针。
数组⼤⼩是固定的,切⽚⼤⼩不是。在运⾏时可以动态地增加或减少切⽚的⼤⼩,但数组不可以。切
⽚类似于链表,可以向切⽚push,pop数据,实现FIFO,LIFO。使⽤了内置的添加、复制功能对切
⽚操作
1.6 🎍slice的底层实现
答:
考点:slice的底层实现
结果:
slice底层存储了三个内容:地址、⻓度、容量。
地址是指数据存储的位置。
⻓度表示有效数据的个数。
容量表示本次(不更换地址)可以扩容的最⼤值。
⻓度和容量随着append的添加⽽改变,地址可能改变。
2、🐑map
2.1 🎒写出⼀下程序运⾏的结果
package main
import (
"fmt"
)
func main(){
dict:=map[string]int{"王五":60,"张三":43}
modify(dict)
fmt.Println(dict["张三"])
}
func modify(dict map[string]int){
dict["张三"]=10
}
答:
考点:map作为函数参数,引⽤传递。
map作为函数参数是引⽤传递,形参可以修改实参的值。
结果:10
2.2 ☁️编译并运行如下代码会发生什么?
package main
import "fmt"
type Test struct {
Name string
}
var list map[string]Test
func main() {
list = make(map[string]Test)
name := Test{"xiaoming"}
list["name"] = name
list["name"].Name = "Hello"
fmt.Println(list["name"])
}
答:
考点:map
结果:编译失败。
编程报错 cannot assign to struct field list[“name”].Name in map 。 因为
list[“name”]不是⼀个普通的指针值,map的value本身是不可寻址的,因为map中的值会在内存
中移动,并且旧的指针地址在map改变时会变得⽆效。 定义的是var list map[string]Test,注意
哦Test不是指针,⽽且map我们都知道是可以⾃动扩容的,那么原来的存储name的Test可能在地
址A,但是如果map扩容了地址A就不是原来的Test了,所以go就不允许写数据。改为var list
map[string]*Test。
2.3 💝Map的键类型不能是哪些类型?
答:
考点:map的键
结果:字典的键类型不能是以下类型:函数类型,字典类型,切⽚类型
键类型的值之间必须⽀持判等操作,函数类型,字典类型,切⽚类型不⽀持判等操作
字典是引⽤类型,只声明⽽不初始化,值是nil。除了添加键-元素对,在值为nil的字典上操作都不
会引起错误。
3、🎑数据定义
3.1 🎅是否可以编译通过?如果通过,输出什么?
const (
x = iota
y
z = "zz"
k
p = iota
)
func main() {
fmt.Println(x,y,z,k,p)
}
答:
考点:常量定义和iota枚举赋值
结果:0 1 zz zz 4
iota 换⾏值+1
3.2 🔔编译执⾏下⾯代码会出现什么?
package main
var(
size :=1024
max_size = size*2
)
func main() {
println(size,max_size)
}
答:
考点:全局变量定义
结果:编译失败。
常量不允许使⽤⾃动推导类型。
3.3 📣下⾯函数有什么问题?
package main
const cl = 100
var bl = 123
func main() {
println(&bl,bl)
println(&cl,cl)
}
答:
考点:常量
结果:编译失败。
常量不同于变量的在运⾏期分配内存,常量通常会被编译器在预处理阶段直接展开,作为指令数
据使⽤,报错:cannot take the address。
3.4 💣编译执行下面代码会出现什么?
package main
import "fmt"
func main() {
type MyInt1 int
type MyInt2 = int
var i int = 9
var i1 MyInt1 = i
var i2 MyInt2 = i
fmt.Println(i1,i2)
}
答:
考点:type起别名
基于⼀个类型创建⼀个新类型,称之为defintion;基于⼀个类型创建⼀个别名,称之为alias。
MyInt1为称之为defintion,虽然底层类型为int类型,但是不能直接赋值,需要强转; MyInt2称
之为alias,可以直接赋值。
结果:编译失败。报错:annot use i (type int) as type MyInt1 in assignment。
3.5 🏠string和[ ]byte的区别
答:
考点:string和[ ]byte的区别
结果:
共同点:可以互相转化、都可以通过下标索引
不同点:
- 1、[ ]byte可以通过下标修改值,string不可以
- 2、string可以⽐较,[ ]byte不可以⽐较,所以[ ]byte不能作为map的key值
- 3、[ ]byte在传输性能⽅⾯要⽐string好
- 4、string的值不可以为nil,所以如果需要nil的特性,就得⽤[]byte
4、😄指针
4.1🍆 是否可以编译通过?如果通过,输出什么?
func main() {
list := new([]int)
list = append(list, 1)
fmt.Println(list)
}
答:
考点:new和make
结果:编译失败。
切⽚指针的解引⽤。
可以使⽤list:=make([]int,0) list类型为切⽚
或使⽤*list = append(*list, 1) list类型为指针
4.2 💜make和new的区别
答:
考点:new和make
结果:⼆者都是内存的分配(堆上),但是make只⽤于slice、map以及channel的初始化(⾮零值);⽽
new⽤于类型的内存分配,并且内存置为零。所以在我们编写程序的时候,就可以根据⾃⼰的需要很
好的选择了。
make返回的还是这三个引⽤类型本身;⽽new返回的是指向类型的指针。
5、💕interface
5.1 👍以下代码输出什么?
func main() {
i := GetValue()
switch i.(type) {
case int:
println("int")
case string:
println("string")
case interface{}:
println("interface")
default:
println("unknown")
}
}
func GetValue() int {
return 1 }
答:
考点:interface{}类型和函数类型
结果:编译失败。
因为type只能使⽤在interface
5.2 🐷是否可以编译通过?如果通过,输出什么?
func Foo(x interface{}) {
if x == nil {
fmt.Println("empty interface")
return
}
fmt.Println("non-empty interface")
}
func main() {
var x *int = nil
Foo(x)
}
答:
考点:interface内部结构
结果:non-empty interface
5.3 🐌ABCD中哪一些存在错误?
type S struct {
}
func f(x interface{}) {
}
func g(x *interface{}) {
}
func main() {
s := S{}
p := &s
f(s) //A
g(s) //B
f(p) //C
g(p) //D
}
答:
考点:interface
结果:B和D错误。
看到这道题需要第⼀时间想到的是Golang是强类型语⾔,interface是所有golang类型的⽗类, 函
数中 func f(x interface{}) 的 interface{} 可以⽀持传⼊golang的任何类型,包括指针,但
是函数 func g(x *interface{}) 只能接受 *interface{} .
6、🍄函数和闭包
6.1 🌝下面函数有什么问题?
func funcMui(x,y int)(sum int,error){
return x+y,nil
}
答:
考点:函数返回值命名
结果:编译出错。
在函数有多个返回值时,只要有⼀个返回值有指定命名,其他的也必须有命名。 如果返回值有有
多个返回值必须加上括号; 如果只有⼀个返回值并且有命名也需要加上括号; 此处函数第⼀个返
回值有sum名称,第⼆个未命名,所以错误。
6.2 🌔是否可以编译通过?如果通过,输出什么?
func GetValue(m map[int]string, id int) (string, bool) {
if _, exist := m[id]; exist {
return "存在数据", true
}
return nil, false
}
func main() {
intmap:=map[int]string{
1:"a",
2:"bb",
3:"ccc",
}
v,err:=GetValue(intmap,3)
fmt.Println(v,err)
}
答:
考点:函数返回值类型
结果:编译失败。
nil 可以⽤作 interface、function、pointer、map、slice 和 channel 的“空值”。但是如果不特别
指定的话,Go 语⾔不能识别类型,所以会报错。
6.3 🔎编译执⾏下⾯代码会出现什么?
package main
func main() {
for i:=0;i<10 ;i++ {
loop:
println(i)
}
goto loop
}
答:
考点:goto跳转语句
结果:编译失败。
goto不能跳转到其他函数或者内层代码,报错:goto loop jumps into block starting at。
6.4 🏀编译执行下面代码会出现什么?
package main
func test() []func() {
var funs []func()
for i:=0;i<2 ;i++ {
funs = append(funs, func() {
println(&i,i)
})
}
return funs
}
func main(){
funs:=test()
for _,f:=range funs{
f()
}
}
答:
考点:闭包延迟求值 for循环复⽤局部变量i,每⼀次放⼊匿名函数的应⽤都是同⼀个变量。
结果:
0xc042046000 2
0xc042046000 2
如果想不⼀样:
func test() []func() {
var funs []func()
for i:=0;i<2 ;i++ {
x:=i
funs = append(funs, func() {
println(&x,x)
})
}
return funs
}
结果:
0xc000096000 0
0xc000096008 1
6.5🍪 编译执行下面代码会出现什么?
package main
func test(x int) (func(),func()) {
return func() {
println(x)
x+=10
}, func() {
println(x)
}
}
func main() {
a,b:=test(100)
a()
b()
}
答:
考点:闭包引⽤相同变量
结果:
100
110
6.6 🍭输出什么?
package main
import (
"fmt"
)
func main() {
fmt.Println(len("你好bj!"))
}
答:
考点:len函数的返回值,编码⻓度。
⼀个中⽂占三个字节。
结果:9
6.7 🍏实现函数
func main(){
var num interface{} = 1.2345
//使⽤reflect输出类型与值
}
答:
考点:反射
结果:
func main(){
var num float64 = 1.2345
//使⽤reflect输出类型与值
//类型
fmt.Println(reflect.TypeOf(num))
//值
fmt.Println(reflect.ValueOf(num))
}
6.8 🍒编写⼀个函数,实现字符串反转,函数输⼊类型为string
示例:锄⽲⽇当午 转换后 午当⽇⽲锄
答:
考点:函数实现
结果:
func reverse(str string) string {
rs := []rune(str)
len := len(rs)
var tt []rune
tt = make([]rune, 0)
for i := 0; i < len; i++ {
tt = append(tt, rs[len-i-1])
}
return string(tt[0:])
}
func main(){
str:="锄⽲⽇当午"
reverse(str)
}
以上是关于①★GO语言面试之数据格式舒适版♥√的主要内容,如果未能解决你的问题,请参考以下文章