Saltar al contenido principal

5 publicaciones etiquetados con "Apuntes de desarrollo"

Apuntes y reflexiones sobre desarrollo y tecnología

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, has caído hasta el fondo de 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

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