¿Por que el software tiene errores? ¿Aceptamos los errores como un subproducto natural del diseño y desarrollo de vanguardia, y esperamos que nuestros clientes sientan lo mismo? ¿O deberían los desarrolladores de software intentarlo un poco más?

¿Por qué los programas tienen errores?

Probablemente deberíamos definir un error como cualquier cosa que haga que el software funcione de manera no intencionada.

Michael O. Church dio una gran respuesta. Voy a responder desde un punto de vista ligeramente diferente.

Algunos de estos errores van a ser causados ​​por problemas de hardware.

Estos pueden incluir fallas en el hardware (memoria o discos duros), desbordamientos de la pila o falta de memoria (que podría ser causada por el hardware en sí o por malas prácticas de programación si el programa asigna la memoria), o especialmente con Internet y el software distribuido , puede encontrarse con problemas derivados de la falta de comunicación debido a congestión u otro problema de red. Algunos programas pueden funcionar bien en una pieza de hardware pero fallar en otra, o incluso fallar si hay cierto otro software ejecutándose al mismo tiempo.

Los problemas de hardware pueden incluso involucrar algo tan simple como una batería con bajo voltaje que impide que el procesador funcione correctamente.

Algunos de estos errores serán causados ​​por problemas de software.

Cuando el software está programado, a menudo espera que las entradas estén en un cierto rango, pero no está programado para manejar excepciones. Por ejemplo, si te pregunta tu edad y pones “A”, el software debe saber que esto no es válido. A veces faltan datos de entrada y se supone que son 0, lo que puede causar un error de división por cero. Esto puede deberse a la falta de previsión o la compensación entre la solidez y la finalización del software. Hay “esperar que la entrada sea correcta”, “detectar cuándo la entrada no es correcta” y “ser lo suficientemente robusto para manejar la entrada que no es correcta”.

El software a menudo se usa más allá de los parámetros de diseño previstos , lo que podría incluir situaciones como que todos intenten inscribirse en Obamacare de inmediato (sobrecarga) o el error Y2K. Esos programadores en la década de 1960 nunca esperaron que su software estuviera en uso 30 años después. O tal vez desborde el valor de la cantidad de milisegundos desde que se inicia el programa, lo que solo sucede si el programa está en funcionamiento continuo durante más de 38 días.

Algunos errores son causados ​​por una simple programación descuidada o descuidada , que creará código que se ejecuta y no arroja un error, pero no funciona como se esperaba. Esto a menudo puede suceder si ejecuta un bucle incorrectamente o utiliza incorrectamente los índices de la matriz, por ejemplo. C ++ le permitirá intentar acceder a un valor de matriz que está fuera de los límites y devolver cualquier valor que esté en esa ubicación de memoria, mientras que otros lenguajes de programación arrojarán un error si intenta hacerlo.

El software a menudo depende de otro software. Cuando juegas a la última versión de Grand Theft Auto, los desarrolladores de juegos confían en los controladores para las tarjetas gráficas y el sistema operativo subyacente, por nombrar algunas cosas. Sin tener todo el código fuente, es imposible para ellos eliminar cada problema potencial. E incluso si tuvieran todo el código fuente, sería una tarea hercúlea. Su código tiene que ejecutarse en muchos sistemas operativos diferentes con muchas configuraciones de hardware diferentes y muchos controladores diferentes.

A menudo, los usuarios finales no saben lo que quieren. Esto significa que la especificación sigue cambiando, o peor, no hay especificación y el programa se convierte en la especificación. La mayoría de los proyectos tienen requisitos de diseño ligeramente fluidos, pero algunos son mucho peores que otros.

Errores interesantes que he visto

Un error interesante que vi fue causado por los diferentes formatos de fecha entre los EE. UU. (Mm-dd-aaaa) y Europa (dd-mm-aaaa). El programa funcionó bien en los EE. UU. Hasta el 13 del mes.

Otra buena que vi fue tratar de registrar un código de error en una tabla de base de datos. Desafortunadamente, el tipo de datos para el código de error no pudo manejar la gama completa de códigos de error, lo que en sí mismo causó su propio error (que no se pudo registrar).

También he visto incompatibilidades cuando se mezclan o combinan diferentes idiomas, como problemas con el escape de diferentes caracteres (especialmente los apóstrofes). El software funcionará bien hasta que alguien ponga un apellido como O’Hara.

El uso de variables con nombres similares también puede ser confuso. Es posible que tenga algo como un “x_val” y un “x_value”. O si sus variables tienen un alcance incorrecto, podría estar accediendo a una variable local cuando cree que está usando una global o viceversa.

Otra cosa que puede hacer que las cosas se rompan son las actualizaciones, ya sea de software o equipo. Puede configurar un nuevo servidor de base de datos pero no configurar las cuentas de usuario correctamente o actualizar la configuración en una pieza de software, lo que hará que ese software ya no funcione.

Con problemas en cualquier proyecto, se debe evaluar lo siguiente:

Gravedad
Probabilidad de ocurrencia
Probabilidad de detección

Lo que esto significa es que a través del ciclo de vida del software, los peores errores se corrigen primero, pero puede haber muchos más pequeños que permanecen en el código que tienen poco o ningún impacto y nunca se corrigen. A menudo, los errores requieren el conjunto perfecto de circunstancias antes de que ocurran, lo que los hace extremadamente difíciles de detectar.

Otros factores

Una cosa a tener en cuenta es que el código se usa a menudo en tantos lugares y tantas cosas dependen de él que cualquier cambio en una pieza crítica de código puede afectar literalmente a cientos de aplicaciones. A menudo es necesario asegurarse de que el código sea compatible con versiones anteriores antes de realizar cualquier cambio, o estar absolutamente seguro de que cierta funcionalidad puede ser desaprobada o eliminada.

Tenga en cuenta que incluso en un programa “simple” con 100 líneas de código, hay miles de decisiones que deben tomarse para que el programa funcione correctamente. Incluso con algunas malas decisiones, el programa puede funcionar correctamente la mayor parte del tiempo o el tiempo suficiente para ser útil, con la intención de solucionar cualquier problema que se encuentre a través del uso en la vida real.

También tenga en cuenta que cuando el software se desarrolla, no se desarrolla de forma lineal y, a menudo, lo desarrolla más de una persona. No es como leer una historia de principio a fin. Hay un objetivo general para lo que hace el software. Luego se crean esquemas para determinar qué módulos se necesitan. Se desarrollan algoritmos y estructuras de datos para cada módulo. Y una vez que se entiende, la codificación (y las pruebas) pueden comenzar. A menudo se hacen suposiciones durante todo el proceso para que el código pueda continuar desarrollándose y probado.

