Jak spędzić mniej czasu na debugowaniu? [Zamknięte]

15

Zgodnie z zasadą Pareto programista spędza tylko 20% swojego czasu na naprawdę przydatnych rzeczach.

80% mojego czasu spędzam na debugowaniu, naprawianiu drobnych rzeczy, aby wszystko działało.

Czy istnieje sposób, aby spędzić mniej czasu na debugowaniu?

uhbif19
źródło
9
Nie jestem pewien, czy tak interpretowałbym zasadę Pareto.
c_maker
6
<meme> Spójrz na TDD. </meme>
StuperUser
1
Co właściwie robisz podczas debugowania?
3
musisz poświęcić więcej czasu na dbałość o szczegóły
1
Wiele czasu można zyskać, przeglądając kod od czasu do czasu. Jeszcze lepiej, pisz komentarze, gdy poczujesz potrzebę, dzięki czemu łatwiej będzie później zauważyć błędy.
Joey Adams,

Odpowiedzi:

5

Kod w języku Agda lub Coq . Po skompilowaniu kod będzie działał. Jeśli jest to zbyt hardkorowe, wybierz język ze słabszym systemem typowania, np. Haskell lub F #.

Ale w większości przypadków będziesz o wiele bardziej produktywny, spędzając 20% czasu na kodowaniu i 80% na testowaniu i debugowaniu. 100% tygodnia to znacznie więcej niż 20% godziny. Jeśli potrzebujesz debugowania, to debugowanie nie jest stratą czasu i nie powinieneś przejmować się „poprawianiem” tego odsetka.

Logika SK
źródło
1
JUst, ponieważ coś działa, nie oznacza, że ​​nie ma błędów. Błędy są często wynikiem nieprawidłowego działania kodu.
HLGEM,
3
@HLGEM, przed przegłosowaniem powinieneś przeczytać więcej o Agdzie i Coq. Jeśli kod kompiluje, jest gwarantowany i sprawdzony zrobić dokładnie to, co mówi jego specyfikacja. Oczywiście może również występować błąd w specyfikacji, ale nie nazwałbym naprawiania tego rodzaju problemów „debugowaniem”.
SK-logic,
2
@HLGEM, twoje pojęcie „debugowania” jest dość kreatywne i dalekie od głównego nurtu. Poza tym przy takim podejściu proporcja między kodowaniem a „debugowaniem” byłaby daleka od 20/80. Więc proszę, wyjaśnij swoją opinię.
SK-logic
1
@HLGEM, nie było go na liście wymagań OP. Nic nie wiadomo, ilu jest programistów, kto tu rządzi itp. Jedyne pytanie brzmiało: „jak zmierzyć współczynnik 20/80”, a użycie statycznie zweryfikowanego języka jest zdecydowanie najbardziej oczywistą odpowiedzią na to pytanie. Ale, jak już powiedziałem, ta odpowiedź ma zastosowanie tylko w bardzo rzadkich przypadkach, a ogólnie przestrzeganie zasady 20/80 jest znacznie lepszą opcją.
SK-logic
1
@ uhbif19 Knuth miał na myśli humor. Wiesz, co naprawdę miał na myśli?
Phil
44

Testów jednostkowych.

Po rozpoczęciu stosowania testów jednostkowych okazało się, że napisany przeze mnie kod ma lepszą strukturę. Łatwiej było wtedy uniknąć błędów i wykryć je. Spędziłem mniej czasu na debugowaniu, ale więcej na pisaniu testu jednostkowego.

Myślę również, że czas zainwestowany w testy jednostkowe zapewnia lepszy zwrot z inwestycji niż debugowanie. Po sesji debugowania właśnie poprawiłem kod. Ten sam błąd może pojawić się kilka tygodni później i muszę ponownie debugować. Jeśli napiszę test jednostkowy, błąd jest udokumentowany jako test jednostkowy, a później działa jako test regresji. Jeśli błąd pojawi się ponownie, testy jednostkowe mi to ujawniają.

Theo Lenndorff
źródło
Korzystam z testów jednostkowych i całkowicie się z tobą zgadzam. Ale nie mogę wszystkiego przetestować.
uhbif19
5
Oczywiście że możesz. Cóż, nie wszystko , ale wszystko, co ważne. Używając interfejsów, wstrzykiwania zależności, fałszowania i kpienia z klas / metod będziesz w stanie pisać testy dla prawie całego kodu.
Fredrik
8
@Fredrik, nie można poprawnie przetestować jednostki nawet a + bfragmentu kodu (chyba że test obejmuje cały zakres typu danych arytmetycznych).
SK-logic
„Po sesji debugowania właśnie poprawiłem kod”. - Naprawdę? Myślę, że po sesji debugowania właśnie wprowadziłem więcej błędów - po prostu nie wiem, gdzie one są.
B Siedem
35
  • Testowanie jednostkowe, abyś wiedział, czy Twój kod działa w pierwszej kolejności.
  • Przynajmniej trochę wstępnego projektu, abyś wiedział, co kodujesz.
  • Recenzje kodu, ponieważ dwie głowy są lepsze niż jedna, a czworo oczu jest lepsze niż dwie. Nie wspominając już o tym, że nawet próba wyjaśnienia twojego kodu komuś innemu ujawnia wiele problemów.
  • Kontrola wersji, dzięki czemu można szybko ustalić, które zmiany mogły spowodować błąd.
  • Refaktoryzacja, aby kod nie zamienił się w straszny niezrozumiały bałagan.
  • Przeczytaj „Czysty kod” Roberta C. Martina i zrób to, co ci mówi. Będziesz zaskoczony wynikami.
