¿Es normal que un programador no tenga una claridad del 100% sobre su propio código a veces? [cerrado]

19

No soy un programador experto, así que puede ser por eso, pero he notado que cada vez que creo un código complejo (como un juego de ajedrez que hice recientemente), puedo escribir el código correcto para que el programa funcione, aunque me parece que más tarde, ¡o incluso unos segundos después! - A menudo tengo que hacer una pausa y pensar, ¿cómo funciona esto?

No solo eso, sino que también tiendo a no pensar en el código, y en su lugar simplemente escribo. Por ejemplo, en mi juego de ajedrez, decidí usar una matriz de cinco dimensiones para procesar movimientos, y descubrí que podía hacer esto sin pensar demasiado. Sin embargo, cuando me detuve y lo leí, me resultó difícil entender todo el concepto de cinco dimensiones, y me llevó unos minutos comprender completamente lo que hice y cómo funciona el código.

¿Es normal que los programadores cuando escriben código complejo no entiendan lo que hacen la mitad del tiempo?

83457
fuente
13
Es una señal de que estás tratando demasiado de ser inteligente. Debe escribir un código más simple y modular si tiene problemas para leerlo usted mismo.
SHODAN
3
Para agregar a otras respuestas (perspicaces) en el sentido de que huele a código demasiado complicado o mal diseñado (no se preocupe, la mayoría de nosotros tuvimos que pasar esa fase): Documento . Tanto al dar nombres apropiados a las variables / métodos / clases / módulos, al agregar una descripción adecuada a cada función, y al (cuando no veas lo contrario) escribir un simple comentario en línea que explique por qué y cómo estás usando un fragmento complejo de código.
SJuan76
44
Yo no tengo 100% de claridad sobre mi propio código.
CodesInChaos
2
Esa matriz 5D realmente parece que podría usar algo de abstracción.
3
¿Algún desarrollador tiene 100% de claridad sobre su código en todo momento?
Johan

Respuestas:

30

No, no es normal 1 . Al menos, no es normal para los buenos programadores. Probablemente sea normal que alguien aprenda a programar.

Escribir software no es solo juntar líneas de código hasta que funcione. Debe trabajar conscientemente para que el código sea fácil de entender. Un programador que respeto mucho una vez me dijo "el código se lee mucho más veces de lo que se escribe" . Si bien eso debería ser completamente obvio, era un hecho que no había sabido hasta que él me lo dijo. Gran parte de su código se escribe solo una vez, tal vez reescrito una o dos veces más, pero terminará leyendo el código a menudo durante la vida útil del software.

Si encuentra que el código es difícil de entender minutos después de escribirlo, es una señal de que su código es demasiado complejo. Deja de agregar código y descubre una mejor manera. Por ejemplo, una matriz de cinco dimensiones casi nunca es una buena idea. Incluso los programadores realmente inteligentes tienen dificultades para comprender una estructura de datos tan compleja.

El mismo programador que me habló de la legibilidad del código también dijo "muéstrame tus estructuras de datos y puedo decirte cómo funciona tu código" . Es decir, un buen código comienza con estructuras de datos limpias y comprensibles. Si diseña sus datos correctamente, el código es casi una preocupación secundaria. Es cierto que esta afirmación es un poco exagerada porque el software es obviamente más que solo datos, pero comienza con datos. Por lo tanto, trabaje para crear estructuras de datos limpias y fáciles de entender y el código será considerablemente más fácil de entender.


1 Ciertamente, existe un código que es muy complejo y difícil de entender incluso para los programadores más inteligentes. Algunos problemas son inherentemente complejos. Sin embargo, me aventuraría a decir que la gran mayoría del código escrito por la gran mayoría de los programadores no es ese tipo de código.

