Egy tech cég kulisszatitkai

Aki pokolra kíván jutni...

2014. november 24. - sieglzoltan

 

Ímmáron harmadik napja folytatjuk hadjáratunkat, melynek célja a Spring framework számos bugyrának feltérképezése. Az asztalokon csak gyűlnek az energiaitalos dobozok, az előtérben lévő kávéfőző keresűen sír.

Péter - az egyik akadémiás csapattárs -  végső elkeseredésében az utolsó lehetőséget is megragadta, hogy életet leheljen elhalványuló testébe: Ebédnél a Magic Burgerben csatlakozott a nehézfiúk klubjához. "Pokol Tüze Esszenciával" kérte az ebédjét, amely a kapható legerősebb (kb. 1 000 000 Scorville értékű) chiliesszencia. Béke poraira. Hamvait szétszórjuk a szélben.

A mai nap tanulságaként egy rövid eljárás, amely Péter várhatóan bekövetkező spontán öngyulladása esetén méltó módon elbúcsúzik tőle.

@Component
public class myGrace implements ApplicationListener<SpontaneousCombustionEvent> {
     public void onApplicationEvent(SpontaneousCombustionEvent event) {
          String name = event.getName(); 
          return this.messageSource.getMessage(

                 "goodbye",

                 new Object[](name),

                 new locale("hu", "HU")

          );
     }
}

P.s: Szavazzátok meg, kérlek, hogy ez milyen ülő-fekvő alkalmatosság:

FullSizeRender (1).jpg

Kanapé? Rekamié? Sezlon? Priccs? Pamlag? Szófa? Hencser? Nyoszolya? Dívány? Kerevet?

Első EPAM Budapest Mobile Meetup

 

Október 15-én zajlott le az első EPAM Budapest Mobile Meetup - és mondhatni egész jól sikerült :). Két előadás volt a meetupon, Csanády István és Marinov Iván előadásában, mindketten profi előadónak bizonyultak - köszi nektek srácok! A Mobile Meetup az Epam berkein belül már 2014 március óta majdnem minden héten megrendezésre került - nagyon sok jó témában adtak elő a kollégák Windows Phone, Android és iOS-ről minden mennyiségben, illetve Xamarin-ról, PhoneGap-ről, de sok más IoT témát is érintettünk mint például a Raspberry PI, Netduino vagy a Spark.io. 

 

A meetupon két prezentáció volt. Az elsőt Csanády István (Founder at Shapr) tartotta "Négy nyelv, egy app - C, C++, Objective-C, Swift egy projektben" címmel, ahol a Shapr alkalmazás architektúrájába engedett beletekinteni és nagyon jó optimalizációval kapcsolatos dolgokról is hallhattunk. Második előadóként Marinov Iván (Software Engineering Team Lead @ Epam Systems) lépett fel - ő a "QT: Platform független megoldás mobil alkalmazás fejlesztésre" című előadásával a QT egyszerűségére, könnyedségére világított rá ahol megláthattuk milyen egyszerű akár mobil alkalmazásokat is készíteni ezzel a megoldással. 

 

A kötelező pizzás befejezés után a csapat egy része átvándorolt a Grund-ra a látottakat megbeszélni, illetve sör- és borfogyasztás mellett több-kevesebb sikerrel csocsóban villantani :) ...

 

Ezúton is köszi mindenkinek aki eljött!

 

AbstractSingletonProxyFactoryBean

extreme-abstracting.jpg

A mai napon elkezdük átvenni a Spring framework szépségeit... Kicsit utánakérdezve a témának, az volt a mondás, hogy ez egy elég masszív téma lesz. Ennek megfelelően mindenki jól kipihenten rengeteg koffeinnel felvértezve vágott neki a napnak.

A nap tanulságai 1:

A spring framework megértésének a kulcsa először is az Inversion of Control konténer mibenlétének az elsajátítása. Az IoC megfogalmazása a következő: 
"Az Inversion of Control egy olyan irányelv, amelyben a vezérlés iránya megfordul a hagyományos procedurális programozáshoz képest."

Hát, kérem: ember legyen a talpán, aki ebből megérti, hogy miről van szó.

