2009-02-13 8 views
17

Soy "simplemente" un programador aficionado, pero me parece que a medida que mis programas se vuelven más y más largos, los errores se vuelven más molestos y más difíciles de rastrear. Justo cuando todo parece funcionar sin problemas, aparecerá un nuevo problema, aparentemente espontáneo. Me puede llevar mucho tiempo descubrir qué causó el problema. Otras veces agregaré una línea de código y romperá algo en otra unidad. Esto puede ser un poco frustrante si pensara que todo estaba funcionando bien.¿Cuáles son algunas buenas estrategias para corregir errores a medida que el código se vuelve más complejo?

¿Esto es común a todos, o es más un tipo de cosa novato? He oído hablar de "pruebas unitarias", "marcos de diseño" y varios otros conceptos que parecen disminuir la frescura, hacer que mis aplicaciones sean "robustas" y todo fácil de entender de un vistazo :)

Entonces, qué tan grande ¿un trato son errores para las personas con entrenamiento profesional?

Gracias - Al C.

Respuesta

24

El problema de "corregir, causar un problema en otro lado" es muy conocido, y de hecho es una de las principales motivaciones detrás de las pruebas unitarias.

La idea es que si escribe pruebas exhaustivas para cada pequeña parte de su sistema de forma independiente y las ejecuta en todo el sistema cada vez que realiza un cambio en cualquier lugar, verá el problema de inmediato. El principal beneficio, sin embargo, es que en el proceso de construcción de estas pruebas también mejorará su código para tener menos dependencias.

La solución típica a este tipo de problemas es reducir el acoplamiento; hacer que las diferentes partes sean menos dependientes unas de otras. Los desarrolladores más experimentados a veces tienen hábitos o habilidades de diseño para construir sistemas de esta manera. Por ejemplo, usamos interfaces e implementaciones en lugar de clases; usamos modelo-vista-controlador para interfaces de usuario, etc. Además, podemos usar herramientas que ayudan a reducir aún más las dependencias, como "inyección de dependencia" y programación orientada a aspectos.

Todos los programadores cometer errores. Los programadores buenos y experimentados construyen sus programas para que sea más fácil encontrar los errores y restringir sus efectos.

Y es un gran negocio para todos. La mayoría de las empresas dedican más tiempo al mantenimiento que a escribir nuevos códigos.

+0

Hehe como ingeniero de soporte, me gustaría enmendar que "la mayoría de las empresas * deben * dedicar más tiempo al mantenimiento que escribir un código nuevo;; desafortunadamente, las nuevas funciones venden productos, por lo que tienen prioridad en mi experiencia – Jay

+0

La respuesta es buena . ¡La enmienda también es increíble! – batbrat

+0

Al igual que los virus, [los errores pueden causar una infección] (https://www.youtube.com/watch?t=129&v=Qjwg-9jHGPo) a otras partes del código. – gaborous

1

La idea predominante parece ser que el programador medio crea 12 errores por cada 1000 líneas de código - depende de a quién le pregunte por el número exacto, pero siempre por líneas de código - Entonces, cuanto más grande sea el programa, más bichos.

Los programadores de Subpar tienden a crear más errores.

Los principiantes a menudo quedan atrapados por la idiosincrasia del idioma, y ​​la falta de experiencia también tiende a provocar más errores. A medida que avance, mejorará, pero nunca creará código libre de errores ... bueno, todavía tengo errores, incluso después de 30 años, pero podría ser solo yo.

+0

El único programa libre de errores es un archivo fuente vacío. E incluso entonces, el compilador podría bloquearse. – Thomas

2

Esto es algo común para los novatos. A medida que obtienes más experiencia, por supuesto, seguirás teniendo errores, pero serán más fáciles de encontrar y corregir porque aprenderás cómo hacer que tu código sea más modular (para que cambiar una cosa no tenga efectos de ondulación) en cualquier otro lugar), cómo probarlo y cómo estructurarlo para que falle rápidamente, cerca de la fuente del problema, en lugar de en algún lugar arbitrario. Una cosa muy básica pero útil que no requiere una infraestructura compleja para implementar es verificar las entradas a todas las funciones que tienen precondiciones no triviales con afirmaciones. Esto me ha salvado varias veces en casos en los que de otra manera habría obtenido segfeults extraños y un comportamiento arbitrario que hubiera sido casi imposible de depurar.

3

Obviamente, los errores son un gran problema para cualquier programador. Simplemente mire la lista de preguntas en Stack Overflow para ver esto ilustrado.

