Die 7 ärgerlichsten Probleme bei der Programmierung

Es wurde gesagt, dass die unbekannten Gebiete der alten Karten oft mit der bedrohlichen Warnung markiert wurden: "Hier sind Drachen." Vielleicht apokryphisch, war die Idee, dass niemand, der in diese unbekannten Ecken der Welt wandert, dies tun sollte, ohne bereit zu sein, gegen einen schrecklichen Feind zu kämpfen. In diesen mysteriösen Regionen konnte alles passieren, und oft war etwas nicht gut.

Programmierer mögen etwas zivilisierter sein als mittelalterliche Ritter, aber das bedeutet nicht, dass in der modernen technischen Welt an unvorhergesehenen Orten nicht viele technische Drachen auf uns warten: Schwierige Probleme, die warten, bis die Frist Minuten entfernt ist; Komplikationen, die das Handbuch gelesen haben und wissen, was nicht genau spezifiziert ist; böse Drachen, die wissen, wie man sich in kleine Fehler und vorzeitige Pannen einschleicht, oft direkt nachdem der Code festgeschrieben wurde.

Es wird einige geben, die nachts ruhig ruhen, aufgewärmt von ihrer naiven Selbstsicherheit, dass Computer absolut vorhersehbar sind und ernsthaft die richtigen Antworten liefern. Oh, wie wenig sie wissen. Bei all der harten Arbeit von Chipdesignern, Sprachentwicklern und Millionen von Programmierern gibt es immer noch dornige Programmierprobleme, die selbst die mächtigsten Programmierer in die Knie zwingen können.

Hier sind sieben der knorrigsten Ecken der Programmierwelt, in denen wir große Markierungen mit der Aufschrift "Hier seien Drachen" setzen würden.

Multithreading

Es klang nach einer guten Idee: Teilen Sie Ihr Programm in unabhängige Abschnitte auf und lassen Sie das Betriebssystem sie wie separate kleine Programme ausführen. Wenn die Prozessoren vier, sechs, acht oder sogar mehr Kerne haben, schreiben Sie Ihren Code so, dass er vier, sechs, acht oder mehr Threads haben kann, wobei alle Kerne unabhängig voneinander verwendet werden.

Die Idee funktioniert - wenn die Teile tatsächlich völlig getrennt sind und nichts miteinander zu tun haben. Sobald sie jedoch auf dieselben Variablen zugreifen oder Bits in dieselben Dateien schreiben müssen, sind alle Wetten ungültig. Einer der Threads wird zuerst zu den Daten gelangen, und Sie können nicht vorhersagen, um welchen Thread es sich handelt.

So erstellen wir Monitore, Semaphoren und andere Tools zum Organisieren des Multithread-Chaos. Wenn sie arbeiten, arbeiten sie. Sie fügen lediglich eine weitere Komplexitätsebene hinzu und verwandeln das Speichern von Daten in einer Variablen in ein Element, das etwas mehr Nachdenken erfordert.

Wenn sie nicht funktionieren, ist es Chaos pur. Die Daten machen keinen Sinn. Die Spalten addieren sich nicht. Geld verschwindet von Konten mit einem Haufen. Es sind alles Teile im Speicher. Und viel Glück beim Versuch, irgendetwas davon festzuhalten. Meistens sperren Entwickler große Teile der Datenstruktur, sodass nur ein Thread sie berühren kann. Das kann das Chaos eindämmen, aber nur, indem der größte Teil des Vorteils beseitigt wird, wenn mehrere Threads an denselben Daten arbeiten. Sie können es auch als "Single-Threaded" -Programm umschreiben.

Verschlüsse

Irgendwann entschied jemand, dass es nützlich wäre, Funktionen so weiterzugeben, als wären sie Daten. Dies funktionierte in einfachen Fällen gut, aber Programmierer begannen zu erkennen, dass Probleme auftraten, wenn Funktionen außerhalb ihrer selbst erreichbar waren und auf andere Daten zugegriffen haben, die oft als „freie Variablen“ bezeichnet werden. Welche Version war die richtige? Waren es die Daten, als der Funktionsaufruf gestartet wurde? Oder war es, als die Funktion tatsächlich ausgeführt wurde? Dies ist besonders wichtig für JavaScript, wo es dazwischen lange Lücken geben kann.

