Darbas

Programavime yra keli svarbūs dalykai, kurių laikytis yra tiesiog privaloma, tačiau nemažai programuotojų jų nesilaiko vien tik dėl per mažo žinių kiekio. Nežinau kodėl neretas programuotojas neskaito teorinės medžiagos, o tik skuba kuo greičiau daryti veikiančias programas - galbūt tai kyla iš to, kad iš programuotojų beveik visada reikalaujama galutinio produkto, o laiko gilinti žinias ne visada lieka. Labai naiviai tikiuosi, kad žemiau sekančios mintys padarys įtaką bent vienam būsimajam programuotojui ir jis nepuls daryti žemos kokybės programų.

Logiškumas

Kadangi dažnas kodas yra sudarytas iš daugybės tūkstančių eilučių, tai labai svarbu programuoti taip, kad kodas galėtų būti skaitomas lyg knyga ar straipsnis. Nežinau tokios programavimo knygos, jei kas jas vis dar skaito, kuri nepradėtų nuo skatinimo naudoti aiškius ir konkrečius kintamuosius, komentarus ir įvairią kodo įtrauką. Toks patarimas yra brukamas ne veltui, nes tvarkingai parašytas kodas yra žymiai lengviau skaitomas ir suprantamas, o ir pačiam programuotojui vėliau gali kilti problemų vien tik dėl to, kad jis nebe supras ką daro konkreti kodo vieta. Tokie kintamieji, kaip $a, $pn, $sxy, $ty iš esmės nieko nesako, nes pavadinimai nesusieti su jokia logiška reikšme. Juk akivaizdu, kad kintamojo vardas $puslapio_numeris yra žymiai lengviau suvokiamas nei $pn. Tapati situacija ir su funkcijų vardais - asrt(), h() ir panašūs vardai nieko nereiškia, o pavadinus funkcijas ascending_sort() ir heap() paskirtis iškart žinoma. Tiesiog nesistenkite visko darykite kuo sudėtingiau - paprastumas ir tik paprastumas suteikia kodui lengvumo skaitant, o perdėtas visko iškraipymas tik trukdo programuojant. Jei jau neišvengiate sudėtingo kodo tai bent pakomentuokite jo prasmę ir veikimo principą, nes vėliau galite ir nebe suprasti net savo skurto kodo.

Dinamiškumas

Nelanksti programa yra tinkama tik itin konkrečioje situacijoje, kuri iš esmės yra tik apribotas konkretus laiko tarpas. Kuriant programas visada reikia palikti laisvės tobulinimams, keitimams ir modifikacijoms, nes labai dažnai pradinis variantas netinka užsakovui, todėl neišvengiamai reikia atlikti pakeitimus. Dinamiškumas atsiranda naudojant konstantas, konfigūracijos rinkmenas ir kitus parametrų saugojimo būdus. Labai blogas programavimo pavyzdys - skaičius programos kode. Be abejo, be skaičių neišsiverčiama, tačiau juos reikia naudoti tik kaip konstantas arba aiškiai pakomentuoti jų prasmę, nes kai sudėtingame kode atsiranda kažkokie skaičiai, tai jų prasmės nustatymas gali labai ilgai užtrukti. Blogiausia kai programoje atsiranda neaiškūs keliai iki rinkmenų, kurie tikriausiai vedė į programuotojo kompiuteryje esančias rinkmenas, o kliento kompiuteryje juk sistemos rinkmenų struktūra nebūtinai tapati. Labai patogu iš anksto apsirašyti visus naudojamus skaičius ir reikšmes konfigūracijos rinkmenoje arba klasės antraštėje - taip visada žinosite kur ieškoti statiškų reikšmių kilmės šaltinio. Be to, vienoje vietoje surašę parametrus, galėsite lengvai manipuliuoti programos veikimo subtilybėmis.

Funkcionalumas

Labai dažnas užsakovas reikalauja kuo didesnio funkcionalumo, todėl neretai programuotojai jį sukuria „bile, kad veiktų“. Toks atmestinas požiūris gimsta iš to, kad tiesiog sukuriamos funkcijos, kurios veikia tik su konkrečiais duomenimis, o su išskirtiniais atvejais tiesiog nesusitvarko. Man labai patinka toks testavimo būdas, kai pavyzdžiui vietoje puslapio numerio įvedamas tekstas, o vietoje vartotojo vardo - daug tarpų. Programa neturi nulūžti be jokio pranešimo - programa turi patikrinti įvedamus duomenis ir padaryti tinkamas išvadas apie įvestus duomenis ir jei reikia paprašytų juos pataisyti - niekada neverta pasitikėti vartotoju. Neretai programuotojai neįvertina ir duomenų dydžio, ko pasekoje naudoja elementarius algoritmus, kurių sparta siekia net N^2, o įvedus duomenis, kurių N siekia 2^16, tiesiog nulūžta. Žinoma ne visose situacijose verta tikrinti ką įveda vartotojas, tačiau tiesiog būtina rašyti tokius algoritmus, kurie tvarkingai veiktų su visai įmanomais duomenimis - juk tam yra „unit testing“. Nereikia beatodairiškai siekti maksimalaus funkcionalumo - žymiai svarbiau yra užtikrinti, kad programa veiktų tinkamai ir stabiliai.

Solidumas

Paskutinioji dalis turi keisčiausią pavadinimą, nes nežinau kaip pavadinti rašomo kodo „brandą“ ir „svorį“. Programavime reikia taikyti „9 -is kartus pamatuok - 10-ą pjauk“ principą, nes žymiai geresnė kodo kokybė yra pasiekiama idėją subrandinus teoriškai. Neretai tenka net savaitę ieškoti optimalaus algoritmo ar duomenų struktūros, tačiau mąstymo pastangos atsiperka su kaupu, nes atsisėdus rašyti kodo, jis tiesiog vienu prisėdimu parašomas nuo pradžios iki galo. Anksčiau atsisėsdavau prie kodo rengyklės ir vis bandydavau įvairius sprendimus, tačiau ilgainiui pastebėjau, kad tai yra beprasmiška, nes iki galo nesugalvotas algoritmas yra žymiai ilgiau rašomas, nei prieš tai sugalvotas vien tik dėl to, kad programuojant reikia įvertinti ir kalbos subtilybes, kas neretai atima nemažai laiko. Tai patarimas, kuris ne vienam gali nepatikti vien dėl įpratimo, tačiau mano manymu geriau neskubėti - teisingi sprendimai gali pareikalauti nemažai laiko, bet jie bus iki galo teisingi ir optimalūs, nei atmestinai ir nepamąsčius suręstas kodas. Blogiausia, kai paskubomis padarytas kodas taip ir lieka nesutvarkytas, o jame atrastos klaidos tampa sunkiai ištaisomos.

