Zamknięte . To pytanie musi być bardziej
skoncentrowane . Obecnie nie przyjmuje odpowiedzi.
Komentarze
Odpowiedź
Sposób myślenia i podejście do debugowania to prawdopodobnie najważniejsza część, ponieważ określa, jak skutecznie naprawisz błąd i czego się z niego nauczysz – jeśli cokolwiek.
Klasyki w tworzeniu oprogramowania, takie jak Pragmatic Programmer i Code Complete , w zasadzie przemawiają za tym samym podejściem: każdy błąd jest okazją do nauczenia się, prawie zawsze o sobie (ponieważ tylko początkujący winią najpierw kompilator / komputer).
Więc potraktuj to jako tajemnicę, która będzie interesująca do złamania. A rozwiązywanie tej tajemnicy powinno być wykonywane systematycznie, wyrażając nasze założenia (sobie lub innym), a następnie testując je, jeśli zajdzie taka potrzeba, jedno po drugim – używając każdego narzędzia, które mamy do dyspozycji, zwłaszcza debuggerów i automatycznych frameworków testowych. Następnie, gdy zagadka zostanie rozwiązana, możesz zrobić to 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 zbeształ swoich kolegów za używanie drugiego terminu, ponieważ to nieuczciwe, wspierając ideę, że zgubne i kapryśne wróżki umieszczały błędy w naszych programach, podczas gdy my nie patrzyliśmy, zamiast być tam z powodu naszego (niechlujnego) myślenia: http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html
Moglibyśmy na przykład zacząć od uporządkowania naszego języka już nie nazywanie błędu błędem, ale nazywanie go błędem. Jest o wiele bardziej uczciwy, ponieważ wprost obarcza winę tam, gdzie należy, a mianowicie. z programistą, który popełnił błąd. Animistyczna metafora błędu, który złośliwie wkradł się, gdy programista nie patrzył, jest intelektualnie nieuczciwa, ponieważ maskuje, że błąd jest dziełem programisty. Fajną rzeczą tej prostej zmiany słownictwa jest to, że ma tak głęboki efekt : podczas gdy wcześniej program z tylko jednym błędem był „prawie poprawny”, później program z błędem jest po prostu „zły” (ponieważ zawiera błąd).
Komentarze
Odpowiedź
-
Napisz testy. Testowanie jest nie tylko świetne w zapobieganiu błędom (z mojego doświadczenia, dobrze zrobione TDD eliminuje prawie wszystkie trywialne, głupie błędy), ale także bardzo pomaga w debugowaniu. Testowanie wymusza raczej modułowy projekt, co znacznie ułatwia wyodrębnienie i odtworzenie problemu. Ponadto kontrolujesz środowisko, więc niespodzianek będzie o wiele mniej. Co więcej, gdy otrzymasz przypadek testowy, który kończy się niepowodzeniem, możesz być dość pewny, że „wskazałeś prawdziwy powód takiego zachowania, które Ci przeszkadza.
-
Dowiedz się, jak korzystać z debugera. print
instrukcje mogą działać dość dobrze na pewnym poziomie, ale debugger w większości przypadków jest bardzo pomocny (i kiedyś wiesz, jak go używać, jest to o wiele wygodniejsze niż print
stwierdzenia).
-
Porozmawiaj o kimś o swoim problemie, nawet jeśli to tylko gumowa kaczuszka . Zmuszanie się do wyrażenia problemu, nad którym pracujesz, naprawdę czyni cuda.
-
Wyznacz sobie ograniczenie czasowe. Jeśli na przykład po 45 minutach czujesz, że nigdzie nie idziesz, po prostu przełącz się na jakiś czas do innych zadań. Miejmy nadzieję, że po powrocie do błędu zobaczysz inne możliwe rozwiązania, których wcześniej nie brałeś pod uwagę.
Komentarze
Odpowiedź
Większość pozostałych odpowiedzi mi się podoba, ale oto kilka wskazówek, co robić ZANIM to zrobisz. Pozwoli Ci zaoszczędzić czas.
-
Sprawdź, czy naprawdę jest błąd. Błąd jest ZAWSZE różnicą między zachowaniem systemu a wymaganiami; tester powinien być w stanie wyartykułować oczekiwane i rzeczywiste zachowanie. Jeśli nie jest w stanie zapewnić wsparcia dla oczekiwanego zachowania, nie ma wymagań i nie ma błędu – tylko czyjaś opinia. Odeślij ją.
-
Rozważ możliwość że oczekiwane zachowanie jest nieprawidłowe. Może to być spowodowane błędną interpretacją wymagania. Może to być również spowodowane defektem samego wymagania (różnica między wymaganiem szczegółowym a wymaganiem biznesowym). Te również możesz odesłać.
-
Wyizoluj problem. Tylko doświadczenie nauczy Cię najszybszego sposobu na zrobienie tego – niektórzy ludzie potrafią to prawie zrobić z przeczuciami. Jednym z podstawowych sposobów jest zmiana jednej rzeczy, utrzymanie wszystkich innych rzeczy na stałym poziomie (czy problem występuje w innych środowiskach? z innymi przeglądarkami? w innym regionie testowym? o różnych porach dnia?). Innym podejściem jest przyjrzenie się zrzutom stosu lub komunikatom o błędach – czasami można stwierdzić tak na marginesie jest to sformatowane, który komponent systemu wyrzucił oryginalny błąd (np. jeśli to jest po niemiecku to możesz bla ja ta osoba trzecia, z którą współpracujesz w Berlinie).
-
Jeśli zawęziłeś zakres do dwóch współpracujących systemów, sprawdzaj komunikaty między tymi dwoma systemami za pomocą monitora ruchu lub plików dziennika i określ, który system zachowuje się zgodnie ze specyfikacją, a który nie. Jeśli w scenariuszu są więcej niż dwa systemy, możesz przeprowadzić testy parami i przejść „w dół” stosu aplikacji.
-
Powód, dla którego wyodrębnienie problemu jest tak istotne polega na tym, że problem może nie wynikać z defektu kodu, nad którym masz kontrolę (np. systemów stron trzecich lub środowiska) i chcesz, aby strona ta przejęła ją tak szybko, jak to możliwe. Ma to na celu zarówno zaoszczędzenie pracy, jak i natychmiastowe wykonanie ich, aby rozdzielczość można było osiągnąć w jak najkrótszym czasie. Nie chcesz pracować nad problemem przez dziesięć dni, tylko po to, aby odkryć, że jest to naprawdę problem z usługą sieciową innej osoby.
-
Jeśli ustaliłeś, że rzeczywiście występuje usterka i rzeczywiście znajduje się ona w kodzie, który kontrolujesz, możesz dalej wyodrębnić problem, szukając ostatniej „znanej dobrej” kompilacji i sprawdzanie dzienników kontroli źródła pod kątem zmian, które mogły spowodować problem. Może to zaoszczędzić dużo czasu.
-
Jeśli nie możesz tego rozgryźć na podstawie kontroli źródła, teraz jest czas, aby dołączyć debuger i przejść przez kod, aby go zrozumieć jest już możliwe. Prawdopodobnie i tak masz już całkiem dobre pojęcie o problemie.
Gdy już wiesz, gdzie jest błąd i możesz wymyślić sposób jego rozwiązania, oto procedura naprawy:
-
Napisz test jednostkowy, który odtwarza problem i kończy się niepowodzeniem.
-
Bez modyfikowania testu jednostkowego, przechodzi (modyfikując kod aplikacji).
-
Zachowaj test jednostkowy w swoim zestawie testów, aby zapobiec / wykryć regresję.
Odpowiedź
Myślę, że odtworzenie błędu jest również ważne. Można wyświetlić listę wszystkich przypadków, w których wystąpił błąd, a następnie upewnić się, że poprawka błędu obejmuje wszystkie te przypadki.
Odpowiedź
Jest świetna książka, którą przeczytałem na ten temat, zatytułowana Dlaczego programy zawodzą , w której opisano różne strategie znajdowania błędów, od zastosowania metody naukowej do wyizolowania i rozwiązania problemu błąd, do debugowania delta. Inną interesującą częścią tej książki jest to, że usuwa termin „błąd”. Podejście Zellera jest następujące:
(1) Programista tworzy defekt w kodzie. (2) Defekt powoduje infekcję (3) Infekcja rozprzestrzenia się (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 znalazłem wiele błędów w naszej aplikacji, ale kierownictwo po prostu naciska nas dalej aby uzyskać nowe funkcje. Często słyszałem: „Sami znaleźliśmy ten błąd, a klient jeszcze go nie zauważył, więc po prostu zostaw go, dopóki to nie zrobi”. Myślę, że bycie reaktywnym w przeciwieństwie do proaktywnego w naprawianiu błędów jest bardzo złym pomysłem, ponieważ kiedy przychodzi czas na wprowadzenie poprawki, masz inne problemy, które wymagają rozwiązania, a zarządzanie większą liczbą funkcji chce jak najszybciej wyjść z domu, więc daj się złapać w błędnym kole, które może prowadzić do dużego stresu i wypalenia, a ostatecznie do systemu pozbawionego defektów.
Komunikacja jest również kolejnym czynnikiem w przypadku wykrycia błędów. Wysyłanie e-maila lub dokumentowanie go na narzędzie do śledzenia błędów jest w porządku i dobrze, ale z mojego własnego doświadczenia wynika, że inni programiści znajdują podobny błąd i zamiast ponownie używać rozwiązania, które umieściłeś w celu naprawienia kodu (ponieważ zapomnieli o wszystkim), dodają własne wersje, więc masz 5 różnych rozwiązań w swoim kodzie, przez co wygląda on na bardziej rozdęty i zagmatwany. Kiedy więc naprawisz błąd, upewnij się, że kilka osób przejrzyło poprawkę i przekaże opinię na wypadek, gdyby naprawili coś podobnego i znalazł dobrą strategię radzenia sobie z tym.
limist wspomniał o książce,
Pragmatyczny programista , który ma kilka interesujących materiałów na temat naprawiania błędów. Korzystając z przykładu, który podałem w poprzednim akapicie, „spojrzałbym na to: Software Entrophy , gdzie używana jest analogia do złamanej wdowy. pojawią się okna, Twój zespół może stać się apatyczny wobec ich naprawiania, chyba że przyjmiesz proaktywną postawę.
Komentarze
Błąd, błąd, problem, wada – jakkolwiek chcesz to nazwać, nie ma to większego znaczenia. Będę się trzymać problemu, ponieważ to „To jest to, do czego przywykłem”.
- Dowiedz się, jak postrzegany jest problem: przetłumacz z „s” klienta „Boba nadal nie ma w systemie” na „Kiedy próbuję utworzyć rekord użytkownika dla Roberta, kończy się niepowodzeniem i występuje wyjątek zduplikowanego klucza, chociaż Boba już tam nie ma.
- Dowiedz się, czy to naprawdę problem, czy po prostu nieporozumienie (rzeczywiście, Bob nie jest) t tam, nie ma nikogo o nazwisku bob, a wstawka powinna działać).
- Postaraj się uzyskać minimalne niezawodne kroki, które możesz wykonać, aby odtworzyć problem – coś w rodzaju „Biorąc pod uwagę system z rekordem użytkownika„ Bruce ”, kiedy wstawiany jest rekord użytkownika„ Bob ”, pojawia się wyjątek”
- To jest twój test – jeśli to możliwe, umieść go w automatycznym testową wiązkę przewodów, którą możesz wielokrotnie uruchamiać, będzie to nieocenione podczas debugowania. Możesz również uczynić go częścią swojego zestawu testów, aby upewnić się, że ten konkretny problem nie pojawi się później.
- Pobierz debuger i zacznij wstawiać punkty przerwania – ustal ścieżkę kodu podczas uruchamiania testu, i zidentyfikuj, co jest nie tak. Robiąc to, możesz również udoskonalić swój test, zawężając go tak, jak to tylko możliwe – najlepiej test jednostkowy.
- Napraw to – sprawdź, czy test przebiegł pomyślnie.
- Zweryfikuj pierwotny problem zgodnie z opisem klienta jest również naprawiony (bardzo ważne – być może po prostu rozwiązałeś podzbiór problemu). Sprawdź, czy nie wprowadziłeś regresji w innych aspektach programu.
Jeśli dobrze znasz kod lub jeśli problem lub poprawka są oczywiste, możesz pominąć niektóre z nich kroki.
Jak powinniśmy do tego podejść, aby jak najefektywniej wykorzystać nasz cenny czas i umożliwić nam spędzanie mniej czasu na szukaniu go, a więcej na kodowaniu ?
Nie zgadzam się z tym, ponieważ sugeruje, że pisanie nowego kodu jest bardziej wartościowe niż posiadanie dobrze działającego programu. Nie ma nic złego w byciu tak skutecznym, jak to tylko możliwe w rozwiązywaniu problemów, ale program niekoniecznie staje się lepszy, po prostu dodając do niego więcej kodu.
Komentarze