mar 25th

Book review: Czysty kod. Podręcznik dobrego programisty

Książkę kupiłem chyba rok temu, ale dopiero teraz udało mi się ją przeczytać w całości. Polecała ją duża liczba programistów hasłami typu: „zanim zaczniesz programować, lub jeśli chcesz lepiej programować, musisz ją przeczytać”. Wtedy dopiero zaczynałem programować i po połowie była po prostu.. niezrozumiała, więc skończyłem czytać obiecując sobie, że za jakiś czas zrobię kolejne podejście.

Treść książki to porady jednego z najbardziej znanych programistów na temat pisania czytelnego kodu, używania testów jednostkowych i przykładach refaktoryzacji kodu. Do połowy książkę można czytać szybko, ponieważ zawiera porady, które nawet dla początkujący programista potrafi szybko przetworzyć. Dalsza część książki jest nieco trudniejsza i należy się mocno skupić na przykładach, a nawet zatrzymywać się i próbować samemu analizować  refaktoryzację nieczytelnego kodu. Nie będę się dokładniej rozpisywał o poszczególnych rozdziałach, te informacje możecie znaleźć np. na stronie Helionu, który wydał książkę.

Podsumowując ten krótki opis, dołączam się do rzeszy programistów chwalących tą książkę. Jeśli zamierzasz zawodowo programować, to musisz ją mieć! Nawet jeśli na początku nie wszystko będzie oczywiste, to na pewno po jakimś czasie to co napisał autor wyda Ci się fantastyczną sprawą ;)

 

lut 18th

Proste obliczanie CRC dla strumienia bajtów + OutOfMemoryError

Nie wszystko złoto co się świeci. W książce Common Java CookBook jest przedstawiony prosty sposób obliczenia CRC dla pliku przy użyciu biblioteki google guava. Krótki i czytelny kod świetnie sprawdza się dla małych plików. Ale z dużymi niestety nie współpracuje tak jak się tego spodziewamy. Oto lekko przerobiony kod (zmieniłem sposób wskazania na plik) z rozdziału 15.4:

public static void main(final String[] args) throws Exception {
        final InputStream test = new FileInputStream("test.zip");
        final byte[] byteArray = ByteStreams.toByteArray(test);
        final CRC32 crc32 = new CRC32();
        final long checksum = ByteStreams.getChecksum(
                ByteStreams.newInputStreamSupplier(byteArray), crc32);
        System.out.printf("Checksum: %d", checksum);
    }

Dla pliku test.zip o rozmiarze 140 MB wszystko poszło sprawnie i dostałem wynik: Checksum: 1755861318
Dla pliku o rozmiarze 304 MB niestety dostałem wyjątek:

Exception in thread „main” java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at com.google.common.io.ByteStreams.copy(ByteStreams.java:171)
at com.google.common.io.ByteStreams.toByteArray(ByteStreams.java:210)
at test.Test.main(Test.java:13)

Typowa reakcja na ten wyjątek to zwiększenie pamięci dla JVM. Zwiększyłem więc pamięć dla Eclipse z 512MB do 1GB, ale nie rozwiązało to problemu. A nawet jeśli w tym przypadku by pomogło, to co by było gdybym obliczał za pomocą tego kodu CRC dla pliku np o wielkości 2GB? Prawdopodobnie ten sam problem.
No więc na koniec morał: używanie zewnętrznych bibliotek ułatwia życie, ponieważ pozwala skrócić czas pisania kodu oraz poprawić jego czytelność. Jednak jak każdy kod, mogą zawierać błędy :) Bądźcie ostrożni i testujcie Wasz kod :)
Błąd spowodował ten kawałek kodu: ByteStreams.toByteArray(test);
Zgłosiłem go tutaj: http://code.google.com/p/guava-libraries/issues/detail?id=551
————————————————————————–
update:
Już po godzinie dostałem pouczającą odpowiedź:
This doesn’t have anything to do with ByteStreams.toByteArray. 300 MB is generally too much to be loading into memory, and it isn’t necessary at all in your example. What you should be doing is this:

   CRC32 crc32 = new CRC32();
   File file = new File("test.zip");
   long checksum = ByteStreams.getChecksum(
       Files.newInputStreamSupplier(file), crc32);

Kod sprawdziłem dla pliku 1,42GB i błyskawicznie dostałem odpowiedź: Checksum: 2642167178
Musi się więc zmienić morał: podchodź nieufnie do kodu znalezionego w książkach, ponieważ błąd może się znajdować w logice, a nie w użytych bibliotekach :)

lut 16th

Zapis liczby całkowitej do pliku w postaci little-endian

Zapisywanie liczb całkowitych do pliku w postaci bajtowej domyślnie wykonywane jest w postaci big-endian (najbardziej znaczący bajt umieszczany jest jako pierwszy). A co jeśli potrzebujemy je zapisać w postaci little-endian (mniej znaczący bajt umieszczany jest jako pierwszy)? Strumienie w Java nie posiadają niestety możliwości łatwej zmiany domyślnego zapisu (albo ja takiej nie znalazłem), więc trzeba się ratować napisaniem własnej funkcji. Na tym przykładzie zamierzam pokazać użycie zewnętrznych bibliotek zaprezentowanych w książce Common Java CookBook, o której napisałem w poprzednim wpisie.
Żeby zapisać liczbę całkowitą do pliku w postaci little-endian należy:
1. zapisać ją do strumienia
2. pobrać ją ze strumienia w postaci tablicy bajtów
3. odwrócić bajty w tablicy
4. zapisać tablicę bajtów do strumienia (który zapisuje do pliku)
Czytaj dalej

