Programcıların ve mühendislerin folkloru (bölüm 1)

Programcıların ve mühendislerin folkloru (bölüm 1)

Bu, böceklerin bazen nasıl tamamen inanılmaz tezahürlere sahip olduğuna dair internetten alınan hikayelerden bir seçkidir. Belki sizin de anlatacaklarınız vardır.

Vanilyalı dondurmaya araba alerjisi

Açık olanın her zaman cevap olmadığını ve gerçeklerin ne kadar zoraki görünse de yine de gerçek olduğunu anlayan mühendisler için bir hikaye. General Motors Corporation'ın Pontiac Bölümü bir şikayet aldı:

Bu sana ikinci kez yazıyorum ve cevap vermediğin için seni suçlamıyorum çünkü kulağa çılgınca geliyor. Ailemizde her akşam yemekten sonra dondurma yeme geleneği vardır. Dondurma çeşitleri her seferinde değişiyor ve akşam yemeğinden sonra tüm aile hangi dondurmayı alacağına karar veriyor, ardından ben markete gidiyorum. Yakın zamanda yeni bir Pontiac aldım ve o zamandan beri dondurma almak için yaptığım geziler sorun olmaya başladı. Gördüğünüz gibi ne zaman vanilyalı dondurma alıp mağazadan dönsem araba çalışmıyor. Başka dondurma getirirsem araba sorunsuz çalışıyor. Kulağa ne kadar aptalca gelse de ciddi bir soru sormak istiyorum: "Pontiac'ta vanilyalı dondurma getirdiğimde başlamamasını, ancak başka bir dondurma çeşidi getirdiğimde kolayca başlamasını sağlayan şey nedir?"

Tahmin edebileceğiniz gibi bölüm başkanı mektuba şüpheyle yaklaştı. Ancak her ihtimale karşı kontrol etmesi için bir mühendis gönderdim. Güzel bir bölgede yaşayan, zengin, iyi eğitimli bir adamla karşılaştığında şaşırdı. İkisinin dondurma almak için markete gidebilmesi için akşam yemeğinden hemen sonra buluşmaya karar verdiler. O akşam vanilya rengindeydi ve arabaya geri döndüklerinde araba çalışmadı.

Mühendis üç akşam daha geldi. İlk defa dondurma çikolatalıydı. Araba çalıştı. İkinci kez çilekli dondurma vardı. Araba çalıştı. Üçüncü akşam vanilya almak istedi. Araba çalışmadı.

Mantıklı bir şekilde akıl yürüten mühendis, arabanın vanilyalı dondurmaya alerjisi olduğuna inanmayı reddetti. Bu nedenle araç sahibiyle soruna çözüm buluncaya kadar ziyaretlerine devam edeceği konusunda anlaştım. Ve yol boyunca not almaya başladı: tüm bilgileri, günün saatini, benzin türünü, mağazaya varış ve dönüş saatini vb. yazdı.

Mühendis çok geçmeden araba sahibinin vanilyalı dondurma almaya daha az zaman harcadığını fark etti. Bunun nedeni mağazadaki malların düzeniydi. Vanilyalı dondurma en popüler olanıydı ve bulunmasını kolaylaştırmak için mağazanın önündeki ayrı bir dondurucuda saklanıyordu. Ve diğer tüm çeşitler mağazanın arka tarafındaydı ve doğru çeşidi bulmak ve ödeme yapmak çok daha fazla zaman aldı.

Şimdi mühendis için soru şuydu: Motorun kapatıldığı andan bu yana daha az zaman geçmişse araba neden çalışmadı? Sorun vanilyalı dondurma değil de zaman olduğundan, mühendis hemen cevabı buldu: Gaz kilidiydi. Bu her akşam meydana geliyordu, ancak araç sahibi dondurma aramak için daha fazla zaman harcadığında motor yeterince soğumayı başardı ve kolayca çalıştırıldı. Adam vanilyalı dondurma aldığında motor hâlâ çok sıcaktı ve gaz kilidinin çözülmeye zamanı yoktu.

Ahlaki: Tamamen çılgınca problemler bile bazen gerçektir.

Crash Bandicoot

Bunu yaşamak acı verici. Bir programcı olarak, kodunuzu birinci, ikinci, üçüncü olarak suçlamaya alışırsınız... ve on bininci sırada bir yerlerde derleyiciyi suçlarsınız. Ve listenin ilerleyen kısımlarında zaten ekipmanı suçluyorsunuz.

İşte donanım hatasıyla ilgili hikayem.

Crash Bandicoot oyunu için hafıza kartına yükleyip kaydedecek kod yazdım. Bu kadar kendini beğenmiş bir oyun geliştiricisi için bu, parkta yürüyüşe benziyordu: İşin birkaç gün süreceğini düşünmüştüm. Ancak altı hafta boyunca kodda hata ayıklama yaptım. Yol boyunca başka sorunları da çözdüm, ancak birkaç günde bir birkaç saatliğine bu koda geri döndüm. Acı vericiydi.

Belirti şuna benziyordu: Oyunun mevcut oynanışını kaydettiğinizde ve hafıza kartına eriştiğinizde, her şey hemen hemen her zaman yolunda gider... Ancak bazen okuma veya yazma işlemi belirgin bir neden olmaksızın zaman aşımına uğrar. Kısa bir kayıt genellikle hafıza kartına zarar verir. Bir oyuncu kurtarmaya çalıştığında, yalnızca kaydetmeyi başaramaz, aynı zamanda haritayı da yok eder. Saçmalık.

Bir süre sonra Sony'deki yapımcımız Connie Bus paniğe kapılmaya başladı. Oyunu bu hatayla birlikte yayınlayamadık ve altı hafta sonra soruna neyin sebep olduğunu anlamadım. Connie aracılığıyla diğer PS1 geliştiricileriyle iletişime geçtik: benzer bir şeyle karşılaşan var mı? HAYIR. Kimsenin hafıza kartıyla sorunu yoktu.

Hata ayıklama konusunda hiçbir fikriniz olmadığında, geriye kalan tek yaklaşım "böl ve fethet"tir: hâlâ soruna neden olan nispeten küçük bir parça kalana kadar hatalı programdan daha fazla kodu kaldırın. Yani hatayı içeren kısım kalana kadar programı parça parça kesersiniz.

Ama gerçek şu ki, bir video oyunundan parçalar koparmak çok zor. Yer çekimini taklit eden kodu kaldırırsanız nasıl çalıştırılır? Veya karakter çizmek mi?

Bu nedenle, tüm modülleri, yararlı bir şey yapıyormuş gibi görünen, ancak aslında hata içermeyecek kadar basit bir şey yapan taslaklarla değiştirmemiz gerekiyor. Oyunun en azından işe yaraması için bu tür koltuk değneği yazmamız gerekiyor. Bu yavaş ve acı verici bir süreçtir.

Kısacası başardım. Sistemi oyunu çalıştıracak şekilde yapılandıran, işleme donanımını başlatan vb. ilk kodla kalana kadar giderek daha fazla kod parçasını kaldırdım. Tabii bu aşamada kaydet ve yükle menüsü oluşturamadım çünkü tüm grafik kodları için bir taslak oluşturmam gerekecekti. Ancak (görünmez) kaydetme ve yükleme ekranını kullanarak bir kullanıcı gibi davranabilir ve kaydetmeyi ve ardından hafıza kartına yazmayı isteyebilirim.

Bu bende hala yukarıdaki sorunu yaşayan küçük bir kod parçasıyla baş başa bıraktı - ama yine de rastgele oluyordu! Çoğu zaman her şey yolunda gitti, ancak bazen aksaklıklar yaşandı. Neredeyse tüm oyun kodunu kaldırdım ama hata hala hayattaydı. Bu kafa karıştırıcıydı: Geriye kalan kod aslında hiçbir şey yapmıyordu.

Bir noktada, muhtemelen sabahın üçü civarında aklıma bir fikir geldi. Okuma ve yazma (giriş/çıkış) işlemleri kesin yürütme sürelerini içerir. Bir sabit disk, hafıza kartı veya Bluetooth modülüyle çalıştığınızda, okuma ve yazmadan sorumlu alt düzey kod bunu saat darbelerine göre yapar.

