Proqramçılar və mühəndislərin folkloru (1-ci hissə)

Proqramçılar və mühəndislərin folkloru (1-ci hissə)

Bu, İnternetdəki səhvlərin bəzən tamamilə inanılmaz təzahürlərə sahib olması haqqında hekayələr seçimidir. Bəlkə sizin də deyəcək bir şeyiniz var.

Vanilli dondurmaya avtomobil allergiyası

Aşkar olanın həmişə cavab olmadığını başa düşən mühəndislər üçün bir hekayə və faktlar nə qədər uzaq görünsə də, yenə də faktdır. General Motors korporasiyasının Pontiac şöbəsi şikayət aldı:

İkinci dəfədir ki, sizə yazıram və cavab vermədiyiniz üçün sizi qınamıram, çünki bu, çılğın səslənir. Ailəmizdə hər axşam yeməkdən sonra dondurma yemək ənənəsi var. Dondurmanın növləri hər dəfə dəyişir və axşam yeməyindən sonra bütün ailə hansı dondurmanı alacağını seçir, ondan sonra mağazaya gedirəm. Bu yaxınlarda yeni bir Pontiac aldım və o vaxtdan bəri dondurma almaq üçün səfərlərim problemə çevrildi. Görürsən, hər dəfə vanilli dondurma alıb mağazadan qayıdanda maşın işə düşmür. Başqa dondurma gətirsəm, maşın problemsiz işə düşür. Nə qədər axmaq səslənsə də, ciddi bir sual vermək istəyirəm: “Pontiakda nə var ki, mən vanilli dondurma gətirəndə başlamaz, başqa ləzzətli dondurma gətirəndə asanlıqla başlayır?”

Təsəvvür etdiyiniz kimi, bölmə sədri məktuba şübhə ilə yanaşırdı. Ancaq hər ehtimala qarşı mühəndis göndərdim yoxlamaq üçün. Gözəl bir ərazidə yaşayan varlı, savadlı bir adamın onu qarşılamasına təəccübləndi. Yeməkdən sonra dərhal görüşməyə razılaşdılar ki, ikisi dondurma üçün mağazaya gedə bilsinlər. Həmin axşam vanil idi və onlar maşına qayıdanda işə başlamadı.

Mühəndis daha üç axşam gəldi. İlk dəfə dondurma şokolad idi. Maşın işə başladı. İkinci dəfə çiyələkli dondurma var idi. Maşın işə başladı. Üçüncü axşam o, vanil götürməyi xahiş etdi. Maşın başlamadı.

Mühəndis rasional düşünərək avtomobilin vanil dondurmasına allergiyası olduğuna inanmaqdan imtina etdi. Ona görə də avtomobilin sahibi ilə razılaşdım ki, problemin həllini tapana qədər səfərlərini davam etdirəcək. Və yol boyu qeydlər aparmağa başladı: bütün məlumatları, günün vaxtını, benzinin növünü, mağazadan gəliş və qayıdış vaxtını və s.

Mühəndis tezliklə anladı ki, avtomobil sahibi vanil dondurma almağa daha az vaxt sərf edib. Buna səbəb mağazadakı malların tərtibatı olub. Vanilli dondurma ən populyar idi və tapmaq asan olması üçün mağazanın qabağında ayrıca dondurucuda saxlanılırdı. Və bütün digər növlər mağazanın arxasında idi və düzgün çeşidi tapmaq və ödəmək üçün daha çox vaxt lazım idi.

İndi sual mühəndis üçün idi: mühərrik söndürüldüyü andan daha az vaxt keçibsə, niyə maşın işə düşmədi? Problem vanilli dondurmada deyil, vaxtda olduğundan mühəndis tez bir zamanda cavab tapdı: qaz kilidi idi. Bu, hər axşam baş verirdi, lakin avtomobil sahibi dondurma axtarmağa daha çox vaxt sərf etdikdə, mühərrik kifayət qədər soyudu və asanlıqla işə düşdü. Kişi vanil dondurma alanda mühərrik hələ də çox isti idi və qaz kilidinin əriməyə vaxtı yox idi.

Əxlaq: Hətta tamamilə çılğın problemlər bəzən real olur.

Crash Bandicoot

Bunu yaşamaq ağrılıdır. Bir proqramçı olaraq kodunu birinci, ikinci, üçüncü... və haradasa on mininci yerdə kompilyatoru günahlandırmağa öyrəşirsən. Və daha aşağı siyahıda siz artıq avadanlıqları günahlandırırsınız.

Budur, hardware səhvi haqqında hekayəm.

Crash Bandicoot oyunu üçün yaddaş kartına yükləmək və saxlamaq üçün kod yazdım. Belə lovğa oyun tərtibatçısı üçün bu, parkda gəzinti kimi idi: işin bir neçə gün çəkəcəyini düşünürdüm. Bununla belə, altı həftə ərzində kodu düzəltdim. Yol boyu digər problemləri həll etdim, lakin bir neçə gündən bir bir neçə saat bu koda qayıtdım. Bu əzab idi.

Simptom belə görünürdü: oyunun cari oyununu saxladığınız zaman və yaddaş kartına daxil olduqda, hər şey demək olar ki, həmişə qaydasında gedir... Amma bəzən heç bir aşkar səbəb olmadan oxuma və ya yazma əməliyyatı fasilələri olur. Qısa qeyd çox vaxt yaddaş kartını zədələyir. Oyunçu qənaət etməyə çalışdıqda, o, nəinki qənaət edə bilmir, həm də xəritəni məhv edir. pislik.

Bir müddət sonra Sony-dəki prodüserimiz Connie Bus panikaya başladı. Bu səhvlə oyunu göndərə bilmədik və altı həftə sonra problemin nədən qaynaqlandığını başa düşmədim. Connie vasitəsilə biz digər PS1 tərtibatçıları ilə əlaqə saxladıq: kimsə oxşar bir şeylə qarşılaşıb? Yox. Yaddaş kartında heç kimin problemi yoxdu.

Sazlamaq üçün heç bir ideyanız olmadıqda, qalan yeganə yanaşma “bölmək və fəth etmək”dir: problemə səbəb olan nisbətən kiçik bir fraqment qalana qədər səhv proqramdan getdikcə daha çox kodu silin. Yəni səhv olan hissə qalana qədər proqramı hissə-hissə kəsirsiniz.

Amma məsələ ondadır ki, video oyunundan parçaları kəsmək çox çətindir. Cazibə qüvvəsini təqlid edən kodu silsəniz, onu necə işlətmək olar? Yoxsa personajlar çəkmək?

Buna görə də, bütün modulları faydalı bir şey etdiyini iddia edən, lakin əslində səhvləri ehtiva etməyən çox sadə bir şey edən kötüklərlə əvəz etməliyik. Oyunun heç olmasa işləməsi üçün belə qoltuqağacı yazmalıyıq. Bu yavaş və ağrılı bir prosesdir.

Bir sözlə, mən etdim. Sistemi oyunu idarə etmək üçün konfiqurasiya edən, göstərmə aparatını işə salan və s. ilkin kodla qalana qədər getdikcə daha çox kod parçasını sildim. Təbii ki, bu mərhələdə mən saxlama və yükləmə menyusu yarada bilmədim, çünki bütün qrafik kodu üçün stub yaratmalı olacaqdım. Amma mən (görünməz) saxlama və yükləmə ekranından istifadə edən istifadəçi kimi davrana və yadda saxlamağı və sonra yaddaş kartına yazmağı xahiş edə bilərdim.

Bu, mənə hələ də yuxarıdakı problemi olan kiçik bir kod parçası ilə qaldı - lakin bu, hələ də təsadüfi olaraq baş verirdi! Çox vaxt hər şey yaxşı işləyirdi, lakin bəzən nasazlıqlar olurdu. Demək olar ki, bütün oyun kodunu sildim, lakin səhv hələ də canlı idi. Bu təəccüblü idi: qalan kod əslində heç nə etmədi.

Nə vaxtsa, yəqin ki, səhər saat üç radələrində ağlıma bir fikir gəldi. Oxuma və yazma (giriş/çıxış) əməliyyatları dəqiq icra müddətlərini əhatə edir. Sərt disk, yaddaş kartı və ya Bluetooth modulu ilə işlədiyiniz zaman oxumaq və yazmaq üçün məsul olan aşağı səviyyəli kod bunu saat impulslarına uyğun edir.

