Școală de dezvoltare a interfeței: analiza sarcinilor pentru Minsk și un nou set la Moscova

Astăzi s-a deschis o nouă înscriere în Şcoala de dezvoltare a interfeţei Yandex in Moscova. Prima etapă de pregătire va avea loc în perioada 7 septembrie – 25 octombrie. Studenții din alte orașe vor putea participa la aceasta de la distanță sau în persoană - compania va plăti pentru călătoria și cazarea într-un cămin. Cea de-a doua, tot etapa finală, va dura până pe 3 decembrie, putând fi parcursă doar personal.

Numele meu este Iulia Seredich, am scris această postare împreună cu Serghei Kazakov. Suntem amândoi dezvoltatori de interfețe în biroul Yandex din Minsk și absolvenți ai SRI din anii precedenți.

Școală de dezvoltare a interfeței: analiza sarcinilor pentru Minsk și un nou set la Moscova

Cu ocazia deschiderii înscrierilor la Moscova, publicăm o analiză a sarcinilor introductive la școala anterioară - aici, la Minsk.

Dacă urmăriți istoria misiunilor SRI, de la an la an am testat trei abilități importante pentru un programator:

  • Aspect. Fiecare dezvoltator ar trebui să poată face aspectul. Nu se întâmplă să ai unchiul Seryozha care proiectează pentru întreaga echipă și să scrii doar scenarii. Prin urmare, fiecare elev trebuie să arate cum știe să scrie.
  • JavaScript. Dacă problema s-ar limita la aspect, atunci nu am avea o școală de dezvoltare a interfeței, ci o școală de designeri de layout. Interfața frumos proiectată trebuie reînviată. Prin urmare, există întotdeauna o sarcină pentru JS, dar uneori este și o sarcină pentru algoritmi - îi iubim atât de mult.
  • Rezolvarea problemelor este poate cea mai importantă abilitate a unui dezvoltator. Când vine vorba de crearea de interfețe, lucrurile se schimbă foarte repede. Este ca Lewis Carroll: „Trebuie să alergi cât de repede poți doar pentru a rămâne în același loc, iar pentru a ajunge în alt loc trebuie să alergi de două ori mai repede”. În fiecare zi întâlnim noi tehnologii – trebuie să ținem cont de ele și să le putem înțelege. Prin urmare, în a treia sarcină, ne-am propus să înțelegem tehnologii cu care un dezvoltator începător nu este de obicei familiarizat.

În analiza fiecărei sarcini, vă vom spune nu numai despre procedura corectă, ci și despre greșelile comune.

Sarcina 1: Portofoliu

Prima sarcină a fost lucrată de designerul Yandex.Collections Alexey Cherenkevich, care știe să facă layout, și colegul său de serviciu, dezvoltatorul de interfețe Sergey Samsonov.

Condiție

Creați un site web de portofoliu: spuneți-ne despre tine, despre munca ta și despre așteptările tale de la școală. Site-ul trebuie să corespundă cât mai mult posibil cu aspectul propus (link-uri către machete: 1000px, 600px, 320px, specificație). Suntem interesați doar de aspect, așa că vă rugăm să nu folosiți JavaScript.

La verificare vom lua în considerare:

  • dimensiunile indentării, corectitudinea culorii, stilul fontului, dimensiunea fontului;
  • aspect semantic;
  • prezența diferitelor stări de elemente: afișarea butoanelor și link-urilor la trecerea cursorului, evidențierea câmpurilor de introducere active etc.;
  • compatibilitate între browsere (testată în cele mai recente versiuni ale browserelor populare).

Avantajul va fi:

  • utilizarea soluțiilor CSS moderne: flexbox, grid etc.;
  • Aspect adaptiv;
  • utilizarea pre- și (sau) post-procesoare, asamblare, minificare, optimizare a codului de ieșire;
  • Validare formular HTML, buton de încărcare a fișierelor stilizate.

Sarcina este destul de voluminoasă, așa că puteți sări peste ceea ce nu va funcționa. Acest lucru vă va scădea ușor scorul, dar veți putea în continuare să vă demonstrați cunoștințele. Când ați terminat, trimiteți-ne două linkuri - către portofoliul dvs. și codul sursă de pe GitHub.

