Школа распрацоўкі інтэрфейсаў: разбор заданняў для Мінска і новы набор у Маскве

Сёння адкрыўся новы набор у Школу распрацоўкі інтэрфейсаў Яндэкса у Маскве. З 7 верасня да 25 кастрычніка пройдзе першы этап навучання. Студэнты з іншых гарадоў змогуць у ім паўдзельнічаць дыстанцыйна ці вочна - кампанія аплаціць дарогу і пражыванне ў хостэле. Другі, ён жа фінальны этап працягнецца да 3 снежня, яго можна прайсці толькі вочна.

Мяне клічуць Юлія Сярэдзіч, гэтую пасаду мы напісалі разам з Сяргеем Казаковым. Мы абодва распрацоўшчыкі інтэрфейсаў у мінскім офісе Яндэкса і выпускнікі ШРІ мінулых гадоў.

Школа распрацоўкі інтэрфейсаў: разбор заданняў для Мінска і новы набор у Маскве

З нагоды адкрыцця рэгістрацыі ў Маскве мы публікуем разбор уступных заданняў у папярэднюю Школу - тут, у Мінску.

Калі прасачыць гісторыю заданняў ШРІ, то мы з года ў год правяралі тры важныя для праграміста навыку:

  • Вёрстка. Кожны распрацоўшчык павінен умець вярстаць. Не бывае такога, што ў вас ёсць дзядзька Сярожа, які вярстае для ўсёй каманды, а вы толькі пішаце скрыпты. Таму і кожны студэнт павінен паказаць, як ён умее вярстаць.
  • JavaScript. Калі б справа абмяжоўвалася вёрсткай, то ў нас была б не Школа распрацоўкі інтэрфейсаў, а Школа вярстальнікаў. Прыгожы звярстаны інтэрфейс трэба ажывіць. Таму заўсёды ёсць заданне на JS, але часам яно ж з'яўляецца і заданнем на алгарытмы - настолькі моцна мы іх кахаем.
  • Рашэнне праблем - мабыць, галоўны навык распрацоўніка. У стварэнні інтэрфейсаў усё вельмі хутка мяняецца. Гэта як у Люіса Кэрала: «Даводзіцца бегчы з усіх ног, каб толькі застацца на тым жа месцы, а каб патрапіць у іншае месца, трэба бегчы ўдвая хутчэй». Кожны дзень мы сутыкаемся з новымі тэхналогіямі - неабходна з імі лічыцца і ўмець у іх разабрацца. Таму ў трэцім заданні мы прапанавалі разабрацца ў тэхналогіях, з якімі пачынаючы распрацоўшчык звычайна не знаёмы.

У разборы кожнага задання мы раскажам не толькі аб правільным парадку дзеянняў, але і аб распаўсюджаных памылках.

Заданне 1: Партфоліа

Над першым заданнем працаваў дызайнер Яндэкс.Калекцый Аляксей Чаранкевіч, які ўмее вярстаць, і яго калега па сэрвісе — распрацоўшчык інтэрфейсаў Сяргей Самсонаў.

ўмова

Стварыце сайт-партфоліё: раскажыце пра сябе, свае працы і чаканні ад Школы. Сайт павінен максімальна адпавядаць прапанаванаму макету (спасылкі на макеты: 1000px, 600px, 320px, спецыфікацыя). Нас цікавіць толькі вёрстка, таму JavaScript просьба не выкарыстоўваць.

Пры праверцы мы будзем улічваць:

  • памеры водступаў, правільнасць колеру, напісанне шрыфтоў, памер кегля;
  • семантычную вёрстку;
  • наяўнасць розных станаў элементаў: адлюстраванне кнопак і спасылак пры навядзенні курсора, вылучэнне актыўных палёў уводу і г.д.;
  • кросбраузерность (правяраецца ў апошніх версіях папулярных браўзэраў).

Плюсам будзе:

  • выкарыстанне сучасных CSS-рашэнняў: flexbox, grid і інш.;
  • адаптыўная вёрстка;
  • выкарыстанне прэ- і (або) постпрацэсараў, зборка, мініфікацыя, аптымізацыя выхаднога кода;
  • HTML-валідацыя формы, стылізаваная кнопка загрузкі файлаў.