Tai dar vienas straipsnis labiau orientuotas į pradedančiuosius, nes labai tikiuosi, kad Lietuvos profesionalūs programuotojai dirba tinkamai. Nemanykite, kad teorinės žinios yra bevertės ir praktinė patirtis yra žymiai svarbesnė - be gero teorinio pagrindo, jūsų patirtis ir žinios visada liks tik paviršutiniškos; nemanykite, kad pirmieji knygų skyriai parašyti be reikalo ir juos galima tiesiog praversti. Galiu patikinti iš savo patirties, kad išmokus daugybę dalykų teoriniame lygmenyje, programos rašosi žymiai lengviau, nes daug kas tiesiog tampa natūralu ir nereikia leisti valandų analizuojant kaskur „ateina“ ir kodėl būtent false. Sėkmės!

Vasaris 1, 2008PHP drambliukas

Drambliukas

Šiandien pas mane atvyko labai lauktas PHP talismanas drambliukas. Kadangi pats gana daug domiuosi PHP programavimo kalba, tai turėti tokį talismaną man pasirodė privaloma, todėl susisiekiau su jo „gamintojais“ ir užsisakiau. Senai nebežaidžiu su žaislais, bet šis talismanas pasirodė ne tik, kad mielas, bet ir simbolizuojantis mano aistrą programavimui. Pats drambliukas yra gana nedidelis - žmogaus delno dydžio ir padarytas iš šviesiai mėlynos spalvos minkšto audinio. Be to, nors drambliukas buvo labai šiurkščiai sugrūstas į per pus už jį mažesnę dėžutę, tačiau jį išvadus atgavo savo tikrąją formą ir dabar kartu su manim dirbs PHP darbus :) Įsigykite ir jūs!

Sausis 31, 2008Programavimas sluoksniais

Sluoksniai

Kadangi esu matęs jau gana nemažai įvairiausių stilių programų kodų, tai daug maž esu susidaręs nuomonę kaip viską reikia daryti teisingai taip kaip man atrodo priimtiniausia. Turbūt svarbiausia - programuoti reikia skaidant visą kodą į sluoksnius svarbos ir funkcionalumo prasme. Žinoma tai priklauso nuo programuotojo programavimo stiliau, tačiau aš pabandysiu parodyti kuo toks stilius yra šaunus ir kodėl taip verta programuot. Nesistengsiu to daryti primygtinai - tiesiog paaiškinsiu kodėl aš taip programuoju ir galbūt jus tai sudomins. Be abejo, tai yra vienas iš tų straipsnių, kurie tikriausiai nelabai tinka bendrai auditorijai - šis straipsnis orientuotas į programavimu besidominčius žmones, todėl kitiems jis gali pasirodyti visiškai nesuprantamas.

Esu ne kartą matęs programų, kurių funkcionalumas surašytas didžiuliais blokais ir vieno veiksmo atlikimas visiškai neišskirstytas į atskiras funkcijas. Tai galbūt gerai, kai programa yra maža, pvz.: elementari reprezentacinė svetainė, tačiau didėjant programos mastams darosi sunku suvokti kas, kaip ir kodėl. Pradėkime nuo to, kad visą programą rekomenduojama išskirstyti į daugybę atskirų rinkmenų. Taip dirbant su kodu bus ne tik sutaupoma kompiuterio atminties (įkeliami ne visos rinkmenos, o tik tos kurių tikrai reikia), bet ir supaprastinamas kodo valdymas, nes kai kiekviena klasė įrašyta skirtingoje rinkmenoje, tai nesunku surasti reikiamą metodą. Be to, reikia pasirūpinti kodo per-panaudojimu (angl. reusability), nes labai nenaudinga funkcionalumą deklaruoti vis iš naujo - tai padarius tvarkingai, vėliau juo galima naudotis daug kartų. Visą kodą išskirsčius į daugybę funkcijų (būtinai pavadintų logiškai) darosi žymiai paprasčiau manipuliuoti kodo dinamiškumu, nes praplečiant funkcionalumą nebereikia daug modifikacijų - užtenka naudoti jau sukurtus metodus. Labai patogu funkcionalumo dalinimąsį sukonstruoti naudojant objektinį programavimą ir klasių paveldimumą, nes tėvinėje klasėje apibrėžti metodai yra naudojami visose vaikinėse klasėse. Pavyzdžiui aš savo kodą išskirstau į tokius lygmenis:

  • Branduolys
    • Programos valdiklis (angl. main controller)
    • Peržiūros valdikliai (angl. view controller)
    • Moduliai (angl. module)
      • Modeliai (angl. model)
      • Ruošiniai (angl. template)
      • Valdikliai (angl. controller)

Toks išskirstymas man leidžia modifikuoti visus modulius keičiant tik branduolio klasę arba suteikti papildomo funkcionalumo modeliams, modifikuojant tik tėvinę modelio klasę. Be abejo yra ir kitų būdų kaip „dalintis“ funkcijomis tarp skirtingų kodo dalių, tačiau naudojant paveldimumą tai padaryti yra galbūt paprasčiausia. Žinoma nereikėtų pamiršti ir to, kad pakeitus metodą paveldimoje klasėje, jo funkcionalumas pasikeis visose vietose, taigi vertėtų pasirūpinti, kad atlikus pakeitimus „nesugriūtų“ visa programa.

