Zeigen Sie mir eine Lösung, über die die Entwickler nicht streiten werden, und ich werde Ihnen ein Bier geben



Es gibt zwei unvereinbare Lager. Einige sagen: Sie müssen Ihre Commits genau und kompetent beschreiben. Jedes Commit ist eine vollständige, aussagekräftige Arbeit. Wenn Sie eine Festschreibung nicht klar und einfach beschreiben können, haben Sie die falschen Festschreibungen.

Andere denken, dass Sie Commits machen, wie Sie möchten. Dies ist Teil Ihres persönlichen Workflows. Der Pool der Anfragen wird jedoch ausführlich beschrieben: Was wird getan, wie wird getan, warum wird es getan. Wie getestet, welches Problem löst, worauf Sie achten sollten.

Ich bin ein überzeugter Befürworter des zweiten Ansatzes - es ist für mich unpraktisch, meine Arbeit in Kleinigkeiten zu zerlegen. Ich nehme eine kleine Aufgabe an und rase zufällig durch die Codebasis, experimentiere und nehme Änderungen in der Reihenfolge vor, in der sie sich herausstellt. Wenn ich auf eine Schaltfläche klicken könnte und meine Arbeit in gute Commits umstrukturiert würde, würde ich darauf klicken. Es gibt zwar keinen Knopf, aber ich möchte mich nicht brechen. Gleichzeitig erreichte ich eine gewisse Fähigkeit, den Pool von Anfragen zu beschreiben. Ich habe zufällig den Code in Microsoft herausgefunden (durch Outstaff zählt er nicht) und dort habe ich die besten Standards für die Verarbeitung eines Pools von Anfragen erhalten. Im Laufe der Jahre habe ich diese Praxis gerade entwickelt. Normalerweise gelang es mir, das Team davon zu überzeugen, einen solchen Ansatz zu verwenden.

Aber beim letzten Job wurde ich devlid - ein überzeugter Befürworter detaillierter Commits. Oh, wir haben lange gestritten. Meine untergeordnete Position spielte eine Rolle, die Gewohnheit von Sovkovsky, der Hauptsache zuzustimmen, ist nicht leicht zu schließen. Ich war nicht so kategorisch wie gewöhnlich und wurde auf beide Klingen gelegt. Gestapelt, aber nicht überzeugt.



Wenn sich die Entwickler plötzlich zu einer einzigen Regierung zusammenschließen, Regeln festlegen und bestimmte Ansätze für verboten erklären, beginnt am nächsten Tag ein Bürgerkrieg. Alles nur, weil in der Welt der Entwickler der Glaube an das Ziel und das Messbare besteht. In Wahrheit unabhängig von der menschlichen Wahrnehmung. Und wenn all dies existiert, bedeutet dies, dass einer der Disputanten eindeutig objektiv falsch ist.

Mein erster ernsthafter Arbeitskampf ereignete sich ziemlich früh. Ich war noch ein grüner Juni, der glaubt, er sei Apper Middle und in der Tat ein sehr cooler und kluger Entwickler. Ein echter Entwickler aus meinem Team warf PR. Wir hatten die Praxis, dass alle Teammitglieder einen Überprüfungscode erstellen. Ich öffnete den Code und sah fast sofort das Problem. Ein Mann schrieb einen Test für eine Funktion, die eine Nummer nahm. Also fütterte er sie mit 0, 1000 und zufällig (0, 1000).

Zu dieser Zeit hatte ich das starke Gefühl, dass andere Teamkollegen mich als dummen Neuling betrachteten. Und er wartete einen Moment, um sie mit seiner Vision zu beschmieren. Ich hatte Glück - zufällig in Tests!

