miércoles, 30 de octubre de 2019

Disponible Fedora 31


¡Esta aquí! Esta disponible Fedora 31. Gracias al arduo trabajo de miles de miembros y colaboradores de la comunidad de Fedora, celebramos otro lanzamiento a tiempo. ¡Esto se está convirtiendo en un hábito!

Entre las mejoras, Firefox se ejecutará de forma nativa en la sesión de GNOME Wayland, por lo que no se apoyará más en XWayland, la capa de compatibilidad para ejecutar aplicaciones Xorg en Wayland. La inclusión de módulos centrados en la seguridad en la compilación para EFI de Grub 2 y la inclusión de Mono 5.20 son otros aspectos a destacar de este lanzamiento.

Y en la pagina del release aprovecharon para publicitar Fedora Toolbox, Fedora Toolbox es una herramienta simple para iniciar y administrar contenedores de espacios de trabajo personales, para que pueda desarrollar o experimentar en una experiencia aislada. Es tan simple como ejecutar "toolbox enter" desde la línea de comandos.


Dejo link:
https://getfedora.org

Reporting, Predictive Analytics, and Everything In Between: A Guide to Selecting the Right Analytics for You

Debe ser uno de los títulos más largos que he escrito.

Me llego un mail de la empresa que tiene soporte comercial de jasperreports promocionando un libro que regala :

TIBCO Software Inc.View in browser
New O'Reilly Ebook:
Reporting, Predictive Analytics, and Everything In Between
Hi Emanuel,
Any organization considering investing in a data analytics initiative today has a lot of options to choose from, including visual, predictive, or even embedded analytics.
But which type of analytics is right for you? This ebook explains the different types of analytics and helps you determine the best course of action based on your business needs. 
oreilly-ebook-asset-img.png
Read this ebook to learn:
  1. How analytics types differ and the pros and cons of each
  2. How to identify the right analytics for your use case
  3. Key considerations to evaluate before getting started
 
Cheers!
The TIBCO Team
TIBCO Software Inc. 
3303 Hillview Ave, Palo Alto, California 94304 
This marketing email was sent to emanuelpeg@yahoo.com.ar 
Copyright and Privacy Policy   |   Manage Preferences or Unsubscribe 
Get the latest news at tibco.com.
Facebook    LinkedIn    Twitter    Youtube

Aprovechar!!

Dejo link:
https://www.tibco.com/resources/ebook-download/reporting-to-predictive-analytics?utm_source=emailblast&utm_medium=email&utm_campaign=jaspersoft_globl_js-oreilly-ebook-edm-10-19&mkt_tok=eyJpIjoiWXpNM1lUSmtPV1F6WTJVMiIsInQiOiJXRVwvSEJSMFhMSlFUOWNDZ0d6VnpuOUh4N2g0TlhuUFBpSU15Q1wva2tLUEQ1MEdLUFlLQVdcL25la0ZISEw5czhSR2NrUVdRa1ZJM3RxRFhZYWZSWUpLT1wvTkZnOXE1K29CZTRZT0h3NjJuUzUxZ2tKYit0bGVrMDNvZnRcL2RjdFhIIn0%3D

viernes, 25 de octubre de 2019

Libros de Java geek

Download IT Guides!

 
JavaServer Faces (JSF) is a Java specification for building component-based user interfaces for web applications. JSF 2 uses Facelets as its default templating system. Other view...
 
 
Scala is a general-purpose programming language. It has full support for functional programming and a very strong static type system. Designed to be concise, many of Scala's design...
 
 
Text provides support for most advanced PDF features such as PKI-based signatures, 40-bit and 128-bit encryption, color correction, Tagged PDF, PDF forms (AcroForms), PDF/X, color...
 
 
Spring Integration extends the Spring programming model to support the well-known Enterprise Integration Patterns. Enables lightweight messaging within Spring-based applications and...
 

martes, 22 de octubre de 2019

Procedimientos almacenados y funciones en MariaDB


Si ya usamos bases de datos como Oracle, Interbase / Firebird, PostgreSQL, seguro escuchamos hablar de procedimientos almacenados. Y en MariaDB esto no es una novedad.

