Pull to refresh
520.94
Яндекс
Как мы делаем Яндекс

Третий набор в Школу разработки интерфейсов Яндекса. Разбор вступительных заданий и полезные советы

Reading time 10 min
Views 32K
Осталось совсем немного до окончания набора в третью Школу разработчиков интерфейсов, которая в этот раз пройдёт в Москве. Упор в ней будет сделан на практику в формате виде мини-хакатонов. Его мы уже опробовали в прошлом году в Минске и Екатеринбурге. Студенты будут делиться на команды, и уже командно реализовывать проект. Кроме написания самого кода, нужно будет уметь принимать решения, разбираться с возникшими спорными вопросами, разбивать весь процесс разработки на логические итерации. Помогать в этом будут ребята из Яндекса, которые будут работать индивидуально с каждой командой. Занятия начнутся 7 сентября.

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

Вступительное испытание в Школу тоже очень практическое. Мы закончим принимать заявки 16 августа в 23:59. Пока есть еще время справиться с заданиями, мы попросили наших преподавателей немного помочь будущим студентам и на примере прошлогодней анкеты объяснить, какой логикой стоит руководствоваться, решая предложенные задачи, и рассказать, чему они уделяют внимание при их проверке.

image

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

Задание 1


Автор задания и разбора — Олег Olegbl4 Мохов. В Яндексе руководит разработкой интерфейсов нескольких сервисов, а вне Яндекса организует конференции FrontTalks, EkbJS и ChellyJS и читает спецкурс по разработке интерфесов в УрФу.

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

Решение


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

Конечно, решения данного задания можно найти в просторах интернета за условные пять минут. И оно, например, может быть таким: css-tricks.com/centering-css-complete-guide. Поэтому при реализации было немаловажно кроме количества решений привести ещё и пояснения, где какое стоит использовать. Например, мы намеренно не стали писать, что размеры элемента можно задавать, и в некоторых решениях это приемлемо. Также мы уделяли внимание таким вещам, как CodeStyle, именование классов или id'шников элементов, использование семантических тегов и вообще культуру оформления вёрстки (сборка, разбиение на файлы).

Давайте рассмотрим возможные решения. Для начала пусть мы знаем ширину элемента. Тогда есть такие варианты:

  1. margin-left и margin-right в auto. Это, пожалуй, самое распостранённое использование отступной математики блочных элементов.
  2. В ту же копилку решение с заданием position: absolute; left: 50%; margin-left: <-половина ширины>. И это второй по популярности способо справиться с ним.
  3. Модификация первого варианта для position: absolute блоков. В этом решении важно задать не только автоматические margin'ы, но и left: 0; right: 0;

Решения центровать элемент по вертикали с заданной высотой рассматривать не очень интересно, так как это, скорее всего, вариация решений по горизонтали. Поэтому далее решения для элементов с неизвестными шириной и высотой:
  1. Положить элемент внутрь ячейки таблицы, для которой заданы выравнивания по середине. Пожалуй раньше, когда был IE6, это был самый пуленепробиваемый способ.
  2. Воспользоваться JavaScript. А что, тоже вполне себе решение.
  3. Более современное решение. Задать элементу inline-block display и родителю выравнивание текста по центру (text-align: center). А для центрования по вертикали псевдоэлементу ::before задать высоту 100%, ширину 0, line-height 100% и vertical-align: middle.
  4. Более современные решения – это использование CSS-функции calc.
  5. Или особенности того, что transform, заданный в процентах, считается от размеров элемента.
  6. И, наконец, флексбоксы, причем ими тоже можно по-разному центровать, потому что есть align-items, есть justify-content, а ещё можно менять направление вывода флексовых блоков через flex-direction.

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

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

Ещё два решения мне подкинули студенты первой ШРИ в Екатеринбурге.

Способ Юли Горшковой. Она придумала следующее: положить элемент в среднюю ячейку таблицы с тремя ячейками и растянутой на 100%, а правой и левой колонкам задать ширину 50%. Зная о том, что таблицы всегда пытаются максимально заполнить свободное пространство, можно сделать так, что элемент будет распирать среднюю ячейку до нужных себе размеров.

Способ Леонида Соломеина. Это мой самый любимый вариант — нужно просто положить элемент в .

Но есть самый прогрессивный способ, который, к сожалению, пока не поддерживается ни одним браузером. Как только это изменится, все 12 перечисленных решений канут в Лету. Это использование position: center.


Задание 2


Автор задания и разбора — Максим KidsKilla Гришаев. В Яндексе занимается разработкой Элементов для Firefox.

Есть страница с «эквалайзерами» — контейнеры произвольных размеров (квадраты 100px, 200px и 300px) заполняются столбцами шириной по 2px (задаётся параметром).

Каждую секунду столбцам задаётся случайная высота в пределах размеров контейнера. Далее при помощи анимации высота столбцов возвращается к середине контейнера. Реализация находится в файле: github.com/yandex-shri-minsk-2014/jade-task. Исходный код работает медленно и приводит к зависанию браузера. Нужно улучшить его так, чтобы анимация стала плавной. Изменять вёрстку необязательно, однако вы можете это сделать, если это поможет решить задачу. Работоспособность в IE ниже 8 не требуется. Желательно добавить помимо анимации «спада» ещё и анимацию «роста». По возможности оформите в качестве jQuery-плагина или напишите без jQuery.

Решение


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

  • наличие ошибок в поведении;
  • удобство чтения, единообразность кода;
  • легкость понимания взаимосвязей;
  • скорость работы;
  • наличие «велосипедов», когда можно воспользоваться уже готовыми рабочими решениями.

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

