Cómo mejorar su capacidad para depurar el código existente [cerrado]
29
Una tarea común en el mundo laboral es tratar con el código existente, pero con errores. ¿Cuáles son algunos consejos para mejorar sus habilidades como depurador?
Waterboard el autor original para obtener respuestas.
Trabajo
Respuestas:
32
No asumas nada
A menudo es tentador decir "oh, sé lo que está haciendo este fragmento de código, está bien". No hagas eso. Pruebe cada suposición y revise todo cuidadosamente.
+1. Absolutamente. Prepárate para sorprenderte de cómo algunas de las cosas, creías saber, te engañarán.
aufather
funciona para mí :)
setzamora
3
La depuración del código de otros es una gran pérdida de tiempo y de productividad, pero así es como es. El único momento en el que realmente tiene sentido corregir los errores de otros es cuando se han ido. Lo que ODIO ODIO ODIO es pasar por un código objetivamente malo por un codificador senior, luego tener que hacer una pregunta para progresar a tiempo y obtener una conferencia sobre cómo mejorar mis habilidades para aprender la base de código existente. A diferencia del estudio de la madre naturaleza, resolver problemas humanos no es divertido. Al menos recibo mi respuesta. La situación inversa no sucederá, porque estoy mejor y dejo menos errores.
Trabajo
1
@ Job: ... ¿de acuerdo? ¿Querías dejar este comentario en la publicación, tal vez? :)
Adam Lear
¡Esta! Es una tontería confiar ciegamente en cualquier parte pequeña de su código si está depurando un problema extraño y el código parece estar bien.
Dan
7
Pruebas incrementales .
Profundice primero en su código y pruébelo desde el módulo más pequeño subiendo gradualmente. De esta manera, no estará demasiado estresado tratando de averiguar dónde podría estar exactamente el problema.
También significa que afecta menos código a la vez ya que te estás moviendo de forma incremental ... ya que a veces he tenido problemas en los que arreglé algo y eso me llevó a romper muchas otras cosas. Le doy crédito a mi jefe por esto, ya que él me enseñó esto cuando jugué.
Dividir y conquistar es un buen enfoque. Intente identificar alguna entrada visible (entrada del usuario / evento de red ...) y salida (registro, salida al usuario, mensaje de red saliente ...) entre las cuales existe el problema. Intente colocar impresiones en trozos considerables o puntos significativos entre ellos e intente reducir dónde está el error en el código.
Dividir y conquistar también puede funcionar muy bien en caso de regresiones sobre código controlado por versión. Encuentre dos compilaciones, una donde funcione como se esperaba, otra con la regresión. Reduzca la brecha hasta que quede con un montón de registros como posibles sospechosos.
En lugar del error binario chop, escribe pruebas en el formulario
Dado...
Cuando...
Esperar...
Para verificar lo que realmente sabe que es cierto sobre el funcionamiento de la aplicación frente a lo que supone que es cierto.
La mayoría de los IDE facilitan la extracción de métodos y la generación de stubs de prueba de xUnit. Haz uso de eso.
¿Por qué no rociar debugs? Porque después de que haya terminado, es probable que tenga que deshacer gran parte de ese trabajo y eliminar una buena cantidad de esos debugs. Cuando escriba pruebas, su depuración ayudará en la prevención y detección de errores futuros.
La depuración absoluta está en el arte en sí misma, especialmente la depuración del código de otras personas.
Gratzy
2
Como han dicho otros, no asumas nada. Esto es especialmente cierto si es el código que has escrito. Al depurar el código de otros, es más probable que disminuya la velocidad porque el código es nuevo para usted o no confía en el codificador. Cuando depure su propio código, es demasiado fácil suponer que lo escribió correctamente, ¡disminuya la velocidad!
Para el proceso real de depuración:
Escriba pruebas unitarias si aún no existen.
Agregue el registro apropiado si aún no existe.
Luego usa la depuración.
Agregar las pruebas unitarias y el registro primero es más eficiente que usar primero el depurador. También obtiene la ventaja adicional de tener las pruebas unitarias para ayudar a no introducir errores futuros y el registro ayudará a las sesiones de depuración en el futuro.
Antes de pasar por encima de un pequeño fragmento de código, vea si puede determinar con precisión el resultado. Esto no suele suponer nada (lo cual voté por cierto), pero a medida que adquieres experiencia, puede ayudar a reducir dónde buscar.
Esto puede sonar trivial, pero aprenda los matices de su depurador y aprenda las teclas de acceso rápido. A veces, los depuradores pueden ser lo suficientemente lentos como para que tu mente se pregunte cuando entras. Si puede mantenerse al día con la máquina y no se está moviendo, eso puede ayudar.
Si puede modificar el código durante la depuración:
considere hacer valer las condiciones previas y posteriores. A veces puede pasar, en lugar de ingresar al código.
para las declaraciones if con expresiones complicadas, considere algo (algunos pueden fruncir el ceño ante esto pero funciona para mí)
me gusta:
bool isLessThan5 = a < 5;
bool isGreaterThan10 = a > 10;
if ( isLessThan5 || isGreaterThan10 )
{
// more code here
}
en lugar de:
if ( a < 5 || a > 10 )
{
// more code here
}
Para los casos en que no puede depurar todo, por cualquier razón, aprenda a "huir" con un compañero de trabajo. A veces el acto de explicar arroja luz. (ok, tal vez esto no está exactamente en el tema de las preguntas, pero creo que está lo suficientemente cerca como para merecer una mención)
El nombramiento de subcondiciones necesita un paso más, es decir, la refactorización de los nombres cuando descubres para qué es la condición. Podría ser if (tooCloseToHydrant || overTheBrink) { cuando aprendas más más tarde.
1
Dos cosas, basadas en pasar la mayor parte de los últimos 22 años manteniendo el código que otras personas escribieron.
Comprende los tipos de errores que sueles escribir.
Por ejemplo, soy un codificador muy meticuloso, así que una vez que mi código se compila, generalmente está libre de errores triviales. Así que mis errores tienden a ser cosas extrañas y complicadas, como puntos muertos de hilo. Por otro lado, tengo un amigo que escribe principalmente errores triviales: punto y coma al final de C ++ para bucles, por lo que la siguiente línea solo se ejecuta una vez, ese tipo de cosas.
No asumas que otras personas escriben los mismos tipos de errores que tú.
No sé cuántas veces he perdido el tiempo sacando las grandes pistolas de depuración, suponiendo que un error era mi tipo de cosa extraña muy sutil, solo para que mi amigo mirara sobre mi hombro y dijera: "¿Notaste ese extra? ¿punto y coma?" Después de años de eso, primero busco la fruta trivial y baja cuando miro el código de otras personas.
@ Thorbjørn: Si tomé posesión del código, a veces lo hago para mejorar la legibilidad, pero no para encontrar errores tipográficos. ¡Idea interesante!
Bob Murphy
no tienes que cometerlo, solo mira lo que sucede. Puedo recomendar encarecidamente la aplicación de un sistema de gobierno que requiere código para formatear - preferiblemente de forma automática - cuando el ingreso.
@ Thorbjørn: Me encantaría hacer eso. ¿Qué me recomiendan como código "prettifier"? Principalmente trabajo en Linux y Mac.
Bob Murphy
Utilizo Eclipse disponible en ambos lugares, y el editor de Java tiene una llamada acción Guardar donde puede especificar qué debe suceder cada vez que se guarda el archivo. Aquí una de las opciones es formatear la fuente. Somos un equipo pequeño, así que no he investigado más en él. Los equipos más experimentados permiten enganches de precompromiso en los sistemas de control de origen, lo que permite rechazar un compromiso de origen si está formateado incorrectamente. Muy eficiente.
1
Conoce tus herramientas. Por ejemplo, el depurador de Visual Studio tiene una característica impresionante llamada TracePoints que son como puntos de interrupción, pero en lugar de detener su código, inserta una declaración de rastreo en la salida de depuración.
Se recomienda leer libros o tomar una clase sobre cómo usar su depurador. Tomé un par de clases y leí algunos libros de John Robbins que marcaron una gran diferencia en mi efectividad como depurador.
Comprenda funcionalmente lo que el código intenta hacer. Si no conoce la imagen completa (todos los casos de prueba que debe pasar este código) es difícil de depurar correctamente sin introducir nuevos errores
Escriba pruebas unitarias automatizadas y otros tipos de integración y pruebas funcionales.
Cuantas más pruebas automatizadas tenga, menos tiempo necesitará pasar en un depurador.
Además, buen diseño: principios SÓLIDOS. Si está escribiendo clases pequeñas y enfocadas y está favoreciendo la composición sobre la herencia, eliminando la duplicación, etc., entonces su código siempre será más fácil de depurar.
Me parece que el código bien diseñado produce un conjunto diferente de errores de ese código que no está bien diseñado. En términos generales, un código bien diseñado produce errores que son más fáciles de encontrar, reproducir y corregir.
La excepción (y siempre hay una) es el código de subprocesos múltiples :-)
Si lo ha reducido a una región pequeña, pero aún no puede detectar el error, pruebe la opción 'ver código + ensamblaje' de su depurador. Conociendo suficiente ASM para decir "debería haber una rama aquí" o "¿por qué solo está copiando la palabra baja?" a menudo identificará el error de codificación.
Las diapositivas del libro están disponibles en línea, pero creo que el libro en sí es más fácil de leer.
El libro te ayudará a comenzar y te hará pensar más científicamente sobre la depuración, pero no sustituye a la práctica. Es posible que deba escribir y depurar durante 10 años antes de ver una mejora en su orden de magnitud. Todavía recuerdo que me quedé boquiabierto con Sun al ver a los desarrolladores senior, que han estado programando para Unix durante 30 años, encontrar oscuros errores de subprocesos múltiples o paralelos en minutos. ¡La experiencia importa!
Respuestas:
No asumas nada
A menudo es tentador decir "oh, sé lo que está haciendo este fragmento de código, está bien". No hagas eso. Pruebe cada suposición y revise todo cuidadosamente.
fuente
Pruebas incrementales .
Profundice primero en su código y pruébelo desde el módulo más pequeño subiendo gradualmente. De esta manera, no estará demasiado estresado tratando de averiguar dónde podría estar exactamente el problema.
También significa que afecta menos código a la vez ya que te estás moviendo de forma incremental ... ya que a veces he tenido problemas en los que arreglé algo y eso me llevó a romper muchas otras cosas. Le doy crédito a mi jefe por esto, ya que él me enseñó esto cuando jugué.
fuente
Dividir y conquistar es un buen enfoque. Intente identificar alguna entrada visible (entrada del usuario / evento de red ...) y salida (registro, salida al usuario, mensaje de red saliente ...) entre las cuales existe el problema. Intente colocar impresiones en trozos considerables o puntos significativos entre ellos e intente reducir dónde está el error en el código.
Dividir y conquistar también puede funcionar muy bien en caso de regresiones sobre código controlado por versión. Encuentre dos compilaciones, una donde funcione como se esperaba, otra con la regresión. Reduzca la brecha hasta que quede con un montón de registros como posibles sospechosos.
fuente
En lugar del error binario chop, escribe pruebas en el formulario
Para verificar lo que realmente sabe que es cierto sobre el funcionamiento de la aplicación frente a lo que supone que es cierto.
La mayoría de los IDE facilitan la extracción de métodos y la generación de stubs de prueba de xUnit. Haz uso de eso.
¿Por qué no rociar debugs? Porque después de que haya terminado, es probable que tenga que deshacer gran parte de ese trabajo y eliminar una buena cantidad de esos debugs. Cuando escriba pruebas, su depuración ayudará en la prevención y detección de errores futuros.
fuente
Sigue depurando. Si depuras mucho, mejorarás.
fuente
Como han dicho otros, no asumas nada. Esto es especialmente cierto si es el código que has escrito. Al depurar el código de otros, es más probable que disminuya la velocidad porque el código es nuevo para usted o no confía en el codificador. Cuando depure su propio código, es demasiado fácil suponer que lo escribió correctamente, ¡disminuya la velocidad!
Para el proceso real de depuración:
Agregar las pruebas unitarias y el registro primero es más eficiente que usar primero el depurador. También obtiene la ventaja adicional de tener las pruebas unitarias para ayudar a no introducir errores futuros y el registro ayudará a las sesiones de depuración en el futuro.
fuente
Antes de pasar por encima de un pequeño fragmento de código, vea si puede determinar con precisión el resultado. Esto no suele suponer nada (lo cual voté por cierto), pero a medida que adquieres experiencia, puede ayudar a reducir dónde buscar.
Esto puede sonar trivial, pero aprenda los matices de su depurador y aprenda las teclas de acceso rápido. A veces, los depuradores pueden ser lo suficientemente lentos como para que tu mente se pregunte cuando entras. Si puede mantenerse al día con la máquina y no se está moviendo, eso puede ayudar.
Si puede modificar el código durante la depuración:
me gusta:
en lugar de:
Para los casos en que no puede depurar todo, por cualquier razón, aprenda a "huir" con un compañero de trabajo. A veces el acto de explicar arroja luz. (ok, tal vez esto no está exactamente en el tema de las preguntas, pero creo que está lo suficientemente cerca como para merecer una mención)
fuente
if (tooCloseToHydrant || overTheBrink) {
cuando aprendas más más tarde.Dos cosas, basadas en pasar la mayor parte de los últimos 22 años manteniendo el código que otras personas escribieron.
Comprende los tipos de errores que sueles escribir.
Por ejemplo, soy un codificador muy meticuloso, así que una vez que mi código se compila, generalmente está libre de errores triviales. Así que mis errores tienden a ser cosas extrañas y complicadas, como puntos muertos de hilo. Por otro lado, tengo un amigo que escribe principalmente errores triviales: punto y coma al final de C ++ para bucles, por lo que la siguiente línea solo se ejecuta una vez, ese tipo de cosas.
No asumas que otras personas escriben los mismos tipos de errores que tú.
No sé cuántas veces he perdido el tiempo sacando las grandes pistolas de depuración, suponiendo que un error era mi tipo de cosa extraña muy sutil, solo para que mi amigo mirara sobre mi hombro y dijera: "¿Notaste ese extra? ¿punto y coma?" Después de años de eso, primero busco la fruta trivial y baja cuando miro el código de otras personas.
fuente
Conoce tus herramientas. Por ejemplo, el depurador de Visual Studio tiene una característica impresionante llamada TracePoints que son como puntos de interrupción, pero en lugar de detener su código, inserta una declaración de rastreo en la salida de depuración.
Se recomienda leer libros o tomar una clase sobre cómo usar su depurador. Tomé un par de clases y leí algunos libros de John Robbins que marcaron una gran diferencia en mi efectividad como depurador.
fuente
Comprenda funcionalmente lo que el código intenta hacer. Si no conoce la imagen completa (todos los casos de prueba que debe pasar este código) es difícil de depurar correctamente sin introducir nuevos errores
fuente
Escriba pruebas unitarias automatizadas y otros tipos de integración y pruebas funcionales.
Cuantas más pruebas automatizadas tenga, menos tiempo necesitará pasar en un depurador.
Además, buen diseño: principios SÓLIDOS. Si está escribiendo clases pequeñas y enfocadas y está favoreciendo la composición sobre la herencia, eliminando la duplicación, etc., entonces su código siempre será más fácil de depurar.
Me parece que el código bien diseñado produce un conjunto diferente de errores de ese código que no está bien diseñado. En términos generales, un código bien diseñado produce errores que son más fáciles de encontrar, reproducir y corregir.
La excepción (y siempre hay una) es el código de subprocesos múltiples :-)
fuente
Si lo ha reducido a una región pequeña, pero aún no puede detectar el error, pruebe la opción 'ver código + ensamblaje' de su depurador. Conociendo suficiente ASM para decir "debería haber una rama aquí" o "¿por qué solo está copiando la palabra baja?" a menudo identificará el error de codificación.
fuente
Consulte el valioso libro Por qué fallan los programas: una guía para la depuración sistemática , de Andreas Zeller. Le presentará muchas técnicas, teorías y herramientas, algunas de las cuales están a la vanguardia de la investigación.
Las diapositivas del libro están disponibles en línea, pero creo que el libro en sí es más fácil de leer.
El libro te ayudará a comenzar y te hará pensar más científicamente sobre la depuración, pero no sustituye a la práctica. Es posible que deba escribir y depurar durante 10 años antes de ver una mejora en su orden de magnitud. Todavía recuerdo que me quedé boquiabierto con Sun al ver a los desarrolladores senior, que han estado programando para Unix durante 30 años, encontrar oscuros errores de subprocesos múltiples o paralelos en minutos. ¡La experiencia importa!
fuente