Nauka sprawdzania błędów [zamknięte]


11

Nie jestem nawet pewien, jak zdefiniować tę trudność. Przypomina mi to test, jaki przeprowadził u mnie kilku potencjalnych pracowników, zanim dostałem pracę. Wybierałyby jakiś przedmiot w pokoju, a następnie pozwalano mi zadawać pytania, które pomogą mi ustalić, co to za przedmiot (podobnie jak 20 pytań). Byłem w tym absurdalnie dobry (nie, nigdy nie dostałem wysokich punktów za pokorę), więc założyłem, że będę naprawdę dobry w rozwiązywaniu problemów ...

Ale oto rzecz, którą ostatnio odkryłem. Jestem naprawdę dobry w tej sytuacji, ponieważ bardzo łatwo jest zobaczyć wszystko, co jest w pokoju, dlatego mogę podejść do mojego problemu z pewną koncepcją części składowych. W istocie „wiem, czego nie wiem”. Ale przy programowaniu napotykam wiele sytuacji, w których problem jest dla mnie zupełnie nieznany. Wiem, że jest zepsuty, ale nie mam pojęcia, jak może być zepsuty. Postępowałem zgodnie ze wszystkimi instrukcjami, dość dobrze znam technologię ...

Jeśli mam być szczery, wydaje mi się, że trudno mi sobie wyobrazić, co może być nie tak, żebym mógł je przetestować i, mam nadzieję, znaleźć rozwiązanie.

Jak mogę zacząć rozwijać tę umiejętność? Co muszę zrobić, aby pomóc mojej, jak się wydaje, ograniczonej wyobraźni wymyślić sposoby, w jakie mój projekt mógłby zostać zepsuty? Czy są jakieś ćwiczenia (być może zagadki?), Które mogą sprawić, że będę w tym lepszy? Zdaję sobie sprawę, że prawdopodobnie największym lekarstwem jest po prostu doświadczenie ... ale mam nadzieję pomóc przyspieszyć ten proces, jeśli będę mógł. Bezmyślne wpatrywanie się w ekran komputera przez kilka godzin jednocześnie nie jest nawet zabawą ...


3
Wyobraź sobie, jak to może działać, i pracuj wstecz od wyników do danych wejściowych, aby znaleźć ścieżki do zbadania
Steven A. Lowe

1
Rzucę tam link - Jak zostać programistą - pierwszą umiejętnością na liście jest „Naucz się debugować”.

1
Chciałem rzucić coś na temat myślenia „po wyjęciu z pudełka”. Jeśli chodzi o błędy, często myślę, że pierwszą rzeczą do zrobienia jest po prostu spis wszystkich współdziałających systemów, a następnie założenie, że jakakolwiek część może być winna, dopóki nie zostanie udowodnione inaczej. Wtedy praca staje się łatwiejsza: załóż, że komponent zawodzi, i znajdź sposób, który mógłby, nawet jeśli na początku wydaje się nielogiczny („dane wyjściowe są uszkodzone” itp.). Następnie udowodnij, że Twój komponent nie działa, zaczynając od najbardziej natychmiastowych interakcji. Po fakcie może to wydawać się wyobraźnią, ale często zaczyna się od pesymistycznego spojrzenia.
J Trana

Napisz printflub printlnczy cokolwiek stosować pod każdym wierszu kodu w 100% pewien, wszystko działa, jak chcesz go do pracy haha. Następnie uruchom konsolę, a App > out.txtpotem pojawi się trudna część przeglądania ogromnego pliku. Czasami moje pliki dziennika mają ponad kilka milionów linii i może to zająć trochę czasu haha. Oczywiście właściwym sposobem byłoby użycie debuggera i punktów przerwania, ale czasami nie jest to możliwe.
SSpoke

1
Przeczytaj Zen Pirsiga i sztukę konserwacji motocykli amazon.com/Zen-Art-Motorcycle-Maintenance- Enquiry
Jeffrey Kemp

Odpowiedzi:


11

Każda wada oprogramowania jest ostatecznie spowodowana rozbieżnością między założeniami a rzeczywistością. Podstępne błędy to po prostu rozbieżności między szczególnie głęboko zakorzenionymi założeniami a rzeczywistością. Zdolność diagnozowania błędów zależy od twojej zdolności do kwestionowania własnych założeń, a to rzeczywiście wymaga świadomości, że nie wiesz pewnych rzeczy, po prostu je przyjąłeś i do tej pory tak było.

