суббота, 31 декабря 2011 г.

[life.sport.darts] Лытдыбр

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

[life.cinema] Очередной кинообзор (2011/12)

Подошло время очередного кинообзора.

Упражнения в прекрасном. Посмотрел с огромным удовольствием.

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

Дом. Очень даже нечего. Если бы не один момент в конце фильма, который все испортил.

Ночь страха. Отличная смесь вампирского фильма с около-молодежной-комедией.

Ронал-варвар. Смешной мультик для тинейджеров, с классной русской озвучкой.

Нечто (2011 года) и Нечто (1982). До просмотра я читал несколько сравнений нового фильма со старым. Не в пользу нового, конечно. Но я никакого разочарования не испытал. Хоть и закручены фильмы вокруг одной и той же идеи, они разные. Тем более, что новый фильм снят как приквел к старому. Хотя мое личное мнение, что старый фильм сильнее. Хоть в нем и спецэффекты совсем примитивные (по сравнении с новым фильмом), но воспринимается он как-то достовернее.

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

Воин. Очень качественно и реалистично сняты сцены боев без правил. Между которыми слишком много соплей и высокопарных диалогов.

Заражение. Попытка снять страшилку на тему глобальной пандемии. Боюсь, что если таковая произойдет на самом деле, то все будет намного страшнее. И фильму не удалось отразить и доли того ужаса, который будет твориться.

Бой с тенью 3D: Последний раунд. Сказочка.

Коломбиана. На один просмотр. Местами много соплей. И все очень невероятно.

Время. Снято добротно. Но воспринимать серьезно происходящее не получалось. Есть во всей тамошней идее какая-то нелогичность. Какая не понял, но есть впечатление, что концы с концами в этой системе ограничения и продления времени не сходятся.

Кожа, в которой я живу. Потрясающе классно снятая потрясающая галиматья.

Красный штат. Потенциально неплохая задумка была полностью испорчена халтурным исполнением (как на уровне сценария, так и на уровне съемок).

среда, 28 декабря 2011 г.

[prog.testing] Ознакомился с описанием тестирования SQLite

Вот здесь наткнулся на интересную статью How SQLite is Tested. Внушаить. Снимаю шляпу, есть чему поучиться и есть к чему стремиться.

Для тех, кто не в курсе: SQLite – это, пожалуй, самая распространенная встраиваемая в приложение легковесная реляционная СУБД, поддерживающая подмножество SQL.

Если коротко, то в тестировании SQLite используется три набора тестов (все цифры относятся к версии 3.7.8):

  1. TCL tests. Находящиеся в открытом доступе тесты, написанные с использованием языка TCL. В них реализовано 28278 тестов (test cases), но некоторые запускаются с разными параметрами, так что суммарно проверяется порядка 1.7 миллиона тестов.
  2. TH3. Это закрытый набор тестов, который нужно лицензировать отдельно. В нем реализовано 33595 различных теста. Этим тестовым набором обеспечивается 100% покрытие кода SQLite (для чего требуется прогон порядка 800 тысяч тестов). Всего же полный тестовый прогон перед релизом SQLite содержит порядка нескольких сотен миллионов тестов.
  3. SQL Logic Test. Прогоняет туеву хучу различных SQL-ных запросов как через SQLite, так и через другие БД для того, чтобы убедиться, что получаются одинаковые результаты обработки запросов. Всего при тестировании выполняется порядка 7.2 миллионов запросов.

Все это дело используется для проверки:

1. Аномальных режимов работы:

  • нехватка памяти. Для симуляции чего SQLite подсовывается специальный менеджер памяти, который специально возвращает 0 при обращении к функции malloc (однократно или последовательно, в зависимости от сценария теста);
  • наличие ошибок ввода-вывода. Для симуляции чего SQLite использует специальную реализацию интерфейса Virtual File System. Эта реализация поддерживает возможность имитации различных ошибок ввода-вывода по различным сценариям;
  • крах приложения. Здесь посредством еще одной реализации Virtual File System проверяется корректность содержимого файлов БД при имитации краха приложений на разных стадиях работы с данными;
  • сочетания различных видов сбоев – например, нехватка памяти при попытке восстановления после ошибки ввода-вывода.

2. Некорректных данные:

  • синтаксически корректные, но семантически неправильные SQL-выражения (во время этого тестирования прогоняется порядка 102.1 тысяч разнообразных SQL выражений);
  • запорченные файлы БД. Берутся нормальные файлы БД, в которых меняется часть байт и испорченные таким образом БД скармливаются SQLite;
  • граничные условия. Проверяется поведение SQLite когда ей пытаются задавать значения, превышающие максимально допустимые. Например, создаются таблицы со слишком большим количеством столбцов и т.д.

3. Отсутствия регрессии при разработке SQLite. На каждый выявленный баг заводится тест, который включается затем в набор регрессионных тестов для проверки того, что он не всплывет в будущих версиях.

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

Так же активно используются средства динамического анализа:

  • assert-ы, которые можно включить посредством символа препроцессора SQLITE_DEBUG;
  • valgrind, который ловит кучу проблем, связанных с памятью, но за счет серьезного снижения скорости работы. Поэтому под valgrind-ом прогоняется только ограниченный набор тестов;
  • memsys2, который контролирует работу с памятью (хуже, чем valgrind, зато намного быстрее);
  • специальные средства для контроля за тем, что мутексы при работе в многопоточной среде захватываются и освобождаются должным образом;
  • journal test VFS, специальная реализация интерфейса Virtual File System, которая контролирует, что все данные, которые SQLite пишет в БД, сначала проходят через rollback journal (т.е. сначала попадают в журнал транзакции);
  • отсутствия переполнения signed int-ов, для чего делаются прогоны кода, скомпилированного посредством GCC с опцией –ftrapv.

Так же SQLite проверяется на получение одинаковых результатов работы с данными в БД при включенной и выключенной оптимизацией запросов.

Еще раз повторюсь – внушаить. Такое впечатление, что в тестирование SQLite вложено в разы больше труда, чем в собственно ядро SQLite. Что подтверждается цифрами: объем кода SQLite – 77.6 KSLOC, объем тестов – 91392.4 KSLOC (в 1177 раз больше).

Если же кого-то информация заинтересовала, то настоятельно рекомендую обратиться к первоисточнику и приведенным там ссылкам.

[prog] Вышла версия 6.0.7 библиотеки ACE

Обновилась библиотека ACE – появилась версия 6.0.7. В этой версии в шаблонный класс ACE_Atomic_Op добавлен метод exchange. В группу шаблонных классов для поддержки таймерных очередей добавлен новый параметр – TIME_POLICY. Класс ACE_Countdown_Time преобразован в шаблон, в котором так же есть параметр TIME_POLICY. Заявлена начальная поддержка MS Visual Studio 11.

Скачать новую версию ACE (а так же обновленные версии TAO, CIAO и DAnCE) можно отсюда: http://download.dre.vanderbilt.edu/previous_versions/

понедельник, 26 декабря 2011 г.

[prog.suddenly] Интересное качество языков программирования

Выдернуто отсюда:

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

Даже не знаю, как прокомментировать. Но фраза замечательная.

[prog.memories] Несколько хороших историй на тему инженерной археологии

…нашлось в разделе юмора на RSDN, хотя место им вовсе не в юморе. Вот они:

Память фирмы (не про программирование, но очень поучительно)

Археология исходников в блоге ув.тов.ShaggyOwl

Археология исходников в Компьютерре за авторством ув.тов.Виктора Шепелева.

На тему первой истории (про установку производства полимеров и “левые” копии технической документации у инженеров) мне вспомнился случай, который произошел со мной.

Когда-то давным-давно сделали систему для большого заказчика. Причем сделали так – есть софт на нашей стороне, есть софт на их стороне. То, что на нашей стороне, мы полностью делали сами. То, что на их стороне – в основном их собственная разработка, в которой использованы наши библиотеки. Понятное дело, что как только возникало что-то странное в работе софта на их стороне, то всех собак вешали на нас (“Ваша библиотека работает не правильно!”) и мы с шилом в заднице пытались найти у себя проблемы, которые чаще всего были не у нас.

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

Минуло еще года три и случился большой Бах-ТРАХ-Тара-Рах (причем ТРАХ именно с большой буквы во всех смыслах этого слова). В конце-концов проблема была найдена – зацикливание при разборе принимаемых данных. Но этого было мало, нужно было еще как-то указать, откуда она взялась. И тут очень пригодился валявшийся все это время без дела архив – зная что именно искать я, в итоге, нашел место, где происходила ошибка. Хотя, по хорошему, этих исходников у меня быть не должно было ;)

воскресенье, 25 декабря 2011 г.

[life.sport.darts] Впечатления от дротиков Unicorn Phase 6 Purist – 25g 97%

В начале 2011 года Фил Тейлор на несколько месяцев сменил дротики. Затем вернулся на свою, уже старую, пятую фазу (Unicorn Phase 5). Но Unicorn через полгода выпустил в продажу ту самую модель, которую назвали Phase 6. После длительного облизывания и глотания слюней я таки решился прикупить себе комплект на пробу. Несколько фотографий и впечатления под катом.

