¿Cómo leer miles de líneas de código sin ninguna documentación? [cerrado]


12

Anteriormente estaba buscando un buen control TimeLine para un proyecto WPF. Encontré una respuesta aquí que me dirige a este proyecto CodePlex .

Ahora quiero cambiar el código para satisfacer mis necesidades culturales. ¡Pero hay algunos desajustes!

Mi pregunta es:

¿Cómo interactúas con miles de líneas de código?

EDITAR:

¡Cualquier atajo será genial!


3
Pide un aumento. Siempre ayuda. (pueden motivar esto)
Nombre para mostrar el

2
golpea tu cabeza contra el escritorio hasta que todo se aclare.
jellyfishtree

19
¿Cómo te comes un elefante? ... Un bocado a la vez.
Bill

1
@Jalal Eso es lo que quieren que pienses.
Mateen Ulhaq

2
@DisplayName, se ha demostrado que el enfoque de la zanahoria y el palo para la motivación es una solución pobre para cualquier trabajo que requiera una habilidad cognitiva rudimentaria. La ciencia de la motivación es más compleja que el sistema de recompensas. Echa un vistazo a 'Drive: la sorprendente verdad sobre lo que nos motiva' de Dan Pink, es una lectura asombrosa. O mira este video de YouTube para una versión condensada. youtube.com/watch?v=u6XAPnuFjJc
Ryan Taylor

Respuestas:


37

Agrega comentarios al código fuente cuando lo ha entendido lo suficiente como para poder hacerlo. Refactorice estos comentarios vigorosamente a medida que entienda más y más.


3
+1 y una buena manera es escribir la documentación mientras explora el código fuente. ¿Y por qué enviar su contribución a los coordinadores de operaciones?

1
+1 Además, si modifica el código, asegúrese de cambiar también sus comentarios, para que las generaciones futuras no se confundan con lo que hizo. ¡Es una pena hacer todo ese documento y hacer que la gente lo odie porque está mal!
Michael K

1
Si el proyecto original está en un sistema de control de fuente distribuido (como git), sería beneficioso bifurcarlo, confirmar sus cambios de forma incremental y hacerlo de una manera para que pueda fusionar sus cambios de forma opcional más tarde con el original

8
  1. Paso a través del código
  2. Renombrar según sea necesario
  3. Refactorizar según sea necesario
  4. Repite hasta que entiendas completamente

... y el código te lo agradecerá. ;-)


77
Cambiar lugares aleatorios en el código de producción solo porque es más fácil, no es una muy buena idea. Solo las solicitudes de funciones deben causar una modificación del código, la refactorización es una solicitud de funciones. No importa qué tan bueno sea, el código se rompe, a veces los efectos secundarios estúpidos son de lo que dependen los clientes. Refactorice solo el código del que está muy seguro. Y recuerde, incluso las pruebas unitarias no garantizan nada.
Codificador

De acuerdo, pero refactorizar solo para probar un diseño puede ayudarlo a comprender por qué el código está escrito de la manera en que está (o confirmar que está en lo correcto si está mal hecho / extraño). No tiene que guardar esos cambios.
Ricky Clarkson

+1 codificador. Y esta respuesta actualmente ni siquiera menciona las pruebas unitarias. De miedo.
MarkJ

Lo sentimos, no significaba una refactorización importante. Estaba hablando más sobre refactorización menor, cosas de tipo de limpieza. Entonces, eventualmente, llega al punto de que el propósito del código es obvio.
John MacIntyre

5

Realice una sola acción, depure (una y otra vez) el código para encontrar cómo se lleva a cabo esa acción. ¡Escriba lo mismo en un lenguaje simple para obtener una mejor comprensión!


