GO语言核心30讲 实战与应用 (io包,bufio包,os包,网络服务,http,性能分析)

news2025/2/28 20:21:21

 原站地址:Go语言核心36讲_Golang_Go语言-极客时间

一、io包中的接口和工具

1. strings.Builder、strings.Reader 和 bytes.Buffer 这些类型实现了 io 包的很多接口,目的是什么

    是为了提高不同程序实体之间的互操作性。 程序实体是指比如网络和文件。

    比如 io.Copy:  func Copy(dst Writer, src Reader) (written int64, err error)

    里面的 Writer 和 Reader 可以是网络,也可以是文件,只要实现了io.Reader接口和io.Writer接口就都可以了。可以把不同的实体抽象成一个统一的实体。

2. 扩展接口和实现类型的区别是什么?

   实现类型是一个结构体; 扩展接口只是通过结构体的方式,嵌入了其他数据类型,达到扩展原有数据类型功能的目的,

   扩展接口是多个接口的集合。要实现扩展接口,需要实现多个接口。

   实现类型是把接口实现了,而扩展接口并没有把接口实现,它只是多个接口的集合。

3. 在io包中,io.Reader的扩展接口实现类型都有哪些? (提升对io包的了解程度)

    io.Reader的扩展接口有下面几种:

(1) io.ReadWriter:包含字节序列读取方法Read,和写入方法Write。

(2) io.ReadCloser:包含字节序列读取方法Read,和关闭方法Close。Close用于关闭数据读写的通路。这个接口是io.Reader和io.Closer的组合。

(3) io.ReadWriteCloser:io.Reader、io.Write 和io.Closer的组合。

(4) io.ReadSeeker:可以根据给定的偏移量去寻找新的位置,作为下一次读的起始索引。包含了寻找读写位置的基本方法Seek。io.Reader 和io.Seeker的组合。

(5) io.ReadWriteSeeker:io.Reader、io.Writer和io.Seeker的组合。

   io.Reader接口的实现类型有下面几种:

(1) *io.LimitedReader:方法Read返回的总数据量会受到限制,无论被调用多少次。

(2) *io.SectionReader:Read方法只能够读取原始数据中的某一个部分。与切片类似,只暴露在窗口之中的数据。

(3) *io.teeReader:接受io.Reader和io.Writer两个类型的参数,把Reader读到的数据,通过字节切片中转的方式,写入io.Writer处。通常使用在数据流的处理中,比如计算下载速度。

(4) *io.multiReader:接受多个io.Reader类型的参数,并从中顺序地读取数据。

(5) *io.pipe:同步内存管道的核心实现

(6) * io.PipeReader:同步内存管道的读取端

4. io包中的接口都有哪些?

(1) 核心接口:io.Reader、io.Writer和io.Closer

(2) io.ByteReader:读取一个单一的字节。 strings.Reader和bytes.Buffer 是它的实现类型。

     io.RuneReader:读取一个单一的Unicode 字符。strings.Reader和bytes.Buffer 是其实现类型

     io.ByteScanner:读取和读回退单个字节

     io.RuneScanner:读取和读回退单个Unicode 字符

     io.ReaderAt:只读取数据,不修改已读计数的值。

     io.ReaderFrom:从一个 Reader 中读取数据

     io.WriteTo:将数据写入到一个 Writer 中

     io.ReadWriter:读和写, *io.pipe 是其实现类型。

     io.ReadWriteCloser:读写和关闭管道,net包有它的实现类型。

     io.ByteWriter和io.WriterAt:功能和上面对应。实现类型是 *os.File

     io.Seeker:寻找并设定下一次读取或写入时的起始索引位置。strings.Reader和io.SectionReader都是其实现类型。

    io.Closer:关闭管道。io.PipeReader和io.PipeWriter 是其实现类型。

(3) io包中的简单接口共有 11 个。读取操作相关的5 个,写入操作相关的 4 个,关闭操作有关的1 个,读写位置设定相关的一个。此外,还包含了 9 个基于这些简单接口的扩展接口。

二、bufio包中的数据类型

