piątek, 7 listopada 2014

JDK 7 i 8 64 bit + Windows 7 - problemy z połączeniem internetowym

Co jakiś czas powraca do mnie problem na mojej maszynie związany chyba z kiepską implementacją IPv6 w 64 bitowym JVM lub Windowsie. Nie wiem dokładnie gdzie leży problem, ale już drugi raz spędziłem sporo czasu, aby znaleźć rozwiązanie, wiec czas na notatkę na blogu. Kłopot się objawia tym że maven / gradle / inny DSL do ściągania połowy Internetu, ma problemy ze dociągnięciem zależności i trzeba go ubić.

Aby rozwiązać ten problem warto dodać / uaktualnić zmienną środowiskową JAVA_OPTS tak, aby znalazła się w niej poniższa flaga:

-Djava.net.preferIPv4Stack=true

W przypadku gradle’a warto to jeszcze wrzucić do pliku gradle.properties w naszym projekcie, np.:

org.gradle.jvmargs=-Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -Djava.net.preferIPv4Stack=true

Teraz już powinno być lepiej, chyba ze akurat trafimy na jakąś przerwę w działaniu ogólnodostępnych repozytoriów, z których aktualnie korzystamy.

Więcej informacji:
Why do I need java.net.preferIPv4Stack=true only on some windows 7 systems?

Networking IPv6 User Guide for JDK/JRE 5.0

czwartek, 6 listopada 2014

Recenzja książki "Czy jesteś wystarczająco bystry, żeby pracować w Google?"

Nie mam w zwyczaju recenzowania na blogu przeczytanych książek (wyjątkiem była dotychczas książka Tomka Kacznowskiego: Practical Unit Testing), ale po przeczytaniu „Czy jesteś wystarczająco bystry, żeby pracować w Google?” Pana Poundstone Williama, postanowiłem to zmienić (aby pojawiały się na moim blogu nie tylko posty relacjonujące różne konferencje, ale i recenzje i tematy techniczne [o te najciężej ze względu na konieczny duży nakład na przygotowanie czegoś fajnego]).

Na książkę wpadłem przypadkiem, będąc kiedyś w księgarni i standardowo przeglądając co jest na półce pod szyldem „informatyka”. Książka jest wydana przez Wydawnictwo SQN, (na stronie Heliona niby też jest, ale wiecznie „czasowo niedostępna”), więc pewnie niewielu z Was na nią trafiło. Sam pewnie bym ją szybciej kupił i przeczytał, gdyby wieść o niej przyszła do mnie wraz newsletter’em wspomnianej księgarni.

Książka od samego początku opisuje z jakimi przywilejami wiąże się, wymarzona przez wielu, praca w Google. Szybko jednak przechodzi do tego, jak bardzo ciężko się tam dostać. W końcu jednej osobie na 130 kandydatów się to udaje. A dlaczego? Głównie ze względu na pytania otwarte, w których trzeba się wykazać swoimi umiejętnościami. Nie ma jednego zbioru pytań (i poprawnych odpowiedzi), z których korzystają podczas rekrutacji w Google. Pytania są tak ciężkie, że albo się już wcześniej zna pytanie wraz z poprawną odpowiedzią, albo się na nie raczej nie odpowie. Co gorsza, pytania często nie mają jednej poprawnej odpowiedzi.

W książce jest również uzasadniona bezsensowność i bezcelowość prowadzenia rozmów kwalifikacyjnych.

Podczas rozmowy o pracę można stwierdzić, czy dana osoba potrafi miło prowadzić rozmowę, można zadać szereg pytań technicznych, by wykluczyć kandydatów, którzy nie mają zielonego pojęcia, o czym mówią, lecz po za tym można by równie dobrze rzucać kośćmi.
- twórca BitTorrenta, Bram Cohen

Niby coś tam można sprawdzić podczas rozmowy kwalifikacyjnej, ale to nie gwarantuje sukcesu, że kandydat sprawdzi się w danym projekcie lub firmie. Poza tym jest ciężko zweryfikować, czy odrzuceni kandydaci by się sprawdzili. Można jedynie zwiększać prawdopodobieństwo, że dany człowiek się nada.

Dalej książka opisuje szczegóły odrzucania aplikacji kandydatów przez Google. Proces ten jest bardzo skomplikowany i decyzja zależy od wielu osób. Taki skomplikowany proces musi sporo kosztować firmę, ale dzięki temu jest ona pewniejsza, że ma u siebie tych najlepszych.

Książka jest przepełniona zabawnymi historyjkami i anegdotami, które w dużej mierze uszczypliwie wyśmiewają podejście do problemów firmy Microsoft. Tzn. książka porównuje, jak pewne zadania rozwiązał by ktoś z Google, a jak ktoś z firmy produkującej Windowsy (lub cokolwiek innego). Ma to jednak na celu pokazanie innego sposobu myślenia.

Powyższa książka nie mogłaby się oczywiście obejść bez zagadek. Są w niej opisane pytania logiczne, pytania wymagające przebłysku geniuszu, myślenia niestandardowego (lateralnego), myślenia rozbieżnego, pytania Fermiego i pytania oparte o algorytmy. Na początku każdego rozdziału, jak i często w środku, dostajemy porcję pytań, aby można było wytężyć swoje szare komórki i zatrzymać degradację neuronów. Oczywiście książka oferuje na koniec odpowiedzi do wszystkich zagadek, jak i praktyczne wskazówki, w jaki sposób próbować odpowiadać na te pytania.

