Gränssnittsutvecklingsskola: analys av uppgifter för Minsk och en ny uppsättning i Moskva

Idag öppnade en ny anmälan in Yandex Interface Development School i Moskva. Den första etappen av utbildningen kommer att äga rum 7 september till 25 oktober. Studenter från andra städer kommer att kunna delta i det på distans eller personligen - företaget kommer att betala för resor och boende på ett vandrarhem. Den andra, även den sista etappen, kommer att pågå till den 3 december, den kan endast genomföras personligen.

Jag heter Yulia Seredich, vi skrev det här inlägget tillsammans med Sergei Kazakov. Vi är båda gränssnittsutvecklare på Yandex-kontoret i Minsk och utexaminerade från SRI från tidigare år.

Gränssnittsutvecklingsskola: analys av uppgifter för Minsk och en ny uppsättning i Moskva

Med anledning av öppnandet av registreringen i Moskva publicerar vi en analys av introduktionsuppgifter till den tidigare skolan - här i Minsk.

Om du spårar historien om SRI-uppdrag, från år till år testade vi tre viktiga färdigheter för en programmerare:

  • Layout. Varje utvecklare bör kunna göra layout. Det händer inte att du har farbror Seryozha som designar för hela teamet, och du skriver bara manus. Därför måste varje elev visa hur han vet hur man sätter.
  • JavaScript. Om frågan var begränsad till layout skulle vi inte ha en School of Interface Development, utan en School of Layout Designers. Det vackert designade gränssnittet behöver återupplivas. Därför finns det alltid en uppgift för JS, men ibland är det också en uppgift för algoritmer – vi älskar dem så mycket.
  • Problemlösning är kanske den viktigaste färdigheten hos en utvecklare. När det kommer till att skapa gränssnitt så förändras saker väldigt snabbt. Det är som Lewis Carroll: "Du måste springa så fort du kan bara för att stanna på samma plats, och för att komma till en annan plats måste du springa dubbelt så snabbt." Varje dag stöter vi på ny teknik – vi måste ta hänsyn till dem och kunna förstå dem. Därför föreslog vi i den tredje uppgiften att förstå teknik som en nybörjarutvecklare vanligtvis inte är bekant med.

I analysen av varje uppgift kommer vi att berätta inte bara om det korrekta förfarandet, utan också om vanliga misstag.

Uppgift 1: Portfölj

Den första uppgiften arbetades med av Yandex.Collections designer Alexey Cherenkevich, som vet hur man gör layout, och hans tjänstekollega, gränssnittsutvecklaren Sergey Samsonov.

Skick

Skapa en portföljwebbplats: berätta om dig själv, ditt arbete och dina förväntningar från skolan. Webbplatsen bör så mycket som möjligt motsvara den föreslagna layouten (länkar till layouter: 1000px, 600px, 320px, Specifikation). Vi är bara intresserade av layouten, så använd inte JavaScript.

Vid kontroll tar vi hänsyn till:

  • indragsstorlekar, färgkorrekthet, teckensnittsstil, teckenstorlek;
  • semantisk layout;
  • närvaron av olika tillstånd av element: visa knappar och länkar när du håller markören, markera aktiva inmatningsfält, etc.;
  • kompatibilitet över webbläsare (testad i de senaste versionerna av populära webbläsare).

Fördelen kommer att vara:

  • användning av moderna CSS-lösningar: flexbox, rutnät, etc.;
  • Adaptiv layout;
  • användning av för- och (eller) postprocessorer, montering, minifiering, optimering av utdatakod;
  • HTML-formulärvalidering, stiliserad filuppladdningsknapp.

Uppgiften är ganska omfattande, så du kan hoppa över det som inte fungerar. Detta kommer att sänka din poäng något, men du kommer fortfarande att kunna visa dina kunskaper. När du är klar, skicka oss två länkar – till din portfölj och källkoden på GitHub.

De layouter som föreslagits i uppdraget var inte bara med skärmar för mobila enheter, surfplattor och stationära datorer, utan även med riktiga specifikationer.

För att få in så mycket objektivitet som möjligt i resultatet av kontrollen av den första uppgiften fanns det många kriterier för denna kontroll.

kriterier

Designad hemsida. Detta verkar självklart, men vissa killar hoppade över några block helt – antingen ville de spara tid eller så kunde de inte göra dem. Layouten kan grovt delas in i fyra huvudskärmar: huvudskärmen med en avatar, ett block med en förväntningslista från SRI, ett block med en portfolio och ett block med kontaktinformation. De kunde göras i sektioner eller helt enkelt med hjälp av divs, huvudsaken är att alla fyra blocken var tillgängliga.

