Szkoła rozwoju interfejsu: analiza zadań dla Mińska i nowego zestawu w Moskwie

Dziś ruszyła nowa rekrutacja Szkoła rozwoju interfejsu Yandex w Moskwie. Pierwszy etap szkolenia odbędzie się w dniach 7 września – 25 października. Studenci z innych miast będą mogli wziąć w nim udział zdalnie lub osobiście – firma pokryje koszty dojazdu i noclegu w hostelu. Drugi, zarazem finałowy etap, potrwa do 3 grudnia, można go ukończyć wyłącznie osobiście.

Nazywam się Julia Seredich, napisaliśmy ten post wspólnie z Siergiejem Kazakowem. Oboje jesteśmy programistami interfejsów w mińskim biurze Yandex i absolwentami SRI z poprzednich lat.

Szkoła rozwoju interfejsu: analiza zadań dla Mińska i nowego zestawu w Moskwie

Z okazji otwarcia zapisów w Moskwie publikujemy analizę zadań wprowadzających do poprzedniej Szkoły – tu, w Mińsku.

Jeśli prześledzić historię zadań SRI, z roku na rok testowaliśmy trzy ważne umiejętności programisty:

  • Układ. Każdy programista powinien umieć tworzyć układ. Nie jest tak, że masz wujka Seryozha, który projektuje dla całego zespołu, a ty piszesz tylko scenariusze. Dlatego każdy uczeń musi wykazać się umiejętnością pisania.
  • JavaScript. Gdyby sprawa ograniczała się do układu graficznego, to nie mielibyśmy Szkoły Rozwoju Interfejsów, a Szkołę Projektantów Layoutu. Pięknie zaprojektowany interfejs wymaga odświeżenia. Dlatego zawsze jest zadanie dla JS, ale czasem jest to także zadanie dla algorytmów – tak je kochamy.
  • Rozwiązywanie problemów jest prawdopodobnie najważniejszą umiejętnością programisty. Jeśli chodzi o tworzenie interfejsów, sytuacja zmienia się bardzo szybko. To tak jak z Lewisem Carrollem: „Musisz biec tak szybko, jak tylko możesz, żeby pozostać w tym samym miejscu, a żeby dostać się do innego miejsca, musisz biec dwa razy szybciej”. Codziennie spotykamy się z nowymi technologiami – trzeba je brać pod uwagę i umieć je zrozumieć. Dlatego w trzecim zadaniu zaproponowaliśmy zrozumienie technologii, z którymi początkujący programista zwykle nie jest zaznajomiony.

Analizując każde zadanie, opowiemy Ci nie tylko o prawidłowym postępowaniu, ale także o typowych błędach.

Zadanie 1: Portfolio

Nad pierwszym zadaniem pracował projektant Yandex.Collections Aleksiej Czerenkiewicz, który wie, jak zrobić układ, oraz jego kolega z serwisu, programista interfejsu Siergiej Samsonow.

Stan: schorzenie

Stwórz stronę portfolio: opowiedz nam o sobie, swojej pracy i oczekiwaniach wobec Szkoły. Strona powinna w miarę możliwości odpowiadać proponowanemu układowi (linki do układów: 1000px, 600px, 320px, specyfikacja). Interesuje nas tylko układ, więc nie używaj JavaScript.

Podczas sprawdzania weźmiemy pod uwagę:

  • rozmiary wcięć, poprawność kolorystyczna, styl czcionki, rozmiar czcionki;
  • układ semantyczny;
  • obecność różnych stanów elementów: wyświetlanie przycisków i linków po najechaniu kursorem, podświetlanie aktywnych pól wejściowych itp.;
  • kompatybilność z różnymi przeglądarkami (testowana w najnowszych wersjach popularnych przeglądarek).

Zaletą będzie:

  • wykorzystanie nowoczesnych rozwiązań CSS: flexbox, grid itp.;
  • Układ adaptacyjny;
  • wykorzystanie pre- i (lub) postprocesorów, montaż, minifikacja, optymalizacja kodu wyjściowego;
  • Sprawdzanie poprawności formularza HTML, stylizowany przycisk przesyłania pliku.

Zadanie jest dość obszerne, więc możesz pominąć to, co nie zadziała. To nieznacznie obniży Twój wynik, ale nadal będziesz mógł wykazać się swoją wiedzą. Kiedy już skończysz, wyślij nam dwa linki – do swojego portfolio i kodu źródłowego na GitHubie.