Saatın köməyi ilə prosessorla birbaşa əlaqəsi olmayan cihaz prosessorda icra olunan kodla sinxronlaşdırılır. Saat ötürmə sürətini - məlumatların ötürülmə sürətini təyin edir. Zamanlamalarla qarışıqlıq varsa, ya hardware, ya proqram təminatı, ya da hər ikisi də qarışıqdır. Və bu, çox pisdir, çünki məlumatlar zədələnə bilər.

Bəs kodumuzdakı bir şey vaxtları qarışdırırsa? Test proqramı kodunda bununla bağlı hər şeyi yoxladım və PS1-də proqramlaşdırıla bilən taymeri 1 kHz (saniyədə 1000 gənə) təyin etdiyimizi gördüm. Bu olduqca çoxdur; standart olaraq, konsol işə salındıqda, 100 Hz-də işləyir. Və əksər oyunlar bu tezlikdən istifadə edir.

Oyun tərtibatçısı Andy, hərəkətlərin daha dəqiq hesablanması üçün taymeri 1 kHz-ə təyin etdi. Andy həddi aşmağa meyllidir və biz cazibə qüvvəsini təqlid etsək, bunu mümkün qədər dəqiq edirik!

Bəs taymerin sürətləndirilməsi proqramın ümumi vaxtına və buna görə də yaddaş kartı üçün ötürmə sürətini tənzimləyən saata bir şəkildə təsir etdisə nə etməli?

Taymer kodunu şərh etdim. Səhv bir daha baş vermədi. Ancaq bu, onu düzəltdiyimiz demək deyil, çünki uğursuzluq təsadüfi baş verdi. Bəxtim gətirsəydi nə olardı?

Bir neçə gündən sonra test proqramı ilə yenidən sınaq keçirdim. Səhv təkrarlanmadı. Mən tam oyun kod bazasına qayıtdım və yadda saxlama və yükləmə kodunu dəyişdirdim ki, proqramlaşdırıla bilən taymer yaddaş kartına daxil olmamışdan əvvəl ilkin dəyərinə (100Hz) sıfırlansın və sonra yenidən 1kHz-ə sıfırlansın. Daha qəzalar yox idi.

Bəs niyə bu baş verdi?

Yenidən test proqramına qayıtdım. 1 kHz taymer ilə səhvin baş verməsində bəzi nümunələri tapmağa çalışdım. Nəhayət, səhvin kimsə PS1 nəzarətçisi ilə oynayanda baş verdiyini gördüm. Mən bunu nadir hallarda özüm etdiyim üçün - saxlama və yükləmə kodunu sınaqdan keçirərkən niyə mənə nəzarətçi lazımdır? - Bu asılılığı hiss etməmişəm. Amma bir gün sənətçilərimizdən biri testi bitirməyimi gözləyirdi - yəqin ki, o an söyürdüm - və əsəbi halda əlindəki nəzarətçini fırladı. Bir səhv baş verdi. "Gözləyin, nə?!" Yaxşı, yenə et!”

Bu iki hadisənin bir-birinə bağlı olduğunu başa düşdükdə, səhvi asanlıqla təkrarlaya bildim: yaddaş kartına yazmağa başladım, nəzarətçini köçürdüm və yaddaş kartını xarab etdim. Mənə bu, hardware səhvi kimi görünürdü.

Mən Konniyə gəldim və ona kəşfim haqqında danışdım. O, məlumatı PS1-i hazırlayan mühəndislərdən birinə ötürdü. "Mümkün deyil" deyə cavab verdi, "Bu hardware problemi ola bilməz." Mən Konnidən bizim üçün söhbət təşkil etməyi xahiş etdim.

Mühəndis mənə zəng etdi və biz onun sınmış ingilis dilində və mənim (son dərəcə) qırıq yapon dilində mübahisə etdik. Nəhayət, dedim: "İcazə verin, nəzarətçinin hərəkəti xətaya səbəb olan 30 sətirlik test proqramımı göndərim." Razılaşdı. Bunun vaxt itkisi olduğunu və o, yeni bir layihə üzərində çox məşğul olduğunu, lakin Sony üçün çox vacib bir tərtibatçı olduğumuz üçün təslim olacağını söylədi. Test proqramımı təmizlədim və ona göndərdim.

Növbəti axşam (biz Los-Ancelesdə idik, o isə Tokioda idi) mənə zəng etdi və həyasızcasına üzr istədi. Bu hardware problemi idi.

Mən səhvin tam olaraq nə olduğunu bilmirəm, amma Sony qərargahında eşitdiyimə görə, əgər siz taymeri kifayət qədər yüksək qiymətə qoyursanız, o, taymer kristalının yaxınlığında ana platada olan komponentlərə müdaxilə edir. Onlardan biri yaddaş kartı üçün ötürmə sürətinin nəzarətçisi idi ki, bu da nəzarətçilər üçün ötürmə sürətini təyin edirdi. Mən mühəndis deyiləm, ona görə də nəyisə qarışdırmışam.

Ancaq nəticə odur ki, anakartdakı komponentlər arasında müdaxilə var idi. 1 kHz-də işləyən taymer ilə nəzarətçi portu və yaddaş kartı portu vasitəsilə eyni vaxtda məlumatları ötürərkən, bitlər itirildi, məlumatlar itirildi və kart zədələndi.

Pis inəklər

1980-ci illərdə mentorum Sergey PDP-1800-in sovet klonu olan SM-11 üçün proqram təminatı yazdı. Bu mikrokompüter SSRİ-nin mühüm nəqliyyat qovşağı olan Sverdlovsk yaxınlığındakı dəmir yolu vağzalında yenicə quraşdırılıb. Yeni sistem vaqonların və yük daşımalarının istiqamətləndirilməsi üçün nəzərdə tutulmuşdu. Ancaq təsadüfi qəzalara və qəzalara səbəb olan zəhlətökən bir səhv var idi. Düşmə həmişə axşam evə gedəndə baş verirdi. Lakin ertəsi gün hərtərəfli araşdırmaya baxmayaraq, kompüter bütün mexaniki və avtomatik testlərdə düzgün işlədi. Bu, adətən müəyyən şərtlər altında baş verən yarış vəziyyətini və ya digər rəqabət səhvini göstərir. Gecə gec saatlarda zənglərdən bezən Sergey bunun dibinə varmaq qərarına gəldi və ilk növbədə meydançadakı şəraitin kompüterin sıradan çıxmasına səbəb olduğunu başa düş.

Əvvəlcə o, bütün açıqlanmayan düşmələrin statistikasını topladı və tarix və vaxta görə qrafik yaratdı. Nümunə aydın idi. Daha bir neçə gün müşahidə etdikdən sonra Sergey başa düşdü ki, gələcək sistem uğursuzluqlarının vaxtını asanlıqla proqnozlaşdıra bilər.

O, tezliklə öyrəndi ki, stansiya Ukraynanın şimalından və qərbi Rusiyadan gələn mal-qara qatarlarını çeşidləyərkən yaxınlıqdakı kəsim məntəqəsinə gedəndə fasilələr baş verib. Bu, özlüyündə qəribə idi, çünki kəsim məntəqəsi daha yaxında, Qazaxıstanda yerləşən təsərrüfatlar tərəfindən təmin edilirdi.

1986-cı ildə Çernobıl Atom Elektrik Stansiyası partladı və radioaktiv tullantılar ətraf əraziləri yaşayış üçün yararsız etdi. Ukraynanın şimalında, Belarusiyada və Rusiyanın qərbində geniş ərazilər çirklənmişdi. Gələn vaqonlarda yüksək səviyyədə radiasiya olduğundan şübhələnən Sergey bu nəzəriyyəni yoxlamaq üçün bir üsul hazırlayıb. Əhaliyə dozimetrlərin olması qadağan edildi, ona görə də Sergey dəmiryol vağzalında bir neçə hərbçinin yanında qeydiyyatdan keçdi. Bir neçə dəfə araq içdikdən sonra o, şübhəli vaqonlardan birində əsgəri radiasiya səviyyəsini ölçməyə razı sala bilib. Məlum olub ki, səviyyə normal dəyərlərdən bir neçə dəfə yüksək olub.

Mal-qara nəinki çoxlu radiasiya buraxırdı, onun səviyyəsi o qədər yüksək idi ki, stansiyanın yanındakı binada yerləşən SM-1800-ün yaddaşında təsadüfi bit itkisinə səbəb olurdu.

SSRİ-də ərzaq qıtlığı var idi və hakimiyyət Çernobıl ətini ölkənin digər bölgələrindən gələn ətlə qarışdırmaq qərarına gəldi. Bu, qiymətli resursları itirmədən radioaktivliyin ümumi səviyyəsini azaltmağa imkan verdi. Bundan xəbər tutan Sergey dərhal mühacirət üçün sənədləri doldurdu. Və zaman keçdikcə radiasiya səviyyəsi azaldıqda kompüter qəzaları öz-özünə dayandı.