¡Normalmente hago esto también hasta que me enfrento a un proyecto que no puede ejecutarse en modo de depuración! ¡Siempre se bloquea durante el arranque! :( Pero funciona bien en Modo de lanzamiento: S
Afriza N. Arief

@afriza QUÉ MIERDA. Ese es un código realmente malo, verifique qué errores le da.
Daniel S

@afriza, lo primero que hay que arreglar!

4

Algo que Joel Spolsky escribió cuando estaba en su blog (no puedo encontrar el artículo ahora) realmente me quedó grabado en relación con esto:

Dijo que el código no es un lenguaje humano natural, pero que como programadores, fácilmente podemos pensar que sí lo es y que deberíamos poder leerlo como tal. En consecuencia, muchos de nosotros miramos el nuevo código y esperamos poder simplemente "leerlo" y entenderlo de inmediato, como si fuera un bloque de texto en inglés.

Así que creo que la clave es básicamente ser lento, metódico y científico. Y como han dicho otros, comente (e incluso refactorice) a medida que avanza. No caigas en la mentalidad de "Debería mirarlo y entenderlo de inmediato".

Ah, y sí, todavía caigo en esta trampa a veces. "Haz lo que digo, no lo que hago", y todo eso. :)


El hecho es que el texto en inglés que puedes "leer" es generalmente lineal, la razón por la cual el código es a menudo difícil de digerir al principio es generalmente porque no es lineal y el truco es simplemente descomponerlo. La gran cantidad de modismos de implementación diferentes que usan los desarrolladores generalmente tampoco ayuda, pero la primera etapa generalmente es ejecutar el código a través de un depurador y usar puntos de interrupción para ver qué es qué. Intentar leerlo es un ejercicio bastante inútil. En serio, ¿cuándo fue la última vez que leíste el código que escribiste? (principio a fin, eso es)
ocodo

En realidad, el código bien escrito es fácil de leer, pero no como un texto. Simplemente escanee para ver los bloques de construcción y comprender la estructura central, no es necesario leer todo. Sin embargo, los enfoques de codificación erróneos, como el viejo código skool, o el abuso de SOLID y patrones pueden dificultar esta tarea.
Codificador

4

SE-Radio entrevistó a Dave Thomas sobre este mismo tema

Este episodio de podcast tiene muchos consejos y técnicas para ingresar a la 'cultura' del proyecto y comprender cómo vivían los habitantes originales.


La parte hilarante sobre la experiencia de Dave Thomas es que la documentación, más allá de una descripción general de alto nivel, es (casi) sin excepción peor que ninguna documentación. (En mi experiencia, es porque la mayoría de la documentación es repetitiva, lo que proporciona una comprensión a nivel superficial del "qué" o "cómo", que invariablemente se deja desactualizado, hasta el punto de ser engañoso).
Michael Kropat,

2

Tuve que hacer esto recientemente con un proyecto de más de 100,000 LOC. Mi primera idea fue que es más fácil ver patrones de gráficos de 100 o incluso 1000 nodos que de 100,000 líneas de texto.