Programos išskirstymas į logines dalis yra taip pat be galo naudingas. Ypač ankstyvose programavimo mokslo stadijose programuotojai dažnai visą programos veikimą patiki vienai funkcijai. Tai taip pat yra patogu tik tol, kol programos dydis yra itin mažas. Pavyzdžiui.: parašote programą, kuri naudojasi MySQL duomenų baze, o vėliau nusprendžiate naudoti tik PostgreSQL. Tai padaryti būtų labai sudėtinga, nes jei naudojotės standartinėmis funkcijomis (pvz.: mysql_connect, mysql_fetch_array ir pan.), tai pakeitimus reikėtų atlikti visame kode, o tai užtruktų daugybę laiko. Naudojantis atskiromis klasėmis darbui su duomenų bazėmis, RSS, ruošiniais ir pan. išvengiame priklausomybės - pakeitimus atlikus klasės kode, jie atsiliepia visam loginiam sluoksniui. Mūsų atveju užtektų modifikuoti duomenų bazės sluoksnį ir MySQL funkcionalumą pakeisti į PostgreSQL - šie pakeitimai iškart atsilieptų visai programai. Man tai vienas didžiausių objektinio programavimo pliusų, nes visą programą išskirsčius į objektus galima lengviau ir paprasčiau manipuliuoti kodu. O svarbiausia yra tai, kad už kiekvieną konkretų veiksmą yra atsakinga skirtinga kodo dalis ir visos kitos funkcijos tik naudojasi ja. Juk akivaizdu, kad kai klausiame žmogaus „Kiek laiko?“ mums visiškai nesvarbu kaip jis sužinos šią informaciją - jis pasakys arba „nežinau“, arba tikslų laiką. Objektiniame programavime galioja tas pats principas - objektai „bendrauja“ taip, kad jų bendravimui vidinis klasių funkcionalumas neturi įtakos.

Šiuo straipsniu daugiausiai taikiau į tuos, kurie vis dar rašo programas neskirstydami jų į įvairiais dalis ar tik pradeda programuoti. Nežinau ar tai padarė jums kokią nors įtaką, tačiau mano manymu objektinis programavimas yra labai nuostabus dalykas ir programuoti kitaip būtų tiesiog neįdomu. Svarbus ne vien kodo tvarkingumas, lankstumas ir funkcionalumas - svarbu tai, kad programos kodas būtų tinkamai struktūrizuotas ir nesudarytų trukdžių praplėtimams. Be abejo, labai svarbu ir tai, kad programavimo stilius patiktų ir jums, nes šis dalykas yra labai subjektyvus ir vienas teisingas būdas tikriausiai niekada nebus atrastas.

Menas

Vakarykštis mano įrašas sulaukė labai įdomios reakcijos, nes turbūt dauguma teigė, jog ne algoritmų žinojimas padaro žmogų geru programuotoju. Žinoma, programuotojas turi turėti ir kitų savybių, tačiau jei iš tikrųjų jūsų nedomina įvairūs algoritmai, tai nemanau, kad jūs esate geras programuotojas. Galiu klysti, bet netikiu, kad baigti projektą laiku jums yra įdomiau, nei atlikti įdomią užduotį, kuri pareikalautų kažko nestandartinio ar puikių matematinių algoritmų. Taip, tarnaujame klientams, tačiau kol aš oficialiai nedirbu, tol galiu sau leisti svajoti apie darbą, kuriame atsiskleistų mano požiūris į programavimą, kaip sritį, kurioje svarbiausias improvizavimas ir noras viską atlikti kuo geriau (ne greičiau). Pabandykime dar kartą panaršyti programuotojų daržą.

Pirmiausia, gerais programuotojais gimstama - tą patį sakė ir asterisk. Kadangi programuoju nuo 12-13 metų, tai laikau save gimusiu programuoti. Nesakau, kad gyvenime daugiau niekuo nesidomiu, tačiau ši sritis mane labiausiai traukia. O problema yra tame, kad visi tie, kurie programuoja vien tik dėl darbo ar pasirinko informatiką, nes niekas kitas netiko, programavimu iš tikrųjų nesidomi. Taip, jūs galite rašyti veikiančias programas, tačiau ar jūs jausite malonumą programuodami? Labai abejoju, nes programavimas juk kaip menas - programuotojai turi kurti, improvizuoti ir surasti savo stilių. Svarbiausia, kad programavimas yra tokia sritis, kurioje reikia labai daug mokytis ir kartu atlikti daug praktinių užduočių, kad jūsų programos iš tiesų būtų geros. Žinoma, programuotojas turi pats mokėti kurti algoritmus ir konkrečius sprendimus, tačiau jau ko ko, bet mano minėtų Dijkstros, Primos ar Floyd-Warshall algoritmų tiesiog negalima nežinoti (nebūtina naudoti). Galite būti labai šaunus programuotojas, tačiau jei jūs domitės tik konkrečios programavimo kalbos konkrečiais aspektais, tai jūs esate labai toli nuo programavimo meno. Labai gerai atsimenu švedų gitaristo Yngwie Malmsteen žodžius, kad norint būti geru gitaristu (dar vienas mano pomėgis) reikia klausytis daug ir įvairios muzikos (pvz.: simfoninės), o ne vien didžiųjų gitaristų. Be abejo, jūs galėtume domėtis kitomis programavimo kalbomis ar pan., tačiau juk tai iš esmės nieko nepakeis - vis tiek jūs kažkada turėsite apsistoti ties viena kalba. Mano manymu, teorinių žinių gilinimas, domėjimasis įvairiomis teorijomis ir būdais programuoti geriau yra tiesiog puikus būdas stiprinti programuotojo įgūdžius, net neskaitant to, kad geras programuotojas ir taip turėtų labai domėtis IT sritimi.

