¿Por qué es mejor para un programador diseñar el algoritmo antes de comenzar a escribir el código?

12

¿Un algoritmo apropiado realmente ayuda a mejorar la calidad y, en última instancia, la eficiencia de un programa?

¿Podemos producir un programa de buena calidad sin el algoritmo?

¿Es necesario un algoritmo apropiado en la programación moderna?

Jervis
fuente
55
Por definición, hay algún algoritmo, incluso si es tan malo que es bueno .
55
No tengo más remedio que codificar el código en lugar de pensar demasiado. La mayoría de las veces no hay un algoritmo glorioso para ningún estándar; Solo estoy tratando de pulir una mierda apestosa;)
Job
13
No puedo creer que esta sea una pregunta seria. Ver en.wikipedia.org/wiki/Algorithm
Steven A. Lowe
2
El título es razonable, pero el texto de la pregunta no lo es tanto. Creo que está preguntando si el algoritmo debe ser clavado antes de que uno pueda comenzar a escribir el código real.
Greg
99
Le digo que no ... siempre es mejor conducir sin rumbo hasta que encuentre su destino por accidente o se quede sin gasolina.
jmq

Respuestas:

29

Creo que esta pregunta plantea una perspectiva histórica.

En los "viejos tiempos" (de los cuales no soy testigo personal, así que esta es solo mi reconstrucción de esa época, siéntete libre de corregirme si experimentaste las cosas de manera diferente) El espacio HW y el rendimiento fueron nulos en comparación con los de hoy. Entonces, todo lo que la gente escribía tenía que ser muy eficiente. Por lo tanto, tenían que pensar mucho e investigar para inventar los mejores algoritmos para lograr el rendimiento de espacio / tiempo necesario para hacer el trabajo. Otro factor en esto fue que los desarrolladores estaban trabajando principalmente en lo que podríamos llamar infraestructura : sistemas operativos, pilas de protocolos, compiladores, controladores de dispositivos, editores, etc. Todo esto es utilizado por mucha gente, por lo que el rendimiento realmente marca la diferencia. .

Hoy en día estamos mimados por tener un HW increíble con procesadores multinúcleo y Gigabytes de memoria incluso en una computadora portátil básica (diablos, incluso en un teléfono móvil). Lo que naturalmente significa que en muchos casos, el rendimiento, por lo tanto, el algoritmo, dejó de ser el problema central, y es más importante proporcionar una solución rápida que proporcionar una solución rápida. OTOH tenemos montones de marcos que nos ayudan a resolver problemas y encapsulan una gran cantidad de algoritmos al mismo tiempo. Entonces, incluso cuando no estamos pensando en algoritmos, es muy posible que estemos usando muchos de ellos en segundo plano.

Sin embargo, todavía hay áreas donde el rendimiento es importante. En estas áreas, aún necesita pensar mucho sobre sus algoritmos antes de escribir el código. La razón es que el algoritmo es el centro del diseño, determinando muchas estructuras de datos y relaciones en el código circundante. Y si descubre demasiado tarde que su algoritmo no está escalando bien (por ejemplo, es O (n 3 ), por lo que se veía bien y rápido cuando lo probó en 10 elementos, pero en la vida real tendrá millones), es muy difícil, propenso a errores y lento para reemplazarlo en el código de producción. Y las micro optimizaciones no le ayudarán si el algoritmo fundamental no es el adecuado para el trabajo.

Péter Török
fuente
1
Que respuesta. ¡Es un privilegio tenerte aquí!
Jervis
55
Además, la computadora era mucho más cara que el programador, por lo que tenía sentido hacer que el programador trabajara más duro.
2
Tiene razón en que lo que estamos optimizando ha cambiado. Pero ahora se espera que manipulemos sistemas mucho más complejos que las personas de entonces. La falta de pensamiento sobre planificación, organización y mantenimiento aún lo matará.
btilly
1
@btilly, estoy de acuerdo en que es muy importante planificar con anticipación (tanto como sea posible, pero no más) y pensar en el mantenimiento con anticipación. Sin embargo, esto no significa necesariamente pasar mucho tiempo en el diseño de algoritmos. Por ejemplo, si una función se ejecuta una vez al mes y tarda una hora en finalizar, probablemente sea excesivo pasar días en el ajuste del algoritmo, incluso si logra reducir su tiempo de ejecución a 10 minutos. Los beneficios simplemente no justificarán el costo.
Péter Török
2
Dos cosas: Primero, el algoritmo puede determinar qué tan bien escala el programa, y ​​eso a menudo es importante. En segundo lugar, hoy en día se ejecuta mucho software en paralelo en los servidores. Eso significa que, si el programa Z se modifica para ejecutarse dos veces más rápido, quien lo esté ejecutando mucho necesita la mitad de servidores Z.
David Thornley
14

