Go语言的简介与特点

Go语言的核心开发团队

Ken Thompson :1983年图灵奖获得者,C语言的主要发明人

 

Rob Pike :贝尔实验室 Unix 团队的成员,和 Ken 共创出广泛使用的 UTF-8 编码


Robert Griesemer :曾协作制作 Java 的 HotSpot 编译器,和 Chrome浏览器 的 JavaScript 引擎 V8

 

三位大佬的合影:


Go语言诞生的小故事

Google 为什么要创造出Go语言?

1、计算机硬件技术更新频繁,目前主流编程语言的发展明显落后于硬件,不能合理利用多核多CPU的优势提升软件系统性能。

2、软件系统复杂度越来越高,维护成本越来越高,目前缺乏一个足够简洁高效的编程语言。

现有的编程语言存在这些问题:

    1、风格不统一。

    2、计算能力不够。

    3、处理大并发不够优秀。

    4、企业运行维护很多 C/C++ 的项目,虽然运行速度很快,但是编译速度很慢,同时还存在内存泄露等一系列的困扰需要解决。

Go语言既兼顾编译语言的运行速度,又同时拥有脚本语言的开发速度。


Go语言的特点

1.Go语言和 C/C++ 一样有指针。Go语言指针案例:

/* 
    1.写一个程序获取一个 int 变量 num 的地址,并显示到终端
    2.将 num 的地址赋值给指针 ptr,并通过 ptr 去修改 num 的值
*/

package main

import "fmt"

func main() {

    // *num 取变量 num 的值
    // &num 取变量 num 的地址
	
    // 1
	var num int
	fmt.Println("the value of num is:", num)
	fmt.Println("the address of num is:", &num)

	// 2
	var ptr *int = &num
	*ptr = 3 // *ptr访问到了这个内存空间,重新给这个内存空间赋值
	fmt.Println("the changed value of num is:", num)

}

2.引入包的概念,用于组织结构,Go语言的文件都要归属于一个包(类似于Java),而不能单独存在。

Go语言同一个文件目录里面的Go文件不能有多个package。

3.引入了自动垃圾回收机制。

4.天然支持高并发(重要特点)

(1)从语言层面支持并发,实现简单

(2)goroutine,轻量级线程,可实现大并发处理,高效利用多核

(3)基于 CPS 并发模型(Communicating Sequential Process)

goroutine 代码示例:

/*
	goroutine 和 channel 结合
	需求:要求统计1-200000的数字中,哪些是素数?
	[为了缩短测试时间,把测试数据200000改为80000]
*/

package main

import "fmt"

// 向管道中放入数字
func putNum(intChan chan int, countNum int) {

	for i := 1; i <= countNum; i++ {
		fmt.Println("往管道中放入数据:", i)
		intChan <- i
	}
    
    // 关闭管道
	close(intChan)

}

// 读取管道中的数字,并判断是否是素数
func readPrime(intChan chan int, primeChan chan int,
	exitChan chan bool) {

	var flag bool

	for {

		v, ok := <-intChan
		if !ok {
			break
		}

		flag = true

		for i := 2; i < v; i++ {

			if v%i == 0 {
				flag = false
				break
			}

		}

		if flag {
			primeChan <- v
		}

	}
    
    // 完成操作后,往管道 exitChan 中置入完成标志 true
	exitChan <- true

}

func main() {

	var routineNum int // 开启的协程数量
	var countNum int   // 统计 1-countNum 的数字

	// 设置开启的协程数量 routineNum
	routineNum = 6
    // 设置数值的范围 countNum
	countNum = 80000

	intChan := make(chan int, countNum)
	primeChan := make(chan int, 80000)      // 放入质数的结果
	exitChan := make(chan bool, routineNum) // 标识退出的管道

	// 开启一个协程,向 intChan 放入 1-countNum 个数
	go putNum(intChan, countNum)

	// 开启 routineNum 个协程,判断是否为质数
	for i := 0; i < countNum; i++ {
		go readPrime(intChan, primeChan, exitChan)
	}

	// 开启协程,查看是否从 exitChan 里读取了 routineNum 个数据
	// 如果没有读取到 routineNum 个数据,则协程处于阻塞状态
	// 直到从 exitChan 读取了相应数量的数据,阻塞才解除
	go func() {

		for i := 0; i < routineNum; i++ {
			<-exitChan
		}

		close(primeChan)
		// close(exitChan)

	}()

	fmt.Printf("1 到 %d 素数为:\n", countNum)

	for {

		result, ok := <-primeChan
		if !ok {
			break
		}
		fmt.Println(result)

	}

}

5.吸收了管道通信机制,形成Go语言特有的管道channel,通过管道channel,可以实现不同的goroutine之间的相互通信。

6.函数返回多个值

7.新的创新:比如切片(slice,类似于Java里面的集合)、延时执行 defer(关键字)等


简单的Go代码示例:

/*
	快速排序
*/
package main

import "fmt"

func quickSort(slice []int, left int, right int) {

	if left >= right {
		return
	}

	// 默认第一个数为基准数
	var pivot int = slice[left]
	// 从第二个数开始扫描
	var i int = left + 1
	var j int = right

	for i < j {

		for slice[i] < pivot {
			i++
		}

		for slice[j] > pivot {
			j--
		}

		if i < j {
			slice[i], slice[j] = slice[j], slice[i]
		}

	}

	var pivotIndex = j
	if slice[left] > slice[pivotIndex] {
		slice[left], slice[pivotIndex] = slice[pivotIndex], slice[left]
	}

	quickSort(slice, left, pivotIndex-1)
	quickSort(slice, pivotIndex+1, right)

}

func main() {
	var slice []int = []int{108, 3, 88, 12, 8, 88, 555, 7, 91, 35, 66}
	quickSort(slice, 0, len(slice)-1)
	fmt.Println("slice = ", slice)
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章