Folklori i programuesve dhe inxhinierëve (pjesa 1)

Folklori i programuesve dhe inxhinierëve (pjesa 1)

Kjo është një përzgjedhje e tregimeve nga Interneti se si gabimet ndonjëherë kanë manifestime krejtësisht të pabesueshme. Ndoshta edhe ju keni diçka për të thënë.

Alergjia e makinës ndaj akullores me vanilje

Një histori për inxhinierët që kuptojnë se e qartë nuk është gjithmonë përgjigjja dhe se sado të largëta mund të duken faktet, ato janë ende fakte. Divizioni Pontiac i General Motors Corporation mori një ankesë:

Kjo është hera e dytë që po ju shkruaj dhe nuk ju fajësoj që nuk përgjigjeni, sepse tingëllon çmenduri. Familja jonë ka traditë të hajë akullore çdo natë pas darkës. Llojet e akullores ndryshojnë çdo herë dhe pas darkës, e gjithë familja zgjedh se cilën akullore të blejë, pas së cilës unë shkoj në dyqan. Kohët e fundit bleva një Pontiac të ri dhe që atëherë udhëtimet e mia për të marrë akullore janë bërë problem. E shihni, sa herë që blej akullore me vanilje dhe kthehem nga dyqani, makina nuk ndizet. Nëse sjell ndonjë akullore tjetër, makina ndizet pa problem. Dua të bëj një pyetje serioze, sado budallaqe të tingëllojë: “Çfarë ka në Pontiac që e bën të mos fillojë kur sjell akullore me vanilje, por fillon lehtësisht kur sjell një shije tjetër akulloreje?”

Siç mund ta imagjinoni, presidenti i divizionit ishte skeptik për letrën. Megjithatë, për çdo rast, dërgova një inxhinier për të kontrolluar. Ai u befasua që u takua nga një burrë i pasur, i mirëarsimuar që jetonte në një zonë të bukur. Ata ranë dakord të takoheshin menjëherë pas darkës në mënyrë që të dy të shkonin në dyqan për akullore. Atë mbrëmje ishte vanilje dhe kur u kthyen në makinë, ajo nuk nisi.

Inxhinieri erdhi edhe tre mbrëmje. Herën e parë akullorja ishte çokollatë. Makina u nis. Herën e dytë ishte akullore me luleshtrydhe. Makina u nis. Në mbrëmjen e tretë ai kërkoi të merrte vanilje. Makina nuk u ndez.

Duke arsyetuar në mënyrë racionale, inxhinieri refuzoi të besonte se makina ishte alergjike ndaj akullores me vanilje. Prandaj, me pronarin e makinës u pajtova që ai të vazhdonte vizitat derisa të gjente një zgjidhje për problemin. Dhe gjatë rrugës, ai filloi të mbante shënime: shkruante të gjitha informacionet, orën e ditës, llojin e benzinës, kohën e mbërritjes dhe kthimit nga dyqani, etj.

Inxhinieri shpejt e kuptoi se pronari i makinës harxhonte më pak kohë duke blerë akullore me vanilje. Arsyeja ishte shtrirja e mallit në dyqan. Akullorja me vanilje ishte më e njohura dhe mbahej në një frigorifer të veçantë në pjesën e përparme të dyqanit për ta bërë më të lehtë gjetjen. Dhe të gjitha varietetet e tjera ishin në pjesën e pasme të dyqanit, dhe u desh shumë më tepër kohë për të gjetur varietetin e duhur dhe për të paguar.

Tani pyetja ishte për inxhinierin: pse nuk u ndez makina nëse kishte kaluar më pak kohë nga momenti i fikur motori? Meqenëse problemi ishte koha, jo akullorja me vanilje, inxhinieri e gjeti shpejt përgjigjen: ishte një bllokues gazi. Ndodhte çdo mbrëmje, por kur pronari i makinës kalonte më shumë kohë duke kërkuar akullore, motori arriti të ftohej mjaftueshëm dhe të ndizte lehtësisht. Dhe kur burri bleu akullore me vanilje, motori ishte akoma shumë i nxehtë dhe bllokimi i gazit nuk kishte kohë të shpërndahej.

Morali: Edhe problemet krejtësisht të çmendura ndonjëherë janë reale.

Crash Bandicoot

Është e dhimbshme ta përjetosh këtë. Si programues, ju mësoheni të fajësoni kodin tuaj së pari, të dytën, të tretën... dhe diku në vendin e dhjetëmijëtë ju fajësoni përpiluesin. Dhe më poshtë në listë, ju tashmë fajësoni pajisjet.

Këtu është historia ime në lidhje me defektin e harduerit.

Për lojën Crash Bandicoot, kam shkruar kodin për ta ngarkuar dhe ruajtur në një kartë memorie. Për një zhvillues kaq të vetëkënaqur lojërash, ishte si një shëtitje në park: mendova se puna do të zgjaste disa ditë. Sidoqoftë, përfundova duke korrigjuar kodin për gjashtë javë. Gjatë rrugës zgjidha probleme të tjera, por çdo disa ditë i kthehesha këtij kodi për disa orë. Ishte agoni.

Simptoma dukej kështu: kur ruani versionin aktual të lojës dhe aksesoni kartën e kujtesës, pothuajse gjithmonë gjithçka shkon mirë... Por ndonjëherë koha e funksionimit të leximit ose shkrimit përfundon pa ndonjë arsye të dukshme. Një regjistrim i shkurtër shpesh dëmton kartën e kujtesës. Kur një lojtar përpiqet të kursejë, ai jo vetëm që nuk arrin të kursejë, por edhe shkatërron hartën. Katrahurë.

Pas pak, producentja jonë në Sony, Connie Bus, filloi të bjerë në panik. Ne nuk mund ta dërgonim lojën me këtë gabim dhe gjashtë javë më vonë nuk e kuptova se çfarë po e shkaktonte problemin. Nëpërmjet Connie, ne kontaktuam zhvilluesit e tjerë të PS1: a ka hasur dikush diçka të ngjashme? Nr. Askush nuk kishte probleme me kartën e kujtesës.

Kur nuk keni ide për korrigjimin e gabimeve, mënyra e vetme që mbetet është "përça dhe pushto": hiq gjithnjë e më shumë kod nga programi me defekt derisa të mbetet një fragment relativisht i vogël që ende shkakton problemin. Domethënë, ju e prisni programin pjesë-pjesë derisa të mbetet pjesa që përmban bug-in.

Por gjëja është se është shumë e vështirë të shkurtosh pjesët e një videolojë. Si ta ekzekutoni nëse keni hequr kodin që imiton gravitetin? Apo vizatimi i personazheve?

Prandaj, ne duhet të zëvendësojmë module të tëra me cungë që pretendojnë se bëjnë diçka të dobishme, por në fakt bëjnë diçka shumë të thjeshtë që nuk mund të përmbajë gabime. Duhet të shkruajmë paterica të tilla që loja të paktën të funksionojë. Ky është një proces i ngadaltë dhe i dhimbshëm.

Me pak fjalë, e bëra. Hoqa gjithnjë e më shumë pjesë kodi derisa mbeta me kodin fillestar që konfiguron sistemin për të ekzekutuar lojën, inicializon harduerin e interpretimit, etj. Natyrisht, në këtë fazë nuk mund të krijoja një menu të ruajtjes dhe ngarkimit, sepse do të më duhej të krijoja një cung për të gjithë kodin grafik. Por unë mund të pretendoj se jam një përdorues duke përdorur ekranin e ruajtjes dhe ngarkimit (të padukshëm) dhe të kërkoj të ruaj dhe më pas të shkruaj në kartën e kujtesës.

Kjo më la me një pjesë të vogël të kodit që kishte ende problemin e mësipërm - por prapë po ndodhte rastësisht! Më shpesh gjithçka funksiononte mirë, por herë pas here kishte defekte. Unë hoqa pothuajse të gjithë kodin e lojës, por defekti ishte ende i gjallë. Kjo ishte e çuditshme: kodi i mbetur në fakt nuk bëri asgjë.

