Golang概述
为什么创造Golang
1)计算机硬件技术更新频繁,性能提高迅速。目前主流的编程语言发展明显落后于硬件,不能合理的应用多核多CPU的优势来提升软件系统的性能。
2)软件系统的复杂程度越来越高,维护成本升高,目前缺乏一个足够简洁高效的编程语言。 【现有的编程语言:风格不统一、计算能力不够、处理大并发不够好】
3)企业运行维护很多C/C++的项目,C/C++虽然运行速度很快,但编译速度却很慢,同时还存在内存泄漏等一系列的困扰需要解决。
Go语言的特点
Go语言既保证了静态编译语言的安全和性能,又达到了动态语言开发维护的高效率,使用表达式来描述Go语言:Go = C + Python,说明Go语言既有C静态语言程序的运行速度,又达到了Python动态语言的快速开发。
1)语言和交互性。从C语言中继承了很多理念,如表达式语法,控制结构,基础数据类型,调用参数传值,指针等。同时保留了和C语言一样的编译执行方式及弱化的指针。
2)引入了包的概念。用于组织程序结构,Go语言的一个文件都要归属于一个包,不能单独的存在。
3)自动垃圾回收机制。内存自动回收,无需人员管理。
4)并发编程:
(1)从语言层面支持并发,实现简单;
(2)引入了goroutine概念,是一种比线程更加轻盈、更省资源的协程,可实现大并发处理,高效利用多核;
(3)实现了CSP(Communicating Sequential Process)模型来作为goroutine间的推荐通信方式;用简单的例子演示一下goroutine和channel的使用方式:
//这是一个并行计算的例子,由两个goroutine进行并行的累加计算,待两个计算都完成后打印结果
package main
import "fmt"'
func sum(values [] int, resultChan chan int) {
sum := 0
for _, value := range values {
sum += value
}
returnChan <- sum //将计算结果发送到channel中
}
func main() {
values := [] int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
resultChan := make(chan int, 2)
go sum(values[:len(values)/2],resultChan)
go sum(values[len(values)/2:],resultChan)
sum1, sum2 := <-resultChan, <-resultChan //接收结果
fmt.Println("Result:", sum1, sum2, sum1 + sum2)
}
5)错误处理。Go语言引入了defer关键字用于标准的错误处理流程,并提供了内置函数panic、recover完成异常的抛出与捕获。
6)匿名函数和闭包。Go语言中,所有的函数也是值类型,可以作为参数传递。支持常规的匿名函数和闭包,如下将f定义为一个匿名函数,可随意对该匿名函数变量进行传递和调用:
f := func(x, y int) int {
return x + y
}
7)类型和接口。Go语言类型定义非常接近于C语言中的结构(struct),甚至直接沿用了struct关键字。Go语言也不是简单的对面向对象开发语言做减法,还引入了一个无比强大的“非入侵式”接口概念,让开发者从以往对C++和Java开发中的接口管理问题中解脱出来。
8)函数多返回值。Go语言革命性地在静态开发语言阵营中率先提供了多返回值功能,此特性让开发者从原来用各种比较别扭的方式返回多个值的痛苦中解脱出来,既不用再区分参数列表中哪几个用于输入,哪几个用于输出,也不用再只为了返回多个值而专门定义一个数据结构。示例如下:
struct name {
char first_name[20];
char middle_name[20];
char last_name[20];
char nick_name[48];
};
//函数原型
extern name get_name();
//函数调用
name n = get_name();
9)反射。反射是Java语言中出现后迅速流行的概念。通过反射可以获取对象类型的详细信息,并可动态操作对象。反射是把双刃剑,功能强大但代码可读性不理想。Go语言实现了反射的大部分功能,但没有像Java那样内置类型工厂,故而无法像Java那样通过类型字符串创建对象实例。若非必要,不推荐Go语言使用反射。
垃圾回收:所有的内存分配动作都会被在运行时记录,同时任何对该内存的使用也都会被记录,然后垃圾回收器会对所有已经分配的内存进行跟踪监测,一旦发现有些内存已不再被任何人利用,就阶段性的回收这些内存。
goroutine原理:Go语言通过系统的线程来多路派遣这些函数的执行,使得每个用Go关键字执行的函数可以运行成为一个单位协程。当一个协程阻塞时,调度器就会自动吧其他协程安排到另外的线程中去执行,从而实现程序无等待并行化运行。且调度的开销非常小,一颗CPU调度的规模不下于每秒百万次,这使得能够创建大量的goroutine,从而可以轻松的编写高并发程序。
CSP模型解释:一个并发系统由若干个并行运行的顺序进程组成,每个进程不能对其他进程的变量赋值。进程之间只能通过一对通信原语实现协作。Go语言用channel这个概念来轻巧的实现了CSP模型,可方便的进行跨goroutine的通信。
反射应用场景:做对象的序列化。如Go语言标注库的encoding/json、encoding/xml、encoding/gob、encoding/binary等包就大量依赖于反射功能实现。