Заданне дастаткова аб'ёмнае, таму можна прапусціць тое, што не будзе атрымлівацца. Гэта крыху знізіць бал, але вы ўсё ж зможаце прадэманстраваць свае веды. Па завяршэнні працы дашліце нам дзве спасылкі - на партфоліё і зыходны код на GitHub.

Макеты, прапанаваныя ў заданні, былі не проста з экранамі для мабільных прылад, планшэтаў і дэсктопаў, але і з сапраўднай спецыфікацыяй.

Каб унесці ў вынік праверкі першага задання як мага больш аб'ектыўнасці, крытэрыяў гэтай праверкі было вельмі шмат.

крытэрыі

Звярстаны сайт. Гэта здаецца відавочным, але некаторыя хлопцы прапускалі некаторыя блокі цалкам - ці то хацелі зэканоміць час, ці то не змаглі зрабіць іх. Макет умоўна можна падзяліць на чатыры асноўныя экраны: галоўны экран з аватаркай, блок са спісам чаканняў ад ШРІ, блок з партфоліё і блок з кантактнай інфармацыяй. Іх можна было рабіць секцыямі або проста з дапамогай div, галоўнае - каб у наяўнасці былі ўсе чатыры блокі.

Адпаведнасць вёрсткі макету. Дызайнер зрабіў асобную спецыфікацыю (уключаючы колеры, друкарку, станы кнопак і іншае), каб кандыдатам было лягчэй. Унізе знаходзілася падказка па водступах і асаблівасцях першага экрана. Вельмі парадавалі хлопцы, якія ўлічылі ўсе пажаданні дызайнера: напрыклад, першы экран павінен быў атрымацца не менш вышыні ўюпарта.

Адаптыўная вёрстка — гэта калі інтэрфейс не проста звярстаны так, каб на трох дазволах усё было піксель у піксель па макеце. У прамежкавых станах вёрстка таксама не павінна развальвацца. Хтосьці забываўся абмежаваць максімальную шырыню кантэйнера і цягнуў усё на 1920 пікселяў, хтосьці напартачыў з фонамі, але ў цэлым кандыдаты справіліся з гэтай задачай добра.

Семантычная вёрстка. «Ужо колькі разоў паўтаралі міру», што спасылка павінна быць аформлена як , кнопка - як . На шчасце, большасць кандыдатаў выканалі і гэтае патрабаванне. Не ўсе распазналі які стаіўся спіс у чаканнях ад ШРИ, зрабіўшы яго пры дапамозе тэгаў div, але гэта не так страшна. Быў кандыдат, які ўставіў усе семантычныя тэгі, якія толькі ведаў - дзе трэба і дзе не трэба. Напрыклад, замест спісу - і . Усё-ткі семантыка - яна пра разуменне складу сваёй старонкі і прызначэнне кожнага блока (тут большасць зладзілася), а таксама пра выкарыстанне пре- і/або постпрацэсараў (тут зладзіліся нешматлікія, хоць гэта таксама было ў пунктах - часцей за ўсё падлучалі less і scss) .

Які працуе слайдэр. У заданні мы напісалі, што JS выкарыстоўваць нельга. Тут правяралася здольнасць вырашаць праблемы - слайдэр можна было зрабіць з дапамогай звязкі і . Уся магія адбываецца на ўзроўні селектара #button-N:checked ~ .slider-inner .slider-slides. Калі мы клікаем па адным з инпутов-чэкбоксаў, ён пераходзіць у стан checked. Мы можам гэтым скарыстацца і прызначыць патрэбны нам translate на кантэйнер са слайдамі: transform: translate(-33%). Рэалізацыю слайдэра можна паглядзець тут.

Раскрываюцца спісы. Тут усё таксама зводзілася да і падобнаму селектару: .accordion-item input:checked ~ .accordion-item__content. Рэалізацыю можна паглядзець тут.