1. bufio 包的程序实体,是在包装简单 I/O 接口类型值的基础上,添加了缓冲区

2. bufio包中的数据类型主要有:(1) Reader (2) Scanner (3) Writer 和 ReadWriter。

3. bufio.Reader类型值中的缓冲区起着怎样的作用?

        Reader值会预先从底层读取器里读出一部分数据,暂存于缓冲区之中。当Reader值下次读取数据时,先从缓冲区中读取。 减少了底层读取器的使用次数,降低读取的执行时间。 

        虽然,读取时会增加填充缓冲区的操作,但从总体上看,平均执行时间会有大幅度的缩短。

4. bufio.Reader类型通过私有的 fill方法 来整理缓冲区,把已读的空间腾出来,提供给底层读取器存放数据。

    整理方法就是把 [已读计数, 已写计数) 范围内的数据往最前面搬运,如下图所示:

5. bufio.Reader类型读取方法分别有哪些?

(1) Peek方法:读取缓冲区中的n个未读字节,n大于缓冲区长度的话,转而直接从底层读取器中读出数据。

      会从已读计数代表的索引位置开始读,读完不更改已读计数。 

(2) Read方法:其他和Peek方法一样,但会更改已读计数。 

(3) ReadSlice方法:持续地读取数据,直至遇到调用方给定的分隔符为止。

     如果缓冲区满了仍然找不到分隔符,会把整个缓冲区作为第一个结果值,缓冲区已满错误作为第二个结果值 返回。

(4) ReadBytes方法: 其他和ReadSlice方法一样,但缓冲区满了仍然找不到分隔符的话,会再次调用ReadSlice方法,整理缓冲区之后继续从底层读取器中读出数据,直至少找到分隔符或者读完全部数据。

6. 内容泄露:Peek方法、ReadSlice方法和ReadLine方法都有可能会造成内容泄露,因为他们都是返回直接基于缓冲区的字节切片。 只有Read方法不会内容泄露。

三、使用os包中的API

1. os代码包中的 API,是对操作系统的某方面功能的高层次抽象,使我们可以用统一的方式,操纵不同的操作系统。

    最有代表性的就是数据类型 os.File,它实现了io包3 个核心接口io.Reader、io.Writer和io.Closer,3 个简单接口,io.ReaderAt、io.Seeker和io.WriterAt,以及9 个扩展接口中的 7 个。

    所以除 文本文件、二进制文件、压缩文件、目录这些常见的形式之外,还有符号链接、各种物理设备、命名管道,以及套接字(socket)都可以被视为文件。

2. 怎样才能获得一个os.File类型的指针值(File值)? 

(1) os.Create函数:根据给定的路径创建一个新的文件。 

      会返回一个File值和一个错误值。可以通过File值进行读写,路径不存在的话会返回错误。

(2) os.Open函数:打开一个文件并返回包装了该文件的File值。

      只能从该File值中读取内容,而不能写入内容。

(3) os.NewFile函数:依据已经存在的文件描述符,新建包装了该文件的File值。

(4) os.OpenFile函数:新建或打开文件。

     可读可写。函数有 3 个参数,为name(文件路径)、flag(操作模式)和perm(权限模式)。

     可以视为这是基础函数,上面3个函数只是这个基础函数的参数组合。

3. 文件描述符,作为某个文件的一个标识存在。由 I/O 相关的系统调用返回,是很小的非负整数。

    任何文件的I/O 操作都需要这个文件描述符,它被存储在File值中。

4. File值的操作模式都有哪些?

    os.O_APPEND:追加模式写入内容。

    os.O_CREATE:路径不存在时创建文件。

    os.O_SYNC:在打开的文件上实施同步 I/O,保证读写的内容总会与硬盘上的数据同步。

    os.O_TRUNC:文件已存在时清空文件内容。

    多个操作模式可以通过按位或操作符 " | " 组合起来的。

5. File值的权限模式都有哪些?

    权限模式参数 是uint32类型的再定义类型,包含了 32 个比特位,每个比特位都有特定含义:

(1) 最高比特位,1 代表 目录。

(2) 第 26 个比特位,1代表 命名管道

