Hallo allerseits! Heute möchte ich meine Erfahrungen mit dem Erlernen der Sprache und der schnellen Implementierung eines Netzwerkprojekts mit hoher Auslastung unter Verwendung der so beliebten und beliebten jetzt nicht blockierenden asynchronen Netzwerkverbindungen in der neuen, schönen, eleganten und sehr effektiven Sprache Rust teilen.
Ich werde in diesem Beitrag besonderen Wert auf eine schnelle und klare Erklärung der Fähigkeiten der Sprache und Plattform für Spezialisten legen, die über umfangreiche Erfahrung in der Webentwicklung verfügen, weil ich es selbst bin. Es besteht ein Missverständnis, dass die Eintrittskurve in Rust sehr, sehr steil ist. Aber ich werde zeigen, dass dies bei weitem nicht der Fall ist. Kaffee einschenken und losfahren!
Eine kurze Geschichte der Programmierwerte
Damit das Material gut im Kopf und im Herzen liegt, ist es schön, sich kurz daran zu erinnern, was die Leute in den letzten 50 Jahren beim Programmieren wollten und was sie letztendlich gemacht haben. Keine Beleidigung, nur persönliche subjektive Meinung und Holivar, unterstützt durch 20 Jahre Entwicklungserfahrung.
Low-Level-Sprachen: C, C ++
Es ist klar, dass Sie das Programm sofort in Form von Zahlen auf Maschinencodes schreiben können und viele haben es auf dem ZX Spectrum, BK0010-01 und auf dem PC getan - der Code ist sehr schnell :-) Aber wir sind Menschen, viele Informationen passen nicht in unsere Köpfe, wir sind abgelenkt und deshalb Selbst die Erfindung des Assemblers hat nicht viel gebracht - Code auf einem so niedrigen Niveau ist sehr selten und sehr genau geschrieben, und wenn Sie keine Treiber, Mikrocontroller oder trickreiche eingebettete Systeme entwickeln, ist dies im Leben höchstwahrscheinlich nicht nützlich.

