Lektor: It-studerende lærer ikke nok om debugging

De danske uddannelser spytter dygtige udviklere ud. Men lærer de også tilstrækkelig fejlfinding og rettelse?
Illustration: Privatfoto

De studerende skal have mere debugging. Det er meldingen fra Klaus Kolle, der er lektor på Ingeniørhøjskolen ved Aarhus universitet. Han mener nemlig ikke, at den undervisning i debugging, der gives, står mål med nødvendigheden af at kunne det, når man er færdiguddannet.

»Debugging er noget, man bruger rigtig meget tid på, når man sidder og udvikler. Derfor bør man træne de studerende godt ud i de forskellige muligheder. Lige nu er det noget, som det er op til den enkelte underviser at hive frem. Men der ligger så mange ting i debugging, at man godt kunne fylde et helt fag ud,« siger Klaus Kolle til Version2.

Tilmeld dig eventet Debugging - for rigtige programmører her

Erhvervslivet efterlyser det

Når de studerende ved ingeniørhøjskolen er i praktik, så er der løbende dialog mellem virksomhed og underviser for at inddrag erhvervslivet i, hvad de studerende bør lære. Og ifølge Klaus Kolle vil erhvervslivet have mere debugging.

»Nu har vi efterhånden en række virksomheder, der efterlyser mere debugging og fejlfinding. Og så må vi jo hellere gøre lidt mere ud af det,« siger Klaus Kolle.

Og lektoren kan da også fortælle, at der er mere debugging på vej.

»Vi har indført et nyt fag, der hedder software-engineering, og det kommer til at indeholde debugging-teknikker. Så der kommer specificerede emner på det, og vi har valgt at sætte fokus på det her hos os«, siger Klaus Kolle til Version2.

Klaus Kolle er en af oplægsholderne på til Version2's debugging-konference lørdag den 26.oktober 2013. Du kan tilmelde dig det gratis arrangement her.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Kommentarer (27)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Nikolaj Brinch Jørgensen

»Debugging er noget, man bruger rigtig meget tid på, når man sidder og udvikler. Derfor bør man træne de studerende godt ud i de forskellige muligheder. Lige nu er det noget, som det er op til den enkelte underviser at hive frem. Men der ligger så mange ting i debugging, at man godt kunne fylde et helt fag ud,« siger Klaus Kolle til Version2.

Men er problemet ikke vendt på hovedet? Deres studerende laver for ringe kode, og derfor sidder de og fedter i en debugger. Burde de ikke heller undervise dem i at lave noget ordenlig kode, og skrive gode tests? Forbyggelse er altså, også i softwareudvikling, langt at foretrække, fremfor behandling.

De skal ikke blive bedre til at debugge, de skal blive bedre til at lave kode der ikke behøver debugges.

Pelle Söderling

Nikolaj: Så enkelt er det jo ikke, selv de bedste udviklere bruger tid på debugging - jo højere niveau man opnår, jo mere komplicerede løsninger er man i stand til at kreere og sålænge man pusher sine evner - hvilket vi vel alle synes er sjovest - så er der altid en hvis risiko for at man begår nogle fejl undervejs.

Jeg tror eksempelvis det er de færreste der vil påstå at debugging af concurrenct kode er piece-of-cake eller at det at undgå at introducere concurrency-fejl i første omgang er det letteste i verden. For simple nok concurrent problemer så ja, men oftest når man er ude i den slags har man også brug for en høj grad af optimering og så ryger det simple.

Forskellen ligger i den tid det tager at finde et problem - for de dygtigste udviklere kan det tage 5 minutter at finde problemer andre bruger dage på. Det handler ikke kun om erfaring og forståelse af teknologierne, omend det også betyder en hel del, men det handler også i meget høj grad om teknikker (ikke så meget værktøjer imo, det meste kan klares med printf hvis man tilgår det rigtigt).

Og ærlig talt er det synd og skam at der ikke undervises mere i disse teknikker, jeg har set alt for mange professionelle udviklere der sad og brugte mere tid på debugging end på udvikling og det er jo spild af tid, penge og ressourcer.