пятница, 23 декабря 2011 г.

[life.politic] Попытался было понять слова нашего президента

Избегаю писать у себя в блоге о политике. Тому есть три причины:

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

Тем не менее, иногда переклинивает. Сегодня с утра в КП-Беларусь (“толстушка”) обнаружил текст интервью Александра Лукашенко Сергею Доренко. Взгляд зацепился за пару вопросов вокруг митинга на Болотной площади в Москве:

ДОРЕНКО: А вы бы приехали на Болотную?

ЛУКАШЕНКО: Если это нужно было, конечно.

ДОРЕНКО: А то, что эта сакральная власть русских царей разрушается от общения с народом? Понимаете? В России есть концепция, что говорить с народом, реагировать на такие проявления — это разрушает сакральную власть русских царей, некую харизму трон Вы не печетесь о харизме трона?

ЛУКАШЕНКО: У меня другая политик Я окунаюсь в гущу. Я сразу же иду в гущу. Взорвали в метро — через час я был там, в метро. Меня там держали за руки, потому что была вероятность второго взрыв Я говорю «нет, даже если второй взрыв». Моя судьба в этой ситуации, человека, допустившего это, — моя судьба пойти. И что уже там будет… Но если есть Господь, наверное, только от него зависит. И я пошел. И не один.

ДОРЕНКО: И на Болотную пошли бы.

ЛУКАШЕНКО: Нет, я не говорю, что я бы пошел. Но если бы… правильно вы говорите: царь и власть должна действовать должно и не бегать по всем этим… она должна пойти только туда и тогда, когда это надо. Если на Болотной сложилась ситуация, что там должен быть глава государства, я бы не раздумывая пошел туд Но я не знаю, я не вовлечен, должен быть там кто-то… Не это главное, Сергей. Или ты прямо придешь и скажешь, или через ящик, Интернет или что — у тебя должно быть право. И у тебя должно быть то, что ты должен положить на стол людям и сказать. И они разведут руками. У вас есть такое право? Вы можете прийти открыто к людям, исходя из их требований?

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

ИМХО, в последнее время никто так сильно не дискредитирует Президента РБ как он сам своими собственными высказываниями.

четверг, 22 декабря 2011 г.

[life] Happy Birthday My Blog – 3!

Тихо и незаметно подкралась очередная годовщина моего активного блоггерства. Сейчас самому уже не верится, что прошло уже три года. Тем не менее, желание пографоманить еще осталось, темы находятся и очень надеюсь, что так будет и далее :)

Хочу выразить благодарность всем своим читателям. Отдельное спасибо тем, кто нашел время и желание зарегистрировался как постоянные читатели. Громадное спасибо всем комментаторам – я очень ценю то, что вы находите возможность поделиться со мной своим мнением.

За сим торжественную часть считаю законченной, пора вновь окунуться в работу :)

[blog] Вставка раскрашенных фрагментов кода в блог

В комментарии к предыдущей заметке ув.тов.Eugeniy спросил о том, как я вставляю раскрашенные фрагменты кода в блог. Решил ответить в виде отдельной заметки на случай, если кому-то еще это пригодится.

Для написания заметок я использую Windows Live Writer. Когда мне нужно вставить фрагмент кода, то использую редактор vim + следующий заготовленный фрагмент HTML:

<table width="100%" bgcolor="#000040"><tbody>
    <tr>
      <td><font color="#c0c0c0" face="monospace">
          </font>
      </td>
    </tr>
  </tbody></table>

Этот фрагмент я добавляю в HTML-код заметки. После чего набираю в vim-е фрагмент исходного кода и даю vim-у команду TOhtml:

Далее выделяю нужный мне кусок сгенерированного vim-ом HTML-я и вставляю его в заранее заготовленный HTML-ный фрагмент в тексте заметки. Получается что-то вроде:

<table width="100%" bgcolor="#000040"><tbody>
    <tr>
      <td><font color="#c0c0c0" face="monospace">
<font color="#ff80ff">#include&nbsp;</font><font color="#ffa0a0">&lt;iostream&gt;</font><br>
<br>
<font color="#60ff60">int</font>&nbsp;main() {<br>
&nbsp;&nbsp; std::cout &lt;&lt;&nbsp;<font color="#ffa0a0">&quot;Hello, colorfull World!&quot;</font>&nbsp;&lt;&lt; std::endl;<br>
}          </font>
      </td>
    </tr>
  </tbody></table>

И это все в результирующем виде будет выглядеть так:

#include <iostream>

int main() {
   std::cout << "Hello, colorfull World!" << std::endl;
}

Цветовая гамма, в которой vim генерирует HTML, соответствует обычной цветовой гамме, которую я vim-у задал для себя (т.е. именно такие цвета я использую в повседневной работе).

Теперь о том, почему я остановился именно на таком способе оформления фрагментов кода. Когда озадачился этой темой, то погуглил по Интернету. И нашел, что самые красиво выглядящие способы требуют изменения CSS-ов и подключения каких-то JavaScript-овых инструментов. Чего мне совсем не хотелось, т.к. лень было разбираться с правкой CSS в blogger-е, да и не хотелось, чтобы вместе с моими заметками к пользователю грузились еще какие-то JavaScript-ы. Мне показалось, что сделать раскрашенный фрагмент вручную намного проще и дешевле ;)

воскресенье, 18 декабря 2011 г.

[prog.memories] О том, как я от CamelCase к lower_case пришел

Когда я только начинал программировать – а это был 1990-й год – особых заморочек по поводу оформления кода не было. Да и смысла это не имело, поскольку сначала был какой-то Basic на БК1001, затем Turbo Pascal 3.0 на Robotron 1715. Насколько я помню, Basic сам все приводил к верхнему регистру. А на Robotron-е, кажется из-за шаманства с добавлением русских символов в кодовую таблицу, строчных латинских букв не было вообще. Поэтому первые программы писались только в UPPERCASE и других вариантов не было вообще.

Чуть позже с Robotron-ов пересел на IBM PC, на Turbo Pascal 5.0. И хоть Pascal не был чувствителен к регистру, программы хотелось оформлять красиво (т.е. так как в книжках и фирменных Borland-овских примерах), поэтому как-то само собой произошел переход к CamelCase. Деталей уже не помню, но вряд ли я писал If, Begin и End. Скорее if, begin и end. А вот функции и переменные точно писал в CamelCase. Даже одно время стандартные функции писал так WriteLn, ReadLn. Но не долго, намного проще было по старинке – writeln, readln.

Там же, на IBM PC к концу первого курса (а это была середина 1991) довелось познакомиться с языком C. После привычного, быстрого и безопасного Pascal язык C казался чем-то жутко сложным, да и изрядно тормознутым (в смысле скорости компиляции и линковки). Да и принятый в нем стиль lower_case вызывал двойственные чувства. Но C – это было намного круче Pascal (просто круче, без подробностей), поэтому изучал я его старательно.

В итоге, когда в самом начале второго курса я написал свою самую большую программу на Pascal (объемом в несколько тысяч строк), то я использовал уже lower_case. Т.е. в Pascal-евской программе все структуры, функции и переменные именовались строчными буквами, а разделителями в именах были подчеркивания. И таким стилем я пользовался затем около года, программируя уже на C, ассемблере x86 и потихоньку изучая C++.

Но где-то в 1992-м мне в руки попал двухтомник по программированию под Windows 3.0 за авторством А.В.Фролова и А.Г. Фролова. Оттуда я узнал по венгерскую нотацию :)

Венгерская нотация произвела на меня очень сильное впечатление. На тот момент она казалась очень логичной, удобной и полезной. Плюс к тому, практически все, что тогда касалось программирования под Windows, использовало именно венгерскую нотацию. Поэтому естественным образом я стал использовать венгерскую нотацию и делал это очень долго. Года где-то до 1998, если не позже.

Основными причинами, которые побудили меня отказаться от венгерки, были:

  • неудобство сопровождения кода. Со временем типы переменных менялись. Если раньше nPercentage была целочисленной, то со временем ее требовалось сделать вещественной и приходилось переименовывать ее в fPercentage. Соответственно, изменяя все места ее использования. Сейчас, при наличии IDE с мощными средствами рефакторинга в это сложно поверить, но тогда переименовать какую-то сущность в большом количестве исходников было не просто :)
  • маразм, до которого стали доходить в формировании префиксов. Когда венгерка ограничивалась префиксами i, n, f, l, p, pc, sz и еще парочкой таких же простых сочетаний, это было вполне удобно. Но когда приходилось писать что-то вроде ppcsz, pppi и пр., закрадывались сомнения в разумности происходящего :) Апогеем же стала как-то попавшая ко мне в руки книжка по Visual Basic-у, в которой перечислению “стандартных” префиксов была посвящена здоровенная таблица на десяток страниц.

Были и другие мелкие и не очень недостатки, но они свойственны не столько венгерской нотации, сколько стилю CamelCase вообще. А к стилю CamelCase я вернулся одновременно с переходом на венгерскую нотацию. И использовал его намного дольше, где-то до 2001 года.

