projifm: fin de primera iteración

El lunes pasado completamos la primera iteración con un muy buen desempeño. A pesar de haber sufrido retraso por parte de un proveedor externo de una API logramos entregar toda la funcionalidad comprometida, solo nos quedó pendiente una tarea relacionada a una aplicación legacy con la que debemos integrarnos.

Me sentí muy cómodo con la estructura del equipo: 3 devs (yo entre ellos) + 1 tester + 1 facilitador + PO (+ 1 persona en tareas de infraestructura con dedicación parcial).  La forma en que trabajamos es bastante aproximada a lo propuesto por XP. Entre las prácticas que utilizamos están: daily stand ups, reunión de planificación, reunión de review, retrospectivas, #noEstimates, product backlog, spikes, pruebas automatizadas, deploy automatizado, mob-programming, collective ownership, control de configuración, TDD (poco pero en ascenso), versionamiento de base de datos, etc.

Entre los temas a mejorar surgidos en la retrospectiva estuvieron:

  • Mejorar el flujo de release: nos pasó que varios de los items del backlog se estiraron durante varios días y luego los cerramos «todos juntos» hacía el final de la iteración. Esto generó que el burn-down chart tenga una meseta importante.
  • Mejorar la interacción con nuestro «DevOp» pues tuvimos algunas fricciones consecuencia de la falta de claridad en algunos acuerdo de trabajo (lo pongo entre comillas pues considero que DevOps es más un mindset que un rol)

Aplicaciones legacy, monolitos y micro-servicios

Una plataforma desarrollada durante varios años sin prestar mayor atención a a algunas buenas prácticas de desarrollo (integración continua, test-automatizados, trazabilidad de artefactos, control de la configuración, separación de ambientes, etc). Desarrollada por una software factory externa a la organización.

En un momento la organización decide cambiar de software factory y es ahí donde entramos somos.

Nos encontramos con una plataforma legacy, con arquitectura monolítica, issues de performance, corriendo sobre máquinas físicas (nada de cloud, ni virtualización), sobre la que el cliente espera que agreguemos nuevas funcionalidades. La visión es ir hacia una arquitectura de micro-servicios corriendo en la nube. Este desafío nos plantea una seria de interrogantes:

  • Cómo organizar el equipo para poder dar soporte a la plataforma actual y al mismo tiempo desarrollar nuevas funcionalidades
  • Cómo mitigar los riesgos de introducir modificaciones sobre una plataforma legacy
  • Cómo vivir en una infraestructura mixta cloud  y on-premise
  • Cómo mantener la motivación al trabajar sobre código legacy/frágil escrito por terceros
  • Cómo introducir la nueva arquitectura basada en nuevas tecnologías de una forma no disruptiva para el negocio y los usuarios

Esta es la situación que estoy afrontando en mi proyecto actual y es también la temática de una charla/presentación que en la que empecé a trabajar esta mañana.

 

Reclutando programadores: juniority

Reclutando programadores: juniority

¿Cuantas veces te cruzaste con alguien supuestamente de cierto nivel de «seniority» que estuvo por encima de las expectativas para ese nivel? Yo creo que muy pocas veces. En general creo que la situación más común es la inversa: quien en los papeles es nivel X , en la práctica termina siendo nivel Z (siendo Z < X). Es por esto que cuando tengo que hablar de seniority prefiero utilizar el término juniority, ¡ja!.

Más allá del chiste, creo que los niveles de seniority/juniority son clasificaciones bastante inútiles en la mayoría de los casos. Las clasificaciones tienen utilidad cuando cada clase tiene un significado universal que permite establecer un lenguaje común. El nivel de seniority suele asociarse a la experiencia. El problema es que no hay un acuerdo universal respecto de cuanta experiencia se requiere para cada nivel de seniority. Para CESSI por ejemplo, senior implica más de 4 años de experiencia, pero conozco de organizaciones en las que se requiere más de 6 años para ese mismo nivel.

Pero aún pudiendo lograr un acuerdo universal sobre la cantidad de años de experiencia de cada nivel de seniority, hay algunas otras cuestiones a considerar:

  • el tiempo que se realiza una actividad de índole intelectual no resulta necesariamente proporcional al nivel de maestría de la persona en esa actividad.
  • en muchos casos resulta más relevante la cantidad de experiencias que la duración de la experiencia. No es lo mismo una persona que durante 6 años trabajó tan solo en 2 proyectos que una persona que en 3 años trabajó en más de 10 proyectos. Yo creo que en la mayoría de los casos preferiría a esta segunda persona.
  • finalmente hay otro conjunto de factores que suelen influir en la determinación del seniority, cuestiones tales como aptitudes, habilidades y conocimiento, temas que trataré en el siguiente artículo.

continuará…