Но были и другие способы улучшить код и произвести впечатление на судей.
  • Привести именование переменных к единому стилю. Очень сложно читать код, где нет единых правил оформления.
  • Разбить код на более мелкие методы. Куда проще прочитать маленький, логически цельный метод, длиною в 5-10 строк, чем «спагетти-код».
  • Сократить кол-во таймеров. Работая с анимаций множества элементов, логично использовать какой-то общий аниматор с единым таймером, который за за одну итерацию обновит сразу всё.
  • Запускать код так рано, как это возможно. В коде использовалось событие window.onload, но куда логичнее было бы использовать событие DOMContentLoaded или просто поставить вызов анимации под блоком.
  • Оптимизировать CSS. В задании анимируется span (display: inline-block). Он привязан к размерам шрифта, строки и прочего окружения и влияет на reflow/repaint всей страницы. Абсолютное анимируемых элементов даст прирост производительности.
  • Оформить код как независимый модуль. Слово модуль в данном контексте можно трактовать довольно широко: это мог быть плагин для jQuery или отдельный «класс». Например, не сразу понятно что значат аргументы при вызове функции: setEqualizer('#eq_1 .equalizer', 1000, 2);. Однако вот так уже гораздо лучше: $('#eq_1 .equalizer').equalizer({itemWidth: 2, animationDuration: 1000}). Или вот так: new Equalizer('#eq_1 .equalizer').setItemWidth(2).setAnimationDuration(1000).start().
  • Применить технологии, более приспособленные для анимации: css, canvas, а то и WebGL.

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


Задача 3*


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

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

При помощи d3.js сделайте интерактивную визуализацию произвольного массива точек, которые плавно и неравномерно меняют цвет от красного к жёлтому и обратно, находятся в броуновском движении и «убегают» от курсора.

Решение


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

Для начала стоит разобраться с тем, что же это за d3.js. Первый же визит на официальный сайт библиотеки показывает, что это не очередная обертка над WebGL для 3d-графики (на что могло намекать название), а очень большой набор средств для визуализации и анимации различных видов данных. Что ж, принципиально новой тут оказалась не только библиотека, но и вся предметная область. Так что не подойдет вариант быстро просмотреть API-документацию нового, но концептуально такого же MVC-фреймворка. Придется начать с чтения tutorial-ов.

Из ознакомительной части стало понятно, что библиотека оперирует наборами данных. В нашем случае это будет набор точек, о каждой из которых известны ее цвет и координаты. Да, и раз уж мы делаем прототип о «разробраться с библиотекой», лучше сразу начать по максимуму использовать ее возможности. Например, d3.range вместо создания массива точек вручную:

 var dots = d3.range(1000);

d3.select('svg').selectAll('circle')
.enter().append('circle');

Тут же заодно проверим, что наши точки нормально выводятся на svg-холсте.

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

И для того, и для другого в d3.js есть функции-хелперы, ими и воспользуемся.

На что обращают внимание при проверке



Евгений FTDeBUGgeR Шпилевский — руководитель разработки интерфейсов прикладных сервисов поиска в минском офисе Яндекса.

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

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

При проверке JS-кода для меня было важно увидеть качественный код, как с точки зрения структуры, так и алгоритмической стороны. В целом я и исходил из тех же принципов, которыми руководствуюсь на код ревью. Хотел бы я видеть этот код в своем репозитории? Готов ли я его поддержать? В итоге самый беспощадный отбор. Минусом было смешение парадигм и нарушение принципов DRY и KISS, ошибки выявленные WebStorm/jshint, неконсистентность логики и подходов. Грубой ошибкой было наличие ошибок в консоле инструментов разработчика.

Использование методологии БЭМ было плюсом при проверке CSS. Также плюсом были количество и лаконичность найденных решений. Минусы ставил только за использование сложных селекторов и селекторов по идентификатору.

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


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

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

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

Отдельно хотелось бы добавить комментарии к каждому заданию:

Задание на верстку. Многие пытались решать эту задачу только средствами CSS и HTML и даже использовали селекторы на фрагменты страницы (:target), чтобы открывать окна. Однако формулировка задания никак не ограничивает использование JavaScript для открытия и центрирования окна. Я согласен, что использовать JavaScript для решения задач верстки не очень хорошо, но если вы продемонстрируете свои знания и оцените свои решения, то это безусловно плюс.

Задание про улучшение кода. У меня сложилось впечатление, что мало кто исследовал исходный код и попытался понять, в чем же причина возникновения тормозов (а уж написать о результате своих исследований точно никто не удосужился). Кто-то, видя «чужой» код на jQuery, переписывал его полностью (даже отказывался от использования библиотеки), пытаясь исправить недостатки кода. На мой взгляд, хорошенько подеббажить исходный код и поправить его, было бы лучше, чем переписывать его полность. Это и выгоднее по времени, и даст понимание проблемы, которое убережет от будущих ошибок.

Задание про «неизвестную» технологию: d3.js Оно было объемным и творческим. С одной стороны интересно посмотреть как ребята осваивают новые интрументы, а с другой — кто же все-таки знает, что такое броуновское движение :) К сожалению, задание выполнили не все, и я бы пожелал ребятам не откладывать заполнение анкеты и начать делать это уже сейчас.

Занятия в Школе начнутся 7 сентября в московском офисе Яндекса. Теоретическое изучение и разбор материалов будет проходить в будние дни с 18:00 до 20:00, а по субботам будет практика в форме хакатонов. Обучение бесплатное.
Tags:
Hubs:
+28
Comments 23
Comments Comments 23

Articles

Information

Website
www.ya.ru
Registered
Founded
Employees
over 10,000 employees
Location
Россия
Representative