четверг, 7 июля 2011 г.

Мосты и самолёты

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

Мне не очень понравился аргумент. Строительство крупных сооружений на разведанной местности была одной из первых инженерных задач и решать её научились тысячи лет назад. Конструкции со сложностью в тысячи, редко десятки тысяч элементов (возможно моя оценка для мостов и неправильна, но количество ноликов явно до 6 не доходит) это самая заря технологии, как для инженерного дела "в железе" так и для разработки программ. С задачами современного программирования соизмеримы скорее проблемы проектирования автомобилей и самолётов. Давайте будем честными и прибавим к тем 600 000 мостов все модели транспортных средств хотя-бы. Не получается того-же объёма опыта, что у машиностроения, никак не получается.

В конце статьи есть предложение, просто заставляющее ощутить гордость за профессию и осознать разницу между программой и мостом: "Software development is about operating on a living breathing thing and all the while keeping it alive.". Но ведь вокруг помимо мостов огромное количество искусственных конструкций поражающей сложности и живучести. Вы когда нибудь смотрели в иллюминатор при посадке самолёта? Автор кажется нет :) Иначе бы он видел изгибающееся под скачущими нагрузками крыло и десятки аэродинамических элементов судорожно пытающихся отодвинуть момент сваливания ещё на десяток км/ч... Эта конструкция считается мёртвой? Или она случайно не попала в область рассмотрения?

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

среда, 1 июня 2011 г.

Одна переписка

Дейсвующие лица:
P. Молодой, но амбициозный и самоуверенный программист.
HR. Умудрённый опытом а также высшими психологическим и неоконченным менеджерским образованиями специалист по управлению персоналом.

HR: "P, вечер добрый. Вы рассматриваете предлоежния на 3000 по разработке лидом на документум в другие компании? Очень спасибо, HR"

P: "Основной класс задач будет синтез текстов, я так понимаю?"

HR: "сейчас уточню у директора..минуточку"

HR: "•Разработка приложений •Разработка технической документации •Коммуникация с Заказчиком по техническим вопросам вот таку штуку прислали"

P: "Ага, то есть для вашего бота уже и заказчик есть? Что-то мне кажется надо будет много дорабатывать. Думаю это на 4000."

HR: "P, мне вчера позвонил Упячкасофт=) и попросил узнать есть ли ребята , которые работаю в этом направлении. Я просто сейчас ище специалистов в одноклассники - ну заодно вот вам решила написать."

HR: "а что такое БОТА?"

P: "Специальная программа, ктороая симулирует мыслительную деятельность. Проблема ведь в этом, я верно понял?"

HR: "Да нет, просто проект расширили и нужны сильны парни готовые сталть лидами через некоторое время. По деньгам надо торговаться как и везде."

P: "Ясно... Ну в общем передайте директору, что я готов написать бота лучше за 5000."

P: "Да, и спросите 5000 чего заодно."

HR: "хорошо, я перешлю ваш профайл - не возражаете?"

HR: "я в данном вопросе не сильна, но 4000 и 5000 - сейча на рынке таких зп не всем дают=)"

P: "Да да, главное передайте мои слова точно."

P: "Я тоже поделсь вашим предложением со знакомыми, не возражаете?"

HR: "да, но вот 4000 и 5000 - я сомневаюсь что они осилят."

четверг, 5 мая 2011 г.

"Version control with Git"

Эх, что-то своих мыслей давно не приходило. Ладно буду компенсировать пересказом чужих.

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

Автор книги, Jon Loelinger, контрибьютор проекта Git и старательно фокусируется на его внутреннем устройстве и логике, лежащей за тем или иным поведением. Книга весьма радикально отличается по глубине изложения от свободно доступной Pro Git и от полупиратски попавшей ко мне "Getting good with Git" (она правда на полноту и не претендует).

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

Этот подход используется повсеместно практически во всей книге и результат по-моему просто отличный. Те места, которые выглядели сложными и запутанными после других источников делаются абсолютно прозрачными и очевидными. Весь этот ад с удалёнными репозитариями, fetch vs pull, tracking branches и т.д. становится более менее понятен или по крайней мере поддаётся освоению с точечными вычитками документации.

Вообще после книжки осталось стойкое ощущение, что использование Git подразумевает изучение его самого, а не того как с ним работать. Причём подразумевает на уровне самых ранних дизайнерских решений. Кстати, интересно есть-ли инструменты (наборы скриптов?..) превращающие его во что-то вроде Subversion c локально доступной историей но при этом соответственно сниженным порогом вхождения?

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

