Enjoy 20% off all plans by following us on social media. Check out other promotions!
Guia de Entrevista Front End

Resumo de Perguntas de Interface de Usuário Front-End

Principais dicas para melhorar as interfaces de usuário que você precisa construir durante entrevistas para desenvolvedores front-end/web - Estrutura de código, gerenciamento de estado, acessibilidade e muito mais.

Aqui estão algumas dicas que você pode usar para melhorar as interfaces de usuário que você precisa construir ou projetar durante entrevistas para desenvolvedores front-end. Essas dicas podem ser aplicadas tanto a Entrevistas de Codificação de Interface de Usuário quanto a Entrevistas de Design de Sistema Front End.

Geral

  • Divida o problema: Divida o problema em etapas/marcos que se constroem progressivamente e escreva seu código de forma progressiva.
  • Teste frequentemente: Teste a interface de usuário no navegador após concluir cada recurso para que você possa identificar bugs precocemente. Bugs detectados mais cedo são mais fáceis de corrigir. Certifique-se de que o recurso atual está funcionando antes de passar para o próximo recurso.
  • Use frameworks JavaScript, se possível: Sua vida será muito mais fácil se você optar por construir interfaces de usuário complexas usando JavaScript puro (Vanilla JavaScript), já que o código pode ficar muito longo e confuso rapidamente. Recomendamos construir aplicativos e jogos usando um framework, se possível.
  • Pense antecipadamente e planeje adequadamente: Pense em quais recursos seu entrevistador pode pedir para adicionar a seguir. Projete seu código de forma que seja fácil adicionar novos recursos.

Organização de Componentes

Como você estrutura seu código?

  • Adote o Padrão Contêiner/Apresentação: Para alcançar um bom desacoplamento, o código de renderização deve ser independente da origem dos dados. Separe os componentes em um externo que fornece os dados e um interno sem estado que renderiza a visualização com base nos dados. Isso facilita a transição da visualização do estado local do componente/aplicativo para os dados carregados da rede e vice-versa. Você só precisa alterar o componente externo, e o componente interno pode ser usado como está.
  • Divida o aplicativo em subcomponentes: Se a interface do usuário tiver várias partes, divida-a em componentes menores e identifique as props/estado necessários para cada componente.
  • Área de superfície da API mínima: Não passe dados em excesso para componentes internos que não os necessitam.
  • Instanciação de Componentes: Ao criar componentes de interface do usuário, defina APIs (geralmente funções) que permitam a criação de várias instâncias independentes dos componentes, juntamente com opções configuráveis e valores padrão. Evite escrever código (por exemplo, dependendo de variáveis globais) que impeça a criação de instâncias separadas de componentes de interface do usuário.
    • JavaScript Puro (Vanilla JavaScript): Crie uma função que receba um elemento DOM (o elemento de contêiner) e um objeto de opções. Dentro da função, você pode criar dinamicamente elementos DOM e anexá-los ao elemento de contêiner. Outra fonte de inspiração para uma API de componente é o jQuery UI, mas ele tem uma dependência do jQuery.
    • Outros Frameworks de UI em JavaScript: A maioria dos modernos frameworks de UI em JavaScript, como o React, o obriga a pensar em termos de componentes por padrão.

Design de Estado

Estado é a informação que muda ao longo do tempo em sua interface do usuário, geralmente devido a interações do usuário ou eventos em segundo plano (resposta de solicitações de rede, passagem do tempo, eventos WebSocket).

A maioria das perguntas de entrevistas relacionadas à interface do usuário exigirá o uso de estado, e projetar o estado de forma adequada é de extrema importância.

  • Determine o estado mínimo necessário em sua interface do usuário: Quanto menor o estado, mais fácil é ler e entender o código -> menor probabilidade de erros.
    • Identificar o estado essencial versus o estado derivado. Estado derivado é um estado que pode ser calculado a partir do estado essencial.
  • Separe o código de renderização do código de gerenciamento de dados: Torne a interface do usuário uma função de seus dados e separe seu código em dois grupos (código de renderização e código de gerenciamento de dados) para uma melhor legibilidade. Se você estiver usando frameworks JavaScript como o React, mais ou menos será obrigado a fazer isso.
  • Utilize o padrão de redutor de estado para interações de estado complexas: Se a pergunta exigir muitos campos de estado e certas ações requererem a alteração de vários campos ao mesmo tempo, utilize um redutor para consolidar a lógica de atualização de estado. Primeiramente popularizado pelo Redux, o padrão de redutor de estado o incentiva a determinar o estado da sua interface de usuário, as ações que podem ser realizadas e como combinar ações com o estado para derivar o próximo estado. Se você estiver usando o React, é possível alcançar esse padrão por meio do gancho (hook) useReducer do React. Geralmente, o Redux é excessivo para entrevistas, e useReducer deve ser suficiente.

