Hola Recientemente, hice un informe para los estudiantes sobre qué obstáculos se pueden llenar haciendo un desarrollo web moderno. ¿Cómo se relacionan las diversas decisiones que tomamos durante el proceso de desarrollo, cómo la elección de la tecnología afecta el tamaño del equipo, cómo el tamaño del equipo afecta los enfoques de prueba, cómo los enfoques de prueba están relacionados con la estructura de toda la empresa ...
Resultó algo así como una búsqueda con una opción distribuida: de qué lenguaje de programación elegir y para quién es mejor contratar un equipo que haga el producto más útil de la historia. Le sugiero que lea esta publicación, elija sus opciones, complete la búsqueda y discuta lo que se ha vuelto doloroso.
upd : se agregó texto al kat.

De la idea al prototipo
Supongamos que mi amiga Valera y yo decidimos hacer una startup. Uber para X , o algo por el estilo. Reunidos en un bar, discutieron esta idea, un tema genial. Debe hacer Tres meses no dormí, no comí, no salí de la casa. Desarrollado Comenzaron y se dieron cuenta de que nadie lo necesitaba.
Tristeza Intentemos de nuevo. Esta vez estudiamos el mercado, observamos qué usuarios tienen necesidades, qué problemas. Hicimos algún tipo de prototipo completamente en la rodilla, de forma rápida y gratuita en dos noches. El prototipo despegó. Genial, sigue adelante.
Elegir tecnología
Ahora podemos tomar y hacer una gran aplicación de un prototipo, desarrollarlo. Pero para esto necesitamos adoptar un enfoque más serio para la elección de las tecnologías que utilizaremos.
Idioma
En orden ¿Qué idioma escribir? Puedes llevar el funcional de moda: Haskell, Erlang, Lisp (muy de moda entre los abuelos mayores de 70 años). O otro asesino JS, que es muy bueno, compilado en JS, tiene todas las características necesarias. Pero lo más probable es que no tengamos a nadie para contratar en un año, porque el próximo asesino JS no despegará y tendrá que volver a aprender o reescribir el proyecto.
Intento número dos. Puedes llevar algo marcado por tiempo. Por ejemplo, PHP. Este es un buen lenguaje, está de moda criticar a veces, tiene sus inconvenientes, pero es fácil hacer lógica de negocios, es lo suficientemente rápido, escala bien, puede contratar personas en cualquier momento y en cualquier lugar. Pero él no es muy productivo. Por lo tanto, necesitamos mucho hierro o escribir nuestro propio compilador, como lo hicieron Facebook o VK.
¿Más opciones? Puedes tomar Perl, pero no habrá nadie para contratar ayer. Más?
Java Java es la norma. Como lenguaje, no es muy, en mi opinión subjetiva, pero la JVM es una gran máquina virtual, todo está bien, funciona rápidamente, pero aún necesita mucho hardware. Y mientras escribíamos en Java un generador abstracto de la fábrica de estrategias, en lugar de crear funciones, los usuarios acudieron a los competidores.
Muy bien, todavía tenemos Python. En principio, todo está bien. Pero ejecutamos la aplicación en Python, usa un núcleo de 56, de lo contrario ... todo está bien. O puede tomar algo moderno: Go, Rust, algo más. Pero son de nivel demasiado bajo, y solo hacemos funciones durante mucho tiempo ... Todavía tenemos que elegir algún idioma. Deja que sea JS al final, baja.

Base de datos
Base JS sin una base de documentos: dinero por el desagüe. Las bases de documentos tienen sus ventajas. Nos permiten desarrollar rápidamente prototipos, no preocuparnos por el esquema, los datos de salchichas de un lado a otro. Hay muchas ventajas, menos una: gachas de los datos. Cuando tenemos diez, veinte o cuarenta colecciones en lugar de tres, cuando tratamos de pegar algo bueno y digerible de ellas sin la ausencia de esquemas, se vuelve cada vez más difícil de hacer. Nuevamente creamos características durante mucho tiempo.
Ok, tomemos una base relacional. MySQL, PostgreSQL u Oracle si tiene suficiente dinero. Con las bases de datos relacionales, un día puede venir a trabajar y encontrarse en el infierno por transacciones y almacenamientos. Esto no necesariamente sucede con nuestro proyecto. Pero si eso sucede, entonces estas complejidades de la lógica serán imposibles de probar. E incluso si de repente alcanzamos el límite vertical de nuestro gran servidor de oro en el que alojamos la base de datos, entonces será bastante difícil separarlos. Hacemos funciones durante mucho tiempo.
Esta bien Tomaron algo de base, ORM golpeó frente a él para facilitar el movimiento de un SQL a otro. Algún día (spoiler: nunca).

