A citação de Torvalds sobre um bom programador [fechado]

238

Acidentalmente, me deparei com a seguinte citação de Linus Torvalds:

"Programadores ruins se preocupam com o código. Bons programadores se preocupam com estruturas de dados e seus relacionamentos."

Pensei nisso nos últimos dias e ainda estou confuso (o que provavelmente não é um bom sinal), por isso queria discutir o seguinte:

  • Que interpretação disso é possível / faz sentido?
  • O que pode ser aplicado / aprendido com isso?
beyeran
fonte
18
Eu acho que essa pergunta provavelmente tem várias respostas que são igualmente válidas. Mas é uma boa pergunta de qualquer maneira. Eu amo essa citação. Expressa por que não entendo programadores preocupados em mudar de idioma. Raramente é a linguagem que importa em um programa, são as estruturas de dados e como elas se relacionam.
Ryan Kinal
5
Talvez se você dedicar algum tempo a tornar as estruturas de dados "elegantes", o código não precisará ser complicado para lidar com essas estruturas de dados? Provavelmente sou burra demais para realmente entender o significado da citação de Torvalds. :}
programador
3
@RyanKinal Mas é claro que a linguagem importa , porque torna consideravelmente mais fácil lidar e pensar em determinadas estruturas de dados. Pense em todos os idiomas especializados em análise LISt, por exemplo, ou idiomas que tenham suporte nativo para estruturas de dados que precisam ser invadidas por outros idiomas (conjuntos e matrizes esparsas vêm à mente).
kojiro
83
Torvalds não está sozinho nisso, a propósito: "Mostre-me seu fluxograma e oculte suas tabelas, e continuarei confuso. Mostre-me suas tabelas e geralmente não precisarei de seu fluxograma; será óbvio. " - Fred Brooks, o mês do homem mítico. "Mostre-me seu código e oculte suas estruturas de dados, e eu continuarei confuso. Mostre-me suas estruturas de dados e normalmente não precisarei do seu código; será óbvio." e "Estruturas de dados inteligentes e código burro funcionam muito melhor do que o contrário." - Eric S. Raymond, a catedral e o bazar.
Jörg W Mittag
4
Isso explica por que o kernel Linux é uma bagunça :)
L1x

Respostas:

326

Talvez seja útil considerar o que Torvalds disse antes disso:

Na verdade, o git tem um design simples, com estruturas de dados estáveis ​​e razoavelmente bem documentadas. Na verdade, sou um grande defensor do design do seu código em torno dos dados, e não o contrário, e acho que é uma das razões pelas quais o git tem sido bastante bem-sucedido […] Eu, de fato, alegarei que a diferença entre um programador ruim e um bom é se ele considera seu código ou sua estrutura de dados mais importante.

O que ele está dizendo é que boas estruturas de dados tornam o código muito fácil de projetar e manter, enquanto o melhor código não pode compensar estruturas de dados ruins.

Se você está se perguntando sobre o exemplo do git, muitos sistemas de controle de versão alteram seu formato de dados com relativa regularidade para oferecer suporte a novos recursos. Quando você atualiza para obter o novo recurso, geralmente precisa executar algum tipo de ferramenta para converter o banco de dados.

Por exemplo, quando o DVCS se tornou popular, muitas pessoas não conseguiam descobrir o que o modelo distribuído tornava as fusões muito mais limpas do que o controle de versão centralizado. A resposta é absolutamente nada, exceto que as estruturas de dados distribuídas tinham que ser muito melhores para ter a esperança de funcionar. Acredito que os algoritmos de mesclagem centralizados já alcançaram, mas demorou bastante tempo porque suas estruturas de dados antigas limitavam os tipos de algoritmos que eles podiam usar, e as novas estruturas de dados quebravam muito código existente.

Por outro lado, apesar de uma explosão de recursos no git, suas estruturas de dados subjacentes praticamente não mudaram. Preocupe-se primeiro com as estruturas de dados e seu código será naturalmente mais limpo.

Karl Bielefeldt
fonte
25
o melhor código não pode compensar estruturas de dados ruins bom molho é verdade
Conrad Frix
5
Ele está falando do ponto de vista dos programadores fazendo alterações no próprio git. O ponto de vista do usuário final é completamente ortogonal a esta discussão, além de facilitar a manutenção de códigos, gerando menos bugs e adições mais rápidas aos recursos.
Karl Bielefeldt
2
@ James: Ele está dizendo que o software é melhor (portanto, mais fácil de usar e usado por mais pessoas) porque as estruturas de dados são melhores. É claro que você não precisa conhecer as estruturas de dados do software que usa, mas se importa com elas indiretamente, mesmo que não perceba, porque as estruturas de dados são o que impulsionam as coisas que você percebe. se importar.
Ruakh 31/08
1
+1. Esta resposta coloca o contexto em uma afirmação que poderia ser interpretada como algo muito diferente. Qualquer pessoa que tenha lido uma monstruosidade de 5000 linhas de um arquivo sabe exatamente o que quero dizer.
riwalk
20
"Preocupe-se primeiro com as estruturas de dados e seu código será naturalmente mais limpo.": O estadista romano Cato ( en.wikipedia.org/wiki/Cato_the_Elder ) costumava dizer "Rem tene, verba sequentur" = "Deixe o argumento claro em sua mente, as palavras seguirão naturalmente ". O mesmo acontece com a programação: entenda primeiro as estruturas de dados e o design, o código real seguirá por si só.
Giorgio
60

