¿Por qué algunos programadores piensan que hay un contraste entre teoría y práctica? [cerrado]


63

Al comparar la ingeniería de software con la ingeniería civil, me sorprendió observar una forma diferente de pensar: cualquier ingeniero civil sabe que si desea construir una pequeña cabaña en el jardín, puede obtener los materiales e ir a construirla, mientras que si desea construirla. una casa de 10 pisos (o, por ejemplo, algo como esto ) que hay que hacer bastantes matemáticas para asegurarse de que no va a desmoronarse.

Por el contrario, hablando con algunos programadores o leyendo blogs o foros, a menudo encuentro una opinión generalizada que se puede formular más o menos de la siguiente manera: la teoría y los métodos formales son para matemáticos / científicos, mientras que la programación se trata más de hacer las cosas .

Lo que normalmente se implica aquí es que la programación es algo muy práctico y que aunque los métodos formales, las matemáticas, la teoría de algoritmos, los lenguajes de programación limpios / coherentes, etc., pueden ser temas interesantes, a menudo no son necesarios si todo lo que uno quiere es obtener cosas hecho .

Según mi experiencia, diría que si bien no necesita mucha teoría para armar un script de 100 líneas (la cabaña), para desarrollar una aplicación compleja (el edificio de 10 pisos) necesita un diseño estructurado. métodos definidos, un buen lenguaje de programación, buenos libros de texto donde puede buscar algoritmos, etc.

Entonces, la teoría IMO (la cantidad correcta de) es una de las herramientas para hacer las cosas .

Mi pregunta es ¿por qué algunos programadores piensan que hay un contraste entre la teoría (métodos formales) y la práctica (hacer las cosas)?

¿La ingeniería de software (software de construcción) es percibida por muchos como fácil en comparación con, por ejemplo, la ingeniería civil (construcción de casas)?

¿O son estas dos disciplinas realmente diferentes (aparte del software de misión crítica, la falla del software es mucho más aceptable que la falla del edificio)?


Trato de resumir lo que he entendido de las respuestas hasta ahora.

  1. A diferencia de la ingeniería de software, en ingeniería civil es mucho más claro qué cantidad de teoría (modelado, diseño) se necesita para una determinada tarea.
  2. Esto se debe en parte al hecho de que la ingeniería civil es tan antigua como la humanidad, mientras que la ingeniería de software ha existido solo durante algunas décadas.
  3. Otra razón es el hecho de que el software es un tipo de artefacto más volátil, con requisitos más flexibles (puede permitirse que se bloquee), diferentes estrategias de marketing (se puede sacrificar un buen diseño para ponerlo en el mercado rápidamente), etc.

Como consecuencia, es mucho más difícil determinar cuál es la cantidad adecuada de diseño / teoría apropiada en ingeniería de software (muy poco -> código desordenado, demasiado -> Nunca puedo terminar) porque no hay una regla general y solo (mucha) experiencia puede ayudar.

Entonces, si interpreto sus respuestas correctamente, esta incertidumbre acerca de cuánta teoría se necesita realmente contribuye a los sentimientos mixtos de amor / odio que algunos programadores tienen hacia la teoría.


99
no, el 90% de los programadores son;)
jk.

24
Bueno, en el software podrías comenzar con la construcción del techo y luego avanzar hasta la base, mientras las partes terminadas flotan en el aire. Si algo no le queda bien, puede usar cinta adhesiva para ductos. Prueba esto cuando construyas un rascacielos. ;)
Asegure el

65
En teoría no hay diferencia entre teoría y práctica, pero en la práctica sí la hay.
Joris Timmermans

66
¿Un buen libro para buscar algoritmos? La mayoría del software es simplemente CRUD sin nada parecido a lo que se incluye en cualquier curso de algoritmo o libro.
Gilles

44
La teoría trata sobre lenguajes y algoritmos modernos. La práctica llega al trabajo el primer día y se le asigna la tarea de agregar una característica menor al software de punto de venta que se ejecuta en una caja registradora que utiliza software que fue convertido manualmente de BASIC a K&R C por personas que no conocían C , utilizando un compilador con errores de un proveedor que se declaró en quiebra y se espera que tenga la función funcionando el viernes a más tardar.
Gort the Robot

Respuestas:


61

Creo que la principal diferencia es que con la ingeniería civil, la física del mundo real actúa como un control constante y poderoso de la realidad que mantiene la teoría sensata y también limita las malas prácticas, mientras que en la ingeniería de software no existe una fuerza igualmente fuerte para mantener los conceptos poco prácticos de la torre de marfil. como mano de obra de mala calidad en jaque.

Muchos programadores han tenido malas experiencias con la teoría desbocada convirtiéndose en un impedimento activo para hacer las cosas (por ejemplo, "UML ejecutable", procesos de desarrollo superburocráticos). Por el contrario, los trucos y parches sucios pueden llevarte bastante lejos, aunque lentamente al final. Y como observa en su último párrafo: las fallas generalmente no son tan definitivas y, por lo tanto, no tan problemáticas.


1
Estoy de acuerdo con usted en que en la ingeniería de software es importante tener la cantidad correcta de formalismo. Demasiado significa que nunca puede comenzar y tal vez cuando descubra que ha cometido un error, es demasiado tarde. Demasiado poco significa que puedes hacer un desastre. Creo que tiene un punto muy fuerte al decir que la productividad y la calidad son mucho más difíciles de medir en ingeniería de software que en ingeniería civil.
Giorgio

2
"... mientras que en la ingeniería de software no existe una fuerza igual de fuerte para no ser práctico ..." Creo que quiere decir que ya no existe tal fuerza. En el pasado, las limitaciones planteadas por los procesadores más débiles, menos memoria y poco / ningún almacenamiento actuaron como tal fuerza.
carne

1
@blesh: No lo creo. Los estrictos límites de hardware limitan la buena y la mala ingeniería por igual.
Michael Borgwardt

Sus ejemplos no son la teoría de la programación. Las restricciones sobre el software tienen que ver con las tecnologías utilizadas y la capacidad matemática de los escritores.
Paul Nathan

55
Definitivamente hay algo "teórico" sobre UML ... ... su utilidad!
ObscureRobot

29

