É possível atingir o estado absoluto de erro zero para software de grande escala?


71

Estou falando de mais de 20 a 30 milhões de linhas de código, software na escala e complexidade do Autodesk Maya, por exemplo.

Se você congelar o desenvolvimento pelo tempo que for necessário, será possível consertar todos os bugs até que simplesmente não haja um único bug, se isso puder ser verificado por computadores? Quais são os argumentos a favor e contra a existência de um sistema livre de erros?

Porque existe alguma noção de que toda correção que você cria cria mais bugs, mas não acho que isso seja verdade.

Por bugs, eu quis dizer desde os erros mais simples na interface do usuário, até erros preventivos mais sérios que não têm solução alternativa. Por exemplo, uma função de script específica calcula valores normais incorretamente. Além disso, mesmo quando existem soluções alternativas, o problema ainda precisa ser corrigido. Então, você poderia dizer que pode fazer isso em particular manualmente, em vez de usar a função fornecida, mas essa função ainda precisa ser corrigida.


11
"foi dito por alguns dos principais programadores" - eles não me parecem os principais programadores. Eles parecem os melhores hackers. Uma das RESPONSABILIDADES PRIMÁRIAS de um programador é entender o que o código faz e como isso afeta o sistema como um todo. É por isso que temos TDD, padrões de design etc. Se isso não puder ser feito, o sistema é inútil - o processo de desenvolvimento foi feito de maneira caótica, aleatória, indisciplinada e não científica.
Vector

51
Se você ainda não sabe que um bug existe, ele ainda é um bug?
Blrfl

5
@Blrf: Mais importante, se o usuário final não souber que existe um bug, ele existe?
mattnz

40
“Existem duas maneiras de construir um design de software. Uma maneira é torná-lo tão simples que obviamente não há deficiências. E a outra maneira é torná-lo tão complicado que não há deficiências óbvias.”- CAR Hoare
Andrew Lewis

5
É verdade, mas muitas pessoas não querem que suas crenças fundamentais sejam questionadas.
Joan Venge

Respostas:


92

Como Mikey mencionou, escrever código sem erros não é o objetivo. Se é isso que você está buscando, então eu tenho más notícias para você.

O ponto principal é que você está subestimando enormemente a complexidade do software.

Primeiras coisas primeiro - você está ignorando a imagem maior de como seu programa é executado. Não é executado isoladamente em um sistema perfeito. Até o mais básico dos programas "Hello World" é executado em um sistema operacional e, portanto, até o mais simples é suscetível a erros que possam existir no sistema operacional.

A existência de bibliotecas torna isso mais complexo. Enquanto os sistemas operacionais tendem a ser razoavelmente estáveis, as bibliotecas são uma mistura de coisas quando se trata de estabilidade. Alguns são maravilhosos. Outros ... nem tanto ... Se você deseja que seu código seja 100% livre de bugs, também será necessário garantir que todas as bibliotecas nas quais você executa sejam completamente livres de bugs, e muitas vezes isso simplesmente não é possível. você pode não ter o código fonte.

Depois, há tópicos em que pensar. A maioria dos programas de larga escala usa threads em todo o lugar. Tentamos ser cuidadosos e escrever threads de maneira que as condições de corrida e o impasse não ocorram, mas simplesmente não é possível testar todas as combinações possíveis de código. Para testar isso efetivamente, você precisaria examinar todas as ordens possíveis de comandos passando pela CPU. Ainda não fiz as contas, mas suspeito que enumerar todos os possíveis jogos de xadrez seria mais fácil.

As coisas vão do difícil ao impossível quando olhamos para a própria máquina. CPU's não são perfeitos. RAM não é perfeita. Discos rígidos não são perfeitos. Nenhum dos componentes de uma máquina é projetado para ser perfeito - eles são projetados para serem "bons o suficiente". Mesmo um programa perfeito acabará por falhar devido a um soluço da máquina. Não há nada que você possa fazer para impedir isso.

Bottom line: Você pode escrever "software livre de erros"?

NÃO

Quem lhe disser o contrário não tem noção.

Apenas tente escrever um software fácil de entender e manter. Depois de fazer isso, você pode encerrar o dia.


EDIT: Algumas pessoas comentaram sobre um ponto excelente que eu havia esquecido completamente: o compilador.

A menos que você esteja escrevendo em assembly, é perfeitamente possível que o compilador atrapalhe seu código (mesmo se você provar que seu código é "perfeito").

Uma lista de bugs no GCC, um dos compiladores mais usados: http://gcc.gnu.org/bugzilla/buglist.cgi?product=gcc&component=c%2B%2B&resolution=---


