成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為 Java 程序員準(zhǔn)備的 Go 入門 PPT

開發(fā) 后端
這是 Google 的 Go 團(tuán)隊(duì)技術(shù)主管經(jīng)理 Sameer Ajmani 分享的 PPT,為 Java 程序員快速入門 Go 而準(zhǔn)備的。

這是 Google 的 Go 團(tuán)隊(duì)技術(shù)主管經(jīng)理 Sameer Ajmani 分享的 PPT,為 Java 程序員快速入門 Go 而準(zhǔn)備的。

視頻

這個(gè) PPT 是 2015年4月23日在 NYJavaSIG 中使用的。

前往 YouTube 觀看視頻

主要內(nèi)容

1. Go 是什么,誰在使用 Go?
2. 比較 Go 和 Java
3. 代碼示例
4. 并發(fā)
5. 工具

Go 是什么?

“Go 是開源的編程語言,可以很簡(jiǎn)單的構(gòu)建簡(jiǎn)單,可靠和高效的軟件。”

golang.org

Go 的歷史

從 2007 后半年開始設(shè)計(jì)

  • Robert Griesemer, Rob Pike 和 Ken Thompson.

  • Ian Lance Taylor 和 Russ Cox

從 2009 年開始開源,有一個(gè)非常活躍的社區(qū)。

Go 語言穩(wěn)定版本 Go 1 是在 2012 年早期發(fā)布的。

為什么有 Go?

Go 是解決 Google 規(guī)模的一個(gè)解決方案。

系統(tǒng)規(guī)模

  • 規(guī)劃的規(guī)模為 10⁶⁺ 臺(tái)機(jī)器

  • 每天在幾千臺(tái)機(jī)器上作業(yè)

  • 在系統(tǒng)中與其他作業(yè)進(jìn)行協(xié)作,交互

  • 同一時(shí)間進(jìn)行大量工作

解決方案:對(duì)并發(fā)的支持非常強(qiáng)大

第二個(gè)問題:工程規(guī)模

在 2011 年

  • 跨 40+ 辦公室的 5000+ 名開發(fā)者

  • 每分鐘有 20+ 修改

  • 每個(gè)月修改 50% 的代碼基礎(chǔ)庫

  • 每天執(zhí)行 5千萬的測(cè)試用例

  • 單個(gè)代碼樹

解決方案:為大型代碼基礎(chǔ)庫而設(shè)計(jì)的語言

誰在 Google 使用 Go?

大量的項(xiàng)目,幾千位 Go 程序員,百萬行的 Go 代碼。

公開的例子:

  • 移動(dòng)設(shè)備的 Chrome SPDY 代理

  • Chrome, ChromeOS, Android SDK, Earth 等等的下載服務(wù)器

  • YouTube Vitess MySQL 均衡器

主要任務(wù)是網(wǎng)絡(luò)服務(wù)器,但是這是通用的語言。

除了 Google 還有誰在使用 Go?

golang.org/wiki/GoUsers

Apcera, Bitbucket, bitly, Canonical, CloudFlare, Core OS, Digital Ocean, Docker, Dropbox, Facebook, Getty Images, GitHub, Heroku, Iron.io, Kubernetes, Medium, MongoDB services, Mozilla services, New York Times, pool.ntp.org, Secret, SmugMug, SoundCloud, Stripe, Square, Thomson Reuters, Tumblr, ...

#p#

比較 Go 和 Java

Go 和 Java 有很多共同之處

  • C 系列 (強(qiáng)類型,括號(hào))

  • 靜態(tài)類型

  • 垃圾收集

  • 內(nèi)存安全 (nil 引用,運(yùn)行時(shí)邊界檢查)

  • 變量總是初始化 (zero/nil/false)

  • 方法

  • 接口

  • 類型斷言 (實(shí)例)

  • 反射

Go 與 Java 的不同之處

  • 代碼程序直接編譯成機(jī)器碼,沒有 VM

  • 靜態(tài)鏈接二進(jìn)制

  • 內(nèi)存布局控制

  • 函數(shù)值和詞法閉包

  • 內(nèi)置字符串 (UTF-8)

  • 內(nèi)置泛型映射和數(shù)組/片段

  • 內(nèi)置并發(fā)

Go 特意去掉了大量的特性

  • 沒有類

  • 沒有構(gòu)造器

  • 沒有繼承

  • 沒有 final

  • 沒有異常

  • 沒有注解

  • 沒有自定義泛型

