Mi aventura en 42 Silicon Valley

Hace unos meses me animé a postular a [42 Silicon Valley] y creo que tuve suerte para ser aceptado (pues no tuve que dar examen de ingreso) o para conseguir un dormitorio gratis (aquí si tuve que esperar confirmación luego de casi dos meses)

El punto de inicio era participar en [The Piscine], el bootcamp para demostrar luego de un mes que tienes las habilidades necesarias para ingresar [al programa] que además de ser gratuito, tiene una duración de cinco años.

¿En qué consistió el bootcamp?

  • Estudiar todos los días de la semana, la mayor cantidad de horas posibles. Podías usar el material disponible o buscar en internet el material de estudio requerido para cada día.
  • Resolver las asignaciones diarias respetando el orden de cada pregunta (es decir, no puedes continuar si no terminas con una pregunta)
  • Respetar reglas de programación sobre el uso de librerías (muchas no se podían usar, te pedían construir tus propias librerías), número de líneas (25 líneas por programa), número de variables (4 por programa), sentencias (el “for” estaba prohibido) y así…
  • Terminar de programar antes de la hora límite (11.42 de la noche)
  • Tener en cuenta que cada línea de código escrita debería ser fácil de entender
  • Recibir diariamente 2 evaluaciones aleatorias que se hacían de manera presencial, lo cual te obligaba entre otras cosas a defender tu código en inglés (sí o sí tenías que hablar)
  • Realizar diariamente 2 evaluaciones (como dije, sí o sí tenías que hablar)
  • Participar en los trabajos grupales, que si bien es cierto no eran aleatorios, requerían mucha coordinación.
  • Participar en los exámenes semanales, en los que cada viernes te asignaban una computadora que no tenía acceso a internet ni a herramientas como Visual Studio Code, así que si no sabías como usar vim o comandos en Linux, estabas muerto 🙂
  • Tener en cuenta que los tres primeros exámenes durarían 4 horas y el último sería de 8 horas
  • Programar en C
  • No hacer trampa, pues si bien es cierto los problemas se pueden conseguir fácilmente, si no puedes explicarlos o se descubre que ese no es tu código, cosas malas pueden ocurrir (además de que queda en tu registro y te podrían invitarte a salir del programa)

Pues bien, fueron cuatro semanas en las que además de compartir dormitorio con dos amigos de China y uno de Kazajistán, conocí amigos de Rusia, Francia, Argentina, Brasil, China, Korea y USA. Además, en todo ese tiempo aprendí de todo un poco, inclusive como ahorrar tiempo y dinero pues a pesar de vivir gratis en el campus, necesitabas dinero para comer y allá todo era caro :O

Sí, hay una bandera de Perú 😀 y como datos anecdóticos, era el único peruano y la foto muestra a los que quedamos hasta el final pues más del 50% se retiró

¿Qué aprendí?

