1.常用
//获取事件类型
fmt.Println("a type by reflect: ", reflect.TypeOf(a))
//获取当下时间
time.Now().Format("2006-01-02 15:04:05")
//睡眠
time.Sleep(2 *time.Second)
//遍历目录
var files []string
err := filepath.Walk(monitorPath, func(path string, info os.FileInfo, err error) error {
files = append(files, path)
return nil
})
2.函数定义/常用函数
func 函数名(形式参数列表)(返回值列表){
函数体
}
//检查字符串是否存在
//使用Contains()函数
res1 := strings.Contains(str1, "lalala")
go结构体设置默认值
func NewXXXEntry() *XXXEntry {
return &XXXEntry{
Debug: false, //默认值
}
}
syncMap的使用
var eventMap sync.Map
//加入
eventMap.Store(event.Name, event)
//遍历
eventMap.Range(func(key, value interface{}) bool {
event := value.(类型)
eventMap.Delete(key)
return true
})
1 读取文件
f, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
fi, err := ioutil.ReadAll(f)
fmt.Println(string(fi))
if err != nil {
log.Fatal(err)
}
2 判断所给路径是否为文件夹
func IsDir(path string) bool {
s, err := os.Stat(path)
if err != nil {
return false
}
return s.IsDir()
}
3 判断所给路径是否为文件
func IsFile(path string) bool {
return !IsDir(path)
}
4.流式读取文件
func readFileContentByFlow(fileName string) bool {
txtFile, err := os.OpenFile(fileName, os.O_RDONLY, 0777)
if err != nil {
util.HandleErr(err)
}
defer txtFile.Close()
bufReader := bufio.NewReader(txtFile)
for {
data, _, err := bufReader.ReadLine() // 读一行日志
if err == io.EOF { // 如果列表读完了,退出
return
}
}
}
//
arr := strings.Split(s,"\n")
for index, value := range arr{
fmt.Println(index, value)
}
//切分字符串,以任意空格切分
arr:=strings.Fields(s)
var inf Information
inf.Name="Alice"
inf.Addr="Green Street"
data, err:=json.Marshal(inf)
if err!=nil{
panic(err)
}
log.Println(string(data))
int, err := strconv.Atoi(string)
int64, err := strconv.ParseInt(string, 10, 64)
7.进程相关
process模块
import "github.com/shirou/gopsutil/process"
process模块的NewProcess会返回一个持有指定PID的Process对象,方法会检查PID是否存在,如果不存在会返回错误,通过Process对象上定义的其他方法我们可以获取关于进程的各种信息。
p, _ := process.NewProcess(int32(os.Getpid()))
// 获取进程占用内存的比例
mp, _ := p.MemoryPercent()
func GetCommandLinuxCon(commandLinux string) []byte {
//需要执行命令: commandLinux
cmd := exec.Command("/bin/bash", "-c", commandLinux)
// 获取输入
output, err := cmd.StdoutPipe()
if err != nil {
fmt.Println("无法获取命令的标准输出管道", err.Error())
return nil
}
// 执行Linux命令
if err := cmd.Start(); err != nil {
fmt.Println("Linux命令执行失败,请检查命令输入是否有误", err.Error())
return nil
}
// 读取输出
bytes, err := ioutil.ReadAll(output)
if err != nil {
fmt.Println("打印异常,请检查")
return nil
}
if err := cmd.Wait(); err != nil {
fmt.Println("Wait", err.Error())
return nil
}
return bytes
}
package main
import (
"container/list"
"fmt"
)
func main() {
var siteList = list.New()
siteList.PushBack("https://qiucode.cn")
for i := siteList.Front(); i != nil; i = i.Next() {
fmt.Println(i.Value)
}
}
package main
import (
"fmt"
"math/rand"
"time"
)
// 数据生产者
func producer(header string, channel chan<- string) {
// 无限循环, 不停地生产数据
for {
// 将随机数和字符串格式化为字符串发送给通道
channel <- fmt.Sprintf("%s: %v", header, rand.Int31())
// 等待1秒
time.Sleep(time.Second)
}
}
// 数据消费者
func customer(channel <-chan string) {
// 不停地获取数据
for {
// 从通道中取出数据, 此处会阻塞直到信道中返回数据
message := <-channel
// 打印数据
fmt.Println(message)
}
}
func main() {
// 创建一个字符串类型的通道
channel := make(chan string)
// 创建producer()函数的并发goroutine
go producer("cat", channel)
go producer("dog", channel)
// 数据消费函数
customer(channel)
}
问题汇总
1.报错信息:
exec: "gcc": executable file not found in %PATH%
解决方案: 安装GCC环境,下载压缩包 解压 配置环境变量
2.报错信息:
Exception in thread “main“ java.lang.ClassNotFoundException: org.sqlite.JDBC
解决方案:要下载数据库的支持文件。
3.git push origin报错信息:
Unable to negotiate with 47.96.92.201 port 29418: no matching host key type found. Their offer: ssh-rsa,ssh-dss
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
新的ssh客户端不支持ssh-rsa算法,要修改本地配置重新使用ssh-rsa算法。
解决方案:
在用户.ssh文件夹中添加config文件
config文件代码:
Host *
HostkeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa
CGO_ENABLED是用来控制golang 编译期间是否支持调用 cgo 命令的开关,其值为1或0,默认情况下值为1,可以用 go env 查看默认值。
当CGO_ENABLED=1,进行编译时会将文件中引用libc的库(比如常用的net包),以动态链接的方式生成目标文件。 当CGO_ENABLED=0,进行编译时则会把在目标文件中未定义的符号(外部函数)一起链接到可执行文件中。
安装go流程
1.需要先删除旧版本的go环境,忘记安装路径的可以通过环境变量查看
echo $GOROOT
通常是在/usr/local/go/目录下,删除
rm -rf $GOROOT
2.下载新版的go,这里的version是1.18.3
wget https://dl.google.com/go/go1.18.3.linux-amd64.tar.gz
或者到 Golang官网 手动下载压缩包
3.解压到usr/local下(官方推荐)
tar -C /usr/local/ -zxvf go1.18.3.linux-amd64.tar.gz
4.修改配置文件(系统配置为/etc/profile,用户配置为~/.profile),这里就修改系统配置
在文件最后加上两行(如果有旧版本的go配置就不用加,或者要修改路径)
export GOROOT=/usr/local/go
export PATH= P A T H : PATH: PATH:GOROOT/bin
或者
sed -i '$aexport GOROOT=/usr/local/go\nexport PATH=$PATH:$GOROOT/bin' /etc/profile
5.执行使配置文件生效
source /etc/profile
6.查看go版本
go version
go相关知识
go.sum工作机制
为了确保一致性构建,Go引入了go.mod文件来标记每个依赖包的版本,在构建过程中go命令会下载go.mod中的依赖包,下载的依赖包会缓存在本地,以便下次构建。 考虑到下载的依赖包有可能是被黑客恶意篡改的,以及缓存在本地的依赖包也有被篡改的可能,单单一个go.mod文件并不能保证一致性构建。
为了解决Go module的这一安全隐患,Go开发团队在引入go.mod的同时也引入了go.sum文件,用于记录每个依赖包的哈希值,在构建时,如果本地的依赖包hash值与go.sum文件中记录得不一致,则会拒绝构建。
go程序性能调优
pprof是GoLang程序性能分析工具,prof是profile(画像)的缩写
第一步 主程序启动协程监听
_"net/http/pprof"
go func() {
http.ListenAndServe("0.0.0.0:8080", nil)
}()
第二步 生成相应文件
go tool pprof http://localhost:8080/debug/pprof/profile
go tool pprof http://localhost:6060/debug/pprof/heap 内存
第三步 通过命令查看
top
list
第四步 定位代码位置
traces
常用优化:
手动回收 垃圾内存:
runtime.GC()
释放资源避免泄露
1 获取http响应
resp, err := http.Get(url)
if resp != nil {
defer resp.Body.Close()
}
if err != nil {
return "", err
}
2 Sql rows
db, err := sql.Open("postgres", dataSourceName)
if err != nil {
return err
}
rows, err := db.Query("SELECT * FROM MYTABLE")
if err != nil {
return err
}
defer rows.Close()
3 文件打开
f, err := os.Open("events.log")
if err != nil {
return err
}
defer f.Close()
4 压缩的写入和读取
var b bytes.Buffer
w := gzip.NewWriter(&b)
defer w.Close()
var b bytes.Buffer
r, err := gzip.NewReader(&b)
if err != nil {
return nil, err
}
defer r.Close()
在一个程序中,操作系统会给程序分配有限的文件描述符(File Descriptor,简称 fd),它们可以理解为打开的文件的标识符。当程序打开一个文件时,会占用一个 fd,而当程序关闭文件时,该 fd 会被释放。
检查系统对单个进程文件句柄的限制
ulimit -n
cat /proc/pid/limits
进程使用了多少文件句柄
lsof -p pid | wc -l
查看当前操作系统已经打开的文件总量
cat /proc/sys/fs/file-nr
第一个值是已开启的,第二个值是分配但未使用,第三个值是总限制数
连接池中的连接有没有正确关闭
cat /proc/pid/net/sockstat
程序内存上限超出后被kill掉
Linux 内核有个机制叫OOM killer(Out Of Memory killer),该机制会监控那些占用内存过大,尤其是瞬间占用内存很快的进程,然后防止内存耗尽而自动把该进程杀掉。
编码规范治理
1 Subprocess launched with variable
2 Potential file inclusion via variabl 解决方案:
f,err := os.Open(filepath.Clean(fname))
3 expect file permissions to be 0600 or less
os.OpenFile(logName, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0600|0064)
deferring unsafe method “Close” on type “*os.File”
4 SQL query construction using format string
解决办法:把大写的WHERE、INSERT INTO等(sql语句关键字:SELECT FROM、 WHERE、 INSERT INTO、 UPDATE、 DELETE FROM)改成小写where、insert into
5 Audit use of command execution
解决办法:将后面的参数使用append([]string{}, args…)