четверг, 31 декабря 2009 г.

Не запускается служба PostgreSql. Что делать?

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

Итак, история начинается с того, что мне 30 декабря в 11-30 звонят с сообщением о том, что у одного из наших клиентов не запускается наша система, поскольку не может подключиться к базе данных (в качестве СУБД у нас используется PostgreSql версии 8.1). Люди объясняют это тем, что час назад вырубило свет и компьютер вырубился некорректно, а после включения – все перестало работать:)

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

После подключения к удаленному компьютеру я попытался запустить службу и получил следующее сообщение: “Служба PostgreSql Database Server 8.1” на “Локальный компьютер” была запущена и затем остановлена. Некоторые службы автоматически останавливаются, если им нечего делать, например, служба журналов и оповещений производительности”. Мда…

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

Отладка служб – процесс не простой, поэтому многие разработчики предусматривают механизмы запуска приложения-службы, как обыкновенного консольного приложения с помощью ключей командной строки. И PostgreSql в этом плане – не исключение; для запуска нужно использовать следующую команду (Hint: эту команду можно запустить только из под неадминистративного пользователя системы, правда, если вы об этом забудете, то PostgreSql очень быстро вам об этом напомнит):

postgres -D "<postgresql data directory>"

Запускаем, и смотрим на сообщение об ошибке. В моем случае это сообщение звучало примерно так:

FATAL - bogus data in lock file "postmaster.pid"

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

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

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

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

Три факта о книге Роберта Гласса «Факты и заблуждения профессионального программирования»

Facts_and_Fallacies

Факт №1. Автор хотел назвать эту книги “The F-book”

Обсуждение

Роберт Гласс изначально хотел, чтобы эта книга получила название “Fifty-Five Frequently Forgotten Fundamental Facts (and a Few Fallacies) about Software Engineering” (Пятьдесят пять часто забываемых фундаментальных фактов (и несколько заблуждений) из области разработки программного обеспечения), или коротко “The F-book”, однако издатели посчитали первое название слишком длинным, а во втором названии букву F – слишком грязной (F-word обозначает не только слово, начинающееся с буквы F, но и вообще слово, не рекомендуемое к употреблению в приличном обществе (спасибо редакторам за разъяснения)), поэтому сошлись на более коротком и презентабельном названии.

Полемика

Каждый автор мечтает о том, чтобы его книга выделялась среди множества книг других авторов. Некоторые наиболее популярные и известные книги получают неформальные названия (например, GoF-book или Dragon-book), которые дают им преданные читатели, и вполне понятно желание Роберта Гласса, чтобы его книга получила подобное особое название. Однако одного желания автора недостаточно, чтобы это произошло и несмотря на намеки автора о неформальном названии этой книги, она так и не получила свое неформальное имя (хотя кто знает, возможно еще не все потеряно).

Факт №2. Практически каждый профессиональный разработчик найдет что-то полезное в этой книге

Обсуждение

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

Полемика

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

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

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

Факт №3. Книга Роберта Гласса весьма интересна, но до шедевра явно не дотягивает

Обсуждение

Книга Роберта Гласса будет полезной многим разработчикам, но я не могу поставить ее в один ряд с книгами Демарко и Листера, Брукса и Йордона, Ханта и Томаса. Книга интересна и полезна, но не гениальна.

Полемика

Этот факт является весьма спорным и многие читатели этой книги могут со мной не согласиться. Гениальность произведения сложно описать словами и еще сложнее обосновать, почему одна книга относится к гениальной, а другая – нет. Нужно признать, что эта книга весьма популярна у читательской аудитории, но нужно признать и то, что ее не цитируют в каждой второй книге по разработке ПО. Книга производит впечатление добротной, хорошо проработанной, она достойно раскрывает практически все темы, которых касается, но все же ей чего-то не хватает. Роберт Гласс придерживается своего стиля, местами ироничного, местами серьезного. Но читая факты нет ощущения эйфории, как от чтения Демарко или Брукса. Разница владения языком становится особенно заметной в главах о менеджменте, в которых Роберт как раз опирается на «Человеческий фактор» и «Мифический человеко-месяц». Написано хорошо, интересно, но цитат, которые бы подошли на роль плакатов в комнату программистов, увы, практически нет. Если взять вопрос о сложности ПО, то ему в книге уделено 15 (!) фактов, но при этом полнота и качество изложения существенно уступает Бруксу и Бучу. Опять же, хорошо, добротно, но не гениально.

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

