Ruta del desarrollador

¡Hola! Mi nombre es Alexey Skorobogaty. En 2015 me incorporé a Lamoda como desarrollador. Ahora soy arquitecto de sistemas de una plataforma de comercio electrónico y también líder técnico del equipo CORE. En este artículo, quiero compartir las ideas que recibí durante estos 5 años, en el formato de comida para llevar, con historias, memes y enlaces a la literatura.



imagen



Me complacería tener alguna discusión en los comentarios debajo del artículo: ¡preguntas, opiniones, refutaciones!



Hay conocidos



En Lamoda, me incorporé al equipo que trabaja en el soporte y desarrollo del sistema de procesamiento de pedidos. Nada es claro, pero es terriblemente interesante.



Después de un pequeño pero ambicioso estudio web donde trabajé antes, me impresionó la sensación de seriedad dentro de una gran empresa. Los procesos de desarrollo organizados parecían un mecanismo perfectamente perfeccionado. Las revisiones de código rigurosas pero de entrenamiento por parte del líder y los miembros del equipo son esenciales para un sistema tan complejo y clave. Para mí, las tareas puntuales volaron, afectando literalmente a uno o dos archivos, no más. La mayor parte de la base de código y el comportamiento del sistema me estaba oculto por la niebla de la guerra.



Después de aproximadamente un mes, completé una de las primeras tareas relacionadas con la realización de cambios reales en un sistema en funcionamiento. Su esencia se reducía a agregar un campo al informe sobre la devolución de fondos al cliente. Revisión de código, pruebas unitarias, ingeniero de control de calidad probando la versión: todo parecía estar bien. Dado que el sistema era grande y complejo, nos lanzaron dos veces por semana, de acuerdo con las regulaciones, y el jueves mi tarea pasó a la producción. Durante la mayor parte del día, el ingeniero de versiones estuvo ocupado construyendo e implementando el código, seguido de un cambio compulsivo entre pestañas con gráficos de monitoreo, errores, colas, registros, todo lo que podría indicar un problema. Pero todo se veía genial. El código se fusionó con la rama maestra y se dispersó para ocuparse de otras tareas.



El silencio en los registros y el seguimiento esconde un error terrible: la consulta de la base de datos arrojó un número incorrecto de filas. El monto total a reembolsar fue varias veces mayor que el real ... Pero nos enteramos de esto solo el lunes. Todavía recuerdo lo cansado y reprochado que me miró el jefe de tecnología mientras subíamos al ascensor de la oficina a la mañana siguiente. Atrapó el error hasta las tres de la mañana y preparó la solución para el lanzamiento. Y la empresa sufrió algún impacto por mi error. Este fue mi primer error crítico, pero lejos del último. La gente comete errores y lo hace todo el tiempo.



Conclusión n. ° 1:Los procesos comerciales y los datos son lo primero. Es importante prestar mucha atención a los datos con los que trabaja el sistema. Determina con qué estás lidiando antes de realizar cambios. Comprender el contexto en el que se realizan los ajustes. Siempre considere el problema que se está resolviendo desde la perspectiva del contexto por encima del nivel. En otras palabras, comprender claramente lo que está sucediendo en términos del proceso comercial y quién es el consumidor de los modelos afectados. La estructura de una aplicación puede tener tantas capas de abstracción como desee y distintos grados de calidad de las abstracciones en sí, pero esto no significa nada si el modelo o el proceso empresarial en su conjunto está roto.



Seguí trabajando en el mismo equipo, gané experiencia y seis meses después, en el stand-up del equipo, lancé una frase que, en general, entendí cómo funciona nuestro sistema de procesamiento de pedidos.



Por supuesto que estaba equivocado.



La complejidad de los grandes sistemas nunca debe subestimarse. El político estadounidense Donald Rumsfeld dijo muy bien sobre esto:

imagen... como sabemos, hay famosos conocidos; Hay cosas que sabemos, que las conocemos. También sabemos que existen incógnitas conocidas; es decir, sabemos que hay algunas cosas que desconocemos. Pero también hay incógnitas desconocidas, aquellas que no conocemos, que no las conocemos. Y si miras la historia de nuestro país y otros países libres, la última categoría suele ser difícil.



