Mamy tutaj system. Ostatnio wystąpił błąd w obliczeniach jednego z numerów w raporcie wygenerowanym przez system. Dzięki naszemu doświadczeniu od kilku lat nie napotykamy żadnych problemów / błędów w tym systemie.
Ponieważ autor tego systemu już zniknął, ledwo możemy śledzić programy. Ale zweryfikowaliśmy dane wejściowe, ustawienia i mają rację.
Teraz moje pytanie brzmi: czy program komputerowy nagle pójdzie nie tak bez żadnego logicznego powodu? Jeśli uderzę w serwer, czy jeden z obliczanych przez komputer liczb stanie się innym i sprawi, że obliczenia będą błędne?
Zgadzam się, że mój pomysł jest dość szalony, ale chcę tylko wiedzieć, skąd możemy wiedzieć, że problem nie jest spowodowany programem i danymi wejściowymi, ale innymi czynnikami?
PS Ten szalony system nie ma dziennika.
Odpowiedzi:
Powiedziałbym nie!
Teoretycznie odpowiedź brzmi nie, możemy jedynie przetestować:
Jest to znacznie mniej niż całkowita możliwa liczba środowisk, czasów i przypadków, w których program może napotkać w ciągu swojego życia. Mamy również niewielką wiedzę na temat przyszłości, czy należy programować radzenie sobie z inflacją na poziomie 10 000%, czy program powinien radzić sobie z nową, 31-bitową architekturą o superdupercji?
Teorię potwierdzają doświadczenia, które osobiście spotkałem:
źródło
Teoretycznie, jeśli zaczniesz od identycznego stanu, wynik będzie identyczny. W rzeczywistości zapewnienie identycznego stanu początkowego w sprzęcie „wielkości serwera” jest prawie niemożliwe.
Weź niezainicjowane zmienne. Spójrz na ten kod:
Spowoduje to nieoczekiwane wyniki w 65536 uruchomieniach. I jeśli nie zapewnisz, że pamięć będzie w tym samym stanie przed każdym uruchomieniem,
i
będzie całkowicie losowa.Istnieją setki podobnych sposobów wyskakiwania błędów po nieprzewidywalnych elementach stanu początkowego, o którym ktoś zapomniał przesłonić, lub przypadki graniczne, które zdarzają się rzadko - warunki wyścigu w środowisku wielowątkowym, dostęp do tablicy poza granicami, IO dysku na uszkodzony system plików i wkrótce.
Jeśli możesz udowodnić, że program jest wolny od błędów, tylko promienie kosmiczne mogą go złamać. Ale matematyczny dowód poprawności czegokolwiek bardziej złożonego niż dwie zagnieżdżone pętle jest znacznie poza zasięgiem największych systemów (i kosztuje niewielką fortunę), a na resztę można tylko mieć nadzieję.
źródło
Jeśli masz dokładnie to samo środowisko komputerowe, wówczas podanie X programu zawsze daje ten sam wynik R. W praktyce rzadko zdarza się, aby pojedynczy program działał osobno. Najprostsza aplikacja działa dzisiaj w systemie operacyjnym i współdzieli pamięć z innymi programami, które mogą być jednocześnie „ładowane” do pamięci. Programy te mogą zmieniać pamięć w sposób, który powoduje nieprawidłowe działanie danego programu. Jest to znany problem np. Ze zmiennymi typu „wskaźnik”. Zwykle takie błędy powodują nieprawidłowe zachowanie systemu i nieprawidłowe wyniki obliczeń.
W twoim przypadku zakładam, że problemem może być (i zwykle nie jest) to, co opisałem powyżej. Problemem może być to, że:
Ze względu na powyższe i wiele innych powodów, dla których ludzie oprogramowania spędzają tak dużo zasobów, próbując stworzyć prawidłowe oprogramowanie, nadal występują błędy oprogramowania, ale błędy są „logiczne” i mają powód, po prostu powód nie jest oczywisty dla niektórych bez dobrych badań. Ogólnie rzecz biorąc, testowane oprogramowanie jest przewidywalne i nie daje losowych wyników. Ze względu na złożoność niektórych programów i inne czynniki nawet przetestowane programy mogą pójść nie tak, ale kiedy tak się dzieje, błędy są z logicznego powodu.
Odpowiedź brzmi: nie, oprogramowanie nie jest w tym sensie kruche.
Co możesz zrobić, to wyizolować przypadki, w których występuje błąd, znaleźć podobieństwo między tymi zestawami danych powodującymi błąd i znaleźć różnicę między tymi zestawami a innymi zestawami, które dają poprawny wynik. Możesz być w stanie zidentyfikować konkretny zestaw wartości powodujących problem. Na przykład może się okazać, że za każdym razem, gdy zmienna ma wartość ujemną, wynik jest błędny.
Zaktualizowano informacje o błędach uszkodzenia pamięci: Zobacz Uszkodzenie pamięci
źródło
Czy możesz zagwarantować, że program nie zawiera błędów i nigdy nie pójdzie źle? Nie, niestety nie.
Czy możesz wykazać, że program zawiera wystarczająco małą liczbę błędów, aby koszt ich znalezienia i naprawienia znacznie przekraczał korzyść z tego działania? Brzmi dla mnie tak, jak już masz.
Parafrazując starą maksymę statystyk, wszystkie programy są błędne, ale niektóre programy są przydatne.
źródło
Jestem skłonny powiedzieć nie , nie możesz udowodnić, że program nigdy nie pójdzie źle lub nie zapewni niepoprawnego wyniku, nawet jeśli możesz założyć idealne dane wejściowe.
Raku wspomniał o formalnym dowodzie poprawności. To jedna rzecz do rozważenia, ale chyba, że się całkowicie mylę, nadal będzie trzeba założyć idealne środowisko wykonawcze. Tak więc przy pewnym nakładzie czasu i wysiłku możesz być może udowodnić, że program jest poprawny , ale niekoniecznie oznacza to, że zawsze będzie dawał poprawne wyniki , nawet przy doskonałym wprowadzeniu danych. Środowisko wykonawcze ma znaczenie. I byłbym ostrożny, zakładając, że dane wejściowe są zawsze doskonałe.
Dlatego w niektórych sytuacjach wysokiej dostępności używanych jest wiele całkowicie niezależnych implementacji i środowisk wykonawczych, a wyniki są porównywane, aby upewnić się, że mieszczą się w dopuszczalnym marginesie błędu. W niektórych sytuacjach margines ten może wynosić zero. Już w latach 60. uznano to za wystarczająco ważne, aby uwzględnić osobne zestawy sprzętu komputerowego w statku kosmicznym. Nawet jeśli błędne wyładowanie statyczne, promień kosmiczny lub cokolwiek innego wpłynęłoby na oba komputery jednocześnie, szanse, że oba wpłynęłyby na nie w ten sam sposób (szczególnie jeśli oba nadal działają i dają prawidłowe wyniki) są znikome. Szanse na pojawienie się tego samego błędu w dwóch całkowicie oddzielnych implementacjach są również bardzo małe. I tak dalej.
źródło
Myślę, że większość (standardowych) komputerów jest deterministyczna.
Jeśli to możliwe, skonfiguruj go, aby wykonać partię 1000 lub 10000 itd., Iteracje z tymi samymi danymi wejściowymi i sprawdź, czy wyniki są takie same.
Upewnij się, że bieżące wartości wchodzące w skład obliczeń spowodują przepełnienie lub niedopełnienie w dowolnym miejscu (jeśli jest to starszy system, być może nie zamierzano go używać tak długo).
Y2K11 ktoś?
źródło
Jeśli nie możesz kontrolować każdego bitu w maszynie i każdego impulsu elektrycznego przepływającego przez zespół obwodów, nie możesz zagwarantować z absolutną pewnością, że coś nie pójdzie nie tak z twoim programem. Awarie modułów pamięci, procesory mogą się przegrzewać i wprowadzać błędy, dyski twarde mogą szyfrować dane, a zasilacze mogą powodować zakłócenia w systemie. Im droższy sprzęt i im bardziej sprzęt jest redundantny, tym mniejsze prawdopodobieństwo wystąpienia takich rzeczy, ale w pewnym momencie sprzęt może ulec awarii.
Następnie masz system operacyjny z błędami, które można łaskotać najbardziej tajemniczymi środkami, jakie można sobie wyobrazić. Kompilatory mogą mieć również niejasne błędy, które tylko czekają, aby zręcznie zmienić nieskazitelny kod w trudne do wyśledzenia błędy. Tam jest dżungla, a twoje słabe oprogramowanie jest podatne na to wszystko. UWAŻAJ!
Z mojego doświadczenia wynika, że za każdym razem, gdy w obliczeniach występuje błąd, nigdy nie musimy kopać tak daleko, aby znaleźć winowajcę. Ogólnie rzecz biorąc, prawie wszystkie błędy, które widziałem w świecie korporacyjnym, można łatwo znaleźć dzięki odpowiednim narzędziom do debugowania i odrobinie smaru do łokci.
Innymi słowy, chociaż sprzęt i system operacyjny mogą nie być idealne, prawdopodobnie nigdy nie będziesz musiał się martwić o ten poziom szczegółowości. Po prostu znajdź kogoś, kto zna język i jest przydatny z debuggerem, i kop się.
„prostsze wyjaśnienia są, przy czym inne rzeczy są równe, ogólnie lepsze niż bardziej złożone”. - Podsumowanie brzytwy Ockhama.
źródło
Tak, uderzenie w system może zgiąć i / lub poruszyć części na tyle, aby spowodować chwilowe przerwanie obwodu (lub ewentualnie zwarcie, choć prawdopodobnie jest to mniej prawdopodobne).
źródło
Pierwszym moim komputerem był Altair 8080 z 256 bajtami pamięci. Dane wejściowe pochodziły z przełączników konsoli, a dane wyjściowe pochodziły z kilku migających lampek. Jeśli nie pozwolicie na promienie kosmiczne i awarie sprzętu, wierzę, że mogę udowodnić, że niektóre programy, które na nim uruchomiłem, zawsze dawałyby takie same wyniki.
Od tego czasu nie.
źródło
Jeśli próbujesz udowodnić, że Twój program działa poprawnie przez testowanie, to nie będzie działać.
Istnieją jednak pewne podejścia w informatyce teoretycznej, w których opracowuje się formalny dowód napisanego oprogramowania. W zależności od złożoności systemu może to być żmudny proces. Jeśli jednak twój system działa na ograniczonym zestawie poleceń, możesz odnieść sukces dzięki temu podejściu.
źródło
Środowiska sprzętowe i programowe podlegają ciągłym zmianom. Przykłady części ruchomych, elektryczności, temperatury, zapylenia i kodu systemu operacyjnego.
Dlatego nie sądzę, że jest nawet prawdopodobne lub oczekiwane, że program komputerowy zawsze będzie zachowywać się tak samo, ponieważ środowisko zawsze się zmienia.
Oprogramowanie może działać przez długi czas, zgodnie z oczekiwaniami, ale ostatecznie albo mała zmiana w oprogramowaniu systemu operacyjnego hosta ulegnie zmianie, co wpłynęłoby na dany program lub wartość sprzętu.
Mówię o komputerach na dzień dzisiejszy.
źródło
Odpowiedź na to pytanie jest nieznana. Nie można udowodnić, że wszystko jest zawsze prawdą we wszechświecie, w którym żyjemy. Zamiast tego przyjmujemy założenia i dowodzimy, że jeśli założenia się utrzymają, wówczas zachowa się również pewna skomplikowana właściwość. Właśnie to gwarantują formalnie zweryfikowane programy. Większość programów nie jest jednak formalnie weryfikowana, zamiast tego próbują zbudować zaufanie poprzez dostarczenie testów. Testy te dają pewność, że pod warunkiem, że testy wykonają to, do czego zostały zaprojektowane i że założenia, które podjąłeś, program, którego używasz, będzie działał przynajmniej przez pewien czas.
źródło
Jest prawie niemożliwe, że problem jest spowodowany awarią pamięci RAM, ale jest to stosunkowo (bardzo) mało prawdopodobne. Uruchom test pamięci, ale przygotuj się na przejrzenie kodu.
źródło