Задача от «Яндекса»: как можно перемещать грузы между планетами

12 комментариев
Задача от «Яндекса»: как можно перемещать грузы между планетами

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

Мы не любим оценивать людей и их способности простыми плюсами и минусами, потому что это как черное/белое, которое не отражает важные оттенки реальности. Поэтому и задачи не оцениваем «правильно/неправильно».

В качестве примера мы попросили преподавателя Школы разработки интерфейсов компании «Яндекс» продемонстрировать собственный ход мыслей в решении одной из тестовых задач прошлых лет. К слову, если задания кажутся сложными – есть еще 7 дней до окончания приема заявок, чтобы углубить свои знания и успешно поступить в ШРИ.

Разбираем задачу

Задача из анкеты для поступления в 2013 году

Автор решения: Илья Довбан, руководитель группы поисковых интерфейсов в минском офисе «Яндекса».

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

Задание:

В файле task.js дан интерфейс корабля и планеты. Эти интерфейсы не являются завершенными и скорее всего потребуют доработки. Напишите недостающий код.

Пример использования:

Перевоз 1000т груза с планеты B на планету A.

Решение:

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

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

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

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

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

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

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

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

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

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

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

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

На самом деле, остался еще один последний штрих: надо причесать весь код синтаксическими и кодстайл-анализаторами. Пару блох JSHint должен найти. А если и не найдет — тем спокойнее.

Горячие события

Testing Stage 2020
26 марта — 28 марта

Testing Stage 2020

Киев
JSNation 2020 Amsterdam
3 июня — 5 июня

JSNation 2020 Amsterdam

Amsterdam

Читайте также

Easybrain открыла ИТ-лабораторию в БГЭУ
Easybrain открыла ИТ-лабораторию в БГЭУ

Easybrain открыла ИТ-лабораторию в БГЭУ

4 комментария
Яндекс сбоит (обновлено)
Яндекс сбоит (обновлено)

Яндекс сбоит (обновлено)

«Яндекс» отображает один день из жизни минского транспорта на интерактивной карте
«Яндекс» отображает один день из жизни минского транспорта на интерактивной карте

«Яндекс» отображает один день из жизни минского транспорта на интерактивной карте

2 комментария
Deloitte открыла в Минске клуб по программированию для детей
Deloitte открыла в Минске клуб по программированию для детей

Deloitte открыла в Минске клуб по программированию для детей

3 комментария

Обсуждение

8

Начав читать задачу, подумал про графы дейкстру комивояжора итд) а тут вот так оно)

-4

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

-2

гуглмэп для минска? я возможно отстал от жизни, но он вроде только кольцевую показывает)

0

Возможно вы просто не понимаете сарказма... И это хуже, чем просто отстать от жизни - последнее можно наверстать.

ЗЫ спросите у яндекса как из Минска доехать в Ставрополь (да и вообще в любую точку Краснодарского края) и спросите Илью Довбана, поедет ли он этим маршрутом. Тестировщики млин.

Владимир Исаев
Владимир Исаев Head of international PR в Яндекс
-1

а в чем проблема с маршрутом, простите? В том, что он по умолчанию идет через Украину? Ну да, это кратчайший по километражу. Если нужен кратчайший по времени - есть специальная галочка "в объезд пробок". Если на нее нажать - случится мэджик.

-1

Владимир, что случится?

30

ЗЫ
без галочки: Ехать 1 дн 4 ч 5 мин, 1 700 км
с галочкой: Ехать 1 дн 10 ч 3 мин, 2 000 км (через Калугу)

ЗЫ с галочкой 5мин. назад было на час меньше и на 100 км длиннее (через Москву), утром на 2 часа больше и те-же 2000 км (через Орёл)...

по уму объезжают пробки что бы быстрее попасть в точку В, пусть и чутка длиннее маршрут. У яндекса же - это всегда и длиннее и дольше, в чем смысл галочки?

действительно фееричный мэджик

Владимир Исаев
Владимир Исаев Head of international PR в Яндекс
0

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

14

Фееричный мэджик в том, что ваше утверждение "Если нужен кратчайший по времени - есть специальная галочка "в объезд пробок"" полностью противоречит результатам моих тестов. А результаты я приводил выше. С галочкой получается ВСЕГДА больше, и по времени и по расстоянию на указанном маршруте. И соответственно галочка что то меняет в расчетах, но совсем не то, что рядом с ней написано.

0

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

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

0

>он вроде только кольцевую показывает
складывается такое чувство, что вы были где то далеко (а может и не очень) без компьютеров и связи с внешним миром и буквально недавно "откинулись" так сказать.

Елена Мышенкова
Елена Мышенкова PR-менеджер в Новый сайт
0

Преподаватели Школы разработки интерфейсов собрали видеозаписи самых лучших докладов ШРИ за предыдущие годы, систематизировали их и объяснили, почему выбрана именно такая структура курса. Поэтому все желающие могут прослушать полную теоретическую программу самостоятельно: http://habrahabr.ru/company/yandex/blog/240373/