8
A resposta ainda é "não", porque sempre haverá "bugs" onde algo funciona - assim como um cliente ou proprietário de produto gostaria que funcionasse. Alguns de nós podem chamar essas solicitações de recursos, ou solicitações para alterar o comportamento ou adicionar funcionalidades - mas para a pessoa que está sendo incomodada por algum "bug" todos os dias, o que os incomoda é um bug. (É um longo caminho para dizer que alguns bugs estão nos olhos de quem vê.) O CÓDIGO GRATUITO DE BUGS é impossível. Aponte para um código que seja bom o suficiente para atender ao seu objetivo.
quickly_now

6
Vou dar um passo adiante: o código pode ter defeitos latentes, por exemplo, você pode ter um código que não alcance adequadamente a verificação de uma entrada. Se, por algum motivo de sorte, a entrada nunca estiver fora de alcance, o erro nunca se manifestará. Então, um dia, durante as alterações de manutenção ou recurso, esse código é chamado de outro lugar que ocasionalmente o exerce com um valor fora do intervalo. O bug agora se manifesta - mas estava lá o tempo todo. Você pode ter graus de loucura em tudo isso - mas a eliminação de todas as possibilidades de erro ainda é impossível.
precisa saber é o seguinte

11
@ JohnR.Strohm Não sei por que você acha que o programa 'modulador de fluxo de mensagens', um programa com 556 linhas de código, tem algo a ver com uma pergunta sobre um sistema teórico de 20 milhões de linhas. Exceto, talvez, para demonstrar que, por mais difícil que fosse provar a correção do minúsculo programa, seria astronomicamente mais difícil provar a correção de um programa massivo.
Eric Rei

9
Enquanto a pergunta original não o fez, gostaria de salientar que há uma diferença gigantesca entre 'teoricamente possível' e 'praticamente possível'. Embora uma base de códigos de 20 milhões de linhas sem erros seja teoricamente possível, é quase certamente uma impossibilidade prática no mercado atual. Quem sabe o que o futuro reserva.
Eric Rei

4
@ JohnR.Strohm Você deve ler o artigo com mais cuidado. Eles dizem eles mesmos: It is important to note, however, that even all of these steps provide no guarantee of absolute security. It is tempting to believe that a formally specified and proved program should be absolutely correct, but there are several reasons why a proved program may not behave exactly as expected.- o que significa que não se pode provar que está livre de bugs, mas sim, menos provável que tenha bugs. Um pouco como TDD.
Izkata

27

Matematicamente, PODE ser possível escrever um software 'sem erros' de tal complexidade, dependendo de como você define 'erros'. Provar que PODE também ser matematicamente possível, projetando um sistema de teste que exercite todas as linhas de código de todas as maneiras possíveis - todos os casos de uso possíveis. Mas não tenho certeza - se você estiver lidando com um sistema que faz cálculos complexos, pode encontrar um 'problema do infinito' ...

Na prática, em um sistema do tamanho e escopo dos quais você está falando, isso é IMPOSSÍVEL . Pode levar mil anos para escrever um sistema 'livre de bugs', e escrever um sistema para provar que levaria exponencialmente mais tempo: você teria que criar todos os casos de uso possíveis e escrever um sistema que testasse cada um - e não acredito que exista uma maneira de determinar se você realmente cobriu todos os casos de uso em um sistema do tamanho e escopo dos quais você está falando em algo semelhante a um período de tempo razoável.

OMI sua pergunta é um pouco mal direcionada: Nosso objetivo como desenvolvedores não é escrever software 'sem erros'. Nosso objetivo é escrever um software utilizável, flexível e fácil de manter .

Utilizável: O sistema atende aos requisitos essenciais para os quais foi projetado. Pode haver erros - mas eles estarão em "casos extremos" - discrepâncias ou aborrecimentos, não erros que comprometam os fundamentos do sistema - robustos.

Manutenção: Os erros podem ser facilmente isolados e corrigidos e NÃO crie novos erros.

Flexível: seu sistema é fácil de mudar e expandir sem redesenho e tempo de inatividade significativos: a maioria das alterações exige simplesmente a adição de uma nova classe ou módulo que se encaixa nos padrões e na estrutura já bem projetados.

Boas práticas de design, boas práticas de controle, bom trabalho em equipe, desenvolvedores conscientes - essa é a fórmula para o BOM SOFTWARE . (não PERFEITO - mas BOM )


3
"Provar que PODE também ser matematicamente possível, projetando um sistema de teste que exercite todas as linhas de código de todas as maneiras possíveis - todos os casos de uso possíveis.": Esse programa não existe em geral (e isso pode ser provado!). Portanto, não existe um algoritmo geral para provar a correção.
Giorgio

3
Correção: Foi conseguido um software sem erros, COMPLETO COM A PROVA MATEMÁTICA FORMAL DE CORREÇÃO. Foi feito em 1982. Google "modulador de fluxo de mensagens".
John R. Strohm