Borular vasitəsilə

Bir zamanlar Movietech Solutions kinoteatrlar üçün mühasibat uçotu, bilet satışı və ümumi idarəetmə üçün nəzərdə tutulmuş proqram təminatı yaratmışdır. Flaqman tətbiqinin DOS versiyası Şimali Amerikadakı kiçik və orta ölçülü kinoteatr şəbəkələri arasında olduqca populyar idi. Buna görə də təəccüblü deyil ki, ən son sensor ekranlar və özünəxidmət köşkləri ilə inteqrasiya olunmuş və bütün növ hesabat alətləri ilə təchiz edilmiş Windows 95 versiyası elan edildikdə, o da tez bir zamanda populyarlaşdı. Çox vaxt yeniləmə problemsiz keçdi. Yerli İT heyəti yeni avadanlıq quraşdırdı, məlumatları köçürdü və iş davam etdi. Davam etmədiyi hallar istisna olmaqla. Bu baş verəndə şirkət "Təmizləyici" ləqəbli Ceymsi göndərəcəkdi.

Ləqəb iyrənc bir növü nəzərdə tutsa da, təmizləyici sadəcə təlimatçı, quraşdırıcı və hər cür işlərin birləşməsidir. Ceyms bir neçə gün müştərinin saytında bütün komponentləri bir yerə yığar, sonra daha bir neçə gün işçilərə yeni sistemdən necə istifadə etməyi öyrədir, yaranan hər hansı hardware problemlərini həll edir və proqram təminatına ilkin mərhələdə kömək edirdi.

Buna görə də təəccüblü deyil ki, bu gərgin vaxtlarda Ceyms səhər tezdən ofisə gəldi və iş masasına çatmamış menecer onu həmişəkindən daha çox kofeinlə qarşıladı.

"Qorxuram ki, ən qısa zamanda Yeni Şotlandiya, Annapolisə getməlisən." Onların bütün sistemi çökdü və mühəndisləri ilə bir gecə işlədikdən sonra nə baş verdiyini anlaya bilmirik. Görünür, şəbəkə serverdə uğursuz olub. Ancaq sistem bir neçə dəqiqə işlədikdən sonra.

- Köhnə sistemə qayıtmadılar? - James tamamilə ciddi cavab verdi, baxmayaraq ki, zehni olaraq təəccüblə gözlərini böyüdü.

— Tam olaraq: onların İT mütəxəssisi “prioritetlərini dəyişdi” və köhnə serverləri ilə ayrılmaq qərarına gəldi. James, onlar sistemi altı saytda quraşdırdılar və sadəcə mükafat dəstəyi üçün pul ödədilər və onların işi indi 1950-ci illərdə olduğu kimi idarə olunur.

Ceyms azacıq özünü düzəltdi.

- Bu başqa məsələdir. Yaxşı, başlayaq.

Annapolisə gələndə ilk işi müştərinin problemi olan ilk teatrını tapmaq oldu. Hava limanında çəkilmiş xəritədə hər şey layiqli görünürdü, lakin istədiyiniz ünvanın ətrafı şübhəli görünürdü. Getto deyil, noir filmini xatırladır. Ceyms şəhərin kənarında park edən zaman bir fahişə ona yaxınlaşdı. Annapolisin ölçüsünü nəzərə alsaq, o, çox güman ki, bütün şəhərdə yeganə idi. Onun görünüşü dərhal böyük ekranda pul müqabilində seks təklif edən məşhur obrazı yada saldı. Xeyr, Culiya Roberts haqqında deyil, Con Voight haqqında ["Gecəyarısı Kovboy" filminə işarə - təqribən. zolaq].

Fahişəni yola salan Ceyms kinoya getdi. Ətraf yaxşılaşmışdı, amma yenə də bərbad vəziyyətdə qalmışdı. Ceymsin çox narahat olduğu deyildi. O, əvvəllər də bərbad yerlərdə olub. Bu, Kanada idi, burada hətta quldurlar pul kisəsini götürdükdən sonra “sağ ol” deyə biləcək qədər nəzakətli olurlar.

Kinoteatrın yan girişi rütubətli xiyabanda idi. Ceyms qapıya tərəf getdi və qapını döydü. Tezliklə cırıldadı və bir az açıldı.

-Sən təmizlikçisən? – içəridən boğuq bir səs gəldi.

- Hə, mənəm... Hər şeyi düzəltməyə gəlmişəm.

Ceyms kinoteatrın foyesinə girdi. Görünür, başqa çarələri qalmadığı üçün işçilər ziyarətçilərə kağız biletlər paylamağa başladılar. Bu, maliyyə hesabatlarını çətinləşdirdi, daha maraqlı detalları bir yana qoyaq. Lakin işçilər Ceymsi rahatlıqla qarşıladılar və dərhal onu server otağına apardılar.

İlk baxışdan hər şey qaydasında idi. James serverə daxil oldu və adi şübhəli yerləri yoxladı. Problem deyil. Bununla belə, çoxlu ehtiyatla Ceyms serveri bağladı, şəbəkə kartını dəyişdirdi və sistemi geri qaytardı. Dərhal tam işə başladı. Heyət yenidən bilet satmağa başlayıb.

Ceyms Marka zəng edərək vəziyyəti ona bildirdi. Təsəvvür etmək çətin deyil ki, Ceymsin yanında qalmaq və gözlənilməz bir şey olub olmadığını görmək istəyə bilər. O, pilləkənləri enərək işçilərdən nə baş verdiyini soruşmağa başladı. Aydındır ki, sistem fəaliyyətini dayandırıb. Onu söndürüb yandırdılar, hər şey işlədi. Lakin 10 dəqiqədən sonra sistem sıradan çıxdı.

Məhz bu anda oxşar bir şey oldu. Birdən bilet sistemi səhvlər atmağa başladı. İşçilər ah çəkib kağız biletləri götürdülər və Ceyms tələsik server otağına getdi. Serverdə hər şey yaxşı görünürdü.

Sonra işçilərdən biri içəri girdi.

- Sistem yenidən işləyir.

Ceyms heç nə etmədiyi üçün çaşqın idi. Daha doğrusu, sistemin işləməsini təmin edəcək heç bir şey yoxdur. O, sistemdən çıxdı, telefonunu götürdü və şirkətinin dəstək xəttinə zəng etdi. Tezliklə həmin işçi server otağına daxil oldu.

- Sistem çöküb.

James serverə baxdı. Çox rəngli formaların maraqlı və tanış nümunəsi ekranda rəqs etdi - xaotik şəkildə qıvrılan və bir-birinə qarışan borular. Biz hamımız bu ekran qoruyucunu nə vaxtsa görmüşük. O, gözəl təsvir edilmiş və sözün əsl mənasında hipnozedici idi.


James düyməni basdı və naxış yox oldu. O, kassaya tələsdi və yolda ona qayıdan işçi ilə qarşılaşdı.

- Sistem yenidən işləyir.

Zehni üz ovucunu edə bilsəniz, Ceymsin etdiyi tam olaraq budur. Ekran qoruyucu. OpenGL istifadə edir. Və buna görə də, əməliyyat zamanı server prosessorunun bütün resurslarını istehlak edir. Nəticədə, serverə edilən hər bir zəng fasilə ilə başa çatır.

James server otağına qayıtdı, daxil oldu və ekran qoruyucunu boş ekranla gözəl borularla əvəz etdi. Yəni prosessor resurslarını 100% istehlak edən ekran qoruyucusu yerinə mən resursları sərf etməyən başqa birini quraşdırdım. Sonra təxminimi yoxlamaq üçün 10 dəqiqə gözlədim.

Ceyms növbəti kinoteatra gələndə o, menecerinə ekran qoruyucunu söndürmək üçün indicə 800 km uçduğunu necə izah edəcəyini düşünürdü.

Ayın müəyyən bir mərhələsində qəza

Həqiqi hekayə. Bir gün ayın fazasından asılı olan bir proqram səhvi yarandı. Ayın həqiqi fazasına yaxınlaşmanı hesablamaq üçün müxtəlif MIT proqramlarında adətən istifadə edilən kiçik bir rutin var idi. GLS bu rejimi fayl yazarkən təxminən 80 simvol uzunluğunda vaxt damğası olan sətir çıxaran LISP proqramına daxil etdi. Mesajın ilk sətirinin çox uzun olması və növbəti sətirə keçməsi çox nadir hal idi. Proqram daha sonra bu faylı oxuyanda lənət etdi. Birinci sətrin uzunluğu dəqiq tarix və vaxtdan, eləcə də vaxt damğasının çap edildiyi vaxtdakı mərhələ spesifikasiyasının uzunluğundan asılı idi. Yəni, səhv sözün əsl mənasında ayın fazasından asılı idi!