Ich habe die Theorie des Unit-Tests nicht wirklich verstanden, aber ich habe ein paar Bücher gelesen und mich fest daran erinnert - der gleiche Unit-Test auf derselben Codebasis sollte das gleiche Ergebnis liefern. Ich habe ungefähr eine Stunde damit verbracht, über den Kommentar nachzudenken, damit er nicht giftig aussieht, aber es wurde klar, dass nur der Affe, dem erst gestern das Zählen beigebracht wurde, eine solche Entscheidung treffen konnte. Infolgedessen sah er auf jeden Fall extrem dumm aus, wie alles, was die Auszubildenden von gestern hatten, und stellte sich vor, wie sich Entwickler aus sich herausgedrückt hätten.

Am nächsten Tag wurde mir klar, dass ich ein Portal zur Hölle geöffnet hatte. Es gab noch hundert unter meinem Kommentar. Für den Rest des Tages waren wir anstelle eines Teams von sechs Entwicklern ein Team von sechs Affen. Wir haben uns in der PR selbst auf Englisch gestritten, obwohl alle Russen waren. Als der Wortbestand nicht ausreichte, riefen sie an. Sie warfen sich gegenseitig mit Links, Zitaten aus Büchern, Studien zu und wandten sich an den Einzelnen. Ein Kollege beantwortete einen meiner Kommentare mit einem Screenshot aus einem englischen Wörterbuch, um mein Englisch lächerlich zu machen. Wir sind jedoch nicht zu einem Kompromiss gekommen.

Die Frage war kompliziert. Einerseits wussten wir alle überhaupt nicht, wofür dieser Parameter verantwortlich war, unsere Funktion gab ihn an die andere weiter, von einem internen Netzwerk, an das es keine Docks gab. Daher könnte die Funktion theoretisch auf einen beliebigen Wert fallen, was bedeutet, dass der Test ihn abfangen könnte, und dann könnten wir den Fehler auf dem Produkt antizipieren. Auf der anderen Seite hatten wir bereits das Problem, Builds zufällig zu suhlen. Aus diesem Grund haben wir, wenn das Projekt lokal erstellt wurde und abstürzte, dumm einen neuen Build bestellt und keine Protokolle angesehen. Immerhin dauerte der Build vier Stunden, und niemand würde sich die Pull-Anfrage ansehen, bis sie CI bestanden hatte.

Außerdem waren die Autos oft beschäftigt - es war viel pragmatischer, einen Bau zu bestellen, während er noch bestellt wurde, als nach einem potenziellen „Problem“ zu suchen (das sich im Integrationstest fast immer als Flug-Timeout herausstellte). Dies bedeutete, dass wir selbst dann nicht aufpassen würden, wenn der Zufallstest ausfiel.

Alles wurde beim nächsten Dealik gelöst. Wir haben das ganze Team angerufen und eine halbe Stunde lang weiter gestritten - auf Russisch. Wir bemerkten nicht, wie sich unser amerikanischer Entwicklungsmanager dem Aufruf anschloss, und zerschmetterten uns weiterhin mit Argumenten in erhöhten Tönen. Bis sie hörten: „Hey Leute, das ist absolut nicht wichtig. Füge es einfach so zusammen, wie es ist. " Ich weiß nicht, wie lange er uns zuvor zugehört hat und wie er verstanden hat, worüber wir gesprochen haben, aber wir haben abrupt aufgehört zu streiten. Sie erstarrten und vergaßen es. In Frieden getrennt, aber nicht überzeugt.



Seitdem habe ich Erfahrung gesammelt, um zu verstehen - aber scheiße nicht, zufällige, Handicap- oder Grenzfälle. Dieser verdammte Unit-Test wird stören - wir werden neu schreiben. Alles ist besser als den ganzen Tag zu streiten. Aber wenn Sie sich vorstellen, dass ich mich in einer idealen Welt befinde, in der es immer notwendig ist, nur korrektere Entscheidungen zu treffen, weiß ich nicht, was ich tun soll. Wir haben einen Test mit Zufälligkeit eingefroren, und jetzt verstehe ich dies als eine Wahl zugunsten der Zuverlässigkeit, aber zum Nachteil der Bequemlichkeit der Entwicklung.