Aspectele propuse în sarcină nu au fost doar cu ecrane pentru dispozitive mobile, tablete și desktop-uri, ci și cu specificații reale.

Pentru a aduce cât mai multă obiectivitate în rezultatul verificării primei sarcini, au existat o mulțime de criterii pentru această verificare.

criterii

Site proiectat. Acest lucru pare evident, dar unii tipi au sărit cu totul unele blocuri - fie au vrut să economisească timp, fie nu au putut să le facă. Aspectul poate fi împărțit aproximativ în patru ecrane principale: ecranul principal cu un avatar, un bloc cu o listă de așteptări de la SRI, un bloc cu un portofoliu și un bloc cu informații de contact. Ele puteau fi realizate în secțiuni sau pur și simplu folosind div-uri, principalul lucru este că toate cele patru blocuri erau disponibile.

Conformitatea aspectului cu aspectul. Designerul a făcut o specificație separată (inclusiv culori, tipografie, stări ale butoanelor etc.) pentru a le ușura candidaților. În partea de jos era un indiciu despre indentările și caracteristicile primului ecran. Am fost foarte mulțumit de băieții care au ținut cont de toate dorințele designerului: de exemplu, primul ecran ar fi trebuit să fie nu mai mic decât înălțimea ferestrei.

Aspect adaptiv - acesta este momentul în care interfața nu este doar aranjată astfel încât la trei rezoluții totul este pixel la pixel în aspect. În stările intermediare, nici aspectul nu ar trebui să se destrame. Unii au uitat să limiteze lățimea maximă a containerului și să seteze totul la 1920 de pixeli, unii au încurcat fundalul, dar în general candidații au făcut față bine acestei sarcini.

Aspect semantic. „De câte ori au spus lumii” că linkul ar trebui să fie conceput ca , butonul – ca . Din fericire, majoritatea candidaților au îndeplinit și această cerință. Nu toată lumea a recunoscut lista ascunsă în așteptările SRI, făcând-o folosind etichete div, dar nu este chiar așa de rău. A fost un candidat care a introdus toate etichetele semantice pe care le știa – unde era necesar și unde nu. De exemplu, în loc de o listă - și . La urma urmei, semantică - este vorba despre înțelegerea compoziției paginii tale și a scopului fiecărui bloc (majoritatea l-a gestionat aici), precum și despre utilizarea pre- și/sau post-procesoare (câțiva au reușit-o aici, deși acest lucru a fost și în puncte - cel mai adesea au folosit mai puțin și scss) .

Glisor de lucru. În sarcină am scris că JS nu poate fi folosit. Aici a fost testată capacitatea de a rezolva probleme - un glisor ar putea fi realizat folosind o grămadă Și . Toată magia se întâmplă la nivelul selectorului #button-N:checked ~ .slider-inner .slider-slides. Când facem clic pe una dintre casetele de selectare de intrare, aceasta intră în starea bifată. Putem profita de acest lucru și atribuim traducerea de care avem nevoie containerului cu slide-urile: transform: translate(-33%). Puteți vedea implementarea glisorului aici.

Liste derulante. Aici totul s-a rezumat și un selector similar: .acordion-item input:checked ~ .accordion-item__content. Puteți vedea implementarea aici.

Disponibilitatea stărilor :hover, :active și :focu*. Un punct foarte important. De el depindea confortul în timpul interacțiunii cu interfața. Utilizatorul ar trebui să primească întotdeauna feedback cu privire la acțiunile sale. Acest item a fost verificat pe parcursul interacțiunii cu chestionarul. Dacă am făcut clic pe butonul „Apelați-mă” și vizual nu s-a întâmplat nimic (chiar dacă solicitarea a fost trimisă), acest lucru este rău, pentru că atunci voi face clic pe el din nou și din nou. Ca urmare, vor fi trimise zece cereri și voi fi sunat înapoi de zece ori. Nu trebuie să uităm că dispozitivele mobile nu au mouse, ceea ce înseamnă că nu ar trebui să existe un hover. Și încă un punct care nu i-a afectat pe cei care au îndeplinit punctul despre semantică. Dacă controlul dvs. nu este un element interactiv, atunci când treceți cu mouse-ul peste el, cursorul va rămâne standard. Pare foarte dezordonat, chiar dacă ați scris o reacție la hover. Nu subestima cursorul: pointerul.