İlk kağız nəşri Jarqon faylı (Steele-1983) təsvir edilən səhvə səbəb olan belə bir xəttin nümunəsini ehtiva edir, lakin yazıçı onu "sabitləşdirdi". O vaxtdan bu, "ay fazasının səhvi" kimi təsvir edilmişdir.

Bununla belə, fərziyyələrlə diqqətli olun. Bir neçə il əvvəl CERN-in (Avropa Nüvə Tədqiqatları Mərkəzi) mühəndisləri Böyük Elektron-Pozitron Kollayderində apardıqları təcrübələrdə səhvlərlə qarşılaşdılar. Nəticəni elm adamlarına göstərməzdən əvvəl kompüterlər bu cihaz tərəfindən yaradılan böyük miqdarda məlumatı aktiv şəkildə emal etdiyi üçün, bir çoxları proqramın ayın fazasına bir növ həssas olduğunu fərz edirdilər. Bir neçə ümidsiz mühəndis həqiqətin dibinə gəldi. Səhv Ayın keçidi zamanı Yerin deformasiyası nəticəsində 27 km uzunluğunda olan halqanın həndəsəsinin cüzi dəyişməsi səbəbindən yaranıb! Bu hekayə fizika folkloruna “Nyutonun hissəciklər fizikasından qisası” kimi daxil oldu və fizikanın ən sadə və ən qədim qanunları ilə ən qabaqcıl elmi anlayışlar arasındakı əlaqə nümunəsi oldu.

Tualetin yuyulması qatarı dayandırır

Haqqında eşitdiyim ən yaxşı hardware səhvi Fransada yüksək sürətli qatarda olub. Səhv qatarın təcili əyləclənməsinə səbəb oldu, ancaq göyərtəsində sərnişinlər olduqda. Hər belə halda qatar istismardan çıxarılıb, yoxlanılıb, lakin heç nə aşkar edilməyib. Sonra onu yenidən xəttə göndərdilər və o, dərhal dayanacağa çırpıldı.

Yoxlamaların birində qatarda gedən mühəndis tualetə gedib. Tezliklə yuyuldu, BOOM! Təcili dayanacaq.

Mühəndis sürücü ilə əlaqə saxlayıb soruşdu:

- Əyləc basmazdan əvvəl nə edirdiniz?

- Yaxşı, enişdə yavaşladım...

Bu qəribə idi, çünki normal iş zamanı qatar enişdə onlarla dəfə yavaşlayır. Qatar hərəkət etdi və növbəti enişdə maşinist xəbərdarlıq etdi:

- Mən yavaşlayacağam.

Heç nə olmadı.

— Sonuncu əyləc zamanı nə etdiniz? – sürücü soruşdu.

- Yaxşı... tualetdə idim...

- Yaxşı, onda tualetə get və biz yenə aşağı düşəndə ​​nə etdinsə et!

Mühəndis tualetə getdi və sürücü xəbərdarlıq etdikdə: "Mən yavaşlayıram" suyu yudu. Təbii ki, qatar dərhal dayandı.

İndi onlar problemi təkrar edə bilərdilər və səbəbi tapmaq lazımdır.

İki dəqiqədən sonra onlar gördülər ki, mühərrik əyləcinin pult kabeli (qatarın hər iki ucunda bir mühərrik var idi) elektrik şkafının divarından ayrılıb və tualetin tıxacının elektromaqnitini idarə edən rele üzərində uzanıb... Röle gələndə işə salındı, əyləc kabelində müdaxilə yaratdı və sistemin nasazlıqlara qarşı qorunması sadəcə təcili əyləcdən ibarət idi.

FORTRAN-a nifrət edən qapı

Bir neçə ay əvvəl biz materikdə (bu Havayda idi) şəbəkə əlaqələrinin çox, çox yavaş olduğunu gördük. Bu 10-15 dəqiqə davam edə bilər və sonra birdən yenidən baş verə bilər. Bir müddət sonra həmkarım mənə materikdə şəbəkə əlaqələrinin olmasından şikayət etdi ümumiyyətlə işləmir. Onun materikdəki maşına kopyalanması lazım olan bəzi FORTRAN kodu var idi, lakin bunu edə bilmədi, çünki "şəbəkə FTP yükləməsini tamamlamaq üçün kifayət qədər uzun müddət dayanmadı".

Bəli, məlum oldu ki, bir həmkarı FORTRAN-da mənbə kodu olan faylı materikdəki bir maşına FTP etməyə çalışarkən şəbəkə xətaları baş verib. Biz faylı arxivləşdirməyə çalışdıq: sonra o, rəvan surətdə kopyalandı (lakin hədəf maşında unpacker yox idi, ona görə də problem həll olunmadı). Nəhayət, biz FORTRAN kodunu çox kiçik parçalara "parçaladıq" və onları bir-bir göndərdik. Fraqmentlərin əksəriyyəti problemsiz surətdə köçürüldü, lakin bir neçə hissə keçmədi və ya sonra keçdi çox sayda cəhdləri.

Problemli keçidləri araşdırdığımız zaman onların ortaq bir cəhətinin olduğunu aşkar etdik: onların hamısında böyük C hərfindən ibarət sətirlərlə başlayan və bitən şərh blokları var idi (bir həmkarım FORTRAN-da şərh verməyə üstünlük verirdi). Biz materikdəki şəbəkə ekspertlərinə e-poçt göndərdik və kömək istədik. Təbii ki, FTP vasitəsilə ötürülə bilməyən fayllarımızın nümunələrini görmək istəyirdilər... amma məktublarımız onlara çatmadı. Nəhayət, sadə bir şey tapdıq təsvir etməkköçürülməyən fayllar nə kimi görünür. İşlədi :) [Bura problemli FORTRAN şərhlərindən birini əlavə etməyə cəsarət edirəm? Yəqin ki, buna dəyməz!]

Sonda bunu başa düşə bildik. Bu yaxınlarda kampusun bizim hissəsi ilə materik şəbəkəsi arasında yeni şlüz quraşdırılmışdır. Böyük C hərfinin təkrar bitlərini ehtiva edən paketləri ötürməkdə ÇOX çətinlik çəkdi! Bu paketlərdən yalnız bir neçəsi bütün şlüz resurslarını ələ keçirə və digər paketlərin əksəriyyətinin keçməsinin qarşısını ala bilər. Şluz istehsalçısına şikayət etdik... və onlar cavab verdilər: “Oh, bəli, təkrarlanan C səhvi ilə üzləşmisiniz! Onun haqqında artıq xəbərimiz var”. Nəhayət, başqa bir istehsalçıdan yeni şlüz almaqla problemi həll etdik (əvvəlkilərin müdafiəsində FORTRAN proqramlarını köçürə bilməmək bəziləri üçün üstünlük ola bilər!).

Çətin dəfə

Bir neçə il əvvəl, 40-cü mərhələ klinik sınaqların xərclərini azaltmaq üçün Perl-də ETL sisteminin yaradılması üzərində işləyərkən, təxminən 000 tarixi emal etməli oldum. Onlardan ikisi imtahandan keçə bilməyib. Bu, məni çox narahat etmədi, çünki bu tarixlər müştəri tərəfindən təqdim olunan məlumatlardan götürülüb ki, bu da tez-tez təəccüblüdür. Amma ilkin məlumatları yoxlayanda məlum oldu ki, bu tarixlər 1 yanvar 2011-ci il və 1 yanvar 2007-ci il tarixləridir. Fikirləşdim ki, səhv indi yazdığım proqramda var, amma məlum oldu ki, artıq 30 ildir. köhnə. Bu, proqram ekosistemi ilə tanış olmayanlar üçün müəmmalı görünə bilər. Başqa bir şirkətin pul qazanmaq üçün uzun müddətdir verdiyi qərara görə, müştərim bir şirkətin təsadüfən, digərinin isə qəsdən təqdim etdiyi səhvi düzəltmək üçün mənə pul ödədi. Nə danışdığımı başa düşməyiniz üçün səhvə çevrilən xüsusiyyəti əlavə edən şirkət, eləcə də həll etdiyim sirli səhvə töhfə verən bir neçə digər maraqlı hadisə haqqında danışmalıyam.

