Amatőr webfejlesztő

Másfél évtizede vagyok része a webfejlesztés világának. Korábban egyszerű HTML oldalak még talán mentek, de munkahelyi ártalomból kénytelen voltam jobban megismerni a dinamikus weboldalak fejlesztésének világát. Mint oly’ sokan, én is a hülyék scriptnyelvével kezdtem – a PHP-val – amit a mai napig is művelek, de még mindig amatőr szinten. Persze itt most ki leszek oktatva, hogy amatőr az, aki ingyen csinálja, profi pedig az, aki pénzért.

A kezdetek

Amikor megismerkedtem a dinamikus webfejlesztés világával, még nagyon gyerekcipőben járt, jellemzően picike weboldalak és minden az egyben portálok készültek ilyen módon. Új munkahelyem miatt volt 2 napom arra, hogy az alapokat elsajátíthassam ami nem professzionális képzésben történt, hanem egy jóbarátom szánt rám pár órát. Ennyi elég is volt az induláshoz. Nem, nem én vagyok ilyen szuper tehetséges, a PHP ennyire könnyen tanulható. Persze az iskolákban ugyanezt 1-2 évig tanítják, nem túl nagy sikerrel. Már ekkor is kényszer volt számomra a webezés, de ha ez kellett a munkáltatónak, akkor meg kellett tanulni.

A betanulás

Természetesen minden kezdő hibát elkövettem, amit csak el lehet követni. Az egyetlen talán ami kimaradt, hogy SQL injectionnel nyomják meg a scriptet. Sohasem voltam jó programozásból, mert nagyon jó memória kell hozzá, nekem pedig 2 másodperces van. Az, hogy komoly matek kell hozzá, totális baromság. A matekra azoknak van szüksége, akik pl. játékokat fejlesztenek, mondjuk az útvonal kereső algoritmusok miatt, vagy mozgások pályaszámításai miatt. Ne add fel a programozás pályát, csak mert nem szereted a matekot.

Kezdetnek egy „egyszerű” feladatom volt: egyből egy ügyviteli rendszerhez kellett hozzáfejleszteni. Irány a mélyvíz. Itt még sikeresen el tudtam kerülni a JavaScriptet, így elég volt a PHP és a HTML minimális ismerete. A mai napig visszasírom a PHP .chm formátumban letölthető helpjét, de a php.net weboldalon található help is az egyik legjobb ami program- vagy scriptnyelvekhez elérhető. Szépen be voltak kategorizálva a függvények, így gyorsan meg lehetett találni, amire szükségem volt. A procedurális PHP fejlesztés szuper jól tanulható, mai szemmel persze már elavultnak hat, de szinte mindent meg lehet benne csinálni.

A hobbi

A következő munkahelyen már nem volt elvárás a webes fejlesztés, így átment hobbiba a dolog. Felhagyni vele nem tudtam, mert a kezdetekben írt portálmotoron futott egy hírportál (ami a mai napon még mindig 98%-ban ugyanazon a kódon fut, de már nem sokáig).

Mivel a PHP volt az egyetlen nyelv amit ismertem, kénytelen voltam mindent PHP-val megcsinálni rendszergazdaként. Igen-igen, sok olyan dolgot csináltam meg PHP-vel, amire az nem való, vagy nem illik használni. Ez lett a Cisco asztali és WiFi telefonokra írt alkalmazások alatt, figyelte a szabad helyet és a rendszerterheléseket a szervereken, olvasta ki a nyomtatók kellékanyag állapotát, cserélgetett adatot alkalmazások között.

Windows szerver CPU terhelés figyelése (a magok átlagolva vannak a könnyű áttekintés miatt) PHP-vel

Az egyetlen termék amit készítettem egy SOAP webservice-t hívogató webshop volt, amit a mai napig bánok. Kevés időm volt rá, közel sem rendelkeztem a megfelelő tudással hozzá, iszonyatosan csúnya lett a kód és a mai napig kísért (ugyanis több helyen fut Európában, még mindig). Az egyetlen kód, aminek még nevet is adtam, annyira rémisztőre sikerült, Freddy lett, Freddy Krüger után.

Mellékállásban a rendszergadáskodást lassan átváltottam amatőr webezésre, majd eljött az idő, hogy a főállású rendszergazdaságot is elhagyjam. Erre motivált az akkori munkahelyem is és a rendszergazdaság sem a leghálásabb szakma jelenleg.