Në një moment, ndoshta rreth tre të mëngjesit, më erdhi një mendim. Operacionet e leximit dhe shkrimit (hyrje/dalje) përfshijnë kohë të sakta të ekzekutimit. Kur punoni me një hard disk, kartë memorie ose modul Bluetooth, kodi i nivelit të ulët përgjegjës për leximin dhe shkrimin e bën këtë në përputhje me pulset e orës.

Me ndihmën e orës, një pajisje që nuk është e lidhur drejtpërdrejt me procesorin sinkronizohet me kodin që ekzekutohet në procesor. Ora përcakton shpejtësinë e zhurmës - shpejtësinë me të cilën transferohen të dhënat. Nëse ka konfuzion me oraret, atëherë ose hardueri ose softueri, ose të dyja, janë gjithashtu të hutuara. Dhe kjo është shumë e keqe, sepse të dhënat mund të dëmtohen.

Po sikur diçka në kodin tonë të ngatërron kohën? Kontrollova gjithçka që lidhet me këtë në kodin e programit të testimit dhe vura re se kohëmatësin e programueshëm në PS1 e vendosëm në 1 kHz (1000 tik-tak në sekondë). Kjo është shumë; si parazgjedhje, kur fillon tastiera, ajo funksionon në 100 Hz. Dhe shumica e lojërave përdorin këtë frekuencë.

Andy, zhvilluesi i lojës, vendosi kohëmatësin në 1 kHz në mënyrë që lëvizjet të llogariteshin më saktë. Andi tenton të kapërcejë detin dhe nëse imitojmë gravitetin, ne e bëjmë atë sa më saktë që të jetë e mundur!

Por, çka nëse përshpejtimi i kohëmatësit ndikoi disi në kohën e përgjithshme të programit, dhe rrjedhimisht në orën që rregullon shpejtësinë e zhurmës për kartën e kujtesës?

Unë komentova kodin e kohëmatësit. Gabimi nuk ndodhi më. Por kjo nuk do të thotë se e rregulluam, sepse dështimi ndodhi rastësisht. Po sikur të isha thjesht me fat?

Disa ditë më vonë eksperimentova sërish me programin e testimit. Defekti nuk u përsërit. U ktheva në bazën e plotë të kodeve të lojës dhe modifikova kodin e ruajtjes dhe ngarkimit në mënyrë që kohëmatësi i programueshëm të rivendosej në vlerën e tij origjinale (100Hz) përpara se të hynte në kartën e kujtesës dhe më pas të rivendosej në 1kHz. Nuk pati më përplasje.

Por pse ndodhi kjo?

U ktheva sërish në programin e testimit. Unë u përpoqa të gjeja një model në shfaqjen e një gabimi me një kohëmatës 1 kHz. Përfundimisht vura re se gabimi ndodh kur dikush luan me një kontrollues PS1. Meqenëse rrallë do ta bëja këtë vetë - pse do të më duhej një kontrollues kur testoja kodin e ruajtjes dhe ngarkimit? - As që e vura re këtë varësi. Por një ditë një nga artistët tanë priste që unë të mbaroja testimin - ndoshta po shaja në atë moment - dhe me nervozizëm rrotulloi kontrollorin në duar. Një gabim ka ndodhur. "Prisni Çfarë?!" Epo, bëje përsëri!”

Kur kuptova se këto dy ngjarje ishin të ndërlidhura, munda ta riprodhoja lehtësisht gabimin: fillova të regjistroja në kartën e kujtesës, zhvendosa kontrolluesin dhe e prisha kartën e kujtesës. Mua më dukej si një gabim harduerësh.

Erdha te Connie dhe i tregova për zbulimin tim. Ajo ia transmetoi informacionin njërit prej inxhinierëve që projektoi PS1. "E pamundur," u përgjigj ai, "Nuk mund të jetë një problem harduer." I kërkova Konit të organizonte një bisedë për ne.

Inxhinieri më thirri dhe ne u grindëm në anglishten e tij të thyer dhe japoneze time (jashtëzakonisht) të thyer. Më në fund thashë: "Më lejoni të dërgoj programin tim të testimit me 30 linja ku lëvizja e kontrolluesit shkakton një gabim." Ai ra dakord. Ai tha se ishte një humbje kohe dhe se ai ishte jashtëzakonisht i zënë duke punuar në një projekt të ri, por do të dorëzohej sepse ne ishim një zhvillues shumë i rëndësishëm për Sony. Pastrova programin tim të testimit dhe ia dërgova atij.

Të nesërmen në mbrëmje (ne ishim në Los Anxhelos dhe ai ishte në Tokio) më thirri dhe më kërkoi falje me turp. Ishte një problem harduerik.

Nuk e di se çfarë ishte saktësisht defekti, por nga ajo që dëgjova në selinë e Sony, nëse e vendosni kohëmatësin në një vlerë mjaft të lartë, ai ndërhynte me komponentët në motherboard në afërsi të kristalit të kohëmatësit. Njëri prej tyre ishte një kontrollues i shpejtësisë së zhurmës për kartën e kujtesës, i cili gjithashtu vendosi shpejtësinë e zhurmës për kontrollorët. Unë nuk jam inxhinier, kështu që mund të kem ngatërruar diçka.

Por në fund të fundit është se ka pasur ndërhyrje midis komponentëve në motherboard. Dhe kur transmetoni të dhëna në të njëjtën kohë përmes portës së kontrolluesit dhe portës së kartës së kujtesës me një kohëmatës që funksionon në 1 kHz, bitët humbën, të dhënat humbën dhe karta u dëmtua.

Lopë të këqija

Në vitet 1980, mentori im Sergei shkroi softuer për SM-1800, një klon sovjetik i PDP-11. Ky mikrokompjuter sapo është instaluar në një stacion hekurudhor pranë Sverdlovsk, një qendër e rëndësishme transporti në BRSS. Sistemi i ri u krijua për të drejtuar vagonët dhe trafikun e mallrave. Por ai përmbante një gabim të bezdisshëm që çoi në përplasje dhe përplasje të rastësishme. Rënia ka ndodhur gjithmonë kur dikush shkonte në shtëpi në mbrëmje. Por pavarësisht një hetimi të plotë të nesërmen, kompjuteri funksionoi si duhet në të gjitha testet manuale dhe automatike. Kjo zakonisht tregon një gjendje gare ose ndonjë gabim tjetër konkurrues që ndodh në kushte të caktuara. I lodhur nga telefonatat natën vonë, Sergei vendosi t'i shkonte në fund dhe para së gjithash, të kuptonte se cilat kushte në oborrin e marshallimit çuan në prishjen e kompjuterit.

Së pari, ai mblodhi statistika të të gjitha rënieve të pashpjegueshme dhe krijoi një grafik sipas datës dhe orës. Modeli ishte i dukshëm. Pasi vëzhgoi për disa ditë të tjera, Sergei kuptoi se ai mund të parashikonte lehtësisht kohën e dështimeve të sistemit të ardhshëm.

Ai shpejt mësoi se ndërprerjet ndodhën vetëm kur stacioni po renditte ngarkesat e trenave me bagëti nga Ukraina veriore dhe Rusia perëndimore që drejtoheshin në një thertore aty pranë. Kjo në vetvete ishte e çuditshme, sepse thertorja furnizohej nga fermat që ndodheshin shumë më afër, në Kazakistan.

Termocentrali bërthamor i Çernobilit shpërtheu në vitin 1986 dhe pasojat radioaktive i bënë zonat përreth të pabanueshme. Zona të gjera në Ukrainën veriore, Bjellorusi dhe Rusinë perëndimore ishin të kontaminuara. Duke dyshuar për nivele të larta rrezatimi në karrocat që mbërrinin, Sergei zhvilloi një metodë për të testuar këtë teori. Popullsia ishte e ndaluar të kishte dozimetra, kështu që Sergei u regjistrua me disa ushtarë në stacionin hekurudhor. Pas disa pije vodka, ai arriti të bindë një ushtar për të matur nivelin e rrezatimit në një nga karrocat e dyshimta. Doli se niveli ishte disa herë më i lartë se vlerat normale.

Jo vetëm që bagëtia lëshonte shumë rrezatim, por niveli i saj ishte aq i lartë sa çoi në humbje të rastësishme të pjesëve në kujtesën e SM-1800, i cili ndodhej në një ndërtesë pranë stacionit.

