Ծրագրավորողների և ճարտարագետների բանահյուսություն (մաս 1)

Ծրագրավորողների և ճարտարագետների բանահյուսություն (մաս 1)

Սա համացանցից պատմությունների ընտրանի է այն մասին, թե ինչպես են սխալները երբեմն ունենում բոլորովին անհավանական դրսևորումներ: Երևի դու էլ պատմելու բան ունես։

Ավտոմեքենայի ալերգիա վանիլային պաղպաղակի նկատմամբ

Պատմություն ինժեներների համար, ովքեր հասկանում են, որ ակնհայտը միշտ չէ, որ պատասխանն է, և որ անկախ նրանից, թե որքան հեռու են փաստերը, այնուամենայնիվ, դրանք փաստեր են: General Motors Corporation-ի Pontiac բաժինը բողոք է ստացել.

Արդեն երկրորդ անգամն է, որ գրում եմ քեզ, և չեմ մեղադրում չպատասխանելու համար, որովհետև դա խենթ է թվում: Մեր ընտանիքում ավանդույթ կա ամեն երեկո ճաշից հետո պաղպաղակ ուտելու: Պաղպաղակի տեսակներն ամեն անգամ փոխվում են, իսկ ընթրիքից հետո ամբողջ ընտանիքն է ընտրում, թե որ պաղպաղակն է գնել, որից հետո ես գնում եմ խանութ։ Ես վերջերս նոր «Պոնտիակ» գնեցի, և այդ ժամանակից ի վեր պաղպաղակ ձեռք բերելու իմ ճամփորդությունները խնդիր են դարձել: Հասկանում եք, ամեն անգամ, երբ ես վանիլային պաղպաղակ եմ գնում և խանութից վերադառնում, մեքենան չի շարժվում։ Եթե ​​ես ինչ-որ այլ պաղպաղակ բերեմ, մեքենան առանց խնդրի միանում է։ Ուզում եմ լուրջ հարց տալ, որքան էլ հիմարություն հնչի. «Ի՞նչն է Pontiac-ի մասին, որը ստիպում է այն չսկսել, երբ ես վանիլային պաղպաղակ եմ բերում, բայց հեշտ է սկսվում, երբ ես բերում եմ մեկ այլ համով պաղպաղակ»:

Ինչպես կարող եք պատկերացնել, բաժնի նախագահը թերահավատորեն էր վերաբերվում նամակին։ Սակայն, ամեն դեպքում, ես ինժեներ ուղարկեցի ստուգելու։ Նա զարմացավ, որ իրեն հանդիպեց մի հարուստ, լավ կրթված մարդ, որն ապրում էր գեղեցիկ տարածքում։ Նրանք պայմանավորվեցին ճաշից անմիջապես հետո հանդիպել, որպեսզի երկուսով գնային խանութ պաղպաղակի։ Այդ երեկո վանիլ էր, և երբ նրանք վերադարձան մեքենա, այն չէր սկսվում:

Ինժեները եկավ ևս երեք երեկո։ Առաջին անգամ պաղպաղակը շոկոլադ էր։ Մեքենան շարժվեց։ Երկրորդ անգամ ելակի պաղպաղակ կար։ Մեքենան շարժվեց։ Երրորդ երեկոյան նա խնդրեց վերցնել վանիլին։ Մեքենան չաշխատեց։

Ռացիոնալ պատճառաբանելով՝ ինժեները հրաժարվեց հավատալ, որ մեքենան ալերգիկ է վանիլային պաղպաղակից։ Ուստի մեքենայի տիրոջ հետ պայմանավորվել եմ, որ նա կշարունակի իր այցելությունները, քանի դեռ չի գտել խնդրի լուծումը։ Ու ճանապարհին նա սկսեց գրառումներ անել՝ գրի էր առնում ամբողջ տեղեկատվությունը, օրվա ժամը, բենզինի տեսակը, խանութից ժամանման և վերադարձի ժամը և այլն։

Ինժեները շուտով հասկացավ, որ մեքենայի տերն ավելի քիչ ժամանակ է ծախսում վանիլային պաղպաղակ գնելու վրա։ Պատճառը խանութում ապրանքների դասավորությունն էր։ Վանիլային պաղպաղակն ամենահայտնին էր և պահվում էր խանութի դիմացի առանձին սառցախցիկում, որպեսզի ավելի հեշտ գտնվի: Իսկ մնացած բոլոր սորտերը խանութի ետնամասում էին, և շատ ավելի շատ ժամանակ պահանջվեց ճիշտ տեսականի գտնելու և վճարելու համար:

Հիմա հարցը ինժեներինն էր. ինչո՞ւ մեքենան չգործարկվեց, եթե շարժիչն անջատելու պահից քիչ ժամանակ է անցել: Քանի որ խնդիրը ժամանակն էր, ոչ թե վանիլային պաղպաղակը, ինժեներն արագ գտավ պատասխանը՝ դա գազի կողպեք էր։ Դա տեղի էր ունենում ամեն երեկո, բայց երբ մեքենայի սեփականատերը ավելի շատ ժամանակ էր ծախսում պաղպաղակ փնտրելու համար, շարժիչը կարողացավ բավականաչափ սառչել և հեշտությամբ գործարկվել: Իսկ երբ տղամարդը վանիլային պաղպաղակ գնեց, շարժիչը դեռ շատ տաք էր, և գազի կողպեքը չէր հասցրել լուծարվել։

Բարոյականություն. Նույնիսկ ամբողջովին խելագար խնդիրները երբեմն իրական են:

Crash Bandicoot

Ցավալի է դա զգալը: Որպես ծրագրավորող՝ դու սովոր ես մեղադրել քո կոդը առաջին, երկրորդ, երրորդ... և ինչ-որ տեղ տասը հազարերորդ տեղում մեղադրում ես կոմպիլյատորին։ Եվ ավելի ուշ ցուցակում դուք արդեն մեղադրում եք սարքավորումներին:

Ահա իմ պատմությունը ապարատային սխալի մասին:

Crash Bandicoot խաղի համար ես գրել եմ կոդ՝ բեռնելու և հիշաքարտի վրա պահելու համար։ Նման ինքնագոհ խաղեր մշակողի համար դա նման էր զբոսանքի այգում. կարծում էի, որ աշխատանքը մի քանի օր կտևի: Այնուամենայնիվ, ես ավարտեցի վեց շաբաթվա ընթացքում ծածկագրի վրիպազերծումը: Ճանապարհին ես լուծում էի այլ խնդիրներ, բայց մի քանի օրը մեկ մի քանի ժամով վերադառնում էի այս ծածկագրին։ Դա տանջանք էր:

Ախտանիշն այսպիսի տեսք ուներ. երբ դուք պահպանում եք խաղի ընթացիկ փուլը և մուտք եք գործում հիշողության քարտ, ամեն ինչ գրեթե միշտ լավ է ընթանում... Բայց երբեմն կարդալու կամ գրելու գործողության ժամանակն անցնում է առանց որևէ ակնհայտ պատճառի: Կարճ ձայնագրությունը հաճախ վնասում է հիշողության քարտը: Երբ խաղացողը փորձում է փրկել, նա ոչ միայն չի կարողանում փրկել, այլև քանդում է քարտեզը: Խեղճ.

Որոշ ժամանակ անց Sony-ի մեր պրոդյուսեր Քոննի Բասը սկսեց խուճապի մատնվել։ Մենք չկարողացանք խաղը ուղարկել այս սխալի հետ, և վեց շաբաթ անց ես չհասկացա, թե ինչն էր առաջացնում խնդիրը: Connie-ի միջոցով մենք կապվեցինք PS1-ի այլ մշակողների հետ. որևէ մեկը նման բանի հանդիպե՞լ է: Ոչ Հիշողության քարտի հետ ոչ ոք խնդիր չի ունեցել։

Երբ վրիպազերծման գաղափարներ չունեք, միակ մոտեցումը մնում է «բաժանել և նվաճել»՝ ավելի ու ավելի շատ կոդ հեռացնել անսարք ծրագրից, մինչև մնա համեմատաբար փոքր հատված, որը դեռ առաջացնում է խնդիրը: Այսինքն, դուք մաս առ մաս կտրում եք ծրագիրը, մինչև մնա այն մասը, որը պարունակում է սխալ:

Բայց բանն այն է, որ տեսախաղից կտորներ կտրելը շատ դժվար է: Ինչպե՞ս գործարկել այն, եթե հանել եք գրավիտացիայի նմանակող կոդը: Կամ կերպարներ նկարե՞լ։

Հետևաբար, մենք պետք է ամբողջ մոդուլները փոխարինենք կոճղերով, որոնք ձևացնում են, թե ինչ-որ օգտակար բան են անում, բայց իրականում անում են մի շատ պարզ բան, որը չի կարող սխալներ պարունակել: Պետք է այսպիսի հենակներ գրենք, որ խաղը գոնե աշխատի։ Սա դանդաղ ու ցավոտ գործընթաց է։

Մի խոսքով, ես դա արեցի: Ես հեռացնում էի ավելի ու ավելի շատ կոդի կտորներ, մինչև որ մնացի սկզբնական կոդը, որը կարգավորում է համակարգը խաղը գործարկելու համար, սկզբնավորում է մատուցման սարքավորումը և այլն: Իհարկե, այս փուլում ես չկարողացա ստեղծել պահման և բեռնման մենյու, քանի որ ես պետք է ստեղծեի անավարտ բոլոր գրաֆիկական կոդի համար: Բայց ես կարող էի ձևանալ, որ օգտատեր եմ, օգտագործելով (անտեսանելի) պահպանման և բեռնման էկրանը և խնդրել պահպանել, ապա գրել հիշողության քարտին:

Սա ինձ թողեց կոդի մի փոքրիկ կտոր, որը դեռևս ուներ վերը նշված խնդիրը, բայց այն դեռ պատահական էր: Շատ հաճախ ամեն ինչ լավ էր աշխատում, բայց երբեմն խափանումներ էին լինում: Ես հանեցի գրեթե բոլոր խաղի կոդը, բայց սխալը դեռ կենդանի էր: Սա տարակուսելի էր. մնացած կոդը իրականում ոչինչ չէր անում:

Ինչ-որ պահի, հավանաբար գիշերվա երեքին մոտ, մի միտք ծագեց գլխումս. Կարդալու և գրելու (մուտքային/ելք) գործողությունները ներառում են կատարման ճշգրիտ ժամանակներ: Երբ աշխատում եք կոշտ սկավառակի, հիշողության քարտի կամ Bluetooth մոդուլի հետ, կարդալու և գրելու համար պատասխանատու ցածր մակարդակի կոդը դա անում է ժամացույցի իմպուլսներին համապատասխան:

