-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpresentacion.slide
617 lines (321 loc) · 18.8 KB
/
presentacion.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
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
Introducción a Go
75.24 - Teoría de Lenguajes
##########################################################
* Integrantes :
- Alexis Daciuk
- Nicolás Ledesma
- Federico Longhi
- Lucas Perea
.image images/gopher-1.png
##########################################################
* Origen I
- Anunciado en noviembre del 2009
- Nace como un experimento de Robert Griesemer y Rob Pike, ingenieros de Google, junto a Ken Thompson (creador del Lenguaje de programación B, predecesor de C)
- Su objetivo era diseñar un lenguaje que resuelva problemas comunes de otros lenguajes de programación, sin perder sus características útiles.
.image images/gopher-6.png
##########################################################
* Origen II
Propusieron un lenguaje con las siguientes características:
- Estáticamente tipado.
- Fácil de leer, sin mucha repetición ni demasiadas palabras reservadas.
- Con una curva de aprendizaje acotada, de forma de optimizar la productividad.
- Sin necesidad de un IDE.
- Versátil, con librerías que permitan diversos usos, y un manejo de concurrencia simple y eficiente.
En entrevistas posteriores, los 3 creadores comentaron su desagrado de C++, por su innecesaria complejidad.
##########################################################
* Características principales
- *Paradigma*: Estructurado y procedural _(como_ _C)_
- *Modelo*: Imperativo
- *Construcción* *y* *ejecución*: Compilado
$ go build main.go # Compila y genera un ejecutable a partir de los archivos .go incluidos
$ go run main.go # Compila y ejecuta inmediatamente el código incluido
- *Tipado:* fuerte y estático. Además, _inferido_
materia := "Teoría del lenguaje" // Esto es una variable de tipo string
listaMaterias := []string{"Algo I", "Algo II"} // Esto es una variable de tipo slice de strings
##########################################################
* Otras características interesantes:
- Soporta concurrencia de una forma muy simple (más adelante ahondaremos)
- Implementa interfaces para definir comportamientos (más adelante ahondaremos)
- Maneja errores, no excepciones (no soporta bloques _try_ & _catch_)
file, err := os.Open(filename)
if err != nil {
fmt.Println("There was an error:", err)
} else {
io.Copy(os.Stdout, file)
}
##########################################################
* Tipos Básicos
- bool
- string
- int, int8, int16, int32, int64
- uint, uint8, uint16, uint32, uint64, uintptr
- byte -_alias_for_uint8_-
- rune -_alias_for_int32_-
- float32, float64
- complex64, complex128
Los tipos int, uint y uintptr tienen un tamaño de 32 bits en sistemas de 32 bits y de 64 bits en sistemas de 64 bits.
Uintptr is an integer type that is large enough to hold the bit pattern of any pointer.
##########################################################
* Inferencia de Tipos
Dijimos que en go teníamos tipado estático, sin embargo puedo definir variables sin definir su tipo!
.code code/type_inference.go /START OMIT/,/END OMIT/
Esto es porque en go el tipo de la variable se infiere del valor.
.play code/type_inference2.go /START OMIT/,/END OMIT/
Acá podemos ver que float depende del sistema
##########################################################
* Features importantes
.image images/gopher-3.gif
########################################################## (Alex)
* Funciones Anónimas (lambdas)
- La definición de una función anónima es muy parecido a la forma de hacerlo en *Oz*
.play code/lambdas.go /START OMIT/,/END OMIT/
- También se puede definir funciones recursivas sin mucho problema.
.play code/recursive.go /START OMIT/,/END OMIT/
##########################################################
* Interfaces
- Las interfaces en Go son herramientas para definir comportamientos similares en entidades o estructuras diferentes.
- La implementación de una interfaz es implícita. Basta con que una estructura implemente exactamente las funciones descriptas por la interfaz.
- Mientras int, float, string, etc. son tipos concretos (al declararlos se infiere automáticamente su tipo), el tipo interfaz se infiere una vez que se definen las funciones que implementa la interfaz.
- Las interfaces *no* son tipos genéricos. Simplemente ayudan a encapsular comportamiento dentro de un contrato.
- El comportamiento de *muchas* librerías de Go está encerrado en interfaces.
##########################################################
* Ejemplo
.play code/interfaces.go /START OMIT/,/END OMIT/
##########################################################
* Usos en packages
En el package `io` se define la siguiente interfaz:
type ReadWriter interface {
Reader
Writer
}
Que a su vez incluye las interfaces `Reader` y `Writer`.
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
Varios paquetes utilizan interfaces como `Reader`, por ejemplo, el `body` de un request del paquete `net/http` lo implementa.
.link https://golang.org/pkg/io/
##########################################################
* Goroutines, la implementación de la concurrencia en Go
- Son *green*threads*, más adelante vamos a ahondar en esto
- La sintaxis es *sumamente*simple*. Se trabaja con concurrencia abstrayéndose completamente del manejo de threads.
- El complemento de las goroutines son los *channels*, que sirven justamente como canal de comunicación entre los distintos threads.
.image images/gopher-5.png
##########################################################
* Ejemplo de juguete (I)
Supongamos que quiero resolver lo siguiente en forma concurrente.
.play code/routines-1.go /START OMIT/,/END OMIT/
##########################################################
* Ejemplo de juguete (II)
Basta con poner "`go`" delante del llamado a las funciones para que se ejecuten en goroutines
.play code/routines-2.go /START OMIT/,/END OMIT/
##########################################################
* ¿Qué pasó?
El *hilo*principal*terminó* de ejecutarse *antes*de*que*pudieran*terminar*las*goroutines*.
*¿Cómo*lo*resolvemos?*
Tenemos que acumular los datos obtenidos en un store e imprimirlos en la medida que se obtengan.
Para esto utilizamos *channels*. Los channels son tipados, esto significa que cada uno maneja *un*único*tipo*de*dato*.
.image images/gopher-4.png
##########################################################
* Ejemplo de juguete (III)
.play code/routines-3.go /START OMIT/,/END OMIT/
########################################################## (Alex)
* La concurrencia en Go (I)
*Funcionamiento*
Las *goroutines* corren en Green Threads, admnistrados por el runtime de Go.
El runtime tiene un thread pool configurable donde las goroutines pueden ser ejecutadas.
*Go* *scheduler*
Solamente se avanza con las goroutines no bloqueadas a nivel SO.
El scheduling es cooperativo: cada proceso voluntariamente cede el control de la CPU al runtime si encuentra en espera. Si una goroutine se bloquea, deja de ejecutarse y pasa a ejecutarse otra.
Por esta razón, las *goroutines* no bloquean el thread en el cual se ejecutan aunque esten bloqueadas por _web_ _requests_, _sleeps_, _operaciones_ _sobre_ _channels_, o _primitivas_ _del_ _paquete_ _sync_.
########################################################## (Alex)
* La concurrencia en Go (II)
*Consumo* *de* *memoria*
La creación de una *goroutine* necesita nada más 2 kB de espacio en el stack, de ser necesario, crece asignándose espacio en el heap.
*Costo* *de* *creación* *y* *destrucción*
Como la creación y la destrucción son manejados por el runtime de Go, así que los costos son bastante bajos.
*Costo* *de* *cambio* *de* *contexto*
Cuando se cambia de contexto, solamente se necesita guardar 3 registros, *Program* *Counter*, *Stack* *Pointer* y *DX*, por ende, el costo de cambio de contexto es muy bajo.
La cantidad de goroutines no afecta el costo temporal de cambio de contexto.
##########################################################
* Cosas curiosas
.image images/gopher-2.png
##########################################################
* Defer
El defer statement hace que la función contenida se ejecute cuando el entorno de la función que lo contiene finaliza.
.play code/defer.go /START OMIT/,/END OMIT/
Vemos como los argumentos de la función son evaluados inmediatamente, pero la función sum es llamada cuando la función main finaliza.
##########################################################
* Defer Panic Recover
.play code/defer_panic_recover.go /START OMIT/,/END OMIT/
##########################################################
* Arrays vs Slices (I)
var a [10]int
- `a` es un array de 10 enteros.
- El tamaño del array es parte de su tipo, entonces (_recordemos_tipado_estatico_), no se pueden re-dimensionar.
- Sin embargo Go nos provee slices, cuyo tamaño es re-dimensionable dinámicamente.
a[1:5]
- Esto es un slice con los elementos del 1 al 5 de `a`
- Los slices y arrays tienen tamaño(len) y capacidad(cap)
##########################################################
* Arrays vs Slices (II)
- Un slice es como una referencia a un array.
- Un cambio en el slice va a afectar al array al cual referencia el slice.
- Por lo tanto el cambio se va a ver reflejado en todos los slices que hacen referencia al mismo array.
.play -edit code/slices.go /START OMIT/,/END OMIT/
##########################################################
* Arrays vs Slices (III) - Construcción
Esto construye un array y después crea un slice que referencia a ese array:
[]string{"Juan", "Pedro", "Maria"}
También podemos construir slices con la función make:
.play -edit code/slices_construccion.go /START OMIT/,/END OMIT/
##########################################################
* Argument functions vs. Receiver functions
Funciones clásicas con argumentos
- Definición
func ladrar(p perro) { // función con argumento
- Invocación
ladrar(p)
Funciones con un parámetro _receiver_
- Definición
func (p perro) ladrar() { // función con "receiver"
- Invocación
p.ladrar() // Method, is that you?
##########################################################
* Comportamiento de ambas
- Ambas formas de definir la función tienen el mismo comportamiento
- Algunos llaman "métodos" a las receiver functions, como si GoLang fuera un lenguaje orientado a objetos.
*¿Cuándo*usar*cada*una?*
- Usar el criterio de la programación orientada a objetos sería un enfoque erróneo. Go no es un lenguaje OOP. _¿Sólo_los_perros_ladran?_¿Puedo_yo_ladrar_como_un_perro?_.
- Si estamos usando interfaces, es más intuitivo usar receivers para el tipo que está implementando la interfaz.
##########################################################
* Las funciones de Go y sus argumentos
Supongamos que queremos actualizar una estructura aplicándole una función:
.play code/impossibru.go /START OMIT/,/END OMIT/
##########################################################
* ¿Qué hicimos mal?
.image images/impossibru.png
##########################################################
* ¿Por qué?
- Todas las *funciones* en Go reciben sus argumentos como *copia*del*valor*. Esta regla *también*aplica*a*las*receiver*functions*.
- En este caso modificamos la copia de Jimmy, pero no a Jimmy.
*¿Cómo*hacemos*lo*que*queríamos*hacer?*
Si una función modifica un valor y queremos que ese cambio persista fuera de la función hay dos opciones:
1. Que la función retorne el valor modificado
2. Que la función reciba un argumento de tipo puntero en lugar de recibir el tipo del valor.
Go permite usar punteros de forma bastante simple.
##########################################################
* Receiver functions con punteros
No hace falta crear un puntero a 'musician'. Go permite saltearse ese paso, sólo hace falta definir que la función reciba un puntero.
.play -edit code/impossibru.go /START OMIT/,/END OMIT/
##########################################################
* Comportamiento en los tipos básicos
Ok, entonces deberíamos esperar este comportamiento en los tipos básicos, ¿no?
.play code/impossibru2.go /START OMIT/,/END OMIT/
##########################################################
* ¿Por qué?
.image images/what.jpg
##########################################################
* Tipos por valor y por referencia
*Tipos*por*valor*
- strings, ints, floats, bools, structs
Con estos tipos sería necesario agregar punteros en casos como el anterior.
*Tipos*por*referencia*
- slices, maps, functions, channels, pointers
Los tipos por referencia se valen de estructuras que referencian a donde están realmente los valores, para se pueda operar con ellos.
No sólo no es necesario operar sobre punteros dentro de las funciones, operar con punteros a estas estructuras ocasionaría errores.
##########################################################
* Cuando usar Go
Go se puede utilizar en casos en los que los siguientes aspectos sean prioridad
- Networking: servidores TCP/HTTP
- Manejo de concurrencia
- Optimización de recursos (- servidores)
- Facilidad de deployment de una solución
- Equipos grandes: Agilidad y calidad en el código
##########################################################
* Cuando no usar Go
Go no es recomendable si uno busca:
- Solución orientada a objetos de la manera tradicional
- Herramientas que resuelvan casi cualquier problema
- Desarrollo de apps desktop/mobile
########################################################## (Alex)
* Estadísticas
Top 5 frameworks (según las estadísticas de golanglibs.com)
beego : Framework open source para APIs REST, webapps y backends.
gin : Framework web con una API del estilo martini (otro framework web).
mattermost-server : Alternativa a Slack escrita en Golang + React.
martini : Framework web para Golang.
revel : Web framework full-stack.
Uso (según OpenHub.net)
Proyectos : 2 673.
Líneas : 142 602 614 de las cuales, 108 513 131 son de código y 20 146 041 son comentarios.
Personas contribuyendo : 18 915.
Commits : 843 727.
A Septiembre de 2017, según el ranking TIOBE de popularidad, Go esta en el puesto 17, ascendiendo 2 puestos con respecto al mismo mes del año pasado, en 2016 fue en lenguaje que más popularidad ganó.
########################################################## (Alex)
* Comparación con otras herramientas populares
Go vs NodeJS
- *Madurez:* En la búsqueda de mejoras, node realiza periódicamente cambios en su API que llevan a un constante cambio de herramientas o codebases.
- *Rendimiento:* Go es compilado mientras node, ejecuta javascript (interpretado). Esto hace que Go sea mucho más performante que node.
- *Concurrencia:* Go usa `goroutines` para concurrencia, mientras que Node maneja operaciones bloqueantes asincrónicamente, basado en su event-loop.
- *Ecosistema:* La comunidad de node es muy grande y abarca más campos de aplicación, la de Go está en crecimiento continuo.
########################################################## (Alex)
* Comparación de rendimiento con otros lenguajes
.image images/go_vs_all-1.png
########################################################## (Alex)
* Caso de estudio : Docker
Docker es un software multiplataforma que permite crear, desplegar y correr aplicaciones en módulos llamados containers. Un container incluye absolutamente todo lo que necesita una aplicación para ejecutarse.
.image images/docker-gopher.png
De esta forma es posible virtualizar un ambiente de trabajo homologado con sólo una única configuración de docker que define el sistema operativo en el que corre la aplicación, el server, las librerías utilizadas, etc.
Docker es mucho más económico para los recursos del equipo que correr una máquina virtual, con o sin interfaz gráfica.
########################################################## (Alex)
* ¿Por qué usan Go en Docker? I
- *Compilación* *estática* *:* *go* *build* compila todo a un solo binario.
No más "tenés que instalar n dependencias" con n -> ∞, a no ser que uses *cgo*, que te permite usar cualquier librería de C. O si no contás a *libc* como una dependencia (pero, quien no tiene libc?).
- *Es* *neutral* *:* No es C++, no es Python, no es Ruby, no es Java.
- *Tiene* *lo* *que* *necesitaban* *:* Buenas primitivas de asincronismo, Interfaces de bajo nivel, extensa libreria standard
- *Duck* *typing* *:* se conoce como duck typing el estilo de tipificación dinámica de datos en que el conjunto actual de métodos y propiedades determina la validez semántica, en vez de que lo hagan la herencia de una clase en particular o la implementación de una interfaz específica.
########################################################## (Alex)
* ¿Por qué usan Go en Docker? II
- *Buen* *conjunto* *de* *herramientas*
*go* *doc* *:* para ver la documentación de un paquete.
*go* *get* *:* para instalar paquetes (github o repositorios propios, basados en git).
*go* *fmt* *:* formateador de código (no más tabs vs espacios).
*go* *test* *:* ejecuta todos los Test* en *_test.go.
*go* *run* *:* ejecuta el código en el archivo, sin crear un binario (scripting).
- *Facilidad* *para* *compilar* *multiplataforma*.
########################################################## (Alex)
* ¿Por qué usan Go en Docker? III
*Desventajas*
*Los* *maps* *no* *son* *thread-safe*
- De cualquier forma, son _muy_ rápidos.
- Hay que restringir el acceso mediante Mutex o usar channels de channels.
*Limitaciones* *de* *go* *get*
- No puede descargar versiones especificas, siempre descarga la última.
- Docker tuvo que descargar localmente el código de todas las dependencias: *vendoring* (no es necesariamente malo, pero no es realmente cómodo ni elegante).
- Descargar de repositorios privados no es trivial.
##########################################################
* Otros proyectos en Go
.image images/go_ranking.png
.link http://herman.asia/open-source-go-projects-to-learn-from
##########################################################
* ¿Dónde puedo seguir aprendiendo?
.link https://play.golang.org/
.link https://tour.golang.org/
.link https://github.com/avelino/awesome-go
.link https://go.libhunt.com/
.link https://github.com/golang/go/wiki/Projects
- Los proyectos que vimos antes!
##########################################################
* Referencias
.link https://golang.org/ golang.org
.link https://es.slideshare.net/jpetazzo/docker-and-go-why-did-we-decide-to-write-docker-in-go
.link https://benchmarksgame.alioth.debian.org/
.link http://herman.asia/open-source-go-projects-to-learn-from
.link https://talks.golang.org/2012/splash.article
.link https://talks.golang.org/2017/state-of-go-may.slide#38
##########################################################
* ¿Preguntas?
##########################################################