6
@ JohnR.Strohm: Não é verdade. Aqui está apenas uma citação - há vários documentos e vários lugares em que eles abordam preocupações semelhantes: "Uma pergunta que surge com frequência é" Você verificou o verificador? "Talvez surpreendentemente, essa pergunta metamatemática seja frequentemente feita por engenheiros, e não apenas por questões pontudas. Certamente, se uma máquina alguma vez responder à pergunta "Você já mente?", a resposta não será mais informativa do que quando um humano responder à pergunta ".
Vector

11
Eu quis dizer que não há algoritmo geral que funcione para qualquer programa de entrada e qualquer especificação de entrada. Você pode lidar apenas com casos específicos (por exemplo, seu exemplo).
Giorgio

11
@Giorgio - portanto, na IMO, seguir boas práticas de design é muito mais importante do que se preocupar com a correção matemática: projete seu código para garantir que ele possa ser bem integrado e compatível com o que já existe - e seja suficientemente robusto para lidar com defeitos facilmente quando eles vem à luz (o que eles querem).
Vector

27

De acordo com este artigo, o software de bordo do Ônibus Espacial chegou muito perto - as últimas três versões do programa de 420.000 linhas tiveram apenas um erro cada. O software foi mantido por um grupo de 260 homens e mulheres. Um grande número dessas pessoas eram verificadores, cujo único objetivo era encontrar erros.

A atualização do software para permitir que o ônibus navegue com os satélites de posicionamento global impactou apenas 1,5% do programa, ou 6.366 linhas de código. As especificações para essa alteração rodavam 2.500 páginas. As especificações para o programa geral preencheram 30 volumes e executaram 40.000 páginas, ou uma média de dez linhas de código por página das especificações.

O orçamento não era um problema - com US $ 35 milhões por ano, eles podiam se dar ao luxo de fazer as coisas corretamente.


25
Um erro detectado cada. Quem sabe quantos erros não detectados? :)
Andres F.

8
Esse "um erro" foi um caso especial. O Shuttle foi originalmente projetado e o software especificado para dois braços de robô. O "erro" foi que ainda havia código lá para apoiar o segundo braço.
John R. Strohm

4
+1 executado sem erros para 135 missões desde 1981 até 2011
MarkJ

5
@ MarkJ: provavelmente não saberíamos se o ônibus espacial realmente não tinha erros. Todas as missões do ônibus espacial são constantemente monitoradas pesadamente por centenas de pessoas, e quaisquer erros na codificação seriam corrigidos / substituídos manualmente.
Lie Ryan

2
@LieRyan O que mostra muito bem uma grande propriedade de sistemas robustos - se eles não falham catastroficamente e sempre permitem ajustes manuais, você pode usar sistemas redundantes (como os do centro de controle) para fazer o trabalho. Obviamente, isso só faz sentido se você tiver esses sistemas redundantes e se puder realmente garantir a correção e a consistência. Em um aplicativo comercial típico, uma falha geralmente é preferível a operar em um estado inconsistente - é a diferença entre um aborrecimento e, por exemplo, enviar dinheiro para o cara errado. Ou receber dinheiro sem que seja enviado ...
Luaan

15

Essencialmente, não, mas você deve fazer o seu melhor de qualquer maneira. Vou explicar o porquê (ou pule para a conclusão, se você não tiver paciência suficiente)

Considere um problema tão trivial quanto a implementação da pesquisa binária. Uma implementação muito popular teve um bug que não foi detectado por cerca de duas décadas. Se vinte linhas levam vinte anos para que o uso livre de bugs seja amplamente utilizado e até supostamente correto, podemos realmente esperar que um programa enorme seja livre de bugs?

Quantos erros podemos esperar que um programa enorme tenha? Um número que encontrei foi "10 defeitos por 1000 linhas" (Code Complete 2nd edition, página 517 - apenas usou um exemplo, sem citar dados). Isso nos dá de 200.000 a 300.000 erros no seu software. Felizmente, temos maneiras de melhorar a qualidade do programa. Testes de unidade, revisões de código e testes manuais comuns são conhecidos por reduzir o número de bugs. Ainda assim, o número ainda será alto.

Se pudéssemos resolver 95% de todos os erros, isso seria incrível. E ainda teríamos de 10.000 a 15.000 bugs no software.

Felizmente, como o software é amplamente utilizado (e, portanto, amplamente testado), serão encontrados erros. Então, gradualmente teremos menos bugs. No entanto, menos erros também significam que os restantes são mais difíceis de encontrar - portanto, não espere uma curva linear na correção de erros. Os últimos erros vai ser muito complicado encontrar e poderia escapar à detecção por vários anos (assumindo que eles estão sempre encontrado).

Você também parece estar assumindo erroneamente que, se o software não mudar, nenhum novo erro será exibido. Se o software depender de bibliotecas de terceiros, novas versões poderão quebrar alguns recursos - introduzindo novos erros, mesmo que o código do aplicativo ainda seja o mesmo. Novos sistemas operacionais também podem interromper um aplicativo que funcionava perfeitamente perfeitamente (consulte o Windows Vista para obter um exemplo popular). Considere também erros do compilador, etc.

