En mi experiencia, los errores que tardan mucho en encontrar son más comunes que los que tardan mucho en solucionarse.
Un ejemplo: pasé unos años trabajando como programador en videojuegos, específicamente en código de cámara. Cada cuadro, la cámara actualiza la matriz que se utiliza para dibujar * todo * dentro del mundo de los juegos en 3D, y si alguna vez está muy mal, el juego se ha bloqueado efectivamente ya que no se puede ver nada en la pantalla. Con un juego en el que estaba trabajando, comencé a recibir informes de bloqueos ocasionales como este.
El síntoma era Inf o NaN apareciendo en la matriz de la cámara (ya no recuerdo cuál). Miré el código muy de cerca y no pude averiguar de dónde venía el valor malo. Agregué un código de verificación que, en cada cuadro, verificó la matriz de la cámara en busca de valores incorrectos antes de devolverlo al código del juego. Este código de verificación se ejecutó durante semanas, con decenas de personas ejecutando el código todo el tiempo, antes de desconectar el cheque. Afortunadamente, esto le sucedió a otro programador, y el juego se detuvo * en un depurador * donde pude ver argumentos y variables en la pila. Las funciones de la biblioteca culpable: sin () o cos () estaban devolviendo el valor incorrecto.
- ¿Cuáles son los mejores campos de entrenamiento para ingenieros de software en Silicon Valley? Especialmente aquellos que apuntan a habilidades en algoritmos, programación, codificación y diseño.
- Con tantas violaciones de seguridad y violaciones de privacidad, ¿el desarrollo de software y la ingeniería eventualmente se convertirán en una industria regulada?
- ¿Cuál es un ejemplo de un programa utilizado de forma orientada a objetos en comparación con la programación funcional?
- ¿Cuál es el proyecto de código abierto más exitoso hasta el momento y por qué?
- Soy un estudiante de secundaria con experiencia en el desarrollo de proyectos Java y en el uso de herramientas de la industria, pero sin antecedentes formales (sobre los cuales las compañías insisten). ¿Cómo puedo desarrollar efectivamente un fondo tan formal?
Hasta que vi la salida del depurador, no se me había ocurrido un problema en la biblioteca matemática. Después de todo, se llama por todas partes, para muchos propósitos, y “siempre” funciona. ¿Por qué no aquí?
Las funciones de activación se llaman con mucha frecuencia en un juego, y alguien había optimizado las versiones en nuestra biblioteca de juegos al reemplazar las implementaciones de biblioteca matemática rigurosas pero lentas con versiones rápidas que evaluaban algunos términos de un polinomio. Esto es lo suficientemente preciso si sabe que el ángulo pasado como argumento siempre se ha reducido al rango [-pi .. pi] de antemano, lo que generalmente era cierto para nuestro código. Entonces, ¿qué salió mal?
Resulta que el código rápido tenía algún tipo de problema numérico cuando la entrada era un número de punto flotante desnormalizado. (Ya no tengo acceso al código, así que no puedo decirte cuál fue el problema exacto). El flotante normalizado más pequeño de 32 bits es 2 ^ (- 126), aproximadamente 1e-38. Mientras el valor absoluto del ángulo fuera mayor que aproximadamente 1e-38, el nuevo código de función trigonométrica devolvió un valor razonable. Además, el código tenía una comprobación explícita de los valores de entrada cuyo valor absoluto era inferior a 1e-40, devolviendo cero en ese caso. Entonces, el * único * momento en que la función trigonométrica “rápida” falló fue cuando el valor absoluto del ángulo era mayor que 1e-40, pero menor que 1e-38.
Un valor de entrada en esta ventana es increíblemente improbable. Con valores de ángulo plausibles que varían de aproximadamente -3 a 3, la parte problemática del rango es aproximadamente 1 parte en 3e38. Si generó números verdaderamente aleatorios en ese rango a una velocidad de 30 por segundo, esperaría obtener uno malo cada 10 ^ 30 años. Pero los ángulos en el sistema de cámara no son aleatorios; generalmente son un pequeño incremento aplicado a los ángulos del cuadro anterior, y por alguna razón vimos que esto sucede cada pocos miles de horas de tiempo de prueba acumulado, lo suficientemente frecuente como para reproducirse eventualmente. Una vez que supe el rango de entradas problemáticas, pude demostrar que la función trigonométrica falla. Entonces lo arreglamos.
Pero tardó 1 o 2 meses desde el primer informe del error hasta la solución final. La mayor parte de eso simplemente estaba esperando que saltara la trampa que había colocado en el código, ya que no tenía idea en ese momento qué condición podría causar el problema observado.
Dave
PD: es posible que una mala decisión de diseño cree un montón de código que nunca funciona correctamente, y que tome un tiempo considerable volver a implementar la sección del problema para que funcione correctamente. Pero no lo llamaría un error, lo llamaría un diseño defectuoso.