Hallo
schon wieder die ewig gleiche Frage werden sich jetzt die meisten denken
und mit irgendwelchen Links Antworten.
Aber darum geht es nicht.
Die gewählte Programmiersprache ist formell in einigen Wochen erlernt
und die Regeln zu ihrer Benutzung sind auch durch Fleiß und Übung in
überschaubarer Zeit in "Fleisch und Blut" übergegangen.
Aber ganz unabhängig von der Programmiersprache kann man in den vielen
Beispielen und auch kompletten Projekten immer wieder sehen das sehr oft
"um die Ecke" gedacht wird und z.B. Fehler in der Funktionalität durch
sehr clevere aber zuerst nur schwer verständliche verschlungen Wege
umgangen und abgefangen werden.
Klar ein Programm entwickelt sich durch Testen und verbessern, aber
trotzdem will man schon im ersten Schritt möglichst viel richtig machen.
Meine Frage ist:
Wie lernt man das "um die Ecke" denken, wie erlernt man das frühzeitige
erkennen von möglichen "versteckten" Fehlern und ähnliches was mit der
eigentlichen Programmiersprache nicht direkt zusammenhängt?
Insbesondere bei vielen echten Anwendungen von Timern und Countern ist
mir dieses "um die Ecke" denken und das nicht sofortige erkennen warum
etwas so gemacht wird oder notwendig ist, besonders aufgefallen.
Aber auch bei logischen Verknüpfungen steckt oft viel "Magie" dahinter.
Wie erlernt man das alles am besten?
Als Ergänzung: Meine Frage bezieht sich auf den Hobbyanwender und der
ihn zur Verfügung stehender und bezahlbarer Hard- und Software.
Mergus
Mergus schrieb:> Wie lernt man das "um die Ecke" denken, wie erlernt man das frühzeitige> erkennen von möglichen "versteckten" Fehlern und ähnliches was mit der> eigentlichen Programmiersprache nicht direkt zusammenhängt?
Indem man es ein oder mehrer male Falsch gemacht hat, hingefallen ist,
und sich dann irgendwann merkt:
Ah, das hab ich schon mal so gemacht, da bin ich hingefallen, vielleicht
sollte ich das jetzt anders machen.
Nennt sich Erfahrung, und die muss man selber machen. :)
Das ist wie mit der heissen Herdplatte. Ja, das kannst du jemandem 5000
mal erzaehlen, und trotzdem wird er irgendwann mal anfassen und sich
verbrennen. Dann hat er diese Erfahrung gemacht, und wenn er schlau
genug ist, wird es bei diesem einen Versuch belassen.
Erfahrung muss man sammeln, die kann man nicht "lernen" durch das lesen
eines Buches oder so. Ein Buch kann dir Tipps und hilfestellung geben,
aber am Ende musst du es mal selber ausprobieren.
Ich würde mal behaupten: Durch Erfahrung.
Du bearbeitest ein Projekt, lernst dabei stetig dazu und bei der
nächsten Aufgabe machst du dann von Beginn an gleich den ein oder
anderen Fehler weniger.
// Kaj hat es etwas asuführlicher formuliert ;)
Es bedarf einiges an Übung um ein guter Programmierer zu werden. Dabei
lernt man fast in jedem Projekt etwas dazu, probiert ggf. verschiedene
Lösungsansätze einmal aus. Man wächst tatsächlich mit seinen Aufgaben.
Folglich wirst du keinen guten Programmierer ohne ein Gewisses Maß an
Übung, Erfahrung und Routine finden.
Wichtig ist dabei, das machen nur sehr wenige, sich wirklich einmal
aufzuschreiben was man eigentlich braucht und will (Problem in Worte
fassen/ abstrahieren/Pflichtenheft). Dann zerlegt man das Projekt in
immer kleiner werdende Problemstellungen. Dabei wird jedes Problem mit
exakt einer Funktion gelöst. Wichtig ist dabei nicht den Faden zu
verlieren.
Wenn etwas mal nicht auf Anhieb klappt, dann einfach mal ne Nacht drüber
schlafen, das hilft mir in 80% aller Fälle.
Ich bin lange kein Profi, aber für meine Hobby- und Dienstlichen
Projekte reichen meine Kenntnisse inzwischen recht gut aus.
Mergus schrieb:> Die gewählte Programmiersprache ist formell in einigen Wochen erlernt> und die Regeln zu ihrer Benutzung sind auch durch Fleiß und Übung in> überschaubarer Zeit in "Fleisch und Blut" übergegangen.
Nö, dazu baucht es Jahre.
Der Rest: Am besten lernt man etwas, wenn der Fehler so richtig weh
getan hat
:-)
Der Andere schrieb:> Der Rest: Am besten lernt man etwas, wenn der Fehler so richtig weh> getan hat> :-)
Am besten aber Anderen. Also Fehler in Fly-By-Wire Systemen, Ariane
Raketen, Aufzügen, Bahn Leitsystemen (letztens haben in da wohl Italien
wieder einige sehr viel gelernt).
Ingo L. schrieb:> Wenn etwas mal nicht auf Anhieb klappt, dann einfach mal ne Nacht drüber> schlafen, das hilft mir in 80% aller Fälle.
oder mit jemanden Reden der nicht mal das Problem ganz verstehen muss,
oft kommt beim Formulieren selbst der zündende Gedanke!
Joachim B. schrieb:> oder mit jemanden Reden der nicht mal das Problem ganz verstehen muss,> oft kommt beim Formulieren selbst der zündende Gedanke!
Das ist richtig, allein das Problem so formulieren zu müssen dass ein
Aussenstehender es versteht hilft oft einen neuen Ansatz zu finden.
Cyblord -. schrieb:> Am besten aber Anderen. Also Fehler in Fly-By-Wire Systemen, Ariane> Raketen, Aufzügen, Bahn Leitsystemen
Es muss nicht unbedingt jemand dabei umkommen. Es reicht wenn du wegen
dem Fehler einen Tag suchen musst um ihn zu finden, DEN machst du dann
nicht so schnell wieder.
Ingo L. schrieb:> Wichtig ist dabei, das machen nur sehr wenige, sich wirklich einmal> aufzuschreiben was man eigentlich braucht und will (Problem in Worte> fassen/ abstrahieren/Pflichtenheft).
So isses!
Das aus dem Kopf coden wird zwar immer wieder gerne gemacht, ist aber
der steinigste, längste und fehlerträchtigste Weg.
Der Andere schrieb:> Es reicht wenn du wegen dem Fehler einen Tag suchen musst um ihn zu> finden, DEN machst du dann nicht so schnell wieder.
Leider finden viele schon nach einem halben Tag einen "brauchbaren
Workaround"... :-/
Mergus schrieb:> Die gewählte Programmiersprache ist formell in einigen Wochen erlernt> und die Regeln zu ihrer Benutzung sind auch durch Fleiß und Übung in> überschaubarer Zeit in "Fleisch und Blut" übergegangen.
Naja, Syntax und Semantik vielleicht - aber um sich das Wissen und die
Erfahrung, um zu wissen, was man da eigentlich aussagt bzw.
beschreibt, anzueignen, benötigt man schon einige Jahre.
> [...] in den vielen Beispielen und auch kompletten Projekten immer wieder sehen
das sehr oft "um die Ecke" gedacht wird
Verstehe ich nicht - hast du einmal ein paar konkrete Beispiele?
> und z.B. Fehler in der Funktionalität durch sehr clevere aber zuerst nur schwer
verständliche verschlungen Wege umgangen und abgefangen werden.
Das ist extrem schlechter Stil. Fehler (ich vermute, du sprichst von
Software-Bugs) sollten immer möglichst "effizient" gefixt werden, wobei
das "effizient" natürlich zunächst bedeutet, dass der Bug durch
Änderungen geringstmöglichen Umfangs gefixt werden sollte, da jede
Änderung am bestehenden Code natürlich das Risiko entsprechender
Seiteneffekte beinhaltet. Allerdings ist es natürlich auch
unverantwortlich, wenn dadurch irgendwelcher Spaghetticode entsteht,
unter dem das Verständnis des Codes leidet - hier geht die Codequalität
vor, d. h. in diesem Falle kann und sollte man auch ruhig zwei, drei
Zeilen Code mehr rausschmeißen und neu machen.
> Klar ein Programm entwickelt sich durch Testen und verbessern, aber> trotzdem will man schon im ersten Schritt möglichst viel richtig machen.
Wer will das nicht?
Kernvoraussetzung ist eine gute Planung, sprich z. B. die
Ressourcennutzung des µCs (welcher Timer macht was, nutze ich den
Watchdog, wie resette ich ihn etc.), Struktur des Programmablaufs,
überschlägige Abschätzung der Ressourcennutzung (reicht die Taktfrequenz
überhaupt für die geforderte Interruptfrequenz bei diesem und jenigem
Code in der ISR) usw.
> Meine Frage ist:> Wie lernt man das "um die Ecke" denken, wie erlernt man das frühzeitige> erkennen von möglichen "versteckten" Fehlern und ähnliches was mit der> eigentlichen Programmiersprache nicht direkt zusammenhängt?
s. o. Darüber hinaus würde ich dringend davon abraten, überhaupt zu
versuchen, beim Programmieren zu sehr "um die Ecke zu denken" und sich
auf Biegen und Brechen irgendwelche Programmiertricks aus den Fingern zu
saugen - darunter leidet die Wartbarkeit des Codes definitiv (kannst du
selbst ausprobieren: Schaue dir deinen Code nach z. B. vier Wochen zum
ersten Mal wieder an und versuche, das, was du da tust, zu verstehen.
Ist es intuitiv und problemlos möglich, oder blickst du überhaupt nicht
mehr durch?)
> Insbesondere bei vielen echten Anwendungen von Timern und Countern ist> mir dieses "um die Ecke" denken und das nicht sofortige erkennen warum> etwas so gemacht wird oder notwendig ist, besonders aufgefallen.> Aber auch bei logischen Verknüpfungen steckt oft viel "Magie" dahinter.
Bitte Beispiele. Ansonsten s. o. - grundsätzlich sollte sich ein
Quellcode jedem, der die Programmiersprache auf Fortgeschrittenem-Niveau
beherrscht, sofort erschließen.
> Wie erlernt man das alles am besten?
Wie gesagt, Übung - und das Prinzip des "Lernens durch Schmerz" (siehe
oben: Nach ein paar Wochen die eigenen geistigen Ergüsse nochmals
anschauen - wenn du daraufhin eine gute Portion Selbsthaß und das
dringende Bedürfnis zur Selbstgeißelung entwickelst, ist das ein guter
Anreiz, es künftig besser zu machen). Ansonsten kannst du dir z. B. für
C die MISRA-Richtlinien anschauen.
Ich schaue mir viel Application Notes der Hersteller an. Die Jungs
schreiben sicher nicht den 100% 'göttlichen' Code, aber sicher sind sie
am nächsten dran in Bezug auf Ressourcen des verwendeten Bausteins und
Programmierstil dafür.
Nicht zu vergessen, auch hinter die Kulissen schauen. Also nicht einfach
stupide Werkzeuge, Bibliotheken usw. nach einem einmal gefundenen
Kochrezept verwenden, sondern gelegentlich mindestens eine Ebene tiefer
gehen.
Beispiele:
* Verstehen was der Compiler oder Linker bei Option -XYZ wirklich macht.
Das heißt nicht, dass man den Quelltext des Compilers auswendig lernen
soll, aber etwas tiefer gehen als nur Kochrezept anwenden.
* Sich bei Gelegenheit eine typische Implementierung einer
Bibliotheksfunktion ansehen. Kürzlich blamierte sich hier ein Fanboy von
C++ und std::string ein bisschen als ich ihm erklären musste, dass
typische std::string-Implementierungen für Mikrocontroller nicht
geeignet sind.
* Verstehe Hardware.
* Ebenfalls: Mathe. Habe deine Theorie im Griff, eine gute Theorie ist
die beste Praxis. Das beginnt mit den ganzen Bit-Tricksereien, dem
Verstehen von Zahlensystemen und Datentypen (nein, double ist nicht
immer die beste Wahl), bis hin zu den anwendungsspezifischen
Algorithmen.
* Und grundsätzlich, habe deine Werkzeuge im Griff. Viele Programmierer
scheitern schon daran die Tabs in ihrem Editor richtig einzustellen :(
Daneben sollte man grundsätzlich nicht vergessen, dass die meisten
Programmiertipps im Internet und in Fachbüchern aus dem Bereich Desktop-
oder Server-Entwicklung kommen, nicht Mikrocontroller. Immer
hinterfragen ob dass was dort empfohlen wird in begrenzten
Mikrocontrollern, am besten ohne Betriebssystem funktionieren.
Beispiele:
* Frameworks, bzw. das Allheilmittel der Informatiker die Abstraktion,
helfen nur sehr bedingt. Wenn du ein Byte verschieben musst, dann geh es
an und verschiebe es und mache keine tiefenphilosophische, metaphysische
Sache daraus.
* Bekannte APIs oder Bibliotheksfunktionen aus dem Desktop- oder
Server-Bereich sind oft nicht vorhanden. Lebe damit statt zu jammern.
Was auch hilft ist alt zu sein. Damit meine ich zum Beispiel einer
Generation anzugehören, die auf Minicomputern, 8-Bit CP/M oder
Heimkomputern mit 2 MHz CPU-Takt und bestenfalls 64 k Hauptspeicher
gelernt hat. Die noch von Hand assembliert hat und Programme in Hex von
Hand Byte für Byte in einen Computer eingetaktet hat.
Das braucht man zwar heute alles nicht mehr, aber dabei hat man einen
Denkart, Geisteshaltung und Gelassenheit entwickelt an µC Probleme
heranzugehen und zu lösen. Man weiß auch was geht wenn man es nur
richtig macht und will.