Podsumowując, polecam tę książkę każdej osobie technicznej, która chce zrobić coś więcej ze sobą niż tylko odbębnić 8 godzin w pracy. Książka nadaje się również dla osób, które nie koniecznie pracują w IT, a ich praca (aktualna lub przyszła) wymaga kreatywności i niestandardowego myślenia. Oczywiście jest to pozycja obowiązkowa dla tych, co wybierają się do Google.

Btw. Za tydzień 15-stego listopada jest Global Day of Code Retreat i obywa się on również we Wrocławiu. Zostało jeszcze kilka wolnych miejsc, więc czas najwyższy się zarejestrować: http://coderetreat-2014-wroclaw.eventbrite.com.

poniedziałek, 29 września 2014

Warsjawa 2014, czyli ja jako prowadzący 2 warsztaty

W tym roku miałem okazję poprowadzić 2 warsztaty na Warsjawie. Wcześniej prowadziłem jedynie prezentacje (czy to w pracy czy na WrocławJUG), a w formie warsztatów to był mój pierwszy raz! I od razu 2 różne tematy!

Jak mi poszło? Uważam, że co najmniej dobrze. Wydaje mi się, że nie miałem większych potknięć, feedback zbierany od uczestników jest jak dotychczas pozytywny.


Podobne opinie słyszałem, gdy się podpytywałem uczestników, jak i przeczytałem w e-mailach. Pewnie coś więcej będę mógł się dowiedzieć (zwłaszcza liczę na uwagi krytyczne, aby wiedzieć co poprawić następnym razem), gdy uczestnicy wypełnią ankietę pokonferencyjną. Wszelakie e-maile i komentarze również mile widziane.

A tymczasem zamieszczam poniżej materiały z których korzystałem.

Upiększ swoje testy! Testowanie jednostkowe dla średniozaawansowanych.



Kod używany na warsztacie: https://github.com/mstachniuk/SolarSystem

Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc z IntelliJ Idea.

Kod napisany przez uczestników podczas warsztatów: https://github.com/mstachniuk/WarsjawaCodingDojo

Co do samej konferencji, to minusy (z punktu widzenia prelegenta):
- nie do końca przygotowane sale (rzutnik, nasłonecznienie, jakieś pudła)
- system do komunikacji z uczestnikami nie wysyła załączników i wiadomości nie dochodzą do wszystkich
- nie do końca udany pomysł ze szwendaniem się po knajpach po konferencji

A na plus:
- obecność zagranicznych spikerów
- wcześniejsza rejestracja dla prelegentów
- transparentnosć, co ile kosztowało
- długie przerwy, dobry timeline

I oby tak dalej, albo i jeszcze lepiej!

czwartek, 11 września 2014

Rusza rejestracja na tegoroczną Warsjawę oraz moje tematy

Już niedługo (21.09.2014 21:00) ruszy rejestracja dla uczestników Warsjawy - darmowej konferencji, która składa się z samych warsztatów! Liczba miejsc jest ograniczona, dlatego warto się spieszyć, zwłaszcza, że jest szansa na warsztaty, które będzie prowadził Venkat Subramaniam! Jest to założyciel Agile Developer, autor wielu książek jak i świetny prelegent, którego mieliśmy okazję wielokrotnie oglądać na polskich konferencjach. Styl jego prezentacji jest specyficzny, a o części jego wystąpień można przeczytać na moim blogu.

Dzięki wizycie Venkata w Warszawie, udało się go zaprosić także do Wrocławia i poprowadzi on wykład Programming with Lambda Expressions w ramach WrocJUG. Będzie również warsztat: Programming Concurrency - Workshop, ale na niego nie ma już miejsc, a lista oczekujących jest długa.

Jednocześnie zapraszam na warsztaty, które sam będę prowadził w ramach Warsjawy. Poniżej przedstawiam tematy, które będę prowadził, wraz z krótkim komentarzem.

Czas: Piątek, 26 września 2014 13:00
Temat: Upiększ swoje testy. Testowanie jednostkowe dla średnio zaawansowanych

