下载wget -c https://dl.google.com/go/go1.20.5.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local
环境变量
这个可以通过添加下面的行到/etc/profile文件(系统范围内安装)或者\(HOME/.profile文件(当前用户安装):`export PATH=\)PATH:/usr/local/go/bin 保存文件,并且重新加载新的PATH 环境变量到当前的 shell 会话:
source ~/.profile`
设置go env -w GOPROXY=https://goproxy.cn,direct
安装 & 升级
wget https://golang.google.cn/dl/go1.21.4.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.21.4.linux-amd64.tar.gz
vi /etc/profile
export PATH=$PATH:/usr/local/go/bin
source /etc/profile
https://pkg.go.dev/golang.org/dl
go get golang.org/dl/go1.10.7
go get golang.org/dl/go1.13.6
原理:go get github.com/golang/dl 库
每个版本install
会在 go/bin 下安装github.com/golang/dl/go1.13.9 并生成 go1.13.9.exe
go1.13.9 download 下载源码到用户目录下的sdk/go1.13.9 下
运行go1.13.6 version 相当于运行 sdk/go1.13.9/bin/go.exe version
docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.17 go build -v
-w, --workdir string
指定工作目录
$file helloworld-default
helloworld-default: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$ldd helloworld-default
不是动态可执行文件
开启 CGO_ENABLED=1
// go-compilation/main-with-os-user.go
package main
import (
"fmt"
_ "os/user"
)
func main() {
fmt.Println("hello, world")
}
$file helloworld-with-os-user
helloworld-with-os-user: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
$ldd helloworld-with-os-user
linux-vdso.so.1 => (0x00007ffcb8fd4000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb5d6fce000)
libc.so.6 => /lib64/libc.so.6 (0x00007fb5d6c00000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb5d71ea000)
通过nm命令我们还可以查看Go程序依赖了哪些C库的符号:
$nm -a helloworld-with-os-user |grep " U "
U abort
U __errno_location
U fprintf
U fputc
U free
U fwrite
U malloc
U mmap
U munmap
U nanosleep
U pthread_attr_destroy
U pthread_attr_getstack
U pthread_attr_getstacksize
U pthread_attr_init
U pthread_cond_broadcast
U pthread_cond_wait
U pthread_create
U pthread_detach
U pthread_getattr_np
U pthread_key_create
U pthread_mutex_lock
U pthread_mutex_unlock
U pthread_self
U pthread_setspecific
U pthread_sigmask
U setenv
U sigaction
U sigaddset
U sigemptyset
U sigfillset
U sigismember
U stderr
U strerror
U unsetenv
U vfprintf
要想实现静态链接,我们需要找出外部go依赖的所有c库的.a文件(静态共享库)。以我们的go-sqlite3示例为例,go-sqlite3是sqlite库的go binding,它依赖sqlite库,同时所有第三方c库都依赖libc,我们还要准备一份libc的.a文件,下面我们就先安装这些:
$yum install -y gcc glibc-static sqlite-devel
... ...
已安装:
sqlite-devel.x86_64 0:3.7.17-8.el7_7.1
更新完毕:
glibc-static.x86_64 0:2.17-326.el7_9.3
接下来,我们就来以静态链接的方式在go-compilation/go-sqlite3-static下编译一下:
$go build -tags 'sqlite_omit_load_extension' -ldflags '-linkmode external -extldflags "-static"' demo
$file ./demo
./demo: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=c779f5c3eaa945d916de059b56d94c23974ce61c, not stripped
这里命令行中的-tags 'sqlite_omit_load_extension'
用于禁用SQLite3的动态加载功能,确保更好的静态链接兼容性。而-ldflags '-linkmode external -extldflags "-static"'
的含义是使用外部链接器(比如gcc linker),并强制静态链接所有库。
$go build -ldflags="-s -w" -o helloworld-default-nosym main.go
$tinygo build -o helloworld-tinygo main.go
go list -deps -f '{{.ImportPath}}: {{.CgoFiles}}' ./... | grep -v '\[\]'
go list -deps -f '{{.ImportPath}}: {{.CgoFiles}}' main-with-os-user.go | grep -v '\[\]'
GolangCI-Lint 检查代码
自带go vet命令 检查代码
更严格的gofmt https://github.com/mvdan/gofumpt
检查没有使用的函数https://github.com/mvdan/unparam
https://github.com/fanjindong/GopherChina
推荐算法、相似度算法、布隆过滤器、均值算法、一致性Hash、数据结构、leetcode练习