In den frühen 70er Jahren erfand Bell Labs die C-Sprache, die dank der lakonischen Syntax und sehr "billigen" Abstraktionen Wurzeln schlug und fast zu einem "portablen Assembler" wurde. Es ist klar, dass Sie, wenn Sie eine Tonsur einnehmen, 10 Jahre lang in C Nächten schreiben, kein Fleisch essen, beten und sich nicht von sozialen Netzwerken und dem fairen Sex ablenken lassen, sehr nützliche und schnelle Programme schreiben können, wie
GNU beredt bezeugt, exzellente produktive Spiele, Geliebte, aber nicht alternative Qualität von Windows, und viele weitere Beispiele können angeführt werden.
Aber die Kehrseite der Medaille macht sich ständig bemerkbar - es wurden regelmäßig Sicherheitslöcher geöffnet (eine ganze Branche für "Löcher in der Software" wurde geschaffen), verursacht durch Löcher im Konzept der C-Sprache selbst - der Compiler ist wie ein unverantwortlicher Bulle, mit unglaublicher Kraft, intensivem Orgasmus und kurzem Gedächtnis. Jegliche Fahrlässigkeit - und Sie können das Programm nicht einfach fallen lassen (einen Nullzeiger dereferenzieren, den Zeiger doppelt freigeben, das Array verlassen), sondern die Daten unwiderruflich ruinieren und es nicht lange bemerken, bis die Clients mit dem Aufrufen beginnen und wenn es zu spät ist („undefiniertes Verhalten“, anders) von Compiler zu Compiler).
Björn Straustrup verwirrte die Situation in den frühen achtziger Jahren nur weiter und fügte OOP-Fähigkeiten zu C hinzu. Trotz seiner großen Beliebtheit wird C ++ im Allgemeinen als eine Reihe von Programmierexperimenten mit unterschiedlichen Erfolgsergebnissen angesehen, einschließlich tödlich. Manchmal scheint es sogar so, als hätte C ++ von Anfang an keinen Sinn gehabt, oder es ging allmählich verloren, was zu einem Haufen von objektiv komplizierten und widersprüchlichen Konzepten führte, die mit jedem neuen Standard immer mehr werden. Trotz des hervorragenden Ziels von „Null-Kosten-Abstraktionen“, die es Ihnen ermöglichen, schnellen Code zu erhalten, um eine zuverlässige Lösung wie in C zu erstellen, sind die folgenden Bedingungen erforderlich:
- erfahrene, vom Wort "sehr" Team (jahrelange Praxis, "Mönche" der Programmierung)
- guter statischer Code Analyzer
- Testabteilung (im Code kann ein verantwortungsloser Compiler Lücken hinterlassen, die sich lange bemerkbar machen können)
- Von allen Teammitgliedern vereinbarte Anforderungen, die sorgfältig überwacht werden (unformatierte Zeiger, strenge Kapselung, strengste Disziplin für das Benennen von Variablen, Initialisieren von Objekten usw. werden nicht verwendet)
Es ist klar, dass die Einhaltung dieser Anforderungen, insbesondere im Kontext eines wachsenden Geschäftsbedarfs für einen „Code, der ohne plötzliche Überraschungen funktioniert“, sehr teuer ist. Der Code in solchen Projekten ist lange geschrieben, er muss lange und sorgfältig getestet werden, aber manchmal war es ohne C / C ++ vor der Erfindung von Rust wirklich schwierig.
Noch einmal eine Zusammenfassung von C / C ++ - wir haben einen mächtigen, aber "unverantwortlichen" Compiler mit "aktuellen Abstraktionen", was dem Entwickler sehr wenig hilft. Dadurch werden alle Probleme auf die Schultern des Programmierers übertragen. Wenn mindestens ein Programmierer im Team keine Erfahrung hat, nicht sehr vorsichtig ist und nicht alle Feinheiten des Compilers kennt (in der Tat kennt niemand alle Feinheiten und Benutzer finden sie später) - warten Sie auf den Fehler. Aber dann funktioniert das Programm schnell und wahrscheinlich richtig :-) Dies brachte natürlich einen ganzen Markt von „Krücken“ hervor - statischen Analysatoren, die, wie sich herausstellte, vom Kunden bezahlt werden sollten. Die Frage stellt sich: Könnte es nicht möglich sein, einen strengeren und sichereren Compiler zu schreiben, der dem Entwickler hilft und Programme ohne Überraschungen und Sicherheitslücken hervorbringt?
Java, C #, Kotlin
Die Situation mit offen gesagt schwacher Kontrolle über „unbestimmtes Verhalten“ und sehr hohen Anforderungen an Entwickler in C / C ++ führte zu dem Wunsch, eine sichere Entwicklungsumgebung zu schaffen, einschließlich für das Internet, zugänglich für die meisten Ankömmlinge. In den späten 90ern erschien Java.
Im Prinzip konnte jetzt jeder mit einem anderen Schulungsniveau alles und jedes schreiben, und es funktionierte und wurde nicht in das Programm aufgenommen - es gab keine Sicherheitslücken auf niedriger Ebene und keine spontanen Abstürze (fast, aber sie wurden bereits durch Fehler verursacht in einer virtuellen Maschine und zentral fixiert). Es gab nur logische „Lücken“ oder versteckten langsamen Code (geboren aus Unkenntnis der Algorithmen, dem Konzept der algorithmischen Kosten und Verlangsamung bei steigendem Datenvolumen), der bereits nicht so beängstigend war und es Ihnen ermöglicht, Programme schnell zu erstellen und, falls erforderlich, kleine Teile mit einem qualifizierten C / C-Team neu zu schreiben C ++.
Die interessanten und wertvollen Dinge, die die Java-Welt gebracht hat, sind die folgenden:
- Der Code wird einmal für eine virtuelle Maschine geschrieben, die auf allen Architekturen (Windows, Linux, Mac) funktioniert.
- der Entwickler verwaltet den Speicher nicht mehr direkt, wie in C / C ++ - dies wird an die Schultern des "Garbage Collector" weitergegeben; Dies beseitigt das Risiko von undefiniertem Verhalten, diskreter Datenbeschädigung und potenziellen Sicherheitslücken auf niedriger Ebene
- Der Code wird im laufenden Betrieb kompiliert (Just_In_Time-Kompilierung), weil Es ist bekannt, dass nur ein kleiner Teil aktiv und häufig im Programm ausgeführt wird. Daher macht es keinen Sinn, alles zu kompilieren
- Es wurde einfacher, effizienten Multithread-Code zu schreiben Das Speichermodell wurde streng spezifiziert (viel früher als in C ++), aber darüber hinaus wurden nicht alle Probleme mit der "logischen Zuverlässigkeit mehrerer Threads" behoben (Deadlocks zum Beispiel oder Datenrassen waren noch möglich).
Das Aufkommen einer so freundlichen Plattform ermöglichte es natürlich, viele nützliche und nutzlose Programme zu schreiben, die das Unternehmen sofort nutzte. Die Unterstützung der Abwärtskompatibilität in Java seit mindestens 15 Jahren hat die Technologie in der Unternehmenswelt so beliebt gemacht.
Ja, ich habe auch Analogien zu alkoholfreien Bier- und Gummifrauen.
Bei weitem nicht sofort traten jedoch die folgenden Probleme in Java auf:
- Aufgrund der logischen „Lücke“ im Typensystem, die von C / C ++ geerbt wurde, gelangte der Typ „Null“ nach Java, was bis heute viele Probleme verursacht und ständig zu Abstürzen von „nicht sehr erfahrenen“ Programmierern führt Ich kenne keinen optionalen Typ und interessiere mich nicht für Monaden aus der funktionalen Programmierung
- Java-Projekte, die manchmal etwas langsamer arbeiten, erfordern um ein Vielfaches mehr RAM als C / C ++, das der Garbage Collector benötigt (wir haben mehrere Projekte, die Dutzende oder Hunderte von Gigabyte RAM verbrauchen). Dies ist oft kein direktes Problem RAM-Preise fallen, aber das "Sediment blieb"
- Trotz der JIT-Kompilierung und der großen Investitionen in die Beschleunigung des Garbage Collectors (von denen viele regelmäßig neu auftauchen und ständig sagen: "Probiere einen neuen GC aus, es ist viel besser") arbeiten einige hochgeladene Java-Projekte seit 20 Jahren mit regelmäßigen Pausen für mehrere Sekunden. die in keiner Weise entfernt werden können (es gibt eine erzwungene Müllabfuhr, und wie Schrauben im GC nicht verdrehen, hat der Müllsammler einfach keine Zeit, alles zu säubern, auch wenn er parallel arbeitet und sogar mehr Ressourcen verschlingt als das Programm selbst)
- Es ist bekannt, dass Java-GUI-Anwendungen manchmal einfrieren und langsamer werden und Ärger bei den Benutzern auslösen, da dieselbe Garbage Collection besteht und keine Hoffnung besteht und nicht erwartet wird
- Die Syntax der Sprache ist sehr ausführlich und überflüssig (Sie müssen die Wörter "public static functon" schreiben und dann lesen, anstatt "pub fn" oder "def"), was manchmal dazu zwingt, sich die Finger an den Nägeln zu brechen und objektive Schmerzen und Blutungen aus den Augen zu verursachen
- Ein starker Rückgang der Anforderungen an das Niveau der Entwicklerqualifikationen und eine ausreichend niedrige Einstiegskurve führten zu einer Menge „seltsamer Frische“ -Code, der sich mein ganzes Leben lang mit einem unvergesslichen Gestank bemerkbar machte
Nach dem Lesen sollte klar sein, dass nicht alles in Java geschrieben werden kann, es wird eher langsam geschrieben, dann wird es regelmäßig langsamer und hängt sich für eine Sekunde unter Last auf, manchmal wird viel RAM "gefressen" (in der Regel wird mindestens die Hälfte des RAMs auf dem Server verbraucht), produktive Spiele Sie werden es auch nicht können, aber einige Teile der Geschäftslogik, die keine besonderen Anforderungen an die Leistung und den Arbeitsspeicher stellen, insbesondere Multithread-Logik, sind durchaus möglich und nützlich, und daher sehen wir eine solche Beliebtheit der Technologie in der Unternehmenswelt. Und wir selbst nutzen Java regelmäßig und aktiv für die Dienste des Unternehmens.
C #, Scala, Kotlin
„Und wann geht es um Rust?“ - Moment mal, du brauchst etwas mehr Vorbereitung, um diese süße Persimone zu essen. Wenn Sie nicht über die Funktionen anderer Technologien sprechen, werden Sie nicht verstehen, warum Rust aufgetaucht ist und warum es so
beliebt und gefragt ist .
Um Java besser und fortschrittlicher zu machen, entwickelte Microsoft in der Person des Autors TurboPascal / Delphi am Anfang der Null C # und das Konzept von .NET. Nach Ansicht vieler angesehener Experten und in den Raucherzimmern von Entwicklern ist „C #“ objektiv sexueller als Java, obwohl es natürlich bisher trotz Mono mit allen Zuflüssen und Konsequenzen eng mit Microsoft verbunden ist :-)
Scala ist zweifellos ein großer Schritt nach vorne Die Sprache erwies sich natürlich als wissenschaftlich abstrus und raffiniert und nahm viele nützliche und nutzlose Dinge aus der Welt der funktionalen Programmierung. Aber irgendetwas ist mit Popularität irgendwie nicht ganz klar. Allerdings ist
Apache Spark wirklich gut und beliebt, nichts zu sagen.
Kotlin ist beliebt, weil macht Java für Anfänger effizienter und einfacher, insbesondere auf mobilen Plattformen, die keine Zeit haben, sich ernsthaft mit Programmierung zu befassen :-)
Das Hauptproblem in C # (auf der .NET-Plattform) sowie in Scala, Kotlin und in anderen JVM-Sprachen blieb jedoch bestehen. Garbage Collector, Carl, schafft eine spürbare Last auf dem Server und stoppt die Ausführung des Codes für Sekunden unter Last und mit hohen RAM-Anforderungen! Und wie viele weitere Sprachen mit einem Garbage Collector und einer JIT-Kompilierung werden nicht auftauchen, diese Probleme werden bestehen bleiben und es gibt noch keine Hoffnung, auch theoretisch.
Scripting
"Aber was ist mit PHP?" Ja, jetzt lass uns über Scripting sprechen. Es scheint, warum ist er? Gegen Ende der 80er Jahre stellte sich heraus, dass Sie ein Skript schreiben können, wenn Sie ein Problem schnell mit Code lösen müssen, der nicht unbedingt superschnell und sicher ist, ohne undefiniertes Verhalten und Lücken auf niedriger Ebene. Skripte wurden zuvor in bash, perl, awk geschrieben, aber es stellte sich heraus, dass Sie in Python große, große Skripte schreiben können, insbesondere wissenschaftliche, und das seit Jahren!
Lua fand seine Nische in Gamedev und Machine Learning (
Torch ), JavaScript - in der Webentwicklung sowohl auf der Browserseite als auch auf der
Serverseite (jeder weiß, dass die
Autorisierung in der "npm" -Infrastruktur von Node.js von Node.js und Node.js umgeschrieben wird Golang auf Rost?). Python - beim maschinellen Lernen und bei der Datenanalyse sowie bei der Skripterstellung. Und PHP - meistert perfekt Serveraufgaben für die Webentwicklung.

