6.1 Debugging mint folyamat

← 6. Debugging gondolkodásmód

6.1 A debugging mint gondolkodási folyamat – nem varázslat

Áttekintő

Ha azt látod, hogy egy senior fejlesztő 10 perc alatt megtalál egy hibát, amit te két óra alatt sem találtál meg – ne azt gondold, hogy ő több éves tapasztalatból „megérzi" a megoldást. Szinte biztosan nem. Amit csinál: egy jól begyakorolt, szisztematikus folyamatot követ. Ezt a folyamatot te is megtanulhatod – és meg is kell tanulnod, mert ez az egyik legtöbbet hasznosított skill az egész fejlesztői pályán.

A debugging nem misztérium és nem varázslat. Tudományos módszer. Megfigyelés, hipotézis, tesztelés, következtetés – ugyanaz a logika, amit a természettudományos gondolkodás alapjaként tanítanak. Csak éppen nem laboratóriumban, hanem egy szövegszerkesztőben.

Ez az alfejezet arról szól, hogyan gondolkodj hibakeresés közben – mielőtt bármilyen eszközhöz nyúlnál.


Részletes leírás

A legdrágább debugging anti-pattern: a random módosítás

Ismerős a helyzet? Nem működik a kód. Nem tudod pontosan miért. De „megpróbálod" ezt-azt – átírod az egyik sort, mozgatod a feltételt, kommenteled ki a blokkot. Ha megjavul, örülsz. Ha nem, próbálkozol tovább.

Ez a random módosítás anti-pattern, és a következő okok miatt veszélyes:

  • Nem tanulsz belőle. Ha véletlenül megjavul, nem tudod, miért. Legközelebb ugyanúgy elveszel.
  • Elronthatod, ami működött. Módosítások közben mellékhatásokat vezetsz be, és hamarabb kerülsz mélyebb bajba.
  • Időt pazarol. Exponenciálisan. Két óra random próbálgatás sokszor megoldható lett volna 20 perc szisztematikus gondolkodással.
  • Csökkenti a magabiztosságodat. Ha nem érted, miért javult meg a hiba, a következő hibánál ugyanolyan tanácstalan leszel.

A senior fejlesztők nem azért gyorsabbak, mert több szintaxist tudnak fejből. Azért, mert nem pazarolnak időt céltalanul – van egy folyamatuk.


A tudományos módszer alkalmazva debuggingra

A klasszikus tudományos módszer négy lépése:

  1. Megfigyelés – Mi történik pontosan?
  2. Hipotézis – Mi okozhatja ezt?
  3. Kísérlet – Hogyan ellenőrzöm a hipotézist?
  4. Következtetés – Igazolódott vagy megcáfolódott?

Debuggingra lefordítva:

1. Megfigyelés – Mi a pontos hibajelenség?

Mielőtt bármit tennél, pontosan fogalmazd meg, mi a baj. Nem elég, hogy „nem működik". Például:

  • Mi az elvárt viselkedés?
  • Mi a tényleges viselkedés?
  • Mikor jelenik meg a hiba? Mindig? Bizonyos feltételek mellett?
  • Mi volt az utolsó változtatás a kódban?

Minél pontosabb a megfigyelés, annál jobban célzott lesz a hipotézis.

2. Hipotézis – Mi okozhatja?

Egy hipotézis egy konkrét, ellenőrizhető feltételezés. Nem „valami elromlott", hanem „valószínűleg az adatbázis-kapcsolat timeout-ol, mert a lekérdezés 30 másodperc után üres eredménnyel tér vissza".

Jó hipotézis jellemzői:

  • Specifikus (nem általános)
  • Ellenőrizhető (le tudod tesztelni)
  • Indokolt (a megfigyelésből következik, nem a levegőből jött)

Ha egyszerre több hipotézised van (és ez normális), rangsorold őket valószínűség szerint – a legvalószínűbbet teszteld először.

3. Kísérlet – Hogyan ellenőrzöm?

A kísérlet célja egy hipotézis igazolása vagy megcáfolása – nem a hiba megjavítása. Ez fontos különbség.

Tesztelési módszerek:

  • Logolás hozzáadása – mi az értéke ennek a változónak ezen a ponton?
  • A kód egy részének izolálása – ha kiveszem ezt, eltűnik a hiba?
  • Reprodukálás különböző feltételekkel – csak nagy adatnál jelenik meg?
  • Debugger futtatása – hol változik meg az érték?

