Saltar al contenido principal

7 publicaciones etiquetados con "Technical"

Ver Todas las Etiquetas

Un cambio de mentalidad

· 9 min de lectura

Borrador de noviembre de 2021.

«Y ese, creo, es el verdadero cambio de mentalidad: pasar de ser alguien que aprende a alguien que resuelve problemas».

Ilustración del artículo

Me di cuenta de que, una vez que terminas un curso, aprendes lo básico y empiezas a trabajar en proyectos reales, rara vez vuelves a ver una sección entera del curso solo porque tenga relación con el problema que intentas resolver.

En su lugar, sueles hacer una de dos cosas.

O bien:

a. Revisas tus apuntes o documentación para comprobar si ya te has encontrado con ese problema, siempre que confíes lo suficiente en tus notas, o

b. Tomas el camino mucho más fácil y rápido: buscar en Google, en Stack Overflow o un caso parecido en YouTube.

Por eso creo que los cursos estructurados son muy útiles durante la etapa de descubrimiento.

Te presentan la tecnología, explican la terminología, muestran cómo se conectan las cosas y te dan una idea de con qué estás tratando.

Pero, cuando intentas utilizar esa tecnología para resolver tus propios problemas, las cosas cambian.

En ese momento suele entrar en juego el instinto.

Buscas el error en Google y esperas que alguien ya haya hecho exactamente la misma pregunta en Stack Overflow.

O quizá alguien subió hace tres años un vídeo de doce minutos a YouTube que, de alguna manera, resuelve justo tu problema.

También he notado que los cursos pueden quedarse obsoletos bastante rápido, sobre todo cuando las tecnologías avanzan a un ritmo muy, muy acelerado.

Se me ocurren ejemplos de la computación en la nube de AWS (puedes saltarte la lista si no te interesan los detalles):

  1. Un día, los límites de EC2 se expresan como un número fijo de instancias por región.
  2. Después, se basan en la cantidad de vCPU que puedes ejecutar.
  3. Un día, ZooKeeper es una pieza importante de la arquitectura que estudias.
  4. Después, las versiones más nuevas de la tecnología empiezan a prescindir de él por completo.

A veces el cambio es importante.

A veces solo es un botón que ha cambiado de sitio en la interfaz.

Pero, cuando sumas todos esos pequeños cambios a todo lo demás que ya intentas aprender, empiezan a pesar bastante.

Un día quizá tengas varias semanas para experimentar con esa fascinante tecnología que acabas de descubrir.

Y al siguiente alguien te dice que tienes dos semanas para entenderla y entregar una solución mínimamente utilizable.

Así que sí.

Las cosas cambian bastante rápido.

Supongo que lo que quiero decir es que tardé casi cuatro años, y sinceramente todavía sigo trabajando en ello, en alejarme de esa forma de aprender estructurada, al estilo universitario, y adaptarme más a cómo se adquiere el conocimiento en la industria.

Cuando digo aprendizaje al estilo universitario, me refiero a aquel en el que tienes un esquema claro que seguir.

Empiezas con los primeros pasos.

Quizá abres tu primera terminal.

Luego aprendes los comandos.

Después los conceptos se van complicando.

Y acabas llegando a las partes más difíciles.

Normalmente sabes qué intentas aprender, cuál es el problema y qué debes lograr antes de pasar a la siguiente lección.

La industria no siempre funciona así.

A veces solo te dan una lista de requisitos.

Y ya está.

Nadie te entrega una lista ordenada de todas las tecnologías que debes aprender de antemano.

Te toca averiguar qué herramientas necesitas.

A veces ni siquiera te dan un problema técnico claramente definido.

Primero tienes que descubrir qué preguntas hay que hacer.

Y luego empiezas a buscar las respuestas.

Supongo que esto entra dentro de lo que se llama problemas mal definidos, donde no siempre existe una solución perfecta o única.

Durante mi trabajo anterior y ahora en el actual, he aprendido mucho sobre cómo se construyen realmente las soluciones.

Puede que tengas ayuda de un proveedor.

Puede que trabajen contigo servicios profesionales externos.

Puede que haya documentación, arquitectos, ingenieros y otros equipos implicados.

Pero, al final, te das cuenta de que resolver problemas no siempre es tan sencillo como parece desde fuera.

De repente, unas tareas pasan a ser más importantes que otras.

Puede surgir algo del lado del negocio a mitad del sprint.

Cambia un requisito.

Se mueve una fecha límite.

Aparece una dependencia.

Y ahora tienes que replantearte cuál de las diez preguntas que tienes delante necesita respuesta primero.

Así que aprender en la industria puede ser bastante desordenado.

Buscas lo que necesitas en ese momento.

Lo pruebas enseguida en tu entorno de pruebas.

Si funciona, genial.

Quizá empiezas a incorporarlo poco a poco al código o a la configuración.

Después vuelves a probarlo.

Revisas los registros.

Ejecutas las pruebas unitarias.

Haces pruebas de aceptación operativa, o cualquier otro proceso de validación que tengas.

Si todo parece correcto y no empiezan a saltar alarmas en los registros, quizá termine llegando a producción.

Ah, y aquí viene la parte divertida:

Tienes que terminar todo esto en cuatro sprints o menos.

Sin presión.

Ahora bien, estas situaciones pueden introducir lo que llamamos deuda técnica.

Suele ocurrir cuando eliges hoy una solución más rápida o más fácil, sabiendo que probablemente tendrás que revisarla o mejorarla después.

¿Es mala la deuda técnica?

Sí.

No.

No lo sé.

Supongo que la verdadera respuesta es: depende.

A veces, sencillamente, no puedes hacer que algo sea perfecto.

Tu solución puede depender de una plataforma gestionada por otro equipo.

Una nueva versión puede cambiar el comportamiento del código.

Otro sistema puede actualizarse.

Los requisitos pueden volver a cambiar.

Siempre habrá factores fuera de tu control.

Y, a veces, poner en marcha una solución que funcione te permite aprender algo que nunca habrías descubierto dedicando otro mes a intentar que todo fuera perfecto.

Cuanto antes falle algo en un entorno controlado, antes podrás entender por qué falló y mejorarlo.

Así que, de una forma extraña, buscamos constantemente maneras de romper cosas de forma segura para averiguar cómo mejorarlas.

Espera. ¿Por dónde iba?​

Ah, sí.