Opis: Warsztat jest przeznaczony dla średniozaawansowanych programistów Java, którzy napisali już trochę testów i chcieliby je upiększyć. Podczas warsztatu będziemy ćwiczyć tworzenie ładnej sekcji given (za pomocą Builder'ów), jak i czytelniejsze zapisywanie assercji (za pomocą Hamcrest'a, FEST'a i AssertJ). Bedzie jeszcze o testowaniu wyjątków i testach parametrycznych. Warsztat będzie prowadzony po polsku, względnie może być po niemiecku;) Wymagane jest zabranie ze sobą własnego komputera ze skonfigurowanym środowiskiem programistycznym i opcjonalnie konto na GitHub'ie (do przesyłania gist'ów).

Być może, jak starczy czasu, będzie można poćwiczyć jeszcze inne rzeczy, ale to już zależy głównie od prędkości grupy, jak i zainteresowania tym, co będą chcieli usłyszeć uczestnicy.

Czas: Sobota, 27 września 2014 16:00
Temat: Poznaj lepiej swoje środowisko programistyczne i zwiększ swoją produktywność z IntelliJ Idea

Opis: Każdy programista powinien poświęcić 10 godzin na dogłębne poznanie swojego zintegrowanego środowiska pracy, aby móc z niego efektywnie (i efektownie) korzystać! A Ty ile czasu na to poświęciłeś? Warsztat jest przeznaczony dla programistów Java, korzystających z IntelliJ Idea, lub chcących się go nauczyć. Warsztat będzie miał formę Coding Dojo, podczas którego będziemy wspólnie pisać Katę i wzajemnie uczyć się korzystania z Idei bez użycia myszki. Warsztat będzie prowadzony po polsku, względnie może być po niemiecku;) Własny komputer nie jest wymagany, gdyż będziemy kodować wspólnie na jednym, podpiętym do rzutnika. Przyda się za to notatnik i długopis do zapisywania nowopoznanych kombinacji klawiszowych.

Na pomysł tego warsztatu wpadłem po tym, jak go z wielkim sukcesem przeprowadziłem w ostatnim projekcie. Po prostu, gdy udało się kupić IntelliJ Idea dla całego zespołu (o co bardzo ciężko walczyłem - skutecznie), musiałem wdrożyć kolegów w nowe środowisko. Wcześniej pokazywałem jedynie czym się różni Idea od Eclipse'a, ale to nie to samo co praktyka przy klawiaturze. Nie chciałem również słyszeć narzekań, że teraz trzeba się na nowo uczyć wszystkich kombinacji klawiszowych.

Zebrałem więc cały zespół, wyjaśniłem zasady i poszłooo! Było bardzo intensywnie, śmiesznie i co najważniejsze pouczająco. Ludzie wychodzili wówczas z sali z ugotowaną głową, ale widziałem później, że te warsztaty bardzo im pomogły. Zebrałem również bardzo pozytywne opinie na retrospektywie.

Mam nadzieję, że na Warsjawie będzie równie gorąco.

P.S. W razie jak byście chcieli się wcześniej zapisać na warsztaty, to przeczytajcie ten status.

poniedziałek, 1 września 2014

Implementacja Singleton’a w Javie

Ostatnio, podczas z jednej z rozmów rekrutacyjnych, dostałem pytanie, "A jak by Pan zaimplementował singleton w Javie?". Pytanie dość standardowe, mógł by je zadać każdy. Odpowiadam więc: „Klasa, z prywatnym konstruktorem, z polem statycznym o typie zadeklarowanej klasy, metoda getInstnce(), itd.”. Rekruter na to: "No dobra, a jakiś inny pomysł?".

Na szybko nie przychodziło mi jednak nic do głowy... Wtedy padło pytanie, które zmotywowało mnie do przygotowania tego wpisu: "A czytał Pan Effective Java, Joshua Bloch?". A no nie czytałem i nie sądzę, abym ją przeczytał.

Dlaczego?

Przede wszystkim uważam że ta książka jest trochę przestarzałą. Drugie wydanie pochodzi z 2008 roku i informacje w niej zawarte są trochę nieaktualne. To nie książka o wzorcach projektowych Bandy Czworga, która nie traci na swojej aktualności, a jedynie pozycja o tym jak coś tam dobrze zrobić w Javie. I tak przykładowo rozdział: "Item 51 Beware the performance of string concatenation", traktujące o tym, aby lepiej używać StringBuilder’a niż + do sklejania tekstów, jest już dawno nieaktualne! Chciałem kiedyś pisać posta o tym, ale na stackoverflow i jeszcze gdzieś tam już dawno o tym było. Nie wiem tylko od kiedy dokładnie istnieje ten mechanizm zamiany + na StringBuilder’a w Javie.

O innych dobrych praktykach, można się dowiedzieć zawsze z innych źródeł, niekoniecznie czytając wspomnianą książkę.

Dobra wróćmy do tematu wpisu. W innym rozdziale Effective Java (Item 3: Enforce the singleton property with a private constructor or an enum type), jest zalecenie, aby Singletona implementować za pomocą Enuma. Z tym rozwiązaniem spotkałem się po raz pierwszy podczas review kodu kogoś, kto czytał tę książkę. Użycie wówczas enuma w roli singletonu było dla mnie zupełnie niezrozumiałe! Musiałem dopytać autora o co chodzi.

Dlaczego nie lubię tego rozwiązania? Spójrzmy na przykładowy kawałek kodu (inspirowany Joshuą Blochem, co bym za dużo nie musiał wymyślać, jak tu mądrze użyć singletona). Kod jest i tak kiepski (obliczanie czasu), ale chodzi mi o zaprezentowanie działania omawianego wzorca.
public enum Elvis {
    INSTANCE;

    private final int ELVIS_BIRTHDAY_YEAR = 1935;

    public int howOldIsElvisNow() {
        return new GregorianCalendar().get(Calendar.YEAR) - ELVIS_BIRTHDAY_YEAR;
    }
}

public class ElvisProfitService {

    public double ELVIS_SALARY_YEAR = 70_000;

    public double calculateElvisProfit() {
        return Elvis.INSTANCE.howOldIsElvisNow() * ELVIS_SALARY_YEAR;
    }
}

No i weź tu panie przetestuj taki kod! Możemy jeszcze Elvisa statycznie zaimportować, to linijka 6 skróci się do jeszcze mniej czytelnej formy.

return INSTANCE.howOldIsElvisNow() * ELVIS_SALARY_YEAR;

Ktoś ma jakieś pomysły jak taki kod przetestować? Da się oczywiście, z wykorzystaniem PowerMock’a [link do rozwiązania na końcu ^1], ale chyba nie o to chodzi aby pisać nietestowany kod?

Dlaczego wolę starszą wersję tegoż rozwiązania:

public class Elvis {

    private static final Elvis INSTANCE = new Elvis();

    private final int ELVIS_BIRTHDAY_YEAR = 1935;

    private Elvis() {
    }

    public static Elvis getInstance() {
        return INSTANCE;
    }

    public int howOldIsElvisNow() {
        return new GregorianCalendar().get(Calendar.YEAR) - ELVIS_BIRTHDAY_YEAR;
    }
}

Dochodzi prywatny konstruktor, statyczna metoda getInstance() i inicjalizacja pola klasy wraz z deklaracją.

W tym przypadku kod korzystający z tego singletonu, mógłby być następujący:

public class ElvisProfitService {

    private final double ELVIS_SALARY_YEAR = 70_000;
    private Elvis elvis = Elvis.getInstance();

    public double calculateElvisProfit() {
        return elvis.howOldIsElvisNow() * ELVIS_SALARY_YEAR;
    }

    // For tests
    void setElvis(Elvis elvis) {
        this.elvis = elvis;
    }
}

W linii 4 wywołałem getInstance(), aby w przykładowym kodzie produkcyjnym było wszystko cacy. Dzięki temu, zależność ta jest definiowana jako pole w kasie i mamy setter do tego, więc możemy sobie bardzo ładnie przetestować tą funkcjonalność, bez hackowania z PowerMockiem:

public class ElvisProfitServiceTest {

    @Test
    public void shouldCalculateElvisProfit() {
        // given
        ElvisProfitService service = new ElvisProfitService();
        Elvis elvis = mock(Elvis.class);
        when(elvis.howOldIsElvisNow()).thenReturn(1);
        service.setElvis(elvis);

        // when
        double elvisProfit = service.calculateElvisProfit();

        // then
        assertEquals(70_000, elvisProfit, 0.1);
    }
}

W sekcji given mamy bardzo ładnie zdefiniowane zachowanie, za pomocą Mockito, jakie ma przyjmować masz singleton na potrzeby tego testu.

A Ty jak definiujesz (o ile to robisz) swoje singletony? Które rozwiązanie uważasz za lepsze?



[1] Co do rozwiązania zagadki, jak przetestować Singletona jako Enum’a, to tutaj jest odpowiednia rewizja na github’ie: SingletonInJava e714fb a kod poniżej:

@RunWith(PowerMockRunner.class)
@MockPolicy(ElvisMockPolicy.class)
public class ElvisProfitServiceTest {

    @Test
    public void shouldCalculateElvisProfit() {
        // given
        ElvisProfitService service = new ElvisProfitService();

        // when
        double elvisProfit = service.calculateElvisProfit();

        // then
        assertEquals(70_000, elvisProfit, 0.1);
    }
}

public class ElvisMockPolicy implements PowerMockPolicy {

    @Override
    public void applyClassLoadingPolicy(MockPolicyClassLoadingSettings settings) {
        settings.addFullyQualifiedNamesOfClassesToLoadByMockClassloader("com.blogspot.mstachniuk.singletoninjava.Elvis");
    }

    @Override
    public void applyInterceptionPolicy(MockPolicyInterceptionSettings settings) {
        Method method = Whitebox.getMethod(Elvis.class, "howOldIsElvisNow");
        settings.proxyMethod(method, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return 1.0;
            }
        });
    }
}