Men ærlig talt tror jeg at de bedste debuggere også er dem der skriver mest defensiv kode og er bedst til at undgå at introducere bugs, fordi de forstår hvor der bør sættes præventivt ind - så faktisk mener jeg lidt det er 2 sider af samme sag.

Anders Brander

De skal ikke blive bedre til at debugge, de skal blive bedre til at lave kode der ikke behøver debugges.

Jeg ved ikke om du er naiv eller du troller?

Ingen programmør forstår 100% hvad der sker. Debuggeren er løsningen på det problem. Det er det "looking glass" der kan se hvad computeren rent faktisk laver. Den er uvurderlig, specielt hvis man er afhængig af andres kode - og det er alle (måske undtagen mikrokodeprogrammører).

Kim Hansen

Det kan godt være at debugging bør stå højt på listen over ting de studerende bør lære i dybden, men mindst lige så vigtigt er version control (Git, Subversion, CVS, ...) og skalérbarhed.

Hvor ofte er det ikke at man støder ind i udviklere rundt omkring i virksomhederne som laver løsninger hvor det sikkert virker fint med 1-5000 records i en database, men den dag der kommer 1 million records så kører det hele ad helvedes til. Eller udviklere som laver løsninger med lister med 20 rækker hvilket måske er fint til demo-formål men hvis der kommer flere data og der skal bladres... hvad så?

En anden ting er resize af vinduer eller opløsning på devices. Hvor mange udviklere bruger tid på at resize op/ned for at se at ting flyder som de skal, at der ikke sker ting som skjuler data eller lign.?

Pelle Söderling

Der er rigtig mange områder indenfor vores fag som der kunne sættes fokus på og jeg er helt enig i at især skalering er overset.

Men jeg synes det giver god mening at kigge på hvad det er der koster mest tid og tage fat der og umiddelbart er jeg ret enig i at dette pt. er debugging som rigtig mange - både studerende, men også professionelle - bruger ALT for meget tid på.

Der er noget alvorligt galt når folk bruger mere tid på debugging end på udvikling.

Michael Zedeler

Jeg vil til dels give Pelle ret. Man bruger kun rigtig meget tid på debugging når kodens design er defekt. Hvis man ser på debugging i et bredere perspektiv så handler det om at verificere at koden gør, som man forventer. Et led i den proces er at man sikrer sig at det underliggende design tillader effektiv fejlsøgning. Hvis det ikke er tilfældet, er det i sig selv grund nok til at skrive koden om før man overhovedet fortsætter.

Stort set hver gang jeg har brugt mange ressourcer på at omskrive kode, har det været med det hovedformål at at simplificere og generalisere, så det bliver enklere at forudsige hvordan systemet opfører sig. I de konkrete situationer har debugging før omskrivningen været fuldstændig håbløst (f. eks. scripts på 10.000 linier med 20-30 funktioner som kalder hinanden på kryds og tværs og udelukkende benytter globale variable - ja - den slags findes derude).

I særdeleshed er jeg bekymret når det gælder idéen med at bruge avancerede debuggere, for hvis man endelig har brug for sådan en, er koden med stor sandsynlighed blevet så kompleks at den er for omkostningstung at vedligeholde.

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.", Brian W. Kerninghan.

Det betyder omvendt at jo mere af arbejdet med at fejlsøge du kan løse igennem simpelt design, jo mere frihed er der til at lave avanceret kode :)

Jakob Rosenkrantz de Lasson

Jeg er ikke software ingeniør, men har i flere år arbejdet med at kode og programmere for at lave simuleringer inden for fysikken - og jeg har brugt helt afsindigt meget tid på at debugge! I nogle situationer har jeg brugt mere tid på at lokalisere og rette banale og subtile fejl i koden, før den kom til at virke, som det var hensigten. Jeg tænker hver gang over, hvad jeg gjorde i min debugging, og hvordan jeg kan bruge det næste gang, jeg skal debugge et stykke kode.

Mine erfaringer skrev jeg tidligere i år om på ing.dk: http://ing.dk/blog/den-noble-kunst-debugge-157225