La ingeniería de software y la ingeniería civil tienen poco en común. Los esfuerzos de ingeniería civil están limitados por las propiedades físicas de sus materiales y el medio ambiente. Los ingenieros civiles pasan mucho tiempo aprendiendo sobre las propiedades del suelo y las características del material. El desarrollo de software está limitado físicamente solo por la velocidad de los procesadores y el almacenamiento disponible. Ambos son fáciles de entender y no pasamos mucho tiempo estudiándolos. La principal limitación para el desarrollo de software es el intelecto humano. Y no hay dos desarrolladores iguales. ¿Se puede mantener este código? ¿Por quién? Una implementación de tres líneas de quicksort en Haskell puede ser obviamente correcta para algunos, pero incomprensible para otros. Un equipo de dos puede completar una solicitud en un mes, mientras que otro equipo de diez lucha por cumplir en un año.

El desarrollo de software es todo diseño, los artefactos diseñados son órdenes de magnitud más complejos que cualquier artículo fabricado, y cada uno es único.


1
Estoy de acuerdo con sus observaciones de que el factor humano es mucho más fuerte en el software, pero aún así, creo que tratar de analizar un problema o estructurar su solución es una actitud / herramienta general. Mi pregunta es por qué algunos programadores piensan que no es un enfoque útil (o incluso una pérdida de tiempo). Usted mencionó a Haskell: hice el esfuerzo de aprender algo de Haskell a pesar de que no lo usé en ningún proyecto porque pensé que me ayudaría a escribir un mejor código (incluso en C ++ o Java). Incluso si no puedo medir esto, mi sensación es que me he vuelto más productivo: hago más cosas.
Giorgio

2
¿Un quicksort de Haskell de tres líneas? Hmm ... ¿es posible implementar Quicksort en un lenguaje donde todo es inmutable por diseño?
Mason Wheeler

3
@MasonWheeler Primer resultado de Google: Quicksort en Haskell .
chrisaycock 01 de

3
@Mason: el tiempo de ejecución sigue siendo O (n log n). También requiere memoria O (n log n), a diferencia de un ordenamiento rápido en el lugar, que requiere solo memoria adicional O (log n) para la recursividad.
Kevin Cline

2
@kevincline En la medida en que un proyecto de software típico es único, me embarqué en un proyecto único para remodelar mi baño. La diferencia es que si arruino mi código, mis pruebas se ponen rojas, y si arruino mi cableado, mi casa se quema. Por supuesto, ese proyecto también fue tiempo extra y sobre presupuesto, porque no tengo experiencia en resolver problemas de remodelación. El principal problema que he visto en los proyectos de software es similar ... no es que las personas adecuadas no puedan resolver estos problemas más rápido, es que las personas adecuadas no están disponibles y tenemos que convertirnos en las personas adecuadas en el volar.
philosodad

17

Como ingeniero mecánico más o menos honesto (con algo de civil) convertido en programador, luego doctorado en CS (AI), luego maestro, luego programador nuevamente (disculpe, ingeniero de software ), tengo una queja. Este tema general.

En ingeniería tradicional

  • debes conocer tus matemáticas y ciencias porque todo lo que haces se basa en ello
  • Los "héroes" en el campo son personas que inventan cosas nuevas, descubren nuevas ideas, resuelven problemas considerados irresolubles.

Hay una "física" que se aplica al software: la teoría de la información, pero los ingenieros de software tienen poca exposición a ella, y ciertamente nada se aplica. La mayor teoría que obtienen es computabilidad y big-O.

Además, continuamente me sorprenden las personas que piensan que conocer la programación es suficiente y no necesitan comprender el tema de lo que tratan sus programas.

Además, no se fomenta la inventiva. Se desaconseja, a favor de los métodos de pensamiento grupal con el denominador menos común, disfrazados de "legibilidad". (Imagínese si se alienta a los ingenieros aeronáuticos o nucleares a no hacer nada que pueda ser difícil de entender para sus compañeros más jóvenes)

Las cosas que aprenden, como cómo programar aplicaciones web, son de gran valor. Así es la habilidad de un plomero o electricista, pero no es ingeniería.


55
La física puede decirle si alguna estructura colapsará o no bajo su propia carga. CS le dice que no puede saber si un programa dado detendrá una determinada entrada. Los métodos formales de la OMI escalan mucho mejor en ingeniería civil o mecánica que en software, principalmente porque los sistemas son menos complejos y menos dinámicos ...
Guy Sirton

66
@GuySirton "CS te dice que no puedes saber si un programa determinado detendrá una determinada entrada". si eso es todo lo que crees que hace CS, creo que es posible que no sepas tanto sobre CS como crees que sabes ...
gregghz

2
Guy, es increíblemente improbable que hayas usado materiales de software que nadie haya usado antes. McCarthy lo hizo, y Turing lo hizo, pero realmente, la ingeniería de software no es tan increíble. Si estaba bien que el edificio se hundió hasta el fondo del océano, ya que sólo podría reiniciar el sistema, que sería como la ingeniería de software.
philosodad

3
Te daría un +1 a excepción del crack sobre la legibilidad. La capacidad de mantenimiento es el 80% del costo del software, por lo que la legibilidad no es un problema menor. Además, cuando ese ingeniero aeronáutico o nuclear está haciendo algo que se fabricará haciendo que otras personas entiendan que es importante. Los militares, el gobierno o incluso las grandes instituciones no están contentos con un invento mágico que no puede ser replicado o entendido por nadie más que el inventor.
Thomas

2
@Thomas: la afirmación de que las soluciones viables a menudo se descartan en la alteración de la "legibilidad", por mentes inferiores, no significa necesariamente que las soluciones no sean tan legibles como deberían ser. Lo he visto suceder. Demonios, me sorprendí haciéndolo.
Erik Reppen

13

Si corto la esquina en la mayoría del software y hago algo que no es el mejor diseño, pero que hará el trabajo, nadie va a morir. Es la misma razón por la que una cabaña en el jardín no necesita los mismos estándares que un edificio de 10 pisos. Sin embargo, puedo construir una aplicación muy grande como Facebook, y si se arruina y pierde algunos datos, o lo que sea, en realidad no es tan importante. También es más sencillo arreglar la base de una aplicación grande después del hecho, que reemplazar la base de un edificio de 10 pisos. Todo se reduce al contexto y al cálculo del riesgo.

También puedo, de forma segura y sencilla, seguir agregando a una aplicación. No puedes lanzar fácilmente un nuevo tercer piso de un edificio de 10 pisos (lo que hace que sea 11). Puedo agregar una nueva función a una aplicación grande todos los días si lo deseo.