Solo para señalar algo:

Un algoritmo es en sí mismo una solución general paso a paso de su problema. Entonces, si resolvió el problema, de hecho utilizó un algoritmo.

El punto más importante aquí es que debe usar algoritmos para resolver problemas, de una forma u otra. La mayoría de las veces es mejor pensar en su problema antes de saltar a la codificación: esta fase a menudo se llama diseño. Pero, cuánto y de qué manera hará esto depende de usted.

Además, no debe mezclar el concepto de algoritmo con diagramas de flujo (sospecho que esto está sucediendo aquí). Los diagramas de flujo son solo una representación gráfica que se puede usar y se usó en los días anteriores para ilustrar un algoritmo. Es bastante obsoleto hoy en día.

EDITAR:

De hecho, hay muchas formas de representar un algoritmo y el código del lenguaje de programación en sí es una de ellas. Sin embargo, a menudo es mucho mejor o más fácil no resolver todo el problema de una vez, sino solo un esquema y luego llenar los espacios en blanco a medida que avanza.

  • Mi favorito personal aquí es el pseudocódigo, y solo para cubrir un resumen general del algoritmo en cuestión: es ridículo entrar en detalles con el pseudocódigo , para eso sirve el código real.

  • Pero se puede usar código real para el esquema. Por ejemplo, a las personas TDD les gusta diseñar el algoritmo a medida que codifican, y como tampoco pueden resolverlo todo de una vez, diseñan un esquema de la ejecución del programa en código real y usan objetos simulados (o funciones, métodos ... .) como espacios en blanco para rellenar más tarde.

  • Los diagramas de actividad UML parecen ser una encarnación moderna de diagramas de flujo de estilo antiguo con notación adicional para las cosas nuevas como el polimorfismo y el subprocesamiento múltiple. Realmente no puedo decir cuán útil es esto, ya que realmente no los usé mucho, solo lo menciono para completar.

  • Además, si está basando su algoritmo en el cambio entre estados, entonces un diagrama de estado es bastante útil.

  • En general, cualquier medio que tenga que esbozar simplemente la idea detrás de cierto algoritmo es un buen camino a seguir.

Goran Jovic
fuente
Hay muchas formas diferentes de presentar el algoritmo, ¿cuál me recomiendan? ¿Y por qué?
Jervis
@Jervis: Vea mi actualización, enumeré algunos de ellos.
Goran Jovic
¿Donde esta el enlace?
Jervis
4

Una buena analogía es que debes conocer una receta antes de comenzar a cocinar. Ok, puede ajustarlo a medida que avanza, pero aún necesita saber qué quiere hacer antes de comenzar. Si quiero hacer un estofado de cordero, haré cosas muy diferentes de lo que sería si quisiera hornear una barra de pan.

Zachary K
fuente
Algoritmo = ideas ???
Jervis
Algoritmo == receta !!
Pero diferentes chefs tienen diferentes formas de cocinar de acuerdo con la misma receta.
Jervis
Claro, cuando horneo pan sale diferente de cuando mi esposa hornea pan. Pero las partes básicas son las mismas (harina, agua, levadura, sal)
Zachary K
también hay tiendas donde puedes ir a comprar una barra de pan hecha por un panadero profesional
jk.
3

El código implementa algoritmos. Intentar escribir código sin haber diseñado el algoritmo es como intentar pintar una casa antes de construir las paredes. Los algoritmos han sido un "DEBE" desde el comienzo de la programación.

Jerry Coffin
fuente
OKAY. Pintar una casa es tan fácil como ABC, puede comenzar a planificar sin la existencia de la casa.
Jervis
2
@Jervis: Del mismo modo, puede planificar algunas partes del código sin especificar el algoritmo para otras partes (p. Ej., Puede decidir que habrá una función para ordenar los datos sin decidir cómo funcionará, pero debe decidir en el momento en que lo haga). escribe el código de clasificación).
Jerry Coffin
1
Prefiero la analogía de pintar un cuadro que pintar una casa. Si toda mi codificación fuera como pintar una casa, encontraría otro trabajo. Y pintar una imagen puede ser iterativo. A menudo comienzo a crear prototipos en código real antes de que el algoritmo sea completamente claro para mí. Muy a menudo, de hecho.
Greg
3

