Hallo. Kürzlich habe ich für Studenten einen Bericht darüber erstellt, welche Probleme durch moderne Webentwicklung behoben werden können. Wie hängen die verschiedenen Entscheidungen, die wir während des Entwicklungsprozesses treffen, zusammen, wie wirkt sich die Wahl der Technologie auf die Größe des Teams aus, wie wirkt sich die Größe des Teams auf die Testansätze aus, wie hängen die Testansätze mit der Struktur des gesamten Unternehmens zusammen?
Es stellte sich so etwas wie eine Suche mit einer verteilten Auswahl heraus: Aus welcher Programmiersprache man wählen sollte und für wen es besser ist, ein Team einzustellen, das das nützlichste Produkt aller Zeiten herstellt. Ich schlage vor, Sie lesen diesen Beitrag, wählen Ihre Optionen, schließen die Quest ab und diskutieren, was schmerzhaft geworden ist.
upd - hat dem kat Text hinzugefügt.

Von der Idee zum Prototyp
Angenommen, mein Freund Valera und ich haben beschlossen, ein Startup zu machen. Uber für X oder so etwas. Versammelt in einer Bar, diskutierte diese Idee, cooles Thema. Muss tun. Drei Monate haben nicht geschlafen, nicht gegessen, das Haus nicht verlassen. Entwickelt. Sie fingen an und erkannten, dass niemand es brauchte.
Traurigkeit. Versuchen wir es noch einmal. Dieses Mal haben wir den Markt untersucht und uns angesehen, welche Bedürfnisse Benutzer haben und welche Probleme sie haben. Wir haben an zwei Abenden eine Art Prototyp komplett auf dem Knie hergestellt, schnell und kostenlos. Der Prototyp startete. Cool, mach weiter.
Technologie auswählen
Jetzt können wir aus einem Prototyp eine große Anwendung machen, sie entwickeln. Dafür müssen wir jedoch die Auswahl der Technologien, die wir verwenden werden, ernsthafter angehen.
Sprache
In Ordnung. Welche Sprache soll ich schreiben? Sie können die modische Funktion nehmen: Haskell, Erlang, Lisp (sehr modisch unter Großvätern über 70). Oder ein anderer Killer JS, der sehr cool ist und in JS kompiliert wurde, verfügt über alle notwendigen Funktionen. Aber höchstwahrscheinlich werden wir in einem Jahr niemanden mehr einstellen können, da der nächste Killer JS nicht abheben wird und das Projekt erneut lernen oder neu schreiben muss.
Versuch Nummer zwei. Sie können etwas nach Zeit überprüft nehmen. Zum Beispiel PHP. Dies ist eine gute Sprache, es ist in Mode, manchmal zu kritisieren, es hat seine Nachteile, aber es ist einfach, Geschäftslogik darauf zu machen, es ist schnell genug, skaliert gut, man kann jederzeit und überall Leute einstellen. Aber er ist nicht sehr produktiv. Deshalb brauchen wir entweder viel Eisen oder schreiben unseren eigenen Compiler, wie es Facebook oder VK getan haben.
Weitere Optionen? Sie können Perl nehmen, aber dann wird gestern niemand eingestellt. Noch?
Java Java ist die Norm. Als Sprache ist es meiner subjektiven Meinung nach nicht sehr, aber die JVM ist eine großartige virtuelle Maschine, alles ist in Ordnung, es funktioniert schnell, aber es benötigt immer noch viel Hardware. Und während wir in Java einen abstrakten Builder der Strategiefabrik schrieben, gingen die Benutzer zu Konkurrenten, anstatt Funktionen zu erstellen.
Okay, wir haben immer noch Python. Im Prinzip ist alles in Ordnung. Aber wir führen die Anwendung in Python aus, sie verwendet einen Kern von 56, sonst ... ist alles in Ordnung. Oder Sie können etwas Modernes nehmen: Gehen Sie, Rust, etwas anderes. Aber sie sind zu niedrig und wir machen nur lange Zeit Features ... Wir müssen noch eine Sprache auswählen. Lass es am Ende JS sein, komm runter.

Datenbank
Basis. JS ohne Dokumentenbasis - Geld den Bach runter. Dokumentenbasen haben ihre Vorteile. Sie ermöglichen es uns, schnell Prototypen zu entwickeln, nicht über das Schema zu baden und die Wurstdaten hin und her zu bewegen. Es gibt viele Pluspunkte, minus eins: Brei aus den Daten. Wenn wir zehn, zwanzig oder vierzig Sammlungen anstelle von drei haben und versuchen, etwas Gutes und Verdauliches ohne das Fehlen von Schemata daraus zu kleben, wird es immer schwieriger, dies zu tun. Wieder machen wir Features für eine lange Zeit.
Ok, nehmen wir eine relationale Basis. MySQL, PostgreSQL oder Oracle, wenn Sie genug Geld haben. Mit relationalen Datenbanken können Sie eines Tages zur Arbeit kommen und sich von Transaktionen und Speichern in der Hölle befinden. Dies muss bei unserem Projekt nicht unbedingt der Fall sein. Aber wenn das passiert, können diese Feinheiten der Logik nicht getestet werden. Und selbst wenn wir plötzlich die vertikale Grenze unseres großen Goldservers erreichen, auf dem wir die Datenbank hosten, wird es ziemlich schwierig sein, sie zu trennen. Wir machen Features für eine lange Zeit.
Okay. Sie nahmen eine Basis, ORM schlug davor, um den Wechsel von einem SQL zu einem anderen zu erleichtern. Eines Tages (Spoiler: nie).

