Aprendiendo a investigar errores [cerrado]

11

Ni siquiera estoy seguro de cómo definir esta dificultad. Me recuerda a la prueba que me hicieron un par de posibles empleados antes de conseguir un trabajo. Escogerían un objeto en la habitación y luego se me permitiría hacer preguntas para ayudarme a determinar qué es ese objeto (como 20 preguntas). Fui ridículamente bueno en esto (no, nunca obtuve puntos altos por humildad), así que asumí que sería realmente bueno para solucionar errores ...

Pero aquí está lo que descubrí recientemente. Soy realmente bueno en esa situación porque es muy fácil ver todo lo que hay en la sala, por lo tanto, puedo abordar mi problema con algún concepto de sus componentes. En esencia, "sé lo que no sé". Pero con la programación me encuentro con muchas situaciones en las que el problema es completamente desconocido para mí. Sé que está roto, pero no tengo idea de cómo podría estar roto. He seguido todas las instrucciones, conozco la tecnología bastante bien ...

Si soy honesto, siento que me está costando imaginar cosas que podrían estar mal para poder probarlas y, con suerte, encontrar una solución.

¿Cómo hago para desarrollar esa habilidad? ¿Qué necesito hacer para ayudar a mi, aparentemente, limitada imaginación a encontrar formas de que mi proyecto pueda romperse? ¿Hay ejercicios (¿tal vez rompecabezas?) Que puedan hacerme mejor en esto? Soy consciente de que probablemente la mayor cura es la experiencia ... pero espero poder ayudar a acelerar el proceso si puedo. Mirar fijamente la pantalla de mi computadora en blanco por algunas horas seguidas ni siquiera es divertido ...

Jay Carr
fuente
3
imagina cómo crees que podría funcionar, y trabaja hacia atrás desde las salidas hasta las entradas para encontrar caminos para investigar
Steven A. Lowe
1
Voy a lanzar un enlace: Cómo ser un programador , la primera habilidad que aparece es "Aprender a depurar".
1
Quería tirar algo sobre el pensamiento "fuera de la caja". Con respecto a los errores, a menudo pienso que lo primero que debe hacer es simplemente enumerar todos los sistemas que interactúan, y luego asumir que cualquier parte podría tener la culpa hasta que se demuestre lo contrario. Entonces su trabajo se vuelve más fácil: suponga que el componente está fallando y encuentre la forma en que podría hacerlo, incluso si al principio parece ilógico ("la salida se está corrompiendo", etc.). Luego, pruebe que su componente no falla, comenzando con las interacciones más inmediatas. Después del hecho, puede parecer imaginación, pero a menudo solo comienza con una visión pesimista.
J Trana
Escriba uno printfo printlnlo que sea que use debajo de cada línea de código para estar 100% seguro de que todo funciona como desea que funcione jaja. Luego ejecute su aplicación de consola y App > out.txtluego viene la parte difícil de ver el archivo enorme ... a veces mis archivos de registro superan los pocos millones de líneas y puede llevar algún tiempo jaja. Por supuesto, la forma correcta sería usar un depurador y puntos de interrupción, pero a veces no es posible hacerlo.
SSpoke
1
Lea el Zen de Pirsig y el arte del mantenimiento de motocicletas amazon.com/Zen-Art-Motorcycle-Maintenance-Inquiry/dp/0060589469
Jeffrey Kemp el

Respuestas:

11

Cada defecto en el software se debe en última instancia a una discrepancia entre los supuestos y la realidad. Los errores insidiosos son simplemente discrepancias entre suposiciones particularmente arraigadas y la realidad. La capacidad de diagnosticar errores depende de su capacidad para cuestionar sus propias suposiciones, y eso requiere una conciencia de que no sabe ciertas cosas, simplemente las asumió y solía estar en lo cierto hasta ahora.

Obviamente, las herramientas del comercio, los archivos de registro, los depuradores, etc. son útiles para descubrir tales suposiciones y realinear su modelo mundial con el sistema real. Pero hasta que esté listo para cuestionar la suposición crucial, por ejemplo, "No puede ser una mala entrada porque tenemos una verificación de entrada completa", pasará todo su tiempo revisando las partes incorrectas del sistema, o simplemente no sabrá dónde buscar. en primer lugar.

Kilian Foth
fuente
3
Odio decirlo Killian, pero creo que has dado en el clavo. Me he enorgullecido mucho de mi "conocimiento" de los sistemas que he adquirido con el tiempo que llevo aquí y creo que soy mentalmente resistente a la idea de estar equivocado. Como ya he mencionado, nunca obtuve un puntaje alto en humildad. Seguir su consejo para desafiar mis propias suposiciones realmente me permitió hacer un progreso sólido en un par de problemas que enfrentaba en mi propio código. Entonces, gracias, lo tendré en cuenta en el futuro.
Jay Carr
2
@ JayCarr: " mentalmente resistente a la idea de estar equivocado " - ¿Qué pasa si tratas de ver los errores como una fuente de aprendizaje en lugar de una falla? No hay nada de malo en estar equivocado, siempre y cuando no te detengas allí.
JensG
14

