É normal que um programador não tenha 100% de clareza sobre seu próprio código às vezes? [fechadas]

19

Não sou um programador especialista, por isso pode ser o motivo, mas percebi que sempre que crio código complexo (como um jogo de xadrez que fiz recentemente), sou capaz de escrever o código correto para que o programa funcione, embora eu ache que mais tarde - ou mesmo alguns segundos depois! - muitas vezes tenho que fazer uma pausa e pensar em como isso funciona?

Não apenas isso, mas também tendem a não pensar no código e, em vez disso, apenas digito. Por exemplo, no meu jogo de xadrez, decidi usar uma matriz de cinco dimensões para processar movimentos, e descobri que podia fazer isso sem pensar muito. No entanto, quando parei e li sobre isso, achei difícil entender meu conceito tridimensional e demorei alguns minutos para entender completamente o que eu fazia e como o próprio código funciona.

É normal que os programadores, ao escreverem códigos complexos, não entendam o que estão fazendo metade do tempo?

83457
fonte
13
É um sinal de que você está se esforçando demais para ser inteligente. Você precisa escrever um código mais simples e mais modular se tiver problemas para lê-lo.
SHODAN 23/11
3
Para adicionar outras respostas (perspicazes), no sentido de que cheira a código muito complicado ou mal projetado (não se preocupe, a maioria de nós teve que passar nessa fase): Documento . Fornecendo nomes próprios para variáveis ​​/ métodos / classes / módulos, adicionando uma descrição adequada a cada função e escrevendo (quando você não vê outra maneira) escrever um simples comentário embutido explicando por que e como você está usando algum trecho complexo de código.
SJuan76
4
Eu nunca tenho 100% de clareza sobre meu próprio código.
CodesInChaos
2
Essa matriz 5D realmente parece que poderia usar alguma abstração.
3
Algum desenvolvedor tem 100% de clareza sobre seu código o tempo todo?
23414 Johan Johan

Respostas:

30

Não, não é normal 1 . Pelo menos, não é normal para bons programadores. Provavelmente é normal alguém aprender a programar.

O software de escrita não está apenas juntando linhas de código até que funcione. Você precisa trabalhar conscientemente para facilitar a compreensão do código. Um programador que eu respeito muito me disse uma vez "o código é lido muito mais vezes do que está escrito" . Embora isso devesse ser completamente óbvio, era um fato que eu não sabia até que ele me contou. Grande parte do seu código é gravada apenas uma vez, talvez reescrita uma ou duas vezes mais, mas você acaba lendo o código frequentemente durante a vida útil do software.

Se você está achando difícil entender o código minutos depois de escrevê-lo, é um sinal de que seu código é muito complexo. Pare de adicionar código e descubra uma maneira melhor. Por exemplo, uma matriz em cinco dimensões quase nunca é uma boa ideia. Mesmo programadores muito, muito inteligentes têm dificuldade em entender uma estrutura de dados tão complexa.

O mesmo programador que me falou sobre a legibilidade do código também disse "me mostre suas estruturas de dados e eu posso lhe dizer como seu código funciona" . Ou seja, um bom código começa com estruturas de dados limpas e compreensíveis. Se você projetar seus dados corretamente, o código é quase uma preocupação secundária. É certo que essa afirmação é um pouco exagerada, porque o software é obviamente mais do que apenas dados, mas começa com dados. Portanto, trabalhe na criação de estruturas de dados limpas e fáceis de entender, e o código será consideravelmente mais fácil de entender.


1 Certamente existe um código muito complexo e difícil de entender, mesmo pelos programadores mais inteligentes. Alguns problemas são inerentemente complexos. No entanto, eu arriscaria dizer que a grande maioria do código escrito pela grande maioria dos programadores não é esse tipo de código.

