Hola Mundo! Y ahora, ¿por dónde empiezo?
¿Qué lenguaje elegir? ¿Backend, fronted o ambos? ¿Qué diferencias hay? Estas y otras muchas preguntas seguro que han pasado por tu cabeza si estás empezando en esto del software. En este post daré respuesta a algunas de las preguntas más frecuentes y algunas pincelazas sobre temas relacionados.
# Por dónde empezar (según los datos)
Es posible que si quieres empezar en el mundo del software, y andas algo perdido, lo primero que hagas sea preguntar a una IA para que te oriente un poco. Esto podría ser una buena estrategia y seguramente te ayude, así que te insto a que contrastes con ella lo que te voy a contar aquí. Nosotros vamos a hacerlo a la manera tradicional: usando datos.
Manfred es una empresa de recruiting bastante famosa a nivel español y que tiene muy buena base de conocimiento para hablar de estos temas. Anualmente suelen hacer un reporte sobre la distribución de tecnologías según demanda y rol, entre otras cosas y se pueden sacar conclusiones muy interesantes. Ciertamente este reporte es de 2024, pero nos sirve. Por ejemplo, en la gráfica de roles más demandados se puede ver que los roles de frontend y backend se mantienen estables a lo largo del tiempo, por lo que parece interesante centrarse en alguno de estos roles.
Roles como ingenieros de datos o en Machine Learning han empezado a ganar muchísimo peso en estos últimos años. Aún así, no voy a listarlos aquí ya que la ingeniería de datos e inteligencia artificial son una rama distinta al desarrollo de software más “tradicional” y las competencias necesarias son muy distintas.
# Pues ni Backend ni Frontend: ¡ambos!
Si eres de los que has pensado que por qué elegir pudiendo aprenderlo todo te diré dos cosa. La primera: ¡Enhorabuena! Las ganas de aprender son esenciales para dedicarte a esto ya que te requerirá mucho tiempo y esfuerzo mantenerte al día con las tecnologías y avances del sector. Ahora, la segunda. Como se suele decir: “El que mucho abarca poco aprieta”, al menos al principio y, sobre todo, en el contexto de una persona junior o sin experiencia. ¿Quiere esto decir que debes elegir una y descartar tajantemente la otra? No, al contrario. Es más, te insto a que pruebes y experimentes con todas las tecnologías que puedas, pero que elijas una de sus vertientes y te hagas un experto en ella (y sobre todo que al principio dediques la mayor parte del esfuerzo en asentar las bases como comentaré después). Esto no te lo recomiento por capricho sino porque, de nuevo, remitiéndome a los datos, para poder llegar a hacer lo que la mayoría no hace (perfiles Full-Stack, Software Architect, etc) se requiere de mucho aprendizaje, sí, pero también de mucha experiencia.
También, y esto es experiencia personal, los equipos de desarrollo suelen ser equipos multidisciplinares o mixtos, donde en cada equipo hay una o varias personas desempeñando roles concretos, y es menos común ver proyectos donde todos hacen de todo. De nuevo, sí que existen proyectos de este tipo, por supuesto, pero a lo largo de los años me los he encontrado en un porcentaje mucho menor.
# Pues lo tengo claro: elijo lo que me dé más dinero 💸
Bueno… Aunque es totalmente lícito basar la elección en el dinero no te lo recomendaría. ¿Por qué? Porque normalmente aprender el lenguaje, la tecnología o el framework de turno puede beneficiarte a corto plazo o medio plazo. Pero a la larga el problema es obvio: apuestas por una tecnología que es muy relevante y demandada de la cual te beneficias hoy. Pero mañana, por cualquier motivo, deja de ser relevante y las empresas dejan de demandar esos perfiles. Es por eso que uno de los mejores consejos que podría dar a una persona que va a empezar es que comience por las bases.
# Las bases ⭐️
Voy a asumir que partes de manejar con soltura estructuras de control básicas:
if/else
,switch
,for
ywhile
en cualquier lenguaje. Si los términos anteriores te suenan a hacker, o te suenan pero tampoco los has usado mucho, te recomendaría que dejes de leer este post ahora mismo y que vayas a alguna de las páginas que te dejo a continuación para que practiques todo lo posible: Codecombat, Codewars, Adventofcode. O pregunta a tu IA favorita por problemas básicos de programación e impleméntalos en el lenguaje de programación que más te llame.
En esta sección vamos a tocar “todos los palos”. Todo lo que voy a citar aquí es lo mínimo indispensable que cualquier desarrollador de software debe conocer, en mayor o menor medida y con mayor o menor soltura. Otro tema es la profundidad de dicho conocimiento, pero al menos un conocimiento básico de todos ellos es esencial.
# El paradigma
Presta atención a esta gráfica. ¿Qué dirías que tienen en común esos lenguajes? Más del 50% de ellos son lenguajes de programación orientados a objetos (OOP para los amigos). La mayoría de los lenguajes que el sector demanda suelen ser, en la gran mayoría de los casos, lenguajes de este tipo, por lo que es clave manejar conceptos básicos de este paradigma de programación: objetos, herencia, polimorfismo, abstracción, encapsulamiento, sobrecarga y un largo etc. Sé, por experiencia propia, que la primera vez que se escuchan estas cosas se tiene un sentimiento de decepción, como que hay un océano de conocimiento que tienes que llenar “solo para empezar”. Créeme, el esfuerzo merecerá la pena. Todo lo que aprendas cuando masterices esto será extrapolable a la mayoría de lenguajes y tecnologías que uses, ya que muchos de ellos están bajo el paraguas de dicho paradigma, por lo que el retorno de inversión está más que justificado. De ahí que no importe tanto el lenguaje, sino cómo de asentados tienes todos esos conocimientos. Un mismo diseño o problema se puede abordar usando la misma base independientemente de si el lenguaje es Java o JavaScript, backend o frontend, porque la base es común.
# Patrones de diseño
Aunque estas bases no están pensadas como una lista ordenada per-sé, sí que hay una pequeña “jerarquía” de aprendizaje donde, para poder avanzar al siguiente, deberías tener bastante controlado el anterior. Y, por supuesto, también hay temas ortogonales a otros que se pueden aprender en paralelo o sin necesidad de un orden específico. En este caso, yo diría que hay una dependencia entre controlar sobre los principios de orientación a objetos y los patrones de diseño. Dado que la piedra angular de la mayoría de patrones son la herencia, la abstracción y encapsulamiento (entre otros) estos conceptos deben manejarse con mediana soltura. Dicho esto, patrones de diseño hay un montón y, si bien es cierto que todos son importantes y que merece mucho la pena tenerlos siempre en mente, hay algunos que son más comunes de usar que otros. Voy a dar una lista de los que a mí me parecen esenciales, pero no deja de ser criterio personal y basado en mi experiencia. Dicho esto, los patrones de diseño que se tienen que conocer mínimamente y tener una imagen clara en la mente de la jerarquía de interfaces, implementaciones y sus conexiones serían:
- Factory (no incluiría factoría abstracta)
- Builder
- Singleton
- Decorator
- Command
- Chain of Responsibility
- State
- Strategy
- Template
- Iterator
# Estructuras de datos y algoritmos (en adelante DSA)
Bueno, aquí llegamos al apartado que, en mi opinión, es el más importante de todos. Es más, diría que las estructuras de datos y los algoritmos son la base de la base. Y, paradójicamente, son a la vez, lo que más se desconoce y lo que menos se practica (supongo que porque la curva de aprendizaje es muy pronunciada). Lamentablemente este punto es tan sumamente grande que, no es que no se pueda contar en este párrafo o en esta entrada, es que necesitaría un blog completo para hablar exclusivamente de esto con suficiente rigor.
Por suerte hay buenas noticias. Siempre puedes quedarte con una visión más pragmática de este tema, conociéndolo un poco por encima y sin entrar en mucha profundidad. ¿Es esto suficiente? Pues como siempre: depende. Pero dado que este post está pensado para personas que quieren empezar quizás sí lo es. Por tanto, puede estar justificado tener una vista de águila de los conceptos y algoritmos esenciales en primera instancia y, a medida que se vaya ganando experiencia y madurando, ahondar todo lo posible.
Fun (o no tan fun) fact
Cuando comencé mi carrera profesional, empecé a interesarme (y a necesitar) conocer más sobre DSA. Al ser un mundo tan amplio y complejo, pregunté a algunos compañeros de trabajo cuestiones sobre cómo medir y optimizar algoritmos, ya que algunos de ellos habían estudiado en la universidad (yo nunca fui, aunque eso es otro tema). Supuse que debían conocer estos temas muy bien. Recuerdo que uno de ellos me dijo: “no hace falta que estudies la complejidad de los algoritmos, ya te lo resumo yo: lo importante es evitar los bucles, sólo eso”. En aquel entonces no tenía demasiado criterio para dudar de lo que me dijo (aunque ya ahí tenía serias dudas) pero esa frase se me quedó marcada y, desde hace mucho, sé cuán equivocada, reducida a lo absurdo y simplista fue esa respuesta. Por suerte no hice caso y te diría que, en general, cuestiones y contrastes la información de algo que no controlas.
Entonces, ¿por dónde empezamos? Como he dicho, es un mundo muy amplio pero sí que hay algunos puntos por los que se podría empezar, entendiendo el algoritmo, su funcionamiento e implementación, sin entrar a hacer análisis de complejidad de los mismos.
# Algoritmos
Dentro del vasto océano de algoritmos famosos que existen, yo empezaría por algoritmos de ordenación. En mi opinión son los más fáciles de entender y de implementar (mi primera ""implementación"" fue usando una baraja de cartas). Pecando de simplista, diría que los más interesantes a conocer por su diversidad de implementación serían:
- Insertion sort
- Selection sort
- Merge sort
- Heap sort
- Quick sort
Con esa lista, mínimo, te aseguras de entender algo de recursividad, matrices, un poco de árboles binarios y, con suerte, empezará a sonarte algo de la notación big-O. Una vez vistos los algoritmos de ordenación pasaría a los algoritmos de búsqueda, también muy útiles:
- Linear search
- Binary search (éste, además de ser muy fácil de entender e implementar, es muy eficiente)
- Depth-First Search
- Breadth-First Search
# Estructuras de datos
Pasando a un segundo gran bloque tendríamos estructuras de datos, que son elementos que nos sirven para trabajar con datos (seguro que no te lo esperabas) de forma eficiente. Todos tienen pros y contras respecto a los demás, y justo es interesante estudiarlos para saber cuál usar dependiendo de la necesidad.
- Arrays, Stacks y Queues (los agrupo por similitud aunque realmente son estructuras distintas)
- Linked Lists
- Hash Tables
- Grafos y árboles
Cierro este apartado comentando que, efectivamente, es mucha tela que cortar. Pero entender e implementar cada uno de los algoritmos y estructuras de datos mencionados por uno mismo vale oro, al menos una vez.
DSA’s en el día a día
La mayoría de los lenguajes de programación (y no digo todos por si hay alguno especialito) tienen su propia implementación de la mayoría de algoritmos y estructuras de datos que en este apartado se mencionan. Si te pica la curiosidad, coge tu lenguaje favorito e infórmate sobre cuántos de los anteriores implementa. E incluso, si te engancha el tema, puedes echar un vistazo a cómo están implementados!
# SQL y sistemas de bases de datos
Con lo que llevamos hasta ahora, conseguiríamos desarrollar el software necesario para cubrir una funcionalidad dada, utilizando para ello un diseño y estructura del código óptimos, permitiéndonos iterarlo de forma efectiva con el tiempo. También sabriamos identificar cómo de eficiente es el código que hemos escrito a la hora de trabajar con un gran volumen de datos. Y eso está genial pero, ¿de dónde sacamos esos datos?
Otro gran bloque que es esencial conocer y dominar para cualquier desarrollador que se precie, son los sistemas de bases de datos (RDBMS) y cómo interactuar con ellos. Tipos de bases de datos también hay un montón (esto tampoco te lo veías venir, eh 😉 ). Siguiendo con el principio de Pareto, como venimos haciendo hasta ahora, lo más útil sería aprender bases de datos relacionales, que es algo que seguro vas a usar en el 90% de los proyectos a los que te enfrentes.
Cada vendor de base de datos tiene sus particularidades en cuanto a funcionalidades, configuración, logs, etc. Por tanto vamos a centrarnos en el contenido que sí que es común a todas y que es necesario conocer:
# RDMBS
Qué son y qué elementos componen a las RDBMS (Relational Database Management System)
- Esquemas, tablas, columnas, filas, atributos y tipos
- Claves primarias y foráneas
- Relaciones
- Restricciones
- Transaccionabilidad
- Indexación
- Normalización y formas normales
# SQL
Por último, una vez conoces cómo almacenar datos necesitas algún mecanismo para trabajar con ellos. SQL al rescate! SQL (Structured Query Language) es un lenguaje estándar que nos permite hablar con cualquier motor de base de datos que se acoja a dicho estándar (que ya os adelanto que son muchos. Muchísimos!). Es un lenguaje declarativo donde básicamente dices qué quieres hacer pero no cómo. De eso se encarga el propio motor.
A su vez, motores de bases de datos relacionales hay muchísimos y aquí sí que da un poco igual cuál escojas. Si tienes alguno de preferencia porque esté de moda; adelante. Yo comencé usando MySQL porque era el motor “de moda” en mi época. Hoy día (y en aquel entonces también) hay muchas alternativas. Voy a listar unas cuantas pero, me reitero, puedes elegir el que más te guste:
- PostgreSQL
- MySQL
- MariaDB
- SQLite
- H2
H2 no es un motor de bases de datos “tradicional” sino una implementación de motor de base de datos en memoria. Muy útil para hacer pruebas en local de forma rápida. Además te comunicas usando SQL siendo una buena alternativa para empezar.
Si has llegado hasta aquí ¡enhorabuena! Lo que resta aunque sigue siendo muy importante, ocuparía una posición inferior en una lista de cosas prioritarias. ¡Ojo! No estoy diciendo que no tengas que conocerlo, solo digo que “al César lo que es del César”.
# Herramientas de versión de control
Normalmente las primeras líneas de código que tiramos las escribimos solos, en un ambiente controlado, donde al retormar lo que hiciste ayer sigue estando tal y como lo dejaste. Esto, como podrás imaginar, dista mucho de lo que te puedes encontrar en un entorno colaborativo. El tema es que el código que normalmente escribes cuando no estás tú solo en el proyecto es dinámico y otras personas pueden participar dentro de la misma base de código que estás tocando tú. Para tener un registro vivo de todo lo que ha ocurrido en el proyecto, tener un control de qué persona ha hecho qué y cuándo, por qué lo hizo, a qué hora, etc. Es necesario usar (y saber usar) un sistema de control de versiones. Aquí no voy a deciros que hay una lista inmensa y ni nada de eso. Aquí el rey es el rey: Git.
“Git es un sistema de control de versiones distribuido que permite gestionar y hacer un seguimiento de los cambios en el código fuente de un proyecto, facilitando la colaboración entre desarrolladores.” - by Chatgpt. Cortita y al pie; no hay mucho más que añadir.
Si aspiras a dedicarte a esto o lo haces por hobbie; aprende Git. Pero no aprender a usarlo a través de interfaces gráficas que no sabes muy bien qué o cómo hacen lo que hacen, sino usando la terminal, a puro comando. Una vez asentadas las bases y sabiendo lo que hay “under the hood” entonces, si lo veis necesario, pasad a usar una interfaz de usuario.
# Testing
Normalmente las primeras líneas de código que tiramos las escribimos solos, en un ambiente controlado donde al retormar lo que hiciste ayer sigue estando tal y como lo dejaste. No, no se me ha escapado el usar la misma frase que en el párrafo anterior. Aquí el contexto es el mismo: cuando trabajas solo o en un proyecto sin mucha repercusión quizá esto no te interese. Pero si tu objetivo es trabajar con otras personas o hacer software de calidad esto es indiscutible.
Saber hacer testing es necesario, puesto que a medida que iteras y evolucionas tu código necesitas cerciorarte de que lo una vez hiciste y dejaste funcionando, a día de hoy y después de todos los cambios que el ciclo de vida del proyecto haya requerido, sigue funcionando exactamente igual. Si ya has elegido lenguaje o estás buscando candidato para aprender, échale un ojo al internet porque seguro que de una forma u otra puedes hacer testing con ese lenguaje.
De entre todos los tipos de tests que hay, el que yo os recomendaría para ir empezando es hacer testing unitario.
# Un largo (y apasionante) etcétera
Probablemente si has llegado a este punto, estarás pensando que cómo es posible que diga que hay tantísimo contenido esencial, solo para empezar, cuando hay por ahí cursos y bootcamps que prometen convertirte en un desarrollador listo para el mundo laboral, de zero-to-hero 🚀, en meses o semanas (algunos incluso en horas 🥲). Paradójicamente, yo me hago la misma pregunta. Reitero lo que decía al principio: cuestiona y contrasta todo lo que te digan o leas. Prueba, es gratis! (casi siempre 🤣). Saca tus propias conclusiones. Sé crítico. Si algo es demasiado bonito para ser cierto, ya sabes… Probablemente lo sea.
Voy a dejar como referencia esta página: https://roadmap.sh. Me parece súper interesante ya que, de forma colaborativa, se están construyendo distintas hojas de ruta en base a distintas tecnologías través de las cuales te puedes ir abriendo camino entre tanto follaje tecnológico.
Mi idea es ir creando una serie de entradas en el blog hablando detalladamente de cada uno de los puntos que aquí se tratan y de muchos más. Mientras tanto, en la sección de Recursos voy a dejar enlaces a cursos, charlas y, en general, contenido que a mi me ha resultado útil o de interés. Como comento en la sección donde hablo de mí, uno de los motivos por los que hago este blog es para poder contar aquellas cosas que me hubiera encantado que me contaran cuando yo empecé. Cualquier duda, comentario, corrección o crítica, tienes mi correo justo en el footer.