Não está claro se as ferramentas à prova de código podem realmente resolver o problema do software de buggy. Certamente não é possível resolver o problema de interrupção de nenhum programa, mas pode ser possível provar que um programa se comporta conforme especificado ... Mas e daí? Talvez o programa de provas tenha um bug. Talvez a especificação em si tenha um erro.

Claramente, podemos reduzir bastante o número de bugs, mas é muito improvável que cheguemos a zero.

Porque existe alguma noção de que toda correção que você cria cria mais bugs, mas não acho que isso seja verdade.

(enfase adicionada)

Você está certo. Esta afirmação está errada. Aqui está um exemplo:

int main() {
    int x[10];
    x[10] = 8; //Buffer overflow here
    return 0;
}

Agora, vamos corrigir este bug:

int main() {
    int x[11];
    x[10] = 8; //No buffer overflow here
    return 0;
}

Vejo? Corrigimos um erro e não introduzimos novos.

No entanto, é certamente correto que toda vez que você conserte um erro, arrisque criar um novo, embora esse risco possa ser mitigado (por exemplo, com testes de unidade).

Digamos que, para cada 100 bugs corrigidos, introduzo acidentalmente um novo. Portanto, se eu corrigir 10.000 erros, apresento 100 novos erros. E se eu corrigir esses novos erros, apresento um erro. Mas e daí? O programa agora possui 9.999 bugs a menos, então provavelmente é melhor do que era (assumindo que o novo bug não seja 10.000 vezes pior que os anteriores).

Além disso, a correção de um bug pode expor novos. Mas esses erros também podem ser corrigidos. Se você fizer as coisas corretamente, eventualmente o software estará em um estado melhor do que o iniciado.

Eu era velho por alguns programadores de destaque que é melhor não corrigir muitos bugs por causa da noção que mencionei no OP.

Esse comportamento é negligente. Se houver um erro e você pode corrigi-lo. Faça. É claro que você deve fazer o possível para evitar a adição de novos, mas se eu apresentar um pequeno bug para cada 10 erros graves que eu corrigir, esse não é um motivo válido para parar de corrigir erros. De fato, é uma boa razão para continuar corrigindo bugs .

Portanto, menos bugs corrigidos, menos bugs voltarão para você no futuro

Quanto menos erros você consertar, mais erros permanecerão no seu software, incomodando os usuários. De fato, eles não "voltarão para você no futuro". Eles não vão voltar porque nunca foram embora. A noção de "voltar" está relacionada a regressões. Novamente, é possível reduzir o risco de regressões.

Alguns bugs não podem ser corrigidos porque se tornaram tão amplamente utilizados que as pessoas começaram a depender deles e a correção do bug interromperia o programa para esses usuários. Acontece. No entanto, eles podem realmente ser considerados erros nesse caso?

A mentalidade "conserte um bug, faça um bug" pode estar relacionada ao monstro horrível - código que é tão ilegível e impossível de manter que apenas tocá-lo cria bugs. Se você tem um monstro em sua base de código, pode ser necessário desmonstrificá-lo antes de fazer qualquer coisa.

Finalmente, se você é um péssimo programador, existe o risco de que qualquer coisa que você toque crie novos bugs. Obviamente, isso deixaria programadores seniores nervosos. No entanto, dizendo "Não faça nada. Não toque em nada. Nem respire". provavelmente não é o caminho certo para criar um ambiente de trabalho saudável. A educação é melhor.

Conclusão:

  • Software que continua recebendo toneladas de novos recursos, mas nenhuma correção de bug inevitavelmente será péssima.
  • O software que obtém um número moderado de novos recursos, mas corrige seus erros, tem mais chances de ser utilizável.
  • Aqueles que tentam ter poucos erros têm (em média) menos erros do que aqueles que não se importam.
  • Não é razoável esperar que um programa acabe ficando livre de erros.
  • Programadores seniores não são necessariamente competentes.
  • Corrija seus erros.
  • Adote metodologias que melhorem a qualidade do seu software.

+1: eu mesmo estava procurando pelo exemplo de pesquisa binária;) Se 20 linhas de código amplamente discutido e circulado mantiveram um bug por 20 anos, quanto tempo você precisaria para uma base de código de 20 milhões de linhas que em quantas dúzias de pessoas ocupadas já viram?
scrwtp

Obrigado. Gostaria de saber se esse bug de pesquisa binária (que eu nunca ouvi antes) está relacionado a pessoas que copiam colando muito código sem pensar muito? Além disso, se tivermos tantos bugs que são suficientes para enumerar, talvez as ferramentas e práticas que estamos usando não sejam ótimas?
Joan Venge