Además de respirar programación, encontré cosas muy interesantes:

  1. Resiliencia: Si hay una palabra para definir a las personas que conocí en el bootcamp, esa es la primera que podría decir. Muchos amigos tenían unas ganas de superación increibles, algunos trabajaban por las tardes o noches. Otros no lograron conseguir dormitorio, así que viajaban una o dos horas (algunos manejando) para llegar diariamente al campus. Todo por estudiar.
  1. Colaboración: Si bien es cierto encontré casos de segregación de acuerdo al país de origen o similitud de conocimientos, cuando había problemas nadie dudaba en ayudar si te acercabas a preguntar. Algunos lo hacían con muchas más ganas que otros, pero todos terminaban respondiendo al pedido de ayuda.
  1. Empatía: Algunas veces mi evaluador no sabía como decirme que me había equivocado pues le daba pena que eso afectara a mi promedio. Esto lo supe pues me puse a conversar con ellos pidiendo más detalle ya que al igual que todos, quería aprender.
  1. Humildad: Algunas personas sabían lo suficiente como para terminar el trabajo en la mitad del tiempo o menos, pero a pesar de ello ni alardeaban, ni lo demostraban cuando te tocaba evaluar su código o cuando ellos evaluaban el tuyo. Me pasó más de una vez que hubo personas que me para preguntaban como había resuelto un problema y a veces descubrían un error en su lógica o algo por mejorar en ella. Nunca se molestaban, siempre agradecían.
  1. Optimismo: Una frase con la que siempre me encontraba cuando cometía un error era “no te preocupes, es solo un test, mañana lo haremos mejor” Lo genial es que a veces ocurría con personas que acababa de conocer.
  1. Competencia sana: Si bien es cierto todos sabíamos que cada examen semanal era determinante para ser aceptado en el programa oficial y que no todos seríamos aceptados, todos nos animábamos antes de empezar cada evaluación. Al finalizar nos preguntábamos comos fue y hubo casos en los que comparábamos soluciones. En mi caso prefería ir a dormir –pues terminaba muy cansado– pero al día siguiente la conversación seguía 🙂
  1. Comunicación: Si me preguntan cuál es diferenciador con respecto a lo que he visto en el medio local (es decir, Perú), este es un elemento muy importante. Teniendo en cuenta de que los programadores no hablamos mucho, eso también ocurre fuera del país, pero la diferencia es que estando allá, me encontré con personas que además de escribir buen código, explicaban muy bien lo que hacían o en todo caso, sabían vender muy bien sus ideas. Cosa que humildemente tenemos que seguir mejorando.

¿Qué pasó después?

Como mencioné anteriormente, el examen final fue un viernes y tenía una duración de 8 horas, en mi caso terminé de programar en la séptima hora. No recuerdo el número de problemas que resolví pero sí que había programado sin descanso alguno, así que cuando sentí que necesitaba salir de ahí, fue lo que hice. La verdad es que, cuando tu cabeza no da para más, lo mejor es dejar de programar.

A las dos semanas de dar el examen estaba de viaje y con poco acceso a internet, recuerdo que cuando pude conectarme, recibí con mucha sorpresa el correo de aceptación al programa, podía irme a estudiar por tres años y si no tenía donde vivir, podía postular nuevamente para conseguir un dormitorio.

¿Qué es lo que haré?

En esta época de mi vida me gustaría volver a enseñar, mientras tanto estoy retomando mi práctica de escribir y reforzar mis conocimientos en [arquitectura] (es por eso que mi blog ha renacido), además estoy presentando una tesis para conseguir mi maestría en administración y en paralelo a esto, me puse a estudiar mi segunda maestría mientras busco un nuevo empleo.

Creo que estoy algo ocupado por el momento (o quizá algo loco), pero bueno, nunca se sabe 🙂

Un abrazo,

Microservicios y código de ejemplo

Estaba preparando una propuesta de charla de [microservicios] y mientras buscaba información para el código de ejemplo, me di con la sorpresa de que lo que encontraba en la web era de complejidad media/alta (o no se entendía) o peor aún, a pesar de que muchos (podría afirmar que más del 50%) indicaban que se trataban de microservicios, pues no lo eran.

Fuente: [microservices]

¿Cómo confirmas si estás viendo un microservicio?

Siendo concretos, un microservicio debe:

  1. Responder a un solo trabajo, es decir, una sola funcionalidad
  2. Ser autónomo incluso en su instalación

Okey, hay [otras consideraciones] a tomar en cuenta, pero a mi entender si no pasamos los dos primeros filtros, no tiene sentido seguir avanzando.

¿Qué hice al respecto?

Sin ir en muchos detalles, se me ocurrió detener lo que estaba haciendo para ponerme a escribir códigos de ejemplo de microservicios.

Ojo, no me considero un experto pero creo que mi idea es sencilla, crear un proyecto para compartir lo que voy aprendiendo.

¿En qué consiste el proyecto?

El requitisto principal es que el código sea fácil de entender y que además permita aprender a construir microservicios. Es así que lo que tengo en mente hasta ahora es:

  • Una plantilla de código (incluye soporte de HTTP GET)
  • Código de ejemplos para:
    1. Soporte de HTTP GET
    2. Soporte de HTTP GET y parámetros
    3. Soporte de HTTP POST y parámetros
    4. Soporte de HTTP GET y Docker para desplegar el microservicio