Oczywiście narzędzia handlu, pliki dziennika, debugery itp. Są pomocne w odkryciu takich założeń i ponownym dopasowaniu modelu świata do rzeczywistego systemu. Ale dopóki nie będziesz gotowy zakwestionować kluczowego założenia, np. „To nie może być zły sygnał wejściowy, ponieważ mamy kompleksowe sprawdzanie danych wejściowych”, poświęcisz cały swój czas na sprawdzanie niewłaściwych części systemu lub po prostu nie wiedząc, gdzie jeszcze szukać na pierwszym miejscu.


3
Nienawidzę tego mówić Killian, ale myślę, że trafiłeś w sedno. Byłem bardzo dumny z mojej „wiedzy” na temat systemów, które nabyłem przez ten czas, kiedy tu jestem i myślę, że jestem odporny psychicznie na myśl, że się mylę. Jak mogłem wspomnieć, nigdy nie uzyskałem wysokiej oceny pokory. Postępowanie zgodnie z twoją radą w celu zakwestionowania moich własnych założeń pozwoliło mi poczynić pewne postępy w kilku kwestiach, które napotkałem we własnym kodzie. Dziękuję, będę o tym pamiętać, idąc naprzód.
Jay Carr

2
@JayCarr: „ odporny psychicznie na ideę bycia w błędzie ” - co jeśli próbujesz postrzegać błędy jako źródło wiedzy, a nie błąd? Nie ma nic złego w tym, że się mylisz, dopóki się na tym nie zatrzymasz.
JensG

14

Co muszę zrobić, aby pomóc mojej, jak się wydaje, ograniczonej wyobraźni wymyślić sposoby, w jakie mój projekt mógłby zostać zepsuty?

W większości przypadków nie powiedziałbym absolutnie nic. Nie powinieneś próbować wymyślać rzeczy, które mogą powodować awarię programu. Powinny być systematycznie ustalania, co jest przyczyną, że do złamania.

Powinieneś być w trakcie debugowania z następującymi informacjami:

  • kroki, które zostały podjęte, i wartości, które zostały wprowadzone w celu wywołania błędu;
  • co program powinien robić, biorąc pod uwagę te kroki i dane wejściowe;
  • co program ma robić, gdy dana te kroki i wejść.

Jeśli pojawi się komunikat o błędzie, uzyskaj wszystkie informacje na jego temat. Jeśli sam komunikat o błędzie nie jest jasny, a nie wiesz, co to znaczy w praktyce (niektóre komunikaty o błędach nie zawsze są szczególnie przydatne), skorzystaj z Google, StackOverflow lub innego zasobu online, aby znaleźć informacje na jego temat .

Jeśli na interfejsie nie wyświetla się komunikat o błędzie, sprawdź, czy w dziennikach zapisanych przez aplikację nie ma komunikatów o błędach w okresie, w którym odtworzono błąd. Kod mógł zostać wykonany do końca, ale napotkał wyjątek, który jest obsługiwany po drodze, odrzucając wynik końcowy i generując wpis w dziennikach. Poszukaj ich, zrób to samo powyżej i dokładnie określ ich znaczenie.

Jeśli istnieją stosy śledzenia z wyjątkami zgłaszanymi przez kod (i powinny być), spójrz na wspomniane wiersze kodu. Sama linia może nie być tą, która faktycznie powoduje problem. Jeśli otrzymujesz NullPointerException w kawałku kodu Java, stacktrace powie ci, gdzie próbowałeś użyć czegoś, co było zerowe, gdy się tego nie spodziewałeś. To nie wskazuje dokładnie linii powodującej problem, ale ogólnie mówi ci, która zmienna nie ma oczekiwanej wartości, więc możesz spojrzeć na wszelkie odniesienia / przypisania do tej zmiennej, aby ustalić, że wartość nie jest ustawiony lub że wartość jest ustawiana niepoprawnie.