(3) 最低的 9 个比特位才用于文件的权限,分别是 文件所有者、用户组、其他用户 对该文件的访问权限(读、写和执行)。

四、访问网络服务

1. 进程间通信,称为 IPC。主要方法包括:系统信号(signal)、管道(pipe)、套接字(socket)、文件锁、消息队列、信号量(semaphore)等。 socket 是最为通用和灵活的一种。

2. socket实例相关的API,是由一个名为 socket系统调用 代表的,它是连接应用程序和操作系统内核的桥梁。

    syscall代码包中,有一个与这个 socket系统调用 相对应的函数。函数本身是平台不相关的。在其底层,Go 为每个操作系统都做了适配,所以无论在哪个平台上总是有效的。

    net代码包中的很多程序实体,都会直接或间接地使用到syscall.Socket函数,比如net.Dial函数

3. net.Dial函数的第一个参数network有哪些可选值?

(1) TCP、TCP4、TCP6:代表 TCP 协议,自适应、第四版、第六版

(2) UDP、UDP4、UDP6:代表 UDP 协议,自适应、第四版、第六版

(3) unix、unixgram、unixpacket:代表 Unix 通信域下的内部 socket 协议,socket 类型分别为SOCK_STREAM、SOCK_DGRAM、SOCK_SEQPACKET。

4. 有消息边界,是指内核程序在发送或接收数据时,是以消息为单位的。

    有逻辑连接,是指通信双方在收发数据之前必须先建立网络连接

5. TCP 没有消息边界,有逻辑连接。 好处:保证可靠性,有序,双向传输。坏处:速度慢。

    UDP 有消息边界,没有逻辑连接。好处:速度快。坏处:不保证可靠,无需,只能单向传输。

6. net.DialTimeout函数 调用时给定的超时时间意味着什么?

   给定的超时时间,意味着函数为网络建立连接,可以等待的最长时间。

   调用net.DialTimeout函数之后,时间主要花费在 “解析参数network和address的值”,以及“创建 socket 实例并建立网络连接”这两件事情上。

五、基于HTTP协议的网络服务

1. net/http代码包 可以使用 基于http协议的网络服务。比如 http.Get函数。

    实例:  resp, err := http.Get(url)    返回两个值:resp 和 err

    resp:数据类型是*http.Response,响应内容的结构体。

    err:数据类型是error,创建、发送请求、接收和解析、响应 全过程中,可能发生的错误。

2. http.Get函数

    http.Get函数会在内部使用 缺省HTTP客户端,它是 net/http包中的公开变量DefaultClient代表的,其类型是 *http.Client, 它是开箱即用的。

3. http.Client类型中的 Transport字段 代表着什么?

(1) Transport字段 的数据类型是 *http.Transport,会在内部使用net.Dialer类型值,实现 连接 和 超时 的功能。

(2) http.Transport类型的值(以下简称Transport值)会对每一个网络服务的空闲连接的总数做出限定。 一个网络服务由网络地址、网络协议、代理 三方面来鉴定。

     在默认情况下,空闲连接总数最大为100,而每个网络服务的最大空闲连接数为2。

(3) *http.Transport 是 http.RoundTripper接口 的实现类型。RoundTripper 内部有一个DefaultTransport的缺省值。 前面提到的 缺省HTTP客户端 DefaultClient ,其实也就是使用这个DefaultTransport。

(4) 总的来说 Transport字段代表着:向网络服务发送 HTTP 请求,并从网络服务接收 HTTP 响应的整个操作过程。

4. http.Server类型的ListenAndServe方法都做了哪些事情?

(1) 对一个基于 TCP 协议的网络地址进行监听(net.Listen),并对接收到的 HTTP 请求进行处理。

(2) 默认开启针对网络连接的存活探测机制,以保证连接是持久的。

(3) 该方法会一直执行,直到有严重的错误发生或者被外界关掉。

5. net.Listen函数都做了哪些事情?

(1) 解析参数值中网络地址包含的 IP 地址端口号

(2) 根据给定的网络协议,确定监听的方法,并开始进行监听。

6. http.Server类型的Serve方法是怎样接受和处理 HTTP 请求的?