Neulich stand ich vor einem ähnlichen Dilemma. Ich habe mit dem neuen Timecode gespielt und etwas geschrieben, das so verwendet werden kann

// LessThan<T>  MoreThan<T> -    ,   . 
// ,        

//      , 
//   ,   100
const consumeNumberLessThan100 = (v: LessThan<100>) => 
    doWork(v);

//     ,   100
const consumeNumberMoreThan100 = (v: MoreThan<100>) => doWork(v);

const sample = (x: number) => {

    //     check  , 
    //   x  100
    //  "<"  ">"  , 
    //     -   
    const lessThan100 = check(x,'<', 100);

    if (lessThan100) {
        //     -  
        //       
        //    ,  lessThan100  - LessThan<100>
        //    
        consumeNumberLessThan100(lessThan100); 

        //   -  ,   , 
        //  ,   > 100.
        consumeNumberMoreThan100(lessThan100);
    }

    const moreThan100 = check(x, '>', 100);

    if (moreThan100) {
        consumeNumberMoreThan100(moreThan100); // 
        consumeNumberLessThan100(moreThan100); // 
    }

    consumeNumberLessThan100(x); // 
    consumeNumberMoreThan100(x); // 
}

Ich dachte, verdammt, das ist sehr cool - so dass Sie zu einem früheren Zeitpunkt eine große Anzahl von Fehlern abfangen können. Das Design meiner Tools zur Wertbeschränkung ist schrecklich, aber im Moment ist es nur ein Konzept. In Zukunft können Sie es problemlos erweitern, ein leistungsstarkes DSL erstellen und wirklich komplexe Bedingungen für die Parameteranpassung formulieren, die in der Kompilierungsphase garantiert werden. Ich habe herausgefunden, wie es die Zuverlässigkeit jeder Codebasis erhöhen kann, habe mich verbessert und ein Snippet an verschiedene bekannte Entwickler gesendet.

Die Meinungen waren wieder geteilt und nicht in meine Richtung. Nachkomplikationen, Überentwicklungen werden nicht unterstützt, jeder wird Ihre Wache mit Hilfe einer Besetzung von eni stören. Nicht lesbar. Gut wie ein Experiment ist im vorliegenden Projekt schlecht. Anwendungsbeispiele werden vom Finger gezogen. Komm zur Sache, Phil.

Befürworter des Ansatzes sagten ja, so zuverlässig. Je früher Sie einen Fehler bemerken, desto besser. Wenn Sie eine Funktion schreiben, die mit einer begrenzten Anzahl funktioniert, müssen Sie noch eine Prüfung schreiben, die jedoch nur zur Laufzeit funktioniert und die Codemenge im Hauptteil der Funktion erhöht.

Jetzt bin ich etwas schlauer als zuvor und habe gelernt, die Argumente zu hören. Ich stellte mir vor, ich würde eine von meinem Typ geschützte Funktion in einem realen Projekt schreiben. Wie jeder, der es benutzt, fragt er mich, was zum Teufel das ist. Wie sie nach dem Fummeln des Chips beginnen, die Codebasis mit einem benutzerdefinierten, faul aussehenden DSL zu beschichten. Da wir dreihundert Mal prüfen, werden die Werte, die tatsächlich niemals die zulässigen Werte überschreiten. Der Ansatz ist wirklich schrecklich zu verwenden, einige Probleme können gelöst oder geglättet werden, aber zum Beispiel ein solcher Fall

consumeNumberLessThan100(90);

In keiner Weise glätten. Ich muss dem Compiler beweisen, dass 90 weniger als 100 ist. Ich werde jede Aktivität bereitstellen, und es wird sich herausstellen

consumeNumberLessThan100(assert(90, '<', 100)); 