Die Vorteile von Scripting liegen auf der Hand:
- Sicherer, effizienter Code ohne undefiniertes Verhalten und Sicherheitslücken auf niedriger Ebene unter Verwendung gängiger Algorithmen und Datenstrukturen (Listen, Wörterbücher, Warteschlangen) wird in wenigen Minuten erstellt
- Ein sehr schneller Start und eine sanfte Einstiegskurve. Es dauert mehrere Tage, um ein nützliches Python-Skript zu entwickeln und zu schreiben, die Logik von nginx durch Skripterstellung in Lua zu ändern oder die Integration von Online-Shops in PHP durchzuführen
- Wenn Sie Skripte diszipliniert, unter Einhaltung von CodeStyle und so streng wie möglich schreiben, können Sie schnell komplexe Probleme lösen und große Softwareprodukte erstellen: eine große Anzahl wissenschaftlicher Bibliotheken in Python, Geschäfts- und Website-Managementsysteme in PHP, neuronale Netzwerkplattform Torch in LuaJit, Game Scripting in a very berühmte und beliebte Spiele usw.
- Einige Arten der Multithread-Programmierung, bei denen E / A der Engpass ist, werden in Python ziemlich effizient gelöst. Durch die Verwendung der neuesten Python-Funktionen mit Zukünften wie „async / await“ ist es sogar noch einfacher, die Probleme bei der Verarbeitung einer großen Anzahl von Netzwerk-Sockets zu lösen
- Sehr elegant wurde die Aufgabe der asynchronen Verarbeitung einer großen Anzahl von Sockets, auch ohne Multithreading, in Node.js "out of the box" gelöst
- Erstellen Sie Webseiten, verwenden Sie zahlreiche Unix-Bibliotheken, gehen Sie in die Datenbank und nutzen Sie PHP und darauf basierende Produkte einfach und bequem
- Unter Python, PHP und JavaScript ist es sehr praktisch, Hypothesen zu testen und Prototypen in Stunden und nicht Monaten zu erstellen
- Für die Analyse und Datenverarbeitung ist es traditionell sehr praktisch, Python / R in Verbindung mit einer großen Anzahl hochwertiger Bibliotheken (Pandas, Scikit-Learn, Seaborn, Matplotlib ...) zu verwenden.
Sie können jedoch die möglichen Nachteile von Skripten nicht kennen:
- Eine niedrige Einstiegsstufe und eine sehr schnelle Scripting-Geschwindigkeit führen bei unzureichender Kontrolle über Entwickler manchmal zu einer Unmenge ineffizienter und schwer zu wartender Codes auf jeder Plattform
- Das Fehlen eines Compilers, eines Typensystems und einer statischen Typisierung erfordert eine dynamische Überprüfung der Parameter, die an Funktionen und Methoden für Typen übergeben werden, sowie eine qualitativ hochwertige Codeabdeckung mit Autotests. Andernfalls kann eine Änderung des Codes das Programm beschädigen, und der Client und nicht der Entwickler wird als erster davon erfahren (ja, ich kenne TypeScript, aber das sind Krücken und tote Umschläge).
- Objektiv und offensichtlich können Sie in Sprachen ohne statische Typisierung und Kompilierung, in denen viele Dinge zur Laufzeit passieren, nicht zahlreiche Optimierungen verwenden. In einigen Aufgaben arbeiten Skripte daher um Größenordnungen langsamer und verbrauchen ein Vielfaches an Ressourcen. Trotz der Versuche, die JIT-Kompilierung in Python (pypy), PHP (hhvm), JavaScript (Übersetzung in Maschinencode, wow, Node.js v8) und LuaJIT zu implementieren, sollten wir uns nichts vormachen: All dies sieht nach schwach effizienten Krücken aus. Der Grund ist, und es muss ein für allemal verstanden werden, dass Skripte aufgrund der absichtlich schwachen Typisierung von Sprachen kaum jemals eine effektive Laufzeit schreiben können, die sich der Geschwindigkeit von viel stärker typisiertem Java / C # annähert.
- Und in Python scheint es aufgrund der GIL nie ein effizientes Multithreading wie in Java / C # zu geben
Seitdem jedoch in den meisten Geschäftsanwendungen, einschließlich Site-Management-Systeme, CRM usw. Da der größte Teil der Code-Ausführungszeit für Abfragen an die Datenbank aufgewendet wird, wird der Vorteil von jit Java / C # durch die Geschwindigkeit des Schreibens von Lösungen in PHP / Python / JavaScript deutlich. Für die Erstellung von Webanwendungen wähle ich 10 bis 20 Zeilen in PHP als 10.000 aus Zeichenfolgen und eine Reihe von Innereien in Java / Spring. Und PHP7 irgendwie übertaktet, so dass es schneller läuft als Python3 ;-)
Welche Schlussfolgerung kann hier gezogen werden? Es ist nicht notwendig, alle Probleme zu lösen, wie es jetzt populär ist, nur durch Skripten. In einigen Fällen ist es sinnvoll, ein anderes, besser geeignetes Werkzeug zu verwenden, wenn es gute Gründe dafür gibt:
- Sehr hohe Netzwerklasten und "extremes" Multithreading, Tausende - Zehntausende von Netzwerk-Sockets usw.
- Einschränkung der Verwendung von RAM und Hardware
- intensive Datenverarbeitung und -verarbeitung, Matrizen mit Millionen von Entitäten, GPUs (obwohl Python / Numpy / Pandas hier helfen können)
Oft praktizieren wir im Unternehmen diesen Ansatz:
- Treffen Sie schnell eine Entscheidung in PHP / Python / JavaScript / Node.js, starten Sie den Kampf und beginnen Sie, Kundenprobleme zu lösen
- Wir bieten Funktionen, Möglichkeiten und verbessern Services
- In seltenen Fällen werden erfahrungsgemäß, in der Regel frühestens nach einigen Jahren, einige der bereits funktionsstabilen Dienste in C / C ++ / Java / Golang / Rust umgeschrieben
Daher ist es in der Regel besser, mit dem Schreiben von Skripten zu beginnen, einen Kampf zu beginnen und dann, wenn Sie es direkt benötigen, andere Werkzeuge aufzunehmen, und dies geschieht normalerweise reibungslos und ohne Risiken.
Funktionale Programmierung, Lisp, Haskell, F #
Viele kommen für die gesamte Karriere eines Entwicklers nie hierher, aber vergebens. Es ist äußerst hilfreich zu verstehen, warum die FP (funktionale Programmierung) aufgetaucht ist und warum sie in einigen Bereichen so beliebt ist.
Ich erkläre es einfach. In der Mathematik gibt es ein so unlösbares Problem wie das
"Halteproblem" . Wenn Sie es in sehr einfachen Worten und nicht streng formulieren, aber es ist klar, dann können Sie keinen Algorithmus finden, der beweist, dass das Programm fehlerfrei funktioniert. Warum? Denn anfangs wurde aggressiv und zwingend programmiert mit:
- veränderbare Variablen
- Zyklen mit Bedingungen
- Nebenwirkungen
Und sie begannen Fehler zu machen. Wir sehen dies jetzt und beobachten eine große Anzahl von Fehlern sowohl im Web als auch in Desktop- und Mobilanwendungen. Und unabhängig davon, wie Sie den Code mit Autotests abdecken, lecken weiterhin Fehler, verteilen sich auf dem Boden und kichern.
Um diesen Albtraum des Einbruchs von fehlerhafter und gnadenloser Software zu stoppen,
tauchten in den späten 50er Jahren eine Richtung der funktionalen Programmierung und der
Lisp-Sprache auf . Jetzt repräsentiert diese Sprachfamilie
Haskell mehr oder weniger angemessen.
Trotz der Tatsache, dass eine große Anzahl möglicher Fehler im Code tatsächlich beseitigt wird, aufgrund von:
- algebraische Datentypen und Mustervergleich auf ihnen
- das Fehlen von Zyklen (nur durch Rekursion) und veränderlichen Variablen innerhalb der Reichweite eines ausgestreckten Arms (Krücken, wie man das umgehen kann, sind natürlich zu finden )
- Sehr strenge statische Eingabe und gleichzeitig sehr komfortable automatische Ausgabe von Hindley-Milner- Typen
- sehr leistungsfähige Funktionen, mit der Unterteilung in "rein" und "mit Nebenwirkungen", mit der Möglichkeit der teilweisen Verwendung
- sichere Unterstützung für die gleichzeitige Programmierung
- Unterstützung für Kombinatoren durch Monaden für alle Gelegenheiten (mehr dazu in der Sektion Rust)
Haskell «» — , , , :
. Haskell «», , , , . Haskell .
, , — Haskell , , , Java/C#.
, . Haskell , , , , . , «» — Haskell .
«C/C++» — Golang, D
, , C/C++ (, Forth).
C++ , ,
D ( — , ).
, - /C++ c
RAII , . 2009 Google
Golang .
, Golang , , , . Golang Java/C# ( ) ,
… , Golang:
- «green threads» ( ), python
- , , (, Docker ) :-)
. Node.js python .
, Golang , Google vs Sun/Oracle, , , , :-) , « Java/C#» , — . Docker Golang . Golang — Java/C#, , .