czwartek, 17 lipca 2014

Wyższy poziom produktywności w IntelliJ Idea

Ostatnio natrafiłem na nagrania z konferencji Geekout z Estonii. Zainteresowała mnie 3cia prezentacja: Mouseless Driven Development by Hadi Hariri.


Prelegent (pracownik JetBains’a) opowiadał o tym jak efektywnie kodować bez użycia myszki. Myślałem, że już dostatecznie poznałem to moje ulubione środowisko developerskie, ale jak zobaczyłem pierwszą ciekawostkę, którą pokazał Hadi, to zacząłem robić notatki. A skoro notatki to już nie wiele trzeba, aby był wpis na bloga…

Uważam, że najlepszą metodą poznawania środowiska pracy, jest patrzenie jak korzystają z niego inni. I to może być przy okazji warsztatów typu Code Retreat, Coding Dojo czy innych hackathon'ów, lub właśnie oglądając screencasty i wystąpienia z konferencji. Zachęcam do obejrzenia powyższego video (choć ten efekt z przekrzywionym obrazem z rzutnika uważam za głupi), gdyż opisałem poniżej rzeczy dla mnie nowe, tudzież te wymagające mojego odświeżenia. Warto, przed dalszą lekturą tego wpisu, znać choć połowę skrótów z IntelliJIDEA_ReferenceCard.pdf, gdyż niżej będzie o bardziej zaawansowanych zagadnieniach. A więc do dzieła!

Jak wszyscy zapewne wiedzą (albo powinni wiedzieć), Ctrl + N otwiera klasy lub pliki (gdy dwa razy naciśniemy tą kombinację, lub Ctrl + Shift + N). I tutaj nazwę możemy podawać w szelaki sposób: CamelCase, snake_case (ale dla ułatwienia ze spacją), wspomagając się gwiazdką itd. Idea będzie szukać wszystkiego co pasuje i wyświetli w logicznym porządku. W Eclipse „jakoś tam” też to działa, ale o wiele gorzej.

Ale co mnie właściwie onieśmieliło, to gdy pisząc po nazwie klasy :<numer lini> (słownie: dwukropek i numer linii), plik zostanie otworzony na żądanej pozycji! Ciekawie działa również Alt + F1, które pozwala otworzyć nam plik np. w Project View, Structure, Exporatorze Windowsa, i w innych oknach. A chcąc otworzyć plik w osobnym oknie można zamiast Entera wcisnąć Shift + Enter. A jak chcemy wyszukiwać wszędzie, to możemy to zrobić za pomocą podwójnego naciśnięcia Shift. Część tych wskazówek zaczerpnąłem ze strony JetBrains’a: Navigating to Class, File or Symbol by Name, a część z opisanego na początku video.

