Olá, queria compartilhar minha experiência no desenvolvimento de um caso de teste para a Aviasales.
Recentemente, me deparei com um trabalho de desenvolvedor do React na Aviasales. Enviei uma inscrição, após o que no dia seguinte o RH me respondeu e me informou que eu teria que fazer uma tarefa de teste. Realmente não gosto de executar tarefas de teste, pois tenho que gastar bastante tempo na implementação delas e, em caso de falha, isso será desperdiçado. Mas eu concordei ...
Você pode encontrar a tarefa de teste aqui no link .
Aqui está um link para o meu repositório da tarefa concluída.
Limitei-me a concluir a tarefa em um dia (embora tenha feito pequenas melhorias após a publicação: terminei o esboço, por assim dizer).
O que eu escolhi para o desenvolvimento:
- Escolhi o NextJS como base, porque não queria mexer na configuração do ambiente para o Webpack e você pode implantar o projeto em si com apenas alguns cliques.
- Eu queria escrever rápido e escolhi o pacote React-IOC em conjunto com o MobX, em vez do Redux. Este é um pacote que permite escrever aplicativos por meio de serviços semelhantes a serviços angulares.
- Usei o Web Worker para que não houvesse atrasos na interface ao classificar uma grande quantidade de dados.
- Não usei o Typecript com o objetivo de não escrever código adicional com um desperdício inútil de tempo em uma tarefa de teste.
- Com base no parágrafo 4, também não escrevi testes.
- Adicionei dois pacotes adicionais ao projeto: debounce, RxJS. O primeiro é necessário para criar retornos de chamada simples, por exemplo, alterando o estado do download para que o girador não mostre a carga se o download demorar muito pouco. Eu sempre uso o segundo pacote para criar um script de ação, por exemplo, para processar estados em caso de erro ao enviar uma solicitação ao servidor.
O procedimento para o primeiro estágio de desenvolvimento:
- Repositório inicializado.
- Projeto NextJS inicializado.
- Adicionada uma página base de índice com uma mensagem Hello World.
- Criou um serviço ticket.provider que interage com o servidor api.
- Criou o serviço ticket.service, que injeta ticket.provider e preenche o observador com uma variedade de tickets exibidos
- Criado ticket.filter.service, que armazena dados filtrados injetados a partir do ticket.service via @computed
A segunda etapa do desenvolvimento:
- Criou componentes e estilos pintados para eles usando o layout fornecido no repositório de tarefas.
- Fiz uma rotação do download e reduzi o valor dos serviços.
- Conectou toda a lógica de serviço aos componentes.
- Adicionados utilitários com formatação de dados, como tempo e dinheiro.
Decidi experimentar a interface "touch" e encontrei falhas ao usar o aplicativo:
- Existem lentidões na interface ao alterar o filtro e a classificação, por isso transferi o armazenamento, a recuperação e a filtragem de dados para o Web Worker, após o que os atrasos desapareceram completamente.
- O Spinner não corrigiu a animação da linha de salto, então substituí-a por uma exibição visual de linhas por uma animação tremeluzente.
- Para facilitar a renderização de dados, transferi as chamadas de formatação de dados para o Web Worker, o que reduz a carga na renderização de componentes
Então terminei meu trabalho e, no final do dia, enviei uma tarefa para verificação.
Como me limitei no tempo, não otimizei ainda mais o aplicativo, ou seja, não usei React.memo (...). Também não comecei a substituir a janela e o roteador por injetores nos serviços. Perdoe-me por isso, isso é uma falha.
Mas no dia seguinte, adicionei a funcionalidade de lembrar o estado do filtro na linha de URL do navegador, após o qual já estava satisfeito com o trabalho realizado.
Eu esperei uma resposta deles por 7 dias, eles não responderam a nenhuma das minhas mensagens. Foi uma experiência desagradável, por assim dizer. Mas ainda assim eles responderam, e a resposta foi extremamente angustiante de se ler. A mensagem pode ser vista abaixo.
Vamos dar uma olhada nos pontos:
[1] "O trabalho foi feito com muito cuidado"
Não vejo onde, nem argumento, pois não há exemplos.
[2] "Parece que o desenvolvimento seguiu os objetivos de" funciona "e ignorou" como funciona ".
Não é um argumento, não há exemplos.
[3] "Com base em nossos requisitos para os níveis de candidatos, a tarefa concluída mal chega ao meio."
Quais são os requisitos? Onde eles estão?
[4] “Esperamos que os filtros não sejam codificados e se adaptem aos dados. Se você for para aviasales, poderá ver que os ingressos são mostrados imediatamente quando a primeira parcela aparecer e não esperamos que todos carreguem. "
Este requisito não estava na tarefa anexada. E o próprio aplicativo Aviasales, na minha opinião, não possui uma interface de referência, e saltar bilhetes não é a melhor solução.
[5] “Por que o filter.service conhece o roteador e a janela? Ele não deve controlar o estado do aplicativo e ter essas dependências. ”
Porque os serviços são criados para controlar o estado de todo o aplicativo ou o módulo onde eles existem. Aqui o autor sugere claramente escrever toda a lógica nos componentes.
[6] “Trabalhadores da Web. Qual é o lucro? Nesse caso, muito tempo é gasto em operações assíncronas e a carga salva no encadeamento principal é gasta em serializar / desserializar objetos (e objetos observáveis). Se estamos falando de otimizações, vale a pena começar não com a remoção no web worker, mas com a correção dos problemas no segmento principal. ”
Como lidar com o processamento de grandes quantidades de dados no thread principal e ao mesmo tempo sem atrasos na interface? Será extremamente interessante para mim descobrir se alguém tem um exemplo e depois escrever nos comentários. Aparentemente, estou perdendo alguma coisa.
[7] “Não faz sentido adicionar rxjs ao projeto apenas para implementar o carregamento repetitivo e sequencial.”
Por que não faz sentido? Você pode importar funções estritamente necessárias para o RxJS; se pacotes e funções de agitação de árvore não funcionarem corretamente, isso não aumentará o tamanho do aplicativo.
[8] “O projeto não pode ser escalado e mantido. Construções como (ticket.segments || [{}, {}]).map((ticket) => ...)
muito complicadas. ”
Vamos examinar os critérios de dimensionamento e suporte: acessibilidade (serviços resolvem esse problema), riscos ( ticket.segments || [{}, {}]
- este é apenas um exemplo de como lidar com casos se a entrada não contém dados. Um exemplo é ruim, mas a estrutura anulável se aproxima, pelo menos, mas eu tento cumprir), código limpo (bem, pelo menos eu sei o que é :), embora eu tentei escrever tudo como deveria). Parece que tudo é capturado, novamente não um argumento.
[9] “Tive a impressão de que não há absolutamente nenhuma compreensão de como o React funciona sob o capô. Existem muitos erros críticos no trabalho com acessórios para componentes que têm um efeito muito ruim no desempenho. Os mecanismos de otimização de reação são ignorados. ”
Não consigo entender onde estão esses problemas descritos. Que tipo de mecanismos?
[10] "Criando funções de manipulador dentro da renderização".
Eu não tenho nenhuma função de manipulador em renderização, alguém entende o que está escrito aqui? Eu até transferi o processamento de formatação para o Web Worker
[11] “Criando um novo objeto vazio e transferindo-o para o ticket. ticket-list-loading.jsx:10
ou Ticket.tsx:24
"
Não há nada crítico aqui, exceto a minha preguiça de remover separadamente o componente do ticket de carregamento. Passar um objeto vazio não viola nenhum princípio de programação, exceto que aqui era necessário fazer isso através de ticket = ticket || {};
ticket = ticket || {};
mas isso se deve ao fato de que o tempo de desenvolvimento foi limitado a um dia e levaria mais tempo para corrigir todas as falhas menores.
[12] "Índices de matriz como chaves na lista de tickets"
Há uma pergunta sobre o porquê da api não retornar elementos com id. Portanto, ao receber dados do servidor, eu precisaria gerar chaves exclusivas para cada elemento, o que não fiz como parte da tarefa de teste, pois mesmo em um projeto real, essa é uma abordagem duvidosa.
E, finalmente, a conclusão: “Em geral, o React não funcionou (
Total: para o nível médio, esperamos que não haja problemas críticos com a reação, mas existem muitos deles no trabalho realizado. ”
Já não há comentários ...
Obrigado se você ler até o fim. Tenho uma opinião muito negativa sobre a Aviasales, por isso posto tudo aqui para que você possa avaliar se deve contatá-los ou não.
Texto completo da mensagem:
O trabalho é feito com muito cuidado. Parece que durante o desenvolvimento os objetivos foram "funciona" e "como funciona" foi ignorado. Com base em nossos requisitos para os níveis de candidatos, a tarefa concluída mal chega ao meio.
Desempenho e estrutura:
Esperamos que os filtros não sejam codificados e se adaptem aos dados. Se você for para aviasales, poderá ver que os tíquetes são mostrados imediatamente quando a primeira parcela aparecer, e não esperamos que todos carreguem.
Além disso, mais pontos técnicos.
- Por
filter.service
conhece o roteador e a janela? Ele não deve controlar o estado do aplicativo e ter essas dependências. - Trabalhadores da Web. Qual é o lucro? Nesse caso, muito tempo é gasto em operações assíncronas e a carga salva no encadeamento principal é gasta em serializar / desserializar objetos (e objetos observáveis). Se estamos falando de otimizações, vale a pena começar não com a remoção no web worker, mas com a correção dos problemas no thread principal.
- Não faz sentido adicionar rxjs ao projeto apenas para implementar novas tentativas e carregamento sequencial.
- O projeto não pode ser dimensionado e mantido. Construções como (
ticket.segments || [{}, {}]).map((ticket) => ticket
) são muito complicadas.
Reagir:
Tive a impressão de que não há absolutamente nenhuma compreensão de como o React funciona sob o capô. Existem muitos erros críticos no trabalho com acessórios para componentes que têm um efeito muito ruim no desempenho. Os mecanismos de otimização de reação são ignorados. Brevemente sobre os problemas: - Criando funções de manipulador dentro de renderização.
- Crie um novo objeto vazio e transfira-o para o ticket.
ticket-list-loading.jsx:10
ou Ticket.tsx:24
. - Índices de matriz como chaves em uma lista de tickets.
Em geral, o React não funcionou :(
Total: para o nível intermediário, esperamos que com o react não haja problemas críticos, mas existem muitos deles no trabalho realizado.