Dima
źródło
5
Dokładnie - żadna pojedyncza praktyka (np. Testy jednostkowe) nie da rzędu poprawy wielkości, ale kombinacja praktyk może. Innymi słowy ... nie ma srebrnej kuli.
Michael
Dodałbym TDD (tam, gdzie to możliwe).
Tom
1
Najpierw posortowałbym czysty kod i refaktoryzację. Testy jednostkowe dobrze sprawdzają się we wczesnym wykrywaniu i usuwaniu błędów, ale nie zmniejszają ich liczby (nieco skracają czas, ponieważ będziesz naprawiać błędy, gdy wszystko będzie świeże w pamięci, ale nadal). Z drugiej strony napisanie czystego kodu zmniejsza faktyczną liczbę błędów.
Jan Hudec
1
@ JanHudec Refaktoryzacja + czysty kod + testy = TDD
Tom
1
@Tom: Tak, ale różne jego części mają różne efekty. Nauka pisania czystego kodu pomoże ci skrócić czas debugowania bez żadnych testów. Dostępne są testy, dzięki którym można przetestować moduły przed ich użyciem, a także zweryfikować, czy nie zmodyfikowano zachowania podczas refaktoryzacji - co jest potrzebne do wyczyszczenia starego bałaganu.
Jan Hudec
8

Mamy nadzieję, że testy jednostkowe pomogą, jeśli wprowadzisz błędy, które złamią przed kodem produkcyjnym - dobrze napisane testy jednostkowe również pokażą dokładnie, co się zepsuło.

To da ci większość możliwości, ale dla 99,999% projektów nadal będziesz musiał debugować różne rzeczy od czasu. Najlepszą rzeczą, jaką mogę tutaj zrobić, jest zrobienie 4 rzeczy:

  1. wszędzie tam, gdzie to możliwe, używaj niezmiennych typów - jeśli coś ma niewłaściwą wartość, będziesz wiedział dokładnie, gdzie natychmiast szukać (gdzie jest budowany).
  2. wymuszaj niezmienniki w kodzie - jeśli wiesz, że wartość jest zdecydowanie niedozwolona, ​​sprawdź ją i wyrzuć wyjątek w punktach wejścia do metod i konstruktorów. Jeśli połączysz to z niezmiennymi typami, możesz także zacząć przyjmować pewne założenia dotyczące tego, co jest ważne, czy nie.
  3. upewnij się, że masz odpowiednie logowanie - zdobądź je wcześnie, a dostarczy Ci wielu ważnych informacji o tym, kiedy coś pójdzie nie tak. AOP działa tutaj naprawdę dobrze. Logowanie jako refleksja jest zwykle trochę banalne - zdobądź je wcześnie w ramach konfiguracji projektu.
  4. jeśli twoja baza kodu jest wystarczająco duża / złożona, unikaj używania prymitywów - np. stosuj typ „Age” zamiast tylko int. Na początku będzie to trochę bezcelowe, ale możliwość natychmiastowego wyśledzenia wszystkich zastosowań czegoś to ogromna wygrana debugowania.
FinnNk
źródło
6

Moje 80% to debugowanie. Naprawiam proste błędy i staram się, aby wszystko działało.

Zacznij od napisania testów jednostkowych i postaraj się uzyskać jak najwyższy zasięg. Ktoś wspomniał o TDD, ale wybrałbym BDD .

Na koniec najprawdopodobniej wydasz 80% na debugowanie złożonych błędów.

BЈовић
źródło
6

Jak spędzić mniej czasu na debugowaniu? Napisz mniej kodu.

Poważnie, dopóki piszesz kod, musisz go debugować. Testy jednostkowe itp. Ogromnie pomagają, ale nie sądzę, że kiedykolwiek całkowicie zlikwidujesz ich potrzebę.

Daniel Roseman
źródło
4