, ,
Swift , c « » . macOS.
— Rust!
, , 40-50 , , , «zero-cost» , , - - :-) , , (Java/C#), , (C/C++), -, — . , ?
— . , , , 50 , 2010 Mozilla Research. , :
- «zero-cost» ( C/C++ ), .. , , ------ « » (, , )
- cargo ,
- (* — ): , — « », , , ,
- , , ( , , GC , - runtime, )
- -, Null (!),
- Haskell pattern-matching , Enumeration (Golang, , )
- ( Java, )
- ( Golang — ; Java/C#/Erlang .. , )
- , ( C/C++)
, , -. ? ! , 50 . , , «» , , .
Rust «» , , Haskell .
Rust , , , Java :-) — Nulls, pattern-matching , generics traits . . , , , « Haskell», .
.
?
Und so! , «» («ownership») . « » ( «lifetime», Rust book, ),
( , ).
/, . /, .
C++, - move-. , rust , .
zero-cost ?
, traits, . , , Golang. , , - pattern-matching, ( Golang, ). / . : .
(«borrowing»). , ( «read-write locks», ). , , , , .
slice , , , . — « » , , ; , .
:
, ( , )
… . / , C/C++ . .
, - , - . - , . Sync/Send, , : , , , .
, , 1-2 futures
. , Node.js python async/await, , . , ?
unit
, unit .
.
— cargo
Java, «Maven
cargo » , : , . , , , .
Heap
, , heap. , , ( ) « » ( «lifetime»). ,
( Swift). , — , heap . — , .
, , , . , (2 ) , , , ,
,
AmazonWebServices c tls/ssl, .
, , , , , - .
« » ( «lifetimes») .
, . IntelliJ
rust , . Notepad++ — .
Rust
- Verstehen Sie, dass Sie wirklich sehr schnellen Systemcode schreiben müssen, der unter hoher Last arbeitet und nur ein Minimum an Ressourcen verbraucht und keinen Overhead wie einen Garbage Collector verursacht. Wenn nicht, schreiben Sie ein Skript in python / PHP / Node.js und kehren nach 2-3 Jahren zur Aufgabe zurück (in 97% der Fälle müssen Sie nicht zurückkehren).
- Hab keine Angst vor Rust. Das Hauptmerkmal der Sprache ist ein sehr intelligenter und mathematisch strenger Compiler, der KEINEN gefährlichen und falschen Code VERPASST. Durch Ausprobieren und Vermeiden scharfer Ecken lernen Sie, wie man mit dem Compiler streng und sicher programmiert :-)
- Lerne die Sprache mit einem " Rust-Buch ". Ein wunderschönes, sexy Buch, das einfach zu lesen ist und Spaß macht. Aber es ist besser, es zweimal zu lesen und alle Beispiele "aufzulösen".
- Das " Rust Kochbuch " hilft sehr . Es ist auch wünschenswert, es zu "lösen" und zu sehen, wie der Code funktioniert, um es zu fühlen.
- Es gibt Literatur über Rust für fortgeschrittene Benutzer wie Rustonimicon , aber ich empfehle nicht, sich unnötig mit wirklich komplizierten technischen Dingen zu beschäftigen.