Ser fluido en su idioma ayuda a mejorar la calidad y la productividad. Y resolver pequeños problemas algorítmicos es mucho más útil para eso que repetir las mismas cosas MVC 100 veces.
Aunque, supongo que hay otras formas de lograr fluidez.

¿El algoritmo se convertirá en un DEBE en el dominio de programación moderno?
Ya es un 'must', a menos que seas un 'php ninja' escribiendo 'cool codez'. Todas las 'mejores' compañías (Google, Amazon, etc.) prueban su experiencia algorítmica en una entrevista, e imagino que no lo harían sin ninguna razón.

Pero volviendo al punto original, debe desafiarse constantemente a sí mismo si desea mejorar. Y dado que los trabajos normales (también conocidos como "ahora escriben administradores CRUD para 100 objetos más") no siempre ofrecen un buen desafío, los algoritmos lo compensan.

Nikita Rybak
fuente
1

Diría que necesita al menos una idea inicial de un algoritmo antes de comenzar a codificar. Probablemente revisará su idea mientras codifica en función de las estructuras de datos, etc.

Más tarde, puede volver a revisar el código si la creación de perfiles sugiere que hay un problema de rendimiento en esa área.

Richard Miskin
fuente
1

La razón es que es más rápido corregir errores antes de haber escrito el código equivocado.

Más prosaicamente, se miden rutinariamente 10 a 1 diferencias de productividad entre diferentes programadores. Cuando observa a los programadores que están en el nivel de productividad 10 veces, pasan la menor fracción de su tiempo realmente codificando. El tiempo para escribir el código no debe ser el cuello de botella. En cambio, pasan una mayor fracción de su tiempo asegurándose de que tienen requisitos directos, planificación, pruebas, etc.

Por el contrario, cuando observa a los programadores que se sumergen en la codificación sin pausa, inevitablemente tienen que escribir el código una y otra vez, ya que se encuentran con problemas previsibles por completo, y el resultado final es menos mantenible y tiene más errores. (Por cierto, ¿sabía que un promedio del 80% del dinero gastado en desarrollo de software se encuentra en la fase de mantenimiento? Hacer que las cosas sean mantenibles es importante. Mucho).

btilly
fuente
Tienes toda la razón.
Jervis
1

Generalmente, los algoritmos y las estructuras de datos primero, el código después. Pero depende mucho del dominio de programación. Solía ​​hacer muchas cosas de tipo matemático aplicado, y realmente miraba el modelo de cascada que prevalecía en ese momento. Eso se debía a que los algoritmos de nivel bajo a medio rara vez se podían dar por sentados. Diseñe una estructura grande alrededor de la existencia de subsistemas no escritos, luego descubra al final del juego que las matemáticas para uno de esos subsistemas cruciales no funcionan (es inestable o lo que sea). Así que siempre pensé primero en los subsistemas más desafiantes, y si había alguna razón para dudar, escribí y probé la unidad primero. Pero, para algunos dominios problemáticos, puede avanzar sin mucha planificación.

Omega Centauri
fuente
Estoy de acuerdo contigo.
Jervis
Estás hablando de la diferencia entre el diseño de arriba hacia abajo y de abajo hacia arriba, que es un tema diferente. Cuando "simplemente sigue adelante" todavía está implementando un algoritmo de algún tipo. Es posible que no piense en esos términos, tal vez porque el algoritmo le parece obvio o porque ya está muy familiarizado con el problema, pero eso no significa que el algoritmo aún no esté allí.
Caleb
0

Diseñe un algoritmo en secciones, luego divida esas secciones y codifique cada una de ellas individualmente. De esa manera puedes mezclar ambos puntos de vista:

  1. Use sus capacidades de lenguaje para que funcione el algoritmo
  2. Intenta pensar antes del código, para que tu idea no se fusione con el idioma (un día necesitas mover tu algoritmo a otro idioma y terminarás en spagetthi)
Guiman
fuente
¡Ladrar! Sé que el algoritmo es independiente del lenguaje. Es cierto que puede usar cualquier lenguaje de programación existente para expresar el mismo algoritmo.
Jervis
0

Para mí, es casi todo el código. Creo que eso es cierto para la mayoría de los programadores altamente productivos. Puedo escribir código tan fácilmente como escribo texto.

En la medida de lo posible, trato de capturar los requisitos como pruebas ejecutables (código). El diseño es solo codificación de alto nivel. Es más rápido y más preciso capturar el diseño en el idioma de destino que capturarlo de alguna otra forma y luego traducirlo.