Do wyszukiwania użycia jakiejś zmiennej lub metody, zawsze korzystałem z Alt + F7. Jest to skrót, który swoimi korzeniami sięga TotalCommandera, a nawet Norton Commandera. Podobnie jest zresztą z Shift + F6 - rename. Natomiast jak chcemy widzieć dolnego okienka z wynikami poszukiwań, możemy skorzystać z Ctrl + F7, które to skoczy nam do pierwszego wykorzystania i zaznaczy pozostałe. A jak byśmy chcieli podświetlić wykorzystanie wielu różnych zmiennych, to na każdej możemy skorzystać z Ctrl + Shift + F7. Jeszcze podobnie zachowuje się Ctrl + Alt + F7, które to pokazuje wyniki wyszukiwania w popupie. Poniżej przykłady z mojego projektu HamcrestVsFest.

Alt + F7

Ctrl + F7. Obiekt mercury jest tworzony w lini 10, ale po raz pierwszy jest użyty w linii 20.

Ctrl + Shift + F7. Tutaj wykonane na mercury, PlanetBuilder, RotationDirection i Gases.

Ctrl + Alt + F7

Dalej było o tym, jak zmaksymalizować przestrzeń na pisanie kodu. I tak prelegent, przekonywał nas, że można się obejść bez nawigation bara na górze ekranu.


To ten pasek, gdzie jest rozpisane, w jakim pakiecie i pliku aktualnie jesteśmy. Nie jest on nam potrzebny, bo możemy się dostać do niego za pomocą Alt + Home. Mi osobiście on nie przeszkadza, bo jest na tym samym poziomie, co ostatnio uruchamiana konfiguracja projektu, a to lubię widzieć.

Nie potrzebujemy również Tab’ek, gdy mamy wiele otwartych plików, bo przeglądanie ich i szukanie odpowiedniej po nazwie zajmuje wiele czasu.


Tak naprawdę potrzebujemy tylko Ctrl + E, które w bardziej czytelny sposób nam pokazuje, jakie pliki ostatnio przeglądaliśmy i szybciej je w ten sposób odnajdziemy. Jeśli zależy nam tylko na tych które ostatnio edytowaliśmy, to możemy skorzystać z Ctrl + Shift + E. Jest to ulubiony skrót prowadzącego prezentację do tego stopnia, że musi używać zewnętrznej klawiatury w laptopie, bo przycisk E mu się zepsuł. Przykłady użycia poniżej, a Tab'ki możemy całkowicie wyłączyć w ustawieniach.


Ctrl + E
Ctrl + Shift + E

Jak usunąć Tab'ki z otwartymi plikami.

Przeskakiwać pomiędzy poszczególnymi oknami w IntelliJ Idea można za pomocą Alt + <numer okienka>, widoczny przy jego nazwie. Niestety nie na wszystkie okienka wystarczyło numerków, więc jak chcemy np. dostać się do Mavena lub Bazy danych, to Ctrl + Tab jest twoim przyjacielem.

Ctrl + Tab

A jak już w ogóle byśmy chcieli tylko i wyłącznie kod widzieć, to warto się zapoznać z Prezentation Mode. Warto na Windowsie sobie zdefiniować skrót Ctrl + Shift + P jako wejście do tego trybu. Na pewno może się to przydać podczas prezentacji, jak i osobom lubiącym widzieć tylko kod na ekranie.

Następnie poznałem nowe znaczenie F4 w oknie projektu. Dotychczas używałem tego klawisza tylko do otwierania właściwości projektu, a w ten sposób można również otworzyć plik i automatycznie skoczyć do jego edycji. Jest to lepsze od oczywistego Entera, który tylko otwiera wybrany plik, ale fokus pozostaje na oknie projektu.

A co z operacjami typowymi dla myszki, jak dostrajanie wielkości okna projektu? Sam dotychczas myślałem, że jest to jedynie możliwe za pomocą myszki, ale da się też z klawiatury! To kolejne moje wielkie odkrycie z tej prezentacji, po którym mi i osobom na sali opadła szczęka. Chcąc przykładowo zmienić rozmiar widoku projektu, musimy mieć na nim focus (Alt + 1) i teraz już wciskamy tylko Ctrl + Shift + Prawo / Lewo. Okno z wynikami testu? Po porostu Alt + 4 aby uzyskać fokus i Ctrl + Shift + Góra / Dół. Na oknie z kodem to nie działa, gdyż te skróty odpowiadają za zaznaczanie tekstu i przenoszenie linii w pionie.

Było jeszcze o mulitikursorze, który swoim zasięgiem może objąć wiele wierszy. Tu już trzeba zrobić z użyciem prawego Alt’a i myszki. Ale Idea proponuje jeszcze  coś innego, a mianowicie Alt + J, które zaznacza dany tekst w pliku i tworzy multikursor. Jest jeszcze: Ctrl + Alt + Shift + J, ale jak to działa, sprawdźcie sami. Aby opuścić ten tryb edycji, trzeba wcisnąć 2 x Esc.

Warto przypomnieć o Live Templates (Ctrl + J) i Postfix templates, o których to się nie pamięta, a za pomocą których można tworzyć kod w ciekawszy sposób. Możemy również otaczać kawałek kodu różnymi konstrukcjami (np. if, try/catch, itp.) za pomocą Ctrl + Alt + T.

Warto także utworzyć własną szybka listę (Quick Lists w Settings), gdzie można wrzucić operacje, które często używamy i przypisać wywołaniu tej listy jakiś skrót klawiaturowy. Muszę sobie przygotować taką listę, z rzeczami które często potrzebuję, a nie mają domyślnego skrótu klawiaturowego.

Na koniec jeszcze pozostaje nam Ctrl + ~, które to umożliwia nam szybką zmianę, m.in. kolorów, Look and Feel jak i skrótów klawiaturowych (przykładowo na te z Eclipse’a). Może się to przydać, gdy akurat musimy zrobić Pair Programing z użytkownikiem Eclipse’a. I aby śledzić nasze postępy w niewykorzystywaniu myszki, warto się przyjrzeć statystykom z menu Help -> Productivity Guide.