Överensstämmelse med layout med layout. Designern gjorde en separat specifikation (inklusive färger, typografi, knappstatus, etc.) för att göra det lättare för kandidaterna. Längst ner fanns en antydan om indragen och funktionerna på den första skärmen. Jag var mycket nöjd med killarna som tog hänsyn till designerns alla önskemål: till exempel borde den första skärmen inte ha varit mindre än höjden på utsiktsplatsen.

Adaptiv layout - det är då gränssnittet inte bara är upplagt så att vid tre upplösningar är allt pixel till pixel i layouten. I mellanlägen bör layouten inte heller falla isär. Vissa glömde att begränsa behållarens maximala bredd och satte allt till 1920 pixlar, vissa förstörde bakgrunderna, men överlag klarade kandidaterna denna uppgift bra.

Semantisk layout. "Hur många gånger har de sagt till världen" att länken ska utformas som , knappen - som . Lyckligtvis uppfyllde de flesta kandidater även detta krav. Inte alla kände igen den dolda listan i förväntningarna på SRI, vilket gjorde att den använde div-taggar, men det är inte så illa. Det var en kandidat som satte in alla semantiska taggar han kände till – där det var nödvändigt och där det inte var nödvändigt. Till exempel, istället för en lista - och . När allt kommer omkring, semantik - det handlar om att förstå sammansättningen av din sida och syftet med varje block (de flesta klarade det här), såväl som användningen av för- och/eller efterbehandlare (några få klarade det här, även om detta fanns också i poängen - oftast använde de mindre och scss) .

Fungerande reglage. I uppdraget skrev vi att JS inte kan användas. Här testades förmågan att lösa problem - en reglage kunde göras med hjälp av ett gäng och . All magi sker på väljarnivån #button-N:checked ~ .slider-inner .slider-slides. När vi klickar på en av ingångskryssrutorna går den till det kontrollerade tillståndet. Vi kan dra fördel av detta och tilldela översättningen vi behöver till behållaren med bilderna: transform: translate(-33%). Du kan se genomförandet av reglaget här.

Nedrullningslistor. Här kom allt också ner på och en liknande väljare: .accordion-item input:checked ~ .accordion-item__content. Du kan se genomförandet här.

Tillgänglighet för :hover, :active och :focu* tillstånd. En mycket viktig punkt. Komforten under interaktion med gränssnittet berodde på det. Användaren ska alltid få feedback på sina handlingar. Denna post kontrollerades under hela interaktionen med frågeformuläret. Om jag klickade på "Ring mig"-knappen och visuellt ingenting hände (även om förfrågan skickades) är detta dåligt, för då kommer jag att klicka på det igen och igen. Som ett resultat kommer tio förfrågningar att skickas och jag kommer att bli uppringd tio gånger. Vi får inte glömma att mobila enheter inte har en mus, vilket betyder att det inte ska finnas en hovring. Och ytterligare en punkt som inte påverkade dem som uppfyllde poängen om semantik. Om din kontroll inte är ett interaktivt element kommer markören att förbli standard när du håller muspekaren över den. Det ser väldigt ostädat ut, även om du har skrivit en reaktion på att sväva. Underskatta inte markören: pekare.

Animationer. Det är viktigt att alla reaktioner som sker med elementen är jämna. Ingenting i livet är omedelbart, så att ha övergångar på svävande och aktiva var tillräckligt för att göra gränssnittet trevligare. Tja, de som animerade reglaget och listorna är generellt bra.

Använder den senaste tekniken. Många använde flex, men ingen slutförde uppgiften med hjälp av rutnät. Poängen räknades om flex användes korrekt. Om layouten någonstans gick isär på grund av just dessa flexer, tyvärr, fick du inga ytterligare poäng.

Formulärvalidering. Allt som krävdes var att lägga till det nödvändiga attributet till varje inmatning av formuläret. Vi har lagt till poäng till de som validerat e-postfältet som e-post.

Styling av filuppladdningsknappen. Vi förväntade oss att se en kombination som: och Välj fil . Därefter behövde vi dölja input och stil etiketten. Det finns ett annat vanligt sätt - att göra en transparent inmatning och lägga den ovanpå knappen. Men inte alla webbläsare tillåter styling , och en sådan lösning kan inte kallas helt över webbläsare. Och det är semantiskt mer korrekt att göra en etikett.

Kompatibilitet över webbläsare. Vi kontrollerade att allt var bra i de två senaste versionerna av moderna webbläsare (utan IE - deltagarna hade tur), samt i Safari på iPhones och Chrome på Androids.

Tvärtom, vi drog av poäng om någon använde JS eller Bootstrap: båda skulle besegra syftet med hela uppgiften. Dessutom fick deltagare med Bootstrap inte bara ett minus, utan förlorade också många poäng för semantik och implementerade element.