вторник, 8 декабря 2009 г.

О цитате “Преждевременная оптимизация – корень всех зол”

Многие специалисты компьютерной области знают (ну, или хотя бы слышали) следующее высказывание:

Преждевременная оптимизация - корень всех зол в программировании

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

Существует как минимум три разновидности этой фразы, которая встречается в различных трудах Дональда Кнута.

Первый вариант:
Преждевременная оптимизация - корень всех зол в программировании
Оригинал:
Premature optimization is the root of all evil
Источник:
1974 год, лекция, посвященная вручению премии Тьюринга, Computer Programming as an Art, Communications of the ACM, Volume 17, Issue 12, Dec. 1974 (see p.671)).
Полная версия оригинала:
The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.

Второй вариант:
Нам следует забывать о небольшой эффективности, например, в 97% случаев: преждевременная оптимизация - корень всех зол. Хотя мы не должны отказываться от своих возможностей в этих критических 3%
Оригинал:
We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3.
Источник:
1974 год, статья Structured Programming with go to Statements, ACM Computing Surveys, Vol 6, No. 4, Dec. 1974 (see p.268)  (эта статья является критикой статьи Эдсгера Дейкстры Go To Sta­te­ment Con­si­de­red Harm­ful).

Третий вариант:
Я также знал, но забыл афоризм Хоара о том, что преждевременная оптимизация — корень всех зол в программировании
Оригинал:
But I also knew, and forgot, Hoare’s dictum that premature optimization is the root of all evil in programming.
Источник:
1989 год, статья The Errors of Tex, Software—Practice & Experience, Volume 19, Issue 7 (July 1989), pp. 607–685, а также в книге Literate Programming (p. 276)

Все три варианта появились в трудах Дональда Кнута, но судя по третьей цитате складывается впечатление, что изначальным автором фразы был другой знаменитый ученый в области компьютерной науки Тони Хоар (C.A.R. Hoare), также лауреат премии Тьюринга, автор быстрой сортировки, Логики Хоара и много чего другого.

С момента выхода в свет The Errors of Tex, прошло уже два десятка лет, но до сих пор нигде не удается найти информацию, подтверждающую слова Кнута о том, что автором этой фразы является именно Хоар. Более того, сам Хоар в 2004 году в личной переписке с Hans Genwits написал о том, что он НЕ является автором этой цитаты (оригинал здесь):

Dear Hans,
I’m sorry I have no reco­llec­tion how this quo­ta­tion came about.? I might have attri­bu­ted it to Eds­ger Dijkstra.
I think it would be fair for you assume it is com­mon cul­ture or folklore.
Tony.

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

Ну и последнее, помните, Дональд Кнут говорил о 97%, а не о 100%;)

пятница, 4 декабря 2009 г.

Новый блог. Цитатник компьютерной литературы

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

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

Собственно сам блог: ru-quotes.blogspot.com

Буду рад любым комментариям, как по форме (оформлению блога), так и по содержимому.

четверг, 19 ноября 2009 г.

Злые баги. Или почему неприятности приходят в самый неподходящий момент

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