A magyar wikipedia szócikk már kicsit slendriánabb, de kicsit emészthetőbb: 
"Az inversion of control (röviden IoC) főleg objektumorientált programozási nyelvekben használt technika a komponensek összeillesztésére, konfigurálására és kezelésére."
Tiszta? Nem? Oké, megmagyarázom:

Hagyományos megközelítés:

Álmos vagyok, tehát azt mondom:

- Hé! Kávéfőző! Főzz egy kávét! Itt van ez a két cukor! Ezt tedd bele. Itt egy kis tej. Ezt is kérem a kávémba! Add ide a kávét.

Inversion of control - elkérem a konténertől megközelítés:

Álmos vagyok, tehát azt mondom:

- Kávét!

Csodák csodájára a kezemben terem egy kávé. Nem tudom, ki főzte, és mi van benne, de én pont ezt a kávét szeretem.

Inversion of Control - konstruktor megközelítés:

Álmos vagyok. Szerencsére épp van egy tökéletes kávém.

Inversion of Control - Lasy loading megközelítés:

Elálmosodom. Odalép hozzám egy IoC konténer.

- Hé! Álmosnak tűnsz. Tessék, itt egy kávé!

Na jó! Fogalmazzuk meg komolyabban a problémát. Az IoC lényege, hogy elválasszuk a "hogyan?" kérdésre adott válaszokat a "mikor?" kérdésre adott válaszoktól. Egy-egy objektumnak ugyebár vannak dependenciái. Ezeket valamilyen módon be kell állítani. Ha nekem, mint objektumnak szükségem van egy loggerre, akkor nem nekem kell tudnom, hogy milyen logger hozok létre, az syslogba logol, vagy fileba, annak milyen egyéb függőségei vannak, hanem egyszerűen csak kérek az IoC konténertől egy loggert. Az ehhez szükséges beállítások, amelyek megmondják a kérdés hogyanságát, azok egy elkülönített helyen, valamiféle beállítás definíciós fileban dőlnek el.

Egy rövid példa kód a két megközelítésre:

IoC nélkül:

public class TestBankServiceIntegration {
    @Test
    public void testList() {
        //given
        List<String> expected = new ArrayList<>();
        expected.add("Béla");
        expected.add("Géza");
        expected.add("Jenő");

        BankService sut = new BankService(new BankDao());

        //when
        List<String> result = sut.listClients();

        //then
        Assert.assertEqualsNoOrder(result.toArray(), expected.toArray());
        }
     }

IoC konténerrel:

@ContextConfiguration(classes = AppConfig.class)
public class TestBankService extends AbstractTestNGSpringContextTests {

    @Autowired
    private BankService sut;

    @Test
    public void testGetClients() {
        //given
        List<String> expected = new ArrayList<>();
        expected.add("Béla");
        expected.add("Géza");
        expected.add("Jenő");

        //when
        List<String> result = sut.listClients();

        //then
        Assert.assertEqualsNoOrder(result.toArray(), expected.toArray());
}

Mit látunk a fenti kódban ami érdekes lehet?

@ContextConfiguration(classes = AppConfig.class)

Tehát itt egy config class számunkra mágikus módon megmondja, hogy hogyan kell BankService osztályt példányosítani.

 

    BankService sut = new BankService(new BankDao());

 

Az első kódban itt ugyebár a hagyományos módon példányosítottuk a BankService osztályunkat. Gondolom nem kell magyaráznom, hogy amennyiben több dependenciája van, amelyeknek további dependenciái vannak, akkor ez mennyire nehézkes lehet.

Ehelyett IoC konténerrel:

    @Autowired
    private BankService sut;

Voillá! Ennyi az egész.

Ha ezt megérted, akkor már csak meg kell tanulni, hogy hogyan lehet ezt a létrehozási mechanizmust konfigurálni XML-el, Java osztályokkal, annotációkkal, és milyen pontokon miféle módon avatkozhatsz bele a gyártási folyamatba, de ezek már a nagy felismeréshez képest részletkérdések.



A nap tanulságai 2.

A spring framework POJO-val (Plain Old Java Object) dolgozik. Viszlát, PHP-s világ. (Viszlát Plain Old PHP Objectek azaz POPÓ-k! :( ) Azt is megtudhadtuk, hogy a POJO annyiban különbözik a java bean-től, hogy nincsenek megkötései. Bármilyen számunkra kedves Java objektumot példányosíthatunk az IoC konténerünkben. 

Aztán megtudhadtuk, hogy amennyiben egy POJO életciklusáról a spring gondoskodik, onnantól azt a POJO-t valójában Bean-nek (Spring bean) nevezzük. Valamint, hogy amennyiben szeretnénk könnyen beállítható propertyket használni, akkor nem baj, ha azokat a setPropertyName - getPropertyName konvenciót követő accessorokkal látjuk el. Valamint hogy ezekhez definiálhatunk a Jaba Bean világból származó PropertyEditorokat. De fontos tudni, hogy a spring POJO-val dolgozik, nem pedig bean-ekkel. :)



A nap tanulságai 3.

Egyelőre nem olyan ijesztő a spring, mint elsőre tűnt. Szép nagy anyagrész, amit 4 nap alatt kell átrágnunk, végre láttam a csapatban szünetben a kinti nagyon desinos de ülésre-fekvésre használhatatlan bútorokon szünetben fáradtságtól összeesve alvó embert, és a nap végére már többen a zombiság olyan szintjére jutottunk, hogy egymás agyának elfogyasztása hívogatóbb volt az amúgy nagyon ízletes minden nap ajándékba kapott tökmagos pogácsánál. Ezaz! Végre rock and roll! Várom a holnapi napot!

 

Hello world

Sziasztok! Siegl Zoltán vagyok, barátaim Eddienek szóítanak. Úgy tűnik én foglak néha postokkal ellátni titeket itt a Life in Tech blogon.

Összeszámolni is ijesztő, hány éve foglalkozom programozással, és agilis projektmenedzsmenttel. A PHP-s világból érkeztem ide az EPAM Java academy falai közé, ahol lassan másfél hónapja koptatom a billentyűzetet. A web-es PHP-s világban bőséggel láttam már falon pókot. Implementáltam nagy látogatottságú rendszereket, elosztott rendszereket, demonizált folyamatokat, és még sok egyebet.

Az egyetemen sok tárgyból Java-ban kellet implementálni a feladatokat, és mindig úgy éreztem, hogy az erős típusosság valahogy önmagában az achitektúra jobb átgondolására készteti az embert. Ez persze így nem teljesen igaz, típusos nyelven is lehet nagyon jó és nagyon rossz rendszereket készíteni, de most, hogy kicsit több időt foglalkoztam a Java-val továbbra is szépnek, és kényelmesnek találom.

A programnyelv váltás mellett elsősorban azért döntöttem, mert bár sok izgalmas projekt van a PHP-s világban is, az igazi nagyvállalati rendszerek általában nem szkript nyelven íródnak. Az EPAM Academy adta meg a végső lökést. Amivel meggyőzött:

  • Kiváló feltételek az oktatás időszaka alatt is
  • Hasznos, gyakorlatias oktatás
  • Kemény kihívás az oktatás alatt
  • Az academy után sok és változatos projektlehetőség
Szóval viszlát PHP, Helló Java, Helló Epam, Helló Világ!

Inverted Index és Fordító Motor

Az inverted index egy adatstruktúra, ami egyszerűvé teszi egy szó (token) előfordulásainak a meghatározását egy szótár kifejezéseiben. A fordító motornak az a feladata, hogy meghatározza egy mondat összes szótárban szereplő rész kifejezését. Azt szeretnénk belátni, hogy az inverted index segítségével hatékony fordító motort tudunk építeni.

A fordító motor segítségével fordítót lehetne gyártani azáltal, hogy megmondjuk, hogy a mondat kifejezéseiből melyeket és azokat milyen sorrendben kívánjuk lefordítani és kombinálni a célnyelv mondatává. Fordítási stratégiák, heurisztikák definiálásával azonban most nem foglalkozunk.

A pontosabb érthetőség kedvéért ábrázoljuk a szótárat egy d: E -> E' függvénnyel, ahol E és E' az L és L' nyelvek kifejezéshalmazai.

Ha d(e) = e', akkor azt mondjuk, hogy az e kifejezés fordítása e'. Minden mondat kifejezések, minden kifejezés tokenek (szavak) sorozata. A fordítási problémánk abból fakad, hogy egyrészt egy mondatot értelmezni kell ahhoz, hogy felismerjük mely kifejezések alkotják, másrészt ez a felismerhető szerkezet nem feltétlenül egyértelmű. Gondoljunk csak arra az elemi algebrából jól ismert "asszociatív" esetre, amikor is egy szótár forrás nyelvének mindössze öt kifejezése van "a", "b", "c", "ab", "bc" és az "abc" mondatot kell értelmeznünk. Ekkor az {"a", "b", "c"}, {"ab", "c"}, {"a", "bc"} felbontások egyaránt helyesnek tekinthetők, azaz a fordítást bármelyikre lehetne alapozni. Szerencsére most nem kell a lehetséges felbontásokkal, átzárójelezésekkel törődnünk, hiszen csak a fordító motor definiálására vállalkoztunk, aminek mindössze az input mondat összes kifejezésével kell visszatérni:

 