İşlemciye doğrudan bağlı olmayan bir cihaz, saat yardımıyla işlemcide çalışan kodla senkronize edilir. Saat, baud hızını, yani verinin iletilme hızını belirler. Zamanlamalarla ilgili bir karışıklık varsa, o zaman donanım ya da yazılım ya da her ikisi de karışmış demektir. Ve bu çok kötü çünkü veriler zarar görebilir.

Ya kodumuzdaki bir şey zamanlamaları karıştırırsa? Test programı kodunda bununla ilgili her şeyi kontrol ettim ve PS1'deki programlanabilir zamanlayıcıyı 1 kHz'e (saniyede 1000 tıklama) ayarladığımızı fark ettim. Bu oldukça fazla; varsayılan olarak konsol başlatıldığında 100 Hz'de çalışır. Ve çoğu oyun bu frekansı kullanır.

Oyunun geliştiricisi Andy, hareketlerin daha doğru hesaplanabilmesi için zamanlayıcıyı 1 kHz'e ayarladı. Andy aşırıya kaçma eğilimindedir ve eğer yerçekimini taklit edersek, bunu mümkün olduğunca doğru bir şekilde yaparız!

Peki ya zamanlayıcıyı hızlandırmak programın genel zamanlamasını ve dolayısıyla hafıza kartının baud hızını düzenleyen saati bir şekilde etkiliyorsa?

Zamanlayıcı kodunu yorumladım. Hata bir daha oluşmadı. Ancak bu, sorunu düzelttiğimiz anlamına gelmiyor çünkü arıza rastgele meydana geldi. Ya sadece şanslı olsaydım?

Birkaç gün sonra test programını tekrar denedim. Hata tekrarlanmadı. Tam oyun kod tabanına geri döndüm ve kaydetme ve yükleme kodunu, programlanabilir zamanlayıcının hafıza kartına erişmeden önce orijinal değerine (100Hz) sıfırlanması ve ardından 1kHz'e sıfırlanması için değiştirdim. Artık kaza olmadı.

Peki bu neden oldu?

Tekrar test programına döndüm. 1 kHz'lik bir zamanlayıcıda hata oluşmasında bir model bulmaya çalıştım. Sonunda, birisi PS1 denetleyicisiyle oynadığında hatanın oluştuğunu fark ettim. Bunu nadiren kendim yapacağımdan, kaydetme ve yükleme kodunu test ederken neden bir denetleyiciye ihtiyacım olsun ki? - Bu bağımlılığı fark etmedim bile. Ancak bir gün sanatçılarımızdan biri testi bitirmemi bekliyordu - o anda muhtemelen küfrediyordum - ve elindeki kontrol cihazını gergin bir şekilde döndürdü. Bir hata oluştu. "Bir dakika ne?!" Peki, tekrar yap!”

Bu iki olayın birbiriyle bağlantılı olduğunu fark ettiğimde hatayı kolayca yeniden üretebildim: Hafıza kartına kayıt yapmaya başladım, kumandayı hareket ettirdim ve hafıza kartını mahvettim. Bana göre donanımsal bir hata gibi görünüyordu.

Connie'ye geldim ve ona keşfimi anlattım. Bilgileri PS1'i tasarlayan mühendislerden birine aktardı. "İmkansız" diye yanıtladı, "Donanımsal bir sorun olamaz." Connie'den bizim için bir konuşma ayarlamasını istedim.

Mühendis beni aradı ve onun bozuk İngilizcesi ve benim (aşırı) bozuk Japoncamla tartıştık. Sonunda dedim ki, "Kontrol ünitesini hareket ettirmenin hataya neden olduğu 30 satırlık test programımı göndereyim." O kabul etti. Bunun zaman kaybı olduğunu ve yeni bir proje üzerinde çalışmakla çok meşgul olduğunu ancak Sony için çok önemli bir geliştirici olduğumuz için pes edeceğini söyledi. Test programımı temizledim ve ona gönderdim.

Ertesi akşam (biz Los Angeles'taydık, o da Tokyo'daydı) beni aradı ve utangaç bir tavırla özür diledi. Bu bir donanım sorunuydu.

Hatanın tam olarak ne olduğunu bilmiyorum ama Sony genel merkezinden duyduğuma göre eğer zamanlayıcıyı yeterince yüksek bir değere ayarlarsanız anakartta zamanlayıcı kristalinin yakınındaki bileşenlere müdahale ediyormuş. Bunlardan biri, kontrolörlerin baud hızını da ayarlayan hafıza kartı için bir baud hızı denetleyicisiydi. Ben mühendis değilim o yüzden bir şeyleri karıştırmış olabilirim.

Ancak sonuç olarak anakarttaki bileşenler arasında parazit vardı. Ve 1 kHz'de çalışan bir zamanlayıcıyla denetleyici bağlantı noktası ve hafıza kartı bağlantı noktası üzerinden eşzamanlı olarak veri iletirken, bitler kayboldu, veriler kayboldu ve kart hasar gördü.

Kötü inekler

1980'lerde akıl hocam Sergei, PDP-1800'in Sovyet kopyası olan SM-11 için yazılım yazdı. Bu mikro bilgisayar, SSCB'nin önemli bir ulaşım merkezi olan Sverdlovsk yakınlarındaki bir tren istasyonuna yakın zamanda kuruldu. Yeni sistem, vagonları ve yük trafiğini yönlendirmek için tasarlandı. Ancak rastgele çökmelere ve çökmelere yol açan sinir bozucu bir hata içeriyordu. Düşmeler her zaman biri akşam eve gittiğinde meydana gelirdi. Ancak ertesi gün yapılan kapsamlı araştırmaya rağmen bilgisayar, tüm manuel ve otomatik testlerde doğru şekilde çalıştı. Bu genellikle bir yarış durumunu veya belirli koşullar altında meydana gelen başka bir rekabet hatasını gösterir. Gece geç saatlerde yapılan aramalardan bıkan Sergei, konunun özüne inmeye ve her şeyden önce, yönlendirme sahasındaki hangi koşulların bilgisayarın bozulmasına yol açtığını anlamaya karar verdi.

Öncelikle tüm açıklanamayan düşmelerin istatistiklerini topladı ve tarih ve saate göre bir grafik oluşturdu. Desen açıktı. Birkaç gün daha gözlem yaptıktan sonra Sergei, gelecekteki sistem arızalarının zamanını kolayca tahmin edebildiğini fark etti.

Kısa süre sonra, aksaklıkların yalnızca istasyonun kuzey Ukrayna'dan ve batı Rusya'dan gelen tren dolusu sığırları yakındaki bir mezbahaya doğru yola çıkarken meydana geldiğini öğrendi. Bu başlı başına tuhaf bir durumdu çünkü mezbahaya çok daha yakın olan Kazakistan'daki çiftlikler tarafından tedarik sağlanıyordu.

Çernobil nükleer santrali 1986'da patladı ve radyoaktif serpinti çevredeki bölgeleri yaşanmaz hale getirdi. Kuzey Ukrayna, Beyaz Rusya ve Batı Rusya'daki geniş alanlar kirlendi. Gelen vagonlarda yüksek düzeyde radyasyon olduğundan şüphelenen Sergei, bu teoriyi test etmek için bir yöntem geliştirdi. Nüfusun dozimetre bulundurması yasak olduğundan Sergei kendisini tren istasyonunda birkaç askerin yanına kaydettirdi. Birkaç kadeh votka içtikten sonra, şüpheli vagonlardan birindeki radyasyon seviyesini ölçmesi için bir askeri ikna etmeyi başardı. Seviyenin normal değerlerden birkaç kat daha yüksek olduğu ortaya çıktı.

Sığır sadece çok fazla radyasyon yaymakla kalmadı, aynı zamanda seviyesi o kadar yüksekti ki, istasyonun yanındaki binada bulunan SM-1800'ün hafızasında rastgele bit kaybına yol açtı.