Fontos: egy kísérlet, egy hipotézis. Ha egyszerre három dolgot változtatsz, nem fogod tudni, melyik segített.

4. Következtetés – Mit tanultam?

A kísérlet vagy igazolta a hipotézist, vagy megcáfolta. Mindkét eset hasznos:

  • Igazolva: Megtaláltad a hibaforrást. Most már javíthatsz.
  • Megcáfolva: Kizártál egy lehetséges okot. Ez is haladás – visszalépj és fogalmazz meg új hipotézist.

Türelem és szisztematikusság – az igazi skill

A debugging közben érzett frusztráció teljesen normális. De a türelmetlenség vezet a random próbálgatáshoz. Amikor azt érzed, hogy „csak próbáljuk ki, hátha" – ez a jele, hogy vissza kell lépni.

Néhány praktikus gondolat:

„Biztos vagyok benne, hogy tudom, hol a hiba" Ritkán igaz. A leggyakoribb hibakeresési csapda, hogy egy feltételezéssel elindulsz, és minden mást figyelmen kívül hagysz. Kérdezd meg magadtól: hogyan bizonyítanám be, hogy igazam van?

„Már rég nézem ezt, nem látom a megoldást" Ez nem azt jelenti, hogy hülye vagy. Azt jelenti, hogy a szemed és az agyad megszokta, amit lát – és átugorja a hibát. Legjobb döntés: szünet, vagy más szempontból nézd meg (rubber duck debugging – magyarázd el a kódot egy képzeletbeli kacsának).

„Majd megoldom gyorsan" Ha 15-20 perc után nem közelebb a megoldás, változtass stratégián. Nem érdemes tovább menni ugyanazon az úton.


A debugging gondolkodásmód összefoglalva

Hibajelenség észlelése
       ↓
Pontos megfigyelés (mi, mikor, milyen körülmények)
       ↓
Hipotézis megfogalmazása (mi okozhatja?)
       ↓
Hipotézis tesztelése (egy változtatás, egy teszt)
       ↓
Következtetés levonása
  ├── Igazolva → Hiba megtalálva → Javítás
  └── Megcáfolva → Új hipotézis megfogalmazása

Életszerű példák

Példa 1: A bejelentkezés nem működik

Hibajelentés: „Nem tudok belépni az oldalra."

Rossz megközelítés (random módosítás): Valaki átírja a session kezelés kódját, mert „gondolja, ott lehet valami". Közben a hiba az volt, hogy a form action URL-je egy régi végpontra mutatott.

Jó megközelítés:

Megfigyelés: A bejelentkezési gomb megnyomásakor mi történik pontosan? A böngésző Network tabján milyen kérés megy el? Milyen válasz érkezik vissza?

Hipotézis: A hálózati tab azt mutatja, hogy 404-es választ kap a kérés. Valószínűleg a request rossz URL-re megy.

Kísérlet: Megnézem a form action attribútumát és összehasonlítom az elérhető route-okkal.

Következtetés: Az action egy régi, már nem létező végpontra mutat. Javítás: a helyes URL-re cserélni.


Példa 2: Az API időnként üres listát ad vissza

Hibajelentés: „Néha nem jön vissza semmi az API-tól."

Rossz megközelítés: Valaki caching réteget von be „mert talán az okozza", majd adatbázis indexet is hozzáad, majd az API timeout értéket növeli – és mindeközben nem tudja, mi a tényleges ok.

Jó megközelítés:

Megfigyelés: Mikor jelenik meg? Minden felhasználónál? Bizonyos szűrési feltételek mellett? Az üres lista 200-as vagy más státuszkóddal érkezik?

Hipotézis: Az üres lista csak akkor jelenik meg, ha a szűrő paraméter üres string. Valószínűleg a lekérdezés nem kezeli az üres string esetét, és nem talál egyező rekordot.

Kísérlet: Küldök egy kérést szándékosan üres szűrőparaméterrel, és nézem a generált SQL lekérdezést a logban.

Következtetés: A lekérdezés WHERE name = '' feltétellel fut üres string esetén – és valóban nulla rekordot talál. Javítás: üres string esetén ne adjuk hozzá a szűrőfeltételt.


Példa 3: Éjjel tört el, reggel nem tudjuk, miért

Helyzet: A staging szerveren reggel nem indul el az alkalmazás. Tegnap este még működött.