Начну по-порядку. В последнее время наша команда снова вернулась к проекту, который мы закончили несколько лет назад. Тогда реализация всей серверной части была сделана на С++, ядро системы оборачивалось в "управляемую" (managed) оболочку и использовалась в управляемом коде. Клиент-серверное взаимодействие реализовывалось на .Net Remoting, а два типа клиентских приложения были реализованы на .Net с использованием технологии Windows Forms. Все это было реализовано под .Net 1.1, и, естественно, новую версию мы захотели перевести на .Net 3.5, благо никаких особых проблем это не предвещало, но давало ряд преимуществ, главным из которых было повторное использование кода и архитектурных решений (за несколько лет у нас накопилось достаточное количество компонентов, реализованных под .Net 3.5), да и вообще, очень  сложно переходить с LINQ 2 Objects обратно на .Net 1.1, где нет даже Nullable-типов и типизированных коллекций.

Взаимодействие управляемого и неуправляемого кода попило немало крови в исходной версии проекта (под .Net Framework 1.1 есть свои особенности, связанные с необходимостью вручную вызывать функции __crt_dll_initialize() и __crt_dll_terminate()) и оставалось наиболее рисковой составляющей перехода на новую версию .Net Framework. Дело, к тому же, осложнялось тем, что мы приняли решение отказаться от использования старых драйверов взаимодействия с СУБД PostgreSql (libpqxx), в пользу использования оболочки, которая бы позволила использовать ADO.NET провайдера доступа к БД (в данном случае, Npgsql) из native-кода (механизм использования управляемых библиотек из неуправляемого кода изложены в моей статье "Взаимодействие управляемого и неуправляемого кода", RSDN Magazine, 3-2008). Сам перевод на новую технологию доступа к данным не занял особо много времени, благодаря четкому выделению слоя доступа к данным, но само взаимодействие управляемого и неуправляемого вызывало наибольшее количество беспокойство и, как оказалось, не зря.

Итак, работа над проектом двигалась вперед, мы показали людям сырую альфу, чтобы скорректировать направление нашего движения и пообещали предоставить бету через две недели. За пару дней до контрольного срока я заметил, что серверные части системы (которые реализованы в виде служб Windows NT, но имеют также и тестовые консольные версии), начали "падать" с какой-то ошибкой при завершении работы, причем "падать" стали не в момент завершения, а уже после него, выдавая такое замечательное сообщение: «Исключение unknown software exception (0xc0020001) в приложении по адресу 0x7c81eb33».

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

Судя по симптомам, ошибка происходила где-то при освобождении статических объектов. Первая мысль пала на синглтоны от Loki, в частности на использование стратегии управления временем жизни Phoenix (если кто не знаком с синглтонами из библиотеки Loki (автор Андрей Александреску), то идея заключается в использовании паттерна "стратегия" для задания таких параметров, как способ выделения памяти, управление временем жизни и управление параллелизмом). Стратегия управления временем жизни Phoenix как раз предназначена для решения известной проблемы С++, связанной с неопределенным порядком создания и уничтожения статических объектов в различных единицах трансляции; например, при обращении в деструкторе одного синглтона к другому синглтону поведение будет не определенным.

При поиске ошибок каждый разработчик придерживается ряда правил, основанных человеческом опыте и отлично озвученных Джоном Роббинсоном:

Шаг 1. Воспроизведите ошибку

Шаг 2. Опишите ошибку

Шаг 3. Всегда предполагайте, что ошибка ваша

Шаг 4. Разделяйте и властвуйте

Шаг 5. Думайте творчески

Шаг 6. Используйте инструменты

Шаг 7. Начните тяжелую отладку

Шаг 8. Убедитесь, что ошибка исправлена

Шаг 9. Извлеките урок и поделитесь им с другими

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

Код ошибки 0xc0020001 определен следующим образом: BOOTUP_EXCEPTION_COMPLUS и может возникать при попытке достучаться к CLR до ее инициализации или после ее деинициализации. Как известно, в проекте C++/CLI любой cpp-файл (если не оговорено обратное) компилируется с ключем /clr, что позволяет создавать «смешанные» (mixed-mode) сборки, в которых сосуществует управляемый и неуправляемый код. Теперь, если объект некоторого класса будет сохранен в статической переменной, то время жизни этого объекта будет определяться моментом выгрузки этого модуля, что будет соответствовать моменту непосредственно перед завершением приложения. При этом совершенно неизвестно, будет ли «жива» CLR или нет, т.к. порядок выгрузки различных модулей неопределен (именно поэтому, в течение какого-то времени эта ошибка у меня не проявлялась).

