Pull to refresh

Какие вопросы задавать на собеседовании

ProgrammingDevelopment for iOSObjective CXcodeSwift
Каждый разработчик время от времени ищет работу и проходит собеседования. Кто-то хочет попробовать что-то новое, получить большую ЗП или попасть в компанию, в которую всегда мечтал. Не обошло это событие и меня стороной.

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

Чтобы в итоге собеседование не выглядело для соискателя как:


Статья в первую очередь будет полезна всем, кто ищет работу в среде iOS разработки или хоть как-то связан с набором IT специалистов: проводит технические собеседования или любые другие.

И добро пожаловать под кат.

Вступление


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

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

Нерафинированная 100% теория без какой-либо связи с практикой. Никто не поинтересовался как я размышляю, подхожу к задачам, как стал бы ловить нестандартные вылеты, искать причины плохой производительности в приложении и решать прочие будничные проблемы с которыми разработчик сталкивается каждый день. Всех интересовало только отличие ARC от MRC и разнообразная ни разу в жизни не понадобившаяся муть. Например: чем строение файла xib отличается от строения файла storyboard. Именно файла. Такая полезная вещь. Каждый день ковыряюсь в xml.

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

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

Вопросы


Приведу пример вопросов, которые, на мой взгляд, лучше раскрывают букет навыков девелопера, чем просто в лоб: 'Как работает memory management в iOS?'. Важно не только с ходу решить задачу, но еще и уметь найти/придумать это решение, если не знаешь как делать.

  1. Как бы вы стали верстать такой экран? Какие узкие места тут есть и как бы вы их решали?

    Входящая информация:
    Есть объект Product, который состоит из некой общей информации, которая находится в шапке, и массива Parameters. Каждый параметр — это строковые поля name и value. Value — это самая обычная строка, где каждое значение отделено вертикальной чертой от другого. Например: «VM 505|BWM ZIGZAG 3|SOLID REKT 101». Каждое значение должно находиться на новой строке как в 'Спецификации OEM'.

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

    Уровень: middle и выше.
    Решение
    В первую очередь стоит услышать ход мыслей разработчика. Большинство людей залипают на этой задаче и упускают из виду множество деталей.

    На мой взгляд, самый оптимальный вариант — это попросить дизайнера переделать.
    Если решать задачу технически, то я бы провел линию от хвоста одного лейбла до хвоста другого. Чтобы линия именно заходила за лейбл с value. Потом добавляем атрибут с background color на лейбл. В итоге фоновый цвет закрасит вьюху под ним.

    Еще вариант — это отсортировать слова по длине и наверх ставить самое длинное, а линию выровнять по началу value лейбла.

    Попробуйте найти еще решения.

  2. Что произойдет после запуска приложения?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions...) -> Bool {
        DispatchQueue.global().async {
            Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(self.tickTimer), userInfo: nil, repeats: true)
        }
        return true
    }
        
    func tickTimer() {
        print("Tick-Tack")
    }
    

    Я обычно не сторонник задач в стиле: 'Какая проблема в коде на картинке?', но слишком уж часто всплывает непонимание принципов работы таймера и ранлупов, которые выливаются в крайне неприятные и трудноуловимые баги.

    Вопрос можно переформулировать в задачу: 'Нужно сделать повторяемый таймер, который вызывается каждую минуту в бекграунде. Прицельная точность тиков не важна, достаточно некая периодичность. Как это сделать?'

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

    Если надо сделать таймер в фоне, то стоит выбирать поток с бегущим ранлупом. Либо воспользоваться уже готовым решением для GCD.

  3. Поступила задача. Нужно написать приложение, цветовая гамма которого конфигурируется на сервере. То есть, приложение получает конфиг в котором содержится набор цветов, степень скругления иконок, и так далее. Как лучше сделать такое приложение? Что будем использовать? Какие будут ограничения у того или иного решения?

    Уровень: junior/middle и выше.

    Обратить внимание: не дай бог кандидат промолчит о UIAppearance. Просто сc***ми тряпками гнать такого, особенно, если это middle и далее. Здесь же можно спросить про базовые классы Obj-C в качестве небольшого отступления к теории.

    Отмечу, что кандидату не обязательно в деталях повествовать о работе UIAppearance. Он мог ни разу не использовать его, но что это такое знать обязан.
    Решение
    Создаем класс цветовой схемы и конфигурируем все элементы UI через UIAppearance. Для кастомных вьюх тоже реализуем этот протокол. Есть отличная статья на этот счет.

  4. Как сделать так, чтобы приложение могло себя обновлять без участия AppStore? Добавлять новые экраны и логику к ним, например. Какие есть ограничения у такого решения? Какое лучше подойдет в том или ином случае? Когда может быть реальная необходимость в этом механизме?

    Уровень: senior.
    Решение
    Задачи для senior идут без решения. Набивайте опыт, господа.

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

    Уровень: middle и выше.
    Решение
    Причиной торможения может быть:
    • Перегруженный main thread.
    • Инстанциирующиеся в процессе ячейки. Если у вас таблица состоит больше, чем из одного вида ячеек, то при отсутствии в очереди нужной, она сначала создастся, это требует ресурсов. Особенно при разархивации из nib.
      Одно время даже либу написал, которая позволяет все cells заранее создать, чтобы не происходило скачков при скролле.
    • Все касающееся прорисовки, подсчета высоты и переиспользуемых ресурсов. Есть потрясающее исследование, которое на 100% закрывает этот пункт.


  6. Вопрос по Realm. Есть приложение с тем же чатом(можно любой другой пример), где таблица имеет некие разделители в виде даты или любого другого варианта. Как наиболее производительно сделать разделение по секциям? Какие есть варианты?

    Уровень: middle и выше.
  7. Вопрос по CoreData. Есть приложение с тем же чатом. Сообщения могут приходить из сокета в одном из фоновых потоков. Нужно, чтобы пришедшее сообщение добавлялось в таблицу. Как будем делать? Какие есть варианты? С какими сложностями можно столкнуться?

    Уровень: junior/middle и выше.
  8. Есть экран, наполнение которого зависит от нескольких запросов к серверу. То есть, содержимое должно быть показано только когда все они выполнятся. Например, страничка вконтакте. Пока не загрузится инфа о пользователе, сообщения со стены, первый поток фоток, должен крутится прогресс индикатор. Как будем строить логику?

    Уровень: junior и выше.
    Обратить внимание: хочу особенно здесь акцентировать на необходимость понимания gcd групп и синхронизации задач в Operation Queue. Будет здорово, если кандидат еще расскажет в чем разница того или иного решения.
    Решение
    Dispatch group, синхронизированные операции.

  9. Случилась проблема. К вам прибежал разработчик из соседней команды и просит о помощи: приложение стало вылетать в релизе, но при этом нормально работает в дебаге. Как будем ловить ошибку? Что это может быть?

    Уровень: middle и выше.

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

    Почему это так важно: есть люди процесса, а есть результата. Разработчики процесса просто тратят деньги компании, что особенно заметно при лове нетривиальных багов. Они(разработчики) будут получать удовольствие от собственной компетенции, выставляя море бряков, читая статьи о вылетах и ошибках компилятора, погружаясь в профайлер с головой на весь день, когда достаточно было всего-то убрать сомнительный кусок кода. Это не значит, что не надо пользоваться профайлером и бряками. Просто надо понимать цель ради чего это делается.
    Решение
    Для начала надо вычислить точку вылета. Часто сомнительный код лежит на поверхности, стоит только сузить область поиска.
    Если требуется отладка, то ставим whole module optimization + fast и проверяем вылет(для Swift). С вероятностью 90% воспроизведется в дебаге. Advanced отладку описывать нет смысла.
    Еще можно попробовать обойтись только whole module optimization.

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

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        for index in 0...1000000 {
            let string = NSString(format: "test + %d", index)
            print(string)
        }
        return true
    }
    

    Что это может быть? Как это вылечить?

    Уровень: middle и выше.

    Обратить внимание: понимание принципов управления памятью. Хотя бы в целом.
    Я бы сказал, что ситуация из вопроса крайне редкая и задачу стоит использовать только для совсем уж распальцованных синьеров, всем остальным достаточно знать о наличии retain/release/retain count и retain circle.
    Решение
    Дело в autoreleasepool. Лечится созданием своего пула или использованием не autoreleased объектов.

  11. Немного классики. Вы проводите Code Review подопечного джуна, который пишет класс календаря для вашего приложения, и обнаруживаете следующий кусок кода:

    protocol CalendarDelegateProtocol {
        func didSelect(date: Date)
    }
    
    public class Calendar: UIView {
        var delegate: CalendarDelegateProtocol!
        ...
        func didReceiveTouchForDate(date: Date) {
            self.delegate.didSelect(date: date)
            print("Did touch: \(date)")
        }
    }
    

    didReceiveTouchForDate — внутренний метод календаря, который вызывается при нажатии на определенную дату. Все ли тут в порядке на ваш взгляд?

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

    Уровень: junior и выше.
    Решение
    // Избыточное слово 'Protocol'. Достаточно просто 'CalendarDelegate'
    protocol CalendarDelegateProtocol { 
        // Метод обязателен? Вряд ли. Должен быть optional.
        func didSelect(date: Date)
    }
    // Зачем public во внутреннем инструменте? Это только создаст помехи при оптимизации.
    public class Calendar: UIView {
        // Где weak? Потребуется еще отметка ':class' у протокола. 
        // delegate не должен быть force-unwrapped
        var delegate: CalendarDelegateProtocol!
        ...
        // Название не по гайдлайнйам. Для Swift 3 должно быть: didReceiveTouch(date:)
        // Явно внутренний метод должен быть приватным
        func didReceiveTouchForDate(date: Date) {
           // Вызов должен быть опциональным. 
            self.delegate.didSelect(date: date)
           // Лишний вывод. Просто мусор в логи
            print("Did touch: \(date)")
        }
    }
    


  12. Тестировщики обнаружили баг, что пуши в приложении приходят только на iOS 10, но не на iOS 9. Как будем исправлять? В чем может быть проблема?

    Еще одна задачка из той же серии: пуши приходят при установке приложения напрямую на устройство, но не из Testflight/Crashlytics/HockeyApp. Как с этим жить?

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

    Уровень: middle и выше.
    Решение
    Возможно, уведомления рассылаются только с development сертификатом. Больше стоит уделить внимание тому как соискатель будет искать решение.

  13. Есть одномерный строковый массив, данные из которого выводятся в таблицу. При этом массив может меняться откуда-то извне. Как сделать так, чтобы данные в таблице обновлялись по мере изменения массива? Например, если объект добавился в массив, то в таблице должна появиться новая строка.

    Уровень: junior и выше.
    Решение
    KVO. Если хочется совсем чистого решения, то можно еще засвиззлить некоторые методы.

  14. Вы делаете экран авторизации для Skype в storyboard с использованием autolayout. Так получилось. Все просто — квадратный лого, под ним текстовое поле и кнопка.


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

    Уровень: junior и выше.
    Решение

  15. Нужно сделать scrollView с двумя картинками определенного размера друг под другом и отступами от края экрана со всех сторон в 30px. Нарисуйте на листочке какие будут констрейны.


    Обратить внимание: понимает ли кандидат как определяется content size для scrollView? А если помнит про инсеты, так вообще замечательно. Может быть предложит поставить контент скроллвью на весь ее размер, без отступов, а расстояние от краев экрана сделать через margins.
    Уровень: junior и выше.