Algoritmos + Estruturas de Dados = Programas

Código é apenas a maneira de expressar os algoritmos e as estruturas de dados.

zxcdw
fonte
Última edição ethoberon.ethz.ch/WirthPubl/AD.pdf
dchest
Isso é verdade para programação procedural; no POO é um pouco diferente.
M3th0dman
3
Não é fundamentalmente qualquer diferente. Você tem dados e realiza um conjunto de operações. Variáveis ​​e métodos de membros. Exatamente a mesma coisa. Toda a essência da computação, desde os anos 50, foi construída com base na regra muito simples de que os programas consistem em algoritmos que modificam as estruturas de dados, e ela se mantém verdadeira 60 anos depois. Você também pode considerar programas como funções . Eles recebem informações sobre as quais operam para produzir resultados . Exatamente como as funções matemáticas fazem.
Zxcdw
31

Esta citação é muito familiar a uma das regras em "The Art of Unix Programming", que é o forte de Torvalds sendo o criador do Linux. O livro está localizado online aqui

Do livro está a seguinte citação que expõe o que Torvalds está dizendo.

Regra de representação: dobre o conhecimento em dados para que a lógica do programa possa ser estúpida e robusta.

Mesmo a lógica processual mais simples é difícil para os humanos verificarem, mas estruturas de dados bastante complexas são bastante fáceis de modelar e raciocinar. Para ver isso, compare a expressividade e o poder explicativo de um diagrama de (digamos) uma árvore de ponteiros de cinquenta nós com um fluxograma de um programa de cinquenta linhas. Ou compare um inicializador de matriz que expresse uma tabela de conversão com uma instrução de opção equivalente. A diferença de transparência e clareza é dramática. Veja a Regra 5 de Rob Pike.

Os dados são mais tratáveis ​​que a lógica do programa. Daqui resulta que, onde você vê uma escolha entre complexidade nas estruturas de dados e complexidade no código, escolha a primeira. Mais: ao desenvolver um design, você deve procurar ativamente maneiras de mudar a complexidade do código para os dados.

A comunidade Unix não originou esse insight, mas muito código Unix mostra sua influência. A facilidade da linguagem C em manipular ponteiros, em particular, incentivou o uso de estruturas de referência modificadas dinamicamente em todos os níveis de codificação do kernel para cima. As perseguições simples de ponteiros em tais estruturas freqüentemente cumprem tarefas que as implementações em outros idiomas teriam que incorporar em procedimentos mais elaborados.

Jay Atkinson
fonte
Lembrei-me disso também!
Jesvin Jose
1
OTOH, olhe para qualquer pergunta sobre StackOverflow int**. Isso deve convencê-lo de que os dados NÃO são de fato óbvios; isso só acontece com a anexação de significado aos dados. E esse significado está no código.
MSalters
29

O código é fácil, é a lógica por trás do código que é complexa.

Se você está preocupado com o código, isso significa que você ainda não entendeu o básico e provavelmente está perdido no complexo (por exemplo, estruturas de dados e seus relacionamentos).

idiotas
fonte
17
Heh, eu me pergunto se a próxima geração de programadores perguntará: "Os idiotas disseram uma vez Code is easy, it's the logic behind the code that is complex, o que ele quis dizer?"
31712 yannis
36
@YannisRizos Isso será especialmente confuso quando as pessoas não tiverem certeza se foi dito por pessoas que eram idiotas ou por uma única pessoa com o nome de idiotas.
KChaloux
14

Para expandir um pouco a resposta dos idiotas , a idéia é que entender os detalhes do código (sintaxe e, em menor grau, estrutura / layout) é fácil o suficiente para criarmos ferramentas que possam fazê-lo. Os compiladores podem entender tudo o que precisa ser conhecido sobre o código para transformá-lo em um programa / biblioteca em funcionamento. Mas um compilador não pode realmente resolver os problemas que os programadores fazem.

Você poderia levar o argumento um passo adiante e dizer "mas nós temos programas que geram código", mas o código que ele gera é baseado em algum tipo de entrada que quase sempre é construída à mão.

