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



Будем честными, большинство программистов не любят писать код на собеседовании. Некоторые даже угрожают уйти из профессии по этой причине. Но в ближайшее время ничего не изменится. Так что если вы действительно хотите получить работу, то придётся понять, как можно добиться успеха на этих собеседованиях. Я помогу вам. Мы изучим процесс, и я объясню, что именно я хочу добиться от собеседования, так что у вас сложится довольно чёткое представление, как его пройти.

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


Ты больше, чем просто машина для кодинга

Часть 1. Программирование на доске


Кто вообще в этом мире программирует на доске? В самом деле, серьёзно. Тем не менее, я попрошу вас сделать это. Не волнуйтесь, я не сошёл с ума. Я знаю о Google и что доска плохо справляется с автодополнением. Меня это не волнует. Я проверяю не то, насколько красивый код вы пишете на доске, а кое-что другое.

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

«Я проверяю не то, насколько красивый код вы пишете на доске»


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

1. Вербализуйте свои допущения и постарайтесь их подтвердить


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

2. Думайте вслух


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

3. Не бойтесь попросить помощи


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

4. Честно покажите свои способности и опыт


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

Часть 2. Программирование на компьютере




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

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

Палиндром — это число, буквосочетание, слово или текст, одинаково читающееся в обоих направлениях. Разрешаются корректировки к прописным буквам, пунктуации и пробелам. Некоторые примеры на английском: “A man, a plan, a canal, Panama!”, “Amor, Roma”, “race car”, “stack cats”, “step on no pets”, “taco cat”, “put it up”, “Was it a car or a cat I saw?” и “No ‘x’ in Nixon”.

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

Ваша функция должна принимать строку как параметр и возвращать булево значение (true, если строка является палиндромом, и false, если не является).

Предполагайте, что этот код будет поставлен в реальную систему на рабочем сервере, и пишите соответственно с этим.

Когда я предлагаю такую задачу на собеседовании, первым делом я смотрю, зададите вы мне дополнительные вопросы или нет. Как я уже говорил раньше, лучшие программисты понимают, что допущения — это именно то, что убивает вас в этом бизнесе. Мой совет каждому, кто получил инструкции для написания кода, — сделать паузу и подумать, какие допущения следует сделать для того, чтобы выполнить задание (они всегда есть) и найти способ подтвердить или прояснить эти допущения. Я понимаю, что во время выполнения задачи люди уходят в «тестовый режим» и думают, что им запрещено говорить. Я же полагаю, что вы начнёте с вопроса интервьюеру: «Мне разрешено задать вам один или два вопроса, чтобы прояснить некоторые допущения?» (Я всегда отвечаю «да»), и тогда вы получите ОГРОМНОЕ преимущество.

Хорошие вопросы для этой конкретной задачи:

  • Здесь клиентский JavaScript или на стороне сервера?

  • В контексте данной задачи может ли считаться пустая строка валидной строкой на входе?

  • Нужно ли обрабатывать символы Unicode?