(hvilket i øvrigt også kom med i den printede udgave af Ingeniøren: http://www.jakobrdl.dk/misc/IngBlog_Mar2013.pdf)

Ivan Johansen

Det er meget muligt at problemet er at koden er skrevet dårligt og designet er forkert og den rigtige løsning er ikke at lave nogen fejl. Det hjælper mig bare ikke ret meget når jeg er sat til at rette fejl #1234 i noget kode som er skrevet af en der ikke længere er ansat.

Men som Kim Hansen skriver er der mange andre ting jeg også godt kunne savne på uddannelsen. Men der er jo grænser for hvor meget der er plads til. Jeg er dog sikker på at det vil være en god ting at vænne eleverne til at bruge versionsstyring under uddannelsen. Gode vaner skal startes tidligt.

Skalering går for øvrigt begge veje. Jeg har aldrig arbejdet med store systemer, men jeg har set folk der ikke var i stand til at få noget til at køre på en processor med 4 kB RAM fordi de kun var vandt til at bruge Java på en PC.

Jesper Louis Andersen

Men er problemet ikke vendt på hovedet? Deres studerende laver for ringe kode, og derfor sidder de og fedter i en debugger. Burde de ikke heller undervise dem i at lave noget ordenlig kode, og skrive gode tests? Forbyggelse er altså, også i softwareudvikling, langt at foretrække, fremfor behandling.

Der er helt klart en snert af rigtighed i det udsagn Nikolaj bringer her. Velgennemtestet kode der har fornuftig specifikation er typisk lang mere fejlfri end kode der er skrevet som noget klyt patch på patch. Men virkeligheden er også den at det meste kode der bliver skrevet ikke er af den kvalitet. Så du skal have færdigheder i at kunne finde fejl i eksisterende kode.

Det er meget sjældent jeg selv bruger debuggere. Som oftest stirrer jeg bare på koden indtil jeg regner ud hvad der går galt. Men bemærk at jeg som oftest skriver i funktionelle sprog og derfor ikke har state at bekymre mig om i samme grad. Og at jeg derfor nemmere kan teste ting. Den anden ting er at det ikke er ualmindeligt at vi har 100.000 samtidige (concurrent) aktiviteter, så debugging af en enkelt af disse er sjældent problemet. Det er ofte samspillet mellem processer der skaber problemerne. Og hvis du smækker debuggeren på en process, så kører de andre videre.

Nikolaj Brinch Jørgensen

Jeg ved ikke om du er naiv eller du troller?


Jeg tror udemærket du forstår hvad jeg mener. Læg vægt på at lære de studerende programmere, design og at kompleksitet er ondt - lav simple løsninger (simpel != let).

Det tror jeg personligt, er langt bedre, og burde på længere sigt nedsætte behovet for debugging. Altså forebyggelse fremfor diagnostik og behandling.

Så ved jeg godt at debuggeren er nødvendig i mange sammenhænge. Men jeg ser alt for ofte at folk udvikler i debuggeren, hvilket ofte leder til tunnel-vision løsninger med en helt masse if-sætninger der prøver at fikse en bestemt tilstand (for det er jo det debuggeren belyser - altså tilstand). For det meste er koden jo ude af trit med det verdensbillede den skal beskrive, fordi de antagelser der ligger til grund for koden, enten aldrig har været korrekte, eller fordi verdensbilledet har ændret sig.
Mange gange er helikopteren et bedre værktøj end en lup. Alt for meget tid bliver brugt på ligegyldig optimering og debugging af løsninger der er arkitektonisk og designmæssigt skruet helt forkert sammen.

Jeg håber du forstår hvad jeg mener? Debuggeren er et godt værktøj, brugt korrekt. Men det er samtidigt et enormt farligt værktøj brugt forkert. Derfor er jeg meget ambivalent ved brug af den.

Nikolaj Brinch Jørgensen

Du er naiv. Du forstår ikke konceptet kompleksitet.

Du er en fejl. Debug dig selv, og kom tilbage når du er rettet.

Lav beregningerne. Se hvordan kompleksiteten stiger eksponentielt, ved selv de mindste logiske konstruktioner i dit ligegyldige lille program.

Så smid dine uendelige ligegyldige små eksponentielle tal ind i en virksomheds +-100000 programmer. Derefter lig dig ned og græd, og indse at din eksistens er ligegyldig, at du altid vil fejle, og at dine drømme om perfektion er en digital drøm i en ond, ond verden af kode der fucking hader din sjæl.

Lav hellere sort magi. Du forstår det ikke, men det virker, hvis du tilbeder de onde kræfter nok, og forbered dig til debug helvede. Vi har kaffe og uendelig tålmodighed hernede.


Uha det var en smøre (det er dog ikke mig der har downvoted dit indlæg - for jeg kan som sådan godt lide modspil).
Men jeg tror du misser pointen. Mange IT uddannelser misser totalt at lærer de studerende at skrive ordenlig kode, tests mm. Der starter problemet og det øger behovet for en debugger.
Vi kan ikke komme af med debuggeren, og den er nødvendig. Men det er altså bagsiden af en lægtehammer, som er til at rive bøjede søm op med, og kræfterne skal bruges på at lære at slå søm rigtig i.
Hvis alt for meget byggesjusk er lavet, så henter vi et nedrivningsfirma og bygger derefter noget nyt, med nogle ordenlige håndværkere.

Jeg er usikker på om du selv helt har forstået kompleksitet. Kompleksitet er ofte det man ender med når man vælger den lette vej fremfor den simple vej. Simpel er svært.

Pelle Söderling

Jamen det har jeg ikke noget problem med :)