Тут нужно чуть подробнее остановиться на особенностях CamelCase применительно к объектно-ориентированным языкам. В процедурных языках, вроде C или Pascal, все довольно просто. Но в том же C++ добавляются еще и классы, их атрибуты и методы. Как-то само собой получалось, что нужно уметь их выделять визуально среди остальных сущностей. Поэтому были разные варианты CamelCase, в которых существовали более-менее серьезные различия.

Нужно сказать, что упомянутая мной книга Фроловых о Windows 3.0 кроме приобщения к венгерской нотации, донесла до меня (и моих коллег) очень важную вещь – в отдельно взятом коллективе все должны использовать один и тот же стиль оформления кода. До этого я об этом даже не задумывался, а затем стал твердым приверженцем этой точки зрения, хотя и без фанатизма.

Так вот, для того, чтобы поддерживать единообразие кода в тех коллективах, где я работал в 1994-1996 годах, был выработан некий вариант стиля CamelCase, которым я пользовался до 2001 (и который, возможно, живет там до сих пор). Основными его чертами были:

  • префикс T для имен типов. Т.е. TFile, TByteStream и т.д.;
  • префикс m для имен атрибутов. Т.е. TFile::mHandle, TByteStream::mSize, TByteStream::mCapacity и т.д.;
  • именование методов со строчной буквы: TFile::open(), TByteStream::writeBlock() и т.д.;
  • именование свободных функций с прописной буквы: OpenFile, CreateByteStream и т.д.

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

А вот специальное выделение имен типов и имен атрибутов для меня имело и имеет практический смысл. Причина, нужно сказать, банальная – лень. Мне тупо лень выдумывать разные имена. Так, пусть у меня есть тип file и мне нужно в какой-то маленькой функции создать переменную этого типа. Если имена типов ничем не отличаются от других сущностей, то я уже не могу написать просто:

file file(…);

Поскольку компилятор даст по рукам. А вот так запросто:

TFile file(…);

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

TPoint(int x, int y) : x(x), y(y) {}

нужно придумывать какие-то новые имена для параметров конструктора. Причем чем проще ситуация (как в примере с TPoint) тем сложнее выдумать что-то отличное от x и y. А вот с префиксами для атрибутов нет никаких заморочек:

TPoint(int x, int y) : m_x(x), m_y(y) {}

С атрибутами есть еще одна штука. В теле метода очень хочется видеть где ты изменяешь атрибут, а где локальную переменную. И префиксы для атрибутов в этом так же помогают. Я знаю, что многие для этих целей используют конструкции вида this->x или this.x, но я ленивый. Мне проще набрать m_x, чем this->x ;) Кроме того, если придется запрограммировать какое-нибудь математическое выражение, то с именами m_x, m_y оно еще будет читаться, а вот с this->x и this->y уже вряд ли.

В общем, CamelCase я использовал до 2001. Но в тот год решительно и бесповоротно (надеюсь) перешел на lower_case. Причина банальна – работая с кодом в lower_case у меня глаза устают намного меньше, чем с CamelCase. Видимо, начал сказываться возраст и многие часы, проведенные за не самыми хорошими мониторами. Как бы то ни было, в один прекрасный момент я понял, что illegal_indirection пишется и читается намного удобнее, чем IllegalIndirection. Причем вне зависимости от шрифта.

Поскольку я стал пользоваться lower_case, то претерпели изменения четыре упомянутых выше принципа:

  • типы имеют суффикс _t вместо префикса T;
  • атрибуты имеют префикс m_ вместо m (поскольку если раньше mX читалось нормально, то сейчас mx уже совсем не то, в отличие от m_x);
  • имена методов и свободных функций записываются строчными буквами и не отличаются.

Нужно сказать, что поначалу я еще пытался делать разные правила для разных ситуаций. Например, пытался применять подчеркивание в конце имени свободной функции (т.е. create_file_ вместо create_file), но это оказалась нежизнеспособная идея. Так же использовал разные префиксы для разных сущностей: m_ для атрибутов, g_ для глобальных переменных, c_ для констант, e_ для перечислений. Но со временем выжили только m_ для атрибутов и g_ для глобальных переменных (да и то не всегда).

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

Главное при этом выдерживать единый стиль. Можно легко разобраться в коде, где человек именует классы, например, SMTP_session_t или SMPP_parser_t (вместо более привычного тебе smtp_session_t или smpp_parser_t). И придерживается этого стиля во всем своем коде. Но вот когда в начале заголовочного файла дается имя SMPP_paser_t, а следом за ним идет smpp_parser_state_t – вот это уже плохо. Т.к. заставляет искать разумную причину разных подходов к именам. Даже если ее нет :)

Напоследок еще несколько лирических отступлений. Самые удобные стандартные стили кодирования я видел в Eiffel и Ruby. Но, если говорить об Eiffel, то там язык не столь богат на возможности, как C++ – в нем есть только классы, методы и атрибуты. А вот в Ruby используется зашитая в синтаксис языка система префиксов для глобальных переменных, атрибутов классов и статических атрибутов классов (если пользоваться терминологией С++). Что мне представляется пока и разумным, и удобным. Понятное дело, что поскольку мне не нравится Java, то мне не нравится и ее стиль оформления кода. Ну а C# – это та же Java, но немного другая ;)

Если же говорить об отступах и фигурных скобках, то я перепробовал разные их сочетания:

if(...)
{
}

if(...) {

}

if(...)
  {
  }

Все они работают. Я могу свободно читать и писать код в любом из этих стилей. Но для меня самым удобным оказался последний вариант. Поскольку лично мне вот такой код разбирать много проще:

if(...)
  {
  }
else
  {
  }

чем вот такой:

if(...)
{
}
else
{
}

Но, полагаю, это дело личных предпочтений.

А вот чего я не люблю, так это экономии на пробелах и переносах строк. И никогда не мог понять, как люди умудряются писать и читать вот такой код:

if(0==Hf&&0==Mf)return 24;

если можно записать его вот так:

if( 0 == Hf && 0 == Mf )
   return 24;

В заключении пару ссылок на самого себя:

суббота, 17 декабря 2011 г.

[prog] Где прозвучала фраза avoid success at any cost?

Прочитав вот этот комментарий, в частности следующие предложения:

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

попытался вспомнить, где именно я видел высказывание “avoid success at any cost” по отношению к Хаскелю.

Если не ошибаюсь, вот в этой презентации Саймона Пейтона Джонеса – Wearing the hair shirt. A retrospective on Haskell.

[life] Хорошая иллюстрация способностей настоящего руководителя

Неожиданно для себя нашел ее в книжице Петра Подгородецкого “Машина” с евреями. Книжица, кстати, редкая мура, я даже дочитать ее не смог. Но вот две нижеследующие цитаты впечатлили. Обе относятся к рассказу о способностях Иосифа Давыдовича Кобзона.

Первая про организованность:

Иосиф Давыдович — фантастический организатор. У него феноменальная память, которой он умело и профессионально пользуется. Надо видеть, как утром он, еще лежа в постели, вызывает своего директора и дает ему задания на день, примерно с полчаса. Директор стоит с блокнотом и ручкой, а Кобзон диктует: «Итак, сегодня третье ноября. Необходимо от моего имени послать букет цветов (красные розы) такой-то такой-то в день сороковин ее супруга. Поздравить телефонным звонком (пусть меня соединят) такого-то с днем рождения. Забрать два концертных костюма из химчистки. Перенести массаж с 16 на 16.30. Позвонить от моего имени на „Мосфильм" и извиниться за то, что не приму участия в вечере в Доме кино. Соединить меня с Юрием Михайловичем Лужковым — я подтвержу свое участие в мероприятии, которое он организует. Послать такой-то два билета на концерт в „России" с моей визиткой и букетом цветов. Заказать обед в ресторане „Метрополь" на три лица». И далее в том же духе. Без пауз и перерывов, разве что сока глотнет, и все.

Лично я придерживаюсь мнения, что одно из главных требований к руководителю – это умение справляться с потоком разнообразных и разнокалиберных дел. Вспомогательные средства вроде ежедневников, TODO-списков, будильников и напоминалок – это всего лишь вспомогательные средства. Если ты сам не в состоянии запомнить, что тебе нужно сделать, то поможет разве что тотальное внесение всех предстоящих дел в электронный ежедневник, да еще с напоминалками на каждое дело в режиме snooze ;)

Тут, кстати, уместно вспомнить случай, который произошел со мной совсем недавно. Сидел у коллеги в кабинете и перед уходом сказал: “Хорошо, сейчас вернусь к себе и отошлю всем письмо.” Но пока шел к себе напрочь об этом забыл. Вспомнил случайно где-то через час, в течении которого с головой был погружен в какую-то техническую проблему, о которой задумался еще в коридоре, пока шел от коллеги в свою комнату.

И еще одна цитата о способности переключать контексты:

У великого мастера мозги работали одновременно как бы в двух режимах. Помню, как во время очередной поездки в Афганистан мы работали в армейском госпитале, где лечились самые тяжелые раненые. Представляете, сидят, лежат молодые пацаны, кто без рук, кто без ног, кто вообще как обрубок. У кого-то глаз нет… В общем, без слез смотреть в зал нельзя. Мы играем, а сами ревем. А Кобзон поет какую-то песню про маму, про Родину. У него течет огромная слезища. И тут, во время проигрыша, он совершенно спокойно оборачивается к кому-то из музыкантов и спрашивает: «А какой сейчас курс чека в Москве?» То есть с одной стороны — артистизм, неподдельные эмоции, а с другой — прагматичность, холодный расчет, так необходимый в бизнесе. Я не знаю, хорошо это или плохо, кто-то назовет это профессиональным цинизмом, какой бывает у опытных врачей. Но главное — чтобы этот цинизм никогда не перевешивал. Вот этому равновесию у Кобзона надо учиться. У него все всегда было под контролем, и зрители в зале никогда не чувствовали, что у певца в голове работает мощный компьютер, который может решать совершенно иные проблемы.

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

пятница, 16 декабря 2011 г.

[prog] Ввязался в спор о краткости имен идентификаторов

Вот в этот: Наименования переменных.

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

Когда я слышу разговоры о том, что идентификаторы (имена констант или переменных) должны быть короткими, я инстинктивно считаю, что люди предлагают вместо:

const size_t expected_bytes = calculate_expected_message_size();
const size_t bytes_read = load_data_from_stream( expected_bytes );
if( bytes_read != expected_bytes )
   ...;
binary_buffer_ptr_t whole_message = extract_raw_message();
binary_buffer_ptr_t message_payload =
   check_and_remove_protocol_headers( whole_message );

писать так:

const size_t e = calculate_expected_message_size();
const size_t r = load_data_from_stream( e );
if( r != e )
   ...;
binary_buffer_ptr_t m = extract_raw_message();
binary_buffer_ptr_t p = check_and_remove_protocol_headers( m );

Чего лично я не приемлю и за что “бью по рукам”. Ничего не поделать, учился у хороших учителей, давно, когда в образовании использовался Паскаль и книжки Вирта. А место, даже на дискетах, под исходные тексты экономить уже было не принято. Кстати, мониторы тогда были еще алфавитно-цифровые, с разрешением 80x25 знаков, так что текста на экране было намного меньше, чем сейчас. И IDE с автодополнением, подсказками и нафигацией по коду не было. Зато хороший стиль кода очень ценился.

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

Допустим, нам нужно сформировать SQL-ный select, где количество столбцов определяется внешними параметрами. Как это может выглядеть в императивном стиле с переменными? Как-то вот так:

std::string select_statement = "select id";
if( need_creation_time )
   select_statement += ", ctime";
if( need_modificaton_time )
   select_statement += ", mtime";
...
select_statement += " from my_table where ...";

Переменная одна, название ей дано длинное. А вот если мы напишем что-то подобное в функциональном стиле с иммутабельными сущностями, то получится что-то вроде:

s1 = "select id";
s2 = if( need_creation_time ) s1 + ", ctime" else s1;
s3 = if( need_modificaton_time ) s2 + ", mtime" else s2;
...
select_statement = sN + " from my_table where ...";

Т.е. если давать сущностям s1…sN какие-то вменяемые названия (вроде statement_with_opt_ctime, statement_with_opt_mtime и т.д.), то элементарно задолбешься выдумывать промежуточные названия. Да и смысла большого они нести не будут. Хотя, по моему мнению, обилие сущностей вида s1, s2 и т.д., не есть хорошо. Страшно далеко ФП от народа железа ;)

В общем, в программировании есть две неразрешимые проблемы – предсказание сроков и выбор названий для идентификаторов. Только временами кому-то начинает казаться, что они нашли серебряную пулю решение какой-то из них. Забывая четко обозначить тот сильно ограниченный контекст, в котором их частные решения работают.

PS. Почему я так резко прореагировал на эту тему? Потому, что на днях случайно была найдена серьезная ошибка. В одной из версий программы один разработчик заменил код:

stream << range.m_left
   << range.m_right
   << range.m_client
   << range.m_priority;

на код:

// Если диапазон оказался слишком большим, то нужно его сузить
// принудительно передвинув правую границу.
id_t right = range.m_right;
if( range.m_right > range.m_left + package_size )
   right = range.m_left + package_size;
stream << range.m_left
   << right
   << range.m_client
   << range.m_priority;

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

// Если диапазон оказался слишком большим, то нужно его сузить
// принудительно передвинув правую границу.
id_t right = range.m_right;
if( range.m_right > range.m_left + package_size )
   right = range.m_left + package_size;
stream << range.m_left
   << range.m_right
   << range.m_client
   << range.m_priority;

Понятное дело, что ошибка обнаружилась далеко не сразу и случайно. А уж если бы вместо range, right, m_left, m_right использовались бы имена вида R, L, R1, R2 и т.д., то я бы только функциональщикам и пожелал бы сопровождать такой код.

PPS. Еще ссылки:
- заметка в блоге lionet на какое-то исследование понятности написанного в разном стиле кода;
- очень интересная реакция на это исследование в блоге sleepy_drago;
- скептическая точка зрения Бертранда Мейера на околопрограммистские исследования (на английском).

вторник, 13 декабря 2011 г.

[life.sport.darts] Дартс и алкоголь (читая воспоминания Эрика Бристоу)

Когда я первый раз год назад приехал на соревнования по дартс в Минск, то ближе к вечеру с удивлением обнаружил, что от многих игроков начинает изрядно попахивать. Потом обнаружилось, что потребление алкоголя до, во время и, особенно, после турниров – это в порядке вещей. Некоторые игроки прямо с утра начинают разминаться пивком и продолжают делать это в течении всего дня.

Потому-то их так трудно обыграть ;) Поскольку в разумных количествах алкоголь в дартсе является допингом. Меньше волнуешься, меньше думаешь, бросаешь на инстинктах, поэтому-то и попадаешь туда, куда нужно. Я и сам в изрядном подпитии (правда уже после официального турнира) на Дартс-Весне 2011 в коммерческом парном турнире умудрился сделать два 180 в матче до двух побед – результат, который мне пока не удалось превзойти :)

Тем не менее лично я, как и еще (к счастью) многие спортсмены, в официальных соревнованиях играю трезвым. Так честнее, интереснее. И, главное, участвую я в турнирах для того, чтобы проверить собственный уровень. А с допингом это уже не проверка, а обман самого себя. Поэтому-то я не очень хорошо отношусь к пьянству во время соревнований. Особенно, когда это приобретает такие масштабы, как на Belarus Open 2011.

В этой связи интересно было узнать, что традиция пьянства в дартсе имеет давние корни. Очень красочно это описывает в своих воспоминаниях Эрик Бристоу – пятикратный чемпион мира, легенда дартса, под именем которого прошла целая эпоха в 1980-х годах. Всем интересующимся рекомендую пятую главу его автобиографии, опубликованную недавно на dartslife.ru. Занимательное чтиво.

суббота, 10 декабря 2011 г.

[life.photo] Подборка фотографий с фотоконкурса National Geographic 2011

Вот здесь – 54 снимка (трафика больше чем на 20Mb). Некоторые просто потрясающие.

FLIGHT OF AN EAGLE OWL: A large adult eagle owl in flight. Lingfield, Surrey, UK. (Photo and caption by Mark Bridger/Nature/National Geographic Photo Contest).

пятница, 9 декабря 2011 г.

[life.sport.darts] Проиграл финал в офисе

После двух победных финалов случился проигрыш. Выиграв одинадцать матчей подряд, двенадцатый, в финале, я проиграл Андрею Бузуверову -- 2-3 по сетам (3-1, 2-3, 1-3, 3-0, 1-3).

Матч получился очень напряженным. Длился он один час и сорок пять минут. Андрей выиграл заслуженно. У меня были шансы зацепиться за борьбу (один раз я дважды профукал возможность закрыть 13, попадая в 12, второй раз, уже в последнем леге я дважды упустил шанс закрыть 8 попав сначала в D18, затем в D13 (сектора сверху и снизу D4)), но я не смог их реализовать. Тогда как Андрею в нужный момент удавалось собраться и попасть в нужное удвоение.

Не смотря на проигрыш настроение хорошее. Все-таки третий финал подряд. Плюс хорошо прочувствовал, в чем именно состояли просчеты в моей подготовке этой осенью. В частности, чем вызвана моя плохая игра на 4-м этапе Кубка Беларуси 2011 года, и не очень удачная игра в этом финале. А это дорогого стоит. Более-менее понятно, в какую сторону двигаться.

Так что играйте в дартс -- это здорово!

четверг, 8 декабря 2011 г.

[work] Быть начальником? Самомасштабирование

Около года назад я начал серию заметок под общим подзаголовком “Быть начальником?” (вот начало, а вот на этом я остановился). Первые заметки из серии вышли “из под пера” довольно быстро, предпоследняя вынашивалась подольше. Но все равно оставалось чувство, что тема еще далеко не закрыта. Не удавалось нащупать нужную тему и нужные слова. Поэтому очередная заметка в цикле появилась только сейчас, когда в результате различных житейских и рабочих перипетий удалось осознать еще одно важное отличие простого разработчика от руководителя.