Ahora, un buen diseño facilita todo esto en la programación. Pero no es imposible con un diseño deficiente, y los riesgos son ... software defectuoso. No suele ser la muerte.


Bueno, espero que no mueran ... depende de su software;)
Rig

3
@Rig, por eso dije 'más' y 'generalmente'. Algunos programas son mucho más críticos.
CaffGeek

Creo que esto es cada vez más una muy mala punto de vista, seguro que la mayoría de software no tiene ninguna incidencia de seguridad, pero no hay dinero y privacidad involucrado en una gran cantidad de software, conseguir estos mal también podría llevarlo a la corte
jk.

11

Ten paciencia conmigo en este caso. Tengo un punto

Un profesor me dijo una vez que postergar lleva a más dilaciones, a pesar de que la mayoría de las personas después de una noche de apresuradas escrituras en papel / hacinamiento / programación se dicen a sí mismas: "Nunca volveré a hacer eso. La próxima vez, comenzaré temprano y terminar temprano ". En mi experiencia como el dilatador consumado, he descubierto que esto es cierto, y aquí está la explicación del profesor por qué: no importa cuán desagradable sea la experiencia de postergar, en la mayoría de los casos, terminas habiendo logrado un éxito relativo. Este es un comportamiento de alto riesgo / alta recompensa. Después de un tiempo, te olvidas de todo lo desagradable y solo recuerdas la recompensa. Por lo tanto, la próxima tentación de posponer las cosas es aún más atractiva, porque lo logró la última vez.

Creo que aquí se puede hacer una analogía con la técnica de programación "hacer las cosas" que con demasiada frecuencia vemos. Un programador o equipo de programadores, tal vez por ignorancia, pereza o por una limitación de tiempo genuina, adopta el enfoque de "hacer las cosas" en la programación, arrojando toda su teoría y matemática y buenas prácticas por la ventana. ¿Y sabes qué? Ellos hacen las cosas. No es elegante, bonito o fácil de mantener, pero hace el trabajo. Tal vez un superior no técnico que no conoce un punto y coma de un semáforo les da un gran elogio por "hacer las cosas". Por lo tanto, la próxima vez que el programador tenga la tentación de adoptar este enfoque flojo de la programación, es mucho más fácil, porque bueno, funcionó la última vez, ¿no? Es la salida "fácil", a menos que seas pobre,

He sido esa alma pobre y desafortunada, y muchos de ustedes probablemente también. Les imploro a todos. ¡No tomes el camino fácil! :)


3
Si tiene que hacerlo una vez y olvidarse de eso, está bien. Pero si tiene que extenderlo y mantenerlo después, está buscando problemas. Necesita tener una idea de cuánta teoría: demasiado significa que nunca lo hará, muy poco significa que lo hará 10 veces antes de que realmente se haga. Mis 2 centavos
Giorgio

66
Pero a veces necesitas sacar tu software AHORA . Necesitas vencer a un competidor para comercializar. O tiene un requisito legal para proporcionar alguna información. O simplemente necesita obtener un flujo de caja para poder seguir existiendo cuando el desorden que creó en su enfoque de "hacerlo" es un problema ... que a veces es un buen problema. Porque si no lo tenía, no lo soltó a tiempo y su compañía está muerta antes de que comience.
CaffGeek

1
@ Chad - Estoy de acuerdo contigo. Es un equilibrio. Todas las cosas que mencionas caen dentro de "una restricción de tiempo genuina" como razones para la programación, y en el corto plazo, está bien e incluso es ventajoso que lo hagas.
FishBasketGordo 01 de

@FBG: Dijo brillantemente.
Kuba Ober

@ Chad, buen punto. Martin Fowler hace un punto similar en martinfowler.com/bliki/TechnicalDebt.html . A veces es una compensación que vale la pena.
John M Gant

9

Tu premisa es defectuosa. La razón principal por la que los ingenieros civiles utilizan la ingeniería al diseñar grandes edificios, puentes, túneles, etc. es para asegurarse de que están utilizando una cantidad mínima de material (concreto, acero estructural, etc.) que satisfaga los estándares de seguridad requeridos. Es completamente posible construir un edificio alto sin muchas matemáticas (p. Ej., Las pirámides de las antiguas civilizaciones egipcia y maya) si los costos de material y mano de obra no son un objeto, pero una vez construido, por lo general no tiene sentido modificar para que utilicen el material de manera más eficiente.

Hay una dinámica algo diferente en el diseño de grandes sistemas de software. En todo caso, generalmente están sub-diseñados, pero esto se debe a que el diseño se puede cambiar dinámicamente a medida que avanza el trabajo, lo que simplemente no se puede hacer tan fácilmente con proyectos de ingeniería civil.

El factor común es el costo. El diseño en un proyecto de ingeniería civil tradicional reduce los costos (tanto reales, en términos de material, como potenciales en términos de responsabilidad), mientras que llega un punto en el desarrollo de software donde el costo del diseño aumenta más allá del valor devuelto.


"llega un punto en el desarrollo de software donde el costo del diseño aumenta más allá del valor devuelto": he escrito explícitamente "la cantidad correcta de teoría". Sé que sobre ingeniería no aumenta la productividad.
Giorgio

Hay casi cero proyectos de la OMI que están diseñados por adelantado que realmente siguen su diseño. La ingeniería civil es (¿generalmente?) Construir lo mismo una y otra vez (una carretera, una maldita, un túnel, un edificio, un puente). Las técnicas son bien conocidas. Esto no es cierto en el software. Debido a que puede cambiarse fácilmente y porque las personas no saben lo que quieren o lo que funciona hasta que lo prueban, el diseño inicial serio es una pérdida de tiempo. Construimos, probamos e iteramos. Algo que no es posible con la Ingeniería Civil como se señaló anteriormente. Las 2 disciplinas no son comparables.
Gman 01 de

55
Lo siento, tengo que señalar el error tipográfico: no creo que a los ingenieros civiles les importe un comino. ;-)
Giorgio

2
Me imagino que en el futuro, cuando nosotros, los ingenieros de software, construyamos un excelente software de simulación de ingeniería civil, los ingenieros civiles podrán eliminar todas estas cosas de matemáticas. Simplemente construye un rascacielos virtual de 10 km de altura. Si no se colapsa bajo su propio peso en los primeros 100 años virtuales y puede resistir un huracán virtual cat 5, utilice la impresora 3D de rascacielos especial para construirlo.
emory