11
@JoanVenge Citei esse exemplo para mostrar como os erros podem ser difíceis de encontrar. Nesse caso, colar a cópia era realmente a coisa certa a ser feita, pois estava comprovadamente correto e a implementação gravada do zero provavelmente teria mais bugs. As ferramentas e práticas que nós - como uma indústria em geral - estamos usando certamente não são ótimas. As melhores práticas são fáceis de ignorar e os maus hábitos são fáceis de manter. Por fim, os bugs sempre existirão porque os humanos não são perfeitos. Mas podemos reduzir o número de bugs fazendo o melhor possível e insistindo em uma educação de alta qualidade.
precisa saber é o seguinte

7
Eu acho que o bug no código de pesquisa binária demonstra o quão complexa é essa questão. O bug subjacente na pesquisa foi um potencial excesso de número inteiro em uma adição. Tais "erros" são onipresentes porque a maioria das pessoas depende de uma suposição implícita (e ocasionalmente incorreta) de que as entradas não serão grandes o suficiente para causar um estouro. É realmente um bug ou apenas um contrato de interface mal documentado? Quando foi a última vez que você analisou os summands em uma adição de número inteiro ou verificou o estouro após o fato?
Charles E. Grant

4
Seu exemplo de servidor destaca uma observação bastante óbvia sobre a linguagem de programação e a qualidade da ferramenta. Um compilador com qualidade de produção para uma linguagem robusta deveria ter se recusado a compilar seu primeiro exemplo, retornando um erro fatal de compilação. O fato de ser possível compilar essa abominação diz tudo o que você precisa saber sobre a qualidade dessas ferramentas e a viabilidade de seu uso para fornecer software livre de erros.
John R. Strohm

12

As razões para não escrever programas sem erros são principalmente econômicas.

Não são métodos matemáticos para provar a correção de um programa. Em um curso de alta qualidade em Ciência da Computação, eles serão mencionados. Existem linguagens de programação inventadas especialmente para esse fim. Em teoria, é possível programar sem bugs .

Sim, existe o hardware imperfeito que às vezes pode mudar um pouco, porque um neutrino disparou de uma supernova distante milhões de anos atrás, por acaso, atingiu seu processador no lugar certo. Ok, toda teoria tem suas suposições e abstrações. Mas, supondo que o processador funcione como anunciado, existem ferramentas matemáticas para garantir que o programa funcione corretamente também.

Algumas respostas altamente votadas neste tópico são enganosas. Por exemplo, o teorema da incompletude de Gödel e o problema de parada implicam apenas que você não pode ter, por exemplo, uma ferramenta automatizada que decida a correção ou a incorreção de qualquer programa. Mas não queremos decidir a correção de nenhum programa, queremos apenas uma prova de correção de um programa específico .

(Analogicamente, apenas porque você não pode escrever um programa para decidir automaticamente a verdade de qualquer teorema matemático, isso não significa que você não pode provar um teorema matemático específico .)

O problema, em vez disso, é este:

Embora seja teoricamente possível escrever um programa sem erros, isso seria muito caro . Escrever um código com uma prova de sua correção é mais complicado do que simplesmente jogar algo em uma parede para ver se ele fica preso. Mesmo se "ver se está preso" for feito por testes de unidade; e muitos programadores nem se importam em fazer isso. A maioria dos programadores nem sabia como fazer isso, o que significa que, como empresa, você teria que contratar empresas mais caras.

Considerando todos os custos, um cliente típico fica mais satisfeito com um software barato que funciona bem 99% das vezes (e 99,9% do tempo após a instalação de atualizações adicionais) do que ter um software talvez mil vezes mais caro que funciona bem com 100% das vezes. A Hora. Além disso, o cliente deseja ter esse software agora , e não em dez ou vinte anos.

Portanto, as pessoas produzem conscientemente um software que tem alguma chance de erros, tentando atingir a combinação ideal em que os erros não são muito frequentes nem muito graves, e a produção é rápida o suficiente e barata o suficiente. A combinação que oferece mais lucro na vida real. (Às vezes, significa até lançar um software cheio de bugs antes que seus concorrentes lançem algo, e apenas lançar uma versão mais decente 2.0 quando seus concorrentes estiverem prontos para lançar sua primeira versão decente.)

Se você congelar o desenvolvimento pelo tempo que for necessário, será possível consertar todos os bugs até que simplesmente não haja um único bug, se isso puder ser verificado por computadores?

Matematicamente falando, você poderia. Economicamente falando, por que alguém faria isso? Isso significaria gastar talvez vinte anos e alguns milhões de dólares. Enquanto isso, os clientes desejam novos recursos e seus aplicativos congelados não podem fornecê-los. Portanto, no momento em que sua versão perfeita estiver pronta, o mercado já estará ocupado por seus concorrentes.

Raciocinar economicamente é bom. Vivemos em um mundo onde dinheiro e tempo importam. Mas apenas porque não fazemos algo por razões econômicas, não devemos falar bobagens sobre como isso não pode ser feito, nem mesmo na teoria. Quem sabe ... talvez em alguns anos teremos algumas novas linguagens de programação e ferramentas que possam tornar correção provando fácil .


