Sie kennen den bestimmten Teil Ihres Codes, der für das Projekt wichtig ist, aber wahrscheinlich viel Zeit in Anspruch nehmen wird? Haben Sie jemals das Gefühl, dass Sie lieber an etwas anderem arbeiten (vielleicht weniger wichtig) oder gar nicht programmieren, anstatt an diesem Teil zu arbeiten? Dieses Biest, das du so schwer versuchst zu vermeiden und jeden faulen Trick zu benutzen, den du kennst, um seine unvermeidliche Umsetzung zu verzögern?
Nun, ich bin wahrscheinlich nur faul, aber ich musste mich immer mit Code wie diesem befassen. Schreibe etwas, dem ich nicht nachschreiben möchte (und es ist schlimmer, wenn du es aus Spaß machst und nicht bezahlt wirst!). Ein großes System, das viel Zeit braucht, um es in eine Phase zu bringen, in der Sie nützliche Ergebnisse oder Hinweise darauf erhalten, dass es funktioniert. Wie fängt man an, so etwas zu programmieren? Die meisten Leute würden wahrscheinlich "Teile und herrsche" und ähnliche architektonische Techniken vorschlagen, aber es geht nicht darum, wie du es tust; es geht darum, wie du dich damit beginnst. Was sind die allerersten Schritte, die du unternehmen würdest?
Ich werde eine Geschichte von einem Fall erzählen, in dem mir das passiert ist.
Ich wollte einen neuen Frametyp-Entscheidungsalgorithmus für x264 implementieren, der dynamische Vorwärtsprogrammierung (den Viterbi-Algorithmus) verwendet. Aber es würde kompliziert, unordentlich, hässlich und so weiter. Und ich wollte es wirklich nicht tun. Ich habe versucht, das Projekt auf Google Summer of Code zu verpfänden, aber aus irgendeinem schrecklichen Pech heraus hat der eine Student, den wir hatten, einfach sein Projekt gerettet ... war der Student, der dieses Projekt ausgewählt hat.
Nach zwei Monaten, in denen ich mich darüber beschwert und ihm ausgewichen bin, habe ich endlich an dem Algorithmus gearbeitet. Und so habe ich es gemacht.
Zuerst habe ich mit dem anderen Entwickler gesprochen, der anscheinend schon einige Ideen hatte, wie es geht. Wir haben darüber gesprochen und er hat es mir erklärt, bis ich den Prozess von einem algorithmischen Standpunkt vollständig verstanden habe. Dies ist der erste Schritt eines solchen Projekts: Verstehen Sie den dahinter stehenden Algorithmus so gut, dass Sie das Ganze pseudocodieren können.
Dann habe ich mit einem anderen meiner Kollegen gesprochen. Wir gingen zu einem Whiteboard und ich skizzierte es, bis er es auch verstand. Indem ich es jemand anderem erklärt habe, habe ich selbst Verständnis gewonnen. Dies ist der zweite Schritt: Erklären Sie den Algorithmus jemandem so gut, dass sie ihn pseudocodieren können. Dies ist eine Emulation des Programmierprozesses, da die Programmierung eine Form der "Erklärung" eines Algorithmus für den Computer ist.
Dann schrieb ich einen einfachen Java-Prototyp, der willkürliche falsche Werte für die Kostenfunktion verwendete und ausschließlich zum Testen der Viterbi-Suche verwendet wurde. Ich beendete es und überprüfte es gegen eine erschöpfende Suche - es passte tadellos zusammen. Meine dynamische Programmierung war korrekt. Dies ist der dritte Schritt: Schreiben Sie die einfachste mögliche Form des Algorithmus in die einfachste mögliche Umgebung.
Dann portierte ich es in C, x264s Muttersprache. Es hat wieder funktioniert. Dies ist der vierte Schritt: portiere diese einfache Form des Algorithmus in die vollständige Umgebung.
Dann habe ich schließlich die falsche Kostenfunktion durch die echte ersetzt. Nach einigen Reparaturen und Reparaturen funktionierte es. Dies ist der letzte Schritt: Integriere den Algorithmus vollständig in die Umgebung.
Dieser Prozess dauerte kaum eine Woche, aber aus der Perspektive von mir zu Beginn des Projekts war es völlig entmutigend und ich konnte mich nicht dazu durchringen, überhaupt anzufangen - und trotzdem einen solchen Schritt zu machen Schritt Prozess konnte ich nicht nur es erledigen , sondern bekommen es ist viel schneller als ich erwartet hatte.
Und die Vorteile gingen weit über x264 hinaus; Ich verstehe Viterbi jetzt so gründlich, dass ich es jetzt anderen erklären kann ... und diese anderen können davon sehr profitieren. Zum Beispiel verwendet einer der ffmpeg-Entwickler eine Anpassung meines Algorithmus und Codes, um ein etwas anderes Problem optimal zu lösen: optimale Header-Platzierung in Audiodateien.
Im Allgemeinen liebe ich den großen, komplexen Teil. Sie sind die Teile, die tatsächlich eine Herausforderung darstellen und mich zwingen, sorgfältig darüber nachzudenken, was ich tue. Es sind all die kleinen, langweiligen Teile, die ich nicht mag. Aber wenn es darum geht, etwas zu tun, was ich verschoben habe, finde ich einen einfachen Ratschlag wichtig:
JUST DO IT!
Ernsthaft, wenn es einmal angefangen hat, ist es viel einfacher zu beenden. Ich finde immer, dass ich die Dinge ausschalte, bis ich sie anfange, und plötzlich stelle ich fest, dass es jetzt, wo ich angefangen habe, nicht so schlimm ist, wie ich es mir vorgestellt habe, und schau, es ist schon fast fertig!
Teilen und erobern bedeutet nicht nur, den Code zu strukturieren, sondern er dient auch dazu, ein Projekt konzeptionell überschaubar zu machen. Wenn es mir schwer fällt, mit einem Projekt anzufangen, dann fast immer, weil es zu groß und gruselig ist. Durch die Aufteilung in konzeptionell überschaubare Teile wird es weniger beängstigend.
Ich glaube auch an " Leuchtspur-Kugeln ", wie von den pragmatischen Programmierern beschrieben. Reduzieren Sie das Projekt auf den absolut einfachsten möglichen "proof of concept" der Kernteile, z. ohne UI, Sonderfälle, Fehlerbehandlung und so weiter. Vielleicht sind es nur ein paar Kernroutinen mit zugehörigen Unit-Tests. Damit hast du die gruseligen Teile erobert und kannst aus dem Kern bauen.
Grundsätzlich ist der Trick, um (zumindest für mich) loszulegen: Starten Sie nicht am ganzen Projekt. Fange an einem kleinen (vorzugsweise Kern) Teil an und baue von dort aus. Wenn es mir immer noch schwer fällt, anzufangen, liegt das daran, dass der kleine Teil, den ich mir ausgesucht habe, immer noch zu groß ist, also muss ich ihn weiter teilen und reduzieren.
Ich stimme Ihnen zu, dass viele große, wichtige Teile einer Software nicht Spaß machen zu schreiben. Normalerweise beginne ich meinen Entwicklungstag mit kleineren Dingen, wie dem Hinzufügen eines Features oder dem Beheben eines Fehlers. Wenn es Zeit ist, beginne ich mit dem großen Teil, aber wenn ich das Ding nicht mehr sehen kann, mache ich etwas anderes. Das ist alles in Ordnung, wenn Sie immer noch alles rechtzeitig fertig bekommen. Und denk daran, dass es die Dinge leichter machen kann, wenn du mit anderen Leuten über das große Biest sprichst, bevor du es tust, während du es tust und nachdem du fertig bist. Dies befreit nicht nur Ihre Gedanken, sondern Sie erhalten auch die Meinung anderer aus einer weniger subjektiven Sichtweise. Solche Dinge zusammen zu planen, hilft auch.
Komisch, ich bin genau umgekehrt. Wenn ich anfange, ein Problem anzugehen, gehe ich zuerst zu den Großen. Der Kern des Problems ist normalerweise, was mich interessiert.
Wenn ich ein Projekt für mich selbst mache, könnte ich normalerweise nicht daran interessiert sein, alle unscharfen Bits an den Rändern zu implementieren, damit sie nie fertig werden. Wenn ich etwas wirklich mache, komme ich schließlich zu all den verschwommenen Bits, aber es ist nicht mein Lieblingsteil.
Ich denke, hier gibt es zwei Probleme.
Zuerst wird tatsächlich begonnen. Wie du sagst, kann das ziemlich schwierig sein. Persönlich fange ich einfach an, nur um etwas auf Papier / Bildschirm zu bekommen. Es wird wahrscheinlich falsch sein und muss bearbeitet werden, aber im Allgemeinen ist es leichter zu kritisieren als zu erstellen, selbst bei deiner eigenen Arbeit.
Dann gibt es den eigentlichen Prozess der Lösung schwieriger Probleme. Dort gibt es ein großartiges Buch mit dem Titel "Conceptual Blockbusting", in dem verschiedene Lösungsansätze diskutiert werden. Ich habe viel darüber gelernt, wie ich Problemlösungen und meine blinden Flecken mit diesem Buch anschaue. Sehr empfehlenswert.
Ich versuche, eine Metapher dafür zu finden, was das System zu tun versucht. Ich fühle mich immer wohler, wenn ich das Verhalten als Metapher beschreiben kann.
Ich gehe dann von einem testgetriebenen Entwicklungsstandpunkt aus darauf zu, d. h. beginne zu beschreiben, was das System tun muss, indem ich die Tests einrichte, die das korrekte Verhalten verifizieren.
HTH.
Prost,
Rob
Der schwierigste Teil des Projekts besteht darin, nichts in die erste Zeile zu schreiben. Wenn man etwas auf Papier schreibt, wird dieser Prozess gestartet und es ist erstaunlich, wie schnell der Rest von hier aus fließen kann.
Ich bin ein Fan des " Teile und herrsche " - Ansatzes selbst.
Wenn eine bestimmte große Aufgabe in einem System über mir hängt, verlasse ich den Computer, nehme einen Stift und Papier und teile die Aufgabe in alle logischen Komponenten und den Arbeitsablauf auf.
Nehmen Sie dann jede dieser Aufgaben, und brechen Sie die unten in den grundlegenden Funktionen / Anrufe erforderlich.
Ich kann dann Stub-Methoden einbauen, von denen ich glaube, dass ich sie brauche. und fülle sie einzeln aus. An dieser Stelle ist jede dieser "Teilaufgaben" nicht größer als die kleineren Entwicklungsaufgaben, die das gleiche Projekt umkreisen, also fühle dich wie eine viel weniger belastende Aufgabe, die über mir schwebt.
Ich gehe normalerweise mit einem Stift und einem Stück Papier zu Hause auf diese Art von Problemen ein. Ich stelle mir den Algorithmus und / oder den logischen Ablauf vor und stub (auf dem Papier!) die Klassen und Methoden-Stubs und wenn ich reinkomme vor dem / dem Computer kann ich es viel einfacher machen ... Wahrscheinlich ist es nur ich ..
Tags und Links language-agnostic abstraction