Jeśli to nie pomogło, uruchom swój debugger. Jeśli zawęziłeś go do części kodu, o której wiesz, że powoduje problem - ale nie wiesz dokładnie, które wiersze - to przejdź przez to. Jeśli nie, po prostu przejdź przez całą sprawę. W tym miejscu musisz dokładnie wiedzieć, co program powinien robić przy danych wejściach, ponieważ musisz spojrzeć na każdą wartość po każdej linii i dokładnie określić, gdzie odbiega ona od tego, czego się spodziewasz.

Nadal nie masz pojęcia, na czym polega problem? Poproś kogoś o pomoc . Współpracownik, przyjaciel, społeczność internetowa. Pokaż im całą pracę, którą właśnie wykonałeś. Pokaż im komunikaty o błędach, ślady stosu, wyjaśnij, co program robi ogólnie (jeśli jeszcze nie wie), co powinien robić w tym konkretnym przypadku (np. Zwracając wartość 4), co faktycznie robi (np. zwracanie wartości 5). Jeśli zawęziłeś go do kilku linii kodu w debuggerze, powiedz „Wiem, że problem jest spowodowany przez te linie w kodzie, ustawia wartość na X, kiedy powinna być Y, ale nie widzę dlaczego tak się dzieje.

Spędzenie kilku godzin bezmyślnie wpatrując się w ekran z pewnością nie jest zabawne, ale nie ma powodu, byś to robił. Jeśli występuje problem z Twoim kodem, musisz czytać lub przechodzić przez kod.


Mogłem nieco szybko ocenić tę odpowiedź, byłem nieco sfrustrowany, gdy ją przeczytałem. Dobra rada. Komentarze Killians po prostu mówiły bardziej do istoty mojego problemu. To jedyny powód, dla którego nie jest to wybrana odpowiedź.
Jay Carr

4

W pewnym stopniu przypomina śledztwo w sprawie karnej lub oszałamiającą łamigłówkę.

Najpierw masz ofiarę. Po wgłębieniu się w sprawę zidentyfikowałeś kilku podejrzanych, a także opracowałeś hipotezę dotyczącą tego, jak dokładnie ofiara mogła zostać zamordowana. Kontynuujesz badanie, szukając bardziej przydatnych informacji, przybliżając się do prawdziwego źródła problemu.

Zdarza się, że od czasu do czasu wchodzisz w ślepy zaułek (gra słów zamierzona). To część tego i nie ma w tym nic złego, o ile uda ci się jak najszybciej przywrócić właściwy kierunek. Kluczem jest, aby zawsze myśleć o tym, jakiej informacji potrzebujesz następnie, która albo dostarcza twojej hipotezy (i dostarcza dalszych informacji), albo dowodzi, że jest błędna. Następnie znajdź sposób na skuteczne uzyskanie tych informacji, wyciągnij wnioski i przejdź dalej, aż w końcu będziesz w stanie skazać winnego.

A czasem zdajesz sobie sprawę, że wszystkie fakty i wskazówki niezbędne do wykrycia sprawcy czekają już przed tobą pół godziny temu. Choć denerwujące, jest to jedna z najbardziej interesujących części, ponieważ jeśli dokonasz krytycznej oceny swoich działań i błędów, możesz być w stanie się uczyć i poprawiać . Zadaj sobie pytania takie jak:

  • Jak mogłem uniknąć marnowania czasu?
  • Co przeoczyłem i dlaczego?
  • Na jakich nieuzasadnionych i / lub błędnych założeniach polegałem?

To ćwiczy twoje umiejętności. Rozwija także twój instynkt jelitowy , więc z czasem uczysz się automatycznie zauważać wszystkie drobne rzeczy, które zbyt łatwo można przeoczyć, prowadząc cię szybciej do właściwej odpowiedzi. Na koniec chodzi o celową praktykę .

Na koniec zawsze pamiętaj, czego nauczył nas Sherlock Holmes: kiedy wyeliminowałeś niemożliwe, wszystko, co jest nieprawdopodobne, musi być prawdą.


3

Co muszę zrobić, aby pomóc mojej, jak się wydaje, ograniczonej wyobraźni wymyślić sposoby, w jakie mój projekt mógłby zostać zepsuty?

Niech historia będzie twoim przewodnikiem. Jeśli Twój projekt jest dobrze zarządzany, powinieneś mieć bazę danych każdego błędu, który kiedykolwiek został naprawiony w produkcie, wraz z analizą tego, jak błąd został znaleziony, jak został odtworzony, jak został przeanalizowany i jak został naprawiony. To nie jest baza danych tylko do zapisu. Przeczytaj bazę danych , a już wkrótce zaczną się pojawiać taksonomie błędów.