Наяўнасць станаў :hover, :active і :focu*. Вельмі важны пункт. Ад яго залежаў камфорт падчас узаемадзеяння з інтэрфейсам. Карыстальнік заўсёды павінен атрымліваць зваротную сувязь аб сваіх дзеяннях. Гэты пункт правяраўся на працягу ўсяго ўзаемадзеяння з анкетай. Калі я націснуў кнопку "Патэлефануйце мне" і візуальна нічога не здарылася (хоць запыт і адправіўся) - гэта дрэнна, таму што затым я націсну яе зноў і зноў. У выніку адправіцца дзесяць запытаў і мне ператэлефануюць дзесяць разоў. Не трэба забываць і пра тое, што на мабільных прыладах няма мышы - а значыць, не павінна быць hover. І яшчэ адзін момант, які не закрануў тых, хто выканаў пункт пра семантыку. Калі ваш кантроль не з'яўляецца інтэрактыўным элементам, то пры навядзенні на яго курсор застанецца стандартным. Гэта выглядае вельмі неахайна, нават калі вы прапісалі рэакцыю на hover. Не варта недаацэньваць cursor: pointer.

Анімацыі. Важна, каб усе, што адбываліся з элементамі рэакцыі, былі плаўнымі. У жыцці няма нічога імгненнага, таму наяўнасці transitions на hover і active было дастаткова для таго, каб зрабіць інтэрфейс прыемней. Ну а тыя, хто анімаваў слайдэр і спісы, увогуле малайцы.

Выкарыстанне найноўшых тэхналогій. Многія выкарыстоўвалі flex, пры гэтым ніхто не выканаў заданне з дапамогай grid. Пункт залічваўся, калі flex выкарыстоўваўся пісьменна. Калі дзесьці вёрстка з-за гэтых самых flex раз'язджалася - нажаль, дадатковых балаў вы не атрымлівалі.

Валідацыя формы. Патрабавалася ўсяго толькі дапісаць у кожны input формы атрыбут required. Мы дадавалі бал тым, хто валідаваў поле электроннай пошты як email.

Стылізацыя кнопкі загрузкі файлаў. Мы чакалі ўбачыць звязак выгляду: і Абярыце файл . Далей трэба было схаваць input і стылізаваць label. Ёсць яшчэ адзін распаўсюджаны спосаб – зрабіць празрысты input і пакласці яго па-над кнопкай. Але не ўсе браўзэры дазваляюць стылізаваць , і такое рашэнне нельга назваць у поўнай меры кросбраўзерным. Ды і семантычна правільней зрабіць label.

Кросбраўзернасць. Мы правяралі, што ўсё добра, у двух апошніх версіях сучасных браўзэраў (без IE – удзельнікам павезла), а таксама ў Safari на айфонах і ў Chrome на андроідах.

Мы, наадварот, здымалі балы, калі хто-небудзь выкарыстоўваў JS ці Bootstrap: і тое і іншае пазбаўляла сэнсу ўсё заданне. Прычым удзельнікі з Bootstrap не толькі атрымлівалі мінус, але і недаатрымлівалі шмат балаў за семантыку і рэалізаваныя элементы.

Тыя, хто размеціў свой сайт дзе-небудзь у інтэрнэце, не атрымалі асаблівай перавагі - але правяраючыя вельмі радаваліся, калі не даводзілася спампоўваць рэпазітары і запускаць іх лакальна ў сябе на кампутары. Так што гэта служыла плюсам у карму.

Першае заданне было вельмі карысным у першую чаргу для студэнта. У тых, каго мы не прынялі, зараз ёсць звярстанае рэзюмэ - можна ганарліва прымацоўваць яго да ўсіх водгукаў або выкласці на свой gh-pages.

Заданне 2: Транспартны шлях

Аўтар задання - кіраўнік групы пошукавых інтэрфейсаў Дзяніс Балыка.

ўмова

У вас ёсць карта зорнага неба. На ёй указана назва кожнай зоркі, а таксама адлегласць ад яе да іншых зорак у светлавых секундах. Рэалізуйце функцыю solution, якая павінна прымаць тры аргументы: аб'ект, у якім ключамі з'яўляюцца назвы зорак, а значэннямі - адлегласці да зорак (у космасе аднабаковы рух), а таксама назвы пачатковай і канчатковай кропкі шляху - start і finish адпаведна. Функцыя павінна вяртаць найкароткую адлегласць ад зоркі start да зоркі finish і шлях, па якім трэба прайсці.

