2014. december 12., péntek

Java SE 8 - Funkcionális interfészek

Miután megismerkedtünk a Lambda kifejezésekkel, folytassuk az utunkat a funkcionális interfészekkel amiknek a jellemzője, hogy csak egyetlen egy absztrakt metódussal rendelkeznek és a Lambda kifejezések típusát fogják majd meghatározni. A metódus neve bármi lehet, a lényeg hogy a szignatúrája kompatibilis legyen a Lambda kifejezéssel. Funkcionális interfészekkel már korábban is találkozhattunk a Java nyelvben (Runnable, Callable, Comparator), azonban a JDK8-at is kiegészítették jó pár generikus funkcionális interfésszel:
// Predicate<T>
Predicate<Integer> p = x -> x > 5;
System.out.println(p.test(10)); //true

// Consumer<T>
Consumer<Integer> c = i -> System.out.println(i);
c.accept(111); //111

// Function<T,R>
Function<Integer, String> f = i -> i > 10 ? "OK" : "NOT OK";
System.out.println(f.apply(100)); //OK

// Supplier<T>
Supplier<Integer> s = () -> 66;
System.out.println(s.get()); //66

// UnaryOperator<T>
// return használatakor a {}-t ki kell tenni 
UnaryOperator<Boolean> u = (bool) -> {return !bool;};
System.out.println(u.apply(false)); //true

// BinaryOperator<T>
BinaryOperator<Double> b = (Double d1, Double d2) -> d1 + d2;
System.out.println(b.apply(11d, 22d)); //33.0
A fenti kódrészleten látható Predicate funkcionális interfész egyetlen egy absztrakt metódust tartalmaz (test()), ami paraméterként Integer típust vár és a visszatérési értéke boolean. Érdemes megemlíteni, hogy a paraméter típusát nem kötelező definiálni, mivel a Type Inference feature segítségével a java compiler ezt képes kikövetkeztetni.

A beépített funkcionális interfészek mellett akár sajátot is létrehozhatunk és opcionálisan elláthatjuk a @FunctionalInterface annotációval, így a fordító azonnal szól ha esetleg több absztrakt metódust is defniáltunk volna az interface-ben.

A folytatásban a Stream API következik.

2014. december 1., hétfő

Java SE 8 - Lambda kifejezések

A Java SE 7 újdonságai után haladjunk a korral és nézzük meg a Java SE 8 leginkább várt feature-ét, a Lambda kifejezéseket. A Lambda kifejezések és a hozzá kapcsolódó újítások (Stream API, funkcionális interfészek, alapértelmezett metódusok, metódus referenciák) azért is jelentősek, mivel a Java SE 5 verzióban megjelent generikusok és annotációk óta nem volt ilyen nagy változás, ami ennyire átalakította volna a Java nyelv használatát. A lambda kifejezésekkel tisztább, sokkal kifejezőbb és így karbantarthatóbb kódot írhatunk valamint már nyelvi szinten is kihasználhatjuk a több processzoros gépek párhuzamos feldolgozási képességeit. De mik is azok a lambda kifejezések?

A lambda kifejezések olyan névtelen metódusok, amiket ott írunk meg ahol ténylegesen használunk. Egy remek példa erre az anonim osztályokkal megvalósított Swing-es eseménykezelők átírása lambda kifejezések használatával:
Button btn = new Button();

//anonymous inner class
btn.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent event) {
  System.out.println("print");
 }
});

//lambda expression
btn.addActionListener(event -> System.out.println("print"));
A lambda kifejezéssel magát a viselkedést, tehát az implementációt adjuk át az addActionListener() metódusnak, nem pedig egy olyan objektumot ami megvalósítja a kívánt interfészt. A fenti példa alapján beazonosítható a Lambda kifejezések szintaktikája, azaz definiáljuk a paramétereket - akár a típus megnevezése nélkül - (event), a nyíl tokent (->) majd az implementációt (System.out.println("print")).

A továbbiakban nézzünk meg néhány mintát a Lambda kifejezésekre. Az első példában egy Comparator-nak adjuk meg az implementációját, majd a 10 és 20 értékre vonatkozólag megjelenítjük az eredményt. A második példa pedig egy argumentum nélküli, több soros implementációval rendelkező Lambda kifejezést mutat.
// sample1
Comparator<Integer> myComparator = (a, b) -> a.compareTo(b) * -1;
System.out.println(myComparator.compare(10, 20));

// sample2
int i = 10;
// i=777; fordítási hiba, mivel az i változó "effectively final"
Runnable r2 = () -> {
 int c = i + 8;
 System.out.println("Adder: " + c);
};
r2.run();
Érdemes megemlíteni, hogy az i változó értékét nem módosíthatjuk annak ellenére, hogy a final módosító nincs kiírva, mivel azt egy lambda kifejezésben is használjuk. (effectively final)

A cikk hamarosan folytatódik, legközelebb a Lambda kifejezésekhez szorosan kapcsolódó funkcionális interfészekről fogok blogolni. Egyébként használja már valaki a Java 8-ast éles fejlesztéshez? :)

2014. november 18., kedd

A Java Standard Edition 7 újdonságai

A munkámból adódóan sok vállalatnál megfordulok és azt látom, hogy a legtöbb helyen még mindig csak a Java 6-os verzióját használják annak ellenére, hogy 2014 március óta már a Java SE 8 is elérhető. Habár a hivatalos roadmap szerint a Java SE 7 publikus frissítései csak 2015 áprilisig várhatóak, érdemes a legfontosabb újdonságokat megismerni, mert azok természetesen a Java SE 8 verzióban is használhatók. Ezekből feature-ökből gyűjtöttem most össze néhányat.