Un cambio en la forma de pensar.

Supongo que he dedicado todo este tiempo a explicar en qué se diferencia el aprendizaje estructurado de aprender cuando ya estás intentando resolver un problema real.

Entonces, ¿debería dejar los cursos y centrarme solo en proyectos?​

No.

Si algo es completamente nuevo para ti, sigues necesitando alguna base.

Y los cursos son muy buenos para eso.

Te dan herramientas básicas que quizá necesites más adelante.

Te muestran lo que es posible.

Te presentan la terminología.

Te dan suficiente conocimiento como para saber, al menos, qué buscar cuando todo se rompa.

Luego, en algún punto del camino, empiezas a usar esas herramientas para responder tus propias preguntas.

A veces seguirás utilizándolas.

Otras descubrirás que la herramienta que aprendiste no es la mejor para el problema que tienes delante.

Así que la dejas y aprendes otra.

Y no pasa nada.

Sigo confundido​

Bueno, no eres el único.

Yo tampoco he resuelto todo esto.

Sigo teniendo en el portátil una cantidad absurda de cursos sin terminar.

Y, como el tiempo es limitado, he ido desarrollando mi propia estrategia para aprender cosas y aplicarlas de verdad.

Si mi objetivo es hacer un examen de certificación, normalmente sigo el curso, hago las prácticas, tomo apuntes y después me preparo con exámenes de prueba.

¿Y cuando apruebo?

Borro el curso.

Sí.

Sin dudarlo.

Llegado ese punto, sé que probablemente no volveré a sentarme a verlo entero.

Si más adelante necesito esa tecnología para un proyecto y me encuentro con un problema, lo más probable es que busque directamente ese problema.

Y, sinceramente, lo prefiero así.

En vez de repasar horas de vídeo, puedo buscar exactamente lo que necesito.

Es un poco como recoger manzanas.

Coges las que necesitas y dejas el resto del árbol en paz.

Lo importante es que, durante la etapa de descubrimiento y repaso, utilicé el curso para construir una base.

Aprendí lo suficiente para conocer la terminología.

Aprendí lo suficiente para comprender los conceptos básicos.

Y, con suerte, aprendí lo suficiente para reconocer lo que no sé.

Después llega la etapa de aplicación.

Ahí empiezo a depender más de mis propias herramientas.

Mis apuntes.

La documentación.

Los experimentos.

Y, por supuesto, mi Google-fu.

Ahora mismo estoy preparándome para hacer el RHCSA el año que viene.

Así que, para entonces, espero haber eliminado la mayoría de los cursos de RHEL que tengo en el disco duro.

Al borrarlos, también me obligo a pensar por mi cuenta en vez de volver constantemente a copiar los pasos exactos del instructor.

Si quiero recordar cómo hice una práctica, consulto mis apuntes.

Si no está ahí, probablemente esté en algún lugar de la documentación oficial.

¿Y si tampoco está?

Bueno.

Google seguramente conoce a alguien que lo sabe.

Vale, creo que lo he entendido​

Si es así, probablemente ya me lleves un paso de ventaja.

Repito: no tengo todas las respuestas.

La mitad del tiempo ni siquiera sé todavía cuáles son las preguntas correctas.

Pero espero ir entendiendo más a medida que continúe.

Haré más prácticas.

Romperé más código.

Seguiré más registros en tiempo real.

Probaré soluciones que no funcionen.

Y acabaré encontrando otras que sí.

Después documentaré lo ocurrido para, quizá, no tener que sufrir dos veces el mismo problema.

Y, en algún punto de ese proceso, algo cambia.

Dejas de preguntar únicamente: «¿Qué debería aprender ahora?».

Y empiezas a preguntar: «¿Qué necesito para resolver esto?».

Ese, creo, es el verdadero cambio de mentalidad.

Pasar de ser alguien que aprende a alguien que resuelve problemas.

Y quizá, después de resolver suficientes problemas, acabes entrando en otra forma de aprendizaje:

Transmitir lo que has aprendido a otra persona.

El día del examen

· 7 min de lectura

Comparto mis apuntes y reflexiones sobre el examen AWS SysOps Administrator Associate.

Ilustración del artículo

Antes que nada, quiero decir que resulta sumamente útil presentarse primero al examen AWS Solutions Architect Associate antes de abordar los otros dos exámenes de nivel Associate: SysOps Associate y Developer Associate.

Hacer primero el examen de Solutions Architect te ayuda a entender cómo funcionan los distintos servicios de AWS, cómo se conectan y cómo se utilizan para construir soluciones.

Como con cualquier habilidad, creo que es importante empezar por lo básico.

Aprende la teoría.

Experimenta.

Rompe cosas.

Y después intenta arreglarlas.

Una vez que entiendes bien cómo se diseñan las soluciones, puedes empezar a aprender a operarlas y mantenerlas.

Y ahí entra AWS SysOps Administrator Associate.

Ilustración sobre AWS

Para darte algo de contexto, empecé mi carrera en redes informáticas, trabajando con routers, switches y herramientas de gestión de redes.

También pasé un breve periodo en soporte de aplicaciones en una empresa de tecnología financiera, y en mi anterior trabajo tuve la oportunidad de trabajar con servidores Linux.

En conjunto, diría que soy más bien alguien de infraestructura con un poco de programación.

Aunque todavía sigo en construcción.

Me quedan muchas tecnologías por aprender, así que intento participar en tantos proyectos de Linux y Python como puedo.

La automatización sigue siendo un concepto relativamente nuevo para mí, pero poco a poco me siento más cómodo creando mis propios scripts y procesos.

Ilustración sobre el aprendizaje

Mi recorrido por AWS empezó con el examen AWS Cloud Practitioner en agosto pasado.

Luego, 29 días después, me presenté al examen AWS Solutions Architect Associate.

Después puse la mira en SysOps.

Por desgracia, en ese momento había otras cosas del trabajo que requerían mi atención, así que tuve que aparcar los estudios de SysOps un tiempo.

Retomé el repaso entre enero y febrero y decidí empezar a publicar mis apuntes en GitHub.

Por esas fechas también surgieron algunas dificultades personales en casa que me frenaron un poco.

Aun así, intenté recomponerme, seguir adelante con la misión y fijarme el objetivo de hacer el examen en marzo.

Poco sabía entonces que acabaría posponiéndolo otros dos meses.

