Często kuszące jest powiedzenie „och, wiem, co robi ten kawałek kodu, w porządku”. Nie rób tego Przetestuj każde założenie i przejrzyj wszystko dokładnie.
+1. Absolutnie. Przygotuj się na zaskoczenie tym, jak niektóre rzeczy, o których myślałeś, że wiesz, będą na ciebie grać.
sierpień
działa dla mnie :)
setzamora,
3
Debugowanie kodu drugiej osoby to ogromna strata czasu, zabójca produktywności, ale tak właśnie jest. Jedynym momentem, kiedy naprawienie błędów innych osób ma sens, jest odejście. Czego NIENAWIDZĘ NIENAWIDZĘ przechodzę przez jakiś obiektywnie kiepski kod przez starszego programistę, a następnie muszę zadać pytanie, aby zrobić postęp w odpowiednim czasie, i uzyskać wykład na temat doskonalenia moich umiejętności uczenia się istniejącej bazy kodu. W przeciwieństwie do studiowania natury matki rozwiązywanie wpadek spowodowanych przez człowieka nie jest zabawne. Przynajmniej dostaję odpowiedź. Odwrotna sytuacja nie nastąpi, ponieważ jestem po prostu lepszy i zostawiam mniej błędów.
Job
1
@Job: ... dobrze? Może chciałeś zostawić ten komentarz w poście? :)
Adam Lear
To! Głupio jest ślepo ufać niewielkiej części kodu, jeśli debugujesz dziwny problem, a kod wydaje się w porządku.
Dan
7
Testy przyrostowe .
Najpierw przejdź do kodu i przetestuj go od najmniejszego modułu, przesuwając się stopniowo w górę. W ten sposób nie musisz się zbytnio stresować, próbując dowiedzieć się, gdzie dokładnie może być problem.
Oznacza to również, że wpływa to na mniej kodu naraz, ponieważ poruszasz się stopniowo. Czasami miałem problemy, w których coś naprawiłem i które prowadzą do zepsucia wielu innych rzeczy. Uznam za to mojemu szefowi, ponieważ nauczył mnie tego, kiedy się bałam.
Dziel i rządź to dobre podejście. Spróbuj zidentyfikować jakieś widoczne dane wejściowe (dane wejściowe użytkownika / zdarzenie sieciowe ...) i dane wyjściowe (dziennik, dane wyjściowe dla użytkownika, wychodząca wiadomość sieciowa ...), między którymi występuje problem. Spróbuj umieścić odciski w znacznych fragmentach lub znaczących punktach między nimi i spróbuj zawęzić miejsce, w którym błąd znajduje się w kodzie.
Dziel i rządź mogą również działać bardzo dobrze w przypadku regresji w stosunku do kodu kontrolowanego przez wersję. Znajdź dwie kompilacje - jedną, w której działa zgodnie z oczekiwaniami, drugą z regresją. Zmniejsz lukę, dopóki nie pozostanie z grupą czeków jako potencjalnych podejrzanych.
Zamiast binarnego rozdrabniania błędów napisz testy w formie
Dany...
Kiedy...
Oczekiwać...
Aby zweryfikować, co naprawdę wiesz o prawdzie w działaniu aplikacji, w porównaniu z tym, co uważasz za prawdę.
Większość IDE ułatwia wyodrębnianie metod i generowanie kodów testowych xUnit. Skorzystaj z tego.
Dlaczego nie posypać debugowania? Ponieważ po zakończeniu prawdopodobnie będziesz musiał cofnąć dużą część tej pracy i usunąć sporą liczbę tych debugowania. Podczas pisania testów debugowanie pomoże w zapobieganiu i wykrywaniu przyszłych błędów.
Absolutne debugowanie samo w sobie jest sztuką, szczególnie debugowanie kodu innych osób.
Gratzy
2
Jak powiedzieli inni - niczego nie zakładaj. Jest to szczególnie prawdziwe, jeśli kod, który napisałeś. Podczas debugowania innych kodów istnieje większe prawdopodobieństwo spowolnienia, ponieważ kod jest dla Ciebie nowy lub nie ufasz programistom. Podczas debugowania własnego kodu zbyt łatwo jest założyć, że napisałeś go poprawnie, zwolnij!
Rzeczywisty proces debugowania:
Napisz testy jednostkowe, jeśli jeszcze nie istnieją.
Dodaj odpowiednie rejestrowanie, jeśli jeszcze nie istnieje.
Następnie użyj debugowania.
Dodawanie testów jednostkowych i rejestrowanie najpierw bardziej wydajne niż przy użyciu debugera w pierwszej kolejności. Dodatkową zaletą jest to, że testy jednostkowe pomagają nie wprowadzać przyszłych błędów, a rejestrowanie pomoże w debugowaniu sesji w przyszłości.
Zanim przejdziesz przez małą część kodu, sprawdź, czy możesz dokładnie określić wynik. To zwykle latać w obliczu niczego nie zakładaj (co głosowałem BTW), ale jak zdobędziesz doświadczenie, może pomóc zawęzić miejsce, w którym szukać.
Może się to wydawać trywialne, ale poznaj niuanse swojego debuggera i naucz się skrótów klawiszowych. Czasami debuggery mogą działać na tyle wolno, że twój umysł zastanawia się, kiedy przechodzisz. Jeśli potrafisz nadążyć za maszyną i nie krążysz po okolicy, to może ci pomóc.
Jeśli możesz zmodyfikować kod podczas debugowania:
rozważ zachowanie warunków wstępnych i końcowych. Czasami możesz zamiast tego przejść do kodu.
bo jeśli stwierdzenia ze skomplikowanymi wyrażeniami, zastanów się nad czymś (niektórzy mogą się na to skrzywić, ale to działa dla mnie)
lubić:
bool isLessThan5 = a < 5;
bool isGreaterThan10 = a > 10;
if ( isLessThan5 || isGreaterThan10 )
{
// more code here
}
zamiast:
if ( a < 5 || a > 10 )
{
// more code here
}
W przypadkach, w których nie możesz debugować wszystkiego, z jakiegokolwiek powodu, naucz się „gumowej kaczki” ze współpracownikiem. Czasami wyjaśnienie rzuca światło. (ok, może nie jest to dokładnie w temacie pytań, ale myślę, że jest wystarczająco blisko, aby uzasadnić wzmiankę)
Nazewnictwo warunków podrzędnych wymaga jeszcze jednego kroku, mianowicie refaktoryzacji nazw, gdy dowiesz się, do czego służy warunek. Może się okazać if (tooCloseToHydrant || overTheBrink) { , że później dowiesz się więcej.
1
Dwie rzeczy, oparte na spędzaniu większości ostatnich 22 lat na utrzymywaniu kodu napisanego przez innych ludzi.
Poznaj rodzaje błędów, które zwykle piszesz.
Na przykład jestem bardzo skrupulatnym programistą, więc kiedy mój kod się skompiluje, zwykle jest wolny od drobnych błędów. Więc moje błędy bywają dziwnymi, skomplikowanymi rzeczami, takimi jak zakleszczenia wątków. Z drugiej strony mam przyjaciela, który najczęściej pisze trywialne błędy - średniki na końcu C ++ dla pętli, więc następna linia jest wykonywana tylko raz, tego rodzaju rzeczy.
Nie zakładaj, że inni ludzie piszą te same rodzaje błędów co ty.
Nie wiem, ile razy marnowałem czas na wyciąganie dużych pistoletów do debugowania, zakładając, że błąd był moją bardzo subtelną dziwną rzeczą, tylko po to, aby mój przyjaciel spojrzał mi przez ramię i powiedział: „Czy zauważyłeś to dodatkowe średnik?" Po latach zacząłem od banalnego, nisko wiszącego owocu, patrząc na kodeks innych ludzi.
Czy formatujesz kod, aby zobaczyć, czy coś się porusza?
@ Thorbjørn: Jeśli przejęłem na własność kod, czasami robię to, aby poprawić czytelność, ale nie znaleźć literówek. Ciekawy pomysł!
Bob Murphy,
nie musisz tego robić, po prostu zobacz, co się stanie. Zdecydowanie mogę zalecić egzekwowanie polityki, która wymaga
@ Thorbjørn: Chciałbym to zrobić. Co polecasz jako „prettifier” kodu? Pracuję głównie na systemach Linux i Mac.
Bob Murphy
Korzystam z Eclipse dostępnego w obu miejscach, a edytor Java ma tak zwaną akcję Zapisz, w której możesz określić, co powinno się stać przy każdym zapisywaniu pliku. Tutaj jedną z opcji jest formatowanie źródła. Jesteśmy małym zespołem, więc nie zbadałem go więcej. Bardziej doświadczone zespoły pozwalają na przechwytywanie przed zatwierdzeniem w systemach kontroli źródła, co pozwala na odrzucenie zatwierdzenia źródła, jeśli jest niepoprawnie sformatowane. Bardzo wydajny.
1
Poznaj swoje narzędzia. Na przykład debugger programu Visual Studio ma niesamowitą funkcję o nazwie TracePoints, które są jak punkty przerwania, ale zamiast zatrzymywania kodu zamiast tego wstawia instrukcję śledzenia do wyniku debugowania.
Zdecydowanie zaleca się czytanie książek lub lekcje na temat korzystania z debuggera. Wziąłem kilka zajęć i przeczytałem kilka książek Johna Robbinsa, które miały duży wpływ na moją skuteczność jako debuggera.
Zrozum funkcjonalnie, co próbuje zrobić kod. Jeśli nie znasz pełnego obrazu (wszystkie przypadki testowe, które musi przejść ten kod), trudno jest poprawnie debugować bez wprowadzania nowych błędów
Napisz automatyczny test jednostkowy i inne typy testów integracyjnych i funkcjonalnych.
Im więcej masz zautomatyzowanych testów, tym mniej czasu potrzebujesz na debugger.
Dobry projekt - SOLIDNE zasady. Jeśli piszesz małe, skoncentrowane klasy i preferujesz kompozycję zamiast dziedziczenia, eliminując powielanie itp., Twój kod będzie zawsze łatwiejszy do debugowania.
Uważam, że dobrze zaprojektowany kod powoduje inny zestaw błędów, które nie są dobrze zaprojektowane. Ogólnie rzecz biorąc, dobrze zaprojektowany kod powoduje błędy, które są łatwiejsze do znalezienia, odtworzenia i naprawy.
Wyjątkiem (i zawsze istnieje) jest kod wielowątkowy :-)
Jeśli zawęziłeś go do małego regionu, ale nadal nie możesz wykryć błędu, wypróbuj opcję „zobacz kod + zestaw” swojego debuggera. Znając wystarczająco dużo ASM, aby powiedzieć „powinna istnieć tu gałąź” lub „dlaczego kopiuje tylko niskie słowo?” często wskazuje błąd kodowania.
Slajdy do książki są dostępne online, ale uważam, że sama książka jest łatwiejsza do odczytania.
Książka pomoże ci zacząć i sprawi, że będziesz bardziej naukowo zastanawiać się nad debugowaniem, ale nie zastąpi praktyki. Być może będziesz musiał pisać i debugować przez 10 lat, zanim zauważysz poprawę wydajności o rząd wielkości. Nadal pamiętam, jak rzuciłem szczękę na Sun, widząc starszych programistów, którzy programują dla Uniksa od 30 lat, w ciągu kilku minut znajdują niejasne błędy wielowątkowości lub równoległe błędy. Doświadczenie ma znaczenie!
Odpowiedzi:
Nic nie zakładaj
Często kuszące jest powiedzenie „och, wiem, co robi ten kawałek kodu, w porządku”. Nie rób tego Przetestuj każde założenie i przejrzyj wszystko dokładnie.
źródło
Testy przyrostowe .
Najpierw przejdź do kodu i przetestuj go od najmniejszego modułu, przesuwając się stopniowo w górę. W ten sposób nie musisz się zbytnio stresować, próbując dowiedzieć się, gdzie dokładnie może być problem.
Oznacza to również, że wpływa to na mniej kodu naraz, ponieważ poruszasz się stopniowo. Czasami miałem problemy, w których coś naprawiłem i które prowadzą do zepsucia wielu innych rzeczy. Uznam za to mojemu szefowi, ponieważ nauczył mnie tego, kiedy się bałam.
źródło
Dziel i rządź to dobre podejście. Spróbuj zidentyfikować jakieś widoczne dane wejściowe (dane wejściowe użytkownika / zdarzenie sieciowe ...) i dane wyjściowe (dziennik, dane wyjściowe dla użytkownika, wychodząca wiadomość sieciowa ...), między którymi występuje problem. Spróbuj umieścić odciski w znacznych fragmentach lub znaczących punktach między nimi i spróbuj zawęzić miejsce, w którym błąd znajduje się w kodzie.
Dziel i rządź mogą również działać bardzo dobrze w przypadku regresji w stosunku do kodu kontrolowanego przez wersję. Znajdź dwie kompilacje - jedną, w której działa zgodnie z oczekiwaniami, drugą z regresją. Zmniejsz lukę, dopóki nie pozostanie z grupą czeków jako potencjalnych podejrzanych.
źródło
Zamiast binarnego rozdrabniania błędów napisz testy w formie
Aby zweryfikować, co naprawdę wiesz o prawdzie w działaniu aplikacji, w porównaniu z tym, co uważasz za prawdę.
Większość IDE ułatwia wyodrębnianie metod i generowanie kodów testowych xUnit. Skorzystaj z tego.
Dlaczego nie posypać debugowania? Ponieważ po zakończeniu prawdopodobnie będziesz musiał cofnąć dużą część tej pracy i usunąć sporą liczbę tych debugowania. Podczas pisania testów debugowanie pomoże w zapobieganiu i wykrywaniu przyszłych błędów.
źródło
Kontynuuj debugowanie. Jeśli dużo debugujesz, poprawisz.
źródło
Jak powiedzieli inni - niczego nie zakładaj. Jest to szczególnie prawdziwe, jeśli kod, który napisałeś. Podczas debugowania innych kodów istnieje większe prawdopodobieństwo spowolnienia, ponieważ kod jest dla Ciebie nowy lub nie ufasz programistom. Podczas debugowania własnego kodu zbyt łatwo jest założyć, że napisałeś go poprawnie, zwolnij!
Rzeczywisty proces debugowania:
Dodawanie testów jednostkowych i rejestrowanie najpierw bardziej wydajne niż przy użyciu debugera w pierwszej kolejności. Dodatkową zaletą jest to, że testy jednostkowe pomagają nie wprowadzać przyszłych błędów, a rejestrowanie pomoże w debugowaniu sesji w przyszłości.
źródło
Zanim przejdziesz przez małą część kodu, sprawdź, czy możesz dokładnie określić wynik. To zwykle latać w obliczu niczego nie zakładaj (co głosowałem BTW), ale jak zdobędziesz doświadczenie, może pomóc zawęzić miejsce, w którym szukać.
Może się to wydawać trywialne, ale poznaj niuanse swojego debuggera i naucz się skrótów klawiszowych. Czasami debuggery mogą działać na tyle wolno, że twój umysł zastanawia się, kiedy przechodzisz. Jeśli potrafisz nadążyć za maszyną i nie krążysz po okolicy, to może ci pomóc.
Jeśli możesz zmodyfikować kod podczas debugowania:
lubić:
zamiast:
W przypadkach, w których nie możesz debugować wszystkiego, z jakiegokolwiek powodu, naucz się „gumowej kaczki” ze współpracownikiem. Czasami wyjaśnienie rzuca światło. (ok, może nie jest to dokładnie w temacie pytań, ale myślę, że jest wystarczająco blisko, aby uzasadnić wzmiankę)
źródło
if (tooCloseToHydrant || overTheBrink) {
, że później dowiesz się więcej.Dwie rzeczy, oparte na spędzaniu większości ostatnich 22 lat na utrzymywaniu kodu napisanego przez innych ludzi.
Poznaj rodzaje błędów, które zwykle piszesz.
Na przykład jestem bardzo skrupulatnym programistą, więc kiedy mój kod się skompiluje, zwykle jest wolny od drobnych błędów. Więc moje błędy bywają dziwnymi, skomplikowanymi rzeczami, takimi jak zakleszczenia wątków. Z drugiej strony mam przyjaciela, który najczęściej pisze trywialne błędy - średniki na końcu C ++ dla pętli, więc następna linia jest wykonywana tylko raz, tego rodzaju rzeczy.
Nie zakładaj, że inni ludzie piszą te same rodzaje błędów co ty.
Nie wiem, ile razy marnowałem czas na wyciąganie dużych pistoletów do debugowania, zakładając, że błąd był moją bardzo subtelną dziwną rzeczą, tylko po to, aby mój przyjaciel spojrzał mi przez ramię i powiedział: „Czy zauważyłeś to dodatkowe średnik?" Po latach zacząłem od banalnego, nisko wiszącego owocu, patrząc na kodeks innych ludzi.
źródło
Poznaj swoje narzędzia. Na przykład debugger programu Visual Studio ma niesamowitą funkcję o nazwie TracePoints, które są jak punkty przerwania, ale zamiast zatrzymywania kodu zamiast tego wstawia instrukcję śledzenia do wyniku debugowania.
Zdecydowanie zaleca się czytanie książek lub lekcje na temat korzystania z debuggera. Wziąłem kilka zajęć i przeczytałem kilka książek Johna Robbinsa, które miały duży wpływ na moją skuteczność jako debuggera.
źródło
Zrozum funkcjonalnie, co próbuje zrobić kod. Jeśli nie znasz pełnego obrazu (wszystkie przypadki testowe, które musi przejść ten kod), trudno jest poprawnie debugować bez wprowadzania nowych błędów
źródło
Napisz automatyczny test jednostkowy i inne typy testów integracyjnych i funkcjonalnych.
Im więcej masz zautomatyzowanych testów, tym mniej czasu potrzebujesz na debugger.
Dobry projekt - SOLIDNE zasady. Jeśli piszesz małe, skoncentrowane klasy i preferujesz kompozycję zamiast dziedziczenia, eliminując powielanie itp., Twój kod będzie zawsze łatwiejszy do debugowania.
Uważam, że dobrze zaprojektowany kod powoduje inny zestaw błędów, które nie są dobrze zaprojektowane. Ogólnie rzecz biorąc, dobrze zaprojektowany kod powoduje błędy, które są łatwiejsze do znalezienia, odtworzenia i naprawy.
Wyjątkiem (i zawsze istnieje) jest kod wielowątkowy :-)
źródło
Jeśli zawęziłeś go do małego regionu, ale nadal nie możesz wykryć błędu, wypróbuj opcję „zobacz kod + zestaw” swojego debuggera. Znając wystarczająco dużo ASM, aby powiedzieć „powinna istnieć tu gałąź” lub „dlaczego kopiuje tylko niskie słowo?” często wskazuje błąd kodowania.
źródło
Sprawdź bardzo cenną książkę Dlaczego programy nie działają: przewodnik po systematycznym debugowaniu autorstwa Andreasa Zellera. Wprowadzi Cię w wiele technik, teorii i narzędzi, z których niektóre znajdują się w czołówce badań.
Slajdy do książki są dostępne online, ale uważam, że sama książka jest łatwiejsza do odczytania.
Książka pomoże ci zacząć i sprawi, że będziesz bardziej naukowo zastanawiać się nad debugowaniem, ale nie zastąpi praktyki. Być może będziesz musiał pisać i debugować przez 10 lat, zanim zauważysz poprawę wydajności o rząd wielkości. Nadal pamiętam, jak rzuciłem szczękę na Sun, widząc starszych programistów, którzy programują dla Uniksa od 30 lat, w ciągu kilku minut znajdują niejasne błędy wielowątkowości lub równoległe błędy. Doświadczenie ma znaczenie!
źródło