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

Залишилося зовсім небагато до закінчення набору в третю Школу розробників інтерфейсів, яка в цей раз пройде в Москві. Упор буде зроблений на практику у форматі вигляді міні-хакатонов. Його ми вже випробували в минулому році в Мінську і Єкатеринбурзі. Студенти будуть ділитися на команди, і вже командно реалізовувати проект. Крім написання самого коду, потрібно буде вміти приймати рішення, розбиратися з виниклими спірними питаннями, розбивати весь процес розробки на логічні ітерації. Допомагати в цьому будуть хлопці з Яндекса, які будуть працювати індивідуально з кожною командою. Заняття розпочнуться 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 блоків. У цьому рішенні важливо встановити не тільки автоматичні магдіп'и, але і 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%. Знаючи про те, що таблиці завжди намагаються максимально заповнити вільний простір, можна зробити так, що елемент буде розпирати середню комірку до потрібних розмірів собі.

Спосіб Леоніда Соломеина. Це мій улюблений варіант — потрібно просто покласти елемент
<button></button>.


Але є найбільш прогресивний спосіб, який, на жаль, поки не підтримується жодним браузером. Як тільки це зміниться, всі 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 або окремий «клас». Наприклад, не одразу зрозуміло що означають аргументи при виклику функції:
    zer('#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, а по суботах буде практика у формі хакатонов. Навчання безкоштовне.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.