О неадекватности отбора программистов
Автор позиционирует себя как безусловного эксперта в подборе программистского персонала, иллюстрируя это разбором реальных и гипотетических ответов на одну даваемую им на собеседованиях задачку: составить PHP-скрипт, переставляющий в произвольной строке символы в обратном порядке. В конце он пишет:
«Уверяю вас — пользуясь этой задачкой (и, конечно, еще многими другими) я ещё ни разу серьёзно не ошибся с кандидатом. Ведь формальное знание PHP в кандидате — поверьте, далеко не главное. Значительно важнее — отношение к своему занятию, стремление к развитию, способность играть в команде, видение мира, если угодно. Мне гораздо интереснее, как человек решает задачу, чем её фактическое решение».
Парадоксально, что демонстрируемый им подход соответствует сему посылу с точностью до наоборот. Выстроенная им иерархия ответов — от самого отстойного до самого ценного, на самом деле, прямо противоположна истинной, и я берусь это показать.
Итак, задачу автор формулирует так:
<?php $a = 'abcdefgh'; // Напишите здесь недостающий код, // чтобы результатом работы скрипта // была строка $a, повернутая наоборот echo $a; ?>
Для начала — «нулевое» решение, наилучшее, но, видимо, настолько ужасное с точки зрения автора, что он его даже не упоминает:
$a='hgfedcba';
Гы! Я серьёзно. «Уот ю уонт из уот ю гет» (What you want is what you get), как говорят в «Мак-Доналдсе», или выпьем же за то, чтобы правильно формулировать технические задания! Как поёт Канцлер Ги, «А на столе сидеть — удобно! И не гоните меня со стола…».
Ладно, поехали:
«Номер пять в моем хит-параде занимает ответ „я не знаю, и не буду это писать“. Иногда с вариантом „что за дурацкая задача, в жизни такого не бывает“. Слив, как говорится, засчитывается сразу».
Ай, зря! То, что задачу сию «дают на собеседовании в Microsoft» не говорит в пользу ни неё, ни «Майкрософта». Автор же сам признаёт:
«Задачка, конечно, „плюшевая“. Я сам могу придумать десяток причин, по которым она плоха — не отражает знание PHP, не соответствует реальной жизни…».
Итак, он унижает специалиста, предлагая ему откровенно неадекватную задачу, а потом удивляется, что его посылают. А могли бы и в ухо дать. Коль скоро он вступает на скользкую почву игры со стрессоустойчивостью, свойством, кое программисту при нормально организованном рабочем процессе никогда не должно потребоваться. Вариант номер пять — вполне адекватный ответ уважающего себя профессионала. Что же делать? Как отличить такового от невежды? Да очень просто. Погладь кота, сука! ™ Возьми работника на испытательный срок! Если даже ты какого чёрта не доверяешь диплому государственного образца (что, вообще-то, на грани национальной измены), то обрати внимание, что для специалиста потерянный месяц-другой на той ставке, кою предлагают на испытательных сроках, является достаточно высокой ставкой, чтобы ещё терзать его экзаменационными испытаниями (за кои, между прочим, он ни копейки не получает) в духе, как неодобрительно говаривал Мао, «внезапных атак».
«Номер четыре занимает вариант „В PHP вроде должна быть такая функция…“. Что ж, справедливости ради, должен сказать, что в PHP действительно есть такая функция. Названия её, конечно же, никто не помнит. Это нормально. Но неужели вы думаете, что я задавал эту задачку, чтобы услышать такой ответ? Следом за таким ответом предлагаю реализовать эту функцию самостоятельно».
Не помнить название какой-нибудь экзотической функции в PHP — это действительно нормально. Ненормально в такой ситуации писать её реализацию самому, вместо того, чтобы глянуть в мануал, ибо изобретение велосипедов — большое социальное зло. Помнится, был у меня сотрудник, который перебирал дочерние узлы в DOM-дереве, отбирая по селектору всех потомков, а затем проверяя у каждого родителя! Потому что изобретал велосипеды, там, где надо было изучать Javascript.
Номер три пропустим, он какой-то слабоадекватный («ну, как-то через массивы»), к тому же в принципе сводится к номеру четыре, за той оговоркой, что человек либо не знал, либо от волнения забыл, что к строкам в PHP уже можно обращаться как к массивам. (Но это если мы имеем дело с однобайтной кодировкой. С UTF-8 фигня получится; нужно использовать соответствующее семейство функций. Гы! То, что автор об этом не вспоминает и все перечисляемые им решения для этого случая не годятся, не слишком говорит в его пользу. Впрочем, с многобайтной кодировкой и встроенная функция (сюрприз!) обращается некорректно, а её mb-аналога нету, так что это вообще отдельная опера. Которая, вообще-то, должна оговариваться при постановке задания.)
$b = ''; for ($i = strlen($a)-1; $i>=0; $i--) $b .= $a[$i]; $a = $b;
Автор называет это решение «минимально адекватным для того, чтобы я рассматривал человека всерьёз». На самом деле решение логичное, очевидное и вполне достаточное (для однобайтной кодировки). Работает оно, конечно, в сотни раз медленнее встроенной функции, но куда ж деваться? Но автору этого мало и он выкатывает «джедайские техники»? по коим будто бы опознаются «чемпионы». Первая «джедайская техника» выглядит так:
$b = ''; $l = strlen($a)-1; for ($i = 0; $i < $l/2; $i++) { $b = $a[$i]; $a[$i] = $a[$l-$i]; $a[$l-$i] = $b; }
Для начала хочется проворчать, что нельзя так именовать переменные, имена должны быть говорящими: $char, $half_length, $char_counter
, например. Этому нас учит Стив Мак-Коннелл в «Совершенном коде», да это и так понятно (фигура «склонного к насилию психопата, который знает, где вы живете» должна быть в сознании всякого программера). Добавим, что этот код гораздо хуже читается даже при такой замене. Назначение его при беглом взгляде не очевидно, что плохо.
Затем отметим, что это — типичный пример преждевременной оптимизации, кою Доналд Кнут (кстати, всуе поминаемый автором) назвал «корнем всех зол».
Наконец, если кому-то интуиция подсказывает (как мне), что вот такое дёрганье символов строк по позиции — операция не настолько быстрая, чтобы её лихо множить, и чувствительная к длине строки, то этот кто-то прав. Проверка показывает, что этот метод в разы медленнее простого, а на длинной строке — в десятки раз! Так что это вовсе не оптимизация, а наоборот.
Наконец, вторая (и, на мой взгляд, наихудшая, хотя, чтобы так написать, надо, конечно, обладать изрядной изощрённостью) «джедайская техника», про кою автор вздыхает — «…так хотелось бы, что-то кто-то написал что-то вроде» (та-дамм!):
$l = strlen($a)-1; for ($i = 0; $i < $l/2; $i++) { $a[$i] = $a[$l-$i]^$a[$i]; $a[$l-$i] = $a[$l-$i]^$a[$i]; $a[$i] = $a[$l-$i]^$a[$i]; }
Что это было? На самом деле, этот трюкаческий метод справляется с длинными строками куда лучше предыдущего (с короткими, где-то до нескольких тысяч символов, кстати,— хуже,— а ведь в предложенном примере очень короткая строчка). Но он ещё хуже семантически, ибо применяет числовую, по существу, операцию (побитовое исключающее «или») к символам, подразумевая неявное преобразование типа. Тому, кто так пишет, «лучше было бы, если бы повесили ему жерновный камень на шею и бросили его в море». Ну, и всё равно он заметно уступает по производительности простому, не «джедайскому» методу.
Резюме: Jedi suxx, Sith rules…
Автор: torbasow