Ժամացույցի օգնությամբ սարքը, որն ուղղակիորեն կապված չէ պրոցեսորին, համաժամացվում է պրոցեսորի վրա կատարվող կոդի հետ։ Ժամացույցը որոշում է բուդ արագությունը՝ տվյալների փոխանցման արագությունը: Եթե ​​ժամանակացույցի հետ շփոթություն կա, ապա կա՛մ ապարատը, կա՛մ ծրագրաշարը, կա՛մ երկուսն էլ նույնպես շփոթված են: Եվ սա շատ վատ է, քանի որ տվյալները կարող են վնասվել։

Ի՞նչ անել, եթե մեր օրենսգրքում ինչ-որ բան շփոթում է ժամկետները: Ես ստուգեցի դրա հետ կապված ամեն ինչ փորձարկման ծրագրի կոդում և նկատեցի, որ PS1-ում ծրագրավորվող ժմչփը սահմանել ենք 1 կՀց (1000 տիզ վայրկյանում): Սա բավականին շատ է, լռելյայն, երբ վահանակը միանում է, այն աշխատում է 100 Հց հաճախականությամբ: Եվ խաղերի մեծ մասը օգտագործում է այս հաճախականությունը:

Խաղի մշակող Էնդին ժմչփը դրեց 1 կՀց, որպեսզի շարժումներն ավելի ճշգրիտ հաշվարկվեն: Էնդին հակված է չափն անցնելու, և եթե մենք ընդօրինակում ենք գրավիտացիան, մենք դա անում ենք հնարավորինս ճշգրիտ:

Բայց ի՞նչ կլիներ, եթե ժմչփի արագացումն ինչ-որ կերպ ազդեր ծրագրի ընդհանուր ժամանակի վրա, հետևաբար՝ ժամացույցի վրա, որը կարգավորում է հիշողության քարտի բուդի արագությունը:

Ես մեկնաբանեցի ժամանակաչափի կոդը: Սխալն այլևս չի առաջացել: Բայց դա չի նշանակում, որ մենք դա շտկել ենք, քանի որ ձախողումը պատահական է եղել։ Իսկ եթե ես ուղղակի բախտ ունենայի:

Մի քանի օր անց ես նորից փորձարկեցի թեստային ծրագիրը: Սխալը չի ​​կրկնվել: Ես վերադարձա խաղի ամբողջական կոդերի բազան և փոփոխեցի պահման և բեռնման ծածկագիրը, որպեսզի ծրագրավորվող ժամանակաչափը վերականգներ իր սկզբնական արժեքը (100 Հց) մինչև հիշողության քարտ մուտք գործելը, այնուհետև վերականգնվեր մինչև 1 կՀց: Այլևս վթարներ չեն եղել:

Բայց ինչո՞ւ դա տեղի ունեցավ։

Ես նորից վերադարձա թեստային ծրագրին։ Ես փորձեցի 1 կՀց ժմչփով սխալի առաջացման որոշ օրինաչափություն գտնել: Ի վերջո, ես նկատեցի, որ սխալը տեղի է ունենում, երբ ինչ-որ մեկը խաղում է PS1 կարգավորիչով: Քանի որ ես ինքս հազվադեպ էի դա անում, ինչո՞ւ ինձ պետք է վերահսկիչ պահման և բեռնման կոդը փորձարկելիս: - Ես նույնիսկ չեմ նկատել այս կախվածությունը: Բայց մի օր մեր արտիստներից մեկը սպասում էր, թե երբ կավարտեմ թեստավորումը - երևի այդ պահին հայհոյում էի - և նյարդայնացած պտտեց հսկիչը ձեռքերում: Սխալ է տեղի ունեցել. "Սպասեք ինչ?!" Դե, նորից արա»։

Երբ ես հասկացա, որ այս երկու իրադարձությունները փոխկապակցված են, ես կարողացա հեշտությամբ վերարտադրել սխալը. ես սկսեցի ձայնագրել հիշողության քարտի վրա, տեղափոխեցի կարգավորիչը և փչացրեցի հիշողության քարտը: Ինձ համար դա կարծես ապարատային սխալ էր:

Ես եկա Քոնիի մոտ և պատմեցի իմ հայտնագործության մասին։ Նա տեղեկությունը փոխանցեց PS1-ը նախագծող ինժեներներից մեկին: «Անհնար է», - պատասխանեց նա, «դա չի կարող լինել ապարատային խնդիր»: Ես խնդրեցի Քոնիին մեզ համար զրույց կազմակերպել։

Ինժեները կանչեց ինձ, և մենք վիճեցինք նրա կոտրված անգլերենով և իմ (չափազանց) կոտրված ճապոներենով։ Վերջապես ես ասացի. «Թույլ տվեք ուղարկել իմ 30 տողով թեստային ծրագիրը, որտեղ կարգավորիչը տեղափոխելը սխալ է առաջացնում»: Նա համաձայնեց։ Ասաց, որ դա ժամանակի վատնում է, և որ ինքը սարսափելի զբաղված է նոր նախագծի վրա աշխատելով, բայց կհանձնվի, քանի որ մենք շատ կարևոր ծրագրավորող ենք Sony-ի համար: Ես մաքրեցի իմ թեստային ծրագիրը և ուղարկեցի նրան:

Հաջորդ օրը երեկոյան (մենք Լոս Անջելեսում էինք, իսկ նա՝ Տոկիոյում) նա զանգահարեց ինձ և ողորմորեն ներողություն խնդրեց։ Դա ապարատային խնդիր էր։

Ես չգիտեմ, թե կոնկրետ ինչ սխալ է եղել, բայց այն, ինչ ես լսել եմ Sony-ի գլխավոր գրասենյակում, եթե ժմչփը բավականաչափ բարձր արժեք եք դնում, այն խանգարում է մայր տախտակի բաղադրիչներին, որոնք գտնվում են ժամանակաչափի բյուրեղի մոտակայքում: Դրանցից մեկը հիշողության քարտի բուդ արագության կարգավորիչն էր, որը սահմանում էր նաև կարգավորիչների համար բուդ արագությունը: Ես ինժեներ չեմ, ուստի կարող էի ինչ-որ բան խառնել:

Բայց հիմնականն այն է, որ մայր տախտակի բաղադրիչների միջև միջամտություն է եղել: Իսկ վերահսկիչի պորտի և հիշողության քարտի պորտի միջոցով միաժամանակ 1 կՀց հաճախականությամբ ժմչփով տվյալներ փոխանցելիս բիթերը կորչում էին, տվյալները կորչում և քարտը վնասվում:

Վատ կովեր

1980-ականներին իմ դաստիարակ Սերգեյը ծրագրային ապահովում է գրել SM-1800-ի համար՝ PDP-11-ի խորհրդային կլոնի համար: Այս միկրոհամակարգիչը նոր է տեղադրվել Սվերդլովսկի մոտ գտնվող երկաթուղային կայարանում, որը ԽՍՀՄ-ում կարևոր տրանսպորտային հանգույց է: Նոր համակարգը նախատեսված էր վագոնների և բեռնափոխադրումների ուղղորդման համար: Բայց այն պարունակում էր անհանգստացնող սխալ, որը հանգեցրեց պատահական վթարների և վթարների: Ընկնելը միշտ լինում էր, երբ ինչ-որ մեկը տուն էր գնում երեկոյան: Բայց չնայած հաջորդ օրը մանրակրկիտ հետաքննությանը, համակարգիչը ճիշտ է աշխատել բոլոր ձեռքով և ավտոմատ թեստերում: Սա սովորաբար ցույց է տալիս մրցավազքի վիճակ կամ մրցակցային այլ սխալ, որը տեղի է ունենում որոշակի պայմաններում: Գիշերը ուշ ժամերին զանգերից հոգնած Սերգեյը որոշեց խորանալ և առաջին հերթին հասկանալ, թե մարշալինգի բակում ինչ պայմաններ են հանգեցրել համակարգչի խափանմանը:

Նախ, նա հավաքեց բոլոր անբացատրելի անկումների վիճակագրությունը և ստեղծեց գրաֆիկ ըստ ամսաթվի և ժամի: Կաղապարն ակնհայտ էր. Եվս մի քանի օր դիտարկելուց հետո Սերգեյը հասկացավ, որ հեշտությամբ կարող է կանխատեսել ապագա համակարգի խափանումների ժամանակը։

Շուտով նա իմացավ, որ խափանումները տեղի են ունեցել միայն այն ժամանակ, երբ կայանը տեսակավորում էր հյուսիսային Ուկրաինայից և արևմտյան Ռուսաստանից անասունների գնացքները, որոնք շարժվում էին դեպի մոտակա սպանդանոց: Սա ինքնին տարօրինակ էր, քանի որ սպանդանոցը մատակարարվում էր շատ ավելի մոտ՝ Ղազախստանում գտնվող գյուղացիական տնտեսություններից։

Չեռնոբիլի ատոմակայանը պայթեց 1986 թվականին, և ռադիոակտիվ արտանետումները շրջակա տարածքները դարձրեցին անմարդաբնակ։ Ուկրաինայի հյուսիսում, Բելառուսում և Ռուսաստանի արևմտյան մասում հսկայական տարածքներ աղտոտված են: Կասկածելով ժամանող վագոններում ճառագայթման բարձր մակարդակ՝ Սերգեյը մշակեց այս տեսությունը ստուգելու մեթոդ։ Բնակչությանը արգելված էր դոզաչափեր ունենալ, ուստի Սերգեյը մի քանի զինվորականների հետ գրանցվեց երկաթուղային կայարանում։ Մի քանի անգամ օղի խմելուց հետո նրան հաջողվել է զինվորին համոզել կասկածելի վագոններից մեկում չափել ճառագայթման մակարդակը։ Պարզվել է, որ մակարդակը մի քանի անգամ բարձր է նորմալ արժեքներից։

Անասունը ոչ միայն շատ ճառագայթում էր արձակում, այլև դրա մակարդակն այնքան բարձր էր, որ դա հանգեցրեց SM-1800-ի հիշողության բիթերի պատահական կորստի, որը գտնվում էր կայանի հարևանությամբ գտնվող շենքում:

ԽՍՀՄ-ում սննդի պակաս կար, և իշխանությունները որոշեցին Չեռնոբիլի միսը խառնել երկրի այլ շրջանների մսի հետ։ Դա հնարավորություն տվեց նվազեցնել ռադիոակտիվության ընդհանուր մակարդակը՝ առանց արժեքավոր ռեսուրսների կորստի։ Տեղեկանալով այս մասին՝ Սերգեյն անմիջապես լրացրեց արտագաղթի փաստաթղթերը։ Իսկ համակարգչի խափանումներն ինքնուրույն դադարեցին, երբ ժամանակի ընթացքում ճառագայթման մակարդակը նվազեց:

