¿Cuáles son los ‘conceptos difíciles’ más comunes para entender cuando se aprende a programar?

Algunos conceptos se explican mejor por otro estudiante que acaba de entender un concepto que por un profesor que encuentra casi todo lo obvio.

Así que mi lista de conceptos difíciles de aprender está hecha de las muchas cosas que la mayoría de las personas hacen mal, incluso con muchos años de experiencia.

  • Casos de borde

Casi todos pueden obtener la versión de un algoritmo que funciona feliz con un poco de trabajo.
No todos pueden obtener la permutación de posibilidades y casos de borde a la perfección.

  • Código de organización

Casi todos pueden obtener una hoja de código mal diseñado que no se puede mantener, escupir un resultado coherente.
Ni siquiera todos pueden entender cuando ven un gran desastre, ¿por qué es un desastre?

  • Evitar la repetición

Esta complejidad surge de la necesidad de tener un sistema enorme _sometimos_ en su cabeza al mismo tiempo.
Diseñar bibliotecas pequeñas y hacer un diseño de abajo hacia arriba ayuda, pero llegará el momento en que necesite tener esta enorme monstruosidad en su cabeza al mismo tiempo, y fallará.

  • Concurrencia

Si bien hay muchas estrategias para lidiar con muchas cosas que suceden a la vez con su realidad, tener muchas partes móviles es difícil. Ya que es difícil tener un sistema con miles de piezas pequeñas que se hablan entre sí.

Muchas de estas situaciones son solo casos particulares derivados del artículo de Brooks http://en.wikipedia.org/wiki/No_…, no se puede evadir la complejidad esencial de la realidad haciendo trucos dirigidos a la complejidad accidental de la programación.

Programar es difícil, porque la realidad es dura.

Recursión, y cualquier concepto o construcciones que dependan de la recursión.

Cosas como afirmar el problema correcto (y expresarlo correctamente), la abstracción, la simplicidad en el diseño, etc., son todas luchas, pero son más viajes que conceptos que una vez que comprendes, tienes.

El paralelismo y la concurrencia son difíciles de razonar, pero no son difíciles de comprender conceptualmente. Descubrí que las personas pueden obtener los inconvenientes fundamentales de la concurrencia con bastante rapidez, incluso llegar al punto en el que realizan tomas de bote decentes en algoritmos y diseños concurrentes, pero eso no significa que puedan sintetizar buenos diseños concurrentes. Los conceptos son fáciles de entender y difíciles de aplicar.

Creo que los punteros solo son difíciles en los idiomas que admiten tipos de valor también. No es el concepto de un puntero que es difícil de entender, se trata de punteros y no de punteros y referencias que actúan como punteros y actos como valores que es difícil. El concepto de punteros no es difícil, es hacer un seguimiento de todos los otros conceptos similares que pueden aplicarse simultáneamente.

Creo que la mayoría de los programadores finalmente entienden cómo usar punteros, entienden cómo enlazar y hacen muchas cosas complicadas con las que un principiante tendría problemas. Puede tomarles un tiempo aprenderlo, pero eventualmente lo obtienen si se esfuerzan lo suficiente.

Siento que el concepto más difícil de enseñar es cómo casarse con el arte y la ciencia de la programación. ¿Cómo se escribe una aplicación que sea fácil de entender para la computadora y agradable y simple para que la lea un humano? El problema es que, para hacer esto, necesitas tener un pie en ambos campos. Debe estar pensando en las necesidades de las máquinas y en cómo prefiere recibir instrucciones, al mismo tiempo que considera lo que las personas necesitan para mirar realmente el código, percibir de forma rápida y sencilla el funcionamiento y los conceptos involucrados, y cómo usarlo.

La mayoría de los programadores no son precisamente agradables y la mayoría de ellos tienden a pensar sobre sí mismos con bastante frecuencia. Entonces, se necesita un programador verdaderamente brillante o socialmente inclinado para hacer esto y simplemente no hay muchos de ellos.

Quora User tiene razón al mencionar los punteros, pero yo iría un paso más general. Diría que la indirección es el concepto difícil aquí (que es lo que hace que los punteros sean difíciles de entender para los principiantes).

Además, subprocesos / concurrencia en lenguajes de programación con datos mutables.

He pasado mucho tiempo enseñando a los nuevos programadores las cuerdas, tanto en el contexto académico como en la industria. Así que esto viene principalmente de esa experiencia.

El mayor problema inicial es entender la ejecución procesal. Comprender la ejecución de los procedimientos parece realmente simple: un programa simplemente ejecuta los pasos que le dices y nada más. No hay supervisión racional, solo ejecución. Cuando ‘simula un programa en su cabeza’, los nuevos programadores no limitan la ejecución a lo que está allí, sino el contexto de fondo de lo que están tratando de hacer, que no se expresa como un código.