A Ty jakie znasz bardziej zaawansowane i skomplikowane skróty w IntelliJ Idea? Pisz w komentarzu!

piątek, 11 lipca 2014

Konfitura, marmolada, dżem, powidło i spiżarnia, czyli wrażenia po confiturze 2014

Rapid dev environments, Marcin Brański i Przemek Hejman
Prelegenci opowiadali o tym w jaki sposób tworzyć środowiska developerskie, a właściwie ich konfiguracje i obrazy, aby później można było je szybko odtworzyć np. na nowej maszynie. Chłopaki bardzo sprawnie i płynnie mówili, widać, że przećwiczyli to wystąpienie wcześniej. Ale niestety używali w swoich wypowiedziach sporo skrótów, które nie koniecznie musieli wszyscy znać. Pokazywali również sporo detalów, a zabrakło mi jakiegoś big picture, co do czego jest, oraz czym różnią się opisywane rozwiązania.

I tak oto było o następujących narzędziach: Packer.io, PuppetVagrantAnsibleChefSaltFabricDocker i Fig (nakładka na dockera). Niestety z powodu znikomej znajomości tematu nie jestem w stanie nic więcej tutaj napisać.

Git nie dla początkujących, Tomasz Borek
Tomek na początku przedstawił różnicę, pomiędzy surowym repozytorium (utworzonym z flagą --bare), a zwykłym repozytorium. Dalej już było ciekawiej. Prelegent pokazywał, co tak naprawdę jest potrzebne w katalogu .git, aby istniało repozytorium. I tak są to katalogi: objects i refs/heads oraz plik HEAD z zawartością (np.: „ref: refs/heads/master”). Ciekawa sztuczka, ale trwała trochę za długo i prelegent miał problemy z koordynacją, tj. czy klepać w klawiaturę, trzymać mikrofon, stać, siedzieć, czy mówić do mikrofonu stojącego na biurku (o którym później prelegent kompletnie zapomniał).

To było trochę jako ciekawostka, ale Tomek omówił również, po co są pozostałe katalogi i pliki. I tak w description jest opis projektu, który nie jest nigdzie pushowany i prawie nigdzie nie używany. W info/exclude można zignorować pewne pliki, których nie chcemy wersjonować. Przydaje się to w momencie, gdy mamy jakiś plik z ustawieniami lub hasłami, który tylko lokalnie powinien być dostępny, a z jakiś powodów nie chcemy go ignorować za pomocą .gitignore.

Jeszcze było o  wewnętrznej budowie commit’a. Ogółem git’a można potraktować jak acykliczny graf skierowany. Pojedyńczy commit może wskazywać na drzewo lub inne commity, drzewo wskazuje na BLOBy lub drzewa, a w BLOBach zapisywana jest zawartość plików. Co ciekawe, to nazwy plików nie są zapisywane w BLOBie, a w drzewie. Dlatego łatwo jest wykrywać zmiany położenia plików, nawet jak częściowo zmieni się zawartość.

Było jeszcze o root-commit’cie, który jest praojcem wszystkich commit’ów. Jak jakiś inny commit nie jest w stanie osiągnąć tegoż praojca, to znaczy, że jest wiszącym commit’em i można go usunąć. Swoją drogą ciekawi mnie, skąd się biorą takie wisielce? Chyba jak nie usuwamy niezmerge'owanych branchy z flagą -D, lub jakiś pojedynczych commit'ów, to nie powinno dochodzić do takich sytuacji.

Dalej było wspomniane, że nie warto wrzucać duże pliki do repozytorium. Nawet jak te pliki tam umieścimy, a następnie usuniemy, to i tak strasznie nam to spowolni pracę z git’em. A ciężko takie coś usunąć z historii tak, aby jej nie popsuć.

Oczywiście ta prezentacja nie mogłaby się odbyć z pominięciem tematu funkcji skrótu SHA1. Organizacja NIST(National Institute of Standards and Technology), która to ogłosiła ten algorytm, obecnie wycofuje się z niego i zaleca zastąpienie go SHA3. Ale w Gitcie ta funkcja skrótu nie jest wykorzystywana w celach kryptograficznych a identyfikacyjnych, więc zagrożenie jest naprawdę niewielkie. Co prawda można wygenerować plik, który będzie nam kolidował z czymś w repozytorium, ale na to pewnie też się znajdzie obejście. Po za tym zmiana funkcji hashującej wymusiłaby zmianę protokołów git’a, a ta jest dodatkowo tak zoptymalizowana, że trafia z chache CPU.

SHA1 jest wykorzystywana w Gitcie do identyfikowania commitu i innych obiektów. Dla commitów wystarczają nam zazwyczaj pierwsze 6, lub 8 znaków tegoż skrótu. Największy otwarty znany projekt hostowany na Gicie, czyli linux kernel, potrzebuje 12 znaków do identyfikacji commit’a. Wartości te są widoczne w .git/objects i są one pogrupowane w podkatalogi, aby nie osiągnąć maksymalnego limitu ilości plików w jednym katalogu i aby można było je szybko odszukać.

Było jeszcze o różnicy w sposobie przechowywania zmian w gitcie, a w SVNie. I tak SVN przechowuje różnice w plikach. Natomiast Git przechowuje całe pliki i gdy się nic w nich nie zmienia, to aktualizuje tylko wskaźnik na aktualną wersję pliku. Nie jest to do końca prawdą, gdyż gdy repozytorium nam rośnie, to git przechowuje stare rewizje również jako różnice w pliku i dodatkowo je kompresuje. Najnowsza wersja jest zawsze przechowywana jako pełen plik, gdyż najczęściej jej potrzebujemy. Dodatkowo Git został zoptymalizowany pod względem ilości zajmowanego miejsca na dysku.