Obrigado, embora eu deseje que a maioria dos softwares funcione 99% do tempo, a maioria dos grandes que eu uso como o do OP é extremamente bugs. Mas acho que o monopólio e a compra de concorrentes também são um fator nisso. Mas entendo o seu ponto.
Joan Venge

11
"Caro" é relativo. Compare o custo de encontrar e consertar os bugs com o custo de, por exemplo, uma máquina de radioterapia matando vários pacientes e mutilando vários outros. (Google "Therac 25".)
John R. Strohm 23/04

6

Não.

David Hilbert propôs seu segundo problema de matemática em 1900, que essencialmente pediu ao mundo para provar que a aritmética funcionava como pretendido. Mais tarde, ele propôs " o problema de Entscheidung ", que pedia algo semelhante em termos lógicos. O " primeiro teorema da incompletude " de Kurt_Gödel provou em 1931 que nenhuma teoria da aritmética elementar podia ser consistente e completa. A representação de Alan Turing do problema do Entscheidung como " o problema da parada " levou a questão diretamente ao cerne dessa questão, onde ele provou que é impossível provar se um programa será executado ou não. Dado que a indeciabilidade, também é impossível provar se um programa tem algum erro ou não.

Nada disso liberta os programadores praticantes entre nós de lutar por nenhum erro. Significa apenas que não podemos ter sucesso em geral.


9
A indecidibilidade somente se aplica em geral - existem programas para os quais você não pode provar nem exatidão nem incorreção. Porém, para um determinado programa específico, a correção (ou mais frequentemente: a incorreta) pode ser comprovada. Isso pressupõe que você tenha uma especificação formal de linguagem e um compilador comprovadamente correto - o último não existe para nenhuma linguagem de programação de alto nível, embora o CompCert se aproxime.
Daniel

+1 para citar o referencial teórico relevante. Ainda não sabia que o "Entscheidungsproblem" se chama o mesmo em inglês e em alemão!
Peopleware

5
Concordo com Daniel. O desafio é sobre uma única instância; os problemas de parada tratam de todas as instâncias possíveis. int main() { return 0; } Parada de forma trivial e sem erros.
precisa saber é o seguinte

11
O problema da parada não diz que é impossível provar se um programa será executado até a conclusão; diz que existem programas para os quais é impossível provar. Os programas regulares do dia a dia não estão nesta classe. "Embora a prova de Turing mostre que não há método ou algoritmo geral para determinar se os algoritmos são interrompidos, instâncias individuais desse problema podem muito bem ser suscetíveis a ataques. Dado um algoritmo específico, muitas vezes é possível mostrar que ele deve ser interrompido para qualquer entrada, e, de fato, os cientistas da computação costumam fazer exatamente isso como parte de uma prova de correção ".
endolith

6

Errare humanum est

Mesmo se você escrever código com uma linguagem formal, como o método B , que você pode usar para provar matematicamente que os requisitos são atendidos,

Mesmo se você usar uma linguagem formal de especificação,

Sempre existe uma etapa humana que consiste em extrair as necessidades do usuário de um ou mais cérebros para um computador.

Este passo humano é propenso a erros, e o verme está na maçã.


11
Ainda é um bug quando um programa faz o que foi solicitado, em vez do que foi planejado?
precisa saber é o seguinte

Eu acho que é ..
Joan Venge

4
@MSalters - Claro que é. Não do ponto de vista contratual, mas no final o problema do cliente não foi resolvido. Você voaria em um avião cujos computadores fazem o que pediu, mas não o que pretendia?
Mouviciel

3

Uma proporção justa dos "bugs" que encontrei pode ser mais adequadamente descrita como incompatibilidade entre o design do sistema e a expectativa do cliente.

Agora, se nós chamamos esses bugs ou não, é acadêmico, mas o fato é que uma boa parte do trabalho de manutenção surge como resultado direto da comunicação imperfeita e da mudança nas expectativas dos clientes.

Mesmo que um sistema seja tecnicamente comprovadamente "correto" no sentido de atender a uma especificação (por mais improvável que isso possa ser para o software comercial do mundo real), você ainda terá o problema de corresponder a função do software à sempre atendida pelo cliente. expectativas mutáveis ​​e mal definidas.

Em resumo:

Não.


+1 Um desenvolvedor e um cliente podem ter visões muito diferentes sobre o que define um 'bug'.
GrandmasterB

Mas e se o desenvolvedor também for o usuário? I encontrar geralmente melhor software de essas pessoas em termos de usabilidade, uma vez que sabe exatamente como algo deve funcionar, etc.
Joan Venge

2