Köhnə yaxşı günlərdə Apple kompüterləri bəzən kortəbii olaraq tarixlərini 1-cü il yanvarın 1904-nə sıfırlayırdılar. Səbəb sadə idi: tarix və vaxtı izləmək üçün batareya ilə işləyən “sistem saatı”ndan istifadə edirdi. Batareya öləndə nə oldu? Kompüterlər tarixi bir dövrün başlanğıcından saniyələrin sayına görə izləməyə başladılar. Epoxa dedikdə biz istinadın orijinal tarixini nəzərdə tuturduq və Macintoshes üçün bu, 1 yanvar 1904-cü il idi. Batareya bitdikdən sonra cari tarix göstərilən tarixə sıfırlandı. Bəs niyə bu baş verdi?

Əvvəllər Apple orijinal tarixdən bəri saniyələrin sayını saxlamaq üçün 32 bitdən istifadə edirdi. Bir bit iki dəyərdən birini saxlaya bilər - 1 və ya 0. İki bit dörd dəyərdən birini saxlaya bilər: 00, 01, 10, 11. Üç bit - səkkizdən bir dəyər: 000, 001, 010, 011, 100 , 101, 110, 111 və s. 32 isə 232 dəyərdən birini, yəni 4 saniyəni saxlaya bilirdi. Apple tarixləri üçün bu, təxminən 294 ilə bərabərdir, ona görə də köhnə Mac-lər 967-cı ildən sonrakı tarixləri idarə edə bilməz. Sistemin batareyası ölürsə, tarix dövrün əvvəlindən 296 saniyəyə sıfırlanır və siz kompüteri hər dəfə açdığınız zaman (və ya yeni batareya satın alana qədər) tarixi əl ilə təyin etməlisiniz.

Bununla belə, Apple-ın tarixləri epoxadan bəri saniyələr kimi saxlama qərarı, görəcəyimiz kimi, epoxdan əvvəlki tarixləri idarə edə bilməyəcəyimiz anlamına gəlirdi ki, bu da görəcəyimiz kimi çox geniş nəticələrə malikdir. Apple səhv deyil, bir xüsusiyyət təqdim etdi. Digər şeylər arasında bu, Macintosh əməliyyat sisteminin “minilliyin səhvinə” qarşı immunitetə ​​malik olması demək idi (məhdudiyyətləri aşmaq üçün öz tarix sistemlərinə malik olan bir çox Mac tətbiqləri haqqında bunu söyləmək mümkün deyildi).

Davam et. Biz Lotus 1-2-3-dən, IBM-in “qatil proqramı”ndan istifadə etdik ki, bu da PC inqilabının başlamasına kömək etdi, baxmayaraq ki, Apple kompüterlərində fərdi kompüteri uğur qazandıran VisiCalc var idi. Ədalət naminə deyim ki, 1-2-3 görünməsəydi, fərdi kompüterlər çətin ki, havaya qalxardı və fərdi kompüterlərin tarixi çox fərqli inkişaf edə bilərdi. Lotus 1-2-3 səhv olaraq 1900-cü ili sıçrayış ili kimi qəbul etdi. Microsoft özünün ilk elektron cədvəli olan Multiplan-i buraxdıqda bazarın kiçik bir hissəsini ələ keçirdi. Excel layihəsini işə saldıqda, onlar Lotus 1-2-3-dən təkcə satır və sütun adlandırma sxemini köçürmək deyil, həm də 1900-cü ili qəsdən sıçrayış ili kimi nəzərdən keçirməklə səhv uyğunluğunu təmin etmək qərarına gəldilər. Bu problem bu gün də mövcuddur. Yəni, 1-2-3-də bu bir səhv idi, lakin Excel-də bu, səhv olsa belə, bütün 1-2-3 istifadəçilərinin məlumatları dəyişdirmədən öz cədvəllərini Excel-ə idxal edə bilmələrini təmin edən şüurlu bir qərar idi.

Amma başqa problem var idi. Əvvəlcə Microsoft Macintosh üçün 1-cü il yanvarın 1904-dən əvvəlki tarixləri tanımayan Excel-i buraxdı. Exceldə isə 1-cü il yanvarın 1900-i eranın başlanğıcı hesab olunurdu. Buna görə də, tərtibatçılar elə bir dəyişiklik etdilər ki, onların proqramı dövrün növünü tanısın və məlumatları istənilən dövrə uyğun olaraq özündə saxlasın. Microsoft hətta bununla bağlı izahatlı məqalə də yazıb. Və bu qərar mənim səhvimə səbəb oldu.

ETL sistemim müştərilərdən Windows-da yaradılmış, lakin Mac-da da yaradıla bilən Excel cədvəllərini aldı. Buna görə də, cədvəldəki dövrün başlanğıcı ya 1-cü il, ya da 1900-cü il yanvarın 1-i ola bilər. Necə tapmaq olar? Excel fayl formatı lazımi məlumatları göstərir, lakin mənim istifadə etdiyim təhlilçi onu göstərmədi (indi göstərir) və müəyyən bir cədvəl üçün dövrü bildiyinizi güman etdi. Yəqin ki, Excel binar formatını başa düşmək və təhlil edən müəllifə yamaq göndərmək üçün daha çox vaxt sərf edə bilərdim, lakin müştəri üçün daha çox işim var idi, ona görə də dövrü müəyyən etmək üçün tez bir evristik yazdım. O, sadə idi.

Excel-də 5 iyul 1998-ci il tarixi "07-05-98" (yararsız Amerika sistemi), "5 iyul 98", "5 iyul 1998", "5-iyul-98" və ya formatında təqdim edilə bilər. başqa bir format.başqa bir faydasız format (ironik olaraq, Excel versiyamın təklif etmədiyi formatlardan biri ISO 8601 idi). Bununla belə, cədvəl daxilində formatlaşdırılmamış tarix ya dövr-35981-cü il üçün "1900", ya da dövr-34519-cü il üçün "1904" (rəqəmlər dövrdən sonrakı günlərin sayını göstərir) kimi saxlanılıb. Mən sadəcə olaraq formatlaşdırılmış tarixdən ili çıxarmaq üçün sadə analizatordan istifadə etdim və sonra formatlaşdırılmamış tarixdən ili çıxarmaq üçün Excel analizatorundan istifadə etdim. Hər iki dəyər 4 il fərqlənirdisə, onda mən epoch-1904 ilə bir sistemdən istifadə etdiyimi bilirdim.

Niyə sadəcə formatlaşdırılmış tarixlərdən istifadə etmədim? Çünki 5-ci il iyulun 1998-i itirilmiş ayın günü ilə “98 iyul” kimi formatlana bilər. Cədvəlləri o qədər müxtəlif yollarla yaradan bir çox şirkətdən aldıq ki, tarixləri müəyyən etmək bizim (bu halda məndən) asılı idi. Bundan əlavə, əgər Excel bunu düzgün başa düşürsə, biz də bunu etməliyik!

Eyni zamanda 39082 ilə qarşılaşdım. Nəzərinizə çatdırım ki, Lotus 1-2-3 1900-cü ili sıçrayış ili hesab edirdi və bu, Excel-də sədaqətlə təkrarlandı. Və bu, 1900-cü ilə bir gün əlavə etdiyi üçün, bir çox tarix hesablama funksiyaları həmin gün üçün səhv ola bilər. Yəni, 39082 1 yanvar 2011-ci il (Mac-lərdə) və ya 31 dekabr 2006-cı il (Windows-da) ola bilərdi. Əgər mənim “il analizatorum” formatlanmış dəyərdən 2011-ci ili çıxarıbsa, hər şey qaydasındadır. Lakin Excel analizatoru hansı dövrün istifadə edildiyini bilmədiyi üçün defolt olaraq 1900-cı ili qaytararaq epoch-2006-ə keçir. Ərizəm fərqin 5 il olduğunu gördü, səhv hesab etdi, onu qeyd etdi və formatlaşdırılmamış bir dəyər qaytardı.

Bunu aradan qaldırmaq üçün bunu yazdım (psevdokod):

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

Və sonra bütün 40 tarix düzgün təhlil edildi.

Böyük çap işlərinin ortasında

1980-ci illərin əvvəllərində atam yüksək sürətli lentlə qidalanma üçün lent ötürücüləri və pnevmatik sistemlər yaradan, hazırda fəaliyyət göstərməyən Storage Technology bölməsində işləyirdi.

Sürücüləri elə yenidən dizayn etdilər ki, yeddi “B” diskinə birləşdirilmiş bir mərkəzi “A” sürücüsü ola bilsin və “A” sürücüsünü idarə edən RAM-dakı kiçik ƏS bütün “B” disklərinə oxuma və yazma əməliyyatlarını həvalə edə bilsin.