Creo que esta es la razón por la que los cursos de programación le dan problemas en los que rastrea la ejecución de un programa sin un significado claro (por ejemplo, int * magicfoo = y algún otroVarVar) porque todo tiene un significado limitado, no intenta imponer sus expectativas sobre lo que programa está tratando de hacer

También creo que esta es la razón por la que el aprendizaje de código codificado en términos de jugar un videojuego tiene mucho sentido. La mayoría de los jugadores, entiendan que un juego ejecuta sus comandos a ciegas.

Más allá de eso, creo que el problema mucho más grande que obstaculiza a los programadores nuevos y a los más antiguos es una gran comprensión de la abstracción: cómo diseñarlos y construirlos, y dónde son apropiados. Una vez que entienda, la ejecución del procedimiento, los pasos que puede dar están circunscritos y debe construir pasos más ricos a partir de pasos más pequeños.

Gran parte de este problema se debe a que los primeros idiomas que enseñamos a las personas son Java y Python, que no admiten de forma nativa abstracciones. Y a diferencia del pensamiento procedimental, la noción de construir abstracciones no tiene un análogo a otra actividad que nos gusta jugar videojuegos.

Hay problemas más pequeños y específicos, como comprender qué es una variable y el papel que desempeña dentro de una función. Este es un obstáculo importante, pero creo que es algo que se debe a un error en la ejecución de los procedimientos.

Punteros (*, **, &)

Los punteros varables de C ++ (y los punteros de función, en menor medida) son lo que más explico en nuestro CS.

Los subprocesos múltiples, lo que es y por qué no es tan simple como parece, surgen muchas cosas.

El subcampeón sería una recursión, y por qué querrías hacer tal cosa.

No es tanto un concepto sino una habilidad: traducir un problema en algo que una computadora podría funcionar y resolver.

Aquí hay algunos principios tomados libremente de las Perlas de Programación de Jon Bentley, Capítulo 1.

Indicar el problema correcto.

“El mayor desafío para cualquier pensador es plantear el problema de una manera que permita una solución”. – Bertrand Russell (filósofo)

Haciendo un diseño simple.

“Un diseñador sabe que ha llegado a la perfección no cuando ya no hay nada que agregar, sino cuando ya no hay nada que quitar”. -Antoine de Saint-Exupéry

Programación de perlas es un gran libro, por cierto.

Determinando el nivel correcto de abstracción / s. Dicho de otra manera, diseñar buenas API es difícil, donde “bueno” se aplica a la facilidad de refactorización, a la profundidad correcta y al alcance de la generalidad para el alcance del problema, a la facilidad de las pruebas. Cuando aprende por primera vez, es posible que no sepa cómo diseñar uno, pero debe saber cuándo lo está utilizando para que pueda comenzar a ver por qué son buenos.

Refactorización. Si aprende a resolver un problema de una manera, puede adquirir el hábito de resolver problemas similares de la misma manera, sin darse cuenta de que podría darle la vuelta al problema, resolverlo de adentro hacia afuera o mover las cosas para llegar al problema. misma solución más rápida. Puede que no sea el concepto “más difícil” de aprender, pero ciertamente es uno de los más importantes.

Mi primer idioma fue Fortran IV, en 1974. Me tomó aproximadamente una semana aprenderlo leyendo Guía de programación de Fortran IV: Daniel D. McCracken: 9780471582816: Amazon.com: Libros. (Sorprendentemente, el libro todavía está disponible; aunque el mío se ha ido hace mucho tiempo).

En ese momento tuvimos que marcar nuestros programas en tarjetas y enviarlos para su ejecución. Tenemos nuestras impresiones al día siguiente. Mi Hello, World estaba resolviendo una ecuación cuadrática dados los 3 coeficientes. Bastante aburrido, ¿no? Pero también lo es producir “Hola, Mundo” como salida. 🙂

No le pidió a la computadora que hiciera lo que pensaba que estaba preguntando si la computadora hace algo diferente a lo que usted quiere o espera. Que tener algo que funcione es solo el 10% de la manera de tener un producto para vender.

La primera vez que ves “hola mundo” en una pantalla negra te enamoras de él y te hace quererlo más. No es difícil si lo quieres. Una vez que haya terminado con el aprendizaje de un idioma, comenzará a pensar qué hacer ahora. Te mueves a otro idioma. No es difícil si te gusta.

Mi primer idioma fue QBASIC, el que vino con DOS. Ayer, Tim Hofstetter me dijo que no necesitaba usar números de línea, ya que solo eran necesarios para las versiones antiguas de BASIC (para las que estaban escritos los libros que teníamos en casa).

Me mudé a otros idiomas hace mucho, mucho tiempo, pero creo que es bastante claro que aprendí algo nuevo 20 años después … No puedo dejar de preguntarme qué aprenderé sobre los idiomas que creo que sé hoy en otros 20 años. 😀

Resumiendo el problema en cuestión.