SSCB'de yiyecek sıkıntısı vardı ve yetkililer Çernobil etini ülkenin diğer bölgelerinden gelen etlerle karıştırmaya karar verdi. Bu, değerli kaynakları kaybetmeden genel radyoaktivite düzeyini azaltmayı mümkün kıldı. Bunu öğrendikten sonra Sergei hemen göç belgelerini doldurdu. Ve zamanla radyasyon seviyesi azalınca bilgisayar çökmeleri kendiliğinden durdu.

Borular aracılığıyla

Bir zamanlar Movietech Solutions sinemalar için muhasebe, bilet satışı ve genel yönetim için tasarlanmış yazılımlar yaratıyordu. Amiral gemisi uygulamasının DOS sürümü, Kuzey Amerika'daki küçük ve orta ölçekli sinema zincirleri arasında oldukça popülerdi. Bu nedenle, en yeni dokunmatik ekranlar ve self-servis kiosklarla entegre edilmiş ve her türlü raporlama aracıyla donatılmış bir Windows 95 sürümü duyurulduğunda, bu sürümün de hızla popüler hale gelmesi şaşırtıcı değil. Çoğu zaman güncelleme sorunsuz geçti. Yerel BT personeli yeni ekipmanı kurdu, verileri taşıdı ve işler devam etti. Uzun sürmediği zamanlar hariç. Bu olduğunda şirket "Temizleyici" lakaplı James'i gönderecekti.

Takma adı hain bir türü çağrıştırsa da, temizlikçi yalnızca eğitmen, kurulumcu ve her işi bilenlerin bir birleşimidir. James, müşterinin tesisinde tüm bileşenleri bir araya getirmek için birkaç gün harcıyordu ve ardından birkaç gününü daha personele yeni sistemin nasıl kullanılacağını öğreterek, ortaya çıkan donanım sorunlarını çözerek ve esasen yazılımın başlangıç ​​aşamasında yardımcı olarak geçirerek geçiriyordu.

Dolayısıyla bu yoğun saatlerde James'in sabah ofise gelmesi ve daha masasına varamadan müdür tarafından her zamankinden daha fazla kafein dolu bir şekilde karşılanması şaşırtıcı değil.

"Korkarım en kısa zamanda Annapolis, Nova Scotia'ya gitmen gerekiyor." Tüm sistemleri çöktü ve mühendisleriyle bir gece çalıştıktan sonra ne olduğunu anlayamıyoruz. Sunucudaki ağ başarısız olmuş gibi görünüyor. Ancak sistem birkaç dakika çalıştıktan sonra.

— Eski sisteme dönmediler mi? - James, zihinsel olarak şaşkınlıkla gözlerini açmasına rağmen tamamen ciddi bir şekilde cevap verdi.

— Kesinlikle: BT uzmanları "öncelikleri değiştirdi" ve eski sunucularından ayrılmaya karar verdi. James, sistemi altı tesise kurdular ve premium destek için ödeme yaptılar ve işleri artık 1950'lerdeki gibi yürütülüyor.

James hafifçe doğruldu.

- Bu başka bir konu. Tamam, başlayalım.

Annapolis'e vardığında yaptığı ilk iş, müşterinin sorunlu olan ilk sinema salonunu bulmak oldu. Havaalanında çekilen haritada her şey düzgün görünüyordu ancak istenen adresin etrafındaki alan şüpheli görünüyordu. Getto değil ama kara filmi anımsatıyor. James şehir merkezindeki kaldırıma park ederken bir fahişe ona yaklaştı. Annapolis'in büyüklüğü göz önüne alındığında, büyük ihtimalle şehrin tamamındaki tek şehirdi. Görünüşü hemen beyazperdede para karşılığında seks teklif eden ünlü karakteri hatırlattı. Hayır, Julia Roberts hakkında değil, Jon Voight hakkında."Gece Yarısı Kovboyu" filmine gönderme - yakl. Lane].

Fahişeyi yoluna gönderen James sinemaya gitti. Çevredeki alan iyileşmişti ama hâlâ yıkılmış gibi bir izlenim veriyordu. James'in çok endişeli olduğu söylenemezdi. Daha önce de berbat yerlere gitmişti. Burası Kanada'ydı; soyguncular bile cüzdanınızı aldıktan sonra "teşekkür ederim" diyecek kadar kibardı.

Sinemanın yan girişi nemli bir ara sokaktaydı. James kapıya doğru yürüdü ve kapıyı çaldı. Çok geçmeden gıcırdadı ve hafifçe açıldı.

-Temizlikçi misin? - içeriden boğuk bir ses geldi.

- Evet benim... Her şeyi düzeltmeye geldim.

James sinema lobisine girdi. Görünüşe göre başka seçeneği kalmayan personel, ziyaretçilere kağıt bilet dağıtmaya başladı. Bu, bırakın daha ilginç ayrıntıları, finansal raporlamayı zorlaştırdı. Ancak personel James'i rahatlayarak karşıladı ve onu hemen sunucu odasına götürdü.

İlk bakışta her şey yolundaydı. James sunucuya giriş yaptı ve olağan şüpheli yerleri kontrol etti. Sorun değil. Ancak James çok dikkatli davranarak sunucuyu kapattı, ağ kartını değiştirdi ve sistemi geri aldı. Hemen tam anlamıyla çalışmaya başladı. Personel yeniden bilet satışına başladı.

James Mark'ı aradı ve durumu ona bildirdi. James'in burada kalıp beklenmedik bir şey olup olmadığını görmek isteyebileceğini hayal etmek zor değil. Merdivenlerden aşağı inip çalışanlara ne olduğunu sormaya başladı. Açıkçası sistem çalışmayı durdurdu. Kapatıp açtılar, her şey çalıştı. Ancak 10 dakika sonra sistem çöktü.

Tam bu sırada benzer bir şey oldu. Bir anda biletleme sistemi hata vermeye başladı. Personel içini çekerek kağıt biletleri aldı ve James aceleyle sunucu odasına gitti. Sunucuda her şey iyi görünüyordu.

Daha sonra çalışanlardan biri içeri girdi.

— Sistem yeniden çalışıyor.

James hiçbir şey yapmadığı için şaşkındı. Daha doğrusu sistemin çalışmasını sağlayacak hiçbir şey yok. Oturumu kapattı, telefonunu aldı ve şirketinin destek hattını aradı. Kısa süre sonra aynı çalışan sunucu odasına girdi.

- Sistem çöktü.

James sunucuya baktı. Ekranda çok renkli şekillerden oluşan ilginç ve tanıdık bir desen dans ediyordu - kaotik bir şekilde kıvranan ve iç içe geçen borular. Hepimiz bu ekran koruyucuyu bir noktada görmüşüzdür. Çok güzel bir şekilde işlenmişti ve kelimenin tam anlamıyla hipnotize ediciydi.


James bir düğmeye bastı ve desen ortadan kayboldu. Aceleyle bilet gişesine gitti ve yolda kendisine dönen bir çalışanla karşılaştı.

— Sistem yeniden çalışıyor.

Eğer zihinsel bir yüz maskesi yapabiliyorsanız, James'in yaptığı da tam olarak budur. Ekran koruyucusu. OpenGL'yi kullanıyor. Bu nedenle işlem sırasında sunucu işlemcisinin tüm kaynaklarını tüketir. Sonuç olarak, sunucuya yapılan her çağrı bir zaman aşımı ile sona erer.

James sunucu odasına döndü, oturum açtı ve ekran koruyucuyu boş ekranlı güzel borularla değiştirdi. Yani işlemci kaynaklarının% 100'ünü tüketen bir ekran koruyucu yerine kaynakları tüketmeyen bir ekran koruyucu kurdum. Daha sonra tahminimi kontrol etmek için 10 dakika bekledim.

James bir sonraki sinemaya vardığında menajerine ekran koruyucuyu kapatmak için 800 km uçtuğunu nasıl açıklayacağını düşünüyordu.

Ayın belirli bir evresinde çarpışma