¿Qué necesito hacer para ayudar a mi, aparentemente, limitada imaginación a encontrar formas de que mi proyecto pueda romperse?

En la mayoría de los casos, no diría absolutamente nada. No deberías intentar soñar cosas que podrían estar causando que el programa se rompa. Debería determinar sistemáticamente qué está causando que se rompa.

Debería entrar en el proceso de depuración con la siguiente información:

  • los pasos que se tomaron y los valores que se ingresaron para producir el error;
  • qué debe hacer el programa cuando se le dan esos pasos e insumos;
  • lo que el programa está haciendo cuando se les da esos pasos y entradas.

Si hay un mensaje de error, obtenga toda la información que pueda al respecto. Si el mensaje de error en sí no está claro y no sabe lo que significa en la práctica (algunos mensajes de error no siempre son particularmente útiles), utilice Google, StackOverflow o cualquier otro recurso en línea para encontrar información al respecto. .

Si no se muestra un mensaje de error en el front-end, revise los registros en los que la aplicación escribe para ver si hay mensajes de error durante el período en que reprodujo el error. Es posible que el código se haya ejecutado hasta su finalización, pero encontró una excepción que se está manejando en el camino y que arroja el resultado final y produce una entrada en los registros. Busque esos, haga lo mismo arriba e identifique exactamente lo que significan.

Si hay códigos de pila proporcionados con excepciones lanzadas por su código (y debería haberlo), mire las líneas de código mencionadas. La línea en sí misma puede no ser la que realmente está produciendo el problema. Si obtiene una NullPointerException en un fragmento de código Java, el stacktrace le dirá dónde intentó usar algo que era nulo cuando esperaba que no lo fuera. Eso no lo señala exactamente a la línea que causa el problema, pero generalmente le dice qué variable no tiene el valor que espera, por lo que puede ver las referencias / asignaciones a esa variable para determinar que el valor no se establece o que el valor se establece incorrectamente.

Si nada de eso ha ayudado, encienda su depurador. Si lo ha reducido a una sección del código que sabe que está causando el problema, pero no sabe exactamente qué línea (s), pase a través de eso. Si no, solo pasa por todo el asunto. Aquí es donde debe saber exactamente qué debe hacer el programa con las entradas dadas, porque debe mirar cada valor después de cada línea y determinar exactamente dónde se está desviando de lo que espera que haga.

¿Aún no tienes idea de cuál es el problema? Pídele ayuda a alguien . Un compañero de trabajo, un amigo, una comunidad en línea. Muéstrales todo el trabajo que acabas de hacer. Muéstreles los mensajes de error, los stacktraces, explique qué hace el programa en términos generales (si aún no lo saben), qué debería estar haciendo en este caso particular (por ejemplo, devolver el valor 4), qué está haciendo realmente (por ejemplo devolviendo el valor 5). Si lo ha reducido a unas pocas líneas de código en el depurador, diga "Sé que el problema es causado por estas líneas en el código, está estableciendo el valor en X cuando debería ser Y, pero no puedo ver por qué está pasando eso ".

Pasar unas horas mirando fijamente tu pantalla definitivamente no es divertido, pero no hay razón para que lo hagas. Si hay un problema con su código, entonces debe estar leyendo o revisando el código.

Anthony Grist
fuente
Puede haber sido un poco rápido para juzgar esta respuesta, estaba un poco frustrado cuando lo leí. Aviso sonoro. Los comentarios de Killians simplemente hablaron más sobre el corazón de mi problema, creo. Esa es la única razón por la que esta no es la respuesta seleccionada.
Jay Carr
4

Hasta cierto punto, es como investigar un caso criminal o un rompecabezas alucinante.

Primero, tienes a la víctima. Después de investigar un poco el caso, identificó a algunos sospechosos y también desarrolló una hipótesis de trabajo sobre cómo exactamente la víctima podría ser asesinada. Continúa investigando, buscando información más útil, acercándose cada vez más a la fuente real del problema.

Sucede que de vez en cuando entras en un callejón sin salida (juego de palabras). Eso es parte de eso, y no tiene nada de malo, siempre y cuando consigas volver a la pista lo más rápido posible. La clave es, siempre pensar en qué información necesita a continuación, que le brinde su hipótesis (y le brinde más información) o que demuestre que está equivocada. Luego encuentre una manera de obtener esa información de manera eficiente, saque sus conclusiones y siga adelante, hasta que finalmente pueda condenar al culpable.

