Temos um sistema aqui. Recentemente, há um cálculo incorreto em um dos números no relatório gerado pelo sistema. Ao longo de nossa experiência, nunca encontramos nenhum problema / erro neste sistema há alguns anos.
Como o criador deste sistema já havia saído, dificilmente podemos rastrear os programas. Mas verificamos os dados de entrada, a configuração e eles estão corretos.
Agora, minha pergunta é: um programa de computador de repente dará errado, sem qualquer motivo lógico? Se eu bater na máquina do servidor, um dos números calculados pelo computador se tornará outro número e cometerá erros de cálculo?
Concordo que minha ideia é bastante louca, mas eu só quero saber, como podemos saber que o problema não é causado pelo programa e pela entrada, mas por alguns outros fatores?
PS Este sistema louco não tem log.
Respostas:
Eu diria que não!
Em teoria, a resposta é não, só podemos testar:
Isso é consideravelmente menor que o número total possível de ambientes, horários e casos que o programa pode encontrar durante sua vida útil. Além disso, temos pouco conhecimento do futuro, caso você planeje lidar com uma inflação de 10.000%, o seu programa deve lidar com uma nova arquitetura super 31 de 31 bits?
A teoria é apoiada pela experiência que eu pessoalmente encontrei:
fonte
Em teoria, se você começar com um estado idêntico, o resultado será idêntico. Na realidade, garantir um estado inicial idêntico em equipamentos "de tamanho de servidor" é praticamente impossível.
Pegue variáveis não inicializadas. Veja este código:
Isso produzirá resultados inesperados uma vez em 65536 execuções. E, a menos que você garanta que a memória estará no mesmo estado antes de cada execução,
i
será inteiramente aleatória.Existem centenas de maneiras semelhantes para que os erros apareçam após elementos imprevisíveis do estado inicial que alguém esqueceu de substituir ou casos de fronteira que acontecem raramente - condições de corrida em ambiente multithread, acesso fora do limite da matriz, E / S de disco no sistema de arquivos corrompido e em breve.
Se você pode provar que o programa está livre de bugs, existem apenas os raios cósmicos que podem quebrá-lo. Mas a prova matemática de correção de qualquer coisa mais complexa do que dois loops aninhados está muito além do escopo dos maiores sistemas (e custa uma pequena fortuna) e, pelo resto, você só pode esperar.
fonte
Se você tiver exatamente o mesmo ambiente de computação, a entrada X de um programa sempre produzirá o mesmo resultado R. Na prática, raramente é possível executar um único programa isoladamente. Hoje, o aplicativo mais simples é executado em um sistema operacional e compartilha memória com outros programas que podem ser 'carregados' na memória ao mesmo tempo. Esses programas podem alterar a memória de maneira a causar mau funcionamento de um determinado programa. Este é um problema famoso com variáveis do tipo 'ponteiro', por exemplo. Geralmente, esses erros causam comportamentos anormais do sistema e não resultados de cálculos incorretos.
No seu caso, suponho que o problema possa não ser (e geralmente não é) o que descrevi acima. O problema pode ser o seguinte:
Por causa do exposto e de muitos outros motivos pelos quais as pessoas do software gastam tantos recursos na tentativa de criar software correto, no entanto, os erros de software ainda ocorrem, mas os erros são 'lógicos' e têm um motivo, apenas que o motivo não é óbvio. para alguns sem boas pesquisas. Portanto, em geral, o software testado é previsível e não produz resultados aleatórios. Devido à complexidade de alguns programas e outros fatores, até os programas testados podem dar errado, mas quando isso acontece, os erros são por um motivo lógico.
A resposta é não, em geral, o software não é frágil nesse sentido.
O que você pode fazer é isolar os casos em que o erro está ocorrendo, encontrar a semelhança entre esses conjuntos de dados que causam o erro e encontrar a diferença entre esses conjuntos e os outros conjuntos que produzem o resultado correto. Você pode identificar o conjunto específico de valores que está causando o problema. Por exemplo, você pode achar que toda vez que uma variável tem um valor negativo, o resultado está errado.
Informações atualizadas sobre erros de corrupção de memória: Consulte Corrupção de memória
fonte
Você pode garantir que um programa não tem bugs e nunca dará errado? Não, infelizmente não.
Você pode demonstrar que um programa tem um número suficientemente pequeno de bugs que o custo de encontrá-los e corrigi-los excede em muito os benefícios dessa ação? Parece-me que você já tem.
Parafraseando uma antiga máxima estatística, todos os programas estão errados, mas alguns são úteis.
fonte
Estou inclinado a dizer não , você não pode provar que um programa nunca dará errado ou fornecerá um resultado incorreto, mesmo se você puder assumir uma entrada perfeita.
Raku mencionou prova formal de correção. É uma coisa a considerar, mas, a menos que eu esteja completamente enganado, isso ainda terá que assumir um ambiente de execução perfeito. Portanto, com uma certa quantidade de tempo e esforço, talvez você possa provar que o programa está correto , mas isso não prova necessariamente que ele sempre produzirá os resultados corretos , mesmo com a entrada perfeita. O ambiente de execução é importante. E eu seria cauteloso em assumir que a entrada é sempre perfeita também.
É por isso que, em determinadas situações de alta disponibilidade, várias implementações e ambientes de execução completamente independentes são usados e os resultados são comparados para garantir que eles estejam dentro de uma margem de erro aceitável um do outro. Em algumas situações, essa margem pode muito bem ser zero. Mesmo na década de 1960, isso foi considerado importante o suficiente para incluir conjuntos separados de hardware de computação nas naves espaciais. Mesmo que uma descarga estática incorreta, um raio cósmico ou o que quer que seja afete ambos os computadores simultaneamente, as chances de que ambos sejam afetados da mesma maneira (principalmente se ainda estiverem trabalhando e produzindo resultados válidos) são minúsculas. As chances do mesmo bug se espalhar em duas implementações completamente separadas também são extremamente pequenas. E assim por diante.
fonte
A maioria da computação (padrão) é determinística, eu acho.
Se possível, configure-o para fazer um lote de 1000 ou 10000 etc., iterações com os mesmos dados de entrada e verifique se os resultados são iguais.
Certifique-se de que os valores atuais que entram no cálculo causem um excesso ou excesso de fluxo em qualquer lugar (se for um sistema mais antigo, pode não ter sido planejado para ser usado por tanto tempo).
Y2K11 alguém?
fonte
A menos que você possa controlar todos os bits da máquina e todos os impulsos elétricos que fluem pelos circuitos, não poderá garantir com absoluta certeza que algo não vai dar errado no seu programa. Os módulos de memória falham, as CPUs podem superaquecer e introduzir erros, os discos rígidos podem embaralhar os dados e as fontes de alimentação podem introduzir ruído no sistema. Quanto mais caro o hardware e mais redundante, menor a probabilidade de ocorrerem essas coisas, mas em algum momento o hardware pode falhar.
Então você tem o sistema operacional, com bugs que podem ser afetados pelos meios mais misteriosos que se possa imaginar. Os compiladores também podem ter erros obscuros, apenas esperando para habilmente transformar seu código original em erros difíceis de rastrear. É uma selva lá fora, e seu software ruim é vulnerável a tudo isso. TENHA CUIDADO!
E, na minha experiência, na maioria das vezes, sempre que há um erro no cálculo, nunca precisamos ir tão longe para encontrar o culpado. De um modo geral, quase todos os bugs que vi no mundo corporativo são facilmente encontrados com as ferramentas de depuração corretas e um pouco de graxa nos cotovelos.
Em outras palavras, embora o hardware e o SO não sejam perfeitos, você provavelmente nunca precisará se preocupar com esse nível de detalhe. Basta encontrar alguém que conheça o idioma e que seja útil com um depurador e desenterrar.
"explicações mais simples são, outras coisas iguais, geralmente melhores do que as mais complexas". - Resumo da Navalha de Occam.
fonte
Sim, bater em um sistema pode dobrar e / ou mover peças o suficiente para causar um circuito aberto temporário (ou possivelmente um curto-circuito, embora seja provavelmente menos provável).
fonte
O primeiro computador que eu possuía era um Altair 8080 com 256 bytes de memória. A entrada era dos comutadores do console e a saída era de algumas luzes piscantes. Se você não permitir raios cósmicos e falhas de hardware, acredito que poderia provar que alguns programas executados nele sempre produziriam os mesmos resultados.
Desde então, não.
fonte
Se você está tentando provar que seu programa funciona corretamente testando, ele não funcionará.
No entanto, existem algumas abordagens na ciência da computação teórica, nas quais você desenvolve uma prova formal do software que escreveu. Dependendo da complexidade do seu sistema, esse pode ser um processo tedioso. Se o seu sistema, no entanto, funcionar com um conjunto restrito de comandos, você poderá ser bem-sucedido com essa abordagem.
fonte
Os ambientes de hardware e software estão em constante estado de fluxo. Peças móveis, eletricidade, temperatura, poeira e alterações no código do SO são exemplos.
Portanto, não creio que seja provável ou esperado que um programa de software sempre se comporte da mesma maneira, pois o ambiente está sempre mudando.
O software pode ser executado por um longo período de tempo, mas eventualmente uma pequena alteração no software do sistema operacional host será alterada, afetando o programa em questão ou o valor do hardware.
Estou falando dos computadores atuais.
fonte
A resposta a essa pergunta é incognoscível. É impossível provar que qualquer coisa sempre é verdadeira no universo em que vivemos. Em vez disso, fazemos suposições e provamos que, se as suposições se mantiverem, alguma propriedade complicada também se manterá. É isso que os programas formalmente verificados garantem. A maioria dos programas não é formalmente verificada, mas eles tentam criar confiança ao fornecer testes. Esses testes garantem que, desde que os testes façam o que eles foram projetados, e que as suposições feitas por você, o programa que você está usando, funcionem pelo menos uma parte do tempo.
fonte
É quase impossível que o problema seja causado pela falha da RAM, mas isso é relativamente (muito) improvável. Execute um teste de memória, mas esteja pronto para examinar o código.
fonte