Различие это определяется масштабом дел, которыми хочет заниматься человек.

Например, что может хотеть сделать программист? Если верить старому афоризму, каждый настоящий программист должен написать собственный текстовый редактор, компилятор собственного языка программирования и собственную операционную систему :)

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

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

Т.е. если один разработчик пишет программы, то коллективы выпускают продукты. Чем серьезнее продукт, тем больше коллектив. Нуждающийся, что немаловажно, в руководстве. Чем больше коллектив, тем более нуждающийся.

А что нужно, чтобы достичь успеха в каком-либо начинании?

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

Так вот, способность вырасти из разработчика в начальника проявляется в том, насколько разработчик готов расти в серьезности взятых на себя задач. Хочет ли он перерасти уровень “свой текстовый редактор, свой компилятор…” и выйти на уровень “свой текстовый процессор, своя IDE…”? При том, что “свой” будет означать не “сделанный своими руками”, а “сделанное чужими руками, но под моим надзором”. Настолько перерасти, что в управляемом им продукте может вообще не быть его собственных технических идей.

Этому переходу я дал в заголовке название “самомасштабирование”. Хотя кто-то может обозвать то же самое “уровнем амбиций”. Но, в моем понимании, чтобы говорит об амбициях, они должны доминировать изначально. Т.е. человек начиная работать программистом уверен, что он поработает чуток, наберется опыта, затем станет менеджером проекта, затем еще поднаберется опыта и продвинется дальше и т.д.

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

Во втором сценарии у человека возникают вопросы, вроде “Интересно ли это мне?”, “Сможет ли это захватить меня с головой?”, “Справлюсь ли я с этой ответственность?” и т.д. Ответы на которые не так просты. Чтобы ответить “Да” нужно суметь отказаться от того, что тебя занимало ранее и найти себе новые интересы, новую специализацию.

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

И непонятно, нафик это вообще нужно.

[prog] Вышла версия 6.0.6 библиотеки ACE

Обновилась библиотека ACE – вышла версия 6.0.6, в которой, как сообщают разработчики ACE, полностью удалена поддержка autoconf, добавлена поддержка 64-битовой RHEL 6.1 и исправлено несколько ошибок.

Скачать новую версию ACE (а так же обновленные версии TAO, CIAO и DAnCE) можно отсюда: http://download.dre.vanderbilt.edu/previous_versions/

воскресенье, 4 декабря 2011 г.

[life] Расторопная, однако, организация – Православная Церковь

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

А вот храм уже есть (снимок сделан мобильным телефоном):

Оперативно, ничего не скажешь.

Слева на снимке виден еще один зеленый вагончик. По виду жилой. Рядом с ним играли двое детей. Такое впечатление, что там обитает настоятель храма с семьей. Не хоромы, конечно, но зато уже собственный приход ;)

суббота, 3 декабря 2011 г.

[life.photo] Несколько фотографий, которые меня зацепили

Зацепили в плане композиции и исполнения.

Все из разных выпусков WSJ’s Photos of the Day. Первая вот (взята отсюда, автор Navesh Chitrakar):

Прямо иллюстрация к главе о цветовых акцентах учебника по фотографии. Как и вторая (взята отсюда, автор Rod Sanford):

Ну и третья (взята отсюда, автор Damir Sagolj):

Удивительно: бОльшую часть снимка занимает дверь лимузина, да и у героя снимка видна лишь половина лица. Но снимок производит на меня сильное впечатление – подчеркивается мимолетность и отстраненность, показушность приветливости властьимущих. Интересно, фотограф выцеливал такой момент, или же это оказался единственный стоящий кадр из серии снимков отъезжающего кортежа?

[prog] Диагностика vs Скорость

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

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

Раньше было “ответ такой-то проигнорирован потому-то”, а стало “ответ такой-то проигнорирован”. И все. Такие дела.

PS. Усвоенная мной за последние десять лет мудрость: логов мало не бывает ;)

[life] 10 мифов об интровертах

Здесь. Интересно. Особенно понравилось вот это (курсив мой):

Миф 9. Интроверты не умеют расслабляться и получать удовольствие.
Интроверты обычно расслабляются дома или на лоне природы, а не в шумных общественных местах. Интроверты не охотятся за острыми ощущениями и не являются адреналиновыми наркоманами. Если вокруг них слишком много разговоров и шума, они просто “выключаются”. Их мозг очень чувствителен к нейротрансмиттеру допамину. У интровертов и экстравертов различаются ведущие нейронные пути. Просто учитывайте это.

Курсивом я выделил еще одну хорошо сформулированную причину того, почему я не хочу быть начальником. Просто “выключаюсь” :)

PS. Ссылка найдена здесь.

пятница, 2 декабря 2011 г.

[prog] Слоистость, мать ее!

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

Этот афоризм вспомнился в попытках понять, почему select из временной таблички с сотней записей и двумя столбцами занимает десятки миллисекунд. Хотя более тяжелые запросы из больших таблиц, как правило, отрабатывают в три-четыре раза быстрее.

Есть MS SQL Server (не важно, 2005 или 2008), есть ODBC, над ODBC еще есть OTL. И простой select длится 50 миллисекунд (при том, что insert-ы – всего 7 миллисекунд). Какой слой здесь выступает тормозом? На кого вешать собак?… Тайна сия велика есть.

Павбывавбы, короче.

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

четверг, 1 декабря 2011 г.

[life.photo] Ёлочка, лети!

Здорово фотограф (Pascal Lauener) скомпоновал все! Это рождественскую ёлку доставляют в Берн на вертолете.

Снимок найден в очередном выпуске WSJ’s Photos of the Day.

[life.science.wow] The Scale of the Universe

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

The Scale of the Universe.

Хотя, подозреваю, что это баян.

[life.wow] Фокус с картами и аквариумом

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

среда, 30 ноября 2011 г.

[life.cinema] Очередной кинообзор (2011/11)

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

Липучка. Малобюджетненько и, местами, туповато. Но забавно.

Бабло. Забавно.

Всегда говори "ДА". Смешной. Правда видно, что Джим Керри не очень вписывается в роль намного более молодого героя.

Профессионал (который Killer Elite). Очередной фильм с участием Джейсона Стэтхэма в очередной роли "круче меня только яйца". Впрочем сделано добротно, крепкий боевичок. Но в "основан на реальных событиях" не верится.

Ларри Краун. Совершенно нулевой фильм в плане сюжета и идеи. Но актерского мастерства у Тома Хэнкса с годами меньше не становится.

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

Опасный квартал. Посмотрел этот весьма качественно снятый фильм, с хорошими актерами, но не понял, о чем он. И зачем его вообще снимали.

Аполлон 18. Не могу сказать, что мне понравилось. Слишком часто пытаешься отогнать от себя мысль "а это какая камера снимала и откуда она там взялась?" Не говоря уже о том, как все эти записи попали на Землю :)

Драйв. Редкая нудятина. Чтобы получить настолько сильное несоответствие между названием и содержанием фильма пришлось, полагаю, немало потрудиться.

11-11-11. Дешевенькая галиматься. Дешевизна проявляется как в сюжете, так и в спецэффектов. В общем, смело можно не смотреть.


Пересмотрел три серии “Крестного отца”. Точнее, посмотрел сначала первую часть. Впечатление пострясающее. Я смотрел его давным-давно, кода мне было лет семнадцать. Тогда было понятно, что это фильм очень сильный. Теперь еще раз удостоверился в этом. Что любопытно, первой части уже почти 40 лет. Но приставка “ретро” не нему до сих пор не применима.

Жаль, что Коппола не ограничился только первой частью. Вторую уже можно было бы и не снимать. Хотя впечатления она и не портит. А вот от съемок третьей части вполне можно было бы отказаться. Впрочем, это мое личное мнение.

[life.photo] Завораживающе…

Справа на снимке – вулкан Tungurahua в Эквадоре, слева – какой-то городок около его подножия:

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

PS. Снимок найден в очередном выпуске WSJ’s Photos of the Day.

воскресенье, 27 ноября 2011 г.

[prog] Немного о двух недавно найденных багах, их причинах, способах выявления и вообще

Последние недели выдалась весьма напряженными. Как водится, в самый неподходящий момент появился баг, проживший незаметным полтора года в активно использующемся приложении. Точнее говоря, это был не баг, а своеобразная реализации выборки из БД новых данных для обработки. Построенная по принципу работы маляра Шлемиля – чем больше данных накапливается данных, тем больше времени занимает поиск необработанных частей. Самое удивительное в этом то, что сия неэффективность смогла прожить незамеченной столь долгое время. Ведь приложение неоднократно подвергалось специальному нагрузочному тестированию, а так же выдерживало нагрузку в реальной эксплуатации. Но только недавно звезды расположились так, что новые данные в БД были перемешаны со старыми именно таким образом, который и привел к резкому росту времени на их поиск.