                {"a", "b", "c", "ab", "bc"}.

 

Egy egyszerű, de helyesen működő fordító motort nyerünk azáltal, hogy eldöntjük az input mondat összes összefüggő részhalmazáról (intervallumáról), hogy a szótárnak kifejezése-e. A példánkban szereplő "abc" mondat esetén az {"a", "ab", "abc", "b", "bc", "c"} részekről kell döntenünk. Általában egy n tokenből álló mondat esetén n(n-1)/2 részhalmazról kell dönteni. Ez nem feltétlenül rossz eljárás, azonban hosszú mondat és kifejezésekben szegény szótár esetén feleslegesen sok munkát végez.

Egy másik motor definíció lehet a következő. Először készítsünk el egy inverted index-et. Tokenizáljuk a szótár kifejezéseit és az így nyert tokenek mindegyikéhez rendeljük hozzá a szótárnak ezzel a tokennel kezdődő kifejezéseinek a halmazát. A példa szótárunk esetén az

 

                a -> {"a", "a b"}

                b -> {"b", "b c"}

                c -> {"c"} 

 

inverted index-hez jutunk.

 

Az inverted index elkészítése után feltehetjük, hogy kapunk egy tokenizált mondatot. A mondat lehetséges kifejezéseinek egy P halmazát fogjuk fenntartani. Egy kifejezést lehetségesnek mondunk, ha az inverted index a mondat egyik tokenjéhez rendeli. Minden lehetséges kifejezésnek van egy i életkora. Az életkor egy természetes szám, 0-val kezdődik és minden lépéssel 1-et nő.

Kezdetben P üres. Az eljárás annyi lépésből áll ahány tokenje van a mondatnak. Minden lépés elején kibővítjük P-t azokkal a kifejezésekkel (i=0 életkorral) amelyeket az aktuális tokenhez rendel az inverted index. Ezután, ha egy kifejezés életkora megegyezik a kifejezés tokenekben mért hosszával, akkor a kifejezést elfogadjuk és eltávolítjuk P-ből. A p kifejezést elutasítjuk és eltávolítjuk P-ből, ha p[i] nem egyenlő t-vel, ahol p[i] a p kifejezés i-edik tokenje, i az életkora, t pedig az aktuális token. A lépés befejeztével P azon tokenekből fog állni, amelyeket a fentiek alapján vagy nem fogadtunk el de el sem utasítottunk vagy újonnan vettünk hozzá P-hez.

Ha elfogyott az összes token visszaadjuk az elfogadott kifejezéseket.

Könnyen igazolhatjuk, hogy az algoritmus helyes, azaz a mondatban szereplő minden kifejezést megtalál és csak azokat. Műveletigénye arányos a mondatban szereplő tokenekhez az inverted index által hozzárendelt kifejezésekben szereplő tokeneknek a számával, azaz 