En mi primer intento tuve problemas con la conexión a internet y el supervisor canceló el examen mientras esperaba a que se cargara la ventana de la prueba.

Ya había hecho varios exámenes de certificación en línea con Pearson VUE, pero era la primera vez que cerraban uno sin avisarme antes.

Informé del problema y, unos cuatro días después, me devolvieron tanto el importe del examen como el cupón que había utilizado.

Como iba algo justo de presupuesto, esperé a recibir el reembolso antes de programar el segundo intento.

Y llegó el 24 de mayo.

Preparé el escritorio de casa, despejé la mente y me senté a hacer el examen.

La verdad es que recé con ganas para que esta vez todo funcionara, porque ya había dedicado muchísimo tiempo a prepararlo.

Tras unos 48 minutos, envié la respuesta a la pregunta 65.

Unos clics más tarde, apareció el resultado delante de mí.

RESULTADO: APROBADO

Y, vaya, qué bien sabe esa victoria.

Apuntes que quizá te ayuden​

Por supuesto, es bastante probable que hayas encontrado este artículo buscando apuntes y consejos para preparar el examen AWS SysOps Administrator Associate.

Así que sí, también los incluyo aquí.

Puedes encontrar mis apuntes de GitHub aquí.

No olvides revisar también los resúmenes.

Estos fueron los materiales en los que me centré:

Por dónde empezar​

Yo recomendaría empezar por el curso de Stephane Maarek o por el de Neal Davis.

Sinceramente, completar uno de los dos ya debería aportarte mucho.

Yo hice ambos porque tienen enfoques algo distintos y me gustaba la idea de que uno cubriera los detalles que pudiera haber pasado por alto en el otro.

Pero no te limites a ver vídeos.

Asegúrate de pasar tiempo de verdad dentro de la consola de AWS.

Creo que es imprescindible familiarizarse con las pestañas, opciones, menús y ajustes, porque verlos y utilizarlos ayuda a afianzar los conceptos que aprendes en los cursos.

Y, además de seguir las prácticas, intenta romper algunas de las cosas que construyas.

En serio.

Rómpelas.

Y luego averigua cómo arreglarlas.

Así no te limitas a memorizar los pasos de un tutorial. También entrenas tu capacidad para diagnosticar problemas, consultar documentación y aprovechar tus habilidades de búsqueda.

Una vez que hayas terminado el curso y te muevas con soltura por la consola de AWS, puedes pasar a los exámenes de práctica.

Puedes probar los de Maarek y Davis, también disponibles en Udemy, y combinarlos con las pruebas de Tutorials Dojo.

Algo que me gustó mucho de los exámenes de Tutorials Dojo es que cada pregunta viene con una explicación de las respuestas correctas e incorrectas.

No memorices solo qué opción es la correcta.

Lee las explicaciones.

Entiende por qué una respuesta funciona y las otras no.

Hay preguntas en las que más de una respuesta parece razonable a primera vista, así que es muy importante comprender las diferencias.

Por último, complementa los cursos y los exámenes de práctica con la documentación oficial de AWS.

Por supuesto, no podrás leer todas las páginas de documentación de cada servicio.

Probablemente perderías la cabeza intentándolo.

Pero leer la documentación oficial de los servicios y conceptos que te cuestan sí puede ayudarte a cubrir las lagunas.

REFLEXIONES FINALES​

Pensé en poner esta sección al principio porque creo que es algo que deberías tener claro antes incluso de empezar a estudiar.

Hazte todas estas preguntas.

¿Por qué quieres hacer el examen?​

Quizá sea para avanzar en tu carrera.

Quizá quieras aprender una habilidad nueva.

Quizá estés intentando entrar en un puesto relacionado con la nube.

Quizá simplemente sientas mucha curiosidad por AWS.

Sea cual sea tu razón, creo que es importante conocerla, porque determinará cómo afrontas todo el proceso de aprendizaje.

No hagas el examen solo por conseguir la certificación o la insignia​

Está bien tener una certificación, pero, en cualquier puesto relacionado con la nube, tarde o temprano tendrás que respaldarla con habilidades y experiencia reales.

Y la única forma de hacerlo es construir algo.

No tiene que ser enorme.

No tiene que ser una arquitectura disparatada, lista para producción y con veinte servicios de AWS.

Simplemente construye.

Rompe cosas.

Arréglalas.

Vuelve a probar algo.

Manos a la obra.

Yo sigo en esa misma búsqueda, intentando conocer tantas tecnologías de la nube como sea posible.

Y sería estupendo que más personas se subieran al mismo tren.

Aprende por el placer de aprender​

Aprende porque algo te despierta muchísima curiosidad.

Aprende porque hay algo que todavía no entiendes y quieres descubrirlo.

Si consigues mantener esa mentalidad, creo que llegarás lejos en lo que decidas emprender.

¡Y ahora, a disfrutar aprendiendo!

Los 100: Días después

· 8 min de lectura

Hola. Si estás leyendo esto, probablemente seas una de esas cien personas que ahora mismo buscan algo de motivación y que, de alguna manera, se toparon con la inspiradora imagen de este artículo.

Luego leíste el título y te preguntaste de qué va este blog tan genial.

Ilustración del artículo

Bueno, antes que nada, quiero aclarar que esto no trata sobre la emocionante serie de ciencia ficción The 100.

Aunque te recomendaría verla. Seguro que te atrapan su ambiente posapocalíptico, la forma en que la humanidad intenta reconstruir la sociedad y cómo la serie pone a prueba tus ideas sobre el liderazgo y las decisiones cuando apenas quedan buenas opciones.

La verdad es que no empecé a disfrutarla de verdad hasta el cuarto episodio, más o menos.

Y, de alguna manera, acabé aplaudiendo al llegar al final de la quinta temporada.

Dato curioso: el primer episodio de la quinta temporada se llama «Eden».

Imagen de la serie

En fin, ¿por dónde iba?

Ah, sí. De qué trata realmente este artículo tan genial.

Vale, un poco de contexto.

Empecé el reto #100DaysOfCode el 6 de noviembre de 2020, y hoy puedo decir con orgullo que lo he conseguido.

He completado los 100 días.

Entonces, ¿de qué demonios va esto?​

He estado leyendo blogs de desarrolladores y he visto mencionar mucho el reto #100DaysOfCode.

La idea es bastante sencilla.