Animații. Este important ca toate reacțiile care apar cu elementele să fie netede. Nimic în viață nu este instantaneu, așa că a avea tranziții pe hover și activ a fost suficient pentru a face interfața mai plăcută. Ei bine, cei care au animat glisorul și listele sunt în general grozavi.

Folosind cea mai recentă tehnologie. Mulți oameni au folosit flex, dar nimeni nu a finalizat sarcina folosind grid. Punctul a fost numărat dacă flex a fost folosit corect. Dacă undeva aspectul s-a destrămat din cauza acestor flexiuni, din păcate, nu ați primit niciun punct suplimentar.

Validarea formularului. Tot ceea ce era necesar a fost să adăugați atributul necesar la fiecare intrare a formularului. Am adăugat puncte celor care au validat câmpul de e-mail ca e-mail.

Stilul butonului de încărcare a fișierului. Ne așteptam să vedem o combinație ca: și Selectați fișierul . Apoi trebuia să ascundem intrarea și să stilăm eticheta. Există o altă modalitate comună - de a face o intrare transparentă și de a o pune deasupra butonului. Dar nu toate browserele permit stilul , iar o astfel de soluție nu poate fi numită complet cross-browser. Și din punct de vedere semantic este mai corect să faci o etichetă.

Compatibilitate între browsere. Am verificat că totul este în regulă în cele mai recente două versiuni ale browserelor moderne (fără IE - participanții au fost norocoși), precum și în Safari pe iPhone și Chrome pe Android.

Dimpotrivă, am dedus puncte dacă cineva a folosit JS sau Bootstrap: ambele ar învinge scopul întregii sarcini. Mai mult, participanții cu Bootstrap nu numai că au primit un minus, dar au și pierdut multe puncte pentru semantică și elemente implementate.

Cei care și-au găzduit site-ul undeva pe Internet nu au primit niciun avantaj anume - dar recenzenții au fost foarte fericiți când nu au fost nevoiți să descarce depozite și să le ruleze local pe computerul lor. Deci asta a servit ca un plus pentru karma.

Prima sarcină a fost foarte utilă în primul rând elevului. Cei pe care nu i-am acceptat acum au un CV pregătit - îl puteți atașa cu mândrie la toate răspunsurile sau îl puteți posta pe paginile dvs. gh.

Sarcina 2: Ruta de transport

Autorul sarcinii este șeful grupului de interfețe de căutare Denis Balyko.

Condiție

Ai o hartă cu stele? Afișează numele fiecărei stele, precum și distanța de la aceasta la alte stele în secunde lumină. Implementați funcția de soluție, care ar trebui să ia trei argumente: un obiect în care cheile sunt numele stelelor, iar valorile sunt distanțele până la stele (trafic unic în spațiu), precum și numele stelelor. punctele de început și de sfârșit ale traseului - început și, respectiv, sfârșit. Funcția ar trebui să returneze cea mai scurtă distanță de la steaua de start la steaua de sosire și calea de urmat.

Semnătura funcției:

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

Exemple de date de intrare:

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'; 

Exemplu de ieșire:

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

Notă: Scheletul soluției se află în folderul src/, puneți soluția în solution.js.

Verificarea celei de-a doua sarcini a fost cea mai automatizată și obiectivă. Majoritatea băieților au ghicit că este necesar să se implementeze algoritmul lui Dijkstra. Cei care au găsit descrierea acesteia și au implementat algoritmul în JS sunt bine făcut. Cu toate acestea, la verificarea sarcinii, am dat peste multe lucrări cu aceleași erori. Am căutat pe Internet fragmente de cod și am găsit un articol din care participanții au copiat algoritmul. Este amuzant că mulți au copiat codul din articol împreună cu comentariile autorului. Astfel de lucrări au primit un punctaj scăzut. Nu interzicem utilizarea niciunei surse, dar dorim ca o persoană să se aprofundeze în ceea ce scrie.

criterii