(1) listen之后,进入一个for循环。

(2) for循环中,Accept方法会被不断地调用,该方法返回两个值:

     net.Conn类型:代表包含了新到来的 HTTP 请求的网络连接

     error类型:代表是否发生了错误。暂时性的错误的话for会继续执行,否则会for循环都会被终止

(3) 把 net.Conn类型的结果值包装成一个*http.conn类型,并启用新的 goroutine ,去调用这个conn值的serve方法,来对当前的 HTTP 请求进行处理。

六、程序性能分析基础

1. 性能分析 API 在这三个代码包中:

(1) runtime/pprof

(2) net/http/pprof

(3) runtime/trace

2. 概要文件(Profile)

   runtime 代码包中包含更底层的 API,用来收集程序运行过程中的一些关键指标,并生成概要文件,提供分析使用。

    go test 命令也可以在测试完成后生成 概要文件(Profile)。

3. 概要文件采样时刻的内容

      分析程序性能的概要文件有CPU、内存、阻塞三种概要文件。文件里每段概要信息都记录着,某个采样时刻的内容分别是:

(1) CPU 概要文件:CPU 上正在执行的 Go 代码。

(2) 内存概要文件:内存的使用情况,已分配和已释放的字节数量和对象数量。

(3) 阻塞概要文件:goroutine 阻塞事件

4. 概要文件内容格式

    这些概要文件是以二进制存储的,是通过 protocol buffers 生成的二进制字节流。

    可以使用 go tool pprof 工具查看。

5. 怎样让程序对 CPU 概要信息进行采样?

(1) 进行采样调用StartCPUProfile函数;停止采样调用StopCPUProfile函数。

(2) StartCPUProfile函数,会设定 CPU 概要信息的采样频率,并在单独的 goroutine 中进行收集和输出。 CPU采样频率总是固定100赫兹的,经过大量实验证明最优。

(3) StopCPUProfile函数,会采样频率设为0,采样工作停止。

6. 怎样设定内存概要信息的采样频率?

(1) 为 runtime.MemProfileRate变量赋值即可。 含义是,每分配多少个字节,就对堆内存的使用情况进行一次采样。缺省值是512 KB。

(2) 越早设定越好,避免运行时造成不良影响。最好只在main函数的开始处设定一次。

(3) 想获取内存概要信息的时候, 调用WriteHeapProfile函数。但它并非实时数据,是在最近一次的内存垃圾收集工作完成时产生的。

(4) 可以调用runtime.ReadMemStats函数,获得实时数据。不过该函数会引起 Go 语言调度器的短暂停顿。

7. 怎样获取到阻塞概要信息?

(1) 调用runtime包中的SetBlockProfileRate函数,可对阻塞概要信息的采样频率进行设定。

(2) 函数有一个名叫rate的参数,int类型。含义是,只要发现一个阻塞事件的持续时间达到了多少纳秒,就对其进行采样。

(3) 在runtime包中,有一个名叫blockprofilerate的私有变量,uint64类型。含义是,只要发现一个阻塞事件的持续时间跨越了多少个 CPU 时钟周期,就对其进行采样。和(2)的区别仅仅在于单位不同。 

(4) 缺省值是0,所以默认情况下并不会记录任何阻塞事件。

(5) 需要获取阻塞概要信息的时候,做两步操作:

    调用runtime/pprof包中的 Lookup函数 并传入参数值"block",得到*runtime/pprof.Profile类型的值     

    调用Profile值的 WriteTo方法,把概要信息写进指定的写入器中。

8. runtime/pprof.Lookup函数的正确调用方式是什么?

(1) Lookup函数的功能是,提供 给定的名称 相对应的概要信息。

(2) 给定的名称 包括:

goroutine:收集当前正在使用的所有 goroutine 堆栈跟踪信息。会引起 Go 调度器的短暂停顿。

heap:收集与堆内存的分配和释放有关的采样信息。也就是前面的内存概要信息。

allocs:与heap大致一样,但 allocs 收集到的是已分配空间(已分配不管有否释放),heap是在用空间(已分配未释放)。