Вопросы приведены в качестве примера. Если будет интересно, то составлю еще.

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

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

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



Незаметное зло


Но сомнительные вопросы — не единственная проблема. Есть еще один фактор, который может отпугнуть даже успешного кандидата. Это неуважительное, надменное или высокомерное отношение. И я говорю не о девочках-hr или важных руководителях. А о будущих коллегах.

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

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

На тему задранных носов есть замечательная картинка у xkcd:
image

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

При этом нет никаких стандартов, образцов и требований. Каждый проводит собеседование в меру своего понимания и мироощущения при полном отсутствии обратной связи. Ведь кто может дать эту обратную связь? Руководство/HR и кандидаты. Первые в процессе не участвуют и ничего не могут сказать, а кандидатам точно уж не до этого. Если их приняли, то значит все хорошо. Если же нет, то смысл дальше разговаривать?

Всем этим я хочу сказать как компаниям, так и каждому коллеге-разработчику в отдельности: обратите внимание не только на то как вы проводите интервью, но и манеру в которой общаетесь со своими подчиненными и коллегами. Канцерогенное отношение может проявляться не только к соискателям.
Попросите кого-то поприсутствовать на паре собеседований и дать вам обратную связь. Спросите у самих кандидатов впоследствии как все прошло, было ли некомфортно или еще что. Это как Code Review, ничего постыдного тут нет. Вы только станете лучше как специалист.

Уважительное общение должно являться стандартом в технической сфере.

Заключение


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

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

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

И, как говорится, уважайте друг друга. Независимо от глубины ваших познаний в материале — это не повод смотреть сверху вниз на окружающих. Аминь.
Only registered users can participate in poll. Log in, please.
Сталкивались ли вы с некорректным поведением на собеседованиях?
62.5% Да. 170
27.57% Нет. 75
9.93% Сам люблю так делать. 27
Nobody voted yet. Nobody abstained.
Tags:iosсобеседованиезадачи для собеседованийswiftobjective-c
Hubs: Programming Development for iOS Objective C Xcode Swift
Total votes 28: ↑23 and ↓5+18
Views42K

Popular right now