Podemos garantir que um programa nunca dará errado?


10

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.


8
Um dos módulos de RAM do meu PC tinha exatamente um bit com defeito; portanto, um programa com a infelicidade de usá-lo pode gerar um resultado errado. A execução do memtest86 em sua máquina pode ser uma maneira simples de excluir esse tipo de problema.
precisa saber é o seguinte

16
sim, excluindo-o
Steven A. Lowe

6
Algumas peças de hardware têm bugs. É uma prova para os fabricantes de chips do dia que eles são tão poucos. Eu suspeitaria do software primeiro.

Sempre há uma razão lógica para um programa dar errado. Um slam é uma razão lógica.
Mouviciel 4/10

2
Você pode ter uma bomba estatística ou um compilador mal-intencionado, ram ou disco defeituoso ou um vírus que possa gravar no seu ram ou modificar o SO ou o bug do SO ou um bug em uma biblioteca de algum lugar ou o famoso bug de classificação por mesclagem, ou ...
Job

Respostas:


8

Eu diria que não!

Em teoria, a resposta é não, só podemos testar:

  • um número limitado de ambientes.
  • algum número limitado de escalas de tempo.
  • algum número limitado de casos de teste.

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:

  • Programas interrompidos quando movidos para um código de idioma diferente. Verificando "MAIO" quando o mês era "MAI".
  • Programas com falha nos testes em uma nova versão do compilador. Um erro na versão anterior em conjunto com um erro no programa produziu o resultado correto.
  • Programas quebrando em uma nova versão do sistema operacional. Quando o Solaris aumentava o número padrão de entradas do diretório, o SMALLINT retornado por ftok () sempre retornava zero para o primeiro arquivo no diretório.
  • programas foram interrompidos porque foi a primeira vez que encontraram uma combinação específica de insumos, que eram válidos e inesperados e nunca teriam sido testados - taxas de juros negativas sobre depósitos, itens com peso zero a serem enviados, itens de tão baixo valor que Não foi possível calcular o IVA, etc. etc.

Eu digo que sim, com uma provisão - se você tiver um multi-threading. Já ouviu falar de "Condição de Corrida".
mattnz

6

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:

  short i;

  if(i==-1)
  {
        //do something special
  }
  else
  {
        i=0;
        //do something else
  }

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, iserá 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.


6

Agora, minha pergunta é: um programa de computador de repente dará errado, sem qualquer motivo lógico?

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:

  • o programa usou o (s) tipo (s) de dados errado (s) para calcular o resultado, esse erro só se manifesta quando valores especiais são usados.
  • o programa encontrou um erro no cálculo (devido a uma condição lógica), mas não tratou do erro e ainda produziu o resultado. (por exemplo, mistura de float e aritmética inteira)
  • uma regra de negócios ou uma condição lógica não foi codificada corretamente, os dados inseridos representam essa condição, mas o cálculo errado foi usado. (por exemplo, subtraia o valor do valor da conta antes de verificar o valor na conta primeiro).
  • usando fórmulas que se aplicam apenas a determinado intervalo de números, mas os dados contêm um intervalo diferente. (por exemplo, calcular uma taxa de juros com base em uma faixa de valores)

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.

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?

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


estava pensando nos erros de arredondamento compostos como fonte de tais problemas. Eles podem não aparecer por muito tempo, até que exatamente a combinação certa (ou errada) de entradas leve a todas elas combinadas, resultando em um resultado diferente do que deveria ser.
jwenting

3
Os sistemas operacionais modernos não permitem que os programas modifiquem (ou mesmo leiam) a memória pertencente a outros programas.
Péter Török

Sim, os sistemas operacionais modernos não permitem nada dessa natureza.
DeadMG

"Se você tiver exatamente o mesmo ambiente de computação, a entrada X em um programa sempre produzirá o mesmo resultado R" Não sei se isso é verdade. E se uma das travas SR nos componentes de memória receber dois 1s devido a alguma corrupção anterior? en.wikipedia.org/wiki/…
Yam Marcovic 04/04

@DeadMG e Péter Török, obrigado por seus comentários, editei a mensagem e adicionei uma referência a uma página descrevendo que o problema ainda pode ocorrer (eu sei, como mencionado no texto, que é altamente improvável).
NoChance

5

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.


11
+1 para "todos os programas estão errados, mas alguns são úteis"
um CVn

Não acho que essa resposta seja realmente relevante. Parece que ele está perguntando se um programa correto às vezes pode funcionar inesperadamente por causa de alguma falha ambiental.
Yam Marcovic

Meu argumento é que nenhum programa está "correto". Tudo é sempre um trabalho em andamento, e só está certo até que esteja errado. A ciência da computação é uma ciência, afinal. Entendo o que você está dizendo, e esse pode ser mais o foco da pergunta dele. No entanto, acho que isso torna minha resposta ainda mais relevante, e não menos.
John N

@Hallainzil: Eu acredito que escrevi com sucesso "Olá, Mundo!" programas e similares. Até escrevi programas úteis corretos (embora não sejam grandes).
precisa

2

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.


1

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?


Realizar N iterações e verificar os resultados não prova a exatidão. Na melhor das hipóteses, isso prova a ausência de erro no conjunto de amostras, e até isso pressupõe que seu caso de teste (e a implementação dele, bem como sua execução) esteja absolutamente correto. Embora o teste seja muito útil, ele não trata da preocupação do OP.
um CVn

@ Michael Talvez eu deva esclarecer, não estou sugerindo tentar "provar" alguma coisa com essa abordagem, mas se for muitas outras iterações sem mostrar o erro novamente, eu estaria pensando em manchas solares e não em excesso de número inteiro. Ainda lhe dá mais insights do que não, IMHO.
jonsca

1

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.


0

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).


0

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.


0

O teste mostra a presença, não a ausência de bugs (Edsger W. Dijkstra)

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.


Você leu a pergunta?
Winston Ewert

Eu fiz e estou dizendo que ele não pode usar testes para garantir que um programa nunca dê errado. É o que diz o título da pergunta, certo?
Raku

Sim, o título parece dizer isso. O corpo claramente não.
Winston Ewert

0

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.


0

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?

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.


-1

É 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.


Para o downvoter - eu já vi isso acontecer. Uma vez.
James McLeod
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.