Architektur
Welche Architektur soll man nehmen? Leute auf Habré schreiben, dass Microservices cool sind. Oleg Bunin sagt: "Nehmen Sie Microservices."
Wenn Sie mit Microservices beginnen, sind die Grenzen mit einer Wahrscheinlichkeit von achtzig Prozent falsch, da sie das Domänenmodell nicht vollständig durchdacht haben und schlecht verstanden haben, wo geschnitten werden soll und wo nicht. Außerdem nutzen sie alle Microservices, stellen sie in Stapeln im gesamten Cluster bereit, und einen Monat später stellt sich die Frage: "Wie kann ich das alles jetzt testen?" Services funktionieren bereits in der Produktion, aber wir testen sie nicht. Mit bekannten Methoden (Testpyramide, manuelle Integrationstests, End-to-End-Tests) ist es schwierig, Microservices zu testen. Daher machen wir schon lange Features.
Ok, dann lass uns einen Monolithen schlagen. Dies ist die richtige Idee für ein Startup. Sie können sehr lange mit einem großen Monolithen leben und haben keine Probleme. Aber wenn wir uns entschließen, das Team stark zu erweitern, müssen wir vorsichtig sein. Der Monolith skaliert normal, während die Entwickler 20, 30, 50 sind. Außerdem sinkt die Geschwindigkeit der Bereitstellung von Features exponentiell und wir verlieren Benutzer.

Wo soll das Projekt beginnen?
Es muss alles irgendwo gestartet werden. 2018 ist die logischste Option, dies in der Cloud zu tun. Lass es nicht in der Wolke laufen - die Jungs werden lachen. Erstens gibt es jedoch das Bundesgesetz 152, das die Auswahl der Cloud-Anbieter, die gehostet werden können, erheblich einschränkt. Zweitens ist es sehr einfach, versehentlich einen privaten Schlüssel für Ihr Konto bei Amazon bei Github zu reservieren, und auf jeden Fall wird jemand kommen und Ihr gesamtes Geld ausgeben. Und wenn dies nicht der Fall ist, werden Sie irgendwann durch Cloud-Tarife kaputt gehen.
Sie können ein Rechenzentrum mieten. Vielleicht ist dies anfangs nicht so ressourceneffizient, aber auf lange Sicht wird es wahrscheinlich billiger sein als das Hosting in der Cloud. Aber hier brauchen wir Leute, die es unterstützen. Nach meiner Erfahrung kommunizieren diejenigen, die es lieben und wissen, wie man es macht, nicht wirklich gerne mit allen anderen, deshalb sind sie in der Abteilung organisiert. Und die Abteilung ist Separatismus. Ich meine, es wird einfacher sein, Erfahrungen innerhalb des Admins-Teams auszutauschen, aber in Zukunft wird dies möglicherweise nicht sehr gut funktionieren. Es wird Fragen zur Priorisierung von Aufgaben anderer Kollegen und zur Synchronisierung geben. Andere Spezialisten wissen nicht, was in der Abteilung passiert, die unser Rechenzentrum unterstützt.
Separatismus passt im Allgemeinen nicht zu uns. Logischerweise wenden wir uns der Frage der Rekrutierung eines Teams zu.
Das Team
Entwicklung
Nehmen wir an, wir haben herausgefunden, in welchen Sprachen, Datenbanken und wo das Projekt gehostet werden soll. Es ist Zeit, ein Team zu rekrutieren. Sie können einige sehr coole Typen nehmen, die alle Probleme lösen: hundertfache Entwickler, Backend-Ninjas, verstehen Sie? Vielleicht wird es eine Fahrt geben. Tatsächlich ist es jedoch wahrscheinlich, dass die eingeladenen Stars:
- giftige Typen, die nichts tun und eine schlechte Atmosphäre im Team schaffen,
- oder Idealisten, die Stück für Stück eine makellose Architektur aufbauen und ORM vor Basen stellen, die Sie nie ändern müssen ...
Am Ende ... ja, wir machen schon lange Features. Eine andere Möglichkeit besteht darin, gewöhnliche Mädchen und Männer, die nur Code schreiben, mit Funktionen zu beauftragen. Aber wenn Sie viele nicht sehr erfahrene Entwickler mit unterschiedlichen Hintergründen nehmen, können sie Code in einem anderen Stil schreiben, Dinge anders machen und bei einer ausreichenden Größe des Teams wird jeder eng, jeder hat geschweifte Klammern in den Pull-Quests des anderen. Es ist nicht sehr effektiv. Wie kann das gelöst werden? Der Chef kann den gesamten Code lesen. Ich kann alle Pull-Quests lesen, und mein Freund und Mitbegründer Gründer Valera wird sie dann zum zweiten Mal erneut lesen (nur für den Fall, dass Sie es nie erfahren). Es ist klar, dass dies nicht skaliert und alle Funktionen langsam erstellt werden.
Eine korrektere Option besteht darin, einen Codestil für das Unternehmen zu definieren. Für viele Sprachen existiert es bereits und Sie können es einfach befolgen. Oder wenn jemand wirklich möchte, können Sie ein fertiges nehmen und es ein wenig hochziehen. Schauen Sie sich dann die Pull-Quests an und sagen Sie, dass die geschweifte Klammer nicht vorhanden ist, sie sollte gemäß dem Codestil vorhanden sein. Sie können mit einem solchen Argument nicht argumentieren, aber in Wirklichkeit ist es nicht viel besser als die vorherige Version, trotzdem machen wir langsam Features. Die richtige Option für alle modernen Sprachen besteht darin, dies automatisch zu überprüfen.