Խողովակների միջով

Ժամանակին Movietech Solutions-ը ծրագրային ապահովում էր ստեղծել կինոթատրոնների համար, որոնք նախատեսված էին հաշվապահական հաշվառման, տոմսերի վաճառքի և ընդհանուր կառավարման համար: Ֆլագման հավելվածի DOS տարբերակը բավականին տարածված էր Հյուսիսային Ամերիկայի փոքր և միջին չափի կինոթատրոնների ցանցերում: Ուստի զարմանալի չէ, որ երբ հայտարարվեց Windows 95-ի տարբերակը, որը ինտեգրված էր վերջին սենսորային էկրաններին և ինքնասպասարկման կրպակներին և հագեցած էր հաշվետվությունների բոլոր տեսակի գործիքներով, այն նույնպես արագորեն հայտնի դարձավ: Ամենից հաճախ թարմացումն անցել է առանց խնդիրների: Տեղի ՏՏ անձնակազմը տեղադրեց նոր սարքավորումներ, տեղափոխեց տվյալները, և բիզնեսը շարունակվեց: Բացառությամբ այն դեպքերի, երբ դա չտեւեց: Երբ դա տեղի ունեցավ, ընկերությունը կուղարկեր Ջեյմսին, որը մականունով էր «Մաքրողը»:

Թեև մականունը ենթադրում է անպիտան տեսակ, մաքրող սարքը պարզապես հրահանգիչի, տեղադրողի և բոլոր արհեստավորների համադրություն է: Ջեյմսը մի քանի օր կանցկացնի հաճախորդի կայքում՝ միացնելով բոլոր բաղադրիչները, իսկ հետո ևս մի քանի օր կանցկացնի անձնակազմին սովորեցնելով, թե ինչպես օգտագործել նոր համակարգը՝ լուծելով ծագած ապարատային խնդիրները և, ըստ էության, օգնելով ծրագրային ապահովմանը իր սկզբնական շրջանում:

Հետևաբար, զարմանալի չէ, որ այս բուռն ժամանակներում Ջեյմսը առավոտյան ժամանեց գրասենյակ, և մինչ կհասներ իր գրասեղանին, նրան դիմավորեց մենեջերը՝ սովորականից ավելի կոֆեինով լցված։

«Ես վախենում եմ, որ դուք պետք է գնաք Աննապոլիս, Նոր Շոտլանդիա, որքան հնարավոր է շուտ»: Նրանց ամբողջ համակարգը խափանվեց, և նրանց ինժեներների հետ մեկ գիշեր աշխատելուց հետո մենք չենք կարող պարզել, թե ինչ է տեղի ունեցել: Կարծես սերվերում ցանցը ձախողվել է: Բայց միայն այն բանից հետո, երբ համակարգը մի քանի րոպե աշխատել է:

- Նրանք չե՞ն վերադարձել հին համակարգին: - Ջեյմսը պատասխանեց միանգամայն լուրջ, թեև մտովի զարմանքից բացեց աչքերը։

— Ճիշտ է. նրանց ՏՏ մասնագետը «փոխեց առաջնահերթությունները» և որոշեց հեռանալ իրենց հին սերվերով: Ջեյմս, նրանք համակարգը տեղադրեցին վեց տեղամասերում և պարզապես վճարեցին պրեմիում աջակցության համար, և նրանց բիզնեսն այժմ աշխատում է այնպես, ինչպես 1950-ականներին էր:

Ջեյմսը մի փոքր ուղղվեց։

-Դա ուրիշ հարց է։ Լավ, եկեք սկսենք:

Երբ նա հասավ Աննապոլիս, առաջին բանը, որ նա արեց, հաճախորդի առաջին թատրոնն էր, որը խնդիր ուներ: Օդանավակայանում արված քարտեզի վրա ամեն ինչ պարկեշտ էր թվում, սակայն ցանկալի հասցեի շրջակայքը կասկածելի էր թվում։ Ոչ թե գետտո, այլ ֆիլմ նուար հիշեցնող: Երբ Ջեյմսը կայանել էր քաղաքի մայթեզրին, նրան մոտեցավ մի մարմնավաճառ։ Հաշվի առնելով Աննապոլիսի չափերը, այն ամենայն հավանականությամբ միակն էր ամբողջ քաղաքում։ Նրա արտաքինն անմիջապես մտքում բերեց հայտնի կերպարին, ով մեծ էկրանին փողի դիմաց սեքս էր առաջարկում։ Ոչ, ոչ թե Ջուլիա Ռոբերթսի, այլ Ջոն Վոյթի մասին [ակնարկ «Կեսգիշերային կովբոյ» ֆիլմին - մոտ. գոտի].

Մարմնավաճառին ճանապարհ դնելով՝ Ջեյմսը գնաց կինոթատրոն։ Շրջակա տարածքը բարելավվել էր, բայց դեռևս փլուզվածի տպավորություն էր թողնում։ Ոչ թե Ջեյմսը շատ անհանգստացած էր։ Նա նախկինում եղել է թշվառ վայրերում: Եվ սա Կանադան էր, որտեղ նույնիսկ գողերը բավական քաղաքավարի են՝ դրամապանակդ վերցնելուց հետո «շնորհակալություն» ասելու համար:

Կինոթատրոնի կողային մուտքը խիտ ծառուղում էր։ Ջեյմսը գնաց դեպի դուռը և թակեց։ Շուտով այն ճռռաց ու մի փոքր բացվեց։

-Դու հավաքարար ես? - ներսից խռպոտ ձայն լսվեց.

-Այո, ես եմ... Եկել եմ ամեն ինչ շտկելու։

Ջեյմսը մտավ կինոթատրոնի նախասրահ։ Ըստ երևույթին, այլ ելք չունենալով՝ անձնակազմը սկսեց թղթե տոմսեր բաժանել այցելուներին: Սա դժվարացրեց ֆինանսական հաշվետվությունները, էլ չեմ խոսում ավելի հետաքրքիր մանրամասների մասին: Բայց անձնակազմը թեթեւացած դիմավորեց Ջեյմսին և անմիջապես տարան սերվերի սենյակ։

Առաջին հայացքից ամեն ինչ լավ էր։ Ջեյմսը մուտք գործեց սերվեր և ստուգեց սովորական կասկածելի վայրերը։ Ոչ մի խնդիր. Այնուամենայնիվ, շատ զգուշությունից ելնելով, Ջեյմսը անջատեց սերվերը, փոխարինեց ցանցային քարտը և հետ գլորեց համակարգը: Նա անմիջապես սկսեց աշխատել ամբողջությամբ։ Անձնակազմը նորից սկսեց տոմսեր վաճառել։

Ջեյմսը զանգահարեց Մարկին և տեղեկացրեց նրան իրավիճակի մասին։ Դժվար չէ պատկերացնել, որ Ջեյմսը կարող է ցանկանալ մնալ և տեսնել, թե արդյոք ինչ-որ անսպասելի բան է պատահում: Նա իջավ աստիճաններով և սկսեց հարցնել աշխատակիցներին, թե ինչ է պատահել։ Ակնհայտ է, որ համակարգը դադարել է աշխատել։ Անջատեցին ու միացրին, ամեն ինչ աշխատեց։ Բայց 10 րոպե անց համակարգը փլուզվեց։

Հենց այս պահին նման բան տեղի ունեցավ. Հանկարծ տոմսերի համակարգը սկսեց սխալներ նետել։ Անձնակազմը հառաչեց և վերցրեց թղթե տոմսերը, և Ջեյմսը շտապեց դեպի սերվերի սենյակ։ Ամեն ինչ լավ տեսք ուներ սերվերի հետ:

Հետո ներս մտավ աշխատակիցներից մեկը։

- Համակարգը նորից աշխատում է:

Ջեյմսը շփոթված էր, քանի որ ոչինչ չէր արել։ Ավելի ճիշտ՝ ոչ մի բան, որը կստիպի համակարգը աշխատել։ Նա դուրս եկավ, վերցրեց հեռախոսը և զանգահարեց իր ընկերության աջակցության գիծ: Շուտով նույն աշխատակիցը մտավ սերվերի սենյակ։

- Համակարգը խափանված է:

Ջեյմսը նայեց սերվերին։ Էկրանի վրա պարում էին բազմերանգ ձևերի հետաքրքիր և ծանոթ նախշը` քաոսային պտտվող և միահյուսվող խողովակները: Մենք բոլորս ինչ-որ պահի տեսել ենք այս էկրանապահին: Այն գեղեցիկ էր մատուցված և բառացիորեն հիպնոսացնող:


Ջեյմսը սեղմեց կոճակը, և նախշը անհետացավ: Նա շտապել է տոմսարկղ ու ճանապարհին հանդիպել իր մոտ վերադարձող աշխատակցին։

- Համակարգը նորից աշխատում է:

Եթե ​​դուք կարող եք մտավոր դեմքի ափի մեջ անել, ապա դա հենց այն է, ինչ արել է Ջեյմսը: Էկրանապահիչ. Այն օգտագործում է OpenGL: Եվ հետևաբար, շահագործման ընթացքում այն ​​սպառում է սերվերի պրոցեսորի բոլոր ռեսուրսները: Արդյունքում սերվերի յուրաքանչյուր զանգ ավարտվում է ժամանակի վերջում:

Ջեյմսը վերադարձավ սերվերի սենյակ, մուտք գործեց և փոխարինեց էկրանապահիչը դատարկ էկրանով գեղեցիկ խողովակներով: Այսինքն՝ պրոցեսորային ռեսուրսների 100%-ը խլող էկրանապահի փոխարեն տեղադրեցի մեկ ուրիշը, որը ռեսուրսներ չի սպառում։ Հետո ես սպասեցի 10 րոպե, որպեսզի ստուգեմ իմ գուշակությունը:

Երբ Ջեյմսը հասավ հաջորդ կինոթատրոն, նա մտածում էր, թե ինչպես բացատրել իր մենեջերին, որ ինքը հենց նոր թռել է 800 կմ՝ անջատելու էկրանապահիչը։

Վթար լուսնի որոշակի փուլում

Իրական պատմություն. Մի օր առաջացավ ծրագրային սխալ, որը կախված էր լուսնի փուլից: Կար մի փոքր ռեժիմ, որը սովորաբար օգտագործվում էր MIT-ի տարբեր ծրագրերում՝ Լուսնի իրական փուլի մոտավորությունը հաշվարկելու համար: GLS-ը այս ռեժիմը կառուցեց LISP ծրագրի մեջ, որը ֆայլ գրելիս թողարկեր տող մոտ 80 նիշ երկարությամբ ժամանակի դրոշմով: Շատ հազվադեպ էր, որ հաղորդագրության առաջին տողը շատ երկար ավարտվեր և տաներ հաջորդ տող: Եվ երբ ծրագիրը հետագայում կարդաց այս ֆայլը, անիծեց: Առաջին տողի երկարությունը կախված էր ճշգրիտ ամսաթվից և ժամից, ինչպես նաև ժամանակի դրոշմանիշի տպագրման պահին փուլային բնութագրերի երկարությունից: Այսինքն, սխալը բառացիորեն կախված էր լուսնի փուլից:

Առաջին թղթային հրատարակություն Ժարգոնային ֆայլ (Steele-1983) պարունակում էր նման տողի օրինակ, որը հանգեցրեց նկարագրված սխալին, բայց գրամեքենան «ուղղեց» այն: Դրանից հետո սա նկարագրվել է որպես «լուսնային փուլի սխալ»:

Այնուամենայնիվ, զգույշ եղեք ենթադրությունների հետ: Մի քանի տարի առաջ CERN-ի (Միջուկային հետազոտությունների եվրոպական կենտրոնի) ինժեներները Էլեկտրոն-պոզիտրոնային խոշոր բախիչում կատարված փորձերի ժամանակ սխալներ են հանդիպել: Քանի որ համակարգիչները ակտիվորեն մշակում են այս սարքի ստեղծած հսկայական տվյալները՝ նախքան արդյունքը գիտնականներին ցույց տալը, շատերը ենթադրում էին, որ ծրագրաշարը ինչ-որ կերպ զգայուն է լուսնի փուլի նկատմամբ: Մի քանի հուսահատ ինժեներներ հասան ճշմարտության խորքին: Սխալն առաջացել է 27 կմ երկարությամբ օղակի երկրաչափության մի փոքր փոփոխության պատճառով՝ Լուսնի անցման ժամանակ Երկրի դեֆորմացիայի պատճառով։ Այս պատմությունը մտել է ֆիզիկայի բանահյուսություն որպես «Նյուտոնի վրեժը մասնիկների ֆիզիկայի վրա» և ֆիզիկայի ամենապարզ և հնագույն օրենքների և ամենաառաջադեմ գիտական ​​հասկացությունների միջև կապի օրինակ։

Զուգարանի լվացումը կանգնեցնում է գնացքը

Ամենալավ ապարատային սխալը, որի մասին երբևէ լսել եմ, եղել է Ֆրանսիայում արագընթաց գնացքում: Վրիպակը հանգեցրել է գնացքի արտակարգ արգելակման, բայց միայն այն դեպքում, եթե ինքնաթիռում ուղևորներ են եղել։ Յուրաքանչյուր նման դեպքում գնացքը դուրս է բերվել շահագործումից, ստուգվել, բայց ոչինչ չի հայտնաբերվել։ Հետո նրան հետ են ուղարկել գիծ, ​​և նա անմիջապես վթարի է ենթարկվել կանգառ:

Ստուգումներից մեկի ժամանակ գնացքով ընթացող ինժեները գնացել է զուգարան։ Նա շուտով լվացվեց, ԲՈՒՄ! Վթարային կանգառ.

Ինժեները կապվեց վարորդի հետ և հարցրեց.

- Ի՞նչ էիք անում արգելակելուց անմիջապես առաջ:

-Դե, իջնելիս դանդաղեցի...

Սա տարօրինակ էր, քանի որ բնականոն աշխատանքի ընթացքում գնացքը տասնյակ անգամ դանդաղում է իջնելիս։ Գնացքը շարժվեց, և հաջորդ իջնելիս վարորդը զգուշացրեց.

-Ես պատրաստվում եմ դանդաղեցնել:

Ոչինչ չի պատահել.

- Ի՞նչ արեցիք վերջին արգելակման ժամանակ: - հարցրեց վարորդը:

-Դե... զուգարանում էի...

-Դե ուրեմն գնա զուգարան և արա այն, ինչ արեցիր, երբ մենք նորից իջնենք:

Ինժեները գնաց զուգարան, և երբ վարորդը զգուշացրեց. «Ես դանդաղում եմ», նա ջուրը ողողեց։ Իհարկե, գնացքը անմիջապես կանգ առավ։

Այժմ նրանք կարող էին վերարտադրել խնդիրը և պետք էր գտնել պատճառը:

Երկու րոպե անց նրանք նկատեցին, որ շարժիչի արգելակման հեռակառավարման մալուխը (գնացքը յուրաքանչյուր ծայրում մեկ շարժիչ ուներ) անջատված է էլեկտրական պահարանի պատից և ընկած է զուգարանի խրոցակի էլեկտրամագնիսը կառավարող ռելեի վրա... Երբ ռելեը միացված էր, այն խանգարում էր արգելակային մալուխին, և խափանումներից համակարգի պաշտպանությունը պարզապես ներառում էր վթարային արգելակումը:

Դարպաս, որն ատում էր FORTRAN-ը

Մի քանի ամիս առաջ մենք նկատեցինք, որ ցանցային կապերը մայրցամաքում [սա Հավայան կղզիներում էր] շատ ու շատ դանդաղ էին դառնում: Սա կարող է տևել 10-15 րոպե, այնուհետև նորից հանկարծակի առաջանալ: Որոշ ժամանակ անց իմ գործընկերը դժգոհեց ինձ, որ ցանցային կապերը մայրցամաքում են ընդհանրապես չի աշխատում. Նա ուներ FORTRAN-ի որոշ կոդ, որը պետք է պատճենվեր մայրցամաքում գտնվող մեքենայի վրա, բայց դա հնարավոր չէր, քանի որ «ցանցը բավականաչափ երկար չէր պահվում, որպեսզի FTP վերբեռնումն ավարտվեր»:

Այո, պարզվեց, որ ցանցի խափանումները տեղի են ունեցել, երբ գործընկերը փորձել է FORTRAN-ի սկզբնական կոդով ֆայլը FTP-ով ուղարկել մայրցամաքային մեքենա: Մենք փորձեցինք արխիվացնել ֆայլը. այնուհետև այն սահուն պատճենվեց (բայց թիրախային մեքենան չուներ unpacker, ուստի խնդիրը չլուծվեց): Վերջապես մենք «բաժանեցինք» FORTRAN կոդը շատ փոքր կտորների և ուղարկեցինք դրանք մեկ առ մեկ: Ֆրագմենտների մեծ մասը պատճենվել է առանց խնդիրների, բայց մի քանի կտոր չի անցել, կամ անցել է հետո բազմաթիվ փորձեր.

Երբ մենք ուսումնասիրեցինք խնդրահարույց հատվածները, հայտնաբերեցինք, որ դրանք ընդհանուր բան ունեին. դրանք բոլորը պարունակում էին մեկնաբանությունների բլոկներ, որոնք սկսվում և ավարտվում էին մեծատառ C-ից բաղկացած տողերով (ինչպես գործընկերը նախընտրեց մեկնաբանել FORTRAN-ում): Մենք էլեկտրոնային փոստով ուղարկեցինք մայրցամաքի ցանցի փորձագետներին և օգնություն խնդրեցինք: Իհարկե, նրանք ուզում էին տեսնել մեր ֆայլերի նմուշները, որոնք հնարավոր չէ փոխանցել FTP-ով... բայց մեր նամակները չեն հասել: Վերջապես մենք պարզեցինք նկարագրելինչ տեսք ունեն չփոխանցվող ֆայլերը: Աշխատեց :) [Կհամարձակվե՞մ այստեղ ավելացնել FORTRAN-ի խնդրահարույց մեկնաբանություններից մեկի օրինակը: Հավանաբար չարժե այն:]

Ի վերջո, մեզ հաջողվեց պարզել դա։ Վերջերս նոր դարպաս է տեղադրվել համալսարանի մեր մասի և մայրցամաքային ցանցի միջև: Այն մեծ դժվարությամբ էր փոխանցում փաթեթներ, որոնք պարունակում էին մեծատառ C-ի կրկնվող բիթ: Այս փաթեթներից ընդամենը մի քանիսը կարող են գրավել դարպասի բոլոր ռեսուրսները և կանխել այլ փաթեթների մեծ մասի մուտքը: Մենք բողոքեցինք gateway արտադրողին... և նրանք պատասխանեցին. «Օ, այո, դուք բախվել եք կրկնվող C! Մենք արդեն գիտենք նրա մասին»։ Մենք ի վերջո լուծեցինք խնդիրը՝ գնելով նոր դարպաս մեկ այլ արտադրողից (ի պաշտպանություն առաջինի, FORTRAN ծրագրերը փոխանցելու անկարողությունը կարող է առավելություն լինել ոմանց համար):

Դժվար ժամանակներ

Մի քանի տարի առաջ, երբ աշխատում էի Perl-ում ETL համակարգի ստեղծման վրա՝ նվազեցնելու 40-րդ փուլի կլինիկական փորձարկումների ծախսերը, ես պետք է մշակեի մոտ 000 ամսաթվեր: Նրանցից երկուսը չեն անցել թեստը։ Սա ինձ շատ չանհանգստացրեց, քանի որ այս ամսաթվերը վերցված էին հաճախորդի կողմից տրամադրված տվյալներից, որոնք հաճախ, կարելի է ասել, զարմանալի էին: Բայց երբ ստուգեցի սկզբնական տվյալները, պարզվեց, որ դրանք եղել են 1 թվականի հունվարի 2011-ը և 1 թվականի հունվարի 2007-ը: Կարծում էի, որ սխալը կա իմ գրած ծրագրում, բայց պարզվեց, որ դա արդեն 30 տարի է: հին. Սա կարող է խորհրդավոր թվալ նրանց համար, ովքեր ծանոթ չեն ծրագրային էկոհամակարգին: Մեկ այլ ընկերության՝ գումար աշխատելու վաղեմի որոշման պատճառով, իմ հաճախորդը վճարեց ինձ, որպեսզի շտկեմ սխալը, որը մի ընկերություն էր ներկայացրել պատահաբար, իսկ մյուսը՝ դիտմամբ: Որպեսզի դուք հասկանաք, թե ինչի մասին եմ խոսում, ես պետք է խոսեմ այն ​​ընկերության մասին, որն ավելացրեց այն գործառույթը, որն ի վերջո դարձավ վրիպակ, ինչպես նաև մի քանի այլ հետաքրքիր իրադարձություններ, որոնք նպաստեցին իմ շտկված առեղծվածային սխալին:

Հին բարի ժամանակներում Apple-ի համակարգիչները երբեմն ինքնաբերաբար վերականգնում էին իրենց ամսաթիվը մինչև 1 թվականի հունվարի 1904-ը: Պատճառը պարզ էր. այն օգտագործում էր մարտկոցով աշխատող «համակարգային ժամացույց»՝ ամսաթվին և ժամին հետևելու համար: Ի՞նչ պատահեց, երբ մարտկոցը մեռավ: Համակարգիչները սկսեցին հետևել ամսաթվին դարաշրջանի սկզբից սկսած վայրկյանների քանակով: Դարաշրջան ասելով մենք նկատի ունեինք հղման սկզբնական ամսաթիվը, իսկ Macintoshes-ի համար դա 1 թվականի հունվարի 1904-ն էր: Եվ մարտկոցի մահից հետո ընթացիկ ամսաթիվը վերափոխվեց նշվածին: Բայց ինչո՞ւ դա տեղի ունեցավ։

Նախկինում Apple-ն օգտագործում էր 32 բիթ՝ սկզբնական ամսաթվից սկսած վայրկյանների քանակը պահպանելու համար: Մեկ բիթը կարող է պահել երկու արժեքներից մեկը՝ 1 կամ 0։ Երկու բիթ կարող է պահել չորս արժեքներից մեկը՝ 00, 01, 10, 11։ Երեք բիթ՝ ութ արժեքից մեկը՝ 000, 001, 010, 011, 100։ , 101, 110, 111 և այլն: Իսկ 32-ը կարող է պահել 232 արժեքներից մեկը, այսինքն՝ 4 վայրկյան: Apple-ի ամսաթվերի համար դա հավասար է մոտ 294 տարվա, ուստի հին Mac-երը չեն կարող կարգավորել ամսաթվերը 967-ից հետո: Իսկ եթե համակարգի մարտկոցը մեռնում է, ամսաթիվը զրոյացվում է դարաշրջանի սկզբից ի վեր 296 վայրկյանի, և ամեն անգամ համակարգիչը միացնելիս պետք է ձեռքով սահմանել ամսաթիվը (կամ մինչև նոր մարտկոց գնելը):

Այնուամենայնիվ, Apple-ի որոշումը՝ ամսաթվերը դարաշրջանից ի վեր պահելու վայրկյաններ, նշանակում էր, որ մենք չէինք կարող կարգավորել դարաշրջանից առաջ ամսաթվերը, ինչը, ինչպես կտեսնենք, հեռու գնացող հետևանքներ ունեցավ: Apple-ը ներկայացրել է ոչ թե սխալ, այլ ֆունկցիա: Ի թիվս այլ բաների, սա նշանակում էր, որ Macintosh օպերացիոն համակարգը անձեռնմխելի էր «հազարամյակի սխալից» (ինչը չի կարելի ասել Mac-ի շատ հավելվածների մասին, որոնք ունեին իրենց ամսաթվերի համակարգերը սահմանափակումները շրջանցելու համար):

Շարունակիր. Մենք օգտագործեցինք Lotus 1-2-3-ը՝ IBM-ի «մարդասպան հավելվածը», որն օգնեց սկսել PC-ի հեղափոխությունը, չնայած Apple-ի համակարգիչներն ունեին VisiCalc, որը անձնական համակարգիչը հաջողության հասավ: Հանուն արդարության, եթե չհայտնվեր 1-2-3-ը, հազիվ թե ԱՀ-ները հանվեին, իսկ անհատական ​​համակարգիչների պատմությունը կարող էր շատ այլ կերպ զարգանալ: Lotus 1-2-3-ը 1900 թվականը սխալ է համարել որպես նահանջ տարի: Երբ Microsoft-ը թողարկեց իր առաջին աղյուսակը՝ Multiplan-ը, այն գրավեց շուկայի փոքր մասնաբաժինը: Եվ երբ նրանք գործարկեցին Excel նախագիծը, նրանք որոշեցին ոչ միայն պատճենել տողերի և սյունակների անվանման սխեման Lotus 1-2-3-ից, այլ նաև ապահովել սխալների համատեղելիությունը՝ միտումնավոր համարելով 1900 թվականը որպես նահանջ տարի: Այս խնդիրն այսօր էլ կա։ Այսինքն, 1-2-3-ում սա վրիպակ էր, բայց Excel-ում դա գիտակցված որոշում էր, որը երաշխավորում էր, որ բոլոր 1-2-3 օգտվողները կարող էին ներմուծել իրենց աղյուսակները Excel առանց տվյալները փոխելու, նույնիսկ եթե դրանք սխալ էին:

Բայց կար մեկ այլ խնդիր. Նախ, Microsoft-ը թողարկեց Excel-ը Macintosh-ի համար, որը չէր ճանաչում 1 թվականի հունվարի 1904-ից առաջ ժամկետներ: Իսկ Excel-ում 1 թվականի հունվարի 1900-ը համարվում էր դարաշրջանի սկիզբ: Հետևաբար, մշակողները փոփոխություններ կատարեցին այնպես, որ իրենց ծրագիրը ճանաչեց դարաշրջանի տեսակը և պահպանեց տվյալներն իր ներսում՝ համապատասխան ցանկալի դարաշրջանին: Այս մասին Microsoft-ը նույնիսկ բացատրական հոդված է գրել։ Եվ այս որոշումը հանգեցրեց իմ սխալին:

Իմ ETL համակարգը հաճախորդներից ստացել է Excel աղյուսակներ, որոնք ստեղծվել են Windows-ում, բայց կարող են ստեղծվել նաև Mac-ում: Հետևաբար, աղյուսակում դարաշրջանի սկիզբը կարող է լինել կամ 1 թվականի հունվարի 1900-ը, կամ 1 թվականի հունվարի 1904-ը: Ինչպե՞ս պարզել: Excel ֆայլի ձևաչափը ցույց է տալիս անհրաժեշտ տեղեկատվությունը, բայց իմ օգտագործած վերլուծիչը դա ցույց չի տալիս (այժմ ցույց է տալիս), և ենթադրում է, որ դուք գիտեք որոշակի աղյուսակի դարաշրջանը: Ես, հավանաբար, կարող էի ավելի շատ ժամանակ ծախսել Excel-ի երկուական ձևաչափը հասկանալու և վերլուծիչի հեղինակին պատչ ուղարկելու համար, բայց ես շատ ավելին ունեի հաճախորդի համար, ուստի ես արագ գրեցի էվրիստիկա՝ դարաշրջանը որոշելու համար: Նա պարզ էր:

Excel-ում 5 թվականի հուլիսի 1998-ի ամսաթիվը կարող է ներկայացվել «07-05-98» (անօգուտ ամերիկյան համակարգ), «հուլիսի 5, 98», «հուլիսի 5, 1998», «5-հուլիս-98» ձևաչափով կամ ինչ-որ այլ ձևաչափ, ևս մեկ անօգուտ ձևաչափ (հեգնանքով, որ Excel-ի իմ տարբերակը չէր առաջարկում ISO 8601-ի ձևաչափերից մեկը): Այնուամենայնիվ, աղյուսակում չֆորմատավորված ամսաթիվը պահվել է որպես «35981»՝ 1900-ի դարաշրջանի կամ «34519»՝ 1904-ի դարաշրջանի համար (թվերը ներկայացնում են դարաշրջանից սկսած օրերի թիվը): Ես պարզապես օգտագործեցի պարզ վերլուծիչ՝ տարին ֆորմատավորված ամսաթվից հանելու համար, այնուհետև օգտագործեցի Excel վերլուծիչը՝ տարին չֆորմատավորված ամսաթվից հանելու համար: Եթե ​​երկու արժեքներն էլ տարբերվում էին 4 տարով, ապա ես գիտեի, որ օգտագործում եմ 1904-ի դարաշրջանի համակարգ:

Ինչո՞ւ ես պարզապես չօգտագործեցի ձևաչափված ամսաթվերը: Քանի որ 5 թվականի հուլիսի 1998-ը կարող է ձևակերպվել որպես «հուլիս, 98»՝ կորցրած ամսվա հետ: Մենք աղյուսակներ ստացանք այնքան շատ ընկերություններից, որոնք ստեղծեցին դրանք այնքան տարբեր ձևերով, որ ամսաթվերը պարզելը մեզնից էր (այս դեպքում՝ ինձ): Բացի այդ, եթե Excel-ը ճիշտ է հասկանում, ապա մենք նույնպես պետք է:

Միևնույն ժամանակ ես հանդիպեցի 39082-ին։ Հիշեցնեմ, որ Lotus 1-2-3-ը 1900 թվականը համարում էր նահանջ տարի, և դա հավատարմորեն կրկնվում էր Excel-ում։ Եվ քանի որ սա 1900 թվականին ավելացավ մեկ օր, ամսաթվի հաշվարկման շատ գործառույթներ կարող էին սխալ լինել հենց այդ օրվա համար: Այսինքն՝ 39082-ը կարող էր լինել 1 թվականի հունվարի 2011-ը (Mac-ներում) կամ 31 թվականի դեկտեմբերի 2006-ը (Windows-ում): Եթե ​​իմ «տարվա վերլուծիչը» հանել է 2011 թվականը ֆորմատավորված արժեքից, ապա ամեն ինչ լավ է: Բայց քանի որ Excel վերլուծիչը չգիտի, թե որ դարաշրջանն է օգտագործվում, այն լռելյայն սահմանում է epoch-1900-ը՝ վերադարձնելով 2006 թվականը: Իմ հավելվածը տեսավ, որ տարբերությունը 5 տարի է, դա համարեց սխալ, գրանցեց այն և վերադարձրեց չֆորմատավորված արժեք:

Սա շրջանցելու համար ես գրեցի սա (կեղծկոդ).

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

Եվ հետո բոլոր 40 ամսաթվերը ճիշտ վերլուծվեցին:

Մեծ տպագրության աշխատանքների մեջտեղում

1980-ականների սկզբին հայրս աշխատում էր Storage Technology-ում, որն այժմ չգործող ստորաբաժանում էր, որը ստեղծում էր ժապավենային կրիչներ և օդաճնշական համակարգեր բարձր արագությամբ ժապավենի սնուցման համար:

Նրանք վերանախագծեցին կրիչներն այնպես, որ նրանք կարողանան ունենալ մեկ կենտրոնական «A» սկավառակ՝ միացված յոթ «B» կրիչներին, իսկ RAM-ի փոքր ՕՀ-ն, որը կառավարում էր «A» սկավառակը, կարող էր կարդալ և գրել գործողությունները պատվիրակել բոլոր «B» կրիչներին:

Ամեն անգամ, երբ «A» սկավառակը գործարկվում էր, անհրաժեշտ էր անգործունյա սկավառակ տեղադրել «A»-ին միացված ծայրամասային սկավառակի մեջ՝ օպերացիոն համակարգը հիշողության մեջ բեռնելու համար: Դա չափազանց պարզունակ էր. հաշվողական հզորությունը տրամադրվում էր 8-բիթանոց միկրոկոնտրոլերի միջոցով:

Նման սարքավորումների թիրախային լսարանը շատ մեծ տվյալների պահեստներ ունեցող ընկերություններն էին` բանկեր, մանրածախ ցանցեր և այլն, որոնք պետք է տպեին բազմաթիվ հասցեների պիտակներ կամ բանկային քաղվածքներ:

Մի հաճախորդ խնդիր ուներ. Տպման աշխատանքի մեջտեղում «A» հատուկ սկավառակը կարող է դադարեցնել աշխատանքը՝ հանգեցնելով ամբողջ աշխատանքի դադարեցմանը: Սկավառակի աշխատանքը վերականգնելու համար անձնակազմը ստիպված էր ամեն ինչ վերագործարկել: Եվ եթե դա տեղի է ունեցել վեց ժամ տևողությամբ առաջադրանքի կեսին, ապա կորել է հսկայական ծախսատար համակարգչային ժամանակ և խաթարվել է ողջ գործողության ժամանակացույցը։

Տեխնիկները ուղարկվել են Storage Technologies-ից: Բայց չնայած իրենց լավագույն ջանքերին, նրանք չկարողացան վերարտադրել սխալը փորձարկման պայմաններում. թվում էր, թե այն առաջացել է մեծ տպագրության աշխատանքների մեջ: Խնդիրը սարքաշարը չէր, նրանք փոխարինեցին այն ամենը, ինչ կարող էին՝ RAM, միկրոկոնտրոլեր, անգործունյա սկավառակ, ժապավենի սկավառակի ամեն հնարավոր հատված. խնդիրը շարունակվում էր:

Հետո տեխնիկները զանգել են շտաբ ու կանչել Փորձագետին։