Сігнатура функцыі:

const solution = function(graph, start, finish)  {
    // Ваше решение
} 

Прыклад уваходных дадзеных:

const graph = {
  start: { A: 50, B: 20 },
  A: { C: 40, D: 20 },
  B: { A: 90, D: 90 },
  C: { D: 160, finish: 50 },
  D: { finish: 20 },
  finish: {}
};
const start = 'start';
const finish = 'finish'; 

Прыклад выходных дадзеных:

{
    distance: 90,
    path: ['start', 'A', 'D', 'finish']
} 

Нататка: каркас рашэння знаходзіцца ў тэчцы src/, змесціце сваё рашэнне ў solution.js.

Праверка другога задання была самай аўтаматызаванай і аб'ектыўнай. Большасць рабят здагадаліся, што неабходна рэалізаваць алгарытм Дэйкстры. Тыя, хто знайшоў яго апісанне і рэалізаваў алгарытм на JS, - малайцы. Аднак пры праверцы задання мы сустрэлі шмат прац з аднолькавымі памылкамі. Мы пашукалі ў інтэрнэце па фрагментах кода і знайшлі артыкул, адкуль удзельнікі спісалі алгарытм. Цікава, што многія капіравалі код з артыкула разам з каментарамі аўтара. Такія працы атрымалі нізкі бал. Мы не забараняем карыстацца любымі крыніцамі, але хочам, каб чалавек унікаў у тое, што ён піша.

крытэрыі

Асноўныя балы налічваліся за тэсты. Часам было відаць, што хлопцы пагаспадарылі ў рэпазітары, пераназваўшы тэчкі, і тэсты падалі проста таму, што не маглі знайсці патрэбныя файлы. У гэтым годзе мы стараліся дапамагчы такім хлопцам і вярталі ўсё на месца за іх. Але ў наступным годзе мы плануем перайсці на сістэму кантэстаў, і такое ўжо не будзе развітвацца.

Былі і "чалавечыя", ручныя крытэры. Напрыклад - наяўнасць адзінага кодстайла. Ніхто не зніжаў балы за тое, што вы выкарыстоўваеце табы замест прабелаў ці наадварот. Іншая справа, калі вы чаргуеце адзінкавыя двукоссі з падвойнымі па адным вам вядомаму правілу, а кропкі з коскамі ставіце ўразнобой.

Асобна ўлічвалася зразумеласць і чытальнасць рашэння. На ўсіх канферэнцыях свету расказваюць, што работа праграміста на 80% складаецца з чытання чужога кода. Нават школьнікі праходзяць кодрэўю - у сваіх куратараў і адзін аднаго. Так што гэты крытэр меў значную вагу. Сустракаліся працы, у якіх не было зменных даўжэй аднаго знака - калі ласка, не рабіце так. Вельмі цешылі каментары ўдзельнікаў - за выключэннем тых, якія былі ідэнтычныя каментарам Стэлы Чанг.

Апошні крытэр - наяўнасць аўтатэстаў. Іх дадалі ўсяго некалькі чалавек, але для кожнага гэта стала вялізным плюсам у карму.

Правільнае рашэнне:

const solution = function(graph, START, FINISH)  {
    // Всё не бесплатно в этом мире
    const costs = Object.assign({[FINISH]: Infinity}, graph[START]);

    // Первая волна родительских нод
    const parents = { [FINISH]: null };
    Object.keys(graph[START]).reduce((acc, child) => (acc[child] = START) && acc, parents)

    const visited = [];
    let node;

    // Ищем «дешёвого» родителя, отмечаем пройденные
    do {
        node = lowestCostNode(costs, visited);
        let children = graph[node];
        for (let n in children) {
            let newCost = costs[node] + children[n];

            // Ещё не оценена или нашёлся более дешёвый переход
            if (!costs[n] || costs[n] > newCost) {
                costs[n] = newCost;
                parents[n] = node;
            }
        }
        visited.push(node);
    } while (node)

    return {
        distance: costs[FINISH],
        path: optimalPath(parents)
    };

    // Возврат назад по самым «дешёвым» родителям
    function optimalPath(parents) {
        let optimalPath = [FINISH];
        let parent = parents[FINISH];
        while (parent && parent !== START) {
            optimalPath.push(parent);
            parent = parents[parent];
        }
        optimalPath.push(START);
        return optimalPath.reverse();
    }

    // Минимальная стоимость из текущей ноды среди непросмотренных
    function lowestCostNode(costs, visited) {
        return Object.keys(costs).reduce((lowest, node) => {
            if (lowest === null || costs[node] < costs[lowest]) {
                if (!visited.includes(node)) {
                    lowest = node;
                }
            }

            return lowest;
        }, null);
    };
};

Заданне 3: Каляндар падзей

Яго падрыхтавалі распрацоўшчыкі інтэрфейсаў Сяргей Казакоў і Аляксандр Падскрабкін.

ўмова

Напішыце міні-каляндар для адлюстравання раскладу. Можна ўзяць любы расклад, які вам спадабаецца. Напрыклад, расклад фронтэнд-канферэнцый у 2019 годзе.

Каляндар павінен выглядаць, як спіс. Іншых патрабаванняў да дызайну няма. Зрабіце магчымасць ставіць напамінкі аб падзеі за 3, 7 і 14 дзён. Пасля першай загрузкі з інтэрнэтам каляндар павінен адчыняцца і функцыянаваць у афлайне.

карысныя рэсурсы

Расклад фронтэнд-канферэнцый:
confs.tech/javascript?topics=javascript%2Bcss%2Bux

Service workers:
developer.mozilla.org/be/docs/Web/API/Service_Worker_API/Using_Service_Workers
developers.google.com/web/fundamentals/primers/service-workers

Notifications API:
developer.mozilla.org/be/docs/Web/API/Notifications_API

Трэцяе заданне было самым цікавым для праверкі, бо знайшлося вельмі шмат варыянтаў рашэння, у кожнага свой. Мы правяралі, як кандыдат звяртаецца з незнаёмымі тэхналогіямі — ці ўмее даследаваць, ці тэсціруе свае рашэнні.

крытэрыі

Звярстаны каляндар. Так, яго ўсё ж патрабавалася звярстаць. Былі і тыя, хто зразумеў умову занадта літаральна і не ўставіў ні радкі CSS-кода. Гэта выглядала не вельмі прыемна, але калі ўсё працавала - балы не зніжаліся.

Атрыманне спісу падзей з крыніцы. Гэта ўжо заданне не на вёрстку, таму ўшыты ў яе спіс мерапрыемстваў не залічваўся. Заўсёды можна адмяніць канферэнцыю, перанесці яе, дадаць новую. Так што патрабавалася атрымліваць дадзеныя звонку і рэндэрыць вёрстку ўжо на аснове атрыманага JSON. Важна было якім заўгодна спосабам (метадам fetch або з дапамогай XMLHttpRequest) атрымаць дадзеныя. Калі чалавек дадаваў паліфіл для fetch і пазначаў у readme свой выбар - гэта залічвалася як плюс.

Рэгістрацыя service worker без памылак і праца ў афлайне пасля першай загрузкі. Вось прыклад service worker з кэшаваннем раскладу на першай загрузцы. Падрабязнасці пра service workers, іх магчымасці і спосабы працы з імі (стратэгіі працы з кэшам, працу ў афлайне) можна паглядзець тут.

Магчымасць усталяваць напамін, Каб яно сапраўды спрацавала праз 3, 7, 14 дзён. Трэба было разабрацца ў Notifications API, спасылка на які знаходзілася проста ў заданні. Мы не чакалі нейкай канкрэтнай рэалізацыі праверкі таго, ці надышоў час для пуша. Прымаўся любы які працуе варыянт: захоўванне ў localStorage, IndexDB або перыядычнае апытанне сэрвіс-воркерам. Можна было нават зрабіць пуш-сервер (вось прыклад), але ў афлайне ён бы не працаваў. Не менш важна было атрымаць пуш пасля таго, як старонку закрылі - і адкрылі праз нейкі час. Калі напамінак «паміраў» адначасова з закрыццём старонкі, рашэнне не залічвалася. Стромка, калі хлопцы думалі пра правяраючых і рабілі магчымасць атрымаць пуш прама цяпер - каб не чакаць 3 дні.