1. Numerikus literáloknál aláhúzásjel használata

Az aláhúzásjelek használatának a célja, hogy megkönnyítse a számok olvashatóságát.
class Numbers {
 public static void main(String args[]) {
  int i = 1_000_000;
  long m = 9_999_999_999_999L;
  double pi = 3.14_15;
 }
}

2. String használata switch szerkezetben

A String equals() metódusával lesz kiértékelve a kifejezés. Érdemes tudni, hogy a Java compiler hatékonyabb bytekódot generál ebben az esetben, mintha az if-else szerkezetet használnánk!
class StringSwitch {
 public static void main(String args[]) {
  String fruit = "apple";
  switch (fruit) {
   case "orange":
    System.out.println("orange");
    break;
   case "apple":
    System.out.println("apple");
    break;
   case "banana":
    System.out.println("banana");
    break;
  }
 }
}

3. Erőforrások automatikus lezárása (try-with-resource)

Az erőforrások automatikusan lezárásra kerülnek, ha a try-with-resource szerkezetben, AutoCloseable vagy a Closeable interfészt implementáló osztályokat használunk.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

class TryWithResousrce {
 public static void main(String args[]) throws IOException {
  try (BufferedReader br = new BufferedReader(
                           new FileReader("c:/temp/myfile.txt"));
   PrintWriter pw = new PrintWriter(
                    new FileWriter("c:/temp/myfile.txt"))) {
   pw.println("mytext");
   pw.flush();
   System.out.println(br.readLine());
  }
 }
}

4. Multi Catch

A kód duplikáció elkerülése miatt hasznos, amikor ugyanazt a kivétel lekezelő műveletet szeretnénk használni unrelated kivételek esetén, anélkül hogy a közös ősüket kellene elkapnunk.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

class MultiCatch {
 public static void main(String args[]) {
  try {
   BufferedReader br = 
    new BufferedReader(new FileReader("myfile.txt"));
   Connection con = DriverManager
    .getConnection("jdbc:postgresql://myhost/db","u","p");
  } catch (IOException | SQLException ce) {
   //handle exceptions
  }
 }
}

5. Precise ReThrow

Nem kapunk fordítási hibát annak ellenére, hogy a kivétel lekezelő ágban feldobott e objektum általánosabb, mint a throws-nál deklarált FileNotFoundException, mivel a fordító képes meghatározni, hogy a kivétel aktuális típusa ebben az esetben FileNotFoundException lesz.
import java.io.FileNotFoundException;

public class PreciseReThrow {

 public static void main(String args[]) 
                                throws FileNotFoundException {
  try {
   throw new FileNotFoundException();
  } catch (Exception e) {
   throw e;
  }
 }
}

6. Diamond operátor használata

Az olvashatóság megkönnyítése érdekében, a jobb oldalról elhagyhatjuk a generikus típus paramétereket a <> operátor kiírásával.
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class DiamondUsage {
 public static void main(String args[]) {
  List<String> list1 = new ArrayList<>();
  List<Map<Integer,List<Double>>> list2 = new ArrayList<>();
 }
}
Persze a lista koránt sem teljes, érdemes még megismerni a NIO 2, a Concurrency API és a JDBC 4.1 újdonságait is mert hasznosak lehetnek a munkánk során és az 1Z0-804 vizsgán is kérdezhetik! .)

2014. november 7., péntek

Oracle 1Z0-804 vizsga feladatok

Ebben a bejegyzésben összegyűjtöttem néhány feladványt az 1Z0-804 vizsga kérdésekből, amelyek tipikusan jellemzik a feladatokat. A vizsgán 90 feladatot kell megoldani 150 perc alatt, amiből legalább 65%-ot kell teljesíteni! A feladatok egy része a lexikális Java API tudásra épít (pl. milyen konstruktorai vannak a Locale osztálynak) a többi pedig az alábbi példákhoz hasonló mit ír ki program:

1. Enum 
  
public enum Book {
 BEGINNER, INTERMEDIATE;

 static {
  System.out.println("static init block");
 }

 {
  System.out.println("instance initializer");
 }

 Book() {
  System.out.println("constructor");
 }

 public static void main(String... args) {
  System.out.println(Book.BEGINNER);
 }
}

2. Integer
  
public class MyInteger {
 public static void main(String[] args) {
  Integer i1 = 127;
  Integer i2 = 127;
  Integer i3 = 128;
  Integer i4 = 128;
  if (i1 == i2)
   System.out.println("same");
  else
   System.out.println("different");

  if (i3 == i4)
   System.out.println("same");
  else
   System.out.println("different");
 }
}

3. CopyOnWriteArraySet
  
public class MyCopy {
 public static void main(String[] args) {
  Set<String> set = new CopyOnWriteArraySet<String>();
  set.add("2");
  Iterator<String> iter = set.iterator();
  set.add("3");
  while (iter.hasNext()) {
   System.out.print(iter.next() + " ");
  }
 }
}

4. Overload
  
class MyOverLoad {
 private void overload(Object o) {
  System.out.println("Object");
 }

 private void overload(double[] arr) {
  System.out.println("double []");
 }

 private void overload(double arr) {
  System.out.println("double");
 }

 private void overload(int arr) {
  System.out.println("int");
 }

 private void overload() {
  System.out.println("void");
 }

 public static void main(String[] args) {
  new My().overload(null);
 }
}

5. Calendar
  
class MyCalendar {
 public static void main(String[] args) {
  DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.US);
  Calendar c = Calendar.getInstance();
  c.set(Calendar.YEAR, 2012);
  c.set(Calendar.MONTH, 12);
  c.set(Calendar.DAY_OF_MONTH, 1);
  System.out.println(df.format(c.getTime()));
 }
}