Conclusión n. ° 2: cuando se trabaja con sistemas complejos, es importante comprender lo que sabemos sobre ellos, lo que no sabemos y cuál es su comportamiento ni siquiera adivinando. Y no se trata solo de la caja de herramientas y de seguir la tendencia de “Monitoreo hacia la Observabilidad” , sino también de la gestión de la dependencia y la evaluación de riesgos en el diseño. Por ejemplo, antes de decidirse a utilizar una base de datos de tendencias interesante para un sistema crítico, le recomiendo encarecidamente que se adhiera a este sitio boringtechnology.club



Todo está roto



Después de dos años de trabajar con el sistema de procesamiento de pedidos, podría decir que conozco alrededor del 80% de la solicitud con confianza. Es decir, sobre cada módulo del sistema entiendo cómo funciona y puedo hacer cambios. Sé qué procesos comerciales se reflejan en un modelo en particular, cómo están interconectados y se afectan entre sí. Realicé la integración con el sistema de procesamiento de pagos, que fue diseñado por el equipo vecino. Además de la integración, era necesario deshacerse del legado del código antiguo, ya que los pagos eran anteriormente parte de nuestro sistema; esta tarea fue mi última y más ambiciosa refactorización de un módulo grande. Todo salió tan bien que ni siquiera fue interesante.



Al mismo tiempo, se estaba gestando un conflicto dentro de mí, como desarrollador. Sinceramente, no entendía por qué nuestro sistema de procesamiento de pedidos, que es tan fundamental para el funcionamiento de todo nuestro negocio, era tan frágil. Los grandes sistemas vecinos eran igualmente frágiles. De toda la experiencia que obtuve en dos años de trabajo, parecía que se podía esperar algún tipo de confiabilidad de sistemas complejos solo al realizar casos estándar probados. Y cuando intentas hacer los cambios que tu negocio demanda, las cosas se desmoronan ante la primera maniobra drástica de un desarrollador desafortunado.



Reflexionando sobre todo esto, me encontré con el artículo Todo está roto , en el que el autor escribe sobre el mismo problema, pero en una escala aún mayor (y también sobre el mismo, pero desde un ángulo diferente - Desencanto del software). Cada vez que me emociono cuando encuentro desde el exterior la confirmación de mis sentimientos internos, entonces, después de leer el artículo, finalmente sentí cómo mi vago descontento se convirtió en una visión vívida y obvia:

El software es tan malo porque es muy complejo.



No tuvimos que ir muy lejos para dar un ejemplo en nuestro trabajo: justo en ese momento, agregando solo un par de polos, rompimos por completo la creación de un pedido por un tiempo.



¡Nuestros grandes e importantes sistemas son tan malos porque no caben en nuestras cabezas! Y todos los procesos comerciales que están cerrados dentro de los sistemas no encajan en las cabezas de los gerentes y analistas, y en general no existe tal persona que entienda cómo funciona todo en conjunto.



Conclusión n. ° 3: al diseñar sistemas, es importante tener en cuenta su carga cognitiva. Consiste en la complejidad de las soluciones técnicas, así como de los modelos y procesos del área temática. Los sistemas bien diseñados tienen una alta carga cognitiva en el área temática y pocas soluciones técnicas.Idealmente, un solo sistema debería tener una carga cognitiva que una persona pueda manejar.



De acuerdo, el problema está claro. Pero supongamos que tenemos la oportunidad de reescribir un sistema demasiado complejo y por lo tanto malo simplificándolo. ¿A qué más deberías prestar atención? En cibernética, existe el teorema de Conant-Ashby:



un buen regulador de un sistema debe tener un modelo de ese sistema. Buen regulador



El significado de este teorema es que si queremos controlar algún objeto, necesitamos un buen modelo (preciso y comprensible) de este objeto. Y cuanto más complejo es un objeto o menos información sobre él, más difícil es obtener un buen modelo del mismo, y esto afecta negativamente a la gestión.



