Çoğu insan hata ayıklamayı bir bilimden ziyade bir sanat gibi görüyor. Burada bir sanattan ziyade bir bilim gibi davrananlar için - yeni bir sorun / hata / sorunla karşılaştığında normal olarak hangi süreçleri kullanıyorsunuz?
Çoğu insan hata ayıklamayı bir bilimden ziyade bir sanat gibi görüyor. Burada bir sanattan ziyade bir bilim gibi davrananlar için - yeni bir sorun / hata / sorunla karşılaştığında normal olarak hangi süreçleri kullanıyorsunuz?
Yanıtlar:
Çok genel anlamda, yaptığım şey:
Sorunu izole etmeye çalışın. Hata ilk ortaya çıktığında nelerin değiştiğini düşünün. Nerede çalışıyorsun? Kodun hangi kısmını değiştiriyordunuz? Böceklerimin% 99'u bu şekilde çözüldü. Genellikle aptalca bir şeydir.
Sorunun nerede olduğu hakkında bir tahminim varsa, nedeni gibi görünen koda iyi bir göz atın. Oku onu. Hatta yüksek sesle oku. Kendime şunu sor: "Neyi başarmaya çalışıyorum?". Bazı sorun türleri için: Bazı yan etkileri olabilir mi ya da başka bir yerde koddan hiç düşünmediğim bir şekilde etkilenebilir mi?
Neyin yanlış gittiğini, nerede ve ne zaman analiz ettiğini çeşitli şekillerde deneyin (aşağıya bakın).
Hala bir ipucum yoksa, kaynağımın eski bir sürümünün aynı soruna sahip olup olmadığını kontrol ediyorum, geliştirme zaman çizelgemde sorunun ilk ortaya çıktığında bulmaya çalışın. Bunu yapmak için git gibi iyi bir sürüm kontrol sistemi ile çalışmanız gerekir (git tam olarak bu tür hata ayıklama için bisect adlı bir özelliğe sahiptir).
Hala ipucu yoksa, bir ara verin .... aslında sık sık yardımcı olur.
Çizim tahtasına geri dönün - programınızın nasıl çalışması gerektiğini ve bunun gerçekten mantıklı olup olmadığını gözden geçirin.
Gerçekten sorunun türüne bağlıdır, ancak sorunun nerede olabileceğine dair genel bir fikrim olduğunu varsayarsak, o zaman:
Sorunun kodun / son değişikliğin bir bölümünde olduğundan şüphelenirim, önce kodu daha basit hale getirerek kaybolmasını sağlamak için herhangi bir şeyi kaldırmayı / yorumlamayı / değiştirmeyi ya da neyi kaldırmaya çalışıyorum ve sonra sorunlu kodu geri getirip iyi bak.
Kesme noktaları ile bir hata ayıklayıcı çalıştırın (mümkünse) ve işlerimin nerede yanlış gittiğine dair daha iyi bir fikir edinmek için verilerimin kötü davranmaya başladığında nasıl bulmaya çalıştığına bir göz atın.
bzr qdiff
komutla kolayca görülebilir .
Test odaklı geliştirme ( TDD ) kullanmaya çalışıyorum. Hatayı çoğaltan bir test yazıyorum, sonra testi geçmeye çalışıyorum. Bazen testi yazma eylemi hatayı bulmaya yardımcı olur.
Bu beni çoğu zaman hata ayıklayıcıdan uzak tutar ve hatanın yeniden ortaya çıkmasını önlemek için regresyon testleri sağlar.
Bazı bağlantılar:
Bilim kelimesi için bir takım tanımlar vardır, ancak kulağa muhtemelen " bilimsel yöntem " olarak isimlendirilebilecek şeyden bahsettiğiniz anlaşılmaktadır . Bilimsel yöntem, bazı fenomenleri (muhtemelen bir hata veya beklenmedik bir program davranışı) gözlemleme, davranışı açıklamak için bir hipotez veya hipotez formüle etme ve bunu kanıtlamak için en olası deney (problemi güvenilir bir şekilde yeniden üreten bir test yazma) şeklinde özetlenebilir.
Oluşabilecek hata türleri (fenomenler) neredeyse sınırsızdır ve bazıları mutlaka iyi tanımlanmış bir süreç gerektirmez. Örneğin, bazen bir hata gözlemlersiniz ve neye sebep olduğunu anında bilirsiniz çünkü koda çok aşinadır. Diğer zamanlarda, bazı girdiler (eylem, adımlar dizisi vb.) Verildiğinde, yanlış bir sonucun (kilitlenme, bozuk çıktı vb.) Meydana geldiğini bilirsiniz. Bu durumlar için, genellikle çok fazla "bilimsel" düşünce gerektirmez. Bazı düşünceler arama alanını azaltmaya yardımcı olabilir, ancak yaygın bir yöntem, bir hata ayıklayıcıdaki kodda adım atmak ve işlerin nereye gittiğini görmek.
Yine de, en ilginç ve muhtemelen bilimsel bir sürece layık bulduğum durumlar, bazı sonuçların verildiği ve bunun nasıl olduğunu açıklamanızın istendiği yerlerdir. Bunların açık bir örneği, bir çökme dökümüdür. Çökme dökümünü yükleyebilir ve sistemin durumunu gözlemleyebilirsiniz ve işiniz bu duruma nasıl geldiğini açıklamaktır. Çökme (veya çekirdek) dökümü, kullanıcı tarafından tanımlandığı gibi bir istisna, kilitlenme, dahili hata veya bazı "istenmeyen" bir durum gösterebilir (örn. Halsizlik). Bu durumlar için genellikle şu satırdaki adımları izlerim:
Dar Gözlem : Varsa, spesifik problemi doğrudan çevreleyen bilgileri inceleyin. Burada bariz şeyler çağrı yığını, görebiliyorsanız yerel değişkenler, sorunu çevreleyen kod satırları. Bu tür özel bir konum çalışması her zaman uygulanamaz. Örneğin, "yavaş" bir sistemin incelenmesi böyle bir başlangıç noktasına sahip olmayabilir, ancak bir çökme veya dahili hata durumunun acil ve belirgin bir ilgi alanı olacaktır. Buradaki belirli bir adım, windbg (run! Analyze -v'yi yüklü bir çökme dökümünde kullanmak ve size ne söylediğine bakmak) gibi araçları kullanmak olabilir.
Geniş Gözlem : Sistemin diğer bölümlerini inceleyin. Sistemdeki tüm iş parçacıklarının durumunu inceleyin, tüm global bilgilere (kullanıcı / işlem / öğe sayısı, etkin işlemler / işlemler / widget'lar vb.), Sistem (OS) bilgilerine vb. Bakın. Kullanıcı herhangi bir dış ayrıntı sağladıysa , gözlemlediklerinizle birlikte düşünün. Örneğin, size sorunun her Salı öğleden sonra meydana geldiğini söylediler, kendinize bunun ne anlama gelebileceğini sorun.
varsayımda bulunmak: Bu gerçekten eğlenceli olan kısım (ve eğlenceli olduğu için mizaçlı değilim). Çoğu zaman tersine çok fazla mantıksal düşünme gerektirir. Sistemin mevcut duruma nasıl girdiğini düşünmek çok keyifli olabilir. Bunun birçok insanın bir sanat olarak düşündüğü kısım olduğundan şüpheleniyorum. Ve sanırım programcı hangi çubukları görmek için rastgele bir şeyler atmaya başlarsa olabilir. Ancak tecrübeyle, bu oldukça iyi tanımlanmış bir süreç olabilir. Bu noktada çok mantıklı düşünürseniz, belirli bir duruma yol açan olası yol kümelerini tanımlamak çoğu zaman mümkündür. S5 eyaletinde olduğumuzu biliyorum. Bunun gerçekleşmesi için, S4a veya S4b'nin meydana gelmesi gerekiyordu ve belki de S4a'dan önce S3 vb. Bazen bir not defterine basit bir akış veya durum diyagramı veya zamanla ilgili bir dizi adımın yazılmasına yardımcı olabilir. Buradaki gerçek süreçler duruma bağlı olarak büyük ölçüde değişecektir, ancak şu anda ciddi düşünce (ve önceki adımlarda yeniden inceleme) genellikle bir veya daha fazla makul cevap verecektir. Ayrıca bu adımın son derece önemli bir kısmının imkansız olan şeyleri ortadan kaldırmak olduğunu unutmayın. İmkansızı kaldırmak çözüm alanını düzeltmeye yardımcı olabilir (imkansızı ortadan kaldırdıktan sonra Sherlock Holmes'un neler söylediğini hatırlayın). Ayrıca bu adımın son derece önemli bir kısmının imkansız olan şeyleri ortadan kaldırmak olduğunu unutmayın. İmkansızı kaldırmak çözüm alanını düzeltmeye yardımcı olabilir (imkansızı ortadan kaldırdıktan sonra Sherlock Holmes'un neler söylediğini hatırlayın). Ayrıca bu adımın son derece önemli bir kısmının imkansız olan şeyleri ortadan kaldırmak olduğunu unutmayın. İmkansızı kaldırmak çözüm alanını düzeltmeye yardımcı olabilir (imkansızı ortadan kaldırdıktan sonra Sherlock Holmes'un neler söylediğini hatırlayın).
Deney : Bu aşamada, sorunu önceki adımda elde edilen hipotezlere göre yeniden oluşturmaya çalışın. Önceki adımda ciddi düşünceyi yaptıysanız, bu çok basit olmalıdır. Bazen "hile" ve belirli bir test yardımcı olmak için kod tabanı değiştirin. Örneğin, son zamanlarda bir yarış koşulundan kaynaklandığım bir çöküşü araştırıyordum. Bunu doğrulamak için, başka bir iş parçacığının "doğru" zamanda kötü şeyler yapmasına izin vermek için birkaç kod satırı arasına bir Uyku (500) koydum. Buna "gerçek" bilimde izin verilip verilmediğini bilmiyorum, ancak sahip olduğunuz kodda son derece makul.
Yeniden üretmeyi başarırsanız, şansınız neredeyse bitmiş demektir (geriye kalan tek şey onu düzeltmek için basit bir adımdır ... ama bu başka bir gün içindir). Regresyon test sistemine yeni testi kontrol ettiğinizden emin olun. Ve şunu belirtmeliyim ki, yanaktaki dil olarak basitleştirmenin düzeltilmesi hakkındaki önceki ifadeyi amaçladım. Bir çözüm bulmak ve uygulamak kapsamlı bir çalışma gerektirebilir. Bence bir hatanın düzeltilmesi hata ayıklama sürecinin bir parçası değil, daha çok gelişmedir. Ve eğer düzeltmeyle ilgiliyse, bir miktar tasarım ve inceleme gerektirmelidir.
Test senaryosunu azaltmaya çalışın. Yeterince küçük olduğunda, soruna neden olan ilgili kodu bulmak genellikle daha kolaydır.
Soruna yeni bir check-in neden olması muhtemeldir ve önceki günlük derleme iyi olmuştur. Bu durumda, kaynak denetiminden değişiklik günlüğünüz kimi yakalayacağınıza karar vermenize yardımcı olur.
Ayrıca, C / C ++ ile ilgileniyorsanız, valgrind çalıştırmayı veya bellekle ilgili sorunları izole etmek için arındırmayı düşünün.
Hata ayıklamanın en zor kısmı, özellikle sorun birkaç katmanın altına gömüldüğünde sorunu izole etmektir. Üniversitede müzik kaydı okudum ve garip bir şekilde burada doğrudan uygulanan bir Studio Electronics sınıfı vardı. Bir stüdyo ortamında hata ayıklamayı sistematik hata ayıklama sürecinin bir örneği olarak kullanacağım.
Hata ayıklama kodu gerçekten çok farklı değil. Kod bir istisna atarken hata ayıklama çok daha kolaydır. Bu istisnanın yığın izlemesinden geriye doğru izleyebilir ve anahtar konumlarında kesme noktaları ayarlayabilirsiniz. Genellikle bir değişken ayarladıktan hemen sonra veya istisnayı atan yöntemi çağıran satırda. Değerlerden bir veya daha fazlasının doğru olmadığını görebilirsiniz. Eğer doğru değilse (olmaması gerektiğinde null veya değer aralık dışındaysa), neden doğru olmadığını keşfetme sürecidir. Bir IDE'deki kırılma noktaları, elektronik test noktalarına eşdeğerdir (bir ölçüm cihazının devreyi kontrol etmesi için tasarlanmıştır).
Şimdi, asıl problemimin nerede olduğunu keşfetmenin bu zor kısmını geçtikten sonra, gelecekte bunu kontrol etmek için bazı birim testleri yazacağım.
Daha pratik bir yaklaşım için:
Hata işlenmeyen bir istisna ile ilgiliyse - yığın izlemesine bakın. Boş referans, sınırların dışında dizin vb. Ve kendi tanımladığınız istisnalar en yaygın olanıdır, bu hatayı küçük bir geliştiriciye, muhtemelen kolay ve iyi bir öğrenme deneyimine atayabilirsiniz.
Her makinede olmazsa, muhtemelen bir çeşit yarış durumu / diş çekme sorunu. Bunlar, takip etmek, sıkılmış kıdemli programcınızı üzerine koymak için süper eğlencelidir. Çok sayıda günlük kaydı, iyi bilgi ve iyi araçlar bunu yapar.
Bir başka büyük hata sınıfı, test ekibinin veya müşterilerin / uzmanların belirli bir davranışı sevmediğidir. Örneğin, kullanıcı kimliklerini göstermeye karar vermenizi veya arama yaparken otomatik olarak tamamlanmamanızı sevmezler. Bunlar gerçek hatalardır, daha iyi bir ürün yönetimine ve daha geniş bir görünüme sahip geliştiricilere sahip olmayı düşünün. Bir geliştiriciyi, sistemi genişleme düşünülerek oluşturuyorsa, bunu "düzeltmek" için nispeten kısa bir zaman alması gerekir.
Diğer tüm hataların% 80'i, iyi bir kayıt sistemine sahip olmak ve bunları çözmek için yeterli bilgi toplayarak çözülür. Log4Net / Log4J gibi çok sayıda karmaşık günlük sistemiyle yerleşik izlemeyi kullanın
performans hataları kendi kategorisidir, buradaki daha altın kuralı "önce ölç, sonra düzelt!" daha sonra yanıt süresinde sadece% 3-4 oranında bir azalma olur.
Akış iki yaklaşımım var:
Divide and Conquer
Paradigma'dan .Bu yaklaşımlar bana çoğu zaman yardımcı oldu.