La diferencia entre un aficionado y un profesional experimentado es que el profesional podrá utilizar su experiencia para codificar de una manera más "defensiva", evitando muchos tipos de errores en primer lugar.

+0

Como programador aficionado, no creo estar más o menos "a la defensiva", incluso cuando solo haces algo por diversión aún puedes tratar de hacerlo bien. No todos los aficionados son inexpertos. –

+0

Tiene razón; una mejor distinción sería "inexperta" frente a "experimentada". (Diablos, aunque casi tengo una maestría en ciencias de la computación, nunca he codificado una sola línea por dinero en mi vida, sin embargo, no me llamaría inexperto). – Thomas

+0

Estoy de acuerdo con Thomas, excepto por, como noté , la desafortunada elección de palabras. ¡Hay algunos profesionales terribles y terribles por ahí! :-) –

5
  1. Hay dos formas de escribir programas sin errores; solo el tercero funciona. ~ Alan J. Perlis

  2. La única forma de que se produzcan errores en un programa es poniéndolo allí por el autor. No se conocen otros mecanismos. Los programas no pueden adquirir errores al sentarse con otros programas con errores. ~ Harlan Mills

+0

Nunca había escuchado esa cita de Perlis antes: va en mi colección de favoritos. – slothbear

+0

Aunque la cita de Harlan es bastante precisa, no es tanto hoy en día que el software depende de tantos componentes externos, es muy probable que adquiera errores al sentarse con otros programas con errores en mi humilde opinión. –

+0

Eso no es del todo cierto. Los programas también pueden corromperse y generarse errores debido a errores silenciosos a lo largo del tiempo en el medio de almacenamiento. Es por eso que hay un campo de investigación que se centra en [estructuras de datos resistentes a la corrupción] (https://encrypted.google.com/search?q=corruption+resilient+data+structures) y programas. – gaborous

1

Errores desagradables le ocurren a todos, desde profesionales hasta aficionados. A los programadores realmente buenos se les pide que busquen errores realmente desagradables. Es parte del trabajo. Sabrá que lo hizo como desarrollador de software cuando mira fijamente un desagradable error durante dos días y, con frustración, grita: "¿Quién escribió esta basura??!?" ... solo para darte cuenta de que eras tú. :-)

Parte de la habilidad de un desarrollador de software es la capacidad de mantener un gran conjunto de elementos interrelacionados directamente en su cabeza. Parece que estás descubriendo lo que sucede cuando tu modelo mental del sistema se descompone. Con la práctica aprenderá a diseñar software que no se sienta tan frágil. Hay toneladas de libros, blogs, etc. en el tema del diseño de software. Y Stack Overflow por supuesto para preguntas específicas.

Dicho todo esto, aquí hay un par de cosas que puede hacer:

  1. Un buen depurador es muy valiosa. A menudo tiene que pasar por su código línea por línea para descubrir qué salió mal.
  2. Utilice un lenguaje recogido de basura como Python o Java si tiene sentido para su proyecto. GC lo ayudará a enfocarse en hacer que las cosas funcionen en lugar de atascarse al enloquecer los errores de memoria.
  3. Si escribe C++, aprenda a amar RAII.
  4. Escribe MUCHOS de código. El software es algo así como una forma de arte. Mucha práctica lo hará mejor en eso.

¡Bienvenido a Stack Overflow!

2

¡Si los errores no fueran un problema, entonces podría escribir un programa de 100.000 líneas en 10 minutos!

Su pregunta es como: "Como médico aficionado, me preocupa la salud de mis pacientes: a veces, cuando no soy lo suficientemente cuidadoso, enferman. ¿La salud de los pacientes también es un problema para los médicos profesionales?"

Sí: es el problema central, incluso el único problema (para cualquier definición suficientemente completa de 'error').

15

¿Está automatizando sus pruebas? Si no lo hace, se registra creando errores sin encontrarlos.

¿Estás al agregar las pruebas de los errores mientras los arreglas? Si no lo hace, se registra para crear los mismos errores una y otra vez.

¿Está usted pruebas de unidad de escritura? De lo contrario, se registra para largas sesiones de depuración cuando falla una prueba.

¿Está escribiendo su unidad pruebas primero? De lo contrario, las pruebas de su unidad serán difíciles de escribir cuando sus unidades estén bien acopladas.

¿Estás refactorizando sin piedad? Si no, cada edición será más difícil y más probable que introduzca errores. (Pero asegúrese de tener buenas pruebas, primero.)

Cuando soluciona un error, ¿está arreglando toda la clase? No solo arregles el error; no solo corrija errores similares a través de su código; cambia el juego para que nunca puedas volver a crear ese tipo de error.

+0