Gracias por la oportunidad de citar el libro más perspicaz sobre pruebas, escrito por Gerald Weinberg.

Entonces, “¿Por qué el software tiene errores? ¿Aceptamos los errores como un subproducto natural del diseño y desarrollo de vanguardia, y esperamos que nuestros clientes sientan lo mismo? ¿O deberían los desarrolladores de software simplemente esforzarse un poco más?

Porque nada es perfecto

  • Los humanos no son pensadores perfectos. No importa cuán duro los humanos intenten hacer un trabajo perfecto, a veces cometen errores.
  • La perfección es imposible de lograr. Intentar hacer lo imposible te matará.
  • Nuestras decisiones son emocionales, no racionales.
  • Las personas tienen una inversión emocional en no descubrir que han cometido errores.
  • Cada vez que intentas influir en esos factores cargados de emociones, las intervenciones pueden ser contraproducentes.

Porque probar todo es efectivamente imposible

  • “Probar todo” – demanda imposible.
  • El cerebro humano no solo comete errores, su capacidad es finita.
  • Por mucho que nos gustaría realizar todas las pruebas posibles, no podemos pensar en ellas e, incluso si pudiéramos, no viviríamos lo suficiente como para hacerlas todas.
  • Costaría demasiado.
  • Hay un número infinito de posibles pruebas.
    • Como no puede ver el interior del programa, no tiene idea de qué condiciones extrañas podría haber configurado el programador.
    • Multiplicador: diferentes combinaciones de pasos y datos
    • Multiplicador: pruebas en diferentes configuraciones de hardware.
    • Multiplicador: prueba en diferentes configuraciones de software.

    Debido a que las pruebas y la corrección de errores a menudo no se incluyen en las estimaciones

    • La prueba real, la detección de fallas, solo toma una fracción del tiempo contabilizado en la etiqueta general Prueba, y la falta de definición hace imposible la estimación y programación precisas.
    • Muchas tareas diferentes que requieren muchas habilidades diferentes a menudo se agrupan bajo la rúbrica Pruebas. Tal acumulación distorsiona la planificación, la estimación y las asignaciones de trabajo, en detrimento de todo el proyecto.
    • Las reparaciones hechas a toda prisa tienen muchas probabilidades de empeorar las cosas. Si no tiene prisa, puede ser lo suficientemente cuidadoso con las reparaciones como para no necesitar una nueva prueba, pero si no tiene prisa, ¿por qué no volver a realizar la prueba?

    Debido a la poca conciencia – ignorar o no entender la información

    • Los gerentes generales no necesitan conocer muchos detalles sobre las pruebas, pero sí deben saber que ninguna cantidad de pruebas “probará” que un programa es “correcto”. También necesitan saber que “correcto” ni siquiera es un concepto definible.
    • Las personas a menudo ven la información como amenazante.
    • Debido a que la información puede ser tan amenazante, todos hemos desarrollado un “sistema inmune” que tiende a protegernos de la información que no queremos escuchar.
    • La inmunidad a la información puede socavar todos sus mejores esfuerzos de prueba porque su mensaje sobre errores puede caer en oídos sordos.
  • La regla de tres
    • No importa cómo se le presenten los resultados de las pruebas, tenga en cuenta que su aparente objetividad puede engañarlo.
    • Si no puede pensar en al menos tres posibles interpretaciones del resultado de la prueba, no ha pensado lo suficiente.

    Hice lo mejor que pude resumiendo todo el libro para encajar con la pregunta, pero sé que no es perfecto 🙂

    Si no ha leído el libro, puede obtener una copia electrónica aquí: Perfect Software en LeanPub. Esa será la mejor inversión de $ 10 en su educación en pruebas, independientemente de los años de experiencia en pruebas. Y también conozco a muchos desarrolladores y gerentes de proyectos que adoran este libro.


    ¡Gracias por leer!

    • Si te gustó esta respuesta, vota y sígueme
    • Si lo encuentra útil, por favor comparta con otros

    Puedo sacar cinco puntos principales y uno gigantesco.

    No podemos eliminar todos los errores de software, pero creo que nosotros, como industria, podríamos hacer dos o tres órdenes de magnitud mejor (es decir, 0.1% a 1% tantos errores como hay ahora) si profesionalizamos adecuadamente . En este momento, no usamos las herramientas adecuadas, no construimos compañías con la capacidad de producir un excelente software, y la mayoría de los desarrolladores están mal capacitados, si no completamente incompetentes.

    Ahora para responder a tu pregunta…

    1. El software no siempre es determinista. Tiene que interactuar con el mundo real, lo cual es impredecible. Además, los programas concurrentes o distribuidos a menudo son inherentemente no deterministas.
    2. Razonar sobre el código, en su totalidad, es matemáticamente imposible. La pregunta más básica que puede hacer sobre un programa es: “¿Alguna vez termina?” Incluso esa pregunta no se puede responder para todos los programas. Los programas específicos escritos por humanos para resolver problemas particulares generalmente se encuentran en un subespacio de bajo entropía bien comportado en el que esas preguntas se responden fácilmente, pero el espacio mayor (alta entropía) de “todos los programas” es intratable. A medida que más manos pasan el código, se adentra más en ese espacio de alta entropía. La razón principal por la que “goto” (establecer explícitamente el puntero de instrucción, permitiendo la transferencia de control a cualquier punto del programa) se considera “dañino” es que tiende a producir código de alta entropía y difícil de razonar muy rápidamente.
    3. Pueden ocurrir errores entre dos módulos de trabajo. Puede tener dos módulos que funcionen en sus propios términos, pero uno hace suposiciones sobre el otro que son incorrectas. A veces, estos son errores de comunicación explícitos. Sin embargo, a menudo son más sutiles.
    4. La gente comete errores. Nos pasa a todos. Una de las razones por las que he crecido para preferir la escritura fuerte y estática (por ejemplo, Haskell) es que detecta errores de forma temprana. Los errores están destinados a suceder; Mi objetivo es limitar su costo. Atraparlos temprano es lo mejor. Todavía cometo tantos errores, por línea de código, usando Haskell como en cualquier otro idioma. Es solo que el compilador captura el 95% de ellos muy rápidamente. (Haskell también tiene la buena propiedad de no requerir muchas líneas de código).
    5. Si los insectos viven lo suficiente, la gente comenzará a depender de ellos. Muchos sistemas llegan a un punto en el que corregir un error introduce otros nuevos. Un módulo estaba haciendo lo incorrecto, pero tanta gente dependía del comportamiento incorrecto que solucionarlo causaría roturas en sentido ascendente. En ese punto, te estás acercando mucho al antipatrón “SIWID”: la especificación es lo que hace.
    6. La calidad del software simplemente no es importante para las personas que emplean a la mayoría de los programadores. Este es el grande. Sí, necesita una confiabilidad extremadamente alta si está escribiendo código que se ejecutará en Curiosity, el “Mars rover”. La mayoría de nosotros no lo somos. La mayoría de nosotros escribimos software de línea de negocio para personas y ejecutivos no técnicos de “productos”. Si está escribiendo software comercial aburrido que ocasionalmente elimina los contactos de alguien, corresponde a los ejecutivos y abogados decidir si está bien. Como programadores, odiamos los errores. Son vergonzosos y a menudo no deberían estar allí, y a menudo es más barato arreglarlos que vivir con ellos, a largo plazo. Sin embargo, los ejecutivos han renunciado a la calidad del software. Si pudieran tenerlo a su manera, contratarían schlubs sin talento tan barato como pudieran conseguirlos. Saben que no pueden, por eso no lo hacen, pero no están dispuestos a pagar por el talento y asignar el tiempo que sería necesario para producir software altamente confiable.

    La mayoría de las suposiciones sobre los proyectos de ingeniería tradicionales no se mantienen tan bien con el software:

    * En ingeniería tradicional, el producto de “ingeniería” es un plan y / o un prototipo. En ingeniería de software, el producto final es una versión de software. En las disciplinas de ingeniería tradicionales, como la ingeniería civil, eléctrica o mecánica, el ingeniero toma el diseño conceptual (que es uno de los “requisitos”: cómo debería ser el producto terminado y cómo debería comportarse), y completa todas las incógnitas; qué tan gruesa debe ser la base (y qué tipo de mezcla de concreto se requiere para obtener la resistencia necesaria en ese grosor). ¿Qué calibre de cable se requiere para esta línea troncal para proporcionar un consumo máximo de 1000 amperios a este piso a 120 VCA? ¿Qué valor debería tener esta resistencia para efectuar una caída constante de 3dB en el nivel de señal dado un nivel de señal nominal de 0dBu a una impedancia de 20 ohmios? Todas esas cosas se incorporan en un conjunto final de “planos”, en cuyo momento el trabajo del ingeniero está completo al 80%; luego se queda a la mano mientras alguien más construye la cosa, para que pueda hacer cualquier ajuste al diseño que pueda ser necesario cuando el mundo real levanta su fea cabeza.

    En ingeniería de software, planificar cada línea de código que está a punto de escribir antes de escribirlo es una duplicación del trabajo. El código fuente del programa es, más o menos, el “diseño” final del programa; compilarlo y ejecutarlo es relativamente trivial y requiere casi cero mano de obra. El verdadero trabajo es “finalizar” el diseño conceptual en código fuente.

    * La mayoría de las personas, incluso los no iniciados, pueden leer y comprender un plano. Muy pocos pueden leer el código fuente de la computadora y entender lo que se está haciendo. Utilizamos varias herramientas visuales y de lenguaje natural, como diagramas de entidades, diagramas de flujo, historias de usuarios, etc. para interactuar con nuestros clientes con respecto a lo que estamos a punto de construir para ellos. Estos son necesarios para nosotros porque nadie quiere tratar de descifrar el código de la computadora. A veces ni siquiera un compañero desarrollador de software. El producto principal de un ingeniero es un esquema o plano; Estos están diseñados específicamente para que otros humanos los entiendan, por lo que tienen una simbología relativamente intuitiva y bien entendida. El código de máquina de la computadora está diseñado principalmente para que las computadoras lo comprendan. El código fuente (C ++, C #, VB, Delphi, Objective-C, etc.) es un compromiso que utiliza un lenguaje relativamente más intuitivo para permitir que el desarrollador codifique de la manera que él piensa. Sin embargo, una computadora todavía tiene que entenderlo, y gran parte del talento y la capacitación de un programador de computadoras se dedica simplemente a cómo pensar de una manera que la computadora entienda.

    El resultado es que la forma más fácil de comunicarnos en lo que estamos trabajando es simplemente darle un programa de trabajo para sus comentarios. La mayoría de las metodologías modernas de desarrollo de software tienen como objetivo hacer que el “ciclo de retroalimentación” sea lo más corto posible; desarrollamos una pequeña pieza, la prueba, nos dice que le gusta o no, incorporamos sus comentarios en la próxima pequeña pieza de desarrollo.

    * Es natural suponer que cambiar un edificio una vez construido es difícil, pero cambiar el software una vez escrito es fácil, incluso cuando ninguno de los dos es cierto. Nos parece muy lógico que si los propietarios del Empire State Building, mientras estaba en construcción con un enmarcado y remachado activo en, oh, el piso 35, volvieran al ingeniero y le dijeran “queremos 25 pisos más en el mismo diseño “, el ingeniero les diría que se rellenaran, o al menos que estarían contentos de acomodar esos cambios en los planos , pero los chicos que construyen el edificio real probablemente se alejarían del proyecto por completo si lo pidieran ellos para incorporar los cambios en un edificio a medio terminar. Como resultado, la ingeniería civil a menudo se aborda con una mentalidad de “para siempre”, y los diseños son tan a prueba de futuro como se puede hacer con un conocimiento imperfecto del futuro. Esto a menudo se extiende a los propietarios que se muestran reacios a cambiar las cosas en su propia casa, creyendo, a menudo erróneamente, que el cambio costaría mucho tiempo y dinero.

    Sin embargo, los clientes parecen no pensar en acercarse primero a un equipo de desarrollo de software con requisitos que indican que una aplicación de escritorio escribe en archivos planos, luego, después de que ya llevamos cinco semanas en desarrollo, agregamos algunos requisitos más que, si los hubiéramos conocido antes empezamos, apuntaríamos a una aplicación web con un servidor de base de datos detrás para el almacenamiento de datos. Por alguna razón, el cliente a menudo se enoja cuando decimos que tendremos que comenzar de nuevo y que le estamos facturando por el tiempo y los materiales desperdiciados.

    * En la línea de tiempo relativa del proyecto de ingeniería civil promedio, casi todo lo relacionado con un proyecto de ingeniería de software puede cambiar. Actualmente estoy tolerando varios proyectos de construcción alrededor de mi casa para expandir las autopistas en respuesta al crecimiento en mi área metropolitana. Se abrió el camino para uno de los proyectos más grandes, para volver a desarrollar un intercambio importante, en enero de 2009 y ahora se está acercando a la “finalización sustancial” (donde solo quedan letreros menores y franjas de carril finales). El diseño y la ingeniería de ese proyecto probablemente comenzaron varios años antes del inicio de la construcción. El intercambio y las autopistas circundantes son ahora algunos de los más fáciles de negociar en la ciudad.

    Si un programa de desarrollo de software hubiera comenzado al mismo tiempo, se inició el proyecto de intercambio, prácticamente todo lo relacionado con la plataforma objetivo del diseño inicial, si fuera el estado del arte en ese momento, ahora sería totalmente obsoleto, al igual que todo lo que solía desarrollarse eso. Si estuviera pidiendo una solución integral de hardware / software para un problema, no estaría satisfecho en lo más mínimo con el resultado final.

    * Se espera que los desarrolladores de software pasen una parte significativa de su tiempo desafiando y reinventando la forma en que hacen su trabajo. No se espera que un aprendiz de carpintero que trabaja para un GC diga “esta forma de cablear un interruptor es estúpida, lleva demasiado tiempo y es demasiado difícil. ¿Por qué no puedo hacerlo de esta manera? Es mucho más fácil y rápido” y, de hecho, dicho aprendiz puede ser despedido por ser tan molesto preguntando por qué todo se hace de esta manera en lugar de simplemente hacer lo que se le dijo para que se pueda hacer el trabajo.

    Por el contrario, los desarrolladores de software, incluso los junior, esperan que sus pares ofrezcan ideas y desafíen la forma en que se hacen las cosas. Si ven una forma en que el proceso de desarrollo se puede hacer más eficiente, y lo señalan, generalmente son elogiados, incluso si eso significa que alguien ha desperdiciado su día haciéndolo de la manera “antigua”.

    * La solución de un problema en el software a menudo tiende a crear otro, porque la “solución” simplemente cambia un problema por otro. Las actualizaciones de seguridad a menudo intercambian seguridad por rendimiento; algo se hizo de una manera que funciona más rápido pero espera que una entrada esté en cierto formato. Luego, un atacante se da cuenta de que darle a este código una entrada especialmente formada hace que se asuste, lo que podría bloquear todo el sistema.

    La solución es pasar más tiempo validando la entrada que se le da a este código para que falle “con gracia”. El problema es que esto lleva más tiempo, y si esta es una tarea altamente repetitiva como validar datos de paquetes de red (realizados millones o incluso miles de millones de veces por segundo en servidores o computadoras de juegos), pequeños cambios pueden tener grandes efectos netos.

    * También hay muchos “errores” en los productos de ingeniería convencionales. Considere el 787. Se realizaron cientos de vuelos de prueba, miles de horas hombre de prueba de materiales en tierra, antes de que un solo pasajero que pagara despegara en un 787. Sin embargo, después de que el avión entró en servicio, se han identificado numerosos problemas graves. Incendios de batería, problemas hidráulicos, fugas en el tanque de combustible, grietas en el larguero del ala, etc. No hay un tipo de avión que vuele hoy que no haya sido aterrizado en un momento u otro para la inspección obligatoria de un posible defecto mecánico, basado en algo que salió terriblemente mal en una circunstancia.

    Otro ejemplo; Coche recuerda. Los autos se retiran todo el tiempo por problemas que pueden tener serias implicaciones de seguridad si no se corrigen. Mi propio automóvil está siendo retirado del mercado en estados que usan mucha sal para descongelar carreteras (vivo en el sur, donde la mayoría de nosotros solo llamamos los dos días al año que las carreteras se congelan) porque las líneas de freno están propenso a salpicarse con agua salada, causando corrosión excesiva. GM es infame en los últimos meses por su retiro del interruptor de encendido, y Toyota resistió un calor similar para los pedales de aceleración. A menudo se pierden vidas antes de que estos problemas se identifiquen como lo suficientemente generalizados y peligrosos como para ser retirados del mercado.

    Sí, queremos respuestas sobre por qué estos retiros a veces tardan mucho en llegar después de los informes de fallas. Sí, queremos que quienes intentan ocultar los problemas rindan cuentas. ¿Pero estamos diciendo necesariamente que la forma en que diseñamos y construimos autos es inherentemente defectuosa, que debemos insistir en la “tolerancia cero” para los defectos de fabricación? La gran mayoría dice que no, que este tipo de problemas pueden pasarle a cualquiera, son el resultado de un diseño ideal que se encuentra con el mundo real. Y, sin embargo, en la industria del software, hay gerentes y clientes que insisten en la “tolerancia cero” a los errores de software.

    Al mismo tiempo, hay muchos clientes dispuestos a aceptar defectos de software. Un presentador en una conferencia a la que asistí recientemente dijo que recientemente (en el momento de la presentación) implementaron una versión en el entorno de producción de un cliente que no tenía uno o dos, sino 25 defectos identificados como “críticos”, lo que significa que el defecto impide el acceso a alguna característica básica del sistema requerida por el cliente, o el defecto se identificó como causante de corrupción de datos o una vulnerabilidad de seguridad grave. El cliente no solo aceptó y comenzó a usar la versión implementada, sino que se alegró de hacerlo. ¿Por qué? Porque no tener el software fue más doloroso que vivir con los defectos durante el tiempo que llevaría repararlos.

    Los productos de software han evolucionado durante varias décadas. Tenemos muchas razones para creer que la tecnología de la información es uno de los campos de desarrollo más rápido.

    Las aplicaciones modernas son inteligentes y fáciles de usar. Hay muchos tipos de productos de software; están elaborados para diversos dispositivos, sirven para diferentes propósitos.

    Los desarrolladores de software utilizan muchos métodos e instrumentos para escribir aplicaciones mejores y más complejas. Existen tecnologías realmente buenas que permiten construir un buen software con pocos defectos.

    Pero los especialistas en pruebas de aplicaciones móviles, pruebas de escritorio y pruebas de sitios web saben que los programas libres de errores no existen hoy en día a pesar de las garantías de los ingenieros de software de que sus programas son perfectos.

    Escribir código es una actividad que requiere mucho tiempo y requiere habilidades de conocimiento y creatividad sustanciales. Los programadores hacen lo mejor que pueden, y no es de extrañar que consideren que sus productos son perfectos.

    Cualquier actividad de prueba debe generar informes de error. Si no se encuentran errores de software durante las pruebas de comercio electrónico, pruebas de juegos, pruebas móviles o cualquier otro tipo de prueba, significa que se realizó mal.

    Con frecuencia aparecen errores de software debido a:

    • requisitos incompletos;
    • análisis insuficiente del proyecto;
    • imperfecciones de usabilidad;
    • errores en el código;
    • errores en la lógica de operación.

    Por lo tanto, el mayor productor de errores es la especificación. El asunto es que muy a menudo no hay ninguna especificación sobre el proyecto, no está escrito. A veces, la especificación no se crea de manera adecuada (se omitieron las pruebas de documentación ). En otros casos, las especificaciones cambian y se modifican constantemente durante el proceso de desarrollo, y es difícil comprender los requisitos finales.

    La especificación debe estar bien planificada y formulada. En el campo de las pruebas de software, la planificación es el factor esencial del éxito.

    El segundo generador de errores grandes es el diseño (la implementación del producto en código). Los errores de programación pueden estar relacionados con una documentación deficiente, la complejidad del sistema, la presión de la fecha límite, etc. A veces pueden ocurrir errores debido a errores de prueba.

    Tanto el equipo de desarrollo como el de pruebas deben tener en cuenta un dicho útil: “Si no puedes decirlo, no puedes hacerlo”.

    Además de las excelentes respuestas ya, me gustaría agregar una perspectiva diferente.

    La ingeniería de software no es realmente como construir un puente, a menos que en su proyecto de puente:

    • a mitad de la construcción, la ciudad te dice que quiere cuatro carriles, no dos
    • no tiene forma de estimar con precisión el costo final y, en consecuencia, está ajustando el diseño completamente para adaptarse al presupuesto disponible
    • a mitad de la construcción, la ciudad le dice que omita las características críticas para cumplir con una nueva fecha de apertura

    Ahora, por supuesto, puede crear software de una manera y con un gobierno adecuado, para que no sea víctima de estos y otros factores similares. Las aplicaciones financieras o críticas para la seguridad se crean de esta manera todo el tiempo, y no se envían con errores si se prueban de manera adecuada (exhaustiva) y todo, desde el entorno de ejecución hasta el hardware, está estrictamente controlado. Incluso entonces, Y2K golpea y te das cuenta de que tu diseño no era perfecto. Pero la mayoría de las aplicaciones no financieras / de seguridad se envían con errores, porque las esquinas se cortan y el alcance se arrastra y la estimación es mucho, mucho más difícil que en ingeniería civil.

    El software se parece mucho menos a la ingeniería civil que a la jardinería. Empiezas con un plan y comienzas a hacerlo crecer. Algo no se ve bien, así que desenterrarlo y plantar algo más. Tiende, riega, poda y coaxial. Buscas errores, algunos de los cuales encuentras y otros no. Una enfermedad ataca, paralizando el jardín hasta que se pueda combatir. Y eventualmente, lo llevas a una etapa que es lo suficientemente bueno para que la gente lo vea. La mitad de los que lo ven lo amarán, y la otra mitad pensarán que necesita trabajo: no hay correcto o incorrecto, todo es experiencia del usuario.

    Finalmente, cuando construyes un puente obtienes un puente. Un puente grande, impresionante y monstruoso que puedes ver y tocar y conducir tanques. Cuando construyes software, obtienes … unos y ceros. El tipo con el dinero lo mira y dice: “¿Es esto? ¿Es todo lo que obtuve por mi medio millón de dólares?”. Existe una falta de comprensión en las personas que no son de software acerca de cuán difícil es construir software robusto y eficiente, y por lo tanto, los proyectos están inevitablemente subfinanciados, con muy poco tiempo y con un alcance demasiado ambicioso para el tiempo y el presupuesto asignados. Todos los otros problemas como la calidad (errores) se derivan de eso.

    En primer lugar, permítanme aclarar un punto: las personas pueden escribir software sin errores mediante la verificación formal (como demostrar matemáticamente que el algoritmo es correcto, usando Coq / Agda / Idris).


    Pero, ¿por qué muchos software tienen errores cuando se entregan?
    Razones puramente económicas.
    1: La verificación formal es extremadamente tediosa y no es adecuada para un desarrollo rápido. Por ejemplo, Coq no se completa con Turing al no admitir la recursión arbitraria. Además, todo en Coq es inmutable. La cantidad de bibliotecas del mundo real para desarrollar aplicaciones Coq es casi nula en comparación con las de los lenguajes populares. No tener punteros hace que sea más difícil desarrollar programas de controladores. Pruébelo usted mismo para ver cuánto arrastra su productividad.
    2: Las pruebas muestran la presencia, no la ausencia de errores: Dijkstra.
    3: Los errores que te pican probablemente no te harán mucho daño. Un buen estilo de prueba / codificación / otro software Los métodos de ingeniería detectarán la mayoría de los errores, y el resto de los errores solo afectará a una pequeña proporción de los usuarios. Además, el software siempre puede tener parches / actualizaciones.
    4: Algunas personas creen que Peor es mejorWikipedia , la enciclopedia libre. Si es correcto o no, pone la importancia de estar libre de errores en un nivel inferior.


    En el caso de que la confiabilidad del programa sea la máxima prioridad, de hecho se usa la verificación formal ( http://en.wikipedia.org/wiki/For …), pero ese no es el caso con Google Chrome o Windows.

    En la mayoría de las formas de ingeniería, los errores se considerarían fallas catastróficas. No puedes construir un Bridge v1.0, luego prueba beta en tus primeros 100 clientes. Tienes que hacerlo bien la primera vez.

    Creo que hay dos problemas con esta premisa.

    En primer lugar, los proyectos de construcción tienen todo tipo de “errores” que no son catastróficos. Incluso hay una fase explícita en los proyectos de construcción para identificar y corregir estos errores: la puesta en marcha. Y la mayoría de los grandes proyectos de construcción, por ejemplo, tendrán cientos de “errores” que son reconocidos y aceptados y trasladados a la fase de operación y mantenimiento de la vida de los edificios a tratar; al igual que los proyectos de software. Los errores continuarán apareciendo y continuarán siendo tratados.

    En segundo lugar, puedes construir un “Puente 1.0” e iterar. Esto se hace todo el tiempo durante la fase de Diseño y Documentación del proyecto. Estas iteraciones pueden ser solo dibujos, o pueden ser modelos físicos, recorridos en 3D y simulaciones computacionales (por ejemplo, flujo de calor y aire a través del edificio). Y los experimentos y cambios (“soluciones puntuales”) continuarán durante la construcción, particularmente para aspectos complejos y nuevos del proyecto.

    El London Millennium Bridge es un buen ejemplo de un “error” que se encontró en un puente y que llevó a que el puente se cerrara hasta que pudiera ser “eliminado”.

    Entonces, la respuesta es que el software tiene errores, al igual que todo lo que los humanos construyen.

    (1) El software no es realmente tan determinista. Una gran cantidad de software hoy en día es altamente multiproceso o incluso distribuido, por lo que los eventos internos pueden ocurrir en un orden aleatorio efectivo que conduce a diferentes resultados.

    (2) Incluso el software determinista puede parecer no determinista si tiene algún tipo de dependencia de entrada. Cada pulsación de botón, pulsación de tecla, mensaje o disparo del temporizador conduce a un cambio en el estado interno, lo que puede conducir a resultados diferentes para lo que parecen ser las mismas entradas posteriores. Una sola secuencia de eventos no anticipada puede conducir a un estado interno erróneo, que permanece latente en el sistema hasta que algún evento posterior genere una salida errónea.

    (3) El camino de la intención al resultado deseado no siempre es claro. Los programas a menudo se comparan con las recetas, así que usemos un soufflé de queso como ejemplo. ¿Conoces todos los pasos? ¿Conoce todas las correcciones que podría necesitar hacer en función de pequeñas diferencias en los ingredientes, o entre un horno y otro? Es fácil dejar de lado un paso, o no manejar una condición especial, lo que lleva a un soufflé colapsado. Los programas son muchos órdenes de magnitud más complejos que las recetas, con un potencial correspondientemente mayor para tales errores.

    Como alguien que hizo mi carrera como productor de software de depuración automática y semiautomática, mi función requería aún más atención (en la medida de lo posible) al código 100% correcto. Mis sistemas de depuración eran máquinas virtuales (hipervisores tipo 2) y cualquier “bandera falsa” era obviamente indeseable.

    Pasé la mayor parte del tiempo ajustando el software para permitir que los errores “menos serios” pasen por intervención manual, “permitiendo” que ciertos programas o instrucciones se ejecuten una vez que fueron detectados. Esto generalmente estaba en código multitarea (enhebrado) con memoria a veces compartida.

    La experiencia común era que los programadores en su mayoría querían que la “luz de advertencia naranja” desapareciera (como la luz de presión de aceite en el tablero de un automóvil) independientemente de las consecuencias. A algunas compañías no les gustaba que su código de programador fuera expuesto a críticas. Los más iluminados lo hicieron, así es como me ganaba la vida.

    Los programadores de HLL fueron los peores porque rara vez apreciaron las consecuencias de su falta de conocimiento. Saber cómo funciona realmente una máquina hace que uno se dé cuenta de lo que se puede hacer y no se debe hacer.

    Mi propio código estaba controlado por una tabla de control del 90%, que en mi opinión es la forma más segura de “codificar”. Un intérprete MUY rápido que trabajaba en una mesa de decisiones siempre me funcionó. El diseño de la mesa fue clave para esto. La lógica era del 95% en la tabla, no en el código de programación, que en teoría podría hacerse 100% portátil.

    Siempre comienzo un nuevo programa con una tabla de decisiones y trabajo desde allí.

    Programas deterministas
    El software no es tan determinista en un entorno de subprocesos múltiples donde el tiempo de múltiples interacciones / subprocesos (que son casi imposibles de replicar) tiene lugar en tiempo real.

    Parte de esto se debe a la complejidad y las incógnitas.

    Una pieza de software de tamaño mediano podría tener 200,000 líneas de código nuevo, que requieren algunos millones de otras líneas de sistema y rutinas de biblioteca. Cada línea posiblemente puede estar equivocada de una a cinco formas diferentes. Podría ser una lógica incorrecta, o desactivada por una, o no manejar las condiciones de contorno, o perder importancia, o desbordar la memoria, o bucle sin fin. Cada línea tiene que ser examinada por todos los posibles errores, y los humanos no son buenos en eso.

    También hay muchas incógnitas. El sistema, el lenguaje y las bibliotecas están repletos de detalles no especificados. ¿Qué sucede si envía un código de control ANSI para mover el cursor a la línea -1? ¿Qué sucede si pasa demasiados o muy pocos argumentos? ¿Qué sucede si una red lee el tiempo de espera? ¿Qué sucede si un DIV especifica float: left pero tiene otro div que dice float: right? Muchas incógnitas en un sistema típico.

    Y eso ni siquiera toca los problemas de múltiples versiones del sistema operativo, la plataforma, la base de datos y el navegador. O condiciones de carrera. Hay muchas formas de fallar.

    En el ejemplo del puente, uno no hará un puente de tamaño en kilómetros antes de probar los métodos desarrollando un puente de 20 metros.

    Además, en la estructura y el trabajo mecánico hay muchas aplicaciones de simulación. Proporcionan estimaciones de resistencia casi perfectas para cualquier estructura civil o mecánica.

    Esto no es posible al desarrollar un nuevo producto de software y estas son mis razones:

    La mayoría de los desarrolladores no se esfuerzan más porque no necesitan

    Los desarrolladores de un software son principalmente empresarios y están interesados ​​principalmente en enviar el software. Envío y venta lo antes posible.

    Durante V 1.0 no les interesa la calidad. Están interesados ​​en el valor comercial.

    Además, sus primeros clientes no son público en general. Sus primeros clientes son entusiastas, primeros usuarios y locos. A estas personas no les importa si su aplicación se cuelga todo el tiempo.

    Una vez que el producto tiene el valor comercial suficiente , pueden mejorar sus deficiencias.

    Esta discusión plantea otra pregunta:

    ¿Por qué hay errores incluso en las aplicaciones más maduras?

    Creo que la razón más importante es la diferencia entre los supuestos del usuario final y del desarrollador.

    La parte más difícil en el desarrollo de software es comprender adecuadamente el modelo mental del software del usuario final. Lo que el usuario final piensa y visualiza sobre su software.

    El software desarrollado de acuerdo con el modelo mental del usuario final seguramente contendrá menos cantidad de errores y cambios.

    La segunda razón importante para los errores no es abordar los requisitos no funcionales. Por ejemplo, los recursos necesarios para ejecutar y la aplicación (procesador y ram). Requisitos de escalabilidad y muchos otros.

    Hola a todos,

    Les recomendaré a todos ustedes que defiendan que es probable que ocurran errores en los Programas.

    Lea el libro The Software Conspiracy: Mark Minasi: Amazon.com: Books

    También está disponible en formato PDF en su sitio perosnal.

    Aunque no estoy seguro si puedo pegar el enlace aquí.

    El autor ha emitido un veredicto muy claro y claro sobre por qué el software tiene errores y por qué estamos obligados a tolerarlos.

    Uno de los ejemplos que recuerdo haber leído en este libro es:

    ¿Le gustaría comprar un vehículo que ya sabe que no funcionará de la manera en que se supone que debe hacerlo?

    Puede ser que el motor esté defectuoso o que el embrague o la marcha no puedan aplicar los frenos.

    NO, no tomarás esto.

    Entonces, ¿por qué aceptamos software defectuoso?

    Si bien todos los chicos de TI saltarán sobre mí diciendo que no podemos eliminar todos los posibles errores.

    Entonces, ¿de qué sirve escribir una pieza de software horrible?

    No entiendo por qué necesitamos aceptar software con errores.

    Incluso los peces gordos como MS, Oracle no pueden proporcionar software libre de errores.

    Razón, la ley no es muy estricta con ellos.

    Si hubiera habido una ley muy estricta sobre el software propenso a errores, nunca habría habido esta situación en la que de vez en cuando nos encontramos con algún error nuevo en el sistema.

    Imagine un error en algún software médico que proporcione información incorrecta y resulte en un tratamiento incorrecto.

    Las consecuencias son muy altas y preocupantes.

    Le recomendaré leer algunas páginas de este libro y decidir por qué el software tiene errores.

    Según yo, los humanos son propensos a cometer errores y algunos de ellos son demasiado vagos para molestarse y corregirse a sí mismos.

    Eso lo dice todo

    La ingeniería tiene muchos errores

    Y sí, la mayoría de las veces se consideran fallas catastróficas.

    Tanto el software como el hardware están limitados por Calidad vs Tiempo vs Costo, también conocidos como restricciones triples.
    No puedes tener los tres al mismo tiempo.

    En un proyecto de hardware, la calidad suele ser más importante que el costo y el tiempo, pero hay muchos ejemplos en los que se hizo otra prioridad. A veces está bien, a veces las cosas van bien.

    En el software, el tiempo de comercialización suele ser el factor más importante y, dado que tiene la opción de actualizar una vez que ha llegado al mercado, tiene sentido desde una perspectiva comercial priorizar de manera diferente.

    La misma razón por la que cualquier programa tiene algo: para interesar a los espectadores y, por lo tanto, obtener calificaciones más altas. Los programas sobre errores generalmente intentan ser atractivos por su valor educativo o por su valor “bruto”; ver El mundo de los insectos o Insectos del infierno para ver ejemplos de ambos.

    Oh espera . . . no quiso decir “por qué los programas de televisión contienen información sobre los insectos”, quiso decir “por qué los programas de computadora no funcionan como pretendían sus autores”. Ese fue completamente mi error. Comencé a devolverte una respuesta inmediatamente después de analizar la primera parte de tu pregunta cuando pensé que había identificado toda la información relevante porque estaba tratando de ser lo más eficiente posible.

    El software no es completamente determinista. Incluso problemas aparentemente sencillos, como la aritmética de punto flotante, pueden estar llenos de problemas cuando el programador no comprende completamente cómo funcionan el lenguaje de programación y el hardware subyacente.

    También es extremadamente difícil escribir un programa libre de errores si el problema no se entiende perfectamente.

    Podría seguir elaborando pero, en aras de la eficiencia, solo diré que la respuesta de Michael O. Church es bastante buena.

    Junto con las preguntas y respuestas sobre los números y los porqués de los nuevos errores de lanzamiento, pensé que a los lectores que no son programadores de sistemas les gustaría leer sobre un error real de nuevo lanzamiento -> cómo / por qué sucedió y cuál fue el mecanismo por el cual provocó la presentación de un informe de error. Entonces, lo que se necesitó para arreglarlo.
    En 1968, después de más de un año de capacitación en operaciones y programación, tuve la suerte de mudarme directamente al Grupo de Soporte de Software Regional para la región Este-Central de Honeywell. Mi trabajo consistía en investigar y potencialmente resolver problemas informados por los usuarios con nuestro software del sistema. Mis especialidades eran compiladores y sistemas operativos. El primer problema que analicé acababa de pasar a la parte superior de la lista de problemas de la nueva versión de COBOL.
    Resultó que varios de nuestros clientes clave de Automotive Branch habían estado utilizando una función de compilación que permitía la escritura y, por supuesto, la lectura de archivos de cinta de longitud variable. Esa característica dejó de funcionar correctamente con la introducción de la última versión del compilador; 9.0. Las ventajas de esa característica fueron que, para algunas aplicaciones de uso frecuente, permitió una reducción significativa en el número de cintas utilizadas, una reducción en el tiempo de E / S de escritura y lectura y una reducción en el número de rebobinados de cinta que requieren mucho tiempo. remontajes.
    El problema básico era que los programas que usaban esa función, después de ser compilados nuevamente con la nueva versión, comenzarían y, durante cierto tiempo de cinta en el segundo y posteriores carretes, continuarían escribiendo solo registros de la misma longitud que el último en el carrete anterior o más corto. La prioridad del problema se intensificó porque, por alguna razón, ¡a los usuarios no les gusta perder los datos de los clientes!
    Afortunadamente, fue fácil para mí replicar el problema escribiendo un simple programa COBOL de caso de prueba que usara la característica de longitud variable de manera aleatoria y usara una cinta de salida virgen relativamente corta. Efectivamente, la secuencia de grabación que elegí fue tal que la falla apareció en el primer intercambio de carrete. Esto podría demostrarse mediante simples volcados de cinta a la impresora. Ahora la pregunta era: ¿Por qué estaba “repentinamente” fallando de esa manera?
    Para comprender el mecanismo de falla, debe tener en cuenta que la arquitectura de la computadora en cuestión usó “signos de puntuación” para controlar el movimiento de datos dentro y fuera de la memoria principal. En este caso, parte de la lógica de la función de longitud variable era establecer una “Marca de registro” en la dirección correcta en el búfer de salida para terminar la transferencia de datos de salida de cinta. El puntero utilizado para mantener esa dirección en el código original era un DSA (Definir dirección de símbolo) etiquetado como “ptrchr”. Originalmente, después del intercambio de cinta, en el siguiente comando de escritura de cinta, el código eliminaría la marca de registro previamente establecida y establecería una nueva en la nueva dirección correcta (como ahora se almacena en ptrchr). Lo hizo si el nuevo registro tenía la misma longitud que el anterior o no.
    La nueva versión tenía código para implementar una nueva característica, una “Máquina de escribir de consola”. Anteriormente, el operador realizaba el intercambio de cintas en función de los códigos octales que se muestran en un panel de luces; ahora el operador recibiría instrucciones simples en la máquina de escribir. El problema surgió porque el desarrollador del nuevo código, aparentemente en un intento por conservar la memoria (?), Optó por “reutilizar” ptrchr para administrar su propia puntuación. Por lo tanto, durante el intercambio de cinta, la dirección del búfer de salida de cinta contenida en ptrchr se superpuso con una dirección totalmente no relacionada y se perdió.
    La solución fue fácil: simplemente asigné un nuevo DSA para la lógica de la máquina de escribir y cambié la referencia en el código de administración del búfer de la máquina de escribir para referirme a él (creo que lo llamé “Bob”). ¡Todos estaban felices, especialmente mi nuevo jefe, porque el mundo ahora era un lugar mejor!

    Mientras que Dave Hagler, Dustin Taylor y Nick Drew están en lo correcto, hemos sido condicionados a esperar errores y son muy difíciles de rastrear. Hay una serie de otros problemas que enfrentan los ingenieros de software que no enfrentan los ingenieros civiles.

    1. Llevamos mucho tiempo construyendo puentes. Tenemos los principios abajo. Llevamos 50 años escribiendo software. Todavía estamos aprendiendo
    2. El kit de herramientas de ingenieros civiles es antiguo. El kit de herramientas de ingenieros de software tiene como máximo 50 años, suponiendo que usa C. Diez años para gran parte del código que escribe. No hay garantía de que, incluso si el código es perfecto, la herramienta lo interprete correctamente. El error está en la herramienta, no en el programa.
    3. Parece que hemos olvidado que debemos escribir código para hacer una cosa y luego juntar las partes.
    4. El ingeniero civil puede “sobre” construir su puente. ¿Debo usar una viga “T” o una viga “I”? Bueno, la “T” probablemente será suficiente, pero de todos modos use la “I”. Nadie se queja nunca de un puente que no se derrumba. Ni siquiera hay un concepto de sobre construcción en software.
    5. Las herramientas de software cambian constantemente, lo que hace que la escritura de código sea un proceso nuevo. Imagine que un carpintero tuviera que volver a aprender cómo usar un martillo, cada vez que Black & Decker lanzara una nueva versión. Y esto no es solo aprender nuevas características, esto se aplica a la sintaxis del código en sí. Piense en PHP4 y PHP5.
    6. El software le permite obtener el mismo resultado en una miríada de formas diferentes. A menudo, dos ingenieros de software que usan el mismo lenguaje encontrarán dos, quizás tres formas de llegar al resultado deseado. Agregue a eso una opción en el lenguaje que podrían usar y el resultado final podría ser cincuenta programas diferentes, todos dando el mismo resultado.

    //EDITAR//

    Hace poco vi esto en SciAm:
    http://www.scientificamerican.co
    Tal vez los ingenieros civiles no son tan buenos como creemos que son.

    Porque es difícil hacer las cosas bien.

    Estás hablando de sistemas que potencialmente involucran millones de pequeñas operaciones que mueven fragmentos de información de un lado a otro que luego son utilizados por millones de personas de diferentes maneras. A veces, esas personas están interactuando.

    Por lo tanto, para asegurarse de que no tiene ningún problema, necesitaría probar todas las posibles interacciones con todas las formas posibles en que las personas podrían usar el proyecto, que es literalmente millones de millones de cosas para verificar.

    Cuando tienes una fecha límite además de eso, no hay posibilidad de probar todo. A menudo tienes suerte si hay tiempo para probar las cosas que sabes que han cambiado.

    Tenga en cuenta que las empresas han estado fabricando automóviles durante cien años, y de vez en cuando, alguien lanza un modelo que realmente mata a las personas. Misma razón.

    Todos los problemas de la computadora son creados por una tuerca floja entre la silla y el teclado – My Tshirt

    Todos los errores informáticos son problemas humanos. Suele surgir porque

    1) La forma en que un usuario usa el sistema es diferente de cómo fue diseñado para ser usado. Esto podría deberse a que el usuario lo está usando mal, o las personas que escribieron las especificaciones no anticiparon que el usuario lo usara de cierta manera. Es lo mismo que sucede cuando le pides a un jardinero que elimine las malas hierbas de tu jardín. ¡Si no eres muy específico, él podría eliminar todas tus plantas!

    2) Hay requisitos implícitos que los programadores no pudieron anticipar. Por ejemplo, desde el punto de vista del usuario, existe un requisito implícito de que los dispositivos en su casa no interfieran entre sí; Que usar su microondas no debería crear una explosión EMP que elimine todos los componentes electrónicos. Sin embargo, hasta hace unas décadas, la gente veía habitualmente interferencias en la televisión cuando usaban su licuadora.

    3) Determinista no significa simple. Cuando habla de un sistema, las entradas y salidas pueden estar bien definidas. Sin embargo, las diversas permutaciones de entradas pueden llegar a ser bastante grandes. Esto hace que sea costoso probar el sistema en cada combinación posible de entrada. La cantidad de tiempo invertido en las pruebas generalmente es una función de cuánto dinero van a gastar las personas en las pruebas, que es una función de a) cuánto dinero tienen b) cuánto dinero van a perder cuando aparece una falla. Por lo tanto, la mayoría de las compañías priorizan los diferentes tipos de pruebas que se pueden hacer, y luego básicamente trazan una línea donde las pruebas deberían detenerse. No muchas compañías prueban completamente todas las entradas y salidas posibles. Si se trata de una aplicación de misión crítica, como si la vida de alguien depende de ella, o si un cohete de un millón de dólares está montado en ella, entonces sí, habrá muchas más pruebas. ¿Pero un enrutador doméstico? ¡Reiniciar soluciona la mayoría de los problemas! Fuggetaboutit! A la mayoría de las compañías les resultará más barato contratar personal de servicio al cliente que le diga al cliente que reinicie el enrutador que probarlo por completo. Por supuesto, la mayoría de las empresas establecidas han “probado en campo” sus dispositivos. Detrás de escena, trabajan para solucionar los problemas comunes que se encuentran en el campo.

    3) El software en sí mismo es determinista. Pero el hardware no lo es. Las cosas no suelen suceder en el orden correcto. Especialmente cuando estás hablando de CPU multi-core que pueden ejecutar 2 cosas al mismo tiempo. El orden en que se ejecutan las cosas puede cambiar. Además, el ruido externo puede crear entradas imprevistas. Enciende su licuadora que interfiere con su enrutador, y de repente su enrutador recibe una entrada que nunca antes había visto. ¡No hay forma de que el fabricante pruebe eso!

    De la pregunta: “absolutamente ninguna experiencia escribiendo programas, pero puedo seguir un poco de matemática y lógica”.

    Imagine la vida de un programador, haciendo “matemáticas y lógica” todo el día. Es posible cometer errores, tanto que los sistemas están desarrollados para detectar esos errores o evitarlos en primer lugar.

    Es posible cansarse o distraerse mentalmente; de ​​ahí la pregunta: ¿cómo pueden los programadores lidiar con la carga cognitiva de la programación?

    La carga cognitiva se refiere al esfuerzo de hacer matemáticas y lógica, o tipos similares de pensamiento, todo el día, enseñarle a la computadora qué hacer y verla cometer errores. Y a menudo, mientras corres o haces múltiples tareas con otra cosa.