Šiandien taip pat gavau ir nebepirmą darbo pasiūlymą. Kadangi laiško autorius Vladas Sapranavičius paprašė pasiūlyti darbą ir kitiems PHP programuotojams, tai jei susidomėjote ar neturite darbo - rašykite tiesiai jiems. Tačiau šį pasiūlymą miniu ne dėl to - apie jį užsiminiau dėl to, kad šiek tiek keista būti kviečiamam dirbti dar nebaigus mokyklos (o dar sako Lietuvoje sunku darbą susirasti). Nejaugi trūksta darbo jėgos, kad kviečiami dirbti mokiniai? :) Blogiausia, kad darbo pasiūlyme nurodytas atlygis, mano manymu, visiškai neatitinka surašytų reikalavimų ir galimybių, todėl labai abejoju, kad priimčiau jį jei net ir turėčiau laiko darbui. Be to, toks darbas tikriausiai būtų be galo nuobodus ir jame dingtų visas programavimo įdomumas, nes reikėtų tik vieną po kitos štampuoti svetaines, o tai labai retai būna įdomu. Žinoma, pradžiai toks darbas yra tikrai geras, nes įgaučiau darbo įmonėje patirties, tačiau nemanau, kad jame būtų galima išsilaikyti ilgesniam laikui - ten tiesiog nebūtų ką veikti. Galbūt labai daug noriu, tačiau nematau prasmės eiti dirbti į darbą, kuris ilgainiui pavirs nuobodžia rutina - tikrai įmanoma susirasti tokią vietą, kurioje iššūkiai ir sprendimų ieškojimas lydėtų kiekvieną darbo dieną. Juk programavimas tai menas ir improvizacija ir darbdavys neturėtų „užšaldyti“ darbuotojo tobulėjimo skirdamas iššūkių nereikalaujančius darbus. Čia ir vėl galiu prisiminti jau ne kartą minėtuosius algoritmus ir teorijas, juk tai vienas iš tų dalykų, kuris programavimui suteikia subjektyvaus grožio ir įdomumo, nes juk ne veltui didūs matematikai ir informatikai juos sukūrė - jie ne tik tiesiog veikia sparčiausiai konkrečioje situacijoje, bet ir parodo, kad programavime reikia matematikos žinių (kurių ne vienas norėtų atsisakyti). Galbūt jums jie nepatinka, galbūt jums atsibodo teorija, tačiau aš mielai juos naudosiu tik pasitaikius progai, nes nematau prasmės išradinėti dviračio iš naujo ir rašyti kodą, kuris tik veiktų.

Asterisk, savo straipsnyje minėjo, kad geri programuotojai jaučia aistrą programavimui - aš ją taip pat jaučiu. Nežinau ar universitetas pakeis mano požiūrį į programavimą, bet kol kas man programavimas yra daugiau nei darbas. Man visiškai nesvarbi projekto kaina ir vertė - svarbu, kad jis būtų įdomus, nes kasdien 8 valandas „kurti“ reprezentacines svetaines net už didelius pinigus vargu ar sutikčiau. Sakykite ką tik norite, bet man tiesiog įdomu gilinti žinias teoriniame lygmenyje ir analizuojant mokslininkų sukurtas teorijas, nes tai suteikia įkvėpimo pačiam rašyti tvarkingą ir svarbiausia gerą kodą. Galbūt jūs nusivylę gyvenimu ir pykstate už tokius lengvabūdiškus „bedarbio“ pasamprotavimus, bet argi jums patinka programuoti vien tik, kad suspėtumėte baigti projektą laiku? Gero savaitgalio!

Sausis 23, 2008Ar tu moki programuoti?

Beždžionėlė

Tikrai, ar tu moki programuoti? Jei nemoki, tai pernelyg nenusimink - abu turėsime progą šiek tiek pamokyti programuojančius. Tačiau jei iš tikrųjų manai, kad esi programuotojas, tai gerai pagalvok - ar tikrai mokti programuoti? Tai yra be galo subjektyvus dalykas, bet programavimas šiais laikais yra gana lengvai prieinamas mokslas dėl to yra daugybė programuotojų, kurie tiesiog nemoka elementarių programavimo tiesų. Žinoma, bepigu man teigti, kai pats nesu baigęs jokio universiteto ir turiu dar visai nedaug gilių teorinių žinių, tačiau esu skaitęs gana nemažai įvairios medžiagos ir pasižiūrėjus į kai kurių žmonių programavimo stilių galiu gana drąsiai teigti, kad neretas programuoja neteisingai. Netiki? Panagrinėkime keletą faktų ir galbūt man pavyks tave įtikinti, kad programavimas yra visai ne lengvas dalykas.

Nežinau kiek iš jūsų yra dalyvavę informatikos olimpiadose, tačiau kiekvienam programuotojui tiesiog privalu žinoti tai, ką žino ten dalyvaujantys mokiniai. Šiais laikas kompiuteriai atlieka milijonus operacijų per sekundę todėl vis dažniau pasirodo programos visiškai netvarkingai dirbančios su duomenimis. Vykdomos olimpiados yra šaunios tuo, kad jose pateiktas užduotis galima išspręsti labai įvairiais būdais, tačiau elementarūs metodai tiesiog yra tokie neoptimalūs, kad programa veikia per ilgai - visoms programoms yra nustatytas atminties ir vykdymo laiko (< 1 sec.) limitas. Programuoti pradėjus nuo tokių kalbų kaip PHP tikrai sunku mokėti gerai programuoti, nes šioje kalboje iš vis niekuo nereikia rūpintis - daugybė jau paruoštų funkcijų ir viskas tiesiog veikia. Olimpiadose leidžiama naudoti Pascal, C++ arba C kalbas, taigi didžiąją dalį funkcionalumo reikia kiekvieną kartą perkurti pritaikant savaip. Įsivaizduokite elementarų uždavinį, kuriame pavyzdžiui reikia apdoroti nekryptinį svorinį 100′000 viršūnių grafą ir surasti trumpiausią atstumą tarp M ir N viršūnių. Turbūt neretas žmogus pasinaudotų foreach ir pan. ciklais ir prasuktų šį viršūnių masyvą keletą kartų, tačiau juk tai užtruktų visą amžinybę - čia negalima nenaudoti Dijkstros ar Primos algoritmų. Ko tokių? Žinoma juos reikia pirma žinoti, tačiau parašyti optimalesnį kodą turbūt sunkiai pavyktų, o jų nežinant kartais gali net nepavykti įveikti užduoties. Jei visgi tikitės, kad jūsų būdai yra pakankamai optimalūs, galiu nurodyti vietą su standartiniais uždaviniai, kad patys galėtumėte įsitikinti klydę!

