编程笔记

lifelong learning & practice makes perfect

workflow

config

  1. set editor for git

    • configfile: .gitconfig

    • positon: ~/.git/.gitconfig or ~/.gitconfig

    • add one row: editor = vim

      1
      2
      [core]
      editor = vim

using git

stash

  1. 通过git stash命令将本地修改暂存至stash中,等同于git stash push

    1
    2
    git stash
    git stash push
  2. 通过git stash pop命令将stash中的修改恢复至本地

    1
    2
    git stash appply # 当仅有一个stash时,可以直接用apply
    git stash pop
  3. git stash show 展示暂存的内容

    1
    2
    git stash show
    git stash show 1 # 展示第一个stash,每个暂存有序号,默认是0
  4. git stash push将修改暂存

references

what

  1. m3u8

  2. ffmpeg

how

  1. 通过fiddler等工具拿到m3u8文件,查看文件内容是否规范
    下载时通过文件类型,url过滤快速找出含有m3u8文件的数据,在pc端抓包比较方便.手机端抓包https需要安装证书.

  2. 通过ffmpeg下载

    1
    ffmpeg.exe -i input.m3u8 -c copy output.mp4
    • -i 指定输入参数,m3u8文件
    • -c copy 指定输出文件
  3. 在m3u8文件内的视频文件如果是通过http/https下载需要指定白名单

    1
    -protocol_whitelist "file,http,https,tls,tcp"

    把这个参数加上,指定协议白名单即可,完整的命令如下:

    1
    ffmpeg.exe -protocol_whitelist "file,http,https,tls,tcp" -i input.m3u8 -c copy output.mp4

    不指定白名单ffmpeg会报错:”Protocol ‘https’ not on whitelist ‘file,crypto’!”

string

redis的string是动态字符串,可以修改

底层结构,分为embStr和raw两种格式

较短的使用embStr存储,最多44字节,更长的使用raw格式存储。两种格式的底层结构不同。
  1. emb

  2. raw

list

底层数据结构:链表

  1. 插入、删除 O(1)
  2. 查询O(n)
  3. redis底层存储使用的不是简单的链表,使用了quicklist(快速链表:A doubly linked list of ziplists意思为一个由ziplist组成的双向链表)。
    ziplist,压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会
    改成 quicklist。因为普通的链表需要的附加指针空间太大,会比较浪费空间,而且会加重内存的碎片化。

set

Usage

  1. api

    redis support sadd,members…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // using go-zero
    go func() {
    for {
    s := time.Now().Second()
    redis.Sadd("order_id"+strconv.Itoa(s), strconv.Itoa(s))
    }
    }()
    tt := time.NewTicker(time.Second)
    for now := range tt.C {
    vs, _ := rr.Smembers("order_id" + strconv.Itoa(now.Second() ))
    fmt.Println(now.Second(), vs)
    redis.Del("order_id" + strconv.Itoa(now.Second()))
    }

redis 安全

Reids 支持tcp,不支持ssl安全链接,可以通过ssl代理软件实现安全通讯,在公网使用时需要考虑加上ssl保证服务安全。

  1. spiped:redis官方推荐的代理软件
    会在客户端和服务器各启动一个spiped 进程。redis客户端和服务端通信需要通过sniped。

  2. 单节点设置password

    • config file:
      • redis.conf (位置: /etc/redis.conf)
    • setting:
      • requirepass “hello world”
      • 注意需要带上引号
      • 这种设置方式需要重启redis
      • 重启命令: sudo redis-server /etc/redis.conf
  3. 集群

redis性能

指标查看

通过客户端执行info,可查看,加上参数可以查询特定指标,如memory查看内存相关的,包含:

  • server: 查看 Redis 服务器信息,如 Redis 的版本
  • clients: 客户端的连接部分
  • memory: 内存消耗相关信息
  • persistence: RDB和AOF相关信息
  • stats: 一般统计
  • replication: 主/从复制信息
  • cpu: 统计CPU的消耗
  • commandstats: Redis命令统计
  • cluster: Redis集群信息
  • keyspace: 数据库的相关统计
  • modules: Module 相关信息
    它也可以采取以下值:
  • all: 返回所有信息
  • default: 值返回默认设置的信息
  • everything: 包括 all 和 modules

key

  1. evicted_keys: 因为maxmemory限制被回收的key
  2. expired_keys:过期的key数量
  3. keyspace_hits: 在主字典中成功查找到key的次数
  4. keyspace_misses: 在主字典中查找key失败的次数
  5. 阿里云dms,redis监控图例

参考

  1. https://www.redis.com.cn/commands/info.html
  2. 缓存模式:Cache-Aside,Read-Through…

disadvantage

  1. 输出日志不方便,直接输出无法用于辅助定位错误,指针直接输出是一串地址

advantage