Ahora bien, ¿qué son en realidad los procedimientos almacenados? Luego de sumergirnos en este tema veremos que el nombre es plenamente identificatorio y casi explica lo que es un procedimiento almacenado.

Los procedimientos almacenados son un conjunto de instrucciones SQL más una serie de estructuras de control que nos permiten dotar de cierta lógica al procedimiento. Estos procedimientos están guardados en el servidor y pueden ser accedidos a través de llamadas, como veremos más adelante.

Para crear un procedimiento, MariaDB nos ofrece la directiva CREATE PROCEDURE. Al crearlo éste es ligado o relacionado con la base de datos que se está usando, tal como cuando creamos una tabla, por ejemplo.

Para llamar a un procedimiento lo hacemos mediante la instrucción CALL. Desde un procedimiento podemos invocar a su vez a otros procedimientos o funciones.

Un procedimiento almacenado, al igual cualquiera de los procedimientos que podamos programar en nuestras aplicaciones utilizando cualquier lenguaje, tiene:
  • Un nombre.
  • Puede tener una lista de parámetros.
  • Tiene un contenido (sección también llamada definición del procedimiento: aquí se especifica qué es lo que va a hacer y cómo). Ese contenido puede estar compuesto por instrucciones sql, estructuras de control, declaración de variables locales, control de errores, etcétera.

MariaDB sigue la sintaxis SQL:2003 para procedimientos almacenados, que también usa IBM DB2.

En resumen, la sintaxis de un procedimiento almacenado es la siguiente:

  CREATE PROCEDURE nombre (parámetro)
      [características] definición

o para ser más técnicos:

CREATE
    [OR REPLACE]
    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
    PROCEDURE sp_name ([proc_parameter[,...]])
    [characteristic ...] routine_body

proc_parameter:
    [ IN | OUT | INOUT ] param_name type

type:
    Any valid MariaDB data type

characteristic:
    LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'

routine_body:
    Valid SQL procedure statement

Puede haber más de un parámetro (se separan con comas) o puede no haber ninguno (en este caso deben seguir presentes los paréntesis, aunque no haya nada dentro).

Los parámetros tienen la siguiente estructura: modo nombre tipo

Donde:
  • modo: es opcional y puede ser IN (el valor por defecto, son los parámetros que el procedimiento recibirá), OUT (son los parámetros que el procedimiento podrá modificar) INOUT (mezcla de los dos anteriores).
  • nombre: es el nombre del parámetro.
  • tipo: es cualquier tipo de dato de los provistos por MariaDB.
  • Dentro de características es posible incluir comentarios o definir si el procedimiento obtendrá los mismos resultados ante entradas iguales, entre otras cosas.
  • definición: es el cuerpo del procedimiento y está compuesto por el procedimiento en sí: aquí se define qué hace, cómo lo hace y bajo qué circunstancias lo hace.
Así como existen los procedimientos, también existen las funciones. Para crear una función, MariaDB nos ofrece la directiva CREATE FUNCTION.

La diferencia entre una función y un procedimiento es que la función devuelve valores. Estos valores pueden ser utilizados como argumentos para instrucciones SQL, tal como lo hacemos normalmente con otras funciones como son, por ejemplo, MAX() o COUNT().

Utilizar la cláusula RETURNS es obligatorio al momento de definir una función y sirve para especificar el tipo de dato que será devuelto (sólo el tipo de dato, no el dato).

Su sintaxis es:

CREATE FUNCTION nombre (parámetro)
RETURNS tipo
[características] definición

o para ser más técnicos:

CREATE [OR REPLACE]
    [DEFINER = {user | CURRENT_USER | role | CURRENT_ROLE }]
    [AGGREGATE] FUNCTION [IF NOT EXISTS] func_name ([func_parameter[,...]])
    RETURNS type
    [characteristic ...]
    RETURN func_body


func_parameter:
    param_name type


type:
    Any valid MariaDB data type


characteristic:
    LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'


func_body:
    Valid SQL procedure statement

Puede haber más de un parámetro (se separan con comas) o puede no haber ninguno (en este caso deben seguir presentes los paréntesis, aunque no haya nada dentro). Los parámetros tienen la siguiente estructura: nombre tipo