O ką jau kalbėti apie tokius dalykus kaip dinaminis programavimas, heapas, greitasis rikiavimas ar pan. Problema tame, kad daugybė programuotojų naudojasi tik standartinėmis funkcijomis ar rašo programas, kurios veikia su konkrečiais duomenimis. Tai iš esmės yra prastas pavyzdys, nes turbūt visi besiruošiantys olimpiadoms parašytų puikias programas, o tikrieji programuotojai tikriausiai raudonuotų palyginę su savo kodu. Ir vėl negaliu nepaminėti PHP kalbos, nes su ja daugiausiai dirbu. Jau nekalbant apie tai, kad joje kintamieji atsiranda iš niekur, tai dar ir nereikia beveik nieko mokytis - imi funkcijas ir naudojiesi. Bjauriausia yra tai, kad dirbant su PHP beveik nereikia jokių algoritmavimo žinių - internete yra tiek pavyzdžių ir jau parašytų programų, kad realiai viską galima susirinkti iš dalių be jokio supratimo kaip viskas veikia. Po vieno iš mano pirmųjų įrašų atsirado keletas žmonių, kurie siūlėsi perimti keletą mano projektų ir labai aktyviai įrodinėjo, kad turi „geras“ PHP žinias. Tačiau kaip paaiškėjo vėliau - žmonių programavimo patirtis apsiriboja PHP-Nuke. Nežinau kokiu reikia būti žmogumi, kad su tokiu žinių bagažu išdrįsti siūlytis į darbą, juk jie tikriausiai net nelietę programavimo. Kažkodėl net neabejoju, kad kažkiek panašūs programuotojai dirba ir rimtuose darbuose - kokiu būdu jie ten patenka nežinau, bet spėju, kad programuotojų darbo kokybė, ypač Lietuvoje, yra gana žema. Sprendžiu iš to, kad dar nei viename programuotojų ar IT forume netekto sutikti nagrinėjant gilių ir įdomių teorinių temų, o tokius dalykus įvaldyti be problemų tikriausiai yra beveik neįmanoma. Tikiuos, kad klystu.

Turbūt jums kilo klausimas, ką aš noriu įrodyti. Aš noriu įrodyti tai, kad kažkuri dalis programuotojų yra lyg beždžionėlės, kurios programuoja tokiame žemame lygyje (ne gerumo prasme), kad juos vadinti programuotojais būtų tiesiog neapdairu. Labai norėčiau sužinoti kiek tokių yra Lietuvoje - tikiuosi mažiau nei 50%. Tačiau jei jų yra tiek, tai liūdžiu pasirinkęs programuotojo profesiją, nes bus nelengva surasti gerą komandą produktyviam darbui. Nors pats dar nesu gerai įvaldęs programavimo, bet kuo toliau, tuo labiau manau, kad galbūt man verta užsiimti „aukštesne“ profesija - kaip paprastas programuotojas aš pernelyg daug siekiu ir „matau“. Galbūt taip nėra, tačiau man akivaizdu, kad pernelyg programuotojų renkasi lengvą kelią ir tiesiog teršia pasaulį prastomis programomis. Tikiuosi viską daryi kitaip.

Lėtai

Šiandien galų gale gavome priėjimą prie hanza.net elektroninės bankininkystės testavimo sistemos. Prieš šiek tiek mažiau nei mėnesį skundžiausi, jog prieš Kalėdas ir per jas niekas nedirba, tačiau nedirbo ir po jų. Ilgai kankinome Hansabanko vyrukus, kol jie galų gale prisiruošė suteikti priėjimą prie šios sistemos. Neanalizuosiu kodėl jie taip ilgai užtruko (viską pradėjome 2007 Gruodžio pradžioje), tačiau pasidžiaugsiu, kad taip ilgai lauktas dalykas iš tiesų nesukėlė jokių problemų.

Turbūt svarbiausias dalykas - bendravimas su bankininkystės sistemomis vyksta šifruotai, naudojant jūsų ir banko viešo ir privataus rakto poras. Svarbiausias, nes šifruojant duomenis yra svarbus kiekvienas pradinių duomenų bitas, nes gautas rezultatas yra visiškai neatitinkantis pradinių duomenų ir vienu bitu besiskiriančios eilutės užkoduotos gali atrodyti visiškai kitaip. Kadangi reikalingas šifravimo algoritmas aprašytas tik teoriniu aprašu ir jokių veikiančių pavyzdžių bankas nepateikia, tai teko jų ieškoti kitais keliais. Pasitelkus Google į pagalbą internete susiradau jau veikiantį kodą ir jį tik šiek tiek modifikavęs, buvau visiškai įsitikinęs, kad nekils jokių problemų. Taip ir atsitiko - šiandien gavęs patvirtinimą, jog galiu pradėti testavimą iš kart atlikau pirmąjį sėkmingą mokėjimą - sistema suveikė iš pirmo karto. Tai yra tikrai šaunu, nes labai bijojau problemos dėl koduočių (bankas naudoja windows-1257, o aš - UTF-8) ir šifravimo raktų. Tačiau blogiausia neatsitiko ir sistema jau puikiai veikia.

Kaip matote - per ilgą laukimo laiką pasiruošiau taip, kad atėjus darbo metui jau nebebuvo ką dirbti. Keista, tačiau taip jau yra, jog kartais įmanoma programavimo užduotis labai šauniai atlikti ir teoriniame lygmenyje, nes labai dažnas programuotojas rašo kodą taip, kad jis tik veiktų, bet ne taip, kad jis veiktų visada ir su visais duomenimis. Beliko SEB

Sausis 20, 2008Ar tu moki save parduoti?

Pardavimai

Jau gana seniai rašiau apie tai, kad neatsiginu darbo pasiūlymų. Nors nuo to laiko nemažai dalykų pasikeitė, ko pasekoje mano „kaina“ išaugo keletą kartų, t.y. visus projektus dabar darau tik oficialiai, tačiau visgi pasiūlymų kiekis ne kiek neapmažėjo. Nors laisvalaikiu ir pats susirandu ką veikti ir darau tik super įdomius projektus, tačiau tą laiką, kurį skiriu darbui, vis dar užpildau maksimaliai. Nenagrinėsiu kodėl aš turiu tiek darbų, nes ir vėl būsiu apkaltinas žemos kainos laikymu ir pan., o pasistengsiu apžvelgti ką reikia daryti norint užsimti savo vietą tarp kitų programuotojų. O svarbiausia - ką reikia daryti, norint save „parduoti“? (Šis straipsnis ne apie prostituciją)

