Błędy wkradające się do kodu można zminimalizować, ale nie do końca wyeliminować, ponieważ jest napisane - programiści, choć wielu by się nie zgodziło , tylko ludzie.
Kiedy wykryjemy błąd w naszym kodzie, co możemy zrobić, aby go usunąć? Jak powinniśmy do tego podejść, aby jak najbardziej efektywnie wykorzystać nasz cenny czas i pozwolić nam poświęcać mniej czasu na szukanie go, a więcej na kodowanie? Czego powinniśmy unikać podczas debugowania?
Zauważ tutaj, że nie mówimy o zapobieganiu błędom; mówimy o tym, co zrobić, gdy błędy nie pojawiają. Wiem, że to szerokie pole i może być w dużym stopniu zależne od języka, platformy i narzędzi. Jeśli tak, staraj się obejmować odpowiedzi, takie jak sposób myślenia i ogólne metody.
Odpowiedzi:
Sposób myślenia i podejście do debugowania jest być może najważniejszą częścią, ponieważ określa, jak skutecznie naprawisz błąd i czego się z niego nauczysz - jeśli w ogóle.
Klasyki dotyczące tworzenia oprogramowania, takie jak The Pragmatic Programmer i Code Complete, w zasadzie przemawiają za tym samym podejściem: każdy błąd jest okazją do nauki, prawie zawsze o sobie (ponieważ tylko początkujący obwiniają kompilator / komputer jako pierwszy).
Więc potraktuj to jako tajemnicę, która będzie interesująca do złamania. I łamanie tej tajemnicy powinno odbywać się systematycznie, poprzez wyrażanie naszych założeń (sobie lub innym), a następnie testowanie naszych założeń, jeden po drugim, w razie potrzeby - przy użyciu każdego dostępnego narzędzia, zwłaszcza debuggerów i zautomatyzowanych platform testowych. Następnie po rozwiązaniu tajemnicy możesz zrobić jeszcze lepiej, przeglądając cały kod pod kątem podobnych błędów, które mogłeś popełnić; i napisz automatyczny test, aby upewnić się, że błąd nie powtórzy się nieświadomie.
Ostatnia uwaga - wolę nazywać błędy „błędami”, a nie „błędami” - Dijkstra skarcił kolegom, że użyli tego drugiego terminu, ponieważ jest nieuczciwy, popierając pomysł, że zgubne i niestabilne wróżki robaków podsycały błędy w naszych programach, gdy my „ patrzę, zamiast być tam z powodu naszego (niechlujnego) myślenia: http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html
źródło
Napisz testy. Testowanie jest nie tylko świetne w zapobieganiu błędom (z mojego doświadczenia, dobrze wykonane TDD eliminuje prawie wszystkie trywialne, głupie błędy), ale także bardzo pomaga w debugowaniu. Testowanie zmusza projekt do raczej modułowej budowy, co znacznie ułatwia izolowanie i replikowanie problemu. Ponadto kontrolujesz środowisko, więc będzie mniej niespodzianek. Co więcej, gdy otrzymasz niesprawny przypadek testowy, możesz być całkiem pewny, że trafiłeś na prawdziwą przyczynę niepokojącego Cię zachowania.
Dowiedz się, jak korzystać z debugera.
print
instrukcje mogą działać dość dobrze na pewnym poziomie, ale debugger przez większość czasu jest bardzo pomocny (a gdy już wiesz, jak go używać, jest o wiele wygodniejszy niżprint
instrukcje).Porozmawiaj o kimś z twoim problemem, nawet jeśli to tylko gumowe kaczątko . Zmuszenie się do wyrażenia problemu, nad którym pracujesz słowami, naprawdę czyni cuda.
Daj sobie limit czasu. Jeśli na przykład po 45 minutach poczujesz, że nigdzie się nie wybierasz, po prostu przełącz się na inne zadania na jakiś czas. Kiedy wrócisz do swojego błędu, możesz mieć nadzieję, że zobaczysz inne możliwe rozwiązania, których wcześniej nie wziąłbyś pod uwagę.
źródło
Myślę, że odtworzenie błędu jest również ważne. Wszystkie przypadki, które odtwarzają błąd, mogą być wymienione, a następnie możesz upewnić się, że poprawka błędu obejmuje wszystkie te przypadki.
źródło
Jest świetna książka, którą przeczytałem na ten temat, zatytułowana „ Dlaczego programy nie działają” , która przedstawia różne strategie znajdowania błędów, od zastosowania metody naukowej do izolacji i rozwiązania błędu, po debugowanie delta. Inną interesującą częścią tej książki jest to, że eliminuje ona termin „błąd”. Podejście Zellera to:
(1) Programista tworzy defekt w kodzie. (2) Wada powoduje infekcję (3) Infekcja się rozprzestrzenia (4) Infekcja powoduje awarię.
Jeśli chcesz poprawić swoje umiejętności debugowania, bardzo polecam tę książkę.
Z własnego doświadczenia wynika, że w naszej aplikacji znalazłem wiele błędów, ale zarządzanie po prostu naciska na nas, aby udostępnić nowe funkcje. Często słyszałem: „Znaleźliśmy ten błąd, a klient jeszcze go nie zauważył, więc zostaw go, dopóki nie zauważy”. Myślę, że bycie reaktywnym w przeciwieństwie do proaktywnego naprawiania błędów jest bardzo złym pomysłem, ponieważ kiedy przychodzi czas na naprawę, masz inne problemy, które wymagają rozwiązania, a zarządzanie funkcjami wymaga natychmiastowego działania, więc jesteś złapany jak najszybciej w błędnym cyklu, który może prowadzić do dużego stresu i wypalenia, a ostatecznie do wadliwego systemu.
Komunikacja jest także kolejnym czynnikiem w przypadku wykrycia błędów. Wysłanie wiadomości e-mail lub udokumentowanie jej w narzędziu do śledzenia błędów jest w porządku i dobrze, ale z własnego doświadczenia wynika, że inni programiści odnajdują podobny błąd i zamiast ponownie użyć rozwiązania podjętego w celu naprawy kodu (ponieważ o tym zapomnieli ), dodają własne wersje, więc masz w swoim kodzie 5 różnych rozwiązań, przez co wygląda to na bardziej rozdętą i mylącą. Tak więc, kiedy naprawisz błąd, upewnij się, że kilka osób zapoznało się z poprawką i przekazało informacje zwrotne na wypadek, gdyby naprawili coś podobnego i znaleźli dobrą strategię radzenia sobie z tym.
limist wspomniał o książce The Pragmatic Programmer, która zawiera interesujące materiały na temat naprawiania błędów. Korzystając z przykładu podanego w poprzednim akapicie, przyjrzałbym się temu: Entrofia oprogramowania , w której zastosowano analogię zepsutą wdową. Jeśli pojawią się dwa zepsute okna, twoja drużyna może być apatyczna, aby je naprawić, chyba że podejmiesz proaktywne podejście.
źródło
Błąd, błąd, problem, wada - jakkolwiek chcesz to nazwać, nie ma to wielkiego znaczenia. Będę trzymać się problemu, ponieważ do tego jestem przyzwyczajony.
Jeśli znasz kod, lub problem lub naprawa jest oczywista, możesz pominąć niektóre z tych kroków.
Mam z tym problem, ponieważ sugeruje, że pisanie nowego kodu jest cenne w ruchu niż posiadanie wysokiej jakości działającego programu. Nie ma nic złego w byciu jak najbardziej skutecznym w rozwiązywaniu problemów, ale program niekoniecznie poprawia się po prostu dodając do niego więcej kodu.
źródło
Podoba mi się większość innych odpowiedzi, ale oto kilka wskazówek, co robić PRZED zrobieniem tego. Zaoszczędzi ci czas na beaucoup.
Sprawdź, czy naprawdę występuje błąd. Błąd jest ZAWSZE różnicą między zachowaniem systemu a wymaganiami; tester powinien być w stanie wyrazić oczekiwane i rzeczywiste zachowanie. Jeśli nie jest w stanie zapewnić oczekiwanego zachowania, nie ma wymagań i nie ma błędu - tylko czyjaś opinia. Odeślij to.
Rozważ możliwość, że oczekiwane zachowanie jest nieprawidłowe. Może to wynikać z błędnej interpretacji wymogu. Może to być również spowodowane wadą samego wymagania (różnica między wymaganiem szczegółowym a wymaganiem biznesowym). Możesz je również odesłać.
Wyizoluj problem. Tylko doświadczenie nauczy Cię najszybszego sposobu, aby to zrobić - niektórzy ludzie mogą to zrobić prawie z jelitami. Jedno podstawowe podejście polega na różnicowaniu jednej rzeczy przy jednoczesnym utrzymaniu wszystkich pozostałych rzeczy na stałym poziomie (czy problem występuje w innych środowiskach? Z innymi przeglądarkami? W innym obszarze testowym? O różnych porach dnia?) Innym podejściem jest przyjrzenie się zrzutom stosów lub komunikaty o błędach - czasem po sposobie sformatowania można stwierdzić, który składnik systemu wyrzucił pierwotny błąd (np. jeśli jest w języku niemieckim, można winić osobę trzecią, z którą pracujesz w Berlinie).
Jeśli zawęziłeś go do dwóch współpracujących systemów, sprawdź komunikaty między tymi dwoma systemami za pomocą monitora ruchu lub plików dziennika i ustal, który system działa zgodnie ze specyfikacją, a który nie. Jeśli w scenariuszu występują więcej niż dwa systemy, możesz przeprowadzić sprawdzanie parami i pracować w dół „stosu” aplikacji.
Powodem, dla którego izolowanie problemu jest tak ważne, jest to, że przyczyną problemu nie może być defekt w kodzie, nad którym sprawujesz kontrolę (np. Systemy stron trzecich lub środowisko) i chcesz, aby ta strona przejęła jak najszybciej . Ma to na celu zarówno oszczędność pracy, jak i natychmiastowe rozpoczęcie pracy, aby rozdzielczość mogła zostać osiągnięta w jak najkrótszym czasie. Nie chcesz pracować nad problemem przez dziesięć dni, aby odkryć, że to naprawdę problem z czyjąś usługą internetową.
Jeśli ustalisz, że naprawdę istnieje usterka i naprawdę kontrolujesz kod, możesz dalej izolować problem, szukając ostatniej „znanej dobrej” wersji i sprawdzając dzienniki kontroli źródła pod kątem zmian, które mogły spowodować problem. To może zaoszczędzić dużo czasu.
Jeśli nie możesz tego zrozumieć na podstawie kontroli źródła, nadszedł czas, aby dołączyć swój debugger i przejść przez kod, aby to rozgryźć. Możliwe, że i tak masz całkiem dobre pojęcie o problemie.
Gdy wiesz, gdzie jest błąd i możesz wymyślić poprawkę, oto dobra procedura naprawy:
Napisz test jednostkowy, który odtwarza problem i kończy się niepowodzeniem.
Bez modyfikowania testu jednostkowego należy go przekazać (modyfikując kod aplikacji).
Zachowaj test jednostkowy w swoim zestawie testów, aby zapobiec / wykryć regresję.
źródło
Oto jak to robię:
źródło
Zakładając, że jesteś w środowisku produkcyjnym, oto, co musisz zrobić:
Prawidłowo opisz „błąd” i zidentyfikuj zdarzenia, które go powodują.
Sprawdź, czy „błąd” jest błędem kodu lub błędem specyfikacji. Na przykład wpisanie 1-literowej nazwy może być traktowane jako błąd w niektórych systemach, ale w innych systemach jest to akceptowalne zachowanie. Czasami użytkownik zgłasza błąd, który uważa za problem, ale oczekiwanie użytkownika na zachowanie systemu nie było częścią wymagań.
Jeśli udowodniono, że wystąpił błąd, a błąd wynika z kodu, możesz określić, które fragmenty kodu należy naprawić, aby zapobiec błędowi. Zbadaj również wpływ zachowania na bieżące dane i przyszłe operacje systemowe (analiza wpływu na kod i dane).
W tym momencie prawdopodobnie będziesz mieć szacunkową ilość zasobów, które zostaną zużyte na naprawę błędu. Możesz to naprawić od razu lub zaplanować poprawkę w nadchodzącym wydaniu oprogramowania. Zależy to również od tego, czy użytkownik końcowy jest skłonny zapłacić za poprawkę. Powinieneś także ocenić różne dostępne opcje, aby naprawić błąd. Może być więcej niż jeden sposób. Musisz wybrać podejście, które najlepiej pasuje do sytuacji.
Przeanalizuj przyczyny, które spowodowały pojawienie się tego błędu (wymagania, kodowanie, testowanie itp.). Wymuszaj procesy, które zapobiegną ponownemu wystąpieniu warunku.
Odpowiednio udokumentuj odcinek.
Wydaj poprawkę (lub nową wersję)
źródło