A documentação do React sobre "Gerenciamento de Estado" é um excelente recurso sobre como projetar e usar o estado de componentes corretamente. Algumas das ideias mencionadas não são específicas do React e podem ser aplicadas a qualquer estrutura de interface do usuário (UI).

JavaScript

O seu JavaScript utiliza uma sintaxe moderna da linguagem e boas práticas, evitando práticas ruins?

  • Utilize um guia de estilo: Utilize um guia de estilo de JavaScript como o Guia de Estilo JavaScript da Airbnb. Durante o desenvolvimento, ferramentas de análise estática como o ESLint podem ajudar a aplicar algumas dessas boas práticas. No entanto, essas ferramentas podem não estar disponíveis durante entrevistas. Tente se acostumar a escrever código com um bom estilo de codificação sem depender de uma ferramenta.
  • Não altere o ambiente global: Isso se aplica a cenários de JavaScript puro (Vanilla JavaScript). Evite poluir o escopo global ao declarar variáveis e funções globais. Escreva uma Expressão de Função Imediatamente Invocada (IIFE) e coloque todo o código personalizado dentro dela.

HTML

Você está escrevendo HTML semântico com os atributos corretos?

  • Tags semânticas: Use tags de cabeçalho para títulos, tags de botão para elementos interativos, tags de lista para elementos sequenciais, e assim por diante. Não utilize <div> para tudo!
  • Hierarquia de títulos: Garanta que as tags de cabeçalho tenham uma hierarquia e que não haja mais de um <h1> no DOM.
  • Elementos interativos: Utilize <button> para elementos que requerem interação. Evite adicionar manipuladores de clique (click handlers) a elementos <div> e <span>.

Formulários

Os formulários são complexos por si só e merecem sua própria seção.

  • Vincular rótulos e entradas: Os elementos <input> devem ser vinculados aos elementos <label> usando os atributos id e for.
  • Agrupe entradas em um formulário: Os elementos <input> devem ser envolvidos em um elemento <form> para que ao clicar nos botões e pressionar Enter o formulário seja enviado. Lembre-se de adicionar event.preventDefault() se a solicitação de rede deve ser feita usando Ajax.
  • Os campos de entrada devem ter tipos apropriados: Os elementos <input> devem ter o atributo type apropriado, como email, password, number, etc.
  • Aproveite a validação nativa de formulários HTML: Sempre que possível, utilize o atributo required combinado com outros atributos como pattern, min, max, etc.

CSS/Styling

Seu CSS está escrito de forma escalável e fácil de entender?

  • Escreva CSS puro: Aprenda a escrever CSS sem depender de pré-processadores como Sass e Less. Nem todos os ambientes permitirão o uso de processadores, e as perguntas de entrevista provavelmente são pequenas e não se beneficiam realmente dos recursos que os pré-processadores CSS trazem. A funcionalidade mais útil dos processadores CSS é o uso de variáveis, que está disponível nativamente por meio das propriedades personalizadas CSS (variáveis).
  • Adote uma convenção de nomenclatura CSS: Considere adotar uma metodologia de nomenclatura CSS como o Block Element Modifier (BEM) ao escrever suas classes.
  • Evite seletores #id em componentes: Ao construir componentes de interface do usuário destinados a serem reutilizados (por exemplo, botões, abas, menus, modais etc.), evite usar seletores #id no HTML, pois os id devem ser globalmente exclusivos, mas você pode ter várias instâncias do componente.
  • Organize seu CSS: Leia sobre como organizar seu CSS em projetos grandes e como ter uma Arquitetura Escalável e Modular para CSS.

Experiência do Usuário

