De mest pinlige fejl i min programmeringskarriere (indtil videre)

De mest pinlige fejl i min programmeringskarriere (indtil videre)
Som de siger, hvis du ikke skammer dig over din gamle kode, så vokser du ikke som programmør - og jeg er enig i denne udtalelse. Jeg begyndte at programmere for sjov for over 40 år siden, og professionelt for 30 år siden, så jeg har mange fejl. meget meget. Som professor i datalogi lærer jeg mine elever at lære af fejl – deres, mine og andres. Jeg synes, det er på tide at tale om mine fejltagelser for ikke at miste min beskedenhed. Jeg håber, de vil være nyttige for nogen.

Tredjeplads - Microsoft C compiler

Min skolelærer mente, at Romeo og Julie ikke kunne betragtes som en tragedie, fordi karaktererne ikke havde nogen tragisk skyldfølelse – de opførte sig simpelthen dumt, som teenagere burde. Jeg var ikke enig med ham dengang, men nu ser jeg et gran af rationalitet efter hans mening, især i forbindelse med programmering.

Da jeg afsluttede mit andet år på MIT, var jeg ung og uerfaren, både i livet og i programmering. Om sommeren arbejdede jeg hos Microsoft, på C-compiler-teamet. Først lavede jeg rutinemæssige ting som profileringssupport, og derefter blev jeg betroet at arbejde med den sjoveste del af compileren (som jeg troede) - backend-optimering. Især var jeg nødt til at forbedre x86-koden til branch-udsagn.

Fast besluttet på at skrive den optimale maskinkode til alle mulige tilfælde, kastede jeg mig hovedkuls i poolen. Hvis fordelingstætheden af ​​værdier var høj, indgik jeg dem overgangstabel. Hvis de havde en fælles divisor, brugte jeg den til at gøre bordet strammere (men kun hvis opdelingen kunne udføres vha. bitskifte). Da alle værdierne var to potenser, lavede jeg endnu en optimering. Hvis et sæt værdier ikke opfyldte mine betingelser, opdelte jeg det i flere optimerbare tilfælde og brugte den allerede optimerede kode.

Det var et mareridt. Mange år senere fik jeg at vide, at programmøren, der arvede min kode, hadede mig.

De mest pinlige fejl i min programmeringskarriere (indtil videre)

Lektion lært

Som David Patterson og John Hennessy skriver i Computer Architecture and Computer Systems Design, er et af hovedprincipperne for arkitektur og design generelt at få tingene til at fungere så hurtigt som muligt.

At fremskynde almindelige tilfælde vil forbedre ydeevnen mere effektivt end at optimere sjældne tilfælde. Ironisk nok er almindelige tilfælde ofte enklere end sjældne. Dette logiske råd forudsætter, at du ved, hvilket tilfælde der anses for almindeligt – og dette er kun muligt gennem en proces med omhyggelig test og måling.

Til mit forsvar forsøgte jeg at finde ud af, hvordan brancheudsagn så ud i praksis (såsom hvor mange grene der var, og hvordan konstanter var fordelt), men i 1988 var denne information ikke tilgængelig. Jeg skulle dog ikke have tilføjet særlige tilfælde, når den nuværende compiler ikke kunne generere optimal kode til det kunstige eksempel, jeg kom med.

Jeg havde brug for at ringe til en erfaren udvikler og sammen med ham tænke over, hvad de almindelige sager var, og behandle dem specifikt. Jeg ville skrive mindre kode, men det er en god ting. Som Stack Overflow-grundlæggeren Jeff Atwood skrev, er en programmørs værste fjende programmøren selv:

Jeg ved, at du har de bedste intentioner, ligesom vi alle har. Vi laver programmer og elsker at skrive kode. Det er sådan, vi er skabt. Vi tror, ​​at ethvert problem kan løses med gaffatape, en hjemmelavet krykke og en knivspids kode. Så meget som det piner kodere at indrømme det, den bedste kode er den kode, der ikke eksisterer. Hver ny linje har brug for fejlfinding og support, den skal forstås. Når du tilføjer ny kode, bør du gøre det med modvilje og afsky, fordi alle andre muligheder er udtømt. Mange programmører skriver for meget kode, hvilket gør det til vores fjende.

Hvis jeg havde skrevet enklere kode, der dækkede almindelige sager, ville det have været meget nemmere at opdatere, hvis det var nødvendigt. Jeg efterlod et rod, som ingen ønskede at håndtere.

De mest pinlige fejl i min programmeringskarriere (indtil videre)

Andenplads: annoncering på sociale netværk

Da jeg arbejdede hos Google med annoncering på sociale medier (kan du huske Myspace?), skrev jeg sådan noget i C++:

for (int i = 0; i < user->interests->length(); i++) {
  for (int j = 0; j < user->interests(i)->keywords.length(); j++) {
      keywords->add(user->interests(i)->keywords(i)) {
  }
}

Programmører kan straks se fejlen: det sidste argument skal være j, ikke i. Enhedstest afslørede ikke fejlen, og det gjorde min anmelder heller ikke. Lanceringen blev gennemført, og en nat gik min kode til serveren og crashede alle computere i datacentret.

Der skete ikke noget dårligt. Intet gik i stykker for nogen, for før den globale lancering blev koden testet i ét datacenter. Medmindre SRE-ingeniører holdt op med at spille billard i et stykke tid og lavede en lille tilbagerulning. Næste morgen modtog jeg en e-mail med et crash-dump, rettede koden og tilføjede enhedstests, der ville fange fejlen. Da jeg fulgte protokollen - ellers ville min kode simpelthen ikke køre - var der ingen andre problemer.

De mest pinlige fejl i min programmeringskarriere (indtil videre)

Lektion lært

Mange er sikre på, at en så stor fejl helt sikkert vil koste den skyldige afskedigelse, men det er ikke tilfældet: For det første laver alle programmører fejl, og for det andet laver de sjældent den samme fejl to gange.

Faktisk har jeg en programmørven, som var en genial ingeniør og blev fyret for at lave en enkelt fejl. Derefter blev han ansat hos Google (og snart forfremmet) - han talte ærligt om den fejl, han begik i et interview, og det blev ikke betragtet som fatalt.

Her er hvad fortælle om Thomas Watson, den legendariske leder af IBM:

En regeringsordre til en værdi af omkring en million dollars blev annonceret. IBM Corporation - eller rettere sagt Thomas Watson Sr. personligt - ønskede virkelig at få det. Desværre var salgsrepræsentanten ikke i stand til at gøre dette, og IBM tabte buddet. Den næste dag kom denne medarbejder ind på Mr. Watsons kontor og lagde en konvolut på hans skrivebord. Mr. Watson gad ikke engang se på det – han ventede på en medarbejder og vidste, at det var et opsigelsesbrev.

Watson spurgte, hvad der gik galt.

Sælgeren fortalte detaljeret om udbudsforløbet. Han nævnte fejl, der kunne have været undgået. Til sidst sagde han: "Mr. Watson, tak fordi du lod mig forklare. Jeg ved, hvor meget vi havde brug for denne ordre. Jeg ved, hvor vigtig han var,” og gjorde sig klar til at tage af sted.

Watson nærmede sig ham ved døren, så ham i øjnene og returnerede konvolutten med ordene: "Hvordan kan jeg lade dig gå? Jeg har lige investeret en million dollars i din uddannelse.

Jeg har en T-shirt, hvor der står: "Hvis du virkelig lærer af fejl, så er jeg allerede en mester." Faktisk, når det kommer til fejl, er jeg en doktor i videnskab.

Førstepladsen: App Inventor API

Virkelig forfærdelige fejl påvirker et stort antal brugere, bliver offentligt kendt, tager lang tid at rette, og er lavet af dem, der ikke kunne have lavet dem. Min største fejl passer til alle disse kriterier.

Jo værre jo bedre

jeg læser essay af Richard Gabriel om denne tilgang i halvfemserne som kandidatstuderende, og jeg holder så meget af det, at jeg spørger mine studerende om det. Hvis du ikke husker det godt, så genopfrisk din hukommelse, den er lille. Dette essay kontrasterer ønsket om at "få det rigtigt" og "værre er bedre"-tilgangen på mange måder, herunder enkelhed.

Sådan skal det være: designet skal være enkelt i implementering og interface. Enkelheden af ​​grænsefladen er vigtigere end enkelheden i implementeringen.

Jo værre, jo bedre: designet skal være enkelt i implementering og interface. Enkelhed af implementering er vigtigere end enkelhed af grænsefladen.

Lad os glemme det et øjeblik. Desværre har jeg glemt det i mange år.

App opfinder

Mens jeg arbejdede hos Google, var jeg en del af teamet App opfinder, et træk-og-slip online udviklingsmiljø for håbefulde Android-udviklere. Det var 2009, og vi havde travlt med at udgive alfaversionen i tide, så vi om sommeren kunne holde master classes for lærere, der kunne bruge miljøet, når de underviste om efteråret. Jeg meldte mig frivilligt til at implementere sprites, nostalgisk over, hvordan jeg plejede at skrive spil på TI-99/4. For dem, der ikke ved det, er en sprite et todimensionelt grafisk objekt, der kan bevæge sig og interagere med andre softwareelementer. Eksempler på sprites omfatter rumskibe, asteroider, kugler og ketsjere.

Vi implementerede objektorienteret App Inventor i Java, så der er bare en masse objekter derinde. Da bolde og sprites opfører sig meget ens, har jeg lavet en abstrakt sprite-klasse med egenskaber (felter) X, Y, Speed ​​​​(hastighed) og Heading (retning). De havde de samme metoder til at detektere kollisioner, hoppe af kanten af ​​skærmen osv.

Den største forskel mellem en bold og en sprite er, hvad der præcist er tegnet - en udfyldt cirkel eller et raster. Da jeg implementerede sprites først, var det logisk at specificere x- og y-koordinaterne for det øverste venstre hjørne af det sted, hvor billedet var placeret.

De mest pinlige fejl i min programmeringskarriere (indtil videre)
Da sprites virkede, besluttede jeg, at jeg kunne implementere kugleobjekter med meget lidt kode. Det eneste problem var, at jeg tog den enkleste rute (set fra implementerens synspunkt), idet jeg angiver x- og y-koordinaterne i det øverste venstre hjørne af konturen, der indrammer bolden.

De mest pinlige fejl i min programmeringskarriere (indtil videre)
Faktisk var det nødvendigt at angive x- og y-koordinaterne for midten af ​​cirklen, som det er undervist i enhver matematik lærebog og enhver anden kilde, der nævner cirkler.

De mest pinlige fejl i min programmeringskarriere (indtil videre)
I modsætning til mine tidligere fejl, påvirkede denne ikke kun mine kolleger, men også millioner af App Inventor-brugere. Mange af dem var børn eller helt nye til programmering. De skulle udføre en masse unødvendige trin, når de arbejdede på hver applikation, hvor bolden var til stede. Hvis jeg husker mine andre fejltagelser med grin, så får den her mig til at svede selv i dag.

Jeg fik endelig rettet denne fejl først for nylig, ti år senere. "Patched", ikke "fixed", for som Joshua Bloch siger, API'er er evige. Ude af stand til at foretage ændringer, der ville påvirke eksisterende programmer, tilføjede vi OriginAtCenter-egenskaben med værdien falsk i gamle programmer og sand i alle fremtidige. Brugere kan stille et logisk spørgsmål: hvem har overhovedet tænkt på at placere udgangspunktet et andet sted end centrum. Til hvem? Til en programmør, der var for doven til at lave en normal API for ti år siden.

Erfaringer

Når du arbejder på API'er (hvilket næsten enhver programmør nogle gange skal gøre), bør du følge de bedste råd, der er beskrevet i Joshua Blochs video "Hvordan man laver en god API, og hvorfor det er så vigtigt"eller i denne korte liste:

  • En API kan give dig både stor fordel og stor skade.. En god API skaber tilbagevendende kunder. Den dårlige bliver dit evige mareridt.
  • Offentlige API'er, som diamanter, varer evigt. Giv det hele: Der vil aldrig være en chance for at gøre alt rigtigt.
  • API-oversigter skal være korte — én side med klasse- og metodesignaturer og beskrivelser, der ikke fylder mere end en linje. Dette giver dig mulighed for nemt at omstrukturere API'en, hvis den ikke bliver perfekt første gang.
  • Beskriv use casesfør du implementerer API'en eller endda arbejder på dens specifikation. På denne måde undgår du at implementere og specificere en fuldstændig ikke-funktionel API.

Hvis jeg havde skrevet selv en kort synopsis med et kunstigt script, ville jeg højst sandsynligt have identificeret fejlen og rettet den. Hvis ikke, så ville en af ​​mine kolleger helt sikkert gøre det. Enhver beslutning, der har vidtrækkende konsekvenser, skal overvejes i mindst en dag (dette gælder ikke kun programmering).

Titlen på Richard Gabriels essay, "Worse Is Better", refererer til den fordel, der er ved at være den første på markedet – selv med et uperfekt produkt – mens en anden bruger en evighed på at jagte det perfekte. Når jeg reflekterer over sprite-koden, indser jeg, at jeg ikke engang behøvede at skrive mere kode for at få det rigtigt. Uanset hvad man kan sige, så tog jeg groft fejl.

Konklusion

Programmører begår fejl hver dag, uanset om det er at skrive buggy-kode eller ikke ønsker at prøve noget, der vil forbedre deres færdigheder og produktivitet. Selvfølgelig kan du være programmør uden at begå så alvorlige fejl, som jeg gjorde. Men det er umuligt at blive en god programmør uden at erkende dine fejl og lære af dem.

Jeg støder konstant på elever, der føler, at de laver for mange fejl og derfor ikke er skåret ud til at programmere. Jeg ved, hvor almindeligt bedragersyndrom er inden for IT. Jeg håber, du vil lære de lektier, jeg har nævnt - men husk den vigtigste: hver af os laver fejl - pinligt, sjovt, forfærdeligt. Jeg vil blive overrasket og ked af det, hvis jeg i fremtiden ikke har nok materiale til at fortsætte artiklen.

Kilde: www.habr.com

Tilføj en kommentar