Dlaczego jeden błąd jest tak powszechny i ​​co możemy zrobić, aby temu zapobiec?

20

Wydaje się, że błędy off-by-one są jednym z najbardziej (jeśli nie najbardziej) typowych błędów programistycznych (patrz /software/109/what-are-common-mistakes-in-coding i konwencjonalna mądrość).

Z jakiego powodu są one tak powszechne, czy ma to związek z tym, jak działa ludzki mózg?
Co możemy zrobić, aby zapobiec popadnięciu w ofiarę jednym błędem?

Malfist
źródło
8
Czy są wspólne? Zgłaszam sporo błędów, ale bardzo rzadko występują wśród nich błędy. Może dlatego, że najczęściej używam Pythona, tzn. Używam iteratorów zamiast żonglowania indeksami? (I: Co to nam mówi
Im mniej musisz myśleć, tym bardziej jesteś produktywny?
Malfist
@delnan: Zgadzam się. Błędy „jeden po drugim” są zwykle wychwytywane jako pierwsze, gdy koduję (zanim przejdę nawet do oficjalnej „fazy testowania”).
FrustratedWithFormsDesigner
7
Prawie odpowiedziałem przez pomyłkę na poprzednie pytanie ...
DevSolo,
> Co możemy zrobić, aby zapobiec popadnięciu w ofiarę jednym błędem? Użyj iteratora .
Jim G.

Odpowiedzi:

18

To ma coś wspólnego z tym, jak działa ludzki mózg. Jesteśmy przekonani, że jesteśmy „wystarczająco dobrzy” do zadań, które zwykle nie wymagają precyzji inżynierskiej. Jest powód, dla którego przypadki, z którymi mamy największe problemy, nazywane są skrzynkami „krawędziowymi”.

Prawdopodobnie najlepszym sposobem na uniknięcie błędów off-by-one jest hermetyzacja. Na przykład, zamiast używać pętli for, która iteruje kolekcję według indeksu (od 0 do zliczenia - 1), użyj pętli dla każdego stylu z logiką, w której przestaje być wbudowany w moduł wyliczający. W ten sposób musisz tylko raz poprawnie wyrównać granice, pisząc moduł wyliczający, zamiast za każdym razem, gdy przeglądasz kolekcję.

Mason Wheeler
źródło
6
+1 za enkapsulację. Najgorsze błędy off-by-one, jakie kiedykolwiek widziałem, to to, że część programu jest oparta na 1, a część oparta na 0, a przy każdej używanej funkcji musisz pamiętać, która to była i czy musisz dokonaj konwersji czy nie, i w którą stronę pójść. Kilka miesięcy temu musiałem wyśledzić trudny błąd off-by- 2, ponieważ zła enkapsulacja oznaczała, że ​​ktoś popełnił błąd off-by-1 w dwóch oddzielnych miejscach. Wszędzie wszędzie były konwersje, których nie można było śledzić i udało mi się sprowadzić je do jednej konwersji za pomocą jednej metody.
Karl Bielefeldt,
2
Chciałbym dowiedzieć się więcej na temat nauki tego, jeśli ktoś ma więcej informacji. Myślę też, że właśnie dlatego programowanie stylów, takie jak CSS, jest tak frustrujące, gdy wszystko jest na krawędzi ...
Company Laser
7

Jest coś szczególnego w tym, jak mózg obsługuje granice i krawędzie.

Podczas gdy mózg łatwiej myśli w kategoriach zasięgu i przestrzeni , skupienie się na krawędzi wydaje się wymagać nieco więcej uwagi. Oto, jak to się dzieje, chwilowa utrata uwagi lub niewystarczająca koncentracja i przeoczyłeś granicę.

Innym niewielkim dodatkiem do problemu jest to, że różne środowiska programistyczne mają różne systemy indeksacji zaczynające się od 0 lub 1, co może wprowadzać zamieszanie u osób aktywnie narażonych na oba typy środowisk.


źródło
4

Uważam, że jest to spowodowane przełączaniem kontekstu. W naszym codziennym życiu używamy indeksów 1. Z tego powodu nasz mózg nie jest w stanie zapisać prawidłowego zachowania w pamięci długoterminowej.

ChaosPandion
źródło
2
A potem jest fajnie przełączać się między programowaniem języków, których indeks DO zaczyna się od 1 (np. PL / SQL).
FrustratedWithFormsDesigner
3
+1 za to. 1-indeksowana numeracja odpowiada na pytanie „ile ich tam jest?”, Które precyzyjnie odwzorowuje większość rzeczywistych zadań. Indeksowanie 0 dotyczy „w jakiej pozycji znajduje się każdy element?”, Co ma mniejsze zastosowanie w obszarze mięsnym.
Dan Ray