Se você tiver uma especificação suficientemente rígida e restrita, poderá provar um programa sem erros, mas apenas com base em suposições não comprováveis ​​sobre o funcionamento correto de tudo o mais no sistema. Isso deixa claro que não há como provar que as especificações seriam consideradas corretas por quem colocou o problema original ou por quem estava usando o serviço.


1

Achei a seção No Bugs, de Jim Shore, uma leitura muito útil sobre esse tópico. A forma abreviada: não é possível desenvolver sem produzir bugs - mas podemos trabalhar de maneira a detectá-los o mais cedo possível.

Durante a produção do próprio código. Por exemplo, escrevendo e executando testes de unidade com freqüência durante o desenvolvimento, garantimos constantemente que o código faz o que deve fazer. Além disso, é útil reescrever perpetuamente o código existente de forma a expressar mais claramente o comportamento pretendido do sistema.

No seu caso, no entanto, você está falando de uma base de código já existente com milhões de linhas de código. Se você deseja obter um bug desse sistema livre, primeiro precisa saber o que "é um bug" para este sistema. Você pode escrever conjuntos de testes post-hoc, garantindo a funcionalidade do sistema (se ainda não existir). A rede desses testes pode servir como uma definição aproximada para o comportamento correto do sistema. Mas quanto mais código você tiver, mais esforço será envolvido nesses exercícios. Portanto, a maioria das empresas faz um compromisso: elas vivem com o imperfeito, trabalhando com listas de bugs e manutenção para obter os bugs mais irritantes do sistema.


1

Sobre a verificação por parte do computador.

Existem duas maneiras de verificar um programa usando um computador. Um está testando, o outro está usando o sistema de prova.

Assim que testes exaustivos não são possíveis, os testes se tornam incapazes de mostrar que um programa não possui bugs, apenas que possui alguns. (E você tem o problema de mostrar que seus próprios testes não estão testando a presença de erros).

Para usar um sistema de prova, você começa com requisitos formais (e eles próprios podem ter erros, espero que a linguagem usada para os requisitos seja mais adequada para se convencer de que não há erros do que com uma linguagem de programação) e construa / prove com a ajuda dos sistemas de prova de que o programa está livre de bugs (e há a questão de bugs nos sistemas de prova, mas eles se mostraram corretos). O estado da arte atual é um compilador para um subconjunto C (e o subconjunto não é acadêmico ", o CompCert suporta todo o subconjunto MISRA-C 2004 de C, além de muitos recursos excluídos pelo MISRA").


Para citar Donald Knuth (de memória): Você pode provar que um programa é livre de bugs, mas isso não significa que ele não tem erros :-)
gnasher729

1

Não, porque o ambiente de computadores e software em que o aplicativo é executado continuará sendo alterado, mesmo enquanto o código estiver congelado. O sistema operacional continua a evoluir com correções e correções, além dos dispositivos e drivers. Apenas quando você acha que atingiu o ponto de nenhum erro conhecido, a AMD ou a nVidia lançam uma atualização de driver de vídeo que afeta a maneira como você interage com o subsistema de vídeo. Agora, seu aplicativo tem defeitos visuais (como piscar, piscar ou reduzir a taxa de quadros) para clientes que possuem uma determinada placa de vídeo ou configuração (SLI? LOL).

Além do hardware e do sistema operacional, também existem vários produtos de middleware sob os aplicativos mais significativos que também evoluirão além do seu controle e, assim como você coloca seu código em um defeito zero, declara as camadas abaixo de EOL.

A tecnologia evolui, assim como os negócios que a alavancam, e a idéia de "liberar" o código não é possível ou viável. A empresa que solicita um novo conjunto de recursos não responde bem a "temos o código bloqueado enquanto perseguimos todos os erros conhecidos e ninguém relata um defeito de software válido em X meses". Mesmo que a empresa compre essa linha, após X meses, eles perguntarão como os novos recursos estão chegando, e a resposta não pode ser "decidimos estender o congelamento porque a Oracle acabou de lançar um patch e precisamos levar X mais meses para certificar isso ".

Não, em algum momento a empresa procurará uma equipe de desenvolvimento mais flexível que suporte a necessidade de avançar na velocidade da tecnologia. Esse é o problema fundamental que as equipes de desenvolvimento modernas enfrentam.


0

Sim, mas você nunca saberá com certeza. Quanto mais você olhar, mais você encontrará. Quanto mais pesado o sistema é usado e mais caixas de aresta são usadas, mais provável você encontrará outra incompatibilidade com a intenção ou especificação original. Isso implica que um bug em si não é uma coisa exata e geralmente dependerá da interpretação, de quão ruim alguém avalia uma anomalia percebida.

É uma coisa confusa. Poucos sistemas são especificados até o último bit. Se um sistema funcionar bem e os usuários não tiverem reclamações (eles não foram corrigidos por nada) e estiverem totalmente adaptados a ele, você também pode chamá-lo sem erros.


-2

