Pedido para acabar com desafios de programação irreais
(blackentropy.bearblog.dev)- Algumas tarefas de programação irreais em entrevistas técnicas criam uma situação de pressão diferente do trabalho real e não conseguem medir adequadamente a capacidade prática do desenvolvedor
- Tarefas individuais de alta pressão não refletem um ambiente de trabalho com colaboração e suporte, e tendem a virar algo como depurar uma base de código antiga sem documentação nem ajuda da equipe
- Mesmo quando a empresa fala em uma “tarefa de 4 horas”, somando pesquisa sobre a empresa, revisão dos requisitos da vaga e refinamento da entrega, isso pode virar mais de 8 a 10 horas
- Tarefas em uma stack sem relação com o cargo costumam ser justificadas como avaliação de adaptabilidade, mas pedir a um desenvolvedor Ruby que faça debugging em PHP pode não condizer com a aderência real ao papel
- A contratação deve focar em tecnologias relevantes, resolução de problemas, colaboração e potencial de crescimento, em vez de tarefas arbitrárias de alta pressão; tarefas excessivas podem desgastar e afastar bons candidatos
Tarefas de entrevista desalinhadas do trabalho real
- Algumas entrevistas técnicas pedem que o desenvolvedor resolva tarefas como depurar PHP legado ou criar um miniapp em poucas horas
- Essas tarefas individuais diferem da forma como o trabalho realmente acontece
- No trabalho, normalmente existe colaboração com a equipe e acesso ao suporte necessário
- Ter de depurar rapidamente uma base de código antiga sozinho, sem documentação nem ajuda da equipe, não corresponde a um ambiente normal de desenvolvimento
- As empresas veem isso como avaliação de “capacidade de resolver problemas”, mas, se a tarefa não estiver ligada às exigências reais do cargo, fica difícil avaliar a adequação prática do candidato
O custo oculto de tempo e o peso para o candidato
- O tempo recomendado para tarefas de programação muitas vezes não reflete adequadamente o tempo que o candidato realmente gasta
- Antes da tarefa, é preciso pesquisar a empresa e verificar os requisitos da vaga
- Também é necessário tempo para refinar o projeto e deixá-lo em boas condições para entrega
- Uma tarefa “de 4 horas” pode virar 8 horas, 10 horas ou mais
- Para desenvolvedores que conciliam trabalho e vida pessoal, isso pode passar a sensação de trabalho não remunerado por um emprego que ainda nem conquistaram
Quando a avaliação de adaptabilidade erra o alvo
- Tarefas em stacks sem relação com a vaga às vezes são justificadas como avaliação de “adaptabilidade”
- Pedir a um desenvolvedor Ruby para depurar PHP, independentemente da importância da adaptabilidade, pode ser um critério inadequado para julgar o valor do candidato
- Apenas a capacidade de lidar rapidamente com tarefas ambíguas e irrelevantes não basta para determinar se a pessoa se encaixa no cargo real
- Algumas tarefas podem parecer mais uma forma de a empresa exibir um padrão “de elite” do que de avaliar a adequação do candidato
- Se toda contratação criar uma barreira de “top 1%”, até candidatos experientes que poderiam desempenhar bem o trabalho podem desistir por causa de situações artificiais e de alta pressão
O que uma tarefa de contratação deve avaliar
- O processo de contratação deve ser desenhado em torno das competências concretas exigidas pelo cargo
- É preciso evitar tarefas no estilo bootcamp de programação que não tenham relação com as demandas reais do trabalho
- O foco deve estar em resolução de problemas, colaboração e potencial de crescimento em áreas relevantes
- Adaptabilidade deve ser avaliada como a capacidade de aprender no longo prazo, e não pela rapidez com que a pessoa executa tarefas arbitrárias
1 comentários
Opiniões do Hacker News
Quando foi a última vez que você depurou uma base de código antiga sem documentação nem ajuda da equipe? Sempre foi assim. Era uma base de 300 a 400 mil linhas de C++, e “legado” significava não ter teste nenhum; quase não havia documentação e, como único desenvolvedor de uma pequena empresa, eu precisava manter o serviço funcionando para dezenas de milhares de usuários enquanto corrigia bugs e adicionava funcionalidades.
Um caso recente: havia um patch para uma funcionalidade central que estava parado havia mais de um ano; o autor original já não estava mais lá, e eu precisava reescrever o código do zero ou ressuscitar o patch para alinhá-lo ao
master.A capacidade de entrar em um projeto e conduzir as pessoas em direção a um objetivo é claramente uma habilidade necessária para um desenvolvedor sênior, e concordo com a conclusão de que é preciso testar a capacidade de resolver problemas. Mas o conteúdo da entrevista técnica deve variar conforme a função: não há necessidade de pedir a um desenvolvedor web júnior que resolva algoritmos de grafos no quadro branco, mas um desenvolvedor sênior ou arquiteto de um produto de rede social precisa entender isso profundamente.
Na semana passada, depurei um código Go de 2020, também sem comentários nem documentação; também era uma parte central do sistema e parecia ter sido escrito por lunáticos. Doloroso.
Vejo a disposição de cavar até a camada inferior para resolver o problema na camada correta como uma das grandes soft skills que diferenciam engenheiros sênior. Em vez de contornar no próprio código, com correções posteriores, um bug ou uma funcionalidade ausente em uma camada mais baixa, corrigir na camada certa torna o sistema inteiro mais robusto a mudanças acima e abaixo na stack e a casos de uso futuros inesperados.
Por outro lado, quando essa abordagem não é adotada, a base de código começa a apodrecer depois que os engenheiros sênior saem ou são substituídos por juniores. Por exemplo: se, para cada caso de borda no parsing de entrada, você acrescenta mais uma regex ingênua de validação antes de um parser assustador e opaco, em vez de corrigir a própria gramática do parser, a base de código está evoluindo para uma bola de lama.
Claro que, ao corrigir na camada certa, muitas vezes a empresa precisa manter um pequeno branch de hotfix privado e de longo prazo de algum software do ecossistema usado na stack. O upstream normalmente não vê aquilo como um problema e não aceita o patch, então você precisa mantê-lo por conta própria.
Em tom de brincadeira, talvez bastasse autenticar o perfil no GitHub e contar quantas vezes alguém criou ou manteve esses branches privados de hotfix de longo prazo para medir a senioridade de um engenheiro de forma muito mais simples do que com testes de programação.
Não ajuda fingir que isso é inútil no mundo real. A realidade é bagunçada, a documentação muitas vezes não existe ou não é confiável, e a pessoa ou equipe que escreveu o código original pode já não estar mais lá.
Tenho uma pequena anedota. O cônjuge de um amigo saiu do emprego no início deste ano e passou 4 a 6 semanas se preparando para entrevistas em cada empresa de Big Tech. Preparou-se 4 a 6 semanas para a Meta, 4 a 6 semanas para a Stripe, e assim por diante; no meio disso também fez entrevistas aleatórias para praticar e criar memória muscular, pesquisou os tipos de problemas que poderiam aparecer em cada empresa e resolveu LeetCode por algumas horas por dia
No fim, deu tudo certo e aceitou uma oferta L6/staff de uma MAANG. Mas, conversando com essa pessoa esta semana, ela disse que, embora ainda nem tenha começado a nova função, já esqueceu a maioria dos detalhes que praticou. Disse que a preparação para system design foi a parte mais difícil, porque não tinha experiência em design de sistemas, mas agora se tornou staff eng em uma MAANG. Na prática, em um pequeno projeto que fizemos juntos, era uma ótima pessoa, mas não um engenheiro excepcionalmente brilhante
É realmente estranho, e parece explicar bastante os ciclos de alta e baixa nas contratações. Quando você assiste a vídeos de preparação para entrevistas de system design, eles parecem quase roteiros. Basta entrar na entrevista e seguir o roteiro; não parece importar se a pessoa de fato já projetou sistemas parecidos ou mais complexos. O objetivo da entrevista de system design, no fim, parece ser “você conhece o roteiro?”
Se você assistir a estes dois vídeos em sequência a 2x, é surpreendente como a execução parece roteirizada: https://www.youtube.com/watch?v=4_qu1F9BXow, https://www.youtube.com/watch?v=_K-eupuDVEc
Meus pais estiveram no setor de tecnologia de Santa Cruz nos anos 1980 e 1990, e naquela época o pool de talentos não era grande, então isso era uma ferramenta inclusiva para encontrar pessoas que pudessem crescer como desenvolvedores. A indústria atual adotou essa prática, mas a transformou no exato oposto: algo excludente
Uma das pessoas que contratei era física, não conhecia nada da terminologia especializada e ficou apavorada quando viu o primeiro problema de quadro branco. Quando a levei até um ponto em que se sentisse confortável, ela começou a falar sobre ferramentas que tinha criado para ajudar em seu trabalho de física; quando eu disse que aquelas ferramentas, feitas sem conhecimento de desenvolvimento, eram software, ela ficou surpresa. Não só aquilo era software de verdade como era muito impressionante, e o problema de quadro branco serviu como ferramenta para revelar potencial
Entendo que grandes empresas queiram widgets prontos para encaixar no lugar de pessoas, mas é engraçado que estejam usando algo que foi criado originalmente para o propósito oposto. Também penso que, de certa forma, é uma sorte eu já estar velho o bastante para não ter esperança de entrar em uma empresa bacana que usa esses desafios de código
A lógica é que, independentemente da universidade em que você estudou, das disciplinas que cursou ou das vantagens e desvantagens que teve, se você tem as qualidades necessárias para a função, esse é um conteúdo que pode aprender em poucos meses. Como as técnicas são muito padronizadas, o processo também se torna bastante objetivo
Não se espera que você use aquelas técnicas específicas no trabalho real. Em vez disso, você demonstra que consegue aprender esse tipo de técnica e desempenhar em alto nível em uma situação de entrevista muito estressante. A lógica é que isso é um bom sinal de que você conseguirá aprender as tecnologias necessárias para o projeto ao qual será alocado depois e entregar sob grande pressão de prazo
Não estou defendendo esse sistema, mas há uma lógica clara por trás dele
A pessoa diz que esqueceu, mas, se conseguiu aquela posição, provavelmente era capaz de resolver problemas médios do LeetCode. É difícil acreditar que tenha esquecido tudo; é bem possível que ainda consiga resolver problemas fáceis que a maioria das pessoas não resolveria de improviso. Provavelmente ainda sabe a complexidade de operações essenciais de backend, como busca, ordenação, arrays e consultas em hash, e percursos em árvores e grafos
E talento para atuação talvez seja mais comum na população geral do que talento para programação
Recentemente conduzi um processo de entrevista para uma vaga relativamente sênior de engenharia em uma startup pequena. Como acredito que pessoas diferentes se dão melhor com formatos diferentes de entrevista, ofereci opções a todos:
Quanto mais reclamações vejo online sobre entrevistas de programação, mais me convenço de que a entrevista de programação é, de longe, a melhor forma de filtrar candidatos para vagas de desenvolvimento de software. No setor como um todo, há gente demais que só fala bem, impostores e pessoas que marcam reuniões, e falta gente disposta a arregaçar as mangas, mergulhar no código e realmente terminar o trabalho. Esse problema fica ainda pior em níveis mais altos. Pode reclamar à vontade, mas uma vaga confortável de US$ 500 mil por ano na FAANG não é um direito adquirido. Se você não está disposto a revisar programação básica e escrever alguns loops
for, a empresa simplesmente vai passar para alguém que estejaPedir a um desenvolvedor Ruby para depurar PHP como teste de flexibilidade soa como um teste razoável. Um bom desenvolvedor, especialmente um desenvolvedor sênior, deveria conseguir fazer esse tipo de coisa. Classificar-se apenas como “desenvolvedor Ruby” é uma armadilha de carreira
Às vezes é preciso depurar uma DSL antiga e específica de fornecedor, ou código em que o framework e os padrões são tão antigos que quase viraram outra linguagem
Também há casos de adicionar suporte a funcionalidades backportadas ou corrigir falhas de segurança em clientes antigos e stacks legados. Em uma empresa grande, já tivemos de assumir a responsabilidade pelo código em escrow de um parceiro muito menor
Preparar o ambiente para conseguir depurar direito muitas vezes dá mais trabalho do que a correção em si. Ainda assim, é um bom teste para nível sênior ou acima
Quando o entrevistador disse “inverta este array”, respondi: “Em Python eu usaria array.reverse() ou reversed(array), e em JS deve haver uma dessas opções, então provavelmente é o método .reverse”. O entrevistador disse: “Bom palpite”
Achei sinceramente divertido, saí com a sensação de ter aprendido algumas coisas, e eles também puderam ver como eu raciocinava diante de um problema novo
Já depurei várias vezes bases de código antigas sem documentação nem ajuda da equipe. Existem, sim, sistemas em que ninguém que os criou continua por perto e a documentação não existe ou não pode ser encontrada. Então esse exemplo não é muito bom. A capacidade de depurar um programa, seguir o fluxo de uma requisição e ver o que está acontecendo é uma boa habilidade
Mas o ponto em que esse exemplo é realmente ruim é encaixotar o desenvolvedor em uma tecnologia específica. Se você tem uma aplicação PHP legada, acaba filtrando desenvolvedores Java, Python, Ruby e Go que têm essa habilidade de depuração, mas que seriam mais lentos por não conhecer PHP. Mesmo que, depois de alguns meses mexendo diretamente com PHP, eles pudessem ser desenvolvedores mais fortes
Concordo que uma “tarefa de 4 horas” pode facilmente virar 8, 10 horas ou mais para produzir algo bom. O tempo indicado pode ser manipulado com facilidade, então quem tem mais tempo pode parecer um candidato melhor
Quando foi que depurei uma base de código antiga sem documentação nem ajuda da equipe? Todos os dias desta semana
Quanto à documentação, o código foi atualizado pela última vez em junho e a documentação foi atualizada pela última vez em janeiro de 2022
Quanto à equipe, a metade que não foi demitida há dois anos já saiu para lugares melhores. Claro que existe uma equipe dona deste projeto, mas ela também tem outros três projetos, e no último ano contribuiu aqui com uma dúzia e poucos de linhas, das quais 11 eram atualizações de dependências
“Parece fazer um desenvolvedor Ruby depurar PHP”, “se a função exige uma tecnologia específica, teste essa tecnologia” soa como alguém que foi reprovado em um desafio de código
Falando sério, empresas raramente adotam práticas de contratação só por diversão. Normalmente é a melhor forma que aquela inteligência coletiva conseguiu conceber. Pedir para acabar com isso sem tentar entender qual problema elas estão tentando resolver e sem propor alternativas não é produtivo
Acho que, em desenvolvimento de software, reinventamos a roda com frequência demais em vez de tomar emprestadas práticas de outras profissões. Vamos ver por quais processos de contratação os engenheiros civis passam para ganhar metade do salário de desenvolvedores de software e integrar isso às nossas práticas. Aí todos seremos soldados felizes
Acho muito improvável que tenham refletido sobre o que realmente queriam alcançar. Elas simplesmente fizeram porque os outros fazem e acreditam que alguém, em algum lugar, criou o processo com uma intenção
A contratação em tecnologia se perdeu tanto que parece ter se acomodado, na melhor das hipóteses, em um máximo local
Tive uma experiência muito ruim em uma empresa que não fazia nenhum teste de programação. Eram apenas 2 ou 3 entrevistas
O problema apareceu quando comecei a trabalhar com a equipe de engenharia de dados. A maior parte da stack era baseada em Hadoop, Kubernetes, Ruby, Python e várias outras tecnologias, e exigia uma compreensão básica de computação em nuvem
Mas as experiências profissionais e os históricos eram tão díspares que, em vez de fazer o trabalho para o qual fui contratado, eu muitas vezes ficava cobrindo lacunas de outras pessoas. Alguns colegas não conseguiam fazer nem tarefas básicas, como empacotar uma CLI em Python usando Docker ou verificar jobs do Hadoop, então acabei fazendo muito trabalho de cola para compensar isso
No fim, saí. Não porque eu me achasse especial, mas porque me cansei de gastar 80% do meu tempo dando suporte a pessoas contratadas no mesmo nível que eu ou em níveis mais altos. Reconheço que as práticas de contratação daquela empresa eram muito ruins, mas algum tipo de teste técnico básico é necessário
Outra pergunta importante é se era preciso explicar a mesma coisa repetidamente para a mesma pessoa. Não saber algo é aceitável, mas não querer aprender é difícil de aceitar
A parte interessante dos testes em formato de tarefa é que existe um risco moral que incentiva a pessoa a gastar mais tempo, mesmo quando dizem “use apenas X horas”. Também surge o incentivo para mentir sobre o tempo realmente gasto se a empresa perguntar.
Já entreguei tarefas várias vezes resolvendo o problema de forma adequada e enfatizando que fiquei dentro do tempo recomendado, mas na entrevista seguinte fui repreendido com “por que você não implementou X?”.
Nesse sentido, testes em formato de tarefa excessivamente abertos são tarefas ruins. Porque favorecem quem tem mais tempo livre e consegue caprichar mais. Um abraço para os testes em formato de tarefa de ciência de dados que exigem uma apresentação em PowerPoint como entrega final.