Bryan Oakley
fuente
8
[1] Desde un punto de vista más pesimista, es normal pero no es bueno.
Dan
1
Si la "matriz de cinco dimensiones" es simplemente un mapa de una tupla de 4 o una tupla de 5 a una estrategia, el autor podría haber utilizado una tabla hash o una función de búsqueda auxiliar. Sin embargo, si el autor pasa la mayor parte del tiempo codificando la mecánica de inicializar la matriz (bucles for anidados), entonces el "conocimiento del algoritmo" real se ahogará en la pila de "código mecánico". Los programadores buscan mantener el último tipo de ruido separado. Por lo tanto, los buenos programadores deben saber cómo escribir bibliotecas principalmente para albergar esos códigos mecánicos.
rwong
La matriz 1-D es una línea, 2-d es una cuadrícula, 3-d es un cubo, 4-d es una línea de cubos, 5-d es una cuadrícula de cubos, etc. pero no veo un uso para una estructura de datos tan compleja cuando se trata de ajedrez.
user2785724
15

Hay dos tipos de esto: 1.) confusión 2.) ignorancia feliz

El primero es malo y puede desaparecer con el tiempo y la experiencia.

El segundo es bueno si los proyectos se hacen más grandes: si tiene que recordar cada detalle de implementación solo para poder trabajar con su código, hay algo mal en él (consulte "ocultación de información").

Cada desarrollador olvidará cómo funcionaba el código, por lo que lo escribe de manera que otro nuevo desarrollador lo entienda y pueda mantenerlo sin romper otras partes del programa que él también desconoce.

Así que "no saber" es en realidad una constante en el desarrollo de software, es solo cómo o si lo administras.

telep
fuente
1
Aquí está tocando algo importante, que es lo vital que es programar usando patrones y convenciones de sentido común , porque los detalles de implementación se olvidan. Pero si los patrones y convenciones en el código son razonables, es bastante fácil recuperar los detalles del contexto cuando sea necesario. Por otro lado, si el código es todo monolítico, inescrutable y demasiado inteligente, no solo olvidará eventualmente los detalles, sino que otros programadores que intenten mantener el código lo tendrán mucho más difícil.
Craig
12

Yo diría que es más común de lo que la gente quiere admitir. Incluso Brian Kernighan aludió a eso:

La depuración es el doble de difícil que escribir el código en primer lugar. Por lo tanto, si escribe el código de la manera más inteligente posible, por definición no es lo suficientemente inteligente como para depurarlo.

Cuando conducimos a la tienda, realizamos una secuencia de ajustes detallados en las posiciones de los pedales y el volante. Esto es muy fácil en este momento. Ahora, imagine si registró esos ajustes en papel y se los dio a un amigo que necesitaba instrucciones para llegar a la tienda.

Del mismo modo, nos gusta escribir código en un nivel de abstracción, pero nos gusta leerlo en múltiples capas superiores de abstracción. Por lo tanto, nuestra forma preferida de escribir y leer código está en conflicto. Eso significa que hacer que el código sea fácil de leer suele ser un paso independiente y consciente, con un conjunto diferente de habilidades.

Lo que hace a un buen programador es que cuando tienen dificultades para leer lo que acaban de escribir, crean una abstracción en ese punto. Un mejor programador lo hace varias veces, cada vez más exigente. Eventualmente, los programadores experimentados comienzan más adelante en el proceso, pero a menudo aún pueden ver margen de mejora después de leer lo que acaban de escribir.

Karl Bielefeldt
fuente
Tengo que estar en desacuerdo con Brian en eso, me encanta depurar, soy una de las pocas personas que conozco en la industria que lo hace, pero no califico el código que escribo tan alto.
James Snell el
@JamesSnell No dijo que la depuración es mala o desagradable, simplemente que es difícil, y que la depuración de código complicado es aún más difícil.
cbojar
5

Creo que esto es algo que desaparecerá con experiencia.

Si está escribiendo sistemas complejos, debe tener la capacidad de escribir código limpio y fácil de mantener que tanto usted en el futuro como alguien más en el futuro puedan comprender. Entonces, en esencia, lo que estás haciendo ahora no es escalable.