6. TreeSet
  
class MyTreeSet {
 public static void main(String[] args) {
  TreeSet<StringBuilder> treeSetNames = new TreeSet<StringBuilder>();
  treeSetNames.add(new StringBuilder("aaa")); 
  treeSetNames.add(new StringBuilder("bbb"));
  treeSetNames.add(new StringBuilder("ccc"));
  treeSetNames.add(new StringBuilder("ddd"));
  Iterator it = treeSetNames.descendingIterator();
  while (it.hasNext())
   System.out.print(it.next() + ":");
 }
}

és a megoldások:

1. Enum
instance initializer
constructor
instance initializer
constructor
static init block
BEGINNER

2. Integer:
same
different

3. CopyOnWriteArraySet:
2

4. Overload:
double []

5. Calendar:
January 1, 2013

6. TreeSet:
java.lang.ClassCastException

2014. október 30., csütörtök

Oracle Certified Professional, Java SE7 Programmer

Nagyjából fél évvel ezelőtt raktam le az 1Z0-803 vizsgát és akkor úgy döntöttem, hogy még az idén leteszem ennek a folytatását, az 1Z0-804 vizsgát is. Sikerült!


A kérdések jellege nem sokat változott, - ott próbálnak becsapni ahol csak tudnak :) - figyelni kell a részletekre, mivel néha teljesen máshol van a probléma mint ami a feladatból először következne. Viszonylag sok témakört pakoltak ebbe a vizsgába, amivel szerintem sikerült is lefedni a legfontosabb core Java ismereteket: Class Design, Design Patterns, Generics, Collections, String Processing, Exceptions and Assertions, Java IO, Java NIO2, JDBC, Thread, Concurrency, Localization. 

A felkészüléshez Mala Gupta, OCP Java SE 7 Programmer II Certification Guide könyvét olvastam át, ami még nem végleges kiadás, így elég sok hibával találkoztam. Ezenkívül átfutottam Tushar Sharma, OCP Java SE 7 Programmer Exams 1Z0-804 and 1Z0-805 könyvét is, ami szintén tartalmazott jópár elírást. 

Összességében továbbra is azt tudom mondani, hogy bőven megérte a felkészülésre rászánni az időt, mivel helyretett dolgokat és olyan API-kat ismertem meg, amiket eddig nem használtam (pl.:NIO2, Concurrency). Hamarosan belinkelem ide a saját jegyzetemet is hátha hasznos lesz valakinek. Irány a következő Java vizsga! :)

2014. szeptember 29., hétfő

Web Konferencia 2014 - Kapcsold fel a lámpát!

Idén is lesz webkonf ahonnan én sem hiányozhatok, sőt egy előadást is fogok tartani. A mostani előadásom rendhagyó lesz, mivel az áttekintő bevezető után megmutatom azt is, hogyan kezdhetsz neki az analizálásnak a teljes funkcionalitású ingyenes dynaTrace trial segítségével. Ha követed az előadásom, meglátod hogy soha többé nem akarsz majd dynaTrace nélkül fejleszteni legyél Java, .NET vagy PHP guru! .)

Időpont: 2014. november 8., szombat 15:15
Téma: dynaTrace - Kapcsold fel a lámpát!

Eddig a sötétben tapogatóztál, most megmutatom hogyan kapcsolhatod fel a lámpát! Az előadás azoknak a Java, .NET és PHP fejlesztőknek szól, akik szeretnék megtudni, hogy pontosan mit is csinál az alkalmazásuk, milyen hibákat és performancia problémákat tartalmaz.


Az előadás prezentációja itt tölthető le!

2014. július 1., kedd

dynaTrace ingyen - Teljes verzió, 30 napig

Frissítve: 2016.05.25

Igen! Ezen az oldalon bárki számára letölthető a teljes funkcionalitású dynaTrace és 30 napon keresztül szabadon használható, akár éles környezetben is. A free trial licence a következőket tartalmazza:
  • Java agents: 5
  • .NET agents: 5
  • Webserver agents: 5
  • PHP agents: 5
  • Node.js agents: 5
  • No SQL: 5
  • Native (C/C++) agent: 5
  • Database: 5 (8 CPU Core)
  • Host monitoring agent: 5
  • IBM Integration Bus agent: 5
  • UEM volume: 100.000

Először is regisztrálni kell egy céges e-mail címmel a Compuware web-oldalán, majd a kiküldött e-mailben található linkre kattintva meg kell adni az új jelszavunkat. Ezután egyből hozzáférést kapunk a közösségi portálhoz, a hivatalos fórumhoz és a dynaTrace teljes dokumentációjához, amelyben részletesen le van írva minden információ egészen a telepítéstől a használatig! Az induláshoz szerencsére nem kell átolvasni a teljes doksit, mivel a kezdőoldalon egy 4 lépéses varázsló vezet el minket a dynaTrace használatba vételéhez. A letöltéstől számítva, nagyjából 15 perc alatt beüzemelhető a rendszer!

A dynaTrace használata és a performancia vagy funkcionális problémák beazonosítása persze igényel egy kis gyakorlatot, ezért ha bármilyen kérdésed lenne a telepítéssel vagy a konfigurálással kapcsolatban esetleg egy gyors elemzést kérnél tőlem a vizsgált alkalmazásodról, nagyon szívesek segítek! Ne kíméljetek! .)

2014. június 19., csütörtök

Raspberry Pi - Apache web-szerver otthonra 2.