Die Lösung, der „Abschluss“, ist eine der größten Ursachen für Kopfschmerzen für JavaScript-Programmierer (und jetzt Java- und Swift-Programmierer). Neulinge und sogar viele Veteranen können nicht herausfinden, was geschlossen wird und wo die Grenzen der sogenannten Schließung liegen könnten.

Der Name hilft nicht - es ist nicht so, als wäre der Zugang dauerhaft geschlossen wie eine Leiste, die den letzten Anruf ankündigt. Wenn überhaupt, ist der Zugriff offen, aber nur durch ein Wurmloch im Daten-Zeit-Kontinuum, ein seltsamer Zeitverschiebungsmechanismus, der schließlich eine Science-Fiction-TV-Show hervorbringen wird. Die Bezeichnung "Complex Stack Access Mechanism" oder "Data Control Juggling System" scheint jedoch zu lang zu sein, sodass wir uns auf "Closures" beschränken. Lassen Sie mich nicht wissen, ob jemand für die nicht freien Variablen bezahlen muss.

Zu große Datenmengen

Wenn sich der Arbeitsspeicher füllt, läuft alles schief. Es spielt keine Rolle, ob Sie eine neue statistische Analyse von Verbraucherdaten durchführen oder an einer langweiligen, alten Tabelle arbeiten. Wenn der Maschine der Arbeitsspeicher ausgeht, wird ein sogenannter virtueller Speicher verwendet, der auf die superslow-Festplatte gelangt. Es ist besser, als komplett zusammenzubrechen oder den Job zu beenden, aber der Junge macht alles langsamer.

Das Problem ist, dass Festplatten mindestens 20- oder 30-mal langsamer als RAM sind und die Festplattenlaufwerke im Massenmarkt häufig langsamer sind. Wenn ein anderer Prozess ebenfalls versucht, von der Festplatte zu schreiben oder zu lesen, wird alles dramatisch schlechter, da die Laufwerke jeweils nur eine Aufgabe ausführen können.

Das Aktivieren des virtuellen Speichers verschärft andere, versteckte Probleme mit Ihrer Software. Wenn es Threading-Störungen gibt, brechen diese viel schneller ab, da die Threads, die im virtuellen Festplattenspeicher stecken, so viel langsamer laufen als die anderen Threads. Dies dauert jedoch nur eine kurze Zeit, da die einmaligen Mauerblümchenfäden in den Speicher getauscht werden und die anderen Fäden auflegen. Wenn der Code perfekt ist, ist das Ergebnis nur viel langsamer. Wenn dies nicht der Fall ist, führen die Fehler schnell zu einem Absturz in eine Katastrophe. Das ist ein kleines Beispiel.

Dies zu verwalten ist eine echte Herausforderung für Programmierer, die mit großen Datenmengen arbeiten. Jeder, der beim Aufbau verschwenderischer Datenstrukturen etwas schlampig wird, erhält Code, der in der Produktion langsamer wird. Es mag mit ein paar Testfällen gut funktionieren, aber echte Lasten führen dazu, dass es spiralförmig versagt.

NP-komplett

Jeder mit einer Universitätsausbildung in Informatik kennt die mysteriösen Probleme, die mit einem Akronym verbunden sind, das selten formuliert wird: nichtdeterministisches Polynom vollständig, auch bekannt als NP-vollständig. Das Erlernen der Details dauert oft ein ganzes Semester, und selbst dann haben viele CS-Studenten die neblige Vorstellung, dass niemand diese Probleme lösen kann, weil sie zu schwer sind.

