博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
go http获取ajax参数_Go语言基础(十二)
阅读量:5108 次
发布时间:2019-06-13

本文共 4406 字,大约阅读时间需要 14 分钟。

2573241c6272788a357a0f8e447172d9.png

Go语言基础(十二)

一、pprof调试工具

二、获取命令行参数

三、面试题分享


一、pprof调试工具

Go语言性能优化主要有以下几个方面:

  • CPU Profile:报告程序的CPU使用情况,按照一定的频率采集应用程序在CPU和寄存器上面的数据;
  • Memory Profile:报告程序内存使用情况
  • Block Profiling: 报告goroutine不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈;
  • Goroutine Profiling:报告goroutine的使用情况,有哪些goroutine,他们的调用关系是怎样的;

在计算机性能调试领域里,profiling是指对应用程序的画像,画像就是应用程序使用CPU和内存的情况,Go语言中自带profiling库。Go语言中内置了获取程序的运行数据的工具,包括以下两个标准库:

  • runtime/pprof:采集工具型应用运行数据分析
  • net/http/pprof:采集服务型应用运行时数据进行分析

pprof开启后,每个一段时间(ms)就会收集下当前的堆栈信息,获取各个函数占用的CPU以及内存资源,最后通过对这些采样数据进行分析,形成一个性能报告。

1、CPU性能分析

开启CPU性能分析:

pprof.StartCPUProfile(w io.Writer)

停止CPU性能分析:

pprof.StopCPUProfile()

应用执行结束后,就会产生一个新文件,保存CPU Profiling数据,得到采样数据之后,使用go tool pprof工具进行CPU性能分析。

2、内存性能优化

记录程序的堆栈信息:

pprof.WriteHeapProfile(w io.Writer)

得到采样数据之后,使用go tool pprof工具进行内存性能分析,go tool pprof默认使用

-inuse_space进行统计,还可以使用-inuse-objects查看分配对象的数量。

3、服务型应用

使用net/pprof库,它能够提供HTTP服务进行分析。如果使用默认的http.DefaultServeMux通常代码直接使用http.ListenAndServe("0.0.0.0:8000", nil),只需要:

import _ "net/http/pprof"

如果使用自定义的Mux,则需要手动注册一些路由规则。

如果使用的是gin框架,推荐使用“github.con/DeanThompson/ginpprof”

4、具体示例

package mainimport (	"flag"	"fmt"	"os"	"runtime/pprof"	"time")// 一段有问题的代码func logicCode() {
var c chan int // nil for {
select {
case v := <-c: // 阻塞 fmt.Printf("recv from chan, value:%vn", v) default: } }}func main() {
var isCPUPprof bool var isMemPprof bool flag.BoolVar(&isCPUPprof, "cpu", false, "trun cpu pprof on") flag.BoolVar(&isMemPprof, "mem", false, "turn men pprof on") flag.Parse() if isCPUPprof {
f1, err := os.Create("./cpu.pprof") if err != nil {
fmt.Printf("create cpu pprof failed, err:%vn", err) return } pprof.StartCPUProfile(f1) defer func() {
pprof.StopCPUProfile() f1.Close() }() } for i := 0; i < 6; i++ {
go logicCode() } time.Sleep(10 * time.Second) if isMemPprof {
f2, err := os.Create("./mem.pprof") if err != nil {
fmt.Printf("create mem pprof failed, err:%vn", err) return } pprof.WriteHeapProfile(f2) f2.Close() }}

执行xxx.exe -cpu=true之后生成一个cpu.pprof,使用go tool pprof cpu.pprof进入交互界面:

1762d7d568d3d279b199bf3b214b0219.png

在交互界面输入top3或者top5查看程序中占用CPU前3位或前5位的函数:

dfcaf9eb96aa28018b16c0f37b6cb211.png

其中:

  • flat:当前函数占用CPU的耗时
  • flat%:当前函数占用CPU的耗时百分比
  • sum%:当前函数占用CPU的耗时累计百分比
  • cum:当前函数加上调用函数的函数占用CPU的总耗时
  • cum%:当前函数加上调用函数的函数占用CPU的总耗时百分比
  • 最后一列:函数名称

使用list 函数名命令查看具体的函数分析,例如:

ef4aa44072002fccffd18ec83dffb373.png

将有问题的代码进行修复:

func logicCode() {
var c chan int // nil for {
select {
case v := <-c: // 阻塞 fmt.Printf("recv from chan, value:%vn", v) default: time.Sleep(time.Millisecond * 500) } }}

再次执行:

1755920da0498802f217dd0fd52c2b69.png

5、图形化

windows下载[graphviz](https://graphviz.gitlab.io/_pages/Download/Download_windows.html)将graphviz安装目录下的bin文件添加到Path环境变量中,在终端输入dot -version查看是否安装成功。

2dad8abd5e1a32a31547649fb0c94275.png

在交互界面输入web,会在本地浏览器打开一张svg的图片:

1253b64365f16a3f1c3dc1b70336f06b.png

6、go-torch火焰图

后续更新

二、获取命令行参数

1、os.Arg获取命令行参数

package mainimport (	"fmt"	"os")// os.Arg获取命令行参数func main() {
fmt.Printf("%#vn", os.Args) fmt.Println(os.Args[0], os.Args[2]) fmt.Printf("%Tn", os.Args)}

4e678935f532354fc26efd95ee8b490f.png

2、定义命令行flag参数

flag包支持的命令行参数类型有bool、int、int64、uint、uint64、float、float64、string、duration。

d29a0b52d07f8b089579a34cbbbe17c9.png
package mainimport (	"flag"	"fmt"	"time")// flag 获取命令行参数func main()  {
// 创建一个标志位参数 name := flag.String("name", "康辉", "请输入名字") age := flag.Int("age", 25, "请输入真是年龄") married := flag.Bool("married", false, "结婚了吗") cTime := flag.Duration("ct", time.Second, "结婚多久了?") flag.Parse() fmt.Println(*name) fmt.Println(*age) fmt.Println(*married) fmt.Println(*cTime) fmt.Println(flag.Args()) fmt.Println(flag.NArg()) fmt.Println(flag.NFlag())}

0ac0b3c194b0af98cdba15a0d9aa01ec.png
package mainimport (	"flag"	"fmt"	"time")func main() {
var name string var age int var married bool var delay time.Duration flag.StringVar(&name, "name", "张三", "姓名") flag.IntVar(&age, "age", 18, "年龄") flag.BoolVar(&married, "married", false, "婚否") flag.DurationVar(&delay, "d", 0, "时间间隔") flag.Parse() fmt.Println(name) fmt.Println(age) fmt.Println(married) fmt.Println(delay)}

3、flag.Parse()

通过以上两种方法定义好命令行flag参数后,使用flag.Parse()来对命令进行解析。

支持的命令行参数格式有以下几种:

  • -flag xxx(使用空格,一个 - 符号)
  • --flag xxx(使用空格,两个 - 符号)
  • -flag=xxx(使用等号, 一个 - 符号)
  • --flag=xxx(使用等号,两个 - 符号)

其中,布尔类型的参数必须使用等号的方式指定。

flag其他函数:

flag.Args()    // 返回命令行参数后的其他参数,以[]string类型flag.NArg()    // 返回命令行参数后的其他参数个数flag.Nflag()   // 返回使用的命令行参数个数

三、面试题分享

1、爬台阶

c8cc5fb0f00a2db140a8c7d50ddb2798.png
func f(n int) int {
if n == 1{
retrun 1 } if n == 2 {
retrun 2 } retrun f(n-1) + f(n-2)}

虽然这样递归能够解决问题,但是如果有1w或者更多的台阶,显然这不是一个最优解法。

最优解法:待更新。

2、判断一个链表是否闭环?

31b6ced6ac8c24016d4d9c6727af2277.png

我是尾巴~

每日一句毒鸡汤:某些希望的破灭其实也是好事,最起码不用每天带着傻傻的期望,能够犀利死心地去投入到新的开始。

本次推荐:

题库 - 力扣 (LeetCode)​leetcode-cn.com
605d052b4cae8cfc637480a421cbcde1.png

继续加油~!

立个flag,坚持刷LeetCode并附上python和Go的代码!

转载地址:http://yljdv.baihongyu.com/

你可能感兴趣的文章
大家在做.NET B/S项目的时候多用什么设技术啊?
查看>>
投资策略 ——摘自凤凰网
查看>>
Java SE和Java EE应用的性能调优
查看>>
Android设计模式系列--原型模式
查看>>
spring boot 整合 云之讯 demo
查看>>
CoolBlog开发笔记第4课:数据库模型设计
查看>>
翻译:给19岁有志青年的建议 Advice for ambitious 19 year olds
查看>>
DenyHosts 阻止SSH暴力攻击
查看>>
java001-Helloworld
查看>>
免费的论文查重网站
查看>>
C语言程序第一次作业
查看>>
leetcode-Sort List
查看>>
常用的Javascript设计模式
查看>>
静态库
查看>>
关于hibernate查询结果类的封装
查看>>
突然感到人生很绝望_
查看>>
IIS7:通过脚本来配置ftp站点
查看>>
淘宝用户杭州30个小区分布,根据默认收货地址统计用户id
查看>>
一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
查看>>
北京信息科技大学第十一届程序设计竞赛(重现赛)I
查看>>