Creo que muy pocas personas estarían en desacuerdo con que todos nuestros servicios son modelos. Pero, ¿qué estamos modelando? Es muy importante prestar atención a los procesos comerciales, para modelar no solo el estado, sino también el comportamiento.



A finales de 2017, me trasladé al nuevo equipo CORE. Este equipo se formó luego específicamente para realizar las tareas de la estrategia de TI para la descomposición de sistemas monolíticos. Nuestro principal objetivo era cortar ese enorme, pero frágil sistema de procesamiento de pedidos (voz en off: ¡entonces el samurái no sabía que este camino tenía un principio, pero no un final!).

Fue una nueva experiencia para mí. Un equipo con principios y formas de pensar completamente diferentes. Las decisiones se tomaron rápidamente, hubo experimentos y el derecho a cometer errores. El equilibrio resultó perfecto: lo intentamos y retrocedimos donde el impacto era mínimo, pero prescribimos cada paso en detalle para los momentos críticos.



Escribimos un nuevo servicio para crear pedidos desde cero en otro idioma (siendo desarrolladores de php, cambiamos a golang). Evaluamos el primer resultado y lo reescribimos nuevamente. Se hizo hincapié en la sencillez y la fiabilidad. Pusieron el modelo de datos en el centro y construyeron toda la arquitectura alrededor. El resultado es un servicio confiable y resistente. Logramos ponerlo en funcionamiento sin fallos utilizando el mecanismo experimental. Con el tiempo, el sistema construido ha demostrado su valor más de una vez.



imagen



Conclusión # 4:Todos los modelos son incorrectos pero algunos son útiles. Modelar estados no es suficiente para construir sistemas correctos y estables. Es necesario observar el comportamiento: patrones de comunicación, flujos de eventos, quién es responsable de tal o cual información. Debe buscar relaciones entre los datos y prestar atención a las razones de estas relaciones.



Se trata del dum dum da da dum dum



En mi universidad había un curso de análisis matemático, que fue impartido por un profesor asociado y Ph.D. Elena Nikolaevna. Ella era muy estricta, pero justa. Durante las pruebas, de vez en cuando encontré problemas, para cuya solución era necesario "torcer" un poco las conferencias, dar un paso independiente hacia la comprensión del material. Y en el examen final, que por cierto aprobé la segunda vez, tuve que mostrar flexibilidad de pensamiento y utilizar mi intuición para resolver el problema como “bueno”. Aquí está la regla que E.N. nos contó todo el curso, y que estoy usando diez años después:

Cuando no sepa qué hacer, haga lo que sepa.



Por eso estaba orgulloso de conocer a matan good. Porque según los estándares de E.N. No basta con conocer el material, pero también es importante comprenderlo, para poder sintetizar algo nuevo.



Conclusión n. ° 5: cuanto más avanza, más responsabilidad tiene que asumir y más decisiones tiene que tomar. En un momento determinado, la confianza absoluta desaparece como categoría, pero en su lugar surge el arte del equilibrio tras el coraje de dar un paso.



Llega un momento en el que no hay una persona adecuada a tu alrededor que pueda eliminar la incertidumbre existente. Tienes que evaluar los riesgos por ti mismo y asumir la responsabilidad por ti mismo. Toma decisiones frente a la incertidumbre.



En la segunda mitad de 2018, nuestro equipo lideró el proyecto de Certificados de regalo. Inicialmente, fui responsable del desarrollo en y alrededor del procesamiento. Más tarde, a finales de año, asumí el liderazgo técnico de todo el proyecto y la tarea de restablecer el equilibrio de poder después de que parte del equipo se fuera.



Las reglas que existían en la cabeza y el orden mundial del desarrollador estaban a punto de estallar y finalmente colapsaron. La responsabilidad de un proyecto grande y complejo me quitó las ideas idealistas sobre el mundo del desarrollo con conceptos y un arco iris. El mundo cruel de las restricciones y las soluciones suficientes requirió una comprensión y revisión de todos los enfoques y reglas que seguí.



imagen



Conclusión n. ° 6:Sindrome impostor. ¿Qué pasa si me expongo? Por supuesto que expondrán si no se hace nada. Si hace algo importante, luego de un tiempo se da cuenta de que no hay nadie que lo exponga.