Donde:
  • nombre: es el nombre del parámetro.
  • tipo: es cualquier tipo de dato de los provistos por MariaDB.
  • Dentro de características es posible incluir comentarios o definir si la función devolverá los mismos resultados ante entradas iguales, entre otras cosas.
  • definición: es el cuerpo del procedimiento y está compuesto por el procedimiento en sí: aquí se define qué hace, cómo lo hace y cuándo lo hace.

Para llamar a una función lo hacemos simplemente invocando su nombre, como se hace en muchos lenguajes de programación.

Desde una función podemos invocar a su vez a otras funciones o procedimientos.

delimiter //
CREATE PROCEDURE procedimiento (IN cod INT)
    BEGIN
        SELECT * FROM tabla WHERE cod_t = cod;
    END
//
Query OK, 0 rows affected (0.00 sec)
delimiter ;
CALL procedimento(4);


En el código anterior lo primero que hacemos es fijar un delimitador. Al utilizar la línea de comandos de MariaDB vimos que el delimitador por defecto es el punto y coma (;): en los procedimientos almacenados podemos definirlo nosotros.

Lo interesante de esto es que podemos escribir el delimitador anterior; sin que el procedimiento termine. Más adelante, en este mismo código volveremos al delimitador clásico. Luego creamos el procedimiento con la sintaxis vista anteriormente y ubicamos el contenido entre las palabras reservadas BEGIN y END.

El procedimiento recibe un parámetro para luego trabajar con él, por eso ese parámetro es de tipo IN. Definimos el parámetro como OUT cuando en él se va aguardar la salida del procedimiento. Si el parámetro hubiera sido de entrada y salida a la vez, sería de tipo denominado INOUT.

El procedimiento termina y es llamado luego mediante la siguiente instrucción:

  mysql> CALL procedimento(4);


Otro ejemplo:

CREATE PROCEDURE procedimiento2 (IN a INTEGER)
BEGIN
DECLARE variable CHAR(20);
IF a > 10 THEN
SET variable = ‘mayor a 10’;
ELSE
SET variable = ‘menor o igual a 10’;
END IF;
INSERT INTO tabla VALUES (variable);
END

  • El procedimiento recibe un parámetro llamado a que es de tipo entero.
  • Se declara una variable para uso interno que se llama variable y es de tipo char.
  • Se implementa una estructura de control y si a es mayor a 10 se asigna a variable un valor. Si no lo es se le asigna otro.
  • Se utiliza el valor final de variable en una instrucción SQL.


Recordemos que para implementar el ultimo ejemplo se deberán usar nuevos delimitadores, como se vio anteriormente.

Observemos ahora un ejemplo de funciones:

delimiter //
CREATE FUNCTION cuadrado (s SMALLINT) RETURNS SMALLINT
   RETURN s*s;
//
Query OK, 0 rows affected (0.00 sec)
delimiter ;
SELECT cuadrado(2);


En definitiva hemos dado un recorrido por el mundo de la programación de procedimientos almacenados en MariaDB.

Dejo Links:
https://mariadb.com/kb/en/library/create-procedure/
https://mariadb.com/kb/en/library/stored-procedures/


Aprender Go en codecademy

En 2009, Google se propuso crear un lenguaje de programación que fuera rápido, productivo y divertido de usar. Y lo más importante, no querían hacer compensaciones entre legibilidad, eficiencia o rendimiento.

10 años después, Go esta estable y lo usan compañías como Netflix, Uber, Codecademy y, por supuesto, Google.

Hoy, nos complace anunciar que nos hemos asociado con Google para crear el mejor curso Go para principiantes más amigable en cualquier lugar. Aprenderá la sintaxis, recibirá preguntas sobre cómo declarar funciones y creará proyectos.

Los primeros cuatro módulos de "Learn Go" están en vivo en nuestro catálogo en este momento.

Este es el mail (la traducción) que me llego de los amigos de Codecademy, con el cual nos invitan a hacer un curso gratuito de Go.

Dejo el link: https://www.codecademy.com/learn/learn-go

Dejo el mail :

 
 
Codeacdemy Presents Learn Go in Partnership with Google
Learn Go
 
 
 
 
In 2009, Google set out to create a programming language that was fast, productive, and fun to use. And most importantly, they didn’t want to make any tradeoffs between readability, efficiency, or performance.
 