1
@RexKerr: cortó la mitad de su declaración: "... que cumple con los estándares de seguridad requeridos"
Lie Ryan

7

También señalaría, además de varias otras excelentes respuestas, que la humanidad ha estado haciendo el equivalente de "ingeniería civil" desde la época de los egipcios, por lo que hemos tenido mucho tiempo para perfeccionar la teoría general de cómo deberían ser las cosas. ser hecho Hemos estado construyendo software durante unos 70 años más o menos (dependiendo de lo que consideres el primer "software"); Quiero decir que no hemos tenido la misma cantidad de tiempo para desarrollar el mismo tipo de experiencia.


6

Los planos de un arquitecto / ingeniero civil prácticamente nunca son idénticos a los planos "tal como están construidos". Algo SIEMPRE cambia. ¿Por qué? Porque hay, y siempre habrá, "incógnitas desconocidas". Hay cosas que sabe y por lo tanto puede planificar, cosas que sabe que son desconocidas y que puede investigar y estimar, y luego hay cosas que no sabe que no sabe; "sorpresas". Su objetivo es eliminarlos en la mayoría de los sistemas aprendiendo todo lo que pueda, pero todo lo que se necesita es una pequeña violación del código de construcción (que puede basarse en una regla que no existía hace 2 años cuando su edificio estaba siendo conceptualizado) y todo El plan maestro que abarca tiene que cambiar, a veces de manera bastante drástica.

El software es muy parecido a esto; Siempre hay un desconocido desconocido. Sin embargo, a diferencia de la ingeniería civil o estructural, el desarrollo de software es mucho más tolerante al cambio basado en los problemas que crean las incógnitas desconocidas. Si está construyendo un edificio de 10 pisos y sobreestimó la capacidad de carga de la base que colocó en su diseño, o no puede construir el edificio con 10 pisos o tiene que arrancar una cantidad significativa de trabajo para volver a la base y reforzarlo o reconstruirlo. Sin embargo, en el software, si subestimó las demandas en un nivel particular de la estructura general de la solución, hay muchas opciones para arreglar ese nivel que no implican invalidar todo el otro trabajo. Puede reemplazar un único servidor de base de datos por uno más potente, o un clúster de replicación / conmutación por error, o un clúster de equilibrio de carga / distribuido. Lo mismo para el servidor web. Si codificó un algoritmo que es ineficiente pero simple basado en supuestos defectuosos del tamaño de entrada, casi siempre puede simplemente eliminar y reescribir la implementación de una manera relativamente quirúrgica, sin afectar otro código que tenga conocimiento del algoritmo (llama y pasa la entrada a o espera una salida de él).

Esta relativa facilidad de cambio permite a un ingeniero de software codificar según lo que sabe sin preocuparse demasiado por lo que no sabe. Esto permite una aplicación más laxa de la teoría y el diseño conceptual inicial; te sumerges y lo haces, y en el camino encuentras las cosas que codificaste que deben cambiar y cambiarlas. Aún debe conocer los conceptos y la teoría, porque cuando se descubre un problema, son esas cosas las que lo ayudarán a identificar la causa y crear una solución. Pero se le permite tomar una decisión rápida sin sucumbir a la "parálisis de análisis", porque si resulta que tomó la decisión equivocada en base a algo que no sabía o que no tuvo en cuenta en sus "cálculos", el El error es más fácil de corregir.


3
También hay muchas más incógnitas desconocidas en el desarrollo de software: puede comenzar a construir un rascacielos, pero cuando el cliente lo mira, le dicen "en realidad quería un cubo Rubix de diez pisos de altura".
Tacroy

@Tacroy: Curiosamente, un ingeniero civil probablemente consideraría que este es un mal cliente que está desperdiciando su tiempo y recursos, un ingeniero de software intentará desarrollar una nueva metodología para satisfacerlo. :-)
Giorgio

1
@Giorgio, o factura en consecuencia ...
CaffGeek 01 de

5

La diferencia se debe principalmente a los requisitos conocidos:

  • En el lado de la teoría, todo se define por adelantado, por lo que puede saber exactamente lo que necesita antes de comenzar.
  • En la práctica, a menudo no están todos allí, o descubres algo a la mitad de la implementación que hace que tengas que rediseñar algo. Por lo tanto, es mucho mejor saltar con al menos diseños rudimentarios, para que pueda descubrir estos problemas desde el principio.

Además, cuando se habla de "teoría", generalmente significa el lado teórico de la informática, en lugar de la ingeniería de software. Esta es la parte de la informática que se trata principalmente de encontrar algoritmos mejores y más eficientes, que demuestren si algo es o no posible (P y NP, por ejemplo), y así sucesivamente. Si bien es bueno tener esto en mente, no aparecen en el desarrollo de software con mucha frecuencia.

Usamos bibliotecas para ese tipo de cosas tanto como sea posible.


1
+1 para "cuando se habla de 'teoría', generalmente significa el lado teórico de la informática".
Joshua Drake

5

En realidad, hay bastantes niveles de ingeniería de software dependiendo de lo que esté haciendo el software que está creando.

La NASA necesita un software para controlar los transbordadores tripulados en el espacio, por lo que, naturalmente, el nivel del proceso de ingeniería es mucho más estricto que el de construir un sitio web para mostrar imágenes de cohetes.

¡Uno de mis compañeros de trabajo que trabajaba para la NASA describió previamente su proceso de ingeniería de software como escribir cientos de páginas de justificación y cientos de horas de reuniones para justificar la escritura de una sola línea de código!

No me malinterpreten porque no estoy tratando de parecer irrespetuoso cuando digo esto, pero incluso después de todo ese costo de tiempo, recursos y miles de millones de dólares, el transbordador espacial todavía explotó.

Incluso los ingenieros civiles saben que no importa cuánta teoría pongan en un diseño, algo lo romperá, por lo que también deben desarrollar planes de contingencia.

Cuando se construye software, el costo de su caída rara vez causa la pérdida de vidas, por lo que es mucho más fácil arrojar cosas rápidamente y probarlo. Acordemos que hacer las cosas rápidamente resulta en un código débil. Incluso si este es siempre el caso, ver el software en acción es la mejor manera para que un desarrollador vea dónde es débil y necesita fortalecerse frente a dónde es débil y muchas veces más fuerte de lo que debe ser para mantenerse al día la carga.