Miután beállítottuk, hogy az otthon.no-ip.org és a munka.no-ip.org címről kívülről is elérhető legyen a web-szerverünk, nézzük meg hogyan állítható be, hogy ezek a címek két különböző website-ra mutassanak. (Virtual Hosting)


Az Apache webszerver fő konfigurációs beállításai az /etc/apache2/apache2.conf fájlban találhatók, ami hivatkozik az engedélyezett website-okat tartalmazó könyvtárra (/etc/apache2/sites-enabled). Itt pedig sym linkek találhatók az elérhető website-okat tartalmazó könyvtárra (/etc/apache2/sites-available/).

Hozzuk létre a 2 website állományait és naplófájljait tartalmazó könyvtárakat:
mkdir /var/www/otthon.no-ip.org
mkdir /var/www/munka.no-ip.org
mkdir /var/log/apache2/otthon.no-ip.org>
mkdir /var/log/apache2/munka.no-ip.org
Hozzuk létre az első web-site virtuális hoszt beállításait tartalmazó fájlt /etc/apache2/sites-available/otthon.no-ip.org az alábbi tartalommal:
<VirtualHost *:80>
 ServerAdmin webmaster@otthon.no-ip.org
 ServerName otthon.no-ip.org
 DocumentRoot /var/www/otthon.no-ip.org

 CustomLog ${APACHE_LOG_DIR}/otthon.no-ip.org/access.log combined
 ErrorLog ${APACHE_LOG_DIR}/otthon.no-ip.org/error.log
 LogLevel warn
</VirtualHost>
Hozzuk létre a második web-site virtuális hoszt beállításait tartalmazó fájlt /etc/apache2/sites-available/munka.no-ip.org az alábbi tartalommal:
<VirtualHost *:80>
 ServerAdmin webmaster@munka.no-ip.org
 ServerName munka.no-ip.org
 DocumentRoot /var/www/munka.no-ip.org

 CustomLog ${APACHE_LOG_DIR}/munka.no-ip.org/access.log combined
 ErrorLog ${APACHE_LOG_DIR}/munka.no-ip.org/error.log
 LogLevel warn
</VirtualHost>
Engedélyezzük a site-okat a /etc/apache2/sites-enabled könyvtárban:
ln -s /etc/apache2/sites-available/otthon.no-ip.org otthon.no-ip.org
ln -s /etc/apache2/sites-available/munka.no-ip.org munka.no-ip.org>
Hozzunk létre egy-egy index.html-t más-más tartalommal a web-site-ok teszteléséhez
touch /var/www/otthon.no-ip.org/index.html
touch /var/www/munka.no-ip.org/index.html
Frissítsük az Apache web-szerver beállításait: sudo service apache2 reload

/var/www/otthon.no-ip.org/images könyvtár tartalmát az egyszerűség kedvéért egy BASIC authentikációval védtem le, amihez először létrehoztam egy password fájlt és hozzáadtam két felhasználót.
mkdir /etc/htpasswd
htpasswd -c /etc/htpasswd/.htpasswd user1
htpasswd /etc/htpasswd/.htpasswd user2
Az /etc/apache2/sites-available/otthon.no-ip.org fájlban pedig felvettem az alábbi sorokat:
 <Directory "/var/www/otthon.no-ip.org/images">
   AuthType Basic
   AuthName "Authentication Required"
   AuthUserFile "/etc/htpasswd/.htpasswd"
   Require valid-user
 
   Order allow,deny
   Allow from all
 </Directory>
Végül újraindítottam a webszervert: sudo service apache2 restart


2014. június 2., hétfő

Raspberry Pi - Apache web-szerver otthonra 1.

A Raspberry Pi fogyasztása minimális (2-4W), így nagyjából havi 200 forintos áram költség mellett egy teljesen hangtalan szervert üzemeltethetsz folyamatosan otthonról, amit a kis mérete miatt (8.5cm x 5.6mm x 2.1cm) akár a szekrény tetejére is felrakhatsz.

Szerettem volna egy jelszóval védett web oldalon néhány családi fényképeket publikálni a rokonoknak (A Facebook-ot és a társait inkább hagyjuk) valamint néhány munkával kapcsolatos oktatási anyagot közzétenni az ügyfelek számára. Nem számítok nagy forgalomra, így adódott a remek alkalom hogy a Raspberry Pi-n alakítsak ki egy web-szervert méghozzá két website-al! (A példa kedvéért legyen ez az otthon és a munka)

Először is telepítettem az Apache HTTP szervert a sudo apt-get install apache2 paranccsal majd leellenőriztem, hogy a http://localhost:80 címen megjelenik-e a /var/www/index.html tartalma. Mivel a web-szervert kívülről is elakartam érni, ezért az otthoni routerem virtual szerver beállításainál kinyitottam a TCP/80-as portot, így a szolgáltatótól kapott IP címmel már meg is jelent az index.html tartalma. Szuper! Az IP címemet azonban dinamikusan adja a szolgáltató,  - ami naponta akár többször is megváltozhat - ezért az ingyenes noip DDNS szolgáltatását használtam arra, hogy a noip-nél beregisztrál domain neveim mindig az aktuális IP címemre mutassanak. Ahhoz, hogy az IP címem mindig szinkronizálódjon a noip felé, egy kliens alkalmazást telepítettem az Raspberry Pi-re, ami periodikusan elküldte a noip-nek az IP címemet. Érdemes megemlíteni, hogy az újabb routerek esetén már nem szükséges a kliens alkalmazás feltelepítése, mivel támogatják a DDNS beállítását.

Tehát beregisztráltam a noip.com-ra, majd a Hosts/Redirects, Manage Hosts alatt felvettem két hoszt nevet, ahogy az alábbi képen is látható: otthon.no-ip.org és a munka.no-ip.org. Mivel az aktuális IP címem automatikusan kitöltésre került, mindkét hoszt névvel egyből elértem a web-szerverem.