Es sieht nicht sehr cool aus. Alle Argumente gegen sind vorhanden, aber sie widersprechen nicht den Argumenten für. Es stellt sich als Dilemma heraus - einfache Entwicklung oder Zuverlässigkeit. Hier geraten wir in die Falle, wir beginnen zu denken, dass wir berechnen müssen, welche Art von Bequemlichkeit es gibt und welche Art von Zuverlässigkeit es gibt. Bequemlichkeit und Zuverlässigkeit bei der Entwicklung sind jedoch sehr, sehr komplexe Dinge. Sie bestehen aus Tausenden von Parametern.

Zum Beispiel ist es praktisch, wenn die IDE den Code für Sie aus einem Paar eingegebener Zeichen kompiliert, wenn der Code leicht zu lesen ist und Sie die Funktionalität der Methode ändern können, ohne das Dokument zu betrachten. Wenn der Compiler nicht mit statischer Analyse geladen ist, ist der Build schnell und der Texteditor rendert sofort Zeichen. Wenn der Compiler den Fehler für Sie erkennt und hervorhebt, ist dies ebenfalls eine Annehmlichkeit. Und es ist auch Zuverlässigkeit. Was wiederum aus einer Vielzahl völlig unterschiedlicher Dinge zusammengesetzt ist.

Sie müssen sich hinsetzen und berechnen, wie lange das Projekt dauern wird, in welche Richtung es gehen wird, wie oft in der Geschichte der Menschheit jemand die eine oder andere Methode Ihrer Codebasis aufruft, die Entwickler hier arbeiten werden. Dies ist eine endlose Liste von Fragen, für deren gute Hälfte es unmöglich ist, die richtige Antwort zu berechnen. Rate einfach.



Einmal bat mich ein Freund, technische Fragen für ein Interview mit Andrei Breslav vorzubereiten. Ich ging zum Dock von Kotlin, um kontroverse Punkte im Design zu finden. Sie sind dort, wie anderswo, Dunkelheit. Am meisten interessierte mich jedoch der Umgang mit Ausnahmen. Ein Ausnahmebehandler in Kotlin ist ein Ausdruck, ein vollständig funktionaler und zuverlässiger Ansatz. Das ist nur um Fehler zu behandeln ist nicht notwendig. Das lässt jede Zuverlässigkeit auf Null fallen. Und das ist interessant, weil die Entwickler direkt im Dock nicht zu faul waren, um ihre Wahl zu erklären: „Es gibt Studien, nach denen die obligatorische Fehlerbehandlung die Produktivität von Entwicklern mit einer leichten Verringerung der Fehler erheblich verringert.“

Ich bin verrückt, wie kannst du Code schreiben, wenn du keine Ahnung hast, was zu tun ist, wenn es nicht richtig funktioniert? Wenn Sie nicht wissen, wie Sie mit der Ausnahme umgehen sollen, behandeln Sie sie nicht - keine Lösung für das Problem, sondern Regale. Irgendwann fällt der Code ab und ein Problem, das immer besteht, verursacht Schäden, die hätte erwartet werden können.

Ein logisches Argument dagegen ist jedoch nicht erforderlich, Sie können nur Statistiken erstellen. Für Kotlin-Entwickler bricht die Forschung die Logik, weil sie eine Philosophie haben. Ihre Philosophie ist Pragmatismus. Eisen, unzerbrechlicher Pragmatismus, konsequent in alle Funktionen dieser Programmiersprache eingebaut. Die Idealisten, die die Haskels / Idris gesehen haben, und die Govnokoders, die den Golang geschrieben haben, tun genau das Gleiche. Die Philosophie eines vernünftigen Kompromisses herrscht in der F # -Codebasis vor. Und es gibt kein Gefühl, dass einer von ihnen Recht hat, und der Rest sind Dummköpfe.

Alle diese Leute sind viel schlauer und erfahrener als Leute wie ich, und sie scheinen lange verstanden zu haben, dass Sie eine Philosophie für sich selbst entwickeln, und dann folgen Sie einfach dieser. Denn das Killer-Merkmal jeder Philosophie ist es, die Dilemmata zu lösen.