threadcreate:收集堆栈跟踪信息,描绘出代码调用链。

block:在代码同步竞争中被阻塞的代码的堆栈跟踪信息。就是前面的阻塞概要信息。

mutex:在代码同步竞争中,获得过执行的代码的堆栈跟踪信息。

9. 如何为基于 HTTP 协议的网络服务添加性能分析接口?

(1) 在程序中导入net/http/pprof代码包。

     import _ "net/http/pprof"

(2) 启动网络服务并开始监听。

     log.Println(http.ListenAndServe("localhost:8082", nil))

(3) 在浏览器中访问  http://localhost:8082/debug/pprof  看到一个简约的网页

(4) 在/debug/pprof/ 这个URL路径下还有很多可用的子路径,包括:profile,trace,allocs、block、goroutine、heap、mutex、threadcreate。

(5) 返回二进制内容时,需要使用  go tool pprof 工具去查看。

    go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1681721.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

给app引导页说goodbye吧,皮之不存,毛将焉附。

有几个原因导致大部分创业者选择不开发独立的移动应用程序(App): 成本和资源:开发和维护一个独立的移动应用程序需要投入大量的时间、资金和人力资源。对于创业公司来说,他们可能没有足够的资源来支持这样的开发和维护…

jumpserver接入ldap

ldap部署 基本安装和人员导入 1.CentOS7安装配置OpenLDAP与phpLDAPadmin (koomu.cn) 2.https://koomu.cn/centos7-install-openldap-server-and-phpldapadmin/ https://senmer.github.io/zh/posts/tech/ldap/openldap%E5%AE%89%E8%A3%85%E5%92%8C%E4%BD%BF%E7%94%A8/#%e4%b8%…

【上海生物发酵展精选展商】三门峡市高瑞生物技术有限公司

三门峡市高瑞生物技术有限公司注册成立于2017年2月23日,经营范围是微生物培养基原材料制造、销售。2017年度因场地搬迁、异地重建,公司由“三门峡市高山生物制品有限公司”更名为“三门峡市高瑞生物技术有限公司”。 该公司具有20余年丰富经验的微生物培…

杨校老师项目之基于SpringBoot的驾校预约课程管理系统

1.获取代码: 有偿获取:mryang511688 2.技术栈 后端 SpringBoot MySQL MyBatis Redis 前端 html、css、Javascript、Jquery 3.开发环境 JDK1.8、Maven3.5.4、MySQL5.7、Redis5.0.5、IntelliJ IDEA 4.内置功能 Springboot的项目,代码简…

React渲染流程

在 React 渲染分为两个阶段,Render 和 Commit,Render 是修改 React 组件的状态,把需要更新的组件标记为待更新,在 Commit 阶段将待更新的组件进行渲染并最终更新到浏览器的 Dom 树中。 Render 阶段是可以并执行操作的&#xff0c…

创龙教仪联合武汉纺织大学机械工程与自动化学院DSP实验室建设案例

原文链接:http://985.so/9n8h7 1►院校简介 西安邮电大学是一所以工为主,以信息科学技术为特色,工、管、理、经、文、法、艺多学科协调发展的普通高等学校,是我国特别是西北地区信息产业和现代邮政业人才培养、科学研究的重要基地…

Alembic 的使用(配合一款免费云数据库MemfireDB)

已经使用 Go 开发好一段时间了,最近因为工作原因又重操旧业搞起了 Python,基于 FastAPI 进行接口开发,然后去找了一下相关的脚手架,发现这其中挺多都用到了 Alembic,之前没使用过,于是学习了一下&#xff0…

MySQL创建存储过程函数(2)