為什么 Go 要省去那些特性?

代碼清晰明了是首要的

當(dāng)查看代碼時(shí),可以很清晰的知道程序?qū)?huì)做什么

當(dāng)編寫代碼的時(shí)候,也可以很清晰的讓程序做你想做的

有時(shí)候這意味著編寫出一個(gè)循環(huán)而不是調(diào)用一個(gè)模糊的函數(shù)。

(不要變的太枯燥)

詳細(xì)的設(shè)計(jì)背景請(qǐng)看:

示例

Java程序猿對(duì)Go應(yīng)該很眼熟

Main.java

  1. public class Main {  
  2.     public static void main(String[] args) {  
  3.         System.out.println("Hello, world!");  
  4.     }  

hello.go

  1. package main  
  2. import "fmt" 
  3. func main() {  
  4.     fmt.Println("Hello, 世界!")  

Hello, web server(你好,web服務(wù))

package main

  1. import (  
  2.     "fmt" 
  3.     "log" 
  4.     "net/http" 
  5. )  
  6. func main() {  
  7.     http.HandleFunc("/hello", handleHello)  
  8.     fmt.Println("serving on http://localhost:7777/hello")  
  9.     log.Fatal(http.ListenAndServe("localhost:7777", nil))  
  10. }  
  11. func handleHello(w http.ResponseWriter, req *http.Request) {  
  12.     log.Println("serving", req.URL)  
  13.     fmt.Fprintln(w, "Hello, 世界!")  

(訪問權(quán)限)類型根據(jù)變量名來聲明。
公共變量名首字大寫,私有變量首字母小寫。

示例:Google搜索前端

  1. func main() {  
  2.     http.HandleFunc("/search", handleSearch)  
  3.     fmt.Println("serving on http://localhost:8080/search")  
  4.     log.Fatal(http.ListenAndServe("localhost:8080", nil))  
  5. }  
  6. // handleSearch handles URLs like "/search?q=golang" by running a  
  7. // Google search for "golang" and writing the results as HTML to w.  
  8. func handleSearch(w http.ResponseWriter, req *http.Request) { 

請(qǐng)求驗(yàn)證

  1. func handleSearch(w http.ResponseWriter, req *http.Request) {  
  2.     log.Println("serving", req.URL)  
  3.     // Check the search query.  
  4.     query := req.FormValue("q")  
  5.     if query == "" {  
  6.         http.Error(w, `missing "q" URL parameter`, http.StatusBadRequest)  
  7.         return 
  8.     } 

FormValueis 是 *http.Request 的一個(gè)方法:

  1. package http  
  2. type Request struct {...}  
  3. func (r *Request) FormValue(key string) string {...} 

query := req.FormValue("q")初始化變量query,其變量類型是右邊表達(dá)式的結(jié)果,這里是string類型.  

取搜索結(jié)果

  1. // Run the Google search.  
  2.    start := time.Now()  
  3.    results, err := Search(query)  
  4.    elapsed := time.Since(start)  
  5.    if err != nil {  
  6.        http.Error(w, err.Error(), http.StatusInternalServerError)  
  7.        return 
  8.    } 

Search方法有兩個(gè)返回值,分別為結(jié)果results和錯(cuò)誤error.

  1. func Search(query string) ([]Result, error) {...} 

當(dāng)error的值為nil時(shí),results有效。

  1. type error interface {  
  2.     Error() string // a useful human-readable error message  

Error類型可能包含額外的信息,可通過斷言訪問。 

渲染搜索結(jié)果

  1. // Render the results.  
  2.     type templateData struct {  
  3.         Results []Result  
  4.         Elapsed time.Duration  
  5.     }  
  6.     if err := resultsTemplate.Execute(w, templateData{  
  7.         Results: results,  
  8.         Elapsed: elapsed,  
  9.     }); err != nil {  
  10.         log.Print(err)  
  11.         return 
  12.     } 

結(jié)果results使用Template.Execute生成HTML,并存入一個(gè)io.Writer:

  1. type Writer interface {  
  2.         Write(p []byte) (n int, err error)  

http.ResponseWriter實(shí)現(xiàn)了io.Writer接口。

Go變量操作HTML模板

  1. // A Result contains the title and URL of a search result.  
  2. type Result struct {  
  3.     Title, URL string  
  4. }  
  5. var resultsTemplate = template.Must(template.New("results").Parse(`  
  6. <html>  
  7. <head/>  
  8. <body>  
  9.   <ol>  
  10.   {{range .Results}}  
  11.     <li>{{.Title}} - <a href="{{.URL}}">{{.URL}}</a></li>  
  12.   {{end}}  
  13.   </ol>  
  14.   <p>{{len .Results}} results in {{.Elapsed}}</p>  
  15. </body>  
  16. </html>  
  17. `)) 

請(qǐng)求Google搜索API

  1. func Search(query string) ([]Result, error) {  
  2.     // Prepare the Google Search API request.  
  3.     u, err := url.Parse("https://ajax.googleapis.com/ajax/services/search/web?v=1.0")  
  4.     if err != nil {  
  5.         return nil, err  
  6.     }  
  7.     q := u.Query()  
  8.     q.Set("q", query)  
  9.     u.RawQuery = q.Encode()  
  10.     // Issue the HTTP request and handle the response.  
  11.     resp, err := http.Get(u.String())  
  12.     if err != nil {  
  13.         return nil, err  
  14.     }  
  15.     defer resp.Body.Close() 

defer聲明使resp.Body.Close運(yùn)行在Search方法返回時(shí)。

#p#

解析返回的JSON數(shù)據(jù)到Go struct類型

developers.google.com/web-search/docs/#fonje

  1.   var jsonResponse struct {  
  2.         ResponseData struct {  
  3.             Results []struct {  
  4.                 TitleNoFormatting, URL string  
  5.             }  
  6.         }  
  7.     }  
  8.     if err := json.NewDecoder(resp.Body).Decode(&jsonResponse); err != nil {  
  9.         return nil, err  
  10.     }  
  11.     // Extract the Results from jsonResponse and return them.  
  12.     var results []Result  
  13.     for _, r := range jsonResponse.ResponseData.Results {  
  14.         results = append(results, Result{Title: r.TitleNoFormatting, URL: r.URL})  
  15.     }  
  16.     return results, nil  

這就是它的前端

所有引用的包都來自標(biāo)準(zhǔn)庫:

  1. import (  
  2.     "encoding/json" 
  3.     "fmt" 
  4.     "html/template" 
  5.     "log" 
  6.     "net/http" 
  7.     "net/url" 
  8.     "time" 

Go服務(wù)器規(guī)模:每一個(gè)請(qǐng)求都運(yùn)行在自己的goroutine里。

讓我們談?wù)劜l(fā)。

通信順序進(jìn)程(Hoare,1978)

并發(fā)程序作為獨(dú)立進(jìn)程,通過信息交流的順序執(zhí)行。

順序執(zhí)行很容易理解,異步則不是。

“不要為共亨內(nèi)存通信,為通信共享內(nèi)存。”

Go原理: goroutines, channels, 和 select聲明.

Goroutines

Goroutines 就像輕量級(jí)線程。

它們通過小棧(tiny stacks)和按需調(diào)整運(yùn)行。

Go 程序可以擁有成千上萬個(gè)(goroutines實(shí)例

使用go聲明啟動(dòng)一個(gè)goroutines:

  1. go f(args) 

Go運(yùn)行時(shí)把goroutines放進(jìn)OS線程里。

不要使用線程堵塞goroutines。

Channels

Channels被定義是為了與goroutines之間通信。

  1. c := make(chan string)  
  2.    
  3. // goroutine 1  
  4. c <- "hello!" 
  5.    
  6. // goroutine 2  
  7. s := <-c  
  8. fmt.Println(s) // "hello!" 

Select

select聲明一個(gè)語句塊來判斷執(zhí)行。

  1. select {  
  2. case n := <-in:  
  3.   fmt.Println("received", n)  
  4. case out <- v:  
  5.   fmt.Println("sent", v)  

只有條件成立的case塊會(huì)運(yùn)行。

示例:Google搜索(后端)

問: Google搜索能做些什么?

答: 提出一個(gè)問題,它可以返回一個(gè)搜索結(jié)果的頁面(和一些廣告)。

問: 我們?cè)趺吹玫竭@些搜索結(jié)果?

答: 發(fā)送一個(gè)問題到網(wǎng)頁搜索、圖片搜索、YouTube(視頻)、地圖、新聞,稍等然后檢索出結(jié)果。

我們?cè)撛趺磳?shí)現(xiàn)它?

Google搜索 : 一個(gè)假的框架

We can simulate a Search function with a random timeout up to 100ms.

我們要模擬一個(gè)搜索函數(shù),讓它隨機(jī)超時(shí)0到100毫秒。

  1. var (  
  2.     Web   = fakeSearch("web")  
  3.     Image = fakeSearch("image")  
  4.     Video = fakeSearch("video")  
  5. )  
  6. type Search func(query string) Result  
  7. func fakeSearch(kind string) Search {  
  8.     return func(query string) Result {  
  9.         time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)  
  10.         return Result(fmt.Sprintf("%s result for %q\n", kind, query))  
  11.     }  

Google搜索: 測(cè)試框架

  1. func main() {  
  2.     start := time.Now()  
  3.     results := Google("golang")  
  4.     elapsed := time.Since(start)  
  5.     fmt.Println(results)  
  6.     fmt.Println(elapsed)  

Google搜索 (串行)

Google函數(shù)獲取一個(gè)查詢,然后返回一個(gè)的結(jié)果集 (不一定是字符串).

Google按順序調(diào)用Web(網(wǎng)頁)、Image(圖片)、Video(視頻)并將返回加入到結(jié)果集中。

  1. func Google(query string) (results []Result) {  
  2.     results = append(results, Web(query))  
  3.     results = append(results, Image(query))  
  4.     results = append(results, Video(query))  
  5.     return 

Google搜索(并行)

同時(shí)執(zhí)行 Web,、Image、 和Video搜索,并等待所有結(jié)果。

func方法是在query和c的地方關(guān)閉的。

  1. func Google(query string) (results []Result) {  
  2.     c := make(chan Result)  
  3.     go func() { c <- Web(query) }()  
  4.     go func() { c <- Image(query) }()  
  5.     go func() { c <- Video(query) }()  
  6.     for i := 0; i < 3; i++ {  
  7.         result := <-c  
  8.         results = append(results, result)  
  9.     }  
  10.     return 

Google搜索 (超時(shí))

等待慢的服務(wù)器。

沒有鎖,沒有條件變量,沒有返回值。

  1. c := make(chan Result, 3)  
  2. go func() { c <- Web(query) }()  
  3. go func() { c <- Image(query) }()  
  4. go func() { c <- Video(query) }()  
  5. timeout := time.After(80 * time.Millisecond)  
  6. for i := 0; i < 3; i++ {  
  7.     select {  
  8.     case result := <-c:  
  9.         results = append(results, result)  
  10.     case <-timeout:  
  11.         fmt.Println("timed out")  
  12.         return 
  13.     }  
  14. }  
  15. return 

防止超時(shí)

問: 如何防止丟掉慢的服務(wù)的結(jié)果?

答: 復(fù)制這個(gè)服務(wù),然后發(fā)送請(qǐng)求到多個(gè)復(fù)制的服務(wù),并使用第一個(gè)響應(yīng)的結(jié)果。

  1. func First(query string, replicas ...Search) Result {  
  2.     c := make(chan Result, len(replicas))  
  3.     searchReplica := func(i int) { c <- replicas[i](query) }  
  4.     for i := range replicas {  
  5.         go searchReplica(i)  
  6.     }  
  7.     return <-c  

使用First函數(shù)

  1. func main() {  
  2.     start := time.Now()  
  3.     result := First("golang",  
  4.         fakeSearch("replica 1"),  
  5.         fakeSearch("replica 2"))  
  6.     elapsed := time.Since(start)  
  7.     fmt.Println(result)  
  8.     fmt.Println(elapsed)  

Google搜索 (復(fù)制)

使用復(fù)制的服務(wù)以減少多余延遲。

  1. c := make(chan Result, 3)  
  2. go func() { c <- First(query, Web1, Web2) }()  
  3. go func() { c <- First(query, Image1, Image2) }()  
  4. go func() { c <- First(query, Video1, Video2) }()  
  5. timeout := time.After(80 * time.Millisecond)  
  6. for i := 0; i < 3; i++ {  
  7.     select {  
  8.     case result := <-c:  
  9.         results = append(results, result)  
  10.     case <-timeout:  
  11.         fmt.Println("timed out")  
  12.         return 
  13.     }  
  14. }  
  15. return 

其他

沒有鎖,沒有條件變量,沒有調(diào)用。

#p#

總結(jié)

經(jīng)過一些簡(jiǎn)單轉(zhuǎn)換,我們使用 Go 的并發(fā)原語來轉(zhuǎn)換一個(gè)

  • 順序性的

  • 故障敏感的

程序?yàn)橐粋€(gè)

  • 并發(fā)

  • 可復(fù)用的

  • 健壯的

工具

Go 有很多強(qiáng)大的工具

  • gofmt 和 goimports

  • The go tool

  • godoc

  • IDE 和編輯器支持

這語言就是為工具鏈設(shè)計(jì)的。

gofmt 和 goimports

Gofmt 可以自動(dòng)格式化代碼,沒有選項(xiàng)。

Goimports 基于你的工作空間更新導(dǎo)入聲明

大部分人可以安全的使用這些工具。

play.golang.org/p/GPqra77cBK

The go tool

The go tool 可以在一個(gè)傳統(tǒng)目錄布局中用源代碼構(gòu)建 Go 程序。不需要 Makefiles 或者其他配置。

匹配這些工具及其依賴,然后進(jìn)行構(gòu)建,安裝:

  1. % go get golang.org/x/tools/cmd/present 

運(yùn)行:

  1. % present 

godoc

為世界上所有的開源 Go 代碼生成文檔:

godoc.org

IDE 和編輯器支持

Eclipse, IntelliJ, emacs, vim 等等:

  • gofmt

  • goimports

  • godoclookups

  • code completion

  • code navigation

但是沒有 "Go IDE".

Go 工具無處不在。

Go 的下一步計(jì)劃

Go 路線在線查看

tour.golang.org

大量的學(xué)習(xí)資料

golang.org/wiki/Learn

完美的社區(qū)

golang.org/project

Thank you

Sameer Ajmani

Tech Lead Manager, Go team

Google

@Sajma

sameer@golang.org

英文原文:Go for Java Programmers PPT

責(zé)任編輯:林師授 來源: 開源中國(guó)編譯
相關(guān)推薦

2012-07-03 11:18:40

程序員社交網(wǎng)站

2020-12-21 15:30:35

Python工具編程語言

2015-10-27 10:57:08

JavaScript免費(fèi)書籍

2015-07-09 10:38:21

程序員未來

2012-11-09 13:44:48

ScalaJVMJava

2012-07-20 11:16:26

程序員

2022-03-21 15:30:27

面試程序員算法

2020-09-27 14:55:27

程序員技能開發(fā)者

2012-02-15 09:35:17

程序員

2014-02-13 15:38:13

程序員算法面試

2020-07-14 21:53:13

Python Python 工具開發(fā)

2013-08-20 09:33:59

程序員

2012-11-08 09:49:30

C++Java程序員

2014-07-29 10:30:16

JavaJava程序員

2012-11-02 13:47:31

Java程序員編程

2010-12-30 10:04:49

Linux入門

2010-01-14 18:07:30

C++語言

2011-05-13 14:34:02

程序員

2009-07-28 08:28:15

2015-08-27 16:15:10

程序員面試錯(cuò)誤
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 中文字幕 欧美 日韩 | 欧美乱人伦视频 | 在线电影日韩 | 天天射天天干 | 免费观看一级黄色录像 | 亚洲精品白浆高清久久久久久 | 久久久精品一区二区三区四季av | 日韩波多野结衣 | 国产色黄 | 久久久人成影片一区二区三区 | 国产一区中文字幕 | 精品一区二区三区视频在线观看 | 日韩精品一区二区三区在线观看 | 久久久久久天堂 | 色必久久 | 91视频久久 | 一区二区av | 欧美精品网| 亚洲另类春色偷拍在线观看 | 91麻豆精品国产91久久久久久 | 天堂免费看片 | а_天堂中文最新版地址 | 久久久久久国产精品久久 | av在线一区二区 | 亚洲午夜精品一区二区三区他趣 | 欧美色性 | 国产美女精品视频免费观看 | 毛片网站在线观看 | 精品无码久久久久久国产 | 国产午夜精品久久久 | 欧美一级毛片免费观看 | 欧美精品久久久久 | 精品国产一区二区三区观看不卡 | 中文精品视频 | 成人一级片在线观看 | 欧美日韩精品一区二区三区视频 | 在线观看你懂的网站 | 东京久久 | 国产精品久久久久一区二区三区 | 亚洲精品一区国产精品 | av网站免费看 |