Найти проблему помогли, в основном, два фактора:

  • во-первых, это своевременное привлечение разработчиков к выяснению причин странной работы ПО. У нас работает комплекс из программных компонентов, который в совокупности стал показывать меньшую, чем обычно, производительность. А причин этого видно не было. Коллеги из техподдержки попросили меня посмотреть на происходящее. Я же, зная принципы работы частей комплекса увидел, что операция, которая должна отрабатывать за доли секунды, почему-то занимает десятки секунд. Если бы не это, то проблема могла бы остаться незамеченной и дальше;
  • во-вторых, везение. Медленное выполнение одной операции на боевой БД – это хорошая диагностика, но явно недостаточная для выяснения причин. Нужно было как-то повторить такую ситуацию на тестовых стендах. И тут невероятное везение. Первый же запуск приложения на старом тестовом стенде выявил ту же самую проблему. Оказалось, что стенд использовался для проверки разных компонентов и нагрузку на него давали самую разнородную. В результате чего в тестовой БД так же образовалась нужная смесь из старых и новых данных, которая и приводила к увеличению времени на их обработку. Ну а дальше оставалось только спокойно разобраться в ситуации.

Что особенно хотелось бы подчеркнуть говоря об этой проблеме – самые серьезные ошибки в приложениях вызваны вовсе не особенностями языков программирования (чем Java/C#-программисты так любят пугать C++ников, а Haskell-исты вообще гнобят всех нефункциональщиков). А, например, просчетом разработчика при выборе алгоритма. В результате чего есть правильно написанный код, без багов, который делает все, что хотел программист. Только вот не то, что следовало бы делать.

Вторая ошибка вообще вспоминается как страшный сон. Пытаясь ускорить обработку данных в одном из приложений я вместо while(!stream.eof()) написал if(!stream.eof()). Т.е. вместо цикла по содержимому потока сообщений выполнялась обработка только первого сообщения в потоке. Приложение действительно ускорилось – ведь оно стало выполнять в сотни раз меньше действий.

Хохма в том, что модификации касались только обработки двух потоков с ответами от удаленной системы. Т.е. приложение продолжало нормально создавать нагрузку на удаленную систему, но обрабатывало только по одному ответу-подтверждению из сотни.

Причина сей ошибки банальна – модификация делалась в спешке и, поэтому, не была должным образом протестирована. Я прогнал только одиночные тесты. Затем выполнил тесты для пачек сообщений большего размера, но анализ результатов толком не провел. Тем не менее, излишняя самоуверенность и желание быстрее все закончить привели к тому, что обновленная версия ПО с ошибкой была поставлена в бой (хорошо хоть хватило здравого смысла установить ее лишь на одном из многих каналов обработки сообщений).

Обнаружить проблему удалось на следующий день. Благодаря хорошему стечению обстоятельств:

  • во-первых, я таки не поленился создать для новой версии отдельное тестовое окружение чтобы продолжить начатые накануне оптимизации. И именно на новом тестовом стенде стали проявляться странности, природу которых я сразу не понял;
  • во-вторых, приблизительно в это же время стали приходить жалобы из техподдержки о том, что в одном из приложений растут очереди не доставленных ответов. Что было странно, поскольку по логам было видно, что ответы до нужных получателей доходят.

Сложив всю симптоматику я понял, что дело в тех самых внесенных накануне изменениях. Версию, понятное дело, откатили, очереди стали уменьшаться. А я, как идиот, по 20 раз пересматривал куски кода с if-ами вместо while-ов и не мог понять, почему же программа работает не правильно.

Уроки, вынесенные из этого бага до неприличия банальные, но крайне актуальные, даже не смотря на весь мой опыт:

  • тестирование, тестирование и еще раз тестирование. Даже если ты уверен, что изменения незначительные и все работает – проверь еще раз. Особенно, если ты уверен;
  • писать нужно просто. Очень просто. Чуть ли не до дебилизма просто. Поскольку в условиях сильного напряжения, внешнего давления и жестокого цейтнота разобраться в простом коде (пусть даже объемном) еще можно. А вот в сложном, в котором каждая строчка содержит по несколько нетривиальных действий – уже навряд ли.

Ну и в завершение, чтобы не забыть, еще пару тезисов:

  • что-то я стал сомневаться, что посредством каких-то абстрактных слоев (вроде ORM-библиотек) можно создавать нагруженные приложения, способные работать с СУБД от разных производителей. Скажем, которые могут работать и с MS SQL, Oracle и PostgreSQL. Под конкретную СУБД и даже под конкретную инсталляцию БД нужно делать какую-то специфическую заточку напильником. Например, по результатам трассировки активности MS SQL пришлось добавить в один из SQL-запросов опцию MAXDOP. Можно ли делать такие низкоуровневые оптимизации текстов запросов в случае ORM – я не знаю;
  • online-мониторинг происходящего в приложении – это must have. Хорошо, что на заре своей карьеры мне довелось принять участие в разработке SCADA-пакета, где мне и была привита привычка к online-мониторингу. Вообще, чем больше работаю, тем более занимает меня идея о том, что для контроля над приложениями (режима 24x7 в частности) нужно применять те же самые подходы, которые уже давно используются в АСУТП. В частности, приспосабливать системы SCADA для мониторинга внутренностей приложения. Впрочем, это уже тема отдельного разговора.

суббота, 26 ноября 2011 г.

[prog] Разработчики Scala хвастаются ростом популярности своего языка

Свежая заметка на www.scala-lang.org: Scala - Popularity and Use Grow.

Мол и используется Scala в крутых конторах (Twitter, LinkedIn, Foursquare, the guardian, Morgan Stanley, Credit Swiss, UBS, HSBC), и количество посетителей сайта scala-lang.org выросло, и количество загрузок Scala увеличилось, и вакансии для Scala-разработчиков уже не редкость… Лепота, в общем.

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

Меня же интересует вот что: либо я совершенно не в теме, либо же Рунет со своими профессиональными форумами (RSDN, LOR, OpenNet) совершенно не отражает тенденции в буржуинии. Поскольку у меня сложилось впечатление, что чем дальше, тем меньше в Рунете говорят о Scala (а если говорят, то не очень хорошее). Куда больше мне доводится слышать про Erlang и Haskell, чуть реже про OCaml и различные Lisp-ы.

Так вот интересно – есть ли рост какой-нибудь востребованности Scala на просторах бывшего Союза? Или то, о чем рапортуют Scalaделы, касается только Запада?

[prog.thoughts] Что native, а что не native?

Оказалось, что на RSDN разгорелся нешуточный флейм в духе старых-добрых времен: Конец нересурсов. Что особенно приятно, в нем даже дали ссылку на заметку в моем блоге. В принципе, данный флейм был достоин упоминания только за это :) Но в нем было еще несколько интересных моментов.

В частности, довольно долго участники спора противопоставляли native-приложения managed-приложениям. Но когда дело дошло до выяснения того, чем же native отличается от не-native, ничего путного родиться не смогло (вероятно, тот ламер, который больше всех верещал о доминировании managed, слабо разбирается в этом вопросе, а его более матерые собеседники откровенно стебались и не спешили просвещать человека). Хотя вопрос, как мне думается, не так прост, как может показаться. Я и сам бы с ходу не смог сформулировать что есть native, а что managed.

Когда я в бытность активным RSDN-ером бодался с .NET-евангелистами все казалось просто: .NET и JVM – это managed, С/C++ – это native, Python/Perl/Ruby/PHP/Bash и пр. – это managed, Objective-C – это native и т.д. Вроде бы все интуитивно понятно. Но, как показал упомянутый RSDN-овский флейм, интуиция может быть у каждого своя. Поэтому нужно придумать что-то более-менее формальное.

Так вот, мне представляется, что native-приложение – это такое приложение, для запуска и работы которых достаточно только штатных возможностей ОС и которое работает на “голом железе” (т.е. инструкции приложения сразу же выполняются процессором, а не какой-либо виртуальной машиной). А вот для managed-приложения требуется некий промежуточный слой между кодом приложения и ОС. Таким слоем может быть либо интерпретатор (как в случае со скриптовыми языками вроде Python/Perl/Ruby), либо виртуальная машина (JVM), либо JIT-среда, которая компилирует инструкции VM в нативный код при первом обращении (как в .NET).

Вот такое вот простое разграничение. Никакие сборщики мусора, никакие средства трассировки и контроля за исполнением (вроде проверок выхода за рамки массива), никакие средства рефлексии и предоставления метаинформации о коде в расчет не принимаются. Просто потому, что есть примеры вполне себе native-приложений, у которых есть и GC, и контроль за кодом, и подробная диагностика мест возникновения исключений, и прочая лабуда. Например, у разработанных на Eiffel, OCaml, D или Go приложений.

При этом нужно говорить именно о приложениях. А не о коде. И уж тем более не о языках программирования. Просто потому, что один и тот же язык может иметь транслятор как в native-код, так и в код какой-либо виртуальной машины. Как у Eiffel или OCaml, например. И один и тот же код может работать как в native-, так и в managed-приложении. Хотя, если код затачивается под использование возможностей конкретной managed-платформы, то тогда имеет смысл называть код managed-кодом.

