Тег «философия»

О людях, мозгах и нежелании первых пользоваться вторым

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

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

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

  1. Пройти следом за пассажиром с билетом, прижавшись к нему якобы в порыве человеколюбия. Особенно этой уязвимости подвержены турникеты с двумя парами дверок: они не закрываются, пока не сработает сенсор «человек прошел». Ограничения на продолжительность открытия турникета, похоже, нет. Наверное, разработчики посчитали, что люди бывают разные, с большими животами и сумками. Или вдруг человек посреди турникета остановится и захочет постоять. Возникает же иногда такое желание — постоять в турникете. Правда ведь?
    В результате, зафиксированный мной рекорд — четыре человека прошли по одному билету гуськом.
  2. Перепрыгнуть. Тут все ясно, хотя в случае четырехдверчатых экземпляров не каждому это под силу. Видел всего несколько раз.

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

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

Потратили, стало быть, кучу денег, а толку? Не беда — денег еще много! И у турникетов появились крепкие ребята в камуфляже. Народ насторожился. Не каждый теперь рискнет проскочить зайцем — шанс получить по почкам от правоохранителей перевешивал стоимость билета. Но хитрость скоро раскрылась. Крепкие ребята в камуфляже оказались просто крепкими ребятами в камуфляже. При попытке безбилетно преодолеть турникет они лишь устало бубнят: «По одному проходим, по одному». Все вернулось на круги своя. Средства потрачены, безработица среди крепких парней, тетенек и конструкторов турникетов стремительно упала, народ продолжает экономить. Все довольны.

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

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

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

УжасноПлохоНормальноХорошоОтлично (4 голосов, средний: 3,75 из 5)
Loading ... Loading ...

TDD и модульные тесты: нужны ли они?

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

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

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

Началось все с подкаста номер 38 на StackOverflow, в котором Джоэль и Джефф Этвуд диалогируют на разнообразные IT-темы. В частности, они затрагивают вопрос юнит-тестов и методологии TDD; это вызвало такую бурную дискуссию, что Джоэль аж написал целый пост, приведя там стенограмму оного фрагмента подкаста. Вкратце, ключевые мысли примерно такие:

  1. TDD — бесполезная штука, потому что 100% покрытие кода тестами очень тяжело достичь, да и не нужно.
  2. Модульные тесты не нужны, потому что на них тратится слишком много времени. Кроме того, если что-то нужно будет менять в коде, возможно придется изменить кучу тестов.
  3. Писать тесты для унаследованного кода тяжело и ненужно (и поэтому модульные тесты вообще не нужны).

Я, конечно, несколько преувеличил. Но не одному мне это показалось ересью. Разгромный отзыв написал Uncle Bob (автор agile-подхода и принципов SOLID, по которым Джоэль тоже проехался), пожурив авторов с этакой отцовской грустью («Джоэль, ты неправ») и усомнившись в целесообразности использования разрабатываемых ими продуктов. Маленькую обиженную заметку «Джоэль неправ насчет моей работы» опубликовал Кент Бек (соавтор TDD и XP). Ну и понеслось. Нашлись как противники TDD и вообще тестов, так и сторонники (в том числе индийские). bishop3000 высказался против использования TDD и тестов для legacy code (справедливо, см. ниже).  Появилось даже интереснейшее обсуждение на Hacker News.

Любопытно, что большинство противников тестирования приводит аргументы из разряда «мне Петрович напел, не понравилось» или вообще делают чисто умозрительные заключения. Никто из них не смог сказать «Вот мы в нашем проекте фанатично поддерживали полное покрытие кода тестами, но так умаялись, что решили отказаться от тестов вообще. После этого мы выпустили продукт на месяц раньше срока, и теперь тратим половину рабочего дня на чтение благодарственных писем от пользователей». То есть, натурально, против TDD и тестов выступают люди, которые ни того, ни другого не пробовали — максимум прочитали пару статей, на основе которых и сформировали свое мнение. Джоэль, выходит, тоже пусть лучше пишет блог, чем код. Но Этвуд? Может, они его там в StackOverflow на наркотиках держат?

Мое мнение — и TDD, и навыками написания модульных тестов должен в полной мере овладеть каждый уважающий себя программист. Существуют случаи, когда ни то, ни другое применять нет смысла (например, при создании прототипов). Кроме того, 100% покрытия тестами (распространенное заблуждение насчет TDD, что «все должно быть покрыто тестами») — штука действительно сродни мифической, и мало где практикуемая. Хотя бы потому, что это никому не нужно. Зачем, в самом деле, тестировать геттеры/сеттеры? Или настолько тривиальный код, что вы готовы головой за него поручиться?

Модульный тест — это проверка публичного интерфейса. Это фундаментальный принцип, из непонимания которого проистекает множество бед. Например, некоторые думают, что если наш класс использует стороннюю библиотеку, то нужно сначала написать для этой библиотеки тесты. Неверно! Тесты писать нужно для нашего класса, и если поведение класса будет нарушено из-за ошибок библиотеки, тесты на это отреагируют. Та же логика применима и к пресловутому вопросу «как тестировать закрытые методы». Их не нужно тестировать! Если открытые методы протестированы и работают правильно, то закрытые никого не интересуют.

Ну, и наконец, заявление Спольски, что, мол, если понадобится что-то поменять, то придется править много тестов, очевидно вопиюще неверное. Модульные тесты на то и модульные, что… сможете сами догадаться? Вот-вот. И если в вашем коде изменение в одном месте обрушает все остальное — грош вам цена как программисту.

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

УжасноПлохоНормальноХорошоОтлично (Еще не оценили)
Loading ... Loading ...

Ген программизма

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

Не стоит сразу меня обвинять в мракобесии и развешивать ярлыки. Как ни удивительно, проблема склонности к программированию существует, и люди даже пишут по этому поводу серьезные статьи. В статье заявляется с известной долей недоумения, что, оказывается, существует способ сказать до начала обучения, сумеет ли человек осилить программирование или лучше сразу на рудники. Нехило так, а? Приходит студент поступать на программерскую кафедру, а его просят ответить на три простых вопроса, после чего (голосом магистра Йоды): «Тебя обучать не будем мы! Силы в тебе увидеть не можем!..»

Я бы, наверное, принял все это за шутку, если бы сам не столкнулся с живым подтверждением. Однажды я попробовал в порядке развлечения научить азам программирования двух людей. Один из них не смог понять, как работает присваивание значений переменным. То есть, натурально, пришлось минут 20 объяснять, что означает запись a = 1. Другой человек воспринял концепцию присваивания легко и непринужденно, хотя никогда до этого не программировал, да и желания такого не имел. Каково же было мое удивление, когда я наткнулся на пост Джеффа Этвуда, откуда и узнал про существование исследования в этой области. И вопрос на понимание присваивания у них первый в списке!

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

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

  • присваивание;
  • последовательное выполнение;
  • циклы;
  • рекурсию;
  • косвенную адресацию (указатели);
  • мультипрограммирование (многопоточность);
  • «чувство правильной вещи».

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

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

УжасноПлохоНормальноХорошоОтлично (3 голосов, средний: 5,00 из 5)
Loading ... Loading ...