Nejtrapnější chyby v mé programátorské kariéře (zatím)

Nejtrapnější chyby v mé programátorské kariéře (zatím)
Jak se říká, pokud se nestydíte za svůj starý kód, pak jako programátor nerostete – a já s tímto názorem souhlasím. Začal jsem programovat pro zábavu před více než 40 lety a profesionálně před 30 lety, takže mám spoustu chyb. velmi. Jako profesor informatiky učím své studenty učit se z chyb – jejich, mých i jiných. Myslím, že je čas mluvit o svých chybách, abych neztratil svou skromnost. Doufám, že se budou někomu hodit.

Třetí místo - kompilátor Microsoft C

Můj učitel ve škole věřil, že Romea a Julii nelze považovat za tragédii, protože postavy neměly žádnou tragickou vinu – prostě se chovaly hloupě, jak by se náctiletým slušelo. Tehdy jsem s ním nesouhlasil, ale nyní v jeho názoru vidím zrnko racionality, zejména v souvislosti s programováním.

Když jsem dokončil druhý ročník na MIT, byl jsem mladý a nezkušený, jak v životě, tak v programování. V létě jsem internoval v Microsoftu, v týmu kompilátoru C. Nejprve jsem dělal rutinní věci, jako je podpora profilování, a pak jsem byl pověřen prací na nejzábavnější části kompilátoru (jak jsem si myslel) – optimalizaci backendu. Zejména jsem musel zlepšit kód x86 pro příkazy větve.

Odhodlán napsat optimální strojový kód pro každý možný případ jsem se po hlavě vrhl do bazénu. Pokud byla hustota distribuce hodnot vysoká, zadal jsem je přechodová tabulka. Pokud měli společného dělitele, použil jsem ho k utažení tabulky (ale pouze v případě, že rozdělení šlo provést pomocí bitový posun). Když byly všechny hodnoty mocniny dvou, provedl jsem další optimalizaci. Pokud sada hodnot nesplňovala mé podmínky, rozdělil jsem ji do několika optimalizovatelných případů a použil již optimalizovaný kód.

Byla to noční můra. O mnoho let později mi bylo řečeno, že programátor, který zdědil můj kód, mě nenáviděl.

Nejtrapnější chyby v mé programátorské kariéře (zatím)

Poučení

Jak píší David Patterson a John Hennessy v Computer Architecture and Computer Systems Design, jedním z hlavních principů architektury a designu je obecně zajistit, aby věci fungovaly co nejrychleji.

Zrychlení běžných případů zlepší výkon efektivněji než optimalizace vzácných případů. Je ironií, že běžné případy jsou často jednodušší než ty vzácné. Tato logická rada předpokládá, že víte, který případ je považován za běžný – a to je možné pouze prostřednictvím procesu pečlivého testování a měření.

Na svou obranu jsem se snažil zjistit, jak větvení příkazy vypadaly v praxi (např. kolik tam bylo větví a jak byly distribuovány konstanty), ale v roce 1988 tyto informace nebyly k dispozici. Neměl jsem však přidávat speciální případy, kdykoli aktuální kompilátor nedokázal vygenerovat optimální kód pro umělý příklad, se kterým jsem přišel.

Potřeboval jsem zavolat zkušenému vývojáři a společně s ním se zamyslet nad běžnými případy a konkrétně je řešit. Napsal bych méně kódu, ale to je dobrá věc. Jak napsal zakladatel Stack Overflow Jeff Atwood, nejhorším nepřítelem programátora je programátor sám:

Vím, že máte ty nejlepší úmysly, stejně jako my všichni. Vytváříme programy a rádi píšeme kód. Tak jsme stvořeni. Myslíme si, že jakýkoli problém lze vyřešit lepicí páskou, domácí berličkou a špetkou kódu. Jakkoli to kodéry bolí to přiznat, nejlepší kód je kód, který neexistuje. Každý nový řádek potřebuje ladění a podporu, je třeba mu porozumět. Když přidáváte nový kód, měli byste to dělat s nechutí a znechucením, protože všechny ostatní možnosti byly vyčerpány. Mnoho programátorů píše příliš mnoho kódu, což z něj dělá našeho nepřítele.

Kdybych napsal jednodušší kód, který by pokrýval běžné případy, v případě potřeby by bylo mnohem jednodušší aktualizovat. Nechal jsem po sobě nepořádek, který nikdo nechtěl řešit.

Nejtrapnější chyby v mé programátorské kariéře (zatím)

Druhé místo: reklama na sociálních sítích

Když jsem v Google pracoval na reklamě na sociálních sítích (pamatujete na Myspace?), napsal jsem v C++ něco takového:

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)) {
  }
}