Inicialmente pensé en escribir todo en NodeJS pero luego dije ¿Por qué no más lenguajes?

¿Qué he avanzado hasta ahora?

Pues como dije líneas arriba, me animé a escribir algo de código 🙂 El proyecto se llama microservices-templates y ya está en GitHub, aquí la url: https://github.com/jersson/microservices-templates

Si bien es cierto tengo en mente programar en al menos cinco lenguajes, decidí que no podía esperar tanto para liberar algo, así que aquí va la versión en NodeJS: https://github.com/jersson/microservices-templates/tree/master/00-node

Como podrán notar en el código, este incluye descripciones sobre como probar cada microservicio. Además, cada archivo tiene pocas líneas de código y cada una de ellas la he escrito de manera que busqué facilitar su lectura.

Este proyecto me gusta bastante y estoy seguro de que si consigo ayuda podré avanzar más rápido, así que si les interesa aprender o ya saben como escribir o mejorar lo que estoy construyendo, anímense, estaré aquí o en GitHub 🙂

Sin más que decirles me despido esperando que tengan un excelente nuevo año.

Un abrazo.

Fuente imagen cabecera:[what are microservices?]

¿Cómo practicas programación?

Les cuento que casi todo este año tuve el tiempo necesario para programar al menos dos horas al día. En términos simples, programar es uno de los hobbies que he ido desarrollando a lo largo de mi vida 🙂

En fin, como algunos saben, hace unos meses estuve en el bootcamp de [42 Silicon Valley] y si bien es cierto no he tenido la oportunidad de escribir al respecto, puedo adelantar que mi afición por la programación se reforzó de tal manera que ahora veo de forma diferente cualquier lenguaje de programación, estudio mucho más al respecto y si fuera necesario, reviso cómo hacer las cosas con la menor cantidad de librerías y/o frameworks (pues ahora casi todo se resuelve así)

Bueno, para hacer la historia corta, mi interés –y cariño– por el [lenguaje C] ha vuelto, así que he propuesto cuatro problemas que parecen simples, pero si intentas resolverlos con la menor cantidad de código, librerías y además buscas hacerlo entendible, pues ahí llega la complejidad. De estos problemas ya he resuelto dos y los he dejado en un repositorio esperando que alguien quiera unirse para al menos proponer nuevos problemas. Por mi parte ya tengo algunos en mente, pero tengo que ponerlos en limpio.

En fin, si les interesa este es el repositorio que siempre voy actualizando: https://github.com/jersson/c-problems/tree/dev

Ahora, si quieren ver cómo funciona el código y no quieren clonarlo, aquí un espacio para jugar usando el navegador https://repl.it/@jersson1/c-problems. De ser así, tengan especial atención en el archivo .replit

Como ya deben haber notado, la documentación la estoy escribiendo en inglés pues además me pareció buena oportunidad para practicar el idioma 🙂

Espero que puedan unirse y que además pasen unas excelentes fiestas navideñas.

Un abrazo,

Fuente imagen cabecera: http://offeman.com/safe-casting-pointers-in-object-pascal/

¿Qué tanto le debes a tu sistema?

En términos simples, la deuda técnica tiene que ver con el tiempo que tendrías que invertir para solucionar problemas que estás dejando de lado a nombre de generar un resultado en el menor tiempo posible.

Sí, con esto me refiero a las consecuencias del “déjalo ahí, luego lo arreglamos”

Lo que me he encontrado es que esa es una frase que es aceptada hasta que los problemas se empiezan a poner serios. Por otro lado, hay que considerar que si queremos mejorar “algo”, pues tenemos que saber cómo medir ese “algo” antes y después de los cambios realizados.

¿Cómo mido un sistema?

Estoy seguro de que hay muchas formas para eso, pero aquí los pasos que sigo regularmente:

  1. Perspectiva del usuario final
  2. Comportamiento en tiempo real (análisis dinámico de código)
  3. Perspectiva del desarrollador (análisis estático de código)

1. Perspectiva del usuario final