En resumen, Premature optimization is the root of all evil o como siempre diría mi jefeShipping is a feature!


3
¡+1 para "El envío es una característica"! Una vez escuché una oración similar: "La perfección no existe. Este software tiene la ventaja de que existe". Por supuesto que es una broma. Con respecto al software de misión crítica: una excepción no detectada puede hacer que un cohete se estrelle.
Giorgio

this software has the advantage that it exists... No lo había escuchado todavía, pero está en mi lista de excelentes citas de software. me gusta
Albert Lang

@Giorgio: JSF y MISRA C están escritos para que no haya excepciones. Las excepciones y los cohetes no se mezclan.
Codificador

5

Muchas buenas respuestas aquí, pero creo que la comparación entre Ciencias de la Computación e Ingeniería Civil es defectuosa.

Estrictamente hablando, lo que hacen los desarrolladores de software profesionales es más como Ingeniería de Software que Informática. Una mejor analogía es que la informática es la física de la ingeniería de software. Del mismo modo, la Ingeniería Civil es una colección de simplificaciones y aproximaciones de Física para construir prácticamente cosas.

Me imagino que los ingenieros civiles rara vez tienen que tener en cuenta la relatividad general al realizar su trabajo. Gran parte de la Ingeniería Civil se puede construir de manera segura en Mecánica Newtoniana. Del mismo modo, la ingeniería de software se puede lograr con mucho éxito con una comprensión aproximada de la informática teórica.

La gran diferencia es que los puentes, rascacielos y otros productos de Ingeniería Civil son cosas razonablemente bien entendidas. Los ingenieros de software a menudo construyen construcciones novedosas o utilizan métodos novedosos para construir cosas bien entendidas. La Ingeniería de Software es MUCHO menos madura que la Ingeniería Civil, y eso probablemente seguirá siendo cierto en el futuro previsible.

TL; DR : La teoría y la práctica son diferentes en Ingeniería de Software al igual que en cualquier otro lugar. La analogía adecuada es Ingeniería de software: Ingeniería civil :: Informática: Física. Pero en la práctica, es un poco más complejo que eso :)


"Me imagino que los Ingenieros Civiles rara vez tienen que tener en cuenta la relatividad general al realizar su trabajo. Gran parte de la Ingeniería Civil se puede construir de manera segura en Mecánica Newtoniana". Hasta donde yo sé, tienen que usar bastante cálculo (integrales Y cosas como esa). Esto no es mecánica cuántica, pero IMO definitivamente no es trivial.
Giorgio

2
Claro, pero no necesita derivar una ecuación de onda para cada componente de su puente y luego explicar cómo interactúan.
ObscureRobot

Tienes razón. Sin embargo, mi punto no es cuánta teoría se usa en la ingeniería civil y la ingeniería de software. Más bien, los ingenieros civiles saben que tienen que usar sus fórmulas y hacer cálculos sobre cómo construir algún edificio. En la ingeniería de software, tengo la impresión de que hay más improvisación y, a veces, si quieres sentarte y analizar un problema (solo para hacerlo bien, no para escribir una tesis doctoral al respecto), puedes ser mal visto: queremos obtenerlo terminado, no para hacerlo perfecto. ¡Pero la teoría de la OMI (no demasiada) es exactamente lo que puede ayudar a terminarlo más rápidamente!
Giorgio

Necesita encontrar un punto de equilibrio apropiado para su proyecto. Los desarrolladores junior suelen ser más entusiastas acerca de tirar basura juntos para ver qué se quedará. Si provienen de un contexto muy teórico, incluso pueden tener ideas más locas y excesivamente complejas. La gestión eficaz de los desarrolladores junior a menudo implica ayudarlos a dar un paso atrás y analizar su trabajo. Por otro lado, los desarrolladores senior pueden centrarse demasiado en los problemas de diseño a largo plazo hasta el punto en que tengan problemas para concentrarse en las necesidades inmediatas.
ObscureRobot

Wow, lo siento, esto está fuera de tema, pero sin leer su respuesta, terminé exactamente igual, con un TL; DR y luego, literalmente, la misma analogía. Formato SAT. Lo edité de mi respuesta para que no parezca que te estoy copiando, pero todavía me está asustando. Tal vez los programadores piensan demasiado por igual.
Jarsen

3

Entonces mi pregunta es ¿por qué algunos programadores piensan que hay un contraste entre la teoría (métodos formales) y la práctica (hacer las cosas)?

Construir software es diferente a construir un puente. En el software, hay muchos objetos para construir que pueden o no definirse al inicio. Los estándares existen para aumentar la facilidad de mantenimiento y la colaboración del desarrollador, no para adherirse a fórmulas matemáticas arbitrarias u otros ideales similares. Por ejemplo, cuando se selecciona un comportamiento basado en una variable, a veces tiene sentido usar un interruptor, otras veces un patrón de fábrica. Depende de la facilidad de mantenimiento y de los puntos débiles identificados, como los problemas de rendimiento.

Otro ejemplo se puede hacer con la manipulación de datos. A menudo tiene sentido usar delegados en el contexto de .NET. No es tan fácil en Java porque no tiene el soporte de marco para el estilo de programación funcional que tiene .NET. En otras palabras, en el caso general simplemente no es posible hacer X en la situación Y. Esto se debe al hecho de que X e Y dependen del número N de factores variables.

¿La ingeniería de software (software de construcción) es percibida por muchos como fácil en comparación con, por ejemplo, la ingeniería civil (construcción de casas)?

No estoy seguro de que "fácil" sea el término correcto. La falta de evidencia tangible puede llevar a la percepción de que no se está trabajando. O, de manera similar, ese trabajo existente se cambia fácilmente.

¿O son estas dos disciplinas realmente diferentes (aparte del software de misión crítica, la falla del software es mucho más aceptable que la falla del edificio)?

La ingeniería tradicional y la ingeniería de software son muy diferentes por las razones que ya dije.


1

Su percepción puede estar equivocada aquí, o incluye muchos recursos de personas que no han escrito software suficientemente complejo.

Su experiencia está en línea con lo que diría la mayoría de las personas que conozco (que han diseñado y escrito un software suficientemente complejo).