Tendrás muchos momentos en los que mirarás un código que escribiste hace 6 meses y pensarás "¿qué diablos está pasando aquí?", Pero si sucede un día después de que escribiste el código, debes pensar 'limpio código 'más.

Fuente: nunca usó una matriz de 5 dimensiones :)

Erez Eshkol
fuente
3
@ 83457 - porque una matriz 5d es un modelo pobre de un problema 2d. Si realmente cree que es un buen código, colóquelo en codereview.stackexchange.com y vea qué respuestas obtiene.
James Snell
2
@ 83457 - Si ES 'confuso como el infierno', te has respondido a ti mismo. Es posible que una matriz 5-D no sea confusa, pero probablemente no lo sea para la mayoría de nosotros, sin importar nuestro nivel de habilidad.
dbasnett
2
@ 83457 ser confuso como el infierno ya debería ser una muy buena motivación para no usar eso.
Fabio Marcolini
3
Mientras tenga una buena razón para cada dimensión, no veo una razón para evitar una matriz 5D. Quizás haya una mejor solución, como un diccionario con una clave compleja o varias matrices de dimensiones inferiores, pero me imagino que una matriz 5D es apropiada para un problema complicado como una IA de ajedrez.
CodesInChaos
2
@CodesInChaos Excepto que esos no son solo matrices, representan secuencias significativas (por ejemplo, árboles de decisión anidados). Al nombrarlos de manera apropiada y darles tipos para que no se puedan abusar de ellos (incluso si esos tipos son envoltorios sobre arreglos), hace que el código sea más claro y menos propenso a contener errores, por casi cualquier costo.
deworde
5

"Normal" es muy subjetivo, por eso digo: es muy común, pero debe evitarse.

Una de las características del "buen código" (escuché que tal cosa existe) es la claridad: debe ser tan clara como lo permitan los problemas subyacentes. Si el problema es complejo, el código también lo sería, pero esa es una complejidad inherente , en oposición a la complejidad accidental (escuché por primera vez esta distinción en la charla de Rich Hickey ) introducida por el mal uso o no de las herramientas, patrones, técnicas y practicas.

Hay casos en que la falta de claridad es aceptable incluso cuando el problema no es muy complejo, por ejemplo, si escribe un sitio de promoción que sabe que durará mientras dure la campaña de marketing. Ese es un código desechable que no debe ser mantenible. Para otros (y la mayoría de los casos), no es aceptable, porque mantener dicho código costará mucho. Sin embargo, es común.

Relacionado:

  • Cuando comprender significa reescribir : artículo sobre el problema de comprender el código.
  • ML eficaz : una larga charla sobre, entre ML / OCaml, cómo escribir el código para "lectores" (es decir, mantenedores): "Favorecer a los lectores sobre los escritores". Recomiendo ver eso sin importar el idioma que uses.
scriptin
fuente
2

No creo que sea normal, pero para programas muy complejos, como el programa de ajedrez que mencionas, creo que ciertamente es posible.

Hace muchos años, cuando acababa de salir de la escuela de posgrado (por lo que todavía era relativamente inexperto escribiendo grandes programas), escribí mi primer compilador real. El análisis fue sencillo, pero luego necesitaba apuntarlo a cuatro conjuntos de instrucciones de microprocesador diferentes. Tenía la intención de escribir el compilador en su propio idioma, por lo que primero utilicé solo las características del lenguaje que realmente necesitaba, escribí el primer generador de código en lenguaje ensamblador y probé que generaba el código correcto para el subconjunto del idioma. Luego pude usar el compilador para compilarme a partir de entonces, y agregar las características restantes y también usarlas en el compilador mismo

Luego escribí los generadores de código de fondo para cada microprocesador, y probé que todos generaban el código correcto, pero aunque era correcto, no era muy óptimo. Entonces procedí a escribir optimizadores para cada generador de código.