Bryan Oakley
fonte
8
[1] De um ponto de vista mais pessimista, é normal, mas não é bom.
Dan
1
Se a "matriz tridimensional" for apenas um mapa de uma tupla de 4 ou 5 tuplas para uma estratégia, o autor poderia ter usado uma tabela de hash ou uma função de pesquisa auxiliar. No entanto, se o autor passa a maior parte do tempo codificando a mecânica da inicialização do array (aninhados para loops), o "insight do algoritmo" real será afogado na pilha de "código mecânico". Os programadores procuram manter o último tipo de ruído separado. Assim, bons programadores precisam saber como escrever bibliotecas principalmente para abrigar esses códigos mecânicos.
Rwong
A matriz 1-D é uma linha, 2-d é uma grade, 3-d é um cubo, 4-d é uma linha de cubos, 5-d é uma grade de cubos etc. mas não vejo utilidade para uma estrutura de dados tão complexa quando se trata de xadrez.
user2785724
15

Existem dois tipos disso: 1.) confusão 2.) ignorância feliz

O primeiro é ruim e pode desaparecer com o tempo e a experiência.

A segunda é boa se os projetos se tornarem maiores: se você precisar se lembrar de todos os detalhes da implementação para poder trabalhar com seu código, há algo errado com ele (consulte "ocultação de informações").

Todo desenvolvedor vai esquecer como o código estava funcionando, então ele o escreve de uma maneira que outro novo desenvolvedor entenda e possa mantê-lo sem quebrar outras partes do programa que ele também não conhece.

Portanto, "não saber" é realmente uma constante no desenvolvimento de software - é exatamente como ou se você o gerencia.

telep
fonte
1
Você está abordando algo importante aqui, que é vital para programar usando padrões e convenções de bom senso , porque os detalhes da implementação são realmente esquecidos. Mas se os padrões e convenções no código forem sensatos, é fácil o suficiente recuperar os detalhes do contexto, quando necessário. Por outro lado, se o código for todo monolítico, inescrutável e excessivamente inteligente, você não apenas esquecerá os detalhes, mas outros programadores que tentam manter o código terão muito mais dificuldade.
Craig
12

Eu diria que é mais comum do que as pessoas querem admitir. Até Brian Kernighan aludiu a isso:

A depuração é duas vezes mais difícil do que escrever o código em primeiro lugar. Portanto, se você escrever o código da maneira mais inteligente possível, por definição, você não é inteligente o suficiente para depurá-lo.

Quando dirigimos para a loja, fazemos uma sequência de ajustes detalhados nas posições dos pedais e no volante. Isso é muito fácil no momento. Agora, imagine se você registrou esses ajustes no papel e os deu a um amigo que precisava de instruções para a loja.

Da mesma forma, gostamos de escrever código em um nível de abstração, mas gostamos de lê-lo em várias camadas mais altas de abstração. Nossa maneira preferida de escrever e ler código está, portanto, em conflito. Isso significa que facilitar a leitura do código geralmente é um passo consciente e separado, com um conjunto diferente de habilidades.

O que faz um bom programador é que, quando eles têm dificuldade em ler o que acabaram de escrever, eles criam uma abstração nesse ponto. Um programador melhor faz isso várias vezes, ficando cada vez mais exigente. Eventualmente, programadores experientes começam mais adiante no processo, mas geralmente ainda conseguem melhorar depois de ler o que acabaram de escrever.

Karl Bielefeldt
fonte
Eu tenho que discordar de Brian nessa questão, adoro depurar, sou uma das poucas pessoas que conheço na indústria que o faz, mas não avalio o código que escrevo tão bem.
James Snell
@ JamesSnell Ele não disse que a depuração é ruim ou desagradável, apenas que é difícil, e a depuração de código complicado é ainda mais difícil.
Cbojar
5

Eu acho que isso é algo que desaparece com a experiência.

Se você estiver escrevendo sistemas complexos, precisará ter a capacidade de escrever código limpo e sustentável que você, no futuro, e outra pessoa no futuro possam entender. Portanto, em essência, o que você está fazendo agora não é escalável.