Dicho esto, cuando se trata de la mayoría de los programadores , cuando la tarea de escribir algo les llega, el diseño ("las matemáticas", tal como lo expresas) ya ha sido realizado por el arquitecto / líder / etc. antes de que la tarea de escribir les llegue. Por lo tanto, puede parecer así desde el nivel de primera línea.


3
"las matemáticas ... ya se han hecho": no solo, considere todas las funciones de la biblioteca, marcos, DBMS, protocolos y toneladas de otras cosas pesadas que podemos usar en nuestro código llamando a una función con algunos parámetros. Como programador, a veces me siento más como el trabajador que camina en el andamio que como el ingeniero que diseñó el edificio.
Giorgio

1

Creo que la razón de este contraste es que el ciclo de vida de un proyecto de software y hardware o proyecto de arquitectura es diferente. La mayoría del software evoluciona gradualmente, no se planifica desde el principio hasta el final. Los desarrolladores de software pueden aplicar un enfoque iterativo al desarrollo: planificar, implementar y escuchar los comentarios. Si la retroalimentación es positiva, continúe, no; retroceda y reconsidere su estrategia. Es por eso que los desarrolladores de software tienen cosas como desarrollo ágil, producto mínimo viable, etc.

Los ingenieros civiles no tienen ese lujo. Para ellos, una vez que se planifica algo, no puede cambiarlo tan fácilmente, como con el software, porque el costo de dichos cambios puede ser grave. Para el desarrollo de software, por otro lado, no cuesta tanto, y esto puede usarse para su ventaja.

Pero no todas las ramas del desarrollo de software pueden permitirse ese enfoque. Hacer software, por ejemplo, para aviación o servicios médicos requiere una planificación muy cuidadosa y muchos cálculos previos.


1

Me parece lo mismo. Usted construye un gran edificio con bloques estándar, concreto de resistencia estándar, acero estándar. Crea una gran aplicación a partir de bibliotecas estándar.

No intenta y matemáticamente prueba formalmente que una aplicación grande es correcta de la misma manera que no intenta escribir la función de onda para un edificio de 100 pisos


Entonces, ¿cuál es el equivalente de software de un análisis de elementos finitos del edificio de 100 pisos? ¿Cuántos edificios altos tienen errores en therm / crash? :-)
Guy Sirton

@GuySirton: solo puede analizar un edificio grande a un nivel muy grueso, con menos detalles de los que probaría una aplicación típica. Muchos edificios grandes tienen fallas, las ventanas se caen, las pasarelas colapsan, crean efectos de túnel de viento. ¡O en el caso de un hotel curvo altamente reflectante en Las Vegas, usted crea un rayo de la muerte en la piscina!
Martin Beckett

Puede ir muy bien en FEA y predecir el comportamiento con un alto grado de precisión. La gente todavía comete errores. En mi opinión, es simplemente imposible hacer predicciones similares en una pieza compleja de software. Las fallas que menciona son una fracción minúscula del número total de edificios. Las tasas de defectos en el software deben ser dos órdenes de magnitud más altas. Dicho esto, obviamente es un continuo entre donde los métodos formales son útiles y dónde son inútiles.
Guy Sirton

@GuySirton: creo que la dificultad es que confías en otras cosas. La NASA puede probar la aviónica de vuelo a un nivel muy detallado (aunque todavía no lo prueba) porque también crean el sistema operativo y el hardware. Escribir en un sistema operativo general con kits de herramientas y librerías es como construir un puente donde no se le permite conocer los detalles del acero o el hormigón.
Martin Beckett

1
@MartinBeckett, y el coeficiente de gravedad cambia aleatoriamente de una hora a otra ... como cuando el administrador de su sistema decide aleatoriamente actualizar un servidor sin decirle a nadie porque "será transparente".
CaffGeek

1

Era ingeniero mecánico y de fabricación antes de descubrir hace unos 20 años que mis aptitudes radicaban en el software. Simpatizo con muchos de los elementos que usted ha presentado.

Sospecho que la verdadera naturaleza del problema se trata de cómo hacemos las cosas. Ahora tenemos más o menos diez años de desarrollo ágil bajo nuestros cinturones colectivos, y el mensaje es claro. No progreses por capas; Progreso por características. Claro, habrá proyectos cuando necesite progresar por capas (por ejemplo, cree su pila de red antes de su servidor web), pero para la gran mayoría de los proyectos del mundo real, hemos aprendido la lección de que ofrecer funciones de trabajo, una o algunas una vez, es mucho más efectivo construir enormes teorías no probadas y luego tratar de implementarlas.

Así que tomemos su ejemplo de cabaña (generalmente hablo de hacer un puente arrojando un tronco a través de un arroyo frente a un puente colgante de un kilómetro de largo ... ¡lo que sea!), Y llevarlo al mundo de la ingeniería de software. La principal diferencia que veo es que en el software, la mayor parte del trabajo es de una escala que no necesita un gran modelado inicial para tener éxito. El error del principiante es a menudo asumir que las cosas necesitan más de lo que realmente necesitan, y para la mayoría de nosotros, después de haber cometido ese error varias veces, nos damos cuenta de que lo cometemos con demasiada frecuencia.

Sin argumento: hay proyectos que deben comenzar con un comité de 17 arquitectos de software. En verdad, son tan raros como los diamantes de 20 quilates.


1

Creo que la analogía es defectuosa. Que yo sepa, la ingeniería civil no tiene el mismo tipo de base teórica que la informática; la informática nació de las matemáticas teóricas, como las máquinas de Turing. La ingeniería civil se trata de crear estructuras que resistan a la madre naturaleza y tal vez incluso se vean hermosas. Una vez más, realmente no sé mucho sobre ingeniería civil, pero no creo que haya equivalentes de ingenieros civiles de P vs NP, el vendedor ambulante y otras cosas divertidas contra las que golpearse el cerebro. Y definitivamente hay un lugar para nuestra teoría de la informática: si alguien resuelve al vendedor ambulante o el problema de detención, nos encontramos con muchos nuevos avances increíbles. Pero para un ingeniero de software, cuyo negocio es diseñar software, tales problemas son realmente solo diversión y juegos.

Ahora, también creo que depende de lo que entiendas por "teoría". ¿Estamos hablando de patrones de diseño o bombeando lema? Porque tener una buena comprensión sólida de los patrones de diseño es absolutamente crítico para ser un buen ingeniero de software. Sin embargo, al diseñar un sistema de software grande, no es útil teorizar sobre problemas P / NP. En ese sentido, creo que hay un contraste muy marcado entre la ingeniería de software y la informática teórica.