Turbūt svarbiausias dalykas - darbo kokybė. Kadangi pasiūlymų kiekis idealiu atveju auga kaip geometrinė progresija, tai žema darbo kokybė gali ne tik sumažinti pasiūlymų kiekį, bet ir „nukirpti“ vieną iš pasiūlymų „šakų“. Sunku tai apibūdinti paprastai, bet pasiūlymus galima įsivaizduoti, kaip dvejetainį medį: jei jūs atliekate užsakymą ponui X, tai ponas X, jus rekomenduoja kitiems dviems Y, jei tie kiti du ponai Y rekomenduoja jus vėl dviems ponams Z, tai jūs rekomenduojamas jau keturiems ponams Z (seka - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 ir t.t.). Dabar įsivaizduokite, kad jūs atliekate darbą blogai kažkuriam žmogui ir automatiškai jis jūsų niekam kitam nerekomenduoja - čia įvyksta „šakos nukirpimas“, nes nuo to konkretaus pono X jūs nebe sulaukiate daugiau pasiūlymų. Žinoma visada darbą atlikti idealiai tikriausiai yra neįmanoma, tačiau reikia sugebėti klientui parodyti, kad jūsų atliktas darbas yra geras ir tik pavyzdžiui vėlesni kliento pageidavimai įtakojo darbo netobulumą - svarbu užsitarnauti kliento pasitikėjimą. Pasitikėjimą užsitarnauti dažnai nėra lengva, bet kuo daugiau įgaunate patirties, tuo lengviau sekasi susitarti su įvairiais žmonėmis, o kelios stambios pažintys gali jus aprūpinti užsakymais ilgam laikui. Taigi pirmoji taisyklė - nepasišiukšlinkite su klientais, nes vienas blogai atliktas užsakymas jums gali atimti daug kitų užsakymų.

Bendravimas yra taip pat labai svarbus dalykas. Norint pasiekti gerą pripažinimą ir klientų pasitikėjimą būtinai reikia su jais bendrauti - tik jokiu būdu ne el. laiškais. Jau vien susitikimas kavinėje ar bare reiškia tai, kad turbūt klientui su jumis bendrauti yra daug maž malonu ir jis sutinka plėtoti pažintį su jumis. Kadangi pažintys = pelnas, tai kuo daugiau jūs užmegsite pažinčių, tuo lengviau jūs gausite darbo pasiūlymų. Žinoma nereikia pirštis visiems į draugus, bet reikia tiesiog atrasti būdą ir tinkamą situaciją, kai verta prisistatyti savo srities žinovu. Be abejo labai naudinga susilaukti teigiamų komentarų ir internete, spaudoje ar net televizijoje, nes tokioje srityje kaip IT, daugybė potencialių klientų skaito ir žiūri įvairiausius šaltinius ir išgirdę informacijos apie gerą specialistą jie bet kokiu atveju apsvarstys jūsų tinkamumą. Netgi toks dalykas kaip tinklaraštis gali padėti jums susirasti klientų, nes jei jis bus rašomas ir apie IT sritį tai be abejo, kad žmonės jus pastebės. Tačiau labai skaudžiai nukentėsite, jei supykdę klientą, būsite viešai išpeiktas kokiame nors forume, tinklaraštyje ar net naujienų portale, nes tokiu atveju būsimasis klientas gali susidaryti blogą nuomonę apie jus dar prieš ieškodamas darbų atlikėjo. Pvz.: jei aš dabar išpeikčiau Joną Jonaitį, tai visi kas perskaityt tą įrašą, tikriausiai užfiksuotų savo galvose, kad su Jonu Jonaičiu geriau net neprasidėti. Išvada - komunikuokite ir leiskite apie save išgirsti kitiems.

Nežinau ar man pavyko jus įtikinti, kad daug klientų galima pasiekti ne tik žema kaina. Tikrai nemanau, kad atlieku užsakymus labai pigiai ar labai greitai ir gerai, tačiau aš sugebu save parduoti. Žiauriai skamba, bet klientų susirandu lengvai ir dabar jau sunku nuo jų atsiginti. Nejaugi jums nesiseka rasti padorių užsakymų, kad manote, jog tai įmanoma tik laikant mažą kainą?

WWW protocol

Šį straipsnį pradėsiu nuo to, kad mano užduotis buvo padaryti sąskaitų sistemą, kurioje sąskaitas galėtų išrašyti ne vienas projektas. Kadangi “ne vienas”, tai reikėjo užtikrinti, kad visi projektai turėtų galimybę jungtis prie sąskaitų sistemos, bet jiems nereikėtų žinoti sąskaitų sistemos duomenų basės slaptažodžio, šifravimo raktų ir t.t. Pradžioje nežinojau kaip tai tinkamai padaryti, todėl prie projekto saugojau ir sąskaitų sistemos DB prisijungimo duomenis, tačiau ilgainiui pastebėjau, kad tai yra labai nelankstus sprendimas, nes aš ne tik, kad saugau prisijungimo duomenis keliose vietose (problematiškas jų pakeitimas), bet ir keliose vietose apsirašau sąskaitos sukūrimo procesą, kas yra itin nelankstu norint pakeisti sąskaitų struktūrą. Nieko kito neliko, kaip eiti į www.google.com ir ieškoti bendravimo tarp skirtingų PHP programų būdų.

Pirmasis ir paskutinis mano pasirinkimas - XMLRPC. Bendravimas šiuo protokolu vyksta XML struktūromis, kurias galima suformuoti bet kokia kalba, todėl vėliau prireikus galėsiu parašyti ir klientinę programą sąskaitų sistemai. Nors šis protokolas išaugo į žymiai funkcionalesnį SOAP, bet „Some people still prefer XML-RPC to SOAP because of its simplicity, minimalism, and ease of use.“ (angl. kai kurie žmonės vis dar mieliau naudoja XMLRPC, nei SOAP, dėl jo paprastumo, minimalistiškumo ir lengvumo naudotis). Taip jau yra, kad „bendrauti“ XMLRPC protokolu yra išties paprasta, nes užklausos ir atsakymai yra suformuoti XML kalba - kalba, kuria itin lengva manipuliuoti bet kurioje kalboje. SOAP irgi naudoja XML, tačiau šiam protokolui reikia žymiai daugiau žinių ir patyrimo, todėl man buvo žymiai patogiau pasirinkti XMLRPC - kadangi nesimokau universitete ir nelankau jokio rimto būrelio (ar tokie bent būna), tai kiekvieną naują ir nenaudotą technologiją reikia nemažai laiko pačiam studijuoti ir nagrinėti, nes nelabai turiu kas parodo. Pasirinkus technologiją iš kart galime pereiti prie praktinio įgyvendinimo PHP kalboje.