Jeg har set alt for mange der sidder og bruger timer på at indsætte clever breakpoints i deres kode og steppe igennem og tjekke tilstande osv. til de er helt rundtossede - hvor en simpel omgang "printf"s ville have eksponeret problemet på under 5 minutter.

Desuden virker de kun rigtig til at løse simple problemer i single-threaded kode - disse problemer må aldrig tage timer at løse, så er det fordi man gør det forkert.

Med andre ord mener jeg visuelle debuggere i høj grad opfordrer til at gøre det forkert og slut resultatet er en masse waste of time.

Nikolaj Brinch Jørgensen
Pelle Söderling

Skal siges at jeg kan sagtens finde på at bruge debuggere såsom WinDBG/GDB til produktions- eller crash-debugging eller profilere til at tjekke for memory-leaks og CPU forbrug. Eller hvis det er managed kode problemer med evt. GC generations, GC afviklinger og lign.

Men det der med at sidde og steppe igennem ens kode, det giver jeg ikke meget for.

Lars Lundin

selv de bedste udviklere bruger tid på debugging - jo højere niveau man opnår, jo mere komplicerede løsninger er man i stand til at kreere og sålænge man pusher sine evner - hvilket vi vel alle synes er sjovest - så er der altid en hvis risiko for at man begår nogle fejl undervejs.

Om debugging og denne balance mellem at skrive enkel kode og samtidigt udfordre sine evner skriver Brian Kernighan:

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?”

Pelle Söderling

Om debugging og denne balance mellem at skrive enkel kode og samtidigt udfordre sine evner skriver Brian Kernighan:

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?”

Det citat er dukket op en del gange på det seneste herinde og jeg er egentlig ret enig i opfordringen om at skrive kode simpel, læse- og vedligeholsesvenlig.
Men i min verden er det en langt større udfordring at løse komplekse problemer med simpel kode fremfor kompleks kode, så for mig er der ikke et modsætningsforhold her i forhold til at udfordre evner :-)

Når det er sagt så er jeg heller ikke helt enig i citatet, for mig er det værste man kan gøre når man forsøger at debugge noget at læse og forsøge at forstå hvad der sker - det ender i gætværk og gætværk fører sjældent noget godt med sig i debugging sammenhæng. For mig handler debugging i høj grad om at tjekke tilstandsændringer under afvikling og tjekke hvad der bliver afviklet, ofte som en slags manuel "binær søgning" hvor man indskrænker problemet indtil man har den linie eller funktion hvor det går galt. Vel og mærke uden at forsøge at lave antagelser om hvad der sker og ikke sker i koden og dermed uden at forsøge at forstå koden for meget.