De som hostade sin sajt någonstans på Internet fick ingen speciell fördel – men granskarna blev väldigt glada när de inte behövde ladda ner repositories och köra dem lokalt på sin dator. Så detta fungerade som ett plus för karma.

Den första uppgiften var mycket användbar främst för eleven. De som vi inte accepterade har nu ett förberett CV - du kan stolt bifoga det till alla svar eller lägga upp det på dina gh-sidor.

Uppgift 2: Transportväg

Författaren till uppgiften är chefen för sökgränssnittsgruppen Denis Balyko.

Skick

Har du en stjärnkarta? Den visar namnet på varje stjärna, samt avståndet från den till andra stjärnor i ljusa sekunder. Implementera lösningsfunktionen, som bör ta tre argument: ett objekt där nycklarna är namnen på stjärnorna, och värdena är avstånden till stjärnorna (enkelriktad trafik i rymden), samt namnen på stigens start- och slutpunkter - start respektive mål. Funktionen ska returnera det kortaste avståndet från startstjärnan till målstjärnan och vägen att följa.

Funktionssignatur:

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

Exempel på indata:

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

Exempel på utdata:

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

Notera: Lösningsskelettet finns i mappen src/, lägg din lösning i solution.js.

Verifieringen av den andra uppgiften var den mest automatiserade och objektiva. De flesta av killarna gissade att det var nödvändigt att implementera Dijkstras algoritm. De som hittade dess beskrivning och implementerade algoritmen i JS är bra gjort. Men vid kontroll av uppdraget stötte vi på många papper med samma fel. Vi sökte på Internet efter kodfragment och hittade en artikel från vilken deltagarna kopierade algoritmen. Det är roligt att många kopierade koden från artikeln tillsammans med författarens kommentarer. Sådana verk fick ett lågt betyg. Vi förbjuder inte användningen av några källor, men vi vill att en person ska fördjupa sig i vad han skriver.

kriterier

Huvudpoäng delades ut för prov. Ibland var det tydligt att killarna bråkade med förvaret, döpte om mappar och tester misslyckades helt enkelt för att de inte kunde hitta de nödvändiga filerna. I år försökte vi hjälpa sådana killar och lämnade tillbaka allt till sin plats för dem. Men nästa år planerar vi att byta till ett tävlingssystem, och detta kommer inte längre att förlåtas.

Det fanns också "mänskliga", manuella kriterier. Till exempel närvaron av en enda kodstil. Ingen drog av poäng för att använda tabbar istället för blanksteg eller vice versa. Det är en annan sak om du varvar enstaka citattecken med dubbla citattecken enligt en regel som du känner till, och placerar semikolon slumpmässigt.

Lösningens tydlighet och läsbarhet togs i beaktande separat. På alla konferenser i världen säger de att 80 % av en programmerares jobb består av att läsa andras kod. Även skolbarn genomgår kodgranskning – från sina kuratorer och från varandra. Så detta kriterium vägde stor vikt. Det har funnits verk där det inte fanns några variabler längre än ett tecken - snälla gör inte det. Kommentarerna från deltagarna var mycket uppmuntrande – med undantag för de som var identiska med Stella Changs kommentarer.

Det sista kriteriet är förekomsten av autotester. Endast ett fåtal personer lade till dem, men för alla blev det ett stort plus i deras karma.

Rätt lösning:

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

Uppgift 3: Evenemangskalender

Det utarbetades av gränssnittsutvecklarna Sergey Kazakov och Alexander Podskrebkin.

Skick

Skriv en minikalender för att visa ditt schema. Du kan ta vilket schema du vill. Till exempel schemat för frontend-konferenser 2019.

Kalendern ska se ut som en lista. Det finns inga andra designkrav. Gör det möjligt att ställa in händelsepåminnelser 3, 7 och 14 dagar i förväg. Efter den första nedladdningen från Internet bör kalendern öppnas och fungera offline.

Användbara resurser

Frontend-konferensschema:
confs.tech/javascript?topics=javascript%2Bcss%2Bux

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

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

Den tredje uppgiften var den mest intressanta att testa, eftersom det fanns så många möjliga lösningar, var och en med sina egna. Vi kollade hur kandidaten hanterar obekanta teknologier – om han vet hur man forskar, om han testar sina lösningar.

kriterier

Vikt kalender. Ja, det behövde fortfarande läggas ut. Det fanns också de som tog tillståndet för bokstavligt och inte infogade en enda rad med CSS-kod. Det såg inte särskilt attraktivt ut, men om allt fungerade minskade inte poängen.