Asumiendo de que el usuario está contento con las funcionalidades existentes y de que no hay errores en producción (Sí, es un gran supuesto), lo que normalmente sugiero es tomar nota del comportamiento de la aplicación.

¿Qué se hace ahí? Pues se mide lo que llega al usuario ¿Cómo medimos la aplicación? Para nuestra suerte, si estamos trabajando con una aplicación web, existen herramientas gratuitas que nos permiten tener reportes como el que nos genera [GTmetrix]

Fuente: [Análisis del blog personal]

Parece obvio, pero les cuento que he estado en proyectos en los que no se había considerado una revisión bajo esa perspectiva y ya se tenían quejas de que “el sistema estaba lento”

Lo bueno de herramientas como GTmetrix, es que brindan una mirada objetiva de lo que le entregas al consumidor final. Aquí es donde encontrarás aspectos como el tiempo de carga de la página (Fully Loaded Time) o incluso el tamaño de lo que se descarga al navegador (Total Page Size)

Por otro lado, GTmetrix incluye una serie de análisis usando herramientas como [PageSpeed] o [YSlow]. Para ambos casos se genera un score que puede mejorarse si sigues las recomendaciones que, para tener una idea, se crearon bajo estándares de Google (para el caso de PageSpeed) o Yahoo! (para el caso de YSlow)

Otra opción interesante viene con Google Chrome y se puede usar desde la opción Developer Tools/Audits, lo cual, en resumen, hace uso de [Lighthouse], que también es usado por Google PageSpeed 🙂

Fuente: Archivo personal

Los que me conocen saben del cariño que le tengo a YSlow y que me apena que ya no haya una extensión de navegador para hacer un análisis a ese nivel de detalle. Tiempos aquellos 🙂

Update: Si pueden denle una oportunidad a https://yellowlab.tools/ Se ve muy interesante!

2. Comportamiento en tiempo real (análisis dinámico)

Una vía rápida para reaccionar a lo que le ocurre al sistema, es saber lo que le pasa a este mientras va funcionando. No soy partidario de esta forma de trabajo, pero en sistemas que ya se están ejecutando en producción es importante contar con al menos una herramienta que permita tener una vista de ese tipo.

Aquí es donde hablamos del análisis dinámico del código con herramientas del tipo APM (Application Performance Monitor). Una que hace muy bien ese trabajo es [New Relic]

Fuente: [New Relic]

La importancia de este tipo de herramientas radica que no son invasivas. Es decir, no tienes que tocar tu código y la performance de la aplicación no se ve afectada. Antes de New Relic probé otros analizadores que degradaban la aplicación al punto que decidíamos desactivar el analizador.

3. Perspectiva del desarrollador (análisis estático)

Tal como mencioné en la sección anterior, no soy partidario de ir reaccionando acorde a lo que le ocurra al sistema pues creo firmemente que la mejor forma de solucionar un problema es evitándolo.

Bajo esa premisa estamos en la obligación de encontrar mecanismos que permitan controlar lo que se está construyendo o modificando. Aquí es donde entran herramientas como [SonarQube]

Fuente: Archivo personal

Lo bueno de esta herramienta (entre muchas cosas) es que te ayuda a clasificar los posibles problemas de programación y te da una estimación base de lo que necesitarías para cubrir esa deuda técnica.

¿Qué ocurre normalmente?

Lo que he encontrado en algunos proyectos es:

  1. No se mide lo que se está construyendo
  2. Se mide lo que se construye pero en términos de deuda técnica convencional (análisis estático con SonarQube)

No pondré en duda si se toma acción sobre la deuda técnica pero lo que regularmete encuentro es que se pierde la perspectiva de lo que ocurre en producción o se hace a consecuencia de un problema.

¿Qué estamos perdiendo?

No soy un experto en el tema pero les puedo asegurar que poco a poco iremos perdiendo el control de nuestra aplicación analizada. No he encontrado un estudio detallado del impacto financiero al respecto, pero valgan verdades hay situaciones en las que el equipo de desarrollo sugerirá rehacer un componente/servicio/módulo/aplicación a consecuencia de que lo encontrado es inmantenible.

