Blog
Skip to end of metadata
Go to start of metadata

Szinte mindenki tudna mesélni elrettentő példákat, amelyekkel pályafutása során találkozik, esetleg önmaga követ el szándékosan vagy véletlenül. Egy blogbejegyzésben Code of Horror címmel bukkanhatunk egy kisebb gyűjteményre, amely - alkattól függően - mosolyt, röhögögörcsöt vagy maradandó szemöldökrángást okozhat... Néhány szemelvény a hibakezelést illetően:

Java forrás
try
{
  // Itt pár sor programunk van
}
catch (Exception e)
{
  throw e;
}

Ennek egy javított verziója:

Java forrás
try
{
  // Ismét pár sor program
}
catch (Exception e)
{
}

Esetleg egy kis hiányosság a referenciákat illetően:

Java forrás
X x=new X();
x.list.add("...");
X y=x;
x.list=null;
y.list.add("...");
      
      
Page viewed times

36 Comments

  1. Auth Gábor AUTHOR

    Én is tudnék mesélni... ha mindazt felírtam volna, amit 7 év alatt a diákok elkövettek... :)

    De azért én se panaszkodhatok... utoljára fél órán át néztem az alábbi (egyszerűsített :) ciklust, és nem jöttem rá, hogy miért nem hajtja végre a ciklusmagot:

    for ( int count=0; list.size()<count; count++ )
    {
      // [...]
    }

    Van ilyen, nemde? (smile)

    1. Megesik az iesmi! Sajna nem lehet egyből ugy kezdeni mint egy Senior. :)
  2. Én a következő hibákat szoktam elkövetni:
    - elírok valamit a javascript-ben, és az egész oldal működésképtelenné válik, majd fél óráig nyomozok az IE hibaüzenetek alapján
    - elírom a JDBC-ben lévő SQL lekérdezést, amit előszörre megpróbálok javítani, de aztán kénytelen vagyok lenyomkövetni a query string-et, és egy külön DB ablakban megtudni, hogy mégis melyik karakternél van a szintaxis hiba
    - nagy ritkán, amikor csökkenő ciklust írok, zsigerből "i++"-ra veszem a ciklusváltozót. De persze ennek hatása hamar kiderül úgyhogy kill program

    1. Ami szintén gyakori 'hibám':

      catch(Exception ex)
      {
      }

      Valamikor üresen, valamikor egy vacak ex.printStackTrace(), vagy netán System.out.println :)

  3. Én nem nagyon szoktam programot írni, de olvasni elég sokat. Küldöm a legújabb gyöngyszemet, igaz, nem java, hanem C++, de szerintem érthető lesz, blabla.cpp:

    while(true) {
      try {
       // itt van egy csomo kod, ami nem erdekes es meg jol is mukodik
      }
      catch(...) {
        while(1)
          log << "thread = " << tc->id << log;
      }
    }

    Egyébként meg: http://worsethanfailure.com/Series/CodeSOD.aspx

    Egész sok bejegyzés származik tőlem :-p

  4. Unknown User (finrod)

    Nem en csinaltam, de nekem kellett megkeresnem a kovetkezo dolog kovetkezmenyenek az okat. A kovetkezmeny: IBM JDK 1.1.8-as verzio, szerver memoria foglalasa az egeket veri, a billentyuzetre (a szerver gep sajat billentyuzetere!!!) a szerver masodpercek alatt reagal, a webes rendszer gyakorlatilag nem valaszol, timeoutol, a top 90% feletti system CPU-foglaltsagot mutat. Az ok egy ilyesmi jellegu programresz volt (egyszerre tobb szalon is futott):

    String s="...";
    for (int i=0; i<10000; ++i) {
      s += "asdasd";
    }
    // s-el valamit csinalunk....

    Termeszetesen nem ilyen ertelmetlen kod volt, hanem egy olyan ami egy anonim blokkot rakott ossze. De a string osszerakasahoz a memoria footprint tobb szaz mega volt szalankent, es akkoriban ez (alloc, realloc) meg heveny kernel modu cpu hasznalattal jart.

  5. Ha mar ilyenekrol beszelunk, anno en is belfutottam egy nagyon szepseges kodba:

    public class Handler {
      public void handle(int handleType, Map request) {
        switch (handleType) {
          //...
        }
      }
    }

    Ez nem is lenne furcsa, de az a switch kb 2000 sor volt. Ez itt egy program kommunikacios alrendszere volt. Kb 2 hetig gyozkodtem a kollegat, hogy valami minimalis Registry/Factory megoldasra refaktoraljuk at a dolgot.

  6. Légyszi, magyarázzátok el, hogy mi a baj a cikkben szereplő utolsó kóddal, mert úgy látszik, hülye vagyok. Van egy közös lista objektum amire lesz 2 referencia: list és list2. Maga az objektum nem fog megszűnni a list=null után, mivel van még rá még1 ref.

    1. Unknown User (zsiga.peter)

      Mivel mindekét objektum ugyanarra a referenciára mutat, ezért ha list=null, akkor list2 is egyelő lesz null-lal, s ha később a kódban még használjuk list2-t akkor gáz van.

    2. Unknown User (zsiga.peter)

      Az előbb hülyeséget írtam! Valóban nem nullázódik ki a list2 csak a list, a referencia megmarad.
      1. Probléma esetleg akkor lehet, ha a programozó úgy gondolkodik, hogy ezzel felszabadította az objektumot és list2 is null ref lesz. De ilyet én még munka közben sosem láttam.

        1. Unknown User (zsiga.peter)

          Még én sem láttam ilyet, de ezek szerint valahol már előfordult.
          1. Auth Gábor AUTHOR

            Valóban... viszont megnéztem az eredeti forrást, ahol nem ez van... nem tudok rá magyarázatot, hogy miért azt írtam a hírbe, amit... :)

            Az eredeti helyen ilyesmi van:

            X x=new X();
            x.list.add("...");
            X y=x;
            x.list=null;
            y.list.add("...");

            Na, így már jobb, nem? :)

            1. Auth Gábor AUTHOR

              Javítottam a cikkben is... :)

              Így már igaz az elrettentő példa?

  7. Egy kolléga kódjában találtam, szörnyülködjetek ti is:

    for(int c=0;c<=2;c++) {
      switch (c) {
      case 0:
        // ...
      case 1:
        // ...
      case 2:
        // ...
      }
    }
    1. Unknown User (frimen)

      Egy kolléga kódjában találtam, szörnyülködjetek ti is:

      Ezen nincs mit szörnyülködni, vannak bizonyos szituk, aminél még cifrább soroknak is van értelme.. saját kód, hasonló és még cifrább:

      for (int j = 1; j < 3; j++) {
        for (int i = 0; i < x.length; i++) {
          if (x[i] != null) {
            switch (valami(x[i])) {
              case 0:
                // stb.
              default:
                y = kakukk();
                switch (valami(y)) {
                  case 0:
                    // stb.
                }
              }
            }
          }
        }
      }

      Persze leegyszerűsitve... Ezzel a szörnyülködös szerkezettel 70 sorbol oldottam meg, amit 600-bol sem tudtam volna fele ilyen rugalmasan.. lehet szörnyűlködni. :)

      Szóval nyugtával dicsérd a kodot.

      1. Unknown User (frimen)

        Amit meg lefejeltem... ha a "hozott" kódban van break vagy continue, akkor végképp nem feltétlenül  szörnyülködni való.

      2. Ezen nincs mit szörnyűlködni

        De, van. A pontpontpot helyén ugyanis csak ennyi állt:

        bean.setValami(rs.getString(c));
        break;

        igy lehet valamit 3 sor helyett 15-tel leirni. Es nem ertette mi vele a baj.

  8. Ezt ma láttam kódfelülvizsgálat közben:

    try {
      // ....
    } catch (Throwable th) {
      if (th instanceof SOAException) {
        throw new SajatValamilyenException();
      }
    }
    1. Well... Ha eltekintünk az egyszerűbb megoldás létezésétől a Throwable elkapása még mindig nem tűnik annyira jó ötletnek...

  9. Unknown User (crystal)

    catch(Exception ex) { }

    Ezzel mi a baj? Én is szoktam, nem tudom miért ne, ha a blokkon belül többféle kivétel is keletkezhet és egyikkel sem akarok különösebben mitkezdeni... de lehet csak én vok nagyon láma :)

    1. Legalább egy printStackTrace vagy egy "garantáltan sosem fordul elő / nem kell kezelni" komment kell oda.

      Itt a fórumban is volt nem egy olyan kérdés, hogy miért nem működik a kód és ott volt egy üres catch blokk. Persze a stackTrace alapján 2 másodperc alatt meg lehet mondani hol a hiba, de gondolom a srác pörgött már rajta pár órája mire beírta a fórumba.

      1. Unknown User (crystal)

        ja hát igen, mostanában már mindig beírkálom az ex.printStackTrace()-eket :)

        mondjuk ettől függetlenül nem tartom olyan hajmeresztő hibának, ha valaki nem írja be :)

        1. Unknown User (zsiga.peter)

          Múltkor pont emiatt "törtem el" egy kollega kezét:) catch ágat üresen hagyta(gondolta nincs jelentősége loggolni), de amiatt, hogy itt exceptionre futott a kód kb. 10 osztállyal később egy újabb exceptionre dobott a program, vagy 2 napig tartott, mire kiderült a hiba oka, mivel a logban nem volt semmi ami erre utal.

          Kis projekteknél annyira nem nagy gond, de nagy projekteknél életveszélyes lehet.

  10. Integer i = Integer.parseInt("1");
  11. Fő a biztonság!

    public class A {
        public String s1 = null;
        public String s2 = null;
        // ...
    }
    1. Csak kioptimalizalt 2 fuggvenyhivast, igy gyorsabb es kisebb a program.
      1. Unknown User ((k)risztián)

        En valami java performance tuningos izeben azt olvastam hogy a String p=new String(""); a legoptimalisabb persze akkor meg csak 1.4-nel jart a verzio es gyanitom hogy meg regebbivel "mertek"....

        1. Erdekes, 6-os javaban nekem ugy tunik, hogy a String s = "" gyorsabbnak, es kisebbnek tunik, mint a String("").

          Erdemben is hozzaszolnek a topichoz. Nehany honapja talaltam a ceges repoban egy erdekes php kodot:

          //fingom sincs miez
          echo __FILE__;

          Ez volt a teljes tartalma a filenak. Egy masik gyonyoruseg(js):

          function nothing() {}
      2. zmb: Megvoltak a getterek is, ráadásul singleton mintát használva. (!)

        A hangsúlyt a ’=null’ -ra akartam helyezni. Nem oszt nem szoroz, de azért sokat elmond hogy ott van.

        A String s=""; és a new String(""); némileg mást csinál. Az utóbbi mindenképpen létrehoz egy új String példányt, az előbbi pedig megkeresi az eddig létező String-ek között. (Vagy legalábbis megkeresheti, vagy eleve úgy van összerakva a class fájl hogy ugyanazt a konstansot használja a két értékadás a konstans pool-ból.) Sokminden függvénye hogy melyik a gyorsabb, de szerintem ma már a String s = "valami" a versenyképesebb.

        1. Unknown User ((k)risztián)

          Ezek szerint ha tenyleg teljesen uj stringet kell lettrehozni akkor a new String("") megtakaritja a keresest ha viszont valamelyik resze letezik ez csak a "" lenne ha az valami hivatkozaskent kerul atadasra mert a deklaracio miatt a peldany meg nem letezhet akkor az ertekadas tunik jobbnak az elmeletek alapjan...

          1. Ha már String-ekről van szó, éppen most olvastam egy szép "memory leak" lehetőséget. A lényeg: a String.substring() nem csinál egy új String-et, hanem az eredeti String karaktertömbjére mutat és offset, length-tel jelöli ki a részstring-et belőle. Ez jó gyors, viszont nem engedi eldobni az eredeti String-et, ami nem kizárt hogy jó hosszú.

    2. Unknown User (frimen)

      tvik, ne haragudj, de hülyeség amit irtál.

      Nagyon sok esetben érdemes "null" értéket adni egy Stringnek (és másoknak) mivel ha nem adsz semmilyen értéket és valamiért vizsgálni kell azt, olyan szép exception-t dob a kódod ahogy kell. Abban igazad van, hogy ez tényleg a biztonság miatt kell. :)

      1. Lokális változókat kell inicializálni, mert különben fordítási hiba keletkezik.

        Mezőket nem kell inicializálni, mert - a C-nyelvtől eltérően - implicite megtörténik, azaz magától null (0, 0.0, false, ...) értéket kapnak.

        Ha valaki értékkel akar inicializálni mezőt, pl. public String s = ""; az tervezési kérdés. Itt most konkrétan a public String = null; -ról volt szó.

        1. Unknown User (frimen)

          megkövetlek.:)

          Látszik, hogy jó pár hónapja a közelébe se szagoltam a java-nak... :)

  12. Nekem mindig az az elrettentő‘ példa jut eszembe amikor programozó kollégám minden programjában mindig ezeket a változó neveket adta: v1, v2, ..., vN

    Vagyis ha megpróbálok az ő fejével gondolkodni: azért "v" mert változó, tehát az első‘ betű csak ez lehet mivelhogy VÁLTOZÓ, és ugyebár csak kell adni néki egy sorszámot hogy hanyadik.

    A szívás akkor van ha már van a programban v1...v38 és közben rájön hogy a v17-re nincs szüksége. Mert ha a kolléga precíz akkor átnevezi a v18...v38 változókat mindegyiket 1-gyel kisebb számra, mert ugye lyuk nem maradhat, de az is lehet hogy csak a v38-at nevezi át v17-re. Ha pedig más programjába javít és azt látja hogy holt szar változónevek vannak pl: szemelySzuletes, akkor elhányja magát és azonnal átnevezi v543-ra, majd a bigboss-hoz rohan hogy ilyen primitív ember programjába a büdös életbe nem fog többet belenyúlni...

#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))