Divergencia y convergencia



De acuerdo con la cronología de mi "Developer's Path" debería haber una historia interesante desde el punto de vista técnico sobre el proyecto de políticas personales. En este proyecto, implementamos el procesamiento de datos en tiempo real y, sobre la marcha, cambiamos los principios mismos de la arquitectura del sistema, pasando a la Arquitectura basada en eventos. Pero sobre esto, ya tengo un informe separado de la conferencia Highload '19 (y un artículo aquí sobre Habré). Por lo tanto, prefiero hablarles de los "asuntos importantes" de la gestión técnica y no muy.



Cuando un desarrollador asciende a la posición de senior, que debe leerse como "listo para asumir la responsabilidad y saber cómo tomar decisiones de forma autónoma", el siguiente paso clásico es el liderazgo del equipo. Un líder de equipo es una persona que es principalmente responsable del equipo, es decir para las personas y los procesos de desarrollo. El cliente no acude al desarrollador, sino al líder del equipo y también le pregunta sobre las obligaciones del líder del equipo.



Resulta algo paradójico: tan pronto como el desarrollador ha crecido para trabajar de forma independiente como ingeniero, se ve envuelto en una tormenta llamada administración.

No, tal vez para alguien este camino parezca bastante cómodo, y la transición de algoritmos y protocolos extremadamente inequívocos para la interacción de sistemas informáticos a la coordinación de un grupo de personas parece lógica. Pero me parece que no en vano la mayoría de conversaciones en chats especializados y en conferencias para jefes de equipo giran en torno al concepto de "dolor".



¿Cuál es el dolor de un líder de equipo? ¿No es porque un ingeniero está a cargo de la gestión? No, es comprensible por qué sucede esto: no tenemos una escuela de administración técnica como tal, y se supone que un ingeniero de TI es un superhombre que puede resolverlo todo, incluso algo tan “simple” como la administración.



Pero decidí tomar el otro camino y elegí el puesto de líder tecnológico como el siguiente paso de mi carrera. Como arquitecto, trabajo con equipos de desarrollo, y ahora escucho de los muchachos lo que yo mismo dije a los gerentes hace un año:

¿Por qué los requisitos están tan mal desarrollados? ¡Soluciones de muletas! ¡¿Qué dos semanas ?! Aquí trabajo durante un mes.



Pero ehehei, ahora es mi tarea resolver esos problemas. Pero tan pronto como traduce su pensamiento al paradigma de costo y beneficio, se da cuenta de que todos estos problemas no se pueden resolver: ¡se trata de la vida!



Conclusión # 7: ¡Apertura! Los gerentes no se ocupan de la resolución de problemas; manejan el desorden.



Como líder técnico, mi trabajo consiste en eliminar la incertidumbre del equipo de desarrollo. ¿Requisitos no resueltos? ¿Soluciones de muletas? ¿No proporciona la arquitectura? Todas estas son señales de fragilidad y divergencia del sistema.



Digamos que la configuración de la tarea en el servicio de creación de pedidos se ve así:

es necesario agregar el campo X y el campo Y. Se requiere que el valor en el campo Y 'en la salida sea igual al valor Z si X es 1.



El problema radica en la declaración misma de requisitos. El error aquí es que no está completamente claro qué estado del sistema desea lograr. Los pasos completamente definidos en la declaración generan incertidumbre durante la implementación y operación.

Después de varias de estas tareas, el servicio de creación de pedidos estará en un estado bastante frágil, y casos como el que agregamos un par de campos y todo se rompió comenzará a suceder.



Objetivo: asegurar la convergencia de los estados de los sistemas, la coherencia del enunciado de tareas y la reducción de la incertidumbre para lograr la estabilidad.



imagen



Las personas que trabajan en la línea de representación están constantemente construyendo y actualizando sus modelos de lo que está más allá de la línea. Estas actividades son fundamentales para la resiliencia de los sistemas de Internet y son una fuente importante de capacidad de adaptación. Por encima de la línea, por debajo de la línea