Hämta en lista över händelser från en källa. Detta är inte en layoutuppgift, så listan över händelser som ingår i den räknades inte. Du kan alltid avbryta en konferens, boka om den eller lägga till en ny. Så det var nödvändigt att ta emot data utifrån och rendera layouten baserat på den mottagna JSON. Det var viktigt att erhålla data på något sätt (med hjälp av hämtningsmetoden eller med XMLHttpRequest). Om en person lagt till en polyfill för hämtning och markerat sitt val i readme, räknades detta som ett plus.

Registrering av servicearbetare utan fel och arbeta offline efter den första nedladdningen. Här är ett exempel. servicearbetare med cachelagring av schema vid första uppstart. Detaljer om servicearbetare, deras kapacitet och sätt att arbeta med dem (strategier för att arbeta med cacher, arbeta offline) finns här.

Möjlighet att ställa in en påminnelseså att det faktiskt fungerar efter 3, 7, 14 dagar. Det var nödvändigt att förstå Notifications API, länk till vilken hade rätt på uppgiften. Vi förväntade oss inte någon specifik implementering för att kontrollera om det är dags att pressa. Alla arbetsalternativ accepterades: lagring i localStorage, IndexDB eller periodisk polling av en servicearbetare. Det var till och med möjligt att skapa en push-server (här exempel), men det skulle inte fungera offline. Det var lika viktigt att få en push efter att sidan stängts – och öppnats efter en tid. Om påminnelsen dog samtidigt som sidan stängdes räknades inte lösningen. Det är häftigt när killarna tänkte på recensenterna och gjorde det möjligt att få en push just nu - för att inte vänta 3 dagar.

Möjlighet att placera en ikon på skrivbordet (PWA). Vi kontrollerade förekomsten av filen manifest.json med rätt ikoner. Några killar skapade den här filen (eller lämnade den genererad i CreateReactApp) - men lade inte till rätt ikoner. Sedan, när du försökte installera, uppstod ett fel som "en annan ikon behövs".

Codestyle och projektstruktur. Som i den andra uppgiften tittade vi på en enda kodstil (även om den inte sammanföll med vår). Några killar skruvade på linters - det är jättebra.

Konsolfel. Om det fanns en indikator direkt i konsolen att något var fel, och deltagaren inte uppmärksammade det, så drog vi av poäng.

Resultat av

Vad som är roligt med deltagarnas beslut:

  • Ett frågeformulär innehöll följande text: ”En programmerares vän hjälpte mig att sätta ihop en React-applikation. Jag bombarderade honom med frågor om hur och varför, och han berättade för mig. Jag gillade det verkligen, jag vill veta mer om det.” Vi rotade efter denna ansökan av hela vårt hjärta, men tyvärr var kandidatens vän inte till stor hjälp för att få ansökan att fungera.
  • En kandidat skickade en länk till GitHub, där RAR-arkivet fanns - det är svårt att kommentera detta. 🙂
  • En annan kandidat, i kommentaren på den första raden i filen solution.js, erkände ärligt att han kopierade algoritmen.

Vi fick in ansökningar från 76 kandidater och valde ut 23 personer. Vi fick frågeformulär inte bara från Minsk utan också från Moskva, St. Petersburg och till och med Tatarstan. Några av killarna överraskade oss med sina nuvarande yrken: en av dem är kriminaltekniker och den andra är läkarstudent.

Resultatet blev en intressant fördelning av framgångsfrekvenser för att slutföra uppgifter. Deltagarna klarade den första uppgiften med i snitt 60 %, den andra med 50 %, och den tredje visade sig vara svårast och genomfördes med i snitt 40 %.

Vid första anblicken ser uppgifterna komplexa och tidskrävande ut. Anledningen är inte att vi vill sålla bort så många kandidater som möjligt. Under sina studier ställs studenterna inför verkliga uppgifter - att göra en chatt, Yandex.Music för barn eller Yandex.Weather för väderberoende människor. För detta behöver du en startbas.

Jag minns att jag såg min SRI-entréuppgift för två år sedan och tänkte att jag aldrig skulle lösa den. Det viktigaste i detta ögonblick är att sätta sig ner, noggrant läsa igenom villkoren och börja göra det. Det visar sig att förhållandena innehåller nästan 80 % av lösningen. Till exempel, i tillståndet för den tredje uppgiften (den svåraste), la vi till länkar till servicearbetare och Notifications API på MDN. Studenter som studerade innehållet i länkarna slutförde det utan svårighet.

Jag skulle verkligen vilja att den här artikeln skulle läsas av kandidater som planerar att gå in i SRI i framtiden, som inte kunde komma in på Minskskolan eller som börjar göra någon annan testuppgift. Som du kan se är det fullt möjligt att göra det. Du behöver bara tro på dig själv och lyssna på alla tips från författarna.

Källa: will.com

Lägg en kommentar