go语言学习笔记,特点

1、并发编程


Go语言在并发编程方面比绝大多数语言要简洁不少,这一点是其最大亮点之一,也是其未来进入高并发高性能场景的重要筹码。
golang的并发执行单元是一种称为goroutine的协程。协程又称为微线程,比线程更轻量、开销更小,性能更高。
操作起来非常简单。语言级别提供关键字go用于启动协程,并且在同一台机器上可以启动成千上万个协程。
协程间一般由应有程序显式实现调度,上下文切换无需下到内核层,高效不少。协程间的通信靠独有的channel机制实现。

2、内存回收GC

  • 内存自动回收,再也不需要开发人员管理内存
  • 开发人员专注业务实现,降低了心智负担
  • 只需要new分配内存,不需要释放

GC过程是:先stop the world 扫描所有对象判活。把可回收对象在一段bitmap区中标记下来,
接着立即start the world 恢复服务。同时起一个专门goroutine回收内存到空闲list中以备复用。
不物理释放,物理释放由专门线程定期来执行。GC瓶颈在于每次都要扫描所有对象来判活,待收集的对象数目越多,速度越慢
GC性能可能随着版本不断更新会不断优化。

 

go语言学习笔记,特点_第1张图片

go语言学习笔记,特点_第2张图片

go语言学习笔记,特点_第3张图片

go语言学习笔记,特点_第4张图片

go语言学习笔记,特点_第5张图片

go语言学习笔记,特点_第6张图片

go语言学习笔记,特点_第7张图片

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的引入,在很大程度上可以简化编程,并且在语言描述上显得更为自然。极大地增强了代码的可读性。

4、包的概念

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编码。

go语言学习笔记,特点_第8张图片

go语言学习笔记,特点_第9张图片

太多工程师,写了百万行代码,而且还具有分布式的编译系统和百万的服务器,于是google在开发中就会存在一些痛点,
最大的痛点就是编译速度特别慢,所有程序之间耦合性非常强,所有依赖几乎是失控的。
每个工程师,使用不同的语言,而且只使用这个语言的一部分,程序越来越难以维护,可读性越来越差,文档也不清晰。
对于更新来讲也是非常可怕的一件事。因为需要花费的时间会越来越长,而且交叉编译变得越来越困难,
为了解决这些问题和痛点。

go语言学习笔记,特点_第10张图片

go语言学习笔记,特点_第11张图片

go语言学习笔记,特点_第12张图片

go语言有接近c的运行效率,和接近Python的开发效率。

它唯一的创新之处是Goroutine和Channel
Goroutine是Go语言面向线程的轻量级解决方案,创建Goroutine的成本很低,只需要几千个字节的额外内存,所以我们可以同时运行数百个,数千个Goroutine
因为它对于内存的消耗是比较小的,而且可以借助Channel实现Goroutine之间的通信,Goroutine以及基于CHannel的并发性方法。
是它非常容易使用所有可用的cpu内核,而且处理并发的IO相比于python java
在一个Goroutine上运行一个函数需要最小的代码,
Go是一种非常高效的语言高度支持并发性,Go是为大数据,微服务,并发而生的一种编程语言。
go语言学习笔记,特点_第13张图片

go语言学习笔记,特点_第14张图片

go语言学习笔记,特点_第15张图片

go语言学习笔记,特点_第16张图片

go语言学习笔记,特点_第17张图片

 

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执行流程分析

  • 如果对源码编译后,在执行,Go的执行流程
  1.     xxx.go文件==>经过go build ==>编译 可执行文件==>运行得出结果
  • 如果我们对源码执行go run 源码,Go的执行流程如下

    xxx.go文件==>经过go run ==>得出结果

两种执行流程的方式区别

  1. 如果我们先编译生成可执行文件,那么我们可以将可执行文件拷贝到没有go开发环境的机器上,任然可以运行
  2. 如果我们是直接go run  源代码,那么如果要在另一个机器上这么运行,必须要go的开发环境,不然不可运行。
  3. 在变异时,编译器会将程序运行依赖的库文件包含在可执行文件中,所有可执行文件变大了很多。

编译和运行说明

 

build -o  myhello.exe hello.go

 

Go程序开发的注意事项:

  1. Go源文件以".go"为扩展名
  2. Go应用程序的执行入口是main()方法
  3. Go语言区分大小写
  4. Go方法由一条条语句构成,每个语句后面不用加分号;(其实go会自动添加)
  5. Go编译器是一行行进行编译的,所以我们一行最好写一条语句,一般不会把多条语句写在同一行
  6. 如果万不得已多条语句写在同一行,需要加分号;
  7. Go语言定义变量或者import的包如果没有使用到代码不能编译通过
  8. 大括号都是成对出现的,缺一不可。

 

Go程序的注释:

  1. 单行注释  //     尽量使用行注释
  2. 块注释  /*   */

gofmt main.go 

gofmt  -w main.go     //可以将格式化后的文件,重新写入文件

运算符的两边都加空格

 

import 包名

DOS的常用命令:

  • md test200 test300 test400   创建目录    make dir
  • dir  查看当前目录包含的目录和文件
  • cd  /d f:  切换到f盘       change dir
  • cd  d:\test\res
  • cd \  回到根目录
  • rd  test100              删除空目录
  • rd  /q/s test100        删除非空目录  remove directory
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 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Go语言)