Programas de forma constante durante 100 días consecutivos y publicas tus avances en Twitter, o en la red social que uses, con la etiqueta #100DaysOfCode.

No hay reglas estrictas sobre qué lenguaje debes usar ni qué tipo de proyectos debes construir.

Solo tienes que seguir haciendo algo cada día durante 100 días.

Como soy un tipo aventurero, reuní todos los cursos que quería estudiar, hice una lista de lo que quería lograr y empecé el día 1 el 6 de noviembre del año pasado.

Incluso escribí un artículo entonces, que puedes leer aquí.

Ilustración del reto

Durante las primeras semanas estaba lleno de entusiasmo.

Seguí con ganas los vídeos y las prácticas de Git for Developers using Github en Coursera, pasé a la introducción de Todd McLeod a Visual Studio Code y después empecé el popular curso de Python de Al Sweigart, Automate the Boring Stuff with Python.

Pude acceder gratis a todos estos cursos gracias a varios cupones de Udemy y a un programa de estudios de Coursera patrocinado por el gobierno.

Así que sí, eso ayudó mucho.

La cuesta arriba​

Por supuesto, sientes esa pequeña oleada de satisfacción cada vez que terminas un cuestionario, una práctica o una etapa del curso.

Por fin aciertas la respuesta.

Terminas el ejercicio.

Ves esa pequeña marca verde.

La vida es buena.

Luego está la otra cara.

Llegas a una práctica que no consigues superar porque es condenadamente difícil.

Pasas horas intentando resolverla, decides dejarla hasta después de dormir, te despiertas a la mañana siguiente, abres exactamente la misma práctica...

Y sigues atascado.

Solo que en otro día.

Ilustración sobre quedarse atascado

También ves la madriguera, pero nunca llegas al fondo​

Otra cosa que me resultó agotadora fue lidiar con problemas inesperados.

Cada vez que algo no funcionaba, buscaba el error en Google, abría los primeros tres o cinco enlaces y empezaba a probar las soluciones sugeridas.

A veces funcionaba alguna.

La mayoría de las veces, una solución solo me daba un mensaje de error completamente distinto.

Así que, naturalmente, también buscaba ese nuevo error.

Luego leía otros cuantos enlaces.

Veía un vídeo en YouTube.

Probaba otro comando.

Recibía otro error.

Volvía a buscar.

Y, antes de darte cuenta, te has adentrado mucho en una madriguera.

Solo querías resolver un problemita, pero, de alguna manera, has descubierto otros cinco por el camino.

Ilustración sobre las búsquedas interminables

Pero ¿sabes qué?

De tanto excavar en madrigueras salió algo bueno.

Empecé a darme cuenta de cuándo los problemas nuevos me estaban alejando poco a poco del que realmente quería resolver.

Y, cuando eso ocurría, aprendí a parar, ordenar mis ideas y preguntarme si de verdad necesitaba seguir excavando.

Un ejemplo fue cuando un instructor de KodeKloud estaba instalando Docker en su máquina Ubuntu mientras yo usaba una instancia EC2 con RHEL 8.

Me apareció un error al utilizar uno de los scripts de instalación rápida del sitio de Docker.

La verdad es que ya no recuerdo el error exacto.

Pero tenía la sensación de que podía estar relacionado con RHEL 8.

Nunca llegué a confirmarlo porque, en vez de seguir buscando el error en Google, decidí comprobar si AWS tenía una AMI de RHEL 7 disponible.

Por desgracia, no la tenía.

Así que probé con CentOS.

¿Y sabes qué?

Todo funcionó.

Así que supongo que, con el tiempo, desarrollas una especie de extraño sentido sobrehumano para detectar cuándo un problema está a punto de llevarte por una madriguera interminable de mensajes de error.

Entonces decides si merece la pena seguir por ahí o si existe otra forma de llegar a donde necesitas sin perder otras tres horas.

Por cierto, en algún momento también aprendí el término deuda técnica.

Aunque no diría que se aplica a todas las situaciones de este tipo.

Lo que sí aprendí es que no deberías dejar que se acumule indefinidamente, porque tarde o temprano volverá para darte una buena mordida en el trasero.

Quizá algún día haga una pequeña búsqueda para averiguar por qué aquel script de Docker no funcionaba en RHEL 8.

Ya sabes.

Para cerrar el tema.

La realidad se hace sentir​

Pasaron unas semanas y llegó mi primer bajón.

Seguía haciendo prácticas, pero ya no terminaba tantas como antes.

Había mucho trabajo en ese momento, y el esfuerzo mental adicional de estudiar y hacer prácticas por mi cuenta empezaba a pasar factura.

Así que reduje la actividad durante unos días.

Por mucho que quisiera parar y descansar del todo, ese pequeño cabr*n dentro de mi cabeza no me dejaba abandonar el reto.

Tampoco pude seguir el plan original del día 1.

Por ejemplo, al final no hice otro curso de desarrollo web porque decidí centrarme más en la automatización.

El segundo y tercer mes fueron una especie de montaña rusa.

En total, tuve unos tres periodos en los que bajé mucho el ritmo.

Y debo admitir que hubo bastantes dudas durante aquellos 100 días.

Hubo momentos en que me pregunté de verdad si todo ese esfuerzo serviría para algo.

Quizá estaba perdiendo el tiempo.

Quizá nada de esto me ayudaría.

Quizá las cosas no saldrían como esperaba.

Y, por extraño que parezca, no intenté expulsar esos pensamientos por completo.

Les di espacio.

Dejé que se quedaran en mi cabeza.

Pero, de alguna manera, había una versión testaruda de mí que se negaba a tirar la toalla.

¿Y sabes qué?

Consiguió vencer esos miedos cada vez.

Ilustración sobre perseverar

Para cerrar este capítulo​

Ahora que por fin han terminado los 100 días, he repasado todos mis tuits desde el principio y me he permitido descansar un poco.

Sé que no he producido una enorme cantidad de proyectos.

Pero, al mirar atrás, sí aprendí mucho sobre Linux, Python, Git, automatización e incluso sobre mi manera de abordar los problemas en general.

Y, por extraño que parezca, después de todo, los 100 días se me hicieron cortos.

Por eso he decidido emprender otra aventura.

Segunda ronda del reto #100Days.

Solo que esta vez me lanzo a dos retos a la vez:

  • #100DaysOfCode
  • #100DaysOfFit

