Golang
Go 语言设计初衷
为了解决当时 Google 开发遇到的问题:
- 编译慢;
- 大量的 C++代码,同时又引入了 Java 和 Python;
- 更新的花费越来越长;
- 分布式的编译系统;
- 数百万的服务器;
Go 语言的特色
- 高效的并发编程(基于 CSP);
- 内存回收(GC);
- 编译速度快;
- 函数多返回值;
- 语言交互性;
- 没有异常处理(Error is value);
Go 语言的优势
- 学习曲线容易;
- 效率:快速的编译时间,开发效率和运行效率高;
- 出身名门,血统纯正;
- 并行和异步编程几乎没有痛点;
- 自由高效:组合的思想、无侵入式的接口、强大的标准库、部署方便、稳定性;
我们为什么选择 Go 语言
- 执行性能
- 开发效率
Go 语言能做什么
- 服务器编程;
- 分布式系统、数据库代理器、中间件等;
- 网络编程;
- 数据库操作;
- 开发云平台;
信息
- 官网:https://golang.google.cn/
- API 文档:https://golang.google.cn/doc/
- 教程:http://www.w3cschool.cn/go/go-tutorial.html
- 下载:https://golang.google.cn/dl/
- 标准库:https://pkg.go.dev/std
- Go 语言设计与实现
- 重点是设计原理 挺底层的
- 李文周-Go 语言学习之路/Go 语言教程
- Go语言中文文档 :https://www.topgoer.com/
- 必看,非常全
- GO语言设计模式 :https://www.topgoer.cn/docs/golang-design-pattern/golang-design-pattern-1cbgha2ltg796
- GO语言标准库文档:https://topgoer.cn/docs/golangstandard/golangstandard-1cmks9a4kaj3c
- 地鼠文档,学习GO的好地方:https://www.topgoer.cn/
- 必看
GC
安全编译
在Go语言中,“安全编译”可能指的是使用安全的编译参数,以确保代码的安全性和性能最优。这通常涉及到使用编译器的各种安全和性能参数,比如:
使用 -s 或 -w 参数来减少编译后的二进制文件大小,去掉调试信息和符号信息。
使用 -ldflags 来设置链接器的标志,比如 -s -w 来进一步优化编译结果。
使用 -buildmode 参数来指定编译模式,比如 pie 来生成位置无关的可执行文件,增加安全性。
下面是一个简单的例子,演示如何使用 -ldflags 来优化编译结果:
go build -ldflags "-s -w" -o myapp .
这条命令会编译当前目录下的Go代码,并输出一个没有调试信息、符号和优化过的、体积更小的可执行文件 myapp。
如果你想进一步确保安全性,可以使用Go的安全性标志,比如 -tags safe,这取决于你使用的第三方库是否支持这个tag。
go build -tags safe -o myapp .
请注意,每个项目可能有特定的安全和性能要求,因此编译参数应根据具体情况选择和调整。
#
go build -ldflags "-s -w -buildmode=pie -linkmode external -extldflags=-Wl,-z,relro,-z,now" -o CcspUtilRemote-`uname -m`
#
go build -tags safe -o myapp .
# 使用此命令查看
go tool link --help
实际问题例子:
# 安全编译检查 出现两个问题 [STACK CANARY/FORTIFY]
checksec --file=./xxx-x86_64
# 处理[STACK CANARY/FORTIFY] 增加CGO 以及CGO代码文件cgo_safe.go
CGO_ENABLED=1 CGO_CFLAGS="-fstack-protector-all -D_FORTIFY_SOURCE=2 -O" go build -ldflags "-s -w -buildmode=pie -linkmode external -extldflags=-Wl,-z,relro,-z,now" -o xxx-`uname -m`
cgo_safe.go
package main
/*
#include <stdio.h>
#include <stdlib.h>
*/
import "C"
import "fmt"
func init() {
s := C.CString("hello")
fmt.Println(s)
// C.puts(s)
// C.free(unsafe.Pointer(s))
}
跨平台编译
具体操作
编译跨平台的只需要修改GOOS、GOARCH、CGO_ENABLED三个环境变量即可
- GOOS:目标平台的操作系统(darwin、freebsd、linux、windows)
- GOARCH:目标平台的体系架构32位还是64位(386、amd64、arm)
- 交叉编译不支持 CGO 所以要禁用它
GOARCH(目标平台架构)可能的值:
amd64
:64位 x86 架构386
:32位 x86 架构arm
:ARM 架构(32位)arm64
:ARM64 架构(64位)ppc64
:64位 PowerPC 架构ppc64le
:64位小端 PowerPC 架构mips64
:64位 MIPS 架构mips64le
:64位小端 MIPS 架构s390x
:64位 IBM z/Architecture
GOOS(目标平台操作系统)可能的值:
linux
:Linux 操作系统windows
:Windows 操作系统darwin
:macOS 操作系统freebsd
:FreeBSD 操作系统netbsd
:NetBSD 操作系统openbsd
:OpenBSD 操作系统dragonfly
:DragonFly BSD 操作系统solaris
:Solaris 操作系统plan9
:Plan 9 操作系统aix
:IBM AIX 操作系统
CGO
go mod 依赖问题
- go mod init:初始化go mod, 生成go.mod文件,后可接参数指定 module 名,上面已经演示过。
- go mod download:手动触发下载依赖包到本地cache(默认为$GOPATH/pkg/mod目录)
- go mod graph: 打印项目的模块依赖结构
- go mod tidy :添加缺少的包,且删除无用的包
- go mod verify :校验模块是否被篡改过
- go mod why: 查看为什么需要依赖
- go mod vendor :导出项目所有依赖到vendor下
- go mod edit :编辑go.mod文件,接 -fmt 参数格式化 go.mod 文件,接 -require=golang.org/x/text 添加依赖,接 -droprequire=golang.org/x/text 删除依赖,详情可参考 go help mod edit
- go list -m -json all:以 json 的方式打印依赖详情-
- Golang中GoPath和GoModule模式的区别
代理
#
go env
# 原代理
# GOPROXY='https://proxy.golang.org,direct'
# go模块(七牛云)代理
go env -w GOPROXY=https://goproxy.cn,direct