A következő lépés a noip kliens telepítése:
cd /usr/local/src/
wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz
tar xf noip-duc-linux.tar.gz
cd noip-2.1.9-1/
make install
A noip programot a sudo /usr/local/bin/noip2 paranccsal tudjuk elindítani, azonban érdemes beállítani az alábbi tutorial alapján, hogy a Raspbian indulásával a noip szolgáltatás is mindig elinduljon. Innentől kezdve az otthoni web-szerverünk, a két beregisztrált hoszt névvel folyamatosan elérhető lesz bárki számára.

Tulajdonképpen egy mobiltelefonról is bárhonnan hozzáférhetünk az otthoni Raspberry Pi mini-számítógépünkhöz, lekérdezhetjük a GPIO portra kötött szenzorokat vagy a rákötött kamera segítségével megnézhetjük mi történik odahaza... :)

A folytatásban azt fogom megmutatni, hogy hogyan lehet mindkét website-ot üzemeltetni ugyanerről a web-szerverről, a virtuális hoszt beállítások segítségével.

2014. május 20., kedd

Raspberry Pi - Raspbian kezdő lépések

Miután megnéztük, hogy milyen lehetőségek rejlenek a Raspberry Pi-ben folytassuk a beüzemeléssel. A Debian alapú Raspbian használatához, először töltsük le az image fájlt, majd írjuk ki egy minimum 4GB-os SD kártyára. Windows alatt használjuk a Win32DiskImager programot, Linux alatt pedig a sudo dd bs=1M if=2014-01-07-wheezy-raspbian.img of=/dev/sdb parancsot. A későbbiekben ugyanilyen módon, backup mentést is érdemes készíteni az SD kártyáról. Ha wifi-n keresztül fogjuk használni a RPI-t vagy éppen nincs kéznél Ethernet kábel, akkor még a legelső indítás előtt érdemes a wifi beállításokat elvégezni a kiírt SD kártyán az /etc/network/interfaces fájlban:

auto lo
iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-ssid "MY_SSID"
wpa-psk "MY_PASSWORD"

Ha ez megvan akkor tegyük be az RPI-be az SD kártyát és a nano wifi adaptert, majd csatlakoztassuk a micro USB tápot. Nézzük meg, hogy a DHCP-n keresztül milyen IP címet kaptunk, majd egy ssh klienssel csatlakozhatunk az alapértelmezett pi felhasználónévvel és a raspberry jelszóval. 

Adjuk ki a sudo raspi-config parancsot és válasszuk ki az Expand Filesystem opciót a teljes SD kártya használatához, változtassuk meg a pi felhasználó jelszavát (Change User Password) és a használat szerint konfiguráljuk be (nálam 16MB), hogy mennyi memóriát adunk a GPU-nak (Memory Split). Itt még más hasznos beállításokat is találhatunk, érdemes körülnézni! A változtatások életbelépéshez a sudo reboot paranccsal indíthatjuk újra a Raspbian-t. Az újraindulás után frissítsük a firmware-t a sudo apt-get install rpi-update, a csomag index fájlokat - azaz a lokális szoftver repositoryt - a sudo apt-get update paranccsal és a telepített csomagokat a sudo apt-get upgrade kiadásával. 

A nano WIFI adapterem mellett, maradt még egy szabad USB port, ezért oda egy pendrive-ot tettem be. Ahhoz hogy a Raspbian kezelni tudja az NTFS-t feltelepítettem a linuxos ntfs driver-t a sudo apt-get install ntfs-3g paranccsal, majd a sudo fdisk -l kiadásával megkerestem hova került beillesztésre a pendrive-om (/dev/sda1) ezután tartósan felcsatoltam a /media könyvtár alá, úgy hogy az /etc/fstab fájlban felvettem ezt a sort: /dev/sda1 /media ntfs-3g defaults,rw,gid=100,umask=002 0 0

Végül pedig létrehoztam egy új felhasználót az users csoportba, sudo useradd -m -G users -s /bin/bash myuser és beállítottam neki a jelszavát: sudo passwd myuser.

2014. május 6., kedd

Raspberry Pi - Nekem kell ez a kütyü!

Legutóbb akkor volt ilyen hűha érzésem amikor a dynaTrace-szel találkoztam, ez a kis cucc tényleg beindította a fantáziámat, csak repkednek az ötleteim hogy mire lehetne még használni. Hogy mi ez? Hát a Raspberry Pi! :)

Raspberry Pi egy nagyon olcsó, bankkártya méretű miniszámítógép (áramköri lapka), amiből egy A és egy B model is létezik 25$ ill. 35$-os áron. Ezek specifikációja itt megtalálható. Persze nem kell meglepődni ennyiért nem egy erőgépet fogunk kapni, de amire kitalálták arra pont jó lesz! USB-n keresztül csatlakoztathatunk hozzá egeret és billentyűzetet, az analóg vagy a HDMI kimenetre pedig TV-t vagy monitort is ráköthetünk, habár a későbbiekben úgyis távolról fogjuk használni. Szükségünk lesz még egy min. 700mA Micro USB tápra, egy ethernet kábelre vagy wifi adapterre és egy sd kártyára amire az operációs rendszer kerül.


A Raspberry Pi legnagyobb előnye talán a testreszabhatóság, amit mi sem bizonyít jobban mint hogy milyen sok mindenre felhasználható.

Linux szerver otthonra