                complexity = O(sum{|p| : p inv(t), t s}),

 

ahol "s" az input mondat, "t" egy tokenje, "inv" az inverted index, p egy t-vel kezdődő kifejezés, |p| a p kifejezés tokenjeinek a száma, "sum" pedig az összeadás.   

 

 

Type-Safety

Elkezdődött az akadémia, túl vagyunk az első benyomásokon. Mindannyian találkoztunk jól ismert, kevésbé ismert és új dolgokkal. Például elhangzott egy fogalom, hogy egy program "type safe", ha warning-ok nélkül fordul és ha nem használunk benne explicit típus konverziót, akkor futásidőben nem fog ClassCastException-t dobni. Számomra ez új volt, de legalábbis eddig nem érdekelt vagy foglalkoztam vele, hiszen a scriptjeimet nem különösebben érintette. Mindenesetre ez a definíció arra bátorít, hogy konstruáljunk olyan programot, ami warningok nélkül fordul, nem konvertál, mégis ClassCastException-t dob, úgyse fog sikerülni.

Nézzük hát a következő explicit konverzió mentes program részletet:

                ArrayList<Object> l = new ArrayList<Integer>();

                l.add(new Object());

                Integer i = l.get(0);

Készítünk egy üres Integer listát amire Object lista referenciával mutatunk. Ezt a referenciát használva kibővítjük a listát egy új Object-el, majd elkérünk egy Integer referenciát az Integer lista első elemére. Mivel Object-et nem lehet Integer-be konvertálni azt várjuk, hogy ezért futásidőben CastCastException-t kapunk.

Nem ez a helyzet, mivel a compiler már az első sort type mismatch error-al jutalmazza pont emiatt a példa miatt.

Ezek után felmerül bennem az esetleges vizsgakérdés, hogy vajon ugyanez a műsor tömb esetén mit eredményez?

 

                Object[] a = new Integer[1];

                a[0] = new Object();

                Integer i = a[0];

 

                (a) lefordul és fut

                (b) lefordul és ClassCastException-t dob

                (c) nem fordul és az első sor type mismatch error-t ad

                (d) nem fordul és a harmadik sor type mismatch error-t ad

 

Ezt ténylegesen ki is próbáltam, de azért nagyon nem szeretnék vele semmilyen vizsgán se találkozni. Nagy a fogadkozás, hogy az Epam Academy vizsgán ilyen kérdések nem lesznek, de hát ez csak az első vizsga után tud kiderülni ami egy hét múlva lesz, és természetesen én addig semmit sem hiszek el.

Végezetül talán érdemes megjegyezni, hogy az alábbi program lefordul és ArrayStoreException-t dob - mellékesen a helyes választ is mutatja az előző kérdésre:

 

                Object[] a = new Integer[1];

                a[0] = new Object();