Miért nem találsz rendszergazdát?

Átvettem egy böngészős játék – a Zandagort –  forráskódját és üzemeltettem azt pár szerveren át. PHP-MySQL-JavaScript technológiákra épült, és nagyon jó tanulási alapnak bizonyult. A mai napig ajánlom bátran mindenkinek. Mindhárom területen nagyon sokat lehet tanulni belőle, mert tele van tipikusan előforduló problémákkal, azok (sokszor szedett-vetett) megoldásaival. Sok mindent lehet rajta optimalizálni, de látványos és kihívásokkal teli.

A fő- és mellékállás

Az új munkák már megkövetelték, hogy kissé magasabb szintre képezzem magam a témában. Szóval jöttek a CSS és JS frameworkök, az objektum-orientáció alapjai és a SELECT/INSERT/UPDATE/DELETE SQL-től kicsit összetettebb adatbázis lekérdezések. Az OOP már nehéz volt a szürnyű memóriámnak. Hiába néztem meg vagy olvastam el egy rakás oktatót, valahogy nem akart megragadni a dolog a fejemben soha, egészen addig, amíg egy új ismerős nem mutatott egy JAVA-hoz készült oktatóvideót a témában.

Tudni kell, hogy a PHP még mindig nagyon-nagyon sok sebből vérzik. Nem alkalmas professzionális dolgokra, még akkor sem, ha nagyon sokan arra használják. A szigorú típusosság részleges hiánya és a hibakezelés káosza, valamint a függvények váratlan – és néha logikátlan – visszatérési értékei egy aknamezővé teszik. Persze ettől még a webezésre az egyik legjobb megoldás.

Már nem volt elég a PHP, nagyon sok JavaScriptre volt szükség, egyre jobban jött a jQuery ismerete, ami a lusta fejlesztők egyik jóbarátja. A megszerezett tudás hatására kissé felbátorodtam és belenéztem a NodeJS-be, valamint az arra épülő megoldásokba, például az Apache Cordova alapú mobil alkalmazás fejlesztésbe. A főállásom egyik feladata is az volt, hogy okosTV-re fejlesszek alkalmazást (TizenOS – Samsung és WebOS – LG), azt is JavaScript alapon.

Hatalmas hibákat követtem el azzal, hogy hallgattam a profikra. A PHP és a NodeJS területén is. Most már tudom, hogy a PHP-t nem szabad úgy kezelni, mint a .NET-et vagy a JAVA-t, hogy még a „primitív” adattípusok is objektumok, metódusokkal (igen, tudom, valódi primitívként is léteznek). Nem szabad mindent abba erőltetni, ráadásul még mindig hiányzik pár dolog, ami ennek a megfelelő kihasználásához kellene. Például még a PHP 7.2-ben sem lehet megadni, hogy egy metódus egy komplex adattípus tömbjét fogadhatja el mint bemeneti paraméter. (Ha mégis van erre lehetőség, valaki mutassa meg legyen szíves, hogyan lehet. ) Sajnos nem szabad követni az ajánlásokat, különben a több hónapja fejlesztett kódban dolgozni olyan lesz, mint bombát hatástalanítani. Szépen fog mutatni az értekezleten, és a GitHubon de ha újra elő kell venni valamiért, akkor lesz baj gazdagon. Főleg akkor, ha az adatbázis mögötte már szépen felhízott.

A csodaszépen megírt, PDO FETCH_CLASS alapú komplex adattípusba lekérések olyan szép ciklusban-ciklusban-ciklusban-ciklusban-ciklust fognak generálni, hogy a MySQL non-stop tartja majd melegen a CPU-t. Persze ez a profi fejlesztőket kicsit sem érdekli, mert szupi a Products::getByCategory( int $category_id = 0 ) , milyen beszédes osztály és metódus név igaz? Milyen kényelmes ezt használni az oldal minden részén, mert praktikus, kéznél van. Csak hát a fekete dobozban valójában egy általánosra megírt SQL kérés van, benne sok-sok kapcsolódó adattal (ki hozta létre, ki szerkesztette, a termék gyártójának kapcsolódó adatai, miegymás). Ez persze csak egy nagyon piti példa volt arra, hogy egy ilyen szép nevű fekete dobozban valójában sok adatbázis kérés is lehet egyszerre. Előbb vagy utóbb ezek a szép metódusok ciklusba kerülnek pl. egy másik komplex adattípusnak köszönhetően, ami tartalmazza ezt, mondjuk Products::getSale( string $category_filter = 'digital' ). Ezek pedig szépen egyre nagyobbra nőnek.

