-
Notifications
You must be signed in to change notification settings - Fork 1
/
go1.6.slide
411 lines (225 loc) · 17.2 KB
/
go1.6.slide
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
O que há de novo no release 1.6?
Go Meetup VI + Go 1.6 release party
20 Feb 2016
Vitor De Mario
Mendelics
@vdemario
* Bem-vindos
No dia 17 de fevereiro a versão 1.6 do Go foi lançada. No mesmo dia vários meetups foram realizados ao redor do mundo para comemorar.
Hoje (20 de fevereiro) nos juntamos à festa.
Mais de 50 grupos estão participando, [[https://github.com/golang/go/wiki/Go-1.6-release-party#whos-involved][listados aqui]].
Essa apresentação é _fortemente_ baseada nos [[http://tip.golang.org/doc/go1.6][release notes oficiais da versão 1.6]].
A apresentação contém muitos links com mais detalhes das novidades e pode ser encontrada no github em [[https://github.com/vdemario/talks/blob/master/go1.6.slide][https://github.com/vdemario/talks/blob/master/go1.6.slide]].
A versão original dessa apresentação foi criada pelo Dave Cheney para o meetup de Sidney e pode ser encontrada online em [[http://talks.godoc.org/github.com/davecheney/gosyd/go1.6.slide][talks.godoc.org/github.com/davecheney/gosyd/go1.6.slide]].
* Arte do evento
.image go1.6/Go_release_party_1.6_wide.png 500 _
_Créditos_: [[https://groups.google.com/d/msg/go-meetup-organisers/5FFI9Azo2TE/_lyJU_xMEgAJ][Frédéric Menez / Golang Paris meetup]].
* Go 1.6
O release mais recente do Go, versão 1.6, chega seis meses depois do 1.5.
A maior parte das mudanças foram na implementação da linguagem, do runtime e das bibliotecas. Nenhuma mudança foi feita na especificação da linguagem.
Como sempre, o release mantém a [[http://tip.golang.org/doc/go1compat.html][garantia de compatibilidade do Go 1]].
Praticamente todos os programas em Go devem continuar compilando e rodando como sempre.
* O projeto Go em números
O Go foi anunciado como um projeto open source em 10 de Novembro de 2009.
Novas versões saem a cada 6 meses em média com várias versões menores com correções de bugs entre os releases principais.
Linha do tempo:
- [[http://blog.golang.org/the-path-to-go-1][Go 1.0]] lançado em 28 de março de 2012
- [[http://talks.golang.org/2013/go1.1.slide#1][Go 1.1]] lançado em 13 de maio de 2013
- Go 1.2 lançado em 1 de dezembro de 2013
- Go 1.3 lançado em 18 de junho de 2014
- Go 1.4 lançado em 10 de dezembro de 2014
- [[https://talks.golang.org/2015/state-of-go.slide#8][Go 1.5]] lançado em 19 de agosto de 2015
- Go 1.6 lançado em 17 de fevereiro de 2016
* Plataformas
O Go 1.6 roda nos seguintes sistemas operacionais:
- Windows, OSX (darwin), Android, iOS, NaCl, DragonflyBSD, FreeBSD, Linux, NetBSD, OpenBSD, Plan 9, Solaris/Illumos
O Go 1.6 suporta as seguintes arquiteturas de CPU:
- Intel (386 e amd64), arm (ARMv5, v6, v7), arm64, 64 bit PowerPC (big endian e little endian), 64 bit MIPS (big endian e little endian)
No futuro:
- s390x (IBM série Z) planejado para o Go 1.7
- RISC-V tem chances de ser implementado
* Compilação multiplataforma
Desde o Go 1.5, compilação multiplataforma funciona automaticamente*.
# compilando um binário para Windows na sua máquina (Linux com bash, por exemplo)
env GOOS=windows go build $YOURPACKAGE
Funciona com o binário baixado no [[https://golang.org/dl/][golang.org]].
Mais detalhes (em inglês):
- [[http://dave.cheney.net/2015/08/22/cross-compilation-with-go-1-5][Cross compilation with Go 1.5]]
- [[https://medium.com/@rakyll/go-1-5-cross-compilation-488092ba44ec#.7wrgy0a5s][Go 1.5: Cross compilation]]
_*_A_não_ser_que_você_use_cgo_
* Melhorias no garbage collector
O Go 1.5 introduziu um novo garbage collector de baixa latência.
O novo gc troca throughput for latência reduzida.
Alocações pagam (em termos de tempo) um pouco antecipadamente para reduzir o tempo necessário para coleta, o que reduz o tempo total de pausa do gc.
No Go 1.6, muito trabalho foi feito para otimizar e tunar o gc, com pausas de 10ms ou menos mesmo para heaps muito grandes.
Em outras palavras, o gc ficou muito mais eficiente para programas com alto consumo de memória.
* Go 1.5
Na [[https://www.youtube.com/watch?v=aiv1JOfMjm0][GopherCon 2015 Rick Hudson fez uma apresentação]] sobre o gc de baixa latência do Go 1.5
.image go1.6/go15.png 400 _
* Go 1.6
Na [[http://www.infoq.com/presentations/go-gc-performance][QCon SF de novembro Rick Hudson]] deu uma nova apresentação que mostrou essa comparação entre o Go 1.5 e o Go 1.6
.image go1.6/go16.png 400 _
_Sim,_o_eixo_X_está_em_gigabytes_
* HTTP/2
O Go 1.6 adiciona suporte transparente ao protocolo HTTP/2 no pacote `net/http`.
Clientes e servidores Go vão usar HTTP/2 automaticamente quando for apropriado no uso de HTTPS.
Programas que precisem desabilitar o HTTP/2 podem fazer isso setando o `Transport.TLSNextProto` (para clientes) ou `Server.TLSNextProto` (para servidores) como um map vazio, não nulo.
Mais detalhes (em inglês):
- [[https://http2.golang.org/][demo do HTTP/2]] (feito em Go)
- [[https://www.youtube.com/watch?v=gukAZO1fqZQ][Vídeo do Brad Fitzpatrick dando uma visão geral do suporte a HTTP/2 no Go 1.6]] no evento London Go Gathering de 2015.
* Passando ponteiros entre Go e C
A maior mudança para o cgo no Go 1.6 é que as regras para compartilhar ponteiros de Go com código em C, para garantir que código em C pode coexistir com o garbage collector do Go, foram clarificadas.
Go e C podem compartilhar memória alocada no Go quando:
- um ponteiro para essa memória é passado para o C durante uma chamada cgo,
- desde que essa memória não tenha ponteiros para mais memória alocada em Go,
- desde que o código em C não retenha o ponteiro depois que retornar.
Essas regras são verificadas em tempo de execução: se uma violação é detectadada, um diagnóstico sai na tela e o programa crasha.
Isso pode ser desativado usando a variável de ambiente `GODEBUG=cgocheck=0`, mas cuidado pois desativar isso costuma levar a falhas misterioras.
Recomenda-se fortemente corrigir esse tipo de código em vez de desativar as verificações.
* Passando ponteiros entre Go e C (cont.)
.play go1.6/cgo.go
* Compilador
Por fora, a cadeia de compilação permanece a mesma do Go 1.5.
Internamente, a principal mudança é que o parser agora é feito à mão em vez de gerado pelo yacc.
O novo compilador SSA deve sair no Go 1.7 mas apenas para amd64.
* Mudanças para a flag -X
No Go 1.5 a flag -X do linker mudou.
No Go 1.4 e antes, ela levava dois argumentos:
-X pathdeimportacao.nome valor
O Go 1.5 adicionou uma sintaxe alternativa usando só um argumento que é um par chave-valor:
-X pathdeimportacao.nome=valor
No Go 1.5 a sintaxe antiga ainda era aceita, com um warning sugerindo o uso da nova sintaxe. O Go 1.6 mantém esse comportamento. No Go 1.7 o suporte à sintaxe antiga será removido.
* maps dão panic se forem usados errado
O runtime adicionou uma detecção leve para uso concorrente incorreto de maps.
Se o runtime detecta essa condição, ele imprime um diagnóstico e crasha o programa.
fatal error: concurrent map writes
goroutine 2726 [running]:
runtime.throw(0x192d630, 0x15)
/usr/lib/go/src/runtime/panic.go:530 +0x90 fp=0xc8202eb838 sp=0xc8202eb820
A melhor maneira de entender melhor o problema é rodar o programa usando o race detector.
* maps dão panic se forem usados errado (example)
.play go1.6/map.go /START OMIT/,/END OMIT/
* Mensagens de panic são mais curtas por padrão
Para panics que terminanm o programa, o runtime agora _só_exibe_a_stack_da_goroutine_em_execução_, não todas as goroutines.
Em geral só a goroutine que está rodando importa para o panic, então omitir as outras reduz muito a quantidade de output irrelevante numa mensagem de crash.
Para ver as stacks de todas as goroutines, use a variável de ambiente `GOTRACEBACK=all` or faça uma chamada para `debug.SetTraceback` antes do crash e rode o programa novamente.
env GOTRACEBACK=all ./crashy
Mais detalhes (em inglês):
- [[http://dave.cheney.net/2015/11/29/a-whirlwind-tour-of-gos-runtime-environment-variables#GOTRACEBACK][A whirlwind tour of Go’s runtime environment variables]]
* Mensagens de panic são mais curtas por padrão (example)
.play go1.6/crashy.go /START OMIT/,/END OMIT/
* Resolução de timers no Windows
No Windows, programas em Go 1.5 e versões anteriores forçavam a resolução de timers gloabl para 1ms na inicialização chamando `timeBeginPeriod(1)`.
Isso gastava muita bateria.
O Go 1.6 não precisa mais disso para uma boa performance do scheduler e mudar esse valor global causava problemas em alguns sistemas, então a chamada foi removida.
* Support a vendoring
O Go 1.5 introduziu suporte experimental a vendoring, habilitado com o uso da variável de ambiente `GO15VENDOREXPERIMENT` com o valor 1.
O Go 1.6 mantém o suporte, que não é mais considerado experimental, e habilita ele por padrão.
Ele pode ser desativado explicitamente usando `GO15VENDOREXPERIMENT=0`. O Go 1.7 vai remover o suporte a essa variável de ambiente.
O problema mais provável causado pelo vendoring habilitado por padrão acontece em bases de código que já tenham um diretório chamado `vendor` criado anteriormente com outros objetivos. Nesse caso, a solução mais simples é renomear esse diretório para qualquer coisa diferente de vendor.
* Como funciona?
/home/user/gocode/
src/
server-one/
main.go (import "github.com/gorilla/mux")
server-two/
main.go (import "github.com/gorilla/mux")
vendor/
github.com/
gorilla/
mux/
...
`server-one` usa o pacote `mux` em
$GOPATH/src/github.com/gorilla/mux
`server-two` usa o pacote `mux` em
$GOPATH/src/server-two/vendor/github.com/gorilla/mux
* Armadilhas do vendoring
O código na pasta vendor é acessado quando se usa ./...
Se você está acostumado a fazer
% cd $GOPATH/github.com/you/repo
% go test ./...
O operador `...` _também_retorna_ o conteúdo da pasta `vendor/`.
Isso se resolve filtrando os pacotes vendorizados
go test $(go list ./... | grep -v /vendor/)
Mais detalhes (em inglês):
- [[https://github.com/golang/go/issues/11659#issuecomment-171678025][Issue 11659]]
* Performance
Na média os programas da suíte de benchmarks do Go 1 rodam alguns porcento mais rápido no Go 1.6 do que rodavam no Go 1.5.
As pauas do garbage collector são ainda menores do que eram no Go 1.5, embora o efeito provavelmente só seja visível para programas usando muita memória.
Para os pacotes compress/bzip2, compress/gzip, crypto/aes, crypto/elliptic, crypto/ecdsa, e sort foram feitas otimizações com impacto bem acima dos 10%.
* Ordenação
No pacote sort, a implementação do `Sort` foi reescrita e faz cerca de 10% menos chamadas para os métodos `Less` e `Swap` da Interface.
O novo algoritmo acaba escolhendo uma ordenação diferente para valores que são considerados iguais (pares quem que `Less(i,`j)` e `Less(j,`i)` são false).
A definição do `Sort` não dá nenhuma garantia sobre a ordem final de _valores_iguais_, o novo comportamento pode quebrar programas que esperam uma ordenação específica para eles.
Esses programas terão que refinar a sua implementação do Less para reportar essa ordem desejada ou passar a usar o `sort.Stable`, que preserva a ordem do input no caso de valores iguais.
* Exemplo do sort.Sort
.play go1.6/sort.go /START OMIT/,/END OMIT/
_Mude_de_sort.Sort_para_sort.Stable_e_observe_o_efeito_nos_Bills_
* Remoção de espaço em branco com text/template
Agora é possível dar trim em espaços em volta de ações de template, o que pode deixar templates mais legíveis.
Um sinal de menos no começo de uma ação significa trim spaces antes da ação e um sinal de menos no final da ação significa trim spaces depois da ação.
.play go1.6/template.go
* Comando go vet
O comando go ver agora diagnostica passagem de funções ou métodos como valor para o Printf, como por exemplo passar f em vez de f().
.code go1.6/vet.go
% go tool vet -all go1.6/vet.go
go1.6/vet.go:6: arg r.UserAgent in printf call is a function value, not a function call
* Gccgo
Os calendários para o release do GCC e do Go não coincidem.
O GCC versão 5 contém a versão Go 1.4 do gccgo.
No próximo release, GCC 6, passará a conter a versão Go 1.5 do gccgo.
Por causa dos calendários dos releases, é provável que o Go 1.5 não seja incluído em um release do GCC até o GCC 7.
* Pequenas mudanças na standard library
Assim como as grandes melhorias já mencionadas, a standard library recebeu várias correções de bugs e pequenas melhorias.
Essa seção mostra algumas dessas mudanças.
Leia mais (em inglês):
- [[https://tip.golang.org/doc/go1.6#minor_library_changes][Go 1.6 release notes]]
* archive/tar
Joe Tsai trabalhou muito em cima do pacote archive/tar, corrigindo vários bugs em casos raros desse formato de arquivo.
Uma mudança visível é que o método Read do tipo Reader agora apresenta o conteúdo de tipos de arquivo especiais como vazio em vez de retornar `io.EOF` imediatamente.
* bufio
O tipo Scanner do pacote bufio agora tem um método Buffer que especifica um buffer inicial e tamanho máximo de buffer a serem usados durante o escaneamento.
Isso permite, quando necessário, que se escaneie tokens maiores do que o MaxScanTokenSize.
Também para o Scanner, o pacote agora define o erro ErrFinalToken, para ser usado em funções de split para abortar o processamento ou para retornar um token vazio no final.
* bufio (example)
.play go1.6/scan.go /START OMIT/,/END OMIT/
* Mudanças nos pacotes net/*
O pacote net/http teve algumas pequenas alterações além do suporte a HTTP/2.
- O FileServer agora ordena os arquivos por nome.
- O Client agora que permite que se use o header Expect: 100-continue (ver Transport.ExpectContinueTimeout).
- Existem agora quatro novos tipos de códigos de erro do RFC 6585: StatusPreconditionRequired (428), StatusTooManyRequests (429), StatusRequestHeaderFieldsTooLarge (431), and StatusNetworkAuthenticationRequired (511).
- A implementação e documentação do CloseNotifier foi fortemente modificada. A interface Hijacker agora funciona corretamente em conexões que tenham sido usadas antes com o CloseNotifier. A documentação agora descreve quando se espera que o CloseNotifier funcione.
* Mudanças nos pacotes net/* (cont.)
- O ResponseRecorder do pacote net/http/httptest agora inicializa o header Content-Type default usando os mesmos algoritmos de sniffar conteúdo do http.Server.
- O Parse do pacote net/url agora é mais estrito e adere melhor à especificação de parsing de hostnames. Por exemplo, espaços em hostnames não são mais aceitos.
- O tipo net/url.Error agora implementa o `net.Error` para permitir uso de `Temporary` e `Timeout`.
* GODEBUG=netdns
O pacote `net` implementa dois resolvedores de DNS
- um baseado em cgo que usa a resolução de dns da plataforma
- outro em Go puro
O primeiro é o padrão quando não se compila multiplataforma, o segundo é habilitado exclusivamente durante cross compiling.
Para builds "nativas", você pode controlar essa configuração com
export GODEBUG=netdns=go # forçar Go puro
export GODEBUG=netdns=cgo # forçar cgo
Leia mais (em inglês):
- [[https://golang.org/pkg/net/#hdr-Name_Resolution][Seção name resolution]] da documentação do pacote `net`.
* os
Os métodos `IsExist`, `IsNotExist` e `IsPermission` do pacote os agora retornam valores corretos ao analisar um `SyscallError`.
Em sistemas baseados em Unix, quando uma escrita para o `os.Stdout` ou `os.Stderr` falha por causa de um broken pipe, o programa lança um sinal `SIGPIPE`. Por padrão, isso faz o programa terminar; isso pode ser modificado usando `os/signal.Notify` com o `syscall.SIGPIPE`.
No Go 1.6 uma escrita para um broken pipe em um file descriptor que não seja o 1 ou 2 simplesmente retorna `syscall.EPIPE` (possivelmente aninhado em um `os.PathError` e/ou `os.SyscallError`.
O comportamento antigo de lançar um sinal SIGPIPE que não tinha como ser tratado depois de 10 escritas consecutivas para um broken pipe não acontece mais.
* regexp
No pacote regexp, o tipo Regexp sempre foi seguro para uso concorrent por várias goroutines.
Alguns servidores de alta concorrência usando o mesmo Regexp para várias goroutines já tiveram problemas de performance por contenção causada pelo mutex usado internamente para proteger um cache de buscas de expressões regulares.
Para ajudar esses servidores, o Regexp agora tem um método Copy, que faz uma cópia do Regexp compartilhando quase toda a estrutura do original mas com o seu próprio cache interno.
re1 := regexp.MustCompile(`^(?P<root>github\.com/([A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`)
re2 := re1.Copy()
Uma cópia gasta mais memória, o Copy só deve ser usado se há certeza que contenção causada pelo Regexp foi observada.
* time
A função Parse do pacote time sempre rejeitou qualquer dia do mês acima de 31, como 32 de Janeiro.
No Go 1.6, o Parse agora também rejeita 29 de Fevereiro em anos que não são bissextos, 30 de Fevereiro, 31 de Fevereiro, 31 de Abril, 31 de Junho, 31 de Setembro e 31 de Novembro.
.play go1.6/parse.go
* Go 1.6
.link https://golang.org/dl/
.image go1.6/GoLaunch_Front.png 440 _
_Créditos_: [[http://www.meetup.com/golangsf/events/226090306/][iron.io / GoSF Meetup]].