Układy zaproponowane w zadaniu obejmowały nie tylko ekrany do urządzeń mobilnych, tabletów i komputerów stacjonarnych, ale także rzeczywiste specyfikacje.

Aby wynik sprawdzenia pierwszego zadania był jak najbardziej obiektywny, kryteriów tej kontroli było bardzo dużo.

kryteria

Zaprojektowana strona internetowa. Wydaje się to oczywiste, ale niektórzy całkowicie pominęli niektóre bloki – albo chcieli zaoszczędzić czas, albo nie mogli tego zrobić. Układ można z grubsza podzielić na cztery główne ekrany: ekran główny z awatarem, blok z listą oczekiwań wobec SRI, blok z portfolio oraz blok z danymi kontaktowymi. Można je tworzyć w sekcjach lub po prostu za pomocą elementów div, najważniejsze jest to, że wszystkie cztery bloki były dostępne.

Zgodność układu z układem. Projektant przygotował osobną specyfikację (m.in. kolory, typografia, stany przycisków itp.), aby ułatwić kandydatom. Na dole znalazła się podpowiedź dotycząca wcięć i funkcji pierwszego ekranu. Byłem bardzo zadowolony z chłopaków, którzy wzięli pod uwagę wszystkie życzenia projektanta: na przykład pierwszy ekran powinien mieć nie mniej niż wysokość rzutni.

Układ adaptacyjny - ma to miejsce wtedy, gdy interfejs nie jest po prostu rozplanowany w taki sposób, że przy trzech rozdzielczościach wszystko jest układane piksel po pikselu. W stanach pośrednich układ również nie powinien się rozpadać. Niektórzy zapomnieli ograniczyć maksymalną szerokość kontenera i ustawili wszystko na 1920 pikseli, niektórzy popsuli tła, ale ogólnie kandydaci poradzili sobie z tym zadaniem dobrze.

Układ semantyczny. „Ile razy mówili światu”, że link powinien być zaprojektowany jako , przycisk – jako . Na szczęście większość kandydatów spełniła ten wymóg. Nie wszyscy rozpoznali ukrytą listę w oczekiwaniach SRI, tworząc ją przy użyciu znaczników div, ale nie jest tak źle. Był kandydat, który wstawiał wszystkie znane mu znaczniki semantyczne – tam, gdzie było to konieczne i gdzie nie było to konieczne. Na przykład zamiast listy - i . Przecież semantyka - chodzi o zrozumienie składu Twojej strony i przeznaczenia każdego bloku (tutaj poradziła sobie z tym większość), a także wykorzystanie pre- i/lub postprocesorów (tutaj udało się kilku, chociaż to też było w punktach – najczęściej używali less i scss).

Działający suwak. W zadaniu pisaliśmy, że nie można używać JS. Tutaj sprawdzono umiejętność rozwiązywania problemów - suwak można było wykonać z pęczka i . Cała magia dzieje się na poziomie selektora #button-N:checked ~ .slider-inner .slider-slides. Kiedy klikniemy na jedno z wejściowych pól wyboru, przechodzi ono w stan zaznaczony. Możemy to wykorzystać i przypisać potrzebne tłumaczenie do kontenera ze slajdami: transform: tłumacz(-33%). Możesz zobaczyć implementację suwaka tutaj.

Listy rozwijane. Tutaj również wszystko się sprowadziło i podobny selektor: .accordion-item input:checked ~ .accordion-item__content. Można zobaczyć realizację tutaj.

Dostępność stanów :hover, :active i :focu*. Bardzo ważny punkt. Od tego zależał komfort podczas interakcji z interfejsem. Użytkownik powinien zawsze otrzymać informację zwrotną na temat swoich działań. Pozycja ta była sprawdzana podczas całej interakcji z kwestionariuszem. Jeśli kliknąłem przycisk „Zadzwoń do mnie” i wizualnie nic się nie wydarzyło (mimo że prośba została wysłana), to jest źle, ponieważ wtedy będę go klikał raz za razem. W efekcie zostanie wysłanych dziesięć próśb i dziesięć razy do mnie zadzwonią. Nie możemy zapominać, że urządzenia mobilne nie mają myszy, co oznacza, że ​​nie powinno być najechania myszką. I jeszcze jedna kwestia, która nie miała wpływu na tych, którzy spełnili punkt dotyczący semantyki. Jeśli Twoja kontrolka nie jest elementem interaktywnym, to po najechaniu na nią kursor pozostanie standardowy. Wygląda bardzo niechlujnie, nawet jeśli napisałeś reakcję na najechanie myszką. Nie lekceważ kursora: wskaźnika.