Hasznos ha van egy saját otthoni FTP/WEB/SCM/... szervered vagy egy torrent kliens géped ami egész nap folyamatosan fut és ssh-n keresztül bármikor beléphetsz rá! Mivel a Raspberry Pi kis méretű, teljesen hangtalan (nincsenek benne mozgó alkatrészek) és a fogyasztása is minimális (~4W) az otthoni és tanuló projektek szerver funkcionalitását jól eltudja látni.

Elektronikai hackelés

A Raspberry Pi rendelkezik egy GPIO porttal amire output (led, LCD kijelző, motor) vagy input (mozgás, távolság, hőmérséklet érzékelő szenzor) eszközöket is ráköthetünk és ezeket Python vagy akár Java nyelven is programozhatjuk. Ehhez még hozzájön a Raspberry Pi kamera portja amire akár egy full HD-s éjjellátó kamerát is illeszthetünk. 

Média Center

A HDMI kimenet használatával a TV-n vagy a monitoron zenéket és 1920x1080 Full HD videókat is lejátszhatunk amit az XBMC nyílt forráskódú szoftver segítségével a OpenELEC, Xbian, Raspbmc disztribúciókon keresztül érhetünk el. A beüzemeléshez itt van egy jó leírás.

További alkalmazási lehetőségek:

A Raspberry Pi megismeréséhez és a használatához nagyon sok tutorial fellelhető a neten, a számomra leghasznosabbakat pedig itt gyűjtöttem össze:


Végezetül pedig ha kedvet kaptatok egy kis "hackeléshez" a hazai kereskedők közül a malnapc.hu és az rpibolt.hu weboldalán vagy pedig az ebay-en érdemes szétnézni.

2014. április 22., kedd

Oracle 1Z0-803 vizsga jegyzet

Az Oracle Certified Associate, Java SE 7 Programmer vizsga felkészülés során összeírtam egy rövid jegyzetet és 3 feladványt amit most megosztok veletek is, hátha hasznos lesz valakinek.

- A default package-ben lévő osztályok nem importálhatók
- A main() paramétere vararg is lehet: main(String ...args)
- A hozzáférés és nem hozzáférés módosítók felcserélhetők (pl.: public - static)
- && és || short-circuit operátorok (&, | pedig nem)
- Precedencia táblázat
- A Java Pass By Value-t használ!
- Hozzáférés módosítók (public, protected, default, private)
- Overloading vs Overriding
- Encapsulation, Information hiding
- Polimorfizmus
- A metódus argumentum és a metódus paraméter nem ugyanaz
- A változónevek karakterszáma tetszőleges
- A változónevekben lehetnek számok, de nem a legelső karakter helyen
- A változóneveknél, a speciális karakterek közül csak az aláhúzás és a valuta jel használható, akár a legelső karakter helyen is.
- Lokális változókhoz ill. metódus paraméterekhez nem adható meg hozzáférés módosító
- A vararg az utolsó paraméter lehet és csak egy definiálható metódusonként
- Ha nincs felhasználó által definiált konstruktor, akkor a fordító generál egy paraméter nélkülit
- A String objektum immutable
- A StringBuilder és a StringBuffer mutable
- "ORACLE".substring(2) -> ACLE
- "ORACLE".substring(2,4) -> AC
- A String trim metódusa a kezdeti és a végi white space karaktereket törli csak
- A StringBuilder-nek nincs trim metódusa
- new StringBuilder("0123456").replace(2,3,"ABCD") -> 01ABCD3456
- new StringBuilder("ABC").append("123456",1, 3) -> ABC23
- new StringBuilder("ABC").insert(1,true) -> AtrueBC
- new StringBuilder("ABC").insert(1,"123456",1,3) -> A23BC
- A tömb az egy objektum
- A tömb mérete mindig int típusú és 0 is lehet
- A List<String> list=new ArrayList<>(); is érvényes
- A String class-ban az equals() felül van definiálva, a StringBuilder-ben nincs
- A switch()-ben használható típusok: char, byte, short, int, String, enum
- Az interface-ben minden metódus public és abstract (mégha nincs is kiírva)
- Az interface-ben minden változó public, static, final (mégha nincs is kiírva)
- A finally blokk nem fut le System.exit() hívásnál és fatal error-nál sem
- Ha a catch blokknak van visszatérési értéke a finally blokk akkor is lefut
- Checked vs Unchechked Exceptions, Errors
- invalid ArrayList pozíció esetén -> IndexOutOfBoundsException
- invalid array pozíció esetén -> ArrayIndexOutOfBoundsException
- Ha egy static inicializáló blokkban dobódik bármilyen RuntimeException -> ExceptionInInitializerError
- Rekurzív végtelen hívásánál -> StackOverflowError
- A lokális változók nem kapnak alapértelmezett kezdő értéket
- while (false) {...} vagy for( int i = 0; false; i++) x = 3; -> Fordítási hiba
- A konstruktorok nem öröklődnek
- Short k = 9; Integer i = 9; System.out.println(k == i); // compile error
- 'b'+63+"a" : 161a
- int a = b = c = 100 -> invalid
- byte: -128 to 127

És végül a gyakorláshoz összeírtam három "mit ír ki" jellegű feladványt aminek a megoldását a cikk végén megtaláljátok!

1. Overriding and hiding methods
  
class A {
  int x = 10;
  static int y = 20;

  public void m1() {
    System.out.println("a");
  }

  public static void m2() {
    System.out.println("b");
  }
}

class B extends A {
  int x = 30;
  static int y = 40;

  public void m1() {
    System.out.println("c");
  }

  public static void m2() {
    System.out.println("d");
  }

}

class MyTest {
  public static void main(String[] args) {
    System.out.println(new B().x + ", " + new B().y);
    new B().m1();
    new B().m2();

    A a = new B();
    System.out.println(a.x + ", " + a.y);
    a.m1();
    a.m2();
  }
}