Programátoři mohou okamžitě vidět chybu: poslední argument by měl být j, nikoli i. Testování jednotky chybu neodhalilo a můj recenzent také ne. Spuštění bylo provedeno a jedné noci se můj kód dostal na server a zhroutil všechny počítače v datovém centru.

Nic zlého se nestalo. Nikomu se nic nezlomilo, protože před globálním spuštěním byl kód testován v rámci jednoho datového centra. Ledaže by inženýři SRE na chvíli přestali hrát kulečník a trochu se vrátili. Druhý den ráno jsem obdržel e-mail s výpisem z havárie, opravil kód a přidal testy jednotek, které chybu zachytí. Vzhledem k tomu, že jsem postupoval podle protokolu – jinak by se můj kód jednoduše nespustil – nebyly žádné další problémy.

Nejtrapnější chyby v mé programátorské kariéře (zatím)

Poučení

Mnozí si jsou jisti, že taková závažná chyba bude určitě stát viníka propuštění, ale není tomu tak: za prvé, všichni programátoři dělají chyby a za druhé jen zřídka udělají stejnou chybu dvakrát.

Ve skutečnosti mám kamaráda programátora, který byl skvělý inženýr a byl vyhozen za jedinou chybu. Poté byl přijat do Googlu (a brzy povýšen) - v rozhovoru upřímně mluvil o chybě, kterou udělal, a nebyla považována za fatální.

Tady je co sdělit o Thomasi Watsonovi, legendárním šéfovi IBM:

Byla vyhlášena vládní objednávka v hodnotě asi milionu dolarů. IBM Corporation - nebo spíše Thomas Watson Sr. osobně - to opravdu chtěla získat. Bohužel to obchodní zástupce nedokázal a IBM nabídku prohrála. Následujícího dne přišel tento zaměstnanec do kanceláře pana Watsona a položil mu na stůl obálku. Pan Watson se na to ani neobtěžoval podívat – čekal na zaměstnance a věděl, že jde o rezignaci.

Watson se zeptal, co se stalo.

O průběhu výběrového řízení podrobně hovořil obchodní zástupce. Vyjmenoval chyby, kterým se dalo předejít. Nakonec řekl: „Pane Watsone, děkuji, že jste mě nechal vysvětlit. Vím, jak moc jsme tuhle objednávku potřebovali. Vím, jak byl důležitý,“ a chystal se odejít.

Watson k němu přistoupil u dveří, podíval se mu do očí a vrátil obálku se slovy: „Jak tě můžu pustit? Právě jsem investoval milion dolarů do vašeho vzdělání.

Mám tričko s nápisem: "Pokud se opravdu poučíš z chyb, tak už jsem mistr." Ve skutečnosti, pokud jde o chyby, jsem doktor věd.

První místo: App Inventor API

Skutečně strašné chyby postihují velké množství uživatelů, stávají se veřejně známými, jejich náprava trvá dlouho a dělají je ti, kteří je nemohli udělat. Moje největší chyba splňuje všechna tato kritéria.

Čím horší, tím lepší

čtu esej Richarda Gabriela o tomto přístupu v devadesátých letech jako postgraduálnímu studentovi a líbí se mi natolik, že o něj žádám své studenty. Pokud si to nepamatujete dobře, osvěžte si paměť, je to malé. Tato esej v mnoha ohledech staví do kontrastu touhu „udělat to správně“ a přístup „čím hůř, tím lépe“, včetně jednoduchosti.

Jak by to mělo být: návrh by měl být jednoduchý v implementaci a rozhraní. Jednoduchost rozhraní je důležitější než jednoduchost implementace.

Čím hůř, tím lépe: design by měl být jednoduchý v implementaci a rozhraní. Jednoduchost implementace je důležitější než jednoduchost rozhraní.

Zapomeňme na to na chvíli. Bohužel jsem na to dlouhá léta zapomněl.

App Inventor

Při práci v Googlu jsem byl součástí týmu App Inventor, online vývojové prostředí typu drag-and-drop pro začínající vývojáře Android. Psal se rok 2009 a my jsme spěchali, abychom včas vydali alfa verzi, abychom v létě mohli pořádat mistrovské kurzy pro učitele, kteří by mohli prostředí využívat při podzimní výuce. Dobrovolně jsem se přihlásil k implementaci skřítků, nostalgicky po tom, jak jsem psal hry na TI-99/4. Pro ty, kteří nevědí, sprite je dvourozměrný grafický objekt, který se může pohybovat a interagovat s jinými softwarovými prvky. Příklady skřítků zahrnují vesmírné lodě, asteroidy, kuličky a rakety.

Implementovali jsme objektově orientovaný App Inventor v Javě, takže je tam jen hromada objektů. Protože se koule a skřítci chovají velmi podobně, vytvořil jsem abstraktní třídu sprite s vlastnostmi (pole) X, Y, Speed ​​​​(rychlost) a Heading (směr). Měli stejné metody pro detekci kolizí, odrážení od okraje obrazovky atd.