É possível fornecer consistentemente software livre de erros, com disciplina suficiente e cultura de equipe compartilhada. (E código modular bem fatorado, um conjunto abrangente de testes automatizados, inspecionando defeitos e adaptando seu processo, e muitas outras coisas que exigem esforço e humildade, mas pagam mil vezes mais)

Mas, ao fazer isso, geralmente você não pretende construir um sistema de 20 MLOC. Se escrever um código sem erros não é o seu objetivo, também não deve criar um sistema de muitos MLOC.

Meu próprio raciocínio é o seguinte:

Alguma pessoa tem uma necessidade a cumprir. Alguma pessoa (possivelmente a mesma, possivelmente outra) tem um orçamento para atender à necessidade através da criação de software. Todas essas pessoas esperam obter algum benefício pelo seu dinheiro.

A pessoa com um orçamento pagará a algumas pessoas (possivelmente as mesmas, possivelmente diferentes) chamadas de programadores , para que esses programadores transformem parte do tempo acordada em software que atenda à necessidade.

Portanto, esses programadores trabalham para transformar o dinheiro de outra pessoa em software que atenda à necessidade. É sua responsabilidade colocar esse dinheiro em bom uso.

Isso tem as seguintes implicações em relação à sua pergunta:

  • Dado que existe um erro no software, você o corrigirá? Você precisa de um programador para corrigir um erro, e o programador custará dinheiro. Um programador não pode decidir se gasta o dinheiro para fazer isso. É o papel da pessoa que detém o orçamento.
  • Posso criar um software 20MLOC a partir do zero sem deixar erros não corrigidos no final? Bem, planejar construir um 20MLOC exigia a intenção de gastar uma quantidade enorme de dinheiro. Isso é tolice financeiramente. E não é construído em um dia. Mas o software é para as necessidades de hoje, não para amanhã. Haverá uma tentativa equivocada de paralelizar o desenvolvimento , contratando muitos programadores. Mas, então, é provável que você não consiga uma cultura compartilhada, e haverá erros, desperdícios e atrasos, e dinheiro acabará para consertá-los. Ainda não vi nenhum sistema sem erros desse tamanho. (Vi sistemas sem erros e sistemas 20MLOC, mas eles não eram os mesmos)
  • Sou responsável por manter um sistema 20MLOC que não escrevi. Serei capaz de atingir zero bugs conhecidos? Isso não depende dos programadores. Eles não podem decidir consertar bugs porque não é o dinheiro deles em jogo. Existe ROI suficiente para corrigir os erros restantes? Bem, o sistema já existe há algum tempo e os usuários se acostumaram e usam as peculiaridades do sistema como vantagem em seu trabalho diário. Se você corrigir bugs por princípio, a pessoa com o dinheiro poderá ter que pagar para desenvolver novamente um recurso não especificado que desapareceu do sistema, custando ainda mais dinheiro.

É tudo sobre o dinheiro, e com razão.


-2

Sim.

Mas, como você sabe, exige muito esforço para valer a pena.

Antes que eu possa defender minha resposta, precisamos primeiro definir o que é um erro:

  • Um bug é um comportamento contrário à especificação.
  • No entanto, falhas na especificação (por exemplo, a 0ª lei da robótica) não contam como bugs de software.
  • Recursos extras não contam como bugs, a menos que sejam proibidos pela especificação.
  • Por uma questão de argumento, as contradições dentro da especificação também não contam como bugs de software.

Agora, como você já sabe, as boas arquiteturas de software são modulares, para que cada módulo possa ser testado em unidade (ou manualmente, ou o que for) individualmente. Através da disciplina e testes cuidadosos, é possível escrever módulos individuais que não possuem bugs.

"Mas espere!" Eu ouço você protestar: "E se um comportamento inesperado (mas ainda assim correto) de um módulo causar um bug em outro?" Então o bug está no segundo módulo. Os módulos sem erros podem ser tratados como APIs, e as APIs, como você sabe, exigem algum cuidado para serem usadas corretamente.

Escrever código à prova de balas exige amplo conhecimento de casos extremos e lógica de fluxo por parte do desenvolvedor, e a maioria dos desenvolvedores de software não é inteligente o suficiente para aprender ou simplesmente não se importa. Ou, mais frequentemente, eles estão dentro de um prazo.

"Mas me dê um lugar para ficar, e eu mudarei o mundo." - Arquimedes


Exige esforço, mas que retribui.
Laurent LA RIZZA

11
Se você deixar os erros de especificação fora da equação, todo o seu software se tornará inútil: as especificações são apenas ferramentas para anotar as necessidades do usuário de uma maneira relativamente formal, mas, no final, é o usuário que precisa ser satisfeito, não a especificação. E criar a especificação é tão parte do desenvolvimento de software quanto escrever o código. Afinal, uma especificação formal completa descreveria o comportamento do sistema, assim como o código final, a especificação não é executável com eficiência.
Cmaster
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.