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)
}

 

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