|
/ n/ P! w1 P' s
, N5 U9 k" z& s' r; [! u- k! R
go语言与区块链开发,链接:
8 T! [2 Q# N+ D. [0 F+ ?! v$ u p6 c, zGoogle资深工程师深度讲解Go语言,链接:
; Q9 x8 U8 H) X5 d+ yJKSJ-GO语言从入门到实战【完结】,链接: }6 {* N6 q4 L, ]3 h6 l0 @
" `) s5 }- B+ _% }8 E0 Y
# k O- v( S; I9 k5 PGo的优势' p- R- |! [: x& S
/ J; W8 N C( K$ w) S. l, x$ L" v; O* ]8 |原因 1:性能
d3 t9 h2 D# C/ t5 P/ x0 u, g1 p+ M4 P& K9 f' O$ f" Z
图0:Go语言的9大优势和3大缺点
( m2 F6 D2 [1 }6 O6 w' Q9 fGo 极其地快。其性能与 Java 或 C++相似。在我们的使用中,Go 一般比 Python 要快 30 倍。以下是 Go 与 Java 之间的基准比较:
$ b6 Y: h9 E2 U; l* j7 s
% D; e% v; Z# ?7 e g3 Z0 E& ^图1:Go语言的9大优势和3大缺点% ^4 q, g% C6 F3 e) J- v
图2:Go语言的9大优势和3大缺点
* V0 ~; }* K# i2 r' m7 t. D图3:Go语言的9大优势和3大缺点
) ]7 [1 u. S6 A( d. F& g' R1 x- J图3:Go语言的9大优势和3大缺点, Y' D+ I- X* a% G" Q( R* [" H
原因 2:语言性能很重要
, z+ p& o$ C% E2 W5 t7 m% N' w0 d2 y7 U8 T8 Y" q. _5 @- t
对很多应用来说,编程语言只是简单充当了其与数据集之间的胶水。语言本身的性能常常无关轻重。& c1 o9 i+ g( w" X3 r) u' z
9 _( ]: t! {7 ~但是 Stream 是一个 API 提供商,服务于世界 500 强以及超过 2 亿的终端用户。数年来我们已经优化了 Cassandra、PostgreSQL、Redis 等等,然而最终抵达了所使用语言的极限。$ `3 Z1 x' v" E/ @1 D
4 X0 Y8 X3 J( FPython 非常棒,但是其在序列化/去序列化、排序和聚合中表现欠佳。我们经常会遇到这样的问题:Cassandra 用时 1ms 检索了数据,Python 却需要 10ms 将其转化成对象。9 ]# i. o8 \8 T1 T0 p
9 w7 q; \2 A" Z; N* X
原因 3:开发者效率&不要过于创新$ M! M: \5 N4 f6 L: e
5 E/ ^. f, O5 z看一下绝佳的入门教程《开始学习 Go 语言》(http://howistart.org/posts/go/1/)中的一小段代码:! F1 i+ K/ q# \2 U5 \
! k" S, B H I. s; D, |4 y
package main) I/ x5 [- {% B4 ]3 ^' G7 c8 l p
type openWeatherMap struct{}func (w openWeatherMap) temperature(city string) (float64, error) {2 _% B; M, S' Z! E3 g6 C
resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&q=" + city)
# p- y1 b9 w& `/ U6 B if err != nil {6 H4 {: ?; V; ]+ f6 ^1 w
return 0, err6 S0 q0 y0 E7 F+ R9 M
} Q+ y% N0 t! J' |% Y. u* W( k
defer resp.Body.Close()
4 w2 |; u6 y p var d struct {
3 o$ u( a q9 x Main struct {# ]& m7 Q: d/ {! f- e( `: W- \9 V
Kelvin float64 `json:"temp"`4 @: O7 T3 G. j+ t+ p; P
} `json:"main"`
: k- R- ^3 S1 v4 Z) H }' v3 X. K: e/ D5 j2 o; M. s
if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {' n$ w$ r/ @0 a: ^4 i2 E
return 0, err: `/ ?* V' Y# J- K, |; ]
}
! `" R+ y2 h* f; N) Q, X; T8 v log.Printf("openWeatherMap: %s: %.2f", city, d.Main.Kelvin)
3 b) s5 Y" r; A( v- \ return d.Main.Kelvin, nil}
! a* ~7 H2 b+ M, v% A如果你是一个新手,看到这段代码你并不会感到吃惊。它展示了多种赋值、数据结构、指针、格式化以及内置的 HTTP 库。
! o3 ?. }/ `, R5 h" H( E0 f% I" c+ n5 k# f
当我第一次编程时,我很喜欢使用 Python 的高阶功能。Python 允许你创造性地使用正在编写的代码,比如,你可以:' f4 I1 L: V/ [* D" i& X# I$ o
# b# v, D4 A4 ?4 f8 t- q在代码初始化时,使用 MetaClasses 自行注册类别0 ~6 F8 j- F$ t- ]; W( f+ N' e2 r
置换真假3 x1 h3 l' p, c4 z0 y- T
添加函数到内置函数列表中
" o. d( H* {) F* D2 }通过奇妙的方法重载运算符, D# ~+ l. F" k# g: V; v7 e% i
毋庸置疑这些代码很有趣,但也使得在读取其他人的工作时,代码变得难以理解。
, I" w5 m. ~% c! ]! ^- a) a* X. U; N. f
Go 强迫你坚持打牢基础,这也就为读取任意代码带来了便利,并能很快搞明白当下发生的事情。
; j! ~7 S* F' T, y% f3 M0 t9 s0 b% y5 `. V
注意:当然如何容易还是要取决于你的使用案例。如果你要创建一个基本的 CRUD API,我还是建议你使用 Django + DRF,或者 Rails。! {! }% b' @- ?9 d. v
3 g4 _0 V+ ^+ x7 W+ ^+ V1 w
原因 4:并发性&通道- I! H9 Q0 w! {; T5 _* o0 }8 _7 L
$ m4 \# I9 ~" A* o( _; qGo 作为一门语言致力于使事情简单化。它并未引入很多新概念,而是聚焦于打造一门简单的语言,它使用起来异常快速并且简单。其唯一的创新之处是 goroutines 和通道。Goroutines 是 Go 面向线程的轻量级方法,而通道是 goroutines 之间通信的优先方式。
' j5 `% j7 s$ Y5 a% z5 | I2 r' A! n# V
; x3 p' N ]* N* G- N, z' ~* R创建 Goroutines 的成本很低,只需几千个字节的额外内存,正由于此,才使得同时运行数百个甚至数千个 goroutines 成为可能。你可以借助通道实现 goroutines 之间的通信。Go 运行时间可以表示所有的复杂性。Goroutines 以及基于通道的并发性方法使其非常容易使用所有可用的 CPU 内核,并处理并发的 IO——所有不带有复杂的开发。相较于 Python/Java,在一个 goroutine 上运行一个函数需要最小的样板代码。你只需使用关键词「go」添加函数调用:# X* Q; c% Z* T6 b
: T0 y9 ?8 ?" I& D$ ?: E9 p
package main
6 ?, `, ?, W. vimport (% l' R% ?7 x. q& v$ O- i
"fmt"
+ m( c0 o. x! @ "time")func say(s string) {
0 J5 z; z. S9 ^ for i := 0; i < 5; i++ {; d% Q' w6 G- ^7 R7 H2 |4 j6 `
time.Sleep(100 * time.Millisecond)
( B9 |% `% {$ U* C! g fmt.Println(s)
' z; y; C4 ?! o% O8 `$ h' B }}func main() {
3 Y% F; H; I9 F9 W6 z" j4 r go say("world")" D5 M7 O4 m1 A2 Y _7 G9 y1 |
say("hello")}
4 |: v. K1 O* P3 {Go 的并发性方法非常容易上手,相较于 Node 也很有趣;在 Node 中,开发者必须密切关注异步代码的处理。/ T4 e/ q$ v7 T6 `( f2 N
1 w# K3 e l1 \. Y& f2 Z
并发性的另一个优质特性是竞赛检测器,这使其很容易弄清楚异步代码中是否存在竞态条件。下面是一些上手 Go 和通道的很好的资源:
& z4 s% W8 o# f% u$ h+ ^1 p' v; G$ H4 R; R- w8 q& r% |
https://gobyexample.com/channels
; D+ h6 T+ o' Q8 x8 @' H- i4 Hhttps://tour.golang.org/concurrency/2* c, r" ]! b/ F( w
http://guzalexander.com/2013/12/06/golang-channels-tutorial.html
, W* C- _: `7 U' \+ O' Fhttps://www.golang-book.com/books/intro/102 a7 r) @& [+ R. m8 j: h- @* {# ^
https://www.goinggo.net/2014/02/the-nature-of-channels-in-go.html
+ i! W, ?: S4 m2 q1 p8 U5 |! G原因 5:快速的编译时间
8 H) j: \( R1 O: |) I
K% E- B, O9 ]# R) F# H/ _当前我们使用 Go 编写的最大微服务的编译时间只需 6 秒。相较于 Java 和 C++呆滞的编译速度,Go 的快速编译时间是一个主要的效率优势。我热爱击剑,但是当我依然记得代码应该做什么之时,事情已经完成就更好了。
& d+ V- \- ^, q
; j. n0 ]8 \7 C5 l3 _# F: b4 T8 P" K. O图4:Go语言的9大优势和3大缺点
* I3 d' V/ b) a5 N6 A/ R3 f/ ?3 ZGo 之前的代码编译0 a& `1 {8 ^. f
% X# k# A; `) [7 n
原因 6:打造团队的能力) g$ t( m) t% P: P- |* I
& ]7 g5 k1 N4 h# t1 ~2 u首先,最明显的一点是:Go 的开发者远没有 C++和 Java 等旧语言多。据知,有 38% 的开发者了解 Java,19.3% 的开发者了解 C++,只有 4.6% 的开发者知道 Go。GitHub 数据表明了相似的趋势:相较于 Erlang、Scala 和 Elixir,Go 更为流行,但是相较于 Java 和 C++ 就不是了。
9 w$ f% i. O$ x+ t( N8 t
' L1 M D/ Q7 T* }0 ~5 @2 B幸运的是 Go 非常简单,且易于学习。它只提供了基本功能而没有多余。Go 引入的新概念是「defer」声明,以及内置的带有 goroutines 和通道的并发性管理。正是由于 Go 的简单性,任何的 Python、Elixir、C++、Scala 或者 Java 开发者皆可在一月内组建成一个高效的 Go 团队。- @* Q) L5 w$ H. E7 R; H. m
: R9 t2 @: }* Q R" Z原因 7:强大的生态系统0 @7 E" L! K" o6 j# ~* Y
3 {; l0 q# }8 b4 {
对我们这么大小的团队(大约 20 人)而言,生态系统很重要。如果你需要重做每块功能,那就无法为客户创造收益了。Go 有着强大的工具支持,面向 Redis、RabbitMQ、PostgreSQL、Template parsing、Task scheduling、Expression parsing 和 RocksDB 的稳定的库。5 K8 t9 t4 w4 U* W r& @
0 E. ?% O3 s# Q `
Go 的生态系统相比于 Rust、Elixir 这样的语言有很大的优势。当然,它又略逊于 Java、Python 或 Node 这样的语言,但它很稳定,而且你会发现在很多基础需求上,已经有高质量的文件包可用了。
, l+ `/ {! } ]- Y5 K- E& T* e" O# d
6 e0 o$ H: y) Y" y5 B原因 8:GOFMT,强制代码格式
0 d, Z. H7 s1 T! o5 [; `) g- h5 A' B( U/ v2 I$ P4 X% P, A7 q
Gofmt 是一种强大的命令行功能,内建在 Go 的编译器中来规定代码的格式。从功能上看,它类似于 Python 的 autopep8。格式一致很重要,但实际的格式标准并不总是非常重要。Gofmt 用一种官方的形式规格代码,避免了不必要的讨论。
1 X+ f$ \) h6 P- {' K% _- j, \7 E" g7 k1 }7 ]3 }* t$ L
原因 9:gRPC 和 Protocol Buffers% I) Y! f$ A- u; p
3 P5 S8 r0 F$ J3 T
Go 语言对 protocol buffers 和 gRPC 有一流的支持。这两个工具能一起友好地工作以构建需要通过 RPC 进行通信的微服务器(microservices)。我们只需要写一个清单(manifest)就能定义 RPC 调用发生的情况和参数,然后从该清单将自动生成服务器和客户端代码。这样产生代码不仅快速,同时网络占用也非常少。
4 f1 t0 v' b- W/ `* h1 N
, a; i$ f" J+ f/ A R从相同的清单,我们可以从不同的语言生成客户端代码,例如 C++、Java、Python 和 Ruby。因此内部通信的 RESET 端点不会产生分歧,我们每次也就需要编写几乎相同的客户端和服务器代码。
0 U p6 V& S- n$ J8 `
# }6 f2 m8 e" N) n使用 Go 语言的缺点) H6 i( t3 ?6 G2 f6 z
" R) `+ P p% n缺点 1:缺少框架. X5 r% G- M+ b/ ^0 l
% n+ L# ?3 V+ B! z0 {% F
Go 语言没有一个主要的框架,如 Ruby 的 Rails 框架、Python 的 Django 框架或 PHP 的 Laravel。这是 Go 语言社区激烈讨论的问题,因为许多人认为我们不应该从使用框架开始。在很多案例情况中确实如此,但如果只是希望构建一个简单的 CRUD API,那么使用 Django/DJRF、Rails Laravel 或 Phoenix 将简单地多。
- i" ?4 E9 L0 C+ R u+ i
5 f0 s4 j* i: e Q缺点 2:错误处理
" @" T. a- _ ]) Q+ c/ d8 Q
1 a, D7 V5 P: n5 H' K: e程序员专用礼品杯,生日礼物Go 语言通过函数和预期的调用代码简单地返回错误(或返回调用堆栈)而帮助开发者处理编译报错。虽然这种方法是有效的,但很容易丢失错误发生的范围,因此我们也很难向用户提供有意义的错误信息。错误包(errors package)可以允许我们添加返回错误的上下文和堆栈追踪而解决该问题。' I* I A/ J, C* [6 q0 ]- P
' M' K7 w0 _" O: |% r8 o5 ]
另一个问题是我们可能会忘记处理报错。诸如 errcheck 和 megacheck 等静态分析工具可以避免出现这些失误。虽然这些解决方案十分有效,但可能并不是那么正确的方法。1 T& A0 t/ S m' n; ^( r* b/ K- z
. X3 K% }5 g" B- K; \
缺点 3:软件包管理 z: ?& m5 Q+ t( W! d3 X; ?7 s
* o8 x+ }. }; A
Go 语言的软件包管理绝对不是完美的。默认情况下,它没有办法制定特定版本的依赖库,也无法创建可复写的 builds。相比之下 Python、Node 和 Ruby 都有更好的软件包管理系统。然而通过正确的工具,Go 语言的软件包管理也可以表现得不错。
6 e5 W6 g$ i8 f' _1 C) |
C* r4 `! [! X我们可以使用 Dep 来管理依赖项,它也能指定特定的软件包版本。除此之外,我们还可以使用一个名为 VirtualGo 的开源工具,它能轻松地管理 Go 语言编写的多个项目。
6 l3 k* h B4 H# h5 y- T$ L$ K/ Q" e4 j, ?$ A7 X
资源下载地址和密码(百度云盘): [/hide] 百度网盘信息回帖可见
, _: n: \7 v7 k) E- k7 w
: v9 h! f! {" s6 G* ^" |7 A7 ^8 P
$ G' P: Q5 I; h( I( F, z# M
/ Z! U! B$ }6 L0 z本资源由Java自学网收集整理【www.javazx.com】 |
|