Wczoraj wypuściłem wersję 1.0 projektu internetowego, nad którym spędziłem około 6 tygodni (to znaczy włączanie i wyłączanie). Nie zapisałem dokładnie mojego czasu, ale zgodnie z moimi doświadczeniami oszacowałbym, że z całego czasu spędzonego na programowaniu połowa z nich była poświęcona na debugowanie. Szacuję, że jest to około 15-20 godzin spędzonych na debugowaniu, co jest dla mnie cennym czasem, który lepiej byłoby poświęcić na napisanie nowego kodu lub ukończenie projektu wcześniej. Szczególnie nie pomaga to, że za 5 tygodni będę studentem pierwszego roku.
Chodzi mi o to, że źle się czuję, spędzając cały czas na debugowaniu. Cały czas spędzony na debugowaniu uświadamia mi, że popełniłem kilka głupich błędów podczas opracowywania mojego projektu, które kosztowały mnie cholernie dużo czasu.
Jak mogę temu zapobiec w przyszłości? Nie chcę spędzać 50% czasu na debugowaniu, wolę spędzić 10% na debugowaniu, a reszta na pisaniu nowego kodu. Jakie techniki mogę spróbować pomóc w osiągnięciu tego celu?
Odpowiedzi:
Prosisz o Świętego Graala inżynierii oprogramowania i nikt nie ma jeszcze „odpowiedzi” na to pytanie.
Istotne jest, aby śledzić rodzaje popełnianych błędów, a następnie analizować je, aby ustalić, czy występuje wspólny trend. Analiza przyczyn pierwotnych to formalna nazwa tego rodzaju introspekcji, a na jej temat znajduje się mnóstwo materiałów w Internecie.
Specjaliści używają systemu śledzenia błędów, aby mogli (1) wiedzieć, co należy naprawić, ale także (2) analizować, co trzeba naprawić po fakcie. Nie musisz być tak formalny - po prostu zapisywanie notatników w notatniku może być dla Ciebie w porządku.
Wady etapu projektowania
Jeśli okaże się, że większość błędów wynika z niezrozumienia opisu problemu lub jeśli ciągle znajdujesz, że wybrałeś niewłaściwy algorytm lub ścieżkę rozwiązywania problemów, masz problemy na etapie projektowania.
Opłaca się poświęcić więcej czasu na początku projektu i napisać dokładnie, co należy zrobić i jak to zrobić. Dokładnie zapoznaj się z tą pracą i wróć do pierwotnego problemu i ustal, czy naprawdę rozwiązujesz go we właściwy sposób. Dodatkowa godzina lub trzy na starcie mogą zaoszczędzić wiele godzin na drodze.
Błędy kodowania
Jeśli Twój projekt jest solidny, ale ciągle walczysz z językiem, w którym kodujesz, zdobądź narzędzia, które przeanalizują Twój kod i ostrzeżą cię wcześnie i często, że popełniasz błędy.
Jeśli programujesz w języku C, włącz wszystkie ostrzeżenia kompilatora, użyj narzędzia sprawdzania semantycznego
lint
i użyj narzędzia, na przykład,valgrind
aby wychwycić typowe problemy związane z pamięcią dynamiczną.Jeśli programowania Perl, włącz
strict
iwarnings
i Uważajcie, co mówi.Bez względu na to, jakiego języka używasz, prawdopodobnie istnieje wiele narzędzi, które pomagają w wykrywaniu typowych błędów na długo przed osiągnięciem etapu debugowania.
Wady etapu integracji
Gdy rozwijasz swój kod zgodnie z dobrymi praktykami modułowości, musisz zacząć sklejać poszczególne elementy. Na przykład różne sekcje kodu mogą mieć związek z wprowadzaniem danych przez użytkownika, interakcją z bazą danych, wyświetlaniem danych, algorytmami / logiką, a każda z nich jest zbudowana względnie niezależnie od siebie (to znaczy koncentrujesz się na danej sekcji zamiast martwić się integracją ze wszystkim innym).
Tutaj bardzo przydaje się rozwój oparty na testach (TDD). Każdy moduł twojego kodu może mieć testy, które sprawdzą, czy działają zgodnie z tym, jak zostały zaprojektowane. Testy te powinny być napisane jako pierwsze lub na bardzo wczesnym etapie procesu, abyś mógł mieć zestaw „pomocników”, aby zachować uczciwość. Kiedy zaczniesz wszystko działać razem i okaże się, że musisz zmienić sposób, w jaki to lub to jest implementowane lub współdziała z innym podsystemem, możesz cofnąć się w swoich testach, aby upewnić się, że to, co zrobiłeś, aby zrobić wszystko działa razem, nie psuje poprawności kodu.
I tak dalej...
Wybierz kilka książek na temat inżynierii oprogramowania i praktycznych technik kodowania, a nauczysz się wielu różnych sposobów zmniejszania chaosu i zwiększenia niezawodności programowania. Przekonasz się również, że zwykłe, stare doświadczenie - zdobycie dyplomu ze szkoły trudnych uderzeń - również sprawi, że będziesz w formie.
Prawie wszystko sprowadza się do tego, że trochę czasu i pracy z góry opłaca się w postaci ogromnych dywidend później w procesie rozwoju / wydania.
Fakt, że zauważyłeś te problemy na wczesnym etapie kariery, dobrze świadczy o twojej przyszłości i życzę powodzenia.
źródło
Napisz testy jednostkowe
Pisanie testów jednostkowych dla twojego kodu zmusi cię do myślenia o swojej architekturze i zachęci do pisania kodu w małych, dokładnie kontrolowanych, testowalnych częściach. To znacznie zmniejszy wysiłek związany z debugowaniem, a niewielka ilość wykonywanego debugowania będzie ograniczona do małych, ściśle skoncentrowanych fragmentów kodu.
Ponadto pisane testy „zakrywają” Twój kod; będziesz w stanie stwierdzić, kiedy zmiana dokonana w kodzie coś zepsuje, ponieważ co najmniej jeden z istniejących testów zakończy się niepowodzeniem. Zmniejsza to ogólną złożoność procesu debugowania i zwiększa pewność, że kod działa.
Problem polega na tym, że Twój czas poświęcony na debugowanie jest teraz poświęcony na pisanie testów. Ale musisz je napisać tylko raz, a po napisaniu można je wykonać tyle razy, ile to konieczne.
źródło
50% za debugowanie (w szerokim znaczeniu) nie jest wcale takie złe. Ludzie zwykle poświęcają znacznie więcej czasu na projektowanie, testowanie, naprawianie błędów, refaktoryzację i pisanie testów jednostkowych, niż na pisanie rzeczywistego kodu. To część pracy.
I szczerze mówiąc, znacznie gorzej jest w programowaniu konserwacji - dość często spędziłem godzinę, zastanawiając się, co dokładnie poszło nie tak, potem pięć minut, pisząc kod, aby to naprawić, a następnie pół godziny, testując wszystko. To nieco ponad 5% kodowania w porównaniu z prawie 95% niekodowaniem.
Istnieje jednak kilka rzeczy, które możesz zrobić, aby skrócić czas debugowania:
źródło
Więcej planowania
Nieuniknione jest, że spędzasz sporo czasu na debugowaniu, 10% to dość ambitny cel. Chociaż jednym z najlepszych sposobów na ograniczenie czasu poświęcanego na debugowanie i rozwijanie jest spędzanie więcej czasu w fazie planowania.
Może to być zakres od diagramów po pseudo-kod na podkładce planowania. Tak czy inaczej, będziesz miał więcej czasu na zastanawianie się nad tym, co planujesz robić, raczej popełniając te błędy podczas programowania.
źródło
Pracuj ostrożniej
Jest to programowy odpowiednik „zmierzyć dwa razy raz”:
To powiedziawszy, nic nie wyeliminuje całkowicie wad. Musisz zaakceptować to jako fakt z życia. Biorąc pod uwagę ten plan faktyczny dotyczący wad, np. Test jednostkowy. Nie należy również rozumieć tego jako „brać na zawsze” (inaczej analiza-paraliż). Chodzi o znalezienie równowagi.
źródło
Inne odpowiedzi obejmowały już większość tego, co chcę powiedzieć, ale i tak chcę wyrazić moją (brutalnie szczerą) opinię:
Zasadniczo, w przypadku nie trywialnych prac programowych, spodziewaj się, że zdecydowana większość czasu poświęcisz na konserwację i debugowanie. Jeśli pracujesz na dojrzałym, produkcyjnym systemie oprogramowania i spędzasz mniej niż 80-90% czasu na konserwacji i debugowaniu, masz się dobrze!
Oczywiście różnica między „konserwacją” a „debugowaniem” jest nieco subiektywna. Czy uważasz, że „błędy” stanowią problemy z kodem, który został znaleziony po jego wydaniu, a użytkownicy narzekali na nie? Czy może każda drobna rzecz, która nie działa poprawnie w kodzie po dodaniu czegoś (znajdowanego we własnych fazach testowych przed wydaniem)? W nietrywialnym systemie oprogramowania (w zależności od wzorców użytkowania) jeden może być znacznie większy od drugiego. Ale w każdym razie tego właśnie wymaga programowanie czegoś większego niż zabawkowy program „Witaj, świecie” - mnóstwo konserwacji i debugowania. Niektórzy nawet mówią coś w stylu „ wszystko po pierwszym wierszu kodu powinno być w trybie konserwacji”,
TL; DR: Po prostu wydaje mi się, że możesz mieć nieco nierealny obraz tego, na czym polega programowanie nietrywialnych systemów oprogramowania. Ogromna większość wysiłków polega na dopracowywaniu, konserwacji, refaktoryzacji, naprawianiu błędów i ogólnie robieniu rzeczy, które byłyby objęte „debugowaniem” (konserwacją) - przynajmniej w bardzo ogólnym znaczeniu - w przeciwieństwie do wykonywania zupełnie nowej pracy, pisząc nowy kod.
źródło
Trudno podać konkretne techniki bez konkretnych szczegółów na temat tego, co robisz i jakich technologii używasz. Ale nawet naprawdę dobrzy koderzy spędzają dużo czasu na testowaniu i debugowaniu.
Dużo pisania dobrego kodu bez wielu błędów to doświadczenie. Popełniasz błędy, potem je naprawiasz, a następnie pamiętasz, jakie były błędy i co musiałeś zrobić, aby zrobić je dobrze, i nie popełniasz tego samego błędu następnym razem. A jeśli jeszcze nie jesteś na studiach i już zaczynasz poważnie zastanawiać się nad sposobami popełniania mniej błędów, powiedziałbym, że zdecydowanie wyprzedzasz tę grę.
źródło
CIĄGŁA INTEGRACJA (CI) jest odpowiedzią.
Ciągła integracja = system zarządzania konfiguracją (tj. Git, Mercurial, SVN itp.) + Narzędzie CI + testy jednostkowe + testy dymu
Ta formuła powinna zachęcić cię do przeczytania więcej na temat ciągłej integracji (CI). Poniżej znajdują się niektóre zasoby w tym obszarze:
źródło
Naprawdę, aby zmniejszyć debugowanie, możesz załadować go od przodu, planując głębiej. Nie byłeś jeszcze na studiach? Myślę, że na lekcjach w środkowej i późnej szkole średniej zobaczysz szczegóły cyklu życia oprogramowania, które bardzo dobrze rzucą światło na twoje szaleństwa.
Kiedy próbuję wyjaśnić moim pracodawcom, najlepszym sposobem na ograniczenie konserwacji kodu i wsparcia technicznego jest poświęcenie czasu na kompleksowe planowanie kodu z wyprzedzeniem.
źródło
Rozwój oparty na testach może pomóc w skróceniu czasu debugowania poprzez:
Nawet jeśli korzystasz z TDD, nadal będziesz miał czas, kiedy będziesz potrzebował użyć debuggera. Kiedy tak się stanie, powinieneś spróbować napisać test jednostkowy, aby odtworzyć scenariusz, który spowodował sesję debugowania. Zapewni to, że jeśli problem ten wystąpi ponownie, zostanie szybko złapany, gdy test się nie powiedzie, a test będzie działał jako znacznik obszaru kodu, który spowodował problem - zmniejszając potrzebę debugowania.
źródło
Debugowanie jest nieuniknione w programowaniu, ale kluczem jest to, czy kod jest łatwy do debugowania, czy nie? Jeśli potrzebujesz poświęcić wiele godzin na debugowanie czegoś prostego, to musi być coś naprawdę nie tak z architekturą kodu.
Powinieneś przyzwyczaić się do pisania czystego kodu i usuwania złych nawyków, takich jak kopiowanie kodu i pisanie długich metod itp.
Poza tym od czasu do czasu powinieneś refaktoryzować swój kod. Proponuję przeczytać książkę Martina Fowlera: Refactoring: Improving the Design of Existing Code
źródło
Inni wspominali o testowaniu i przeglądzie kodu. Oba są niezwykle przydatne, ale mają zasadniczą różnicę - kiedy najlepiej je wykonać. Testowanie najlepiej przeprowadzić bardzo blisko oryginalnego pisania kodu, aby łatwiej było sobie przypomnieć, dlaczego zrobiłeś to w określony sposób, i szybciej zlokalizować problem, gdy test się nie powiedzie. Z drugiej strony, przegląd kodu lepiej jest zrobić trochę później. Chcesz spojrzeć na kod bez idealnego przypomnienia, abyś nie przerzucał szczegółów, o których pamiętasz, ale o których nie pomyślałeś. Chcesz zdać sobie sprawę z miejsc, w których twój kod jest niejasny. Potrzebujesz dodatkowego wysiłku, aby dowiedzieć się, co robi kod. Chcesz być w stanie zastosować każdą zdobytą wiedzę na temat problemu lub interakcji z innym kodem lub nowymi technikami. Gruntownie,
Wszystko to jest jednak styczne do twojego pytania. Aby poświęcić mniej czasu na debugowanie, musisz przede wszystkim zrozumieć, dlaczego musiałeś debugować. Niezrozumienie problemu, niedoskonała znajomość narzędzi i technologii, po prostu zwykłe napotkanie „prawdziwych danych nie pasujących do danych przykładowych” rodzaje problemów przejawiają się na różne sposoby i wymagają różnych technik i rodzajów praktyki, aby uniknąć w przyszłości.
Ostatnim punktem, na który powiem, jest doświadczenie. Nie ma łatwego sposobu na uzyskanie tego, wystarczy poświęcić czas. W miarę zdobywania doświadczenia spędzasz mniej czasu na debugowaniu, ponieważ na początku będziesz pisać lepszy kod, wcześniej zauważać problemy i rozwijać lepszą intuicję, co może być źródłem problemu. Trzymaj się tego, a będziesz rósł stopniowo w ciągu swojej kariery.
źródło
Świetne odpowiedzi powyżej, ale nikt nie wspomniał bezpośrednio (choć najczęściej o tym wspominano):
CZYTAJ CZYTAJ CZYTAJ CZYTAJ i nauseam ...
Im więcej wiesz, tym mniej nie wiesz. Trochę banalne, ale wciąż podstawowa prawda.
Po wykonaniu powyższych wskazówek i analitycznym udokumentowaniu błędów spróbuj je sklasyfikować, a następnie przeczytaj stosowną literaturę.
Czy to był problem z decyzją projektową? Przeczytaj o wzorach projektowych.
Czy był to brak znajomości frameworka lub języka? Kość na to!
itp
Są dwie rzeczy, których deweloper (na żywo) nigdy nie może uciec: zmiana (jedyna stała w IT) i RTFMing ...
źródło
Testy jednostkowe i stwierdzenia
Tam, gdzie to możliwe, podziel kod na małe części, które można przetestować oddzielnie. Jednak nie zawsze jest to praktyczne. Niektóre funkcje zależą od niezwykle skomplikowanych danych wejściowych. Niektórzy robią coś, czego nie można łatwo zweryfikować w sposób zautomatyzowany, na przykład rysują rzeczy na ekranie. Czasami w grę wchodzi niedeterminizm itp.
Kiedy nie możesz napisać dobrych testów jednostkowych, następną najlepszą rzeczą jest stwierdzenie. Podczas gdy testy jednostkowe sprawdzają, czy uzyskasz prawidłową odpowiedź na niektóre z góry określone dane wejściowe, zapewnia sprawdzanie rozsądności pośrednich kroków na wejściach w świecie rzeczywistym. Jeśli Twój kod zawiera błędy, szybko się nie powiedzie, blisko źródła problemu i z wyraźnym komunikatem o błędzie, a nie daleko od problemu z niejednoznacznym komunikatem o błędzie. Ponadto potwierdza założenia dokumentu i sprawia, że kod jest bardziej czytelny.
źródło
Kiedy zaczynasz projekt, ile alternatywnych podejść rozpoznajesz?
Czy masz od dwóch do czterech różnych podejść, z zaletami i wadami każdego z nich? Czy dokonujesz wśród nich uzasadnionego wyboru?
A zatem, najważniejsze, czy uważasz prostotę za bardzo ważną?
Z mojego doświadczenia wynika, że objętość kodu, a zatem liczba błędów (nie wspominając o wydajności), może różnić się o więcej niż rząd wielkości między jednym podejściem projektowym a drugim. Widzę, jak robią to bardzo doświadczeni ludzie, którzy wykonują zadania bez więcej kodu niż to konieczne.
Są w pełni kompetentni i świadomi wszystkich algorytmów struktury danych, cech języków obiektowych itp., Ale ich kod wygląda tak, jakby ich nie było , ponieważ używają tych rzeczy oszczędnie lub wcale, jeśli problem nie wymagają ich.
źródło
Za każdym razem, gdy naprawisz błąd, chcesz uniknąć ponownego popełnienia tego samego błędu. W tym celu możesz wykonać następujące czynności:
Zapisz to w dzienniku zapisu defektów , który obejmuje:
Zastosuj poradnik stylów, aby znormalizować styl pisania kodu
Zintegruj zasady bezpiecznego kodowania w procesie przeglądu kodu
Wizualizuj przepływ kontrolny i dane
Referencje
Badanie empiryczne dotyczące wpływu PSP na poszczególnych inżynierów (pdf)
Przewodnik po stylu CPP Google
Przyznanie porażki na K&R w LCTHW - Zed A. Shaw
Wtyczki IDE - sposób testowania bezpieczeństwa w celu zautomatyzowania przeglądu kodu | Społeczność TCS Cyber Security
Zestaw reguł bezpieczeństwa dla kodu zarządzanego
Bezpieczne kodowanie w C ++ 11 i C ++ 14
Wizualizuj wykonanie kodu Java
Wizualizacja SPARQL
WWW2012 Samouczek Wizualizacja zapytań SPARQL
źródło