Kishte një mungesë ushqimi në BRSS dhe autoritetet vendosën të përziejnë mishin e Çernobilit me mish nga rajone të tjera të vendit. Kjo bëri të mundur uljen e nivelit të përgjithshëm të radioaktivitetit pa humbur burime të vlefshme. Pasi mësoi për këtë, Sergei menjëherë plotësoi dokumentet për emigracion. Dhe përplasjet e kompjuterit ndaluan vetë kur niveli i rrezatimit u ul me kalimin e kohës.

Përmes tubave

Njëherë e një kohë, Movietech Solutions krijoi softuer për kinematë, i projektuar për kontabilitet, shitje biletash dhe menaxhim të përgjithshëm. Versioni DOS i aplikacionit kryesor ishte mjaft i popullarizuar në mesin e zinxhirëve të kinemave të vogla dhe të mesme në Amerikën e Veriut. Pra, nuk është për t'u habitur që kur u njoftua një version i Windows 95, i integruar me ekranet më të fundit me prekje dhe kioskat e vetë-shërbimit dhe i pajisur me të gjitha llojet e mjeteve të raportimit, ai gjithashtu u bë i njohur shpejt. Më shpesh, përditësimi kaloi pa probleme. Stafi lokal i IT-së instaloi pajisje të reja, migroi të dhënat dhe biznesi vazhdoi. Përveç rasteve kur nuk zgjati. Kur kjo ndodhi, kompania do të dërgonte James, me nofkën "Pastruesi".

Edhe pse pseudonimi sugjeron një lloj të poshtër, pastruesja është vetëm një kombinim i instruktorit, instaluesit dhe jack-of-all-trades. James do të kalonte disa ditë në faqen e klientit duke bashkuar të gjithë komponentët dhe më pas kalonte disa ditë të tjera duke i mësuar stafit se si të përdorte sistemin e ri, duke zgjidhur çdo problem harduerik që lindte dhe duke ndihmuar në thelb softuerin gjatë fillimit të tij.

Prandaj, nuk është për t'u habitur që gjatë këtyre kohërave të trazuara, James mbërriti në zyrë në mëngjes dhe para se të arrinte në tryezën e tij, u përshëndet nga menaxheri, i mbushur me kafeinë përtej zakonit.

"Kam frikë se ju duhet të shkoni në Annapolis, Nova Scotia, sa më shpejt të jetë e mundur." I gjithë sistemi i tyre u rrëzua dhe pas një nate pune me inxhinierët e tyre, ne nuk mund ta kuptojmë se çfarë ndodhi. Duket sikur rrjeti ka dështuar në server. Por vetëm pasi sistemi kishte funksionuar për disa minuta.

- Nuk u kthyen në sistemin e vjetër? - iu përgjigj James plotësisht seriozisht, megjithëse mendërisht zgjeroi sytë nga habia.

- Pikërisht: specialisti i tyre i IT "ndryshoi prioritetet" dhe vendosi të largohej me serverin e tyre të vjetër. James, ata e instaluan sistemin në gjashtë vende dhe sapo paguanin për mbështetje premium, dhe biznesi i tyre tani drejtohet si në vitet 1950.

James u drejtua paksa.

- Kjo është çështje tjetër. Mirë, le të fillojmë.

Kur mbërriti në Annapolis, gjëja e parë që bëri ishte gjetja e teatrit të parë të klientit që kishte një problem. Në hartën e marrë në aeroport, gjithçka dukej e mirë, por zona rreth adresës së dëshiruar dukej e dyshimtë. Jo geto, por të kujton film noir. Ndërsa James parkonte në trotuarin në qendër të qytetit, një prostitutë iu afrua atij. Duke pasur parasysh madhësinë e Annapolis, ka shumë të ngjarë të ishte i vetmi në të gjithë qytetin. Pamja e saj e solli menjëherë në mendje personazhin e famshëm që ofronte seks për para në ekranin e madh. Jo, jo për Julia Roberts, por për Jon Voight [aluzion për filmin "Midnight Cowboy" - përafërsisht. korsi].

Pasi dërgoi prostitutën në rrugën e saj, James shkoi në kinema. Zona përreth ishte bërë më e mirë, por sërish të jepte përshtypjen e rrënuar. Jo se James ishte shumë i shqetësuar. Ai ka qenë në vende të mjerueshme më parë. Dhe kjo ishte Kanadaja, ku edhe grabitësit janë mjaft të sjellshëm për të thënë "faleminderit" pasi të marrin portofolin.

Hyrja anësore e kinemasë ishte në një rrugicë të lagur. James shkoi te dera dhe trokiti. Shpejt kërciti dhe u hap pak.

-A jeni pastruese? - erdhi një zë i ngjirur nga brenda.

- Po, jam unë... erdha të rregulloj gjithçka.

James hyri në hollin e kinemasë. Me sa duket nuk kishte zgjidhje tjetër, stafi filloi të shpërndante bileta letre për vizitorët. Kjo e bëri të vështirë raportimin financiar, e lëre më detaje më interesante. Por stafi e përshëndeti Jamesin me lehtësim dhe e çoi menjëherë në dhomën e serverit.

Në shikim të parë, gjithçka ishte në rregull. James hyri në server dhe kontrolloi vendet e zakonshme të dyshimta. Nuk ka problem. Megjithatë, nga shumë kujdes, James mbylli serverin, zëvendësoi kartën e rrjetit dhe e ktheu përsëri sistemin. Ajo menjëherë filloi punën e plotë. Stafi filloi sërish të shesë bileta.

James thirri Markun dhe e informoi për situatën. Nuk është e vështirë të imagjinohet se James mund të dëshirojë të rrijë dhe të shohë nëse ndodh ndonjë gjë e papritur. Ai zbriti shkallët dhe filloi të pyeste punonjësit se çfarë ndodhi. Është e qartë se sistemi ka ndaluar së punuari. Ata e fikën dhe e ndezën, gjithçka funksionoi. Por pas 10 minutash sistemi ra.

Vetëm në këtë moment ka ndodhur diçka e ngjashme. Papritur, sistemi i biletave filloi të hedhë gabime. Stafi psherëtiu dhe rrëmbeu biletat e letrës dhe James nxitoi në dhomën e serverit. Gjithçka dukej mirë me serverin.

Më pas hyri një nga punonjësit.

- Sistemi po funksionon përsëri.

James ishte në mëdyshje sepse nuk kishte bërë asgjë. Më saktësisht, asgjë që do ta bënte sistemin të funksiononte. Ai doli, mori telefonin e tij dhe telefonoi linjën e mbështetjes së kompanisë së tij. Së shpejti i njëjti punonjës hyri në dhomën e serverit.

- Sistemi ka rënë.

James hodhi një vështrim në server. Një model interesant dhe i njohur i formave shumëngjyrëshe kërcenin në ekran - tubat që përdridhen dhe ndërthurin në mënyrë kaotike. Të gjithë e kemi parë këtë mbrojtës në një moment. Ishte interpretuar bukur dhe fjalë për fjalë hipnotizuese.


James shtypi një buton dhe modeli u zhduk. Ai nxitoi te bileta dhe rrugës takoi një punonjës që po kthehej tek ai.

- Sistemi po funksionon përsëri.

Nëse mund të bëni një pëllëmbë mendore, kjo është pikërisht ajo që bëri James. Mbrojtës Ekrani. Ai përdor OpenGL. Dhe për këtë arsye, gjatë funksionimit, ai konsumon të gjitha burimet e procesorit të serverit. Si rezultat, çdo telefonatë në server përfundon me një afat kohor.

James u kthye në dhomën e serverit, u identifikua dhe zëvendësoi mbrojtësin e ekranit me tubacionet e bukura me një ekran bosh. Kjo do të thotë, në vend të një mbrojtësi ekrani që konsumon 100% të burimeve të procesorit, unë instalova një tjetër që nuk konsumon burime. Pastaj prita 10 minuta për të kontrolluar supozimin tim.

Kur James mbërriti në kinemanë tjetër, ai po pyeste veten se si t'i shpjegonte menaxherit të tij se sapo kishte fluturuar 800 km për të fikur mbrojtësin e ekranit.

Rrëzimi gjatë një faze të caktuar të hënës