¿Se imaginan eso en términos financieros? Pues ahí un primer vistazo al dinero perdido a consecuencia de una deuda técnica mal gestionada.

¿Qué tenemos que hacer?

La primera respuesta es obvia, “tenemos que medir nuestra aplicación” pero en realidad, además de invertir para lograrlo, hay mucho por hacer al respecto pues lamentablemente no he encontrado una herramienta que nos muestre lo que es realmente la deuda técnica. Si bien es cierto SonarQube nos da una idea al respecto, pero no podemos confiar en ese único indicador (Resumen, SonarQube te ayuda pero no es la solución definitiva ☹️)

La segunda respuesta tiene que ver con lo que algunos llamamos el diseño y ejecución de nuestro plan de pagos. Es decir ¿cómo vamos a ir pagando nuestra deuda técnica?

Es aquí donde tenermos una [gran responsabilidad], pues además de englobar esta serie de issues/riesgos/problemas/bugs tenemos que darle forma al indicador y a su impacto técnico/financiero. Por otro lado, debemos aceptar que siempre estará ahí pues estoy seguro de que no hay proyecto que elimine la deuda por completo. Es decir, siempre habrán issues con los que tendremos que convivir, pero si es así, tiene que ser una convivencia sana 🙂

Un abrazo,

¿Qué tan importante es la arquitectura de un sistema?

¿Qué ocurre “normalmente”?

Me gustaría empezar aclarando lo que posiblemente muchos hemos vivido en nuestros proyectos. Un sistema se construye con o sin una arquitectura definida. La realidad indica que quieras o no, el sistema se construirá pues así lo determina el negocio. En resumen, tenemos que responder a una necesidad.

Si el sistema ya está en producción y no está claro si hubo un trabajo de arquitectura, más que tomar una posición al respecto, lo que debemos hacer es evaluar y fundamentar con evidencias, el comportamiento del software desde su primera liberación al usuario.

Fuente: [Clean Code]

Si el sistema no ha presentado problemas a consecuencia de cambios constantes en el negocio, podremos concluir de que la decisión tomada fue la mejor para esa realidad. Claro está, que eso no implica que dicha formula funcione para otras realidades.

Ahora, si es que está en nuestras manos incluir este tipo de trabajos (es decir, los de arquitectura), pues tenemos que hacerlo sin dudar siquiera un segundo 🙂

¿Cuál es el impacto “mínimo” de una arquitectura?

En este tipo de situaciones considero poco profesional que nos basemos en supuestos, puntos de vista, corazonadas o peor aún en feelings, pues lamentáblemente estos no nos servirán en momentos que llegan gracias a los clásicos y no tan queridos “cambios de última hora”. Es por ello que en vez de feelings, lo mejor es que tengamos a la mano hechos concretos:

  1. Impacto en el proyecto: Un caso –muy gráfico– se remonta a un hecho ocurrido en USA en 1940. Si no conocían [la caída del puente Tacoma Narrows], les comento que hay [estudios al respecto] y que todo indica que el diseño inicial omitió consideraciones como por ejemplo, el efecto que tendría el viento sobre la estructura del puente ¿Servirá de algo compartir este tipo de experiencias? Esto lo dejo a su elección, pero vale la pena mencionar que para esa época, USD 6MM fue la cantidad de dinero que literalmente “se fue al agua”
  1. Rapidez de implementación: Podría sonar lógico escuchar que una buena práctica incrementa la rapidez del desarrollo, pero es mejor mostrar un caso en el que, por ejemplo, TDD genera una mejora de al menos 30% del tiempo esperado bajo “condiciones normales”
  1. Costos de mantenimiento: Si bien es cierto este estudio se hizo hace más de veinte años, estoy seguro de que se han encontrado con problemas que son complicados de resolver, pues la solución implicaba “cambiar muchas cosas”. Aquí un gráfico que refleja lo encontrado luego de analizar proyectos en empresas como HP o IBM, el cual en resumen indica que si hemos avanzado mucho en el trabajo y nos encontramos con un error, corregirlo será muy costoso.
Fuente: [Code Complete]