Portanto, qualquer que seja a rota que você use para chegar ao código: seja por meio de algum tipo de configuração ou outra entrada que produz código por meio de uma ferramenta ou se você estiver escrevendo do zero, não é o código que importa. É o pensamento crítico de todas as partes necessárias para chegar ao código que importam. No mundo de Linus, isso é basicamente estruturas e relacionamentos de dados, embora em outros domínios possam ser outras partes. Mas, nesse contexto, Linus está apenas dizendo "Eu não ligo se você pode escrever código, eu ligo para que você possa entender as coisas que resolverão os problemas com os quais estou lidando".

Daniel DiPaolo
fonte
Todo programador usa programas que geram código. Eles são freqüentemente chamados de "compiladores", às vezes em combinação com "vinculadores". Eles recebem uma entrada (relativamente) legível por humanos e gravável por humanos, que geralmente é (mas nem sempre) é fornecida em algum tipo de formato de texto e os transforma em dados que o computador pode entender como instruções e executar.
um CVn
13

Linus significa isso:

Mostre-me seus fluxogramas [código] e oculte suas tabelas [esquema], e continuarei confuso; mostre-me suas tabelas [esquema] e normalmente não precisarei de seus fluxogramas [código]: eles serão óbvios.

- Fred Brooks, "O Mês do Homem Mítico", cap 9.

Daniel Shawcross Wilkerson
fonte
12

Acho que ele está dizendo que o design geral de alto nível (estruturas de dados e seus relacionamentos) é muito mais importante que os detalhes da implementação (código). Eu acho que ele valoriza os programadores que podem projetar um sistema em detrimento daqueles que só podem se concentrar nos detalhes de um sistema.

Ambos são importantes, mas eu concordo que geralmente é muito melhor entender o cenário geral e ter problemas com os detalhes do que o contrário. Isso está intimamente relacionado ao que eu estava tentando expressar sobre dividir grandes funções em pequenas .

GlenPeterson
fonte
+1: eu concordo com você. Outro aspecto é que muitas vezes os programadores estão mais preocupados com o recurso de linguagem interessante que usarão, em vez de se concentrarem em suas estruturas e algoritmos de dados e em como anotá-los de maneira simples e clara.
Giorgio
Eu também concordo. O fato é que é fácil alterar trechos de código isolados, mas mais difícil alterar estruturas de dados ou interfaces entre trechos de código (pois esses tipos de alterações podem afetar muitas coisas, em vez de apenas uma).
Brendan
5

Bem, não posso concordar inteiramente, porque você precisa se preocupar com tudo isso. E, por falar nisso, uma das coisas que adoro em programação são as alternâncias entre diferentes níveis de abstração e tamanho, que saltam rapidamente de pensar em nanossegundos para pensar em meses e vice-versa.

No entanto, as coisas mais altas são mais importantes.

Se houver uma falha em algumas linhas de problemas que causam comportamento incorreto, provavelmente não é muito difícil de corrigir. Se está causando um desempenho abaixo do esperado, provavelmente nem importa.

Se houver uma falha na escolha da estrutura de dados em um subsistema, que causa comportamento incorreto, é um problema muito maior e mais difícil de corrigir. Se está causando um desempenho insatisfatório, pode ser bastante sério ou suportável, ainda muito menos bom do que uma abordagem rival.

Se houver uma falha no relacionamento entre as estruturas de dados mais importantes de um aplicativo, que causa um comportamento incorreto, tenho um grande design redesenhado à minha frente. Se está causando um desempenho inferior, pode ser tão ruim que quase seria melhor se estivesse se comportando errado.

E será isso que dificultará a localização desses problemas de nível inferior (a correção de erros de nível inferior é normalmente fácil, é difícil encontrá-los).

O material de baixo nível é importante, e sua importância remanescente é muitas vezes seriamente subestimada, mas fica pálida em comparação com o material grande.

Jon Hanna
fonte
2

Alguém que conhece o código vê as "árvores". Mas alguém que entende estruturas de dados vê a "floresta". Portanto, um bom programador se concentrará mais em estruturas de dados do que em código.

Tom Au
fonte
2
Mas focar na floresta ou nas árvores, excluindo a outra, pode ser prejudicial, então não acho que essa analogia se encaixe.
Kojiro # 1/12
1
@kojiro: Na expressão não pode ver a floresta para as árvores , supõe-se que alguém que possa ver a floresta também veja as árvores (consulte en.wiktionary.org/wiki/see_the_forest_for_the_trees ). Portanto, acho que é uma boa analogia aqui.
Treb
2

É importante saber como os dados fluirão. Conhecer o fluxo requer que você projete boas estruturas de dados.