Principalele puncte au fost acordate pentru teste. Uneori era clar că băieții se încurcau cu depozitul, redenumeau folderele, iar testele eșuau pur și simplu pentru că nu puteau găsi fișierele necesare. Anul acesta am încercat să ajutăm astfel de băieți și am readus totul la locul său pentru ei. Dar anul viitor plănuim să trecem la un sistem de concurs, iar acest lucru nu va mai fi iertat.

Au existat și criterii „umane”, manuale. De exemplu, prezența unui singur stil de cod. Nimeni nu a dedus puncte pentru utilizarea tabulatorilor în loc de spații sau invers. Este o altă problemă dacă alternezi ghilimele simple cu ghilimele duble conform unei reguli cunoscute de tine și plasezi punct și virgulă la întâmplare.

Claritatea și lizibilitatea soluției au fost luate în considerare separat. La toate conferințele din lume se spune că 80% din munca unui programator constă în citirea codului altor persoane. Chiar și școlarii sunt supuși unor revizuiri de cod - de la curatorii lor și unii de la alții. Deci, acest criteriu a avut o greutate semnificativă. Au fost lucrări în care nu existau variabile mai lungi de un caracter - vă rog să nu faceți asta. Comentariile participanților au fost foarte încurajatoare - cu excepția celor care au fost identice cu comentariile lui Stella Chang.

Ultimul criteriu este prezența autotestelor. Doar puțini oameni le-au adăugat, dar pentru toată lumea a devenit un mare plus în karma lor.

Decizia corecta:

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);
    };
};

Sarcina 3: Calendarul evenimentelor

A fost pregătit de dezvoltatorii de interfețe Sergey Kazakov și Alexander Podskrebkin.

Condiție

Scrieți un mini-calendar pentru a vă afișa programul. Puteți lua orice program doriți. De exemplu, programul conferințelor frontend din 2019.

Calendarul ar trebui să arate ca o listă. Nu există alte cerințe de proiectare. Faceți posibilă setarea mementourilor pentru evenimente cu 3, 7 și 14 zile înainte. După prima descărcare de pe Internet, calendarul ar trebui să se deschidă și să funcționeze offline.

Resurse utile

Programul conferinței Frontend:
confs.tech/javascript?topics=javascript%2Bcss%2Bux

Lucrători de servicii:
developer.mozilla.org/ru/docs/Web/API/Service_Worker_API/Using_Service_Workers
developers.google.com/web/fundamentals/primers/service-workers

Notificări API:
developer.mozilla.org/ru/docs/Web/API/Notifications_API

A treia sarcină a fost cea mai interesantă de testat, pentru că erau atât de multe soluții posibile, fiecare cu propriile sale. Am verificat modul în care candidatul gestionează tehnologii necunoscute - dacă știe să cerceteze, dacă își testează soluțiile.

criterii

Calendar pliat. Da, mai trebuia aranjat. Au fost și cei care au luat condiția prea la propriu și nu au introdus o singură linie de cod CSS. Nu părea foarte atractiv, dar dacă totul a funcționat, punctele nu au scăzut.

Obținerea unei liste de evenimente dintr-o sursă. Aceasta nu este o sarcină de aspect, așa că lista de evenimente incluse în ea nu a fost numărată. Puteți oricând să anulați o conferință, să o reprogramați sau să adăugați una nouă. Deci a fost necesar să primim date din exterior și să redăm aspectul pe baza JSON-ului primit. Era important să obțineți datele în orice mod (folosind metoda fetch sau folosind XMLHttpRequest). Dacă o persoană a adăugat un polyfill pentru preluare și a marcat alegerea sa în readme, acest lucru a fost considerat un plus.

Înregistrarea lucrătorilor de service fără erori și lucrează offline după prima descărcare. Iată un exemplu lucrător de service cu memorarea în cache a programului la prima pornire. Detalii despre lucrătorii de servicii, capacitățile lor și modalitățile de lucru cu aceștia (strategii de lucru cu cache, lucru offline) pot fi găsite aici.

