Certificado de Programación con Go
20h 0m
Curso de Programación Go con certificado de superación. Domina desde la sintaxis, programación orientada a objetos y técnicas de concurrencia y comunicación HTTP en GoLang.
Accede GRATIS y certifícateIntroducción y entorno
Introducción a Go
Go, también conocido como Golang, es un lenguaje de programación desarrollado por Google que ha ganado popularidad en los últimos años gracias a su eficiencia y facilidad para manejar concurrencia. En este curso de backend con Go, exploraremos cómo este lenguaje se ha convertido en una herramienta esencial para el desarrollo backend moderno.
Historia y filosofía de Go
Go fue creado en 2009 por Robert Griesemer, Rob Pike y Ken Thompson, con el objetivo de combinar la eficiencia y seguridad de lenguajes como C++ con la simplicidad y productividad de lenguajes como Python. Su diseño se centra en la simplicidad, la legibilidad y la eficiencia, lo que lo convierte en una opción ideal para desarrollar aplicaciones backend robustas y escalables.
Usos de Go en la actualidad
En la actualidad, Go es utilizado por empresas de renombre como Google, Uber y Dropbox para construir sistemas que requieren alto rendimiento y una gestión eficaz de la concurrencia. Su capacidad para compilar código nativo y su amplio soporte para la programación concurrente lo hacen especialmente adecuado para el desarrollo de servicios web, APIs y aplicaciones de red.
Comparativa de Go con otros lenguajes de programación
A diferencia de lenguajes interpretados como Python o JavaScript, Go es un lenguaje compilado que ofrece un rendimiento cercano al de C y C++. Sin embargo, su sintaxis simplificada y características modernas lo hacen más accesible y productivo. Go se destaca por su gestión de concurrencia nativa y un sistema de tipos robusto que ayuda a prevenir errores comunes durante el desarrollo backend.
Instalación y primer programa de Go
Para comenzar a desarrollar con Go, es esencial configurar el entorno de desarrollo adecuadamente.
Estructura básica de un programa Go
Un programa en Go se estructura en paquetes. El paquete main
es fundamental, ya que contiene la función main()
, punto de entrada de cualquier aplicación ejecutable. Este enfoque facilita la organización y reutilización del código en proyectos de backend.
Compilación y ejecución
Go proporciona herramientas integradas para compilar y ejecutar programas de manera eficiente. Con el comando go run
, se puede compilar y ejecutar un programa en un solo paso, lo que agiliza el proceso de desarrollo y prueba en entornos backend.
El paquete main y la función main
El paquete main
y la función main()
son esenciales en cualquier aplicación Go ejecutable. La función main()
actúa como punto de inicio, y desde allí se pueden llamar a otras funciones y paquetes para construir aplicaciones backend complejas.
Paquetes e importaciones
Go utiliza paquetes para organizar el código. Los paquetes se importan utilizando la palabra clave import
, lo que permite acceder a funcionalidades diversas, desde paquetes estándar hasta terceros, ampliando las capacidades de las aplicaciones backend.
Sintaxis
Tipos de datos, variables y constantes
Go es un lenguaje fuertemente tipado, lo que contribuye a la detección temprana de errores y a un código más seguro en aplicaciones backend.
Declaración y asignación de variables
Las variables en Go pueden declararse de manera explícita o implícita. La declaración explícita especifica el tipo de dato, mientras que la implícita utiliza :=
para que el compilador infiera el tipo.
var mensaje string = "Hola, Go"
contador := 1
Tipos de datos primitivos
Go soporta tipos como enteros (int
), flotantes (float64
), booleanos (bool
) y cadenas (string
), fundamentales para manejar datos en aplicaciones backend.
Uso de constantes con la palabra clave const
Las constantes se declaran con const
y representan valores que no cambian durante la ejecución del programa, lo que es útil para definir configuraciones en servicios backend.
const puertoDefecto = 8080
Operadores y expresiones
Los operadores permiten realizar operaciones matemáticas y lógicas, esenciales en la lógica de negocio del backend.
Operadores aritméticos, lógicos y relacionales
Go incluye operadores como +
, -
, *
, /
para operaciones aritméticas, y &&
, ||
, !
para operaciones lógicas, facilitando la implementación de algoritmos en el backend.
Precedencia y asociatividad de operadores
La precedencia determina el orden en que se evalúan las expresiones. Comprender esto es vital para evitar errores en cálculos y condiciones en código backend.
Conversión y casting de tipos
Go requiere una conversión explícita de tipos, lo que aumenta la seguridad y claridad del código.
var entero int = 42
var flotante float64 = float64(entero)
Cadenas de texto y manipulación
La manipulación de cadenas es frecuente en el desarrollo backend, especialmente al procesar datos de entrada y generar respuestas.
Operaciones básicas con cadenas
Se pueden concatenar cadenas utilizando el operador +
y obtener su longitud con la función len()
.
mensaje := "Hola, " + "mundo"
longitud := len(mensaje)
Uso del paquete strings
El paquete strings
ofrece funciones para manipular y analizar cadenas, como Contains
, Split
y ToUpper
, facilitando tareas comunes en el backend.
Formateo y construcción de cadenas con fmt
El paquete fmt
permite formatear cadenas con funciones como Sprintf
, útil para generar mensajes y logs en aplicaciones backend.
Estructuras de control
Las estructuras de control son esenciales para dirigir el flujo del programa.
Sentencias if
, else if
, else
Estas sentencias permiten ejecutar bloques de código basados en condiciones, fundamentales en la toma de decisiones en el backend.
if usuarioAutenticado {
// Acceso permitido
} else {
// Acceso denegado
}
Uso de switch
y case
El switch
simplifica la evaluación de múltiples condiciones, lo que mejora la legibilidad en código backend complejo.
switch metodoHTTP {
case "GET":
// Manejar GET
case "POST":
// Manejar POST
default:
// Método no soportado
}
Control de flujo y estructuras de bucle
Uso del bucle for
en sus distintas formas
El bucle for
es la única estructura de bucle en Go, pero es muy flexible. Puede usarse como bucle tradicional, infinito o como iterador.
for i := 0; i < 10; i++ {
// Código
}
Iteración sobre colecciones con range
El range
simplifica la iteración sobre arrays, slices y mapas, común al procesar datos en el backend.
for indice, valor := range listaUsuarios {
// Código
}
Control de bucles con break
y continue
Estas instrucciones permiten controlar el flujo dentro de los bucles, lo que es útil para optimizar procesos en aplicaciones backend.
Funciones
Las funciones son bloques reutilizables que encapsulan lógica, esenciales para organizar el código en el backend.
Definición y llamada de funciones
Se definen con la palabra clave func
y pueden llamarse desde otras partes del código.
func calcularSuma(a int, b int) int {
return a + b
}
Parámetros, argumentos y valores de retorno
Las funciones pueden recibir parámetros y devolver valores, lo que permite modularizar y reutilizar código.
Valores de retorno múltiples y nombrados
Go permite que las funciones devuelvan múltiples valores, lo que es útil para retornar resultados y posibles errores.
func dividir(a, b float64) (resultado float64, err error) {
if b == 0 {
err = fmt.Errorf("división por cero")
return
}
resultado = a / b
return
}
Estructuras de datos
Arrays y slices
El manejo de colecciones de datos es fundamental en el desarrollo backend.
Declaración y uso de arrays
Los arrays tienen una longitud fija y almacenan elementos del mismo tipo.
var numeros [5]int
Introducción y manejo de slices
Los slices son más flexibles que los arrays y permiten trabajar con secuencias dinámicas.
clientes := []string{"Ana", "Luis", "María"}
Operaciones comunes: agregar, copiar, segmentar
Con funciones como append
, se pueden agregar elementos a un slice, lo que es frecuente en operaciones de manipulación de datos en el backend.
Mapas
Los mapas asocian claves a valores y son útiles para representar relaciones en datos.
Creación y manipulación de mapas
Se crean utilizando make
o literales de mapa.
edades := map[string]int{
"Carlos": 30,
"Laura": 25,
}
Acceso y modificación de elementos
Se puede acceder y modificar valores utilizando las claves.
edadCarlos := edades["Carlos"]
edades["Laura"] = 26
Detección de claves y eliminación de pares
Es posible comprobar si una clave existe y eliminar pares clave-valor.
if edad, existe := edades["Pedro"]; existe {
// Código si existe
}
delete(edades, "Carlos")
Punteros y referencias
Los punteros permiten referenciar ubicaciones en memoria, lo que es útil para gestionar datos eficientemente en el backend.
Concepto de punteros en Go
Un puntero almacena la dirección de memoria de una variable.
var numero int = 42
var puntero *int = &numero
Operadores &
(dirección) y *
(indirección)
El operador &
obtiene la dirección de una variable, y *
accede al valor apuntado por un puntero.
Punteros a tipos y seguridad de memoria
Go maneja punteros de manera segura, evitando errores comunes como punteros nulos o accesos indebidos.
Programación orientada a objetos
Aunque Go no tiene clases, utiliza structs
y métodos para implementar conceptos similares a la programación orientada a objetos, útiles en la organización de código backend.
Estructuras structs
Los structs
agrupan campos y representan entidades.
Definición y uso de structs
type Usuario struct {
Nombre string
Correo string
Activo bool
}
Campos anónimos y composición
La composición se logra incrustando structs
dentro de otros, promoviendo la reutilización.
type Empleado struct {
Usuario
IDEmpleado int
}
Comparación con clases en otros lenguajes
En lugar de herencia, Go utiliza composición, lo que facilita la creación de estructuras más flexibles en el backend.
Métodos con receptores por valor y por puntero
Asociar métodos a tipos definidos
Se pueden definir métodos asociados a un struct
.
func (u Usuario) Saludar() {
fmt.Println("Hola,", u.Nombre)
}
Receptores por valor y por puntero
Los métodos pueden tener receptores por valor o por puntero, lo que afecta si se modifica el estado del objeto.
func (u *Usuario) Activar() {
u.Activo = true
}
Encapsulación y acceso a datos
El uso de mayúsculas determina la visibilidad de campos y métodos, permitiendo controlar el acceso desde otros paquetes.
Modificación de estado en métodos
Los receptores por puntero permiten modificar los valores del struct
, esencial en operaciones de actualización en el backend.
Polimorfismo a través de interfaces
Cómo definir e implementar interfaces en Go
Las interfaces declaran métodos que un tipo debe implementar.
type Notificador interface {
EnviarNotificacion(mensaje string) error
}
Polimorfismo basado en interfaces
Permite que diferentes tipos sean tratados de la misma manera si cumplen con la misma interfaz, lo que es útil al diseñar sistemas extensibles en el backend.
Uso de interfaces vacías (interface{}
) y su aplicación
La interfaz vacía puede contener cualquier tipo, pero su uso debe ser cuidadoso para mantener la claridad del código.
Composición de structs
en lugar de herencia
Incrustación de structs
y reutilización de código
La composición se logra incrustando un struct
dentro de otro, lo que promueve la reutilización sin los problemas de la herencia múltiple.
Ejemplos de composición vs herencia clásica
La composición permite crear estructuras más flexibles y modulares, lo que facilita el mantenimiento y la evolución de aplicaciones backend.
Cómo la composición promueve la flexibilidad
Al evitar la rigidez de la herencia, la composición facilita la adaptación del código a nuevas necesidades sin reestructuraciones significativas.
Generics
Cómo definir funciones y tipos genéricos
Los generics permiten crear funciones y tipos que pueden trabajar con cualquier tipo de dato.
func Filtrar[T any](datos []T, criterio func(T) bool) []T {
var resultado []T
for _, item := range datos {
if criterio(item) {
resultado = append(resultado, item)
}
}
return resultado
}
Restricciones de tipos mediante type constraints
Se pueden definir restricciones para especificar qué tipos son aceptables en los generics.
Ejemplos de uso de generics
Los generics simplifican el código y evitan la duplicación, lo que mejora la eficiencia en el desarrollo backend.
Manejo de errores y excepciones
El manejo adecuado de errores es esencial para crear aplicaciones backend fiables y robustas.
Manejo explícito de errores
En Go, los errores se manejan de manera explícita, lo que fuerza al desarrollador a considerar y tratar las posibles fallas.
Retorno de tipo error en funciones
Las funciones suelen devolver un valor y un error.
func leerArchivo(nombre string) ([]byte, error) {
datos, err := os.ReadFile(nombre)
if err != nil {
return nil, err
}
return datos, nil
}
Propagación de errores
Es común propagar errores hacia arriba para ser manejados en un nivel superior, manteniendo así la claridad en el flujo de errores.
Evitar el manejo de errores silencioso
Ignorar errores puede llevar a comportamientos inesperados, por lo que siempre se deben manejar o propagar.
Errores personalizados y wrapping para mejorar la trazabilidad
Creación de errores personalizados
Se pueden crear errores con mensajes específicos que aporten contexto.
err := fmt.Errorf("fallo al conectar con la base de datos: %v", errOriginal)
Cómo envolver errores con fmt.Errorf
El wrapping de errores ayuda a mantener la información original del error mientras se añade contexto adicional, esencial en la depuración de aplicaciones backend.
Uso de errors.Is
y errors.As
Estas funciones permiten comparar y extraer información de errores envueltos.
Casos prácticos de wrapping de errores
El uso adecuado de wrapping mejora la capacidad para diagnosticar y resolver problemas.
Mantener la trazabilidad
Proporcionar información detallada en errores facilita el mantenimiento y mejora la calidad del software backend.
Comunicación por HTTP
La comunicación por HTTP es fundamental en aplicaciones backend modernas.
Métodos HTTP con net/http
El paquete net/http
facilita la creación de clientes y servidores HTTP.
Realizar peticiones HTTP GET
Para obtener recursos de un servidor.
resp, err := http.Get("https://api.ejemplo.com/datos")
Realizar peticiones HTTP POST
Para enviar datos al servidor.
resp, err := http.Post("https://api.ejemplo.com/crear", "application/json", cuerpo)
Realizar peticiones HTTP PUT
y PATCH
Para actualizar recursos existentes.
Realizar peticiones HTTP DELETE
Para eliminar recursos.
API REST con net/http
Se pueden crear APIs REST sin necesidad de frameworks adicionales.
Configurar una API REST JSON sin framework
Definiendo handlers y utilizando el paquete encoding/json
para manejar datos JSON.
Recibir peticiones GET
y POST
Manejando diferentes rutas y métodos HTTP para crear endpoints funcionales.
Concurrencia y paralelismo
Go destaca por su manejo eficiente de la concurrencia, lo que es crucial para aplicaciones backend de alto rendimiento.
Goroutines y concurrencia básica
Cómo crear y manejar goroutines
Las goroutines son funciones que se ejecutan concurrentemente, facilitando la ejecución de tareas en paralelo.
go procesarSolicitud(solicitud)
Uso de WaitGroup
para gestionar ciclos de vida
Los WaitGroup
permiten esperar a que un conjunto de goroutines finalice antes de continuar.
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
// Código
}()
wg.Wait()
Ejemplos de ejecución concurrente
La concurrencia mejora la capacidad de respuesta y el rendimiento en aplicaciones backend que manejan múltiples conexiones o tareas.
Canales y comunicación entre goroutines
Creación y uso de canales
Los canales permiten la comunicación segura entre goroutines.
canal := make(chan string)
Cómo enviar y recibir datos entre goroutines
Se pueden enviar y recibir datos a través de canales, sincronizando la ejecución.
canal <- "mensaje"
mensaje := <-canal
Patrones comunes: productor-consumidor y Fan-in/Fan-out
Estos patrones optimizan el procesamiento de tareas y mejoran la escalabilidad.
Condiciones de carrera
Qué es una condición de carrera
Ocurre cuando varias goroutines acceden y modifican una variable compartida sin la debida sincronización.
Cómo detectar condiciones de carrera
Go proporciona la herramienta -race
para detectar condiciones de carrera.
go run -race main.go
Cómo solucionar condiciones de carrera
Utilizando mutexes o canales para sincronizar el acceso a recursos compartidos.
Selectores y mutexes: concurrencia y exclusión mutua
Uso del select
para gestionar múltiples canales
El select
permite esperar en múltiples operaciones de canal, lo que es útil para manejar múltiples fuentes de datos concurrentemente.
select {
case msg := <-canal1:
// Manejar msg de canal1
case alerta := <-canal2:
// Manejar alerta de canal2
}
Uso de mutexes para sincronización explícita
Los mutexes protegen secciones críticas, asegurando que solo una goroutine acceda a una sección de código a la vez.
var mu sync.Mutex
mu.Lock()
// Sección crítica
mu.Unlock()
Ejemplos de patrones concurrentes
Implementar correctamente la concurrencia es esencial para desarrollar aplicaciones backend eficientes y libres de errores.
Tutoriales de programación en este certificado
Completa estas lecciones de programación para obtener tu certificado de superación
Introducción A Go
Introducción Y Entorno
Instalación Y Primer Programa De Go
Introducción Y Entorno
Tipos De Datos, Variables Y Constantes
Sintaxis
Operadores Y Expresiones
Sintaxis
Cadenas De Texto Y Manipulación
Sintaxis
Estructuras De Control
Sintaxis
Control De Flujo Y Estructuras De Bucle
Sintaxis
Funciones
Sintaxis
Arrays Y Slices
Estructuras De Datos
Mapas
Estructuras De Datos
Punteros Y Referencias
Estructuras De Datos
Estructuras Structs
Programación Orientada A Objetos
Métodos Con Receptores Por Valor Y Por Puntero
Programación Orientada A Objetos
Polimorfismo A Través De Interfaces
Programación Orientada A Objetos
Composición De Structs En Lugar De Herencia
Programación Orientada A Objetos
Generics
Programación Orientada A Objetos
Manejo Explícito De Errores
Manejo De Errores Y Excepciones
Errores Personalizados Y Trazabilidad
Manejo De Errores Y Excepciones
Métodos Http Con Net/http
Comunicación Por Http
Api Rest Con Net/http
Comunicación Por Http
Ejercicios de programación de Programación con Go
Completa estos ejercicios de programación para obtener tu certificado de superación
Cadenas de texto y manipulación
Selectores y mutexes: concurrencia y exclusión
Agenda de contactos por consola
Composición de structs en lugar de herencia
Estructuras de control
Arrays y slices
Control de flujo y estructuras de bucle
Sistema API REST gestión de libros
Métodos con receptores por valor y por puntero
API REST con net/http
Generics
Evaluación Go
Métodos HTTP con net/http
Crear e invocar funciones
Operadores y expresiones
Polimorfismo a través de Interfaces
Manejo explícito de errores
Estructuras structs
Tipos de datos, variables y constantes
Introducción a Go
Otros cursos de programación con certificado
Supera todos los retos de Programación con Go y obtén estos certificados de superación para mejorar tu currículum y tu empleabilidad.
Control de versiones con Git
5h 0m
Programación con HTML
10h 0m
Programación con CSS
10h 0m
Programación con JavaScript
20h 0m
Programación con TypeScript
20h 0m
Programación con Python
20h 0m
Programación con Java
20h 0m
Programación con Kotlin
20h 0m
Programación con C#
20h 0m
Consola de comandos Linux Bash
15h 0m
Bases de datos con SQL
20h 0m
Frontend con Bootstrap CSS
10h 0m
Frontend con Tailwind CSS
10h 0m
Frontend con Angular
30h 0m
Frontend con React
30h 0m
Frontend con Vuejs
30h 0m
Frontend básico: HTML, CSS y JavaScript
40h 0m
Frontend avanzado: HTML, CSS, JS, TS, Angular
90h 0m
Backend NestJS
30h 0m
Tecnologías que aprenderás
Al finalizar este curso obtendrás
Certificado de superación en Programación con Go
Tras completar todas las lecciones y ejercicios del curso Programación con Go se te genera un enlace con tu certificado para que lo puedas descargar o compartir directamente en cualquier plataforma, siempre accesible.