Die NP-vollständigen Probleme sind oft recht schwierig - wenn Sie sie einfach mit brutaler Gewalt angreifen. Das „Problem der reisenden Verkäufer“ kann beispielsweise exponentiell lange dauern, da die Verkaufsroute immer mehr Städte umfasst. Das Lösen eines „Rucksackproblems“ durch Finden einer Teilmenge von Zahlen, die einem Wert N am nächsten kommt, wird gelöst, indem alle möglichen Teilmengen ausprobiert werden, was eine sehr große Zahl ist. Alle haben Angst vor diesen Problemen, denn sie sind das perfekte Beispiel für einen der größten Trottel im Silicon Valley: Algorithmen, die sich nicht skalieren lassen.

Der schwierige Teil ist, dass einige NP-vollständige Probleme mit einer Annäherung leicht zu lösen sind. Die Algorithmen versprechen nicht die genaue Lösung, kommen aber ziemlich nahe. Sie finden möglicherweise nicht die perfekte Route für den reisenden Verkäufer, aber sie können innerhalb weniger Prozentpunkte der richtigen Antwort liegen.

Die Existenz dieser ziemlich guten Lösungen macht die Drachen nur mysteriöser. Niemand kann sicher sein, ob die Probleme wirklich schwer oder einfach genug sind, wenn Sie bereit sind, sich mit einer Antwort zufrieden zu geben, die gerade gut genug ist.

Sicherheit

„Es sind bekannte bekannt; Es gibt Dinge, von denen wir wissen, dass wir sie wissen “, sagte Donald Rumsfeld, Verteidigungsminister während der zweiten Bush-Regierung, einmal auf einer Pressekonferenz. „Wir wissen auch, dass es unbekannte Unbekannte gibt. Das heißt, wir wissen, dass es einige Dinge gibt, die wir nicht wissen. Aber es gibt auch unbekannte Unbekannte - diejenigen, die wir nicht kennen, die wir nicht kennen. “

Rumsfeld sprach über den Krieg im Irak, aber das Gleiche gilt für die Computersicherheit. Die größten Probleme sind Löcher, von denen wir nicht einmal wissen, dass sie möglich sind. Jeder versteht, dass Sie Ihr Passwort schwer zu erraten machen sollten - das ist bekanntlich bekannt. Aber wem wurde jemals gesagt, dass in Ihrer Netzwerkhardware eine eigene Softwareschicht vergraben ist? Die Möglichkeit, dass jemand das Hacken Ihres Betriebssystems überspringen und stattdessen auf diese geheime Ebene abzielen könnte, ist unbekannt.

Die Möglichkeit eines solchen Hacks ist Ihnen jetzt vielleicht nicht unbekannt, aber was ist, wenn es andere gibt? Wir haben keine Ahnung, ob wir die Löcher härten können, von denen wir nicht einmal wissen, dass sie existieren. Sie können die Passwörter reduzieren, aber es gibt Risse, die Sie sich nicht einmal vorstellen können. Das macht Spaß, mit Computersicherheit zu arbeiten. Und wenn es um Programmierung geht, wird sicherheitsbewusstes Denken immer wichtiger. Sie können es nicht den Sicherheitsprofis überlassen, Ihr Chaos zu beseitigen.

Verschlüsselung

Die Verschlüsselung klingt mächtig und undurchdringlich, wenn Strafverfolgungsbeamte vor den Kongress treten und nach offiziellen Lücken fragen, um sie zu stoppen. Das Problem ist, dass die meisten Verschlüsselungen auf einer nebligen Wolke der Unsicherheit basieren. Welche mathematischen Beweise wir haben, beruht auf unsicheren Annahmen, wie es schwierig ist, wirklich große Zahlen zu faktorisieren oder ein diskretes Protokoll zu berechnen.

Sind diese Probleme wirklich schwer? Niemand hat öffentlich Algorithmen beschrieben, um sie zu brechen, aber das bedeutet nicht, dass die Lösungen nicht existieren. Wenn Sie einen Weg finden würden, jedes Gespräch zu belauschen und in eine Bank einzubrechen, würden Sie es der Welt umgehend mitteilen und ihnen helfen, die Löcher zu schließen? Oder würdest du schweigen?