El #100DaysOfCode continuará, básicamente, donde acabó la primera ronda, pero esta vez me limitaré a temas más relacionados con mi trabajo actual:

  • Apache Kafka
  • Docker y Kubernetes
  • Python para automatización
  • AWS SysOps, aunque esto es más bien un objetivo personal

Luego está #100DaysOfFit, que en realidad son dos retos más pequeños que decidí unir:

  • 100 días de ayuno: mantener un ayuno de 16 horas de forma constante
  • 100 días corriendo: correr al menos 30 minutos, al aire libre o en una cinta

De nuevo, no espero que todo vaya como la seda durante los próximos 100 días.

Será difícil.

Probablemente me sentiré abrumado de vez en cuando, sobre todo cuando la vida decida intervenir.

Seguramente volveré a atascarme con otro problema.

Seguramente pasaré tardes enteras enterrado en documentación.

Y sin duda habrá días en los que me dé demasiada pereza leer y decida ver vídeos de YouTube.

Probablemente surgirán muchas preguntas al empezar otra vez.

Pero espero que al final también me esperen menos «¿y si...?».

«Puedes hacerlo. Deberías hacerlo. Y si eres lo bastante valiente para empezar, lo harás».

  • Stephen King

Terminar un proceso defunct

· 4 min de lectura

Ilustración del artículo

Me encontré con esto al intentar instalar htop en una de mis instancias EC2 de pruebas con RHEL. Estaba siguiendo los pasos de esta guía.

Esto también me llevó a aprender un poco más sobre los procesos defunct, o zombis, en Linux. Puedes leer más sobre ellos aquí.


Qué ocurrió​

Tenía dos terminales abiertas, ambas conectadas a la misma instancia EC2.

En la primera estaba ejecutando:

yum update -y

Mientras seguía la actualización, intenté instalar otro paquete desde la segunda terminal.

Apareció este mensaje:

Running transaction check
Waiting for process with pid 5941 to finish.

Así que comprobé qué proceso estaba usando el PID 5941:

$ ps -ef | grep 5941

root 5941 5939 18 06:00 pts/0 00:01:42 yum update -y
root 36173 36153 0 06:09 pts/2 00:00:00 grep --color=auto 5941

Efectivamente, el PID 5941 correspondía al proceso yum update que se ejecutaba en la primera terminal.

Como la actualización estaba tardando, decidí cancelarla para instalar primero los paquetes que necesitaba y volver a ejecutarla después.

Pero, al intentar instalar de nuevo el paquete, seguía apareciendo el mismo mensaje sobre el PID 5941.

Al revisar otra vez el proceso, vi algo distinto:

$ ps -ef | grep 5941

root 5941 5939 18 06:00 pts/0 00:01:42 [yum] <defunct>

El proceso yum aparecía ahora como <defunct>.

Naturalmente, lo primero que pensé fue:

kill -9 5941

Problema resuelto, ¿no?

Pues no exactamente.

El proceso seguía apareciendo como <defunct>.

¿Qué significa <defunct>?​

Un proceso marcado como <defunct> ya ha terminado de ejecutarse.

En otras palabras, técnicamente ya no queda nada que terminar.

Cuando un proceso hijo finaliza, su proceso padre debe recoger su estado de salida. Hasta que lo hace, Linux conserva una pequeña entrada del hijo en la tabla de procesos.

Esa entrada restante es lo que llamamos un proceso zombi.

Y, al ejecutar ps, los procesos zombis suelen mostrarse así:

<defunct>

Por eso ejecutar:

kill -9 PID

no lo elimina.

El proceso ya está muerto. SIGKILL no tiene nada que terminar.

Qué hacer​

Primero, localiza el proceso padre del proceso defunct.

Puedes usar:

$ ps -ef | grep defunct

UID PID PPID C STIME TTY TIME CMD
root 5941 5939 6 06:00 pts/0 00:01:42 [yum] <defunct>
eden 36210 6097 0 06:24 pts/2 00:00:00 grep --color=auto defunct

Las columnas importantes son estas:

PID PPID
5941 5939

5941 es el proceso zombi.

5939 es su proceso padre.

Antes de terminar nada, conviene comprobar qué es exactamente ese proceso padre:

ps -fp 5939

Si se puede finalizar de forma segura, puedes intentar detenerlo normalmente:

sudo kill 5939

Después, vuelve a comprobarlo:

ps -ef | grep defunct

Si el padre se resiste a terminar y estás seguro de que es seguro finalizarlo, puedes recurrir a SIGKILL como último recurso:

sudo kill -9 5939

Una vez que finalice el proceso padre, normalmente otro proceso, como init o systemd, debería adoptar y recoger el zombi.

Algo que conviene recordar​

No ejecutes kill -9 de inmediato contra todos los procesos que veas.

Sobre todo al tratar con procesos padre, comprueba siempre primero de qué proceso se trata:

ps -fp <PPID>

Un proceso defunct no está consumiendo CPU ni ejecutándose activamente. Es, en esencia, una entrada que espera a que su padre reconozca que ya ha terminado.

Así que, si alguna vez ves:

[process] <defunct>

recuerda:

El proceso ya está muerto. Lo que realmente debes investigar es su padre.


Referencias​

Día 1: ¿Por dónde empezar?

· 7 min de lectura

Ilustración del art�ículo

DÍA 1: ¿Por dónde empezar?

El reto #100DaysOfCode es uno de esos objetivos que he pospuesto varias veces, ya fuera por falta de tiempo o por alguna carga de trabajo que tenía pendiente.

De hecho, hubo algunas veces en las que empecé el reto y lo dejé después de una semana porque, bueno, sencillamente todavía no sabía lo suficiente.

Lo que quiero decir es que mi forma de aprender nunca fue muy estructurada. En vez de estudiar los fundamentos de una habilidad, solía saltar directamente a lo que necesitaba para resolver el problema que tenía delante.

Y sí, es una manera eficiente de hacer que algo funcione rápido. Pero no es demasiado sostenible. Tarde o temprano, la falta de bases te alcanza.

Puede que consigas resolver un problema, pero, cuando algo vuelve a fallar, de pronto te das cuenta de que no entiendes del todo por qué funcionó aquella solución.

No puedes saltarte el proceso​

Ilustración sobre el proceso de aprendizaje

Otra cosa que siempre se ha interpuesto es mi propia manera de pensar.