错误信息,多次构建,报错信息不一致

  1. 垃圾信息,提示信息不明确
    1
    2
    3
    unexpected fault address 0x7f01d3b9f000
    fatal error: fault
    [signal SIGBUS: bus error code=0x2 addr=0x7f01d3b9f000 pc=0x45b898]
  2. 磁盘不足
    1
    go build github.com/cespare/xxhash/v2: mkdir ....   no space left on device
  3. 磁盘不足
    1
    compile: writing output: write $WORK/....../_pkg_.a: no space left on device
  4. unexpected fault address
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
       unexpected fault address 0x7f713df35000
    fatal error: fault
    [signal SIGBUS: bus error code=0x2 addr=0x7f713df35000 pc=0x45b96a]

    goroutine 1 [running]:
    runtime.throw(0x690d25, 0x5)
    /usr/local/go/src/runtime/panic.go:774 +0x72 fp=0xc000746ef0 sp=0xc000746ec0 pc=0x42da22
    runtime.sigpanic()
    /usr/local/go/src/runtime/signal_unix.go:391 +0x455 fp=0xc000746f20 sp=0xc000746ef0 pc=0x4429c5
    runtime.memmove(0x7f713d9ffea0, 0xc00d5da000, 0x5fc838)
    /usr/local/go/src/runtime/memmove_amd64.s:422 +0x50a fp=0xc000746f28 sp=0xc000746f20 pc=0x45b96a
    cmd/link/internal/ld.(*OutBuf).Write(0xc000096880, 0xc00d5da000, 0x5fc838, 0x68c130, 0x0, 0x0, 0x0)
    /usr/local/go/src/cmd/link/internal/ld/outbuf.go:65 +0xa0 fp=0xc000746f78 sp=0xc00074Build step 'Execute shell' marked build as failure

    磁盘腾出空间后,能够正常构建

  5. 多次构建失败后,尝试构建其他项目,发现大部分都构建失败且失败报错信息类似
  6. du -h 查询文件占用磁盘大小,逸K,M,G为单位
    查询后发现磁盘占用95%,仅剩几G空间,清空部分后构建正常了

what

分布式事务

why

how

what

why

how

Linux 查看端口占用情况可以使用 lsof 和 netstat 命令。

lsof

lsof(list open files)是一个列出当前系统打开文件的工具。

lsof 查看端口

  • lsof -i:端口号

    查看服务器 8000 端口的占用情况:

    1
    2
    3
    # lsof -i:8000
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    nodejs 26993 root 10u IPv4 37999514 0t0 TCP *:8000 (LISTEN)
  • 其他参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    lsof -i:8080:查看8080端口占用

    lsof abc.txt:显示开启文件abc.txt的进程

    lsof -c abc:显示abc进程现在打开的文件

    lsof -c -p 1234:列出进程号为1234的进程所打开的文件

    lsof -g gid:显示归属gid的进程情况

    lsof +d /usr/local/:显示目录下被进程开启的文件

    lsof +D /usr/local/:同上,但是会搜索目录下的目录,时间较长

    lsof -d 4:显示使用fd为4的进程

    lsof -i -U:显示所有打开的端口和UNIX domain文件

netstat

netstat -tunlp 用于显示 tcp,udp 的端口和进程等相关情况。

netstat 查看端口占用语法格式

1
2
3
4
5
6
7
netstat -tunlp | grep 端口号

-t (tcp) 仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名,能显示数字的全部转化为数字
-l 仅列出在Listen(监听)的服务状态
-p 显示建立相关链接的程序名

更多命令

1
2
3
netstat -ntlp              //查看当前所有tcp端口
netstat -ntulp | grep 80 //查看所有80端口使用情况
netstat -ntulp | grep 3306 //查看所有3306端口使用情况

go-repo code snippet

  1. 判断机器位数

    1
    const intSize = 32 << (^uint(0) >> 63)

    在64平台系统:
      1. uint(0)在平台底层是0x0000000000000000
      2. ^uint(0)在平台底层是0xFFFFFFFFFFFFFFFF
      3. ^uint(0) >> 63 在底层平台是0x0000000000000001,也就是1
      4. 32 << 1 结果是32*2 = 64

data conversion

  1. 充分利用已有的实现
1
2
3
4
5
6
7
8
9
10
11
12
type Sorter interface{
Sort()[]int
}

// 自己实现需要为Sequence实现container包内的接口,转换可以利用已有的代码

type Sequence []int
func (s Sequence)Sort()[]int{
copy:=make(Sequence,0,len(s))
append(copy,s...)
sort.IntSlice(s).Sort()
}
  1. 断言防止panic,使用安全方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var list interface{}
    list=&Sequence{1,2,4,3}
    // 不安全方式,assertion不成功,会panic
    convert:=list.(*Sequence)

    // 安全方式
    convert,ok:=list.(*Sequence)
    if !ok{
    return errors.New("convert error")
    }
  2. 反射,通过CanSet()判断反射得到的值能否修改

    1
    2
    3
    var f float64=3
    val:=reflect.ValueOf(x)
    val.CanSet()

    反射在标准库中大量使用,fmt.Fprintf及其他格式化函数大多使用反射实现;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //fmt.Fprintf
    func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
    p := newPrinter()
    p.doPrintf(format, a)
    n, err = w.Write(p.buf)
    p.free()
    return
    }

    // 判断interface的类型,在go 1.15 ".(type)"只能在switch使用
    var i interface{}=&os.File{}
    switch val.(type){
    case int:
    case *os.File:
    case string:
    }

参考文档

  1. golang官方文档 https://golang.google.cn/doc/effective_go#pointers_vs_values
  2. uber代码规范 (https://github.com/uber-go/guide)
  3. code snippet https://www.cnblogs.com/keystone/p/13930136.html

example

  1. top

param

统计数据

  1. load average
  2. uptime

task and cpu states 任务和cpu状态

memory usage 内存使用

process & thread state 进程/线程状态