Und so tauchte Philosophie in allem in der IT auf, und Philosophie ist das genaue Gegenteil der Idee einer einzigen und wahren Objektivität, weil die Philosophie anbietet, die subjektive Wahrheit für sich selbst zu wählen.

Jeder von uns hat seine eigene Philosophie - sie wird nicht in einem Wort beschrieben, sondern ist ein komplexer Satz von Mustern, um Entscheidungen zu treffen. Und wir ändern oder erweitern sie oft. In der Praxis stellt sich heraus, dass Sie ein Projekt mit Ihrer eigenen Philosophie haben, das in einer Programmiersprache mit Ihrer eigenen Philosophie geschrieben ist und Frameworks und Tools verwendet, von denen jedes seine eigene Philosophie hat. Und Entwickler schreiben dieses Projekt, jedes mit seiner eigenen Philosophie. Und jedes Mal, wenn Sie eine Entscheidung treffen müssen, wirkt sich nur eine Kombination von Umständen darauf aus, welche getroffen werden. Kein Komplexitätsmanagement, keine Erfahrung, kein Ansatz, kein Wissen, sondern nur ein Unfall.

Und all diese Projekte funktionieren. Der Löwenanteil aller Aufgaben, die Entwickler lösen, ist die Beseitigung der Folgen von Fehlern anderer Entwickler, aber Projekte funktionieren und lösen die Probleme der Menschen. Kluge Köpfe entwickeln Praktiken und Architekturmuster. Programmiersprachen mit leistungsfähiger Typsteuerung und Verträgen - alles, wenn sich nur die Entwickler weniger irren würden. Und jeden Tag öffne ich das Edge Board bei der Arbeit und sehe, dass es mehr Fehler als Aufgaben gibt. Wo ist jeder Fehler, dies ist ein anderer, der Komplexität verwaltet, Mistentwickler.

Die Entwicklungsphilosophie ist einfach die Wahl, wie Sie das Finale in die Hände bekommen. Aber wenn es keine Philosophie gibt, sondern nur reine objektive Logik, dann wird jedes Argument auf das Problem des allmächtigen Schöpfers und des unerträglichen Steins zurückzuführen sein.



Ich bin schon lange in der Entwicklung und habe gelernt, wie man das macht, was sie sagen, auch wenn ich grundsätzlich nicht einverstanden bin, und habe angefangen, sehr detaillierte Commits zu schreiben. Mein Devlid ist ein echter Vampir. Es erfordert nicht nur eine Beschreibung - er möchte, dass ich schreibe, was jede Datei tut, warum sie es tut, wie sie es tut. Welches Problem hat Commit Commit?

Ich habe acht besonders detaillierte Commits hinzugefügt, die gleiche detaillierte Beschreibung des Anforderungspools - und es hat mir gut gefallen. Seitdem haben wir fast nicht mehr an diesem speziellen Projekt gearbeitet, aber von Zeit zu Zeit gehe ich dorthin, um diese Verpflichtungen zu bewundern. Ernsthaft, wirklich, wirklich cool. Und in allen anderen Projekten, außer meinen persönlichen, wende ich diesen Ansatz jetzt an.

Es war sehr schwierig für mich, den Workflow neu zu erstellen. Eineinhalb Monate sind vergangen, und es fällt mir immer noch schwer, solchen Code zu schreiben. Aber es scheint es wert zu sein.

Oder nicht. Ich weiß es ehrlich gesagt nicht. Und ich weiß nicht, ob es mich zwei Monate alt macht, wenn es sich definitiv lohnt. Ungefähr zehn Menschen laufen irgendwo auf der Welt herum, von denen ich gelernt habe, dass sie solche Verpflichtungen nicht eingehen. Sind sie Idioten? Ich glaube nicht.



Mein Podcast

All Articles