Animacje. Ważne jest, aby wszystkie reakcje zachodzące z pierwiastkami przebiegały płynnie. Nic w życiu nie jest natychmiastowe, więc przejścia po najechaniu myszką i aktywne wystarczyły, aby interfejs był przyjemniejszy. Cóż, ci, którzy animowali suwak i listy, są ogólnie świetni.

Korzystanie z najnowocześniejszych technologii. Wiele osób korzystało z flexu, ale nikt nie wykonał zadania przy użyciu siatki. Punkt był liczony, jeśli flex został użyty prawidłowo. Jeśli gdzieś układ się rozpadł z powodu tych samych wygięć, niestety, nie otrzymałeś żadnych dodatkowych punktów.

Walidacja formularza. Wystarczyło dodać wymagany atrybut do każdego wejścia formularza. Dodaliśmy punkty tym, którzy zatwierdzili pole e-mail jako e-mail.

Stylizacja przycisku przesyłania pliku. Spodziewaliśmy się takiej kombinacji: i Wybierz plik . Następnie musieliśmy ukryć dane wejściowe i nadać styl etykiecie. Istnieje inny powszechny sposób - utworzenie przezroczystego wejścia i umieszczenie go na przycisku. Ale nie wszystkie przeglądarki umożliwiają stylizację , a takiego rozwiązania nie można nazwać w pełni wieloprzeglądowym. I semantycznie bardziej poprawne jest utworzenie etykiety.

Kompatybilność między przeglądarkami. Sprawdziliśmy, czy wszystko działa prawidłowo w dwóch najnowszych wersjach nowoczesnych przeglądarek (bez IE – uczestnicy mieli szczęście), a także w Safari na iPhone’ach i Chrome na Androidach.

Wręcz przeciwnie, odejmowaliśmy punkty, jeśli ktoś korzystał z JS lub Bootstrapa: oba zniweczyłyby sens całego zadania. Co więcej, uczestnicy korzystający z Bootstrapa nie tylko otrzymali minus, ale także stracili wiele punktów za semantykę i zaimplementowane elementy.

Ci, którzy hostowali swoją witrynę gdzieś w Internecie, nie odnieśli żadnej szczególnej korzyści - za to recenzenci byli bardzo zadowoleni, gdy nie musieli pobierać repozytoriów i uruchamiać ich lokalnie na swoim komputerze. Stanowiło to więc plus dla karmy.

Pierwsze zadanie było bardzo przydatne przede wszystkim dla ucznia. Ci, których nie przyjęliśmy, mają już przygotowane CV - możecie je z dumą dołączać do wszystkich odpowiedzi lub umieszczać na swoich gh-page'ach.

Zadanie 2: Trasa transportowa

Autorem zadania jest szef grupy interfejsów wyszukiwania Denis Balyko.

Stan: schorzenie

Czy masz mapę gwiazd? Pokazuje nazwę każdej gwiazdy, a także odległość od niej do innych gwiazd w sekundach świetlnych. Zaimplementuj funkcję rozwiązania, która powinna przyjmować trzy argumenty: obiekt, w którym kluczami są nazwy gwiazd, a wartościami odległości do gwiazd (ruch jednokierunkowy w przestrzeni), a także nazwy punkty początkowe i końcowe ścieżki - odpowiednio początek i koniec. Funkcja powinna zwrócić najkrótszą odległość od gwiazdy początkowej do gwiazdy końcowej oraz ścieżkę, którą należy podążać.

Sygnatura funkcji:

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

Przykładowe dane wejściowe:

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

Przykładowe wyjście:

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

Uwaga: Szkielet rozwiązania znajduje się w folderze src/, umieść rozwiązanie w pliku Solution.js.

Weryfikacja drugiego zadania była najbardziej zautomatyzowana i obiektywna. Większość chłopaków domyśliła się, że konieczne jest wdrożenie algorytmu Dijkstry. Ci, którzy znaleźli jego opis i zaimplementowali algorytm w JS, mają się dobrze. Sprawdzając jednak zadanie, natknęliśmy się na wiele prac z tymi samymi błędami. Przeszukaliśmy Internet w poszukiwaniu fragmentów kodu i znaleźliśmy artykuł, z którego uczestnicy skopiowali algorytm. Zabawne, że wiele osób skopiowało kod z artykułu wraz z komentarzami autora. Prace takie otrzymały niską ocenę. Nie zabraniamy korzystania z jakichkolwiek źródeł, ale zależy nam na tym, aby człowiek zagłębił się w to, co pisze.

