En informatique, la robustesse est la capacité d'un système informatique à faire face aux erreurs pendant l'exécution et à gérer des entrées erronées. Cela englobe de nombreux domaines, notamment la programmation robuste, l'apprentissage automatique robuste et la conception de réseaux robustes. Des techniques formelles, telles que les tests par fuzzing, sont essentielles pour démontrer la robustesse, car elles impliquent de tester avec des entrées invalides ou inattendues. Alternativement, l'injection délibérée de fautes peut être utilisée pour tester la robustesse, et divers produits commerciaux effectuent des tests de robustesse de l'analyse logicielle.
La construction de systèmes robustes couvrant tous les points de défaillance possibles est difficile en raison de la vaste quantité d'entrées et de combinaisons d'entrées possibles. Étant donné que les tests exhaustifs de tous les cas sont impossibles en pratique, les développeurs généralisent les cas de test. Par exemple, lors du test d'entrées entières, un développeur peut sélectionner un nombre négatif, zéro et un nombre positif pour représenter l'ensemble des réels. Cette méthode est plus efficace mais plus sujette aux échecs. La généralisation des cas de test est une technique pour faire face aux défaillances dues aux entrées utilisateur invalides, mais les systèmes peuvent également échouer pour d'autres raisons, telles que les déconnexions réseau. Quoi qu'il en soit, les systèmes complexes doivent gérer toute erreur avec élégance, et certains des systèmes les plus robustes sont évolutifs et facilement adaptables à de nouvelles situations.
Défis pour Atteindre la Robustesse
Les programmes et logiciels sont généralement des outils axés sur des tâches spécifiques, ce qui les rend moins généralisés et flexibles que des systèmes comme Internet ou les systèmes biologiques, qui s'adaptent à leur environnement. Une façon dont les systèmes biologiques atteignent l'adaptation est la redondance. Par exemple, les humains n'ont généralement besoin que d'un seul rein, mais en avoir un second offre une marge de manœuvre en cas de défaillance. Ce principe peut être appliqué aux logiciels, mais avec des défis. Ajouter du code à l'aveugle n'est pas recommandé, car cela introduit plus d'erreurs, augmente la complexité et rend le système plus difficile à comprendre. Le nouveau code doit posséder une fonctionnalité équivalente afin que si une fonction tombe en panne, une autre puisse la remplacer, en utilisant une diversité logicielle manuelle ou automatisée. Cela nécessite une logique supplémentaire pour savoir comment et quand s'adapter au point de défaillance, augmentant ainsi la complexité du système. Les développeurs doivent équilibrer la redondance avec la complexité. Actuellement, les pratiques en informatique tendent à se concentrer sur l'évolutivité et l'efficacité plutôt que sur la construction de systèmes robustes, en partie parce que la robustesse est difficile à atteindre de manière générale.
Programmation Robuste
La programmation robuste est un style qui se concentre sur la gestion élégante des terminaisons inattendues et des actions inattendues, en affichant des messages d'erreur précis et sans ambiguïté qui aident les utilisateurs à déboguer les programmes. Elle est guidée par plusieurs principes :
- Paranoïa : Le programmeur suppose que les utilisateurs cherchent à casser le code et que son propre code peut échouer ou fonctionner incorrectement.
- Stupidité : Le programmeur suppose que les utilisateurs essaieront des entrées incorrectes, bidon et malformées. Par conséquent, le programmeur renvoie des messages d'erreur intuitifs et sans ambiguïté qui ne nécessitent pas de consulter des codes d'erreur, visant à être aussi précis que possible sans être trompeur.
- Impléments dangereux : Les utilisateurs ne doivent pas avoir accès aux bibliothèques, structures de données ou pointeurs vers des structures de données. Ces informations doivent être cachées pour empêcher toute modification accidentelle qui pourrait introduire des bogues. Lorsque les interfaces sont correctement construites, les utilisateurs les utilisent sans trouver de failles, se concentrant uniquement sur leur propre code.
- Impossible : Les modifications de code peuvent introduire la possibilité qu'un cas « impossible » se produise. Ces cas sont supposés être très peu probables, et le développeur met en œuvre une gestion pour eux en conséquence.
Apprentissage Automatique Robuste
La robustesse dans l'Machine learning fait généralement référence à la stabilité des algorithmes. Pour qu'un algorithme d'apprentissage automatique soit considéré comme robuste, soit l'erreur de test doit être cohérente avec l'erreur d'entraînement, soit la performance doit rester stable après l'ajout de bruit à l'ensemble de données. Avec l'essor de l'Deep learning, il y a un intérêt croissant pour la robustesse des réseaux de neurones, en particulier en raison de leur vulnérabilité aux attaques adversariales. La recherche dans ce domaine implique souvent des techniques comme l'entraînement adversarial, où les modèles sont entraînés sur des entrées perturbées pour améliorer leur résilience. Le domaine a des liens avec les travaux de chercheurs tels que Aleksander Madry, qui a étudié la robustesse adversarial, et Thomas G. Dietterich, qui a exploré les codes de sortie correcteurs d'erreurs et l'apprentissage robuste.
Conception de Réseaux Robustes
La conception de réseaux robustes est l'étude de la conception de réseaux face à des demandes variables ou incertaines. Semblable à la conception de logiciels, la robustesse dans la conception de réseaux est vaste en raison des vastes possibilités de changements ou d'entrées. Cela implique de créer des réseaux capables de maintenir les performances et la connectivité sous différentes conditions de trafic ou pannes. Ce domaine est pertinent pour les fournisseurs d'infrastructure cloud comme Amazon Web Services, Microsoft Azure et Google Cloud, qui doivent garantir un service fiable malgré des charges variables et des pannes matérielles potentielles.
Algorithmes Robustes
Il existe des algorithmes qui tolèrent les erreurs dans l'entrée. Ces algorithmes sont conçus pour produire des sorties correctes ou acceptables même lorsque les données d'entrée contiennent du bruit, des valeurs aberrantes ou d'autres inexactitudes. Cela est particulièrement important dans des domaines comme la vision par ordinateur et le traitement du signal, où les données du monde réel sont souvent imparfaites. Les algorithmes robustes peuvent utiliser des méthodes statistiques pour identifier et pondérer à la baisse les valeurs aberrantes, ou ils peuvent être conçus avec la redondance à l'esprit, semblable aux principes de la programmation robuste.
Voir Aussi
- Tolérance aux pannes
- Programmation défensive
- Exigence non fonctionnelle