Go语言在并发编程方面比绝大多数语言要简洁不少,这一点是其最大亮点之一,也是其未来进入高并发高性能场景的重要筹码。
golang的并发执行单元是一种称为goroutine的协程。协程又称为微线程,比线程更轻量、开销更小,性能更高。
操作起来非常简单。语言级别提供关键字go用于启动协程,并且在同一台机器上可以启动成千上万个协程。
协程间一般由应有程序显式实现调度,上下文切换无需下到内核层,高效不少。协程间的通信靠独有的channel机制实现。
GC过程是:先stop the world 扫描所有对象判活。把可回收对象在一段bitmap区中标记下来,
接着立即start the world 恢复服务。同时起一个专门goroutine回收内存到空闲list中以备复用。
不物理释放,物理释放由专门线程定期来执行。GC瓶颈在于每次都要扫描所有对象来判活,待收集的对象数目越多,速度越慢
GC性能可能随着版本不断更新会不断优化。
Go语言不支持try catch 这样的结构化的异常解决方式,因为觉得会增加代码量,而且会被滥用,不管多小的异常都抛出
Go语言提供的异常处理方式是
如果是普通异常,查看被调用方返回error对象,如果是严重异常,指的是中断性panic(比如除0)
使用defer recvoer panic 机制来捕获处理,严重异常一般由Go语言内部自动抛出,不需要用户主动抛出,避免传统try catch写的到处都是的情况。
用户也可以使用panic('xxxxx')主动抛出,只是这样就使得这套机制退化成结构化异常机制了。
类型推导,在定义变量的时候是支持var abc = 10 这样的语法。让Go语言看上去有点像动态类型语言。
但是Go语言实际上是强类型的。前面的定义会被自动推导出int类型。
关于interface接口,一个类型只要实现了某个interface的所有方法。即可实现该interface,无需显示去继承。
Go编程规范推荐每个Interface只提供一到两个方法。这样使得每个接口的目的非常清晰。
在Go语言中,提供关键字defer,可以通过该关键字指定需要延迟执行的逻辑体。也就是在函数体return前或出现panic时执行。
这种机制非常适合善后逻辑处理,比如可以尽早可能出现的资源泄露问题,可以说,defer是继goroutine和channel之后,另一个非常重要,实用的语言特性。
对defer的引入,在很大程度上可以简化编程,并且在语言描述上显得更为自然。极大地增强了代码的可读性。
package main
包的概念和python一样,把相同功能的代码,放到一个目录,称为包。
包可以被其他包引用,main包是用来生成可执行文件,每个程序只有一个mian包
包的主要用途是提高代码的可复用性。通过import可以引入其他包。
package main
inport "fmt"
func test(num int){
*num = 20
fmt.Println("指令3")
}
关于交叉编译,比如你可以在运行Linux系统的计算机上,开发运行Windows下运行的应用程序,这是第一门完全支持UTF-8的编程语言。
这不仅体现在它可以处理使用UTF-8编码的字符串,就连它的源码文件格式都是使用UTF-8编码。
太多工程师,写了百万行代码,而且还具有分布式的编译系统和百万的服务器,于是google在开发中就会存在一些痛点,
最大的痛点就是编译速度特别慢,所有程序之间耦合性非常强,所有依赖几乎是失控的。
每个工程师,使用不同的语言,而且只使用这个语言的一部分,程序越来越难以维护,可读性越来越差,文档也不清晰。
对于更新来讲也是非常可怕的一件事。因为需要花费的时间会越来越长,而且交叉编译变得越来越困难,
为了解决这些问题和痛点。
go语言有接近c的运行效率,和接近Python的开发效率。
它唯一的创新之处是Goroutine和Channel
Goroutine是Go语言面向线程的轻量级解决方案,创建Goroutine的成本很低,只需要几千个字节的额外内存,所以我们可以同时运行数百个,数千个Goroutine
因为它对于内存的消耗是比较小的,而且可以借助Channel实现Goroutine之间的通信,Goroutine以及基于CHannel的并发性方法。
是它非常容易使用所有可用的cpu内核,而且处理并发的IO相比于python java
在一个Goroutine上运行一个函数需要最小的代码,
Go是一种非常高效的语言高度支持并发性,Go是为大数据,微服务,并发而生的一种编程语言。
6、吸收了管道通信机制,形成Go语言特有的管道channel,通过管道,可以实现不同goroutine之间的相互通信。
7、函数可以返回多个值
func getSumAndSub(n1 int,n2 int)(int,int){
sum := n1+n2
sub := n1-n2
return sum,sub
}
8、新的创新,切片,延时执行defer
Golang执行流程分析
xxx.go文件==>经过go run ==>得出结果
两种执行流程的方式区别
编译和运行说明
build -o myhello.exe hello.go
Go程序的注释:
gofmt main.go
gofmt -w main.go //可以将格式化后的文件,重新写入文件
运算符的两边都加空格
import 包名
DOS的常用命令:
package main
import "fmt"
func main() {
fmt.Println("Hello World")
fmt.Println("Hello World")
say()
var num = 1 + 2
fmt.Println("num = ",num)
//1
var i int //默认值为0
i = 10
fmt.Println("i =",i)
//2
var n10 = 10.1
fmt.Println("n10 =",n10)
//3
name2 := "tom" // 注意 : 号不能省略
fmt.Println("name2 =",name2)
var name string = "tom"
fmt.Println("name =",name)
//一次性声明多个变量
var n1,n2,n3 int
fmt.Println("n1 = ",n1,"n2 = ",n2,"n3 = ",n3)
var t1,name21,t3=100,"tom1",888
fmt.Println("t1 = ",t1,"name21 = ",name21,"t3 = ",t3)
}
func say(){
fmt.Println("abc")
}
输出结果:
i = 10
n10 = 10.1
name2 = tom
name = tom
n1 = 0 n2 = 0 n3 = 0
t1 = 100 name21 = tom1 t3 = 888