A NodeJS külön fejfájás… Az egész világ próbál mindent ráerőltetni, mert jó a függőség kezelése, non-blocking I/O-s a PHP-val ellentétben (ezért gyors) és elég hozzá az alap JavaScript tudás. Na ja, az alap NodeJS szuper cucc, de a pluginok hozzá nagyon nem. Rengeteg sebből véreznek a bővítmények, bármit csinál az ember, mindig lesz egy unhandled exception. Nincs is attól bosszantóbb, amikor nem az ember saját kódja okozza a hibát, hanem a plugin, amit azért használ, hogy megkönnyítse a munkáját. Nem tudok kibékülni ezzel, hogy a kód 80%-a csak try-catch, de még így sem lehet rátenni egy lélegeztetőgépet. A profi NodeJS scriptek úgy futnak, hogy egy megölhetetlen programként üzemeltetik. Amint elszáll, azonnal újraindítják. Van aki szerint ez pro, szerintem ez gányolás. A pluginok biztonsága is kétes. A legnépszerűbb MySQL pluginban évekig megvolt az SQL sebezhetőségek lehetősége és hamis bizonságérzettel látta el a fejlesztőket, mert a prepare() metódusnév csak egy alias volt az escape()-re, nem volt valódi prepared statement. Sok olyan dolog megbízhatóbban fut sajnos PHP-val, amire a PHP valójában teljesen alkalmatlan. De a NodeJS ettől még tör fel és szinte már elkerülhetetlen. Főleg, mert olyan alkalmazások épülnek az alapjaira, amik bármilyen platformon képesek futni, legyen az MacOS, Windows, iOS, Linux, Android.

A komoly projektek

Egyszer minden fejlesztő eljut oda, hogy ki kell lépni a komfortzónából és megnyer valami több hónaposra nyúló és/vagy kihívásokkal teli projektet. Nekem ebből már több is van, a leglátványosabb talán az LG WebOS alapú TV-re fejlesztés. De ott van még a SOAP szervert hívogató adatszolgáltatás is. Minél több ilyet ismertem meg, annál inkább láttam, hogy nem szabad igényesnek lenni a saját munkára. Össze kell b@szni az egészet a lehető leggyorsabban, behajtani érte a pénzt és vissza se nézni. Minden, amiről azt hittem, hogy igényesen van megcsinálva, mert nagy név van mögötte, egy hatalmas gányolás gyűjtemény. Akár Cisco telefonról beszélünk, akár okosTV-ről. Ennek ellenére viszont az ilyen termékeket előálltó cégek megkövetelik a profizmust tőlünk, fejlesztőktől. Az LG-nél majdnem 1 évig tartott, mire jóváhagytak egy olyan appot, ami max 2 hét alatt készült el, mert belekötöttek olyan dolgokba, amitől minden jóérzésű ember az agyát eldobná: az alkalmazás háttérképének színe 1 azaz egy bittel eltér az alkalmazás ikonjának színétől. Ember nincs aki észreveszi. De még rengeteg ilyen volt, ami nevetséges dolog.

A dokumentációk nagyon szupernek és igényesnek néznek ki, őrült pénzeket ölhettek bele, hogy a prezentációkon nagyon szépen mutassanak de valójában teljesen használhatatlanok. Mindent úgy kell kikísérletezni. A logika és tudatosság teljes hiánya fedezhető fel, a „józan paraszti ész” nyoma sincs a professzionális termékekben. A Samsung TV-ben többször előfordult, hogy a script feltöltése után kilépett a TV-be égetett Chromium böngésző (ebben futnak valójában a webalkalmazások a TizenOS-ben és a WebOS-ben is), és ott voltam bent emelt jogú felhasználóként a TV linux alapú operációs rendszerében. Az LG TV-k esetén a saját JS frameworkjükben orbitális hibák vannak. A hálózati kapcsolat létezésének figyelése egy vicc, saját megoldást kellett rá írni, mert köszönőviszonyban sincs a valós állapottal valamint megesik, hogy lefagy. Apropó lefagyás. Ha az LG TV azonosítóját lekérdezem egy FullHD TV-n az alkalmazás indulásakor (az oldal generálás után!), akkor annyira gyenge a TV-be épített processzor, hogy 4-ből egyszer totál odafagy a gyári metódus. Nem tér vissza semmilyen eventtel. Sem done(), sem success(), sem error(), semmi. Csak vár a végtelenségig. Tudom-tudom, nincs végtelen ciklus, csak gyenge a processzorom.

