Ngôn ngữ lập trình Go


Đại học Sydney

23 tháng 3, 2010

Go

Mới

Thực nghiệm

Đồng thời

Có bộ gom rác

Ngôn ngữ hệ thống

Hello, world

package main

import "fmt"

func main() {
	fmt.Printf("Hello, 世界\n")
}

Hello, world 2.0

Phục vụ http://localhost:8080/world

package main

import (
	"fmt"
	"http"
)

func handler(c *http.Conn, r *http.Request) {
	fmt.Fprintf(c, "Hello, %s.", r.URL.Path[1:])
}

func main() {
	http.ListenAndServe(":8080",
			http.HandlerFunc(handler))
}

Mới

Ngôn ngữ khoảng hai tuổi:

Tại sao lại tạo ra một ngôn ngữ mới? Các ngôn ngữ cũ không được thiết kế cho lập trình đồng thời, nhưng phần mềm hiện đại cần điều đó:

Mới

Các ngôn ngữ cũ cũng gây phiền toái trong công việc hàng ngày

Các ngôn ngữ kiểu tĩnh (C, C++, Java) có những vấn đề:


Các ngôn ngữ động (Python, JavaScript) giải quyết một số vấn đề nhưng đưa vào những vấn đề khác:

Go có cảm giác nhẹ nhàng như ngôn ngữ kịch bản nhưng được biên dịch

Mới

Các chương trình C++ lớn (ví dụ: Firefox, OpenOffice, Chromium) có thời gian build rất lâu:

Trên Mac (OS X 10.5.8, gcc 4.0.1):

Trong Go: import "fmt" đọc một tệp: 184 dòng tóm tắt 7 package

Mới

Demo biên dịch

Thực nghiệm

Go vẫn chưa được kiểm chứng

Ngôn ngữ vẫn đang phát triển

Thư viện package chưa hoàn chỉnh

Thu gom rác đồng thời vẫn là vấn đề nghiên cứu tích cực

Hồi sinh các khái niệm đã bị lãng quên:

Đồng thời

Triết lý Unix: viết các chương trình làm tốt một việc duy nhất

Kết nối chúng bằng pipe:

Khác với các ngôn ngữ khác, Go giúp dễ dàng:

Đồng thời

Bắt đầu luồng điều khiển mới bằng từ khóa go

Tính toán song song rất dễ dàng:

func main() {
	go expensiveComputation(x, y, z)
	anotherExpensiveComputation(a, b, c)
}

Về cơ bản, goroutine giống một thread nhưng nhẹ hơn:

Đồng thời

Xét các máy chủ web ("bài toán C10k"):

	for {
		rw := socket.Accept()
		conn := newConn(rw, handler)
		go conn.serve()
	}

Đồng thời

Hãy xem lại phép tính song song đơn giản của chúng ta:

func main() {
	go expensiveComputation(x, y, z)
	anotherExpensiveComputation(a, b, c)
}

Câu chuyện này chưa đầy đủ:

Đồng thời

Goroutine giao tiếp với nhau qua channel

func computeAndSend(ch chan int, x, y, z int) {
	ch <- expensiveComputation(x, y, z)
}

func main() {
	ch := make(chan int)
	go computeAndSend(ch, x, y, z)
	v2 := anotherExpensiveComputation(a, b, c)
	v1 := <-ch
	fmt.Println(v1, v2)
}

Đồng thời

Trong các chương trình đồng thời truyền thống, bạn giao tiếp bằng cách chia sẻ bộ nhớ. Trong Go, bạn chia sẻ bộ nhớ bằng cách giao tiếp:

Thread và lock là các nguyên thủy đồng thời; CSP là một mô hình đồng thời:

Học CSP thay đổi cách bạn suy nghĩ về lập trình đồng thời:

Có bộ gom rác

Quản lý bộ nhớ tự động giúp việc viết (và bảo trì) chương trình dễ hơn

Đặc biệt trong thế giới đồng thời:

Các chương trình C++ lớn thường kết thúc với quản lý bộ nhớ bán tự động thông qua "con trỏ thông minh"

Kết hợp hai mô hình có thể gây ra vấn đề:

Có bộ gom rác

Go cũng là ngôn ngữ an toàn hơn:

Không có khai thác tràn bộ đệm

Ngôn ngữ hệ thống

Điều này đơn giản có nghĩa là bạn có thể viết các chương trình khá lớn bằng Go:

Ngôn ngữ hệ thống

Thu gom rác có tiếng là "chậm hơn"

Chúng tôi kỳ vọng Go sẽ chậm hơn C được tối ưu một chút, nhưng nhanh hơn Java tùy theo tác vụ. Tuy nhiên:

Bố cục bộ nhớ có thể ảnh hưởng lớn đến hiệu năng. Hai thiết kế này tương đương trong Go, nhưng khác biệt đáng kể trong Java:

type Point struct { X, Y int }
type Rect struct { P0, P1 Point }

// or ...

type Rect struct { X0, Y0, X1, Y1 int }

Ngôn ngữ hệ thống

Trích dẫn từ http://loadcode.blogspot.com/2009/12/go-vs-java.html

"[Git] được biết đến là rất nhanh. Nó được viết bằng C. Phiên bản Java JGit đã được tạo ra. Nó chậm hơn đáng kể. Việc xử lý bộ nhớ và thiếu kiểu unsigned là một số lý do quan trọng.

Shawn O. Pearce đã viết trên danh sách email git:

Như C, Go cho phép kiểu unsigned và định nghĩa cấu trúc dữ liệu chứa các cấu trúc dữ liệu khác như các khối bộ nhớ liên tục."

Go

Mới

Thực nghiệm

Đồng thời

Có bộ gom rác

Ngôn ngữ hệ thống

Và còn nhiều hơn nữa:

Câu hỏi?