PHP kalboje egzistuoja speciali xmlrpc biblioteka, tačiau kadangi ši biblioteka nėra standartinėje PHP konfigūracijoje, tai šis pasirinkimas iš kart atkrito - šansas, kad kažkas dėl manęs keis veikiančių serverių nustatymus lygus beveik nuliui. Internete susiradau kitą biblioteką - PHPXMLRPC. Šis įrankis pateikiamas kaip atskiras rinkmenų rinkinys, todėl gali būti naudojamas ir su standartine PHP versija. Viskas būtų gerai jei ši biblioteka būtų pakankamai dokumentuota ar pateikiami konkretūs pavyzdžiai. Nors kūrėjų puslapyje ir yra pateikiama dokumentacija, bet jos man pasirodė mažokai, t.y. net ją perskaičius ir peržiūrėjus visus pavyzdžius vistiek nebuvau iki galo supratęs kaip kokie metodai veikia. Tačiau senas-geras bandymų ir klaidų metodas atvedė prie tinkamo rezultato - mano rengiama el. parduotuvė (apie kurią jau ne kartą rašiau) labai šauniai susibendravo su sąskaitų serveriu ir be jokių problemų išrašė sąskaitas, bei vėliau jas pasėmė. Nors pradžioje ir kilo šiek tiek problemų dėl naudojamos koduotės, bet vėliau radau būdą kaip tinkamai nurodyti UTF-8 koduotę, kuri anksčiau nors ir buvo nurodoma, bet rezultatai vis tiek siunčiami be koduotės. Ir dar viena sėkmingai įveikta užduotis!

Nežinau kokia šio įrašo prasmė - gal tai tikrojo asmeninio blogo ir patarimų mišinys. Asmeninio, nes pateikiau savo patirties ir veiklos aprašymą, o patarimo dėl to, kad galbūt perskaitę šį įrašą jūs suprasite, kad kažkokius sprendimus jūs padarėt netinkamai ir XMLRPC jums būtų žymiai geriau tikęs. Be to paskutiniuoju metu tiek daug mokausi (ne tik programavimo, bet ir anglų egzaminui IELTS), kad net nebespėju deramai aprašyti įvairių nutikimų ir patyrimų - tikėkimės vis dar atrasiu laiko ir šiai veiklai (bloginimui). Einu mokytis… O tai dar vadinasi atostogos :)

Kodas

Vakar pristačiau savo būdą kintamiesiems PHP kalboje valdyti, bet nepaskelbiau konkretaus pavyzdžio, t.y. veikiančios funkcijos. Nors tikėjausi, kad skaitytojai, kurie suprato apie ką straipsnis, suprato ir kaip veikia pati funkcija, bet turbūt bus geriau, jei pateiksiu pačią funkciją- vis gi bus aiškiau kaip viskas veikia. Pradžioje aprašysiu patį funkcijos veikimą, o apačioje pateiksiu ir jos kodą. Šią funkciją galite naudoti, modifikuoti ir pritaikyti savo poreikiams visiškai laisvai.

Funkcijos aprašymas