2. Initialization order
  
class AA {

  public AA() {
    System.out.println("AA constructor");
  }

  static int i = 10;
  {
    i = 15;
    System.out.println("AA " + i);
  }
  static {
    System.out.println("AA static " + i);
  }
}

class BB extends AA {

  public BB() {
    System.out.println("BB constructor");
  }

  static {
    i = 45;
    System.out.println("BB static " + i);
  }
  {
    i = 30;
    System.out.println("BB " + i);
  }
}

class MyTest {

  public static void main(String args[]) {
    BB m = new BB();
  }
}

3. Throws
  
import java.io.FileNotFoundException;
import java.io.IOException;

class Super {

  public Super() throws IOException {
  }

  public void m1() throws IOException {

  }
}

class Sub extends Super {

  public Sub()  throws FileNotFoundException{ 
  }

  public void m1() throws Exception {

  }
}

És a válaszok:

1. Overriding and hiding methods

30, 40
c
d
10, 20
c
b

2. Initialization order

AA static 10
BB static 45
AA 15
AA constructor
BB 30
BB constructor


3. Throws

Compile error
throws FileNotFoundException ->  throws Exception
throws Exception ->  throws FileNotFoundException

2014. április 9., szerda

Oracle Certified Associate, Java SE 7 Programmer

A héten sikeresen leraktam az Oracle 1Z0-803 vizsgát, a mai napon pedig megkaptam az Oracle Certified Associate, Java SE 7 Programmer tanúsítványt elektronikus formában. A vizsgán előforduló témakörök az alap Java ismeretekre fókuszáltak, azonban a feladatok többsége tipikusan becsapós volt, mint például ezek a minta feladatok. A vizsgán egyébként 90 kérdésből 150 perc alatt min. 63 %-ot kellett elérni, ami szerintem bőven teljesíthető egy kis készülés után.


A felkészüléshez Mala Gupta - OCA Java SE 7 Programmer I Certification Guide könyvét olvasgattam át és az interneten fellelhető vizsga kérdésekből oldottam meg néhányat. A saját jegyzetemet itt elérhetitek. A felkészülésre fordított idő úgy gondolom megtérült, mivel nemcsak felfrissítettem, de rendszereztem is a Java 7-es ismereteimet. Irány az 1Z0-804!

2014. március 19., szerda

ComputerWorld - Agilis teljesítménymenedzsment

A 6. szoftvertesztelői konferenciával párhuzamosan lehetőségem adódott, hogy a Computerworld folyóirat vélemény rovatában publikáljak. Persze azonnal elfogadtam a felkérést, annak ellenére hogy csak egy "hosszú" estém maradt a cikk megírására. Bónuszként a főcímlapot is megkaptam, szóval mit is mondhatnék még? Jó olvasgatást mindenkinek! :)


2014. március 11., kedd

Szoftvertesztelés VI.

A Compuware és a Telvice kft. támogatásával, előadóként részt veszek a 2014. március 18-án megrendezésre kerülő 6. szoftvertesztelési konferencán, melynek központi témája a változó környezetben való tesztelés lesz. A témák között szerepel a mobil applikációk tesztelése, virtualizált tesztelés, automatizált tesztelés, teszt és kódlefedettség mérése, minőségbiztonsági kérdések, crowdtesting, agilis tesztelés és persze a dynaTrace is! .) A részletes program itt megtekinthető.


Az előadásomnak az Agilis tesztkörnyezeti teljesítménymenedzsment címet adtam és a következő kérdésekre fogok választ adni:
  • Mi a teszteszközök alapvető problémája?
  • Mit nyerünk a dynaTrace használatával?
  • Hogyan alakítsuk ki agilisen a tesztelési folyamatainkat?
  • Hogyan akadályozhatjuk meg, hogy a feltárt hibák visszakerüljenek a rendszerbe?
Az előadásom prezentációja pedig letölthető innen.

2014. február 22., szombat

Compuware EMEA Accelerate Partner Summit 2014

A Telvice kft. jóvoltából részt vehettem a február 18-án kezdődő két napos Compuware konferencián amit az Európai, Közép-Keleti és az Afrikai partnerek számára rendeztek meg Amsterdam-ban.


A találkozón szó volt a tavalyi év sikertörténeteiről és néhány várható technikai újdonságról is valamint azt is megtudhattuk hogy a Compuware most már teljes erővel az APM vonalra fog fókuszálni, aminek a következtében megvált például a Covisint és a ChangePoint szoftverektől is. Magyar vonatkozású sikerekből sem volt hiány, a Provice Kft. kapta meg a 2014-es RFO APM Marketing díjat és a legaktívabb RFO partner díjat is, amihez a Telvice Kft. mint VAR (Value Added Reseller) partner is nagyban hozzájárult.


Habár a konferencia február 18-án kezdődött, mi már 16-án megérkeztünk így volt elég időnk szétnézni Amsterdamban. A cikk végére hagytam egy bejelentést, amit április végéig sajnos nem árulhatok el, de az biztos hogy ez majd felélénkíti a Compuware APM használatát valamint a Java, .NET és PHP szakmai világ is erről fog szólni! .)

http://offers2.compuware.com/APM_ALL_14Q4_EMEAPartnerSummitAmsterdam_EMEA_Agenda.html?utm_campaign=holiday-survey-report&utm_medium=NASDAQ&utm_source=PR

2014. január 19., vasárnap

Firefox OS - Hasznos linkek