Hər dəfə “A” sürücüsü işə salındıqda əməliyyat sistemini onun yaddaşına yükləmək üçün “A”ya qoşulmuş periferik sürücüyə disket daxil etmək lazım gəlirdi. Bu, son dərəcə primitiv idi: hesablama gücü 8 bitlik mikrokontroller tərəfindən təmin edildi.

Bu cür avadanlıqların hədəf auditoriyası çoxlu ünvan etiketlərini və ya bank çıxarışlarını çap etməyə ehtiyac duyan çox böyük məlumat anbarlarına - banklar, pərakəndə satış şəbəkələri və s.-yə malik şirkətlər idi.

Bir müştəri problemlə üzləşdi. Çap işinin ortasında xüsusi bir “A” sürücüsü işləməyi dayandıra bilər və bu, bütün işin dayanmasına səbəb ola bilər. Sürücünün işini bərpa etmək üçün heyət hər şeyi yenidən yükləməli oldu. Və bu, altı saatlıq tapşırığın ortasında baş veribsə, o zaman böyük miqdarda bahalı kompüter vaxtı itirildi və bütün əməliyyatın qrafiki pozuldu.

Storage Technologies-dən texniki işçilər göndərilib. Lakin bütün səylərinə baxmayaraq, sınaq şəraitində səhvi təkrarlaya bilmədilər: bu, böyük çap işlərinin ortasında baş verirdi. Problem aparatda deyildi, onlar bacardıqları hər şeyi əvəz etdilər: RAM, mikrokontroller, disket diski, lent sürücüsünün hər düşünülə bilən hissəsi - problem davam etdi.

Sonra texniki işçilər qərargaha zəng edərək Eksperti çağırdılar.

Mütəxəssis bir stul və bir fincan qəhvə götürdü, kompüter otağında oturdu - o vaxtlar kompüterlər üçün otaqlar var idi - və işçilərin böyük çap işini növbəyə qoymasına baxdı. Mütəxəssis uğursuzluğun baş verəcəyini gözləyirdi - və oldu. Hamı Ekspertə baxdı, amma bunun niyə baş verdiyi barədə heç bir fikri yox idi. Beləliklə, o, işi yenidən növbəyə qoymağı əmr etdi və bütün işçilər və texniki işçilər işə qayıtdılar.

Mütəxəssis yenidən stulda əyləşərək uğursuzluğu gözləməyə başladı. Təxminən altı saat keçdi və uğursuzluq baş verdi. Ekspertin yenə heç bir fikri yox idi, ancaq hər şey insanlarla dolu bir otaqda baş verdi. O, missiyanın yenidən başlamasını əmr etdi, geri oturdu və gözlədi.

Üçüncü uğursuzluqla Mütəxəssis bir şey gördü. Personel xarici diskdəki lentləri dəyişdirərkən nasazlıq baş verdi. Üstəlik, nasazlıq işçilərdən biri yerdəki müəyyən kafeldən keçən kimi baş verdi.

Qaldırılmış mərtəbə 6 ilə 8 düym yüksəklikdə qoyulmuş alüminium plitələrdən hazırlanmışdır. Kompüterlərdən gələn çoxsaylı naqillər hər kəsin təsadüfən mühüm kabelə basmaması üçün qaldırılmış döşəmənin altından keçirdi. Dağıntıların qaldırılmış döşəmənin altına düşməməsi üçün plitələr çox sıx şəkildə qoyulmuşdur.

Ekspert kafellərdən birinin deformasiyaya uğradığını anlayıb. Bir işçi onun küncünə basdıqda, kafelin kənarları bitişik plitələrə sürtülür. Kafelləri birləşdirən plastik hissələr də onlarla sürtülürdü ki, bu da radiotezlik müdaxiləsi yaradan statik mikro boşalmalara səbəb olur.

Bu gün RAM radio tezliyi müdaxiləsindən daha yaxşı qorunur. Amma o illərdə belə deyildi. Mütəxəssis başa düşdü ki, bu müdaxilə yaddaşı və onunla birlikdə əməliyyat sisteminin işini pozur. Dəstək xidmətinə zəng etdi, yeni kafel sifariş etdi, özü quraşdırdı və problem aradan qalxdı.

Yüksək gelgitdir!

Hekayə server otağında, Portsmutdakı ofisin dördüncü və ya beşinci mərtəbəsində (zənn edirəm), doklar sahəsində baş verdi.

Bir gün əsas verilənlər bazası olan Unix serveri qəzaya uğradı. Onu yenidən işə saldılar, lakin o, sevinclə təkrar-təkrar yıxılmağa davam etdi. Dəstək xidmətindən kiməsə zəng etmək qərarına gəldik.

Dəstək adamı... Məncə onun adı Mark idi, amma bunun heç bir əhəmiyyəti yoxdur... Mən onu tanıdığımı düşünmürəm. Fərqi yoxdur, həqiqətən. Markla qalaq, tamam? Əla.

Beləliklə, bir neçə saatdan sonra Mark gəldi (Lidsdən Portsmuta qədər uzun bir yol deyil, bilirsiniz), serveri yandırdı və hər şey problemsiz işlədi. Tipik lənətə gəlmiş dəstək, müştəri bundan çox üzülür. Mark jurnal fayllarına baxır və xoşagəlməz heç nə tapmır. Beləliklə, Mark yenidən qatara minir (yaxud hansı nəqliyyat növünə minirsə gəlsin, mənim bildiyim qədər bu, axsaq inək ola bilərdi... hər halda, fərqi yoxdur, tamammı?) və boş yerə Lidsə qayıdır. gün.

Həmin axşam server yenidən çökür. Hekayə eynidir... server qalxmır. Mark uzaqdan kömək etməyə çalışır, lakin müştəri serveri işə sala bilmir.

Başqa bir qatar, avtobus, limon beze və ya başqa bir pislik və Mark yenidən Portsmutdadır. Baxın, server heç bir problem olmadan yüklənir! Möcüzə. Mark əməliyyat sistemi və ya proqram təminatı ilə hər şeyin qaydasında olub-olmadığını yoxlamaq üçün bir neçə saat sərf edir və Lidsə yola düşür.

Günün ortasında server qəzaya uğrayır (sakin olun!). Bu dəfə serveri əvəz etmək üçün aparat dəstəyi işçilərini cəlb etmək məqsədəuyğun görünür. Amma yox, təxminən 10 saatdan sonra o da düşür.

Vəziyyət bir neçə gün təkrarlandı. Server işləyir, təxminən 10 saatdan sonra çökür və növbəti 2 saat ərzində işə düşmür. Soyutma, yaddaş sızmalarını yoxladılar, hər şeyi yoxladılar, amma heç nə tapmadılar. Sonra qəzalar dayandı.

Həftə qayğısız keçdi... hamı xoşbəxt idi. Hər şey yenidən başlayana qədər xoşbəxt olun. Şəkil eynidir. 10 saat iş, 2-3 saat fasilə...

Sonra kimsə (deyəsən, mənə dedilər ki, bu adamın İT ilə heç bir əlaqəsi yoxdur) dedi:

"Bu gelgitdir!"

Nida boş baxışlarla qarşılandı və yəqin ki, kiminsə əli təhlükəsizlik zəngi düyməsinə tərəddüd etdi.

"O, dalğa ilə işləməyi dayandırır."

Bu, qəhvə içərkən “Tide Yearbook”u oxumaq ehtimalı olmayan İT dəstəyi işçiləri üçün tamamilə yad bir konsepsiya kimi görünür. Onlar izah etdilər ki, bu heç bir şəkildə gelgit ilə əlaqəli ola bilməz, çünki server bir həftə uğursuz işləyirdi.

"Keçən həftə su axını aşağı idi, lakin bu həftə yüksəkdir."

Yaxta lisenziyası olmayanlar üçün bir az terminologiya. Tides Ayın dövründən asılıdır. Yer fırlandıqca isə hər 12,5 saatdan bir Günəş və Ayın cazibə qüvvəsi gelgit dalğası yaradır. 12,5 saatlıq dövrün əvvəlində yüksək gelgit, dövrənin ortasında bir eniş, sonunda isə yenidən yüksək gelgit var. Ancaq ayın orbiti dəyişdikcə aşağı və yüksək gelgit arasındakı fərq də dəyişir. Ay Günəşlə Yer arasında və ya Yerin əks tərəfində olduqda (tam ay və ya ay yoxdur), biz Syzygyn gelgitləri - ən yüksək yüksək gelgitlər və ən aşağı aşağı gelgitlər alırıq. Yarım ayda biz quadratur gelgitləri alırıq - ən aşağı gelgitlər. İki ifrat arasındakı fərq çox azalır. Ay dövrü 28 gün davam edir: syzygian - quadrature - syzygian - quadrature.