Но самое забавное, что даже такие, казалось бы, низкоуровневые языки, как C++ и C, имеет интерпретаторы! Пусть поддерживающие ограниченное подмножество языков, но тем не менее позволяющие запускать довольно-таки серьезные приложения. Первый из них – это CINT. Второй – Ch. Вот такие дела, и C++ приложения могут быть вполне себе managed. По крайней мере согласно моему определению ;)

среда, 23 ноября 2011 г.

[prog] Язык Ceylon от RedHat вышел в свет

Соответствующая новость и обсуждение на OpenNet.

Сегодня утром краем глаза глянул на сайт ceylon-lang.org. Полного впечатления о языке, конечно же, не получил. Но какие-то моменты в глаза бросились.

Из очень хороших вещей в языке встретились nullable-типы, а так же (долгожданный мной) аналог typedef из C/C++.

Так же заметно, что элементы из функциональных языков (вроде паттерн-матчинга) мигрируют в сторону мейнстрима. Но в более примитивной, а значит и более приспособленной к массовому применению ;), форме. В Ceylon это проявляется, например, в возможности указывать объединение типов. Что-то вроде:

//union type
void printName(String|Named name) {
    switch (name)
    case (is String) {
        println(name);
    }
    case (is Named) {
        println(name.first + " " + name.last);
    }
}

Здесь тип аргумента name – это или String, или Named. Чтобы работать с таким аргументом нужно использовать приведенный выше вариант оператора switch. Аналогичная штука может использоваться и для выстраивания объектных иерархий:

abstract class Node() of Leaf | Branch {}

Node node = ...;
switch (node)
case (is Leaf) { ... }
case (is Branch) { .... }

В целом же, читая Quick introduction и первые главы Tour of Ceylon складывается впечатление, что язык получился намного более простым и, вероятно, более приспособленным для “повседневных” задач мейнстрима, чем Scala. Несколько смущает количество дополнительных деклараций – shared, formal, actual, default и пр. для методов классов. Закрадывается подозрение, что авторы языка в чем-то перемудрили и напрасно отказываются от уже привычной терминологии (тех же public или override). Но, может быть, я ошибаюсь из-за незнания предмета.

Так что, на первый взгляд, у RedHat действительно получился язык, который более удобен, чем Java, и более прост, чем Scala. Но вот нужен ли он для JVM – отдельный большой вопрос. Впрочем, меня он пока не волнует, т.к. я все еще C++ программист ;)

вторник, 22 ноября 2011 г.

[life] И еще раз на тему публичных телефонных разговоров

Вчера вечером возвращался домой в средней наполненности автобусе. Недалеко от меня какой-то мужчина лет сорока, вероятно подвыпивший, по телефону выяснял отношения со своей знакомой. И делал это, что совершенно удивительно, хорошим литературным языком. Этакий образчик старого доброго эпистолярного жанра, но по телефону.

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

суббота, 19 ноября 2011 г.

[life.art] Видео о создании самой большой в мире 3D картинки на асфальте

Часть первая (самое начало):

Часть вторая (почти завершение работ):

Часть третья, с вручением заслуженных призов:

четверг, 17 ноября 2011 г.

[prog.flame] Интересно, когда размер дистрибутива Boost обгонит размер дистрибутива Qt?

В связи с выходом Boost 1.48.0 озадачился данным вопросом ;) Насколько я могу судить, с каждым новым релизом размер tar.bz2-архива увеличивается приблизительно на 2Mb. Для версии 1.48.0 это уже 48.2, а zip-овского архива – 94.8Mb. Тогда как размер qt-everywhere-commercial-src-4.7.4.zip – 236Mb. Пока у Qt ощутимое преимущество, но, возможно, всего лишь пока ;)

PS. Да, не любитель я Boost-а :) И чем больше он становится, тем больше не любителем становлюсь я :)))

понедельник, 14 ноября 2011 г.

[life.sport.darts] Съездил на 4-й этап Кубка РБ

Вчера, 13-го ноября, состоялся 4-й этап Кубка БД по дартс. На который я, вместе со своими коллегами – Андреем Бузуверовым и Андрюсом Микялёнисом, съездил чтобы в очередной раз проверить уровень своей игры.

Со спортивной точки зрения поездка оказалась катастрофой. В паре с Андреем Бузуверовым мы не вышли из группы, проиграв решающую игру за выход в плей-офф Игорю Роговому и Андрюсу Микялёнису. Зато Роговой-Микялёнис смогли добраться до полуфинала и, в результате, заняли 3-е место. В личном же турнире никто из нас не смог выбраться из группы и попасть в плей-офф. Результат удручающий и мне еще предстоит разобраться в его причинах.

Но, с другой стороны, я очень рад, что поехал. Удалось вновь окунуться в атмосферу серьезного соревнования. Почувствовать на себе что значит личная игра с намного более сильными соперниками. Узнать свой настоящий уровень. Оглядываясь назад прихожу к выводу, что было ошибкой пропустить 3-й этап в сентябре. Все-таки практика больших турниров – это большое дело, которое ничем не заменить.

Кроме того, мы классно позавтракали и еще лучше поужинали ;) Разве что участие в таком серьезном соревновании в воскресенье, когда на следующий на работу, да еще две ночи нужно провести в поезде – это непростое испытание.

четверг, 10 ноября 2011 г.

[life.art] Чуть-чуть подробностей о том, как создаются 3D-картинки на асфальте

Вот в этой небольшой заметке на английском: Incredible Making of the 3D LEGO Chalk Drawing. С картинками.

Рекомендую. Даже если не читать, а просто посмотреть на фотографии, все равно внушаить.

среда, 9 ноября 2011 г.

[prog.flame] Узнал про операционку B2G от Mozilla

Оказывается, Mozilla готовит операционку под названием B2G (Boot to Gecko). Которая, по сути, будет только браузером. И в которой будут крутиться написанные на HTML5/CSS/JavaScript приложения.

Вспомнилась Chromium OS от Google. Которая, если мне не изменяет склероз, давно уже должна была выйти в широкие массы, да что-то не вышла (или я просто проспал это знаменательное событие?). Еще подумалось, что либо я чего-то не понимаю, либо маразм таки крепчает. Как же иначе расценить превращение браузеров в полноценные ОС?…

Так же возникли вопросы:

  • как быстро Mozilla дойдет до рождения аналога Google-овского Native Client? И переиспользует ли NaCI если поймет, что такая штука в B2G все-таки нужна?
  • будет ли Mozilla поддерживать в своем B2G новый язык Dart от Google?
  • кто же завоюет место под Солнцем: B2G или Chromium OS? Если вообще кто-нибудь из них выживет ;)
  • если вдруг B2G выстрелит, то кто и какими патентами будет ее мочить? Впрочем, список патентов не важен, интереснее будут ли мочить и кто.

А вообще забавно. Сначала писали программы для голого железа. Но выяснилось, что лучше, когда над железом есть ОС. Потом стали писать программы под ОС. Но выяснилось, что лучше, когда над ОС есть еще и Windows (X-Windows). Потом стали писать программы под Windows (KDE, GNome, …). И что, выясняется, что лучше, когда над ОС есть еще и браузер? Если даже и так, то что будет вложено затем в браузер?

понедельник, 7 ноября 2011 г.

[life.sport.darts] 170! I did it again!

Максимально возможный checkout (т.е. списание очков в ноль) – это 170 очков (T20+T20+Bull). До сегодняшнего дня мне удавалось это сделать лишь однажды – чуть больше 10 месяцев назад. Но сегодня я смог это повторить:

Правда на тренировке, а не в матче. И в игре 170, а не 501. Ну да и в прошлый раз было так же :) Главное, что получилось. Очень долго подбирался к этому, но все время не везло на третьем броске, а тут все срослось.

Не могу удержаться, чтобы не сказать несколько слов о том, на каком фоне все это случилось. Фоном были последствия очередной смены дротиков.

Смена дротиков у меня сопровождается тремя обязательными фазами – первые 1-2 недели – это пора головокружительных успехов. Например, когда ко мне в руки попали Target T0.1, мне удалось за 15 минут сделать два 180 и закрыть 143. Когда начал играть Nodor-ами NR-502, то в первый же вечер два 180 + множество закрытий “по учебнику”. Самым ярким же проявлением этой фазы стала проба 26-граммовых MultiRing-ов – пять максимумов и один 150 (три дротика в Bull) на первой же тренировке. С моими текущими дротиками Марка Уолша все складывалось похожим образом, но проявлялось не в большом количестве 180 (как на других моделях), а в больших checkout-ах (138, 155, 156, 158) + одна очень удачная игра против программы n01.

Вторая фаза, которая очень резко, буквально за два-три дня, сменяет первую – это серьезнейшее падение результатов. Очень сильно эта фаза проявилась как раз с MultiRing-ами, когда после недели сумасшедшей игры (включая лег в 13 дротиков) я с большим трудом стал попадать в T20. Но все это оказалось цветочками по сравнению с тем падением, которое со мной случилось после двух недель игры Walsh-ами. Если в начале на тренировках в 501 я имел средний набор с одного дротика не менее 18.5 очков, то вдруг он снизился до каких-то 15, да и те жалкие 15 очков нужно было вырывать зубами.