Você terá muitos momentos em que está olhando para algum código que escreveu há 6 meses e pensando "o que diabos está acontecendo aqui?", Mas se isso acontecer um dia depois que você escreveu o código, precisará pensar 'limpo código 'mais.

Fonte: nunca usou uma matriz 5 dimensional :)

Erez Eshkol
fonte
3
@ 83457 - porque uma matriz 5d é um modelo ruim de um problema 2d. Se você realmente acha que é um bom código, passe-o para codereview.stackexchange.com e veja quais respostas você obtém.
James Snell
2
@ 83457 - Se é 'confuso como o inferno', você já respondeu. Pode ser possível que uma matriz 5-D não seja confusa, mas provavelmente não seja para a maioria de nós, independentemente do nosso nível de habilidade.
precisa saber é o seguinte
2
@ 83457 ser confuso como o inferno já deve ser uma motivação muito boa para não usar isso.
Fabio Marcolini
3
Contanto que você tenha um bom motivo para cada dimensão, não vejo um motivo para evitar uma matriz 5D. Talvez exista uma solução melhor, como um dicionário com uma chave complexa ou várias matrizes de dimensões inferiores, mas posso muito bem imaginar uma matriz 5D sendo apropriada para um problema complicado como uma IA de xadrez.
CodesInChaos
2
@CodesInChaos Exceto que essas não são apenas matrizes, elas representam sequências significativas (por exemplo, árvores de prisão aninhadas). Nomeando-os adequadamente e fornecendo-lhes tipos para que não possam ser abusados ​​(mesmo que esses tipos sejam invólucros sobre matrizes), você torna o código mais claro e com menor probabilidade de conter bugs, por quase nenhum custo.
deworde
5

"Normal" é muito subjetivo, por isso digo: é muito comum, mas deve ser evitado.

Uma das características do "código bom" (ouvi dizer que isso existe) é a clareza: deve ser tão claro quanto os problemas subjacentes permitirem. Se o problema for complexo, o código também seria complexo, mas isso é complexidade inerente , ao contrário da complexidade acidental (ouvi falar dessa distinção na palestra de Rich Hickey ) introduzida por usar ou não as ferramentas, os padrões, as técnicas e os métodos corretos. práticas.

Há casos em que a falta de clareza é aceitável, mesmo quando o problema não é muito complexo, por exemplo, se você escrever um site promocional que sabe que vai durar enquanto durar a campanha de marketing. Esse é um código descartável que não deve ser sustentável. Para outros (e na maioria dos casos), não é aceitável, pois manter esse código custará muito. No entanto, é comum.

Relacionado:

  • Quando Compreender significa Reescrever - artigo sobre o problema de entender o código.
  • ML eficaz - uma longa conversa sobre, entre o ML / OCaml, como escrever o código para "leitores" (ou seja, mantenedores): "Favorecer os leitores sobre os escritores". Eu recomendo assistir, não importa qual idioma você usa.
scriptin
fonte
2

Não acho que seja normal, mas para programas muito complexos, como o programa de xadrez que você mencionou, acho que é certamente possível.

Muitos anos atrás, quando eu estava fora da faculdade (então ainda era relativamente inexperiente escrevendo programas grandes), escrevi meu primeiro compilador real. A análise foi direta, mas então eu precisei direcioná-la para quatro conjuntos de instruções de microprocessador diferentes. Eu pretendia escrever o compilador em seu próprio idioma, então primeiro usei apenas os recursos do idioma que eu absolutamente precisava, escrevi o primeiro gerador de código em linguagem assembly e testei se ele gerava o código correto para o subconjunto do idioma. Eu era capaz de usar o compilador para se compilar a partir de então, adicionar os recursos restantes e também usá-los no próprio compilador