Jó megközelítés:

Megfigyelés: Mi a hibaüzenet az indításkor? (Ne kézzel próbálgass – nézd a logot.)

Hipotézis (a hibaüzenet alapján): ModuleNotFoundError: No module named 'requests' – valószínűleg éjjel futott egy automatikus dependency frissítés, ami eltávolított egy csomagot, vagy egy requirements.txt változtatás nem volt visszafelé kompatibilis.

Kísérlet: Megnézem a git historyt: volt-e változtatás a requirements.txt-ben az utóbbi 12 órában? Megnézem a szerver logjait: volt-e automatikus folyamat?

Következtetés: A CI pipeline tegnap este éjfélkor lefutott, és egy dependency verziókonfliktus miatt a requests könyvtár eltávolításra került. Javítás: a verziópinning helyreállítása.


Tesztfeladatok

1. feladat – Sorrendbe állítás

Az alábbi debugging lépések összekeverve szerepelnek. Rendezd sorba őket a helyes sorrendnek megfelelően!

  • [ ] Logolást adok hozzá az érintett kódhoz, hogy lássam a változó értékét futásidőben
  • [ ] Észreveszem, hogy a felhasználói profil oldal üres adatokat jelenít meg
  • [ ] Megnézem, hogy a logból mit kaptam – igazolódott vagy megcáfolódott a hipotézisem?
  • [ ] Megfogalmazom: valószínűleg az API hívás nem a helyes user ID-t küldi

Helyes sorrend: %%MANUAL_HELP_NEEDED%% (ellenőrizd, hogy a megjelenítés kérdéses-e)

Megoldás: 2 → 4 → 1 → 3


2. feladat – Anti-pattern azonosítása

Melyik az alábbiak közül a random módosítás anti-pattern?

A) „Nézem a stack trace-t, és keresem a saját kódom sorát." B) „Kommentelem ki az egyik blokkot, majd a másikat, aztán megint az elsőt, hátha segít." C) „Loggolom a változó értékét, mielőtt a hibás sor elé kerül." D) „Megkérdezem a kollégát, aki legutóbb szerkesztette ezt a fájlt."

Helyes válasz: B


3. feladat – Jó hipotézis kiválasztása

Adott a következő hibajelenség: „Az alkalmazás csak bejelentkezés után lassul le."

Melyik hipotézis a legjobb (legspecifikusabb és legellenőrizhetőbb)?

A) „Valami nincs rendben a kóddal." B) „Valószínűleg a bejelentkezési folyamat lassú." C) „Bejelentkezés után a felhasználói adatokat betöltő lekérdezés valószínűleg minden requestnél lefut, és nincs cache-elve – ez okozhatja a lassulást." D) „Lehet, hogy a szerver valami mást csinál közben."

Helyes válasz: C – ez specifikus, ellenőrizhető és a megfigyelésből következik.


4. feladat – Egy kísérlet, egy hipotézis

Anikó azt tapasztalja, hogy az alkalmazás adatfeldolgozó funkciója nagy fájloknál hibát dob. Egyszerre a következő változtatásokat teszi:

  • Növeli a PHP memory_limit értékét
  • Átvált szinkron feldolgozásról aszinkronra
  • Hozzáad egy try-catch blokkot

Ezután a hiba eltűnik. Mi a probléma ezzel a megközelítéssel?

Helyes válasz: Anikó nem tudja megmondani, melyik változtatás oldotta meg a hibát – vagy esetleg mindhárom kellett, esetleg csak egy. Ha a jövőben hasonló hiba jelenik meg, ugyanolyan tanácstalan lesz. Ráadásul két felesleges változtatást is bevitt a kódba, amelyek mellékhatásokat okozhatnak.


5. feladat – Megfigyelés minősége

Olvasd el az alábbi hibaleírásokat, és értékeld, melyik a legjobb kiindulópont a debugging folyamathoz!

A) „Nem működik a kosár." B) „A termék hozzáadása gombra kattintáskor a kosár nem frissül, a böngésző konzolján Uncaught TypeError: Cannot read properties of undefined (reading 'push') hibaüzenet jelenik meg, és csak bejelentkezett felhasználóknál reprodukálható." C) „Valaki elrontotta a kosarat." D) „Néha nem működik."

Helyes válasz: B – pontos hibaüzenet, pontos körülmény (bejelentkezett felhasználók), pontos szimptóma (a hibajelzés helye).