Вторая фаза занимает порядка 2-х недель, к концу которых улучшение результатов начинает наблюдаться. Но в случае с Walsh-ами это затянулось еще на неделю. И более-менее нормальная игра появилась только сегодня.

После второй фазы следует третья, когда идет плавный, но устойчивый возврат к той форме, которая была до смены дротиков. Как долго она длится и что следует за ней – я толком не знаю ;) Слишком часто менял дротики в последние месяцы (где-то с марта 2011 я перепробовал семь разных комплектов). И дольше всего за это время я поиграл Bull’s-ами, Anderson-ами и как раз Walsh-ами.

И вот к какому выводу в результате этих экспериментов я пришел: да, вес и форма барреля (а так же сочетание барреля с длиной хвостика и формой оперения) очень важны – у каждого игрока свой хват, своя манера прицеливания, свой способ броска и пр. факторы которые в сумме дают специфическую траекторию полета дротика. Какие-то баррели этой траектории соответствуют лучше, какие-то хуже. На мой взгляд, это объективно и с этим нужно считаться.

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

PS. У меня без дела валяются несколько моделей дротиков, от которых я бы с удовольствием избавился – вот на этой страничке они помечены словом “ПРОДАЮ”. Вдруг кто-то все еще ищет себе “идеальный” вариант ;)

[prog.flame] Ceylon, Kotlin и теперь вот Xtend – кто-нибудь выживет?

Что-то языки под JVM начинают плодиться как грибы. К давно уже заявившей о себе (но не ставшей пока мейнстримом Scala) хотят присоединиться язык Ceylon от RedHat (подробностей о котором совсем не много), Kotlin от JetBrains (пока еще не достигшем стадии стабильного релиза) и совсем свежий Xtend от Eclipse.

Как по мне, так это яркое доказательство того, что как язык программирования Java уже многих основательно забабахал. Настолько, что даже вполне серьезные компании соглашаются субсидировать создание замены Java. Так что удобный повод еще раз самодовольно упомянуть, что не зря мне язык Java вообще никогда не нравился ;)

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

воскресенье, 6 ноября 2011 г.

[life.sport.darts] Первая победа Дейва Chizzy Чизнэлла в PDC!

Чуть менее года назад я написал заметку о том, как очень интересный игрок – Дэйв Чизнэлл (a.k.a. Chizzy) – перешел из BDO в PDC. И вот не прошло и года как состоялась первая победа Чизнэлла. На однодневном турнире в Crawley. До этого у Chizzy были четвертьфиналы, полуфиналы и финалы в однодневках. Плюс попадание в 1/4 на престижнейшем UK Open. А сейчас первая победа. Хочется верить, что не последняя. Ведь только в этом году еще три серьезных турнира – стартующий через неделю Grand Slam of Darts, затем Players Championship Finals и, наконец, PDC-шный Чемпионат Мира.

PS. На самом деле я болею за нескольких дартсистов – за Фила Тейлора, Саймона Витлока, Дейва Чизнэлла и Марка Уолша. Но Чизнэллу, наверное, приходится сложнее всего, ведь в PDC он новичок. Поэтому и слежу за ним пристальнее.

пятница, 4 ноября 2011 г.

[life.photo] Фотографии с конкурса Nikon Small World 2011

Подведены итоги конкурса Nikon Small World 2011. Официальные результаты можно увидеть на сайте проекта. А здесь подборка снимков-конкурсантов в заметно большем размере (для комфортного разглядывания некоторых нужны солидные мониторы). Под катом три снимка, которые понравились лично мне.

(Да, если кому интересно – аналогичная заметка об этом же конкурсе 2010 года)

четверг, 3 ноября 2011 г.

[prog] Говорят, что ViM-у уже 20! Ура! Happy Vimming!

Узнал о юбилее на OpenNet. Так что от души поздравляю Брама Мулленара, всех разработчиков, внесших свой вклад в ViM, а так же всех пользователей этого редактора (коим я являюсь уже семь лет)!

PS. Если кому-то интересно, то вот моя заметка 2-х летней давности о том, каким образом я дошел до ViM-а ;)

среда, 2 ноября 2011 г.

[prog.thoughts] Нашлось время вернуться к обсуждению взаимодействия компонентов программных комплексов

В обсуждении заметки “Нашел интересное в очередном потоке сознания Стива Йегга” я выказал намерение написать о том, почему я считаю хорошими принципы взаимодействия компонентов, озвученные в 2002 году основателем Amazon Джефом Безосом. Тема интересная, но только сейчас нашлось достаточно времени чтобы вернуться к ней.

Итак, вкратце упомянутые принципы в моем русском варианте звучат следующим образом:

1) Все команды начиная с данного момента должны предоставлять данные и функциональность своих компонентов посредством сервисов со специфицированными интерфейсами.

2) Компоненты должны взаимодействовать друг с другом посредством этих интерфейсов.

3) Не должно быть никаких других форм взаимодействия: ни непосредственной линковки, ни прямого чтения хранилищ данных другой команды, ни модели разделяемой памяти, ни каких “черных входов” или чего-то подобного. Единственная разрешенная форма коммуникации – вызовы интерфейсов через сеть.

4) Без разницы какая технология будет использоваться. HTTP, CORBA, Publisher-Subscriber, слабанная на коленке – все равно, это не важно.

5) Все без исключения интерфейсы должны с самого начала проектироваться с прицелом на взаимодействие с внешним миром. Т.е. команды должны планировать и проектировать свои интерфейсы так, чтобы их можно было предоставить разработчикам вне компании. Без исключений.

На мой взгляд, эти принципы могут применяться и для распределенных программных комплексов много меньшего масштаба, нежели платформа Amazon. И в этом случае я бы заменил пункт #5 – поставил бы на его место правило о том, что интерфейсы должны быть асинхронными, ориентированными на обмен сообщениями. И только в крайних случаях они могут быть синхронными, основанными на чем-то вроде удаленных вызовов.

Теперь, после освежения темы в памяти, можно перейти к перечислению достоинств такой модели.

Первое (важное с точки зрения эксплуатации): такой подход позволяет эксплуатировать каждый из компонентов независимо друг от друга. Это затрагивает множество аспектов. Например, масштабирование. Когда конкретный компонент перестает справляться с нагрузкой, можно заниматься его разгоном независимо от других – докупать новые сервера, увеличивать дисковые массивы, производить обновление железа и пр. – вплоть до переезда на совсем другие аппаратные и программные платформы. Скажем, работал компонент на одном сервере с Windows, а перебрался на Linux-овый кластер с балансировщиком нагрузки на входе. При том, что остальные компоненты могут не иметь возможности подобной миграции в принципе (например, привязаны к железякам, драйвера для которых есть только под одну платформу).

Второе (важное с точки зрения разработки): такой подход позволяет разрабатывать компоненты независимо друг от друга. Без оглядки на используемые технологии и их частные особенности. Здесь я противопоставляю взаимодействие с удаленным компонентом взаимодействию через непосредственную линковку кода компонента с вашим кодом. Допустим, в приложении нужно иметь возможность шифрования/подписи данных с использованием HSM. Код по взаимодействию с HSM можно просто прилинковать к своему коду. Но тогда возникают разнообразные проблемы интеграции – на каком языке написан сторонний компонент, совместим ли он с нашей версией компилятора? Какие фреймворки и их конкретные версии используются – совместимы ли они с тем, что используем мы? Какие особенности есть в работе с компонентом – нужно ли его явно инициализировать/деинициализировать, если нужно, то на контексте какой нити это нужно делать? Как компонент может влиять на работу нашего приложения – насколько он дружит с многопоточностью, может ли он непредсказуемо сильно загрузить процессор или вдруг отожрать много памяти? Обо всем этом не нужно думать, если компонент внешний, мы общаемся с ним только через сеть и работает он фиг знает где. Модуль работы с HSM-мом можно сделать на C++, а свой код мы без лишнего геморроя можем написать на Ruby.

Третье (важное как с точки зрения разработки, так и с точки зрения эксплуатации): такой подход позволяет очень гибко и разнообразно менять потоки данных между компонентами. Зачастую совершенно прозрачно для самих компонентов. Особенно в варианте, когда используется асинхронный обмен сообщениями. Простой пример. Допустим, есть компонент A версии 1.0. Мы хотим ввести в эксплуатацию его следующую версию 1.1, но очень плавно – направив сначала на новую версии только 5% от запросов, затем 10%, затем 50% и только убедившись в полной работоспособности, все 100%. Делается это посредством балансировщика, который устанавливается перед двумя версиями компонентов A. Сначала он пропускает 95% запросов на версию 1.0, а 5% – на версию 1.1. Затем пропорции меняются. Когда происходит полный переход на версию 1.1 этот промежуточный компонент может быть вообще устранен. При этом ни сами компоненты A, ни их клиенты даже не догадываются о том, что параллельно работают разные версии.

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

Вот как-то так. Наверняка есть и другие “за” (равно как и “против”), но три вышеозвученных момента сразу же приходят на ум.