Кроме этого, жизнь может осложняться следующим моментом. Предположим у вас есть заголовочный файл, в котором реализована (не только объявлена, но и реализована) некоторая функциональность (например, класс Foo). Тогда, при включении из cpp-файла (который компилируется с ключом /clr) этого заголовочного файла, класс Foo будет скомпилирован в mixed-mode, что не позволит объектам этого класса располагаться в статической памяти (точнее, располагаться-то позволит, а вот с освобождением этой памяти могут быть проблемы).

У этой проблемы есть несколько путей решения, каждый со своими преимуществами и недостатками.

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

Второе решение легче показать на примере кода:

#pragma managed(push, off)

#include "Foo.h"

#pragma managed(pop)

Если заголовочный файл включается в cpp-файл, который, в свою очередь компилируется с ключом /clr, то класс (определенный в этом заголовочном файле) также будет также компилироваться в mixed-mode, что не позволит обращаться к его деструктору в момент завершения приложения. Обрамление заголовочного файла в #pragma managed приведет к компиляции класса, определенного в этом заголовочном файле в native-mode.

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

Самое интересное в этой истории то, что на самом деле это никакой не «злой баг», эта ситуация характеризуется как by design и описана в документе KB956195, смысл которого как раз и сводится к тому, что я описал выше.

Перечень ссылок по теме ошибки 0xc0020001:

1.     C++/CLI application throws 0xC0020001 on exit. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=365110

2.     Static variable in native method causes exception c0020001 during process exit. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=336844

3.     mixed-mode application (C++/CLI) throws unhandled exception '0xC0020001: The string binding is invalid.' on application exit. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=218663

4.     KB 956195. C++/CLI application crashes with 0xc0020001. http://support.microsoft.com/kb/956195

5.     An intereseting issue in mixed-mode application. http://blogs.msdn.com/ravi_kumar/archive/2007/12/30/an-intereseting-issue-in-mixed-mode-application.aspx

P.S. Интересно, что на «синглтоне Мейерса» проблема воспроизводится не всегда, а вот применение синглтона от Loki (со стратегией управления временем жизни не NoDestory), стабильно приводит к выдаче сообщения об ошибке 0xc0020001 в момент закрытия приложения.

P.S.S. Здесь расположен тестовый проект, который стабильно воспроизводит описанное поведение. Проверено на нескольких компьютерах с Windows XP SP2, VS2008 SP1 и на одном Windows 7, VS2008 SP1.

четверг, 12 ноября 2009 г.

“Балдеющие от адреналина и зомбированные шаблонами” на русском языке