Histori e vërtetë. Një ditë u shfaq një gabim softuerësh që varej nga faza e hënës. Kishte një rutinë të vogël që përdorej zakonisht në programe të ndryshme të MIT për të llogaritur përafrimin me fazën e vërtetë të Hënës. GLS e ndërtoi këtë rutinë në një program LISP që, kur shkruante një skedar, do të nxirrte një rresht me një vulë kohore gati 80 karaktere të gjatë. Ishte shumë e rrallë që rreshti i parë i një mesazhi të përfundonte shumë i gjatë dhe të çonte në rreshtin tjetër. Dhe kur programi më vonë lexoi këtë skedar, ai mallkoi. Gjatësia e rreshtit të parë varej nga data dhe ora e saktë, si dhe nga gjatësia e specifikimit të fazës në kohën kur u printua vula kohore. Kjo do të thotë, defekti varej fjalë për fjalë nga faza e hënës!

Botimi i parë në letër Skedari i zhargonit (Steele-1983) përmbante një shembull të një linje të tillë që çoi në gabimin e përshkruar, por shkrimtari e "rregulloi" atë. Që atëherë, kjo është përshkruar si një "gabim i fazës së hënës".

Megjithatë, kini kujdes me supozimet. Disa vite më parë, inxhinierët nga CERN (Qendra Evropiane për Kërkime Bërthamore) hasën në gabime në eksperimentet e kryera në Përplasësin e Madh Electron-Positron. Meqenëse kompjuterët përpunojnë në mënyrë aktive sasinë e madhe të të dhënave të gjeneruara nga kjo pajisje përpara se t'ua tregonin rezultatin shkencëtarëve, shumë spekuluan se softueri ishte disi i ndjeshëm ndaj fazës së hënës. Disa inxhinierë të dëshpëruar arritën në fund të së vërtetës. Gabimi lindi për shkak të një ndryshimi të lehtë në gjeometrinë e unazës 27 km të gjatë për shkak të deformimit të Tokës gjatë kalimit të Hënës! Kjo histori ka hyrë në folklorin e fizikës si "Hakmarrja e Njutonit ndaj fizikës së grimcave" dhe një shembull i lidhjes midis ligjeve më të thjeshta dhe më të vjetra të fizikës dhe koncepteve më të avancuara shkencore.

Shpëlarja e tualetit ndalon trenin

Defekti më i mirë i harduerit që kam dëgjuar ndonjëherë ishte në një tren me shpejtësi të lartë në Francë. Defekti çoi në frenim emergjent të trenit, por vetëm nëse në bord kishte pasagjerë. Në çdo rast të tillë, treni është nxjerrë jashtë shërbimit, është kontrolluar, por nuk është gjetur asgjë. Më pas ai u kthye në linjë dhe ai u rrëzua menjëherë në një ndalesë.

Gjatë njërit prej kontrolleve, një inxhinier që udhëtonte në tren shkoi në tualet. Ai shpejt u la, BOOM! Ndalesa emergjente.

Inxhinieri kontaktoi shoferin dhe e pyeti:

- Çfarë po bënit pak para frenimit?

- Epo, ngadalësova shpejtësinë në zbritje ...

Kjo ishte e çuditshme, sepse gjatë funksionimit normal, treni ngadalësohet në zbritje dhjetëra herë. Treni vazhdoi, dhe në zbritjen tjetër shoferi paralajmëroi:

- Unë do të ngadalësoj.

Asgjë nuk ndodhi.

— Çfarë bëtë gjatë frenimit të fundit? - pyeti shoferi.

- Epo, unë isha në tualet...

- Epo, atëherë shko në tualet dhe bëj atë që bëre kur të zbresim përsëri!

Inxhinieri shkoi në tualet dhe kur shoferi paralajmëroi: "Po ngadalësoj shpejtësinë", ai lau ujin. Natyrisht, treni ndaloi menjëherë.

Tani ata mund të riprodhonin problemin dhe duhej të gjenin shkakun.

Pas dy minutash vunë re se kablloja e telekomandës së frenave të motorit (treni kishte nga një motor në çdo skaj) ishte shkëputur nga muri i kabinetit elektrik dhe ishte shtrirë në stafetën që kontrollonte solenoidin e prizës së tualetit... Kur stafeta ishte ndezur, krijoi ndërhyrje në kabllon e frenave dhe mbrojtja e sistemit kundër dështimeve përfshinte thjesht frenimin emergjent.

Porta që urrente FORTRAN

Disa muaj më parë ne vumë re se lidhjet e rrjetit në kontinent [kjo ishte në Hawaii] po bëheshin shumë, shumë të ngadalta. Kjo mund të zgjasë për 10-15 minuta dhe më pas të ndodhë përsëri papritmas. Pas ca kohësh, kolegu im më ankua se lidhjet e rrjetit në kontinent në përgjithësi nuk punon. Ai kishte një kod FORTRAN që duhej të kopjohej në një makinë në kontinent, por nuk mundi sepse "rrjeti nuk qëndroi aq gjatë sa të përfundonte ngarkimi i FTP".

Po, doli që dështimet e rrjetit ndodhën kur një koleg u përpoq të FTP një skedar me kod burim në FORTRAN në një makinë në kontinent. Ne u përpoqëm të arkivojmë skedarin: më pas ai u kopjua pa probleme (por makina e synuar nuk kishte një shpaketues, kështu që problemi nuk u zgjidh). Më në fund ne "ndamë" kodin FORTRAN në copa shumë të vogla dhe i dërguam ato një nga një. Shumica e fragmenteve u kopjuan pa probleme, por disa pjesë nuk kaluan, ose kaluan më pas i shumtë përpjekjet.

Kur shqyrtuam pasazhet problematike, zbuluam se ato kishin diçka të përbashkët: të gjitha përmbanin blloqe komentesh që fillonin dhe mbaronin me rreshta të përbëra nga shkronja C (pasi një koleg preferoi të komentonte në FORTRAN). U dërguam email ekspertëve të rrjetit në kontinent dhe kërkuam ndihmë. Sigurisht, ata donin të shihnin mostra të skedarëve tanë që nuk mund të transferoheshin me FTP... por letrat tona nuk arritën tek ata. Më në fund dolëm me një të thjeshtë përshkruajsi duken skedarët e patransferueshëm. Ajo funksionoi :) [A guxoj të shtoj një shembull të një prej komenteve problematike të FORTRAN këtu? Ndoshta nuk ia vlen!]

Në fund arritëm ta kuptonim. Një portë e re u instalua kohët e fundit midis pjesës sonë të kampusit dhe rrjetit kontinent. Kishte vështirësi të mëdha në transmetimin e paketave që përmbanin pjesë të përsëritura të shkronjave të mëdha C! Vetëm disa nga këto paketa mund të marrin të gjitha burimet e portës dhe të parandalojnë kalimin e shumicës së paketave të tjera. Ne u ankuam te prodhuesi i portës... dhe ata u përgjigjën: “Oh, po, ju jeni përballur me një defekt të C-së të përsëritur! Ne tashmë dimë për të.” Ne e zgjidhëm problemin përfundimisht duke blerë një portë të re nga një prodhues tjetër (në mbrojtjen e të parës, pamundësia për të transferuar programet FORTRAN mund të jetë një avantazh për disa!).

Koha të vështira

Disa vite më parë, ndërsa punoja për krijimin e një sistemi ETL në Perl për të ulur kostot e provave klinike të fazës 40, më duhej të përpunoja rreth 000 data. Dy prej tyre nuk e kaluan testin. Kjo nuk më shqetësoi shumë sepse këto data u morën nga të dhënat e ofruara nga klienti që shpesh, le të themi, ishin befasuese. Por kur kontrollova të dhënat origjinale, doli që këto data ishin 1 janari 2011 dhe 1 janari 2007. Mendova se gabimi ishte i përfshirë në programin që sapo kisha shkruar, por doli që ishin tashmë 30 vjet e vjetër. Kjo mund të tingëllojë misterioze për ata që nuk janë të njohur me ekosistemin e softuerit. Për shkak të vendimit të gjatë të një kompanie tjetër për të fituar para, klienti im më pagoi për të rregulluar një defekt që njëra kompani e kishte prezantuar rastësisht dhe tjetra me qëllim. Që të kuptoni se për çfarë po flas, më duhet të flas për kompaninë që shtoi funksionin që përfundoi duke u bërë një gabim, si dhe disa ngjarje të tjera interesante që kontribuan në defektin misterioz që rregullova.