Así que pasé 45 minutos y escribí un programa corto de Python (<100LOC) para analizar lo que necesitaba de él y dibujar las relaciones de objeto. Me genera Graphviz fuente, que es un muy fácil de lenguaje para generar. (No hay nada especial sobre Python aquí: Ruby o C # o Common Lisp o lo que sea que pueda hacerlo igual de bien).

En otros proyectos, he visto a personas usar Graphviz para dependencias de módulos, gráficos de llamadas, historial de versiones, todo tipo de cosas. La mejor herramienta de visualización de programas jamás vista.

(Tal vez sea porque tomé compiladores , pero me parece extraño que cuando un programador se enfrenta a un problema, la respuesta parece ser siempre "¡escribir un programa!", Excepto cuando el problema involucra el código fuente de un programa.: - )


1

Paso a paso en el depurador mientras se ejecuta, es casi la única forma de entender una nueva base de código grande.


2
Esa no es una opción práctica cuando tienes miles de líneas de código (especialmente cuando hablamos de decenas o cientos de KLOC), y / o si parte de ese código está en plantillas. Para controlar una nueva base de código (y mal documentada), también se debe involucrar a la empresa e intentar comprender el contexto en el que se supone que se ejecuta el código. Si se puede pasar por el código con un depurador y obtener una comprensión de la misma, que la base de código no era tan grande como para comenzar con (haciendo que el uso de un depurador en lugar innecesario en la mayoría de los casos.)
luis.espinal

Por desgracia, si la base del código es demasiado grande para depurar en un depurador. Ver el código reaccionar a una entrada y salida conocidas ayuda a transformar el conocimiento de "qué" a "cómo". La pregunta "por qué" nunca puede responderse solo con un depurador, pero puede haber comentarios de fuente en línea que puede ver en el IDE a medida que depura.
Grrussel

@grrussel Tengo que estar en desacuerdo porque no es lo que hago ... ¡No tengo ni idea de si soy representativo o no! Puedo ver usar el punto de interrupción impar (pero todavía no paso explícitamente) y uso las funciones IDE para permitirme relacionar una pieza con otra.
Murph

1

Comprenda que realmente no hay atajos para hacer grokking en plenitud. (Y si tiene problemas con esa frase, su educación ha sido MUY descuidada. Es de "Stranger In a Strange Land", de Robert A. Heinlein).

Léalo, una página a la vez, una rutina a la vez. Añadir comentarios. Dibuja imágenes de las principales estructuras de datos. Reconocer algoritmos. Recurrir a conocimientos previos.

Resista la tentación de poner en marcha el depurador. La ventana del depurador es demasiado pequeña: ves una línea a la vez, pero realmente no ves dónde has estado ni a dónde vas.


El depurador explica algunas convenciones de las convenciones del escritor de código original sobre lo que se espera dentro de las variables (por ejemplo, ¿esperan la ruta completa o el nombre de archivo o la ruta relativa?) Y muchas otras cosas, por lo que todavía es importante en mi opinión
Afriza N. Arief

2
-1 por pensar que eres genial porque usas la palabra "grok"
Carson63000

1

Hagas lo que hagas, escribe tanto como puedas a medida que avanzas para que nadie termine en la misma posición que tú.


1

necesitas usar pistas. obtenga una pista de lo que debe buscar y utilice ampliamente la funcionalidad de búsqueda de su entorno o IDE que puede llevarlo a la sección deseada del código en la que necesita realizar cambios.

leer 14 mil líneas de código java no tiene ningún sentido. La funcionalidad de búsqueda es su salvavidas


0

Diferentes personas tienen diferentes estilos de aprendizaje, así que YMMV. Lo primero que hago en esta situación es leer todo el código base al menos una vez. Eso me da una idea general de dónde está todo. Luego elijo una sección para examinar con más detalle. Las estructuras de datos serían un buen lugar para comenzar. Una vez que tengo una idea general de lo que está sucediendo, hago lo mismo con otra parte del código que interactúa con la primera. Después de suficientes iteraciones, tengo una buena idea de cómo funciona el código.


0

La mejor manera, como con toda la programación, no solo grandes fragmentos de código no comentado, es dividirlo en pedazos. Esto es algo que debe hacer en su cabeza, así como visualmente en el código. Esto puede significar agregar grandes comentarios en negrita o saltos de línea múltiples. Esto ayuda mientras te desplazas para ver las piezas. Intenta encontrar los fragmentos lógicos de código.

Por supuesto, a medida que entiendes las partes, coméntalas por lo que sabes en ese momento, posiblemente poniendo notas sobre algo que no entiendes.

También recomendaría no tratar de entender toda la pieza desde el principio. En su lugar, trate de comprender las piezas que necesita saber ahora y trabaje en el resto más tarde.


0

Comenzaría usando Leo Editor en modo @shadow con el uso activo de nodos clonados . Esto permite agregar notas y comentarios para cada sección de código en estudio sin cambiar el código , y las anotaciones siempre estarán en contexto, al lado del código del que está hablando. Aquí hay un ejemplo de flujo de trabajo de los documentos:

Por ejemplo, cuando reparo un error en Leo, creo un nodo ordinario para representar el error. Este nodo de error es mi vista de todos los datos en el código fuente de Leo que se relacionan con el error. Cuando descubro el código relacionado con el error, clono sus nodos y los muevo debajo del nodo de error. También agregaré nodos ordinarios como hijos del nodo de error. Estos nodos contienen el informe de error original, descripciones de cómo solucioné el error, datos de prueba o cualquier otra nota que desee conservar.

Una vez que he creado el nodo de error, me concentro solo en ese nodo y sus hijos. Puedo examinar el nodo de error y sus hijos sin tener que saltar el contorno. Todo lo que necesito está en un solo lugar. Cuando llego a arreglar el error, puedo hacerlo cambiando los clones. Nuevamente, no tengo que saltar el contorno. No importa cuán grande o complejo sea todo el esquema: solo estoy tratando con el nodo de error y sus hijos. Este enfoque extremadamente estrecho hace que sea mucho más fácil corregir errores.


0

Dibuje diagramas de la fuente: las relaciones de datos, las relaciones funcionales, las relaciones de objeto. Determine la agregación, el flujo de datos y el flujo de código. Las imágenes son mucho mejores que los comentarios para esto, y se pueden mantener separadas del código.


0

Antes de refactorizar algo, escribe pruebas. Muchas pruebas. Pruebas muy específicas de pequeños bloques de código que son al menos invocables, ya que dependerá de cómo se escriba su desorden heredado.

Para empezar, la ventaja de escribir pruebas es que debe tener algún tipo de comprensión del código antes de poder probarlo, por lo que, con suerte, cada prueba que escriba tendrá un poco de conocimiento. También puede comentar mucho las pruebas con sus suposiciones junto con las afirmaciones.

Al hacer la prueba primero, no corre el riesgo de alterar algo en el código que tiene efectos secundarios que no puede conocer. También tendrás una red de seguridad cuando vengas a refactorizar el código.


0

Utilizo herramientas como doxygen, para generar un diagrama de clase general, que agrega mi comprensión de lo que hace cada una de las clases.

Luego tomo algunos errores fáciles de la cola de errores (antes de que mi gerente me asigne uno difícil: P), luego ejecuto esa funcionalidad en el depurador e intento generar un flujo de datos aproximado o un modelo de flujo de código.

Por ejemplo, la funcionalidad de exportación en algún software: así que trato de entender cómo se leen los datos de origen, desde qué parte del código (interfaz base) puedo evaluar si los datos se leen correctamente usando mi clase y diagramas de flujo de código, de qué clases son responsables qué tipo de exportaciones, etc. Creo que la mitad de la comprensión se realiza, una vez que tenga los diagramas de clase y los diagramas de flujo.


0

Acérquese a un defecto trivial, por ejemplo, una excepción NullPointerException. Al principio, evite cualquier cosa relacionada con la concurrencia, cualquier cosa que, por su naturaleza, implique comprender gran parte del código a la vez.

Una vez que haya solucionado algunos errores, probablemente tendrá una muy buena idea. Funciona para mí, en cualquier caso.


-2

Básicamente, la acción para escribir un código limpio debe comenzar desde el diseño. Si estamos codificando en el lenguaje OOP, crea un UML, compártelo con tus compañeros y convencerte de que el diseño no es ambiguo. En cualquier caso, los desarrolladores deberíamos convencernos de que el diseño resuelve el problema y no los ambigüedades.

Cuando se trata de codificación, debemos asegurarnos de que el diseño se convierta en código, es decir, una entidad a una clase o estructura, una operación para funcionar, etc.

Y revisé un documento técnico http://queue.acm.org/detail.cfm?id=2063168 que habla sobre el estilo de codificación o cómo podemos usar el espacio, la sangría, la variación de fuentes como la mayoría de los IDE podemos usar para escribir MUCHO Código CLEANER donde los humanos podemos entender tanto como las máquinas. Hace más hincapié en escribir código sin comentarios para que nuestro código aparezca como párrafos en sí.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.