Arquitectura
¿Qué arquitectura tomar? Los chicos de Habré escriben que los microservicios son geniales. Oleg Bunin dice: "toma microservicios".
Si comienza con microservicios, entonces, con una probabilidad del ochenta por ciento, los límites serán incorrectos porque no han pensado completamente en el modelo de dominio y no han entendido bien dónde cortar y dónde no. Además, todos toman microservicios, los implementan en lotes en todo su clúster, y un mes después surge la pregunta: "¿Cómo puedo probar todo esto ahora?" Los servicios ya funcionan en producción, pero no los probamos. Usando metodologías familiares (pirámide de prueba, pruebas de integración manual, pruebas de extremo a extremo), es difícil probar microservicios. Por lo tanto, hemos estado haciendo funciones durante mucho tiempo.
Ok, entonces golpeemos un monolito. Esta es la idea correcta para una startup. Puedes vivir con un gran monolito durante mucho tiempo y no tener problemas. Pero si decidimos expandir en gran medida el equipo, entonces debemos tener cuidado. El monolito se escala normalmente, mientras que los desarrolladores tienen 20, 30, 50. Además, la velocidad de entrega de funciones cae exponencialmente y perdemos usuarios.

¿Dónde comenzar el proyecto?
Todo necesita ser lanzado en alguna parte. 2018, la opción más lógica para hacer esto en la nube. No lo ejecutes en la nube: los chicos se reirán. Pero, en primer lugar, existe la ley federal 152, que limita significativamente la elección de los proveedores de la nube que se pueden alojar. En segundo lugar, es muy fácil ingresar accidentalmente una clave privada a su cuenta en Amazon en Github, y alguien definitivamente vendrá y gastará todo su dinero. Y si esto no sucede, en algún momento las tarifas de la nube lo arruinarán.
Puedes alquilar un centro de datos. Tal vez esto no sea tan eficiente en el uso de recursos inicialmente, pero a la larga probablemente sea más barato que el alojamiento en la nube. Pero aquí necesitamos personas que lo apoyen. En mi experiencia, a quienes les encanta y saben cómo hacerlo, no les gusta comunicarse con todos los demás, por lo que están organizados en el departamento. Y el departamento es el separatismo. Quiero decir, será más fácil intercambiar experiencias dentro del equipo de administradores, pero en el futuro esto puede no funcionar muy bien. Habrá preguntas con priorización de tareas de otros colegas, con sincronización. Otros especialistas no sabrán lo que sucede dentro del departamento que admite nuestro centro de datos.
En general, el separatismo no nos conviene. Lógicamente, pasamos a la cuestión de reclutar un equipo.
El equipo
Desarrollo
Digamos que descubrimos los idiomas, las bases de datos y dónde alojar el proyecto. Es hora de reclutar un equipo. Puedes tomar algunos tipos muy geniales que resolverán todos los problemas: desarrolladores cientos de veces, ninjas de backend, entiendes. Tal vez dará un paseo. Pero, de hecho, es probable que las estrellas invitadas:
- tipos tóxicos que no harán nada y crearán una mala atmósfera en el equipo,
- o idealistas construyendo poco a poco una arquitectura impecable, colocando ORM frente a bases que nunca tendrá que cambiar ...
Al final ... sí, hemos estado haciendo funciones durante mucho tiempo. Otra opción es tomar chicas y chicos comunes que solo escriben código, hacen funciones bien. Pero si toma muchos desarrolladores no muy experimentados con diferentes antecedentes, pueden escribir código en un estilo diferente, hacer las cosas de manera diferente y con un tamaño suficiente del equipo, todos estarán apretados, todos tendrán llaves en las misiones de extracción de los demás. No es muy efectivo. ¿Cómo se puede resolver esto? El jefe puede leer todo el código. Puedo leer todas las misiones de extracción, y mi amigo y cofundador Fundador Valera lo volverá a leer por segunda vez (por si acaso, nunca se sabe). Está claro que esto no escala y todas las características se están haciendo lentamente.
Una opción más correcta es definir un estilo de código para la empresa. Para muchos idiomas, ya existe, y simplemente puede seguirlo. O si alguien realmente quiere, puede tomar uno listo y levantarlo un poco, y luego mirar las misiones de extracción y decir que la llave no está allí, debería estar allí de acuerdo con el estilo del código. No se puede discutir con tal argumento, pero en realidad no es mucho mejor que la versión anterior, de todos modos estamos haciendo funciones lentamente. La opción correcta para todos los idiomas modernos es verificar esto automáticamente.

