go基础语法50问,来看看你的go基础合格了吗?

目录

  • 1.使用值为 nil 的 slice、map会发生啥
  • 2.访问 map 中的 key,需要注意啥
  • 3.string 类型的值可以修改吗
  • 4.switch 中如何强制执行下一个 case 代码块
  • 5.你是如何关闭 HTTP 的响应体的
  • 6.你是否主动关闭过http连接,为啥要这样做
  • 7.解析 JSON 数据时,默认将数值当做哪种类型
  • 8.如何从 panic 中恢复
  • 9.简短声明的变量需要注意啥
  • 10.range 迭代 map是有序的吗
  • 11.recover的执行时机
  • 12.闭包错误引用同一个变量问题怎么处理
  • 13.在循环内部执行defer语句会发生啥
  • 14.说出一个避免Goroutine泄露的措施
  • 15.如何跳出for select 循环
  • 16.如何在切片中查找
  • 17.如何初始化带嵌套结构的结构体
  • 18.切片和数组的区别
  • 19.new和make的区别
  • 20.Printf()、Sprintf()、Fprintf()函数的区别用法是什么
  • 21.说说go语言中的for循环
  • 22.Array 类型的值作为函数参数
  • 23.说说go语言中的switch语句
  • 24.说说go语言中有没有隐藏的this指针
  • 25.go语言中的引用类型包含哪些
  • 26.说说go语言的main函数
  • 27.go语言触发异常的场景有哪些
  • 28.说说go语言的beego框架
  • 29.说说go语言的goconvey框架
  • 30.GoStub的作用是什么
  • 31.go语言编程的好处是什么
  • 32.说说go语言的select机制
  • 33.解释一下go语言中的静态类型声明
  • 34.go的接口是什么
  • 35.Go语言里面的类型断言是怎么回事
  • 36.go语言中局部变量和全局变量的缺省值是什么
  • 37.go语言编程的好处是什么
  • 38.解释一下go语言中的静态类型声明
  • 39.模块化编程是怎么回事
  • 40.Golang的方法有什么特别之处
  • 41.Golang可变参数
  • 42.Golang Slice的底层实现
  • 43.Golang Slice的扩容机制,有什么注意点
  • 44.Golang Map底层实现
  • 45. JSON 标准库对 nil slice 和 空 slice 的处理是一致的吗
  • 46.Golang的内存模型,为什么小对象多了会造成gc压力
  • 47.Data Race问题怎么解决?能不能不加锁解决这个问题
  • 48.在 range 迭代 slice 时,你怎么修改值的
  • 49.nil interface 和 nil interface 的区别
  • 50.select可以用于什么
1.使用值为 nil 的 slice、map会发生啥允许对值为 nil 的 slice 添加元素,但对值为 nil 的 map 添加元素,则会造成运行时 panic 。
// map 错误示例func main() {var m map[string]intm["one"] = 1// error: panic: assignment to entry in nil map// m := make(map[string]int)// map 的正确声明,分配了实际的内存}// slice 正确示例func main() { var s []int s = append(s, 1)}2.访问 map 中的 key,需要注意啥当访问 map 中不存在的 key 时,Go 则会返回元素对应数据类型的零值,比如 nil、’’ 、false 和 0,取值操作总有值返回,故不能通过取出来的值,来判断 key 是不是在 map 中 。
检查 key 是否存在可以用 map 直接访问,检查返回的第二个参数即可 。
// 错误的 key 检测方式func main() { x := map[string]string{"one": "2", "two": "", "three": "3"} if v := x["two"]; v == "" {fmt.Println("key two is no entry") // 键 two 存不存在都会返回的空字符串 }}// 正确示例func main() { x := map[string]string{"one": "2", "two": "", "three": "3"} if _, ok := x["two"]; !ok {fmt.Println("key two is no entry") }}3.string 类型的值可以修改吗不能,尝试使用索引遍历字符串,来更新字符串中的个别字符,是不允许的 。
string 类型的值是只读的二进制 byte slice,如果真要修改字符串中的字符 , 将 string 转为 []byte 修改后,再转为 string 即可 。
// 修改字符串的错误示例func main() { x := "text" x[0] = "T"// error: cannot assign to x[0] fmt.Println(x)}// 修改示例func main() { x := "text" xBytes := []byte(x) xBytes[0] = 'T' // 注意此时的 T 是 rune 类型 x = string(xBytes) fmt.Println(x) // Text}4.switch 中如何强制执行下一个 case 代码块switch 语句中的 case 代码块会默认带上 break,但可以使用 fallthrough 来强制执行下一个 case 代码块 。
func main() { isSpace := func(char byte) bool {switch char {case ' ': // 空格符会直接 break,返回 false // 和其他语言不一样// fallthrough // 返回 truecase '\t':return true}return false } fmt.Println(isSpace('\t')) // true fmt.Println(isSpace(' ')) // false}5.你是如何关闭 HTTP 的响应体的直接在处理 HTTP 响应错误的代码块中,直接关闭非 nil 的响应体;手动调用 defer 来关闭响应体 。
// 正确示例func main() { resp, err := http.Get("http://www.baidu.com")// 关闭 resp.Body 的正确姿势if resp != nil {defer resp.Body.Close() } checkError(err) defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) checkError(err) fmt.Println(string(body))}

推荐阅读