Zrozum co i dlaczego zanim zaczniesz pisać kod. Następnie konsekwentnie stosuj metodologię. Która metodologia, którą wybierzesz, nie jest tak ważna, jak konsekwentne wielokrotne stosowanie tej metodologii. Jeśli chcesz konsekwentnie dobrych wyników, musisz konsekwentnie wykonywać dobrą pracę, a posiadanie „metody szaleństwa” jest pierwszym krokiem do uzyskania tych wyników. Po zidentyfikowaniu problemów możesz dostosować swoją metodologię do potrzeb, a wraz z upływem czasu usprawnisz proces programowania i, mam nadzieję, mniej błędów i więcej nowych, znaczących zmian.

cdkMoose
źródło
3

Dokładnie przeczytaj swój kod, zanim go skompilujesz. Bardzo uważna lektura pod kątem składni i funkcjonalności. Może być zaskakująco pouczający, a także dobrym wskaźnikiem, jeśli część kodu jest zbyt skomplikowana.

zaraz
źródło
W pełni się zgadzam. Czytanie kodu natychmiast po napisaniu może bardzo szybko ujawnić pewne oczywiste błędy, takie jak literówki kopiuj i wklej (które czasem mogą być trudne do znalezienia).
jirkamat
3

Większość odpowiedzi wydaje się koncentrować na tym, jak zmniejszyć liczbę problemów, które musisz debugować, a to jest cenne. Jednak debugowanie zawsze będzie konieczne, dlatego warto przyjrzeć się sposobom przyspieszenia debugowania.

  • Wiedzieć, jak korzystać z oprogramowania do kontroli wersji.

    • Korzystanie z gałęzi pomoże ci oddzielić obszary rozwoju i będziesz mógł zobaczyć, który obszar rozwoju zawiera błąd, a który nie.
    • Dowiedz się, jak używać bisekcji w swoim VCS, Git ma to wbudowane. Jeśli używasz innego VCS, który nie ma wbudowanej bisekcji, poszukaj narzędzia, które działa jak git bisect, ale dla twojego VCS (wiem, że istnieje dla SVN i nie powinno być zbyt trudne do stworzenia dla innych VCS). Pomoże ci to zawęzić do zmiany kodu, która wprowadziła błąd, co pomoże w określeniu, gdzie należy wskazać swój debugger. Ten proces bisekcji będzie szybszy, jeśli przeprowadzisz testy pod kątem błędu, a wiedza o tym, który zatwierdzenie zawiera obrażającą zmianę, będzie bardziej przydatna, jeśli będziesz ćwiczyć atomowe zmiany.
  • Popraw zrozumienie używanego języka programowania.

    • Czytaj książki, blogi i kod o języku programowania.
    • Za każdym razem, gdy naprawisz błąd, upewnij się, że dokładnie rozumiesz, dlaczego kod nie działał i dlaczego działa poprawka. Z biegiem czasu nauczysz się wielu gotch w swoim języku, co pomoże ci uniknąć ich problemów i dostrzec ich objawy w razie ponownego wystąpienia.
  • Bądź logiczny

    • Nie zmieniaj więcej niż jednej rzeczy na raz, w przeciwnym razie, jeśli zachowanie się zmieni, nie będziesz wiedział, która zmiana spowodowała zmianę zachowania.
    • Sprawdź swoje założenia.
Stephen Paulger
źródło
2

Dodanie do komentarzy do testów jednostkowych, ale jest to naprawdę dobre, jeśli twój kod został rozdzielony, aby go obsługiwać (np. MVC). Jeśli nie możesz zaimplementować MVC (lub podobnego) (starszego projektu), testy jednostkowe w ogóle nie działają dla twojego interfejsu użytkownika. Następnie dodałbym automatyczne testowanie interfejsu użytkownika (Microsoft Coded UI Tests, WaitN), ponieważ zmniejszy to liczbę błędów w tej części kodu.

Poleciłbym również uruchomienie narzędzi do analizy statycznej (np. FxCop / Microsoft Code Analysis, Resharper, JustCode dla świata MS). Mogą one znaleźć wszelkiego rodzaju typowe problemy z kodowaniem, które mogą zredukować głupie zadania debugowania i skupić się bardziej na logice biznesowej debugowania.

Scott Wylie
źródło
2

Spraw, aby działał, a następnie spraw, aby był szybki, a następnie uczyń go ładnym. Większość błędów pochodzi z wczesnych optymalizacji lub przefaktoryzowania wierszy kodu, które były całkowicie w porządku. Jeśli wybierasz orientację obiektową, nie powtarzaj się, zachowaj prostotę i zawsze sprawdzaj rozsądność zakresów wartości, szczególnie jeśli twoje metody będą nadal działać z ograniczeniami. Nie pomoże ci popełnić mniej błędów, ale prawdopodobnie pomoże ci szybciej wykryć błędy, a zatem debugowanie zajmuje mniej czasu.