Funkcija veikia itin paprastai, taigi jai aprašyti užteks parametrų aprašymo. Taigi į funkciją kreipiamės 3 arba 4 parametrais:

  1. Kintamojo vardas. Šis parametras nurodo kintamojo vardą masyve, taigi jei mums reikia $_GET['vardas'], tai pirmasis parametras - ‘vardas’ . Pirmajam parametrui taip pat galima perduoti vardus su taškais. Taškai žymi gilesnius masyvus, taigi jei norime pasiekti $_GET['formos']['pirma']['vardas'], tai pirmasis parametras - ‘formos.pirma.vardas’.
  2. Kintamojo vieta - masyvas. Vienas iš super masyvų - GET, POST ar pan. Nesunkiai galima praplėsti ir kitais masyvais, bet man kitų neprireikė (REQUEST, ENV ir pan.).
  3. Kintamojo tipas. Ši vieta taip pat lengvai modifikuojama ir galima sukurti įvairiausių tipų, bet man reikalingi šie - int (skaičiams), float (kainoms ir pan., kableliai keičiami taškais, norint apsisaugoti nuo žmonių, kurie įvedė kablelį vietoje taško), string (pavadinimams, pašalinami visos HTML žymės), text (tekstui iš WYSIWYG laukų, kadangi TinyMCE kai kuriuos simbolius paverčia į „HTML entities“, tai aš juos gražinu atgal), boolean (beveik nenaudojamas, veiktų su ‘true’,'false’).
  4. (Nebūtinas) Ar apsaugoti nuo SQL atakų - escape’inti pavojingus simbolius. Šis parametras nėra būtinas, nes 99% šios funkcijos gražinamų rezultatų naudoju SQL užklausose, o jose escape’inimas privalomas. Escape’inimui naudojama escape funkcija, kuri gali būti pakeista į mysql_real_escape_string ar pan. (aš naudoju AdoDB funkciją).

Funkcijos kodas

function getVar($var, $array, $type, $escapeString = true) {
 
	if (strpos($var, '.') !== false)
		{
			$var_original = substr($var, strpos($var, '.') + 1);
			$var = substr($var, 0, strpos($var, '.'));
		}			
 
	switch ($array) {
		case 'GET' :
			$value = $_GET[$var];
		break;
		case 'POST' :
			$value = $_POST[$var];
		break;
		case 'SESSION' :
			$value = $_SESSION[$var];
		break;
		case 'COOKIE' :
			$value = $_COOKIE[$var];
		break;
		case 'SERVER' :
			$value = $_SERVER[$var];
		break;
		case 'FILES' :
			$value = $_FILES[$var];
		break;
	}
 
	if ($var_original)
	{
		while (strpos($var_original, '.') !== false)
			{
				$var = substr($var_original, 0, strpos($var_original, '.'));
				$value = $value[$var];
				$var_original = substr($var_original, strpos($var_original, '.') + 1);
			}
 
		if (strlen($var_original) > 0)
			{
				$var = $var_original;
				$value = $value[$var];
			}
	};
 
	if (empty($value))
		return null;
 
	switch ($type) {
		case 'int' :
			$value = (is_numeric($value)) ? (int) $value : 0;
			$value += 0;
		break;
		case 'float' :
			$value = str_replace (',', '.', $value);
			$value = is_numeric($value) ? (float) $value : 0;
			$value += 0;
		break;
		case 'string' :
			$value = (string) $this->descript($this->stripTags($value));
		break;
		case 'text' :
			$value = (string) html_entity_decode($this->descript($value), ENT_QUOTES, 'UTF-8');
		break;
		case 'boolean' :
			$value = ($value == "true" || $value == "false") ? $value : null;
		break;
	}
 
	if ((is_string($value) || is_numeric($value)) && $escapeString)
		$value = $this->escape($value);
 
	return (!empty($value)) ? $value : null;
}

Skaičiuojam

PHP kalboje kintamieji visiškai nesiskiria nuo kitų kalbų, tačiau perėjusiems nuo tokių kalbų kaip Pascal kartais atrodo nesuprantami tokie masyvai kaip $_GET, $_POST ir pan. Plačiau nenagrinėsiu jų atsiradimo priežasčių - platesnė informacija pasiekiama HTTP protokolo aprašuose, bet parodysiu kaip aš su jais dirbu. Primygtinai nesiūlau naudoti mano sprendimo, bet manau, kad jis yra gana patogus ir lankstus ir vieną kartą jį pasidarius, vėlesnis darbas su projektu tampa lengvesnis. Šis sprendimas susideda vos iš vienos funkcijos, o jos savybės jaučiamos visame projekte.

Pradėsiu nuo to, kad visi kintamieji programos vykdymo pradžioje turi būti patikrinti - get_magic_quotes_gpc metodas gražina true reikšmę jei serveris visus kintamuosius escape’ina (net neįsivaizduoju kaip išversti, pavyzdys: Juozas’ => Juozas\’, Nice \ Try - Nice \\ Try) - prie kabučių, apostrofų ir pan. simbolių yra prirašomas pasvirasis brūkšnys. Tai yra daroma siekiant apsaugoti žioplus ir pradedančiuosius programuotojus, nes jei tai nebūtų daroma daugybė svetainių jau nebegyvuotų - papildomai neįdiegus SQL injekcijų apsaugos, svetainės taptų visiškai nesaugios ir itin lengvai nulaužiamos. Tačiau šiuos brūkšnius aš visada pašalinu nes:

  1. norint panaudoti kintamuosius puslapyje, papildomi simboliai „sugadins“ informaciją, nes ji nebe sutaps sutaps su vartotojo įvesta (jei vartotojas įvedė „John’s“, tai rezultatas bus - „John\’s“)
  2. apdorojant kintamuosius vėliau, yra žymiai korektiškiau apdoroti originalius duomenis, o ne jau pakeistus
  3. kadangi aš visus kintamuosius apdoroju centralizuotai, man negresia saugumo spragos.

Šiuos brūkšnius pašaliname su stripslashes. Taip apdoroti kintamieji (su stripslashes reikia apdoroti $_GET, $_POST ir pan. masyvus) yra paruoši darbui. Tačiau tai tėra tik pasiruošimas ir jis beveik nesusijęs su mano sprendimu, nes jis tik paruošia kintamuosius naudojimui - užtikrina tai, kad jie būtų identiški vartotojo įvestiems.

Pereikime prie mano sprendimo, kurį šiandien apžvelgsiu daugiau teoriniu pagrindu, nes jo kodas yra tikrai simple ir pagal šią teorinę medžiagą jį nesunku parašyti. Norint patogiai dirbti su kintamaisiais reikia nusistatyti taisykles pagal kurias atsirenkame kintamuosius, nes sieksime centralizuoto jų valdymo:

  • Kintamojo vardas
  • Vieta - GET, POST, SESSION, COOKIE, SERVER, FILES
  • Tipas - string, int, float, text, boolean

Tokios elementarios taisykles leidžia labai patogiai dirbti su kintamaisiais. Patogumas atsiranda tame, kad su viena funkcija mes manipuliuojame visais globaliaisiais kintamaisiais ir visų filtrų taikymas yra centralizuotas, todėl visada žinome iš kur ir kokios reikšmės įgaunamos. Be to, tai yra ir labai saugu, nes žinome ko tiksliai norime (taikome tipo filtrą), o ne pasitikime vartotoju. Tarkime, kad norime pasiekti straipsnio pavadinimo kintamąjį atsiųstą POST metodu, rašome:

$_POST['straipsnio_vardas']

Tačiau toks kintamasis dar netinkamas naudoti, nes reikia pritaikyti XSS atakų filtrą, pašalinti visas HTML žymas, apsaugoti nuo SQL atakų ir t.t. Visus šiuos veiksmus atlikti yra būtina, o jei tai atliekama su kiekvienu kintamuoju atskirai, tai gali būti labai „skausminga“, nes prireiks labai daug rašymo, o vėliau norint pakeisti ar papildyti filtrus, reikės modifikuoti daugybę kodo. Turbūt akivaizdu, kad toks kodas:

print getVar('vardas', 'GET', 'string');

yra žymiai patogesnis ir lankstesnis, nei:

print mysql_real_escape_string(protect_XSS(remove_SQL(strip_tags($_GET['vardas']))));

Aukščiau minėta funkcija getVar atsako už viso kodo kintamuosius - t.y. visame projekte nėra nei vienos kodo eilutės, kuri tiesiogiai kreipiasi į minėtus masyvus. Tai itin naudinga, nes bet kurioje projekto stadijoje sugalvojus papildyti kintamųjų tikrinimą ir apdorojimą nauju filtru užtenka pakeisti vieną funkciją ir pakeitimai įsigalios visame kode.

Nežinau ar iki galo jus įtikinau, kad kintamuosius apdorojant per specialią funkciją yra pasiekiama puikių rezultatų. Turbūt toks mano požiūris į kintamuosius atėjo iš pripratimo visą programą-projektą suskirstyti į logines dalis ir visas manipuliacijas su duomenimis išskirstyti į funkcijas. Jei jūsų stilius ne toks ir jums labiau patinka kintamuosius pasiekti tiesiogiai - tebūnie, tačiau jei nesate apsisprendęs ar esate tiesiog pavargęs nuo daug kodo rašymo, primygtinai rekomenduoju pabandyti pasidaryti funkciją kintamiesiems apdoroti. Iš patirties sakau, kad tokia funkcija suteikia kodui ne tik saugumo, bet ir logiškumo, paprastumo ir dinamiškumo. O jei šiame straipsnyje jūs nieko nesupratote - gerų Kalėdų!


© 2008 Juozo Kaziukėno blogas | TextNData dizainas | Wordpress variklis