вторник, января 23, 2007

Опыт работы: зачем нужен С++?

Недавно составляли вакансию. Необходимо нанять человека, основным занятием которого будет написание пользовательского интерфейса при помощи C# и WPF. В черновике вакансии я написал, помимо всего прочего - опыт работы на C++ - от 2-х лет. При обсуждении требований сразу же возник вопрос: а причём тут собственно опыт работы на C++? Мы ведь проект пишем на C#! И С++ в нем в ближайшее время скорее всего не понадобится. Так зачем же в вакансии требовать опыт работы на C++, отсекая тем самым многих специалистов?

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

Дело в том, что опыт работы на C++ - это некоторый показатель опыта и уровня человека. Сразу оговорюсь - не таланта, способностей к программированию или "крутизны", а именно уровня.

C++ - трудный язык. Я бы даже сказал очень трудный. Мало кто из знакомых мне очень профессиональных программистов рискует сказать что он знает C++ идеально. Причём даже среди тех, кто действительно знает его очень и очень хорошо. Я сам тоже не рискую этого сказать. Это не так. C++ позволяет программисту сделать практически все, но за это требует от программиста внимательности, тщательности и довольно большого объёма работ.

Кроме того, C++ - это "чистый" язык, язык в котором нет "заточенности" на ту или иную библиотеку или стиль программирования. Много ли людей пишет на C#, не используя Framework Class Library? Много ли людей пишет на Java не пользуясь библиотеками от Sun? .NET Framework + C# и Java - это платформы, а не языки.

С++, в отличии от многих, не привязан ни к чему. Это дает программисту на С++ поразительное, я бы даже сказал, иногда угнетающее, количество возможностей и вариантов запрограммировать даже самое простое действие. Как прочитать строчку из файла на C#? 99% ответов, как мне кажется будет выглядеть примерно так:

Textreader tr = new StreamReader("file.txt");
Console.WriteLine(tr.ReadLine());
tr.Close();

А как сделать это в C++? Есть тысяча разных способов - функции Win32, семейства _open, семейства _fopen, функции MFC, ATL, boost, стандартной библиотеки, собственные "единственно верные" функции. 99% ответов будет наверное такими - надо посмотреть что используется в той программе которую мы пишем и постараться использовать то же самое.

С++, кроме того, поддерживает мультипарадигменное программирование, то есть возможность пользоваться при написании программ многими стилями программирования.

Все это приводит к тому, что программисту на С++ приходится много работать. Больше наверное, чем программисту на любом другом из широко распространённых нынче языков. Иногда это работа является рутинной, технической - С++ не освободит за нас выделенную память. Но при выполнении этой работы, программист понимает как должны быть устроены механизмы автоматического освобождения памяти. Программист проникает во внутренности, причём невольно - ему просто приходится, иначе программа не работает как положено. Программисту приходится разбираться во внутренностях работы функций операционной системы, других библиотек. Ему приходится понимать то как устроен экспорт функций в DLL И тысячу других вещей, которые программисту например на C# понимать не нужно. Но ведь бьют то все эти вещи по обоим! Пока что операционные системы написаны большей часть на C/C++.

Поэтому такие программисты и ценны. С++ заставил их понять что-то, что иначе нужно было бы изучать по книгам, или в свободное от работы время. С++ заставил их "погрузиться" вовнутрь.

Disclaimer:
  1. Я понимаю что ассемблер в этом смысле ещё лучше чем С++. А машинные коды ещё лучше чем ассемблер. На самом деле строчку про опыт программирования на ассемблере я бы тоже вписал, только вот боюсь что это отсечёт слишком много кандидатов. А чувство меры терять тоже не следует.
  2. Конечно, все вышесказанное не значит что кто на С++ не писал, тот "жизни не нюхал". И конечно есть огромное количество программистов, вполне квалифицированны и способных, но не имеющих опыта работы на C++. Просто помните - мы писали вакансию. Мы звали к себе незнакомого человека, и всего лишь пытались оценить его и уменьшить количество времени, проведённого на собеседованиях.
  3. И наконец, я не считаю С++ лучше или хуже какого-либо из упомянутых или не упомянутых языков программирования. Я считаю, что С++ это ... как бы сказать, ну скажем как механическая коробка передач на автомобиле. Кто на механике ездил, тот сможет ездить на автомате очень легко. А вот обратное - верно не всегда. При этом, заметьте, на чем ездить лучше - вопрос не рассматривается.