El arquitecto debe comprender la unidad del sistema socio-técnico. Ser capaz de coordinar procesos por encima de la línea de presentación de modo que los sistemas por debajo de la línea de presentación cumplan con las limitaciones de corrección, estabilidad y adaptabilidad.



imagen



Conclusión n. ° 8: si las reglas dejan de funcionar, felicidades, ha alcanzado las condiciones límite en las que el modelo actual deja de funcionar. Es hora de revisar sus ideas y elegir un nuevo modelo que cumpla con las limitaciones actuales y le permita construir procesos y reglas adecuados.



¡Suave es simple, la gente es dura!



No realmente. Esto es lo que se escribió en un libro sobre arquitectura. Y parece que cuanto más avanzo, más a menudo repito este libro.



Los conceptos técnicos, los algoritmos y los estándares son claros; solo necesita tomarlos y resolverlos constantemente. No estoy tratando de descartar el trabajo de los ingenieros: los algoritmos para sistemas distribuidos son extremadamente complejos si no construye dichos sistemas a diario. Pero la mayoría de las veces, la principal dificultad que enfrentamos en el proceso de trabajo surge cuando necesitamos comprender por qué un servicio en particular requiere tal nivel de abstracción para el dominio. Y el problema suele agravarse por el hecho de que la persona que escribió el servicio no está presente.



Los algoritmos que son simples de implementar son más exitosos que los matemáticamente precisos. Paxos es matemáticamente preciso, pero solo con la descripción del protocolo Raft, que es más fácil de implementar, se ha desarrollado la aplicación práctica de algoritmos de consenso.

El idioma Golang es criticado por ser demasiado limitado. Pero es en él donde están escritos Docker, Kubernetes y muchos otros sistemas distribuidos. Un sistema de restricciones bien diseñado sirve como base para sistemas exitosos.



Todo sería mucho más fácil si la tecnología no tuviera que contar con el factor humano. Pero tienen que hacerlo. Cualquier sistema en TI, en cuya construcción y mantenimiento esté involucrado más de una persona, debe tener en cuenta el factor humano.



Y aquí las tecnologías emergen en la interfaz entre el software y las personas, diseñadas para estructurar el caos y describir interacciones complejas. Diseño impulsado por dominio, microservicios, ágil: todos ellos crean restricciones que describen los principios y reglas de interacción. Aparecen estructuras con las que está claro cómo trabajar. Pero no siempre mejora con la llegada de tales tecnologías. Muy a menudo resulta al revés: lo que el dinero no puede comprar .



Conclusión n. ° 9: los programas pueden y deben ser simples. Para hacer esto, debe aplicar fuerza a la formación de una cultura de ingeniería. Es ella quien determina en última instancia la ejecución de los servicios.



imagen



Leyendo lista



Libros



The Manager's Path: una guía para líderes tecnológicos que navegan por el crecimiento y el cambio, Camille Fournier - link



The Elegant Puzzle: Systems of Engineering Management, Will Larson - Link



Team Topologies: Organizing Business and Technology Teams for Fast Flow, Manuel Pais y Matthew Skelton - enlace



corregir software, Juval Lowy - enlace



pensar desde sistemas: una cartilla, Donella Meadows - referencia



los artículos



modelos mentales, Calle general Fernam - enlace



Complejidad Bias: ¿por qué preferimos complicado simple. Fernam Street - enlace



Lo que el dinero no puede comprar, menos incorrecto - enlace



Convertirse inusualmente orientado a la verdad, menos incorrecto -link



Leyes de programación y realidad: ¿sabemos lo que creemos saber? - enlace



Sin esencia Silver Bullet y accidentes de ingeniería de software - enlace



El arte de la resolución de problemas - enlace del



software frágil al antifrágil - enlace Las



computadoras se pueden entender - enlace ¡



Tuckman estaba equivocado! (Acerca de los equipos) - Referencia



Cómo fallar en casi todo y todavía ganar a lo grande - enlace



Simplicidad Antes de generalidad, Uso antes de usar - enlace de

la simplicidad, por favor - Un manifiesto para el Software de Desarrollo - Enlace



Diseño de software es las relaciones humanas - Enlace



All Articles