Y a veces te das cuenta de que todos los hechos e indicaciones necesarios para detectar al culpable ya te esperaban hace media hora. Aunque molesto, esa es una de las partes más interesantes, porque si haces una revisión crítica de tus acciones y errores, puedes aprender y mejorar . Hágase preguntas como:

  • ¿Cómo podría haber evitado esta pérdida de tiempo?
  • ¿Qué pasé por alto en primer lugar y por qué?
  • ¿En qué supuestos no validados y / o incorrectos me basé?

Esto entrenará tus habilidades. También desarrollará tu instinto , por lo que con el tiempo aprenderás a notar automáticamente todas esas cosas menores que se pasan por alto con demasiada facilidad, lo que te llevará más rápido a la respuesta correcta. Al final, se trata de práctica deliberada .

Por último, recuerde siempre lo que Sherlock Holmes nos enseñó: cuando haya eliminado lo imposible, lo que queda, por improbable que sea, debe ser la verdad.

JensG
fuente
3

¿Qué necesito hacer para ayudar a mi, aparentemente, limitada imaginación a encontrar formas de que mi proyecto pueda romperse?

Deja que la historia sea tu guía. Si su proyecto está bien administrado, debe tener una base de datos de cada error que se haya solucionado en el producto junto con un análisis de cómo se encontró el error, cómo se reprodujo, cómo se analizó y cómo se solucionó. Esa no es una base de datos de solo escritura. Lea la base de datos , y muy pronto comenzarán a ocurrir taxonomías de errores.

Eso le dará una buena descripción del tipo de cosas que salen mal en su producto. Si está interesado de manera más general en lo que falla en todo tipo de software, particularmente con un énfasis en los defectos que afectan la seguridad, le sugiero que lea la lista de CWE: http://cwe.mitre.org/data/index.html

Eric Lippert
fuente
2

Entonces, en lugar de tratar de reproducir y corregir un defecto específico, creo que está preguntando si está pensando en nuevas pruebas que podría usar para investigar el producto para ver si el producto funciona en esas circunstancias, por ejemplo: ¿qué sucede si ingreso caracteres especiales en nuestro la contraseña de la página de registro archivada, o qué sucede si cierro forzosamente el programa mientras está escribiendo en la base de datos. Estos casos son realmente difíciles de imaginar.

El desarrollo de software en los últimos 10 años (Agile / XP / TDD, etc.) ha llegado a valorar el cumplimiento de los requisitos explícitos solamente y luego declarar que la característica ha finalizado, y no encontrar todas las formas posibles de romper algo (hay posibles excepciones, si usted es trabajando para la NASA o haciendo seguridad de sombrero blanco, pero incluso entonces hay un caso para llamar a tales cosas en los criterios de aceptación de la historia del usuario).

Entonces, si sus características enumeran explícitamente como criterios de aceptación lo que los sistemas necesitan hacer, como cómo manejar la entrada, sus características de rendimiento, las acciones del flujo de trabajo del usuario, etc., entonces tiene una lista completa de lo que las pruebas deben verificar. Se deben realizar pruebas para validar que se han cumplido los requisitos, y la mejor manera de hacerlo es enumerar explícitamente todos sus requisitos. Eche un vistazo a los Cuadrantes de prueba ágiles .

Algunas personas abogan por que estas pruebas sean la declaración explícita de los requisitos, que deben escribirse antes del código, es decir, Test First (o Test Driven Development).

Sin embargo, agradezco que no parezca que está contemplando un nuevo proyecto en el que puede establecer sus propias mejores prácticas de desarrollo antes de comenzar y, en cambio, entrará después de que se haya escrito el software y se le pida que lo `` pruebe ''. Esto es realmente más desafiante, pero se aplican los mismos principios, solo puede probarlo una vez que sepa lo que se supone que debe hacer. Si no hay una lista completa de los requisitos que el equipo de desarrollo cumplió para que usted pueda trabajar, entonces hacer preguntas es la mejor manera de avanzar. Dependiendo de su equipo, esto debe hacerse con delicadeza ya que a las personas que no enumeraron explícitamente sus requisitos antes de construir un sistema de software no les gusta que les recuerden lo que se perdieron, pero es esencial para realizar bien esta tarea.

Una vez que encuentre un requisito: debe ser robusto / debe ser seguro, luego trate de profundizar y descubrir qué tan seguro debe ser, o cuánta falla es aceptable, siempre hay un límite, no muchas personas tienen una prueba NSA nivel de seguridad como requisito para su aplicación o desearía pagar por eso. Cuanto más excaves, más claro debería ser el tipo de ataques de seguridad contra los que debes defenderte o la facilidad de uso que estás buscando. Algunos conocimientos de dominio son útiles, en seguridad, en diseño, en rendimiento, etc., que es donde usted hace aún más preguntas a los expertos que puede encontrar en su equipo, o aquí en SE, o google / books.

Encaitar
fuente
No es exactamente la pregunta que quería responder, pero un excelente comentario, no obstante. Te voy a votar, este es un comentario muy útil.
Jay Carr