23 сент. 2008 г.

Программисты-олимпиадники

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

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

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

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

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

А в реальной жизни ограничения почти всегда не играют определяющей роли. Если сказано, что программа должна использовать не более гигабайта памяти для вычислений, то ничего страшного, если на каких-то входных данных понадобится 1200 мегабайт. И если заказчик ограничивает время работы 15 секундами, то, скорее всего, можно работать 17 (а то и 20). Потому что заказчику необходим модуль, возвращающий результат нужного качества в рамках ограничений, которые он придумал из головы. Другими словами, качество результата очень важно, а частичное выполнение ограничений - это вопрос, почти не создающий проблем при сдаче проекта.

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

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

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

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

15 комментариев:

  1. Всё бы хорошо, да только пассаж про граничные эффекты неверен и вреден.

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

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

    ОтветитьУдалить
  2. 1. Вообще-то в идеале постановкой задачи и пытками заказчика должны заниматься отдельные люди. Умеющие именно общаться с заказчиком и понимающие, как из него вытянуть, что же ему надо.

    2. Насчет граничных эффектов - не забывайте: "пользователи это осьминоги... восемь кривых шаловливых рук, которые растут из жопы". А программист, напротив, имеет привычку проверять только свой use-case. Поэтому нужна проверка другим человеком - и с крайними случаями.

    ОтветитьУдалить
  3. Bkonst, согласен с Вашим уточнением. Действительно, я слишком широко сформулировал о проверке граничных эффектов. Речь была о нацеленности на проверку именно "корявых" случаев. Например, если в олимпиадной задаче сказано, что некоторое N может быть от 1 до 10000000000, то олимпиадник проверит эти края. Но в реальной жизни число 10000000000 часто берётся из головы. И речь именно об этом: нет резона бороться за достижение фантазий, а надо обеспечивать истинную потребность клиента (поняв её предварительно). Я согласен, что пример какой-то вырожденный. Надо будет подумать над понятной иллюстрацией этой мысли...

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

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

    Как минимум, надо убедиться, что программа не "упадёт" и не унесёт с собой данные клиента; как максимум - сделать так, чтобы программа сама могла решить эту проблему.

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

    ОтветитьУдалить
  5. Bkonst, я с Вами полностью согласен!
    Моя мысль состоит в том, что чрезмерная нацеленность на граничные эффекты - это не жизненный подход. На олимпиадах это работает, а в промышленных задачах - нет.

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

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

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

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

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

    Ограничения - где-то критичны, где-то нет.

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

    > Это значит, что главное в реализации - понятность и модифицируемость.
    Вот это правда.

    > Но у олимпиадника другие привычки: для него понятность программы стоит на последнем месте (ведь её век очень короток - никто кроме него самого не будет читать этот код).
    Называется неумение работать в команде. Да, это часто встречается.

    Где-то я уже что-то подобное читал... Ах да
    http://victorronin.com/2008/05/19/olimpiadnoe/
    По-моему, гораздо больше похоже на правду.

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

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

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

    ОтветитьУдалить
  8. Mark, спасибо за ссылку на Ронина - он выразил суть коротко и точно.

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

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

    Безусловно, есть организации, где такого "бардака" не наблюдается. Но он очень много где есть. И это там считается нормой ("спецификой тематики").

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

    ОтветитьУдалить
  9. Случайно заглянул и хочу добавить пару слов, будучи довольно успешным олимпиадником и одновременно (в последний год) 'промышленным' программистом.

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

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

    ОтветитьУдалить
  10. Nikita, спасибо за полезный комментарий!

    ОтветитьУдалить
  11. Анонимный31.08.2009, 2:49

    Не так давно с удовольствием решил (не полностью, но покатит!) такую задачу.

    Пишем мультиплеер Microsoft Train Simulator. Есть железнодорожная схема. И есть редактор - корявый, как непонятно что (нет даже выделения нескольких вершин, т.к. тяжело программируется и обломище). Выясняется, что мы где-то забыли какой-то светофорчик, и надо расширить схему. Как это сделать?

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

    ОтветитьУдалить
  13. Ну ну. Вы говорите о школьниках?
    Если да, то там нет таких крутых задач, которые не сможет решить простой программист. Все задачи однотипные, так или иначе. Нет творчества.

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

    ОтветитьУдалить
  15. Анонимный06.11.2013, 10:43

    миЛисекунды... ))

    ОтветитьУдалить

Понравилась заметка? Подпишитесь на RSS-feed или email-рассылку.

Хотите поделиться ссылкой с другими? Добавьте в закладки:



Есть вопросы или предложения? Пишите письма на адрес mytribune АТ yandex.ru.

С уважением,
      Илья Весенний