Texniklərə gelgit qüvvələrinin mahiyyəti izah edildikdə, dərhal polisə müraciət etməli olduqlarını düşündülər. Və olduqca məntiqli. Amma məlum oldu ki, oğlan haqlıdır. İki həftə əvvəl bir esmines ofisdən çox uzaqda dayandı. Hər dəfə gelgit onu müəyyən hündürlüyə qaldıranda gəminin radar postu server otağının döşəməsi səviyyəsində sona çatırdı. Və radar (yaxud elektron döyüş texnikası və ya başqa bir hərbi oyuncaq) kompüterlərdə xaos yaratdı.

Raket üçün uçuş missiyası

Mənə böyük (təxminən 400 min xətt) raket buraxılışına nəzarət və monitorinq sistemini əməliyyat sisteminin, kompilyatorun və dilin yeni versiyalarına köçürmək tapşırılmışdı. Daha doğrusu, Solaris 2.5.1-dən Solaris 7-yə və Ada 83-də yazılmış Verdix Ada İnkişaf Sistemindən (VADS) Ada 95-də yazılmış Rational Apex Ada sisteminə. VADS Rational tərəfindən alınıb və onun məhsulu köhnəlmişdir, baxmayaraq ki, Rational Apex kompilyatoruna keçidi asanlaşdırmaq üçün VADS-ə xüsusi paketlərin uyğun versiyalarını tətbiq etməyə çalışmışdır.

Üç nəfər mənə kodun təmiz tərtib edilməsində kömək etdi. İki həftə çəkdi. Sonra sistemin işləməsi üçün öz üzərimdə çalışdım. Bir sözlə, bu, qarşılaşdığım proqram sisteminin ən pis arxitekturası və tətbiqi idi, buna görə də limanı tamamlamaq üçün daha iki ay çəkdi. Daha sonra sistem sınaq üçün təqdim edildi və bu daha bir neçə ay çəkdi. Sınaq zamanı aşkar edilən səhvləri dərhal düzəltdim, lakin onların sayı sürətlə azaldı (mənbə kodu istehsal sistemi idi, ona görə də onun funksionallığı kifayət qədər etibarlı işləyirdi, sadəcə yeni tərtibçiyə uyğunlaşma zamanı yaranan səhvləri aradan qaldırmalı oldum). Nəhayət, hər şey olduğu kimi işləyəndə məni başqa layihəyə keçirdilər.

Şükran günündən əvvəl cümə günü telefon zəng çaldı.

Raketin buraxılışı təxminən üç həftə ərzində sınaqdan keçirilməli idi və geri sayımın laboratoriya sınaqları zamanı əmrlərin ardıcıllığı bloklandı. Real həyatda bu, sınaqdan imtina edərdi və tıxanma mühərriki işə saldıqdan sonra bir neçə saniyə ərzində baş verərsə, köməkçi sistemlərdə bir neçə geri dönməz hərəkət baş verərdi ki, bu da raketin uzun və bahalı hazırlığını tələb edərdi. Başlamazdı, amma bir çox insan vaxt və çox, çox pul itkisindən çox üzüləcəkdi. Heç kimin Müdafiə Nazirliyinin pulu ehtiyatsız xərclədiyini söyləməsinə imkan verməyin - mən heç vaxt büdcəni birinci və ya ikinci, sonra isə cədvələ əməl etməyən müqavilə meneceri ilə rastlaşmamışam.

Əvvəlki aylarda bu geri sayım çağırışı bir neçə kiçik hıçqırıqla bir çox variantda yüzlərlə dəfə icra edilmişdi. Beləliklə, bunun baş vermə ehtimalı çox aşağı idi, lakin onun nəticələri çox əhəmiyyətli idi. Bu amillərin hər ikisini çoxaldın və başa düşəcəksiniz ki, xəbər mənim və onlarla mühəndis və menecer üçün bərbad bir tətil həftəsini proqnozlaşdırırdı.

Və sistemi daşıyan şəxs kimi mənə diqqət yetirildi.

Əksər təhlükəsizlik baxımından kritik sistemlərdə olduğu kimi, bir çox parametrlər qeyd edildi, ona görə də sistem qəzaya uğramazdan əvvəl icra edilən bir neçə kod sətirini müəyyən etmək kifayət qədər asan idi. Və əlbəttə ki, onlarda qeyri-adi heç nə yox idi; eyni ifadələr eyni qaçışda minlərlə dəfə uğurla icra edilmişdir.

Apex-dən olan insanları Rational-a çağırdıq, çünki onlar kompilyatoru inkişaf etdirənlər idi və onların inkişaf etdirdiyi bəzi rutinlər şübhəli kodda çağırıldı. Onlarda (və hamıda) sözün əsl mənasında ümummilli əhəmiyyət kəsb edən problemin kökünə varmaq zərurəti yaranıb.

Jurnallarda maraqlı heç nə olmadığı üçün problemi yerli laboratoriyada təkrar etməyə cəhd etmək qərarına gəldik. Hadisə təxminən hər 1000 qaçışda bir dəfə baş verdiyi üçün bu asan məsələ deyildi. Şübhəli səbəblərdən biri satıcı tərəfindən hazırlanmış mutex funksiyasına (VADS miqrasiya paketinin bir hissəsi) zəng olması idi. Unlock açılmasına səbəb olmadı. Funksiyanı çağıran emal xətti hər saniyə nominal olaraq gələn ürək döyüntüsü mesajlarını emal edirdi. Tezliyi 10 Hz-ə, yəni saniyədə 10 dəfə qaldırdıq və işə başladıq. Təxminən bir saat sonra sistem özünü kilidlədi. Jurnalda, qeydə alınan mesajların ardıcıllığının uğursuz sınaq zamanı olduğu kimi olduğunu gördük. Daha bir neçə qaçış etdik, sistem startdan 45-90 dəqiqə sonra ardıcıl olaraq bloklandı və hər dəfə jurnalda eyni marşrut var idi. Texniki olaraq fərqli kod işlətməyimizə baxmayaraq - mesaj tezliyi fərqli idi - sistemin davranışı eyni idi, ona görə də bu yükləmə ssenarisinin eyni problemə səbəb olduğuna əmin idik.

İndi ifadələr ardıcıllığında bloklamanın tam olaraq harada baş verdiyini anlamaq lazım idi.

Sistemin bu tətbiqi Ada tapşırıq sistemindən istifadə etdi və onu inanılmaz dərəcədə zəif istifadə etdi. Tapşırıqlar Ada-da yüksək səviyyəli eyni vaxtda yerinə yetirilə bilən konstruksiyadır, icra ipləri kimi bir şeydir, yalnız dilin özündə qurulmuşdur. İki tapşırığın ünsiyyət qurması lazım olduqda, onlar "görüş təyin edir", lazımi məlumatları mübadilə edir və sonra görüşü dayandırır və müstəqil icralarına qayıdırlar. Ancaq sistem fərqli şəkildə həyata keçirildi. Hədəf tapşırığı görüşdükdən sonra həmin hədəf tapşırığı başqa bir tapşırıqla görüşdü, sonra üçüncü tapşırıqla görüşdü və bəzi emal tamamlanana qədər belə davam etdi. Bundan sonra bütün bu görüşlər tamamlandı və hər bir tapşırıq öz icrasına qayıtmalı oldu. Yəni, biz daxil edilmiş məlumatların bir hissəsini emal edərkən bütün “çox tapşırıqlı” prosesi dayandıran dünyanın ən bahalı funksiya çağırış sistemi ilə məşğul idik. Və bundan əvvəl yalnız ötürmə qabiliyyəti çox aşağı olduğu üçün problemlərə səbəb olmurdu.

Mən bu tapşırıq mexanizmini təsvir etdim, çünki görüş tələb edildikdə və ya tamamlanması gözlənildikdə, "tapşırıq keçidi" baş verə bilər. Yəni prosessor yerinə yetirilməyə hazır olan başqa bir tapşırığı emal etməyə başlaya bilər. Belə çıxır ki, bir tapşırıq digər tapşırıqla görüşməyə hazır olduqda, tamamilə fərqli bir tapşırıq yerinə yetirilməyə başlaya bilər və nəticədə nəzarət ilk görüşə qayıdır. Və tapşırığın dəyişməsinə səbəb olan digər hadisələr baş verə bilər; belə hadisələrdən biri mutexin çap edilməsi və ya icrası kimi sistem funksiyasına çağırışdır.

