Hallo en welkom.
In deze lezing wil ik het hebben over debuggen.
Dit is een zeer belangrijk concept dat u specifiek moet begrijpen, u moet enkele van de hulpmiddelen en enkele
van de methoden begrijpen die u kunt gebruiken om bugs te vinden en te repareren.
Debuggen is dus het vinden en herstellen van fouten in een programma.
Meestal logische fouten.
En ik ga je het verschil vertellen tussen logica- en syntaxfouten, maar het kan ook compiler syntaxfouten
omvatten.
Het is het hele proces voor syntaxfouten.
Debuggen is begrijpen wat de compiler je vertelt.
U wilt zich altijd richten op het oplossen van het eerste probleem dat wordt ontdekt.
Ik wil enkele veel voorkomende compilerfouten
en waarschuwingen doornemen die je kunt krijgen.
U wilt zich altijd concentreren op de eerste fout, omdat die eerste fout tot andere fouten kan leiden.
Het kan dus erg misleidend zijn als je vijf fouten ziet in een programma dat de compiler je vertelt, dat je misschien maar één
fout hebt en dat die eerste fout de andere fouten veroorzaakt.
Het is dus belangrijk om altijd naar die eerste topfout te kijken en die eerst te herstellen.
In dit zeer simplistische voorbeeld hebben we meerdere fouten in deze code.
We hebben geen.
We hebben geen begin van een haakje links, een accolade.
We hebben geen puntkomma.
We sturen een string terug.
En dus als we dit opslaan en we gaan het compileren en je ziet enkele rode fouten, als
we het gaan compileren, vertelt het ons eigenlijk dat we drie fouten hebben.
U wilt nooit alleen de laatste fout op regel zeven selecteren, ook al is het in dit geval een echte fout.
Je wilt altijd alleen de eerste fout oplossen.
Dus je ziet de eerste fout die hier staat en je herstelt die eerste fout en dan hercompileer je hem en voer je hem opnieuw
uit.
Maar de reden om dit te doen is alleen om die bovenste fout te herstellen, omdat die fout andere problemen kan
veroorzaken.
Richt u dus altijd op het oplossen van die eerste fout. Het opsporen en oplossen van bugs kan zeer complex zijn, van het
vinden van eenvoudige fouten tot het verzamelen van grote hoeveelheden gegevens voor analyse.
Dat hangt ervan af.
Soms heb je geen informatie bij je behalve logging, en in dat geval moet je dingen
analyseren.
Soms heb je bugs die niet herhaalbaar zijn.
Je kunt het niet reproduceren omdat het zo zelden gebeurt.
Dat is meestal wanneer je logs moet analyseren of een variatie daarvan.
Het vermogen van een programmeur om te debuggen is een essentiële vaardigheid.
Het is echt een probleemoplossende vaardigheid die je enorm veel tijd en geld kan besparen.
Het is dus een belangrijke vaardigheid om te leren.
Het is een belangrijke vaardigheid om te ontwikkelen.
Het vergt oefening.
Je gaat het niet zomaar naar je toe trekken.
Er zijn bepaalde technieken die u kunt toepassen en methoden die u kunt toepassen om u beter te maken
in het debuggen.
Ik ken heel wat ontwikkelaars die echt goed zijn in het schrijven van software.
Ze begrijpen de taal heel goed, maar hun debugging vaardigheden zijn zeer slecht.
Ze kunnen een bug krijgen en hun eerste neiging om die bug op te lossen is echt een beetje van slag.
En nogmaals, dit komt met de praktijk.
Je zult steeds beter worden in het debuggen en begrijpen hoe je problemen kunt vinden en oplossen,
maar het is iets wat je ook moet leren.
De onderhoudsfase is de duurste fase van de levenscyclus van software.
De onderhoudsfase is nadat je je product hebt uitgebracht en je het nu moet onderhouden.
Onderhouden betekent nieuwe bugs oplossen en nieuwe functies toevoegen.
Dus, bijvoorbeeld, wanneer Windows een nieuw besturingssysteem zoals Windows 10 uitbrengt, zijn ze nog niet klaar met het
produceren van die software.
Het zal waarschijnlijk tien jaar in het veld blijven.
En het is nog steeds de verantwoordelijkheid van Microsoft als er nieuwe bugs binnenkomen of als ze nieuwe bugs vinden voor die software om ze te repareren.
En daarom doen ze automatische updates en dat soort dingen.
En dan zullen ze ook merken dat het besturingssysteem met nieuwe functies komt naarmate de markt en
de technologie veranderen.
Onderhoud is dus erg belangrijk.
En daarom is het vinden en oplossen van bugs erg belangrijk.
Begrijp echter dat bugs onvermijdelijk zijn.
Alle software heeft fouten.
Niemand kan perfecte code schrijven en het gaat zelfs niet per se om het schrijven van perfecte code.
Het is gewoon dat dingen in de loop der tijd veranderen.
Dus dat kan ook bugs opleveren.
Je moet begrijpen dat het feit dat software bugs heeft niet betekent dat het slecht geschreven code is.
Het is onvermijdelijk.
Dus het is goed om fouten te hebben, weet je, als je ze vindt en oplost, is het nog beter omdat je dan het
gevoel hebt dat je iets bereikt.
Veel voorkomende problemen.
En we gaan het meer hebben over specifieke problemen met betrekking tot zien.
Maar veel voorkomende problemen bij het debuggen zijn logische fouten.
Logische fouten hebben te maken met niet het tegenovergestelde van het soort syntaxfouten dat uw code eigenlijk compileert.
Het werkt, maar het doet niet waarvoor het bedoeld is.
Dus er is een soort logica of bedoelde functionaliteit die niet klopt.
Misschien heb je een IF statement en spring je in dat if statement op de verkeerde voorwaarde.
Misschien heb je een lus en wordt die niet het juiste aantal keren uitgevoerd, of sorteer je niet
goed.
De functionaliteit is gebroken, maar de compiler zegt: "Hé, alles ziet er goed uit.
Hier is een voorbeeld van een logische fout.
Een logische fout is wanneer de syntaxis correct is, maar de gewenste resultaten niet correct zijn door een of ander logisch
probleem.
Dus in deze code zie je dat de for-lus een puntkomma heeft aan het eind, wat syntactisch correct is.
Maar je verwacht dat deze for-lus vijf keer wordt uitgevoerd.
Maar dat is het niet.
Het gaat maar één keer draaien.
Dus als we zeggen bouwen en we bouwen dit project, zien we een waarschuwing, wat leuk is en je zou altijd al je waarschuwingen moeten
oplossen.
Maar het compileerde wel succesvol.
Dus als we dit project uitvoeren, zul je merken dat het eigenlijk maar één keer draait en Hello
World één keer afdrukt.
Dus dit is een voorbeeld van een logische fout.
Syntaxfouten houden rechtstreeks verband met de compiler.
Dit zijn dingen die de regels van de taal niet volgen.
Je hebt geen puntkomma aan het eind van een verklaring.
Je hebt geen einde, toch?
Haakjes met links, haakjes.
Je mist een beugel.
Je gebruikt niet het juiste sleutelwoord, dat soort dingen.
Syntaxfouten worden meestal veroorzaakt door de compiler Logische fouten worden veroorzaakt door de programmeur
tijdens de testfase.
Geheugencorruptie is ook een veel voorkomend probleem, vooral in C.
Als je je geheugen niet correct vrijmaakt na toewijzing, kun je dingen krijgen
als bungelende referenties en je kunt ook geheugenproblemen krijgen met betrekking tot geheugen dat niet wordt gebruikt.
Je kunt geheugenlekken hebben.
Hier is een voorbeeld van een geheugenfout.
In deze specifieke code hebben we eigenlijk een geheugenlek, dus we hebben het nog niet gehad over pointers.
We hebben het nog niet gehad over dynamische geheugentoewijzing.
Maar in C kun je geheugen toewijzen terwijl je programma draait.
Je kunt een malloc functie gebruiken.
En dus markeren we hier, we wijzen geheugen toe, maar we maken het nooit vrij.
Dus we kunnen deze code bouwen en uitvoeren en alles is in orde, maar we maken deze fout niet echt
vrij.
Dus wat we moeten doen om deze geheugenfout te corrigeren is free zeggen en dan free en X zeggen
om die pointer vrij te maken.
Maar wanneer je geheugen toewijst, maak je het niet vrij.
Dat is een geheugenlek.
En een ander voorbeeld zou zijn als we het geheugen niet toewijzen, als we een pointer maken en die dan proberen
toe te wijzen, dan krijgen we geheugencorruptie omdat dat geheugen geen toewijzing heeft en we proberen
er een waarde aan toe te wijzen.
Dus dat is maar een klein tipje van de sluier van wat voorbeelden voor geheugen, corruptie, prestaties en schaalbaarheid.
Dit kan een probleem zijn wanneer je functionaliteit bedoeld is zoals ze is en je code syntactisch correct
is, maar ze is niet erg efficiënt of je hebt niet de hardware om ze te ondersteunen.
Dus als je een server draait en je hebt niet genoeg hardware om alle aanvragen te ondersteunen, dan
zal hij heel erg traag draaien.
Of als u uw programma hebt geschreven om met tien gebruikers te werken, maar als het veel gebruikers krijgt,
is het misschien niet zo snel omdat de database vastloopt of wat dan ook.
De code werkt, maar is niet goed ontworpen om veel, heel veel gebruikers aan te
kunnen.
Gebrek aan samenhang.
Dit kan een probleem in uw code zijn dat de kwaliteit vermindert doordat uw code te veel doet of een
functie te veel doet.
Het is niet één focus of zelfs een applicatie heeft te veel functionaliteit, heeft functies die
nooit worden gebruikt, en dus zou dit waarschijnlijk een herontwerp vereisen.
Hier is een voorbeeld van een programma dat niet gemodulariseerd zou zijn, dat niet samenhangend is.
Je hebt één grote functie die veel te veel dingen doet, honderden regels code, duizenden regels
code.
Je wilt een functie opsplitsen in hulpfuncties, aparte modules.
Dat maakt je programma veel samenhangender, makkelijker te onderhouden.
Dus in plaats van een grote hoofdmethode die de initialisatie, het lezen van de invoer,
het vinden van een aantal, het vinden van het verschil, het vinden van het product, het
vinden van het quotiënt doet, kunt u al deze code in helpermodules plaatsen en de code scheiden.
Cohesie is altijd belangrijk in C en het wordt meestal opgelost waar je een hoge cohesie hebt door helper-methoden
aan te bieden.
Strakke koppeling.
Dit heeft ook te maken met de kwaliteit van de code.
Hier heb je veel afhankelijkheden.
Koppeling is anders dan cohesie.
Cohesie is je enige focus.
Koppeling is wanneer je afhankelijkheden hebt tussen misschien functies of tussen objecten.
We spraken over koppeling, we spraken over globale variabelen.
Als een globale variabele in veel verschillende functies wordt gebruikt, kan dat leiden tot afhankelijkheden
tussen die functies.
Dus waar je naar wilt streven als je code schrijft van hoge kwaliteit is dat je een
zeer hoge cohesie en een zeer lage koppeling wilt hebben.
Het debugproces.
Het eerste wat u moet doen voordat u een fout kunt vinden en oplossen, is het probleem
begrijpen.
Dit is te relateren aan niet zomaar in de code duiken, maar samen met de tester gaan zitten, de eisen
begrijpen, begrijpen wat er aan de hand is.
Want als je niet begrijpt wat er aan de hand is, kun je het niet eens.
Je moet niet eens proberen het op te lossen.
Zodra u de bug begrijpt, probeert u hem te reproduceren, omdat het reproduceren van de bug u kan helpen meer informatie
te verzamelen.
Het is niet altijd mogelijk om bugs te reproduceren, omdat ze in zeer zeldzame omstandigheden kunnen voorkomen.
Dus bijvoorbeeld bugs met bijvoorbeeld race conditions of zelfs geheugencorruptie kunnen alleen voorkomen in
een zeer specifiek gebruik en het kunnen intermitterende problemen zijn.
En is dat zo?
En je kunt het niet reproduceren.
Het wordt steeds moeilijker om te debuggen.
Als je het kunt reproduceren, kun je meestal genoeg informatie verzamelen om het te verhelpen.
De meeste problemen zijn op te lossen.
Ook kun je problemen hebben met het niet kunnen reproduceren van een probleem als je een multithreaded omgeving,
parallelle processen of threading problemen hebt.
Die zijn ook heel moeilijk te debuggen, maar probeer het zeker te reproduceren als je eenmaal hebt uitgezocht
wat het probleem eigenlijk is in termen van je bent in staat om het te begrijpen, als je eenmaal in staat bent om te reproduceren,
als je dat niet bent, dan wil je proberen om een soort verdeel-en-heers aanpak toe te passen.
U wilt proberen de bug te isoleren, het probleem te vereenvoudigen, want als u kunt reduceren, krijgt u informatie terug,
maar het vertelt u misschien niet noodzakelijkerwijs in welk deel van de code de bug zit.
Wat je dus kunt doen om te proberen het probleem te vereenvoudigen, is delen van de oorspronkelijke testcase verwijderen,
zodat je niet te veel test.
Je kunt het probleem nog kleiner isoleren door te zeggen: Oh, het gebeurt alleen in deze specifieke situatie.
U kunt ook code uitcommentariëren.
We hadden het over functies die alleen stubs hebben en geen implementatie.
Soms wordt dat gebruikt bij het testen om de probleemstelling te beperken.
En als je code uitcommentarieert, heb je minder code waar de bug daadwerkelijk kan optreden.
Dus als u code uitcommentarieert of veranderingen terugdraait, kan de bug verdwijnen en als de bug verdwijnt, vertelt dat
u dat de code die u uitcommentarieerde de oorzaak kan zijn geweest.
Maar wat je in wezen wilt doen, is een groot programma veranderen in een heleboel kleine programma's, hetzij door
testen, hetzij door commentaar.
Een andere gebruikelijke techniek is het uitvoeren van unit tests rond uw code.
Als een eenheidstest mislukt, kan dat u precies vertellen waar de logica of het probleem in uw code zit.
Zodra je de bug hebt geïsoleerd, kun je daarmee de oorsprong van het probleem in de code vinden, de specifieke code
die het probleem veroorzaakt.
Soms wordt daarbij gebruik gemaakt van debuggereedschap zoals een debugger.
We gaan het specifiek hebben over een debugger, maar meestal, afhankelijk van welke IDE geïntegreerde ontwikkeling je gebruikt,
zijn er debuggers die met de IDE worden meegeleverd.
Er zijn ook debuggers die standalone kunnen landen.
De grote belangrijke debugger die we gaan gebruiken voor C-programmering heet GDB.
Het is de GNU debugger, dus een mooi grafisch hulpmiddel waarmee je de uitvoering van je programma
kunt stoppen en breekpunten kunt toevoegen.
En als je dan de uitvoering stopt, kun je regel voor regel in je code kijken naar de waarde van variabelen.
U kunt dus precies zien wat er in uw code gebeurt terwijl die draait.
Het is een instrument van onschatbare waarde.
Het is gewoon zo nuttig.
We gaan de debugger doorlopen.
Ik zal je laten zien hoe je breekpunten toevoegt.
Ik zal je laten zien hoe je een horloge instelt zodat je naar variabelen kunt kijken als ze veranderen, en dan ook nog door de code
heen stappen.
Nadat je de oorsprong van het probleem hebt geïdentificeerd, moet je het oplossen.
Dit vergt veel ervaring en oefening.
Alleen omdat u de oorsprong van het probleem hebt gevonden, kunt u het misschien nog steeds niet oplossen
op basis van uw ervaring.
Dit omvat soms ook het herontwerpen of refactoren van andere code die u vooral bij schaalbaarheidsproblemen
of prestatieproblemen moet herontwerpen om uw software schaalbaarder te maken.
Het is dus niet altijd gemakkelijk om het probleem te vinden en het dan te verhelpen.
Het probleem is soms, vooral nog moeilijker problemen zoals threading of parallelle verwerking,
die zijn nog moeilijker op te lossen.
Maar naarmate je meer en meer code schrijft, zal dit gemakkelijker worden.
En tot slot moet je als een gek testen.
Test altijd veel verschillende grenzen.
Goede gevallen, slechte gevallen tussendoor om na te gaan of je het probleem inderdaad hebt opgelost.
Enkele van de beschikbare technieken en hulpmiddelen.
Een veelgebruikt en zeer, zeer veel gebruikt hulpmiddel is het gebruik van afdrukverklaringen.
U kunt print statements gebruiken om uw code te traceren.
Dus in C kun je het print F statement gebruiken en je kunt het op meerdere regels in je code zetten om aan te
geven waar je bent.
Dit is ook handig, heel handig als je programma vastloopt.
Het kan helpen identificeren waar het is gecrasht.
Als u deze afdrukverklaringen toevoegt om uw code te traceren, kunt u output toevoegen in de afdrukverklaringen
om de waarde van variabelen te zien, omdat de waarde van variabelen de toestand kan beïnvloeden en logische problemen
kan veroorzaken.
Dus het toevoegen van print statements is zeer, zeer nuttig.
Het kan de uitvoeringsstroom laten zien en het kan helpen de fout te isoleren.
Debuggers zoals ik er een noemde in GDB, die kunnen de uitvoering van het programma controleren.
Je kunt het stoppen, regel voor regel uitvoeren, opnieuw starten, breakpoints instellen, variabelen en geheugen in de gaten houden.
Zeer, zeer nuttig bij het vaststellen van een probleem.
Logbestanden.
Logbestanden zijn ook zeer nuttig, vooral voor bugs die niet opnieuw kunnen worden gemaakt.
U kunt ze later analyseren om precies te zien wat er aan de hand was toen de bug zich voordeed.
Dit betekent dus dat je goede logging statements in je code zelf moet voorzien om dit
nuttig te laten zijn.
U kunt dus uw eigen logbestand maken en dan naar dat logboek schrijven terwijl het programma draait, zodat als u een fout heeft,
u die logboeken naar de ontwikkelaars kunt sturen.
Bij Xerox gebruiken we dit nogal eens, omdat we problemen niet altijd kunnen reproduceren
of in het veld tegenkomen.
We moeten toegang hebben tot die logs om te zien wat er gebeurde toen die bug zich voordeed.
Monitoring software.
Er is software die het geheugengebruik, het dreigende netwerkverkeer en objectinformatie kan controleren en
runtime analyseren.
Dit kan u vertellen of u misschien te veel geheugen toewijst en het niet verwijdert.
Als je een instrument hebt voor geheugengebruik netwerkverkeer dat je kan vertellen of je al dan niet
te veel pakketten uitstuurt of dat je software al dan niet schaalbaar is, als je een toename van netwerkverkeer
hebt en je ziet dat je je reactietijd verslechtert.
U kunt ook informatie over threads en objecten voor parallelle verwerking monitoren om te zien wat er in bepaalde threads
gebeurt en wat er in een andere thread gebeurt.
Dat zal u helpen bij de diagnose van eventuele problemen.
Enkele andere gebruikelijke debug-gereedschappen die u kunt gebruiken om uw fouten te vinden en op te lossen.
U kunt gebruik maken van uitzonderingsbehandeling.
Veel programmeertalen hebben uitzonderingsafhandeling.
Helaas heeft C geen exception handler die crashes voorkomt en veel dingen doet tijdens
runtime.
Het is niet van toepassing op zien, maar toch goed om te begrijpen.
Trycatch-blokken, dat soort dingen.
Statische analysers.
Er zijn veel statische analyzers voor C beschikbaar.
Analyseer de broncode zonder het eigenlijke uitvoerbare bestand.
Het programma hoeft niet te draaien.
Het gaat regel voor regel en bekijkt de broncode.
En terwijl het de broncode leest, zoekt het naar bekende problemen.
Dus het kan de semantiek controleren.
Het kan ervoor zorgen dat.
Dat is het.
Je hebt geen niet-geïnitialiseerde variabelen als je als je nieuw geheugen toewijst dat verwijdert.
Als je dode code hebt waar code niet echt wordt uitgevoerd, kun je die code verwijderen.
Het analyseert ook zaken als race conditions en deadlocks.
We gebruiken een paar statische analyzers waar ik werk.
We hebben er een die Coverity heet, die vrij populair is, en er is een code sonar tool die we ook gebruiken, en we draaien
dit op onze hele basislijn, onze hele broncode set.
En telkens wanneer wij nieuwe bestanden en nieuwe code invoeren, zal dat instrument op die code worden toegepast en zal het in staat zijn
onmiddellijke problemen met de code op te sporen, zoals niet-geïnitialiseerde variabelen, geheugenlekken enz.
Het analyseert geen syntaxis.
Daar is de compiler voor.
Er is ook een aantal testsuites die een reeks uitgebreide systeem-eind-tot-eind-tests uitvoeren die u op
uw software kunt uitvoeren.
Testen is altijd belangrijk, maar als je het op de een of andere manier kunt automatiseren om bepaalde tests uit te voeren
elke keer dat je bijvoorbeeld een nieuwe build doet, kan dat heel nuttig zijn en dit kan fouten voorkomen, maar
het helpt ook bij het diagnosticeren van fouten.
Debuggen van het programma nadat het is gecrasht.
We gaan het hebben over iets dat de aanroepstapel heet.
Dit is een zeer nuttig mechanisme om te zien, vooral in een taal als C, waar je een crash hebt en de enige informatie
die je krijgt zoiets is als segmentatiefout.
Wanneer je die crash hebt, wat vaak gebeurt, afhankelijk van hoe het crashte, wordt een kernbestand gegenereerd
en kun je het kernbestand analyseren om naar de aanroepstapel te kijken om precies te zien waar het programma stierf.
Het vertelt je de regel code waar het programma stierf.
En dus gaan we leren over de call stack.
En het analyseren van kernbestanden is meer een geavanceerde techniek.
Maar in C kun je een kernbestand genereren en dat analyseren.
Dat is een iets geavanceerdere techniek, maar dat is een andere manier om je software te debuggen.
Hoe zit het met het voorkomen van fouten?
We weten dat debuggen het vinden en herstellen van fouten is, maar als je fouten kunt voorkomen, is dat nog beter.
Een van de manieren waarop je fouten kunt voorkomen is door code van hoge kwaliteit te schrijven.
Dit is niet echt een aandachtspunt voor veel software ingenieurs.
Veel software-ingenieurs schrijven de code, en zolang die werkt, is dat het enige waar
ze zich zorgen over maken, of zolang de output correct is, beschouwen ze zichzelf als klaar.
Maar er bestaat zoiets als code van slechte kwaliteit en die wil je niet schrijven.
Ik heb een en ander gedemonstreerd tijdens de lezingen, maar zaken als het gebruik van betekenisvolle variabele namen
zijn erg belangrijk.
Of als je inefficiënte code schrijft waarin je misschien meer lussen gebruikt dan nodig is, of een if-statement
gebruikt of dat niet nodig is.
Al dit soort dingen vormen code van slechte kwaliteit.
Als je een functie hebt die 100 andere dingen doet en het is niet samenhangend, als je 5000 regels in een
functie hebt, als je code niet modulair is georganiseerd of als je veel afhankelijkheden
hebt tussen functies, nogmaals, dit is allemaal code van slechte kwaliteit en je wilt ernaar streven dit niet te doen.
U wilt technieken toepassen waarbij uw programma wordt georganiseerd.
Het is gemakkelijk te onderhouden, het is zeer samenhangend, het heeft weinig koppeling, en je gebruikt betekenisvolle variabele
namen.
Heel, heel belangrijk.
Nogmaals, het is heel belangrijk ook omdat de onderhoudsfase zo, zo duur is.
Als je code van slechte kwaliteit schrijft, wordt het veel moeilijker te onderhouden.
Het is moeilijker om fouten te isoleren en nieuwe functies toe te voegen.
Werk dus met goede technieken van hoge kwaliteit bij het schrijven van je code.
Unit tests.
Unit tests helpen fouten enorm voorkomen.
Unit tests worden meestal automatisch uitgevoerd wanneer u unit tests compileert, wat regressie kan helpen voorkomen.
Dat is een van de belangrijkste factoren.
Regressie is wanneer je nieuwe code schrijft en een bug introduceert op iets dat voorheen werkte.
Je hebt oude code gebroken.
Dat wil je niet doen.
Als bepaalde software werkt en iets nieuws dat je deed, maakt het kapot, dan wil je daar onmiddellijk van op de hoogte
gebracht worden en eenheidstesten kunnen daarbij helpen, omdat eenheidstesten op die oude code zullen draaien en zullen
zeggen: Hé, dit werkte, nu faalt het.
Het kan ook fouten vinden in nieuwe code voordat die wordt afgeleverd, want nogmaals, ze draaien nadat je hebt gebouwd en
het zal je meteen vertellen dat er iets mis is.
Er is een concept van testgestuurde ontwikkeling dat heel erg populair wordt.
Hierbij schrijf je eerst je tests en ontwikkel je daarna je code.
En het doel hier is als je je eerste test schrijft, je test faalt en dan schrijf je de code om hem te
laten slagen.
Er zitten veel voordelen aan TDD en het is een soort omgekeerde manier van denken.
Normaal gesproken schrijven mensen die code schrijven eerst de code en daarna de test.
Maar met TDD, geeft het je eigenlijk een andere manier van denken zodat je werkt in echt kleine brokken en
je de neiging hebt om zeer samenhangende code te schrijven en je hebt niet de code, heeft niet veel
afhankelijkheden want raad eens?
Als je code kunt testen, betekent dit dat de code niet zoveel afhankelijkheden heeft.
Als je unit test echt, echt groot is en je al die verschillende dingen mockt, is dat
meestal een grote indicator dat je code erg, erg afhankelijk is van andere dingen.
Dus door TDD toe te passen, dwingt het je om zeer losjes gekoppelde code te schrijven die geen afhankelijkheden heeft, en dwingt
het je om je functies zeer samenhangend te laten zijn.
Er zijn veel voordelen van TDD.
Je wilt ook goede documentatie en een goede planning.
Duik niet zomaar in de code en begin met implementeren.
Schrijf je ontwerp op papier.
Gebruik pseudocode.
Juist.
Plan je code.
Als je je code plant, de vereisten begrijpt en een goed doordacht ontwerp hebt, kun je veel,
heel veel fouten voorkomen.
En ik heb dit de hele cursus door vermeld, maar het is heel, heel belangrijk om een verdeel-en-heers
aanpak te hebben, in kleine stapjes te werken en voortdurend te testen na elke stap, geen 1000 regels code te schrijven en
dan te zeggen, oké, compileren en testen.
Dat is geen goede aanpak.
Vermijd te veel veranderingen tegelijk.
Wanneer u wijzigingen aanbrengt, pas ze dan stapsgewijs toe, voeg één wijziging toe en test deze grondig voordat u aan de volgende
stap begint.
Dit kan allerlei bugs helpen verminderen en het beperkt ook uw probleemstelling.
Dus als je een bug hebt, weet je meteen waar die in de code zit, omdat je net hebt gecompileerd
en die regel of dat aantal regels hebt toegevoegd.
Nogmaals, ik kan het belang van debugging niet benadrukken, het schrijven van code van hoge kwaliteit, het voorkomen van fouten.
Deze probleemoplossende technieken zullen u een hoop tijd besparen en u een veel betere programmeur van de bovenste
plank maken.
Dus in de volgende paar lezingen wil ik het hebben over enkele veel voorkomende fouten die we zien in de programmeertaal
c.
Ik wil het ook even hebben over de oproepstapel.
Ik wil de debugger doornemen en u kennis laten maken met de menu-opties en hoe u horloges kunt stoppen en uitvoeren
enzovoort.
En ik wil ook helpen bij het identificeren van enkele veel voorkomende compilerfouten die je ziet hoe je de compilers, compilerwaarschuwingen en -fouten
moet interpreteren.
Wat betekent het als de compiler dit zegt?
Wat betekent het als de compiler u deze waarschuwing geeft?
Bedankt.