kryteria

Główne punkty przyznano za testy. Czasami było jasne, że chłopaki grzebali w repozytorium, zmieniali nazwy folderów, a testy kończyły się niepowodzeniem po prostu dlatego, że nie mogli znaleźć niezbędnych plików. W tym roku staraliśmy się pomóc takim chłopakom i przywróciliśmy dla nich wszystko na swoje miejsce. Ale w przyszłym roku planujemy przejść na system konkursowy i nie będzie to już wybaczane.

Były też kryteria „ludzkie”, manualne. Na przykład obecność jednego stylu kodu. Nikt nie odejmował punktów za używanie tabulatorów zamiast spacji i odwrotnie. Inna sprawa, jeśli cudzysłowy pojedyncze zamienisz na cudzysłów podwójny, zgodnie ze znaną Ci zasadą, i losowo wstawisz średniki.

Odrębnie wzięto pod uwagę przejrzystość i czytelność rozwiązania. Na wszystkich konferencjach na świecie mówi się, że 80% pracy programisty polega na czytaniu kodu innych ludzi. Nawet uczniowie przechodzą przeglądy kodu – od swoich kuratorów i od siebie nawzajem. Zatem to kryterium miało znaczną wagę. Były prace, w których nie było zmiennych dłuższych niż jeden znak - proszę tego nie robić. Komentarze uczestników były bardzo zachęcające – z wyjątkiem tych, które były identyczne z komentarzami Stelli Chang.

Ostatnim kryterium jest obecność autotestów. Dodało je tylko kilka osób, ale dla wszystkich stało się to ogromnym plusem w ich karmie.

Prawidłowe rozwiązanie:

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

Zadanie 3: Kalendarz wydarzeń

Został on przygotowany przez twórców interfejsu Siergieja Kazakowa i Aleksandra Podskrebkina.

Stan: schorzenie

Napisz minikalendarz, w którym będzie prezentowany Twój harmonogram. Możesz wybrać dowolny harmonogram. Przykładowo harmonogram konferencji frontendowych w 2019 roku.

Kalendarz powinien wyglądać jak lista. Nie ma innych wymagań projektowych. Umożliwia ustawienie przypomnień o wydarzeniach z 3, 7 i 14-dniowym wyprzedzeniem. Po pierwszym pobraniu z Internetu kalendarz powinien się otworzyć i działać w trybie offline.

Przydatne zasoby

Harmonogram konferencji frontendowych:
confs.tech/javascript?topics=javascript%2Bcss%2Bux

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

API powiadomień:
developer.mozilla.org/ru/docs/Web/API/Notifications_API

Trzecie zadanie było najciekawsze do przetestowania, ponieważ było tak wiele możliwych rozwiązań, każde z własnym. Sprawdziliśmy, jak kandydat radzi sobie z nieznanymi technologiami – czy umie badać, czy testuje swoje rozwiązania.

kryteria

Składany kalendarz. Tak, nadal trzeba było to ułożyć. Byli też tacy, którzy potraktowali ten warunek zbyt dosłownie i nie wstawili ani jednej linijki kodu CSS. Nie wyglądało to zbyt atrakcyjnie, ale jeśli wszystko działało, punkty nie spadały.

Pobieranie listy zdarzeń ze źródła. Nie jest to zadanie układu, więc lista zdarzeń w nim zawarta nie została policzona. Zawsze możesz anulować konferencję, przełożyć ją na inny termin lub dodać nową. Należało więc pozyskać dane z zewnątrz i wyrenderować układ w oparciu o otrzymany JSON. Ważne było, aby dane pozyskać w jakikolwiek sposób (metodą fetch lub za pomocą XMLHttpRequest). Jeśli ktoś dodał element do pobrania i zaznaczył swój wybór w pliku Readme, liczyło się to jako plus.

Rejestracja pracownika serwisu bez błędów i pracuj w trybie offline po pierwszym pobraniu. Oto przykład. Service Worker z buforowaniem harmonogramu przy pierwszym uruchomieniu. Szczegóły na temat Service Workerów, ich możliwości i sposobów pracy z nimi (strategie pracy z cache, pracy offline) znajdziesz tutaj.

