Introducing Go - O'Reilly 2016 阅读笔记

这篇博客是对O'Reilly 2016年出版的《Introducing Go》的阅读笔记,涵盖了Go语言的基础知识,包括类型、变量、控制结构、数组、切片、映射、函数、结构体、接口、包、测试、并发等内容。文中详细讨论了Go语言的特性和用法,如闭包、map的初始化、接口实现、并发操作等,并提供了实例解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Introducing Go

目录

Get Started

类型

变量

控制结构

  1. for i<=10 { ... } //for关键字这里用作while
  2. if:这里为什么不加()呢?跟Swift学的?还是跟Python?

Arrays, Slices, and Maps

  1. x := make(map[string]int) //map的默认值是nil,所有必须先make,才能往里面add元素
  2. 嵌套的map(JSON?):elements := map[string]map[string]string { ...

Functions

  1. 变参://这到底是运行时还是编译器的?
    1. func Println(a ...interface{}) (n int, err error)
    2. xs := []int{1,2,3}; fmt.Println(add(xs...))
  2. 闭包
    1. 支持闭包的前提是:外部引用变量是heap上分配的,但Go可以直接返回函数和C语言只能返回函数指针有什么不同?
  3. defer, panic, recover
  4. *与&

Structs and Interfaces

  1. c := &Circle{0, 0, 5} //这可能是Go语言里struct的最正常用法?
  2. 因为参数都是传值的(?),所以函数一般使用指针来传参?//C语言不也是传值的嘛,C++里可以传引用&
  3. func (r *Rectangle) area() float64 { ... }
    1. ==> r := Rectangle{0, 0, 10, 10}; r.area()
  4. 表达is-a:嵌入类型(好像另外那个语言也是这种匿名风格的?)
  5. Interfaces
    1. type Shape interface { area() float64 }

  1. strings
    1. strings.Contains("test", "es") //为什么不是直接在string对象上扩展方法?
    2. strings.Join([]string{"a","b"}, "-")
    3. strings.Replace("aaaa", "a", "b", 2) //最后一个参数代表最多替换个数?为什么不是startIndex呢
  2. IO:Reader与Writer
    1. func Copy(dst Writer, src Reader) (written int64, err error)
    2. bytes.Buffer
  3. Files and Folders
    1. file, err := os.Open("test.txt") //rw?
    2. stat, err := file.Stat() ==> stat.Size()
    3. os.Open(".").Readdir(-1) //这个代码有点太低级了
    4. 使用包path/filepath的目录遍历:
      1. filepath.Walk(".", func(path string, info os.FileInfo, err error) error { ...(可返回filepath.SkipDir停止遍历) } //似乎没有控制选项啊?
  4. container/list://双链表??有没有高级一点的数据结构
  5. sort.Sort
    1. 需要(数组)对象实现3个方法:Len() int、Less(i, j int) bool、Swap(i, j int) //Go语言支持a,b=b,a的交换赋值语法
  6. hash与密码学*
  7. Servers
    1. TCP
      1. listener, err := net.Listen("tcp", ":9999")
      2. for { con, err := listener.Accept() //嗯?必须收到一个连接才能收到下一个吗?
      3. err := gob.NewDecoder(c).Decode(&msg) //var msg string; gob是什么编解码算法?
      4. 客户端:
        1. c, err := net.Dial("tcp", "127.0.0.1:9999")
    2. HTTP
      1. http.HandleFunc("/hello", hello) //func hello(res http.ResponseWriter, req *http.Request) { ... }
      2. http.ListenAndServe(":9000", nil)
      3. 静态文件:http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets")),),) //这里是不是多了几个逗号?
    3. RPC(略)
  8. 解析命令行参数
    1. flag.Parse()

Testing

  1. _test.go
  2. import "testing"
    1. func TestAverage(t *testing.T) { ...t.Error(...)... }
  3. $ go test

并发

  1. <创建channel,并传递给goroutine>
  2. select {
    1. case <- time.After(time.Second): //超时
  3. c := make(chan int, 1) //缓冲的channel是异步的(但是超出限制仍然会阻塞吧)
  4. 发起http GET请求:res, err := http.Get(url) //这个也太简洁了吧?(没有请求Header的设置)

Next Steps

  1. 阅读Go pkg下的代码实现?
Linux block IO(块输入输出)是Linux操作系统的IO子系统,用于管理块设备(例如硬盘和SSD)的访问。在多核系统上引入多队列SSD访问是一种优化措施。 传统上,Linux操作系统在处理块设备访问时,使用单个队列(queue)来处理所有IO请求。这种单队列设计对于单核系统来说是合适的,因为只有一个CPU核心可以处理IO请求。然而,在多核系统中,这种设计却成为了性能瓶颈,因为所有的IO请求都必须经过单个队列,即使有多个CPU核心是可用的。 为了解决这个问题,Linux引入了多队列SSD访问功能。这意味着在多核系统上,每个CPU核心都有一个独立的队列来处理IO请求。每个队列可以独立处理IO请求,而不会受到其他队列的干扰。这种设计可以提高系统的并发性和吞吐量。 多队列SSD访问还可以充分利用SSD设备的性能特点。SSD设备通常具有多个通道(channel)和多个闪存芯片(chip),每个通道和芯片都可以同时处理IO请求。通过将IO请求分配给多个队列,可以同时利用多个通道和芯片,从而提高SSD的性能。 在Linux中实现多队列SSD访问需要对内核进行相应的修改和配置。用户可以通过命令和配置文件来设置每个队列的属性和参数,以满足特定场景下的需求。 总之,通过引入多队列SSD访问,Linux在多核系统上可以更好地利用硬件资源,提高系统的性能和吞吐量。这是一个重要的优化措施,可以提高块设备访问的效率和响应速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值