Në ditët e mira të vjetra, kompjuterët Apple ndonjëherë rivendosnin spontanisht datën e tyre në 1 janar 1904. Arsyeja ishte e thjeshtë: përdorte një "orë sistemi" me bateri për të mbajtur shënim datën dhe kohën. Çfarë ndodhi kur bateria vdiq? Kompjuterët filluan të gjurmonin datën me numrin e sekondave që nga fillimi i një epoke. Me epokë nënkuptuam datën origjinale të referencës, dhe për Macintoshët ishte 1 janari 1904. Dhe pasi bateria mbaroi, data aktuale u rivendos në atë të specifikuar. Por pse ndodhi kjo?

Më parë, Apple përdorte 32 bit për të ruajtur numrin e sekondave që nga data origjinale. Një bit mund të ruajë një nga dy vlerat - 1 ose 0. Dy bit mund të ruajnë një nga katër vlerat: 00, 01, 10, 11. Tre bit - një vlerë nga tetë: 000, 001, 010, 011, 100 , 101, 110, 111, etj. Dhe 32 mund të ruajë një nga 232 vlerat, domethënë 4 sekonda. Për datat e Apple, kjo barazohet me rreth 294 vjet, kështu që Mac-ët e vjetër nuk mund të trajtojnë datat pas vitit 967. Dhe nëse bateria e sistemit mbaron, data rivendoset në 296 sekonda që nga fillimi i epokës dhe ju duhet ta vendosni manualisht datën sa herë që ndizni kompjuterin (ose derisa të blini një bateri të re).

Megjithatë, vendimi i Apple për të ruajtur datat si sekonda që nga epoka nënkuptonte se ne nuk mund të përballonim datat para epokës, gjë që kishte pasoja të gjera, siç do ta shohim. Apple prezantoi një veçori, jo një gabim. Ndër të tjera, kjo do të thoshte se sistemi operativ Macintosh ishte imun ndaj "bugut të mijëvjeçarit" (gjë që nuk mund të thuhet për shumë aplikacione Mac që kishin sistemet e tyre të datave për të anashkaluar kufizimet).

Shkoni përpara. Ne përdorëm Lotus 1-2-3, "aplikacioni vrasës" i IBM që ndihmoi në nisjen e revolucionit të PC, megjithëse kompjuterët Apple kishin VisiCalc, i cili e bëri kompjuterin personal një sukses. Me drejtësi, nëse nuk do të ishte shfaqur 1-2-3, PC-të vështirë se do të ishin nisur dhe historia e kompjuterëve personalë mund të ishte zhvilluar shumë ndryshe. Lotus 1-2-3 e trajtoi gabimisht vitin 1900 si një vit të brishtë. Kur Microsoft lëshoi ​​spreadsheet e tij të parë, Multiplan, ai pushtoi një pjesë të vogël të tregut. Dhe kur nisën projektin Excel, ata vendosën jo vetëm të kopjojnë skemën e emërtimit të rreshtave dhe kolonave nga Lotus 1-2-3, por edhe të sigurojnë përputhshmërinë e gabimeve duke e trajtuar qëllimisht 1900 si një vit të brishtë. Ky problem ekziston edhe sot. Kjo do të thotë, në 1-2-3 ky ishte një gabim, por në Excel ishte një vendim i vetëdijshëm që siguroi që të gjithë përdoruesit 1-2-3 të mund të importonin tabelat e tyre në Excel pa ndryshuar të dhënat, edhe nëse ishin të pasakta.

Por kishte një problem tjetër. Së pari, Microsoft lëshoi ​​Excel për Macintosh, i cili nuk njihte data para 1 janarit 1904. Dhe në Excel, 1 janari 1900 konsiderohej fillimi i epokës. Prandaj, zhvilluesit bënë një ndryshim në mënyrë që programi i tyre njohu llojin e epokës dhe ruante të dhënat brenda vetes në përputhje me epokën e dëshiruar. Microsoft madje shkroi një artikull shpjegues për këtë. Dhe ky vendim çoi në defektin tim.

Sistemi im ETL mori fletëllogaritëse Excel nga klientët që ishin krijuar në Windows, por mund të krijoheshin edhe në një Mac. Prandaj, fillimi i epokës në tabelë mund të jetë ose 1 janar 1900, ose 1 janar 1904. Si të zbuloni? Formati i skedarit Excel tregon informacionin e nevojshëm, por analizuesi që përdora nuk e shfaqi atë (tani po) dhe supozoi se ju e dini epokën për një tabelë specifike. Ndoshta mund të kisha shpenzuar më shumë kohë për të kuptuar formatin binar të Excel dhe për t'i dërguar një patch autorit të analizuesit, por kisha shumë më tepër për të bërë për klientin, kështu që shkrova shpejt një heuristikë për të përcaktuar epokën. Ajo ishte e thjeshtë.

Në Excel, data 5 korrik 1998 mund të përfaqësohet në formatin "07-05-98" (sistemi amerikan i padobishëm), "5 korrik 98", "5 korrik 1998", "5-korrik-98" ose ndonjë format tjetër, një tjetër format i padobishëm (për ironi, një nga formatet që versioni im i Excel nuk ofronte ishte ISO 8601). Megjithatë, brenda tabelës, data e paformatuar u ruajt ose si "35981" për epokën-1900 ose "34519" për epokën-1904 (numrat përfaqësojnë numrin e ditëve që nga epoka). Thjesht përdora një analizues të thjeshtë për të nxjerrë vitin nga data e formatuar dhe më pas përdora analizuesin Excel për të nxjerrë vitin nga data e paformatuar. Nëse të dyja vlerat ndryshonin për 4 vjet, atëherë e dija që po përdorja një sistem me epokën 1904.

Pse nuk përdora vetëm data të formatuara? Sepse 5 korriku 1998 mund të formatohet si "Korrik 98" me ditën e muajit të humbur. Ne morëm tabela nga kaq shumë kompani që i krijuan ato në mënyra të ndryshme, saqë na takonte neve (në këtë rast, mua) të përcaktonim datat. Përveç kësaj, nëse Excel e merr atë siç duhet, atëherë duhet edhe ne!

Në të njëjtën kohë u ndesha me 39082. Më lejoni t'ju kujtoj se Lotus 1-2-3 e konsideronte 1900 një vit të brishtë, dhe kjo u përsërit besnikërisht në Excel. Dhe meqenëse kjo i shtoi një ditë vitit 1900, shumë funksione të llogaritjes së datave mund të jenë të gabuara pikërisht për atë ditë. Kjo do të thotë, 39082 mund të ketë qenë 1 janari 2011 (në Mac) ose 31 dhjetor 2006 (në Windows). Nëse "analizuesi i vitit" im e ka nxjerrë vitin 2011 nga vlera e formatuar, atëherë gjithçka është në rregull. Por duke qenë se analizuesi Excel nuk e di se çfarë epoke është duke u përdorur, ai vendos në epoch-1900, duke kthyer vitin 2006. Aplikacioni im pa që diferenca ishte 5 vjet, e konsideroi atë një gabim, e regjistroi dhe ktheu një vlerë të paformatuar.

Për të kapërcyer këtë, unë shkrova këtë (pseudokod):

diff = formatted_year - parsed_year
if 0 == diff
    assume 1900 date system
if 4 == diff
    assume 1904 date system
if 5 == diff and month is December and day is 31
    assume 1904 date system

Dhe pastaj të gjitha 40 datat u analizuan saktë.

Në mes të punëve me printime të mëdha

Në fillim të viteve 1980, babai im punonte në Storage Technology, një divizion tashmë i zhdukur që krijoi disqe shiritash dhe sisteme pneumatike për ushqimin me shirit me shpejtësi të lartë.

Ata ridizajnuan disqet në mënyrë që të mund të kishin një disk qendror "A" të lidhur me shtatë disqe "B" dhe OS i vogël në RAM që kontrollonte diskun "A" mund të delegonte operacionet e leximit dhe të shkrimit te të gjithë disqet "B".