Далее я смотрю, насколько хорошо вы следуете инструкциям. Например, я определил строку как параметр и булево значение как результат. Это то, что выдаёт программа?

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

  • В коде должны быть комментарии.

  • Нужно предусмотреть обработку ошибок или хотя бы ведение логов.

  • Программу следует обложить тестами.

  • Программа не должна сбоить ни в коем случае.

  • Код должен быть легко читаем и говорить сам за себя (легко понятные имена переменных, хорошее форматирование, в идеале — без сложных конструкций и дефектов (“lint free”)

Если вы раньше видели код только в учебниках и руководствах, то не знаете, что означают вышеперечисленные вещи. Мой совет: посмотрите на код популярных open source проектов. Особенно тех проектов, которые развиваются уже давно и стабильны. Для JavaScript вполне хорошим примером будет код jQuery на GitHub.

Далее, мне интересно посмотреть, как вы понимаете слово «эффективный» в сочетании с «продакшн системой». Если у вас есть опыт, то вы понимаете, что понятие «эффективный» для программы в продакшне означает три вещи:

  1. Быстро работает.

  2. Не занимает память, когда она ей не нужна.

  3. Стабильна и легко поддерживается.

Вы должны понимать, что пункт № 3 иногда означает некоторый ущерб для пунктов № 1 и № 2.

В этой конкретной задаче я предполагаю, что многие будут применять здесь регулярные выражения. Они универсально подходят для многих языков, быстры и исключительно удобны (правка: регулярные выражения не всегда работают быстро, в том числе с палиндромом, спасибо AlexDenisov в комментариях). Будет вполне обоснованным предположить, что вы знаете основы регулярных выражений, но вы всё равно можете написать код и без них.

Насчёт тестов я хочу увидеть, что вы предусмотрите много тестов, но все они будут проверять действительно разные сценарии. Проверка “mom”, “dad” и “racecar” избыточна, это всё один и тот же тест. Я также ожидаю увидеть, что вы включите тесты на прочность (краш-тесты); тесты каких-нибудь строк, которые не являются палиндромами. Рассматривайте пограничные случаи, проверяйте нуль или число. Проверяйте пустую строку или набор специальных символов.

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

Если джуниор выдаёт работоспособное и достаточно простое решение, и всё остальное собеседование проходит нормально, этого достаточно для начала работы и повышения своих навыков.

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

Для ведущих программистов хотелось бы видеть оптимальное решение, чистый и поддерживаемый код, обработку ошибок, комментарии, полный набор тестов. Например, если вы применяете console.log() в JavaScript на стороне клиента, то добавьте комментарий, который даёт понять, что вы знаете о необходимости поддержки логгирования также на стороне сервера.

Вот пример хорошего кода, написанного на JavaScript.

'use strict'; // avoid ambiguity and sloppy errors

/**
 * Tests wether or not a given string is a Palindrome
 * @param {string} stringToTest - the string to test.
 */
function isPalindrome(stringToTest) {
    var start = 0,
        end;

    // make sure we have a string.
    if (typeof stringToTest !== "string") {
        // throw if we didn't get a string
        throw new TypeError("isPalindrome() expected a string, but got " +
            Object.prototype.toString.call(stringToTest) + " instead!");
    }

    // normalize string by lowercasing and removing non-word characters
    stringToTest = stringToTest
        .toLowerCase()
        .replace(/[^a-z0–9]/ig, '');

    if (stringToTest.length === 0) {
        // warn if we have no valid characters to test
        console.log("No valid characters to test, treated as empty string" +
            "\nStack: \n" + new Error().stack);
        return true; // an empty string is a palindrome.
    }

    end = stringToTest.length - 1;
    // compare characters from outside in. stop when we get to the middle.
    while (start < end) {
        if (stringToTest[start] !== stringToTest[end]) {
            return false;
        } else {
            start++;
            end--;
        }
    }

    // if we get here, it's a palindrome
    return true;
}

// tests (should be in a seperate file using a test framework)
console.log(isPalindrome("something that is not a palindrome") + " = false");
console.log(isPalindrome("something that is \n not a palindrome") + " = false");
console.log(isPalindrome("race \n car") + " = true");
console.log(isPalindrome("") + " = true + warn");
console.log(isPalindrome("  ") + " = true + warn");
console.log(isPalindrome("1221") + " = true");
console.log(isPalindrome("0") + " = true");
console.log(isPalindrome("racecar") + " = true");
console.log(isPalindrome("No 'x' in Nixon!") + " = true");
console.log(isPalindrome("~~!~!~") + " = true + warn");
console.log(isPalindrome("Momsie") + " = false");
console.log(isPalindrome(12)); // blow up
console.log(isPalindrome(undefined)); // blow up
console.log(isPalindrome(null)); // blow up

Очевидно, есть другие способы написать подходящую программу, но это даёт представление, о чём я говорю.

Если я даю задание на дом, то ожидания ещё выше.

Часть 3. Алгоритмы




Некоторые интервьюеры будут просить написать реализацию конкретного алгоритма. Лично я считаю это гигантской потерей времени. Гораздо более важно для меня, чтобы вы понимали, какой алгоритм применить для какой задачи. Реализацию всегда можно найти в Google.

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

Часть 4. Не сдаваться без борьбы


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



1. Не сдавайтесь слишком легко


Убедитесь, что я заметил ваши усилия. Если вы из тех, кто сдаётся, когда становится трудно, я не будут тратить на вас время.

2. Псевдокод


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

3. Назовите известные неизвестные


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

Часть 5. Практика, практика, практика


Пожалуй, самое важное для успешного собеседования по программированию — хорошая подготовка. Лучше всего практиковаться со стандартными вопросами снова и снова, пока вы не выучите их назубок. Если много тренироваться, то вы сможете отвечать на вопросы, которые не встречали ранее. У вас появится уверенность и вы сможете связать любой вопрос с чем-то другим, что встречали раньше.

Я составил большой список онлайн-ресурсов с примерами вопросов и советами по программированию для 50+ различных языков программирования и технологий, включая C#, JavaScript, Mongo, Node и так далее…

Список здесь (подписка на рассылку) и в pdf.
Поделиться с друзьями
-->

Комментарии (116)


  1. lostpassword
    01.06.2016 12:40
    +13

    Картинка с боулингом прекрасна!)


    1. Zanael
      01.06.2016 16:46
      +8

      Чего не скажешь о третьей картинке с мужчиной по центру, сидящего спиной в наушниках.


  1. AlexTest
    01.06.2016 12:42
    +10

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


    1. KonstantinSpb
      01.06.2016 13:22
      +24

      Это верно, сразу вспоминается:
      www.prikol.ru/wp-content/gallery/september-2011/interview-02.jpg


    1. zarincheg
      01.06.2016 13:43
      +8

      Да ладно, в любой команде/компании всегда бывают жесткие запары. Необязательно из-за того что сотрудники некомпетентны. Сервера падают, случаются атаки на приложения или инфраструктуру в целом, клиенты внезапно осознают проблемы с требованиями — триггеров «аппокалипсиса» очень много может быть. И вот в таких, в идеале редких, ситуациях умение оперативно мобилизировать все свои скиллы очень важно.


      1. AlexTest
        01.06.2016 16:54
        +7

        Запары — да, бывают. Но тут же реально АД описан:

        1. перед самым дедлайном, когда мы вымотаны в край
        Почему команда вымотана перед дедлайном? Налицо серьезные ошибки в управлении.

        2. когда мы все будем ломать головы над проблемой
        Почему ВСЕ должны ломать голову над одной проблемой? Опять ошибки в управлении.

        3. на нас все злятся, а на кону стоит наша работа и репутация
        Не слишком ли много «мы», «все», «нас», «наша»? Какой-то «колхоз», а не фирма по разработке ПО!
        Как я понимаю у автора напрочь отсутствует представление о персональной ответственности конкретных людей за конкретные участки работы.


        1. MacIn
          01.06.2016 21:16
          +1

          Почему ВСЕ должны ломать голову над одной проблемой?

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

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

          Вам как, хороший продукт нужен, или возможность свалить вину на кого-то? Ну, обаружится, что виноват конкретный Вася. Васю поругали, выгнали на мороз. И? От этого ошибка сама пропадет, доверие клиентов восстановится, неустойка исчезнет? Или лучше заранее подстраховаться? А то, знаете ли, и код-ревью можно не делать — пусть будет просто ответственный за плохую строку.


          1. AlexTest
            01.06.2016 23:55
            +3

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


            1. MacIn
              02.06.2016 01:04
              +1

              Вы улавливаете мой месседж о ценности откровений по найму от конкретно этого мегаспеца?

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

              И если это именно он нанял некого условного Васю в свою контору на конкретную должность, на которой этот Вася так облажался в аккурат перед дедлайном — неужели виноват только Вася?

              Почему именно он, а не другой? Да пусть и нанявший, хотя это спорно. Ваша претензия была к слову «мы». Употребление оного указывает на то, что люди в команде заботятся не о том, как прикрыть свою задницу при провале, а о том, чтобы провала не было. Разработка — командный «спорт».


        1. 2PAE
          02.06.2016 07:30

          Почему ВСЕ должны ломать голову над одной проблемой?

          Есть такая техника Мозговой штурм. Возможно автор имел в виду именно это?


      1. Alcor
        04.06.2016 00:01

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


    1. avallac
      04.06.2016 00:01
      +2

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


    1. molchanoviv
      04.06.2016 00:01
      +3

      Так-же по коду сразу видно что интервьюер не читал Чистый код Мартина. Он там дело говорит. Код должен быть читаемым и без комментариев. Необходимость прокомментировать код говорит от том что его нужно рефакторить. А уж комментировать каждую строчку это мягко говоря излишество. Пустая трата времени.


    1. sergyx
      04.06.2016 00:01

      Лучшее что может сделать интервьюер — дать такие гарантии на как можно более раннем этапе собеседования. Это обоим сэкономит уйму времени.


  1. Drag13
    01.06.2016 13:58
    +8

    Есть неплохая теория о том, что наличие комментариев в коде скорее минус. Так как
    1. Желательно, что бы код был достаточно очевидным (имена функций, переменных, использование циклов, иф/елсов)
    2. Комментарии периодически устаревают.

    Так что здесь скорее стоит уточнить, что комментирование кода это скорее конвенция на Вашем проекте, чем требование к продакшн коду.


    1. Ivan22
      01.06.2016 14:01
      +3

      Везде хороша золотая середина.


      1. Drag13
        01.06.2016 14:12
        +2

        Согласен. Если функциональность сложна или содержит сложную идею, то да, хотелось бы увидеть комментарии.


    1. rshadow
      01.06.2016 18:06
      -4

      Дык, любителям самодокоментирующегося кода можно предложить написать ЗАЧЕМ этот простейший код это делает:

      for(var i = 0; i < arr.length; i++) { if(arr[i] === 'ok') ok = true; }


      1. IIvana
        01.06.2016 18:43
        +6

        В смысле, зачем он не прекращает бессмысленную беготню по массиву после первого тру? Действительно, это стоит прокомментировать. Может, оператор "=" здесь перегружен и имеет кучу побочных эффектов?


        1. Wesha
          02.06.2016 03:51

          Или оператор [] перегружен, и на самом деле читает не данные из памяти, а дёргает внешнее устройство, которое совершает какие-то действия — например, ампулы встряхивает.


      1. Drag13
        01.06.2016 20:02
        +3

        Любители самодокументирующего кода обернут это в функцию с адекватным названием. И напишут его через while.


      1. Athari
        01.06.2016 22:15
        +5

        Не то чтобы, но вообще...


        ok = arr.includes('ok');
        ok = arr.indexOf('ok') != -1;
        ok = arr.some(e => e === 'ok');

        P. S. На JS почти не пишу. Так, мимо проходил. Бесполезные циклы в коде не перевариваю — хоть с комментариями, хоть без.


    1. MacIn
      01.06.2016 21:20
      -2

      Это не самая хорошая теория, да и доводы «за» слабоваты.

      Желательно, что бы код был достаточно очевидным (имена функций, переменных, использование циклов, иф/елсов)

      Не бывает слишком понятного и слишком очевидного кода. Бывает достаточно понятный. Для остальных случаев есть комментарии.

      Комментарии периодически устаревают.

      А еще — о ужас — периодически устаревает сам код. По логике «комментарии устаревают, поэтому давайте не будем их писать» код программы, который тоже устаревает, надо не писать. Зачем писать программу, если она гарантированно устареет? И ее придется — представляете — править!


      1. Drag13
        01.06.2016 21:40

        Не бывает слишком понятного и слишком очевидного кода. Бывает достаточно понятный. Для остальных случаев есть комментарии.

        Да. И что? В большинстве своем код достаточно тривиален и конвенций хватает для того, что бы его не комментировать. Для других случаев смотрите ветку выше.

        И ее придется — представляете — править!


        Ирония хороша, когда она по делу.

        Но если по сути, то, помимо кода, Вам придется потратить время и поправить еще и комментарии. А если код живой, то правиться он будет много раз. И одна правка комментариев превратиться в десяток.
        А, если комментарии уровня статьи? Вам оно надо?


        1. MacIn
          01.06.2016 23:15

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

          В этом случае и не нужно комментировать. Концепция «наличие комментариев в коде скорее минус» об этом не говорит. Если предполагать, что код обязан быть тривиальным, то это попросту не всегда возможно.

          Ирония хороша, когда она по делу.

          Дельнее некуда: аргумент «придется править» ни о чем и по сути не отличается от «код придется править». Предполагая, что комментарии не являются частью кода.

          Но если по сути, то, помимо кода, Вам придется потратить время и поправить еще и комментарии

          И на форматирование, и разбивку по блокам и вообще рефакторинг, документирование интерфейсов. А еще написание тестов.

          А если код живой, то правиться он будет много раз. И одна правка комментариев превратиться в десяток.

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


          1. Drag13
            01.06.2016 23:23

            Надеюсь это будет Вам достаточным ответом.

            Drag13 1 июня 2016 в 14:12

            Согласен. Если функциональность сложна или содержит сложную идею, то да, хотелось бы увидеть комментарии.


            1. MacIn
              02.06.2016 01:06

              Собственно о том и речь — есть, где уместно, есть, где нет.
              В чистом виде ваше

              Есть неплохая теория о том, что наличие комментариев в коде скорее минус…
              Так что здесь скорее стоит уточнить, что комментирование кода это скорее конвенция на Вашем проекте, чем требование к продакшн коду.

              неверно.


          1. areht
            03.06.2016 15:12

            > Если предполагать, что код обязан быть тривиальным, то это попросту не всегда возможно.

            Бездоказательный вброс

            > Дельнее некуда: аргумент «придется править» ни о чем и по сути не отличается от «код придется править».

            Да, ни чем не отличается. Придётся править 2 раза вместо одного.


            1. MacIn
              10.06.2016 18:59

              Бездоказательный вброс

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

              Да, ни чем не отличается. Придётся править 2 раза вместо одного.

              Как и тесты, где-то заголовочные файлы, форматирование и все остальное. n+1 раз вместо n.


              1. areht
                10.06.2016 20:48

                > Отнюдь

                бездоказательный вброс

                > Как и тесты, где-то заголовочные файлы, форматирование и все остальное. n+1 раз вместо n.

                Мне про заголовочные файлы особенно понравилось, модно, молодежно.
                То есть вам что n, что n+1, что n^2? Оплата повременная?


                1. MacIn
                  10.06.2016 23:27

                  бездоказательный вброс

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


                  Мне про заголовочные файлы особенно понравилось, модно, молодежно.

                  Модно-не модно, но заголовочные файлы в том числе — отдельный объект возможной правки.

                  То есть вам что n, что n+1, что n^2? Оплата повременная?

                  Переход от n+1 к n^2 очень веселый — математическая обертка обычной демагогии.
                  Ну, не пишите тесты и/или документацию — оплата-то не повременная. Раз-раз и в продакшн, да?


                  1. areht
                    11.06.2016 00:47

                    Разница в том, что я могу аргументировать зачем мне тесты чем-то, кроме «было n, будет n+1»


    1. Wesha
      02.06.2016 03:49
      +1

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


      А вот комментарии предназначены для того, чтобы объяснять, зачем код это делает.


    1. sergeychadov
      04.06.2016 00:01

      Нет, наличие комментариев это плюс
      Просто приведенный пример «хорошего кода» — это просто образец того, как не надо писать комментарии.
      Комментарий
      // throw if we didn't get a string
      перед тем как мы делаем throw только захламляет код

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


    1. v1vendi
      04.06.2016 00:01

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


    1. Galiaf47
      05.06.2016 11:36
      +1

      В коде должны быть комментарии.

      Сразу пропал интерес к статье после этого пункта.


  1. artemlight
    01.06.2016 14:19
    +11

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

    Когда я прочитал эту фразу — я задумался о совершенно других ограничениях, а именно:

    1) Какого размера эта строка? Может ли размер этой строки превосходить размер доступной оперативной памяти (например, при чтении с диска)
    2) Может ли её отдавать, к примеру, устройство блочного вывода без возможности поиска конкретного смещения?
    3) Знаем ли мы заранее размер строки?
    4) Если мы разрабатываем хэш-функцию — каков допустимый уровень коллизий, какое максимальное время выполнения, и какой результат мы можем получить в случае досрочного прерывания выполнения (ложноположительный, ложноотрицательный, исключение?)
    5) Имеет ли каждый символ строки одинаковый размер (в байтах)?
    6) В случае нечетного количества байт в строке — как обрабатывать «средний» символ (безусловно не палиндром, безусловно палиндром, побитовое сравнение). Если побитовое сравнение — как быть с многобайтовыми кодировками на BE\LE архитектурах?

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


    1. boblenin
      01.06.2016 15:35

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

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

      А в целом статья довольно спорная.


      1. milast
        02.06.2016 04:39

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


        1. boblenin
          02.06.2016 05:03

          У вас не выйдет несогласиться со мной, потому как я сказал то же самое :), у фразы есть продолжение после «и также».

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


    1. lain8dono
      01.06.2016 15:36
      +1

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


      Все вопросы по строкам относительно этой задачи можно запихнуть в один: в каком формате строка? (предполагая, что она будет в стандартной для данного ЯП)


      Остальные вопросы (на мой взгляд) надо задавать в другую сторону:


      • Достаточно ли мне ascii набора?
      • Это нормально, если я выброшу исключение для строк, не кратных 2?
      • Можно я не будут писать комментарии в стиле Капитана Очевидность?

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


      1. IIvana
        01.06.2016 18:48

        Это нормально, если я выброшу исключение для строк, не кратных 2?

        Имхо — красный флажок, особенно после приведенных примеров.


    1. VladVR
      01.06.2016 18:02

      Какого размера эта строка? Может ли размер этой строки превосходить размер доступной оперативной памяти
      В задании же явно указано — Ваша функция должна принимать строку как параметр и возвращать булево значение

      В случае нечетного количества байт в строке — как обрабатывать «средний» символ
      В задании фактически есть тест- на строку “race car”, должно возвращать true. Палиндром это не побитовое зеркалирование, такой вариант исключен, тем более непонятно почему бы к среднему символу должно было примениться какое то отличное от других символов правило, если это в задании никак не оговорено.


    1. rshadow
      01.06.2016 18:09

      Автор явно ищет js программиста, а вы пишете явно на Си. Так что и вы и он по своему правы.


    1. Wesha
      02.06.2016 03:54

      я задумался о совершенно других ограничениях, а именно:

      Напомнило: https://habrahabr.ru/post/301924/


    1. daiver19
      03.06.2016 23:48

      Какое, извините, техзадание на такие тривиальные вещи? Или для вас на работе для каждой элементарной задачи специальный человек пишет «техзадание»?


    1. AlexNis
      04.06.2016 00:01

      «Ваша функция должна принимать строку как параметр и возвращать булево значение (true, если строка является палиндромом, и false, если не является).»

      Cтрока в JavaScript имеет фиксированную длинну. Даже при чтении из файла. Поправьте меня, если я ошибся.


    1. Wesha
      05.06.2016 18:11

      del


  1. segment
    01.06.2016 14:31
    +36

    Не понимаю необходимости в такого рода комментариях:

    // make sure we have a string.
    if (typeof stringToTest !== "string")
    

    Если имена функциям/переменным заданы адекватно, то код легко читается. Комментарии ради комментариев.


    1. Athari
      01.06.2016 19:36
      +7

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


      1. Шесть строк кода, чтобы проверить тип аргумента.


      2. Тьма тьмущая комментариев на абсолютно тривиальном коде.


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


      4. Замедление функции на порядки на тривиальных вырожденных случаях из-за костыльного логирования со всякими стеками.


      5. Жёсткие костыли с прототипами, чтобы получить имя типа.

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


      1. Lol4t0
        01.06.2016 21:59
        +1

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

        Самая эффективная реализация же!


        1. Athari
          01.06.2016 22:20
          +1

          Интересно, какая реализация считается неэффективной тогда...


  1. RomanArzumanyan
    01.06.2016 14:39
    +4

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

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


  1. xytop
    01.06.2016 14:59
    +4

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


    Как-то так:


    var isPalindrome = function(){
        var invalidCharsRgx = /^[a-z0-9]/ig;
        return function(){ /* ... */ };
    }();


    1. TheShock
      02.06.2016 03:25

      Они и так кешируются браузером при парсе кода, если не создали ее через new RegExp


    1. Wesha
      02.06.2016 03:59
      +2

      Лично я бы сделал (псевдокод):


      ........
      
      start++;
      while (!isCharater(str[start])) start++;
      end--;
      while (!isCharater(str[start])) end--;

      Не нужны ни регулярки, ни перевыделение памяти при .replace


      1. webkumo
        02.06.2016 17:13

        Немного некорректный код у вас — регулярка чистила от всех неинтересных символов по всей строке, вы — только с концов.
        На самом деле думал о подобном коде, но только не для чистки, а для проверки «палиндромности».

        Например, вариант — если пустая строка тоже является палиндромом:

        var start = 0,
        end = str.length;

        function isPalindrome() {
        while(isNotSymbol(str, start)) {
        start++;
        }
        while(isNotSymbol(str, end)) {
        end--;
        }
        if (end <= start) {
        return true;
        }
        if (charAt(str, start) === charAt(str, end)) {
        return isPalindrome();
        } else {
        return false;
        }
        }


        1. Wesha
          02.06.2016 17:22
          +1

          регулярка чистила от всех неинтересных символов по всей строке, вы — только с концов.

          Хотел только дифф запостить, думал — у народа мозги есть, поймут, но вижу — нет… Вот Вам полный код:


           while (start < end) {
                  if (stringToTest[start] !== stringToTest[end]) {
                      return false;
                  } else {
                    start++;
                    while (!isCharater(str[start])) start++;
                    end--;
                    while (!isCharater(str[start])) end--;        }
              }


          1. Wesha
            02.06.2016 17:30

            (Долбаный таймер хабраредактирования.) В вышеприведённом коде вместо str следует читать stringToTest, при этом предварительная очистка stringToTest регекспом не нужна. Функция isCharater(c) должна возвращать true, если символ c является алфавитным (то есть НЕ пробелом или знаком препинания) — это можно реализовать сравнением ASCII кодов без всяких регекспов.


            1. webkumo
              02.06.2016 20:49

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


              1. Wesha
                02.06.2016 21:31

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


                1. webkumo
                  02.06.2016 21:56
                  +1

                  Неполный код можно по разному показывать — я, например, в своём примере скрыл реализацию строки и проверки валидности символов за отдельными функциями (а надо было ещё и проверку идентичности символов — в текущем варианте разный регистр букв сломает мой код… про некоторые фишки utf-кодировок вообще промолчу)

                  А ваш пример, без дополнительной фразы (о том, что до первой проверки! надо! сдвинуть указатели) даст ошибку. Просто потому, что первый и последний символ — не всегда в списке допустимых. А про тримминг данных вы явно не сказали:
                  «В вышеприведённом коде вместо str следует читать stringToTest, при этом предварительная очистка stringToTest регекспом не нужна. » — тут надо гадать, почистили вы всё-таки строку или нет. Ну т.е. вы ни кодом, ни словами в явном виде не указали на это действие.

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

                  Язвительность же комментариев («думал — у народа мозги есть», «при наличии мозгов, конечно»), заставляют усомниться в вашей компетентности и адекватности.

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


                  1. Wesha
                    02.06.2016 22:52
                    +1

                    Имеющий уши — да слышит, имеющий мозги — да додумает, а у меня в данный момент есть несколько более важное занятие, чем c точностью до запятой расписывать решение детской задачи. Для достижения удовлетворения лично мне достаточно увидеть, что решение существует (и каким путём его достигнуть), а тратить время на расписывание запятых я буду после получения подписанного контракта.


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


    1. ReinRaus
      07.06.2016 11:46

      Регулярные выражения при работе со строками практически всегда быстрее простого кода в некомпилируемых языках (коим и является клиентский JavaScript).
      Сделал небольшой тест: https://jsfiddle.net/yq9gh6mm/1/
      Тестируется очистка строки от лишних символов регулярными выражениями /[^a-z0-9]/ig, /[^a-z0-9]+/ig и реализацией на чистом JS.
      Реализация без регулярных выражений проигрывает почти в 4 раза по скорости второму регулярному выражению.
      Использование регулярных выражений весьма оправдано, как минимум на стороне клиента.
      Компиляция NodeJs немного исправит ситуацию и реализация на чистом JS почти догонит регулярные выражения, но не обгонит. Тот же самый тест на NodeJS: http://ideone.com/juoJQr


      1. ReinRaus
        07.06.2016 12:15

        Хочу извиниться- функция в тесте не оптимальна.
        Тест с оптимальной реализацией: https://jsfiddle.net/yq9gh6mm/2/
        В нем "чистая" реализация проигрывает уже всего в 2 раза.
        А после компиляции NodeJS "чистая" реализация на 13% быстрее регулярки /[^a-z0-9]+/ig
        http://ideone.com/juoJQr


        1. webkumo
          07.06.2016 15:34

          Немного поигрался с вашими примерами (https://jsfiddle.net/4x5v6yk7/), в итоге коэффициент разницы в половине случаев меньше 1.5:
          Test started
          test 1 4948
          test 2 4675
          test 3 6762

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


          1. ReinRaus
            07.06.2016 17:56

            У меня в Chrome крайней версии от 1.7 до 2 колеблется отношении времени теста 3 к тесту 2.
            В этом нет ничего удивительного и неожиданного- такие результаты будут практически в любом языке, который не компилирует код или не имеет JIT-компиляции.
            Конечно, все зависит от конкретных примеров регулярных выражений, но скорее всего большинство их будет быстрее их "чистой" реализации ввиду того, что обработка строки регулярным выражением в таких языках — всего один вызов нативной функции, который быстрее множества инструкций байт-кода.


            1. webkumo
              07.06.2016 18:36

              Специально вывел коэффициент (чтобы вручную не считать) — разброс получается достаточно значимый (в абсолютных цифрах тоже), при этом от чего зависит — понимания нет.
              Версия хрома — 51.0.2704.63 m
              Попробовал в ФФ (45.0.1) — коэффициент болтается около единицы. При сравнимом времени работы теста 1 и меньшем времени работы теста 2

              Test started
              test 1 4411
              test 2 2513
              test 3 2524
              test 3 to test 1: 0.5722058490138291
              test 3 to test 2: 1.0043772383605252
              Test started
              test 1 4394
              test 2 2545
              test 3 2420
              test 3 to test 1: 0.5507510241238052
              test 3 to test 2: 0.9508840864440079


              1. ReinRaus
                07.06.2016 22:46

                Посмотрите этот тест: https://jsfiddle.net/4x5v6yk7/4/
                Решил исключить возможность кэширования регулярных выражений (ведь все-таки к одной строке всегда применяли) и получил интересный результат- теперь даже в FF 47.0 тест 2 в 1,5 раза быстрее теста 3, в хроме в 2,5 раза
                Чем больше длина строки тем сильнее регулярные выражения будут обгонять "чистую" реализацию
                https://jsfiddle.net/4x5v6yk7/5/
                Еще один плюс в пользу регулярных выражений.


          1. ReinRaus
            07.06.2016 18:14

            http://ideone.com/Yo5iDE
            Добавляем поддержку русского алфавита и забываем про то, что NodeJS обгонял по скорости регулярное выражение.


            Test started
            test 1 649
            test 2 584
            test 3 1237


      1. TheShock
        07.06.2016 22:12
        +1

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


        1. TheShock
          07.06.2016 22:29

          Пример. Тут регулярка просто не нужна:

          function isValidChar ( str, index ) {
            c = str.charCodeAt( index );
            return ( c > 47 && c < 58 ) || ( c > 64 && c < 91 ) || ( c > 96 && c < 123 );
          };
          
          function isPalindrome (str) {
            var left = -1, right = str.length;
            
            str = str.toLowerCase();
          
            while (true) {
              right--;
              left++;
          
              // search next valid char from the right
              while (right > left && !isValidChar(str, right)) {
                right--;
              }
          
              // search next valid char from the left
              while (right > left && !isValidChar(str, left)) {
                left++;
              }
              
              if (str[left] != str[right]) {
                return false
              }
          
              
              if (left > right) {
                break;
              }
            }
          
            return true;
          }
          


  1. ildus
    01.06.2016 15:01
    +2

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


    1. boblenin
      01.06.2016 15:38
      +2

      В каких коммандах вы работали? Или даже так: вы проблемы один решали или вместе с коммандой?


      1. DenimTornado
        01.06.2016 17:52
        +3

        Ну так с командной проблема решается не так как на доске! С командой идёт диалог, а тут чувак над душой! С ним не диалог, а таки допрос.


  1. Viacheslav01
    01.06.2016 16:24
    +5

    Тут комментарии, ради комментариев, хорошо что не началось с «сейчас я начинаю писать код».
    Я видел много индуского кода в котором коментарии используются так же, читать его просто ад!

    // make sure we have a string.
    if (typeof stringToTest !== «string») {
    // throw if we didn't get a string
    throw new TypeError(«isPalindrome() expected a string, but got » +
    Object.prototype.toString.call(stringToTest) + " instead!");
    }


    1. Antelle
      01.06.2016 16:27
      +4

      А это что как не "сейчас я начинаю писать код"?)
      'use strict'; // avoid ambiguity and sloppy errors


  1. greywriter
    01.06.2016 16:37

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


    1. boblenin
      01.06.2016 17:14

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


      1. greywriter
        01.06.2016 17:25
        +1

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


        1. boblenin
          01.06.2016 17:29
          +1

          Может быть дело в том, что вы их без одежды представляете.


        1. Wesha
          02.06.2016 04:06
          +2

          я представляю интервьюеров без одежды

          Господи, зачем я это представил? Как мне с этим кошмаром теперь жить?


  1. VladVR
    01.06.2016 17:46
    +11

    Вот пример хорошего кода
    уточнить — пример «не очень» хорошего кода.
    1. Комментарии мусорные, например этот // make sure we have a string.
    2. У метода слишком много ответственности. Он и за входные данные отвечает и строку фильтрует и палиндром вычисляет.
    2а. Я наоборот падавана отучал в каждом методе проверять раз за разом одни и те же входные данные. Если прям хочется поставить проверку или функция «библиотечная» (тоже кстати допущение), то проверку надо вынести в отдельный метод.
    2б Как и остальные две ответственности.
    Таким образом основной метод должен выглядеть вот так:
    function isPalindrome(stringToTest) {
        ensureInputIsString(stringToTest);
        var filtered = filterInput(stringToTest);
        return isPalindromeInternal(filtered);
    }
    

    ensure в данном случае — naming convention для методов, которые делают if{throw}

    3. Раз уж требования к производительности не предъявляются, судя по тому что решение с регексом считается «хорошим», то isPalindromeInternal пишется в одну строку, не считая проверки на пустую строчку, конечно.
    return input === reverseString(input);
    reverseString в проекте, работающем со строками, скорее всего уже должен быть.

    4. Автор пишет о том, что не должно быть повторяющихся тестов, но в примере несколько повторов, вот эти два например как с точки зрения ТЗ, так и с точки зрения реализации тестируют одно и то же.
    console.log(isPalindrome(" ") + " = true + warn");
    console.log(isPalindrome("~~!~!~") + " = true + warn");

    5. Мелкие замечания
    а. не стоило объявлять переменные до мусорного(нефункционального) кода, тем более с инициализацией, ведь при чтении такого захочется поскролить туда-сюда, а этого можно избежать.
    б. else после if{return} режет глаз
    в. я слишком придирчив


    1. Wesha
      02.06.2016 04:05

      isPalindromeInternal пишется в одну строку, не считая проверки на пустую строчку, конечно. return input === reverseString(input);

      reverseString("No 'x' in Nixon!") = "!noxiN ni 'x' oN". Намёк понятен?


      1. b1rdex
        02.06.2016 08:32

        var filtered = filterInput(stringToTest);


        1. Wesha
          02.06.2016 08:45

          1. Это уже две строки, а не одна.
          2. Создание новой (очищенной) строки = выделение дополнительной памяти под неё (а если строка в 32 Мб размером?) = замедление работы, а нас просили код сделать оптимальным насколько возможно.


          1. b1rdex
            02.06.2016 08:48

            Таким образом основной метод должен выглядеть вот так:
            isPalindromeInternal пишется в одну строку
            Так-то строк даже больше чем 2.
            А про память, так там reverseString тоже выделяет память под всю строку. И что? Это оптимально насколько возможно для тестового задания.


      1. letchik
        03.06.2016 23:08

        Не очень. filterInput подразумевает очистку от всех незначащих символов.
        function isPalindrome(stringToTest) {
        ensureInputIsString(stringToTest);
        var filtered = filterInput(stringToTest);
        return isPalindromeInternal(filtered);
        }


    1. IamKarlson
      02.06.2016 17:21

      Приняты


  1. Shamov
    01.06.2016 18:06
    +2

    Как же тяжело, наверное, быть веб-разработчиком. Уже на собеседовании заставляют писать код, как для продакшена… с комментариями и тестами. Даже страшно представить, что приходится делать, когда начинается настоящая работа…


    1. varanio
      01.06.2016 20:19
      +12

      А потом на настоящей работе приходится говнокодить в древнем легаси без комментариев и тестов


      1. Shamov
        01.06.2016 20:31
        +4

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


  1. michael_vostrikov
    01.06.2016 19:30
    +1

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

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

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

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

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


    1. neurocod
      02.06.2016 02:00

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

      >кто способен быстро думать на ходу, под давлением,

      Под давлением это как? Чем на меня можно надавить? Угрозой увольнения? Так я могу легко найти работу взамен. Разве что крик раздражает, ибо работает в обход сознания на эмоциональном уровне — тут хочется в ответ наорать.

      >… в одной комнате с другими.

      Как будто другие люди — это что-то страшное. Прямо вспоминаются всякие анекдоты про интровертов.


  1. J_K
    01.06.2016 19:32

    Спасибо за статью. А нельзя список выложить в нормальном кликабельном виде где-то?


    1. HabrDev
      03.06.2016 23:08

      1. J_K
        03.06.2016 23:31

        Огромное спасибо!


  1. zip_zero
    01.06.2016 23:29

    function isPalindrome(stringToTest) из примера — жесть. В питоне решается одной строчкой return stringToTest == stringToTest[::-1]


    1. TheShock
      02.06.2016 03:27

      И такое?
      isPalindrome("race car")


      1. zip_zero
        02.06.2016 12:04
        +4

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

        Есть два варианта:
        1. следовать Single responsibility principle имени Мартина (увы, его понимание у всех разное до сих пор) и возложить обязанность проверки и нормализации строки на вызывающего. Граничных случаев может быть много. Пробелы, в т.ч. два пробела подряд, знаки препинания в конце, и прочее и прочее.

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

        console.log(isPalindrome("Аргентина манит негра"));
        
        No valid characters to test, treated as empty string
        Stack: 
        Error
            at isPalindrome (<anonymous>:26:29)
            at <anonymous>:46:13
        


        … а чтобы понять, почему, нужно просмотреть чуть больше, чем одну строчку кода, чтобы найти причину:

            // normalize string by lowercasing and removing non-word characters
            stringToTest = stringToTest
                .toLowerCase()
                .replace(/[^a-z0–9]/ig, '');
        


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


    1. alexshelkov
      03.06.2016 07:54
      +2

      В JavaScript она тоже решается одной строчкой:

      function isPalindrome(str) {return str.split('').reverse().join('') == str;}
      

      Но почему то мне кажется, что с таким кодом не пройду я собеседование…


      1. TripleS
        03.06.2016 23:06

        Тогда уж лучше


      1. TripleS
        06.06.2016 11:35

        Я имел в виду, что тогда уж лучше так:

        function isPalindrome(str) {let s = str.toLowerCase().replace(/\W/g, ''); return s.split('').reverse().join('') == s;}


  1. TheShock
    02.06.2016 03:30
    +2

    Кстати, для таких тестов есть console.assert


  1. 776166
    02.06.2016 11:44
    +6

    Комментарии в коде на собеседовании? Серьёзно?
    Если тебе нужно быстро решить задачу, то ты будешь её решать в режиме «прототип». А потом усложнять функциональность.
    То, что программист не уточняет некоторые детали на собеседовании, ничего не говорит о его компетенции, потому что это может обозначать как низкую квалификацию, так и высокую. Если вы хотие посмотерть, какие именно он будет задавать вопросы, то такое задание ему и давайте.


  1. vdonich
    03.06.2016 23:47

    ИМХО, это отличный пример, как *не* надо проводить технические собеседования.
    На 7 строк кода, который, собственно, решает задачу, еще 20 разных оберток и проверок. За то же время, какое ушло бы на это интервью, лучше задать еще 3 вопроса, но попросить написать именно «мясо», а не «а не пустая ли строка?», «а не стреляем мы в ногу?».
    Разумеется, все проверки понадобятся в боевом коде, но тут жеж вопрос приоритетов, правильно? Человек нанимается не для того, чтобы работать компилятором или набором тестов — то, что можно автоматизировать, должно быть автоматизировано.
    Коментарии? Тесты? Вы серьезно? Проблема коментариев решается на этапе code review, покрытие тестами должно вычисляться автоматически.
    Не говоря уже о том, что вопрос уровня телефонного интервью.
    В общем, такое ощущение, что нанимается дрессированная обезьянка, а не инженер, чья основная задача — решать проблемы.


  1. spamas
    03.06.2016 23:48
    +1

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

    Самое важное для успешного собеседования по программированию:
    1. Вовремя распознать на интервью куда вы попали. Туда где вы будете работать или распозновать полиндромы. Если человек не прошерстил ваш профиль в linkedin, не задавал подробных вопросов, что делали на прошлых работах, и если из вышесказанного интервьюер не понимает, насколько вы компетентны, а продолжает вас звать к доске решать полиндромы — бегите оттуда со всех ног.
    2. Покинуть страну, где в 90% компаний верстают сайты, аутсорсят на запад за гроши, и при этом требуют знания профессора математики, а платят копейки, заставляют стоять у доски в 8 часов вечера ибо дедлайн «аутсорса за гроши». В общем покиньте Африку и переезжайте к белым людям. В ту же Чехию из статьи выше.
    2.


    1. vdonich
      04.06.2016 00:23
      +1

      Мммгм. Если компания нанимает человека на конкретный проект — может быть и да.
      А если у компании X открытых позиций без ограничения времени, и поток кандидатов хотя бы больше 10 в день? Прошестить профили затруднительно, а спрашивать кандидата о прошедшем опыте, бывает, не имеет смысла.
      Был случай, когда брали человека чтоб писать Джаву, так его 10+ лет опыта был совсем в другой области, и работал он совсем не с тем.
      Не говоря уже о том, что если имеется хорошо подвешеный язык, то прикрываясь NDA и «самописный фреймворк», кандидат имеет возможность пудрить мозг.

      Задача интервью — проверить, соображает ли человек и способен ли программировать. Всему остальному можно (и как правило нужно) учить, потому как ни одна работа на другую не похожа.


  1. Merkat0r
    04.06.2016 00:00
    +2

    >Когда я предлагаю такую задачу на собеседовании, первым делом я смотрю, зададите вы мне дополнительные вопросы или нет

    Да, единственный — *сколько вы мне заплатите за потраченное время на эту %хотелку%? Я пришел не благотворительностью и доказыванием чего-то заниматься*

    Адекватные или хихикают и все понимают(или довольно часто предлагают $, но только не в СНГ :) ) или *вы нам не подходите*
    Особо одаренные умудряются пытаться спорить давя на *ЭТОЖЕ СОБЕСЕДОВАНИЕ!!111ё*

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


  1. fedrch
    04.06.2016 00:00
    -1

    Напишите самую эффективную функцию, какую сможете найти, чтобы определить, является ли данная строка палиндромом.
    boolean isPalindrome(String s) {
    for (int i = 0, j = s.length() — 1; i


  1. AndrBell
    04.06.2016 00:00
    +1

    Заголовок звучит:… Несколько крайне полезных советов для разработчиков.
    Извиняюсь, но мне показалось, что советы совсем не полезные, они узко специализированы (субъективны, заточены на авторе), и что у другого собеседующего могут прозвучать совсем иной субъективной направленности вопросы.


  1. artemklv
    04.06.2016 00:00

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

    var checkLength = Math.floor(stringToTest.length / 2);
    for ( var i = 0; i < checkLength; i++) {
    if ( stringToTest[i] !== stringToTest[checkLength — 1] ) {
    return false;
    }
    }


    1. Wesha
      04.06.2016 00:04

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


    1. TheShock
      05.06.2016 04:59
      +1

      Работать не будет. checkLength константна, потому вместо проверки на палиндром оно будет проверять символ i с символом посередине. Пока не закончит из-за неравенства.


  1. Grindok
    04.06.2016 00:01
    +2

    По-моему пример хорошего кода — это пример того, как не стоит комментировать код.


  1. old_man_logan
    04.06.2016 00:01
    +2

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

    Такой кусок кода снабжен излишним комментарием, который никакой пользы в себе не несет:
    // make sure we have a string.
    if (typeof stringToTest !== «string») {

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

    Тоже очень спорно. Про скорость уже сказали, скажу про удобство. Регулярные выражения очень удобны, если вам через полгода не нужно будет вносить какие-то изменения в огромную регулярку, которая выглядит как арабская вязь.

    Но это, конечно, мое субъективное мнение.