¿O la teoría se refiere a algoritmos? No gasta una gran cantidad de algoritmos de escritura de temporización que aprendió en su clase de algoritmos. ¿Por qué? Porque normalmente solo los necesita en casos particulares (y luego lo busca e investiga), o usa una biblioteca ya escrita para usted. No es necesario escribir otro clasificador bayesiano. La abstracción es un principio importante en informática. Creo que los ingenieros de software tienden a no aprender cómo funciona un algoritmo hasta que lo necesitan.

Otra razón es que actualmente hay varios métodos populares de desarrollo de software "hacerlo" que son efectivos. Por ejemplo, en el desarrollo ágil, no diseña un sistema completo de antemano. La razón de esto es porque aún no sabe exactamente lo que está construyendo: desea que lo que está haciendo sea flexible y se adapte a la nueva información y requisitos. Diseñar todo desde el principio y luego construir solo eso no siempre produce el mejor software. Sin embargo, no es la solución para todo. Por ejemplo, supongamos que está diseñando algo nuevo distribuido-computación-cluster-loco-nuevo. No puedes hacer algunos bocetos de servilletas y comenzar tu SCRUM.

TL; DR. Creo que hay algunas dudas sobre la palabra "teoría". Tradicionalmente, la teoría se refiere a los aspectos matemáticos teóricos de la informática. A menos que esté investigando nuevas formas de computación, en su mayor parte la informática teórica no desempeña ningún papel en la vida cotidiana de un ingeniero de software. Los ingenieros de software se preocupan por los patrones de diseño y la arquitectura del sistema. Los detalles específicos de implementación de ciertos algoritmos no son importantes. Muchas veces con ideas menos complicadas es apropiado no diseñar mucho y simplemente comenzar a codificar. Y creo que de aquí surge la idea de que a los programadores no les gusta la teoría.


1
Veo algunas similitudes entre nuestras respuestas, pero sus ideas son obviamente originales y hay algunas diferencias. No estoy de acuerdo en que comprender P / NP no sea útil. No es necesario que estudie la teoría de la complejidad en profundidad, pero un ingeniero de software en funcionamiento debería poder estimar la O (n) de cualquier código dado y decir cosas inteligentes sobre el costo de las soluciones alternativas. Un punto que casi hizo, pero no hizo, es que la teoría a menudo está encapsulada en bibliotecas. Esa es una buena para considerar.
ObscureRobot

"Si alguien resuelve ... el problema de detención en el que nos encontramos con muchos nuevos avances impresionantes": Bueno, desafortunadamente la teoría ha demostrado que esto no tiene solución (no existe ningún programa que pueda decidirlo), así que no creo que haya Se están realizando esfuerzos de investigación para tratar de resolver el problema de detención
Giorgio

Las máquinas de Turing no pueden "Sin embargo, no todas las máquinas concebibles para la imaginación humana están sujetas a la tesis de la Iglesia-Turing ... Es una pregunta abierta si puede haber procesos físicos deterministas reales que, a la larga, eluden la simulación por un Máquina de Turing, y en particular si algún proceso hipotético de este tipo podría aprovecharse en forma de una máquina de cálculo (un hiperordenador) que podría resolver el problema de detención ... También es una pregunta abierta si alguno de estos procesos físicos desconocidos están involucrados el funcionamiento del cerebro humano ... "-Halting Problema, Wikipedia
Jarsen

Entonces, hasta donde sé, y corrígeme si me equivoco, creo que todavía tenemos mucho descubrimiento por hacer sobre la computación. Como se ha mencionado varias veces en este hilo, la informática todavía es muy joven; podría haber mucho más allá de Turning Machines y la arquitectura de Von Neumann.
Jarsen

@Jarsen: Es cierto que la informática es muy joven, pero cualquier computadora que se haya construido hasta ahora solo puede hacer cosas computables de Turing. Hasta donde yo sé (muy poco) incluso las computadoras cuánticas no pueden hacer más (podrían resolver ciertos problemas más rápidamente, pero no podrían resolver más problemas). Entonces, sí, quién sabe qué se puede inventar, pero cualquier formalismo informático que se haya imaginado durante los últimos 70 años no puede hacer más que una máquina Turing.
Giorgio

1

La brecha entre la teoría y la práctica es demasiado grande en este momento. Al hacer teoría, se le dan tres axiomas y posteriormente se muestra que un teorema de una línea tiene una prueba de mil páginas, o ninguna prueba. En ingeniería de software, se le otorgan API inconsistentes de miles de funciones que le brindan innumerables maneras (malas) de implementar una característica no especificada.

La ingeniería de software real enloquecería a la mayoría de los que están en el campo formal, y el desarrollo de software matemático real enloquece a los que están en ingeniería. Ambos campos requieren personas de diferentes aptitudes, y no creo que las aptitudes a menudo se superpongan.


0

La teoría formal supone que puede planificar con precisión todo por adelantado como un producto manufacturado, que el software existirá indefinidamente dentro del mismo entorno y que la resolución de un problema abstracto general es siempre el objetivo. Asume un ciclo de vida de software 4D como producto: diseño, desarrollo, implementación, hecho. La teoría formal se trata de resolver el problema del diseño de software mediante análisis, abstracción, generalización y predicción de cambios futuros. Esto es bueno si tiene un problema bien definido en un dominio directo que es fácilmente analizable, predecible y bastante estático.

La programación práctica consiste en resolver el problema correcto (no el diseño de software) de la manera correcta en este momento, para que sus compañeros de trabajo puedan hacer su trabajo mejor / más rápido / en absoluto, o para que los ingresos puedan fluir a la empresa. Gran parte del software no es como un producto, nunca 'hecho', sino más bien como un ser vivo, que comienza altamente especializado para un nicho ecológico, y puede tener una vida útil muy variable durante la cual necesita resolver problemas nuevos e imprevistos en un Amplia variedad de entornos en constante cambio. En el mundo de los negocios, con políticas y legalidades y competencia y organizaciones, estructuras y tendencias en constante cambio, los requisitos son a menudo ambiguos, complicados con todo tipo de casos especiales, mal definidos y sujetos a cambios rápidos e inesperados. No son analizables, predecibles o estáticos, y a menudo no es lógico o razonable. Es probable que el software sea irrelevante en 2 semanas y que todavía esté en uso en 20 años. Llega al mundo sin saber mucho o sin poder hacer mucho, y necesita ser alimentado, arreglado y entrenado durante toda su vida para crecer fuerte, flexible y capaz de adaptarse a sus entornos cambiantes y nuevos problemas. Si lo descuida después del nacimiento, se volverá salvaje si sobrevive el tiempo suficiente y causará dolor y sufrimiento, resolviendo problemas con fuerza contundente.