Die eigentliche Herausforderung besteht darin, die Verschlüsselung in unserem eigenen Code zu verwenden. Selbst wenn wir darauf vertrauen, dass die grundlegenden Algorithmen sicher sind, gibt es viel zu tun, um Passwörter, Schlüssel und Verbindungen zu jonglieren. Wenn Sie einen Fehler machen und ein Passwort ungeschützt lassen, fällt alles auf.

Identitätsmanagement

Jeder liebt diesen New Yorker Cartoon mit der Pointe: "Im Internet weiß niemand, dass Sie ein Hund sind." Es hat sogar eine eigene Wikipedia-Seite mit vier ausführlichen Abschnitten. (Im Internet kennt niemand die alte Säge über die Analyse von Humor und das Zerlegen von Fröschen.)

Die gute Nachricht ist, dass Anonymität befreiend und nützlich sein kann. Die schlechte Nachricht ist, dass wir keine Ahnung haben, wie wir etwas anderes als anonyme Kommunikation machen sollen. Einige Programmierer sprechen von "Zwei-Faktor-Authentifizierung", aber die Schlauen springen zu "N-Faktor-Authentifizierung".

Nach dem Passwort und vielleicht einer SMS an ein Handy haben wir nicht viel, was sehr stabil ist. Fingerabdruckleser sehen beeindruckend aus, aber viele Leute scheinen bereit zu sein, preiszugeben, wie sie gehackt werden können (siehe hier, hier und hier für den Anfang).

Nicht viel davon ist für die Welt des Geschwätzes auf Snapchat oder Reddit von Bedeutung, aber der Strom von gehackten Facebook-Seiten ist etwas beunruhigend. Es gibt keine einfache Möglichkeit, mit ernsten Angelegenheiten wie Eigentum, Geld, Gesundheitsfürsorge oder so ziemlich allem anderen im Leben umzugehen, außer bedeutungslosem Smalltalk. Die Bitcoin-Fanbois lieben es, darüber zu plappern, wie solide die Blockchain sein mag, aber irgendwie werden die Münzen immer wieder abgerissen (siehe hier und hier). Wir haben keine wirkliche Methode, um mit Identität umzugehen.

Härte messen

Gibt es beim Programmieren natürlich überhaupt eine Möglichkeit, die Schwierigkeit eines Problems zu messen? Niemand weiß es wirklich. Wir wissen, dass einige Probleme leicht zu lösen sind, aber es ist völlig anders, eines als schwierig zu zertifizieren. Die NP-Vollständigkeit ist nur ein Teil eines aufwändigen Versuchs, die Komplexität von Algorithmen und Datenanalysen zu kodifizieren. Die Theorie ist hilfreich, kann aber keine Garantien bieten. Es ist verlockend zu sagen, dass es schwer ist zu wissen, ob ein Problem schwer ist, aber gut, Sie verstehen den Witz.

Zum Thema passende Artikel

  • Download: Leitfaden zur Karriereentwicklung von Entwicklern
  • Die Kraft der faulen Programmierung
  • 7 schlechte Programmierideen, die funktionieren
  • 9 schlechte Programmiergewohnheiten, die wir heimlich lieben
  • 21 heiße Programmiertrends - und 21 werden kalt
  • Download: Der Business Survival Guide des professionellen Programmierers
  • Download: 29 Tipps für den Erfolg als unabhängiger Entwickler
  • 7 Programmiersprachen, die wir gerne hassen
  • 5 weitere zeitlose Lektionen zum Programmieren von 'Graubärten'
  • 22 Beleidigungen, die kein Entwickler hören möchte
  • 9 Vorhersagen für die Zukunft der Programmierung
  • Die 13 Entwicklerfähigkeiten, die Sie jetzt beherrschen müssen
  • Programmieren Sie die Welt: 12 Technologien, die Sie jetzt kennen müssen
  • Angriff der Ein-Buchstaben-Programmiersprachen