Sa herë që nisej disku "A", ishte e nevojshme të futej një disketë në diskun periferik të lidhur me "A" në mënyrë që të ngarkohej sistemi operativ në memorien e tij. Ishte jashtëzakonisht primitiv: fuqia llogaritëse sigurohej nga një mikrokontrollues 8-bit.

Audienca e synuar për pajisje të tilla ishin kompanitë me depo të dhënash shumë të mëdha - banka, zinxhirë shitjesh me pakicë, etj. - që duhej të printonin shumë etiketa adresash ose deklarata bankare.

Një klient kishte një problem. Në mes të një pune printimi, një makinë e veçantë "A" mund të ndalojë së punuari, duke bërë që e gjithë puna të ngecë. Për të rivendosur funksionimin e diskut, personeli duhej të rindizte gjithçka. Dhe nëse kjo ndodhi në mes të një detyre gjashtë-orëshe, atëherë një sasi e madhe e kohës së shtrenjtë kompjuterike humbi dhe orari i të gjithë operacionit u ndërpre.

Teknikët u dërguan nga Storage Technologies. Por pavarësisht përpjekjeve të tyre më të mira, ata nuk ishin në gjendje të riprodhonin gabimin në kushte testimi: dukej se ndodhte në mes të punëve të mëdha të printimit. Problemi nuk ishte hardueri, ata zëvendësuan gjithçka që mundën: RAM, mikrokontrollues, disketë, çdo pjesë të mundshme të kasetës - problemi vazhdoi.

Më pas teknikët thirrën selinë dhe thirrën Ekspertin.

Eksperti rrëmbeu një karrige dhe një filxhan kafe, u ul në dhomën e kompjuterit - në ato ditë kishte dhoma të dedikuara për kompjuterët - dhe shikoi se si stafi ishte në radhë për një punë të madhe printimi. Eksperti priste që të ndodhte një dështim - dhe ndodhi. Të gjithë shikuan Ekspertin, por ai nuk e dinte pse ndodhi kjo. Kështu ai urdhëroi që puna të vihej përsëri në radhë dhe i gjithë stafi dhe teknikët u kthyen në punë.

Eksperti u ul përsëri në karrige dhe filloi të priste për një dështim. Kaluan rreth gjashtë orë dhe ndodhi dështimi. Eksperti përsëri nuk kishte asnjë ide, përveç se gjithçka ndodhi në një dhomë të mbushur me njerëz. Ai urdhëroi që misioni të rifillonte, u ul përsëri dhe priti.

Me dështimin e tretë, Eksperti vuri re diçka. Dështimi ndodhi kur personeli ndërroi shiritat në një makinë të huaj. Për më tepër, dështimi ka ndodhur sapo njëri nga punonjësit ka kaluar nëpër një pllakë të caktuar në dysheme.

Dyshemeja e ngritur ishte prej pllakash alumini të shtruara në një lartësi prej 6 deri në 8 inç. Tela të shumta nga kompjuterët kalonin nën dyshemenë e ngritur për të parandaluar që dikush të shkelte aksidentalisht një kabllo të rëndësishme. Pllakat u vendosën shumë fort për të parandaluar që mbeturinat të futeshin nën dyshemenë e ngritur.

Eksperti kuptoi se njëra nga pllakat ishte e deformuar. Kur një punonjës shkeli në cepin e saj, skajet e pllakës fërkoheshin me pllakat ngjitur. Me to fërkoheshin edhe pjesët plastike që lidhnin pllakat, gjë që shkaktoi mikroshkarkime statike që krijonin interferencë të radiofrekuencave.

Sot, RAM-i mbrohet shumë më mirë nga ndërhyrja e frekuencave radio. Por në ato vite nuk ishte kështu. Eksperti kuptoi se kjo ndërhyrje prishi kujtesën, dhe bashkë me të edhe funksionimin e sistemit operativ. Telefonoi shërbimin mbështetës, porositi pllaka të reja, i vendosi vetë dhe problemi u zhduk.

Është baticë e lartë!

Historia u zhvillua në një dhomë serveri, në katin e katërt ose të pestë të një zyre në Portsmouth (mendoj), në zonën e dokeve.

Një ditë serveri Unix me bazën e të dhënave kryesore u rrëzua. Ata e rifilluan atë, por ai i lumtur vazhdoi të binte pa pushim. Vendosëm të telefononim dikë nga shërbimi mbështetës.

Djaloshi mbështetës... Unë mendoj se quhej Mark, por kjo nuk ka rëndësi... Nuk mendoj se e njoh. Nuk ka rëndësi, me të vërtetë. Le të qëndrojmë me Markun, mirë? E madhe.

Kështu që, disa orë më vonë Mark mbërriti (nuk është një rrugë e gjatë nga Leeds në Portsmouth, ju e dini), ndezi serverin dhe gjithçka funksionoi pa probleme. Mbështetje tipike e mallkuar, klienti mërzitet shumë për këtë. Mark shikon nëpër skedarët e regjistrit dhe nuk gjen asgjë të pakëndshme. Kështu që Marku kthehet në tren (ose çfarëdo lloji transporti me të cilin mbërriti, mund të ishte një lopë e çalë për gjithçka që di... gjithsesi, nuk ka rëndësi, mirë?) dhe niset për në Leeds, pasi ka humbur dëm. Dita.

Po atë mbrëmje, serveri rrëzohet përsëri. Historia është e njëjtë... serveri nuk ngrihet. Mark përpiqet të ndihmojë nga distanca, por klienti nuk mund të nisë serverin.

Një tjetër tren, autobus, beze limoni ose ndonjë katrahurë tjetër, dhe Mark është kthyer në Portsmouth. Shikoni, serveri fillon pa asnjë problem! mrekulli. Marku kalon disa orë duke kontrolluar nëse gjithçka është në rregull me sistemin operativ ose softuerin dhe niset për në Leeds.

Rreth mesit të ditës serveri prishet (merreni lehtë!). Këtë herë duket e arsyeshme të sillni njerëz të mbështetjes harduerike për të zëvendësuar serverin. Por jo, pas rreth 10 orësh edhe bie.

Situata u përsërit për disa ditë. Serveri punon, prishet pas rreth 10 orësh dhe nuk fillon për 2 orët e ardhshme. Ata kontrolluan ftohjen, rrjedhjet e kujtesës, kontrolluan gjithçka, por nuk gjetën asgjë. Pastaj përplasjet u ndalën.

Java kaloi pa kujdes... të gjithë ishin të lumtur. Gëzuar derisa gjithçka të fillojë përsëri. Fotografia është e njëjtë. 10 orë punë, 2-3 orë pushim...

Dhe pastaj dikush (mendoj se më tha që ky person nuk kishte të bënte fare me IT) tha:

"Është batica!"

Pasthirrma u prit me shikime të zbrazëta dhe dora e dikujt ndoshta hezitoi te butoni i thirrjes së sigurisë.

"Ajo ndalon së punuari me valën."

Ky do të duket të jetë një koncept krejtësisht i huaj për punonjësit e mbështetjes së IT-së, të cilët nuk kanë gjasa të lexojnë Librin vjetor të Tide ndërsa ulen për kafe. Ata shpjeguan se kjo nuk mund të lidhej në asnjë mënyrë me valën, sepse serveri kishte punuar për një javë pa dështime.

“Javën e kaluar batica ishte e ulët, por këtë javë është e lartë.”

Pak terminologji për ata që nuk kanë patentë jahti. Baticat varen nga cikli hënor. Dhe ndërsa Toka rrotullohet, çdo 12,5 orë tërheqja gravitacionale e Diellit dhe Hënës krijon një valë baticore. Në fillim të ciklit 12,5 orësh ka një baticë të lartë, në mes të ciklit ka një zbaticë dhe në fund ka përsëri një baticë të lartë. Por me ndryshimin e orbitës së Hënës, ndryshon edhe ndryshimi midis baticës së ulët dhe asaj të lartë. Kur Hëna është midis Diellit dhe Tokës ose në anën e kundërt të Tokës (hëna e plotë ose pa hënë), marrim baticat Syzygyn - baticat më të larta dhe baticat më të ulëta. Në gjysmë hëne ne marrim baticat kuadratike - baticat më të ulëta. Dallimi midis dy ekstremeve zvogëlohet shumë. Cikli hënor zgjat 28 ditë: syzygian - kuadraturë - syzygian - kuadraturë.