Ok Wir haben Entwickler bewertet, Feigencode. Aber wir haben angefangen, Features in der Produktion zu veröffentlichen, und wir müssen irgendwie sicherstellen, dass wir sie ohne Fehler rollen, damit bei uns nichts abfällt.
Qualitätssicherung
Wir können sagen, dass wir keine QS-Spezialisten brauchen. Viele machen das, manchmal funktioniert es. Aber nicht alle Entwickler schreiben gerne Tests. Sie können verstanden werden. Und es ist besser, sie zu motivieren, die Tests zu schreiben, aber die Realität ist grausam: Unit-Tests fangen nicht alle Fehler ab. Und wenn einige Entwickler keine Tests schreiben möchten und dennoch damit beginnen, diese zu schreiben, handelt es sich höchstwahrscheinlich um Komponententests.
Außerdem gibt es immer noch Ansätze, bei denen Sie die mittlere Zeit zwischen Ausfällen minimieren, anstatt die mittlere Zeit für die Wiederherstellung. In der Zwischenzeit zwischen den Fehlern sagt ein QS-Spezialist: "Wir werden nicht veröffentlichen, ich habe ein schlechtes Flair, es wird Fehler geben, lasst uns in zwei Wochen ausrollen." Die mittlere Zeit für die Wiederherstellung ist, wenn Sie etwas würfeln. Sie sehen sofort auf den Metriken, dass etwas kaputt ist, und nach zwei Minuten wurde alles zurückgesetzt, repariert und alles ist in Ordnung. Um das Projekt in zwei Minuten zurückzusetzen, müssen Sie jedoch alles mit normalen Metriken abdecken, und dies ist nicht immer trivial. Und wenn sich die Metriken in einem bedauerlichen Zustand befinden und wir eine schlechte Version herausbringen, können wir dies herausfinden, nachdem alle Benutzer uns den Wettbewerbern überlassen haben.
Eine weitere Option: Machen Sie noch eine QS-Abteilung. Sie erinnern sich: Die Abteilung ist nicht sehr gut, es ist Separatismus, es passt nicht zu uns. Separatismus kann mit Hilfe funktionsübergreifender Teams gelöst werden. Ja, sie lösen das Problem, dass unser Administrator separat sitzt, Tester sind getrennt.
Aber sie schaffen andere Probleme. Da Entwickler, Tester und alle anderen Mitglieder funktionsübergreifender Teams beginnen, mehr innerhalb ihrer Teams zu kommunizieren und frühere Probleme zu lösen, kommunizieren sie weniger mit ihren Kollegen in ihrer Funktion: Andere Backder und Tester beginnen, das Rad neu zu erfinden, machen die gleichen Dinge parallel, Isolation zwischen Teams. Ahle nach Seife: Es gab einen Separatismus, es wurde ein anderer.
Wie kann ich das beheben? Kommunizieren Sie mit Kollegen in Hobbygruppen. Irgendwo heißt es Gilden, irgendwo ist es Gemeinschaft. Wenn wir das Team mit funktionsübergreifenden Teams skalieren, damit diese nicht in sich geschlossen werden, organisieren wir einfach einen Kreis von Fans von Backend, funktionalen Sprachen, Sicherheit ...

Zusammenfassung
In der Tat ist nicht alles so schlecht. Sie können einen Ausweg aus jeder Situation finden, eine Lösung finden. Vielleicht nicht ideal, aber am besten geeignet in dieser Situation mit einem Minimum an Problemen. Ein Kompromiss ist immer möglich.
Und doch - das alles ist interessant. Es ist interessant, Probleme zu lösen, die bereits jemand gelöst hat, neue Probleme sind noch interessanter zu lösen. Es ist interessant, Wissen zu teilen.