Reclutando programadores: perfiles

Para algunos el término «programador» no resulta apropiado para describir a aquellos que desarrollan software de forma profesional, por el simple hecho que la actividad de programar es solo una parte de lo que hay que hacer. Un término mucho más aceptado es «desarrollador». Pero  incluso hay empresas que prefieren hablar en formal general de «Ingenieros», independientemente de que una persona tenga formalmente ese título académico.  A propósito de esta diversidad de terminología, hace un par de años la Cámara de Empresas de Software y Servicios Informáticos de Argentina (CESSI) llevó adelante una iniciativa para «estandarizar» los perfiles informáticos. Esta iniciativa derivó en La guía de perfiles ocupacionales de TI. Si bien desconozco cuán utilizada es esta guía en la actualidad por las empresas del sector, creo que resulta un buen punto de partida para hablar sobre perfiles informáticos.

Esta guía no menciona explícitamente un perfil de programador. Los roles más «cercanos» que menciona son: Desarrollador de Software y Arquitecto de Software. Personalmente me gusta la descripción de los perfiles, creo que es bastante completa aunque algunos detalles que me llamaron la atención:

  • En el caso del arquitecto se menciona explícitamente entre sus habilidades «Pasión por la tecnología». Esto me parece fantástico pero me llama la atención que tal característica no figure entre las del desarrollador. No digo que este bien ni mal, simplemente me llama la atención y me hace pensar, en este momento no tengo opinión formada al respecto.
  • Creo que nunca me convenció la idea de «EL arquitecto» (a pesar de haber tenido ese «título» en uno de mis trabajos). Pero creo que de aceptar la existencia de dicho perfil imagino que es naturalmente un perfil senior. Sin embargo la guía de CESSI propone dos niveles de arquitecto: semi-senior y senior.

Este último punto abre la puerta para hablar sobre «seniority», pero eso será parte de otro post ya que es un tema para hablar largo y tendido.

Continuará…

team.split() & Project.new()

Hace tres meses me sume a un proyecto que recién estaba empezando. En aquel momento el equipo estaba aún en formación y éramos unas 9 personas. Hace dos semanas llegamos a ser 15 personas en el equipo. Obviamente ya no era factible alimentarnos con dos pizzas.

Por ello fue que la semana pasada partimos el equipo y ahora estoy trabajando en un equipo de 5 personas: 3 devs, 1 tester y 1 facilitador. Estamos trabajando en rehacer desde cero un componente existente en la plataforma. Esperamos poder liberarlo en aproximadamente 5 o 6 semanas.