Cuando estaba probando la salida de los generadores de código después de agregar toda la optimización, con frecuencia me sorprendía el código que generaba el compilador. A menudo no era la forma en que habría escrito el código a mano, pero era correcto y bastante conciso.

Cuando no era obvio para mí cómo el generador de código producía parte del código que hacía, traté de seguir la lógica a mano, pero a veces me rendí. Si hubiera agregado una gran cantidad de rastreo, habría podido seguirlo, pero no me molesté porque el código generado era satisfactorio y necesitaba continuar con otros proyectos.

tcrosley
fuente
Me parece que tiene una educación extremadamente buena con una base sólida, y que ha internalizado el conocimiento a un nivel muy alto. Supongo que esto es algo raro entre los programadores típicos. La mayoría de los programadores típicos (incluido yo) tienen que luchar para mantenerse al día con los conocimientos necesarios para la tarea de hoy, porque la tecnología cambia muy rápidamente.
rwong
@rwong Gracias. La mayor parte es experiencia: he estado escribiendo programas durante 46 años y no tengo intención de dejarlo pronto.
tcrosley
2

Hay muchas respuestas decentes aquí.

Tengo un par de opiniones sobre esto.

Una es que si no comprende por qué su código parece funcionar, entonces a) probablemente no (probablemente solo parece que funciona), yb) tampoco entendió el dominio del problema lo suficientemente bien cuando comenzó a codificar, o no dividió el dominio del problema en unidades más pequeñas y simplificadas antes de comenzar.

Mi otra opinión sobre esto es que la clave real es usar patrones de sentido común y convenciones en su código. Ese es un tema mucho más grande de lo que una pequeña publicación puede abordar. Pero busque buena literatura sobre el tema, incluidos algunos de los viejos recursos como los libros "Code Complete" y "Writing Solid Code".

Detalles de implementación cambio. La única constante real es el objetivo funcional del código. Si alguna vez escribe más de una función, olvidará detalles de implementación específicos y granulares con el tiempo. Pero ciertamente debe comprender cómo funcionan las piezas cuando las construye, y debe poder dibujar un diagrama del conjunto y comprender cómo funcionan juntas las piezas.

Si usa patrones y sigue convenciones de sentido común, será mucho más fácil volver a elegir los detalles de implementación específicos cuando vuelva a mirar el código. O cuando alguien que nunca ha visto el código lo mira por primera vez. Además, seguir esas convenciones y patrones a lo largo del tiempo significará que los detalles de implementación se destacarán de las convenciones y patrones en sí, lo cual es otro factor que hará que el código sea más fácil de comprender.

La mayoría de los problemas que enfrentamos con el software son complejos por naturaleza. El diseño de software es un ejercicio de gestión de la complejidad.

Craig
fuente
1

No lo llamaría normal , pero definitivamente puede suceder. Si le sucede poco después de escribir el fragmento de código en cuestión, supongo que su código es innecesariamente complejo y debe simplificarse, o simplemente se distrae fácilmente. :)

Pero si guarda su código, se concentra en otros proyectos y vuelve a él después de semanas, meses o incluso años, no es una gran sorpresa que tenga que resolverlo todo nuevamente.

Pero hay algo que puedes hacer al respecto. Por lo que dices, parece que no piensas lo suficiente sobre tu código mientras lo escribes, y por lo tanto estás dificultando que tu futuro yo entienda lo que está sucediendo. Use ese conocimiento para su ventaja: esta es la mejor motivación para producir un código bien estructurado, bien documentado y comprensible. Sabe por experiencia de primera mano lo que sucede cuando no se ocupa de la calidad de su código. Saber eso debería hacerte un mejor programador a largo plazo. Cuando colabore en proyectos de software, sus colegas lo agradecerán por producir un código comprensible. Y la tasa de defectos de su código también mejorará.

mindriot
fuente