Gerçek hikaye. Bir gün ayın evresine bağlı bir yazılım hatası ortaya çıktı. Ay'ın gerçek evresine yaklaşımı hesaplamak için çeşitli MIT programlarında yaygın olarak kullanılan küçük bir rutin vardı. GLS, bu rutini, bir dosya yazarken yaklaşık 80 karakter uzunluğunda zaman damgasına sahip bir satır çıkaran bir LISP programına yerleştirdi. Bir mesajın ilk satırının çok uzun olması ve bir sonraki satıra yönlendirilmesi çok nadir bir durumdu. Ve program daha sonra bu dosyayı okuduğunda lanetledi. İlk satırın uzunluğu, kesin tarih ve saatin yanı sıra zaman damgasının yazdırıldığı andaki aşama spesifikasyonunun uzunluğuna da bağlıydı. Yani böcek kelimenin tam anlamıyla ayın evresine bağlıydı!

İlk makale baskısı Jargon Dosyası (Steele-1983), açıklanan hataya yol açan böyle bir satırın örneğini içeriyordu, ancak dizgici bunu "düzeltti". Bu durum o zamandan beri "ay evresi hatası" olarak tanımlanıyor.

Ancak varsayımlara dikkat edin. Birkaç yıl önce CERN'den (Avrupa Nükleer Araştırma Merkezi) mühendisler, Büyük Elektron-Pozitron Çarpıştırıcısında yapılan deneylerde hatalarla karşılaştılar. Bilgisayarlar, sonucu bilim insanlarına göstermeden önce bu cihazın ürettiği muazzam miktarda veriyi aktif olarak işlediğinden, birçok kişi yazılımın bir şekilde ayın evresine duyarlı olduğunu öne sürdü. Birkaç çaresiz mühendis gerçeğin derinliklerine indi. Hata, Ay'ın geçişi sırasında Dünya'nın deformasyonu nedeniyle 27 km uzunluğundaki halkanın geometrisindeki hafif değişiklik nedeniyle ortaya çıktı! Fizik folkloruna “Newton'un Parçacık Fiziğinden İntikamı” olarak giren bu hikaye, fiziğin en basit ve en eski yasalarıyla en gelişmiş bilimsel kavramlar arasındaki bağlantının bir örneğidir.

Tuvaletin sifonunu çekmek treni durdurur

Duyduğum en iyi donanım hatası Fransa'daki hızlı trende yaşandı. Hata, trenin acil frenlenmesine yol açtı, ancak bu yalnızca gemide yolcu varsa. Her durumda tren hizmet dışı bırakıldı, kontrol edildi ancak hiçbir şey bulunamadı. Daha sonra hatta geri gönderildi ve hemen durdu.

Kontrollerden birinde trende seyahat eden bir makinist tuvalete gitti. Çok geçmeden uzaklaştı, BOOM! Acil durdurma.

Mühendis sürücüyle temasa geçti ve sordu:

— Frene basmadan hemen önce ne yapıyordunuz?

- İnişte yavaşladım...

Bu garipti çünkü normal çalışma sırasında tren inişlerde onlarca kez yavaşlıyor. Tren yoluna devam etti ve bir sonraki inişte makinist uyardı:

- Yavaşlayacağım.

Hiçbir şey olmadı.

— Son frenleme sırasında ne yaptınız? - sürücüye sordu.

- Şey... tuvaletteydim...

- O halde tuvalete git ve tekrar aşağı indiğimizde yaptığını yap!

Mühendis tuvalete gitti ve sürücü "yavaşlıyorum" diye uyardığında suyu sifonu çekti. Tabii tren hemen durdu.

Artık sorunu yeniden üretebilirlerdi ve sebebini bulmaları gerekiyordu.

İki dakika sonra, motor freni uzaktan kumanda kablosunun (trenin her iki ucunda bir motor vardı) elektrik kabininin duvarından ayrıldığını ve tuvalet fişi solenoidini kontrol eden rölenin üzerinde durduğunu fark ettiler. açıldığında, fren kablosunda parazit yaratıyordu ve arızalara karşı sistem koruması, yalnızca acil frenlemeyi içeriyordu.

FORTRAN'dan nefret eden ağ geçidi

