Escola de desenvolvimento de interface: análise de tarefas para Minsk e um novo conjunto em Moscou

Hoje foram abertas novas inscrições em Escola de Desenvolvimento de Interface Yandex em Moscou. A primeira etapa do treinamento acontecerá de 7 de setembro a 25 de outubro. Estudantes de outras cidades poderão participar remotamente ou presencialmente – a empresa custeará a viagem e hospedagem em albergue. A segunda, também última etapa, vai até 3 de dezembro, só poderá ser realizada presencialmente.

Meu nome é Yulia Seredich, escrevemos este post junto com Sergei Kazakov. Somos desenvolvedores de interface no escritório da Yandex em Minsk e graduados em SRI em anos anteriores.

Escola de desenvolvimento de interface: análise de tarefas para Minsk e um novo conjunto em Moscou

Por ocasião da abertura das inscrições em Moscou, publicamos uma análise das tarefas introdutórias à Escola anterior - aqui em Minsk.

Se traçarmos o histórico das atribuições do SRI, ano após ano testamos três habilidades importantes para um programador:

  • Disposição. Todo desenvolvedor deve ser capaz de fazer layout. Não acontece que você tenha o tio Seryozha que desenha para toda a equipe e você apenas escreve roteiros. Portanto, todo aluno deve mostrar como sabe compor.
  • JavaScript. Se o assunto se limitasse ao layout, então não teríamos uma Escola de Desenvolvimento de Interfaces, mas sim uma Escola de Designers de Layout. A interface lindamente projetada precisa ser revivida. Portanto, sempre há uma tarefa para JS, mas às vezes também é uma tarefa para algoritmos - nós os amamos muito.
  • A resolução de problemas é talvez a habilidade mais importante de um desenvolvedor. Quando se trata de criar interfaces, as coisas estão mudando muito rapidamente. É como Lewis Carroll: “Você tem que correr o mais rápido que puder apenas para permanecer no mesmo lugar, e para chegar a outro lugar você tem que correr duas vezes mais rápido”. Todos os dias nos deparamos com novas tecnologias – precisamos levá-las em consideração e ser capazes de compreendê-las. Portanto, na terceira tarefa, propusemo-nos a compreender tecnologias com as quais um desenvolvedor iniciante normalmente não está familiarizado.

Na análise de cada tarefa, iremos falar não só sobre o procedimento correto, mas também sobre erros comuns.

Tarefa 1: Portfólio

A primeira tarefa foi realizada pelo designer do Yandex.Collections, Alexey Cherenkevich, que sabe fazer layout, e seu colega de serviço, o desenvolvedor de interface Sergey Samsonov.

Condição

Crie um site de portfólio: conte-nos sobre você, seu trabalho e suas expectativas em relação à Escola. O site deverá corresponder tanto quanto possível ao layout proposto (links para layouts: 1000px, 600px, 320px, especificação). Estamos interessados ​​apenas no layout, portanto, não use JavaScript.

Ao verificar levaremos em consideração:

  • tamanhos de recuo, correção de cores, estilo de fonte, tamanho de fonte;
  • layout semântico;
  • a presença de diferentes estados dos elementos: exibição de botões e links ao passar o cursor, destaque de campos de entrada ativos, etc.;
  • compatibilidade entre navegadores (testada nas versões mais recentes de navegadores populares).

A vantagem será:

  • utilização de soluções CSS modernas: flexbox, grid, etc.;
  • Layout adaptativo;
  • uso de pré e (ou) pós-processadores, montagem, minificação, otimização de código de saída;
  • Validação de formulário HTML, botão de upload de arquivo estilizado.

A tarefa é bastante volumosa, então você pode pular o que não vai funcionar. Isso diminuirá um pouco sua pontuação, mas você ainda poderá demonstrar seu conhecimento. Quando terminar, envie-nos dois links - para o seu portfólio e o código-fonte no GitHub.

Os layouts propostos no trabalho não eram apenas com telas para dispositivos móveis, tablets e desktops, mas também com especificações reais.

Para trazer o máximo de objetividade possível ao resultado da verificação da primeira tarefa, havia vários critérios para esta verificação.

critérios

Site projetado. Isso parece óbvio, mas alguns caras pularam completamente alguns blocos - ou queriam economizar tempo ou não conseguiram. O layout pode ser dividido aproximadamente em quatro telas principais: a tela principal com avatar, um bloco com uma lista de expectativas do SRI, um bloco com portfólio e um bloco com informações de contato. Eles poderiam ser feitos em seções ou simplesmente usando divs, o principal é que todos os quatro blocos estivessem disponíveis.