Se você voltar vinte anos, esse foi um dos grandes pontos de venda da abordagem orientada a objetos usando SmallTalk, C ++ ou Java. O grande argumento - pelo menos com C ++, porque foi o que aprendi primeiro - foi projetar a classe e os métodos, e então todo o resto se encaixaria.

Sem dúvida, Linus estava falando em termos mais amplos, mas estruturas de dados mal projetadas geralmente exigem retrabalho extra de código, o que também pode levar a outros problemas.

octopusgrabbus
fonte
2

O que pode ser aplicado / aprendido com isso?

Se eu puder, minha experiência nas últimas semanas. As discussões anteriores esclareceram a resposta à minha pergunta: "o que eu aprendi?"

Reescrevi algum código e refletindo sobre os resultados que eu continuava vendo e dizendo "estrutura, estrutura ...", é por isso que havia uma diferença tão dramática. Agora vejo que foi a estrutura de dados que fez toda a diferença. E eu quero dizer tudo .

  • Ao testar minha entrega original, o analista de negócios me disse que não estava funcionando. Nós dissemos "adicionar 30 dias", mas o que quis dizer foi "adicionar um mês" (o dia na data resultante não muda). Adicione anos, meses, dias distintos; não 540 dias por 18 meses, por exemplo.

  • A correção: na estrutura de dados, substitua um único número inteiro por uma classe que contém vários números inteiros, a alteração na construção foi limitada a um método. Altere as declarações aritméticas da data real - todas as duas.

A recompensa

  • A nova implementação tinha mais funcionalidade, mas o código do algoritmo era mais curto e claramente mais simples.

Em Corrigindo o comportamento / resultados do código:

  • Mudei a estrutura de dados, não o algoritmo.
  • Nenhuma lógica de controle foi tocada em qualquer lugar do código.
  • Nenhuma API foi alterada.
  • A classe de fábrica da estrutura de dados não foi alterada.
radarbob
fonte
1

Eu gosto de imaginar uma equipe muito inteligente de bibliotecários em uma biblioteca muito bem feita, com um milhão de livros aleatórios e brilhantes, seria uma loucura.

Tudor Watson
fonte
1

Não posso concordar mais com Linus. O foco nos dados ajuda a destilar bastante uma solução simples e flexível para um determinado problema. O próprio Git é um exemplo comprovado - fornecendo tantos recursos suportados nos anos de desenvolvimento, que a estrutura de dados principal permanece praticamente inalterada. Isso é mágico! --2c

mc2
fonte
0

Eu já vi isso em várias áreas.

Pense em análise de negócios ... Digamos que você esteja analisando a melhor maneira de dar suporte ao marketing em uma empresa de produtos de consumo como a Colgate. Se você começar com janelas sofisticadas ou com a tecnologia mais recente, não ajudará a empresa tanto quanto se pensar primeiro nas necessidades de dados da empresa e depois se preocupar com a apresentação posteriormente. O modelo de dados supera o software de apresentação.

Considere fazer uma página da web. É muito melhor pensar no que você deseja mostrar (o HTML) primeiro e se preocupar com o estilo (CSS) e os scripts (escolha sua ferramenta) depois.

Isso não quer dizer que a codificação também não seja importante. Você precisa de habilidades de programação para obter o que precisa no final. É que os dados são a base. Um modelo de dados ruim reflete um modelo de negócios excessivamente complexo ou impensado.

MathAttack
fonte
0

Eu me pego escrevendo novas funções e atualizando as existentes com muito mais frequência do que adicionando novas colunas ou tabelas ao esquema do banco de dados. Provavelmente isso é verdade para todos os sistemas bem projetados. Se você precisar alterar seu esquema sempre que precisar alterar seu código, é um sinal claro de que você é um desenvolvedor muito ruim.

indicador de qualidade do código = [alterações no código] / [alterações no esquema do banco de dados]

"Mostre-me seus fluxogramas e oculte suas tabelas, e continuarei confuso. Mostre-me suas tabelas, e geralmente não precisarei de seus fluxogramas; elas serão óbvias." (Fred Brooks)

Joel Jacobson
fonte
-2

Parece que essa idéia tem várias interpretações nos vários tipos de programação. Isso vale para o desenvolvimento de sistemas e também para o desenvolvimento da empresa. Por exemplo, alguém poderia argumentar que a acentuada mudança de foco em relação ao domínio no design orientado a domínio é muito semelhante ao foco em estruturas e relacionamentos de dados.

eulerfx
fonte
-4

Aqui está minha interpretação: você usa código para criar estruturas de dados, portanto o foco deve estar no último. É como construir uma ponte - você deve criar uma estrutura sólida em vez de uma que pareça atraente. Acontece que estruturas de dados e pontes bem escritas parecem boas como resultado de seus projetos eficientes.

Prumo
fonte