zoukankan      html  css  js  c++  java
  • 一个测试

    看到晨梦思雨老哥写的一个go语法50问,咱总称自己很懂go,语法总不能还不过关吧,所以当即决定测一下。

    https://blog.csdn.net/ma2595162349/article/details/115255041

    1.使用值为 nil 的 slice、map会发生啥

    slice是允许给nil slice添加值的,但是不能直接索引赋值,会提示index out of slice
    
    map的话,不可以直接操作
    

    2.访问 map 中的 key,需要注意啥

    没什么好注意的,只要知道其实是返回两个值就好
    if v, ok := m["first"]; ok {
        fmt.Println(v)
    }
    

    3.string 类型的值可以修改吗

    这大概牵扯到slice 的指针字段这种概念了。
    老哥一个例子不错,会用避坑就好了。
    // 修改字符串的错误示例
    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
    
    ————————————————
    版权声明:本文为CSDN博主「晨梦思雨」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/ma2595162349/article/details/115255041
    

    4.switch 中如何强制执行下一个 case 代码块

    go中不需要case-break,可能是为了防止不必要的case穿透,但是也可以加上fallthrough强制执行
    

    5.你是如何关闭 HTTP 的响应体的

    因人而异,感觉defer用不用都无所谓,只要别忘了关就好,还有为什么推荐用defer,这里有一个tcp链接的坑,不知老哥会不会补充
    	resp, err := http.Get("http://www.baidu.com")
    	if err != nil {
    		return
    	}
    	defer resp.Body.Close()
    

    6.你是否主动关闭过http连接,为啥要这样做

    咱还真不怎么关注主动关闭这点,一直感觉keepalive就ok了。实际上咱也懂一些网络协议,可以简单分析一下。
    KeepAlive带来的好处是可以减少HTTP连接的开销,提高性能。
    KeepAlive带来的坏处当然是多客户端连接,又都长期占有连接,程序可能会消耗完 socket 描述符。
    
    还有一点,哪边发起关闭连接,哪边会有TIME_WAIT,所以这个最好是客户端主动。
    
    关闭的方式?
    HTTP/1.1 defines the "close" connection option for the sender to signal that the connection will be closed after completion of the response. For example, 
           Connection: close 
           
    func main() {
    	req, err := http.NewRequest("GET", "http://www.baidu.com", nil)
    	if err != nil {
    		return
    	}
    
    	// method 1
    	req.Close = true
    
    	// method 2
    	//req.Header.Add("Connection", "close")
    
    	resp, err := http.DefaultClient.Do(req)
    	if err != nil {
    		return
    	}
    	defer resp.Body.Close()
    
    	b, err := ioutil.ReadAll(resp.Body)
    	
    	fmt.Println(string(b))
    }
    
    创建一个自定义配置的 HTTP transport 客户端,用来取消 HTTP 全局的复用连接。
    func main() {
    	tr := http.Transport{DisableKeepAlives: true}
    	client := http.Client{Transport: &tr}
    
    	resp, err := client.Get("http://www.baidu.com")
    	...
    }
    

    7.解析 JSON 数据时,默认将数值当做哪种类型

    说实话,老哥这有点为难人,不过我根据经验推导出是float64,答案果然是,但是还是验证一下了。
    func main() {
    	var data = []byte(`{"age": 12}`)
    	var res map[string]interface{}
    
    	if err := json.Unmarshal(data, &res); err != nil {
    		fmt.Println(err)
    	}
    	
    	fmt.Println(reflect.TypeOf(res["age"]))		// float64
    }
    
    

    8.如何从 panic 中恢复

    测试开发环境,我个人推荐直接panic,这也符合go的设计哲学,遇事不决,设计哲学。但是生产一定得recover捕捉啊,一个goroutine的panic也会导致整个程序挂掉。
    	defer func() {
    		if e := recover(); e != nil {
    			fmt.Println("recover")
    		}
    	}()
    

    9.简短声明的变量需要注意啥

    已经过24点了,有点困了,怎么才第九个,下面快速过了。
    这个记住一个坑,struct的字段不能直接 := 
    比如people1.age := 12 (wrong)
    为什么,应该讲你在这个属于声明,而你想做的是给people1.age赋值,赋值和声明不是一回事
    
    那为什么可以 a := 1 这里是声明加赋值,你再 a := 2 就报错了,因为声明只能一次,所以以后只能 a = 2
    
    

    10.range 迭代 map是有序的吗

    无序,你去看下汇编会定位到一个rand index的
    

    11.recover的执行时机

    不能直接调用,必须在 defer 函数中运行,而且不能嵌套
    

    12.闭包错误引用同一个变量问题怎么处理

    func main() {
        for i := 0; i < 5; i++ {
            i := i
            defer func() {
                println(i)
            }()
        }
    }
    func main() {
        for i := 0; i < 5; i++ {
            defer func(i int) {
                println(i)
            }(i)
        }
    }
    

    13.在循环内部执行defer语句会发生啥

    函数退出时延迟执行呗,还能发生啥。
    
    defer咱就正常用好吧,这里面的坑太多,不清楚为什么很多人喜欢问defer执行顺序。
    

    14.说出一个避免Goroutine泄露的措施

    不用goroutine!这不是我说的,Davey Cheney说的,简单来讲就是不会用,水平不够咱就别用。
    
    写完代码 go race 一下
    用context设置一下cancel
    尽量的咱用缓冲channel
    测试环境pprof
    ...
    

    15.如何跳出for select 循环

    哈哈,意不意外,居然没法break,这个设计一开始也不懂,后来看了优先级select后突然明白了妙处
    
    这里的答案是goto label 或者 break label
    

    16.如何在切片中查找

    放个截图吧
    

    image.png

    17.如何初始化带嵌套结构的结构体

    就那样初始化呗,嵌套的你就当一个对象“字段”
    

    18.切片和数组的区别

    除非这种需要 a := [3]int{}, 否则直接slice,其他写法也都是slice
    
    区别在于slice有一个数组指针,len,cap字段,还有一些扩容操作啊(这是一个小坑)
    
    

    19.new和make的区别

    老哥怎么也出这么题,这俩就不是一个用途,问区别有啥意思啊。
    
    new 返回一个指针
    
    make主要用于channel slice map的创建,困死不想多写了。
    

    20.Printf()、Sprintf()、Fprintf()函数的区别用法是什么

    有点不太想写了,老哥的问题越来越没意思了。
            fmt.Println(fmt.Sprintf("hello %s", "world"))
    	fmt.Fprintln(os.Stderr, "error!!!")
    

    21.说说go语言中的for循环

    break 和continue正常
    
    不过有一些坑,比如遍历map,slice,其实看汇编,长度已经确定,所以for append不会无限循环
    

    22.Array 类型的值作为函数参数

    // 数组使用值拷贝传参
    func main() {
     x := [3]int{1,2,3}
     
     func(arr [3]int) {
      arr[0] = 7
      fmt.Println(arr) // [7 2 3]
     }(x)
     fmt.Println(x)   // [1 2 3] // 并不是你以为的 [7 2 3]
    }
    
    // 传址会修改原数据
    func main() {
     x := [3]int{1,2,3}
     
     func(arr *[3]int) {
      (*arr)[0] = 7 
      fmt.Println(arr) // &[7 2 3]
     }(&x)
     fmt.Println(x) // [7 2 3]
    }
    

    23.说说go语言中的switch语句

    fallthrough
    

    24.说说go语言中有没有隐藏的this指针

    没有
    

    25.go语言中的引用类型包含哪些

    map slice channel interface
    

    26.go语言中指针运算有哪些

    & *  go不允许一些指针运算的,但是可以unsafe使用
    

    26.说说go语言的main函数

    主协程 mo go
    

    27.go语言触发异常的场景有哪些

    越界
    空指针
    除数0
    panic
    

    28.说说go语言的beego框架

    29.说说go语言的goconvey框架

    单元测试
    断言
    能web ui
    

    30.GoStub的作用是什么

    打桩
    

    31.go语言编程的好处是什么

    没有好处
    

    32.说说go语言的select机制

    for-select 异步io
    每个case都需要当作一个io操作
    

    33.解释一下go语言中的静态类型声明

    编译的时候用。
    
    动态语言一时超爽
    

    34.go的接口是什么

    非侵入式
    
    不懂泛型的码农喜欢自以为是的用interface充当泛型使用hhh
    

    35.Go语言里面的类型断言是怎么回事

    x.(type)
    

    36.go语言中局部变量和全局变量的缺省值是什么

    类型零值
    

    37.go语言编程的好处是什么

    重复了啊
    

    38.解释一下go语言中的静态类型声明

    ???
    

    39.模块化编程是怎么回事

    go以文件夹为模块,千万别再用MVC那种东西了
    

    40.Golang的方法有什么特别之处

    多返回值,可以返回指针(注意内存逃逸,Rust就不允许h
    

    41.Golang可变参数

    func test(a ...interface{}) {}
    

    42.Golang Slice的底层实现

    数组指针
    cap
    len
    

    43.Golang Slice的扩容机制,有什么注意点

    Go 中切片扩容的策略是这样的:
    
    首先判断,如果新申请容量大于 2 倍的旧容量,最终容量就是新申请的容量。
    
    否则判断,如果旧切片的长度小于 1024,则最终容量就是旧容量的两倍。
    
    否则判断,如果旧切片长度大于等于 1024,则最终容量从旧容量开始循环增加原来的  1/4 , 直到最终容量大于等于新申请的容量。
    
    如果最终容量计算值溢出,则最终容量就是新申请容量。
    
    !!!!!!!!!复制Slice,使用Copy(性能已经不错了)~~~~~~~~~~
    

    44.Golang Map底层实现

    底层散列表,map还是有一些复杂了,困就一个字,不写了
    
    1. JSON 标准库对 nil slice 和 空 slice 的处理是一致的吗
    肯定不一致啊
    

    46.Golang的内存模型,为什么小对象多了会造成gc压力

    看下Tmalloc吧
    

    47.Data Race问题怎么解决?能不能不加锁解决这个问题

    发现问题,只能证明存在问题,不能确保解决问题和没有问题。
    
    go test -race mypkg    // 测试包
    go run -race mysrc.go 
    

    48.在 range 迭代 slice 时,你怎么修改值的

    通过索引改
    

    49.nil 和 nil interface 的区别

    记住一点,比较要比较类型和值,两者一个不一致,就不相等
    

    50.select可以用于什么

    清楚 异步和阻塞就ok了
    

    怎么说呢,前面感觉还有点意思,后面就感觉差回事了。

    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    用鼠标滚轮做事件
    0927 匿名函数,隐藏显示层
    好友选中
    bzoj:1687;poj 2434:[Usaco2005 Open]Navigating the City 城市交通
    bzoj:1659: [Usaco2006 Mar]Lights Out 关灯
    bzoj:3392: [Usaco2005 Feb]Part Acquisition 交易
    bzoj:1723: [Usaco2009 Feb]The Leprechaun 寻宝
    poj 2434;bzoj 1686 [Usaco2005 Open]Waves 波纹
    bzoj:3397 [Usaco2009 Feb]Surround the Islands 环岛篱笆
    bzoj:3400 [Usaco2009 Mar]Cow Frisbee Team 奶牛沙盘队
  • 原文地址:https://www.cnblogs.com/CherryTab/p/14696079.html
Copyright © 2011-2022 走看看