Google Analytics

sexta-feira, 21 de janeiro de 2011

"The miserable programmer paradox"

O artigo hoje não é meu. Este post é para apontar para um post de outrem.

Me enviaram o endereço the-miserable-programmer-paradox há alguns dias e no fim de semana consegui ler. Nada mais verdadeiro do que o que ele diz.

E uma grande verdade que todos os envolvidos com desenvolvimento de software deveriam aprender está escrita lá no meio: "A train of thought is a fragile thing". Programação e interrupções ao programador simplesmente não combinam. ;-)

Abraços e até o próximo.
Publicar postagem

sábado, 8 de janeiro de 2011

Identificadores de versão

O assunto de hoje é identificadores de versão. Os famosos v1.0, v1.2.5.9, etc.

Todo mudo já viu estes números em software e a maioria acha que entende bem como funcionam e para que servem. Nem todos... Muitos tem uma vaga idéia; alguns tem uma idéia melhor, mas não sabem como incrementar cada campo e poucos realmente sabem qual a real utilidade destes números e quais são os mecanismos lógicos de avançar os números de versão de um software.

Vamos aos detalhes.

Primeiro, por que se tem números de versão? A resposta é simples: Para termos rastreabilidade do software em campo. E o que é isto? É se poder identificar de forma inequívoca qual versão de um programa um usuário estava rodando (por exemplo, para poder auxiliar o usuário ou reportar/corrigir um bug). Sabendo-se o identificador de versão (VID), deve-se ser também capaz de recuperar os arquivos fonte exatos que geraram aquela versão do software (provavelmente usando tags ou baselines de seu sistema de versionamento de fontes). Isto mostra que temos que garantir que nosso software nunca repetirá um VID, ou seja, se mudamos qualquer coisa no software, temos de mudar o VID.

Há várias estratégias e formatos de VID possíveis que garantem a rastreabilidade e alguns ainda dão indicações de compatibilidade entre versões do software. Eu vou explicar o mecanismo de 4 dígitos comumente usado, pois ele é simples de entender e amplamente difundido. Neste mecanismo, os VIDs têm a forma M.n.r.b ou M.n.r-b, onde M, n, r e b são números naturais (0, 1, 2, 3...). M é chamado de Major, n é o minor, r é o release (também chamado de patch level e abreviado como p) e b é o build.

Como queremos que qualquer mudança no software cause mudanças no VID, vamos incrementar o build number cada vez que buildarmos o software (ou seja, gerou os deliverables -- instaladores, executáveis, etc -- do software, incrementa o build number). Notem que o build number será incrementado SEM TER HAVIDO ALTERAÇÕES NOS FONTES! Alguns vão perguntar: Ué, mas sem alterações nos fontes, então nada mudou e não precisa mudar o VID... Errado! O tempo passou, a máquina em que o build foi realizado envelheceu (pode ter sofrido atualizações de software...), eventualmente até estamos buildando em uma máquina diferente. Ou seja, muita coisa pode ter mudado. Por isso, incrementa-se o build number e assim se tem certeza que não teremos duas cópias com mesmo VID e comportamento diferente. Notem que o processo de incrementar o build number pode e deve ser automatizado. O próprio conjunto de scripts de build ou ferramentas de build deve se encarregar de incrementar o build number, evitando esquecimentos. Detalhe importante: Mesmo que se mude de máquina, o build number tem de ir sempre crescendo, quer dizer, temos de bolar um jeito de que os scripts guardem qual o último build number usado em algum lugar compartilhado e o incrementem. A solução clássica é guardar o buil number (e o resto todo do VID) no repositório de fontes (sistema de versionamento de fontes).

E quando mudamos algo nos fontes? Bom, aí precisamos de um incremento em alguma parte além do build number. Se a alteração foi apenas uma correção de bug ou alteração interna, sem mudança nas funcionalidades do software, se incrementa apenas o release number. Ao incrementar o release number, se volta o build number para zero. Isto faz com que a seqüência de VIDs fique do tipo M.n.0.0, M.n.0.1, M.n.0.2, M.n.1.0, ...

Se houve alteração ou adição de funcionalidades, devemos incrementar o minor ou o major, dependendo do tipo de alteração. O minor é incrementado se podemos garantir que não houve quebra de compatibilidade na nova versão. Isto normalmente ocorre se só houve adições ao software e tudo que se podia fazer antes continua valendo (por exemplo, ler na nova versão os arquivos gerados com a versão anterior, executar as mesmas operações que eram possíveis anteriormente, etc).