6. feladat – Következtetés levonása

Bence azt feltételezi, hogy egy lassú API endpoint azért lassú, mert az adatbázis-lekérdezés nem indexelt. Fut egy EXPLAIN parancsot az adatbázisban, és az megmutatja, hogy a lekérdezés valóban full table scan-t végez egy 500.000 soros táblán. Mit jelent ez a következtetés szempontjából?

A) A hipotézis megcáfolódott – más okot kell keresni. B) A hipotézis igazolódott – hozzáadhat egy indexet és mérheti a javulást. C) A hipotézis részben igazolódott – más tesztet is kell futtatni mielőtt bármit tesz. D) A EXPLAIN parancs nem ad elég információt.

Helyes válasz: B


7. feladat – Mikor lépj vissza?

Döntsd el, hogy az alábbi szituációkban melyik a helyes lépés!

Szituáció: Már 45 perce keresed a hibát. Az utolsó 20 percben három különböző helyen módosítottál a kódon, de a hiba megmaradt. Egyre frusztráltabb vagy.

Melyik döntés a leghelyesebb?

A) Folytatod – közel lehetsz a megoldáshoz. B) Visszavonod az összes változtatást, pontosan megfogalmazod a hibajelenséget, és felírasz 2-3 konkrét hipotézist mielőtt bármit módosítasz. C) Átírod az egész érintett modult – biztosan lesz benne a hiba. D) Megkérsz valakit, hogy csinálja meg helyetted.

Helyes válasz: B – a random próbálgatás megállítása és visszatérés a szisztematikus módszerhez.


8. feladat – Rubber duck debugging

Mi a rubber duck debugging lényege és miért működik?

A) Egy speciális debugger eszköz, ami automatikusan megtalálja a hibát. B) Amikor valakinek elmagyarázod a kódot vagy a problémát (akár egy tárgynak), kénytelen vagy pontosan fogalmazni – és ez a pontosság gyakran magától megmutatja a hibát. C) Fizikai pihenő a monitor előtt, hogy friss szemmel nézhesd a kódot. D) Egy agilis módszertan, amelyet páros programozáshoz fejlesztettek ki.

Helyes válasz: B


9. feladat – Hipotézis rangsorolása

Az alkalmazás elküld egy e-mailt regisztrációkor, de az e-mail néha nem érkezik meg. Az alábbi hipotézisek közül melyiket tesztelné először egy szisztematikus fejlesztő és miért?

A) Az e-mail szerver szoftverében van egy ismeretlen bug. B) Az e-mail tartalom SPAM szűrőbe kerül. C) A kód nem hívja meg az e-mail küldő függvényt bizonyos esetekben. D) A felhasználók nem nézik meg a SPAM mappájukat.

Helyes válasz: C – ez a legközelebbi és legellenőrizhetőbb hipotézis, amit a saját kódban lehet igazolni vagy megcáfolni. A többi feltételezés külső rendszerektől függ. A logból egyértelműen látható, hogy a függvény meghívódik-e.


10. feladat – Összetett szituáció

Olivér a következő hibát tapasztalja: egy webshopban a "Kedvencekhez adás" gomb kattintásra nem reagál mobilon, de asztali böngészőben működik. Írj egy rövid debugging tervet a tudományos módszer alapján!

Elvárás: 4 lépés (megfigyelés, hipotézis, kísérlet, következtetés iránya).

Mintaválasz:

Megfigyelés: A gomb mobilon (Safari iOS / Chrome Android) nem reagál kattintásra. Asztali Chromeben és Firefoxben működik. A böngésző konzolján nincs hibaüzenet mobilon.

Hipotézis: Mobilon a kattintás esemény nem tüzel – valószínűleg a gomb felett van egy láthatatlan elem, ami elfogja az érintést (z-index / overlay probléma), vagy a touch event nincs megfelelően kezelve.

Kísérlet: Mobilon DevTools-ban (remote debugging) megnézem az elemek z-index értékét és az eseményfigyelőket a gombra. Ellenőrzöm, hogy van-e overlay elem a gomb felett.

Következtetés iránya: Ha overlay van → azt kell eltávolítani vagy z-index sorrendet javítani. Ha nincs overlay → az eseménykezelőt kell megvizsgálni, van-e touchstart esemény regisztrálva.

Scroll to Top