Skal vi kode 'Bum' til jobsamtalen?
Det skulle efter sigende være svært at finde nok uddannede programmører til at imødekomme efterspørgslen. Derfor er det nærliggende at prøve at rekruttere dem, der ikke har et eksamensbevis, men er selvlærte og har talent.
Men hvordan finder man ud af, om sådan en selvlært programmør kan kode?
Især i USA kan en begynderstilling som juniorudvikler være særdeles velbetalt i forhold til de fleste andre jobs. Derfor er det oplagt, at der vil være folk helt uden færdigheder, som prøver at få foden indenfor.
I 2007 foreslog en britisk softwareudvikler en simpel test. En ansøger skulle demonstrere sine programmeringsfærdigheder ved at skrive et program med inspiration fra børnelegen 'Bum', eller på engelsk 'FizzBuzz'.
Bum er en leg i skolen, som bruges til at lære om multiplikation og division. Man vælger eksempelvis 3-tabellen, og man skiftes derefter til at tælle op fra 1, og hver gang man kommer til et tal, som 3 går op i, siger man 'bum' i stedet for tallet. Man kan øge sværhedsgraden ved at have flere tabeller i spil på samme tid.
Den oprindelige formulering af spørgsmålet til jobansøgeren lød:
Write a program that prints the numbers from 1 to 100. But for multiples of three print 'Fizz' instead of the number and for the multiples of five print 'Buzz'. For numbers which are multiples of both three and five print 'FizzBuzz'.
Det er en meget enkel øvelse, der lettest løses med en for-løkke og tre if-statements, og samtidig kan vise, at udvikleren kender til modulus og har sin grundlæggende algebra på plads.
function FizzBuzz() { for (i = 1; i <= 100; i++) { if (i % 3 == 0 && i % 5 == 0) { console.log("FizzBuzz"); } else if (i % 3 == 0 && i % 5 != 0) { console.log("Fizz"); } else if (i % 3 != 0 && i % 5 == 0) { console.log("Buzz"); } else { console.log(i); } } }
Men det er også en øvelse, som let kan få øvede programmører til at falde i en fælde, hvor de ganske vist løser opgaven, men gør det på en måde, der ikke er hensigtsmæssig i alle udviklerjob.
På denne side kan man finde forskellige løsninger af FizzBuzz. De er interessante, fordi de viser forskelle mellem programmeringssprog, men de viser også problemer med at skrive brugbar og især læsbar kode.
Eksempelvis er det muligt at lave et enkelt check på modulus 15 i stedet for både at tjekke modulus 3 og modulus 5. Det virker som en god idé at løse opgaven på denne måde, fordi man kan fjerne et check, og man viser matematisk forståelse.
Men det er også en løsning, som øger afstanden mellem den oprindelige kravspecifikation og koden.
Sammenhængen mellem 3, 5 og 15 er ikke umiddelbar uden en kommentar i koden. Den enkle, ligefremme løsning indeholder et ekstra check, men er til gengæld en direkte oversættelse af kravene.
Er Fizz + Buzz det samme som FizzBuzz?
Der er også flere eksempler på, hvordan FizzBuzz kan løses i en enkelt kodelinje, eller ved at tjekke længden af en streng i stedet for at tjekke selve tallet. Det fører igen til kode, der fjerner sig fra beskrivelsen af problemet.
To eksempler i Python hentet fra linket oven for:
python -c "print '\n'.join(['Fizz'*(x % 3 == 2) + 'Buzz'*(x % 5 == 4) or str(x + 1) for x in range(100)])" # # Eller: # for i in xrange(0,101): s = "" if i % 3 == 0: s += "Fizz" if i % 5 == 0: s += "Buzz" print s if len(s) else i
Løsninger, hvor man opbygger en streng ved at tilføje eventuelt tomme strenge for hvert tjek, gør sig desuden skyldige i at antage, at 'Fizz' + 'Buzz' er det samme som 'FizzBuzz'. Det giver et korrekt output i den konkrete opgave, men udvikleren har fortolket opgaven for at kunne lave en bestemt løsning og dermed introduceret en potentiel fejlkilde.
Hvad er kravene - og hvad er optimering?
Kompakt kode kan være en elegant øvelse, men langt det meste kode, en udvikler skal skrive, skal blot opfylde de udstukne specifikationer og være til at teste og vedligeholde. Her kan det være væsentligt at prioritere læsbarhed højt.
Som udvikler bør man derfor være bevidst om opgaven. Hvis opgaven i stedet gik ud på, at man fik udleveret en FizzBuzz-implementering og blev bedt om at gøre den mere effektiv, så ville det være en god løsning at reducere antallet af check.
I min simple implementering ville det eksempelvis være en god optimering at starte med at ændre koden, så det hyppigst forekommende udfald er det, der bliver tjekket for først, hver gang løkken gennemløbes.
function FastFizzBuzz() { for (i = 1; i <= 100; i++) { if (i % 3 != 0 && i % 5 != 0) { console.log(i); } else if (i % 3 == 0 && i % 5 != 0) { console.log("Fizz"); } else if (i % 3 != 0 && i % 5 == 0) { console.log("Buzz"); } else { console.log("FizzBuzz"); } } }
En optimering bør ikke måles i antal kodelinjer, men snarere i forhold til hvordan koden gennemløbes, da det er dét, der vil give en reel forbedring.
Hvordan skal outputtet printes?
I den oprindelige formulering af FizzBuzz-spørgsmålet er der så et lille problem, som en dygtig udvikler i det mindste burde påpege. Outputtet er blot defineret som at printe tal og tekst, men det er ikke klart specificeret, hvordan det skal gøres.
Der er således forskellige løsninger, hvor outputtet printes som:
1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz ... // Eller: 12Fizz4BuzzFizz78FizzBuzz ... // Eller: 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz ...
Alle er gyldige løsninger, men de er også forskellige output. En god programmør burde bemærke i sit svar, at formatet for outputtet ikke er nærmere specificeret.
Bum-legen er ganske vist kun beregnet til at sikre sig, at en jobansøger kan finde ud af for-løkker og if-statements, men der ligger også en implicit test af ansøgerens evne til at fokusere på den givne opgave og være bevidst om sin fortolkning af de krav, opgaven definerer.
Softwareudvikling handler nemlig ikke kun om algoritmer. For mange er det en vigtigere del af arbejdet at kunne tage en beskrivelse af en arbejdsproces og omsætte den til funktioner, der korrekt udfører processen i programmet hver gang.
Så spørgsmålet er, om en test som FizzBuzz er egnet til at teste en uøvet programmørs evner, eller om der er andre egenskaber end simpelt algoritmedesign, der faktisk er vigtigere at teste for, inden man sætter en programmør foran tasterne.

...men det er dyrt at lave god journalistik. Derfor beder vi dig overveje at tegne abonnement på Version2.
Digitaliseringen buldrer derudaf, og it-folkene tegner fremtidens Danmark. Derfor er det vigtigere end nogensinde med et kvalificeret bud på, hvordan it bedst kan være med til at udvikle det danske samfund og erhvervsliv.
Og der har aldrig været mere akut brug for en kritisk vagthund, der råber op, når der tages forkerte it-beslutninger.
Den rolle har Version2 indtaget siden 2006 - og det bliver vi ved med.