Ergo kan man sagtens debugge sig frem til problemer i "clever" kode, men en ting er selvfølgelig at finde det problematiske kode, noget andet er at løse problemet.

Mikkel Krøigård

Jeg synes det virker lidt tænkt med de historier om folk, der bruger timevis på møjsommeligt at placere de rigtige breakpoints. Hvis man har lært at debugge og har sat sit projekt rigtigt op, så man kan komme hurtigt igang med at debugge, kan man ofte løse nogle trælse problemer på få minutter. Jeg har masser af succeshistorier med debuggere, hvor jeg har netop har fundet og rettet en fejl på 5-10 minutter. Ja, det er sværere med flertrådede programmer, men det er bestemt ikke umuligt.

Jeg har det også lidt svært med med påstanden om, at visuelle debuggere skulle opfordre til at gøre det forkert, mens man kan løse tingene hurtigt med printf. Jeg har erfaret netop det modsatte.

Mogens Hansen

Jeg har set alt for mange der sidder og bruger timer på at indsætte clever breakpoints i deres kode og steppe igennem og tjekke tilstande osv. til de er helt rundtossede - hvor en simpel omgang "printf"s ville have eksponeret problemet på under 5 minutter.

Øh, hvordan er den ene metode debugging og den anden ikke? Uanset om du sætter et breakpoint med watches eller skriver printfs, så gør du det for at lære noget om state af nogle variable på et givet tidspunkt.

(i øvrigt køber jeg ikke den der med "simple printfs". Hvor mange gange har dine debug-printf's måttet omskrives fordi du brugte den forkerte formatering? Hvor ofte har du glemt at fjerne dem fra koden igen, inden den gik videre i produktionen?)

Jakub Nielsen

om debugging? det skal de nok lære hurtigt. Det er noget de kan lære enten på uddannelsen, hvor de skal lære at programmere multi-trådet med videre eller når de starter på et team, hvor man hjælper hinanden.
om at indgå i et team, som skal løfte ikke-vel-specificeret opgaver? ja, mange mange færdig uddannede er elendige når de kommer ud. De spørger f.eks. ikke efter hjælp men render i en forkert retning med deres kode. De kan ikke kommunikere med forretningen. Og så videre. Problemet er blot, at de kan de nok ikke lære på et universitet men skal i stedet lære det via "on the job training".
skalering? Generelt, Software Quality Attributes og hvordan du opnår det i arkitektur, design og kode? helt klart, det mangler de.
Sikker kode? helt klart. Jeg oplever mange udviklere, specielt nyuddannede, som ikke aner en bjælde om hvordan de skal angribe sikkerhed. Det kommer typisk med erfaringen og når de bliver udsat for audits.
...

Eller sagt på en anden måde: præmissen om, at studerende mangler mere viden om debugging er sand - det samme er en præmis om mange andre aspekter af udvikling. Svarende til hvad venner som er læge kan fortælle dig: nyuddannede læger er elendige når de kommer ud på hospitalet og afhænger af afdelingens chef sygeplejerske for at lære virkeligheden at kende. Pointen er, at hvis de får de nødvendige redskaber til at tænke logisk, til at bryde opgaver ned, til at strukturere til din kode og principper som SOLID så skal du nok kunne lære det sidste. Også at debugge - jeg har endnu ikke mødt en som ikke lære det hurtigt.

Lars Lundin

Hvor mange gange har dine debug-printf's måttet omskrives fordi du brugte den forkerte formatering? Hvor ofte har du glemt at fjerne dem fra koden igen, inden den gik videre i produktionen?

1) Til debugging med printf() bør man bruge konstante format-strenge (string literals), herefter kan compileren advare om format-fejl, f.eks. med
gcc -Wall
(som aktiverer -Wformat).
2) Disse printf() bør oversættes på betingelse af at makroen NDEBUG ikke er defineret, altså #ifndef NDEBUG. Kode der i produktion ikke laver den slags I/O kan med fordel også nøjes med at inkludere stdio.h, når NDEBUG ikke er defineret.