He descubierto que la mayoría de los usuarios no pueden revisar efectivamente los requisitos de texto. Funcionan bien con casos de uso secuenciales, pero los casos de uso no pueden capturar todos los aspectos de la interfaz de usuario. Lo mejor, con mucho, es tomar un primer corte en la implementación, dejar que los usuarios lo prueben, recibir sus comentarios y modificar el código en consecuencia.

Kevin Cline
fuente
0

Cuando te sientas y comienzas a codificar, tienes un algoritmo en mente, ya sea "diseñado" o no.

Si se sentó y comenzó a codificar sin un algoritmo completo en mente, estaría haciendo uno de los siguientes:

1) Mashing llaves al azar. Esto probablemente producirá un error de compilación

2) escribir código compilable que probablemente haga cualquier cosa excepto lo que quieres que haga

3) escribir código para resolver pequeñas partes del problema, y ​​desarrollarlo a medida que avanza de manera agregada, pero sin pensar realmente en el futuro, por lo que eventualmente se resuelve el problema, pero el código no es de manera muy eficiente, y con posibilidad de tener que retroceder y perder el tiempo en el camino

Por lo tanto, las personas suelen programar con un algoritmo en su cabeza. Puede haber sido desarrollado o razonado sobre papel o algún otro medio.

Puede ser una buena disciplina pensar en su ataque a un problema fuera del teclado, especialmente en sus primeros días como programador. Como han señalado otras respuestas, a medida que tenga más experiencia, puede mejorar en la codificación de algunos fragmentos de problemas más manejables "sobre la marcha". Sin embargo, para problemas difíciles o grandes, es útil pensar y diseñar lejos del teclado: cuando se usa el código, es más probable que piense en términos de construcciones del lenguaje y en cómo abordar la tarea más inmediata en el problema. Mientras que pensar en el problema con, por ejemplo, un bolígrafo y un papel, te libera más del aspecto del código del lenguaje y te permite pensar en un nivel más abstracto más alto.

oculto
fuente
0

Debe dejar de considerar la construcción de software como algo fundamentalmente de la construcción de cualquier otra cosa de valor. No lo es. Entonces, como cualquier otra cosa, siempre se necesita un plan o diseño bien pensado, por breve que sea.

¿Un algoritmo apropiado realmente ayuda a mejorar la calidad y, en última instancia, la eficiencia de un programa?

¿Un plan de construcción / esquemas apropiados ayudan a construir una casa de calidad de manera eficiente?

¿Podemos producir un programa de buena calidad sin el algoritmo?

¿Se puede construir una casa de buena calidad de manera eficiente sin un plan de construcción adecuado? Según el Teorema del mono infinito , probabilísticamente, sí (así como un millón de monos que escriben al azar por la eternidad eventualmente escribirán las obras completas de Shakespeare.

¿Es necesario un algoritmo apropiado en la programación moderna?

Si no quiere ser un mono código y quiere asegurarse de no entregar software que se vea y funcione como una mierda, sí, es imprescindible. Todos los proyectos que he tenido que rescatar (porque el código parecía una mierda imposible de mantener) han comenzado invariablemente con una respuesta negativa a esa pregunta.

De hecho, la programación moderna ha sido el alejamiento del ingeniero de software de programación de vaqueros donde la planificación de algún tipo es imprescindible.

Incluso cuando tenga una biblioteca de algoritmos y estructuras de datos a su disposición (es decir, Boost en C ++ o la biblioteca de colecciones de Java), debe saber cómo funciona ese material para usarlo adecuadamente y componerlo en un nivel razonable y superior. algoritmos de nivel.

luis.espinal
fuente
-2

No es mejor Es mejor no "diseñar" nada. Eso es para personas que no escriben programas. Ya sabes, las personas con experiencia real del problema en cuestión. Si eres matemático, ingeniero o logístico, bien, debes trabajar en el proceso en otro lugar. Pero eso no es 'programación'.

Primero, coloque algún tipo de prueba y punto de referencia.

Luego escribe algo, cualquier cosa. Haga refactor-rewrite -loop hasta que se acabe el tiempo o ya no pueda mejorar.

Si bien muchos parecen pensar que uno puede hacer cosas con una computadora sin realmente hacer nada en una computadora, creo que este es uno de los mitos más comunes que existen. Arquitectura de astronautismos.

Además, no puede optimizar su algo antes de que esté escrito.

IOW, "mantente cerca del metal".

Casimir Pohjanraito
fuente