¿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?
algorithms
Jervis
fuente
fuente
Respuestas:
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.
fuente
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.
fuente
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.
fuente
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.
fuente
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.
fuente
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.
fuente
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).
fuente
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.
fuente
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:
fuente
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.
fuente
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.
fuente
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 plan de construcción / esquemas apropiados ayudan a construir una casa de calidad de manera eficiente?
¿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.
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.
fuente
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".
fuente