Conformidade do layout com o layout. O designer fez uma especificação separada (incluindo cores, tipografia, estados dos botões, etc.) para facilitar para os candidatos. Na parte inferior havia uma dica sobre os recuos e características da primeira tela. Fiquei muito satisfeito com a galera que levou em consideração todos os desejos do designer: por exemplo, a primeira tela não deveria ter menos que a altura da janela de visualização.

Layout adaptativo - é quando a interface não é apenas projetada de forma que, em três resoluções, tudo tenha um layout pixel a pixel. Nos estados intermediários, o layout também não deve desmoronar. Alguns esqueceram de limitar a largura máxima do contêiner e definir tudo para 1920 pixels, alguns bagunçaram os planos de fundo, mas no geral os candidatos lidaram bem com essa tarefa.

Layout semântico. “Quantas vezes eles disseram ao mundo” que o link deveria ser desenhado como , o botão – como . Felizmente, a maioria dos candidatos também cumpriu este requisito. Nem todos reconheceram a lista oculta nas expectativas do SRI, fazendo-a usando tags div, mas não é tão ruim assim. Teve um candidato que inseriu todas as tags semânticas que conhecia - onde era necessário e onde não era necessário. Por exemplo, em vez de uma lista - e . Afinal, semântica - trata-se de entender a composição da sua página e a finalidade de cada bloco (a maioria conseguiu aqui), bem como o uso de pré e/ou pós-processadores (alguns conseguiram aqui, embora este também estava nos pontos - na maioria das vezes eles usavam menos e scss) .

Controle deslizante de trabalho. Na tarefa escrevemos que JS não pode ser usado. Aqui foi testada a capacidade de resolver problemas - um controle deslizante poderia ser feito usando um monte E . Toda a mágica acontece no nível do seletor #button-N:checked ~ .slider-inner .slider-slides. Quando clicamos em uma das caixas de seleção de entrada, ela entra no estado marcado. Podemos aproveitar isso e atribuir a tradução que precisamos ao contêiner com os slides: transform: translate(-33%). Você pode ver a implementação do controle deslizante aqui.

Listas suspensas. Aqui tudo também se resumiu a e um seletor semelhante: .accordion-item input:checked ~ .accordion-item__content. Você pode ver a implementação aqui.

Disponibilidade dos estados :hover, :active e :focu*. Um ponto muito importante. O conforto durante a interação com a interface dependia disso. O usuário deve sempre receber feedback sobre suas ações. Este item foi verificado ao longo da interação com o questionário. Se eu cliquei no botão “Ligue para mim” e visualmente nada aconteceu (mesmo que a solicitação tenha sido enviada), isso é ruim, porque aí vou clicar nele de novo e de novo. Como resultado, dez solicitações serão enviadas e receberei dez ligações de volta. Não devemos esquecer que os dispositivos móveis não possuem mouse, o que significa que não deve haver pairar. E mais um ponto que não afetou quem cumpriu a questão da semântica. Se o seu controle não for um elemento interativo, quando você passar o mouse sobre ele, o cursor permanecerá padrão. Parece muito desarrumado, mesmo que você tenha escrito uma reação ao pairar. Não subestime o cursor: ponteiro.

Animações. É importante que todas as reações que ocorrem com os elementos sejam suaves. Nada na vida é instantâneo, então ter transições em foco e ativas foi o suficiente para tornar a interface mais agradável. Bem, aqueles que animaram o controle deslizante e as listas geralmente são ótimos.

Usando a tecnologia mais recente. Muitas pessoas usaram o flex, mas ninguém concluiu a tarefa usando o grid. O ponto foi contado se o flex foi usado corretamente. Se em algum lugar o layout desmoronou por causa dessas mesmas flexões, infelizmente você não recebeu nenhum ponto adicional.

Validação de formulário. Tudo o que foi necessário foi adicionar o atributo obrigatório a cada entrada do formulário. Adicionamos pontos para quem validou o campo email como email.

Estilizando o botão de upload de arquivo. Esperávamos ver uma combinação como: e selecione o arquivo . Em seguida, precisávamos ocultar a entrada e estilizar o rótulo. Existe outra maneira comum - fazer uma entrada transparente e colocá-la em cima do botão. Mas nem todos os navegadores permitem estilos , e tal solução não pode ser chamada de totalmente cross-browser. E é semanticamente mais correto fazer um rótulo.

Compatibilidade entre navegadores. Verificamos se estava tudo bem nas duas versões mais recentes de navegadores modernos (sem IE - os participantes tiveram sorte), bem como no Safari em iPhones e no Chrome em Androids.

Pelo contrário, deduzimos pontos se alguém usasse JS ou Bootstrap: ambos iriam anular o propósito de toda a tarefa. Além disso, os participantes do Bootstrap não apenas receberam menos, mas também perderam muitos pontos em semântica e elementos implementados.