Sua interface de usuário proporciona uma ótima experiência para o usuário?

  • Amigável para dispositivos móveis: Verifique se você precisa fazer com que sua interface de usuário funcione bem em dispositivos móveis.
    • As consultas de mídia CSS podem ser usadas para renderizar um layout diferente em dispositivos móveis.
    • Faça elementos interativos, como botões, grandes o suficiente para serem pressionados (recomendamos pelo menos 44 x 44 px) e com espaço suficiente entre eles.
  • Estados de erro: Reflita os erros prontamente e de forma clara - erros de validação de formulário, erros de solicitação de rede.
  • Lidar com a renderização de imagens de diferentes dimensões: Faça sua interface de usuário funcionar para renderizar imagens de todas as dimensões, preservando ao mesmo tempo as proporções originais.
    • Use background-image do CSS em conjunto com background-position: contain para que a imagem se ajuste dentro da área definida. Se for aceitável que a imagem seja cortada (por exemplo, para fundos degradê), use background-position: cover.
    • As tags <img> têm uma propriedade semelhante chamada object-fit com valores contain e cover.
  • Atualizações otimistas: Técnica avançada em que o estado de sucesso é refletido mesmo que a solicitação de rede ainda esteja pendente. Se a solicitação falhar, reverta as alterações na interface do usuário e exiba uma mensagem de erro.

Rede

Sua interface do usuário lida com a natureza imprevisível das solicitações e condições de rede?

  • Reflita os estados da solicitação de rede: Se a interface do usuário envolver a realização de solicitações de rede, mostre claramente o estado pendente/sucesso/falha das solicitações
    • Pendente: Desativar campos/botões, mostrar um spinner.
    • Erro: Mostrar uma mensagem de erro.
    • Sucesso: Atualizar a interface do usuário e/ou mostrar uma mensagem de sucesso.
  • Condições de corrida: Uma razão comum é devido a solicitações de rede paralelas, onde a ordem de resposta não é garantida. Uma solicitação feita posteriormente poderia receber uma resposta mais cedo. Se a sua interface de usuário for suscetível a isso, você pode acompanhar as solicitações mais recentes e ignorar os resultados das mais antigas. Alternativamente, faça com que sua interface de usuário não possa enviar várias solicitações de rede ao mesmo tempo, por exemplo, desabilitando elementos que acionam solicitações de rede após serem clicados.
  • Evitar solicitações duplicadas: Os botões devem ser desabilitados após o envio para evitar a realização de solicitações de rede duplicadas.
  • Consolidando solicitações: Se a interface de usuário estiver fazendo um grande número de solicitações de rede, você pode:
    • Debounce/throttle: Limite a taxa de solicitações de rede disparadas.
    • Solicitações em lote: Agrupe solicitações juntas e faça apenas uma única solicitação. Isso requer que o lado do servidor suporte esse formato.
  • Caching: Se uma solicitação com os mesmos parâmetros foi feita recentemente, você pode reutilizar a resposta anterior e economizar uma ida e volta na rede?
  • Tempo limite da solicitação: Você pode querer artificialmente mostrar que a solicitação falhou (expirou) se a solicitação não receber uma resposta após uma duração estipulada.
  • Atualizações otimistas: Técnica avançada na qual o estado de sucesso é refletido mesmo quando a solicitação de rede ainda está pendente. Se a solicitação falhar, reverta as alterações na interface de usuário e exiba uma mensagem de erro.

Acessibilidade (a11y)

Lidar com acessibilidade na interface de usuário é uma grande vantagem e, em alguns casos, um requisito para engenheiros sênior.

  • Você consegue usar a interface de usuário apenas com o teclado?
  • Você consegue usar o componente da sua interface com um leitor de tela?
  • Seu componente de interface pode funcionar sem cores?
  • Seu componente de interface pode funcionar sem som?

Fonte: Componentes de UI Acessíveis para o web

  • Leitores de tela, papéis, estados e propriedades ARIA:
    • Adicione os aria-roles corretos para elementos personalizados construídos sem o uso de tags HTML personalizadas.
    • Use aria-labels para descrever elementos onde o texto não é exibido (por exemplo, botões apenas com ícones).
    • Vincule elementos de mensagens de erro aos elementos responsáveis por eles por meio de aria-describedby ou aria-errormessage.
    • Texto alt de imagens: Adicione o atributo alt aos elementos <img> para que leitores de tela possam descrever a imagem.
  • Interações por teclado
    • Adicione o atributo tabindex aos elementos que você deseja que sejam focáveis através da navegação por teclado.
    • Elementos podem ser acionados via teclado.
    • Verifique se a ordem de foco faz sentido.
  • Problemas visuais
    • Contraste de cores: Contraste de cores suficiente entre texto/imagens e o plano de fundo.
    • Tamanho dos elementos: o tamanho da fonte e dos elementos interativos deve ser grande o suficiente para o meio pretendido.