10 years later, Go is trusted by developers at companies like Netflix, Uber, Codecademy, and, of course, Google.
 
Today, we’re excited to announce that we’ve partnered with Google to build the best, most beginner-friendly Go course anywhere. You’ll learn the syntax, get quizzed on how to declare functions, and build projects like a flight coordinator for an interstellar travel agency.
 
The first four modules of “Learn Go” are live in our catalog right now.
 
Start Now
 

Ya llega Smalltalks 2019!!!

No se pierdan la Smalltalks de este año en la Universidad Nacional de Comahue en Neuquén!


domingo, 20 de octubre de 2019

Channel Buffering en Go


Por defecto, los canales no tienen búfer, lo que significa que solo aceptarán envíos si hay una recepción correspondiente es decir una lista para recibir los valores enviados. Los canales almacenados temporalmente aceptan un número limitado de valores sin un receptor correspondiente para esos valores.

Veamos un ejemplo:

package main

import "fmt"

func main() {
    messages := make(chan string, 2)
    messages <- "buffered"
    messages <- "channel"

    fmt.Println(<-messages)
    fmt.Println(<-messages)
}

$ go run channel-buffering.go
buffered
channel

Aquí hacemos un canal de cadenas que almacenan en búfer hasta 2 valores.

Debido a que este canal está protegido, podemos enviar estos valores al canal sin una recepción concurrente correspondiente.

Más tarde podemos recibir dos valores más.

Dejo link : https://gobyexample.com/channel-buffering

martes, 15 de octubre de 2019

Proba Rust con Play.rust-lang.org


Rust se esta perfilando como el nuevo C y es excelente lenguaje de bajo nivel. Centrado en el paralelismo y buenas prácticas de programación, esta ganando mucho mercado.

A nivel personal, creo que es mejor que Go, pero eso es para otro post ...

Si quieren probar un poco Rust, tienen play.rust-lang.org un sitio donde podemos escribir codigo, compilarlo y correrlo. Ideal para ir probando código a medida que leemos unos posts o un libro.

Dejo link : https://play.rust-lang.org/

R para Ciencia de Datos



Me encontré esta super traducción de “R para Ciencia de Datos” y la quiero compartir. Como ellos han escrito una introducción, que mejor que citarla aquí :

La traducción de “R para Ciencia de Datos” es un proyecto colaborativo de la comunidad de R de Latinoamérica, que tiene por objetivo hacer R más accesible en la región.

En la traducción del libro participaron las siguientes personas (en orden alfabético): Marcela Alfaro, Mónica Alonso, Fernando Álvarez, Zulemma Bazurto, Yanina Bellini, Juliana Benítez, María Paula Caldas, Elio Campitelli, Florencia D’Andrea, Rocío Espada, Joshua Kunst, Patricia Loto, Pamela Matías, Lina Moreno, Paola Prieto, Riva Quiroga, Lucía Rodríguez, Mauricio “Pachá” Vargas, Daniela Vázquez, Melina Vidoni, Roxana N. Villafañe. ¡Muchas gracias por su trabajo! La administración del repositorio con la traducción ha estado cargo de Mauricio “Pachá” Vargas. La coordinación general y la edición, a cargo de Riva Quiroga.

Agradecemos a todas las personas que han ayudado revisando las traducciones y haciendo sugerencias de mejora. Puedes revisar la documentación del proyecto para ver los créditos de participación. Gracias también a Marcela Alfaro por el tuit que hizo visible la necesidad de la versión en español, y a Laura Ación y Edgar Ruiz, que pusieron en contacto a las personas del equipo.

Este proyecto no solo implica la traducción del texto, sino también de los sets de datos que se utilizan a lo largo de él. Para ello, se creó el paquete datos, que contiene las versiones traducidas de estos. Puedes revisar su documentación acá. El paquete fue desarrollado por Edgar Ruiz, Riva Quiroga, Mauricio “Pachá” Vargas y Mauro Lepore. Para su creación se utilizaron funciones del paquete datalang de Edgar Ruiz y las sabias sugerencias de Hadley Wickham.