Problemə hansı kod sətirinin səbəb olduğunu başa düşmək üçün tapşırıq keçidini işə salmadan bir sıra bəyanatlar vasitəsilə irəliləyişi qeyd etməyin yolunu tapmalı idim ki, bu da qəzanın baş verməsinin qarşısını alır. Ona görə də yararlana bilmədim Put_Line()I/O əməliyyatlarını yerinə yetirməmək üçün. Mən sayğac dəyişəni və ya buna bənzər bir şey təyin edə bilərdim, lakin onu ekranda göstərə bilməsəm, dəyərini necə görə bilərəm?

Həmçinin, jurnalı araşdırarkən məlum oldu ki, ürək döyüntüsü mesajlarının emalı zamanı prosesin bütün giriş/çıxış əməliyyatlarını bloklayan və digər emalların yerinə yetirilməsinə mane olan donmaya baxmayaraq, digər müstəqil tapşırıqların icrası davam edir. Yəni iş tamamilə bloklanmadı, yalnız (kritik) vəzifələr silsiləsi.

Bu, bloklama ifadəsini qiymətləndirmək üçün lazım olan ipucu idi.

Tapşırığı, sadalanan növü və bu tip qlobal dəyişəni ehtiva edən Ada paketi hazırladım. Sadalanan hərflər problemli ardıcıllığın xüsusi ifadələri ilə əlaqələndirilirdi (məs. Incrementing_Buffer_Index, Locking_Mutex, Mutex_Unlocked) və sonra qlobal dəyişənə müvafiq siyahı təyin edən təyin ifadələri daxil etdi. Bütün bunların obyekt kodu sadəcə yaddaşda sabit saxladığından, onun yerinə yetirilməsi nəticəsində tapşırıqların dəyişdirilməsi olduqca çətin idi. Biz ilk növbədə tapşırığı dəyişə biləcək ifadələrə şübhə ilə yanaşdıq, çünki bloklama tapşırığı geri qaytararkən (bir neçə səbəbə görə) geri qayıtmaq əvəzinə icra zamanı baş verdi.

İzləmə tapşırığı sadəcə olaraq bir döngədə işlədi və qlobal dəyişənin dəyərinin dəyişib-dəyişmədiyini yoxlamaq üçün vaxtaşırı yoxlanıldı. Hər dəyişikliklə dəyər faylda saxlanılırdı. Sonra qısa bir gözləmə və yeni bir çek. Dəyişənləri fayla yazdım, çünki tapşırıq yalnız problem sahəsində tapşırığı dəyişdirərkən sistem onu ​​icra üçün seçdikdə yerinə yetirilirdi. Bu tapşırıqda baş verənlər digər, əlaqəsi olmayan bloklanmış tapşırıqlara təsir etməyəcək.

Gözlənilirdi ki, sistem problemli kodu icra etmək nöqtəsinə çatdıqda, hər növbəti ifadəyə keçərkən qlobal dəyişən sıfırlanacaq. Sonra tapşırığın dəyişdirilməsinə səbəb olan bir şey baş verəcək və onun icra tezliyi (10 Hz) monitorinq tapşırığından aşağı olduğu üçün monitor qlobal dəyişənin dəyərini tuta və onu yaza bilər. Normal bir vəziyyətdə, mən siyahıların alt dəstinin təkrarlanan ardıcıllığını əldə edə bildim: tapşırıq keçidi zamanı dəyişənin son dəyərləri. Asılan zaman qlobal dəyişən artıq dəyişməməlidir və yazılan son dəyər hansı ifadənin tamamlanmadığını göstərəcək.

İzləmə ilə kodu işlədim. O, donub qaldı. Və monitorinq saat mexanizmi kimi işləyirdi.

Jurnalda mutexin çağırıldığını göstərən dəyərlə kəsilən gözlənilən ardıcıllıq var idi. Unlock, və tapşırıq tamamlanmayıb - minlərlə əvvəlki zənglərdə olduğu kimi.

Apex mühəndisləri bu anda kodlarını qızdırmalı şəkildə təhlil edirdilər və mutexdə nəzəri olaraq kilidin baş verə biləcəyi bir yer tapdılar. Ancaq onun ehtimalı çox aşağı idi, çünki müəyyən bir zamanda baş verən hadisələrin yalnız müəyyən ardıcıllığı blokadaya səbəb ola bilər. Merfi qanunu, uşaqlar, bu Mörfi qanunudur.

Mənə lazım olan kod parçasını qorumaq üçün mən mutex funksiyası çağırışlarını (ƏS mutex funksionallığının üstündə qurulmuş) kiçik yerli Ada mutex paketi ilə əvəz etdim ki, həmin parçaya mutex girişini idarə etdim.

Mən onu koda daxil etdim və sınaqdan keçirdim. Yeddi saat sonra kod hələ də işləyirdi.

Kodum Rational-a təqdim edildi, orada onu tərtib etdilər, sökdülər və problemli mutex funksiyalarında istifadə edilən eyni yanaşmadan istifadə etmədiyini yoxladılar.

Bu, karyeramın ən izdihamlı kod baxışı idi 🙂 Mənimlə otaqda on nəfərə yaxın mühəndis və menecer var idi, daha on nəfər konfrans zəngində idi - və onların hamısı təxminən 20 sətir kodu araşdırdı.

Kod nəzərdən keçirildi, yeni icra edilə bilən fayllar yığıldı və rəsmi reqressiya testinə təqdim edildi. Bir neçə həftə sonra geri sayım sınağı uğurla keçdi və raket havaya qalxdı.

Yaxşı, hər şey yaxşıdır, amma hekayənin mənası nədir?

Bu, tamamilə iyrənc bir problem idi. Yüz minlərlə kod sətirləri, paralel icra, ondan çox qarşılıqlı proses, zəif arxitektura və zəif tətbiq, quraşdırılmış sistemlər üçün interfeyslər və milyonlarla dollar xərclənmişdir. Təzyiq yoxdur, düzdür.

Bu problem üzərində işləyən tək mən deyildim, baxmayaraq ki, daşıma işləri apararkən diqqət mərkəzində idim. Ancaq bunu etsəm də, bu o demək deyil ki, mən bütün yüz minlərlə kodu başa düşdüm və ya hətta onları gözdən keçirdim. Kod və jurnallar bütün ölkədə mühəndislər tərəfindən təhlil edildi, lakin onlar mənə nasazlığın səbəbləri ilə bağlı fərziyyələrini söyləyəndə, onları təkzib etmək mənə cəmi yarım dəqiqə çəkdi. Və məndən nəzəriyyələri təhlil etməyi tələb edəndə mən bunu başqasına ötürərdim, çünki bu mühəndislərin yanlış yolda getdikləri mənə aydın idi. Təkəbbürlü səslənir? Bəli, bu doğrudur, amma mən başqa səbəbə görə fərziyyələri və xahişləri rədd etdim.

Problemin mahiyyətini başa düşdüm. Bunun harada və niyə baş verdiyini dəqiq bilmirdim, amma nə baş verdiyini bilirdim.

Bu illər ərzində çoxlu bilik və təcrübə toplamışam. Mən Adanın istifadəsinin qabaqcıllarından biri idim və onun üstünlüklərini və mənfi cəhətlərini başa düşdüm. Ada iş vaxtı kitabxanalarının tapşırıqları necə idarə etdiyini və paralel icra ilə necə məşğul olduğunu bilirəm. Mən isə yaddaş, registr və assembler səviyyəsində aşağı səviyyəli proqramlaşdırmanı başa düşürəm. Yəni öz sahəmdə dərin biliyə malikəm. Və problemin səbəbini tapmaq üçün onlardan istifadə etdim. Mən sadəcə səhvin üzərində işləmədim, onu çox həssas iş vaxtı mühitində necə tapacağımı başa düşdüm.

Kodla mübarizənin bu cür hekayələri belə bir mübarizənin xüsusiyyətləri və şərtləri ilə tanış olmayanlar üçün çox da maraqlı deyil. Lakin bu hekayələr bizə həqiqətən çətin problemləri həll etmək üçün nə lazım olduğunu anlamağa kömək edir.

Həqiqətən çətin problemləri həll etmək üçün sadəcə bir proqramçı olmaqdan daha çox şey etməlisiniz. Kodun “taleyini”, onun ətraf mühitlə necə qarşılıqlı əlaqədə olduğunu və mühitin özünün necə işlədiyini başa düşməlisiniz.

Və sonra öz bərbad bayram həftəniz olacaq.

Davam etmək.

Mənbə: www.habr.com

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