De ott van egy nagy autógyártó központi szolgáltatás-szervere is. Hat azaz 6 képernyős XML-t kell gyártani ahhoz, hogy 4 azaz négy paramétert küldjek be egy lekérdezéshez. A dokumentáció cserébe hatalmas nagy, és a benne levő linkek 80%-a természetesen döglött.

Ha majd egyszer elérem a profi szintet, talán megértem miért van az, hogy csilli dokumentáció mögé gányolunk valamit. Most pl. megint van egy pro feladathoz megbízásom, de az a feladat, hogy a lehető leggyorsabban hányjam össze és adjam le. Semmi sem számít, csak az, hogy gyorsan legyen kész. Ráadásul olyan dologhoz kell, amiről azt gondoltam, hogy ilyen szinten nagyon nem PHP alapú megoldások vannak, vagy ha mégis, akkor professzionális embereket bíznak meg vele.

LG WebOS emulátor, az egyik ok, amiért a sok magos processzorok léteznek. A másik pedig az LG IDE.

A jövő

Hiába tapasztalok rengeteget, mindig van mit tanulni. A webes világ is megy el mellettem, rengeteg új technológia jön, amit nem is ismerek, vagy évekig nem is tudtam, hogy létezik. A HTML5 nagyon sok API-t hozott be (amik természetesen kicsit mésképpen mennek minden böngészőben), a PHP alapú fejlesztés már nagyon rég nem a natív kódról szól, hanem a framework alapú fröccsöntésről (pl. Laravel), a CSS világban sem lehet élni framework nélkül (Bootstrap), a JavaScript esetén pedig mindenki próbálja megalkotni a világrengető kliens oldali kétirányú adatszinkronizációval rendelkező csodamegoldását (Angular, React, Vue, …). Nem hiszem, hogy egy ember képes lehet ezeket magabiztosan megtanulni. Vagy ha mégis, akkor még most kellene másik szakmát keresnem. Azt látom, hogy átment a fejlesztés divatbemutatóba. Mindent azzal kötelező megcsinálni, ami épp népszerű. Nem baj, ha 3 statikus oldalból áll egy weblap, akkor is kell a Laravel + Angular, mert most az a menő. Natívban betöltődne 20ms alatt, de akkor a látogató nem látná a menő pörgő űrfánkot minden kattintáskor és nem lehetne eladni a 2 foglalatos, 28 magos szervereket.

Úgy döntöttem, hogy követem a dolgok fejlődését, de nem hallgatok a nagyokosokra és megkeresem magamnak azt az irányt, amivel viszonylag jól tudok haladni. A divatmelókat meg el sem vállalom, mert még megtehetem. Sok kísérletezés és tanulás áll még előttem, de nem mondanám egyik technológiára sem, hogy ez a tuti, ez a jövő. Nem vagyok híve a fekete doboz alapú fejlesztésnek, még akkor sem, ha megélni csak abból lehet. Én szeretem tudni mi van abban a dobozban, mi mitől működik. Popcornt ragadok és követem az Angular-Vue-React harcot, a PHP frameworkok felemelkedését és bukását, a blogmotorra hackelt webshopok szárnyalását (WooCommerce), és így tovább. Művelődőm a témákban, de amíg van bőven munkám natívosként, nem töröm kezem-lábam valamiért, ami épp most menő.

Junior webdeveloper