lut 13th

Common Java Cookbook – czyli jak pisać lepszy i zwięzły kod przy pomocy zewnętrznych bibliotek

  • Kategorie Books
  • Komentarze 0

Po co wymyślać kolejny raz koło? Zamiast tracić czas na pisanie kodu rozwiązującego znane problemy warto wcześniej sprawdzić, czy ktoś już tego nie zrobił (i ewentualnie poprawić lub dostosować kod do naszego problemu ;) ). W jednej z takich sytuacji natrafiłem na książkę Common Java Cookbook, opisującej użyteczne biblioteki do realizacji przeróżnych zadań związanych z codzienną pracą programisty. Książkę możecie pobrać w formie pdf tutaj (wymagana rejestracja), zarówno całość jak i pojedynczo konkretne rozdziały lub podrozdziały. Każdy rozdział dotyczy innej problematyki programistycznej, która jest podzielona na typowe problemy oraz przykłady rozwiązań + krótką dyskusję na ten temat. Opisane biblioteki to m. in.: Google Guava, commons-io, commons-lang, commons-collections, commons-digester, commons-betwix, Lucene, Velocity
Polecam zacząć czytanie od tematów dotyczących waszego aktualnego projektu, wtedy chyba najlepiej będzie widać użyteczność i zwięzłość proponowanych rozwiązań. Ja zacząłem od poprawy paskudnego kodu przy zamykaniu strumieni, później doszło rekurencyjne kasowanie katalogu wraz z zawartością (jedna linijka kodu zamiast pisania własnej funkcji), a kończyłem na kilku poradach dotyczących używania strumieni i operacji na stringach. W każdym miejscu w którym zastosowałem rozwiązania z książki poprawiała się jakość kodu – był bardziej zwięzły i czytelny niż przy zastosowaniu klas ze standardowego API Javy. Dodatkowo zaoszczędziłem sporo czasu, który mogłem przeznaczyć na czytanie kolejnych rozdziałów dotyczących rozwiązań problemów czekających mnie przy aktualnym projekcie.
Podsumowując – warto przeczytać całość od deski do deski. Mimo, że nie wszystkie porady są na wysokim poziomie większość z nich skróci czas pisania nudnego kodu i poprawi jego czytelność. W kolejnym artykule przedstawię przykład poprawy rozwlekłego kodu realizującego realny problem. Musi mnie tylko najść wena na napisanie wariantu rozwlekłego ;)

paź 11th

Book review: Programming Scala – Tackle Multi-Core Complexity on the Java Virtual Machine

„Scala – następca Javy”. To hasło marketingowe początkowo zachęciło mnie do sprawdzenia, czy aby na pewno :) Kilka blogów, kilka przykładów i poczułem, że ten język  może być naprawdę wartościowy.  Po lekturze książki jestem pewien, że jeśli nie następca, to język będzie towarzyszem Javy, który będzie upraszczał tworzenie systemów informatycznych. Zwięzłość i elegancja to słowa bardzo często pojawiające się w książce. Muszę przyznać, że te dwa przymiotniki + świetny model współbieżności i możliwość współpracy z Java to ogromna siła tego języka. Na początku może być trochę ciężko na przestawienie myślenia do podejścia funkcyjnego, ale uwierz na słowo – warto. Teraz mam wrażenie, że składnia Javy momentami jest „przerostem formy nad treścią”.

Książkę czyta się bardzo przyjemnie, przykłady i opisy są bardzo przejrzyste i nie sprawiają większych problemów ze zrozumieniem. Opisane są kolejno następujące właściwości Scala:

  • wprowadzenie – czym jest Scala
  • start – instalacja i operacje wykonywane z linii poleceń
  • opis „podstawowych” obiektów
  • klasy i typy
  • domknięcia (closures) i function values (jeśli ktoś wie jak to zrozumiale spolszczyć proszę o info :) )\
  • traits
  • kolekcje
  • pattern maching i wyrażenia regularne
  • współbieżność
  • używanie Scala w Java i odwrotnie
  • testy jednostkowe
  • wyjątki
  • przykłady użycia języka w pisaniu aplikacji (używanie XML, odczytywanie zawartości z pliku i sieci WWW, współbieżność oraz tworzenie GUI)

Polecam książkę i naukę Scala każdemu programiście piszącemu w Javie ;) Pewnie jeszcze trochę czasu minie, zanim język będzie szeroko używany, ale poznanie go na pewno będzie rozwijające na każdego, kto nie miał do czynienia z językami funkcyjnymi. Dla mnie ta książka to dopiero początek, temat Scali będę na pewno zgłębiał. Teraz czas na książkę twórcy języka – Martina Odersky’ego. A co potem? Pewnie Lift ;)