P.S. С удивлением заметил, что в книжке слово developer заменяется местоимением she. Это что получается: разраб в английском по умолчанию - девочка?

воскресенье, 27 марта 2011 г.

"Java concurrency in practice"

Собственно прочитал, наконец сабж. Книга без сомнения отличная и информации о ней в Сети достаточно, добавить особо нечего. Запишу просто пару субъективных впечатлений.

Книга написана просто и понятно. Материал изложен абсолютно последовательно без ссылок вперёд и с минимальным расстоянием в обратных ссылках. Автор старательно избегает обращения ко всяким примитивам синхронизации, вместо этого старается ввести набор паттернов и идиом безопасной синхронизации. Только в последней главе можно увидеть подробное изложение JMM и несколько трюков напрямую с ней связанных.

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

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

P.S. А еще ко мне приехала новая пачка книжек, в том числе DSLs in Action и Version Control with Git, также на подлёте Programming in Scala. В первую очередь навалился на Git. Очень много новой информации относительно устройства репозитария и принципов работы разных комманд. По подробности изложения несравнимо с "Getting good with Git" и "Pro Git".

    пятница, 11 марта 2011 г.

    Об учебных примерах

    Подготовка к продолжению семинара по Java для OSLL/АУ заставила снова глубоко озадачиться построением учебных примеров на тему программирования (кстати, для кого рассказываю и какой уровень ожидается я так и не понял, с одной стороны там рассказывают какой то реальный rocket science мужики зашкаливающей суровости, с другой стороны позвали тупо меня рассказать про тупо фичи Java). Тут ещё наложился затяжной флейм в одной занимательной рассылке. В этой связи я решил выписать важные для меня критерии качества для учебного примера на тему программирования. Для себя точку отсчёта зафиксировать, да может ещё кому интересно будет.

    1. Доступность. Пример должен быть доступен для понимания с минимумом затрат. Требования к теоретическим познаниям должны быть собраны в явные prequisities. Когда в середине, а то и в примечаниях в конце говорят "Так, а вот тут вам нужно (было) прочитать [1], [2], [3] и вот тот учебник." - материал идёт лесом.

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

    3. Простота. В примере должно так мало сущностей, как это возможно. Очень плохо, когда появляются примеры вроде: "Мы реализуем подсистему логирования с помощью аспектно-ориентированного программирования, но ещё нам потребуется IoC контейнер для включения аспектов".

    4. Изолированность. Пример должен задействовать минимальное количество (в идеале одну) фичей языка и/или техник программирования. Если речь идёт о каком-то последовательном изложении (например введении в ЯП) совершенно недопустимы ссылки вперёд. Граница с пунктом 2 не очень чёткая. Я их разделяю так: простота связана с требованиями к окружению (например "мы внутри IoC контейнера" или "у нас есть парсер JSON"), изолированность связана с инструментарием, привлекаемым непосредственно к решению задачи (например "мы используем обобщённые типы" или "мы используем механизм макросов").

    5. Реалистичность. читатель не должен проводить бессонные ночи ищя ответ на вопрос "зачем?". Знание, не подкреплённое практикой или хорошей идеей как эту практику можно устроить, быстро теряется и затирается чем нибудь более актуальным. Чисто эмпирически мне кажется, что пример должен попадать в одну из следующих категорий:
    а) Часть большего и жизненного примера (например "мы пишем графический редактор и нам нужна унифицированная обработка фигур" - "нас спасёт паттерн композит").
    б) Какое-то решение общей проблемы программирования ("нам нужно абстрагировать вычисление расстояния между точками от представления их в памяти") с которой гарантированно сталкивался каждый.
    в) Общеупотребимый алгоритмом или структура данных (например "решение комбинаторной задачи" или "представление графа в памяти").

    6. Масштабируемость. В идеале пример должен быть доведён до конца в несколько итераций, с целью показать несколько доступных уровней глубины. От простого (задача едва-едва решена) и узкого решения к более сложному (максимальному проходящему по критериям 2 и 3) и полному. Соответственно и при практическом применении рассматриваемого инструмента остаётся возможность подвигать ползунок.

    7. Содержательность. Что-то вроде возможности ответить на вопрос "зачем?" на самом высоком уровне. Пробовал сформулировать по разному, но кажется как не крути получается критерий-солянка:
    а) Не велик. Плохо когда что-то делается, а в конце говорится "на самом деле взрослые дяди это уже решили в стандартной библиотеке и лучше пользоваться их решением". Оставляет смешанное чувство собственной убогости ("действительно годное решение мне не понять?") и низкого качества материала ("то есть то же самое можно сделать лучше?"). Но это всё-равно лучше, чем когда такого примечания нет :)
    б) Связь с каким-то юзкейсом верхнего уровня (очевидно что 6. а) избавляет от этой проблемы в принципе).
    в) ..?

    Надо заметить, что это касается технических материалов для практиков. Научные статьи и обзоры по понятным причинам в эту шкалу не вписываются. А те люди которые легко переживают отсутствие таких примеров без сомнения должны бросать неблагодарное инженерное дело и релоцироваться в класс учёных. С другой стороны я недавно видел пример того, что в умелых руках даже казалось бы безнадёжно сложные и теоретизированные вопросы находят прекрасную иллюстративную основу, для сравнения: куча введений в продолжения от скалохаскелистов [1], [2], [3] и одно от питонщика.

    среда, 16 февраля 2011 г.

    "Структура и интерпретация компьютерных программ"

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

    Процесс и правда изрядно затянулся. Я начал её читать ещё в сентябре позапрошлого (2009) года. И вот только пара недель как закончил. Причина очень проста: книга явно требует подходящего настроения и регулярно читать не получалось хронически. Процесс и сам по себе получился не обычным. Я начал её читать с экрана, в виде английской pdf'ки. Однако, когда я был где-то на середине вышел очередной тираж русского издания и я без раздумий добыл себе бумажный экземпляр на русском.

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

    Ещё важный момент, все примеры в книге выполнены на LISPе (а точнее Scheme). Годика три назад, я наверно по этой причине сделал бы из книжки костер и сплясал бы вокруг него. Однако изучение Smalltalk и Python (а точнее отзывов их авторов о влиянии LISP) в последствии немного сгладили мое отношение к скобочкам. Нельзя не признать, что для первых глав, где демонстрируется куча разных подходов к программированию, он является пожалуй оптимальным выбором. Однако длинные куски кода на LISPе всё-таки страшно выглядят, понимание многих примеров из последних глав отнимало много времени, в основном на вычленение стандартных конструкций из мета-кодировки в скобках.

    Итак, о чём же собственно книга.

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

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

    Третья глава, "Модульность, объекты и состояние", вводит в стройный мир асбтрактных вычислений, выстроенный в первых главах, проблемы реального мира: присваивание и время. Примерно половина главы посвящена тому как эти явления аккуратно моделировать в языке программирования, и примерно половина конкретным техникам программирования. В этой главе особо порадовал раздел про потоки, который был прочитан с учётом возвратов из следующей главы и перелистываний на досуге раза три. Совершенно замечательный пример простого решения массы сложных проблем, настоятельно рекомендую для прочтения, даже если за всю книгу лень браться.

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

    Ну и на пятую главу, "Вычисления на регистровых машинах", я забил :)

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

    Вообще книга заставила много раз подряд проклясть родной универ. Всё-таки способность отечественных преподавателей сделать из даже самых интересных и полезных знаний невнятную, серую, трудноперевариваемую массу просто поражает. Вспомнился и курс функционального программирования, двухмесячный, с быстрым рассмотрением синтаксиса и стандартных функций, какого-то древнего ДОСовского ЛИСПА, увенчанный курсовиком, в котором нужно было сделать базу данных то ли студентов на кафедре, то ли телевизоров на складе. Курс, на котором понятие неизменяемой структуры данных даже не звучало, не говоря уже про то, чтобы объяснить выученному на паскале потоку как с ними работать. И курс объектно-ориентированного программирования, без единого упоминания о передаче сообщений.

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

    воскресенье, 13 февраля 2011 г.

    Из рассылки одного Open source проекта

    Q: ... What is the purpose of this group, given the existence of stackoverflow.com? Is there some advantage I am perhaps missing? ...

    A: I believe here we ask serious philosophical questions and get serious philosophical answers. At least we are trying to.

    P.S. Нашел тут случайно в черновиках. Скопипастил недели две назад, да забыл опубликовать... Но кажется эта цитата из нестареющих.