Recentemente, tive uma entrevista de emprego na qual eles me deram uma hora para escrever um código real. Não era uma quantidade enorme, provavelmente menos de 100 linhas. Após cerca de 45 minutos, compilei, executei e fiz funcionar. Eu posso ter gasto de 5 a 10 minutos trabalhando com erros de compilação e alguns pequenos erros, mas no geral foi muito tranquilo. (Aliás, recebi uma oferta deles.)
No entanto, o que me intrigou foi que, depois que eu entreguei o código completo, o entrevistador me disse que a única coisa que fiz de errado foi "não compilar à medida que avanço". Perguntei a ele qual era a diferença e ele disse "o que você faria se terminasse o código e ele não fosse compilado a tempo".
No meu entendimento, esse é um argumento inválido, porque "obter código para compilar" para um determinado comprimento de código geralmente envolve a correção de um número constante de erros de compilação e leva um tempo bastante constante, que deve ser o mesmo, se você fizer isso depois de fazer o mesmo. termine de escrever o código ou se você o intercalar com o tempo de codificação. Se alguma coisa, interromper sua codificação para procurar pontos e vírgulas ausentes provavelmente seria prejudicial à sua eficiência. Exceto em circunstâncias extremas, quando estou experimentando obscuridades em casos extremos em coisas como funções virtuais em classes derivadas, etc. parece razoável esperar que o código escrito por um desenvolvedor experiente compile, menos o erro de digitação ocasional e até se não, é '
Em outro incidente semelhante, recebi uma base de código incompleta em uma entrevista e pedi para finalizá-la e fazer as modificações necessárias para fazê-la funcionar. Comecei lendo o código existente e, depois de alguns minutos (mesmo antes de terminar de ler o código), o entrevistador me disse que isso basta. Quando perguntei a ele o que ele teria feito (ou seja, "o que eu fiz de errado"), ele me disse que começaria obtendo imediatamente o código para compilar.
Por que isso é relevante? Na minha opinião e na minha experiência, se um pedaço de código é compilado ou não é essencialmente aleatório, envolvendo coisas como falta ou não-ponto-e-vírgula e pouco tem a ver com a correção do programa subjacente. (Para mim, focar na compilação é como executar um artigo em uma verificação ortográfica sem revisão para verificar a gramática.)
Se você me der um pedaço de código incompleto, a primeira coisa que faço será lê-lo. Nem tentarei compilá-lo até saber o que o código está fazendo e o algoritmo está correto.
De qualquer forma, esses foram apenas alguns incidentes recentes, mas, em geral, ouvi muitos desenvolvedores falarem sobre a compilação de seu código à medida que avançam, e ainda assim ninguém foi capaz de me dizer o benefício disso. Entendo os benefícios de testar seu código à medida que avança, mas por que compilar?
Então, minha pergunta é a seguinte: há algo que eu perdi? Existe realmente um benefício em compilar à medida que avança? Ou isso é algum tipo de mito propagado pela comunidade de software de que você deve compilar seu código com frequência?
fonte
Respostas:
Há sim. Ele fornece um ciclo de feedback mais curto - o que, em geral, ao projetar (interface do usuário, software de gravação, design visual etc.) é uma coisa boa.
Um curto ciclo de feedback significa que você pode corrigir rapidamente os erros desde o início, antes que eles se tornem mais caros.
Para emprestar seu exemplo, digamos que você estava codificando em uma linguagem C e se esqueceu de
}
algo em algum lugar no meio do programa.Se você compilar logo após terminar de escrever a instrução, pode ter certeza de que acabou de introduzir o erro de compilação e poderá corrigi-lo ali e, em segundos.
Se não o fizer, você teria que gastar bastante tempo lendo o código, procurando a posição exata
}
e certificando-se, depois de localizar o erro de que a correção é realmente o que foi planejado. Isso aconteceria um tempo depois que você deixasse esse pedaço de código. Não seria tão claro como no momento em que você o escreveu.Agora, sim, o resultado final é o mesmo, mas você perdeu uma boa quantidade de tempo em questões sintáticas com as quais o compilador está presente para ajudá-lo - uma quantidade de tempo que poderia ser significativamente menor se você compilasse à medida que avançava.
fonte
Compilar é uma forma de teste, especialmente em idiomas que fazem uso extensivo de tipos como Haskell ou ML . Em outros idiomas, é uma varredura sintática que conta pouco.
Dito isto, "compilar à medida que avança" me parece um hábito muito situacional. Você poderia igualmente ser marcado por ser "nervoso" por compilar com mais frequência do que o preconceito pessoal do entrevistador. Parece nitpicking; ninguém gosta de admitir que um entrevistado foi aprovado no teste; inclina as escalas da negociação salarial.
Nem todos os sistemas de construção são rápidos. Eu trabalhei em um projeto (C ++), onde Marca iria gastar 30 segundos apenas status 'ting tudo para determinar se ele necessária para construir ou não, e a maioria dos arquivos levaria um par de minutos para construir se você fez alterações. Relutamos em fazer isso com mais frequência do que a cada 10 a 15 minutos. Alguém sem dúvida fornecerá uma anedota sobre quando compilar envolve levar seu baralho de cartões perfurados e carregá-los para um prédio diferente ...
Compile quando sentir que fez uma unidade conceitual completa em sua cabeça e está pronto para validá-la. Uma vez por minuto ou uma vez por semana, dependendo do fluxo de trabalho.
fonte
Sim: sua mente não é um compilador. Enquanto um compilador pode fazer n trocas de contexto por segundo, sua mente não pode. O número de mudanças de contexto que sua mente pode fazer em um dia depende de vários fatores, como experiência / familiaridade com a base de código, quão imerso você está no código, quão limpo é o código, quão complexo é o problema que você está enfrentando, quão cansado você está, se você é frequentemente interrompido ou em um ambiente barulhento e assim por diante.
Compilar uma base de código (tudo ao mesmo tempo), pela primeira vez (pense em "projeto com 20 arquivos") forçará você a alternar o contexto com o que você está pensando (por exemplo, "esse valor é definido como 5 aqui e depois em o loop for blablabla e o algoritmo complexo produz o valor correto no retorno ") para um problema de compilação que não tem nenhuma relação com o que você está pensando (diferentes arquivos / módulos / funções / pré-condições / sintaxe / nomes de variáveis, pré-condições etc.) )
Quanto mais código você compilar de uma só vez, mais contexto mudará de ideia. Isso não é um problema para uma pequena base de código, quando todo o código que você escreveu é o que você escreveu em uma hora. Porém, é um grande problema ao trabalhar em uma base de código existente, com várias interdependências (e muitas vezes não documentadas).
Você minimiza o contexto que sua mente precisa fazer, permitindo que você se concentre mais no impacto e nos efeitos colaterais das alterações que você faz. Também o deixa menos cansado (e menos propenso a erros) e aumenta a qualidade de sua saída (ou seja, você pode garantir efeitos colaterais minimizados mais facilmente quando você altera e compila um arquivo de cada vez, do que quando compila e altera dez).
Se você compilar em iterações muito curtas (isso pressupõe que o processo de compilação seja otimizado para demorar um pouco), é possível corrigir erros de compilação sem sair da "zona".
Também é propagado pela comunidade de software, mas tem boas razões por trás disso.
Parece-me que você tem pouca (ou nenhuma) experiência na manutenção de bases de códigos herdadas de médio a grande porte (centenas ou milhares de arquivos de origem). É aqui que essa atitude (ou seja, "compile conforme você avança") ajudará mais, e é aí que você forma esse tipo de hábito.
Eu imaginaria que as pessoas que o analisaram chegaram a uma conclusão semelhante ("você tem pouca ou nenhuma experiência em grandes bases de código").
fonte
Eu acho que há mais do que um pouco de esnobismo profissional aqui. A implicação parece ser "se você nunca teve a necessidade de compilar regularmente, nunca trabalhou com algo tão complicado - obtenha mais experiência e volte quando aprender a trabalhar exatamente da maneira que fazemos".
Mas, obviamente, há um outro lado disso. Alguns projetos levam um tempo para serem compilados. Eu trabalhei com estruturas que levam 30 minutos ou mais para serem compiladas depois de edições menores. Deus o ajude se você precisar editar um arquivo de cabeçalho. Geralmente, as recompilações completas são feitas da noite para o dia e, se você confiar no compilador para detectar seus erros, ainda existem erros raros que não serão detectados durante uma compilação parcial. Você simplesmente não recompila a cada 5 minutos nessas condições - a menos que esteja com preguiça .
O compilador não pode ajudá-lo com erros lógicos ou semânticos e os erros de sintaxe não são tão difíceis de evitar que gastar metade do seu dia compilando valha a pena. É claro que você cometerá erros de digitação ocasionais, mas vou assumir que você pode digitar e ler. Se você tiver a liberdade de escolha, use um estilo de codificação que faça bom uso do layout para destacar visualmente os erros e você nunca mais eliminará uma chave, colchete ou ponto e vírgula. É preciso um pouco de prática e um pouco mais de disciplina do que a maioria está acostumada, mas é possível. Posso escrever código por algumas horas de cada vez, em um editor de texto simples, e compilá-lo pela primeira vez melhor do que nove em cada dez. Claro, eu poderia compilar com mais frequência, mas não me lembro da última vez que tive um erro que teria sido mais fácil de corrigir como resultado.
Se você não é fã de recompilação constante, está em boa companhia. Aqui está Donald Knuth:
Tudo isso dito ... se você está trabalhando em um contexto em que a compilação é uma ação livre, por que não? Em casa, em projetos pessoais, pressiono ctrl-S cerca de uma vez a cada 30 segundos e o atalho "compilar" quase sempre, em um IDE que executa constantemente o código no front end do compilador para fornecer realce de erros em tempo real. Por que deixar passar um almoço grátis?
fonte
I hit ctrl-S about once every 30 seconds
. Eu provavelmente salvo duas vezes mais lol. É um péssimo hábito. Às vezes, salvei no meio de uma linha de código e salve novamente no final. Sempre que paro para pensar por um segundo e não digito, eu salvo.Há méritos na compilação à medida que avança. Mas concordo plenamente que permanecer na tarefa é uma estratégia de codificação OK.
O benefício mais significativo para a compilação incremental é a mentalidade que muitos entendem se aguardam o final da compilação e teste : no final, estamos mais preocupados em executar o código do que qualquer outra coisa nesse momento. Dizemos "Ah, só precisamos adicionar esse colchete para que o compilador pare de reclamar" ou "oh, só precisamos capitalizar isso" sem pensar se há um erro semântico subjacente que esse erro de sintaxe oculta. Realmente acho que erros sintáticos geralmente se aninham em erros semânticos (o inverso não é verdadeiro).
Como exemplo, digamos que mudei o significado de uma variável e, como resultado, mudei seu nome. A mudança de nome gera um erro de sintaxe posteriormente no código, mas se eu apenas agradar o complier corrigindo o nome, ignorei por que esse erro surgiu.
fonte
Mas como você testará seu código à medida que não compilar de acordo?
O caso extremo é o desenvolvimento orientado a teste (TDD). É óbvio que o TDD não funciona com sua estratégia, pois TDD significa ciclos extremamente curtos de teste de gravação, compilação (deve falhar), código de gravação, compilação novamente, teste de execução, correção de bugs, compilação novamente, refatoração, compilação de novo, teste de execução e assim por diante ...
Então, nem todo mundo faz TDD, pelo menos nem sempre (eu também, eu admito). Com sua estratégia atual, você nunca terá a chance de experimentar o TDD. Mas mesmo quando você não está fazendo TDD, é extremamente útil testar seu código com mais frequência - o que não é possível quando você não o compila regularmente. E quando seu teste falha, você está executando a depuração (o que pode ajudá-lo a entender por que o algoritmo de boa aparência que você escreveu alguns minutos antes não se comporta tão bem quanto você pensou que deveria). E quanto mais código você escreve sem compilar, maior o código que você escreve sem testar; portanto, é mais provável que você se depare com um caso em que não possa prever que o tempo para corrigir o problema seja "O (1)", como você escreveu.
fonte
new Foo();
que obviamente não será compilado, pois você não escreveu a definição da classe. No TDD, esse é um motivo válido para executar um compilador - isso prova que seu teste de unidade está funcionando (por falha).Na verdade, eu concordo com você que os erros do compilador não devem ser um grande problema para um desenvolvedor experiente. Eu não acho que o custo de consertá-los aumente significativamente o suficiente com o tempo para se preocupar. Se fosse possível adiar a correção de todos os erros do compilador até pouco antes de um push, eu o faria, pois apresentaria uma interrupção muito menor e mais consolidada.
Infelizmente, encontrar erros de compilador não é a única coisa que os compiladores fazem. Correndo o risco de afirmar o óbvio, a compilação é necessária para executar o programa, e a execução do programa é necessária para encontrar todos os bugs de tempo de execução mais complexos, sutis e interessantes criados por desenvolvedores experientes. E esses tipos de bugs são mais difíceis e, portanto, mais caros para corrigir quanto mais você adia a depuração, porque eles podem criar ou mascarar uns aos outros.
No entanto, eu não indicaria necessariamente alguém em um exercício de entrevista por adiar a compilação até o final. Os exercícios para entrevistas tendem a ser muito diretos, e desenvolvedores experientes geralmente conhecem seus limites. Quanto mais confiante você estiver sobre o que escreveu, mais tempo passará entre as compilações. Essa é apenas a natureza humana.
A fim de não marcar você para baixo, a confiança teria que ser justificada. Se você tivesse passado 45 minutos escrevendo algo sem compilar e precisado de mais 45 minutos para depurá-lo, eu teria pesado muito contra você.
fonte
A única coisa importante sobre compilar com frequência, ausente de outras respostas, até onde posso ver, é a seguinte: se você compila raramente e recebe uma grande quantidade de erros do compilador, a maioria deles não tem sentido, porque são gerados pelo primeiro erro. Pode ser porque você teve um erro de digitação, erro de digitação ou sintaxe simples que invalida alguma declaração.
Você sempre pode consertar o primeiro, recompilar, consertar o próximo e assim por diante, mas com uma grande base de código isso pode ser lento. Mas se você tentar percorrer a longa lista de erros do compilador e detectar erros que são independentes, passa muito tempo lendo mensagens irrelevantes ou navegando no código do ponto de erro secundário para a causa real.
Outra coisa interessante para compilações regulares é que nada impede que você comece a compilar assim que tiver um bloco completo de código escrito, que deve ser compilado. Você pode continuar escrevendo mais código enquanto a compilação continua, desde que não salve as novas edições até que a compilação termine. Portanto, praticamente não há tempo perdido na espera pela compilação. Se você esperar até escrever tudo o que vai escrever naquele momento, precisará aguardar a compilação sem nada para fazer. Esta é basicamente a versão manual do que os IDEs modernos podem fazer em segundo plano automaticamente.
fonte
Para um programador suficientemente experiente, o código de compilação nunca é o gargalo.
Depois de conhecer uma linguagem suficientemente bem (ou seja, quando você não precisa mais pensar na sintaxe e apenas codificar a funcionalidade), você tende a não cometer erros sintáticos simples. Aqueles que você faz geralmente são erros de digitação ou erros de copiar e colar e podem ser limpos em pouco tempo com apenas alguns passes de compilação.
Escrevo regularmente código o dia todo sem compilar, depois compilarei e corrigirei os erros de sintaxe e os avisos que o compilador relata antes de confirmar meu código (com uma observação que diz "precisa ser testado!" ). Não tenho problema em limpar mais de 1.000 linhas de código C ou C ++ em apenas alguns minutos.
Depurar e testar, por outro lado, é o que leva um tempo. Os erros de lógica surgem por todos os tipos de razões e eu ainda não encontrei um compilador que me falasse sobre a sub-rotina que esqueci totalmente de escrever ou notará que minha árvore binária não funciona porque eu colei
node->left
quando deveria ter sidonode->right
.Embora eu ache geralmente imprudente brigar com um entrevistador, eu diria que, se você acha que vale a pena defender seu estilo, deveria ter salientado que se deixou tempo suficiente para depurar o código que escreveu. É isso que nenhum bom programador negligencia.
ps - Se eu estivesse assistindo você revisar o código lendo-o, teria contratado você imediatamente. Isso é o que um profissional faz, sempre.
fonte
Não, não é razoável adiar a compilação até que você tenha criado uma quantidade suficiente de código (e uma 'quantidade suficiente' depende do codificador e do código que está sendo gravado).
Por exemplo, se você é um codificador incrível que leva o tempo necessário para acertar e não está escrevendo quantidades maciças ou código complicado, compilar regularmente é um desperdício e provavelmente uma distração também. Caso contrário, compilar todas as funções pode ser uma coisa boa. Isso depende da pessoa.
Como um contra-exemplo, imagine que você está escrevendo código JavaScript - não há compilador. Em vez disso (dada a natureza da maioria dos códigos JavaScript), você executaria o programa (ou atualizaria a página) para ver os resultados da sua codificação. Agora, você não pode fazer isso até escrever código suficiente para fazer sentido. Como resultado, os desenvolvedores de JavaScript tendem a "compilar" o mais rápido possível, o que não é necessariamente com muita frequência.
Em resumo, não há resposta correta aqui - o entrevistador não está errado, mas você também não. Faça o que o torna produtivo e esqueça o que alguém lhe diz que você deve fazer. Existem fatores muito mais importantes sobre a codificação do que sua tendência a bater F7regularmente (ou não) não tem absolutamente nenhuma conseqüência.
fonte
Com um bom ambiente de desenvolvimento, vejo poucas razões para compilar, a menos que você esteja planejando testar o código. As ferramentas de verificação de sintaxe de segundo plano capturam quase tudo o que o entrevistador parece estar falando, embora eu admita que ainda existam alguns casos (envolvendo alterações que se propagam por arquivos) que nem sempre são totalmente identificados.
Dito isto, tentarei compilar e executar praticamente a menor unidade de código que pode realmente produzir um resultado. Há meia hora, eu estava criando um meio de imprimir alguns resultados de pesquisa e fiz meia dúzia de impressões de teste (para .pdf, não papel), fazendo alterações no resultado para torná-lo melhor - uma taxa de cerca de 1 compilação por 10 linhas.
fonte
Minha experiência é muito diferente: menos de 5% dos erros de compilação que recebo são sobre sintaxe . Conheço bem a linguagem, quando recebo erros, na maioria das vezes são erros de tipo, dizendo que a semântica não está correta.
É por isso que fico feliz em me beneficiar o mais rápido possível dos comentários do meu compilador. Você já experimentou usar um IDE que sublinha erros de compilação em tempo real? Ter um ciclo de feedback mais curto pode ser muito valioso.
Se você espera trabalhar no código escrito por outra pessoa, nem sempre você tem tempo para ler tudo. A boa notícia é: código bem escrito tem baixo acoplamento e deve permitir que você raciocine independentemente sobre apenas a parte do código que você precisa.
Nesses casos, você deve assumir que o código que você ainda não leu está correto e investigar preguiçosamente quando houver um problema.
A troca de contexto é cara para o seu cérebro, portanto, corrigir pequenos erros assim que você os escrever pode ser mais eficiente.
EDIT: Eu também posso fazer uma analogia com o controle de fonte, quando uma equipe inteira está trabalhando nas mesmas fontes. Compilar à medida que avança é como fazer confirmações frequentes, ajuda a evitar muita dor no final quando você precisa mesclar e resolver tudo.
Você diz que desabilita itens como linhas vermelhas no seu texto. Você também faz isso ao digitar um email ou escrever um documento técnico? Em seguida, você deve revisar todas as páginas novamente, em vez de corrigir erros.
Outra vantagem é que, ao trabalhar no seu código, se você o mantiver compilando ou quase compilando o tempo todo, poderá se beneficiar de muitos recursos IDE semânticos (renomeação, refatoração segura, localização de usos de um símbolo ...) .
Se você quiser entender melhor como esses recursos ajudam, tente habilitá-los e praticar para experimentar seus benefícios. Você também pode tentar programar em pares com qualquer pessoa que esteja acostumada com eles e ver como eles se beneficiam.
fonte
Pensei um pouco mais sobre isso, porque senti que havia algo muito, muito errado com o entrevistador e não consegui dizer exatamente o que é. Aqui está o problema: para qualquer código que escrevi nos últimos vinte anos, a quantidade de tempo necessária para transformar um algoritmo viável em código compilado foi mínima. Qualquer ganho de eficiência nessa área tem tão pouco impacto no tempo total de desenvolvimento que é totalmente desprezível, e um entrevistador que rejeita um candidato por ineficiências percebidas nessa área não tem idéia do que faz um bom desenvolvedor.
A maior parte do tempo deve ser gasta na coleta de informações sobre o que o código deve fazer, na coleta de informações e especificações sobre serviços externos que precisam ser usados, criando um design global que levará ao código correto e de manutenção, em vez do código cortado e à descoberta de algoritmos. isso levará ao código ativo, em vez do código que será corrigido juntos até que funcione (código que obviamente não possui erros vs. código que não possui erros óbvios).
Depois, dedique uma pequena quantidade de tempo escrevendo o código que é compilado.
Em seguida, vem uma quantidade maior de tempo gasto para garantir que o código funcione e para que saibamos que o código funciona e continuará funcionando. Isso é feito escrevendo testes de unidade, percorrendo o código e, em grande parte, tendo um código bem projetado em primeiro lugar.
Esse entrevistador se concentrou em algo coberto por dez palavras em minha resposta. Que representam 10% ou menos do tempo real de trabalho. E tem quase zero de influência na capacidade desse desenvolvedor de produzir código confiável e funcional.
fonte
A vantagem de "compilar à medida que avança" é que você recebe feedback constante e não terá chance de dar muito errado antes de ser empurrado na direção certa. Para um programador competente como você, isso não é uma grande consideração, mas para muitos outros é. Em outras palavras, "compilar à medida que avança" é uma maneira de "minimizar a perda máxima", mesmo que haja algumas perdas potenciais de eficiência no seu caso.
Atualmente, as empresas não estão interessadas apenas em um produto acabado. Eles querem saber que estava "sob controle" o tempo todo. Para eles, "chegar lá é metade da diversão".
fonte
As outras respostas aqui são uma boa defesa para compilar com frequência no trabalho , mas como sua pergunta está centrada em entrevistas , eu gostaria de abordar esse ângulo.
Nas minhas entrevistas, faço exatamente o oposto: os candidatos não podem usar um compilador. Eles escrevem programas curtos no quadro branco e depois discutimos sobre eles. Descobri que muitos desenvolvedores usam o compilador (ou intérprete) como muleta, e isso é uma perda de tempo muito maior do que compilar com pouca frequência. Se estou oferecendo muito dinheiro e você nem consegue escrever o FizzBuzz corretamente sem um compilador, você nunca vai cortá-lo a longo prazo, trabalhando em problemas 100x mais difíceis do que os exercícios de brinquedo na entrevista. E, no entanto, esses exercícios simples eliminam mais candidatos do que qualquer outra parte da entrevista.
O objetivo de uma entrevista é avaliar o ajuste mútuo do candidato e da empresa. Uma boa pergunta para entrevista deve indicar os objetivos da pergunta e como o entrevistado será avaliado. Iniciar uma pergunta complicada sobre o entrevistado e penalizá-lo por não saber a resposta oculta não ajuda o entrevistador ou o entrevistado. Infelizmente, a maioria dos programadores - mesmo os mais velhos - não é treinada para entrevistar outros programadores; portanto, confiam nos clichês e fazem os mesmos tipos de perguntas que fizeram quando entrevistaram, sem muita dúvida se essas são técnicas eficazes para avaliar candidatos. ou não.
Não estou afirmando que minha abordagem é a "única maneira verdadeira", mas me serviu muito bem. Como muitas metodologias de software que começam com uma letra maiúscula, há um número igual de "mandatos" para entrevistas. Eles são todos beliches. Você precisa fazer o que funciona para você e sua empresa.
fonte
Em projetos maiores, com várias sub-rotinas, você deseja testar essas partes, antes de usá-las no esquema maior, pois é muito mais fácil depurar se você souber que certas partes já funcionam.
Para testar essas partes menores, você precisa compilar.
Pode ser que o entrevistador confunda essa situação com um pequeno programa que não foi projetado dessa maneira.
fonte
Em relação à segunda entrevista, um benefício da compilação é que você pode observar, em apenas alguns segundos, o que os programas fazem (ou não). A partir daí, é mais fácil ler o código e concentrar seus esforços nas partes relevantes. Talvez seja isso que o entrevistador estava esperando.
Ler uma base de código desconhecida como essa do começo ao fim pode ser bastante improdutivo (você não é um compilador), enquanto compilar / executar o aplicativo rapidamente fornecerá uma imagem maior.
fonte