Se ocorre quebra de compatibilidade, devemos incrementar o major number. Muitos recomendam também incrementar o major number quando houve muitas alterações no software, mas há que se olhar esta recomendação com certo cuidado, pois é difícil definir o que são "muitas"...

Resumindo a conversa:
  • Os números de versão existem para permitir rastreabilidade. 
  • Há muitos procedimentos (especificações) de como atualizar números de versão que funcionam, garantindo a rastreabilidade (e existem também alguns escritos por aí que não funcionam, portanto, caveat...). 
  • Um mecanismo lógico possível de ser usado estabelece um identificador de versão de 4 números (major, minor, release e build) incrementados da seguinte forma:
    • No mínimo o build number é incrementado sempre que se reconstroi o software.
    • No mínimo o release number é incrementado se houve alterações nos fontes.
    • No mínimo o minor number é incrementado se houve alterações de funcionalidade no software.
    • O major number é incrementado se houve alterações no software com quebra de compatibilidade.
PS.: Se fala em "compatibilidade para trás" (backward compatibility). Para explicar este conceito, o melhor jeito é usando um exemplo. Imagine que você usa a versão 1.1 de um editor de textos para criar alguns arquivos. Logo a seguir, você instala a versão 1.2 deste editor e cria novos arquivos com ela. Se diz que há backward compatibility se a versão 1.2 do editor conseguir abrir sem problemas os arquivos da 1.1. O  contrário, ou seja, abrir os arquivos da 1.2 usando a 1.1 pode não ser possível, e, por isso, se fala em "para trás". No esquema de versionamento descrito neste artigo, alterações no minor number indicam que há compatibilidade para trás.

PS2: No caso das duas versões do software abrirem arquivos uma da outra, independentemente de qual é mais nova, têm-se compatibilidade total. No esquema de versionamento descrito neste artigo, alterações no release number indicam compatibilidade total.

PS3: O exemplo de abrir arquivos de outras versões é APENAS UM EXEMPLO DIDÁTICO para explicar o conceito de compatibilidade. Na realidade, todas as funcionalidades do software devem ser levadas em conta e cada tipo de software tem coisas diferentes a serem avaliadas. Exemplos: Uma biblioteca com backward compatibility significa que programas linkados com uma versão mais antiga vão funcionar com a mais nova; no caso de servidores, os clientes que sejam feitos para a versão mais antiga do servidor devem continuar funcionando com a versão mais nova; e por aí vai.

Abraços e até o próximo artigo.
LGM

quinta-feira, 23 de dezembro de 2010

Microsoft Office

O artigo de hoje é curto e não é sobre programação. É sobre compra de software da MS. Tentei comprar o Office Home & Student hoje via internet. Incrível, mas provavelmente é mais difícil comprar do que usar uma versão pirata.

Depois de duas horas de trabalho infrutífero e frustrante, finalmente consegui ao menos baixar uma versão de avaliação do 2010. Desagradável que no final, por eu estar no Brasil, ele não deu muita atenção ao meu pedido inicial de baixar a versão em inglês e, em algum dos milhares de reloads de página que precisei dar, deve ter mudado para pt_BR sem eu notar. Resultado: Estou novamente tentando baixar a versão em inglês. Agradeci a todas as divindades de todas as religiões que eu estava baixando o trial version e não tinha feito nenhum pagamento...

Resumindo, além de ser caro, o Office é difícil de ser comprado. A não ser que esta versão seja realmente maravilhosa e me surpreenda muito durante o trial, vou acabar mesmo é usando Google Docs para editar documentos. (E viva o SaaS...)

domingo, 12 de dezembro de 2010

O procedimento de correção de bug

Pessoal, parece incrível, mas a maioria das pessoas não tem a menor noção dos passos básicos para corrigir um bug. Então, decidi escrever um pequeno texto falando sobre isto.

Vamos começar definindo o que é um bug. Bug é um resultado obtido que é diferente do desejado. Trata-se de um defeito.