Ну и напоследок. После того как я объяснил свою позицию, другой участник обсуждения текста вакансии сказал: "Да, мне тоже не очень нравится это предложение - опыт работы на С++ от 2-х лет ... не маловато ли?".

воскресенье, января 21, 2007

Оценка сроков

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

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

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

Всегда, в процессе разработки, выясняется что исходное разбиение на задачи и подзадачи было не совсем верным. Что не приняли во внимание то-то и то-то. Что есть другой способ, который позволяет эту и эту подзадачи не делать, но требует сделать некую новую подзадачу и так далее. Все зависит от количества этих изменений. Если их слишком много, то проект в конце будет совершенно не похож на то, чем он являлся в начале. Обратная связь пропадает и не с чем оказывается сравнить первоначальные сроки. А значит говорить об рациональном, происходящем с "открытыми глазами" улучшении качества оценки собственной работы говорить не приходится. Если программист давал оценку, что для выполнения задач A, B и С ему потребуется месяц, то что ему дает знание о том что для выполнения задач D, E и F ему потребовалось полтора? Насколько точно были оценены A, B и С? это остается неизвестным. А значит, обратная связь становится "слабым" игроком, не очень помогающим в оценке будущих проектов.

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

Стадии разработки программ

В процессе прочтения замечательной книги Microsoft Secrets: How the World's Most Powerful Software Company Creates Technology, Shapes Markets and Manages People обнаружил описание процесса разработки в Microsoft. Спешу поделиться, но заранее предупреждаю, что книга вышла в 1995 году, так что описание имеет скорее исторический и "общекультурный" интерес.

Итак, сам процесс разбит на три основные фазы: Планирование, Разработка и Стабилизация.

  1. Планирование
    В результате выполнения фазы планирования должны образоваться следующие материалы:
    • vision statement
    • спецификация
      • описание функциональных возможностей продукта (product features)
      • приоритет каждой из функциональных возможностей
    • прототипы различных частей продукта, пользовательских интерфейсов
    • план проекта, включающий в себя календарный план
  2. Разработка
    • состоит из нескольких milestones
    • "Замораживание" пользовательского интерфейса
    • Завершение добавления всех функциональных возможностей
    • Окончание кодирования
  3. Стабилизация
    • Тестирование
    • Исправление найденных ошибок
    • Проведение оценки проекта (post-mortem)

Согласитесь, ничего такого особенно нового в таких этапах нет. Все примерно таким образом и делают. Тем не менее, хочу отметить несколько моментов, которые отличают именно Microsoft:

  • Чрезвычайно активное использование "буферного" времени, причём исключительно для неопределённых вещей. Часто бывает так, что буферное время используется в качестве дополнительного времени для проведения инспекций кода, unit-тестирования, планирования и тому подобного. В Microsoft же для всей этой активности выделяется отдельное специальное время. А буферное время - это именно буферное время.

  • Для продуктов разрабатываемых в Operating Systems Division, его начальник, Brad Silverberg, требовал не менее 50% буферного времени. (то есть если оценка времени на задание была 1 месяц, то Silverberg требовал 2 месяца)

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

    Например, между окончанием работ над Excel 4.0 и началом работ над Excel 5.0 на это было потрачено 2 месяца.

  • "Поддержкой" предыдущих версий (починкой ошибок в них) занимаются те же самые
    разработчики, что и разрабатывающие новую версию

  • Принцип "бездефектных" milestones - идея состоит в том, что по достижении milestone - продукт не содержит дефектов и (относительно того, что было запланировано для данного milestone) является готовым чуть ли не к выпуску

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