Iøvrigt synes jeg det er imponerende hvad gdb med årene har udviklet sig til at kunne.

Pelle Söderling

Mogens: En væsentlig ting når man omtaler "printf" debugging er at det er sjældent man kalder "printf", "System.out/err.println", "Console.WriteLine" etc. direkte i praksis.

Normalt har man en utility-metode til formålet hvor man kan redirecte outputtet hen hvor man vil - det kunne f.eks. være til konsollen, men det kunne også være til en fil eller til et program ala Sysinternals DebugView. Det er også normalt at indkapsle indholdet heri med et preprocessor statement der sikrer at det kun afvikles i debug mode.
Desuden har jeg også nogle options her der gør jeg kan enable automatisk prepending af ting såsom timestamp, threadid og tid i ms siden afvikling af sidste debug statement hvis det er relevant.

Når du bruger "printf" debugging korrekt så får du et bredere og bredere overblik over staten for hver afvikling og en afvikling går normalt så hurtigt i de fleste scenarier at du har din info efter få sekunder (og langsomme afviklinger er trælse at debugge uanset metode). Når du bruger en visuel debugger og stepper dig igennem koden så skal du i højere grad holde styr på historiske state-ændringer i hovedet og du skal gøre det for hver afvikling (hvad du så i en afvikling er ikke nødvendigvis sandt i næste) og det tager tid at steppe dig igennem for at få informationen. Ved "printf" løsningen tager du tidshittet upfront da der skal indføres lidt linjer rundt omkring, men tilgengæld går selve debuggingen ekstremt hurtig fordi du får dit output med det samme. Ved visuel debugging har du ikke noget upfront hit, men tilgengæld går det at tracke state ændringer langsomt og det er svært at få et overblik fordi du bare graver dig ind et eller andet sted i koden og begynder at steppe. Jeg vover at påstå at "upfront" costen ved "printf" debugging altid kan svare sig. Jeg er helt med på der er cases der kan være hurtigere i en visuel debugger, men i sagens natur ved du det somregel ikke på forhånd og omvendt kan visuel debugging gå ekstremt langsomt når tingene ikke er så obvious - set over en bred kam er det min klare erfaring at det ikke er det værd.

Visual Studio understøtter i Ultimate udgaven noget der hedder IntelliTrace der giver dig mulighed for at se historisk state, men ærlig talt er det total overkill når man nu engang kan løse det problem langt simplere.

"printf" debugging har den store fordel at det virker til alle formål, i alle sprog, på alle platforme og uafhængigt af IDE og de teknikker man lærer sig selv her kan ligeledes bruges på tværs af alt og det er kun dig selv der sætter begrænsningerne (ikke hvad der er understøttet i en evt. debugger) - derfor mener jeg det er klart den mest powerfulde måde at debugge på. Selvom jeg er sikker på "de unge" sikkert vil synes man er et gammelt kvaj hvis man ikke udnytter mulighederne i moderne IDEs.

Det ser ud til at Peter Makholm har et indlæg om ligepræcis denne form for debugging, hvis du har mulighed for det vil det formentlig være en god demonstration - det er svært at diskutere debugging teknikker på tekst, det er meget mere effektivt at demonstrere det.

Mikkel Krøigård

Det er vel et spørgsmål om at bruge de redskaber, der er til rådighed. Jeg har ikke noget imod, hvad I netop har beskrevet (lyder som trace logging), men samtidig er det lige voldsomt nok at skrive al tilstand ud hele tiden. Min erfaring er, at man kan få meget ud af debugging, og derfor har jeg svært ved at acceptere, at det skulle være spild af tid. Det betyder ikke, at jeg hader trace logging. Hvis man er god til debugging, er man vel netop i stand til at vælge den bedste metode i en given situation uden at skulle afvise noget af religiøse årsager.

Log ind eller Opret konto for at kommentere