Փորձագետը վերցրեց աթոռը և մի բաժակ սուրճ, նստեց համակարգչային սենյակում (այդ ժամանակներում կային սենյակներ, որոնք նվիրված էին համակարգիչներին), և հետևեց, թե ինչպես են աշխատակիցները հերթագրում մեծ տպագրական աշխատանք: Փորձագետը սպասում էր ձախողման, և դա արվեց: Բոլորը նայեցին Փորձագետին, բայց նա չէր պատկերացնում, թե ինչու դա տեղի ունեցավ: Ուստի նա հրամայեց նորից հերթագրել աշխատանքը, և ամբողջ անձնակազմն ու տեխնիկները վերադարձան աշխատանքի։

Փորձագետը կրկին նստեց աթոռին և սկսեց սպասել ձախողման։ Անցավ մոտ վեց ժամ, և ձախողումը տեղի ունեցավ։ Փորձագետը կրկին գաղափար չուներ, միայն թե ամեն ինչ տեղի ունեցավ մարդկանցով լի սենյակում։ Նա հրամայեց վերսկսել առաքելությունը, նորից նստեց և սպասեց:

Երրորդ ձախողման դեպքում Փորձագետը մի բան նկատեց. Խափանումը տեղի է ունեցել, երբ անձնակազմը փոխել է ժապավենը արտասահմանյան սկավառակում: Ընդ որում, խափանումը տեղի է ունեցել հենց այն պահին, երբ աշխատակիցներից մեկն անցել է հատակի որոշակի սալիկի միջով։

Բարձրացված հատակը պատրաստված էր ալյումինե սալիկներից, որոնք դրված էին 6-ից 8 դյույմ բարձրության վրա: Բազմաթիվ լարեր համակարգչից անցնում էին բարձրացված հատակի տակ, որպեսզի որևէ մեկը պատահաբար չմտնի կարևոր մալուխի վրա: Սալիկները դրված էին շատ ամուր, որպեսզի բեկորները չհայտնվեն բարձրացված հատակի տակ:

Փորձագետը հասկացել է, որ սալիկներից մեկը դեֆորմացված է։ Երբ աշխատակիցը ոտք դրեց նրա անկյունը, սալիկի եզրերը քսվեցին հարակից սալիկներին: Սալիկները կապող պլաստիկ մասերը նույնպես քսվել են դրանցով, ինչը առաջացրել է ստատիկ միկրոլիցքավորումներ, որոնք առաջացրել են ռադիոհաճախականության խանգարումներ։

Այսօր RAM-ը շատ ավելի լավ պաշտպանված է ռադիոհաճախականության խանգարումներից: Բայց այդ տարիներին այդպես չէր։ Փորձագետը հասկացել է, որ այդ միջամտությունը խաթարել է հիշողությունը, դրա հետ մեկտեղ՝ օպերացիոն համակարգի աշխատանքը։ Զանգել է սպասարկման ծառայություն, պատվիրել է նոր սալիկներ, ինքն է տեղադրել, խնդիրն անհետացել է։

Մակընթաց է։

Պատմությունը տեղի է ունեցել սերվերի սենյակում, Պորտսմուտի գրասենյակի չորրորդ կամ հինգերորդ հարկում (կարծում եմ), նավահանգիստների տարածքում:

Մի օր հիմնական տվյալների բազայով Unix սերվերը խափանվեց: Նրանք վերագործարկեցին նրան, բայց նա ուրախությամբ շարունակեց նորից ու նորից ընկնել: Մենք որոշեցինք զանգահարել որևէ մեկին աջակցության ծառայությունից:

Աջակցող տղան... Կարծում եմ՝ նրա անունը Մարկ էր, բայց դա նշանակություն չունի... Չեմ կարծում, որ ճանաչում եմ նրան։ Կարևոր չէ, իսկապես: Եկեք մնանք Մարկի հետ, լա՞վ: Հիանալի:

Այսպիսով, մի քանի ժամ անց Մարկը ժամանեց (գիտեք, Լիդսից Պորտսմուտ երկար ճանապարհ չէ), միացրեց սերվերը և ամեն ինչ աշխատեց առանց խնդիրների: Տիպիկ անիծյալ աջակցություն, հաճախորդը շատ է վրդովվում դրանից: Մարկը նայում է տեղեկամատյանների ֆայլերը և ոչ մի տհաճ բան չի գտնում: Այսպիսով, Մարկը վերադառնում է գնացք (կամ տրանսպորտի ցանկացած եղանակով, որով նա ժամանել է, դա կարող էր լինել կաղ կով, ինչ ես գիտեմ... այնուամենայնիվ, դա կարևոր չէ, լա՞վ:) և իզուր վատնելով՝ վերադառնում է Լիդս: օրը.

Նույն օրը երեկոյան սերվերը կրկին խափանում է: Պատմությունը նույնն է... սերվերը չի բարձրանում։ Մարկը փորձում է օգնել հեռակա կարգով, բայց հաճախորդը չի կարողանում գործարկել սերվերը:

Եվս մեկ գնացք, ավտոբուս, կիտրոնի բեզե կամ ինչ-որ այլ խայտառակություն, և Մարկը վերադարձել է Պորտսմուտ: Տեսեք, սերվերը բացվում է առանց որևէ խնդիրների: Հրաշք. Մարկը ծախսում է մի քանի ժամ՝ ստուգելով, որ ամեն ինչ կարգին է օպերացիոն համակարգի կամ ծրագրային ապահովման հետ, և մեկնում է Լիդս։

Օրվա կեսին սերվերը խափանում է (հանգստացեք): Այս անգամ խելամիտ է թվում սերվերը փոխարինելու համար ապարատային աջակցության ներգրավումը: Բայց ոչ, մոտ 10 ժամ հետո այն նույնպես ընկնում է։

Իրավիճակը կրկնվեց մի քանի օր շարունակ։ Սերվերն աշխատում է, խափանում է մոտ 10 ժամ հետո և չի գործարկվում հաջորդ 2 ժամվա ընթացքում։ Ստուգեցին սառեցումը, հիշողության արտահոսքը, ամեն ինչ ստուգեցին, բայց ոչինչ չգտան։ Հետո վթարները դադարեցին։

Շաբաթն անցավ անհոգ... բոլորը ուրախ էին։ Երջանիկ, քանի դեռ ամեն ինչ նորից չի սկսվել: Պատկերը նույնն է. 10 ժամ աշխատանք, 2-3 ժամ պարապ...

Եվ հետո ինչ-որ մեկը (կարծում եմ, նրանք ինձ ասացին, որ այս մարդը ՏՏ-ի հետ կապ չունի) ասաց.

«Դա մակընթացություն է»:

Բացականչությունն ընդունվեց դատարկ հայացքներով, և ինչ-որ մեկի ձեռքը հավանաբար վարանեց անվտանգության զանգի կոճակի վրա:

«Այն դադարում է աշխատել ալիքի հետ»:

Թվում է, թե սա բոլորովին օտար հասկացություն է ՏՏ աջակցության աշխատողների համար, ովքեր հազիվ թե կարդան «Tide» տարեգիրքը սուրճ խմելու ժամանակ նստած: Նրանք բացատրեցին, որ դա որևէ կերպ չի կարող կապված լինել ալիքի հետ, քանի որ սերվերը մեկ շաբաթ աշխատել է առանց խափանումների։

«Անցյալ շաբաթ ալիքը ցածր էր, բայց այս շաբաթ այն բարձր է»:

Մի փոքր տերմինաբանություն նրանց համար, ովքեր չունեն զբոսանավի լիցենզիա։ Մակընթացությունները կախված են լուսնային ցիկլից: Եվ երբ Երկիրը պտտվում է, յուրաքանչյուր 12,5 ժամը մեկ Արեգակի և Լուսնի գրավիտացիոն ձգողականությունը ստեղծում է մակընթացային ալիք: 12,5-ժամյա ցիկլի սկզբում մակընթացություն է, ցիկլի մեջտեղում՝ մակընթացություն, իսկ վերջում՝ կրկին բարձր մակընթացություն։ Բայց քանի որ Լուսնի ուղեծիրը փոխվում է, մակընթացության և մակընթացության միջև տարբերությունը նույնպես փոխվում է: Երբ Լուսինը գտնվում է Արեգակի և Երկրի միջև կամ Երկրի հակառակ կողմում (լիալուսին կամ առանց լուսնի), մենք ստանում ենք Syzygyn մակընթացություններ՝ ամենաբարձր մակընթացությունները և ամենացածր մակընթացությունները: Կիսալուսնի ժամանակ մենք ստանում ենք քառակուսի մակընթացություն՝ ամենացածր մակընթացությունը: Երկու ծայրահեղությունների միջև տարբերությունը զգալիորեն նվազում է: Լուսնային ցիկլը տևում է 28 օր՝ սիզիգյան - քառակուսի - սիզիգյան - քառակուսի:

Երբ տեխնիկներին բացատրեցին մակընթացային ուժերի էությունը, նրանք անմիջապես մտածեցին, որ պետք է ոստիկանություն կանչեն։ Եվ միանգամայն տրամաբանական. Բայց պարզվում է, որ տղան ճիշտ էր: Երկու շաբաթ առաջ ավերիչ նավը կանգնեցրեց գրասենյակից ոչ հեռու։ Ամեն անգամ, երբ մակընթացությունը բարձրացնում էր այն որոշակի բարձրության վրա, նավի ռադարային կետը հայտնվում էր սերվերի սենյակի հատակին: Իսկ ռադարը (կամ էլեկտրոնային պատերազմի սարքավորումը կամ ռազմական այլ խաղալիք) քաոս առաջացրեց համակարգիչներում։

Թռիչքի առաքելություն հրթիռի համար

Ինձ հանձնարարված էր մեծ (մոտ 400 հազար տող) հրթիռների արձակման կառավարման և մոնիտորինգի համակարգը տեղափոխել օպերացիոն համակարգի, կոմպիլյատորի և լեզվի նոր տարբերակներ: Ավելի ճիշտ՝ Solaris 2.5.1-ից մինչև Solaris 7, և Verdix Ada Development System-ից (VADS), որը գրված է Ada 83-ով, մինչև Rational Apex Ada համակարգ, որը գրված է Ada 95-ով: VADS-ը գնել է Rational-ը, և դրա արտադրանքը եղել է. հնացած, չնայած Rational-ը փորձեց կիրառել VADS-ի հատուկ փաթեթների համատեղելի տարբերակներ՝ հեշտացնելու անցումը Apex կոմպիլյատորին:

Երեք հոգի ինձ օգնեցին պարզապես մաքուր կերպով հավաքել կոդը: Երկու շաբաթ տեւեց։ Եվ հետո ես ինքնուրույն աշխատեցի, որպեսզի համակարգը աշխատի: Մի խոսքով, դա ամենավատ ճարտարապետությունն ու ծրագրային համակարգի ներդրումն էր, որին ես հանդիպել էի, ուստի ևս երկու ամիս պահանջվեց պորտն ավարտելու համար: Այնուհետեւ համակարգը ներկայացվել է փորձարկման, որը տեւել է եւս մի քանի ամիս։ Ես անմիջապես ուղղեցի փորձարկման ժամանակ հայտնաբերված սխալները, բայց դրանց թիվը արագորեն նվազեց (աղբյուրի կոդը արտադրական համակարգ էր, ուստի դրա ֆունկցիոնալությունը բավականին հուսալի էր աշխատում, ես պարզապես ստիպված էի հեռացնել այն սխալները, որոնք առաջացել են նոր կոմպիլյատորին հարմարվելու ժամանակ): Ի վերջո, երբ ամեն ինչ աշխատում էր այնպես, ինչպես պետք է, ես տեղափոխվեցի մեկ այլ նախագծի։

Իսկ Գոհաբանության օրվան նախորդող ուրբաթ օրը հեռախոսը զանգեց։

Հրթիռի արձակումը պետք է փորձարկվեր մոտ երեք շաբաթից, իսկ հետհաշվարկի լաբորատոր փորձարկումների ժամանակ արգելափակվել էր հրամանների հաջորդականությունը։ Իրական կյանքում դա կդադարեցնի փորձարկումը, և եթե խցանումը տեղի ունենար շարժիչը գործարկելուց հետո մի քանի վայրկյանում, ապա օժանդակ համակարգերում մի քանի անդառնալի գործողություններ կկատարվեն, ինչը կպահանջի հրթիռի երկար և թանկ պատրաստություն: Դա չէր սկսվի, բայց շատերը շատ կվրդովվեին ժամանակի և շատ, շատ փողի կորստից: Թույլ մի տվեք, որ որևէ մեկը ձեզ ասի, որ Պաշտպանության նախարարությունը փող է ծախսում անխոհեմաբար. ես երբեք չեմ հանդիպել պայմանագրային մենեջերի, ով առաջինը կամ երկրորդը չդներ բյուջեն, որին հաջորդում էր ժամանակացույցը:

Նախորդ ամիսներին այս հետհաշվարկի մարտահրավերը գործարկվել էր հարյուրավոր անգամներ բազմաթիվ տատանումներով՝ ընդամենը մի քանի փոքր զկռտոցներով: Այսպիսով, դրա հավանականությունը շատ ցածր էր, բայց դրա հետևանքները շատ նշանակալի էին: Բազմապատկեք այս երկու գործոններն էլ, և դուք կհասկանաք, որ լուրերը իմ և տասնյակ ինժեներների ու մենեջերների համար կանխատեսում էին կործանված արձակուրդային շաբաթ։

Եվ ուշադրություն դարձվեց ինձ՝ որպես համակարգը տեղափոխող անձի։

Ինչպես անվտանգության համար կարևոր համակարգերի մեծ մասի դեպքում, շատ պարամետրեր գրանցվեցին, ուստի բավականին հեշտ էր բացահայտել կոդի այն մի քանի տողերը, որոնք կատարվել էին մինչև համակարգի խափանումը: Եվ իհարկե, նրանց մեջ բացարձակապես ոչ մի արտասովոր բան չկար, նույն արտահայտությունները հաջողությամբ կատարվել են բառացիորեն հազարավոր անգամներ նույն վազքի ընթացքում:

Մենք Apex-ից մարդկանց կանչեցինք Rational, քանի որ նրանք էին, ովքեր մշակեցին կոմպիլյատորը, և նրանց մշակած որոշ առօրյաներ կանչվեցին կասկածելի կոդով: Նրանք (և բոլորը) տպավորված էին, որ կարիք կա հասնելու բառացիորեն ազգային նշանակության խնդրի արմատներին:

Քանի որ ամսագրերում ոչ մի հետաքրքիր բան չկար, մենք որոշեցինք փորձել վերարտադրել խնդիրը տեղական լաբորատորիայում: Սա հեշտ գործ չէր, քանի որ իրադարձությունը տեղի էր ունենում մոտավորապես մեկ անգամ 1000 վազքում: Կասկածելի պատճառներից մեկն այն էր, որ զանգը վաճառողի կողմից մշակված mutex գործառույթին (VADS միգրացիոն փաթեթի մաս) Unlock չի հանգեցրել ապակողպման: Գործառույթը կոչող պրոցեսորային շարանը մշակում էր սրտի զարկերի հաղորդագրությունները, որոնք անվանականորեն հասնում էին ամեն վայրկյան: Մենք հաճախականությունը բարձրացրինք մինչև 10 Հց, այսինքն՝ վայրկյանում 10 անգամ և սկսեցինք վազել։ Մոտ մեկ ժամ անց համակարգը կողպվել է։ Գրանցամատյանում մենք տեսանք, որ ձայնագրված հաղորդագրությունների հաջորդականությունը նույնն էր, ինչ անհաջող թեստի ժամանակ։ Մենք կատարեցինք ևս մի քանի վազք, համակարգը հետևողականորեն արգելափակվեց մեկնարկից 45-90 րոպե անց, և ամեն անգամ, երբ գրանցամատյանը պարունակում էր նույն երթուղին: Թեև մենք տեխնիկապես գործարկում էինք տարբեր կոդ. հաղորդագրության հաճախականությունը տարբեր էր, համակարգի վարքագիծը նույնն էր, ուստի մենք վստահ էինք, որ բեռնվածության այս սցենարը նույն խնդիրն է առաջացնում:

Այժմ մենք պետք է հասկանանք, թե կոնկրետ որտեղ է արգելափակվել արտահայտությունների հաջորդականության մեջ:

Համակարգի այս ներդրումն օգտագործեց Ada առաջադրանքի համակարգը և այն աներևակայելի վատ օգտագործեց: Առաջադրանքները Ada-ում միաժամանակ կատարվող բարձր մակարդակի կառուցվածք են, կատարման թելերի պես մի բան, որը միայն ներկառուցված է հենց լեզվի մեջ: Երբ երկու առաջադրանք պետք է շփվեն, նրանք «հանդիպում են դնում», փոխանակում են անհրաժեշտ տվյալները, իսկ հետո դադարեցնում են ժամադրությունը և վերադառնում իրենց անկախ մահապատիժներին։ Սակայն համակարգը այլ կերպ է ներդրվել։ Նպատակային առաջադրանքի հանդիպումից հետո այդ նպատակային առաջադրանքը հանդիպում էր մեկ այլ առաջադրանքի հետ, որն այնուհետև հանդիպում էր երրորդ առաջադրանքի հետ, և այդպես շարունակվում էր մինչև որոշակի մշակման ավարտը: Դրանից հետո այս բոլոր ժամադրություններն ավարտվեցին, և յուրաքանչյուր առաջադրանք պետք է վերադառնար իր կատարմանը: Այսինքն՝ մենք գործ ունեինք աշխարհում ամենաթանկ գործառույթների կանչի համակարգի հետ, որը դադարեցրեց «բազմաբնույթ առաջադրանքների» ամբողջ գործընթացը, մինչդեռ այն մշակում էր մուտքային տվյալների մի մասը: Իսկ մինչ այդ դա խնդիրներ չէր առաջացնում միայն այն պատճառով, որ թողունակությունը շատ ցածր էր։

Ես նկարագրեցի առաջադրանքի այս մեխանիզմը, քանի որ երբ հանդիպում էր պահանջվում կամ ակնկալվում էր ավարտվել, կարող էր տեղի ունենալ «առաջադրանքի փոխարկում»: Այսինքն՝ պրոցեսորը կարող է սկսել մշակել մեկ այլ առաջադրանք, որը պատրաստ է կատարման։ Ստացվում է, որ երբ մի առաջադրանքը պատրաստ է հանդիպել մեկ այլ առաջադրանքի, կարող է սկսել կատարել բոլորովին այլ առաջադրանք, և ի վերջո վերահսկողությունը վերադառնում է առաջին հանդիպմանը: Եվ այլ իրադարձություններ կարող են տեղի ունենալ, որոնք առաջացնում են առաջադրանքի անցում. Այդպիսի իրադարձություններից մեկը զանգ է դեպի համակարգի ֆունկցիա, ինչպիսին է տպագրությունը կամ մուտեքսի կատարումը:

Որպեսզի հասկանայի, թե կոդի որ տողն էր առաջացնում խնդիրը, ես պետք է գտնեի առաջընթաց արձանագրելու մի միջոց՝ հայտարարությունների հաջորդականության միջոցով՝ առանց առաջադրանքի անջատիչ գործարկելու, որը կկանխեր վթարի առաջացումը: Այնպես որ, ես չկարողացա օգտվել Put_Line()I/O գործողություններ կատարելուց խուսափելու համար: Ես կարող եմ սահմանել հաշվիչի փոփոխական կամ նման բան, բայց ինչպե՞ս կարող եմ տեսնել դրա արժեքը, եթե չեմ կարող այն ցուցադրել էկրանին:

Նաև գրանցամատյանը ուսումնասիրելիս պարզվեց, որ չնայած սրտի բաբախման հաղորդագրությունների մշակման սառեցմանը, որն արգելափակում էր գործընթացի բոլոր մուտքային/ելքային գործողությունները և կանխում այլ մշակումների իրականացումը, այլ անկախ առաջադրանքներ շարունակվում էին կատարել: Այսինքն՝ աշխատանքը ամբողջությամբ արգելափակված չէր, միայն առաջադրանքների (կրիտիկական) շղթա։

Սա արգելափակող արտահայտությունը գնահատելու համար անհրաժեշտ հուշումն էր:

Ես պատրաստեցի Ada փաթեթ, որը պարունակում էր առաջադրանք, թվարկված տեսակ և այդ տեսակի գլոբալ փոփոխական: Բազմաթիվ բառացիներ կապված էին խնդրահարույց հաջորդականության հատուկ արտահայտությունների հետ (օրինակ. Incrementing_Buffer_Index, Locking_Mutex, Mutex_Unlocked), և այնուհետև դրա մեջ տեղադրեց հանձնարարական արտահայտություններ, որոնք վերագրում էին համապատասխան թվարկումը գլոբալ փոփոխականին: Քանի որ այս ամենի օբյեկտի կոդը պարզապես պահում էր հիշողության մեջ հաստատուն, դրա կատարման արդյունքում առաջադրանքների փոխարկումը չափազանց քիչ հավանական էր: Մենք հիմնականում կասկածում էինք այն արտահայտություններին, որոնք կարող էին փոխել առաջադրանքը, քանի որ արգելափակումը տեղի է ունեցել կատարման ժամանակ, այլ ոչ թե վերադարձելիս՝ առաջադրանքը հետ փոխարկելիս (մի քանի պատճառներով):

Հետևելու առաջադրանքը պարզապես գործարկվում էր մի օղակով և պարբերաբար ստուգվում՝ տեսնելու, թե արդյոք փոխվել է գլոբալ փոփոխականի արժեքը: Յուրաքանչյուր փոփոխության դեպքում արժեքը պահվում էր ֆայլում: Հետո կարճ սպասել և նոր ստուգում: Ես գրել եմ փոփոխականը ֆայլում, քանի որ առաջադրանքը կատարվել է միայն այն ժամանակ, երբ համակարգը ընտրել է այն կատարման համար, երբ առաջադրանքը փոխարկել է խնդրի տարածքում: Ինչ էլ որ պատահի այս առաջադրանքում, չի ազդի այլ, անկապ արգելափակված առաջադրանքների վրա:

Ակնկալվում էր, որ երբ համակարգը հասնի խնդրահարույց կոդը գործարկելու կետին, գլոբալ փոփոխականը կզրոյացվի յուրաքանչյուր հաջորդ արտահայտությունին անցնելիս: Այնուհետև կկատարվի մի բան, որը կհանգեցնի առաջադրանքի փոխարկմանը, և քանի որ դրա կատարման հաճախականությունը (10 Հց) ավելի ցածր է, քան մոնիտորինգի առաջադրանքը, մոնիտորը կարող է գրավել գլոբալ փոփոխականի արժեքը և գրել այն: Նորմալ իրավիճակում ես կարող էի ստանալ թվարկումների ենթաբազմության կրկնվող հաջորդականություն՝ փոփոխականի վերջին արժեքները առաջադրանքի անջատման պահին: Կախվելիս գլոբալ փոփոխականն այլևս չպետք է փոխվի, և գրված վերջին արժեքը ցույց կտա, թե որ արտահայտությունը չի ավարտվել։

Ես գործարկեցի կոդը հետագծման միջոցով: Նա քարացավ։ Իսկ մոնիտորինգն աշխատում էր ժամացույցի նման։

Գրանցամատյանը պարունակում էր սպասվող հաջորդականությունը, որն ընդհատվում էր մի արժեքով, որը ցույց է տալիս, որ mutex է կանչվել Unlock, և առաջադրանքն ավարտված չէ, ինչպես նախկինում հազարավոր զանգերի դեպքում:

Apex-ի ինժեներներն այս պահին տենդագին վերլուծում էին իրենց ծածկագիրը և գտան մի տեղ մուտեքսում, որտեղ, տեսականորեն, կարող էր կողպեք առաջանալ: Բայց դրա հավանականությունը շատ ցածր էր, քանի որ որոշակի ժամանակում տեղի ունեցող իրադարձությունների միայն որոշակի հաջորդականություն կարող էր հանգեցնել արգելափակման: Մերֆիի օրենքը, տղաներ, դա Մերֆիի օրենքն է:

Ինձ անհրաժեշտ կոդի կտորը պաշտպանելու համար ես փոխարինեցի mutex ֆունկցիայի կանչերը (կառուցված OS mutex ֆունկցիոնալության վրա) փոքր բնիկ Ada mutex փաթեթով՝ վերահսկելու mutex մուտքն այդ կտոր:

Ես այն տեղադրեցի կոդի մեջ և կատարեցի թեստը: Յոթ ժամ անց կոդը դեռ աշխատում էր։

Իմ կոդը ներկայացվեց Rational-ին, որտեղ այն կազմեցին, ապամոնտաժեցին և ստուգեցին, որ այն չի օգտագործում նույն մոտեցումը, որն օգտագործվում էր խնդրահարույց mutex ֆունկցիաներում։

Սա իմ կարիերայի ամենամարդաշատ կոդի վերանայումն էր: Ինձ հետ սենյակում մոտ տասը ինժեներ և մենեջեր կային, ևս տասը հոգի կոնֆերանսի զանգի մեջ էին, և նրանք բոլորն էլ ուսումնասիրեցին կոդերի մոտ 20 տող:

Կոդը վերանայվեց, նոր գործարկվող ֆայլեր հավաքվեցին և ներկայացվեցին պաշտոնական ռեգրեսիայի փորձարկման: Մի քանի շաբաթ անց հետհաշվարկի փորձարկումը հաջողությամբ ավարտվեց, և հրթիռը թռավ։

Լավ, ամեն ինչ լավ է, բայց ո՞րն է պատմության իմաստը:

Դա բացարձակապես զզվելի խնդիր էր։ Հարյուր հազարավոր կոդերի տողեր, զուգահեռ կատարում, ավելի քան մեկ տասնյակ փոխազդող գործընթացներ, վատ ճարտարապետություն և վատ իրականացում, ներկառուցված համակարգերի ինտերֆեյսներ և ծախսված միլիոնավոր դոլարներ: Ոչ մի ճնշում, ճիշտ է:

Ես միակը չէի, ով աշխատում էր այս խնդրի վրա, չնայած ես ուշադրության կենտրոնում էի, երբ տեղափոխում էի: Բայց թեև ես դա արեցի, դա չի նշանակում, որ ես հասկացել եմ կոդերի հարյուր հազարավոր տողերը կամ նույնիսկ սփռել դրանք: Կոդն ու տեղեկամատյանները վերլուծվել են ամբողջ երկրի ինժեներների կողմից, բայց երբ նրանք ինձ ասացին իրենց վարկածները ձախողման պատճառների մասին, ինձնից ընդամենը կես րոպե պահանջվեց դրանք հերքելու համար: Եվ երբ ինձ խնդրում էին վերլուծել տեսությունները, ես դա կփոխանցեի մեկ ուրիշին, քանի որ ինձ համար ակնհայտ էր, որ այդ ինժեներները սխալ ճանապարհով են գնում։ Հավակնոտ է հնչում: Այո, դա ճիշտ է, բայց ես մերժեցի վարկածներն ու խնդրանքները մեկ այլ պատճառով.

Ես հասկացա խնդրի էությունը։ Ես չգիտեի, թե կոնկրետ որտեղ է դա տեղի ունենում կամ ինչու, բայց գիտեի, թե ինչ է կատարվում:

Տարիների ընթացքում ես կուտակել եմ մեծ գիտելիքներ և փորձ։ Ես Ադա-ի օգտագործման ռահվիրաներից էի և հասկացա դրա առավելություններն ու թերությունները: Ես գիտեմ, թե ինչպես են Ada-ի գործարկման ժամանակի գրադարանները կատարում առաջադրանքները և զբաղվում զուգահեռ կատարմամբ: Իսկ ես հասկանում եմ ցածր մակարդակի ծրագրավորում՝ հիշողության, ռեգիստրների ու անսամբլերի մակարդակով։ Այսինքն՝ խորը գիտելիքներ ունեմ իմ ոլորտում։ Եվ ես դրանք օգտագործել եմ խնդրի պատճառը գտնելու համար: Ես պարզապես չաշխատեցի սխալի շուրջ, ես հասկացա, թե ինչպես գտնել այն շատ զգայուն գործարկման միջավայրում:

Կոդի հետ պայքարի նման պատմություններն այնքան էլ հետաքրքիր չեն նրանց համար, ովքեր ծանոթ չեն նման պայքարի առանձնահատկություններին ու պայմաններին։ Բայց այս պատմություններն օգնում են մեզ հասկանալ, թե ինչ է անհրաժեշտ իսկապես բարդ խնդիրներ լուծելու համար:

Իսկապես դժվար խնդիրներ լուծելու համար պետք է լինել ավելին, քան պարզապես ծրագրավորող: Դուք պետք է հասկանաք կոդի «ճակատագիրը», ինչպես է այն փոխազդում իր միջավայրի հետ և ինչպես է գործում միջավայրը:

Եվ հետո դուք կունենաք ձեր սեփական կործանված տոնական շաբաթը:

Շարունակելի

Source: www.habr.com

Добавить комментарий