Birkaç ay önce ana karadaki (burası Hawaii'ydi) ağ bağlantılarının çok ama çok yavaşladığını fark ettik. Bu 10-15 dakika kadar sürebilir ve sonra aniden tekrar ortaya çıkabilir. Bir süre sonra meslektaşım bana anakaradaki ağ bağlantılarının hiç çalışmıyor. Ana karadaki bir makineye kopyalanması gereken bir FORTRAN kodu vardı, ancak "ağ, FTP yüklemesinin tamamlanmasına yetecek kadar uzun süre dayanamadığından" kopyalanamadı.

Evet, bir meslektaşın FORTRAN'daki kaynak koduna sahip bir dosyayı ana karadaki bir makineye FTP yoluyla göndermeye çalıştığında ağ arızalarının meydana geldiği ortaya çıktı. Dosyayı arşivlemeye çalıştık: sonra sorunsuz bir şekilde kopyalandı (ancak hedef makinede paket açıcı yoktu, bu nedenle sorun çözülmedi). Son olarak FORTRAN kodunu çok küçük parçalara ayırıp birer birer gönderdik. Parçaların çoğu sorunsuz kopyalandı, ancak birkaç parça geçemedi ya da sonradan geçti sayısız denemeler.

Sorunlu pasajları incelediğimizde ortak bir noktaları olduğunu keşfettik: Hepsi büyük C harfiyle başlayan ve biten satırlarla biten yorum blokları içeriyordu (bir meslektaşımızın FORTRAN'da yorum yapmayı tercih ettiği gibi). Anakaradaki ağ uzmanlarına e-posta gönderdik ve yardım istedik. Elbette FTP ile aktarılamayan dosya örneklerimizi görmek istediler... ama mektuplarımız onlara ulaşmadı. Sonunda basit bir çözüm bulduk betimlemekaktarılamayan dosyalar nasıl görünür? İşe yaradı :) [Sorunlu FORTRAN yorumlarından birinin örneğini buraya eklemeye cesaret edebilir miyim? Muhtemelen buna değmez!]

Sonunda bunu çözmeyi başardık. Kampüsün bizim kısmı ile anakara ağı arasına yakın zamanda yeni bir ağ geçidi kuruldu. Tekrarlanan büyük harf C bitlerini içeren paketleri iletmekte BÜYÜK zorluk yaşadı! Bu paketlerden yalnızca birkaçı tüm ağ geçidi kaynaklarını kullanabilir ve diğer paketlerin çoğunun geçmesini engelleyebilir. Ağ geçidi üreticisine şikayette bulunduk... ve onlar şöyle yanıtladılar: "Ah, evet, tekrarlanan bir C hatasıyla karşı karşıyasınız! Onu zaten biliyoruz." Sonunda başka bir üreticiden yeni bir ağ geçidi satın alarak sorunu çözdük (eski üreticinin savunmasında, FORTRAN programlarının aktarılamaması bazıları için bir avantaj olabilir!).

Zor zamanlar

Birkaç yıl önce, 40. aşama klinik deneylerinin maliyetlerini azaltmak için Perl'de bir ETL sistemi oluşturmaya çalışırken, yaklaşık 000 tarihi işlemem gerekiyordu. Bunlardan ikisi testi geçemedi. Bu beni çok fazla rahatsız etmedi çünkü bu tarihler müşteri tarafından sağlanan verilerden alınmıştı ki bu da çoğu zaman şaşırtıcıydı diyelim. Ancak orijinal verileri kontrol ettiğimde bu tarihlerin 1 Ocak 2011 ve 1 Ocak 2007 olduğu ortaya çıktı. Hatanın az önce yazdığım programda olduğunu sanıyordum ancak üzerinden 30 yıl geçmiş olduğu ortaya çıktı. eskimiş. Bu, yazılım ekosistemine aşina olmayanlar için gizemli görünebilir. Başka bir şirketin uzun süredir para kazanma kararı nedeniyle, müşterim bana bir şirketin kazara, diğerinin ise bilerek yol açtığı bir hatayı düzeltmem için para ödedi. Neden bahsettiğimi anlamanız için, sonunda hata haline gelen özelliği ekleyen şirketten ve düzelttiğim gizemli hataya katkıda bulunan diğer birkaç ilginç olaydan bahsetmem gerekiyor.

Eski güzel günlerde, Apple bilgisayarları bazen kendiliğinden tarihlerini 1 Ocak 1904'e sıfırlardı. Nedeni basitti: Tarih ve saati takip etmek için pille çalışan bir "sistem saati" kullanıyordu. Pil öldüğünde ne oldu? Bilgisayarlar tarihi bir çağın başlangıcından bu yana geçen saniye sayısına göre izlemeye başladı. Dönem derken referans orijinal tarihini kastettik ve Macintosh'lar için bu 1 Ocak 1904'tü. Pil bittikten sonra geçerli tarih belirtilen tarihe sıfırlandı. Peki bu neden oldu?

Daha önce Apple, orijinal tarihten bu yana geçen saniye sayısını depolamak için 32 bit kullanıyordu. Bir bit, 1 veya 0 olmak üzere iki değerden birini saklayabilir. İki bit, dört değerden birini saklayabilir: 00, 01, 10, 11. Üç bit - sekizden bir değer: 000, 001, 010, 011, 100 , 101, 110, 111 vb. Ve 32, 232 değerden birini, yani 4 saniyeyi saklayabilir. Apple tarihleri ​​için bu yaklaşık 294 yıla denk geliyordu, dolayısıyla daha eski Mac'ler 967'tan sonraki tarihleri ​​işleyemez. Sistem pili biterse tarih, dönemin başlangıcından bu yana 296 saniyeye sıfırlanır ve bilgisayarı her açtığınızda (veya yeni bir pil satın alana kadar) tarihi manuel olarak ayarlamanız gerekir.

Ancak Apple'ın tarihleri ​​çağdan bu yana geçen saniyeler olarak saklama kararı, ileride göreceğimiz gibi geniş kapsamlı sonuçları olan çağdan önceki tarihleri ​​işleyemediğimiz anlamına geliyordu. Apple bir hata değil, bir özellik sundu. Bu, diğer şeylerin yanı sıra, Macintosh işletim sisteminin "milenyum hatasına" karşı bağışık olduğu anlamına geliyordu (bu, kısıtlamaları aşmak için kendi tarih sistemlerine sahip birçok Mac uygulaması için söylenemezdi).

Devam etmek. IBM'in PC devrimini başlatmaya yardımcı olan "mükemmel uygulaması" Lotus 1-2-3'ü kullandık, ancak Apple bilgisayarlarında kişisel bilgisayarı başarıya ulaştıran VisiCalc vardı. Adil olmak gerekirse, eğer 1-2-3 ortaya çıkmasaydı, PC'ler pek yükselişe geçemezdi ve kişisel bilgisayarların tarihi çok farklı şekilde gelişebilirdi. Lotus 1-2-3, 1900'ü hatalı bir şekilde artık yıl olarak değerlendirdi. Microsoft ilk e-tablosu Multiplan'ı piyasaya sürdüğünde pazardan küçük bir pay aldı. Excel projesini başlattıklarında, yalnızca Lotus 1-2-3'teki satır ve sütun adlandırma şemasını kopyalamaya değil, aynı zamanda 1900'ü bilinçli olarak artık yıl olarak ele alarak hata uyumluluğunu da sağlamaya karar verdiler. Bu sorun bugün hala mevcuttur. Yani 1-2-3'te bu bir hataydı, ancak Excel'de tüm 1-2-3 kullanıcılarının yanlış olsa bile verileri değiştirmeden tablolarını Excel'e aktarabilmesini sağlayan bilinçli bir karardı.

Ama başka bir sorun daha vardı. İlk olarak Microsoft, 1 Ocak 1904'ten önceki tarihleri ​​tanımayan Macintosh için Excel'i yayınladı. Excel'de ise 1 Ocak 1900, dönemin başlangıcı olarak kabul edildi. Bu nedenle geliştiriciler, programlarının çağın türünü tanıması ve verileri istenilen çağa uygun olarak kendi içinde saklaması için bir değişiklik yaptılar. Hatta Microsoft bu konuda açıklayıcı bir makale bile yazmıştı. Ve bu karar benim hatama yol açtı.

ETL sistemim, müşterilerden Windows'ta oluşturulan ancak Mac'te de oluşturulabilen Excel elektronik tablolarını aldı. Dolayısıyla tablodaki dönemin başlangıcı 1 Ocak 1900 ya da 1 Ocak 1904 olabilir. Nasıl öğrenilir? Excel dosya formatı gerekli bilgileri gösteriyor, ancak kullandığım ayrıştırıcı bunu göstermiyordu (şimdi gösteriyor) ve belirli bir tablonun dönemini bildiğinizi varsayıyordu. Muhtemelen Excel ikili formatını anlamak ve ayrıştırıcı yazarına bir yama göndermek için daha fazla zaman harcayabilirdim, ancak müşteri için yapacak daha çok işim vardı, bu yüzden dönemi belirlemek için hızlı bir şekilde bir buluşsal yöntem yazdım. O basitti.

Excel'de 5 Temmuz 1998 tarihi "07-05-98" (işe yaramaz Amerikan sistemi), "5 Temmuz 98", "5 Temmuz 1998", "5-Temmuz-98" biçiminde temsil edilebilir veya başka bir format, başka bir işe yaramaz format (ironik bir şekilde, Excel sürümümün sunmadığı formatlardan biri ISO 8601'di). Ancak tabloda biçimlendirilmemiş tarih, dönem-35981 için "1900" veya dönem-34519 için "1904" olarak saklandı (sayılar, dönemden bu yana geçen gün sayısını temsil eder). Yılı biçimlendirilmiş tarihten çıkarmak için basit bir ayrıştırıcı kullandım ve ardından yılı biçimlendirilmemiş tarihten çıkarmak için Excel ayrıştırıcısını kullandım. Her iki değerde de 4 yıllık fark varsa o zaman Epoch-1904'lü bir sistem kullandığımı biliyordum.

Neden yalnızca biçimlendirilmiş tarihleri ​​kullanmadım? Çünkü 5 Temmuz 1998, ayın günü kaybedilerek "98 Temmuz" olarak biçimlendirilebilir. O kadar çok şirketten masalar aldık ki, onları o kadar farklı şekillerde yarattık ki, tarihleri ​​belirlemek bize (bu durumda bana) kalmıştı. Ayrıca, eğer Excel bunu doğru yapıyorsa, biz de öyle yapmalıyız!

Aynı zamanda 39082 ile karşılaştım. Lotus 1-2-3'ün 1900'ü artık yıl olarak kabul ettiğini ve bunun Excel'de de aynen tekrarlandığını hatırlatayım. Ve bu da 1900 yılına bir gün eklendiğinden, birçok tarih hesaplama fonksiyonu o gün için yanlış olabiliyor. Yani 39082, 1 Ocak 2011 (Mac'lerde) veya 31 Aralık 2006 (Windows'ta) olabilirdi. "Yıl ayrıştırıcım" 2011 yılını biçimlendirilmiş değerden çıkardıysa, her şey yolunda demektir. Ancak Excel ayrıştırıcısı hangi dönemin kullanıldığını bilmediğinden, varsayılan olarak Epoch-1900'e ayarlanır ve 2006 yılını döndürür. Başvurum farkın 5 yıl olduğunu gördü, bunu hata olarak değerlendirdi, kaydetti ve biçimlendirilmemiş bir değer döndürdü.

Bunu aşmak için şunu yazdım (sözde kod):

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

Ve sonra 40 tarihin tamamı doğru şekilde ayrıştırıldı.

Büyük baskı işlerinin ortasında

1980'lerin başında babam, yüksek hızlı bant beslemesi için bant sürücüleri ve pnömatik sistemler üreten, artık kullanılmayan bir bölüm olan Depolama Teknolojisi'nde çalıştı.

Sürücüleri, yedi "B" sürücüsüne bağlı bir merkezi "A" sürücüsüne sahip olacak ve "A" sürücüsünü kontrol eden RAM'deki küçük işletim sistemi, okuma ve yazma işlemlerini tüm "B" sürücülerine devredebilecek şekilde yeniden tasarladılar.

“A” sürücüsü her başlatıldığında, işletim sistemini belleğine yüklemek için “A” sürücüsüne bağlı çevresel sürücüye bir disket takmak gerekiyordu. Son derece ilkeldi: Bilgi işlem gücü 8 bitlik bir mikro denetleyici tarafından sağlanıyordu.

Bu tür ekipmanların hedef kitlesi, çok sayıda adres etiketi veya banka ekstresi yazdırması gereken çok büyük veri ambarlarına (bankalar, perakende zincirleri vb.) sahip şirketlerdi.

Bir müşterinin sorunu vardı. Bir yazdırma işinin ortasında belirli bir “A” sürücüsü çalışmayı durdurabilir ve tüm işin durmasına neden olabilir. Sürücünün çalışmasını yeniden sağlamak için personelin her şeyi yeniden başlatması gerekti. Ve eğer bu altı saatlik bir görevin ortasında meydana gelirse, büyük miktarda pahalı bilgisayar zamanı kaybedilir ve tüm operasyonun programı bozulur.

Depolama Teknolojileri'nden teknisyenler gönderildi. Ancak tüm çabalarına rağmen, test koşullarında hatayı yeniden oluşturamadılar: büyük baskı işlerinin ortasında meydana gelmiş gibi görünüyordu. Sorun donanımda değildi, ellerinden gelen her şeyi değiştirdiler: RAM, mikro denetleyici, disket sürücüsü, teyp sürücüsünün akla gelebilecek her parçası - sorun devam etti.

Daha sonra teknisyenler genel merkezi arayarak Uzman'ı aradılar.

Uzman bir sandalye ve bir fincan kahve kaptı, bilgisayar odasında oturdu (o günlerde bilgisayarlara ayrılmış odalar vardı) ve personelin büyük bir baskı işi için sıraya girmesini izledi. Uzman bir arızanın meydana gelmesini bekliyordu ve öyle de oldu. Herkes Uzman'a baktı ama bunun neden olduğu hakkında hiçbir fikri yoktu. Bunun üzerine işin tekrar kuyruğa alınmasını emretti ve tüm personel ve teknisyenler işlerine geri döndü.

Uzman tekrar sandalyeye oturdu ve başarısızlığı beklemeye başladı. Yaklaşık altı saat geçti ve arıza meydana geldi. Her şeyin insanlarla dolu bir odada gerçekleşmesi dışında Uzman'ın yine hiçbir fikri yoktu. Görevin yeniden başlatılmasını emretti, yerine oturdu ve bekledi.

Üçüncü başarısızlıkta Uzman bir şeyi fark etti. Arıza, personelin yabancı bir sürücüdeki bantları değiştirmesi sonucu meydana geldi. Üstelik arıza, çalışanlardan birinin yerdeki belli bir döşemenin üzerinden geçmesiyle meydana geldi.

Yükseltilmiş zemin, 6 ila 8 inç yüksekliğe döşenen alüminyum karolardan yapılmıştır. Herhangi birinin yanlışlıkla önemli bir kabloya basmasını önlemek için bilgisayarlara ait çok sayıda kablo yükseltilmiş zeminin altından geçiyordu. Kiremitlerin yükseltilmiş zeminin altına girmesini önlemek için fayanslar çok sıkı bir şekilde döşendi.

Uzman, fayanslardan birinin deforme olduğunu fark etti. Bir çalışan köşesine bastığında döşemenin kenarları bitişikteki döşemelere sürtüyordu. Fayansları birbirine bağlayan plastik parçalar da onlara sürtünerek radyo frekansı paraziti oluşturan statik mikro deşarjlara neden oldu.

Günümüzde RAM, radyo frekansı girişiminden çok daha iyi korunmaktadır. Ancak o yıllarda durum böyle değildi. Uzman, bu müdahalenin hafızayı ve dolayısıyla işletim sisteminin işleyişini bozduğunu fark etti. Destek servisini aradı, yeni döşemeler sipariş etti, kendisi taktı ve sorun ortadan kalktı.

Sular yükseliyor!

Hikaye, Portsmouth'taki (sanırım) liman bölgesindeki bir ofisin dördüncü veya beşinci katındaki bir sunucu odasında gerçekleşti.

Bir gün ana veritabanının bulunduğu Unix sunucusu çöktü. Onu yeniden başlattılar ama o mutlu bir şekilde tekrar tekrar düşmeye devam etti. Destek servisinden birini aramaya karar verdik.

Destek elemanı... Sanırım adı Mark'tı ama bunun bir önemi yok... Onu tanıdığımı sanmıyorum. Gerçekten önemli değil. Mark'la kalalım, tamam mı? Harika.

Böylece, birkaç saat sonra Mark geldi (Leeds'ten Portsmouth'a çok da uzak değil), sunucuyu açtı ve her şey sorunsuz çalıştı. Tipik kahrolası destek, müşteri buna çok üzülür. Mark günlük dosyalarını inceliyor ve herhangi bir terslik bulamıyor. Böylece Mark trene geri döner (ya da hangi ulaşım aracıyla geldiyse, bildiğim kadarıyla topal bir inek olabilirdi... neyse, bunun bir önemi yok, tamam mı?) ve boşa harcayarak Leeds'e geri döner. gün.

Aynı akşam sunucu tekrar çöküyor. Hikaye aynı... sunucu yükselmiyor. Mark uzaktan yardım etmeye çalışıyor ancak istemci sunucuyu başlatamıyor.

Başka bir tren, otobüs, limonlu krema veya başka bir saçmalık ve Mark Portsmouth'a geri döndü. Bakın, sunucu sorunsuz açılıyor! Mucize. Mark, işletim sistemi veya yazılımda her şeyin yolunda olup olmadığını kontrol etmek için birkaç saat harcıyor ve Leeds'e doğru yola çıkıyor.

Günün ortasında sunucu çöküyor (sakin olun!). Bu sefer sunucuyu değiştirmek için donanım destek personelini çağırmak mantıklı görünüyor. Ama hayır, yaklaşık 10 saat sonra o da düşüyor.

Durum birkaç gün boyunca kendini tekrarladı. Sunucu çalışıyor, yaklaşık 10 saat sonra çöküyor ve sonraki 2 saat boyunca başlamıyor. Soğutmayı, bellek sızıntılarını kontrol ettiler, her şeyi kontrol ettiler ama hiçbir şey bulamadılar. Daha sonra çökmeler durdu.

Hafta kaygısız geçti... herkes mutluydu. Her şey yeniden başlayana kadar mutluyuz. Resim aynı. 10 saat çalışma, 2-3 saat kesinti...

Ve sonra birisi (sanırım bana bu kişinin BT ile hiçbir ilgisinin olmadığını söylediler) şöyle dedi:

"Bu gelgit!"

Bu ünlem boş bakışlarla karşılandı ve muhtemelen birisinin eli güvenlik çağrısı düğmesinde tereddüt etti.

"Gelgitle çalışmayı bırakıyor."

Bu, kahve içmek için otururken Tide Yıllığı'nı okuması pek mümkün olmayan BT destek çalışanları için tamamen yabancı bir kavram gibi görünebilir. Bunun hiçbir şekilde gelgitle ilgili olamayacağını, çünkü sunucunun bir haftadır hatasız çalıştığını açıkladılar.

"Geçen hafta gelgit düşüktü, ancak bu hafta yüksek."

Yat ehliyeti olmayanlar için küçük bir terminoloji. Gelgitler ay döngüsüne bağlıdır. Ve Dünya dönerken, her 12,5 saatte bir Güneş ve Ay'ın çekim kuvveti bir gelgit dalgası yaratır. 12,5 saatlik döngünün başında sular yükseliyor, ortasında bir çekiliyor ve sonunda yine bir su yükseliyor. Ancak ayın yörüngesi değiştikçe gelgit ve gelgit arasındaki fark da değişir. Ay, Güneş ile Dünya arasında veya Dünya'nın karşı tarafında olduğunda (dolunay olsun ya da olmasın), Syzygyn gelgitlerini, yani en yüksek gelgitleri ve en düşük alçak gelgitleri yaşarız. Yarım ayda karesel gelgitler elde ederiz - en düşük gelgitler. İki uç arasındaki fark büyük ölçüde azalır. Ay döngüsü 28 gün sürer: syzygian - quadrature - syzygian - quadrature.

Teknisyenlere gelgit kuvvetlerinin özü anlatıldığında hemen polisi aramaları gerektiğini düşündüler. Ve oldukça mantıklı. Ama adamın haklı olduğu ortaya çıktı. İki hafta önce bir destroyer ofisten çok da uzak olmayan bir yere demirlemişti. Gelgit onu belirli bir yüksekliğe çıkardığında, geminin radar direği sunucu odasının zemini hizasında kalıyordu. Ve radar (veya elektronik savaş ekipmanı veya başka bir askeri oyuncak) bilgisayarlarda kaos yarattı.

Roket için uçuş görevi

Büyük (yaklaşık 400 bin hat) bir roket fırlatma kontrol ve izleme sistemini işletim sisteminin, derleyicinin ve dilin yeni sürümlerine taşımakla görevlendirildim. Daha doğrusu Solaris 2.5.1'den Solaris 7'ye ve Ada 83'te yazılan Verdix Ada Development System'den (VADS), Ada 95'te yazılan Rational Apex Ada sistemine. VADS, Rational tarafından satın alındı ​​ve ürünü Rational, Apex derleyicisine geçişi kolaylaştırmak için VADS'ye özgü paketlerin uyumlu sürümlerini uygulamaya çalışsa da artık kullanılmıyor.

Üç kişi kodun temiz bir şekilde derlenmesine yardımcı oldu. İki hafta sürdü. Daha sonra sistemin çalışması için kendi başıma çalıştım. Kısacası karşılaştığım en kötü yazılım sistemi mimarisi ve uygulamasıydı, bu yüzden taşıma işlemini tamamlamak iki ay daha sürdü. Sistem daha sonra birkaç ay daha süren teste sunuldu. Test sırasında bulunan hataları hemen düzelttim, ancak sayıları hızla azaldı (kaynak kodu bir üretim sistemiydi, bu nedenle işlevselliği oldukça güvenilir bir şekilde çalıştı, sadece yeni derleyiciye uyum sırasında ortaya çıkan hataları kaldırmak zorunda kaldım). Sonunda her şey olması gerektiği gibi giderken başka bir projeye transfer oldum.

Ve Şükran Günü'nden önceki Cuma günü telefon çaldı.

Roket fırlatmanın yaklaşık üç hafta içinde test edilmesi gerekiyordu ve geri sayımın laboratuvar testleri sırasında komut dizisi engellendi. Gerçek hayatta bu, testi iptal eder ve eğer tıkanma, motorun çalıştırılmasından sonraki birkaç saniye içinde meydana gelirse, yardımcı sistemlerde, roketin uzun ve pahalı bir şekilde hazır olmasını gerektirecek, geri dönüşü olmayan birkaç eylem meydana gelir. Başlamazdı ama birçok insan zaman ve çok çok para kaybından dolayı çok üzülürdü. Kimsenin size Savunma Bakanlığı'nın parayı pervasızca harcadığını söylemesine izin vermeyin; bütçeyi ilk veya ikinci sıraya koymayan ve ardından programı yapmayan bir sözleşme yöneticisiyle hiç tanışmadım.

Önceki aylarda, bu geri sayım mücadelesi, yalnızca birkaç küçük aksaklık haricinde birçok varyasyonla yüzlerce kez gerçekleştirilmişti. Yani bunun gerçekleşme ihtimali çok düşüktü ama sonuçları çok önemliydi. Bu iki faktörü çarptığınızda, haberin benim ve onlarca mühendis ve yönetici için berbat bir tatil haftası öngördüğünü anlayacaksınız.

Ve sistemi taşıyan kişi olarak bana ilgi gösterildi.

Güvenlik açısından kritik sistemlerin çoğunda olduğu gibi, çok sayıda parametre günlüğe kaydedildi; bu nedenle, sistem çökmeden önce yürütülen birkaç kod satırını belirlemek oldukça kolaydı. Ve tabii ki, kesinlikle sıra dışı hiçbir şey yoktu; aynı ifadeler, aynı çalıştırma sırasında kelimenin tam anlamıyla binlerce kez başarıyla uygulanmıştı.

Apex'teki insanları Rational'a çağırdık çünkü derleyiciyi geliştirenler onlardı ve geliştirdikleri rutinlerden bazıları şüpheli kodda çağrıldı. Onlar (ve diğer herkes), kelimenin tam anlamıyla ulusal öneme sahip bir sorunun kökenine inme ihtiyacının varlığından etkilenmişlerdi.

Dergilerde ilginç bir şey bulunmadığından sorunu yerel bir laboratuvarda yeniden oluşturmaya karar verdik. Olay yaklaşık 1000 çalıştırmada bir kez meydana geldiğinden bu kolay bir iş değildi. Şüphelenilen nedenlerden biri, satıcı tarafından geliştirilen mutex işlevine (VADS geçiş paketinin bir parçası) yapılan çağrıydı. Unlock kilidin açılmasına yol açmadı. İşlevi çağıran işleme iş parçacığı, nominal olarak her saniye gelen kalp atışı mesajlarını işledi. Frekansı 10 Hz'e yani saniyede 10 defaya çıkardık ve koşmaya başladık. Yaklaşık bir saat sonra sistem kendini kilitledi. Günlükte kaydedilen mesajların sırasının başarısız test sırasındakiyle aynı olduğunu gördük. Birkaç çalıştırma daha yaptık, sistem başlangıçtan 45-90 dakika sonra sürekli olarak engellendi ve günlük her seferinde aynı rotayı içeriyordu. Teknik olarak farklı kod çalıştırıyor olsak da (mesaj frekansı farklıydı) sistemin davranışı aynıydı, dolayısıyla bu yükleme senaryosunun aynı soruna neden olduğundan emindik.

Şimdi ifade dizisinde engellemenin tam olarak nerede gerçekleştiğini bulmamız gerekiyordu.

Sistemin bu uygulamasında Ada görev sistemi kullanıldı ve inanılmaz derecede kötü kullanıldı. Görevler, Ada'da üst düzey eş zamanlı yürütülebilir bir yapıdır; yürütme iş parçacıklarına benzer, yalnızca dilin kendisinde yerleşiktir. İki görevin iletişim kurması gerektiğinde, "bir randevu ayarlarlar", gerekli verileri paylaşırlar ve ardından randevuyu durdurup bağımsız uygulamalarına geri dönerler. Ancak sistem farklı uygulandı. Bir hedef görevin randevusu alındıktan sonra, bu hedef görev başka bir görevle randevulaştı, o da daha sonra üçüncü bir görevle randevulaştı ve bazı işlemler tamamlanana kadar bu şekilde devam etti. Bundan sonra tüm bu randevular tamamlandı ve her görevin yerine getirilmesine geri dönmek zorunda kaldı. Yani, girdi verilerinin bir kısmını işlerken tüm "çoklu görev" sürecini durduran, dünyanın en pahalı işlev çağrı sistemiyle karşı karşıyaydık. Ve bundan önce, yalnızca verim çok düşük olduğu için sorunlara yol açmıyordu.

Bu görev mekanizmasını anlattım çünkü bir randevu istendiğinde veya tamamlanması beklendiğinde bir "görev değişimi" meydana gelebilir. Yani işlemci, yürütülmeye hazır başka bir görevi işlemeye başlayabilir. Bir görev başka bir görevle buluşmaya hazır olduğunda, tamamen farklı bir görevin yürütülmeye başlayabileceği ve sonunda kontrolün ilk randevuya geri döndüğü ortaya çıktı. Ve görevin değişmesine neden olan başka olaylar da meydana gelebilir; Böyle bir olay, bir muteksin yazdırılması veya çalıştırılması gibi bir sistem işlevine yapılan çağrıdır.

Soruna hangi kod satırının neden olduğunu anlamak için, bir görev anahtarını tetiklemeden bir dizi ifade aracılığıyla ilerlemeyi kaydetmenin bir yolunu bulmam gerekiyordu; bu, bir kilitlenmenin meydana gelmesini önleyecekti. O yüzden yararlanamadım Put_Line()G/Ç işlemlerini gerçekleştirmekten kaçınmak için. Bir sayaç değişkeni veya buna benzer bir şey ayarlayabilirim ama ekranda görüntüleyemiyorsam değerini nasıl görebilirim?

Ayrıca günlüğü incelerken, sürecin tüm G/Ç işlemlerini engelleyen ve diğer işlemlerin gerçekleştirilmesini engelleyen kalp atışı mesajlarının işlenmesindeki donmaya rağmen, diğer bağımsız görevlerin yürütülmeye devam ettiği ortaya çıktı. Yani iş tamamen engellenmedi, yalnızca (kritik) bir görev zinciri engellendi.

Bu, engelleme ifadesini değerlendirmek için gereken ipucuydu.

Bir görevi, numaralandırılmış bir türü ve bu türden bir genel değişkeni içeren bir Ada paketi hazırladım. Numaralandırılabilir değişmezler sorunlu dizinin belirli ifadelerine bağlandı (örn. Incrementing_Buffer_Index, Locking_Mutex, Mutex_Unlocked) ve ardından karşılık gelen numaralandırmayı genel bir değişkene atayan atama ifadelerini buna ekledim. Tüm bunların nesne kodu bellekte bir sabiti sakladığından, yürütülmesinin bir sonucu olarak görev değiştirme olasılığı son derece düşüktü. Engelleme, görevi geri alırken geri dönmek yerine (birkaç nedenden dolayı) yürütme sırasında meydana geldiğinden, öncelikle görevi değiştirebilecek ifadelerden şüpheleniyorduk.

İzleme görevi basitçe bir döngü içinde yürütülüyordu ve global değişkenin değerinin değişip değişmediğini görmek için periyodik olarak kontrol ediliyordu. Her değişiklikte değer bir dosyaya kaydedildi. Daha sonra kısa bir bekleme ve yeni bir çek. Değişkeni dosyaya yazdım çünkü görev yalnızca sorunlu alanda görev değiştirilirken sistem onu ​​yürütme için seçtiğinde yürütülüyordu. Bu görevde olup bitenler diğer ilgisiz engellenen görevleri etkilemeyecektir.

Sistem sorunlu kodu çalıştırma noktasına ulaştığında, bir sonraki ifadeye geçerken global değişkenin sıfırlanması bekleniyordu. Daha sonra görevin değişmesine neden olan bir şey olacaktır ve yürütme frekansı (10 Hz) izleme görevininkinden daha düşük olduğundan, monitör global değişkenin değerini yakalayıp yazabilir. Normal bir durumda, bir numaralandırma alt kümesinin yinelenen bir dizisini elde edebilirim: görev değişimi sırasında değişkenin son değerleri. Askıya alınırken global değişken artık değişmemelidir ve yazılan son değer hangi ifadenin tamamlanmadığını gösterecektir.

Kodu izleme ile çalıştırdım. Dondu. Ve izleme saat gibi işledi.

Günlük, bir muteksin çağrıldığını belirten bir değerle kesintiye uğrayan beklenen diziyi içeriyordu. Unlockve önceki binlerce aramada olduğu gibi görev tamamlanmadı.

Apex mühendisleri bu sırada kodlarını hararetle analiz ediyorlardı ve mutekste teorik olarak kilitlenebilecek bir yer buldular. Ancak bunun olasılığı çok düşüktü, çünkü yalnızca belirli bir zamanda meydana gelen belirli bir dizi olay blokajla sonuçlanabiliyordu. Murphy Yasası arkadaşlar, bu Murphy Yasası.

İhtiyacım olan kod parçasını korumak için, o parçaya muteks erişimini kontrol etmek amacıyla muteks işlev çağrılarını (işletim sistemi muteks işlevinin üzerine inşa edilmiş) küçük bir yerel Ada muteks paketiyle değiştirdim.

Bunu koda ekledim ve testi çalıştırdım. Yedi saat sonra kod hala çalışıyordu.

Kodum Rational'a gönderildi, burada derlendi, parçalara ayrıldı ve sorunlu muteks işlevlerinde kullanılan yaklaşımın aynısını kullanmadığı kontrol edildi.

Bu kariyerimin en kalabalık kod incelemesiydi 🙂 Odada yaklaşık on mühendis ve yönetici vardı, diğer on kişi de konferans görüşmesindeydi ve hepsi yaklaşık 20 satırlık kodu inceledi.

Kod gözden geçirildi, yeni yürütülebilir dosyalar bir araya getirildi ve resmi regresyon testi için gönderildi. Birkaç hafta sonra geri sayım testi başarılı oldu ve roket havalandı.

Tamam, bunların hepsi iyi güzel de hikayenin amacı ne?

Kesinlikle iğrenç bir sorundu. Yüz binlerce kod satırı, paralel yürütme, bir düzineden fazla etkileşimli süreç, zayıf mimari ve kötü uygulama, gömülü sistemler için arayüzler ve harcanan milyonlarca dolar. Baskı yok, doğru.

Taşıma işlemini yaparken ilgi odağı olmama rağmen bu sorun üzerinde çalışan tek kişi ben değildim. Ancak bunu yapmış olsam bile bu, yüzbinlerce kod satırının tamamını anladığım, hatta onları gözden geçirdiğim anlamına gelmiyor. Kod ve kayıtlar ülkenin her yerindeki mühendisler tarafından analiz edildi, ancak bana başarısızlığın nedenleri hakkındaki hipotezlerini anlattıklarında, onları çürütmek sadece yarım dakikamı aldı. Benden teorileri analiz etmem istendiğinde bunu başka birine aktarırdım çünkü bu mühendislerin yanlış yola gittikleri benim için açıktı. Kulağa küstahça mı geliyor? Evet bu doğru ama ben hipotezleri ve istekleri başka bir nedenden dolayı reddettim.

Sorunun doğasını anladım. Tam olarak nerede ve neden olduğunu bilmiyordum ama ne olduğunu biliyordum.

Yıllar geçtikçe birçok bilgi ve deneyim biriktirdim. Ada'yı kullanmanın öncülerinden biri oldum, avantajlarını ve dezavantajlarını anladım. Ada çalışma zamanı kitaplıklarının görevleri nasıl yerine getirdiğini ve paralel yürütmeyle nasıl ilgilendiğini biliyorum. Ve bellek, yazmaçlar ve birleştirici düzeyindeki düşük seviyeli programlamayı anlıyorum. Yani alanımda derin bilgiye sahibim. Ve bunları sorunun nedenini bulmak için kullandım. Sadece hatayı çözmekle kalmadım, onu çok hassas bir çalışma zamanı ortamında nasıl bulacağımı da anladım.

Bu tür kodla mücadele hikayeleri, böyle bir mücadelenin özelliklerine ve koşullarına aşina olmayanlar için pek ilginç değil. Ancak bu hikayeler gerçekten zor sorunları çözmek için ne gerektiğini anlamamıza yardımcı oluyor.

Gerçekten zor problemleri çözmek için bir programcıdan daha fazlası olmanız gerekir. Kodun "kaderini", çevresiyle nasıl etkileşime girdiğini ve ortamın kendisinin nasıl çalıştığını anlamanız gerekir.

Ve sonra kendi mahvolmuş tatil haftanızı yaşayacaksınız.

Devam edecek.

Kaynak: habr.com

Yorum ekle