Aqueles que hospedaram seu site em algum lugar da Internet não receberam nenhuma vantagem especial - mas os revisores ficaram muito felizes quando não tiveram que baixar repositórios e executá-los localmente em seus computadores. Então isso serviu como uma vantagem para o carma.

A primeira tarefa foi muito útil principalmente para o aluno. Aqueles que não aceitamos agora têm um currículo preparado - você pode anexá-lo com orgulho a todas as respostas ou publicá-lo em suas páginas gh.

Tarefa 2: Rota de transporte

O autor da tarefa é o chefe do grupo de interfaces de pesquisa, Denis Balyko.

Condição

Você tem um mapa estelar? Mostra o nome de cada estrela, bem como a distância dela a outras estrelas em segundos-luz. Implemente a função de solução, que deve receber três argumentos: um objeto em que as chaves são os nomes das estrelas e os valores são as distâncias às estrelas (tráfego de mão única no espaço), bem como os nomes dos os pontos inicial e final do caminho - início e fim, respectivamente. A função deve retornar a distância mais curta da estrela inicial até a estrela final e o caminho a seguir.

Assinatura da função:

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

Dados de entrada de exemplo:

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

Exemplo de saída:

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

Nota: O esqueleto da solução está na pasta src/, coloque sua solução em solução.js.

A verificação da segunda tarefa foi a mais automatizada e objetiva. A maioria dos caras adivinhou que era necessário implementar o algoritmo de Dijkstra. Aqueles que encontraram sua descrição e implementaram o algoritmo em JS estão bem. Porém, ao verificar o trabalho, nos deparamos com muitos artigos com os mesmos erros. Pesquisamos fragmentos de código na Internet e encontramos um artigo do qual os participantes copiaram o algoritmo. É engraçado que muitas pessoas copiaram o código do artigo junto com os comentários do autor. Tais trabalhos receberam nota baixa. Não proibimos o uso de nenhuma fonte, mas queremos que a pessoa se aprofunde no que escreve.

critérios

Os principais pontos foram atribuídos aos testes. Às vezes ficava claro que os caras estavam mexendo no repositório, renomeando pastas, e os testes falhavam simplesmente porque não conseguiam encontrar os arquivos necessários. Este ano tentamos ajudar esses caras e devolvemos tudo ao seu lugar para eles. Mas no próximo ano pretendemos mudar para um sistema de concurso, e isso não será mais perdoado.

Havia também critérios manuais “humanos”. Por exemplo, a presença de um único estilo de código. Ninguém deduziu pontos por usar tabulações em vez de espaços ou vice-versa. Outra questão é alternar aspas simples com aspas duplas de acordo com uma regra que você conhece e colocar ponto-e-vírgula aleatoriamente.

A clareza e a legibilidade da solução foram levadas em consideração separadamente. Em todas as conferências do mundo dizem que 80% do trabalho de um programador consiste em ler código de outras pessoas. Até mesmo crianças em idade escolar passam por revisões de código – de seus curadores e uns dos outros. Portanto, este critério teve um peso significativo. Houve trabalhos em que não havia variáveis ​​com mais de um caractere - por favor, não faça isso. Os comentários dos participantes foram muito encorajadores – com exceção daqueles que foram idênticos aos comentários de Stella Chang.

O último critério é a presença de autotestes. Apenas algumas pessoas os adicionaram, mas para todos isso se tornou uma grande vantagem em seu carma.

A decisão correta:

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

Tarefa 3: Calendário de Eventos

Foi preparado pelos desenvolvedores de interface Sergey Kazakov e Alexander Podskrebkin.

Condição

Escreva um mini-calendário para exibir sua programação. Você pode escolher qualquer horário que desejar. Por exemplo, a programação de conferências frontend em 2019.

O calendário deve se parecer com uma lista. Não há outros requisitos de design. Possibilita definir lembretes de eventos com 3, 7 e 14 dias de antecedência. Após o primeiro download da Internet, o calendário deverá abrir e funcionar offline.

Recursos úteis

Cronograma da conferência de front-end:
confs.tech/javascript?topics=javascript%2Bcss%2Bux

Trabalhadores de serviço:
developer.mozilla.org/ru/docs/Web/API/Service_Worker_API/Using_Service_Workers
desenvolvedores.google.com/web/fundamentals/primers/service-workers

API de notificações:
developer.mozilla.org/ru/docs/Web/API/Notifications_API

A terceira tarefa foi a mais interessante de testar, pois havia tantas soluções possíveis, cada uma com a sua. Verificamos como o candidato lida com tecnologias desconhecidas – se ele sabe pesquisar, se testa suas soluções.

critérios

Calendário dobrado. Sim, ainda precisava ser definido. Houve também quem interpretasse a condição muito literalmente e não inserisse uma única linha de código CSS. Não parecia muito atrativo, mas se tudo funcionasse os pontos não diminuíam.