Assim sendo, a correção do bug deve começar com uma indicação clara do defeito, ou seja, com um bom bug report. Buenas, não adianta inventar no bug report, nem usar ferramentas com milhares de campos, nem com letras em ouro. O que resolve é ter claramente no report as seguintes informações:
  • Passos que fazem com que o resultado indesejado (o bug) aconteça de forma determinística. De forma determinística significa: aconteça SEMPRE que eu seguir aqueles passos e sem precisar de nada mais...
    Por que isto é importante? Porque sem ter um modo consistente de fazer o bug manifestar-se, a pessoa que vai tentar corrigir teria de agir por adivinhação e isto não é nem muito científico nem muito profissional.
  • Resultado esperado.
    Por que é importante? Para o corretor saber quando ele chegou onde devia.
  • Resultado obtido.
    Por que é importante? Para o corretor saber se ele realmente está vendo O MESMO bug que quem reportou (o reporter).
  • Versão do software em que o bug foi visto.
    Não queremos perder tempo tentando corrigir algo que já foi corrigido em um patch, service pack ou versão mais nova...
Tendo isto, podemos começar o processo de investigação e correção:
  1. Reproduza o bug.
    1. Instale EXATAMENTE a mesma versão do software indicada no report. Use o instalador que foi para campo e não uma recompilação de fontes.
    2. Siga os passos de como reproduzir o bug.
    3. Certifique-se de que obteve o "resultado obtido" citado no report.
  2. Reproduza o bug compilando os fontes.
    Faça isto seguindo os mesmos passo que no item anterior, mas recompile o software a partir dos fontes em que vai trabalhar. Você vai se surpreender com a quantidade de vezes que, mesmo após ter passado no passo anterior, com os fontes de trabalho, o bug não aparece.
  3. Investigue a causa raiz do bug.
    Aqui entram em cena as ferramentas de depuração: debugger, instrumentação de código, código dos unittests, inteligência e experiência do corretor, etc. É impossível descrever em detalhes como se faz isto, e só sobre este item eu poderia escrever vários artigos, então aqui vamos apenas dizer que tem de investigar até achar a causa do bug.
  4. Arrume seus unittests para pegarem o erro.
    Seus unittest não pegaram o erro anteriormente, pois ele foi visto por alguém. Então há uma falha nos unittests e ela deve ser corrigida. Ao fim deste passo, seu unittest deve estar apontando um erro.
  5. Altere o código para corrigir o bug.
    Certifique-se também de que agora os unittests estão passando. A propósito, use os unittest do módulo sendo alterado como auxiliar na alteração do código, ou seja, não compile o software inteiro antes que o unittest do módulo alterado esteja passando.
  6. Rode TODOS os unittests do software.
    Isto vai deixá-lo mais seguro de que nada foi quebrado no conserto.
  7. Faça um rebuild incluindo as correções.
  8. Re-execute os passos descritos no bug report e certifique-se de que o resultado esperado agora é obtido.
  9. Levante (ao menos mentalmente) as possíveis áreas adjacentes do software que podem ter tido efeitos colaterais com sua mexida e TESTE-AS.
  10. Se o bug não foi encontrado como resultado da execução de seus testes internos, revise seu plano de teste para incluir um caso de teste que pegue o bug.
Pronto. Agora você tem um bug corrigido apropriadamente e com maiores chances de sucesso.

Os princípios que norteiam este processo são:
  • Trabalho metódico: sem adivinhações, basear-se em fatos.
  • Melhoria contínua: melhorar as redes de proteção (unittests e plano de testes) quando um bug passa por elas e a cada novo bug elas ficam melhores.
  • One var is gooood, two vars is baaaaad: Uma variável é bom, duas variáveis é ruim.... Mude sempre apenas uma coisa de cada vez. -- a propósito, a frase é uma brincadeira com o slogan das ovelhas do Animal Farm.
Abraços e até o próximo artigo.

Inauguração do BLOG

Buenas, então vamos a uma breve introdução sobre este blog.

Originalmente, eu criei uma página com artigos em http://www.lgmoreira.com, mas está me parecendo que escrever e gerenciar a página com o google sites é meio enfadonho e que é mais simples com um blog. Por isso, criei o blog aqui e vou passar os artigos da página para cá.

No começo, vou tentar manter o material nos dois locais. Mas com o tempo, vou optar por um deles e deixar no outro apenas um link para o local escolhido.

Abraços e até mais.

PS: Não esqueçam que este trabalho é voluntário e, no caso de alguém querer contribuir com alguns reais pelo trabalho, pode fazer através do SourceForge.