Verstehen Sie noch einmal - um die Technologie zu beherrschen, müssen Sie damit beginnen, Code zu schreiben, der für das Unternehmen nützlich ist. Der Rust-Compiler ist so schlau, dass er Garantien gibt (in der Tat ist es sehr wichtig, dass der C ++ - Compiler nicht weiß, wie man das macht) und keinen gefährlichen / speicherbeschädigten Code kompiliert. Experimentieren Sie also so viel Sie wollen - und Sie werden den Code schnell und sicher bekommen und noch besser werden Sie mit der Programmierung beginnen: )
Details zur Projektimplementierung
Ich werde ein kleines Detail des Projekts enthüllen. Amazon SQS verschüttet Hunderte von Datenpaketen pro Sekunde. Die Warteschlange wird gelesen, lokal von den Mitarbeitern analysiert, jede Nachricht wird vom Broker verarbeitet und auf einen anderen externen Server umgeleitet. Es gibt mehrere externe Server. Anfänglich wurde die Lösung per Skript implementiert: Das Skript, das einen Prozess im Betriebssystem aufnimmt, Nachrichten liest, verarbeitet und über das Netzwerk versendet. Auf mehreren leistungsstarken Eisenservern (8 Kerne, 16 GB RAM) wurden Hunderte von Skripten gestartet (auf jedem!), Die gleichzeitig aus SQS lesen, Daten verarbeiten und senden. Einfach, zuverlässig, aber die Eisenaufnahme begann zu stören. Die Eisenkosten stiegen ständig.
Rust verwendete hauptsächlich Standardbibliotheken und Module aus Fracht:
- rusoto_sqs - für die Arbeit mit Amazon Web Services stehen keine Fragen zur Verfügung
- rustls - für tls, inkl. Interaktionen mit TLS-Diensten von Google, Apple und der Verwendung von Client-Zertifikaten
- signal-hook - um kill abzufangen und die Transaktion zum Senden von Daten zu beenden
- Futures, Tokio-Rustls - „faule“, asynchrone Multithread-Arbeit mit Netzwerk-TLS-Sockets, ua Node.js
- clap - Parsen von Kommandozeilenargumenten
- serde_json - json formation, hier nichts interessantes
Leider war es nicht ohne die Verwendung von "unsicheren" Blöcken und "std :: mem :: transmute" - die Standardbibliothek konnte keine Werkzeuge zum Parsen von Binärdaten in Bäumen finden.
Die Hauptsache, wenn Sie es so nennen können, "plugging" geschah in der Kompilierung - Bibliotheken wurden unter CentOS6 nicht kompiliert, weil der "veraltete Assembler" in binutils vorhanden war, aber es gab keine Probleme unter CentOS7.
Der allgemeine Eindruck ist, dass die Entwicklung auf Rust eher einer „strengen Skripterstellung“ als einer Systemprogrammierung ähnelt, nicht viel länger als eine Skripterstellung oder eine Webentwicklung, sowohl in Bezug auf Ressourcen als auch in Bezug auf Tests. In diesem Fall eine strikte statische Kompilierung, das Fehlen eines Garbage Collectors und algebraische Datentypen.
Das allgemeine Gefühl ist sehr positiv. Anstelle von mehreren Eisenservern (8 Kerne, 16 GB RAM) wurde das Problem durch einen Prozess (mit Dutzenden von Threads) gelöst, der nicht mehr als 5 GB RAM beansprucht und eine kaum merkliche Belastung der Kerne mit Datenverkehr im Bereich von 0,5 bis 1 Gigabit verursacht .
Fazit
Nun, das endete mit einem langen, aber hoffentlich inspirierenden und nützlichen Beitrag über effektive Technologie. Jetzt kennen Sie ein anderes Tool und können es bei Bedarf sicherer verwenden. Wir haben die Geschichte der Entwicklung von Programmiersprachen, ihre Fähigkeiten und Funktionen durchgesehen und haben möglicherweise die richtigen Schlussfolgerungen gezogen oder werden diese ziehen. Viel Glück bei deinen Projekten und gute, nein, gute Laune!
PS:
* - Ja, ich hätte es fast vergessen. Natürlich müssen Sie über den unsicheren Block sprechen. In diesem Block können Sie:
- Dinge zu programmieren, die nicht in gewöhnlichen "rohen" Zeigern für Rostdereferenzierung verfügbar sind, und einige potentiell gefährlichere Dinge zu tun, die manchmal bei der Systemprogrammierung erforderlich sind. Aber alles ist nicht so beängstigend:
- unsichere Blöcke sind sichtbar und es gibt entweder überhaupt keine oder der verantwortliche Code ist in ihnen konzentriert
- Die Roststandardbibliothek wurde gründlich getestet, was bedeutet, dass unsichere Blöcke darin funktionieren
- Beliebte Bibliotheken in Ladung werden ebenfalls gründlich getestet (alles ist für Einheits- und Integrationstests in Rost eingebaut) und können daher sicher mitgenommen und verwendet werden
Das heißt Im "unsicheren" Block können Sie sich nicht an willkürlichen Ausschweifungen beteiligen, die in C verfügbar sind - sondern nur bei
genau bestimmten Arten gefährlicher Aktivitäten. Deshalb kannst und solltest du ruhig schlafen :-)