o web.dev, do Google, oferece um curso abrangente e gratuito sobre acessibilidade, o qual recomendamos fortemente.

Casos extremos

Provavelmente não há tempo suficiente para lidar com todos os cenários de casos extremos no seu código durante a entrevista, mas é bom mencioná-los ao entrevistador para ganhar pontos extras.

  • Lidar com strings longas: Strings na interface de usuário (por exemplo, títulos/rótulos de botões) podem fazer com que a interface de usuário se comporte de maneira estranha, como o overflow de texto, afetando a posição de elementos circundantes. Strings longas podem ser resultado de entradas do usuário ou de traduções.
  • Estados vazios: Mostrar uma mensagem/indicador de estado vazio para indicar a ausência de conteúdo, por exemplo, quando a lista está vazia. Mostrar nada pode fazer com que o usuário pense que há uma solicitação de rede pendente e que os dados ainda estão sendo buscados.
  • Muitos itens em uma lista: Mostrar muitos itens em uma única página pode resultar em uma má experiência do usuário (o usuário precisa rolar muito) e baixo desempenho em termos de responsividade e consumo de memória.
    • Paginação: Divida uma longa lista de itens em várias páginas.
    • Listas virtuais: Renderização apenas das linhas visíveis de conteúdo em uma lista dinâmica em vez da lista inteira.
    • Truncar o conteúdo excedente e mostrar uma elipse. A propriedade CSS word-break será útil.
    • Limite o conteúdo às primeiras X caracteres/palavras e oculte o conteúdo excedente atrás de um botão "Mostrar Mais".

Performance

  • Throttle/debounce: Throttle e debounce são técnicas de limitação de taxa para evitar operações desnecessárias. Essa técnica pode ser usada para operações que não são extremamente sensíveis ao tempo, como solicitações de rede e callbacks de eventos de rolagem/redimensionamento.
  • Cache: Os resultados de cálculos duplicados ou solicitações de rede podem ser armazenados em memória/armazenamento do navegador e não repetidos.
  • Carregamento sob demanda: Carregue os dados/código do componente apenas quando forem necessários, em vez de carregar tudo no início.
  • Pré-carregamento de dados: Reduza a latência de rede pré-carregando dados imediatamente antes de serem necessários, para que as atualizações apareçam instantaneamente.
  • Muitos itens em uma lista: Consulte o ponto sob "Casos Especiais" acima.

Segurança

  • Scripting Cross-site (XSS): Evitar atribuir a [Element.innerHTML](https://developer.mozilla. rg/en-US/docs/Web/API/Element/innerHTML) ou dangerouslySetInnerHTML do React ao renderizar conteúdo no DOM se ele vier de usuários para impedir script entre sites, atribuir ao Node. extContent ou use o método experimentalElement.setHTML() em vez disso. Consulte o Folha de Dicas de Prevenção de XSS do OWASP
  • Codificação de saída para "Contextos de URL": Se a entrada fornecida pelo usuário puder ser usada em parâmetros de consulta de URL, use encodeURIComponent para evitar que valores indesejados façam parte da URL (por exemplo, parâmetros de consulta extras).
  • Cross Site Request Forgery (CSRF): Consulte a OWASP's XSS Prevention Cheat Sheet para obter informações sobre prevenção de CSRF e outras vulnerabilidades de segurança.

Internacionalização (i18n)

Sua interface de usuário funciona para múltiplos idiomas? Quão fácil é adicionar suporte para mais idiomas?

  • Evite a codificação rígida de rótulos em um determinado idioma: Alguns componentes de interface do usuário têm strings de rótulo incorporadas (por exemplo, um carrossel de imagens tem rótulos para os botões anterior/próximo). Seria bom permitir a personalização dessas strings de rótulo tornando-as parte das props/opções do componente.
  • A UI pode renderizar strings longas: Consulte a seção acima sobre a renderização de strings longas.
  • Idiomas da direita para a esquerda: Alguns idiomas (por exemplo, árabe, hebraico) são lidos da direita para a esquerda, e a interface do usuário precisa ser virada horizontalmente. Use propriedades lógicas CSS para fazer seu layout funcionar para diferentes modos de escrita.