Gran respuesta. ¡Creo que da el zen de las pruebas bien! – batbrat

+0

Esta respuesta también se enfoca demasiado (¿religiosamente?) En las pruebas unitarias y el diseño basado en pruebas. Estas prácticas solo hacen que sea más probable que el código haga lo que pretendía hacer, pero no que su software sea correcto al final. –

+0

Estoy de acuerdo tanto con el OP como con los dos comentarios anteriores. Si bien soy un gran admirador de TDD, no es una panacea, y creo que es importante equilibrar la utilidad de las suites de prueba y la cordura de la vida real. De lo contrario, terminas con un código que es imposible de cambiar sin un trabajo significativo. –

5

Los errores son un gran problema para todos. Siempre he descubierto que cuanto más programo, más aprendo acerca de la programación en general. ¡Me avergüenzo del código que escribí hace unos años! Comencé como aficionado y me gustó tanto que fui a la facultad de ingeniería para obtener una especialización en Ingeniería en Informática (estoy en mi último semestre). Estas son las cosas que he aprendido:

  1. Me tomo el tiempo para realmente diseñar lo que voy a escribir y documentar el diseño. Realmente elimina muchos problemas en el futuro. Si el diseño es tan simple como escribir algunos puntos sobre lo que voy a escribir o el modelado completo de UML (:() no importa. Es la claridad de pensamiento y propósito y tener material para mirar cuando vengo. volver al código después de un tiempo que importa más.

  2. No importa en qué idioma escriba, mantener mi código simple y legible es importante. Creo que es extremadamente importante no complicar demasiado el código y al mismo tiempo para no simplificarlo demasiado. (¡Lección aprendida!)

  3. Las optimizaciones de eficiencia y los trucos de fantasía deben aplicarse al final, solo cuando sea necesario y solo si son necesarios. Otra cosa es que los aplico solo Si realmente sé lo que estoy haciendo y siempre pruebo ¡mi código!

  4. El aprendizaje de los detalles del idioma me ayuda a mantener mi código libre de errores. Por ejemplo, aprendí que scanf() es malo en C!

  5. Otros ya han comentado sobre el zen de escribir pruebas. Me gustaría agregar que siempre debes hacer pruebas de regresión. (es decir, escriba un código nuevo, pruebe todas las partes de su código para ver si se rompe)

  6. Mantener una imagen mental del código es difícil a veces, por lo que siempre doy mi código.

  7. Utilizo métodos para asegurarme de que existe una dependencia mínima entre partes diferentes de mi código. Interfaces, jerarquías de clases, etc. (Diseño desacoplado)

  8. Pensar antes de codificar y ser disciplinado en lo que escribo es otra habilidad crucial. Conozco personas que no formatean su código por lo que es legible (¡Shudder!).

  9. Leer la fuente de otras personas para aprender las mejores prácticas es bueno. Hacer mi propia lista es mejor !. Cuando se trabaja en equipo, debe haber un conjunto común de ellos.

  10. No se paralice por el análisis. Escribir pruebas, luego codificar, luego ejecutar y probar. Enjuague lavado repetir!

  11. Aprender a leer mi propio código y peinarlo en busca de errores es importante. Mejorar mi arsenal de habilidades de depuración fue una gran inversión. Los mantengo afilados ayudando a mis compañeros de clase a corregir errores regularmente.

  12. Cuando hay un error en mi código, supongo que es mi error, no las computadoras y el trabajo desde allí. Ese es un estado mental que realmente me ayuda.

  13. Un par de ojos nuevos ayuda a la depuración. Los programadores tienden a perder incluso los errores más obvios en su propio código cuando están agotados. Tener a alguien para mostrar tu código es genial.

  14. tener a alguien para tirar ideas y no ser juzgado es importante. Hablo con mi madre (que no es programadora), le lanzo ideas y encuentro soluciones. Ella me ayuda a relanzar mis ideas y refinarlas. Si ella no está disponible, hablo con mi gato mascota.

  15. No estoy tan desanimado por los errores. Aprendí a amar eliminar errores casi tanto como la programación.

  16. Usar el control de versiones realmente me ha ayudado a gestionar diferentes ideas que obtengo durante la codificación. Eso ayuda a reducir los errores. Recomiendo usar git o cualquier otro sistema de control de versiones que te pueda gustar.

  17. Como dijo Jay Bazzuzi - Código de refactorización. Acabo de agregar este punto después de leer su respuesta, para mantener mi lista completa. Todo el crédito va a él.

  18. Intenta escribir código reutilizable. Código de reutilización, tanto suyo como de las bibliotecas. Usar bibliotecas libres de errores para realizar algunas tareas comunes realmente reduce los errores (a veces).

creo que la siguiente cita lo dice mejor - "Si la depuración es el arte de la eliminación de errores, la programación debe ser el arte de poner en."

Sin ofender a nadie que no esté de acuerdo. Espero que esta respuesta ayude.

Nota
Como otros Peter ha señalado, el uso de Programación Orientada a Objetos si está escribiendo una gran cantidad de código. Existe un límite para la longitud del código, luego de lo cual se vuelve más y más difícil de administrar si se escribe de forma escrita. Me gusta el procedimiento para cosas más pequeñas, como jugar con algoritmos.

0

Si no está bien organizado, su código base se convertirá en su propio Zebra Puzzle. Agregar más código es como agregar más personas/animales/casas a tu rompecabezas, y pronto tienes 150 diversos animales, personas, casas y marcas de cigarrillos en tu rompecabezas y te das cuenta de que solo te tomó una semana agregar 3 líneas de código porque todo está tan relacionado que tarda una eternidad en asegurarse de que el código todavía se ejecute como usted lo desea.

El paradigma organizacional más popular parece ser Object Oriented Programming, si puede dividir su lógica en pequeñas unidades que pueden construirse y usarse independientemente una de la otra, entonces encontrará errores mucho menos dolorosos cuando ocurran.

3

Todas las demás respuestas son geniales. Añadiré dos cosas.

  1. El control de código fuente es obligatorio. Supongo que estás en Windows aquí. VisualSVN Server es gratis y tal vez 4 clics para instalar. TortoiseSVN también es gratuito y se integra en Windows Explorer, evitando las limitaciones de VS Express sin complementos. Si crea demasiados errores, puede revertir su código y comenzar de nuevo. Sin control de fuente, esto es casi imposible. Además, puede sincronizar su código si tiene una computadora portátil y una computadora de escritorio.
  2. La gente va a recomendar muchas técnicas como pruebas unitarias, burlas, inversión de control, desarrollo controlado por prueba, etc. Estas son buenas prácticas, pero no trates de meter todo en tu cabeza demasiado rápido. Debes escribir código para mejorar al escribir código, así que trabaja estas técnicas lentamente en la escritura del código. Tienes que gatear antes de caminar y caminar antes de poder correr.

¡La mejor de las suertes en tus aventuras de codificación!

2

Los errores son comunes a todos, profesionales o no.

Cuanto más grande y distribuido sea el proyecto, más cuidadoso debe ser. Una mirada a cualquier base de datos de errores de código abierto (por ejemplo, https://bugzilla.mozilla.org/) lo confirmará por usted.

La industria del software ha evolucionado varias programmingstyles y standards, que cuando se usan a la derecha, hacen que el código incorrecto sea más fácil de detectar o limitado en su impacto.

Por lo tanto, el entrenamiento tiene una muy buena calidad de código ... Pero al final del día, los errores aún se cuelan.

2

Si solo es un programador aficionado, aprender TDD y OOP completos puede implicar más tiempo de lo que está dispuesto a aportar. Por lo tanto, suponiendo que no quiere dedicarle tiempo ellos, algunas sugerencias de fácil digestión de reducir los errores son:

  1. Mantenga cada función de hacer una cosa. Sospeche de una función de más de, digamos, 10 líneas de longitud. Si crees que puedes dividirlo en dos funciones, probablemente deberías hacerlo. Algo que te ayudará a controlar esto es nombrar tus funciones de acuerdo con lo que están haciendo exactamente. Si encuentra que sus nombres son largos y difíciles de manejar, entonces su función probablemente esté haciendo demasiadas cosas.

  2. Convierta las cadenas mágicas en constantes. Es decir, en lugar de utilizar:

    personas [ "madre"]

uso en lugar

var mom = "mom"; 
people[mom] 
  1. diseño de sus funciones ya sea a hacer algo (comando) u obtener algo (consulta), pero no ambos.

Una toma extremadamente corta y digerible en OOP está aquí http://www.holub.com/publications/notes_and_slides/Everything.You.Know.is.Wrong.pdf. Si obtienes esto, tienes la esencia de OOP y estás bastante francamente por delante de muchos programadores profesionales.

1

Lo que realmente cambió mis probabilidades frente a la complejidad del código y los errores estaba usando un estándar de codificación: cómo colocar los corchetes y así sucesivamente.Puede parecer aburrido e inútil, pero realmente unifica todo el código y hace que sea mucho más fácil de leer y mantener. Entonces, ¿usas un estándar de codificación?

Cuestiones relacionadas