Era más joven, tenía poca experiencia, pero mucho entusiasmo y empeño para lanzarme a los retos sin revisar antes qué hacía falta.

De verdad: de niño era divertido enfrentarse a cualquier cosa que te lanzara el mundo, porque así se enfrentan los niños a las cosas. Sin tonterías. Sin complicarse. Solo por diversión.

Pero, de adulto, o al menos de veintitantos, no siempre puedes agarrar un problema e intentar resolverlo sin examinarlo con cuidado primero. Para empezar, nuestras acciones tienen consecuencias.

Por pequeño que creamos que es un efecto, el verdadero problema comienza cuando esos efectos se encadenan y bajan como una bola de nieve por una montaña empinada.

Un día crees que no necesitas aprender estructuras de datos y algoritmos porque ya has conseguido montar un script con fragmentos de varias fuentes de internet.

Y al día siguiente te encuentras de frente con un problema que nadie ha preguntado todavía en Stack Overflow.

Ilustración sobre resolver problemas

No puedes saltarte el proceso.

Puede parecer que aprender algo bien lleva más tiempo, pero oye, no se mueven montañas a la fuerza. Lo que haces es dividir el Everest en sus piezas más pequeñas y moverlo piedra a piedra.

Cambiar de lugar​

He pasado a puestos para los que estaba solo parcialmente cualificado o, sinceramente, para los que no estaba cualificado en absoluto.

Supongo que el entusiasmo y la perseverancia me ayudaron a conseguir esos trabajos, pero he aprendido que los fundamentos siempre vuelven. Estás investigando un problema y, de pronto, otra vez estás buscando lo básico en internet.

Bueno, quizá exagero un poco cuando digo que nunca me preocupé por aprender los fundamentos de nada.

Sí empecé desde lo más básico de redes cuando volví a estudiarlo todo para mi CCNA el año pasado. Fue muy satisfactorio comprender bien las subredes, cómo funcionan las redes y cómo el enrutamiento permite que los datos lleguen a su destino.

Pero también sé que las redes son solo una de las bases que debería tener un profesional de TI.

Y, a medida que descubro más sobre el mundo de DevOps, he aceptado que saber de redes no basta si de verdad quiero tener éxito como ingeniero de DevOps o de la nube.

Por eso empecé a aprender Linux el pasado febrero.

Resultó bastante útil cuando pasé a mi trabajo actual, donde me encargo de algunos de nuestros sistemas de gestión de redes. Todas esas herramientas NMS están alojadas en servidores Linux Red Hat 7 con los que he tenido la suerte de experimentar.

Bueno, sobre todo en los servidores de laboratorio.

Practicar en servidores de producción es, obviamente, un NO rotundo.

Ilustración sobre los servidores de producción

Vale, creo que ya basta de historia y de memes.

Ya he dedicado más o menos una hora a investigar en qué me centraré durante este reto y, por supuesto, a buscar los estupendos memes que pondré aquí.

Por ahora, he reducido mi lista a esto:

  1. Estandarizar mis convenciones de nombres: Sí, sé que parece algo bastante trivial, pero creo que ayudará a largo plazo, sobre todo si algún día vuelvo a revisar mis archivos antiguos.

  2. Linux: Todavía me considero relativamente nuevo en Linux, pero ahora estoy mucho más cómodo trabajando en servidores Linux y en mis máquinas virtuales. Solo han pasado unos meses desde que me metí de lleno, así que todavía queda mucho por aprender.

    Otro buen lugar para practicar Linux es KodeKloud. Entra en www.kodekloud-engineer.com, crea una cuenta e intenta completar tu primera tarea de administración de sistemas.

  3. Git: Ya tengo una cuenta de Git y he aprendido a trabajar con mis repositorios locales, pero todavía no sé trabajar bien con GitHub.

    Así que sí, el día 1 será para Git y GitHub.

    Para ello usaré un proyecto guiado de Coursera llamado Git for Developers Using GitHub, que puedes encontrar aquí:

    https://www.coursera.org/learn/git-for-developers-using-github/

  4. Python: Entre tantos lenguajes, he decidido centrarme en Python durante, supongo, los primeros 50 días.

    Eso incluirá resolver problemas en HackerRank y trabajar de verdad en proyectos.

    Python es un lenguaje bastante cercano para mí porque llevamos un tiempo con una relación intermitente. Hay temporadas en las que me concentro mucho en hacer cosas con Python y luego paro de repente porque tengo otra carga de trabajo o porque estoy preparando otro examen de certificación.

    Esta vez quiero ser más constante.

    Usaré el certificado profesional Google IT Automation with Python de Coursera:

    https://www.coursera.org/professional-certificates/google-it-automation

Certificado profesional Google IT Automation with Python​

Para volver a aprender Python como es debido, empiezo con el Google IT Automation with Python Professional Certificate de Coursera, que se compone de seis cursos.

La plataforma indica que puede completarse en ocho meses dedicándole unas cuatro horas de estudio a la semana.

Como pienso trabajar en esto a diario, incluidos los fines de semana, y normalmente veo los vídeos al doble de velocidad, mi objetivo es terminar el certificado completo en unos dos meses.

Eso sí, a lo que realmente quiero dedicar más tiempo es a los ejercicios prácticos.

De momento, sigue siendo un plan aproximado.

Si has leído la sección de Python de arriba, esto es solo lo que tengo previsto para la primera mitad de los 100 días.

Para la segunda mitad, quiero trabajar en desarrollo web.

Puede que digas que 50 días son muy pocos para terminar ese curso.

Y sí, probablemente tengas razón.

Simplemente terminaré lo que pueda entre el día 50 y el 100. Lo que quede, lo continuaré en mi próximo #100DaysOfCode.

En definitiva, creo que este reto #100DaysOfCode es, para mí, más bien un reto de constancia.

Quiero comprometerme de verdad con algo y seguir hasta alcanzar cierto nivel de dominio.

Por supuesto, convertirse en experto lleva mucho más de 100 días. Pero creo que estos 100 días pueden, al menos, ponerme en el camino adecuado.

Además, todavía no tengo muy claro dónde publicaré todo esto, porque he abierto mis cuentas de Twitter e Instagram hace poco.

Supongo que usaré ambas.

El problema de Twitter es el límite de caracteres, así que quizá tenga que dividir las publicaciones: poner la primera mitad en el tuit principal y continuar en las respuestas.