                Integer i = (Integer) a[0];

EPAM Academy

Az EPAM budapesti irodája olyan tehetséges embereket keres, akikben van szenvedély, büszkék a munkájukra és maximalisták abban, amit csinálnak. Hisszük, hogy a munkatársaink különbözőségei mozdítják előre cégünket, hozzájárulnak sikereinkhez és ennek is köszönhetjük az eddig elért eredményeinket.

Itt az alkalom, hogy csatlakozz az EPAM Academy-hez mely egy olyan oktatási program, melynek keretében magas szintű Java fejlesztőket képzünk, úgy hogy már a képzés ideje alatt versenyképes fizetést biztosítunk számukra.

Tovább

EPAM Academy Miklós Zoltán szemével

Sziasztok!

Miklós Zoltánnak hívnak, egy hónapja vagyok az EPAM-nál és jelenleg az EPAM Academy programban veszek részt. Az ELTE-n végeztem elméleti matematikusként. Fő tárgyam kombinatorikus optimalizálás volt. Sokáig nem programoztam, mert azt gondoltam, hogy a matematika nyelve és a matematika nyelvén megírt program - a bizonyítás - a legalkalmasabb az élet bonyolult dolgainak a megértésére. Aztán változott a világ körülöttem és elszegődtem az Ericsson R&D-be majd a Morgan Stanley-be programozni.

Szembesültem azzal, hogy emberek csoportjai terveznek, írnak és üzemeltetnek hatalmas, reménytelenül bonyolult, de sok esetben mégis működő rendszereket, amiket nem szükséges senkinek sem teljes részleteiben megérteni: néha elég annyi is, hogy a rendszer legalábbis működik.  Az EPAM Academy programban az a cél, hogy megtanuljuk, de legalábbis az alapjait lefektessük annak a tudásnak, ami a reménytelenül bonyolultnak látszó rendszerek tervezéséhez, írásához, teszteléséhez és biztonságos üzemeltetéséhez szükségeltetik. A blogot azzal a szándékkal kezdtem el írni, hogy az olvasókkal megismertessem a programot és ezzel felkeltsem a hozzám hasonló gondolkodású emberek érdeklődését a szakma iránt.  A posztokban a training során felmerülő érdekes kérdéseket szeretném hétről hétre kiragadni és megosztani a blog olvasóival. 

Hello! Itt a „Life@EPAM” blog!

 

Ez az oldal azzal a céllal indult, hogy megosszunk minden olyan eseményt, történetet és gondolatot mely az EPAM Magyarország munkatársaihoz, közösségéhez kapcsolódik. Az oldal mindazoknak szól, akik velünk dolgoznak, dolgoztak vagy a jövőben csatlakoznak hozzánk és bárkinek, akit érdekel, hogy milyen nálunk/velünk az élet.

A jövőben képeket, videókat, élménybeszámolókat találhattok itt az EPAM háza tájáról. Írni fogunk minden olyan eseményről, amin közösen vettünk részt (AirSoft bajnokság, Hackathon, Beer lesson, bográcsozás, stb.) és olyanokról is, ami munkatársainkkal történt és büszkévé tesz minket, inspirációul szolgálhat másoknak. Számunkra nagyon fontos a munkánk ezért olykor szakmai bejegyzésekkel is találkozhatsz majd, programajánlatokat és IT-s érdekességeket is közzé fogunk tenni.

Nem akarunk untatni, de hogy kicsit megismerd a céget röviden írunk arról, kik is vagyunk és mivel foglalkozunk.

Az EPAM Systems egy világméretű software fejlesztő és IT tanácsadó cég, 1993-ban alapította a fehérorosz származású Arkadiy Dobkin és Leo Lozner. A vállalat szinte a világ minden táján rendelkezik fejlesztő központokkal: Egyesült Királyság, Kanada, USA, Svájc, Németország, Svédország, Hollandia, Fehéroroszország, Magyarország, Oroszország, Ukrajna, Kazahsztán, Lengyelország, Szingapúr, Hongkong.

Budapesti irodánk 2004-ben alakult, mikor a magyar alapítású Fathom Technology beolvadt az EPAM Systems-be. A budapesti iroda mellett 2004-ben Debrecenben majd 2008-ban Szegeden is megnyitottuk irodánkat, jelenleg több mint 1000 fős létszámmal dolgozunk Magyarországon.

Neked is van egy történeted, amit el szeretnél mesélni? Küld el a epam.life@gmail.com címre és a Te történeted is bekerül az EPAM sztorik közé.

 

Welcome to the “Life@EPAM” blog!

 

This site was launched with the purpose of sharing all the events, stories and thoughts about the employees and the community of EPAM Hungary. The site is for all of you who are working, have worked or in the future will be working with us and for everyone else who is interested in our traditions. You will find photos, videos and posts about the everyday life at EPAM. We will write about every event in which we participated (AirSoft Championship, Hackathon, Beer lesson, barbecue, etc.) and also about what happened to our colleagues, what made us proud and what may be inspirational for you. Our work is very important for us, therefore you might find some professional posts, program suggestions and interesting IT facts.

We don’t want to sound boring however you might want to know some basic facts about who we are and what we do.

EPAM Systems is a global Software Developer and IT Consultant Company founded in 1993 by the Belarussian Arkadiy Dobkin and Leo Lozner. The company has headquarters all over the world: UK, Canada, USA, Switzerland, Germany, Sweden, The Netherlands, Belarus, Hungary, Russia, Ukraine, Kazakhstan, Poland, Singapore and Hong Kong.

Our office in Budapest was established in 2004 when the Hungarian-founded Fathom Technology merged with EPAM Systems. In Hungary, after the opening of Budapest office, other offices opened in Debrecen (2004) and later in Szeged (2008). At the moment our staff consists of more than 1000 people in Hungary.

Have you got a story that you would like to share? Send it to the epam.life@gmail.com address and your story will become one of ours.  

 

süti beállítások módosítása