La teoría formal no aborda las necesidades de mucho software empresarial del mundo real. Nos engaña a creer que el software puede ser diseñado y hecho. Que es un producto que puede ser ocasionalmente arreglado, pulido o tener cosas pegadas, pero no un ser vivo que necesita ser criado adecuadamente con cuidado y atención constantes durante toda su vida útil. Así que terminamos con un código heredado feo realmente feo, pero la teoría formal probablemente no hubiera ayudado con eso.

Todo eso suena bastante negativo, pero en realidad me encanta usar la teoría formal. Un hermoso diseño siempre me hace sonreír. Sin embargo, eso está principalmente en mi programación de aficionados que no está sujeta a las vicisitudes de los negocios. En el trabajo, trato principalmente con código orgánico y solo espero poder prestarle suficiente atención para que crezca bien, me enorgullezca y no sea desagradable y grosero con otros que tienen que lidiar con él.


0

Las apuestas son menores, el trabajo es más fácil y la administración rara vez ve el valor de un buen diseño. La inestabilidad, mantenibilidad e integridad del sistema son un problema de "TI", no un problema de "Empresa". Todos los ejecutivos tienen una cosa en común. Están 95% enfocados en el dinero o informan a alguien que sí lo está.

El resto de la batalla es con tus compañeros programadores. Muchos de ellos no pueden o no se comprometen a pensar en un problema antes de que comience la codificación. Debido a lo anterior, una buena parte de estas personas son desarrolladores senior, lo que hace aún más difícil lograr un buen diseño en producción.

He visto cómo los líderes de proyectos pierden años agregando funciones y arreglos ad-hoc a proyectos que eran difíciles para empezar, y luego derribo cada intento de poner orden en el caos con frases como "demasiado complicado" o "pérdida de tiempo". No es agradable ver una espiral de proyectos importantes a su inevitable destino porque la gerencia no admitirá que están construyendo su propia prisión diariamente; Sin embargo, me temo que es una desafortunada realidad que muchos desarrolladores han presenciado y, para bien o para mal, han aprendido.

Intento encontrar un medio en mi trabajo. Escribo no más código en proyectos "contaminados" de lo absolutamente necesario, y aprovecho cada oportunidad para mover la funcionalidad fuera de ellos. "Entre proyectos", paso tiempo en el diseño y la limpieza de los proyectos sobre los que realmente tengo control.

Al final, es un gran desastre de política e integridad personal que el 75% de los programadores del mundo no tienen ganas. Apenas puedo soportarlo, yo mismo.


0

En primer lugar, me encanta esta pregunta. He escrito como tres respuestas de 1000 palabras y todas estaban terriblemente equivocadas cuando llegué al final de ellas.

El problema al intentar comparar los dos como análogos, creo, es que la programación es un proceso de modelado que puede ser tan abstracto o tan estrictamente ligado al concreto como desee.

La teoría de la ingeniería estructural, por otro lado, está estrechamente vinculada a conjuntos muy específicos de leyes basadas en la realidad a las que debe ajustarse. No puedes simplemente alterar el contexto o las leyes. El problema en sí está enraizado en esas leyes. Sin embargo, en la programación, a veces la solución está alterando la naturaleza de la pregunta o simplemente colocándola en un contexto diferente.

Si el patrón MVC, por ejemplo, encaja perfectamente, tiene mucho que ver con ese contexto. Una aplicación de escritorio generalmente se ocupa de un idioma y solo un idioma, sin contar los archivos de configuración.

El front-end de una aplicación web, por otro lado, consiste principalmente en dos lenguajes declarativos (no de programación) y JavaScript. La única cosa física que no puede abstraer por completo es el hecho de que siempre existe este muro http para arrojar cosas entre el servidor y el navegador. Independientemente de cómo lo entierre en el código, eso lleva tiempo y un diseño asincrónico.

Obviamente, no puede usar un patrón popular y bien considerado como MVC para manejar las preocupaciones de front-end en la web exclusivamente sin alterar la forma en que podría manejarlo en el contexto de una aplicación de escritorio. De hecho, diría que debe ser consciente de lo que hace que MVC sea útil, pero ni siquiera tratar de implementarlo de una manera particularmente exigente o general. El paradigma de la aplicación web es único, ya que todas las cosas de mirarme son manejadas por el navegador del usuario y todas las cosas de datos / modelos están típicamente en el servidor en alguna parte. Pero, ¿dónde deja eso al controlador? ¿Todo en el servidor o todo en el front-end? Alguien tiene que tener eso. O tal vez MVC no es 100% el mejor ajuste para el escenario. No es un mal ajuste para .NET back end. No es terrible en el contexto de widgets de IU específicos.

Construir una casa resuelve un problema. Sin embargo, los problemas de programación típicos a menudo implican resolver problemas dentro de problemas y, a veces, la solución es redefinir el problema externo. Desafortunadamente, la realidad no está especialmente interesada en esa idea.


0

Glenn Vanderburg presenta una excelente visión sobre las diferencias entre la ingeniería de software y las disciplinas de ingeniería más tradicionales: http://www.youtube.com/watch?v=NP9AIUT9nos

Si un ingeniero civil pudiera probar sus diseños sin ningún costo antes de construir la última cosa, haría mucho menos uso de la teoría. Si en cuestión de segundos pudiera construir un puente miles de veces de forma gratuita para probar cuándo se rompería, lo haría en lugar de pasar meses calculando cuándo podría romperse en teoría ...

En el desarrollo de software, eso es exactamente lo que haces. En lugar de calcular qué tan rápido es su algoritmo en teoría, puede probarlo y conocer la respuesta en cuestión de segundos.

De hecho, la mayoría del software actual ya no está limitado por restricciones físicas como la potencia informática o la memoria. La limitación del software es la complejidad que equivale a sistemas cada vez más grandes. Su gestión de esta complejidad al mantener el sistema comprensible para los humanos es lo que hace el gran desafío en la programación actual.

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.