O podría publicar todo también en dev.to o Hashnode.

Lo único que me preocupa es si todas las imágenes que pongo aquí se verán bien en esas plataformas.

En cuanto a Instagram...

Sí, eso todavía no lo tengo resuelto.

Y una última cosa: mis próximas publicaciones o tuits probablemente serán mucho más cortos. Serán, sobre todo, actualizaciones sobre cómo fue el reto ese día.

Luego, quizá al final de cada mes, haga un resumen más largo como punto de control y lo publique en dev.to, Hashnode o freeCodeCamp.

Bien.

Entonces, día 1. ¿Por dónde empezar?

Sí.

Git.

Programar es fácil, ¿a que sí?

· 8 min de lectura

Mi forma de entender la programación. También he incluido algunos conceptos fundamentales que creo que todos deberían conocer cuando empiezan a adentrarse en el código.

Para empezar, quiero decirte que has hecho bien en abrir este artículo.

Ilustración del artículo

Puede que lleves jugando con el código desde pequeño, o que simplemente hayas seguido una cadena de enlaces interesantes en Google y, de alguna manera, hayas acabado con ganas de aprender más sobre programación.

En cualquier caso, seguramente hay una idea, o más bien una pregunta, rondándote la cabeza:

¿De verdad es fácil programar?

Bueno, intentemos responder esa pregunta de una vez por todas.

Programar es relativamente fácil.

Repítelo conmigo.

Sí, en gran medida, programar consiste en juntar palabras clave e instrucciones en líneas que el ordenador pueda entender, y luego pasar a la siguiente línea.

Algo así como formar una oración.

Pero ¿de verdad es solo eso?

Piensa en cómo formas una oración en inglés. Hay ciertas reglas que debes seguir. Tienes que pensar qué tiempo verbal usar, desde qué punto de vista escribes, dónde van las palabras y con qué signo de puntuación terminar.

La programación funciona de manera parecida.

Tienes unas reglas, un vocabulario y una estructura que debes seguir.

Por supuesto, hay otros conceptos fundamentales que conviene entender antes de empezar a crear tus propios programas.

¿Cómo se dice?​

Cuando empiezas a aprender un idioma nuevo, por ejemplo japonés, puede que esta sea tu reacción al encontrarte por primera vez con los kanji:

Ilustración sobre aprender un idioma

Parece complicado, así que debe de ser complicado.

Pero no es tan difícil cuando das los primeros pasos y empiezas a aprender lo básico.

Todo puede resultar confuso y frustrante la primera vez. Pero, cuando empiezas a descomponerlo en piezas y a entender cómo funcionan juntas, las cosas poco a poco cobran sentido.

Y, con el tiempo, se convierte en pan comido.

Lo que vino antes​

Sea cual sea el lenguaje de programación que intentes aprender, notarás que muchos comparten ideas similares.

Los lenguajes suelen crearse para resolver determinados problemas, introducir nuevas formas de hacer las cosas o superar limitaciones de lenguajes anteriores.

Por eso, los lenguajes más nuevos suelen tomar conceptos, técnicas e incluso sintaxis de los antiguos.

Por supuesto, no todos funcionan exactamente igual, pero, una vez que aprendes los fundamentos de un lenguaje, probablemente reconocerás muchos conceptos familiares al pasar a otro.

Así que podría decirse que los lenguajes de programación hablan de formas distintas, pero muchos piensan de manera parecida.

En el fondo​

Como he mencionado, muchos lenguajes comparten los mismos conceptos básicos. La principal diferencia suele ser cómo se escriben o se implementan.

Estas son algunas de las cosas que encontrarás casi en todas partes.

  • Sintaxis

    Recuerda que cada lenguaje tiene sus propias reglas.

    Pueden estar influidas por lenguajes anteriores, pero cada uno tiene su propia manera de escribir instrucciones.

    Ejemplo de sintaxis

    Cuando leíste el título de este artículo en inglés, quizá notaste que había algo un poco raro en cómo estaba escrito.

    Si fue así, enhorabuena. Ya entiendes la idea básica de la sintaxis.

    La sintaxis es, en esencia, el conjunto de reglas que te dice cómo debe escribirse algo.

    Entonces, programar sí que es fácil, ¿verdad? 😄

  • Variables

    La idea principal de las variables es asociar un valor con un nombre.

    Piensa en una variable como un recipiente con etiqueta en el que puedes guardar información para usarla después.

    Puedes cambiar esos valores, pasarlos de un lugar a otro, compararlos, hacer cálculos con ellos, mostrarlos y utilizarlos a lo largo de tu programa.

    Por ejemplo, en vez de escribir una y otra vez la edad de una persona como 25, podrías asignar ese valor a una variable llamada age.

    A partir de ahí, el programa puede referirse a age cada vez que necesite ese valor.

    Ejemplo de variables

  • Mostrar resultados

    Mostrar un resultado consiste, básicamente, en decirle al programa que presente algo como salida.

    Puede ser el resultado de un cálculo, el valor de una variable, un mensaje o prácticamente cualquier cosa que quieras que vea el usuario o el programador.

    Quizá escuches a los programadores decir algo como:

    «El código devolvió este valor».

    Lo que suelen querer decir es que, después de procesar las instrucciones, el programa produjo algún resultado.

    Pero los programas no siempre muestran esos resultados automáticamente.

    A veces el cálculo ocurre en segundo plano y, si quieres ver el resultado, debes indicarle al programa expresamente que lo imprima o lo muestre.

    Probablemente ya viste un adelanto de esto en el ejemplo de variables de arriba.

    Ejemplo de salida del programa

  • Comentarios

    Los comentarios son notas que los programadores dejan dentro del código.

    Sirven para explicar qué hace una sección, por qué se escribió de una manera determinada, qué representa una variable o cualquier otra cosa útil para quien lea el código después.

    Y sí, esa persona podrías ser tú dentro de seis meses, preguntándote:

    «¿Por qué demonios escribí esto?».

    El programa no procesa los comentarios como instrucciones.

    Cada lenguaje tiene su propia forma de marcar los comentarios.

    En Python, por ejemplo, puedes poner un # al principio de una línea para indicar que es un comentario y que no debe ejecutarse.

    Ejemplo de comentarios

  • Cadenas de texto

    Antes hablamos de los comentarios y de cómo Python reconoce una línea que empieza con # como algo que no debe ejecutarse.

    Pero ¿y si quieres que tu programa trabaje con palabras u oraciones?

    Ahí entran las cadenas de texto.

    Una cadena es, básicamente, texto almacenado como datos.

    Ejemplo de cadenas de texto

    Cuando asignas texto a una variable, normalmente lo rodeas de comillas para que el lenguaje sepa que está tratando con texto y no con otra instrucción.

    También puedes combinar cadenas con otros valores mediante el formateo.

    Por ejemplo, si tienes una variable con el nombre de alguien, puedes insertar su valor en una oración en vez de escribir el nombre manualmente cada vez.

  • Arreglos

    Un arreglo es, básicamente, una colección de valores agrupados.

    En vez de crear una variable diferente para cada dato, puedes guardar varios valores relacionados en una sola colección.

    Según el lenguaje, estas colecciones pueden contener números, cadenas, objetos o incluso otras colecciones.

    Python, por ejemplo, suele utilizar algo llamado lista para este propósito.

    Ejemplo de listas

    También es importante entender que los valores dentro de estas colecciones ocupan posiciones.

    Así que, si solo quieres un valor concreto, no necesitas recuperar todo. Puedes referirte a su posición, normalmente mediante lo que llamamos un índice.

    Por ejemplo, si tienes una lista de cinco nombres y solo necesitas el primero, puedes acceder directamente a ese elemento.

    Y aquí va algo que al principio puede resultar extraño:

    En muchos lenguajes de programación, la cuenta empieza en 0, no en 1.

    Bienvenido a la programación.