Em seguida, escrevi os geradores de código de back-end para cada microprocessador e testei que todos geravam código correto, mas, apesar de correto, não era o ideal. Então, comecei a escrever otimizadores para cada gerador de código.

Quando eu estava testando a saída dos geradores de código após adicionar toda a otimização, fiquei frequentemente surpreso com o código que o compilador gerava. Geralmente não era assim que eu escreveria o código manualmente, mas era correto e bastante conciso.

Quando não era óbvio para mim como o gerador de código produzia parte do código, tentei seguir a lógica manualmente, mas houve momentos em que desisti. Se eu tivesse adicionado muita saída de rastreio, seria capaz de segui-la, mas não me incomodei, pois o código gerado era satisfatório e precisava entrar em outros projetos.

tcrosley
fonte
Parece-me que você tem uma educação extremamente boa, com uma base sólida e que internalizou o conhecimento em um nível muito alto. Eu acho que isso é um tanto raro entre os programadores típicos. A maioria dos programadores típicos (inclusive eu) precisa lutar para acompanhar o conhecimento necessário para a tarefa de hoje, porque a tecnologia muda muito rapidamente.
Rwong
@rwong Obrigado. A maior parte é experiência - estou escrevendo programas há 46 anos e não tenho intenção de desistir tão cedo.
tcrosley
2

Há muitas respostas decentes aqui.

Eu tenho algumas opiniões sobre isso.

Uma é que, se você não entende por que seu código parece funcionar, então a) provavelmente não funciona (provavelmente apenas parece que funciona) eb) você não entendeu o domínio do problema suficientemente bem quando começou a codificar ou não dividiu o domínio do problema em unidades menores e simplificadas antes de começar.

Minha outra opinião é que a chave real é usar padrões e convenções de bom senso no seu código. Esse é um tópico muito maior do que um pequeno post pode abordar. Mas procure uma boa literatura sobre o assunto, incluindo algumas das antigas esperanças, como os livros "Code Complete" e "Writing Solid Code".

Detalhes da implementação alterados. A única constante real é o objetivo funcional do código. Se você escrever mais de uma função, esquecerá detalhes específicos e detalhados da implementação ao longo do tempo. Mas você certamente deve entender como as peças funcionam quando as constrói e deve poder desenhar um diagrama do todo e entender como as peças funcionam juntas.

Se você usar padrões e seguir as convenções de bom senso, será muito mais fácil escolher os detalhes específicos da implementação quando você olhar o código novamente. Ou quando alguém que nunca viu o código antes olha pela primeira vez. Além disso, seguir essas convenções e padrões ao longo do tempo significará que os detalhes da implementação se destacarão das próprias convenções e padrões, que é outro fator que facilitará a compreensão do código.

A maioria dos problemas que enfrentamos com o software é complexa por natureza. O design de software é um exercício de gerenciamento da complexidade.

Craig
fonte
1

Eu não diria que é normal , mas isso definitivamente pode acontecer. Se isso acontecer logo após você ter escrito o trecho de código em questão, acho que seu código é desnecessariamente complexo e deve ser simplificado, ou você fica facilmente distraído. :)

Mas se você deixar seu código de lado, se concentrar em outros projetos e retornar a ele depois de semanas, meses ou até anos, não é surpresa que você precise descobrir tudo de novo.

Mas há algo que você pode fazer sobre isso. Pelo que você diz, parece que você não pensa o suficiente sobre o seu código enquanto o escreve e, portanto, está dificultando o seu futuro entender o que está acontecendo. Use esse conhecimento para sua vantagem: Essa é a melhor motivação para produzir código bem estruturado, bem documentado e compreensível. Você sabe por experiência própria o que acontece quando você não cuida da qualidade do seu código. Saber isso deve torná-lo um programador melhor a longo prazo. Quando você colabora em projetos de software, seus colegas agradecem por produzir um código compreensível. E a taxa de defeitos do seu código também melhorará.

mindriot
fonte