Solidez (informática)
# Solidez (informática)

En informática, la solidez (Robustness en inglés) es la capacidad de un sistema informático para hacer frente a errores durante la ejecución y a entradas erróneas. La solidez puede abarcar muchas áreas de la informática, como la programación sólida, el aprendizaje automático sólido y la red de seguridad sólida. Las técnicas formales, como las pruebas fuzz, son esenciales para demostrar la solidez, ya que este tipo de pruebas implican entradas no válidas o inesperadas. También se puede utilizar la inyección de fallos para probar la solidez. Varios productos comerciales realizan pruebas de solidez de análisis de software.

## Introducción

En general, construir sistemas solidos que abarquen todos los puntos de fallo posibles es difícil debido a la gran cantidad de entradas y combinaciones de entradas posibles. Dado que probar todas las entradas y combinaciones de entradas requeriría demasiado tiempo, los desarrolladores no pueden analizar todos los casos de forma exhaustiva. En su lugar, el desarrollador intentará generalizar dichos casos. Por ejemplo, imagine que introduce algunos valores enteros. Algunas entradas seleccionadas podrían consistir en un número negativo, un cero y un número positivo. Al utilizar estos números para probar el software de esta forma, el desarrollador generaliza el conjunto de todos los reales en tres números. Se trata de un método más eficaz y manejable, pero más propenso al fracaso. La generalización de los casos de prueba es un ejemplo de una técnica para hacer frente a los fallos, en concreto, los debidos a la introducción de datos no válidos por parte del usuario. Por lo general, los sistemas también pueden fallar por otros motivos, como la desconexión de la red.

En cualquier caso, los sistemas complejos deben gestionar con elegancia los errores que se produzcan. Hay muchos ejemplos de sistemas con éxito. Algunos de los sistemas más robustos son evolutivos y pueden adaptarse fácilmente a nuevas situaciones.

## Desafíos

Los programas y el software son herramientas centradas en una tarea muy específica, por lo que no son generalizados ni flexibles. Sin embargo, las observaciones en sistemas como Internet o los sistemas biológicos demuestran la adaptación a sus entornos. Una de las formas en que los sistemas biológicos se adaptan al entorno es mediante el uso de la redundancia. Muchos órganos son redundantes en los seres humanos. El riñón es un ejemplo. Por lo general, los seres humanos sólo necesitan un riñón, pero tener un segundo riñón permite prever posibles fallos. Este mismo principio puede aplicarse al software, pero existen algunas dificultades. Cuando se aplica el principio de redundancia a la informática, no se sugiere añadir código a ciegas. Añadir código a ciegas introduce más errores, hace el sistema más complejo y lo hace más difícil de entender. El código que no aporta ningún refuerzo al ya existente no es deseable. Por el contrario, el nuevo código debe poseer una funcionalidad equivalente, de modo que si una función se rompe, otra que proporcione la misma función pueda sustituirla, mediante la diversidad manual o automatizada del software. Para ello, el nuevo código debe saber cómo y cuándo acomodarse al punto de fallo, lo que significa que hay que añadir más lógica al sistema. Pero a medida que un sistema añade más lógica, componentes y aumenta de tamaño, se vuelve más complejo. Por tanto, al hacer un sistema más redundante, el sistema también se vuelve más complejo y los desarrolladores deben considerar el equilibrio entre redundancia y complejidad. En la actualidad, las prácticas informáticas no se centran en la construcción de sistemas sólidos, sino más bien en la escalabilidad y la eficiencia. Una de las principales razones por las que hoy en día no se presta atención a la solidez es porque es difícil de hacer de forma general.

## Ámbitos

### Programación sólida

La programación sólida es un estilo de programación que se centra en el manejo de terminaciones y acciones inesperadas. Requiere que el código maneje estas terminaciones y acciones con elegancia mostrando mensajes de error precisos e inequívocos. Estos mensajes de error permiten al usuario depurar más fácilmente el programa.

**Paranoia**

Al crear software, el programador asume que los usuarios van a romper su código. El programador también asume que su propio código escrito puede fallar o funcionar incorrectamente.

**Estupidez**

El programador asume que los usuarios probarán entradas incorrectas, falsas y malformadas. En consecuencia, el programador devuelve al usuario un mensaje de error inequívoco e intuitivo que no requiere buscar códigos de error. El mensaje de error debe intentar ser lo más preciso posible sin inducir a error al usuario, de modo que el problema pueda solucionarse con facilidad.

**Herramientas peligrosas**

Los usuarios no deben tener acceso a bibliotecas, estructuras de datos o punteros a estructuras de datos. Esta información debe ocultarse al usuario para que éste no las modifique accidentalmente e introduzca un error en el código. Cuando estas interfaces están correctamente construidas, los usuarios las utilizan sin encontrar resquicios para modificarlas. La interfaz ya debe estar correctamente implementada, por lo que el usuario no necesita hacer modificaciones. Así, el usuario se centra únicamente en su propio código.

**No puede suceder**

Muy a menudo, el código se modifica y puede introducir la posibilidad de que se produzca un caso "imposible". Por lo tanto, los casos imposibles se asumen como altamente improbables. El desarrollador piensa en cómo manejar el caso que es altamente improbable, e implementa el manejo en consecuencia.

### Aprendizaje automático sólido

El aprendizaje automático sólido se refiere normalmente a la robustez de los algoritmos de aprendizaje automático. Para que un algoritmo de aprendizaje automático se considere sólido, el error de prueba debe ser coherente con el error de entrenamiento, o el rendimiento debe ser estable después de añadir ruido al conjunto de datos. Recientemente, en consonancia con su creciente popularidad, ha aumentado el interés por la solidez de las redes neuronales. Esto se debe especialmente a su vulnerabilidad frente a ataques adversos.

### Diseño de red sólido

El diseño de redes sólido es el estudio del diseño de redes ante demandas variables o inciertas. En cierto sentido, la solidez en el diseño de redes es tan amplia como la solidez en el diseño de software, debido a las enormes posibilidades de cambios o entradas.

### Algoritmos sólidos

Existen algoritmos que toleran errores en la entrada.