Hlavním rozdílem mezi míčem a skřítkem je to, co přesně je nakresleno - vyplněný kruh nebo rastr. Vzhledem k tomu, že jsem nejprve implementoval sprity, bylo logické určit souřadnice x a y levého horního rohu místa, kde se obrázek nacházel.

Nejtrapnější chyby v mé programátorské kariéře (zatím)
Jakmile skřítci fungovali, rozhodl jsem se, že bych mohl implementovat kuličkové objekty s velmi malým kódem. Jediný problém byl v tom, že jsem zvolil nejjednodušší cestu (z pohledu realizátora) s vyznačením souřadnic x a y levého horního rohu obrysu orámujícího míč.

Nejtrapnější chyby v mé programátorské kariéře (zatím)
Ve skutečnosti bylo nutné uvést souřadnice x a y středu kruhu, jak se to učí v jakékoli učebnici matematiky a jakémkoli jiném zdroji, který zmiňuje kruhy.

Nejtrapnější chyby v mé programátorské kariéře (zatím)
Na rozdíl od mých minulých chyb se tato dotkla nejen mých kolegů, ale také milionů uživatelů App Inventoru. Mnoho z nich byly děti nebo úplně nové programování. Při práci na každé aplikaci, ve které byl míček, museli provést spoustu zbytečných kroků. Pokud se smíchem vzpomínám na své další chyby, tak u této se zapotím i dnes.

Tuto chybu jsem konečně opravil teprve nedávno, o deset let později. „Opraveno“, nikoli „opraveno“, protože jak říká Joshua Bloch, API jsou věčná. Protože jsme nemohli provést změny, které by ovlivnily existující programy, přidali jsme vlastnost OriginAtCenter s hodnotou false ve starých programech a true ve všech budoucích. Uživatelé si mohou položit logickou otázku: koho vůbec napadlo umístit výchozí bod jinam než do středu. Komu? Jednomu programátorovi, který byl před deseti lety líný vytvořit normální API.

Ponaučení

Při práci na rozhraních API (což musí občas udělat téměř každý programátor) byste se měli řídit nejlepšími radami uvedenými ve videu Joshuy Blocha "Jak vytvořit dobré API a proč je to tak důležité"Or v tomto krátkém seznamu:

  • API vám může přinést velký užitek i velkou škodu.. Dobré API vytváří opakované zákazníky. Ten špatný se stane vaší věčnou noční můrou.
  • Veřejná rozhraní API, jako diamanty, vydrží navždy. Dejte do toho všechno: už nikdy nebude šance udělat všechno správně.
  • Nástin API by měl být stručný — jedna stránka s podpisy tříd a metod a popisy, která nezabere více než řádek. To vám umožní snadno restrukturalizovat API, pokud nebude napoprvé dokonalé.
  • Popište případy použitípřed implementací API nebo dokonce prací na jeho specifikaci. Vyhnete se tak implementaci a specifikaci zcela nefunkčního API.

Kdybych napsal byť jen krátkou synopsi umělým scénářem, s největší pravděpodobností bych chybu identifikoval a opravil. Pokud ne, pak by to určitě udělal někdo z mých kolegů. Každé rozhodnutí, které má dalekosáhlé důsledky, je potřeba alespoň den promyslet (platí nejen pro programování).

Název eseje Richarda Gabriela „Horší je lepší“ odkazuje na výhodu, kterou má být první na trhu – dokonce i s nedokonalým produktem –, zatímco někdo jiný stráví věčnost honbou za dokonalým. Když se zamyslím nad kódem sprite, uvědomuji si, že jsem ani nemusel psát další kód, abych to udělal správně. Ať si někdo říká cokoli, hrubě jsem se mýlil.

Závěr

Programátoři dělají chyby každý den, ať už píší chybný kód nebo nechtějí vyzkoušet něco, co zlepší jejich dovednosti a produktivitu. Samozřejmě můžete být programátorem, aniž byste dělali tak závažné chyby jako já. Ale je nemožné stát se dobrým programátorem, aniž byste si uvědomili své chyby a poučili se z nich.

Neustále se setkávám se studenty, kteří mají pocit, že dělají příliš mnoho chyb, a proto nejsou stvořeni pro programování. Vím, jak častý je syndrom podvodníka v IT. Doufám, že se naučíte poučení, které jsem uvedl – ale pamatujte si to hlavní: každý z nás dělá chyby – trapné, vtipné, hrozné. Budu překvapen a naštvaný, pokud v budoucnu nebudu mít dostatek materiálu na pokračování článku.

Zdroj: www.habr.com

Přidat komentář