Ayer empezamos la primer iteración. La planning estaba agendada para las 11 de la mañana, pero como todos estabámos en la oficina desde las 9, decidimos comenzar a trabajar en algunas tareas de setup todos juntos: creación del repositorio Git y de la estructura de la solución base y configuración del Jenkins para que haga integración continua (#ci). Luego hicimos la planning donde acordamos con nuestro PO los items a trabajar durante la iteración. Por el momento y dadas las particularidades de nuestro proyecto, no estamos estimando los items de nuestro backlog (#NoEstimates). Simplemente intentamos particionar los items de forma tal que sean pequeños y que requieran no más de 2 días de trabajo cada uno. De esta forma medimos cantidad de items completados por iteración.

A continuación de la planning debatimos algunas cuestiones de diseño de alto nivel. Ya por la tarde, con todo el equipo trabajando sobre una compu + proyector (#mob-programming like) comenzamos a escribir las pruebas de aceptación que nos guiarán en el desarrollo de las funcionalidades comprometidas (#tdd). Esto nos permitió detectar en forma temprana algunas dudas sobre el comportamiento esperado de la aplicación.

Estoy muy entusiasmado con este proyecto, ya que implica el trabajo con un equipo nuevo, teniendo la confianza del cliente para hacer las cosas de la forma que nosotros consideramos más apropiada.

Continuará…

Reclutando programadores: cortesía

Reclutando programadores: cortesía

Una empresa analiza el CV de una candidato, lo contacta y decide citarlo para una entrevista. El candidato acepta la invitación y la entrevista se concreta. La empresa finalmente por X motivo decide no contratar al candidato pero no se lo notifica explícitamente, simplemente no vuelve a contactarlo.

Fea la actitud.

Si el candidato se tomó el tiempo para asistir a la entrevista, la empresa debería mínimamente enviarle un mail para notificarle su decisión. No pretendo que la empresa de explicaciones, simplemente que tenga la cortesía mínima de enviar un mail para que el candidato no quede pendiente de una falsa ilusión. Y no importa que la entrevista haya terminado con la clásica frase «Gracias por venir, si decidimos avanzar con el proceso te llamamos», creo que de todas formas hay que notificar al candidato, es una cuestión de cortesía.

Adicionalmente si se le pidió al candidato resolver algún tipo de ejercicio considero que la empresa debería mínimamente dar algún tipo de feedback al respecto. Una vez más una simple cuestión de cortesía. El costo es mínimo y deja una buena imagen de la empresa.

Reclutando programadores

Desde hace ya un par de años que la demanda de profesionales informáticos en Argentina está por encima de la oferta disponible. Por esto es que algunas empresas han comenzado a prestar mayor atención a ciertas cuestiones como el proceso de reclutamiento y los planes de carrera.

El año pasado una empresa en que había trabajado como empleado tiempo atrás, me contactó para que los ayudara con un plan de entrenamiento para programadores y líderes técnicos. Nos reunimos a hablar del tema para entender mejor sus necesidades y finalmente terminé presentando una propuesta integral que incluía trabajar sobre el proceso de reclutamiento, el entrenamiento y los planes de carrera. Si bien el proyecto nunca se concretó, yo estuve pensando bastante en el tema y un libro que lei recientemente me ayudó a confirmar algunos puntos de mi visión.

Una charla que tuve con un colega la semana pasada me motivó para compartir mis ideas, así que decidí inaugurar una nueva serie de artículos en este blog y que voy a bautizar como: «Reclutando programadores».

Continuará…

recluting

.Net: infraestructura de desarrollo & test

Quiero compartir la infraestructura que estamos usando en el proyecto que estoy trabajando en este momento.

Como repositorio de código estamos usando Git, más específicamente GitLab (aunque a pedido del cliente en breve migraremos a BitBucket).  Dado que estamos usando una arquitectura «micro-servicios-like» tenemos un repositorio por cada micro-servicio, más un repositorio general para configuración, más un conjunto de repositorios adicionales para algunas librerías de uso común y finalmente un repositorio para los scripts de operaciones.

Estamos usando Nexus como repositorio de binarios NuGet y Maven, ya que tenemos componentes .Net y Java.

El servidor de integración continua y orquestador de deployments es Jenkins 2. El proceso de Build lo tenemos armado con MSBuild de manera que Jenkins simplemente obtiene el código de Git, dispara MSBuild y genera reportes y notificaciones basados en el resultado del proceso.

Los deployments los hacemos con MSDeploy y los disparamos desde Jenkins.

De esta forma, los componentes comunes compartidos entre distintos micro-servicios están publicados en nuestro NuGet/Nexus y quien necesita utilizarlos simplemente agrega una referencia a nivel binario usando NuGet. Esto nos permite evitar almacenar binarios en Git y al mismo tiempo que nos habilita a que cada parte de la arquitectura pueda ser versionada en forma independiente.

Para la gestión del backlog utilizamos Jira que a su vez lo tenemos integrado con Hiptest para el manejo de los casos de prueba. Personalmente nunca antes había trabajado con Hiptest y algo que me gusta mucho es que se integra con SpecFlow para la definición de los casos de prueba y el registro centralizado del resultado de la ejecución de las pruebas reportado por SpecFlow.

Para comunicarnos tenemos una lista de correo, un Slack y Skype/Hangout para las video conferencias.

pipeline_net

.Net Core: un primer vistazo

El último fin de semana estuve haciendo un par de Katas para familiarizarme con el nuevo stack de herramienta de .Net Core. Lo que aprendí me gustó mucho y para compartirlo hice este breve video introductorio. Espero resulte de utilidad.

Nota: en el video también hice uso de algunas herramientas «extra .net», más concretamente utilicé un generador de código, un Yeoman.

.Net: abuso de AppSettings

Toda aplicación .Net cuenta con un archivo xml de configuración. Dicho archivo tiene un conjunto de secciones predefinidas entre las que se encuentra la sección AppSettings que permite definir parámetros de configuración del tipo clave-valor.

Considero que este mecanismo resulta muy útil y apropiado para cuando uno tiene que manejar un set reducido de entradas en esta sección. Sin embargo me he cruzado con aplicaciones con más de 10 entradas en appsettings. Más aún, en alguna ocasión que me cruzado con aplicaciones con ¡más de 50 appSettings!. El problema que veo con esto es que cuando uno cuenta con tal cantidad de parámetros de configuración, es muy posible que dichos parámetros tengan cierta relación/estructura, la cual no es posible reflejar usando el mecanismo de AppSettings. Para estos casos resulta mucho más conveniente en mi opinión utilizar el mecanismo de extensión de configuración que ofrece .Net definiendo secciones personalizadas.

Este breve artículo de MSDN explica de forma muy concreta cómo hacer uso de este mecanismo. Personalmente no suelo usarlo porque en mis proyectos generalmente uso algún inyector de dependencias y hago uso de las funcionalidades del inyector para precisamente inyectar los parámetros de configuración.