GO的代表项目来感受下它的牛逼
- Docker - 容器
- Kubernetes - 容器管理
- Caddy - 一个webservice 可以用于替代nginx
- CockroachDB - 一个new sql数据库
- MongoDB/Couchbase 工具
- Dropbox
- Uber
- Google 部分产品
发展趋势
- 09年谷歌开源
- 12年发布1.0版
- 15年发布1.5版,重写垃圾回收,更好的并发
- ...
- 当前1.15,工具链的完善
go语言设计
- C++: 有性能保障,比如搜索引擎
- JAVA: 复杂业务逻辑
- Python: 大量内部工具
- Go: 新的内部工具,业务模块 dl.google.com
对比:
- Go vs C++:没有C++繁琐的类型系统,统一的模块依赖管理,编译速度快
- Go vs Java:比java快,能垃圾回收,但是垃圾回收效率更高
- Go vs Python: 同样灵活的同时提供编译器静态类型检查
-
Go: 加入很好的并发编程,通过channel来实现不同routine的访问
Go语言特性:
- 类型检查:编译时
- 运行环境,编译成机器代码直接运行(任何机器),不需要一个java虚拟机
- 编程范式:面向接口(注意不是面向对象),函数式编程,并发编程
Go语言并发编程
- 采用CSP编程(Communication Sequential Process)
不需要锁,不需要callback
Go安装和开发环境
- 下载安装:https://studygolang.com/dl
- idea安装go语言插件(其他编译器也有,idea是java开发者比较熟悉的idea)
- 也可以用GoLand,一个专门用于go的ide,现在不要钱,以后嘛....
创建项目
- file-> project(语言选go)
-
新建一个Go file,类型选择 simpleApplication,如果是工具类选择 EmptyFile
第一个hello world程序
package main
import "fmt"
func main() {
fmt.Println("hello world!")
}
- 运行,通过idea的run or 命令行用 go run xxx.go
- go build命令可以编译,生成可运行的机器码(go run中是先编译后运行)
一个简单的http server
package main
import (
"fmt"
"net/http"
)
func main() {
// 注意参数名称和类型 和 其他语言是反的
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
fmt.Fprintf(writer, "<h1>hello world %s</h1>", request.FormValue("name"))
})
http.ListenAndServe(":8888", nil)
}
服务器访问:
并发的Demo: go routine
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan string) // : 的语法是声明变量,编译器自己匹配,等同于var
var routineNumber int = 10
for i := 0; i < routineNumber; i++ {
go printHello(i, ch) // go starts a go routine(不是一个线程,比线程粒度更细)
}
for { // 注意 go 语言只有for 没有 while
msg := <-ch
fmt.Println(msg)
}
time.Sleep(time.Microsecond * 1000)
}
func printHello(i int, ch chan string) {
fmt.Printf("hello world in Printf: %d \n", i)
ch <- fmt.Sprintf("hello world in channel: %d \n", i)
}
排序的demo
package main
import (
"fmt"
"sort"
)
func main() {
// its a slice of int
a := []int{3, 6, 8, 1, 0}
sort.Ints(a)
for _, v:= range a { // 定义不使用,用_ 表示,否则要使用_,表示索引
fmt.Println(v)
}
}
归并排序的Demo
func Merge(in1, in2 <-chan int) <-chan int {
out := make(chan int)
go func() {
v1, ok1 := <-in1
v2, ok2 := <-in2
for ok1 || ok2 {
if !ok2 || (ok1 && v1<=v2) {
out<-v1
v1, ok1=<-in1
} else {
out <- v2
v2, ok2 = <-in2
}
}
close(out)
}()
return out
}
文件读写
先创建util(空文件 + 函数)
func ReaderFile(reader io.Reader) <-chan int {
out := make(chan int)
go func() {
buffer := make([]byte, 8)
for {
n, err := reader.Read(buffer)
if n > 0 {
v := int(binary.BigEndian.Uint64(buffer))
out <- v
}
if err != nil {
break
}
}
close(out)
}()
return out
}
func WriteFile(writer io.Writer, in <-chan int) {
for v := range in {
buffer := make([]byte, 8)
binary.BigEndian.PutUint64(buffer, uint64(v))
writer.Write(buffer)
}
}
// 随机数,用于生成writer中的内容
func RandomSource(count int) <-chan int {
out := make(chan int)
go func() {
for i := 0; i < count; i++ {
out <- rand.Int()
}
close(out)
}()
return out
}
主函数中进行读写
import (
"../pipelineUtil"
"bufio"
"fmt"
"os"
)
func main() {
const filename = "test.in"
const size = 50
create, err := os.Create(filename)
if err!= nil {
panic(err)
}
p := pipelineUtil.RandomSource(size)
writer := bufio.NewWriter(create)
pipelineUtil.WriteFile(writer, p) // buffer
writer.Flush() // buffer flush, 注意这里别忘记
defer create.Close() // defer函数退出前close,出错也保证运行
open, err := os.Open(filename)
if err != nil {
panic(err)
}
defer open.Close()
p = pipelineUtil.ReaderFile(bufio.NewReader(open))
for v := range p {
fmt.Println(v)
}
}
go tool tour
一个交互式编程学习工具
安装
go get golang.org/x/tour
现在已经不需要安装,如果要源码安装似乎也只有gitee上容易找到源码
在线版更香