124 pontos por GN⁺ 8 일 전 | 2 comentários | Compartilhar no WhatsApp
  • Uma coleção que reúne em um só lugar 56 princípios e padrões que afetam sistemas de software, equipes e tomada de decisão, cobrindo amplamente desde a operação de times até arquitetura, qualidade, design e decisões
  • Leis relacionadas a equipes, como a Lei de Conway, a Lei de Brooks e o número de Dunbar, mostram que a estrutura organizacional afeta diretamente o design do sistema e a produtividade
  • Na área de arquitetura, organiza restrições e princípios que precisam ser considerados ao projetar sistemas complexos, como a Lei de Hyrum, o teorema CAP e a Lei de Gall
  • As leis relacionadas à qualidade tratam de dívida técnica, da pirâmide de testes, da Lei de Kernighan e das dificuldades reais de manter a qualidade do código e depurar
  • Na área de tomada de decisão, abrange vieses cognitivos e critérios de julgamento nos quais é fácil cair durante o desenvolvimento, como o efeito Dunning-Kruger, a falácia do custo afundado e o princípio de Pareto

Equipes (Teams)

1. Lei de Conway (Conway's Law)

> Organizações projetam sistemas que refletem sua própria estrutura de comunicação

  • A arquitetura de software tende naturalmente a seguir a estrutura de comunicação da organização que a criou
  • Se a equipe estiver dividida em 3 grupos, o sistema também tende a se dividir em 3 grandes módulos
  • Também existe a "estratégia inversa de Conway" (Inverse Conway Maneuver): uma abordagem em que a estrutura da equipe é reorganizada primeiro de acordo com a arquitetura desejada
  • Ao adotar microservices, é eficaz alinhar os limites das equipes com os limites dos serviços

2. Lei de Brooks (Brooks's Law)

> Adicionar pessoas a um projeto de software atrasado o torna ainda mais atrasado

  • Quando novos membros entram, os integrantes atuais da equipe gastam tempo com treinamento e coordenação, o que reduz temporariamente a produtividade geral
  • À medida que o número de membros cresce, os caminhos de comunicação aumentam exponencialmente (com n pessoas, n(n-1)/2)
  • Frederick Brooks formulou isso em seu livro de 1975 The Mythical Man-Month, com base na experiência no projeto IBM OS/360
  • Pode ser explicado quantitativamente pela Lei de Little (L = λ × W): ao adicionar pessoas, o WIP (trabalho em andamento) aumenta, mas o throughput fica estagnado, fazendo o lead time crescer
  • A solução não é adicionar gente, e sim ajustar o escopo ou alterar o cronograma

3. Número de Dunbar (Dunbar's Number)

> O limite cognitivo de relações que uma pessoa consegue manter de forma estável é de cerca de 150 pessoas

  • Valor derivado por Robin Dunbar a partir da correlação entre o tamanho do cérebro de primatas e o tamanho dos grupos sociais
  • A estrutura hierárquica social de Dunbar: ~5 pessoas (relações íntimas), ~15 (colaboradores de confiança), ~50 (relações de trabalho próximas), ~150 (conexões sociais estáveis)
  • Quando uma organização de engenharia ultrapassa 150 pessoas, a comunicação informal chega ao limite e passa a exigir hierarquias e processos formais
  • O "Two-Pizza Team" da Amazon (5~10 pessoas) reflete que, mesmo dentro de 150 pessoas, a colaboração real acontece em unidades menores

4. Efeito Ringelmann (The Ringelmann Effect)

> Quanto maior o grupo, menor a produtividade individual

  • Fenômeno de "preguiça social" (social loafing), no qual a contribuição de cada pessoa diminui à medida que o grupo cresce
  • Também em equipes de software, quando o time aumenta, o senso de responsabilidade individual se dilui e o custo de coordenação cresce
  • Explica por que equipes pequenas geram mais resultado por pessoa

5. Lei de Price (Price's Law)

> Um número de pessoas equivalente à raiz quadrada do total de participantes realiza 50% de todo o trabalho

  • Em uma organização de 100 pessoas, cerca de 10 pessoas respondem por metade de todo o trabalho
  • Quanto maior a organização, maior a dependência de um pequeno grupo de profissionais de alto desempenho
  • Explica por que a produtividade não cresce linearmente quando a equipe é expandida

6. Lei de Putt (Putt's Law)

> Quem entende de tecnologia não gerencia, e quem gerencia não entende de tecnologia

  • Expressa de forma satírica o descompasso entre o papel de gestão e a expertise técnica em organizações técnicas
  • Ao desenhar a estrutura de liderança técnica, é preciso reconhecer essa lacuna e criar mecanismos para compensá-la

7. Princípio de Peter (Peter Principle)

> Em uma organização, todo funcionário tende a ser promovido até seu nível de incompetência

  • Padrão em que uma pessoa competente em um papel é promovida e se torna incompetente na nova função
  • Reflete a realidade de que um excelente desenvolvedor não necessariamente se torna um bom gestor
  • Mostra a necessidade de um sistema de carreira em dupla trilha, separando a trilha IC (Individual Contributor) da trilha de management

8. Bus Factor

> Número mínimo de saídas de membros da equipe que pode colocar um projeto em risco grave

  • Se o Bus Factor é 1, existe um ponto único de falha (Single Point of Failure)
  • É importante aumentar o Bus Factor por meio de compartilhamento de conhecimento, pair programming e documentação
  • Code review e cross-training são formas práticas de melhorar o Bus Factor

9. Princípio Dilbert (Dilbert Principle)

> Empresas tendem a promover funcionários incompetentes para cargos gerenciais a fim de limitar os danos

  • Observação satírica proposta por Scott Adams, uma variação do Princípio de Peter
  • Fenômeno organizacional paradoxal em que cargos de gestão são vistos como posições que causam menos prejuízo às operações

Planejamento (Planning)

10. Otimização prematura / princípio de otimização de Knuth (Premature Optimization)

> A otimização prematura é a raiz de todos os males

  • Apresentado por Donald Knuth em um artigo de 1974: "em cerca de 97% dos casos, pequenas eficiências devem ser ignoradas"
  • Como cerca de 20% do código responde por 80% do tempo de execução, otimizar os 80% restantes é desperdício
  • Ordem correta: primeiro fazer funcionar → depois fazer corretamente → e, se necessário, tornar rápido
  • Como código otimizado aumenta a complexidade, isso deve ser feito após confirmar os gargalos reais por meio de profiling

11. Lei de Parkinson (Parkinson's Law)

> O trabalho se expande até preencher todo o tempo disponível

  • Se o prazo é de 2 semanas, o trabalho cresce por 2 semanas; se é de 4, cresce por 4
  • Explica por que é importante definir milestones curtos e claros em projetos de software
  • O ágil baseado em sprints é uma resposta prática a essa lei

12. Regra 90-90 (The Ninety-Ninety Rule)

> Os primeiros 90% do código consomem 90% do tempo de desenvolvimento, e os 10% restantes consomem outros 90% do tempo

  • Alerta que os 10% finais de um projeto de software (edge cases, polishing, correção de bugs) levam muito mais tempo do que o esperado
  • A expressão "quase pronto" pode, na prática, significar o meio do cronograma total

13. Lei de Hofstadter (Hofstadter's Law)

> Sempre leva mais tempo do que o esperado, mesmo quando se leva em conta a Lei de Hofstadter

  • Lei com estrutura de autorreferência recursiva, que expressa a dificuldade intrínseca de estimar cronogramas de software
  • A realidade em que, mesmo adicionando buffer, o prazo ainda estoura
  • Apresentada por Douglas Hofstadter no livro de 1979 Gödel, Escher, Bach

14. Lei de Goodhart (Goodhart's Law)

> Quando uma métrica se torna alvo, ela deixa de ser uma boa métrica

  • Um caso representativo é quando cobertura de código vira KPI e passa a gerar testes sem sentido
  • Se a produtividade é medida por linhas de código (LOC), acaba-se produzindo código desnecessariamente prolixo
  • É preciso focar não na otimização da métrica, mas no alcance do valor essencial

15. Lei de Gilb (Gilb's Law)

> Quando é necessário quantificar, medir de algum modo é melhor do que não medir

  • Mesmo que uma medição perfeita seja impossível, uma medição aproximada é sempre mais útil do que nenhuma medição
  • Também se aplica a itens difíceis de quantificar, como qualidade de software e satisfação do usuário

Arquitetura (Architecture)

16. Lei de Hyrum (Hyrum's Law)

> Se houver usuários suficientes de uma API, alguém dependerá de todo comportamento observável do sistema

  • Não apenas a especificação oficial da API, mas também comportamentos não oficiais como timing, formato das mensagens de erro e ordem de classificação acabam se tornando objetos de dependência
  • Caso do Microsoft Windows, que manteve comportamentos de versões antigas para garantir compatibilidade com apps de terceiros que dependiam de comportamentos e bugs não documentados
  • Observado por Hyrum Wright, do Google, por volta de 2011-2012, a partir de experiências com mudanças em bibliotecas internas do Google
  • O colega Titus Winters deu o nome de "Lei de Hyrum" (incluída em Software Engineering at Google)
  • O contrato real não é a API oficial, mas todo o comportamento efetivamente observável

17. Lei de Gall (Gall's Law)

> Um sistema complexo que funciona inevitavelmente evoluiu de um sistema simples que funcionava

  • Ao projetar um sistema complexo desde o início, há variáveis desconhecidas demais e ainda não validadas, o que aumenta muito a probabilidade de fracasso
  • Base teórica para a abordagem de MVP (Minimum Viable Product)
  • Exemplo do Facebook, que começou em 2004 como um sistema simples de perfis para estudantes de Harvard e foi se expandindo gradualmente
  • Mesmo em uma transição para microsserviços, é vantajoso começar com um monólito e separar gradualmente
  • Proposta por John Gall no livro Systemantics (1975), um clássico cult publicado depois de ser rejeitado por 30 editoras)

18. Lei das abstrações vazantes (The Law of Leaky Abstractions)

> Toda abstração não trivial vaza em algum grau

  • Um exemplo clássico é o ORM, que esconde SQL, mas quando surgem problemas de performance é inevitável inspecionar as queries geradas
  • O garbage collection de Java/Python também é uma abstração, mas comportamentos internos como pausas de GC afetam o desempenho
  • A lição não é que abstrações sejam ruins, e sim que é preciso se preparar para quando a abstração quebrar
  • Apresentada por Joel Spolsky em um post de blog de 2002, junto com exemplos como TCP e memória virtual
  • Também se conecta, em contexto, à frase de George Box: "Todos os modelos estão errados, mas alguns são úteis"

19. Lei de Tesler / Lei da conservação da complexidade (Tesler's Law)

> Toda aplicação tem uma complexidade inerente que não pode ser removida; ela só pode ser deslocada

  • Pergunta central: quem vai arcar com a complexidade (usuário vs. sistema)
  • O Calendly absorve no sistema a complexidade de coordenar agendas, enquanto threads de e-mail a repassam ao usuário
  • Um bom design desloca a complexidade da experiência do usuário para dentro do sistema
  • Formulada por Larry Tesler nos anos 1980, durante o trabalho no Apple Lisa e em GUIs iniciais

20. Teorema CAP (CAP Theorem)

> Em sistemas distribuídos, só é possível garantir duas entre consistência (C), disponibilidade (A) e tolerância a partição (P)

  • Partições de rede são inevitáveis na prática, então a escolha real é entre consistência vs. disponibilidade
  • Sistemas CP (ex.: MongoDB): em caso de partição, bloqueiam escrita para manter todas as réplicas sincronizadas
  • Sistemas AP (ex.: Cassandra, DNS): continuam respondendo durante a partição, aceitando inconsistências temporárias entre réplicas
  • Proposto por Eric Brewer em 2000, no contexto de serviços web, e formalmente provado por Gilbert & Lynch em 2002

21. Efeito do segundo sistema (Second-System Effect)

> Após um sistema pequeno e bem-sucedido, tende a vir um sistema sucessor inchado e projetado em excesso

  • Padrão em que o sucesso do primeiro sistema dá confiança para despejar todas as ideias no segundo
  • Feature creep e generalização excessiva (over-generalization) são as principais causas
  • Identificado por Frederick Brooks em The Mythical Man-Month

22. Falácias da computação distribuída (Fallacies of Distributed Computing)

> Oito suposições equivocadas comuns entre quem projeta sistemas distribuídos pela primeira vez

  • As 8 falácias: (1) a rede é confiável, (2) a latência é zero, (3) a largura de banda é infinita, (4) a rede é segura, (5) a topologia não muda, (6) há um único administrador, (7) o custo de transporte é zero, (8) a rede é homogênea
  • Projetar com base nessas suposições leva a falhas inesperadas e problemas de desempenho em produção

23. Lei das consequências não intencionais (Law of Unintended Consequences)

> Ao alterar um sistema complexo, é preciso esperar resultados inesperados

  • Ao mudar um componente do sistema, efeitos colaterais podem surgir em lugares imprevisíveis
  • Princípio que reforça a necessidade de chaos engineering e testes abrangentes

24. Lei de Zawinski (Zawinski's Law)

> Todo programa tenta se expandir até conseguir ler e-mail

  • Satiriza o fenômeno de inchaço de funcionalidades (feature bloat), em que softwares bem-sucedidos tentam adicionar cada vez mais recursos
  • Observada por Jamie Zawinski (um dos primeiros desenvolvedores da Netscape)
  • Um alerta sobre a tendência de ferramentas simples tentarem se transformar, com o tempo, em plataformas universais

Qualidade (Quality)

25. Regra do escoteiro (The Boy Scout Rule)

> Deixe o código em um estado melhor do que o encontrou

  • O ponto central não é um grande refactoring, mas sim a melhoria contínua e incremental
  • Corrigir nomes de funções confusos, remover código duplicado, adicionar testes ausentes: praticar pequenas melhorias a cada vez
  • Robert C. Martin (Uncle Bob) a aplicou ao desenvolvimento de software em Clean Code (2008)
  • Princípio entre engenheiros do Google: "If you touch it, you own it" — ao modificar o código, você também assume responsabilidade por sua qualidade
  • Seguir essa regra ajuda a prevenir o efeito da janela quebrada (Broken Windows) e o acúmulo de dívida técnica

26. Lei de Murphy (Murphy's Law)

> Se algo pode dar errado, vai dar errado

  • Base para programação defensiva, tratamento de exceções e design preparado para falhas
  • Em software, é preciso projetar tratamento de erros e fallbacks com a postura de que "todo erro que pode acontecer, vai acontecer"

27. Lei de Postel / princípio da robustez (Postel's Law)

> Seja conservador no que faz e liberal no que aceita dos outros

  • Ao projetar APIs, o princípio é seguir a especificação com rigor na saída, mas aceitar com flexibilidade vários formatos de entrada
  • Jon Postel estabeleceu esse princípio da robustez (Robustness Principle) ao projetar os protocolos TCP/IP
  • Diretriz prática para aumentar a interoperabilidade entre sistemas

28. Teoria das janelas quebradas (Broken Windows Theory)

> Não deixe design ruim, decisões erradas ou código de baixa qualidade sem correção

  • Se uma "janela quebrada" (código ruim) é deixada de lado, ela provoca degradação adicional da qualidade
  • Quando comentários TODO, código morto e warnings não resolvidos se acumulam na base de código, novos trechos também tendem a ser escritos em baixo nível
  • É importante cultivar a prática de corrigir imediatamente mesmo problemas pequenos

29. Dívida técnica (Technical Debt)

> Tudo o que reduz a velocidade do desenvolvimento de software

  • Ward Cunningham usou pela primeira vez a metáfora financeira na OOPSLA de 1992: optar por atalhos no código é pegar tempo emprestado do futuro
  • Principal (custo de correção) + juros (queda contínua de produtividade causada por código bagunçado)
  • Dívida técnica intencional às vezes é racional (timing de lançamento no mercado, prototipagem), mas um plano de pagamento é indispensável
  • Um caso típico é pular testes automatizados: o release dá certo, mas mudanças futuras passam a gerar bugs inesperados
  • Formas de resolver: refactoring, adicionar testes faltantes, melhorar o design

30. Lei de Linus (Linus's Law)

> Com um número suficiente de revisores, todo bug se torna fácil de encontrar

  • Princípio central do desenvolvimento open source: com muitos olhos revisando o código, bugs viram problemas triviais
  • Eric Raymond deu esse nome em The Cathedral and the Bazaar, em referência a Linus Torvalds
  • Reforça a importância da cultura de code review

31. Lei de Kernighan (Kernighan's Law)

> Depurar é duas vezes mais difícil do que escrever o código originalmente

  • Portanto, se você escrever código inteligente demais, provavelmente não será inteligente o bastante para depurá-lo depois
  • Eis por que é preciso escrever código simples e de alta legibilidade
  • Apresentado por Brian Kernighan em The Elements of Programming Style

32. Pirâmide de testes (Testing Pyramid)

> Um projeto deve ter muitos testes unitários rápidos, menos testes de integração e apenas alguns testes de UI

  • Testes unitários (base): rápidos, baratos e os mais numerosos
  • Testes de integração (meio): verificam a interação entre componentes
  • Testes de UI/E2E (topo): devem ser minimizados, pois são lentos e frágeis
  • Modelo de estratégia de testes apresentado por Mike Cohn em Succeeding with Agile

33. Paradoxo do pesticida (Pesticide Paradox)

> Se os mesmos testes forem executados repetidamente, sua eficácia diminui com o tempo

  • Como os bugs que os testes existentes já conseguem encontrar acabam sendo todos capturados, é necessário adicionar continuamente novos casos de teste
  • Revisar e atualizar regularmente o conjunto de testes é essencial

34. Leis da evolução de software de Lehman (Lehman's Laws of Software Evolution)

> Software que reflete o mundo real inevitavelmente precisa evoluir, e essa evolução tem limites previsíveis

  • Software do tipo E (que reflete o mundo real) inevitavelmente precisa de mudanças contínuas para continuar sendo útil
  • A cada mudança, a complexidade aumenta e, se isso não for gerenciado ativamente, a qualidade se deteriora

35. Lei de Sturgeon (Sturgeon's Law)

> 90% de tudo é inútil

  • Proposta por Theodore Sturgeon em resposta a críticas à literatura de ficção científica
  • Também se aplica ao software: entre a maior parte do código, das ferramentas e dos frameworks, apenas uma minoria é realmente excelente
  • É preciso manter um alto padrão de qualidade e focar nos 10% que realmente têm valor

Escala (Scale)

36. Lei de Amdahl (Amdahl's Law)

> O ganho de velocidade obtido com paralelização é limitado pela proporção do trabalho que não pode ser paralelizado

  • Se 5% de um programa for sequencial, por mais processadores que sejam adicionados, o ganho máximo teórico de velocidade será de 20x
  • Reconhecer os limites da paralelização e reduzir os gargalos sequenciais é mais eficaz
  • Proposta por Gene Amdahl em 1967

37. Lei de Gustafson (Gustafson's Law)

> Ao aumentar o tamanho do problema, é possível obter ganhos significativos de velocidade com processamento paralelo

  • Uma perspectiva complementar à Lei de Amdahl: em problemas escaláveis, e não fixos, adicionar processadores é eficaz
  • Em processamento de big data, simulações científicas etc., mais recursos permitem resolver problemas maiores

38. Lei de Metcalfe (Metcalfe's Law)

> O valor de uma rede é proporcional ao quadrado do número de usuários

  • Se há 10 usuários, o valor é 100 unidades; se há 100, sobe para 10.000 unidades
  • Base teórica do efeito de rede em redes sociais, mensageiros, marketplaces etc.
  • Proposta por Robert Metcalfe para explicar o valor da tecnologia Ethernet

Design

39. Princípio DRY (Don't Repeat Yourself)

> Todo conhecimento deve ter uma única representação clara e autoritativa

  • Inclui não apenas duplicação de código, mas também duplicação de conhecimento, lógica e dados
  • A duplicação exige alterações simultâneas em vários pontos, tornando-se fonte de bugs e inconsistências
  • Formalizado por Andy Hunt e Dave Thomas em The Pragmatic Programmer

40. Princípio KISS (Keep It Simple, Stupid)

> O design e os sistemas devem ser o mais simples possível

  • A complexidade aumenta o custo de entendimento, manutenção e depuração
  • Soluções simples costumam ser mais eficazes na maioria dos casos e também têm menor probabilidade de defeitos
  • Deriva de um princípio de design proposto pela Marinha dos EUA na década de 1960

41. Princípios SOLID (SOLID Principles)

> Cinco diretrizes centrais para melhorar o design de software

  • S — Princípio da responsabilidade única (Single Responsibility): uma classe deve mudar por apenas um motivo
  • O — Princípio aberto-fechado (Open-Closed): deve estar aberta para extensão e fechada para modificação
  • L — Princípio da substituição de Liskov: subtipos devem poder substituir seus tipos base
  • I — Princípio da segregação de interfaces: clientes não devem depender de interfaces que não usam
  • D — Princípio da inversão de dependência: módulos de alto nível não devem depender de módulos de baixo nível, mas de abstrações
  • Formalizado por Robert C. Martin, e o acrônimo SOLID foi nomeado por Michael Feathers

42. Lei de Demeter (Law of Demeter)

> Objetos devem interagir apenas com seus amigos diretos e evitar comunicação direta com objetos estranhos

  • É o princípio de evitar chamadas encadeadas como a.getB().getC().doSomething()
  • Reduz o acoplamento e fortalece a encapsulação, diminuindo o alcance do impacto de mudanças
  • Também é chamada de "princípio do menor conhecimento"

43. Princípio da menor surpresa (Principle of Least Astonishment)

> Softwares e interfaces devem funcionar de modo a surpreender o mínimo possível usuários e outros desenvolvedores

  • Funções, APIs e UIs devem ter comportamento previsível em seus nomes e convenções
  • Se uma função delete() na prática apenas arquiva algo, isso causa surpresa → falha de design
  • Comportamentos não intuitivos causam bugs e erros de usuário

44. YAGNI (You Aren't Gonna Need It)

> Não adicione funcionalidades antes de elas serem necessárias

  • Princípio central do Extreme Programming (XP), proposto por Ron Jeffries no fim dos anos 1990
  • Escrever código porque "talvez seja necessário no futuro" gera overengineering e carga de manutenção
  • Para praticar YAGNI, é preciso ter confiança no refactoring (boa cobertura de testes, CI)
  • Se hoje só é necessário exportar JSON, implemente apenas JSON; XML/YAML etc. podem ser adicionados quando houver demanda

Decisões

45. Efeito Dunning-Kruger (Dunning-Kruger Effect)

> Quanto menos se sabe sobre algo, maior tende a ser a confiança

  • Fenômeno em que desenvolvedores iniciantes subestimam a dificuldade de sistemas complexos, enquanto especialistas às vezes são mais humildes em relação ao próprio conhecimento
  • É importante aumentar a precisão da autoconsciência por meio de code review, mentoria e aprendizado contínuo

46. Navalha de Hanlon (Hanlon's Razor)

> Não atribua à malícia aquilo que pode ser suficientemente explicado por estupidez ou descuido

  • Antes de interpretar código ruim ou uma decisão equivocada de um colega como sabotagem intencional, considere primeiro ignorância, erro ou falta de tempo
  • Base da confiança e da comunicação construtiva dentro da equipe

47. Navalha de Occam (Occam's Razor)

> A explicação mais simples costuma ser a mais correta

  • Ao depurar, verifique primeiro a possibilidade mais simples, antes de causas complexas
  • No design de arquitetura, também vale explorar primeiro soluções simples antes de adicionar camadas desnecessárias de abstração

48. Falácia do custo afundado (Sunk Cost Fallacy)

> A tendência de continuar mantendo uma escolha ruim só porque tempo ou energia já foram investidos nela

  • A psicologia de não conseguir abandonar uma funcionalidade em direção errada só porque 6 meses já foram investidos em seu desenvolvimento
  • A decisão correta deve se basear no valor futuro, não no investimento passado

49. O mapa não é o território (The Map Is Not the Territory)

> Uma representação da realidade (modelo) não é igual à própria realidade

  • Diagramas UML, documentos de arquitetura, modelos de dados etc. são apenas aproximações da realidade
  • Não se deve confiar cegamente no modelo; é preciso observar o comportamento real do sistema e atualizar o modelo

50. Viés de confirmação (Confirmation Bias)

> A tendência de preferir informações que apoiem crenças ou ideias já existentes

  • A armadilha de coletar seletivamente apenas informações favoráveis à stack tecnológica ou à decisão de design que você escolheu
  • Buscar ativamente evidências contrárias e aceitar diferentes perspectivas é a chave para uma tomada de decisão equilibrada

51. Hype Cycle e a Lei de Amara (The Hype Cycle & Amara's Law)

Há uma tendência de superestimar os efeitos de curto prazo da tecnologia e subestimar seu impacto de longo prazo

  • Hype Cycle do Gartner: gatilho tecnológico → pico das expectativas infladas → vale da desilusão → rampa de esclarecimento → platô de produtividade
  • Ao adotar novas tecnologias (blockchain, AI etc.), é preciso não se deixar levar pelo superaquecimento de curto prazo e avaliar a utilidade prática de longo prazo

52. Efeito Lindy (The Lindy Effect)

Quanto mais tempo algo foi usado, maior a probabilidade de continuar sendo usado no futuro

  • Tecnologias usadas há décadas, como UNIX, SQL e a linguagem C, têm grande probabilidade de continuar sobrevivendo por muito tempo
  • Base teórica para escolher tecnologias comprovadas em vez de frameworks novos
  • Popularizado por Nassim Nicholas Taleb em Antifragile

53. Pensamento por primeiros princípios (First Principles Thinking)

Uma forma de pensar que decompõe problemas complexos em seus componentes mais básicos e depois os reconstrói a partir disso

  • Remove práticas e suposições existentes e chega a soluções partindo de verdades fundamentais
  • Ficou conhecido pelo caso de Elon Musk aplicando isso à redução de custos de foguetes da SpaceX
  • Ao projetar sistemas complexos, é preciso evitar a mentalidade de "sempre foi feito assim"

54. Pensamento por inversão (Inversion)

Um método de resolver problemas assumindo o resultado oposto e raciocinando de trás para frente

  • Em vez de "como ter sucesso", pensar primeiro em "como fracassar" para identificar fatores de risco
  • Base teórica para a análise de modos de falha (Failure Mode Analysis) e o pre-mortem
  • Modelo mental usado com frequência por Charlie Munger

55. Princípio de Pareto / Regra 80/20 (Pareto Principle)

80% dos problemas surgem de 20% das causas

  • Há uma tendência de que 80% de todos os bugs se concentrem em 20% do código
  • Concentrar recursos nos 20% de maior impacto é uma estratégia eficiente de alocação de recursos
  • Deriva do princípio observado por Vilfredo Pareto na distribuição da posse de terras na Itália

56. Lei de Cunningham (Cunningham's Law)

A melhor maneira de obter a resposta certa na internet não é fazer uma pergunta, mas publicar uma resposta errada

  • As pessoas tendem a participar mais ativamente corrigindo informações erradas do que respondendo perguntas
  • É uma lei que leva o nome de Ward Cunningham (inventor do Wiki), mas na prática foi Steven McGeady quem lhe deu esse nome
  • Um insight aplicável à documentação e ao compartilhamento de conhecimento em comunidades open source

2 comentários

 
choam2426 2 일 전

Quando se faz vibe coding, no começo até parece bom, mas no fim parece que isso volta como karma...

 
GN⁺ 8 일 전
Comentários do Hacker News
  • Eu detesto especialmente a frase "otimização prematura é a raiz de todo mal". Essa frase surgiu no contexto de 1974, então as premissas são diferentes das de hoje. Naquela época, otimização era algo mais próximo de assembly e contagem de ciclos, mas hoje desempenho é, em grande parte, uma questão de escolhas de arquitetura, então precisa ser considerado desde o início. O conselho de usar profiling para encontrar bugs de desempenho acidentais, como um O(n²), ainda continua válido, mas quando o custo das abstrações vira gargalo, é fácil acabar só empilhando cache e paralelismo e criando um sistema mais complexo e mais lento. Hoje, acho que otimização tardia é tão ruim quanto otimização prematura, talvez até pior

    • Acho que essa é uma das frases mais mal interpretadas na programação. Se você ler o texto original de Donald Knuth, a ideia é não gastar energia com melhorias de desempenho desnecessárias sem nem medir antes, exceto nos 10% dos casos em que desempenho é essencial. Mas vejo com frequência gente tratando isso como uma doutrina estranha de "não meça nada"
    • O que eu considero a verdadeira má otimização prematura é quando a pessoa fica obcecada por diferenças mínimas que nem importam. Por exemplo, em Java eu uso bastante ConcurrentHashMap porque depois talvez o código vá para um contexto multithread, e na maioria dos casos a diferença de desempenho não é grande. Mesmo assim, PRs acabam bloqueados e surgem discussões intermináveis porque "HashMap é mais rápido". Em vez disso, faz mais sentido focar nos lugares que realmente mudam a experiência, como 40 chamadas bloqueantes ao PostgreSQL ou requisições web desnecessárias. Dito isso, acho perfeitamente válido fazer otimização cedo no nível de algoritmo
    • Eu gosto de brincar dizendo que, em vez de "otimização prematura", eu só faço otimização madura. Pensar antes no modo de uso, nos padrões de acesso a dados e nos requisitos de desempenho antes de sair empilhando frameworks é uma abordagem bem madura. Na maioria dos casos não precisa chegar à contagem de ciclos, mas decidir cedo se é bulk load ou processamento unitário, se é preciso considerar concorrência ou distribuição, faz bastante diferença. O pessoal do "desempenho a gente vê depois" costuma travar bastante na hora de melhorar isso mais tarde
    • No ano passado, passei 6 meses removendo uma camada de abstração que adicionava 40 ms a cada requisição. O profiling encontrou o hot path, mas não havia solução sem reescrever. O lado do "vamos otimizar depois" normalmente não deixa claro que esse depois pode, na prática, nunca chegar
    • Acho que, com as ferramentas modernas, é relativamente fácil fazer um design escalável. Então eu entendo otimização prematura como lapidar demais algo que já está suficientemente bom, e não como uma licença para escrever código ruim desde o começo
  • Senti falta da Lei de Curly. Uma variável deve ter um único significado e não deve armazenar valores de domínios diferentes dependendo da situação, nem cumprir dois papéis ao mesmo tempo. A metáfora de não virar algo que é "cera para piso e cobertura de sobremesa" cai perfeitamente

    • Dá vontade de brincar que essa metáfora de "cera para piso e cobertura de sobremesa" talvez não seja uma lei tão universal assim. Pela minha experiência trabalhando com limpeza perto de restaurantes, se dissesse que dá barato, provavelmente teria bastante gente disposta a experimentar cera para piso como se fosse cobertura
    • Eu não conhecia esse princípio pelo nome, mas já aprendi isso na prática. Por exemplo, se existe a regra de que y vira 0 quando x não é 0, então, se você quer saber se x é 0, não deve olhar para y como sinal indireto. Pior ainda é reaproveitar y para outro uso só porque estava sobrando
    • Isso me lembrou que Shellac realmente já foi tanto cera para piso quanto aditivo alimentar. Hoje existem substitutos melhores, mas antigamente era usado especialmente em doces, e pelo que sei ainda é usado como adesivo para instrumentos de sopro
    • Eu gostava bastante do absl::StatusOr usado no Google
    • Eu geralmente chamo esse tipo de situação de POSIWID
  • Quando juntam todas essas "leis" de software num lugar só, sinto que há contradições internas demais, e no fim fica fácil escolher a frase que melhor justifica o argumento que a pessoa já queria defender. A parte realmente difícil é saber quando quebrar qual lei, e por quê

    • Acho que o conflito entre a Lei de Postel e a Lei de Hyrum é um caso clássico. Se você aceita entradas de forma liberal, alguém vai acabar dependendo de todo comportamento observável da API, e depois, no momento em que você a torna mais estrita, isso vira quebra de compatibilidade mesmo que não estivesse documentado. Então a conclusão a que cheguei é: ser estrito nos limites internos que eu controlo, e liberal só nos limites externos onde não posso forçar upgrade de clientes. O mais difícil, na prática, costuma ser distinguir essas fronteiras
    • Eu costumo citar DRY como exemplo clássico desse tipo de contradição. Já vi muitas vezes gente evitando duas funções parecidas e, em troca, jogando a complexidade conceitual nas alturas
    • Como SWE há bastante tempo, ainda tiro muito proveito só de KISS e YAGNI. Grande parte da engenharia de software me parece excesso de projeto, e sinceramente acho que este site também é. Em outras áreas da engenharia, custo de material e mão de obra aparecem de forma tão concreta que esse tipo de exagero não se sustenta por muito tempo
    • Também senti isso com os Leadership Principles da Amazon. Em geral são orientações razoáveis, mas nas discussões reais muitas vezes viravam uma disputa para ver quem conseguia transformar algum princípio na arma mais convincente para anexar ao próprio argumento. Também acho que isso não é necessariamente só ruim
    • Em vez de guerras formais entre leis de TI, prefiro alternativas como o CUPID do Dan North. Como conjunto de propriedades para joyful coding, ele me parece mais prático do que SOLID
  • Como lei da engenharia de software versão 2026, eu queria brincar que todos os sites vão ser feitos por vibe coding com Claude Opus. O resultado seria um fundo em tom creme lembrando a Anthropic, uma mistura exagerada de fontes e pesos como se alguém tivesse acabado de descobrir tipografia, uma abundância de interfaces em cartões, e aquele padrão repetido de borda colorida arredondada em apenas um lado do cartão

    • Se a pessoa fez o site por vibe coding, eu provavelmente vou presumir que fez o livro também por vibe coding e vou passar reto. Além disso, fui olhar o histórico dessa pessoa programando e é basicamente cheio de cheat sheets e roadmaps, então isso quase não me passa confiança no conteúdo do livro
    • Também imagino que o domínio certamente vai ser algo no formato título longo literal + .com
  • Acho que a Lei da Iteração de Boyd também deveria entrar. A ideia é que, ao lidar com complexidade, iteração rápida muitas vezes produz resultados melhores do que análise profunda, o que fica ainda mais marcante quando se lembra que Boyd foi o criador do loop OODA

    • Gosto muito dessa lei e queria que mais gente a entendesse. O lado de gestão ou negócios quer planejamento prévio, mas no software não dá para prever todos os problemas desde o começo. Em vez de se prender a uma estrutura rígida desenhada de antemão, acho mais eficaz resolver os problemas refatorando sobre uma arquitetura flexível
    • De modo geral, acho desenvolvimento iterativo melhor do que desenvolvimento excessivamente cauteloso. O exemplo do manche de avião de combate também era muito sutil e muito bom. Isso me fez lembrar de um projeto doloroso da faculdade em que o build levava 10 minutos. Eu precisava ter trocado a implementação real por componentes mock fornecidos, mas descobri isso tarde demais e não consegui terminar antes do prazo. Desde então, sempre procuro primeiro formas de reduzir o tempo de build
    • Acho que, se levarem demais a lei de Boyd ao extremo, isso acaba escorregando para coisas como sprints de 1 semana ou menos
  • Acho que havia um melhor meta-princípio nos comentários apagados sobre este texto. Era algo como: "toda lei da engenharia de software é imediatamente mal interpretada e aplicada sem senso crítico de um jeito que horrorizaria o autor original". Olhando para o comportamento de LLMs sem o contexto principal, isso fica ainda mais compreensível. No fim, há um limite para comprimir décadas de sabedoria e experiência em uma frase de efeito

  • Em vez de fazer por vibe coding um site inteiro de "leis da engenharia de software", quero perguntar que lei foi quebrada ao não simplesmente criar uma página na Wikipedia

    • Também acho meio estranha a sugestão de "criar uma página na Wikipedia". A Wikipedia de 2026 parece, na prática, um lugar onde é difícil criar uma página nova se você não for praticamente um especialista profundo da cultura da Wikipedia. Os veteranos do wiki dizem que qualquer um consegue se seguir só 137 diretrizes, mas na prática existe um cinismo de que é fácil um admin apagar tudo
    • Eu daria a essa lei o nome de Lei do Slop: se dá para fazer de qualquer jeito, no fim vai ser feito de qualquer jeito
    • Como versão 2026 da Lei de Sturgeon, eu resumiria como "99% de tudo é crap ou slop"
  • Acho que esse tipo de conteúdo deveria ser conhecimento básico a ponto de virar requisito de contratação. Parece o tipo de coisa que todo mundo deveria saber

  • Mesmo não sendo uma lei específica de software, costumo ensinar a Cerca de Chesterton primeiro a estagiários e recém-contratados

    • Acho que a Lei das Consequências Não Intencionais que está na lista também descreve o mesmo fenômeno. Ainda assim, pessoalmente eu gosto mais da história da cerca do que dessa formulação
    • Eu trato esse princípio como um dos meus princípios centrais e, em uma frase, o resumiria como pensar e agir
  • Acho que a Lei da Conservação da Complexidade de Tesler já traz uma percepção interessante só na formulação. A ideia de que toda aplicação tem uma complexidade inerente que não pode ser removida, apenas deslocada. Mas quando entra na explicação, parece acabar reduzida ao conselho comum de incomodar menos o usuário, e aí isso perde um pouco do brilho para mim. O usuário inevitavelmente terá de lidar com o nível necessário de complexidade, e reduzi-la à força muitas vezes transforma tudo num brinquedo sem flexibilidade. Por isso, ao refatorar, acho mais útil lembrar que simplificar uma parte pode tornar outra mais complexa