To da ci dobry przegląd tego, co nie działa w twoim produkcie. Jeśli interesuje Cię bardziej ogólnie to, co dzieje się źle we wszelkiego rodzaju oprogramowaniu, szczególnie z naciskiem na defekty wpływające na bezpieczeństwo, sugeruję przeczytanie listy CWE: http://cwe.mitre.org/data/index.html


2

Więc zamiast próbować odtworzyć i naprawić konkretną wadę, myślę, że pytasz o wymyślenie nowych testów, których możesz użyć do zbadania produktu, aby sprawdzić, czy produkt działa w takich okolicznościach, na przykład: co się stanie, jeśli wprowadzę znaki specjalne do naszego zapisz hasło strony, lub co się stanie, jeśli wymuszę zamknięcie programu podczas jego zapisywania w bazie danych. Te przypadki naprawdę trudno wymyślić.

Rozwój oprogramowania w ciągu ostatnich 10 lat (Agile / XP / TDD itp.) Zyskał na wartości, spełniając tylko wyraźne wymagania, a następnie ogłaszając, że funkcja została zakończona, i nie znajdując każdego możliwego sposobu, aby coś zepsuć (są możliwe wyjątki, jeśli jesteś pracując dla NASA lub robiąc bezpieczeństwo w białych kapeluszach, ale nawet wtedy istnieje potrzeba, aby wywoływać takie rzeczy w kryteriach akceptacji historii użytkownika).

Jeśli więc twoje funkcje wyraźnie wymieniają jako kryteria akceptacji to, czego potrzebują systemy, takie jak sposób obsługi danych wejściowych, jego charakterystyka wydajności, działania przepływu pracy użytkownika itp., To masz pełną listę elementów, które należy sprawdzić w testach. Testy powinny zostać przeprowadzone w celu sprawdzenia, czy wymagania zostały spełnione, a najlepszym sposobem na to jest jawne wyszczególnienie wszystkich wymagań. Spójrz na kwadraty testu zwinnego .

Niektóre osoby opowiadają się za tym, aby testy te były wyraźną deklaracją wymagań, które należy napisać przed kodem, tj. Test First (lub Test Driven Development).

Doceniam jednak to, że nie brzmisz tak, jakbyś rozważał nowy projekt, w którym możesz ustawić własne najlepsze praktyki programistyczne przed rozpoczęciem, a zamiast tego przychodzi po napisaniu oprogramowania i proszeniu go o „przetestowanie”. To jest rzeczywiście trudniejsze, ale obowiązują te same zasady, możesz to przetestować tylko wtedy, gdy wiesz, co powinno zrobić. Jeśli nie ma wyczerpującej listy wymagań, które zespół programistów spełnił, aby móc pracować, zadawanie pytań jest najlepszym rozwiązaniem. W zależności od zespołu może to wymagać delikatnego wykonania, ponieważ osoby, które nie określiły wyraźnie swoich wymagań przed zbudowaniem systemu oprogramowania, nie lubią przypominać sobie o tym, co przegapili, ale ważne jest, aby dobrze wykonać to zadanie.

Gdy znajdziesz wymaganie - musi ono być solidne / musi być bezpieczne, a następnie spróbuj kopać głębiej i dowiedz się, jak bezpieczne musi być, lub ile awarii jest do zaakceptowania, zawsze istnieje limit, niewiele osób ma dowód NSA poziom bezpieczeństwa jako wymóg ich zastosowania lub chciałby za to zapłacić. Im więcej kopiesz, tym wyraźniejsze powinno być to, jakie rodzaje ataków bezpieczeństwa musisz bronić lub których chcesz użyć. Pewna wiedza na temat domeny jest wtedy przydatna, jeśli chodzi o bezpieczeństwo, projektowanie, wydajność itp., Gdzie zadajesz jeszcze więcej pytań od ekspertów, których możesz znaleźć w swoim zespole, tutaj na SE lub w google / books.


Nie do końca pytanie, na które chciałem odpowiedzieć, ale doskonały komentarz. Głosuję za tobą, to bardzo użyteczny komentarz.
Jay Carr
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.