Minha pergunta favorita de entrevista de engenharia de software: cálculo da mediana
(krisshamloo.com)- Pequenos problemas de implementação em entrevistas técnicas podem ser mais eficazes do que quebra-cabeças, e o cálculo da mediana revela tanto a habilidade básica de programação quanto o senso de design
- Como é um problema que exige ordenação, ele leva naturalmente a uma discussão de API: se a função deve ordenar diretamente, se quem chama deve ordenar, e se é permitido modificar o array original
- A ramificação entre tamanhos ímpares e pares, o cálculo de índices e erros de off-by-one são bons para observar o processo de depuração do candidato
- Em um problema curto, dá para verificar a diferença entre mediana e média, a facilidade de escrever testes e até o conhecimento da biblioteca padrão statistics do Python
- A implementação de exemplo lança
ValueErrorpara uma lista vazia, faz uma ordenação por cópia comsorted()e retorna, para tamanho par, a média dos dois valores centrais; para tamanho ímpar, o valor central
Por que o problema da mediana é adequado para entrevistas
- Uma boa pergunta de entrevista técnica não deve ser um problema retorcido como um quebra-cabeça; ela deve permitir trazer temas mais profundos a partir de uma implementação intuitiva
- A pergunta “escreva uma função que receba um array de números e retorne a mediana” funciona bem como um sinal no estilo Fizz Buzz para verificar se o candidato realmente sabe programar
- Reduzir os valores de um array a um único resultado é uma competência básica, e o problema em si é pequeno o suficiente para facilitar a conversa e a depuração em conjunto
Pontos de decisão que aparecem durante a implementação
- Para calcular a mediana, primeiro é necessário ordenar
- É preciso decidir se a função vai ordenar diretamente ou se quem chama deve passar um array já ordenado
- Quando o array é passado por referência, permitir ou não alterar o original também faz parte do contrato da API
- Essas escolhas também se conectam a discussões de desempenho
- O cálculo de índices tem armadilhas de off-by-one
- Mais do que observar se há erro, é possível ver como a pessoa depura um problema pequeno
- A forma de retorno muda conforme o tamanho do array
- Para tamanho par, retorna-se a média dos dois valores centrais
- Para tamanho ímpar, retorna-se o valor central
Conversas que se expandem a partir de um problema curto
- A mediana pode levar a uma discussão estatística, por exemplo sobre por que ela pode ser uma escolha melhor do que a média na maioria dos casos
- Como as entradas e os valores esperados são simples, é fácil testar, e o candidato pode mostrar seu senso de testes
- Em Python, também há a oportunidade de demonstrar conhecimento da biblioteca padrão
statistics
Escolhas da implementação Python de exemplo
- Uma lista vazia gera
ValueError("median called with empty list") - Usa
sorted(numbers)para não ordenar diretamente a lista de entrada, diferentemente denumbers.sort() - O tamanho é obtido com
len(numbers), e o índice central é calculado commid = length // 2 - Para tamanho par, retorna
(numbers[mid - 1] + numbers[mid]) / 2.0; para tamanho ímpar, retornanumbers[mid]
1 comentários
Comentários no Lobste.rs
Não entendi muito bem este texto. Parece que o autor não sabe que a mediana pode ser calculada em O(n). Referência: https://rcoh.me/posts/linear-time-median-finding/
Portanto, a afirmação de que “os números precisam estar ordenados desde o início” está errada. Por esse motivo, também não acho que seja uma boa pergunta de entrevista. A solução ótima é um algoritmo complexo; é difícil esperar que alguém chegue a ela na hora, a menos que já a conheça de memória, e saber se o candidato a decorou também não ajuda muito na avaliação.
No máximo, daria para pedir ao candidato uma solução ingênua: ordenar o array com uma função de biblioteca e retornar o valor do meio
n*log(n)para esse problemaMais tarde, em uma aula de algoritmos, aprendi quickselect e pensei: “não é possível que esperassem que eu pensasse nisso na hora”. Bem, talvez eu simplesmente não fosse adequado para aquela vaga
Sobre a ideia de esperar “uma solução ingênua que ordena o array com uma função de biblioteca e retorna o valor do meio”, eu não esperaria de um candidato um código melhor que o da biblioteca padrão do Python
Como bônus, dá para saber na hora se alguém estudou algoritmos, ou pelo menos se se preparou para a entrevista. A pessoa vai sugerir usar quickselect: https://en.wikipedia.org/wiki/Quickselect
E, se eu tivesse que escrever quickselect do zero, também conseguiria. Basicamente, é algo próximo de particionamento + busca binária
O tipo
intdo Python não tem overflow, mas, se você estiver usando C, C++ ou Go, não teria que se preocupar também com overflow na soma no ramo de arrays de tamanho par?float, não emint. Ainda assim, existe a possibilidade de virarinfpor overflow. Se os dois elementos do array foremsys.float_info.max, a resposta deveria sersys.float_info.max, mas o resultado da soma virainf, e dividir isso por 2 continua dandoinfVocê poderia tentar corrigir distribuindo a divisão por 2 sobre a soma, mas aí obteria respostas erradas com números subnormais. Parece que a maioria das pessoas assume que números grandes o suficiente para causar esse problema não aparecem no programa. O numpy também retorna
infaqui, com um aviso:Na verdade, há várias formas de escolher a própria mediana. Há escolhas como usar interpolação linear, usar o limite superior ou usar o limite inferior
E, quando se passa para quantis, dá para conversar por horas. Escolher um único valor e escolher vários de uma vez exigem abordagens diferentes
Eu não uso perguntas de entrevista como a do texto original. Eu exijo suavidade, no sentido de que a dificuldade de resolver o problema deve variar de forma contínua conforme a capacidade e a experiência do candidato. Em especial, se saber da existência de uma função de biblioteca ou de algoritmos como quickselect ou radix sort muda drasticamente o resultado, não é um bom problema de avaliação
Acaba testando se a pessoa conhece um artefato mágico específico, em vez de medir a experiência e a capacidade do candidato. Dá para compensar com perguntas de acompanhamento, mas é melhor propor desde o início um problema mais suave