Магчымасць вынесці абразок на працоўны стол (PWA). Мы правяралі наяўнасць файла manifest.json з правільнымі абразкамі. Некаторыя хлопцы зрабілі гэты файл (ці пакінулі згененераваны ў CreateReactApp) — але не дадалі дакладныя абразкі. Тады пры спробе ўсталёўкі ўзнікала памылка выгляду «патрэбны іншы абразок».

Кодстайл і структура праекта. Як і ў другім заданні, мы глядзелі на адзіны кодстайл (нават калі ён не супадаў з нашым). Некаторыя хлопцы прыкручвалі лінтэры - гэта выдатна.

Памылкі ў кансолі. Калі проста ў кансолі быў індыкатар, што нешта не так, а ўдзельнік не звяртаў на яго ўвагу, то мы здымалі балы.

Вынікі

Пацешнае ў рашэннях удзельнікаў:

  • Адна анкета змяшчала наступны тэкст: «Сабраць рэакт-дадатак дапамог сябар праграміст. Я яго закідваў пытаннямі што як і чаму, ён расказваў. Вельмі спадабалася, хачу больш даведацца пра гэта». Мы ўсім сэрцам хварэлі за гэтую анкету, але на жаль, сябар кандыдата не вельмі дапамог яму зрабіць працуючае прыкладанне.
  • Адзін кандыдат даслаў спасылку на GitHub, дзе ляжаў RAR-архіў - складана гэта неяк пракаментаваць. 🙂
  • Яшчэ адзін кандыдат у каментары першага радка файла solution.js сапраўды прызнаўся, што скапіяваў алгарытм.

Мы атрымалі анкеты ад 76 кандыдатаў і адабралі з іх 23 чалавекі. Нам дасылалі анкеты не толькі з Мінска, але і з Масквы, Санкт-Пецярбурга і нават Татарстана. Некаторыя хлопцы здзівілі сваімі цяперашнімі прафесіямі: адзін з іх судмедэксперт, а другі - студэнт медыцынскай ВНУ.

Атрымалася цікавае размеркаванне паспяховасці выканання заданняў. З першым заданнем удзельнікі справіліся ў сярэднім на 60%, з другім — на 50%, а трэцяе аказалася самым складаным і яго выканалі ў сярэднім на 40%.

На першы погляд, заданні выглядаюць складанымі і працаёмкімі. Прычына не ў тым, што мы хочам адсеяць як мага больш кандыдатаў. Падчас навучання студэнты сутыкаюцца з рэальнымі задачамі - зрабіць чат, Яндекс.Музыку для дзяцей або Яндекс.Надвор'е для метэазалежных людзей. Для гэтага патрэбная стартавая база.

Я памятаю, як убачыла сваё ўступнае заданне ў ШРІ два гады таму і падумала, што мне яго ніколі не вырашыць. Галоўнае ў гэты момант - сесці, добра ўчытацца ва ўмовы і пачаць рабіць. Аказваецца, ва ўмовах змяшчаецца практычна 80 працэнтаў рашэння. Напрыклад, ва ўмову трэцяга задання (самага складанага) мы дадалі спасылкі на service workers і Notifications API на MDN. Студэнты, якія вывучылі змесціва спасылак, справіліся без цяжкасцей.

Вельмі хочацца, каб гэты артыкул прачыталі кандыдаты, якія плануюць паступаць у ШРІ надалей, не змаглі паступіць у мінскую Школу ці пачынаюць рабіць любое іншае тэставае заданне. Як бачыце, паступіць цалкам рэальна. Трэба толькі верыць у свае сілы і слухаць усе падказкі аўтараў.

Крыніца: habr.com

Дадаць каментар