Am Vorabend von Moscow Python Conf ++ sprachen wir mit Nikita Sobolev, CTO des Unternehmens We Make Services, über das globale Problem der Verwaltung der Codekomplexität im Kontext der Entwicklung von Programmiersprachen. Und auch darüber, warum sich die Situation hier im Laufe der Zeit nur verschlechtert. Außerdem fragten sie, warum er seinen eigenen Linter erstellen müsse.
- Erzählen Sie uns ein paar Worte über sich und Ihre Arbeit.Ich bin der technische Direktor von "We do services". Wenn ich den Namen des Unternehmens spreche, stelle ich normalerweise die Frage: "Was denken Sie, was machen wir?". Tatsächlich sind wir auf Webentwicklung spezialisiert: Frontend und Backend für Firmenkunden. Und wir arbeiten nach unserer eigenen Methodik, die wir parallel zur Entwicklung des Unternehmens verbessern - Repeatable Software Development Process (RSDP).
- Bei Moscow Python Conf ++ werden Sie auch über Ihren eigenen Linter sprechen. Wie hängt Ihre Arbeit mit Auditing und Code Complexity Management zusammen?Im Allgemeinen haben wir zwei Hauptbereiche: Entwicklung selbst und alles um sie herum: Beratung, Erstellung von Anforderungen und insbesondere Prüfung, in denen ich den Code vieler anderer Leute sehe. Der Code ist völlig anders: der, der sich derzeit in der Entwicklung befindet, und das Erbe, das niemand jemals reparieren wird; und den Code, den die Spezialisten des Kunden schreiben, und den, den sie nebenbei bestellt haben. Und in allen Versionen des Codes gibt es viele Probleme: gleich und verschieden.
- Sie werden mit Entwicklern speziell in Python sprechen. Verfügt Python über Funktionen zur Verwaltung der Codekomplexität?Natürlich!
Erstens leiden alle Sprachen mit dynamischer Typisierung in größerem Maße unter ungerechtfertigter Komplexität, zumindest aufgrund des Mangels an zusätzlichem Kontext beim Lesen von Code. Und du darfst mehr Dreck.
Zweitens entwickelt sich Python aktiv weiter. Es hat neue Syntaxelemente, neue Konzepte und Module in Standardbibliotheken, die alles kaputt machen, was vorher war.
- Wie schlimm ist alles in Python? Immerhin gibt es andere sich aktiv entwickelnde Sprachen, zum Beispiel JavaScript, das oft dafür kritisiert wird. Ist JavaScript besser?Nein. Ich würde sogar sagen, dass Python in Bezug auf die Komplexität in Bezug auf andere Sprachen ziemlich gut ist. JavaScript ist aus einem einfachen Grund wirklich schlecht: Im JS-Projektcode werden mehrere Entitäten, die nicht mit der Sprache selbst zusammenhängen, gleichzeitig gemischt - Plugins und Bibliotheken von Drittanbietern, die zum Erstellen des Projekts verwendet werden. Wenn Sie beispielsweise Webpack verwenden, können Sie die Funktion "import ()" schreiben, mit der die Module asynchron geladen werden. Es stellt sich heraus, dass der Sammler einige seiner Innenseiten in Ihre Programmiersprache schiebt, und am Ende ist im Allgemeinen unklar, was passiert.
Das Verwalten der Komplexität ist schwierig, wenn sich die Sprache durch die Installation von Babel oder seinen Plugins ändert. Und um zu verstehen, wie sie funktionieren, müssen Sie die Sprachstandards, die spezifische Implementierung usw. befolgen.
In Python ist die Situation viel besser. Die Sprache entwickelt sich ziemlich systematisch und diese Entwicklung hat verständliche Meilensteine. Darin können Sie die Syntax mit zwei Zeilen in der Konfiguration nicht radikal ändern. Und dies ist immer noch ein Backend, an das wir höhere Anforderungen stellen als an das Frontend. Meiner Meinung nach gibt es in Python jedoch einige neue Änderungen, die das bisherige brechen und zweifelhafte Vorteile bringen.
- Das heißt, mit der Entwicklung der Sprache wird alles schlimmer?Wenn Sie sich daran erinnern, dass AsyncIO - im Wesentlichen eine zweite Sprache in Python - aufgetaucht ist, ist die Komplexität natürlich sehr gewachsen. Tatsächlich gibt es jetzt zwei völlig unabhängige Programmiersprachen mit ähnlicher Syntax: Python und Python + AsyncIO. Das heißt, Python als Entität ist doppelt so kompliziert geworden, weil zwei separate Nachkommen nach unterschiedlichen Regeln arbeiten.
Die Meinung, dass dies verschiedene Programmiersprachen sind, ist nicht beliebt. Wenn Sie jedoch Gegner dieser Meinung bitten, beispielsweise eine asynchrone Funktion aus synchronem Code auszuführen, schlagen sie fehl. Bibliotheken sind auch völlig anders. Möchten Sie eine synchrone Bibliothek verwenden, um mit der Datenbank zu arbeiten - bitte. Und Sie wollen asynchron - das ist es nicht.
In Python, das vor fünf Jahren geschrieben wurde, hat sich jedoch nichts wirklich geändert, und sogar umgekehrt wurden Tools angezeigt, die den Code vereinfachten, z. B. Anmerkungen und Typprüfung.
- Beeinflusst das Komplexitätsmanagement die Tatsache, dass es in der Programmierung mittlerweile ziemlich viele Leute mit einer schwachen technischen Basis gibt?Natürlich. Für solche Leute haben sie sogar eine spezielle Programmiersprache entwickelt. Es heißt Go. Ich scherze nicht. In der Tat war das Ziel der Erstellung der Go-Sprache ein Versuch, Google-Studenten und Praktikanten, die C ++ nicht lernen können, in das Schreiben von Code einzubeziehen. Python passte nicht zu ihnen, sie brauchten etwas anderes, und Google hatte Go entwickelt. Wie sich herausstellte, sind viele Leute bereit, darüber zu schreiben, weil es sehr einfach ist. Aber zu welchem Preis wurde diese Einfachheit erreicht? Sie geben uns keine normale Programmiersprache, sondern eine sehr verkürzte Version - es gibt praktisch keine komplizierten Konzepte. Es gibt keine Generika, es gibt keine Ausnahmen usw. Und es gibt viele Fans dieses Ansatzes.
Es gibt aber auch andere Entwickler, und für sie besteht das Problem darin, dass es Sprachen gibt, in denen es kein Gleichgewicht gibt: Sie können einfache Dinge einfach und komplexe Dinge überhaupt nicht tun. Oder zumindest durch Schmerzen - man muss mit einem Werkzeug kämpfen, um etwas zu tun. Hier scheint mir das Problem des Komplexitätsmanagements zu liegen.
- Was sind die typischen Probleme des Codes eines anderen?Normalerweise sind sie in zwei Teile unterteilt.
Das erste sind die Probleme, die mit der Tatsache verbunden sind, dass sich die Leute nicht darauf einigen können, wo bedingte Kommas gesetzt werden sollen. Sie lesen einen Code und sehen Kommas an einer Stelle, wechseln zu einer anderen Datei - und sehen Kommas an einer anderen Stelle. Dies erschwert die Wahrnehmung, als würde man ein Buch lesen, das an einer Stelle fett und an einer anderen kursiv gedruckt ist. Dies lenkt vom Inhalt ab, da das Gehirn erkennen muss, dass es eine andere Art ist, dasselbe zu schreiben.
Wenn Sie die Syntax korrigieren, achten Sie auf die Semantik, da die Leute konzeptionell anders schreiben. Leider gibt es keine Möglichkeit, sich auf dieser Ebene zu einigen - es ist unmöglich, eine Einigung darüber zu erzielen, dass wir solche Probleme auf diese Weise lösen, aber diese sind es. Es ist zunächst nicht möglich, alle Fälle abzudecken. Dieser Vorgang findet während einer Codeüberprüfung einer sofortigen Aufgabe statt: Wenn dem Entwickler erklärt wird, warum seine Entscheidung nicht getroffen werden kann. Wenn die Praxis der Codeüberprüfung angewendet wird und die Prüfer gut sind, schneiden sie die Lösungskurven ab und es gibt keine Probleme im Code. Aber normalerweise kommen wir zum Audit, wo ein solcher Prozess nicht etabliert ist. Und die Probleme der Semantik und Architektur sind viel schwieriger zu lösen, weil sie manchmal selbst schwer zu formulieren und zu definieren sind.
- Und wie sieht es in der Praxis aus?Beispielsweise können Benutzer das gleiche Problem in Vorlagen, Ansichten oder Modellen lösen. Und es gibt kein allgemein anerkanntes Verständnis, wo genau diese Aufgabe gelöst werden sollte: Keine Dokumentation oder Muster, die speziell für dieses Projekt gelten (hier verwenden wir beispielsweise dicke Modelle und setzen die gesamte Logik in sie ein, aber hier verwenden wir dünne, gut oder schlecht, jetzt es spielt keine Rolle, aber wir waren uns einig).
"Was sehen Sie als Hauptgrund dafür, dass diese Probleme überhaupt existieren?"Alle Menschen wissen nicht, wie man Code schreibt.
Diese These wird wie folgt entschlüsselt: Das Problem ist, dass wir Menschen sind. Und im Allgemeinen fällt es uns sehr schwer, etwas Strukturiertes und Logisches zu schreiben. Und hier haben wir auch zwei verschiedene Arten von Empfängern. Erstens ist dies die Person, die diesen Code liest, und zweitens ist dies die Maschine, die ihn ausführen muss. Der Code für die Maschine sollte gemäß den Kriterien Leistung, Speicherverbrauch und CPU-Zeit erstellt werden, und der Code für die Person sollte auf den Prinzipien der Lesbarkeit, Verständlichkeit usw. basieren. Dies sind zwei entgegengesetzte Aufgaben. Und eine Person, die tatsächlich nicht einmal eine von ihnen vollständig lösen kann, ist gezwungen, beide widersprüchlichen Aufgaben gleichzeitig zu lösen.
"Aber die Verwendung unterschiedlicher Programmiermuster ist im Wesentlichen eine technische Suche?" Ist es wirklich schlimmIngenieurforschung ist natürlich wichtig und notwendig. Er muss aber auch überschaubar sein. Vor jeder dieser Aufgaben müssen klare Kriterien und Einschränkungen festgelegt werden: je nach Zeitaufwand, Geschäftsanforderungen, Konstruktionspraktiken und Tools.
Es ist viel wahrscheinlicher, dass ich kreative Suchanfragen beobachte. Es gibt keine derartigen Einschränkungen, auch keine Validierung der erhaltenen Ergebnisse. Qualität kann - wie in der zeitgenössischen Kunst - nicht gemessen werden.
Fast alle Kunden, die sich für ein Audit an uns wenden, leiden unter einer typischen Situation: Jemand hat ihnen etwas angetan, sie haben einen Entwickler beauftragt, eine Lösung zu entwickeln, aber er kam und breitete die Hände aus: „Ich weiß es überhaupt nicht Lassen Sie uns hier alles neu schreiben. “ Wäre es schön, neu zu schreiben? Wird nicht. Wenn Sie sich zum Umschreiben entscheiden, treten Sie auf genau den gleichen Rechen: Sie vertrauen die Aufgabe einem anderen Entwickler an, der andere Fehler macht, aber am Ende wird alles genau gleich.
- Benötigen Sie einen anderen Ansatz?Ja Während des Audits versuchen wir, die Ursache für die Probleme mit dem Code zu finden: Warum hat niemand das Modul so weit genommen und aufgeblasen, dass es schwierig ist, durch das Modul zu scrollen, und warum wurde ursprünglich die falsche Entscheidung getroffen. Und wir versuchen, die richtigen Entscheidungen innerhalb der vorgegebenen Grenzen so weit wie möglich zu automatisieren oder zu vereinfachen.
Ich werde dem Bericht einen kleinen Einblick geben. Jeder hat das Verständnis, dass Code aus Zeilen besteht - dies ist die einfachste Entität, aus der er bestehen kann. Jede Zeile kann als geschrieben werden
x = 1
oder vielleicht wie
x = Math.median(forecast_data) if forecast_data else compute_probability(default_model)
.
Es gibt einen sehr großen Unterschied zwischen diesen beiden Zeilen, da Sie die erste leicht verstehen und sich viel Logik auf die zweite konzentriert. Es ist notwendig, es parallel zum Interpreter im Kopf auszuführen. Daher müssen Sie steuern, wie Sie den Code schreiben, indem Sie eine einzelne Codezeile steuern. Weiterhin verwandelt sich die Linie in komplexere Konzepte - Funktionen, Klassen, Module usw. Aber die Regeln, die Sie akzeptieren, müssen eine sein.
Infolgedessen verbieten wir nicht, dass viele Dinge getan werden. Weil es beim Management um auferlegte Verbote geht.
- Sind Sie auf lustige Dinge im Code eines anderen gestoßen?Natürlich. Ich habe sogar ein
Repository, in dem ich solche Codebeispiele sammle.
Das gruseligste Beispiel, das ich gesehen habe, hat mir gezeigt, dass Sie in einer Schleife von hundert Iterationen eine Funktion definieren können. Um ehrlich zu sein, als ich es mir ansah, war mein Dolmetscher kaputt. Ich vermutete, wusste aber nicht, dass es möglich war.
Es gab einen Fall, in dem wir viele lustige Kommentare im Code sahen. Jemand beschwerte sich über das Leben, über die Arbeit, es gab diejenigen, die schrieben: "Ich verstehe, dass ich Unsinn schreibe, aber der Kunde zwingt mich dazu." Kunden zwingen Sie jedoch normalerweise nicht dazu, schlechten Code zu schreiben. Sie fragen, um ihr Problem zu lösen, und welchen Code Sie dort schreiben, ist ihnen egal.
- Linter, Codeüberprüfung - nicht speichern?Ich habe zwei Antworten. Ja, das tun sie. Nein, sie sparen nicht. Es ist hilfreich, wenn Sie die Regeln und Vorschriften, die Ihnen von den ausgekleideten Laternen gegeben wurden, genau befolgen (diejenigen, die viel grobe Arbeit für Sie erledigen: Überprüfen Sie die Funktionen auf Komplexität, Codesemantik usw.). Dieser Gegenstand muss blockiert sein. Sie können den Linter manchmal nicht einfach ausführen, um das Ergebnis anzuzeigen. Wenn Sie diese Regeln nicht eingehalten haben, sollten Sie den Code in der Produktion überhaupt nicht freigeben.
Aber in der Tat - sie sparen nicht. Weil die Projekte, die es verwenden, selten sind.
Übrigens fragen sie mich oft: Wie soll ich das einführen? Und ich antworte: Es ist sehr einfach, Sie setzen eine Zeile in CI - überprüfen Sie meinen Code - und wenn es abstürzt, haben Sie es implementiert. Es bleibt nur alles umzugestalten. Glücklicherweise gibt es jetzt Autoformatierer und die Möglichkeit, Code Datei für Datei umzugestalten. Die nächste Frage ist traditionell: Wie kann man dem Unternehmen erklären, dass dies wichtig ist?
- Gibt es eine allgemeine Antwort auf diese Frage?Für jeden Fall sind die Antworten unterschiedlich, so dass es im allgemeinen Fall schwierig ist, sie zu formulieren (darüber müssen Sie nachdenken, darüber ...). Aber normalerweise kommen die Unternehmen, die sich mit diesem Problem befassen, von der technischen Seite. Das heißt, Technikfreaks fragen uns, wie Menschen, die wissen, wie man über Unternehmen und Technologie spricht, verstehen, wie sie dies in ihrem speziellen Fall dem Unternehmen erklären können. Mit einer solchen Problemstellung funktioniert dies ganz einfach. Wenn du kommst, ist schon alles schlecht und jeder versteht das. Ein Gespräch mit dem Geschäft beginnt folgendermaßen: "Sie denken wahrscheinlich, dass Ihre Programmierer sitzen und nichts tun?" Und das Geschäft nickt. Und Sie sagen, das ist nicht der Punkt. Programmierer sind großartige Leute, die versuchen, Ihre Probleme zu lösen. Aber ohne einen integrierten Ansatz für das Projektmanagement gerät alles ins Chaos, und das ist normal.
Und wir schlagen vor, Regeln auszuarbeiten, um bestimmte Probleme zu vermeiden. Wir betrachten die Kosten für die Einführung verschiedener Teile und bewerten dann die tatsächlichen (erreichten) Verluste anhand der Tatsache, dass es noch keine solchen Teile gibt. Zum Beispiel haben Programmierer seit einem Monat einen Fehler behoben, der nicht existiert oder der in 30 Sekunden gefunden werden kann, wenn Sie einen bestimmten Ansatz und ein bestimmtes Tool verwenden. Die Zahlen überzeugen gut.
- Ist das am Ende ein administratives Problem?Natürlich. Ich bin überzeugt, dass Programmierer guten Code schreiben wollen. Es gibt jedoch verschiedene Hindernisse. Jemand weiß aus Unerfahrenheit nicht wie. Jemand hat die Motivation verloren, weil es jedem egal ist. Jemand weiß nicht genau, was ein guter Code ist, zum Beispiel aus kreativen Gründen. Sie üben Druck auf jemanden aus - er will und kann schreiben, aber sie sagen ihm, dass es morgen sein soll. Und anstatt Partnerschaften mit Unternehmen aufzubauen und zu erklären, warum dies morgen nicht passieren wird (oder wenn dies der Fall ist, müssen weitere drei Tage regiert werden), tut er es trotzdem. Und solche Partnerschaften sind für das Unternehmen selbst interessant. Er muss auch dafür sorgen, dass es lange funktioniert und billig zu warten ist.
Das heißt, alle Probleme werden hier gelöst: Es gibt keine unlösbaren Widersprüche.
- Es gibt einen Codestil - PEP 8. Es hilft nicht, schnell zu verstehen, was gut ist?In Kommas hilft es. Aber was bringt es, wenn Sie die Kommas richtig setzen und alles andere schlecht ist?
- Vermissen Sie einige bekannte übergeordnete Dinge?Theoretisch gibt es einige Best-Engineering-Praktiken. Aber sie sind entweder unbekannt oder werden ignoriert. Wenn Sie fragen, warum der Entwickler diese Vorgehensweise nicht befolgt hat, sagt er, dass er gehört hat, dass dies ein gutes Thema ist, aber der Code funktioniert so. Wenn der Code nicht mehr funktioniert, fragen Sie, ob er verstanden hat, woher die entsprechende Best Practice stammt, und warum Sie sie befolgen sollten. Nein, ich verstehe es nicht. Er glaubt, dass er sich einfach geirrt hat.
Es ist ziemlich schwierig, einer Person zu erklären, dass es normal ist, Fehler zu machen. Jeder ist falsch, wir sind alle Menschen. Die beste technische Praxis wurde jedoch nur erfunden, um Sie vor einem Fehler zu bewahren oder Sie vor den Folgen zu schützen. Das heißt, Es ist ein Sicherheitsinstrument wie in Unternehmen. Es ist nur nicht mit Blut geschrieben, sondern mit Zeit und Geld.
Im Allgemeinen besteht unsere unerreichbare globale Aufgabe darin, die Codeüberprüfung zu automatisieren, damit Python selbst (wenn wir über unseren Fall sprechen) weiß, wie man ihn schreibt. Dies sollte ein Tool sein, das Entwicklern nicht nur Möglichkeiten, sondern auch Einschränkungen bietet.
- Warum entwickeln Sie überhaupt einen Linter? Ist es möglich, bestehende zu nutzen (oder zu entwickeln)?Tatsächlich tun wir das. Unser Linter ist in der Tat ein Plugin für Flake8. Wir positionieren es einfach als vollwertiges Tool und nicht nur als Plug-In.
Warum Flake8 und nicht Pylint? Pylint macht viel, was der Linter nicht tun sollte. Beispielsweise wird eine sehr große Anzahl von Typprüfungen implementiert, obwohl die Typprüfung sich mit Typen befassen muss. Außerdem erzeugt es eine sehr große Anzahl von Fehlern, die es tatsächlich nicht sind. Und ich mag seine Dokumentation nicht und habe Angst vor seiner eigenen Implementierung von ast. Es ist schwierig zu konfigurieren. Indem Sie die Konfiguration aktivieren, lassen Sie die Benutzer die falschen Entscheidungen treffen. Daher besteht unsere Aufgabe darin, ein Tool zu erstellen, das nicht konfiguriert werden kann. Also sagst du es - das ist alles.
- Welche Führungen bildeten die Grundlage für diesen Linter? Oder ist es nur deine eigene Erfahrung hier?Jetzt basiert es auf den Regeln, die wir bei der Codeüberprüfung seit vielen Jahren für uns selbst formuliert haben. Einige Regeln wurden von anderen Lintern portiert: ESLint, Pylint, SonarQube, Credo. Der hervorragenden Arbeit
von CognitiveComplexity wurde viel entnommen. Ich habe immer auf Millers Brieftasche zurückgeschaut. Separate Regeln - das ist meine Vision, die nach der Bewertung einer großen Anzahl von Codes anderer Leute entstanden ist. Das heißt, zu diesem Zeitpunkt ist es ein "Durcheinander".
- Worüber werden Sie bei Moscow Python Conf ++ sprechen?Zunächst zum
Komplexitätsmanagement . Dieses Thema ist für alle Entwickler nah und verständlich. Wir werden uns verschiedene Metriken ansehen, um die Komplexität von den einfachsten Komponentencodezeilen auf das komplexeste Modul zu übertragen. Und dann werden wir über den ganzheitlichen Teil sprechen, in dem ich meine Vision vorstellen werde, wie man in Python schreibt oder nicht, und die Benutzer bitten, darüber abzustimmen, was ihnen gefällt und was nicht. Für viele Entwickler sind die Einschränkungen (A machen, aber nicht B machen) ein Versuch für ihren kreativen Raum, daher reagieren sie sehr heftig darauf. Und genau hier können Sie eine interessante Diskussion beginnen.
- Auf wen konzentriert sich der Bericht?Ich denke, dass dies immer noch etablierte Entwickler sind, da sich unerfahrene Programmierer noch keine klare Meinung gebildet haben. Obwohl es für sie interessant sein wird, zuzuhören und zu sprechen. Sie sind definitiv unsere Benutzer.
, ,
Moscow Python Conf++ . . ,
.