Метка: программирование

  • Let’s rock, everybody!

    Важно! Все измышления и предположения отражают мое личное мнение и естественно могут не совпадать с мнением большинства, впрочем, как и другие аналогичные статьи.

    Статья про рок-банды, новое время и программирование.

    rock-and-roll-xs

     

    Давно хотел провести аналогию между музыкой и программированием. Например команда разрабатывающая большие и сложные системы чем-то похожа на симфонический оркестр:
    blog_Classical_

    Вначале гениальный композитор должен написать свое бессмертное произведение, затем талантливый дирижер согласиться его исполнить, а все участники оркестра должны под его чутким руководством выучить и отработать необходимый материал. Итог работы будет зависеть от каждого участника (естественно в разной степени, никого не хочу обидеть, но вклад первой скрипки и парня с тарелками в заднем ряду сильно отличается).

    Если мы посмотрим на разработку программных продуктов по классической водопадной схеме, то состав участников также будет довольно обширным: архитектор, тим лид, ведущие программисты, несколько программистов разной специализации (java, c/с++, javascript и тд) и группа дизайнеров с верстальщиками. Естественно далеко не все компании могут себе позволить идеально укомплектованный состав. Наиболее успешные организации могут заинтересовать в профессиональном и материальном плане более сильных специалистов, остальные конторы довольствуются тем, кто соответствует их уровню.

    Тем не менее, на мой взгляд, существуют предпосылки для все большей популяризации нового формата коллективов. Во-первых это связано с большей доступностью компьютерной техники и развитием сервисов для разработчиков, во-вторых с ростом среднего уровня компьютерной грамотности, в-третьих формирование более позитивного отношения к техногикам у молодежи и общества в целом (сериал Теория Большого Взрыва, истории успеха и биографии Билла Гейтса, Марка Цукерберга, Стива Джобса и тд).

    Под новым форматом я имею в виду небольшой творческий коллективов состоящий из 3-5 человек. Это еще не “оркестр”, но уже и не соло-программист. Естественно масштаб создаваемых произведений не сопоставим с творением Классики. Другими словами, если проводить аналогии, речь идет о коллективах создающие программы “по духу” более близкие к Yesterday Битлз, чем к Хорошо темперированному клавиру И.С. Баха.
    Все идет к тому, что в программировании наступит время аналогичное музыкальной эпохи 60-70гг прошлого века.

    У кого-то может возникнуть такая ассоциация:
    blog_beatles
    у других такая: (далее…)

  • Комиксы

    Поскольку эта рабочая неделя короткая и уже постепенно подходит к концу, то я решил не публиковать сегодня никаких нагружающих мозг публикаций. Давно хотел вместо очередной технической статьи выложить небольшую подборку ссылок на веб-комиксы, которые регулярно читаю в перерывах на обед и перед работой.

    1. CommitStrip

    Французские авторы. Про жизнь небольшой команды занимающейся веб-разработкой.

    (далее…)

  • Java и лямбда-выражения.

    Lambda

    Ни для кого не секрет, что во второй половине 2013 года планируется выпуск Java 8 (UPD: на JavaOne 2013 в Москве сообщили, что выход восьмерки перенесут на 2014). Мне наконец-то надоело быть пассивным читателем всех этих многочисленных восторженных отзывов о нововведениях языка и я решил скачать предварительную версию JDK (благо она уже давно выложена) и начать свои экзерсисы.

    Как правило я стараюсь ждать релиза, но сейчас в новостях столько разговоров о лямбда-выражениях в новой Java, что мне, старому Scala-фанатику и функционального программирования, уж очень сильно захотелось поиграться с новыми возможностями языка. Если смотреть на все новшества восьмой Java со стороны Scala программиста, то в целом лично я отношусь к ним положительно, поскольку такой расклад возможно приведет к уменьшению разрыва между мощью синтаксиса Scala и текущей (седьмой) версией Java как языка программирования. Хотя конечно, даже со всеми новшествами восьмерки Java будет сильно отставать от Scala.

    JDK с “Lambda Project” можно скачать c официальной страницы.
    Также в текущей сборке JDK 8 (на момент написания статьи) лямбды уже тоже есть, но API с коллекциями еще не полностью завершены.

    Целью данной статьи не написание учебного пособия по новым функциям Java, думаю этой работой должны заниматься ребята из Oracle. Здесь я хотел сделать небольшие заметки для себя на будущее вместе с небольшими примерами кода, к которым хотелось бы вернуться после официального выпуска JDK 8.

    В бытовом, чисто утилитарном смысле, под этой пресловутой лямбдой (или лямбда-выражениями) многие программисты как правило подразумевают обычные анонимные функции (хотя конечно это не строгое определение). Причем под функцией имеется в виду первоклассный объект. Его можно передавать как объект в аргументы метода, присваивать какой-то переменной и т.д. С точки зрения конечного пользователя (в нашем случае программиста) мы получаем удобный способ сокращать количество строк кода, без сильной потери в его читаемости.

    Мои опыты

    Один из самых часто встречаемых примеров в интернете, демонстрирующих пользу от использования лямбды — замена старых добрых анонимных классов.
    Сравните. Это новый вариант:

       // Вот она, анонимная функция!
       Runnable r = () -> System.out.println("hello");
       Thread th = new Thread(r);
       th.start();
    

    Вот так по-старинке:

       
       Runnable r = new Runnable() {
            public void run() {
                System.out.println("hello");
            }
       };
       Thread th = new Thread(r);
       th.start();
    

    Естественно и логично применить такой подход для слушателей.
    Вот небольшой сниппет с формочкой и кнопкой.

    public class Main {
        public static void foo(ActionEvent e) {
            System.out.println("hello:" + e);        
        }
    
        public static void main(String arg[]) throws Exception {
            JFrame frame = new JFrame("Demo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JButton button = new JButton("Hello");
            // магия происходит здесь
            button.addActionListener((ActionEvent e)-> { foo(e); });
    
            frame.getContentPane().add(button, BorderLayout.CENTER);
            frame.pack();
            frame.setVisible(true);
        }
    }

    Если у вас аллергия на вложенные скобки, то можно упростить следующим образом:

        // Можно присвоить listener-у
        ActionListener listener = (ActionEvent e)->{ foo(e); };
        // а вот так не скомпилируется ;)
        //Object o = (ActionEvent e) -> { foo(e); };
        button.addActionListener(listener);
    

    Или даже можно сделать так:

            
       button.addActionListener(Main::foo);
    

    Главное никаких отражений, используется invokedynamic.

    Естественно возникает желание посмотреть на API коллекций.

    Можно использовать в качестве Comparator-а функцию сортировщик:

      
       String arr[] = {"a","b","c"};
       Arrays.sort(arr, (x, y) -> x.compareToIgnoreCase(y));
    

    Также в Java 8 будет реализация многопоточной сортировки:

      
      String arr[] = {"a","b","c"};
      Arrays.parallelSort(arr, (x, y) -> x.compareToIgnoreCase(y));
    

    Функциональщики как раз любят такие многопоточные методы. К сожалению, на моих тестах в используемой версии JDK 8 от использования parallelSort польза была только на примитивных данных (например при сортировки массивов int-ов). На массивах с объектами никакой пользы не было, но ведь и релиз только через несколько месяцев, так что сейчас никаких серьезных тестов скорости проводить некорректно.

    Итог

    Думаю многие согласятся, что восьмерка не скоро будет тотально доминировать на серверах и использоваться в промышленной эксплуатации, поскольку существует довольно большая прослойки особо консервативных Java-программистов. Тем не менее функциональщина сейчас в мировом программистком тренде, поэтому Java 8 это безусловно интересно и имеет смысл потратить в дальнейшем дополнительное время на её изучение.

  • Уменьшение размеров JavaScript и CSS файлов.

    В данном случае идет речь о минификации, т.е. например удалении лишних пробельных символов и комментариев. Часто используется при подготовки и развертывании систем готовых к промышленной эксплуатации. Конечно, также с целью экономии трафика имеет смысл включать GZIP compression в настройках сервер, но данная статья не об этом.

    Минификация – операция довольно рутинная и по-хорошему должна быть автоматизирована и встроена в процесс автоматической сборки.
    Тем не менее, иногда возникает необходимость сделать подобную минификацию кода в полевых условиях на сервере заказчика из командной строки. (далее…)

  • Java. Примеры копирования файлов. Эволюция и революция.

    Задачка копирование файлов в свое время была хорошим тестом для программистов.

    1. Streams.

    До появления пакета NIO (New I/O, версия Java 1.4) многие использовали обычные потоки.

        public static void copy(File source, File dest) throws IOException {
            FileInputStream is = new FileInputStream(source);
            try {
                FileOutputStream os = new FileOutputStream(dest);
                try {
                    byte[] buffer = new byte[4096];
                    int length;
                    while ((length = is.read(buffer)) > 0) {
                        os.write(buffer, 0, length);
                    }
                } finally {
                    os.close();
                }
            } finally {
                is.close();
            }
        }
    

    2. New I/O

    В 2000-ном году появился пакет java.nio. Акроним NIO означает New I/O (новый ввод/ввывод). Отчасти я согласен с мнением, что название было выбрано не очень удачным, т.к. не сложно было предположить, что пройдет время и будет нелепо называть новым пакет 12-летней давности.

    С помощью NIO копирование файлов смотрелось более изящно, решение эволюционировало следующим образом:

        public static void copy(File source, File dest) throws IOException {
            FileChannel sourceChannel = new FileInputStream(source).getChannel();
            try {
                FileChannel destChannel = new FileOutputStream(dest).getChannel();
                try {
                    destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
                } finally {
                    destChannel.close();
                }
            } finally {
                sourceChannel.close();
            }
        }
    

    Легко видеть, что здесь мы избавились от цикла, используем “новое” API и сократилось количество кода.

    3. Apache Commons IO.

    Тем не менее, многих ленивых программистов такое развитие не особо впечатлило и те кто знал, продолжил использовать Apache Commons IO.

        public static void copy(File source, File dest) throws IOException {
            FileUtils.copyFile(source, dest);
        }
    

    Единственным неудобством была необходимость в дополнительной сторонней библиотеке. Тем не менее, поскольку библиотека предоставляла программистам еще много другого удобного API для работы с I/O, по моим наблюдениям файл commons-io-*.jar стал присутствовать во многих крупных проектов того времени.

    4. Java 7.

    Революция произошла с выходом Java 7, релиз который был сделан уже Oracle, а не Sun Microsystems.
    Появился класс Files, с помощью которого копирование файлов стало не намного сложнее чем commons-io:

        public static void copy(File source, File dest) throws IOException {
            Files.copy(source.toPath(), dest.toPath());
        }
    

    При этом не нужно прописывать в мавене дополнительную зависимость.

    Понятно, что это доступно только для Java 7 и предыдущие ее версии во всю используются многими компаниями. Тем не менее, в связи с недавней новостью о том, что Oracle выпустил недавно свое последнее публичное обновление для Java 6, возможно многие все-таки будут постепенно переползать на семерку.

  • Сколько стоит талант программиста (и не только).

    gold
    Фото с wikipedia

    Давно уже ничего не писал на общие темы – о выборе профессии, жизненном пути или поиске предназначения. Последний раз подобных тем касался почти три года назад.

    Прежде чем начать изложение, хотел сообщить, что я осознаю всю нестрогость моих расчетов и надеюсь никто не станет воспринимать приведенные ниже доводы буквально!

    Теперь можно приступать.

    Думаю многие знают о происхождении слова талант. Если кто не знает и есть желание подробно изучить этот вопрос, то привожу ссылку на соответствующую статью в википедии. В кратком изложении вся история с талантом выглядит следующим образом.

    Талант, в современном понимании, это определённые способности, которые раскрываются с приобретением навыка и опыта. Поиск источника такого толкования этого слова приведет нас к притче о талантах.

    В древнем мире талант был мерой веса. В той притче некий хозяин раздал своим рабам несколько  талантов золота. Одному дал пять, другом два, третьему один. Затем отлучился на некоторое время. Когда вернулся стал выяснять кто что сделал.

    Один приумножил, второй разменял, а третий закопал свой талант в землю. Того, кто закопал, хозяин отругал, других похвалил и наградил. Мораль — закапывать свой талант плохо, приумножать — хорошо.

    Недавно мне стало интересно, а сколько именно было закопано? Немного покопавшись в интернете нашел приближенные исходные данные и произвел следующий расчет.
    (далее…)

  • Липкий запуск сервисов в Android-e.

    В Android API есть такой абстрактный класс как Service. Он является наследником ContextWrapper-а, который в свою очередь является наследником Context-a. При некоторых допущениях можно относиться к сервисам как к “активити без UI” (хотя это не совсем правильно в деталях). Использовать сервис рекомендуется для задач не требующих прямого вмешательства пользователя.

    В документации особо акцентируется внимание на том, что Service не является ни процессом, ни ниткой. Если сервис должен делать какую-то “тяжелую” работу, то нужно самому выносить ее в отдельный thread, чтобы не получить ANR (Application Not Responding).

    Если делать свой thread лениво, то можно использовать готовый класс для асинхронной работы IntentService.

    Про него нужно знать следующее:

    • IntentService наследуется от Service.
    • Является абстрактным классом.
    • Нужно реализовать в нём метод onHandleIntent(Intent).
    • Обработка intent-ов идёт поочередно, но не в главном, а в своем выделенном thread-e.

    Диаграмма классов сервисов выглядит следующим образом: (далее…)

  • Андроидная венгерско-верблюжья нотация

    Для разработчиков OC Android, как и для других серьёзных программистов, существует соглашение по оформлению кода.
    В целом оно совпадает с соглашением в обычной Java. Как именно нужно оформлять, можно прочитать на официальной странице для Android разработчиков.

    Привожу краткую справку по наименованию полей класса:

    • НЕ паблики и НЕ статики должны начинаться с “m” (анг: Non-public, non-static field names start with m).
    • Статики с “s” (Static field names start with s).
    • Все остальные – со строчной буквы (Other fields start with a lower case letter).
    • Константы – БОЛЬШИМИ_БУКВАМИ (Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES).

    Активно используется верблюжий регистр (Camel Case).

    Пример с официального сайта:

    public class MyClass {
        public static final int SOME_CONSTANT = 42;
        public int publicField;
        private static MyClass sSingleton;
        int mPackagePrivate;
        private int mPrivate;
        protected int mProtected;
    }

    Наверное, гугл не был бы гуглом, если бы не внёс изменения в стандартные соглашения Java. Очень активно используются префиксы.
    Для обычных полей “m” (возможно от англ. member), а для статических полей – “s” (static).
    Это очень похоже на венгерскую нотацию.

    Занятный факт, если пройтись grep-ом по исходникам Android-a, можно найти места, где эти конвенции не соблюдаются. Например статические поля имеют префикс “m”:


    sources/adndroid-16

    ./android/app/ActivityThread.java: static ContextImpl mSystemContext = null;
    ./android/app/SearchManager.java: private static ISearchManager mService;
    ./android/bluetooth/BluetoothTetheringDataTracker.java: private static String mIface;
    ./android/content/res/Resources.java: /*package*/ static Resources mSystem = null;
    ./android/content/res/Resources.java: private static boolean mPreloaded;
    ./android/database/DatabaseUtils.java: private static Collator mColl = null;
    и т.д.

    Непонятно, почему так получилось. Обычно проверка правильности оформления исходного кода в крупных организациях автоматизирована.
    Тем не менее, хотя принцип догфудинга по оформлению исходников гуглом соблюден не в полной мере, думаю, это не оправдание для других Android-программистов нарушать правила.

    UPD! Нужно уточнить, правила действительны для контрибуторов AOSP. То есть тех, кто пишет исходники Андроида.

  • Тренды программистских вакансий на indeed.com

    Пару дней назад прочитал интересную статью на dzone.com с занятными графиками, которые показывали количество вакансий для программистов.

    В статье были опубликованы данные с сайтов: indeed.com и simplyhired.com

    Оба сайта имеют русскоязычный интерфейс, поэтому надеюсь, что приведенные графики отображали не только данные по США (как часто бывает), а мировые тренды.
    Хотя может быть это и не так. К сожалению, не нашел способа получить картинки локализованные под Россию (или Москву).

    Меня в первую очередь конечно интересовала java, а также близкие или “конкурирующие” языки программирования.
    Поэтому в отличие от оригинальной статье на dzone я оставил в графике от indeed.com только такие языки как: java, C++, C#, objective c (убрал Perl и Visual Basic).

    Получилась такая картинка: (далее…)

  • Примеры работы с JMeter в картинках

    Приблизительно раз в год у меня возникает необходимость проводить пробное нагрузочное тестирование очередного проекта. Раньше приходилось сталкиваться с этой задачей чаще, но сейчас больше времени уходит на разработку под мобильные платформы (Android и т.д.) или создание программного обеспечения для решения внутренних инфраструктурных задач клиентов.


    В итоге каждый раз я судорожно вспоминаю как работать с jmeter-ом. Скачиваю, запускаю и полдня вспоминаю как его настраивать.

    Сразу оговорюсь, я не профессиональный тестировщик и проверка работы веб-приложений под нагрузкой не входит в мои прямые обязанности.
    Поэтому фраза “возникает необходимость” скорее нужно понимать не как приказ начальника, а “мне очень любопытно посмотреть, что случиться если…” (особенно если учесть, что начальника у меня нет, но про это в другой раз).

    Лет 10-15 назад на одной из своих первых работ для задач нагрузочного тестирования мы использовали утилиту, которая кажется так и называлась стресс-тул (вроде даже микрософтовская). Она была простая и интуитивно понятная. Только я ее уже 10 лет не видел и не знаю, использует ее кто-нибудь еще сейчас.

    Последние несколько лет пользуюсь JMeter-ом (или облачными сервисами). Пользовательский интерфейс JMeter-а (если с ним не работать регулярно) совсем не интуитивно понятный. Без прочтения документации или просмотра обучающего фильма очень сложно сделать даже самый простой тест (скажем 1000 запросов к одному URL-у).

    Поэтому, чтобы каждый раз не зависать по полдня над этой задачей, я решил написать себе простую шпаргалку-напоминалку по работе с этим jmeter-ом. Понятное дело, что все возможности этой чудесной утилиты не описать в одной статье, тем не менее пошаговую инструкцию в картинках для примитивного случая, думаю, сделать можно.
    Очень надеюсь, что пользовательский интерфейс этой утилиты в ближайшее время не изменится кардинально.

    Итак. (далее…)