Ok Anotamos desarrolladores, código higo. Pero comenzamos a lanzar funciones en producción, y de alguna manera debemos asegurarnos de que las enrollemos sin errores, de que nada se nos caiga.
Aseguramiento de la calidad
Podemos decir que no necesitamos especialistas en control de calidad. Muchos hacen esto, a veces funciona. Pero no a todos los desarrolladores les gusta escribir pruebas. Pueden ser entendidos. Y es mejor motivarlos para que escriban las pruebas, pero la realidad es cruel: las pruebas unitarias no detectan todos los errores. Y si a algún desarrollador no le gusta escribir pruebas y aún así comenzó a escribirlas, lo más probable es que sean pruebas unitarias.
Además, todavía hay enfoques cuando minimiza el tiempo medio entre fallas en lugar del tiempo medio para recuperarse. El tiempo medio entre fallas es cuando un especialista en control de calidad dice: "no vamos a liberar, tengo un mal gusto, habrá errores, vamos a lanzar en dos semanas". Y el tiempo medio para recuperarse es cuando se tira algo, inmediatamente se ve en las métricas que algo está roto, y después de dos minutos todo se revierte, se soluciona y todo está bien. Pero para revertir el proyecto en dos minutos, debe cubrir todo con métricas normales, y esto no siempre es trivial. Y si las métricas se encuentran en un estado deplorable y lanzamos una versión incorrecta, podemos averiguarlo después de que todos los usuarios nos dejen en manos de la competencia.
Otra opción: hacer un departamento de control de calidad. Te acuerdas: el departamento no es muy bueno, es separatismo, no nos conviene. El separatismo puede resolverse con la ayuda de equipos multifuncionales. Sí, resuelven el problema de que nuestro administrador está sentado por separado, los evaluadores están separados.
Pero crean otros problemas. A medida que los desarrolladores, los probadores y todos los demás miembros de equipos multifuncionales comienzan a comunicarse más dentro de sus equipos y resuelven problemas anteriores, se comunican menos con sus colegas en su función: otros backders y probadores, comienzan a reinventar la rueda, hacen las mismas cosas en paralelo, aislamiento entre equipos. Punzón por el jabón: hubo un separatismo, se convirtió en otro.
¿Cómo resolver esto? Comuníquese con colegas en grupos de pasatiempos. En algún lugar se llama gremios, en algún lugar es comunidad. Si escalamos el equipo con equipos multifuncionales para que no se vuelvan autónomos, simplemente organizamos un círculo de fanáticos de backend, lenguajes funcionales, seguridad ...

Resumen
De hecho, no todo es tan malo. Puede encontrar una salida a cualquier situación, encontrar una solución. Quizás no sea ideal, pero es más adecuado en esta situación con un mínimo de problemas. Un compromiso siempre es posible.
Y sin embargo, todo esto es interesante. Es interesante resolver problemas que alguien ya ha resuelto; los problemas nuevos son aún más interesantes de resolver. Es interesante compartir conocimientos.