Tomek wspomniał również o komendzie add w trybie interaktywnym, gdzie można wybrać, które zmiany w danym pliku wejdą do commita. Było również o takich poleceniach jak squash (pozwala złączyć commity w jeden), rebase (modyfikuje historię) i instaweb. Ta ostatnia komenda git’a pozwala przeglądać historię repozytorium przez przeglądarkę. Niestety funkcjonalność ta, póki co, nie działa w mysysgit na Windowsie(#11).

Z rzeczy poza Gitem z prezentacji dowiedziałem się o fajnej powłoce ZSH i o nakładce na nią ze zbiorem fajnych rozszerzeń: Oh My ZSH.

Prezentacja bardzo fajna. Spodziewałem się trochę więcej o komendach typu plumbing i tego co się pod spodem dzieje, gdy wywołujemy komendy typu porcelain. Ale o tym można sobie doczytać (nawet po polsku) w książce Pro Git 9. Mechanizmy wewnętrzne w Git, a prezentacja Tomka była dobrym wstępem do tego.

Po tej prelekcji niestety zmarnowałem trochę czasu na chodzeniu po stanowiskach sponsorskich, ale mówi się trudno. Ominięte wykłady oglądnę, gdy już zostaną opublikowane.

Clean architecture - jak uporządkować architekturę Twojej aplikacji. Wnioski z projektu. Andrzej Bednarz
Prelegent opowiadał, o swoim greenfield projekcie, w którym wraz z zespołem postanowili poszukać dobrej architektury. W tym celu przejrzeli to, co wielkie autorytety tego świata mówią i piszą w tym temacie i zaczęli podążać ścieżką promowaną przez Wujka Boba, a mianowicie Clean architecture.

Podejście nie jest jakoś szczególnie nowe. Mówi o odseparowaniu GUI i baz danych od naszej logiki. Każda sensowna architektura o tym mówi. Kluczowe w czystej architekturze jest odwrócenie zależności, tj. aby nasz core aplikacji NIE był zależny od bazy danych, frameworka GUI i innych komponentów. Czyli w naszych encjach powinniśmy przechowywać przykładowo datę w formacie typowym dla daty, a nie zdeterminowanym przez bazę danych, czy ORM. Innymi słowy, musimy mieć zależności DO naszej aplikacji. Więcej powinien wyjaśnić ten rysunek ze strony Wujka Boba:


Podejście takie powoduje, że nie jesteśmy uzależnieni od używanych framework'ów i możemy je łatwo wymienić. Zyskujemy również na łatwości testowania naszej logiki biznesowej. Architektura ta wymusza jednak pewien narzut na tworzenie warstw abstrakcji, wielu DTO i konwersji między różnymi obiektami.

Prezentacja była ogółem fajna. Andrzej pokazał na przykładzie kodu, jak to wygląda u niego w projekcie. Osobiście zabrakło mi trochę porównania w kodzie, z typową architekturą 3warstwową, aby móc uświadczyć różnice. Wadą wystąpienia było patrzenie prelegenta przez plecy, na kod wyświetlany na ścianie, aby pokazywać gdzie coś jest. Jak by nie można było włączyć odpowiedniego trybu pracy z rzutnikiem.

JVM and Application Bottlenecks Troubleshooting with Simple Tools Daniel Witkowski
W tym roku było sporo wykładów na Confiturze dotyczących szybkości działania tworzonych przez nas aplikacji. Prelegent pokazał kilka prostych sztuczek, jak wyłapywać problemy w naszych aplikacjach.

Na początku trzeba ustalić nasze wymagania jakościowe, czyli SLA, czas odpowiedzi, ile requestów na sekundę musimy wytrzymać itd. Następnie prelegent odpalił przygotowaną aplikację, „klikający” w nią JMeter i obserwowaliśmy, co nam pokazuje nam JVisualVM. I gdzieś tam chyba z Thread Dump’a wyczytaliśmy, że gdzieś jest ręcznie wywoływany Garbage Collector. Oczywiście wiadomo, że to jest zła praktyka, ale można zawsze ją wyłączyć, za pomocą flagi -XX:+DisableExplicitGC.

Będąc już przy temacie GC, to warto zawsze zapisywać logi z jego działania i przeglądać za pomocą GCViewer.

Inną pożyteczną wiadomością, jaką ze sobą niesie JVisualVM, jest podgląd wątków. Można tam przykładowo sprawdzić, czy liczba wątków http (przyjmujących żądania) jest taka jak się spodziewamy. Gdy będzie tylko jeden, to nie dobrze, bo requesty będą obsługiwane sekwencyjnie.

Wykres aktywności wątków, może również pokazać nam problemy z synchronizacją i blokowaniem się. Może to świadczyć o niewłaściwym użyciu słówka synchronized (np. na metodzie doGet()) lub innych mutex’ów. Jeśli widzimy, że wiele wątków nam się blokuje, to musimy znów w Thread dumpie szukać miejsc, gdzie coś może być nie tak.

Warto też spojrzeć, czy nie mamy problemów z odczytem / zapisem na dysku. W Linuxach można to sprawdzić za pomocą top’a, a na Windowsie poprzez Process Explorer. I tak jeśli dyski nie wyrabiają, może to oznaczać, ze mamy włączony za wysoki poziom logowania. Przy tej okazji w końcu zrozumiałem zasadność takich zapisów:
if(log.isDebugEnabled()) {
     log.debug(createLogMessage());
}

Jeśli ktoś napisze jakieś długotrwające operacje w metodzie createLogMessage(), to powyższy if, spowoduje, że nie będą ona wykonywane, gdy są i tak niepotrzebne. I tu bardzo fajnie widać wyższość Scali, gdzie taki argument mógłby być wyliczany w razie potrzeby.

Ponadto jakie nie wiemy w jaki sposób jest zaimplementowane isDebugEnabled(), to lepiej odczytać tą wartość raz i trzymać gdzieś w systemie.

Na koniec była jeszcze (na szczęście krótka) reklama narzędzia Zing Vision, jako że prelegent jest przedstawicielem Azul Systems. Firma ta jest również producentem maszyny wirtualnej Zing, która wg. producenta jest lepsza od implementacji Oracla.

Working with database - still shooting yourself in the foot? Piotr Turski
Prezentacja Piotrka bardzo mi się podobała, gdyż w moim projekcie doszliśmy do prawie tych samych wniosków co prelegent, a o drobnych różnicach mogliśmy sobie porozmawiać na Spoinie.

Piotrek korzysta w swoim projekcie z dwóch baz: H2 i Oracle. Jednak H2 nie do końca sprawdzała się w testach, gdyż czasem pojawiały się błędu specyficzne dla Oracla. Przykładowo w klauzurze in nie może być więcej niż 1000 elementów. Jest to dość znany problem, ale u Piotrka wyszło to dopiero na produkcji. Innym problemem było wykorzystywanie specyficznych możliwości „wyroczni” w zakresie wyszukiwania po umlautach (üöä). H2 tego nie obsługiwało, więc nie dało się testować. Innym problemem był typ Date, który na Oracle, inaczej jak na H2, po za datą zawiera również dokładną godzinę.

Z tych powodów w projekcie prelegenta testy integracyjne puszczano na Oracle, i każdy developer miał pod ręką dla siebie takową bazę. H2 nie zostało jednak wyrzucone z projektu (mimo 3 rund rozmów na ten temat), gdyż jest lżejsze, szybsze, i tylko kilka funkcjonalności na nim nie działa.

W takim wypadku, warto mieć mechanizm czyszczenia bazy na potrzeby testów. Można to załatwić DbUnit’em, ale utrzymywanie plików z danymi jest kosztowne. Po za tym narzędzie to nie zresetuje sekwencji. Można próbować również próbować przywracać dane z backup’a, ale to również może prowadzić do innego stanu bazy. Problematyczne jest tutaj usuwanie constraint’ów i powiązanych z nim index’ów. Dlatego warto wygooglać, jak można resetować bazę na Oraclu i dopasować rozwiązanie do własnych potrzeb.

Przy takich akrobacjach, warto zadbać o proces wprowadzania zmian na bazie danych. Piotrek używał w tym celu flyway, a ja u siebie korzystałem z liquibase. Nie można wtedy niestety ręcznie robić hotfix’ów. Zaletą jest to, że do testów można wtedy budować bazę tak samo jak na produkcji.

Warto również wprowadzić mechanizm testu „produkcyjnego deploymentu”. Chodzi o to, aby zgrywać stan z produkcyjnej bazy danych (schemat i dane) i wykonać deployment aplikacji (co wymusza wykonanie migracji). Zyskujemy wtedy pewność, że nic nie powinno się posypać przy roll out’cie.

Było jeszcze trochę o testowaniu integracyjnym z bazą danych, np., gdy chcemy sprawdzić HQL’a. Można do tego zaprząc wspomnianego już DbUnit’a, ale analizowanie później czemu test się wywalił, jest czasochłonne. Lepiej przygotować dane do testów w teście. Przecież i tak mamy zapewne możliwość zapisywania naszych encji w bazie, więc możemy to wykorzystywać w setupie naszych testów. Warto również przy tej okazji skorzystać z Builder’ów.

Programowanie JEE'ish bez stresu Jakub Marchwicki
Prelegent opowiadał na początku o tym, że warto czasem zbudować jakąś aplikację, wykorzystując inne technologie, niż standardowy Spring, Hibernate i JSF. Pozwala nam to przypomnieć, co te technologie załatwiają za nas, oraz jak działają pewne rzeczy na niższym poziomie. Do tego są lekkie, a przecież nie zawsze potrzebujemy tych wszystkich kombajnów, aby skosić 2m² trawnika.

I tak Jakub pokazał kilka alternatywnych rozwiązań:


Opisywane przykłady, można sobie tutaj przejrzeć: github.com/kubamarchwicki/micro-java

Zakończenie konferencji.
Na zakończenie konferencji było jeszcze losowanie nagród, wręczanie statuetek, podziękowania dla wolontariuszy itd. Szkoda, że część konkursów była wcześniej rozwiązywana, tj. w przerwach międzywykładowych. Niszczyło to szansę potencjalnych zwycięzców. Oganizatorzy od razu zapowiedzieli, że rejestracja w przyszłym roku będzie poprawiona i nie będzie tak długiej kolejki. Trzymam za słowo.

Na koniec była jeszcze impreza: Spoina, gdzie można było jeszcze trochę pogadać, zjeść pizzę, napić się piwka i pograć w kręgle. Bardzo fajne zwieńczenie tej konferencji, na którą 1400 wejściówek rozeszło się w 2 godziny od rozpoczęcia rejestracji.

Organizatorzy namawiali jeszcze do udziału w siostrzanej konferencji tj: w Warsjawie. A ja ze swojej strony dziękuję za super konferencję i zachęcam do nowej inicjatywy dBConf.