kibotu
źródło
1
Twoje stwierdzenie „Większość błędów pochodzi z ...” brzmi dobrze, ale czy masz na to dowody? Myślę, że brzmiałoby to równie przekonująco, gdybym powiedział: „większość błędów wynika ze źle określonych wymagań lub braku jasnego projektu”. Powinieneś dodać link lub cytat do badań, które potwierdzają twoje oświadczenie.
Caleb
2

Ostatnio zastanawiałem się nad tym problemem - najprostszą odpowiedzią jest przeczytanie „Projektu rzeczy codziennych” Dona Normana; Napisz kod tak, jakbyś zaprojektował produkt.

Parafrazując, dobry projekt minimalizuje błąd. Oznacza to kilka rzeczy, z których większość już robisz (chociaż możesz nie wiedzieć dokładnie dlaczego ).

-Name działa intuicyjnie. Jest to formalnie znane jako afordancja. Oznacza to, że przycisk wymaga naciśnięcia, dźwignia umożliwia przełączenie, uchwyt do pociągnięcia itp.

- Utrudnij pisanie złego kodu. Sprawdź, czy dane wejściowe są błędne i wyrzucaj błędy wcześniej niż później, w razie potrzeby używaj aplikacji węgierskiej itp. Są to tak zwane funkcje blokady.

-Użyj abstrakcji tam, gdzie jest to właściwe. Pamięć krótkotrwała jest słaba.

-Dokumentacja jest oczywiście ważna, ale jest najmniej skuteczna w zapewnieniu prawidłowego użycia kodu. Krótko mówiąc, dobrze zaprojektowane produkty nie wymagają żadnej dokumentacji. (Najbardziej oczywistym sposobem na to jest spojrzenie na złe przykłady: mianowicie drzwi z uchwytami, które należy popchnąć).

- Testy jednostkowe. Nie zapobiegają one tak naprawdę błędom, ale pokazują, gdzie są błędy i zapewniają zdrowie psychiczne.

Jestem pewien, że brakuje mi wielu innych zasad, ale najważniejsze jest, aby przeczytać o projektowaniu pod kątem błędów.

Ceasar Bautista
źródło
1

Najlepszym sposobem na zmniejszenie debugowania, IMO, jest koncentracja i spowolnienie podczas kodowania. To zmusza cię do zobaczenia błędów, które mogłeś popełnić!

Dynamiczny
źródło
1

Chociaż całkowicie popieram wyżej opisane testy jednostkowe, TDD lub BDD będą miały wielką wartość, ponieważ musisz najpierw pomyśleć o problemie i rozwiązaniu.

Ale osobiście dla mnie, poświęcenie kilku minut na spokojne siedzenie i zastanowienie się nad problemem oraz jak podejść do niego, a także za i przeciw za każdym podejściem, zastanawia się nad moją jakością kodu i pomaga oczyścić umysł z bałaganu.

Czasami szybkie bazgroły na kartce papieru pozwalają zobaczyć większe połączone elementy układanki.

Piszę najgorszy kod, kiedy po raz pierwszy nurkuję w głowie i walę w klawiaturę. Trochę myśli i kontemplacji robi świat różnic.

PS. Mam na myśli 5, może dziesięć minut, a nie godziny pisania wielkiej specyfikacji.

SetiSeeker
źródło
1

Kilka dobrych odpowiedzi już, po prostu trochę więcej jedzenia, ale oprócz tego, co powiedzieli inni.

Ucz się na swoich błędach. Nie rób ciągle tych samych.

Pamiętaj, aby podczas programowania uwzględnić przypadki skrajne - są to miejsca, w których często występują błędy.

Zwróć uwagę na wymaganie. Nawet jeśli działa, ale nie spełnia wymagań określonych, jest to błąd.

Dzienniki wyjątków mogą być prawdziwą pomocą, gdy coś pójdzie nie tak za sześć miesięcy. Miej zwyczaj rejestrowania wyjątków.

HLGEM
źródło
0

Moje dwie najważniejsze myśli to: 1) Napisz lepszy kod, który zawiedzie, gdy zrobisz coś nieoczekiwanego 2) Stań się lepszy w debugowaniu

Mój kod jest zaśmiecony

if(value!=null) throw new NotImplementedException();
if(obj.v>0) throw new Exception(); //sometimes i dont write NotImplementedException
if(value=="thing") throw ...;

Za każdym razem, gdy wykonuję ten fragment kodu, zgłaszany jest wyjątek, który powoduje zatrzymanie debugera, co pozwala mi kodować nowe funkcje lub unikać warunków, a następnie mylę się co do tego, co się dzieje / mam błąd

Aby lepiej debugować bałagan ze stosem wywołań, punktami przerwania (z warunkami), bezpośrednim oknem (znanym również jako okno zachęty lub repl), zmiennymi „obserwuj” i cokolwiek innego.

użytkownik2528
źródło