Издательство Символ-Плюс (http://www.symbol.ru) работает над переводом новой книги Тома Демарко, Тима Листера (и еще четырех авторов) Adrenaline Junkies and Template Zombies, которая вышла в начале этого года (см. на amazon.com здесь).

Книга, действительно, замечательная, более подробно мое мнение можно узнать по одному из предыдущих моих постов (http://sergeyteplyakov.blogspot.com/2009/09/adrenaline-junkies-and-template-zombies.html).

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

Содержание

Отзывы на книгу “Балдеющие от адреналина и зомбированные шаблонами”

О Гильдии

Введение

1. Балдеющие от адреналина

2. На старт!

3. Дохлая рыба

4. Собрания для оваций

5. Проектный нянь

6. Отраженная боль

7. Manana

8. Зрительный контакт

9. Управление по кольцу настроения

10. Правоверный

11. Сдай душу в аренду

12. Лемминговый цикл разработки систем

13. Без скамейки запасных

14. Очное общение

15. Я дал тебе резец – почему ты не Микеланджело?

16. Приборные панели

17. Бесконечные препирательства

18. Юные щенки и старые псы

19. Кинокритики

20. С кого спрос?

Интерлюдия: проектный жаргон

21. «Советский» стиль

22. Естественный авторитет

23. Слишком тихий офис

24. Аут

25. Молчание – знак согласия

26. Соломенное чучело

27. Притворная срочность

28. Время играет против вас

29. Льюис и Кларк

30. Карандашный огрызок

31. Ритм

32. Гадание по сверхурочным

33. Вечер покера

34. Ложный промежуточный контроль качества

35. Тестирование до тестирования

36. Правила виноделов

37. Сказано – записано

38. Проектные потаскушки

39. Атлант

40. Одежду носят не просто так

41. Командные смотрины

42. Трубка и акваланг

43. Эти чертовы интерфейсы

44. Пограничная зона

45. Улучшение новостей

46. Медленная правда

47. Практика эндшпиля

48. Музыканты

49. Журналисты

50. Свободное кресло .

51. Мой кузен Винни

52. Суп из функций

53. Качиство данных

54. Бен

55. Мисс Манеры

56. Нераздельное внимание

57. «Плаксы не играют в бейсбол!»

58. Хладнокровный Люк

59. Регулярная сдача в срок

60. Пища++

61. Сиротливые артефакты

62. Скрытая красота

63. Я не знаю

64. Дети из Лейк Вобегон

65. Взаимное обучение

66. Seelenverwandtschaft

67. Крестовая отвертка

68. Предсказание инноваций

69. Мэрилин Мюнстер

Интерлюдия: на полу монтажной

70. Ветераны броуновского движения

71. Четко и ясно

72. Предохранительный клапан

73. Вавилонская башня

74. Сюрприз!

75. Дверца холодильника

76. Солнце взойдет завтра

77. Завал

78. Время перемен

79. Бумажная фабрика

80. Офшорное безрассудство

81. Командный пункт

82. Чем пахнет?

83. Неразобранные полеты

84. Святость сырых идей

85. Утечка

86. Зомбированные шаблонами

Авторы иллюстраций

понедельник, 19 октября 2009 г.

Бесконечные споры

Существует тонкая грань между свободой подчиненных и балаганом. С одной стороны руководитель должен давать своим подчиненным достаточно свободы, чтобы они могли раскрыть свой потенциал, участвовать в принятии управленческих решений и, таким образом, перенимать опыт руководителя, с другой стороны, подобная свобода действий может привести к хаосу, когда каждый имеет свою точку зрения и ресурсы каждого сотрудника направлены не на движение вперед, а на убеждения всего коллектива в правильности своей точки зрения.
Потрясающий совет в решении подобной проблемы дают авторы книги Adrenaline Junkies and Template Zombies в шаблоне поведения под названием "Endless Huddle" (Бесконечные совещания).
Основную мысль этого шаблона авторы позаимствовали из документа "Warfighing, United States Marine Corps":

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

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

понедельник, 12 октября 2009 г.

[Visual C++ 2008] Duplicate cpp filename

Я все еще занимаюсь переводом старого С++ проекта с VS2003 на VS2008 и в процессе перевода столкнулся с одной интересной проблемой.

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

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

Для проверки достаточно создать простое консольное приложение добавить Foo.h и Foo.cpp в корень и в подпапку, указать различные пространства имен и попробовать в Main.cpp создать объекты обоих классов.

Интересно то, что подобного поведения не было в предыдущих версиях компилятора и подобные проекты успешно компилировались как на VS2005, так и на VS2008. Там эта проблема решалась путем добавления в имя объектного файла чисел 2, 3 и т.д.

Еще более интересным является то, что эта проблема не будет решена до выхода очередной версии Visual C++. Вот один из ответов команды VC++ Team, найденный на MSConnect:

“Unfortunately we will not be able to fix this issue during this release. Please feel free to reactivate the bug if this is a blocking scenario.

Having duplicate file names in the same project is not a supported scenario. As a workaround as you recognize please change the name of the files that are being included in the same project.”

Подробности можно найти здесь и здесь.

Существует по крайней мере два обходных пути (возможны и другие, о которых я не знаю):

1. Избавиться от неуникальных файлов путем переименования.

2. Явно задавая имя объектного файла в свойствах конкретного файла.

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

Update (2009-10-14)

Существует по крайней мере один более изящный способ решения этой проблемы: можно для группы файлов, чьи имена совпадают с другими cpp-файлами в свойствах изменить поле Object File Name с $(IntDir)\ на $(IntDir)\Your Sub Dir\, в результате чего, объектные файлы для этих cpp-файлов будут складываться в указанную подпапку.

вторник, 6 октября 2009 г.

[Visual Studio] Find & Replace

В данный момент я работаю над переводом одного старого проекта, написанного под .Net Framework 1.1 на .Net Framework 3.5. При этом одной из задач является переход с синтаксиса Managed C++, на синтаксис C++/CLI.

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

Итак, задача: переделать свойства с синтаксиса Managed C++ в синтаксис C++/CLI.

Синтаксис свойства на Managed C++:
__property int get_EventType() { return eventType_; }

Синтаксис свойства на С++/CLI:

property int EventType { int get() { return eventType_; } }

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

Шаблон для поиска:

__property:b+{.#}:b*\*@:bget_{:w}\(\):b*(\n*:b*)\{\n*:b*{.*;}:b*\n*:b*\}

Шаблон для замены:

property \1 \2 { \1 get() { \3 } }

Синтаксис регулярных выражений в Visual Studio несколько отличается от общепринятого, но это не слишком важно, т.к. идея остается той же и в msdn прекрасно описаны особенности.

Теперь, запустив в Visual Studio механизм Find & Replace мы будем заменять свойства вида:

__property int get_EventType() { return eventType_;  }

Или

__property int get_EventType()

{

    return eventType;

}

На свойства вида:

property int EventType { int get() { return eventType; } }

Как правильно писал Джон Роббинс, разработчики очень часто плохо отзываются о своих пользователях, поскольку те не читают документацию и слабо используют функционал их приложений, но сами разработчики в этом плане не так уж и далеки от своих пользователей, когда речь касается об использовании функционала среды разработки.  Visual Studio содержит множество функций и инструментов, способных существенно упростить жизнь каждому разработчику, но мало кто из них (из нас) считает нужным изучать подобные возможности. Функция Find & Replace не является исключением. Представленный шаблон для преобразования синтаксиса свойств не претендует  на полноту, он подходит под тот формат записи, который применяется у меня, но возможно потребует некоторых изменений для вас. Но я и не хотел сделать инструмент, подходящий на все случаи жизни, а, скорее, продемонстрировать возможности инструмента, который всегда рядом и вполне может помочь для решения повседневных задач кодирования.

вторник, 15 сентября 2009 г.

Книга “Adrenaline Junkies and Template Zombies: Understanding Patterns of Project Behavior” by Tom Demarco, Piter Hruschka, Tim Lister et al.

Adrenaline_Junkies_and_Template_Zombies Труды Кристофера Александера вот уже в течение сорока лет оказывают серьезное влияние на светлые умы деятелей программной индустрии. И хотя первое упоминание книг Александера в компьютерной литературе, датируется 1969 годом в книге Эда Йордона и Алистера Коберна, идеи Александера оставались в тени, и не стали достоянием широкой компьютерной общественности, вплоть до середины девяностых годов, до выхода знаменитой книги «Банды четырех». Именно выход этой книги ознаменовал начало новой эпохи в нашей индустрии, эпохи всевозможных шаблонов. Идея шаблонов настолько понравилась общественности, что она стала завоевывать все новые и новые области. Так появились шаблоны реализации (implementation patterns), шаблоны асинхронного программирования, шаблоны корпоративных приложений, шаблоны реализации распределенных приложений и многие другие. Несмотря на свое широкое распространение, шаблоны оставались прерогативой архитектора и разработчика, а не менеджера. Но за последние несколько лет эта картина начала изменяться. Вслед за книгой  Джеймса Коплиена  и Нила Харрисона вышла книга Тома ДеМарко, Тима Листера и др. с интригующим названием “Adrenaline Junkies and Template Zombies: Understanding Patterns of Project Behavior”, посвященная шаблонам поведения программных проектов.

Книга состоит из 86 шаблонов, каждый из которых занимает 2-3 страницы и описывает определенную ситуацию, так или иначе связанную с состоянием или поведением программного проекта. Первым шаблоном в книге является шаблон “Адреналиновые наркоманы” (Adrenaline Junkies), который описывает такое состояние проекта, при котором считается, что «безумная активность является знаком здоровой продуктивности». Сотрудникам проекта приходится постоянно переключаться с одной задачи на другую, так и не доводя ни одну из них до логического завершения. Последним шаблоном в книге является шаблон “Зомби шаблонов” (Template Zombies), когда «проектная команда позволяет, чтобы работа управлялась шаблонами, вместо того, чтобы продумать процесс, необходимый для завершения проекта». Этот шаблон характеризует противоположную ситуацию, в которой форма становится гораздо важнее содержания. Между этими двумя шаблонами располагаются оставшиеся 84 шаблона, так или иначе описывающих поведение или состояние проекта. И хотя эти два шаблона не являются чем-то уникальным, они являются частью названия книги и именно они изображены на обложке книги в виде комичных человечков.

«Большая часть участников проекта довольно хорошо разбираются в распознавании образов и обладают внутренним чутьем (“я чувствую, что с этим проектом случится беда”), но не так хорошо разбираются в обобщении этих шаблонов в более удобную форму. Эта книга именно об этом. Мы, шестеро авторов, собрали весь свой опыт для изложения шаблонов, которые мы изучили в течение общих ста пятидесяти лет опыта».

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

P.S. MUST HAVE

UPD: Спасибо Василию Подобеду за коррективы в русскоязычном написании имени Алистера Коберна (Alistair Cockburn).

Книга Гради Буча и др. "Объектно-ориентированный анализ и проектирование с примерами приложений"

Booch_OOA_And_OOD_2007 «Звезда в преддверии коллапса; ребенок, который учится читать; клетки крови, атакующие вирус, - это только некоторые из потрясающе сложных объектов физического мира. Компьютерные программы тоже бывают сложными, однако их сложность совершенно другого рода. … Эйнштейн утверждал, что должны существовать простые объяснения природных процессов, так как Бог не действует из каприза или по произволу. У программиста нет такого утешения: сложность, с которой он должен справиться, лежит в самой природе системы».

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

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

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

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

Авторы подчеркивают важность архитектурной целостности, итеративного и поступательного жизненного цикла разработки. Интересной особенностью изложения является то, что авторы не считают рациональный унифицированный процесс разработки единственно верным во всех случаях, а ускоренные методы (agile process) неверными в корне. «Выбирая между ускоренным и планомерным проектированием, следует оценивать риск. С какими рисками сталкивается проект? Выберите стиль и соответствующие методы, минимизирующие эти риски…. Выбор процесса проектирования не означает, что работа сделана. Этот процесс следует уточнять на протяжении всего жизненного цикла проекта. Инструменты, работающие хорошо, следует оставить, а инструменты, работающие плохо, - исключить. Целью должен быть непрерывный процесс усовершенствования, основанный на практическом опыте».

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

Так сможет ли эта книга сделать из вас превосходного архитектора? Честно говоря, не знаю… Ведь процесс познания, точно также, как и процесс разработки программного обеспечения, является итеративным и поступательным. Одно только наличие этой книги на полке не является гарантией успеха ваших проектов. Прочитав эту книгу, вы не сможете в первом своем проекте с легкостью анализировать противоречивые требования пользователя, вам не откроются тайны объектно-ориентированной декомпозиции и ваши абстракции будут далеки от идеала. Ведь книга – это всего лишь направление, это не автострада, по которой вы сможете пронестись на бешеной скорости, это всего лишь еле заметная дорожка через тернистый путь, имя которому – объектно-ориентированный анализ и проектирование.