Go语言学习笔记(0)--- 日志

我们在应用调试或者线上业务中经常会用到日志功能,而 Go 语言内置了 log 模块。 log 模块的使用 先来看下 log 模块的基本使用: package main import ( "log" ) func main() { log.Println("hello log.Println") log.Printf("hello %s", "log.Printf") } 我们运行一下可以看到如下输出: > $ go run main.go 2018/10/29 10:45:39 hello log.Println 2018/10/29 10:45:39 hel

go
发布于 5年前

goroutine系统调度

关于线程 我们每运行的一个程序都会创建一个进程,每个进程都有一个初始线程,而后初始线程可以创建更多线程,每个线程互相独立地运行。线程因为其轻量和易用性在并发编程中被大量的使用。而 goroutine 就是基于线程的。线程的实现模型主要有3种:用户级线程模型、内核级线程模型和两级线程模型(或者叫做混合型线程模型)。他们之间的区别就是用户线程和系统最小调度单元内核调度实体(KSE,Kernal Scheduling Entity)的对应关系不同。 用户级线程模型 用户线程与内核线程KSE是多对一的映射模型,多个用户线程一般都是从属于单个进程,并且用户线程的调度都是用户程序的线程库完成的,不需要操作

go
发布于 5年前

[转]Golang中JSON使用小技巧

临时忽略掉struct中空字段 type User struct { Email string `json:"email"` Password string `json:"password"` } 当我们把用户信息返回给前端的时候显然需要忽略调Password 字段,则可以这样做: json.Marshal(struct{ *User Password bool `json:"password,omitempty"` }{ User:user, }) 临时添加额外字段 type User struct { Email string `json:"

go
发布于 5年前

创建最小的运行Go程序的Image

我们首先编写一个简单的Golang服务 package main import "net/http" func main() { http.HandleFunc("/", hello) http.ListenAndServe(":8001", nil) } func hello(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello world!")) } 运行服务 $ go run main.go 访问 http://127.0.0.1:8001 页面返回 Hello world! 构建运

go
发布于 5年前

Go 条件编译

Go语言的条件编译是由go/build包支持的,通过条件编译我们可以实现根据不同的参数编译包里不同的文件。 Go是怎么支持条件编译的 Go通过在源代码里添加编译标签(build tag)实现条件编译的。编译标签是以// +build开始,并且出现在代码文件的最开始。构建选项规则如下: 以逗号分割的选项是并的关系 以空格分割的选项是或的关系 条件项的名字用字母+数字表示,!表示否定的意思 构建标签后必须留一行空行 例如如下的例子: // +build linux,386 darwin,!cgo 对应的布尔表达式就是 (linux AND 386) OR (darwin AND (NOT cg

go
发布于 5年前

GO内存对齐

内存对齐的作用 平台原因(移植):不是所有的硬件平台都可以访问任意位置上的任意数据的,有些硬件只能在特定位置取特定数据。 性能问题:经过内存对齐,CPU的内存访问速度会提升。因为对齐的元素只需要一次内存访问,未对齐的需要两次。 性能问题 一般程序员会认为内存如下图所示,是有一个个的字节组成,而CPU却不是这样看待的。 CPU把内存当作一块一块的,块的大小可以是2、4、8、16字节大小,因此CPU读取内存是一块一块读取的。(块的大小称为内存读取粒度) 假设CPU要读取一个int型4字节大小的数据,分两种情况讨论: 数据从0字节开始 数据从1字节开始 假设内存读取粒度为4

go
发布于 5年前

Go 优秀文章收集

Go并发调度器解析之实现一个协程池 深入golang之---goroutine并发控制与通信 night-reading-go Go语言·听说你想让程序运行的更快? 年终盘点!2017年超有价值的Golang文章 飞雪无情的博客 鸟窝 Go 命令详解 goroutine 实现原理

go
发布于 5年前

Go 中同时使用fmt.Println和println为什么输出顺序不固定

让我们执行如下代码: package main import "fmt" func main() { v := []int{1, 2, 3} for i := range v { println(i) } fmt.Println(v) } 我们可能会得到如下结果(但每次都未必一样): 0 1 [1 2 3] 2 为什么呢? fmt.Println把结果输出到标准错误(standard error)中,println把结果输出到标准输出(standard output),因为两个输出的目标不一样,所以顺序是不固定的。

go
发布于 5年前

golang 中丰富的字符串格式化

golang中字符串格式化输出 package main import ( "fmt" "os" ) type point struct { x, y int } func main() { // Go提供了几种打印格式,用来格式化一般的Go值,例如 // 下面的%v打印了一个point结构体的对象的值 p := point{1, 2} fmt.Printf("%v\n", p) // 如果所格式化的值是一个结构体对象,那么`%+v`的格式化输出 // 将包括结构体的成员名称和值 fmt.Printf("%

go
发布于 5年前

golang 细节总结

自增和自减 golang里包含其他语言常用的自增i++ 和自减i--,但是在golang里他们是语句而不是表达式,所以j=i++这种是错误的写法,而且golang也不支持++和--放在变量前面如++i的形式。 i++ // i的值+1 i-- // i的值-1 ++i //错误 --i // 错误 j = i-- //错误 短变量声明只能在函数内部不能再外部 s := "" //错误 func main() { s := "" prinltln(s) } new只是一个预定义的函数,它并不是一个关键字 func delta(old, new int) int { return

go
发布于 5年前