A kezdő Firefox OS fejlesztőknek zavaró lehet, hogy az információk eléggé szétszórva találhatók meg a weben, ezért most arra vállalkoztam, hogy ezeket egy kicsit rendszerezve összegyűjtöm és ebben a bejegyzésben majd rendszeresen frissítem:

Hivatalos magyarországi kommunikációs csatornák:

2014. január 11., szombat

Firefox OS - Legyen web a mobilodon!

HTML, CSS és JavaScript ennyit kell tudnod, ha Firefox OS-ra akarsz fejleszteni! De kezdjük az elejétől. Pár hónapja hazánkban is megjelent az egyik legígéretesebb új mobil platform, a Firefox OS. A Mozilla operációs rendszere teljes egészében a nyílt webes szabványokra épít és a megírt alkalmazásokat akár a többi mobil platformon is futtathatjuk. Plusz van még egy fontos dolog, hogy mostanság elég nagy pezsgés van körülötte!

A Mozilla nagy ötlete, hogy a telefon felhasználói felülete és az alkalmazások is a nyílt webre, azaz a HTML5, CSS3, JavaScript ill. WebAPI-ra támaszkodnak. Mivel ezeket a technológiákat minden webes fejlesztő ismeri, kifejezetten gyorsan fejleszthetők vele platformfüggetlen alkalmazások, a saját tapasztalatom szerint is!


Az architektúrát tekintve legalul a Gonk Linux kernel valamint az ehhez kapcsolódó könyvtárak és meghajtó programok helyezkednek el, amin a Gecko renderelő motor értelmezi és megjeleníti a HTML - CSS - JavaScript kódot. Legfelül pedig a Gaia található, ami a Firefox OS felhasználói felületét adja. Látható, hogy a Firefox OS mobilokon megjelenő minden komponens ezekre az alapvető webes technológiákra épít, legyen az akár vibrálás, telefonhívás, email küldés, névjegymentés vagy éppen fényképezés. Ezeket a funkciókat a W3C standard WebAPI-k segítségével, egyszerűen javascript hívásokkal érhetjük el.

Ha kedvet kaptál hozzá, akkor legyen neked is web a mobilodon!

http://www.mozilla.org/hu/firefox/os/

2014. január 2., csütörtök

2013-as évértékelő

Mintha csak most írtam volna a tavalyi évértékelőmet, de már megint eltelt egy év! 2012 decemberében nagyjából ott hagytam abba, hogy munkahelyet váltottam és a Telvice Kft.-hez igazoltam át, ahol azóta is a Compuware dynaTrace technikai támogatását végzem. Az évet a dynaTrace oktatási témák (alap, fejlesztői, üzemeltetői, CI és teszt integrációs, kliens oldali eszközök) elméleti és gyakorlati anyagának kidolgozásával kezdtem majd a vezetőséggel elkészítettük a magyarországi support csomagokat. A support keretében egyébként oktatásokat, tanácsadást és hibafeltárási támogatást (SWAT tevékenység) nyújtottam a meglévő ügyfeleink számára:

  • Raiffeisen Bank Zrt.
  • Generali Biztosító Zrt.
  • GIRO Zrt.
  • Magyar Telekom Nyrt.
  • ShiwaForce.com Zrt.
  • Szerencsejáték Zrt.
  • Magyar Közút Nonprofit Zrt.

Az ügyfélkör bővítése érdekében a pilotolásra is nagy hangsúlyt fektettünk. Az elmúlt évben több mint 10 dynaTrace pilot technikai szakértői feladatát láttam el (implementáció, analizálás, vezetői prezentáció). Talán pont ezek voltak a legérdekesebb feladataim, mivel mindig is kíváncsi voltam hogy a hazai nagyvállalatok milyen eszközöket és keretrendszereket használnak és milyen problémáktól "szenvednek". Emellett egy jó rálátást kaptam az egyes rendszerek felépítésére és architektúrájára is, amire azért nem sok mindenkinek adódik lehetősége.

A dynaTrace és a hozzá kapcsolódó kódminőség biztosítás népszerűsítése érdekében több hazai konferenciára is sikerült eljutnom és előadásokat tartanom. A munkatársaim szerint az év elejéhez képest sokat fejlődött az előadói és a prezentációs képességem, sőt állítólag a sales-es tevékenységhez is van érzékem. Hát kitudja..., bár azt kijelenthetem, hogy szakmai váltást nem tervezek! :)


A dynaTrace support mellett a fejlesztői ismereteimet is tudtam bővíteni, méghozzá a mobil technológiák irányában. Elhatároztam, hogy készítek a SonarQube-hoz egy Android alapú alkalmazást és ezen keresztül megismerem az Android-os fejlesztést. Különösen örültem annak, hogy hivatalosan is ez lett a SonarQube mobil alkalmazása és hogy csatlakozhattam a SonarQube közösségi fejlesztőihez, sőt még az Appra Magyar mobilfejlesztői versenyre is beneveztem vele! De a történetnek itt még koránt sincs vége. Nemrég a kis hazánkba is elérkezett a Firefox OS mobil platform aminek a technológiai háttere felkeltette az érdeklődésemet, ezért úgy döntöttem, hogy az androidos appomat átportolom a Firefox OS-ra.

Hogy mi várható erre az évre? Az év vége a cég számára sikeresen alakult mivel a megtartott pilotok felénél már eljutottunk az eladásig, így jövő évre is lesz bőven feladatom, habár úgy tűnik, hogy nemcsak nekem mivel új munkaerőt is keresünk a megnövekedett ügyfélszám miatt. (Ha netán érdekelne szólj mihamarabb!). Tervezem még a SonarQube Android alkalmazásom továbbfejlesztését és a már régóta halogatott Oracle Java-s vizsgák letételét is.