Kur teknikëve iu shpjegua thelbi i forcave të baticës, ata menduan menjëherë se duhej të thërrisnin policinë. Dhe mjaft logjike. Por rezulton se tipi kishte të drejtë. Dy javë më parë, një shkatërrues u ankorua jo shumë larg zyrës. Sa herë që batica e ngrinte atë në një lartësi të caktuar, posti i radarit të anijes përfundonte në nivelin e dyshemesë së dhomës së serverit. Dhe radari (ose pajisjet e luftës elektronike, ose ndonjë lodër tjetër ushtarake) krijuan kaos në kompjuterë.

Misioni i fluturimit për raketën

Unë kisha për detyrë të transferoja një sistem kontrolli dhe monitorimi të lëshimit të raketave të mëdha (rreth 400 mijë rreshta) në versionet e reja të sistemit operativ, përpiluesit dhe gjuhës. Më saktësisht, nga Solaris 2.5.1 në Solaris 7, dhe nga Verdix Ada Development System (VADS), i shkruar në Ada 83, tek sistemi Rational Apex Ada, i shkruar në Ada 95. VADS është blerë nga Rational, dhe produkti i tij ishte i vjetëruar, megjithëse Rational u përpoq të zbatonte versione të pajtueshme të paketave specifike VADS për të lehtësuar kalimin në përpiluesin Apex.

Tre persona më ndihmuan që thjesht të përpiloja kodin pastër. U deshën dy javë. Dhe pastaj punova vetë për ta bërë sistemin të funksionojë. Me pak fjalë, ishte arkitektura dhe zbatimi më i keq i një sistemi softuerësh që kisha hasur, kështu që u deshën edhe dy muaj të tjerë për të përfunduar portin. Sistemi më pas u dorëzua për testim, i cili zgjati disa muaj të tjerë. I korrigjova menjëherë gabimet që u gjetën gjatë testimit, por numri i tyre u ul shpejt (kodi burimor ishte një sistem prodhimi, kështu që funksionaliteti i tij funksionoi mjaft i besueshëm, thjesht më duhej të hiqja defektet që u shfaqën gjatë përshtatjes me përpiluesin e ri). Përfundimisht, kur gjithçka po funksiononte siç duhej, u transferova në një projekt tjetër.

Dhe të premten para Ditës së Falënderimeve, ra telefoni.

Lëshimi i raketës supozohej të testohej në rreth tre javë, dhe gjatë testeve laboratorike të numërimit mbrapsht, sekuenca e komandave u bllokua. Në jetën reale, kjo do ta anulonte testin dhe nëse bllokimi ndodhte brenda pak sekondave nga ndezja e motorit, do të ndodhnin disa veprime të pakthyeshme në sistemet ndihmëse, të cilat do të kërkonin një gatishmëri të gjatë - dhe të shtrenjtë - të raketës. Nuk do të kishte filluar, por shumë njerëz do të ishin mërzitur shumë për humbjen e kohës dhe shumë, shumë para. Mos lejoni askënd t'ju thotë se Departamenti i Mbrojtjes shpenzon para në mënyrë të pamatur - nuk kam takuar kurrë një menaxher kontraktues që nuk e ka vënë buxhetin në radhë të parë ose të dytë, të ndjekur nga orari.

Në muajt e kaluar, kjo sfidë numërimi mbrapsht ishte drejtuar qindra herë në shumë variacione, me vetëm disa lemza të vogla. Pra, gjasat që kjo të ndodhte ishte shumë e ulët, por pasojat e saj ishin shumë domethënëse. Shumëzojini të dy këta faktorë dhe do të kuptoni se lajmet parashikuan një javë pushimi të shkatërruar për mua dhe dhjetëra inxhinierë e drejtues.

Dhe mua më është kushtuar vëmendje si personi që ka bartur sistemin.

Ashtu si me shumicën e sistemeve kritike për sigurinë, shumë parametra u regjistruan, kështu që ishte mjaft e lehtë të identifikoheshin disa rreshta kodi që u ekzekutuan përpara se sistemi të rrëzohej. Dhe sigurisht, nuk kishte absolutisht asgjë të pazakontë rreth tyre; të njëjtat shprehje ishin ekzekutuar me sukses fjalë për fjalë mijëra herë gjatë të njëjtit vrap.

Ne i thirrëm njerëzit nga Apex në Rational sepse ishin ata që zhvilluan përpiluesin dhe disa nga rutinat që ata zhvilluan u thirrën në kodin e dyshimtë. Atyre (dhe të gjithë të tjerëve) u bëri përshtypje se ishte nevoja për të hyrë në rrënjë të një problemi me rëndësi fjalë për fjalë kombëtare.

Meqenëse nuk kishte asgjë interesante në revista, vendosëm të përpiqeshim ta riprodhonim problemin në një laborator lokal. Kjo nuk ishte një detyrë e lehtë pasi ngjarja ndodhte afërsisht një herë në 1000 vrapime. Një arsye e dyshuar ishte se një thirrje për një funksion mutex të zhvilluar nga shitësi (pjesë e paketës së migrimit VADS) Unlock nuk çoi në zhbllokim. Fijet e përpunimit që thirrën funksionin përpunuan mesazhet e rrahjeve të zemrës, të cilat nominalisht vinin çdo sekondë. E ngritëm frekuencën në 10 Hz, domethënë 10 herë në sekondë dhe filluam të vrapojmë. Rreth një orë më vonë sistemi u mbyll në vetvete. Në regjistër, pamë se sekuenca e mesazheve të regjistruara ishte e njëjtë si gjatë testit të dështuar. Ne bëmë disa vrapime të tjera, sistemi u bllokua vazhdimisht 45-90 minuta pas fillimit, dhe çdo herë regjistri përmbante të njëjtën rrugë. Edhe pse teknikisht përdornim kode të ndryshme - frekuenca e mesazheve ishte e ndryshme - sjellja e sistemit ishte e njëjtë, kështu që ne ishim të sigurt se ky skenar i ngarkimit po shkaktonte të njëjtin problem.

Tani na duhej të kuptonim se ku ndodhi saktësisht bllokimi në sekuencën e shprehjeve.

Ky implementim i sistemit përdori sistemin e detyrave Ada dhe e përdori atë jashtëzakonisht dobët. Detyrat janë një konstrukt i ekzekutueshëm njëkohësisht i nivelit të lartë në Ada, diçka si fijet e ekzekutimit, të integruara vetëm në vetë gjuhën. Kur dy detyra duhet të komunikojnë, ata "caktojnë një takim", shkëmbejnë të dhënat e nevojshme dhe më pas ndalojnë takimin dhe kthehen në ekzekutimet e tyre të pavarura. Megjithatë, sistemi u zbatua ndryshe. Pasi një detyrë e synuar ishte takim, ajo detyrë e synuar u takua me një detyrë tjetër, e cila më pas u takua me një detyrë të tretë, dhe kështu me radhë derisa të përfundonte disa përpunime. Pas kësaj, të gjitha këto takime u kryen dhe secila detyrë duhej të kthehej në ekzekutimin e saj. Domethënë, kishim të bënim me sistemin më të shtrenjtë të thirrjes së funksionit në botë, i cili ndaloi të gjithë procesin e “multitasking” ndërkohë që përpunonte një pjesë të të dhënave hyrëse. Dhe më parë kjo nuk çoi në probleme vetëm sepse xhiroja ishte shumë e ulët.

E përshkrova këtë mekanizëm të detyrës sepse kur kërkohej ose pritej të përfundonte një takim, mund të ndodhte një "ndërrim i detyrës". Kjo do të thotë, procesori mund të fillojë të përpunojë një detyrë tjetër që është gati për t'u ekzekutuar. Rezulton se kur një detyrë është gati për t'u takuar me një detyrë tjetër, një detyrë krejtësisht e ndryshme mund të fillojë të ekzekutohet dhe përfundimisht kontrolli kthehet në takimin e parë. Dhe mund të ndodhin ngjarje të tjera që shkaktojnë ndryshimin e detyrës; një ngjarje e tillë është një thirrje për një funksion të sistemit, të tilla si printimi ose ekzekutimi i një mutex.