Abilitatea de a seta un mementoastfel incat sa functioneze efectiv dupa 3, 7, 14 zile. A fost necesar să înțelegem API-ul Notifications, link către care avea dreptate în sarcină. Nu ne așteptam la vreo implementare specifică pentru a verifica dacă este timpul să facem împingere. A fost acceptată orice opțiune de lucru: stocare în localStorage, IndexDB sau interogare periodică de către un lucrător al serviciului. A fost chiar posibil să se realizeze un server push (aici exemplu), dar nu ar funcționa offline. A fost la fel de important să primiți o împingere după ce pagina a fost închisă - și deschisă după ceva timp. Dacă mementoul a murit în același timp în care pagina a fost închisă, soluția nu a fost luată în considerare. Este grozav când băieții s-au gândit la recenzenți și au făcut posibil să obținem un impuls chiar acum - pentru a nu aștepta 3 zile.

Posibilitatea de a plasa o pictogramă pe desktop (PWA). Am verificat prezența fișierului manifest.json cu pictogramele corecte. Unii băieți au creat acest fișier (sau l-au lăsat generat în CreateReactApp) - dar nu au adăugat pictogramele corecte. Apoi, când încercați să instalați, a apărut o eroare precum „este necesară o pictogramă diferită”.

Stilul de cod și structura proiectului. Ca și în a doua sarcină, ne-am uitat la un singur stil de cod (chiar dacă nu a coincis cu al nostru). Unii băieți au înșurubat linters - asta e grozav.

Erori de consolă. Dacă chiar în consolă exista un indicator că ceva nu este în regulă și participantul nu i-a acordat atenție, atunci am dedus puncte.

Rezultatele

Ce este amuzant la deciziile participanților:

  • Un chestionar conținea următorul text: „Un prieten programator m-a ajutat să pun la punct o aplicație React. L-am bombardat cu întrebări despre cum și de ce și mi-a spus. Mi-a plăcut foarte mult, vreau să aflu mai multe despre el.” Am înrădăcinat această aplicație din toată inima, dar, din păcate, prietenul candidatului nu a fost de mare ajutor în a face aplicația să funcționeze.
  • Un candidat a trimis un link către GitHub, unde se afla arhiva RAR - este dificil să comentezi acest lucru. 🙂
  • Un alt candidat, în comentariul de la prima linie a fișierului solution.js, a recunoscut sincer că a copiat algoritmul.

Am primit cereri de la 76 de candidați și am selectat 23 de persoane. Ni s-au trimis chestionare nu numai din Minsk, ci și din Moscova, Sankt Petersburg și chiar Tatarstan. Unii dintre băieți ne-au surprins cu profesiile lor actuale: unul dintre ei este expert criminalist, iar celălalt este student la medicină.

Rezultatul a fost o distribuție interesantă a ratelor de succes în îndeplinirea sarcinilor. Participanții au finalizat prima sarcină cu o medie de 60%, a doua cu 50%, iar a treia s-a dovedit a fi cea mai dificilă și a fost finalizată în medie cu 40%.

La prima vedere, sarcinile par complexe și consumatoare de timp. Motivul nu este că vrem să eliminăm cât mai mulți candidați. În timpul studiilor, studenții se confruntă cu sarcini din viața reală - realizarea unui chat, Yandex.Music pentru copii sau Yandex.Weather pentru persoanele dependente de vreme. Pentru aceasta aveți nevoie de o bază de pornire.

Îmi amintesc că am văzut sarcina mea de intrare în SRI acum doi ani și m-am gândit că nu o voi rezolva niciodată. Principalul lucru în acest moment este să vă așezați, să citiți cu atenție condițiile și să începeți să o faceți. Se dovedește că condițiile conțin aproape 80% din soluție. De exemplu, în condiția celei de-a treia sarcini (cea mai dificilă), am adăugat link-uri către lucrătorii de servicii și API-ul de notificări pe MDN. Elevii care au studiat conținutul linkurilor l-au completat fără dificultate.

Mi-ar plăcea foarte mult ca acest articol să fie citit de candidații care intenționează să intre în SRI pe viitor, care nu au putut intra la Școala din Minsk sau care încep să facă orice altă sarcină de testare. După cum puteți vedea, este foarte posibil să faceți acest lucru. Trebuie doar să crezi în tine și să asculți toate sfaturile autorilor.

Sursa: www.habr.com

Adauga un comentariu