Próba-szerencse programozás

A Wikipédiából, a szabad enciklopédiából

A próba-szerencse programozás a számítógép-programozás egy antimintája. Lényege, hogy a programozó apró változásokat visz véghez, remélve, hogy ezzel kijavít egy hibát. Közben rendszerint nem használja a verziókezelést, emiatt a megelőző változat elveszhet. Az apró változtatásokat, sorok megcserélésének eredményét teszteli is, bár ez a tesztelés nem kimerítő. Oka, hogy a programozó nem érti a hibát és a kódot.

Ezzel a módszerrel olyan új hibákat vezethetnek be, melyeket a teszteléssel nem vesznek észre, így legfeljebb csak akkor derülnek ki, amikor a programozó úgy ítéli, hogy sikerült kijavítania a hibát, és a projekt gépezete működésbe lendül. A taktika nem produktív, ha:

  • Nincsenek könnyen végrehajtható automatizált regressziós tesztek, amelyek lefedik a kódbázist.
  • Nincs tesztvezérelt fejlesztés, így tapasztalati teszteléssel nehéz megállapítani, hogy a releváns esetek többségében működik-e.
  • Nincs verziókezelés (GIT, Mercurial vagy SVN), nincs elmentett megelőző állapot, nincsenek közben mentések sem, így a legrosszabb esetben a régi állapot elvész, pedig lehet, hogy az lenne a legjobb. Sok hibás indítás és javítás történik, mielőtt eléri a megnyugtató végpontot.

Formális verifikáció hiányában a kód minősége nem biztosított.

Oka, hogy a programozó nem érti a hibát, nem érti, hogy miért csinálja a kód azt, amit. Ennek oka lehet az API nem megfelelő dokumentációja. Mások a referencia kódot másolják át, amiről azt hiszik, hogy korrekt, pedig lehet, hogy az is próba-szerencse módon készült.

Bizonyos esetekben a programozó tudja igazolni, hogy a többi lehetséges permutáció, változat közül az egyiknek működnie kell, akkor megtalálhatja azt a változatot, amiről utólag igazolhatja, hogy az a legjobb.

Példa[szerkesztés]

Az alábbi C példa célja, hogy megtalálja számjegyek egy sorozatát egy hosszabb stringben, és kimásolja őket; de több problémától is szenved:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(void)
{
    const char* buffer = "123abc";
    char destination[10];
    int i = 0;
    int j = 0;
    int l = strlen(buffer);

    while (i < l) {
        if (isdigit(buffer[i])) {
            destination[j++] = buffer[i++];
        }
        ++i;
    }

    destination[j] = '\0';
    printf("%s\n", destination);
}

Először is, nem a jó választ adja. A kódban megadott stringet használva "13", míg a korrekt válasz "123". Aki nem veszi észre a szerkezeti problémát, az egy utasításra áll rá, mondva, hogy van egy extra növelés. Eltávolítja a "++i" sort, de a teszt végtelen ciklust eredményez. Visszateszi a ++i sort, majd eltávolítja az előzetes növelést a buffer[i++]-ből:

    if (isdigit(buffer[i])) {
        destination[j++] = buffer[i];
    }

Ezután már megkapja a korrekt választ, és megkönnyebbülten befejezi a kódolást.

További tesztek különféle stringekkel azt mutatják, hogy a kód még nem jó:

  • Ha a bemenetben több szám van, akkor a kimenetbe bekerül az összes számjegy, például "123ab456"-ból kapjuk, hogy "123456".
  • Ha a bemenő string hosszabb, mint a buffer, akkor a buffer túlcsordul.
  • Ha a bemenő string hosszabb, mint INT_MAX, akkor a viselkedés nem definiált. Ennek oka, hogy strlen() unsigned int számot ad vissza, ami így nagyobb lehet a maximális intnél.
  • Ha a char előjeles, és a string olyan karaktereket tartalmaz, amelyek nincsenek a 0..UCHAR_MAX tartományban, az isdigit() viselkedése definiálatlan.

Míg a megoldás sok stringre működik, nem egészen korrekt, és mivel nem sikerült megérteni a kódot, a hibák felderítetlenek maradnak egészen egy későbbi tesztfázisig.[1]

Jegyzetek[szerkesztés]

  1. (1987. április 21.) „{{{title}}}” 21, 78. o, Kiadó: University of Michigan.  

Fordítás[szerkesztés]

Ez a szócikk részben vagy egészben a Programming by permutation című angol Wikipédia-szócikk fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.