Obtendo uma lista de eventos de uma fonte. Esta não é uma tarefa de layout, portanto a lista de eventos nela incluída não foi contabilizada. Você sempre pode cancelar uma conferência, reagendá-la ou adicionar uma nova. Então foi necessário receber dados de fora e renderizar o layout com base no JSON recebido. Era importante obter os dados de qualquer forma (usando o método fetch ou usando XMLHttpRequest). Se uma pessoa adicionou um polyfill para busca e marcou sua escolha no leia-me, isso foi contado como um ponto positivo.

Registro do trabalhador de serviço sem erros e trabalhe offline após o primeiro download. Aqui está um exemplo. trabalhador de serviço com cache de agendamento na primeira inicialização. Detalhes sobre service workers, suas capacidades e formas de trabalhar com eles (estratégias para trabalhar com caches, trabalhar offline) podem ser encontrados aqui.

Capacidade de definir um lembretepara que realmente funcione após 3, 7, 14 dias. Foi necessário entender a API de Notificações, link para o qual estava certo na tarefa. Não esperávamos nenhuma implementação específica para verificar se é hora de avançar. Qualquer opção de trabalho foi aceita: armazenamento em localStorage, IndexDB ou polling periódico por um service worker. Foi até possível fazer um servidor push (aqui exemplo), mas não funcionaria offline. Era igualmente importante receber um push depois que a página fosse fechada – e aberta depois de algum tempo. Se o lembrete morresse ao mesmo tempo em que a página era fechada, a solução não era contabilizada. Foi legal quando a galera pensou nos revisores e deu a oportunidade de conseguir um empurrão agora mesmo - para não esperar 3 dias.

Capacidade de colocar um ícone na área de trabalho (PWA). Verificamos a presença do arquivo manifest.json com os ícones corretos. Alguns caras fizeram esse arquivo (ou deixaram gerado no CreateReactApp) - mas não adicionaram os ícones corretos. Então, ao tentar instalar, ocorreu um erro como “é necessário um ícone diferente”.

Estilo de código e estrutura do projeto. Como na segunda tarefa, analisamos um único estilo de código (mesmo que não coincidisse com o nosso). Alguns caras estragaram os linters - isso é ótimo.

Erros do console. Se houvesse um indicador bem no console de que algo estava errado e o participante não prestasse atenção, deduzimos pontos.

Resultados de

O que há de engraçado nas decisões dos participantes:

  • Um questionário continha o seguinte texto: “Um amigo programador me ajudou a montar uma aplicação React. Eu o bombardeei com perguntas sobre como e por que, e ele me contou. Gostei muito, quero saber mais sobre isso.” Estávamos torcendo por esta inscrição de todo o coração, mas infelizmente o amigo do candidato não ajudou muito a fazer a inscrição funcionar.
  • Um candidato enviou um link para o GitHub, onde estava localizado o arquivo RAR - é difícil comentar sobre isso. 🙂
  • Outro candidato, no comentário na primeira linha do arquivo Solution.js, admitiu honestamente que copiou o algoritmo.

Recebemos inscrições de 76 candidatos e selecionamos 23 pessoas. Recebemos questionários não apenas de Minsk, mas também de Moscou, São Petersburgo e até do Tartaristão. Alguns rapazes nos surpreenderam com suas profissões atuais: um deles é perito forense e o outro é estudante de medicina.

O resultado foi uma distribuição interessante de taxas de sucesso na conclusão de tarefas. Os participantes completaram a primeira tarefa com uma média de 60%, a segunda com 50% e a terceira acabou por ser a mais difícil e foi concluída com uma média de 40%.

À primeira vista, as tarefas parecem complexas e demoradas. A razão não é que queiramos eliminar o maior número possível de candidatos. Durante seus estudos, os alunos enfrentam tarefas da vida real - fazer um bate-papo, Yandex.Music para crianças ou Yandex.Weather para pessoas que dependem do clima. Para isso você precisa de uma base inicial.

Lembro-me de ver minha tarefa de entrada no SRI há dois anos e pensar que nunca a resolveria. O principal neste momento é sentar-se, ler atentamente as condições e começar a fazê-lo. Acontece que as condições contêm quase 80% da solução. Por exemplo, na condição da terceira tarefa (a mais difícil), adicionamos links para service workers e API de Notificações no MDN. Os alunos que estudaram o conteúdo dos links concluíram-no sem dificuldade.

Eu realmente gostaria que este artigo fosse lido por candidatos que planejam ingressar no SRI no futuro, que não conseguiram ingressar na Escola de Minsk ou que estão começando a fazer qualquer outra tarefa de teste. Como você pode ver, é bem possível fazer isso. Basta acreditar em si mesmo e ouvir todas as dicas dos autores.

Fonte: habr.com

Adicionar um comentário