Si quieres conocer más sobre los principios que han orientado nuestro trabajo puedes leer [la documentación del proyecto] (https://github.com/cienciadedatos/documentacion-traduccion-r4ds). Para estar al tanto de novedades sobre el paquete {datos} y nuevas iniciativas del equipo, sigue nuestra cuenta en Twitter.

Dejo link: https://es.r4ds.hadley.nz/?fbclid=IwAR0-hYNZ5oIKmt_tgmDGgaSuwEIi6T6kj1gnLHnQr8DwdnNDHoKgFDHcJGg

Y algo muy importante la versión original :se distribuye bajo los términos y condiciones de la licencia Creative Commons Atribución-No Comercial-Sin Derivados 3.0 vigente en los Estados Unidos de América.

lunes, 14 de octubre de 2019

Achieving Real Business Outcomes from AI can help

O’Reilly nos regala un libro de inteligencia artificial y me mandaron este mail que comparto :

O'Reilly Media Logo
 
 
Hi Emanuel,
Achieving Real Business Outcomes from AI cover
Working on an AI initiative can be demanding, whether you’re in the middle of the process or just getting started. Achieving Real Business Outcomes from AI can help. You’ll learn ways to deal with common AI challenges that arise when creating a strategy, dealing with technical issues, or productizing an AI initiative.
If you’re working in AI, this short ebook is just the beginning. You should also check out the AI Resource Center on the O’Reilly learning platform. The resource center will point you to the best videos, books, and more for each stage of AI expertise.
In the meantime, this short ebook is free, our gift to you.
Enjoy!
 
GET THE EBOOK
 
The O’Reilly Team
PS Interested in AI? Check out the O’Reilly AI Conferences in San Jose, New York, and London. Previous attendees have called these events inspirational, excellent, eye-opening, and awesome.

domingo, 13 de octubre de 2019

HackerRank Women in Tech Report


Hackerrank es una pagina que hace encuestas y las publica, estan muy buenas las conclusiones.

Quiero compartir : HackerRank Women in Tech Report 2019.

Dejo link : https://research.hackerrank.com/women-in-tech/2019/

sábado, 12 de octubre de 2019

Funciones con funciones como parámetros en Scala parte 2

Seguimos con scala : https://emanuelpeg.blogspot.com/2019/09/funciones-con-funciones-como-parametros.html

Cuando pasamos un función por parámetro Scala infiere el tipo de la función y lo chequea con el tipo esperado, esto no es más que el chequeo por tipo que realiza cualquier lenguaje de tipado estático.

Veamos un ejemplo:

valueAtOneQuarter((x: Double) => 3 * x)   // 0.75

Dado que la función valeAtOneQuarter espera un (Doble) => Doble por lo tanto Scala puede inferir que es un double y de esta manera podemos escribir :

valueAtOneQuarter((x) => 3 * x)

También podemos quitar los paréntesis :

valueAtOneQuarter(x => 3 * x)

También podemos utilizar azúcar sintáctica, dado que la variable x no representa algo en particular y no hay muchas lógica aquí :

valueAtOneQuarter(3 * _)

De esta manera,  como la función tiene el tipo declarado Scala lo puede inferir pero si nosotros hacemos :

val fun = 3 * _

Vamos a tener un error dado que no se puede inferir el tipo, pero esto se puede soluciónar así :

val fun = 3 * (_: Double)

o

val fun: (Double) => Double = 3 * _

Especificar el tipo de _ es útil para convertir los métodos en funciones. Por ejemplo, (_: String) .length es una función String => Int, y (_: String) .substring (_: Int, _: Int) es una función (String, Int, Int) => String.

jueves, 10 de octubre de 2019

Libros de Java geek

Download IT Guides!


AWS Lambda is an event-driven, serverless computing platform provided by Amazon as a part of the Amazon Web Services. It is a computing service that runs code in response to events and...

The Java Persistence API (JPA) is a vendor independent specification for mapping Java objects to the tables of relational databases. Implementations of this specification allow...

Apache ActiveMQ is an open source message broker written in Java together with a full Java Message Service (JMS) client. It provides “Enterprise Features” which means fostering the...

JDBC (Java Database Connectivity) is an API provided by Oracle that allows programmers to handle different databases from Java applications: it allows developers to establish connections...

martes, 8 de octubre de 2019

Design Patterns in Go



Quiero compartir esta gran pagina que muestra implementaciones de los patrones de diseño GOF en Go. Sería GOF en Go. Esta bueno como nombre de la página "Gof in Go" , bueno...

Ustedes pensarán igual que yo, como van implementar patrones Gof si Go no es orientado a objetos, pero si, con su polimorfismo en las estructuras, puede.

La verdad es que me cautiva porque en tantas cosas no estoy de acuerdo con esta pagina, pero a la vez me parece un genial ejercicio para aprender. Por ejemplo cuando afirma que Go es orientado a objetos pero no tiene ni clases, ni objetos. No sé, por algun lado no me cierra.

En fin, esta en castellano, así que aprovechen. 

Dejo link: https://www.designpatternsingo.com/

Hacer diagramas de secuencia súper fáciles con sequencediagram.org


Cada tanto te encontras con una herramienta que vale la pena compartir y este es el caso.

sequencediagram.org es un editor de diagramas de secuencia, súper fácil que se basa en texto para generar nuestros diagramas.

Tenes un lenguaje generador de diagramas que es muy fácil de utilizar y a medida que escribimos nuestro código se va generando el diagrama. Este código tiene instrucciones básicas y no ten básicas que permiten generar y embellecer nuestros diagramas.

Generado nuestro diagrama, podemos exportarlo a imagen (png), guardar le texto, compartirlo, guardarlo en un google drive, etc. 

Sin más dejo el link: https://sequencediagram.org/

Cómo dividir cadenas separadas por comas y usarlas en una cláusula IN en un select en oracle


Veamos dijo Stevie Wonder, en el trabajo por x motivos guardamos un campo con ids separados por comas.

Más allá de si esto esta bien o mal, necesitaba cortarlo y buscar por estos datos, como lo hice?  :

 select regexp_substr(columnasConIdsSeparadosPorComa,'[^,]+', 1, level) from tabla;

y bueno, esta query puede estar en un in :

select * from OtraTabla ot
where ot.id in ( select regexp_substr(columnasConIdsSeparadosPorComa,'[^,]+', 1, level) from tabla )

Y eso es todo amigos!

domingo, 6 de octubre de 2019

Channels en Go

Continuamos con en go

Los channels o canales son las tuberías que conectan las goroutinas concurrentes. Puede enviar valores a canales desde una goroutine y recibir esos valores en otra goroutine.

Se puede crear un nuevo channel con make (chan val-type). Los channels o canales están tipificados por los valores que transmiten.

Veamos un ejemplo:

package main

import "fmt"

func main() {
    messages := make(chan string)
    go func() { messages <- "ping" }()
    msg := <-messages
    fmt.Println(msg)
}

$ go run channels.go
ping

Como se puede ver en el ejemplo, se crea un chanel y luego envía valor a este chanel utilizando la sintaxis <-. En el ejemplo enviamos "ping" al canal messages que hicimos arriba, desde una nueva rutina.

La sintaxis <- permite recibir un valor del canal. Aquí recibiremos el mensaje de "ping" que enviamos arriba y lo imprimimos.

Cuando ejecutamos el programa, el mensaje "ping" se pasa con éxito de una rutina a otra a través de nuestro canal.

Por defecto se envían y reciben datos hasta que el emisor como el receptor estén listos. Esta propiedad nos permite esperar al final de nuestro programa el mensaje "ping" sin tener que usar ninguna otra sincronización.

Dejo link: https://gobyexample.com/channels


sábado, 5 de octubre de 2019

Goroutines

Continuamos con en go

Supongamos que tenemos que llamar una función de forma asíncrona en Go, para eso son las goroutines, veamos un ejemplo : 

package main

import (
    "fmt"
    "time"
)

func f(from string) {
    for i := 0; i < 3; i++ {
        fmt.Println(from, ":", i)
    }
}

func main() {

    f("direct")

    go f("goroutine")

    go func(msg string) {
        fmt.Println(msg)
    }("going")

    time.Sleep(time.Second)
    fmt.Println("done")
}

Como se ve, llamamos una función de forma directa sincrona, y otras 2 con goroutines. El resultado va ser : 

$ go run goroutines.go
direct : 0
direct : 1
direct : 2
goroutine : 0
going
goroutine : 1
goroutine : 2
done

Si venimos de lenguajes como C podemos decir que Go con las goroutines crea un hilo por geroutin.