Për të kuptuar se cila linjë kodi po shkaktonte problemin, më duhej të gjeja një mënyrë për të regjistruar përparimin përmes një sekuence deklaratash pa shkaktuar një ndërprerës detyrash, i cili do të parandalonte një përplasje. Kështu që nuk mund të përfitoja Put_Line()për të shmangur kryerjen e operacioneve I/O. Mund të vendos një variabël numërues ose diçka të ngjashme, por si mund ta shoh vlerën e saj nëse nuk mund ta shfaq në ekran?

Gjithashtu, gjatë ekzaminimit të regjistrit, rezultoi se, pavarësisht ngrirjes së përpunimit të mesazheve të rrahjeve të zemrës, që bllokonte të gjitha operacionet hyrëse/dalëse të procesit dhe pengonte kryerjen e përpunimeve të tjera, vazhduan të kryheshin detyra të tjera të pavarura. Domethënë, puna nuk u bllokua tërësisht, vetëm një zinxhir (kritik) detyrash.

Kjo ishte e dhëna e nevojshme për të vlerësuar shprehjen bllokuese.

Unë bëra një paketë Ada që përmbante një detyrë, një lloj të numëruar dhe një ndryshore globale të atij lloji. Literale të shumta ishin të lidhura me shprehje specifike të sekuencës problematike (p.sh. Incrementing_Buffer_Index, Locking_Mutex, Mutex_Unlocked), dhe më pas futi shprehjet e caktimit në të që i caktonin numërimin përkatës një ndryshoreje globale. Meqenëse kodi i objektit të gjithë kësaj thjesht ruante një konstante në memorie, ndërrimi i detyrave si rezultat i ekzekutimit të tij ishte jashtëzakonisht i pamundur. Ne ishim kryesisht të dyshimtë për shprehjet që mund të ndërronin detyrën, pasi bllokimi ndodhi në ekzekutim në vend që të kthehej kur e kthenim detyrën përsëri (për disa arsye).

Detyra e gjurmimit thjesht u zhvillua në një cikli dhe kontrollohej periodikisht për të parë nëse vlera e ndryshores globale kishte ndryshuar. Me çdo ndryshim, vlera u ruajt në një skedar. Pastaj një pritje e shkurtër dhe një kontroll i ri. E shkrova variablin në skedar sepse detyra u ekzekutua vetëm kur sistemi e zgjidhte atë për ekzekutim kur ndërronte detyrën në zonën e problemit. Çfarëdo që të ndodhte në këtë detyrë nuk do të ndikonte në detyra të tjera të bllokuara pa lidhje.

Pritej që kur sistemi të arrinte në pikën e ekzekutimit të kodit problematik, ndryshorja globale do të rivendosej kur kalonte në çdo shprehje tjetër. Atëherë do të ndodhë diçka që shkakton ndërrimin e detyrës dhe meqenëse frekuenca e ekzekutimit të saj (10 Hz) është më e ulët se ajo e detyrës së monitorimit, monitori mund të kapë vlerën e ndryshores globale dhe ta shkruajë atë. Në një situatë normale, unë mund të marr një sekuencë të përsëritur të një nëngrupi numërimesh: vlerat e fundit të ndryshores në kohën e ndërrimit të detyrës. Kur varet, ndryshorja globale nuk duhet të ndryshojë më dhe vlera e fundit e shkruar do të tregojë se cila shprehje nuk ka përfunduar.

Kam përdorur kodin me gjurmim. Ai ngriu. Dhe monitorimi funksiononte si orë.

Regjistri përmbante sekuencën e pritur, e cila u ndërpre nga një vlerë që tregon se ishte thirrur një mutex Unlock, dhe detyra nuk është përfunduar - siç është rasti me mijëra thirrje të mëparshme.

Inxhinierët e Apex po analizonin me ethe kodin e tyre në këtë kohë dhe gjetën një vend në mutex ku, teorikisht, mund të ndodhte një bllokim. Por probabiliteti i tij ishte shumë i ulët, pasi vetëm një sekuencë e caktuar ngjarjesh që ndodhin në një kohë të caktuar mund të çonte në bllokim. Ligji i Murfit, djema, është ligji i Murfit.

Për të mbrojtur pjesën e kodit që më duhej, zëvendësova thirrjet e funksionit mutex (të ndërtuara në krye të funksionalitetit mutex OS) me një paketë të vogël vendase Ada mutex për të kontrolluar aksesin mutex në atë pjesë.

E futa në kod dhe bëra testin. Shtatë orë më vonë kodi ishte ende duke punuar.

Kodi im u dërgua në Rational, ku ata e përpiluan atë, e çmontuan dhe kontrolluan që nuk përdorte të njëjtën qasje që përdorej në funksionet problematike mutex.

Ky ishte rishikimi më i ngarkuar i kodit në karrierën time 🙂 Kishte rreth dhjetë inxhinierë dhe menaxherë në dhomë me mua, dhjetë persona të tjerë ishin në një telefonatë konferencë - dhe të gjithë ekzaminuan rreth 20 rreshta kodi.

Kodi u rishikua, skedarët e rinj të ekzekutueshëm u grumbulluan dhe u dorëzuan për testim formal të regresionit. Disa javë më vonë, testi i numërimit mbrapsht ishte i suksesshëm dhe raketa u ngrit.

Mirë, kjo është e gjitha mirë dhe mirë, por cili është thelbi i historisë?

Ishte një problem absolutisht i neveritshëm. Qindra mijëra rreshta kodi, ekzekutim paralel, mbi një duzinë procesesh ndërvepruese, arkitekturë e dobët dhe zbatim i dobët, ndërfaqe për sisteme të integruara dhe miliona dollarë të shpenzuara. Pa presion, apo jo.

Nuk isha i vetmi që punoja për këtë problem, megjithëse isha në qendër të vëmendjes teksa po bëja portimin. Por edhe pse e bëra këtë, kjo nuk do të thotë se i kuptova të gjitha qindra mijëra rreshtat e kodit, apo edhe i shkrova ato. Kodi dhe regjistrat u analizuan nga inxhinierë në të gjithë vendin, por kur më thanë hipotezat e tyre për shkaqet e dështimit, m'u desh vetëm gjysmë minute për t'i hedhur poshtë. Dhe kur më kërkonin të analizoja teoritë, ia kaloja dikujt tjetër, sepse ishte e qartë për mua që këta inxhinierë po shkonin në rrugën e gabuar. Tingëllon mendjemadh? Po, kjo është e vërtetë, por unë i hodha hipotezat dhe kërkesat për një arsye tjetër.

E kuptova natyrën e problemit. Nuk e dija saktësisht se ku po ndodhte dhe pse, por e dija se çfarë po ndodhte.

Me kalimin e viteve, kam grumbulluar shumë njohuri dhe përvojë. Unë isha një nga pionierët e përdorimit të Ada-s dhe kuptova avantazhet dhe disavantazhet e saj. Unë e di se si bibliotekat e kohës së funksionimit Ada trajtojnë detyrat dhe merren me ekzekutimin paralel. Dhe unë e kuptoj programimin e nivelit të ulët në nivelin e memories, regjistrave dhe asemblerit. Me fjalë të tjera, kam njohuri të thella në fushën time. Dhe i përdora për të gjetur shkakun e problemit. Unë nuk punova vetëm me problemin, por kuptova se si ta gjeja atë në një mjedis shumë të ndjeshëm të ekzekutimit.

Histori të tilla të luftës me kodin nuk janë shumë interesante për ata që nuk janë të njohur me tiparet dhe kushtet e një lufte të tillë. Por këto histori na ndihmojnë të kuptojmë se çfarë nevojitet për të zgjidhur probleme vërtet të vështira.

Për të zgjidhur probleme vërtet të vështira, ju duhet të jeni më shumë se thjesht një programues. Ju duhet të kuptoni "fatin" e kodit, si ndërvepron me mjedisin e tij dhe si funksionon vetë mjedisi.

Dhe atëherë do të keni javën tuaj të rrënuar të pushimeve.

Të vazhdohet.

Burimi: www.habr.com

Shto një koment