[PHP]: Вопросы на собеседовании #2

Продолжаю цикл статей (1, 2, 3) , посвященных вопросам на собеседовании. В этот раз постараюсь рассказать про интересные задачки. Итак, поехали:

1. Задача на логику

Ситуация:

Представьте, что есть 3 бочки с шариками: в одной только черные, во второй только белые, в третьей и черные и белые. На каждой из бочек таблички: черные, белые, черно/белые соответственно. Один раз можно достать один шар из любой бочки. Заведомо известно, что все таблички лгут.

Вопрос: Что же надо узнать? :) В какой бочке какие шарики лежат?

Решение: Берем шар из бочки с табличкой "черно/белые", если там черный, то значит в бочке с табличкой "черные" лежат белые, а бочке с табличкой "белые" лежат черно/белые. В противном случае, в бочке оказывается белый шар и значит в бочке с табличкой "белые" лежат черные, а в бочке с табличкой "черные" лежат черно/белые.

2. Какие паттерны проектирования вы знаете

Размер ответа прямо пропорционален опыту работы. Конечно, такое утверждение тоже далеко от правды, но буду полагать, что все работают в компаниях пропагандирующих ООП и хороший стиль кода. Про паттерны проектирования очень хорошо написано в наверное самой известной книге. Стоит обратить внимание на статью в Википедии, гуляя по просторам рунета наткнулся на хороший блог, в котором освещены самые известные паттерны, и что самое приятное — на PHP. Меня в основном спрашивали про фабрику, синглтон и пару раз про observer и decorator.

3. Привести пример интерфейса из реальной жизни

Забавный вопрос, по крайней мере меня, он на несколько секунд поставил в тупик. Примеров таких много, поэтому напишу, что сам ответил на него: педали в автомобиле. Тут стоит объяснить почему — во всех машинах есть либо 2 либо 3 педали, и любой водитель знает, что справа газ, посередине тормоз, а слева сцепление. Давишь на газ машина едет, при нажатии тормоза автомобиль останавливается. Это и есть пример интерфейса, описаны методы взаимодействия, а как уж там они реализованы внутри, не наши проблемы.

4. Задача на логику № 2

Ситуация:

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

Вопрос:

Определить какой из выключателей управляет ламой.

Решение:

Задачи такого рода называются out-of-the-box, для их решения требуется немного выйти за рамки описанной ситуации. Сначала, все пытаются просчитать ситуации с включением выключением и открыванием двери, в итоге приходят к невозможности решения стандартными средствами. Решение же лежит на поверхности и происходит из бытового опыта. Сказано, что можно зайти в дверь и делать все, что в голову взбредет. Мне данная задача ставилась несколько по-другому, поэтому надо было самому дойти до такого решения. Троллить человека, который задал вопрос, на тему "а я поставлю датчик и выкину провода в коридор" не стоит. Надо сделать следующее: щелкнуть 1 выключатель, подождать чуть чуть, выключить его, щелкнуть 2ой и открыть дверь. Если лампа горит, то это 2ой выключатель, если лампа не горит, то подойти и потрогать её, если горячая, то это 1ый, если холодная, то 3ий. Все как обычно легко и просто. Тут надо либо знать, либо уметь решать такие задачки.

5. Подмена сервиса

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

Вопрос:

Есть приложение, приложение обращается к внешнему сервису, в приложении нужно внести какие-то правки, как сделать так, чтобы на девелоперской машине приложение не стучалось во внешний сервис?

Перед описанием решения:

Вопрос был задан именно в такой формулировке, поэтому с собеседником у нас возникли некоторые разночтения в понимании контекста. Человек задавал вопрос в контексте паттернов, ответ был без их учета. Я подошел к ответу с технической точки зрения. Мои ответы:

  • Через рефлексию обратиться к вызывающему классу и подменить его
  • Подменить через мок внешний сервис, подсунув ответ
  • Есть модуль runkit, с помощью него на лету подменить поведение объекта
  • Сделать тестовую апи и переключить девелоперскую машину на неё

Все они были примерно правильные, но на поставленный вопрос все же не ответил.

Решение

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

P.S. На этом завершим сегодняшнюю top-5 вопросов на собеседовании.