A fejlesztők szintjeinek kategorizálása a legkevésbé sem fedi a tudásszintet. De a jelenleg olvasható állásajánlatok és projektek alapján én úgy érzem, hogy a „junior” szint alatt vagyok picivel. Hiába van 15 évem a dologban, nincs meg a PHP framework ismeretem, így nem lennék piacképes a fejvadászok szemében. A valóságban persze azt látom, hogy a szuper pro cégek kódjai siralmasak, a még professzionálisabb projektek pedig csak a gányolást várják el, csak az idő számít, meg hogy ideális csillagállás esetén fusson a script, a többi senkit sem érdekel. Az adatbázis lekéréséket összevarázsolják ORM-el, senkit sem érdekel, hogy 10ms alatt vagy 10 perc alatt fut-e le. Majd vesznek egy erősebb szervert (hiába, mert úgyis csak 1 threaden fut a lekérdezés jó eséllyel 🙂 ).

Nem tartom magam sem jó, sem képzett fejlesztőnek. Minél több technológia jelenik meg, annál inkább nem. Viszont, amiket 12 éve csináltam, még mindig futnak. Nekem ez elég.

3 Comments

  1. Nagyrészt egyetértek a leírtakkal, szakmai szemmel valóban fájdalmas, ami (főképp a webes-) fejlesztési projektekkel történik. Viszont a szoftverfejlesztői munka nem a minőségről, hanem a gazdaságosságról szól. Minden esetben van egy minőségi igény, amit meg kell ütni, de van egy gazdaságossági határ, amin belül kell maradni a költségekkel. Megrendelői oldalról a szoftver valódi minősége sokszor vagy sokáig nem látható egyértelműen. Amúgy a PHP teljesen alkalmas professzionális munkára (tehát vitázom az állításoddal), más kérdés, hogy a frissen piacra került fejlesztő 0 tudással is bele tud kezdeni, mert a learning curve ez esetben igencsak lankásan indul be (könnyű összepakolni jónak látszó megoldásokat, hogy aztán az ember évekig cipelje magával sűrű anyázások közepette). De a megrendelőnek ez is jó lehet, mert pénzt keres vele. Hidd el, vannak olyan projektek, ahol ez nem megengedhető, ahol alaposan kell tervezni, tesztelni, és a kódnak is olyan minőségűnek kell lennie, hogy azt mondjuk egy másik fejlesztő megértse viszonylag könnyen és ne kezdjen SQL lekérdezéseket hívogatni ciklusból, mert nem tudja, mi történik belül. A „profi fejlesztők tanácsaival” nekem is meggyűlt a bajom több soron is, némelyiket évekig próbáltam adaptálni. A legnagyobb gondom az volt velük, hogy nagyon egyszerű vagy idealizált, elméleti helyzetekre jók, és a gyakorlatban, üzleti környezetben, nem tökéletes csillag együttállásokkor nem lehet őket effektíven használni. Szerintem óriási probléma az, hogy a fejlesztőnek álló emberek 80%-a elemi képességekkel sem rendelkezik a tervezés, a szoftver- és kódminőség biztosítása terén. Amikor elkezd fejleszteni mondjuk PHP-val egy webes appot, akkor gyorsan tud haladni, mert a PHP megengedi a gányolást, a felületességet, de hamar kártyavárként dől össze az egész, mert nincs alaposan átgondolva, megtervezve. De honnan tudhatná a fejlesztő, hogy miként kell tervezni? Iskolákban nem tanítják (én legalábbis egyet sem tudok, ahol gyakorlati és piaci szempontból hasznos tudást kapnánk e téren). Könyvekből tanulni (legalábbis amikkel eddig találkoztam, Tiszta kód, Programtervezési minták, stb.) kb. olyan, mint periódusos rendszert tanulmányozni légzéshez, és amúgy is főképp az oxigén, nitrogén meg szén az, amivel dolgod lesz, a többi időpocsékolás. Gondolj bele, hogy más iparban milyen lenne, ha mondjuk Karcsi, a gyógyszerész gondolna egyet, hogy hát ő elmegy egy fél éves tanfolyamra, és holnaptól önállóan tervez és épít autókat. Hát persze. És a sok ember sok munkával és tanulással elért eredménye, a legyártott autó messze nem tökéletes termék (bár sokkal megbízhatóbb, mint a legtöbb szoftver). Tehát igen, úgy gondolom, hogy a fejlesztők túlnyomó többsége bőven junior. A junior/senior amúgy többféleképp értelmezett kifejezés, hol így, hol úgy gondolnak rá. Én a magam részéről a „senior” alatt azt a fejlesztőt értem, aki önmaga vállalja a felelősséget a szoftverért, amit készít: saját feladatának érzi a jó kommunikációt az ügyféllel, az alapos tervezést, refaktorálást és tesztelést, az igényes felületet, és hajlandó többletmunkát vállalni azért, hogy a szoftver jó minőségű legyen a végén. Ezeket viszont bele is kalkulálja az időbe, amit a fejlesztésre szán. Junior az, aki a fentiek közül legalább egyet nem a saját feladatának gondol. A fejvadászok többnyire 5+ év tapasztalatot már seniornak tekintenek, pedig az semmit nem jelent egy platform meglehetősen alapos ismeretén kívül (a fentiekre vonatkozólag). Emiatt lehet, hogy egy senior fejlesztő is gányol, igénytelenkedik. Vagy csak kellett neki a pénz.

    • Nagyon egyetértek a leírtakkal, viszont a PHP-nek a professionális fejlesztésnél van egy hatalmas baja. A hibakezelési megoldások. Tudok olyan hibákat generálni, amitől a teljes script megáll, nem ír ki semmit a kimenetre, de sehova nem ír semmit, még notice levelre állítva sem. A PDO sem 100%-ban tud Exception-t dobni, a többi osztály vagy metódus pedig egyenként külön hibelekérdezővel rendelkezik, amit soha, senki sem használ, mert a try-catch lenne ügye a legnépszerűbb. Még a nagyon sokat használt json_encode/decode sem dob Exceptiont, hanem külön függvény van a hiba lekérdezésére. Jó irányba halad a PHP a PHP3 óta, de nagyon észnél kell lenni, mert sok esetben ami a kényelme az visszafele is elsülhet. Én az a fajta fejlesztő vagyok, akit leírtál: „a fejlesztőnek álló emberek 80%-a elemi képességekkel sem rendelkezik a tervezés, a szoftver- és kódminőség biztosítása terén”. Én kényszerből kezdtem el, minden amit elértem, kísérletezéssel, StackOverflow bújással vagy GitHub-os mintákból tanultam meg. De legalább az alapvető dolgokat próbálom betartani. Sokkot kapok, ha a pro kódokban SQL querybe tett $_REQUEST-et látok minden szűrés nélkül, vagy számlázó/készletkezelő megoldásokban nincs (SQL) tranzakció kezelés. Gyűlölök fejleszteni, de sajnos azt látom, hogy ezzel a csapnivaló szinttel is megütöm a Magyarországon eladott kódok átlagát simán.

      • Ilyen hibák, hiányosságok mindenhol vannak, nemcsak a PHP-ben. Ha ügyesen strukturálod a kódot, akkor az ilyen részeket ki tudod emelni, külön meg tudod védeni a hibás inputoktól, teszteket írhatsz rájuk, hogy többé ne jöjjön elő a hiba. A hibakezeléseket átírhatod a saját kedved szerint, elrejtve az eredeti változatot. Az ilyen „pro” kódok nyilván nem pro-k, max. a készítőjük állítja azt róluk. 😀 De azért ne feledjük el, hogy minden fejlesztő elkezdte valahol, lehetnek gyengébb pillanatai, időszűkében összetákolt kódjai. 😉 Én is műveltem olyanokat, hogy hujjuj… 😀 Sajnos sok elterjedt keretrendszer van, aminek a dokumentációi nagyon jól használhatók – ha a programot úgy fejleszted, hogy 1x megírod és aztán soha többé nem nyúlsz hozzá. Ha viszont a szoftvert egyfajta szolgáltatásként kezeled, fejleszted, karban tartod, akár évekig, akár más fejlesztőkkel együtt, akkor az ilyen keretrendszerek ajánlott megvalósításai egyenesen károsak a legtöbb esetben (laravel, codeigniter, stb.) Ettől függetlenül nagyon összetett, mégis stabil szoftvereket lehet fejleszteni PHP-ban, csak nem úgy kell elképzelni, hogy 1 tál rizsért óránként lefeljeszti majd Frissókájés Béla 2 hét alatt a mindent is. Szerintem nem árban éri meg versenyezni, hiszen te is látod, hogy mennyi extra meló van elemi dolgok stabil és hosszútávon is karbantartható megvalósításával, tesztelésével. A jó fejlesztő rengeteget tanul, sok időt öl abba, hogy jobban tudjon tervezni és jobb megoldásokat dolgozzon ki a problémákra, ennek pedig ára van.

Comments are closed.