124 puntos por GN⁺ 8 일 전 | 2 comentarios | Compartir por WhatsApp
  • Una colección que reúne en un solo lugar 56 principios y patrones que influyen en los sistemas de software, los equipos y la toma de decisiones, y que abarca un amplio espectro: desde la operación de equipos hasta arquitectura, calidad, diseño y decisiones
  • Las leyes relacionadas con equipos, como la ley de Conway, la ley de Brooks y el número de Dunbar, muestran que la estructura organizacional afecta directamente el diseño del sistema y la productividad
  • En el ámbito de la arquitectura, resume restricciones y principios que deben considerarse al diseñar sistemas complejos, como la ley de Hyrum, el teorema CAP y la ley de Gall
  • Las leyes relacionadas con la calidad abordan la deuda técnica, la pirámide de testing y la ley de Kernighan, entre otras, para tratar el mantenimiento de la calidad del código y las dificultades reales del debugging
  • En el ámbito de la toma de decisiones, abarca sesgos cognitivos y criterios de juicio frecuentes en el desarrollo, como el efecto Dunning-Kruger, la falacia del costo hundido y el principio de Pareto

Equipos (Teams)

1. Ley de Conway (Conway's Law)

Las organizaciones diseñan sistemas que reflejan su propia estructura de comunicación

  • La arquitectura de software tiende naturalmente a seguir la estructura de comunicación de la organización que la creó
  • Si un equipo está dividido en 3 grupos, el sistema también tiende a dividirse en 3 módulos grandes
  • También existe la "estrategia Conway inversa" (Inverse Conway Maneuver): un enfoque que reorganiza primero la estructura del equipo para ajustarla a la arquitectura deseada
  • Al adoptar microservicios, resulta eficaz hacer coincidir los límites del equipo con los límites de los servicios

2. Ley de Brooks (Brooks's Law)

Agregar personal a un proyecto de software retrasado lo retrasa aún más

  • Cuando se suma personal nuevo, los miembros actuales del equipo gastan tiempo en capacitación y coordinación, lo que reduce temporalmente la productividad total
  • A medida que aumenta el número de integrantes, las rutas de comunicación crecen exponencialmente (con n personas, n(n-1)/2)
  • Frederick Brooks la formuló en su libro de 1975 The Mythical Man-Month, basado en su experiencia con el proyecto IBM OS/360
  • Puede explicarse cuantitativamente con la ley de Little (L = λ × W): al agregar personas, el WIP (trabajo en curso) aumenta, pero el throughput se estanca, por lo que el lead time termina creciendo
  • La solución no es sumar gente, sino ajustar el alcance o cambiar el cronograma

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

El límite cognitivo de relaciones que una persona puede mantener de forma estable es de unas 150

  • Robin Dunbar obtuvo esta cifra a partir de la correlación entre el tamaño del cerebro de los primates y el tamaño de sus grupos sociales
  • La estructura jerárquica social de Dunbar: ~5 personas (relaciones íntimas), ~15 (colaboradores de confianza), ~50 (relaciones laborales cercanas), ~150 (conexiones sociales estables)
  • Cuando una organización de ingeniería supera las 150 personas, la comunicación informal llega a su límite y se vuelven necesarios jerarquías y procesos formales
  • El "Two-Pizza Team" de Amazon (5~10 personas) refleja que, incluso dentro de grupos de 150, la colaboración real ocurre en unidades más pequeñas

4. Efecto Ringelmann (The Ringelmann Effect)

A medida que crece el tamaño del grupo, disminuye la productividad individual

  • A mayor cantidad de integrantes en un grupo, menor es la contribución de cada persona; este fenómeno se conoce como "holgazanería social" (social loafing)
  • En los equipos de software, cuando el equipo crece, la responsabilidad individual se diluye y aumenta el costo de coordinación
  • Explica por qué los equipos pequeños generan más resultados por persona

5. Ley de Price (Price's Law)

Un número de personas equivalente a la raíz cuadrada del total de participantes realiza el 50% del trabajo total

  • En una organización de 100 personas, aproximadamente 10 hacen la mitad del trabajo total
  • Cuanto más crece la organización, más se profundiza la dependencia de unos pocos de alto rendimiento
  • Explica por qué la productividad no aumenta linealmente al escalar un equipo

6. Ley de Putt (Putt's Law)

Quienes entienden la tecnología no administran, y quienes administran no entienden la tecnología

  • Una expresión satírica de la brecha entre el rol de gestión y la experiencia técnica en organizaciones tecnológicas
  • Al diseñar una estructura de liderazgo técnico, hay que reconocer esa brecha y prever mecanismos para compensarla

7. Principio de Peter (Peter Principle)

Dentro de una organización, toda persona tiende a ser promovida hasta su nivel de incompetencia

  • Un patrón en el que alguien competente en un rol asciende y se vuelve incompetente en el nuevo rol
  • Refleja la realidad de que un gran desarrollador no necesariamente será un buen manager
  • De ahí la necesidad de un sistema de dual ladder que separe la ruta de IC (Individual Contributor) de la ruta de management

8. Bus Factor

La cantidad mínima de integrantes cuya salida puede poner en grave riesgo un proyecto

  • Si el Bus Factor es 1, existe un Single Point of Failure (punto único de falla)
  • Es importante elevar el Bus Factor mediante compartición de conocimiento, pair programming y documentación
  • El code review y el cross-training son formas prácticas de mejorar el Bus Factor

9. Principio de Dilbert (Dilbert Principle)

Las empresas tienden a promover a puestos de gestión a empleados incompetentes para limitar el daño que causan

  • Una observación satírica propuesta por Scott Adams, variación del principio de Peter
  • Un fenómeno organizacional paradójico en el que los cargos de gestión se consideran los puestos donde menos daño hacen al trabajo práctico

Planificación (Planning)

10. Optimización prematura / principio de optimización de Knuth (Premature Optimization)

La optimización prematura es la raíz de todos los males

  • Donald Knuth la planteó en un artículo de 1974: "en aproximadamente el 97% de los casos, las pequeñas eficiencias deben ignorarse"
  • Como cerca del 20% del código consume el 80% del tiempo de ejecución, optimizar el 80% restante suele ser un desperdicio
  • El orden correcto: primero hacer que funcione → luego hacerlo bien → y solo si hace falta, hacerlo rápido
  • Como el código optimizado aumenta la complejidad, debe realizarse después de identificar los cuellos de botella reales mediante profiling

11. Ley de Parkinson (Parkinson's Law)

El trabajo se expande hasta llenar todo el tiempo disponible

  • Si el deadline es de 2 semanas, el trabajo se extiende 2 semanas; si es de 4, se extiende 4
  • Explica por qué en los proyectos de software es importante fijar milestones cortos y claros
  • El ágil basado en sprints es una forma práctica de responder a esta ley

12. Regla del 90-90 (The Ninety-Ninety Rule)

El primer 90% del código toma el 90% del tiempo de desarrollo, y el 10% restante toma otro 90% del tiempo

  • Advierte que el último 10% de un proyecto de software (edge cases, pulido, corrección de bugs) tarda mucho más de lo esperado
  • La frase "casi terminado" puede significar en realidad que apenas se va por la mitad del cronograma total

13. Ley de Hofstadter (Hofstadter's Law)

Siempre toma más tiempo del esperado, incluso si se toma en cuenta la ley de Hofstadter

  • Una ley con estructura de autorreferencia recursiva que expresa la dificultad inherente de estimar tiempos en software
  • La realidad de que, incluso agregando buffer, el cronograma sigue excediéndose
  • Douglas Hofstadter la presentó en su libro de 1979 Gödel, Escher, Bach

14. Ley de Goodhart (Goodhart's Law)

Cuando una métrica se convierte en objetivo, deja de ser una buena métrica

  • Un ejemplo típico es cuando el code coverage se convierte en KPI y termina generando tests sin sentido
  • Si se mide la productividad por líneas de código (LOC), se produce código innecesariamente verboso
  • Hay que enfocarse no en optimizar la métrica, sino en lograr el valor esencial

15. Ley de Gilb (Gilb's Law)

Cuando algo necesita cuantificarse, medirlo de alguna manera es mejor que no medirlo en absoluto

  • Aunque una medición perfecta sea imposible, una medición aproximada siempre es más útil que no medir
  • También aplica a elementos difíciles de cuantificar, como la calidad del software o la satisfacción del usuario

Arquitectura (Architecture)

16. Ley de Hyrum (Hyrum's Law)

Si hay suficientes usuarios de una API, alguien dependerá de cada comportamiento observable del sistema

  • No solo la especificación oficial de la API, sino también comportamientos no oficiales como timing, formato de mensajes de error y orden de clasificación, se vuelven objeto de dependencia
  • Caso en el que Microsoft Windows mantuvo comportamientos de versiones antiguas para conservar la compatibilidad con apps de terceros que dependían de comportamientos no documentados y bugs
  • Observado por Hyrum Wright de Google a partir de su experiencia modificando bibliotecas internas de Google alrededor de 2011-2012
  • Su colega Titus Winters le dio el nombre de "Ley de Hyrum" (Software Engineering at Google)
  • El contrato real no es la API oficial, sino el conjunto completo del comportamiento efectivamente observado

17. Ley de Gall (Gall's Law)

> Un sistema complejo que funciona necesariamente evolucionó a partir de un sistema simple que funcionaba

  • Si se diseña un sistema complejo desde el inicio, hay demasiadas variables desconocidas sin validar y la probabilidad de fracaso es alta
  • Base teórica del enfoque MVP (Minimum Viable Product)
  • Caso de Facebook, que comenzó en 2004 como un sistema simple de perfiles para estudiantes de Harvard y se expandió gradualmente
  • Incluso al migrar a microservicios, conviene empezar con un monolito y separarlo de forma gradual
  • Propuesta por John Gall en su libro de 1975 Systemantics (un clásico de culto publicado tras el rechazo de 30 editoriales)

18. Ley de las abstracciones con fugas (The Law of Leaky Abstractions)

> Toda abstracción no trivial (non-trivial) presenta fugas en cierto grado

  • Un caso representativo es cuando un ORM oculta SQL, pero al surgir problemas de rendimiento al final hay que revisar las consultas que genera
  • La recolección de basura de Java/Python también es una abstracción, pero comportamientos internos como las pausas del GC afectan el rendimiento
  • La lección no es que la abstracción sea mala, sino que hay que prepararse para cuando la abstracción se rompa
  • Joel Spolsky la presentó en una entrada de blog de 2002 junto con ejemplos como TCP y memoria virtual
  • También se conecta en contexto con la frase de George Box: "Todos los modelos están equivocados, pero algunos son útiles"

19. Ley de Tesler / ley de conservación de la complejidad (Tesler's Law)

> Toda aplicación tiene una complejidad inherente que no puede eliminarse; solo puede desplazarse, no desaparecer

  • Pregunta clave: ¿quién va a cargar con la complejidad? (usuario vs. sistema)
  • Calendly absorbe en el sistema la complejidad de coordinar horarios, mientras que los hilos de correo se la trasladan al usuario
  • Un buen diseño mueve la complejidad de la experiencia del usuario al interior del sistema
  • Larry Tesler la formuló en la década de 1980 mientras trabajaba en Apple Lisa y las primeras GUI

20. Teorema CAP (CAP Theorem)

> En sistemas distribuidos, solo es posible garantizar dos de tres: consistencia (C), disponibilidad (A) y tolerancia a particiones (P)

  • Como las particiones de red son inevitables en la práctica, la elección real es consistencia vs. disponibilidad
  • Sistemas CP (ej.: MongoDB): cuando ocurre una partición, bloquean las escrituras para mantener sincronizadas todas las réplicas
  • Sistemas AP (ej.: Cassandra, DNS): siguen respondiendo solicitudes durante la partición y permiten inconsistencias temporales entre réplicas
  • Propuesto por Eric Brewer en 2000 en el contexto de servicios web, y demostrado formalmente por Gilbert & Lynch en 2002

21. Efecto del segundo sistema (Second-System Effect)

> Después de un sistema pequeño y exitoso, suele venir un sistema sucesor sobrediseñado y excesivamente grande

  • Patrón en el que, tras ganar confianza con el éxito del primer sistema, se vuelcan todas las ideas en el segundo
  • Las causas principales son el exceso de funciones (feature creep) y la generalización excesiva (over-generalization)
  • Identificado por Frederick Brooks en The Mythical Man-Month

22. Falacias de la computación distribuida (Fallacies of Distributed Computing)

> Ocho suposiciones erróneas comunes de quienes diseñan sistemas distribuidos por primera vez

  • Las 8 falacias: (1) la red es confiable, (2) la latencia es cero, (3) el ancho de banda es infinito, (4) la red es segura, (5) la topología no cambia, (6) hay un solo administrador, (7) el costo de transporte es cero, (8) la red es homogénea
  • Si se diseña con base en estas suposiciones, en producción aparecen fallas inesperadas y problemas de rendimiento

23. Ley de las consecuencias no intencionadas (Law of Unintended Consequences)

> Cuando se modifica un sistema complejo, hay que esperar resultados imprevistos

  • Si se cambia un componente del sistema, pueden aparecer efectos secundarios en lugares no previstos
  • Principio que respalda la necesidad de chaos engineering y pruebas exhaustivas

24. Ley de Zawinski (Zawinski's Law)

> Todo programa intenta expandirse hasta poder leer correo

  • Satiriza el fenómeno de inflación de funciones (feature bloat), por el que el software exitoso intenta agregar cada vez más funcionalidades
  • Observado por Jamie Zawinski (desarrollador de los primeros años de Netscape)
  • Advertencia sobre la tendencia de las herramientas simples a querer convertirse, con el tiempo, en plataformas para todo

Calidad (Quality)

25. Regla de los Boy Scouts (The Boy Scout Rule)

> Hay que dejar el código en mejor estado del que se encontró

  • La clave no es un gran refactoring, sino una mejora continua y gradual
  • Practicar pequeñas mejoras en cada ocasión, como corregir nombres de funciones confusos, eliminar código duplicado o agregar pruebas faltantes
  • Robert C. Martin (Uncle Bob) la aplicó al desarrollo de software en Clean Code (2008)
  • Principio de los ingenieros de Google: "If you touch it, you own it" — si modificas el código, también asumes la responsabilidad por su calidad
  • Aplicar esta regla ayuda a prevenir el efecto de las ventanas rotas (Broken Windows) y a evitar la acumulación de deuda técnica

26. Ley de Murphy (Murphy's Law)

> Todo lo que pueda salir mal, saldrá mal

  • Base de la programación defensiva, el manejo de excepciones y el diseño preparado para fallas
  • En software, hay que diseñar el manejo de errores y los fallbacks con la actitud de que "todo error que pueda ocurrir, ocurrirá"

27. Ley de Postel / principio de robustez (Postel's Law)

> Sé conservador en lo que haces y generoso en lo que aceptas de otros

  • En diseño de APIs, el principio indica que la salida debe cumplir estrictamente la especificación, mientras que la entrada debe aceptar con flexibilidad diversos formatos
  • Principio de robustez (Robustness Principle) establecido por Jon Postel al diseñar los protocolos TCP/IP
  • Guía práctica para aumentar la interoperabilidad entre sistemas

28. Teoría de las ventanas rotas (Broken Windows Theory)

> No dejes sin atender un mal diseño, decisiones equivocadas o código de baja calidad

  • Si se deja sin corregir una "ventana rota" (mal código), eso provoca un deterioro adicional de la calidad
  • Cuando se acumulan comentarios TODO, código muerto y advertencias sin resolver en la base de código, el código nuevo también tiende a escribirse con menor calidad
  • Es importante una cultura de corregir incluso los problemas pequeños en cuanto se detectan

29. Deuda técnica (Technical Debt)

> Todo elemento que reduce la velocidad del desarrollo de software

  • Ward Cunningham la usó por primera vez como metáfora financiera en OOPSLA 1992: tomar atajos en el código es pedir tiempo prestado al futuro
  • Principal (costo de corrección) + interés (pérdida continua de productividad causada por código desordenado)
  • La deuda técnica intencional a veces es razonable (timing de salida al mercado, prototipado), pero requiere un plan de pago
  • Omitir pruebas automatizadas es un caso representativo: el release sale bien, pero luego aparecen bugs inesperados con cada cambio
  • Cómo resolverla: refactoring, agregar pruebas faltantes, mejorar el diseño

30. Ley de Linus (Linus's Law)

> Con una cantidad suficiente de revisores, todos los bugs son fáciles de encontrar

  • Principio central del desarrollo open source: muchos ojos revisando el código hacen que los bugs se vuelvan problemas menores
  • Eric Raymond le dio el nombre a partir de Linus Torvalds en The Cathedral and the Bazaar
  • Respalda la importancia de la cultura de code review

31. Ley de Kernighan (Kernighan's Law)

> Debuggear es dos veces más difícil que escribir el código en primer lugar

  • Por lo tanto, si escribes código lo más ingeniosamente posible, no serás lo suficientemente ingenioso al depurarlo
  • Razón por la que hay que escribir código simple y fácil de leer
  • Propuesto por Brian Kernighan en The Elements of Programming Style

32. Pirámide de testing (Testing Pyramid)

> Un proyecto debe tener muchas pruebas unitarias rápidas, pocas pruebas de integración y solo unas cuantas pruebas de UI

  • Pruebas unitarias (base): rápidas, de bajo costo y las más numerosas
  • Pruebas de integración (medio): validan la interacción entre componentes
  • Pruebas de UI/E2E (cima): como son lentas y frágiles, deben minimizarse
  • Modelo de estrategia de pruebas presentado por Mike Cohn en Succeeding with Agile

33. Paradoja del pesticida (Pesticide Paradox)

> Si se ejecutan repetidamente las mismas pruebas, su efectividad disminuye con el tiempo

  • Como las pruebas existentes ya detectaron todos los bugs que podían encontrar, hay que seguir agregando nuevos casos de prueba
  • Es indispensable revisar y actualizar regularmente el conjunto de pruebas

34. Leyes de Lehman sobre la evolución del software (Lehman's Laws of Software Evolution)

> El software que refleja el mundo real necesariamente debe evolucionar, y esa evolución tiene límites predecibles

  • El software de tipo E (que refleja el mundo real) inevitablemente debe cambiar de forma continua para seguir siendo útil
  • Con cada cambio, la complejidad aumenta y, si no se gestiona activamente, la calidad se deteriora

35. Ley de Sturgeon (Sturgeon's Law)

> El 90% de todo es basura

  • Propuesta por Theodore Sturgeon en respuesta a críticas sobre la literatura de ciencia ficción
  • También aplica al software: de la mayoría del código, herramientas y frameworks, solo una minoría es realmente excelente
  • Hace falta mantener un estándar alto de calidad y enfocarse en el 10% que sí aporta valor

Escala (Scale)

36. Ley de Amdahl (Amdahl's Law)

> La mejora de velocidad obtenida por paralelización está limitada por la proporción de trabajo que no puede paralelizarse

  • Si el 5% de un programa es secuencial, por más procesadores que se añadan, la mejora teórica máxima será de 20 veces
  • Reconocer los límites de la paralelización y reducir los cuellos de botella secuenciales suele ser más efectivo
  • Propuesta por Gene Amdahl en 1967

37. Ley de Gustafson (Gustafson's Law)

> Al aumentar el tamaño del problema, se puede lograr una mejora significativa de velocidad con procesamiento paralelo

  • Perspectiva complementaria a la ley de Amdahl: en problemas escalables, y no fijos, añadir procesadores sí resulta efectivo
  • En procesamiento de big data, simulaciones científicas, etc., más recursos permiten resolver problemas más grandes

38. Ley de Metcalfe (Metcalfe's Law)

> El valor de una red es proporcional al cuadrado del número de usuarios

  • Si hay 10 usuarios, el valor es 100 unidades; si hay 100, sube a 10,000 unidades
  • Base teórica del efecto de red en redes sociales, mensajería, marketplaces, etc.
  • Propuesta por Robert Metcalfe para explicar el valor de la tecnología Ethernet

Diseño (Design)

39. Principio DRY (Don't Repeat Yourself)

> Todo conocimiento debe tener una única representación, clara y autoritativa

  • Incluye no solo la duplicación de código, sino también la duplicación de conocimiento, lógica y datos
  • La duplicación obliga a modificar varios lugares al mismo tiempo cuando hay cambios, y por eso causa bugs e inconsistencias
  • Formalizado por Andy Hunt y Dave Thomas en The Pragmatic Programmer

40. Principio KISS (Keep It Simple, Stupid)

> El diseño y los sistemas deben ser lo más simples posible

  • La complejidad aumenta el costo de comprensión, mantenimiento y depuración
  • Una solución simple suele ser más efectiva en la mayoría de los casos y también menos propensa a fallas
  • Deriva de un principio de diseño planteado por la Marina de EE. UU. en la década de 1960

41. Principios SOLID (SOLID Principles)

> Cinco lineamientos clave para mejorar el diseño de software

  • S — Principio de responsabilidad única (Single Responsibility): una clase debe cambiar por una sola razón
  • O — Principio abierto/cerrado (Open-Closed): debe estar abierta a extensión y cerrada a modificación
  • L — Principio de sustitución de Liskov: los subtipos deben poder sustituir a los tipos base
  • I — Principio de segregación de interfaces: un cliente no debe depender de interfaces que no usa
  • D — Principio de inversión de dependencias: los módulos de alto nivel no deben depender de módulos de bajo nivel, sino de abstracciones
  • Robert C. Martin los formalizó y Michael Feathers acuñó el acrónimo SOLID

42. Ley de Demeter (Law of Demeter)

> Un objeto debe interactuar solo con sus amigos directos y evitar comunicarse directamente con objetos desconocidos

  • Principio que indica que deben evitarse llamadas encadenadas como a.getB().getC().doSomething()
  • Reduce el acoplamiento y refuerza la encapsulación, disminuyendo el alcance del impacto de los cambios
  • También se conoce como el "principio del menor conocimiento"

43. Principio de la mínima sorpresa (Principle of Least Astonishment)

> El software y las interfaces deben comportarse de la manera que menos sorprenda a usuarios y otros desarrolladores

  • Las funciones, API y UI deben tener un comportamiento predecible en sus nombres y convenciones
  • Si una función delete() en realidad solo archiva, genera sorpresa → defecto de diseño
  • Los comportamientos poco intuitivos provocan bugs y errores de usuario

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

> No agregues funcionalidades hasta que realmente sean necesarias

  • Principio central de Extreme Programming (XP), propuesto por Ron Jeffries a finales de los años 90
  • Escribir código "por si acaso hace falta en el futuro" genera sobrediseño y carga de mantenimiento
  • Para aplicar YAGNI hace falta confianza en el refactoring (buena cobertura de pruebas, CI)
  • Si hoy solo se necesita exportar JSON, implementa solo JSON; XML/YAML, etc., se agregan cuando se pidan

Toma de decisiones (Decisions)

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

> Cuanto menos sabes sobre algo, más confianza tiendes a tener

  • Fenómeno por el que un desarrollador principiante subestima la dificultad de un sistema complejo, mientras que un experto a menudo es más humilde respecto a su propio conocimiento
  • Es importante mejorar la precisión de la autopercepción mediante code review, mentoría y aprendizaje continuo

46. Navaja de Hanlon (Hanlon's Razor)

> No atribuyas a la malicia lo que puede explicarse suficientemente por estupidez o descuido

  • Antes de interpretar el mal código o una mala decisión de un colega como sabotaje intencional, conviene considerar primero la ignorancia, los errores o la falta de tiempo
  • Base de la confianza y de una comunicación constructiva dentro del equipo

47. Navaja de Occam (Occam's Razor)

> La explicación más simple suele ser la correcta

  • Al depurar, conviene revisar primero la posibilidad más simple antes que causas complejas
  • También en diseño de arquitectura, antes de añadir capas innecesarias de abstracción, es mejor explorar primero una solución simple

48. Falacia del costo hundido (Sunk Cost Fallacy)

> Fenómeno por el que se mantiene una decisión perjudicial solo porque ya se invirtió tiempo o energía en ella

  • La idea de no poder descartar una funcionalidad desarrollada durante 6 meses aunque vaya en la dirección equivocada, solo por el tiempo invertido
  • Las decisiones correctas deben basarse en el valor futuro, no en la inversión pasada

49. El mapa no es el territorio (The Map Is Not the Territory)

> Una representación de la realidad (modelo) no es lo mismo que la realidad misma

  • Los diagramas UML, la documentación de arquitectura, los modelos de datos, etc., son solo aproximaciones de la realidad
  • No hay que confiar ciegamente en el modelo; hay que observar cómo se comporta el sistema real y actualizar el modelo en consecuencia

50. Sesgo de confirmación (Confirmation Bias)

> Tendencia a preferir información que respalda creencias o ideas previas

  • Trampa de recopilar selectivamente solo información favorable al stack tecnológico o a la decisión de diseño que uno eligió
  • Buscar activamente evidencia en contra y aceptar perspectivas diversas es clave para una toma de decisiones equilibrada

51. Hype Cycle y la ley de Amara (The Hype Cycle & Amara's Law)

Existe una tendencia a sobreestimar los efectos de corto plazo de una tecnología y subestimar su impacto a largo plazo

  • El Hype Cycle de Gartner: disparador tecnológico → pico de expectativas sobredimensionadas → valle de la desilusión → pendiente de la iluminación → meseta de productividad
  • Al adoptar nuevas tecnologías (blockchain, IA, etc.), no hay que dejarse arrastrar por el sobrecalentamiento de corto plazo, sino evaluar su utilidad práctica a largo plazo

52. Efecto Lindy (The Lindy Effect)

Cuanto más tiempo se ha usado algo, más probable es que siga usándose en el futuro

  • Tecnologías usadas durante décadas como UNIX, SQL y el lenguaje C tienen altas probabilidades de seguir vigentes por mucho tiempo
  • Sirve como fundamento teórico al elegir tecnologías comprobadas en lugar de frameworks nuevos
  • Nassim Nicholas Taleb lo popularizó en Antifragile

53. Pensamiento de primeros principios (First Principles Thinking)

Una forma de pensar que descompone un problema complejo en sus componentes más básicos y luego lo reconstruye a partir de ellos

  • Se eliminan las prácticas y suposiciones existentes, y se parte de verdades fundamentales para derivar una solución
  • Es famoso el caso de Elon Musk aplicándolo para reducir costos de cohetes en SpaceX
  • Al diseñar sistemas complejos, conviene desconfiar de la idea de “siempre se ha hecho así”

54. Pensamiento por inversión (Inversion)

Método para resolver problemas suponiendo el resultado opuesto y razonando en sentido inverso

  • En vez de pensar “¿cómo tener éxito?”, primero pensar “¿cómo fracasar?” para identificar factores de riesgo
  • Base teórica del análisis de modos de falla (Failure Mode Analysis) y del pre-mortem
  • Un modelo mental que Charlie Munger usa con frecuencia

55. Principio de Pareto / regla 80/20 (Pareto Principle)

El 80% de los problemas proviene del 20% de las causas

  • Existe una tendencia a que el 80% de los bugs se concentre en el 20% del código
  • Concentrar recursos en el 20% con mayor impacto es una estrategia eficiente de asignación de recursos
  • Se origina en un principio observado por Vilfredo Pareto en la distribución de la propiedad de la tierra en Italia

56. Ley de Cunningham (Cunningham's Law)

La mejor manera de obtener una respuesta correcta en internet no es hacer una pregunta, sino publicar una respuesta incorrecta

  • La gente participa más activamente en corregir información errónea que en responder preguntas
  • Lleva el nombre de Ward Cunningham (inventor de la wiki), pero en realidad Steven McGeady fue quien le dio ese nombre
  • Una idea útil que puede aplicarse a la documentación y al intercambio de conocimiento en comunidades open source

2 comentarios

 
choam2426 3 일 전

Cuando haces vibe coding, en el momento está bien, pero al final parece que termina regresando como karma...

 
GN⁺ 8 일 전
Opiniones de Hacker News
  • Me molesta especialmente la frase de que la "optimización prematura es la raíz de todos los males". Esa frase salió en el contexto de 1974 y parte de supuestos distintos a los de hoy. En ese entonces optimizar era algo más cercano a ensamblador y contar ciclos, pero hoy el rendimiento es sobre todo una cuestión de elección de arquitectura, así que hay que pensarlo desde el inicio. El consejo de usar profiling para detectar bugs de rendimiento accidentales como un O(n²) sigue siendo válido, pero cuando el costo de las abstracciones ya se volvió el cuello de botella, es fácil terminar agregando caché y paralelismo encima y acabar con un sistema más complejo y más lento. Hoy veo la optimización tardía como algo igual de malo que la optimización prematura, o quizás peor

    • Creo que esta es una de las frases más malinterpretadas en programación. Si lees el texto original de Donald Knuth, la idea es no gastar esfuerzo en mejoras de rendimiento innecesarias sin medir antes, salvo en ese 10% de casos donde el rendimiento sí es clave. Pero muy seguido la gente lo toma como una doctrina rara de "no midas nada"
    • Para mí la mala optimización prematura de verdad es obsesionarse con diferencias mínimas que ni importan. Por ejemplo, en Java muchas veces usamos ConcurrentHashMap porque después tal vez terminemos en un contexto multihilo, y en la mayoría de los casos la diferencia de rendimiento no es grande. Pero luego un PR se bloquea porque "HashMap es más rápido" y se arma una discusión interminable. Mejor enfocarse en cosas que sí cambian lo que siente el usuario, como 40 llamadas bloqueantes a PostgreSQL o requests web innecesarias. Dicho eso, sí me parece totalmente razonable optimizar temprano a nivel de algoritmos
    • Yo bromeo diciendo que en vez de "optimización prematura" solo hago optimización madura. Pensar primero en cómo se va a usar algo, en los patrones de acceso a datos y en los requisitos de rendimiento antes de apilar frameworks encima, me parece un enfoque muy maduro. La mayoría no necesita llegar a contar ciclos, pero decidir desde temprano si habrá bulk load o procesamiento individual, o si hay que considerar concurrencia o distribución, sí hace diferencia. El bando que dice que el rendimiento se puede pensar después suele atorarse mucho cuando llega el momento de mejorarlo
    • El año pasado me pasé 6 meses quitando una capa de abstracción que le agregaba 40 ms a cada request. Encontré el hot path con profiling, pero no se podía resolver sin reescribirlo. Los que dicen "ya optimizamos después" no suelen decir que ese después en la práctica puede no llegar nunca
    • Creo que con herramientas modernas es relativamente fácil hacer diseños escalables. Por eso entiendo que la optimización prematura es ponerse a pulir de más algo que ya está suficientemente bien, no que esté bien escribir código desastroso desde el principio
  • Me da pena que falte Curly's Law. Una variable debería tener un solo significado, y no guardar valores de dominios distintos según el contexto ni cumplir dos funciones al mismo tiempo. La analogía de no ser "cera para pisos y topping de postre" le queda perfecta

    • Quisiera bromear con que esa analogía de "cera para pisos y topping de postre" tal vez no sea una ley tan universal. Habiendo trabajado limpiando cerca de restaurantes, me da la impresión de que no faltaría quien intentara comerse la cera para pisos como si fuera topping si le prometieran que te pone borracho
    • No conocía este principio por nombre, pero sí lo aprendí en carne propia. Por ejemplo, si existe una regla donde cuando x no es 0 entonces y pasa a 0, no deberías mirar y como señal indirecta para saber si x es 0. Peor todavía, no deberías reciclar y para otro propósito solo porque "queda libre"
    • Esto me hizo pensar en que Shellac de verdad llegó a ser tanto cera para pisos como aditivo alimentario. Hoy hay sustitutos mejores, pero antes se usaba especialmente en dulces, y según entiendo todavía se usa como adhesivo para instrumentos de viento
    • A mí me gustaba bastante absl::StatusOr que usaban en Google
    • Yo a esta situación normalmente la llamo POSIWID
  • Siento que cuando juntas todas estas "leyes" del software, hay tanta contradicción interna entre ellas que al final se vuelve muy fácil escoger la frase que mejor justifique lo que ya querías defender. Lo difícil de verdad es saber cuándo romper una ley, y por qué hacerlo

    • Creo que el choque entre Postel's Law y Hyrum's Law es el ejemplo más claro. Si aceptas entradas de forma tolerante, alguien va a terminar dependiendo de cualquier comportamiento observable del API, y cuando después lo vuelves estricto, aunque nunca haya estado documentado, igual rompes compatibilidad. Así que mi conclusión es: ser estricto en las fronteras internas que controlo, y solo ser tolerante en fronteras externas donde no puedo forzar a los clientes a actualizar. Pero en la práctica, distinguir bien esa frontera es lo más difícil
    • Suelo poner DRY como ejemplo clásico de este tipo de contradicción. He visto demasiadas veces que, por no querer tener dos funciones parecidas, terminan inflando la complejidad conceptual hasta el cielo
    • Como SWE con bastantes años encima, sigo sacándole muchísimo provecho a KISS y YAGNI. Gran parte de la ingeniería de software me parece sobrediseño, y honestamente este sitio también. En otras ramas de la ingeniería los costos de materiales y mano de obra son visibles, así que ese tipo de exceso no aguanta mucho tiempo
    • También sentía algo parecido con los Leadership Principles de Amazon. En general son lineamientos razonables, pero en discusiones reales muchas veces terminaban siendo una competencia por ver qué principio se podía usar como arma de la forma más convincente para respaldar tu postura. Tampoco creo que eso sea necesariamente malo del todo
    • Prefiero alternativas como CUPID de Dan North antes que las guerras entre leyes formales de TI. Como atributos para un coding alegre, me resulta más práctico que SOLID
  • Como ley de ingeniería de software edición 2026, me gustaría bromear con que todos los sitios web van a estar hechos con vibe coding usando Claude Opus. El resultado va a ser un fondo en tono crema que recuerde a Anthropic, una mezcla exagerada de fuentes y grosores como si alguien que apenas empieza en diseño acabara de descubrir la tipografía, y una sobreabundancia de card UI con patrones repetidos como bordes redondeados de color en un solo lado de la tarjeta

    • Yo vería que quien hizo ese sitio con vibe coding probablemente también vibe codeó el libro y mejor lo paso de largo de inmediato. Además, buscando el historial de esta persona, casi todo son cheatsheets y roadmaps, así que el contenido del libro tampoco me inspira mucha confianza
    • También apostaría a que el dominio va a ser claramente eltítulolargotalcual.com
  • También creo que debería estar Boyd's Law of Iteration. La idea es que al lidiar con complejidad, la iteración rápida muchas veces da mejores resultados que el análisis profundo, y sabiendo además que Boyd fue quien creó el OODA loop, suena todavía más potente

    • Esta ley me encanta y ojalá más gente la entendiera. En management o negocio quieren planeación por adelantado, pero en software no puedes prever todos los problemas desde el inicio. Me parece más efectivo resolverlos sobre una arquitectura flexible mientras refactorizas, en vez de diseñar desde el principio una estructura rígida que luego te encierra
    • En general me parece mejor el desarrollo iterativo que un desarrollo excesivamente cauteloso. El caso del control de aviones de combate era un ejemplo muy fino y muy bueno. Esta historia me recordó un proyecto doloroso en la universidad donde los builds tardaban 10 minutos. Había que reemplazar la implementación real por unos mock components provistos, pero me di cuenta demasiado tarde y no logré terminar antes de la fecha límite. Desde entonces siempre busco primero cómo reducir el tiempo de build
    • Siento que si empujas demasiado al extremo la ley de Boyd, terminas en cosas como sprints de 1 semana o menos
  • Creo que entre los comentarios borrados había una mejor meta-ley para este texto. Decía algo como: "todas las leyes de ingeniería de software se malinterpretan de inmediato y se aplican sin crítica de formas que horrorizarían a su autor original". Viendo cómo se comportan los LLM a los que les falta el contexto clave, se entiende todavía mejor por qué pasa eso. Al final, hay un límite para comprimir décadas de sabiduría y experiencia en una sola frase memorable

  • Si ya iban a hacer vibe coding de un sitio entero de "leyes de ingeniería de software", me gustaría preguntar qué ley violaron al no hacer simplemente una página en Wikipedia

    • La sugerencia de "haz una página en Wikipedia" también me suena rara. La Wikipedia de 2026 se siente como un lugar donde en la práctica es difícil crear páginas nuevas si no eres un experto profundo en la cultura de Wikipedia. Los veteranos de wiki dicen que cualquiera puede hacerlo si solo sigue 137 lineamientos, pero en la realidad hay mucho cinismo con que es fácil que un admin te la borre
    • A esa ley yo la llamaría Slop's Law: si se puede hacer de cualquier manera, al final se hará de cualquier manera
    • Me gustaría resumir la Sturgeon's Law versión 2026 como "el 99% de todo es crap o slop"
  • Ojalá este tipo de cosas fuera cultura general básica al nivel de un requisito de contratación. Se siente como algo que todo el mundo debería conocer

  • Aunque no sea una ley exclusiva del software, yo suelo enseñar Chesterton's Fence primero que nada a interns y juniors

    • Creo que la Law of Unintended Consequences que aparece en la lista describe el mismo fenómeno. Aun así, personalmente me gusta más la historia de la cerca
    • Este principio es uno de mis principios centrales, y si tuviera que resumirlo en una frase sería pensar y actuar
  • Siento que la ley de conservación de la complejidad de Tesler ya da una intuición potente solo con la frase. Dice que toda aplicación tiene una complejidad inherente que no se puede eliminar, solo mover. Pero cuando entras a la explicación, al final parece reducirse al consejo bastante común de molestar menos al usuario. El usuario igual termina cargando con el nivel de complejidad necesario, y si lo reduces sin criterio, es fácil terminar con un juguete sin flexibilidad. Por eso me parece más útil recordar, al refactorizar, que si simplificas una parte, otra puede volverse más compleja