Espera, hay más​

A estas alturas, espero que entiendas mejor por qué digo que programar es relativamente fácil.

Mucha gente se centra de inmediato en esta pregunta:

¿Qué lenguaje de programación debería aprender primero?

Y está perfectamente bien.

Pero creo que es más importante entender los conceptos que los lenguajes tienen en común.

Una vez que entiendes ideas como variables, sintaxis, cadenas, colecciones, condiciones, bucles y funciones, pasar de un lenguaje a otro resulta mucho menos intimidante.

La sintaxis puede cambiar.

Las palabras clave pueden cambiar.

Pero las ideas generales suelen seguir ahí.

Si quieres conocer algunas cosas que puedes explorar antes de adentrarte de lleno en la programación, puedes consultar el curso de Evan Kimbrell en Udemy, Pre-Programming: Everything you need to know before you code.

Desde luego, puedes lanzarte directamente al lenguaje que te interese.

Pero si no tienes un perfil técnico y has empezado a interesarte por la programación hace poco, creo que aprender primero estas ideas básicas puede hacer que todo resulte mucho menos abrumador.

Porque programar en sí no es la parte que da miedo.

Lo difícil suele ser averiguar qué quieres que haga el ordenador y descomponer ese problema en instrucciones que pueda entender.

Cuando te acostumbras a hacerlo, el código empieza a tener mucho más sentido.

Como siempre, ¡que disfrutes aprendiendo!

Pensar como un desarrollador

· 3 min de lectura

Ilustración del artículo

Haz las preguntas adecuadas​

Cuando te planteen un problema, asegúrate de hacer las preguntas correctas. Puede que al principio no se te ocurran todas porque todavía no dispones de todos los datos, pero, a medida que ganes experiencia, desarrollarás una idea de cómo deberían arrancar los proyectos y acabarás teniendo un conjunto de preguntas habituales para cuando te presenten requisitos de negocio.

Ejemplo:

El responsable del proyecto le dice al equipo:

Necesitamos una función que invierta cualquier cosa que le pasemos.

Las preguntas habituales:

  • ¿Qué significa «cualquier cosa»?

    ¿Qué hay que invertir? En el contexto de las estructuras de datos, solo:

    • Cadenas de texto
    • Números
    • Arreglos

    Los diccionarios no tienen un orden bien definido ni índices, por lo que no se pueden invertir. Los siguientes elementos no pueden invertirse:

    • Diccionarios u objetos
    • Booleanos
  • ¿Qué hacemos si se pasa otra cosa?

    ¿Cómo debemos manejar entradas que no sean cadenas, números ni arreglos?

  • ¿Qué debería devolver la función?

    ¿Debería devolver siempre una cadena? ¿Debería devolver el mismo tipo que recibió?

Divide y vencerás​

Divide un problema grande en partes manejables o problemas más pequeños para que sea mucho más fácil resolverlo. Al descomponerlo, también podemos comprenderlo mejor.

Con el ejemplo anterior, estos serían los pasos para dividir el problema en otros más pequeños:

  • Comprobar si el argumento es una cadena, un número o un arreglo
  • Implementar la inversión de un número
  • Implementar la inversión de una cadena
  • Implementar la inversión de un arreglo
  • Devolver el valor invertido

Investiga todo lo que necesites​

Al principio, deberíamos intentar resolver los problemas pequeños por nuestra cuenta y con nuestras propias capacidades. Sin embargo, si sigues encontrando obstáculos, conviene recurrir a fuentes externas, como Google o Stack Overflow.

En la práctica, lo normal es ir directamente a Google y comprobar si ya existe una solución al problema.

Escribe pseudocódigo​

Para los problemas más grandes, resulta útil escribir alguna forma de pseudocódigo antes del código real. El pseudocódigo es una descripción informal del código. Por ejemplo:

function reverse(value)

if type(value) == string
reverse_value = reverse string
return reverse_value

else if type(value) == number
reverse_value = reverse string
return reverse_value

else if type(value) == array
reverse_value = reverse string
return reverse_value

else
return "Invalidy input type"

A partir de aquí, puedes usar el lenguaje que prefieras, como Python, y seguir este flujo para crear la función.

El proceso de depuración​

  1. Detectar el error

    Darse cuenta de que hay un error. Puede descubrirse:

    • Durante el desarrollo
    • Al probar el software
    • En distintos contextos: navegadores, usuarios, etc.
    • A través de informes de usuarios en producción, el peor caso porque llegó a publicarse sin ser detectado
  2. Localizar el error

    Aislar la parte del código donde se encuentra el error.

    • Aislarlo mediante la consola de desarrollo
    • Para errores complejos, usar un depurador
  3. Corregir el error

    Corregirlo y asegurarse de que no exista en ninguna otra parte del código.

    • Sustituir la solución existente por una que funcione
    • Buscar el error en código similar
    • Escribir pruebas con herramientas de testing