Continuamos conversando sobre entrevistas técnicas (se você ainda não leu, consulte os artigos anteriores da série -
sobre entrevistas com RH e
técnicos ). Desta vez, haverá uma experiência mais subjetiva, um mínimo de dicas e um pouco sobre tarefas de teste e questões teóricas. Vamos lá
Isenção de responsabilidade: o autor não é um desenvolvedor turbo, mas um macaque da web comum, sem queixas. Portanto, as tarefas e soluções acima podem fazer com que você sorria, com vontade e desejo e indique ao autor sua incompetência. Estou ansioso para vê-lo nos comentários! :)Discussão dos itens de teste concluídos
Na
última parte, descrevi como realizei duas tarefas de teste: a primeira no DevOps Engineer e a segunda no Ruby Developer. Vou contar o que aconteceu a seguir.
Entrevista no Ruby Developer - o entrevistador nem olhou para o meu teste, não fez perguntas, não elogiou (concluí a tarefa melhor do que todos os candidatos anteriores, pelo menos, o recrutador me lisonjeava). Parece que ele nem sabia sobre ele. Isso me chateou um pouco, porque então eles começaram a me perguntar a teoria e, como resultado, recusaram a teoria.
Entrevista no engenheiro do DevOps - o entrevistador olhou para a tarefa, fez um elogio (disse que eu a concluí qualitativamente) e fez algumas perguntas de controle sobre a solução: por que essa linha está aqui? se você substituir a condição por isso, em qual arquivo será necessário fazer isso? por que essa abordagem é usada aqui? e assim por diante. Como o recrutador me disse, alguns candidatos não realizavam tarefas por conta própria e não podiam responder a essas perguntas. Portanto, aqui eu consegui sem problemas.
No primeiro caso, não perguntei ao entrevistado se ele havia assistido minha tarefa de teste e o que ele pensava sobre isso. Mas foi necessário! Se você tiver uma situação dessas, não deixe de contar aos entrevistados sobre isso.
Tarefas da entrevista
Continuamos o tópico das tarefas de teste da parte anterior e consideramos as tarefas de codificação nas entrevistas.
Pode haver vários tipos de tarefas: implementar um algoritmo, escrever uma solução em pseudo-código, refatorar algo e assim por diante. Nossos engenheiros gostam mais de problemas algorítmicos.
Muitas pessoas, inclusive eu, acreditam que essas tarefas mostram apenas a capacidade do candidato de resolver exatamente esses problemas e não mostram como ele lidará com tarefas reais de trabalho, que, em regra, são de nível superior. Por que eles ainda estão dando a eles? Eu acho que o motivo é simples: os entrevistadores simplesmente não conseguem criar algo melhor. E como não podemos encontrar nada melhor, tomemos as boas inversões de linha antiga, classificando, equilibrando árvores e muito mais.
Como as ferramentas usadas para a solução, o editor de código + repl + a possibilidade de colaboração é mais adequado. De todas as opções no mercado, eu gosto
mais do CoderPad . É criada uma sala onde você e os entrevistadores se conectam, você pode editar, executar o código juntos e ver os resultados da execução. Muito confortável Se não houver dinheiro para um
codepad , o
repl.it entra em batalha e o compartilhamento de tela é basicamente o mesmo, apenas sem a possibilidade de colaboração.
Atualização: enquanto o artigo estava sendo traduzido, repl.it adicionou o Modo Multijogador, que permite que um número ilimitado de participantes trabalhe simultaneamente com o código. Totalmente grátis! CoderPad não é mais necessário, saúde!Eu tive uma entrevista com a empresa para o cargo de desenvolvedor Java . A empresa faz algo como CRM e escreve várias integrações. Entrei em contato com um especialista técnico do Zoom e ele diz: "Vamos começar com o problema algorítmico". Respondo: "Ok, farei a tarefa, mas tenho uma pergunta: você precisa desse conhecimento em seu trabalho, precisa resolver coisas semelhantes?" Para a qual recebo uma resposta fenomenal: "Nós escrevemos pontos de extremidade restantes e dirigimos o json-chiki para frente e para trás, mas não é interessante falar sobre isso, então vamos resolver o problema". Ou seja, o próprio entrevistador admitiu sua incompetência. Não sei quem, mas a partir desse momento percebi que não teria nada para pegar lá. No entanto, por interesse esportivo, a conversa continuou.
Abrimos o bloco de codificação e prosseguimos com a tarefa, cuja condição eu era dublada oralmente: "Encontre a sequência mais longa de caracteres únicos em uma determinada string". Depois disso, o entrevistador disse que "alguém poderia dar uma tarefa para programação dinâmica , mas nos limitaremos a uma opção mais simples". Eu gostaria de olhar seriamente para a pessoa que dará a tarefa de programação dinâmica nas entrevistas.
Repeti as condições da tarefa para o entrevistador, para ter certeza de que a entendi corretamente, para a qual recebi uma resposta afirmativa e comecei a trabalhar. Após 5 minutos, percebi que o problema estava incorreto porque era necessário encontrar não uma substring, mas seu comprimento (isso é mais fácil). No entanto, respondi: "Bem, desde que começaram, vamos resolver o problema com um asterisco, e não com um simples". O entrevistador ficou um pouco confuso, porque ele havia preparado os testes especificamente para suas condições, mas eu já decidi que não daria as costas e tentaria fazê-lo como está. Perguntei quanto tempo tenho (cerca de 40 minutos) e comecei a codificar. Observo que, apesar de saber que eles dariam tarefas, não me preparei especialmente.
Então, eu imediatamente escrevi testes e comecei a xamanizar com os índices i, j e k :) Loops nos loops, e assim por diante. Depois de 15 a 20 minutos, eu tinha uma solução meio trabalhada, mas os casos de fronteira que o entrevistador deu não passaram. Outros 20 minutos levaram, no final, eu ainda concluí corretamente a tarefa. O entrevistador pareceu satisfeito e começou a me perguntar sobre estruturas de dados. Aconteceu que, para resolver o problema que ele queria dar inicialmente, seria possível usar um hashset, ou algo assim, e ele esperava exatamente essa solução, mas eu quebrei tudo.
Depois conversamos um pouco sobre o projeto (formas e pilhas). E então ele diz: “Depois disso, haverá uma entrevista sobre o design do sistema. Em geral, não vejo motivo para realizá-lo, porque não fazemos isso aqui e não precisamos desse conhecimento, mas ordem é ordem, então o próximo passo é esse. " Bem, você entende - são realizadas duas (!) Entrevistas para entender se o candidato pode fazer coisas que não são necessárias no trabalho diário desta empresa. Então me permiti falar um pouco sobre a falta de sentido dessas entrevistas. O entrevistador concordou comigo, mas novamente incluiu a delegação de responsabilidades e disse: "Eu não decido qual deve ser o processo, então fazemos o que fazemos". Acrescentarei que passei pela segunda entrevista (sobre design de sistema) e foi tão sem sentido quanto a primeira.
Que erro o entrevistador cometeu - ele não corrigiu as condições da tarefa no texto. Quando conduzi essas entrevistas, simplesmente copiei as condições da tarefa no editor de código para que o candidato não tivesse perguntas.
Que erro eu cometi - imediatamente corri para escrever o código, sem especificar três vezes se entendi a condição corretamente. Se você receber essas tarefas em entrevistas,
desconecte-se imediatamente do bate-papo e encontre uma lição mais interessante; verifique várias vezes se entendeu a condição corretamente, escreva um teste no editor e obtenha a confirmação do entrevistador de que tudo está correto.
Também tive uma entrevista para o cargo de desenvolvedor Ruby . Após responder às perguntas padrão, recebi a tarefa de escrever o método each_slice. Para quem não sabe, isso é uma coisa que atinge uma matriz de subarrays de um determinado tamanho e executa para cada um deles um bloco que passamos para o método ou retorna um iterador sobre esses subarrays. Sentei-me para escrever e depois liguei. O problema é que, no Ruby, durante algum tempo eu participei com sucesso apenas do web macing e, como uma lista de permissões, não conhecia algumas das construções básicas da linguagem. Ou seja - eu não sabia que o índice no loop for é imutável (ao contrário, por exemplo, Java).
Escrevi o método em si mais ou menos rapidamente, mas não funcionou e não consegui entender o porquê. Comecei a entrar em pânico, apaguei tudo e escrevi novamente, mas meu código novamente não funcionou como deveria.
"Não foi", pensei, e disse aos meus interlocutores: "Gente, você sabe, sou bom em hospedagem na web e em projetos, mas não posso fazer nada com suas tarefas estúpidas. Entendo que essa é uma tarefa simples e uma pessoa com 10 anos de experiência é simplesmente obrigada a fazê-la rapidamente. Então não deixe que eu demore mais, e vamos nos dispersar. Os caras concordaram e se separaram.
Fui seriamente bombardeado porque não estava acostumado a perder com tanta facilidade. Para, de alguma forma, obter uma vantagem existencial, escrevi para um recrutador que havia dividido uma tarefa que não está relacionada ao trabalho real. Então ele se acalmou, sentou-se, testou rapidamente como os índices funcionam em ciclos. Percebi que cometi um erro júnior, refiz o índice e obtive uma solução pronta. De fato, o erro que tive foi na mesma linha. Eu contei ao RH sobre isso e sugeri que ela passasse o link para a solução para os caras, se eles estiverem interessados, porque eu ainda resolvia o problema. Mas ela respondeu: "Você não foi mais longe porque não resolveu o problema, adeus ". Eu ainda entendia um pouco sobre os processos de entrevistas interrompidos para justificar a nós mesmos e nos separamos.
Depois disso, repensei minha atitude em relação a essas tarefas. Normalmente, nunca foi um problema para mim codificar algo sob supervisão, mas vários fatores funcionaram aqui: meu pedido de uma posição séria, falta de compreensão das construções básicas da linguagem (embora eu nunca precisei delas e, se estivesse, poderia pesquisar no google a solução em 5 segundos) e o efeito do observador. É claro que li que muitas pessoas não conseguem resolver problemas quando olham para eles, mas sempre me pareceu que isso era uma desculpa para minha própria insegurança e incompetência, até que eu mesmo me deparei com esses caras durões com cada fatia.
Também tive uma entrevista para o cargo de desenvolvedor Java. Desta vez, foi realizada em um formato ligeiramente diferente. Entramos em contato com Zoom e o entrevistador disse: “Diga-me o seu e-mail, eu lhe enviarei uma tarefa, leia-a, diga-me se está tudo claro. Você terá duas horas, ficarei mudo e não vou assistir o que você faz lá (não brincamos com a tela). Duas horas depois, entramos em contato, atrapalhamos a tela e vemos o que você fez lá. Você pode usar qualquer coisa. Li as condições da tarefa, conversei novamente com o entrevistador, desliguei o vídeo (porque a codificação do fluxo devora a CPU) e fiquei confusa. Abriu o IDE e começou.
A tarefa estava relacionada à E / S - era necessário criar uma API para gravar dados em um arquivo no disco, para que tudo fosse rápido e seguro para threads, além de gravar testes de unidade que verificassem isso (incluindo a segurança de threads). Não trabalho com simultaneidade e E / S há muito tempo, então tive que passar rapidamente pelas docas e lembrar o que estava acontecendo. Eu escrevi uma solução na testa, verifiquei se ela é segura para threads e assim por diante. Tudo sobre tudo me levou cerca de uma hora e meia. Eu dei um ping no meu entrevistador, disse que estava pronto, mas havia apenas uma coisinha para polir, vamos ver? Para isso, ele respondeu: "Vamos nos sentar por mais meia hora e terminar tudo o que você não concluiu". Ok, sentei-me e lembrei-me de todas as pequenas coisas e asperezas, terminei o javadki, mais uma vez li tudo o que pude sobre a E / S e pensei quais seriam as desvantagens da minha solução.
Depois de meia hora, entramos em contato, compartilhei a tela, mostrei o código, executei os testes e assim por diante. Na meia hora seguinte, falamos estritamente sobre a solução do problema e as possíveis opções para sua modificação ao alterar determinadas condições. Quero chamar a atenção para o fato de que nas entrevistas anteriores (e nas subsequentes também) ninguém preparou a base para a conversa por tarefas, sempre foi apenas algum tipo de peça abstrata, que deu 0/1 na saída, e passamos à próxima pergunta. E aqui a tarefa era simples o suficiente para que pudesse ser executada em algumas horas, mas ao mesmo tempo completa o suficiente para adicionar condições e discutir com o candidato como ele finalizaria a decisão.
Gostei muito desta entrevista. Pude mostrar que não apenas o fizz buzz pode resolver, mas também entender algo nas arquiteturas. O entrevistador estava convencido de que não estava sentado em junho, mas um especialista que gravou alguma coisa em seu trabalho. Foi a melhor entrevista técnica que já tive. Acho que você já adivinhou que o entrevistador não era um dos nossos :) Acrescentarei também que passei com êxito, depois mais duas etapas e, eventualmente, recebi uma oferta. Mas isso é outra história.
O que foi bom nessa tarefa?
- Proximidade com o trabalho real, com o que eles fazem nessa empresa.
- Prazo.
- Falta de observação.
- A capacidade de usar qualquer coisa e não uma verificação de memória.
- Criando uma base para novas conversas.
- Testando as habilidades do candidato para codificar, use o IDE e pense em geral.
Infelizmente, de todas as entrevistas, eu só tinha três tarefas desse tipo, então a seleção é pequena. Talvez haja alguns testes / tarefas mais complicados, mas eu não os recebi.
Deficiências típicas das tarefas de entrevista
- A tarefa não tem nada a ver com trabalho real. Isso me irrita mais. Os algoritmos podem resolver, embora, na realidade, as pilhas sejam fascinantes. Vamos a tarefa relevante, vou fazer um bruto! Por que você precisa de uma pessoa que saiba procurar substrings em strings?
- Organizacional - geralmente não há ferramenta normal para uma solução. Uma vez que eles me mostraram o código no google docs, uma vez que me atrapalhei na tela em repl.it, uma vez foi o CoderPad.
- A tarefa não cria um contexto para novas conversas - isso é uma consequência do primeiro parágrafo. Por que dar uma tarefa se não discutimos mais tarde?
- Nem todas as pessoas podem lidar com a tarefa sob supervisão. Por conseguinte, um bom candidato pode ser eliminado nesta fase.
Questões teóricas
Esta é a minha parte favorita. Todo mundo adora perguntar teoria, vamos rever isso um pouco.
Por alguma razão, aconteceu que, acima de tudo, me perguntaram a teoria nas posições do Engenheiro Ruby. Eu a conhecia o pior de tudo, então eu constantemente preenchia as entrevistas e parecia um mês de junho até que percebi que não era mais adequado continuar assim. Sentei-me e li um livro sobre o idioma, o que me permitiu falar muito melhor e sem reclamar: “Gente, por que você está me perguntando isso? Eu sou um bom desenvolvedor, qual é a diferença, qual é a ordem do método de busca de um objeto? Quem precisa disso?
A primeira entrevista que eu fui como desenvolvedor Ruby foi exatamente onde a tarefa de teste deveria ser realizada, no entanto, como se viu, ninguém estava interessado. Timlid, que deveria se comunicar comigo, não veio (ele estava preso em um engarrafamento ou algo assim), então eles me deram outro. Após a reunião, ele diz: "Eu tenho uma regra - eu conduzo todas as entrevistas em inglês, então passamos para o inglês". E então meus ouvidos são torcidos em um nanotubo de grafeno, porque o entrevistador tem um sotaque muito forte. Isso me perturbou um pouco (é muito difícil me comunicar com meus compatriotas em inglês).
A seguir, surgiram as perguntas: o que é um módulo, o que é um bloco, o que é rendimento, e eu comecei a arquivar. Em vez de definir "como em um livro", comecei a tagarelar: "Bem, eu não sei a definição exata, mas provavelmente isso é uma coisa, usei assim". O entrevistador ficou infeliz, comecei a sentir e depois pensei que todos haviam chegado.
Havia perguntas sobre métodos específicos, a saber: "Qual é o nome do método que filtra todo o valor nulo na coleção?" Liguei o troll e respondi: "Se você verificar minha memória para conhecer esses métodos, não posso contar nada sobre o que não usei recentemente. Escrevo em vários idiomas e plataformas e não lembro de todos os métodos do SDK ". Isso não satisfez o entrevistador, e a próxima pergunta foi algo como: “O que é Enumerável? Quais métodos existem e quem os estenderá. ” "Tio, você não entendeu?", Pensei comigo mesma, mas disse em voz alta: "Não sei ao certo, acho que existem alguns métodos como mapear / reduzir / cortar e assim por diante". Também não combinava com ele.
Então ele me fez uma pergunta padrão sobre onde colocar a lógica no MVC. Eu respondi isso no modelo e, se não se encaixa no modelo, em algumas outras classes. Descobriu-se que os chamados Objetos de Serviço eram a resposta correta (esse lixo chegou aqui também?). Murmurei algo em resposta, como, bem, você pode chamar assim, mas eu não gosto.
Então ele fez a pergunta padrão sobre SQL, que eu fui capaz de responder corretamente, depois perguntou sobre o RSpec, que eu não usei, só isso. No Rails (e eles tinham apenas trilhos), não recebi uma única pergunta. Além disso, não recebi uma única pergunta sobre minha experiência anterior.
Depois disso, ele me perguntou o que eu penso sobre os levantamentos diários. ( — !), , . Scrum — , , . , .
( ), , , , . , , , . , , , .
. « », — , - . , - , . , , .
, , (Ruby). , .
Ruby Debeloper , . , — , . , : , . , . Rails. «- -», — , . ( ), , : « ». , — each_slice. , , . : « , - Rack middleware?». , . , , ( Java Servlets, middleware - Laravel/Express), . , .
, , . . , , rack middleware, , .
. — . , , , , …
Ruby Developer. , . , , . Proc, , :) : « , , , - ». 100% , - , . .
: « require». Rails Grape, , , . « , ». , . - -, « , ?». ActiveRecord — , .
concurrency ( ). , concurrency Ruby — . , , . , MRI — JVM , volatile synchronized , . , , ( !) concurrency . ? ?
, - SOLID. , « — », . , . , . - , . , « ». .
? . , , , . , ! ( ). , , Cracking Ruby Interview, . , - «» , , , :)
.
Fullstack Java Developer. — . , . , , Java.
, , , - . , , , , . , , .
. . , , , undefined null, var. JS WAT-. : «, WAT . , , , ». , -. «JavaScript: The Good Parts», .
, , . (?) , ( , ) , . . , :)
- , , . jQuery, . :)
DevOps Engineer , . : « ?». - :) , , — . , . , , , . . ( )?
( MVC). (-) 5-10 . ( GoF) . . Ruby-, , — , , ( MVC ActiveRecord ). Java- .
SOLID , , : Ruby-, — Java. DRY :)
?
- , .
- , .
- , .
- , .
, , :
- / . , . : « -AOP AspectJ Spring?» :) , , .
- LeetCode , .
, , . , , « » , .
( , ),
, !