Możliwość ustawienia przypomnieniatak, żeby faktycznie zadziałało po 3, 7, 14 dniach. Konieczne było zrozumienie API powiadomień, link do którego był na właściwym miejscu. Nie spodziewaliśmy się jakiejś konkretnej implementacji, żeby sprawdzić, czy już czas na push. Przyjęto dowolną opcję działania: przechowywanie w localStorage, IndexDB lub okresowe odpytywanie przez pracownika serwisu. Można było nawet stworzyć serwer push (tutaj przykład), ale nie działałoby to w trybie offline. Równie ważne było otrzymanie pushu po zamknięciu strony – i otwarciu po pewnym czasie. Jeśli przypomnienie zniknęło w tym samym czasie, gdy strona została zamknięta, rozwiązanie nie zostało zaliczone. Fajnie, gdy chłopaki pomyśleli o recenzentach i umożliwili uzyskanie impulsu już teraz - aby nie czekać 3 dni.

Możliwość umieszczenia ikony na pulpicie (PWA). Sprawdziliśmy obecność pliku manifest.json z właściwymi ikonami. Niektórzy stworzyli ten plik (lub pozostawili go wygenerowanego w CreateReactApp), ale nie dodali odpowiednich ikon. Następnie podczas próby instalacji wystąpił błąd typu „potrzebna jest inna ikona”.

Styl kodu i struktura projektu. Podobnie jak w drugim zadaniu, przyglądaliśmy się jednemu stylowi kodu (nawet jeśli nie pokrywał się on z naszym). Niektórzy goście wkręcali lintersy – to świetnie.

Błędy konsoli. Jeżeli bezpośrednio w konsoli była kontrolka, że ​​coś jest nie tak, a uczestnik nie zwrócił na to uwagi, wówczas odejmowaliśmy punkty.

Wyniki

Co jest zabawnego w decyzjach uczestników:

  • Jedna z ankiet zawierała następujący tekst: „Przyjaciel programista pomógł mi stworzyć aplikację React. Zasypywałem go pytaniami o to, jak i dlaczego, a on mi powiedział. Bardzo mi się podobało, chcę dowiedzieć się więcej na ten temat.” Kibicowaliśmy tej aplikacji całym sercem, ale niestety znajomy kandydata nie był zbyt pomocny w uruchomieniu aplikacji.
  • Jeden z kandydatów przesłał link do GitHuba, gdzie znajdowało się archiwum RAR – trudno to komentować. 🙂
  • Inny kandydat w komentarzu do pierwszej linijki pliku Solution.js szczerze przyznał, że skopiował algorytm.

Otrzymaliśmy zgłoszenia od 76 kandydatów i wybraliśmy 23 osoby. Ankiety przysyłano do nas nie tylko z Mińska, ale także z Moskwy, Petersburga, a nawet Tatarstanu. Niektórzy z chłopaków zaskoczyli nas swoim obecnym zawodem: jeden jest ekspertem medycyny sądowej, a drugi studentem medycyny.

Rezultatem był interesujący rozkład wskaźników sukcesu w wykonywaniu zadań. Pierwsze zadanie uczestnicy wykonali średnio w 60%, drugie w 50%, a trzecie okazało się najtrudniejsze i zostało zrealizowane średnio w 40%.

Na pierwszy rzut oka zadania wydają się skomplikowane i czasochłonne. Powodem nie jest to, że chcemy wyeliminować jak najwięcej kandydatów. Podczas studiów studenci stają przed realnymi zadaniami - prowadzeniem czatu, Yandex.Music dla dzieci czy Yandex.Weather dla osób zależnych od pogody. Do tego potrzebna jest baza wyjściowa.

Pamiętam, jak dwa lata temu zobaczyłem moje zadanie wstępne do SRI i pomyślałem, że nigdy go nie rozwiążę. Najważniejsze w tym momencie jest usiąść, uważnie przeczytać warunki i zacząć to robić. Okazuje się, że warunki zawierają prawie 80% roztworu. Przykładowo w warunku trzeciego zadania (najtrudniejszego) dodaliśmy linki do service workerów i API Powiadomień na MDN. Studenci, którzy zapoznali się z treścią linków, wykonali je bez trudności.

Bardzo chciałbym, aby ten artykuł przeczytali kandydaci, którzy planują w przyszłości rozpocząć naukę w SRI, którym nie udało się dostać do Szkoły Mińskiej lub którzy rozpoczynają jakiekolwiek inne zadanie testowe. Jak widać jest to całkiem możliwe. Musisz tylko uwierzyć w siebie i wysłuchać wszystkich wskazówek autorów.

Źródło: www.habr.com

Dodaj komentarz