¿Qué consideraciones debe incluir nuestra arquitectura?

La “respuesta corta” es, tenemos que implementar nuestro sistema considerando una arquitectura que soportará las necesidades del negocio.

La “respuesta larga” incluye estas consideraciones:

  1. Estamos en la época en la que gracias a la agilidad, podemos confirmar en plazos cortos si nuestro producto (o parte de este) es útil. De aquí es donde se desprende el concepto de valor.
  1. El valor se asocia a la utilidad desde el punto de vista el usuario, y eso es bueno, pero lo que no debemos olvidar es que el usuario final no es ni será el único usuario del sistema. Pues de alguna u otra manera, los desarrolladores y resto del equipo técnico son usuarios. Por consiguiente, el valor también se debe visualizar desde una perspectiva técnica.
  1. Este “valor técnico” muchas veces es confundido con una necesidad que podría estar en una prioridad distinta a la requerida por el usuario final. Y es lo que comúnmente ocurre, pues “eso es transparente para el usuario”
  1. Esta nueva restricción podría basarse en la experiencia del equipo, pero lo recomendable es incluir criterios de calidad probados por el mercado. Para esto hay muchos modelos, pero creo que una base muy entendible es [la propuesta de Jim McCall]:
  1. Cubrir los criterios de cada perspectiva, requerirá contar con una arquitectura que las soporte y un conjunto de prácticas que no necesariamente se verán reflejadas en el diseño, pero sí en la implementación del mismo. Es aquí donde entran a tallar el uso de estándares de programación o de prácticas como la de TDD o incluso prácticas de DevOps (y la lista podría ser muy larga)

¿Dónde está el código?

Si bien es cierto soy partidario de hablar con código en mano, este es un caso en que necesitamos aceptar que el código llegará luego de entender con claridad los criterios mencionados por el Modelo de McCall. La mala noticia es que no hay magia en este trabajo, si queremos empezar y no sabemos por dónde, pues podríamos tener en cuenta lo siguiente:

  1. Hace poco escribí sobre [10 aspectos a considerar si les interesa la arquitectura]. Si es que ya se sienten listos para empezar con la parte técnica, pues les sugiero revisar los puntos 3 y 7 (Conceptualizar y Estudiar y poner en práctica).
  1. Si bien es cierto [mi post] lo menciona, es posible que no esté claro cómo empezar con lo que denomino “conceptualización” ¿Cómo podrían empezar con esto? Pues este gráfico de niveles de diseño, les dará una idea de lo que a algunos les podría parecer obvio, pero que a pesar de ello he notado que muchas veces no se hace bien, debido a la necesidad de escribir código lo más pronto posible.
Fuente: [Code Complete]
  1. Este tipo de razonamiento se debe complementar con conceptos de diseño como [acoplamiento / cohesión] y claro, de [SOLID]. De este último he encontrado un [video que lo explica muy bien] y que además muestra ejemplos de código.

Conclusiones

Creo que sobran argumentos sobre la importancia de la arquitectura de un sistema, pero esto no sirve de mucho si no aceptamos que la arquitectura es solo una parte del trabajo que debemos realizar.

Líneas arriba mencioné la relación que existe entre la arquitectura y las prácticas como TDD, DevOps y aquí podría agregar los estilos de arquitectura, el uso de patrones de diseño, automatización de pruebas y herramientas que nos permitan acelerar de manera eficiente el trabajo del equipo de desarrollo. Sin olvidar claro, el concepto de valor.

Por otra parte, lo que no debemos hacer es separar el concepto de valor en más de una vertiente. Mi explicación del “valor técnico” fue hecha por la necesidad de demostrar de que el “valor” incluye otros factores, y que en primera instancia estos son transparentes para el usuario, pero con una correcta asesoria este comprenderá la necesidad de incluir estos alcances a lo largo del proyecto.

Me gustaría agregar que la entrega de valor debe estar equibilibrada bajo la premisa de que no hay un solo tipo de usuario. Esta es muchas veces una línea delgada con alto riesgo de ser confundida u omitida.

Un abrazo,

new beta release in process