DDL CREATE TABLE student (id int(11) NOT NULL AUTO_INCREMENT COMMENT 学号,createDate datetime DEFAULT NULL,userName varchar(20) DEFAULT NULL,pwd varchar(36) DEFAULT NULL,phone varchar(11) DEFAULT NULL,age tinyint(3) DEFAULT NULL,sex char(2) DEFAULT NULL,i…

STM32时钟系统和时钟树

目录 STM32时钟系统 认识时钟树 什么是时钟 认识时钟树(F407) 配置系统时钟 系统时钟配置步骤 外设时钟使能和失能 sys_stm32_clock_init函数(F4) 时钟配置一般步骤 System文件夹_时钟系统工作原理 System文件夹介绍 Sys文件介绍 Delay文件介绍 Systic工作原理 S…

Ps 滤镜:干画笔

Ps菜单:滤镜/滤镜库/艺术效果/干画笔 Filter Gallery/Artistic/Dry Brush 干画笔 Dry Brush滤镜用于模拟使用干画笔技术(介于油彩和水彩之间)绘制的效果。此滤镜特别适用于为图像添加粗糙而富有表现力的笔触效果,同时减少细节&…

计算机发展史故事【17】

任天堂崛起 七十年代美国雅达利公司开创一个高科技的电脑游戏业。无独有偶,一家专营电脑游戏机的日本任天堂公司,自八十年代初期把它的家庭电脑游戏机(FC)投放市场后,不平静的世界被再一次激起轩然大波。这个小小的日本…

测缝计测量的是实际缝宽吗?

在土木工程中,测缝计作为一种重要的监测工具,广泛应用于桥梁、隧道、大坝等大型结构中,用以测量和监控结构接缝或裂缝的实际宽度变化。然而,有些人可能会产生疑问:测缝计测量的是实际缝宽吗?本文将对这一问题进行深入…

Linux基础之进程的优先级

目录 一、进程优先级的概念 二、进程优先级的查看 三、怎么修改进程优先级 四、进程饥饿 一、进程优先级的概念 cpu资源分配的先后顺序,就是指进程的优先权(priority)。优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linu…

5W 3KVAC隔离 宽电压输入 AC/DC 电源模块——TP05AL系列

TP05AL系列产品是一款经济型开板式开关电源,输出功率为5W,具有可靠性高、小体积、性价比高等特点,广泛用于工控和电力仪器、仪表、智能家居等相关行业。

云计算第十九课

目录操作 查找文件 locate ocate 查询系统上预建的文件索引数据库 /var/lib/mlocate/mlocate.db 索引的构建是在系统较为空闲时自动进行(周期性任务),执行updatedb可以更新数据库 索引构建过程需要遍历整个根文件系统,很消耗资源 locate和updatedb命…

数据分析实例——搭建电商的指标体系||对应功能开发需要接入的电商API接口说明

前言: 在日常工作中,数据分析中常常涉及搭建指标体系,搭建电商需要接入的电商API接口本文主要以电商为案例,来讲讲如何搭建指标体系。 指标体系的定义: 指标体系是由一系列指标组成的,这些指标是基于不同的…

openGauss一主两备集群异常断电后不能正常启动的解决过程简记

背景 因异常断电后opengauss 5.0.0版本,一主两备集群启动失败。 报错不是主机,由于当时没有截图,查看日志后发现报错是: 定位过程 Day1 1. 尝试用另外两台机器启动每台机器 发现都报错自己不是主机,像极了唐僧被妖…

天锐绿盾 | 设计院、机械制造行业透明加密cad图纸、图纸防泄密软件

天锐绿盾为设计院及机械制造行业量身打造的透明加密CAD图纸解决方案,专注于保障这些行业中的核心资产—设计图纸的安全。通过集成先进的加密技术和访问控制策略,该软件系统能有效防止图纸的未经授权访问和意外泄密。 PC地址: https://isite…

把由十六进制数字组成的字符串(包含可选的前缀0X和0x),转化为与之等价的整数值,字符串中包含的字符可以是0-9,A-F,a-f

方法一: 1-十六进制是一种基数为16的计数系统,是一种逢16进1的进位制。例如十六进制0x57,写成十进制是 5*16^17*16^087。第一位乘16的0次方,第二位乘16的1一次方。 2-如果0x57按顺序来转化,不太好转,因为…

PHP xdebug

使用场景 一台MAC上安装了phpstorm,虚拟机安装了对应的web程序,需要调试。 坑点,网上教程太多,不如看官网,需要按照xdebug版本来配置php.ini https://www.jetbrains.com/help/phpstorm/2023.3/configuring-xdebug.htm…