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
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:
Van ilyen, nemde?
Szőnyi Mihály
Karnok Dávid
É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
Karnok Dávid
Ami szintén gyakori 'hibám':
Valamikor üresen, valamikor egy vacak ex.printStackTrace(), vagy netán System.out.println :)
Mezei Zoltán
É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:
Egyébként meg: http://worsethanfailure.com/Series/CodeSOD.aspx
Egész sok bejegyzés származik tőlem :-p
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):
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.
Böszörményi Péter
Ha mar ilyenekrol beszelunk, anno en is belfutottam egy nagyon szepseges kodba:
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.
Dolphy
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.
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.
Unknown User (zsiga.peter)
Dolphy
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.
Unknown User (zsiga.peter)
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:
Na, így már jobb, nem? :)
Auth Gábor AUTHOR
Javítottam a cikkben is... :)
Így már igaz az elrettentő példa?
Cserép János
Egy kolléga kódjában találtam, szörnyülködjetek ti is:
Unknown User (frimen)
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:
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.
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ó.
Cserép János
De, van. A pontpontpot helyén ugyanis csak ennyi állt:
igy lehet valamit 3 sor helyett 15-tel leirni. Es nem ertette mi vele a baj.
Czimmermann Gábor
Ezt ma láttam kódfelülvizsgálat közben:
Mezei Zoltán
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...
Unknown User (crystal)
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 :)
tvik
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.
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 :)
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.
tvik
tvik
Fő a biztonság!
Böszörményi Péter
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"....
Böszörményi Péter
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:
Ez volt a teljes tartalma a filenak. Egy masik gyonyoruseg(js):
tvik
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.
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...
tvik
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ú.
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. :)
tvik
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ó.
Unknown User (frimen)
megkövetlek.:)
Látszik, hogy jó pár hónapja a közelébe se szagoltam a java-nak... :)
Keresztes József (xesj.hu)
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...