Archive Page 3

Você não vai querer um programador Java

Muito menos um programador C#, Delphi ou Visual Basic. Para falar a verdade, o que você quer não é nem mesmo um programador Python, Ruby ou Lua.

Este texto também não é um elogio aos programadores Haskell. Você também não vai querer um desses.

Se você tem um problema para ser resolvido com algum programa de computador, o que você precisa é de um programador. Simples assim.

Ninguém precisa da especialização em nenhuma linguagem ou plataforma específica para começo de conversa, mas para programar computadores com certeza você vai precisar de um programador. A verdade é que ele vai precisar de muitas outras habilidades além de proficiência com um compilador, mas se você contratar alguém que não sabe programar, terá uma bela enrascada em mãos. Não importa quantos analisadores de problemas e desenhadores de retângulos sua equipe tiver, se eles não puderem conseguir que um computador faça alguma coisa, seu projeto vai ser um fiasco na certa. A não ser — é claro — que os retângulos possam ser transformados de algum modo em instruções detalhadas executáveis por um computador.

Mas nesse caso você teria programadores. Só aconteceria deles programarem com retângulos, mas ainda assim seriam programadores.

Conhecer uma única linguagem de programação não é um empecilho somente porque muito provavelmente ela não vai mais ser a melhor ferramenta para o trabalho daqui a três ou quatro anos, mas porque mostra uma incapacidade (ou falta de vontade) para aprender. O que nenhum cliente deveria querer são programadores altamente especializados a ponto de conhecer uma única linguagem de programação. Ao invés de um programador especialista na plataforma da moda de hoje, o que você precisa é de um que seja capaz de aprender as de amanhã. O que um bom programador mais precisa, como qualquer bom profissional, não é apenas saber usar as ferramentas do presente, mas ter capacidade de aprender as do futuro.

Não se deixe enganar também por programadores de retângulos, mesmo que eles gostem de ser chamados de modeladores, arquitetos ou de qualquer outro nome que esteja na moda na época. Linguagens visuais também são apenas linguagens. São linguagens que, por serem gráficas, podem parecer independentes de linguagem, mas não deixam de ser linguagens. Não importa que o programador desenhe ao invés de escrever, se ele quis se limitar a desenhar, deve ser porque não quer nem se dar ao trabalho de aprender a escrever.

Especialização em excesso além de tudo cria ilhas muito concentradas de conhecimento. Por algum motivo inexplicável, muitos programadores especializados acham que jogam em times adversários, que estão em trincheiras diferentes e que tudo é uma grande guerra. Se quiser experimentar isso, tente publicar uma notícia que simplesmente cite Ruby (nem precisa ser o tema principal) em um fórum Java e observe o que acontece. O triste é que eles acabam isolando a si mesmos dentro de uma comunidade pequena e perdem de aprender o que as pessoas de fora poderiam ensinar.

Anúncios

Blogday 2007

O José Oliveira indicou este blog (junto com outros quatro) em um texto publicado como parte da iniciativa BlogDay 2007. Ele não especificou se isto é algum tipo de meme, mas tem todas as características de um. Parece que estou meio atrasado, já que o tal dia foi na última sexta-feira (dia 31), mas vou usar isto como desculpa para indicar cinco blogs que acompanho de qualquer modo (em nenhuma ordem em particular):

Motor curiosidade — Novo blog do Marcos Pereira sobre desenvolvimento de software e essa vida de programador. Promete ser extremamente interessante, a julgar pela qualidade dos dois primeiros textos e pelos textos dele no blog antigo.

Coding Horror — Talvez um dos blogs mais discutidos no pequeno círculo dos programadores. Jeff Atwood costuma abordar com acidez e bom humor assuntos relacionados a tecnologia que vão desde a relevância dos jardins gradeados na internet até como montar uma máquina silenciosa.

Danilo Sato — Para quem quer estar por dentro das últimas novidades em matéria de agilidade e sempre de olho no mundo acadêmico. Danilo costuma freqüentar conferências ágeis (e também algumas não tão ágeis assim) e relata as experiências neste blog, junto com muitos pensamentos úteis.

Thinking Parallel — Mesmo para quem acha que este barulho todo sobre paralelização é só mais uma onda, não custa nada acompanhar o blog do Michael Suess. Apesar dele ser um pós-doutorando, seus textos passam longe do academiquês e costumam ser dos mais digeríveis sobre o assunto.

{ | one, step, back | } — Jim Weirich não é tão conhecido (e forçadamente controverso) quanto David Hansson, mas é uma das figuras mais relevantes quando o assunto é Ruby. Se você programa em Ruby, mesmo que ainda não tenha ouvido falar no cara, já deve ter usado rake ou builder, duas ferramentas criadas por ele.

Sobre grandes alterações pequenas

Qual é a granularidade das modificações que você envia ao seu sistema de controle de versão? Você se limita a modificações pequenas (que mudam o nome de uma varíavel ou outra, por exemplo) ou gosta das mas volumosas (como as que mudam o nome de uma rotina, introduzem um parâmetro novo e ainda corrigem um defeito em um pedaço do código que a chamava)?

Não é uma pergunta retórica. Pode responder. O espaço para comentários ali embaixo serve exatamente para isso.

Quando envio patches para algum projeto, tento torná-los tão pequenos e localizados quanto possível. Eu sei que não é uma experiência muito agradável revisar modificações monstruosas que afetam toda a base de código e tento poupar disso os mantenedores dos projetos para os quais colaboro. Eles são programadores, mas também são gente.

Não é tão raro que uma parte das modificações em um patch sejam aceitas e outras não. Caso o patch enviado seja muito extenso, o mantenedor vai ter um bocado de trabalho para separar as partes boas das ruins. Se ele tiver muitas outras preocupações no dia (o que não é nada incomum), pode ser que ele simplesmente recuse todo o patch, apesar de haver mudanças úteis, só para poupar o trabalho de filtragem. Para quem está contribuindo, certamente é melhor que as modificações sejam aceitas e um conjunto de patches pequenos torna as chances disso acontecer muito maiores do que um único patch grande. Nem todo patch que enviamos é aceito e precisamos conviver com isso. Modificações pequenas e localizadas ajudam muito quando algumas delas precisa ser rejeitadas.

Patches pequenos costumam ser mais ortogonais e fazem muito sentido no contexto colaborativo de um projeto de código aberto, principalmente com sistemas de controle de versão distribuídos. Mas ainda existem sistemas centralizados e — pior — cuja única solução para edição concorrente é usar travas para tentar tornar o desenvolvimento serializado e impedir toda e qualquer tentativa de paralelismo. Como se este cenário não fosse suficientemente ruim, alguns sistemas não suportam commits com múltiplas modificações e obrigam todo mundo a registrar alterações arquivo por arquivo, mesmo que toquem em muitos pontos. Para terminar imagine que a única forma de interação da equipe com a ferramenta de controle de versão seja um cliente gráfico com interface do século passado e dificilmente automatizável.

É serio mesmo, essas coisas ainda existem.

E tem gente que precisa usá-las.

Quando o mundo conspira contra você com tanta intensidade, fica mais difícil resistir à tentação de fazer uma modificação monstruosa com um comentário altamente descritivo como “Modificações do código”. Porém, mesmo quando estou em algum ambiente parecido com este, ainda tento fazer modificações pequenas. Não faço alterações tão pequenas como quando estou usando Darcs e vez ou outra combino duas ou três modificações em uma, mas sempre evito registrar uma alteração que resolva mais de um defeito ou melhoria.

Parece haver um certo conflito entre commits localizados e implementação de recursos. A renomeação de uma rotina, por exemplo, pode ser um dos passos que leva à inclusão de uma nova funcionalidade, mas com certeza não vai resolver a bronca sozinha. As funcionalidades precisam de modificações maiores, mas modificações menores são mais fáceis de entender, revisar e reverter. Será que este conflito real ou apenas um produto da nossa imaginação?

Twitter, eu me rendo

Twitter é um serviço para publicação de mensagens curtas. As pessoas usam todo tipo de aparelho eletrônico para responder a famigerada pergunta “O que você está fazendo?”. As mensagens precisam caber em 140 caracteres. Isso, além de possibilitar mensagens rápidas enviadas de aparelhos celulares, faz com que todo mundo se concentre em dar o recado com poucas palavras.

Quando tomei conhecimento do Twitter, minha reação inicial foi questionar porque diabos alguém iria querer saber o que eu estou fazendo. Eu definitivamente não estou nem aí para o que milhares de anônimos com acesso à Internet estão fazendo agora. Afinal de contas, esse é mais ou menos o mesmo propósito de um blog-diário, só que mais instantâneo.

Mas eu estou muito interessado em aprender com eles. Não importa quem sejam, se eles podem falar algo sobre um assunto que me interesse, quero pelo menos tentar escutar.

Eu tenho o hábito de compartilhar pensamentos rápidos com as pessoas através de mensagens curtas. Todo mundo que está na minha lista de contatos em alguma rede de mensagens instantâneas já deve ter recebido uma dessas (geralmente acompanhadas de um link). Este meio é muito bom para compartilhar estes estalos, momentos eureka e pequenas descobertas. Porém estas mensagens simplesmente querem ser públicas e não gostam de ficar confinadas entre duas pessoas apenas. Uma das maiores evidências que tenho disso é o fato das minhas mensagens nunca serem enviadas para uma pessoa só. Ao invés disso, quase todo mundo que está on-line no momento recebe uma cópia. Além disso, muitas vezes também tenho vontade de publicar as mensagens neste blog aqui, só não acho que seja a mídia mais apropriada.

Assim como aconteceu com os blogs, eu deixei minha impressão inicial de lado e descobri que um serviço de mensagens públicas não precisa ser usado para futilidades e pode ser muito útil para compartilhar estes pensamentos breves. Faz muito sentido tornar público aquilo que não se tem certeza a exatamente quem pode interessar. Assim as pessoas podem escolher por si mesmas o que ler. Por cima disso tudo, como uma cobertura especial, está o robô de mensagens instantâneas que me permite manter a mesma forma de publicação que usava antes. Ou seja, eu não preciso entrar em algum site especial para publicar minhas mensagens, posso usar meu serviço de mensagens instantâneas favorito como sempre fiz. Só que agora ao invés de mandar uma mensagem para uma ou duas pessoas que eu escolher, posso “falar” apenas com o robô e as pessoas podem escolher me dar um segundo da sua atenção ou não.

Portanto, quem quiser acompanhar alguns devaneios mais curtos do que normalmente encontra aqui neste blog, é só seguir para http://twitter.com/thiagoarrais e quem recebia minhas mensagens de vez em quando só vai ser importunado se quiser. Lá ninguém vai encontrar muita coisa sobre o que eu estou fazendo agora, mas pode ter uma idéia do que estou pensando.

P.S.: Não consegui achar um artigo na wikipedia em português sobre a palavra “Eureka”. Será que alguém tomaria o tempo para começar um?

Fábricas de software – Uma analogia levada longe demais

Analogias costumam ser usadas para tentar entender melhor algo. A idéia é bastante simples: compara-se o objeto ou conceito que não se conhece a outro bem conhecido com o objetivo de aprender alguma coisa ou formar algum argumento. Muito já se descobriu com ajuda das analogias, mas elas também podem ser bem perigosas. Eu poderia repetir tudo aqui, mas o Marcos Pereira saiu na minha frente com o primeiro artigo do seu novo blog que discute várias das mais furadas analogias para desenvolvimento de software (e uma das certeiras). Ao invés disso, este artigo vai se deter em apenas uma delas: a das fábricas.

Fábricas são instalações onde as pessoas se reúnem para produzir um certo tipo de artigo. Fábricas de sapatos fazem sapatos, fábricas de postes fazem postes e fábricas de software fazem software.

Simples assim.

Mas nem tanto…

Fábricas são instalações com estrutura e procedimentos de produção pautados por um certo modelo. Afinal de contas, não são só as fábricas que se encaixam na definição acima. Organizações como oficinas e ateliês também podem perfeitamente produzir artigos de qualidade. A diferença está na organização interna.

Um dos maiores problemas das analogias é que costumam ter limites não muito bem definidos. Toda analogia tem um ponto de quebra a partir do qual não faz mais sentido e nem sempre é fácil identificar até onde podem ser aplicadas. Nas mais rasas este ponto de quebra é alcançado bem rapidamente como neste caso das fábricas.

Ao pensar em fábricas é comum lembrar de linhas de montagem, funcionários altamente especializados e produção em massa. Tudo isso faz muito sentido em boa parte das fábricas, como as de sapatos, automóveis e componentes eletrônicos, mas não tem grande valor para quem produz software.

Software não se encaixa num modelo de produção em massa e manufatura porque não é repetição. Fazer software é projetar, não construir. Ninguém pensa em fazer o mesmo projeto do mesmo sistema duas vezes, mas muita gente pensa em licenciar para dois clientes diferentes. Fábricas são excelentes para reproduzir produtos idênticos ou com pouca variação, mas projetar software — assim como projetar carros, telefones e praticamente qualquer coisa que se possa imaginar — é um processo criativo que não se adapta muito bem à manufatura. Fábricas são bastante eficientes para reproduzir produtos em larga escala. Só que ninguém precisa de uma fábrica para reproduzir software, uma máquina de prensar discos já basta (sim, desenvolvedores web, ainda existe gente que precisa distribuir software em discos).

Muitos programadores felizmente já notaram que especialização extrema e processos de desenvolvimento repletos de fases — e, conseqüentemente, entregas parciais — não fazem muito sentido. Estas abordagens servem muito bem para reproduzir produtos. Só que software não é feito de madeira e cola, nem de aço e solda. Mas de idéias e bytes. Por causa de sua natureza imaterial, reproduzir software é muito simples e barato. Portanto, o problema da reprodução já está resolvido, o que queremos é projetar software com qualidade e de forma economicamente eficaz. Este é o fator primordial que impede esta analogia de ir tão longe.

Muita gente sabe disso, mas misteriosamente ainda gosta de chamar suas organizações de fábricas. Ao contrário do que possa parecer, alguns desses não são completos idiotas e sabem pelo menos alguma coisa do que estão falando. Quando falam em fábricas, eles não estão pensando em programadores operários apertando parafusos, mas em coisas interessantes como linguagens para certos domínios de conhecimento e frameworks especializados. Apesar disso, essas pessoas fazem esforços tremendos para extrapolar a metáfora e chegam a chamar linguagens de fábricas (é verdade, essa eu vi em uma lista de discussão que, infelizmente, não tem arquivos públicos e não pode ser referenciada aqui). Várias dessas idéias fazem todo o sentido do mundo, mas definitivamente não são fábricas.

Provavelmente muitos dos pesquisadores modernos fazem a analogia por razões históricas e não de forma intencional. O problema é que, devido a sua natureza metafórica, a expressão pode ser mal interpretada e, infelizmente, isso não acontece tão raramente quanto gostaríamos. Tem gente que gosta de fingir que acompanha as novidades do meio acadêmico e já viu a expressão “fábrica de software” repetida várias vezes em títulos de artigos científicos. Mas o título deve ser a única linha que eles lêem. Depois de olhar para o nome, acham que podem organizar suas “fábricas” exatamente como manufaturas juntando programadores aos montes para repetir código e fazer trabalho mecânico em geral. Afinal, parece ser a última moda entres esses cientistas inteligentes e deu certo para as fábricas de sapato na China, não deu?

O resultado são fábricas de software funcionando (ou tentando funcionar) igualzinho a fábricas de sapato. Os programadores que dão o azar de ser tratados como máquinas de costura esperneiam de um lado dizendo que esta é a pior idéia desde a bola quadrada e os pesquisadores esperneiam do outro dizendo que o conceito deles de fábrica na verdade é uma boa idéia que não tem nada a ver com aquilo. Enquanto isso os leitores de títulos continuam a construir mais fábricas segundo seu próprio conceito para perpetuar a confusão.

Boa parte disso tudo simplesmente por causa de uma analogia que foi levada longe demais.

Assinar acordos não é entrar em acordo

Toda equipe que desenvolve software já deve ter descoberto que “o entendimento dos requisitos deve ser alcançado.” Eles podem ter lido isso em algum lugar ou simplesmente enxergado algo que é óbvio demais para ser ignorado por qualquer mente saudável. Não importa como chegaram a tomar conhecimento disso, o importante é que qualquer pessoa que se propõe a resolver o problema de outra sabe que precisa entender razoavelmente bem o que está querendo solucionar. A questão interessante é desenvolver uma maneira eficiente de fazer isso.

Uma alternativa que faz muito sentido é tentar escrever e assinar junto com os clientes um belo documento que descreva detalhadamente os requisitos. Esta estratégia parece bastante natural porque a maioria das pessoas já está bem familiarizada com assinaturas e contratos. Afinal não é exagero dizer que este tipo de formalização vem sendo usado há séculos nos mais variados campos de atividade.

Acordo ilusórioPor causa disso não é muito intuitivo pensar que esta abordagem tem um alto potencial para falta de entendimento. Como as coisas estão somente descritas e não há algo realmente tangível para guiar as opiniões, o entendimento depende totalmente da interpretação do texto e é possível que cada uma das partes tenha uma idéia diferente do objeto do acordo na hora da assinatura. Para que um acordo verdadeiro seja firmado, é essencial que ambas as partes estejam pensando na mesma coisa. Sem isso o máximo que se consegue é uma ilusão. Por causa do papel crucial da interpretação do texto, é comum que este tipo de engano ocorra ao usar apenas documentos. Apesar disso as assinaturas geralmente são aceitas como evidências de acordo.

Documentos fazem muito sentido quando o desenvolvimento do produto final precisa levar muito tempo. Quando isto é verdade o registro por escrito dos requisitos é uma opção aceitável. Há o risco de um acordo ilusório, mas ele é menos prejudicial para ambas as partes do que o cancelamento da empreitada. Porém quando os requisitos podem ser suficientemente pequenos e a equipe tem um processo de desenvolvimento suficientemente enxuto, as necessidades do cliente podem ser identificadas na segunda-feira e estarem materializadas em software rodando na sexta-feira seguinte (se é que software pode ser materializado). Quando isto é possível não faz mais sentido utilizar documentos e correr o risco de um falso acordo porque o produto final pode ser usado como objeto do acordo.

Software em execução é a forma mais incontestável de entendimento dos requisitos. Ninguém pode dizer que a equipe de desenvolvimento e o cliente não estão de acordo quando eles concordam sobre o produto final. Não há mais o que refinar, portanto não há mais onde discordar.

A festa seqüencial acabou

Dia desses montei uma máquina nova para mim. Ela tem um desses processadores pomposos de núcleo duplo que já deixaram de ser os artigos de luxo que eram há alguns anos. Minha máquina anterior tem um processador de núcleo simples da época em que os de núcleo duplo tinham preços proibitivos. Este núcleo solitário trabalha a uma freqüência de 1.8GHz enquanto os dois núcleos da máquina nova rodam a 2.2GHz. Acho que a diferença é suficientemente pequena para que possamos dizer que a freqüência é mais ou menos a mesma. Os ganhos de performance, portanto, devem ser proporcionados principalmente pela presença dos dois núcleos e não do aumento de freqüência.

Porém a máquina nova não parece ser muito mais rápida que a antiga. Obviamente ela se sai muito melhor que a anterior quando há vários processos rodando ao mesmo tempo. Mas quando preciso que ela execute um programa único, a performance é mais ou menos a mesma. Por um lado, é verdade que o gargalo da maioria das aplicações realmente não está no processador nem na memória, mas nos dispositivos de entrada e saída como rede e disco. Para estas aplicações é de se esperar que um aumento da capacidade de processamento não faça grande diferença. Por outro lado, esta máquina nova não parece mais rápida nem para atividades com uso intenso do processador.

Utilização de CPUEm nome da boa e velha curiosidade, resolvi fazer um teste rápido. Peguei um dos meus CDs de música e coloquei a máquina para compactar uma amostra razoável de áudio. Compactação de áudio (e vídeo) é uma daquelas tarefas ridiculamente paralelizáveis. Uma forma bastante óbvia de aproveitar melhor o hardware seria deixar que cada um dos processadores ficasse responsável pela compactação de metade do trecho de áudio. Apesar disso, quando estava compactando o áudio, observei que apenas um dos núcleos fica em uso em um dado momento. De vez em quando o processamento é transferido de um núcleo para outro, mas apenas um é usado efetivamente.

Quando há vários processos diferentes brigando por um pouco de tempo de processador, os sistemas operacionais modernos são bastante espertos para distribuírem a carga inteligentemente. O problema acontece quando há um programa que demanda muito do processador mas não está preparado para ser quebrado em partes menores e executado em paralelo. Se ele não usa nenhum mecanismo para identificar os trechos de código que podem ser executados lado a lado, o máximo que o sistema operacional pode fazer é enxergá-lo como um grande amontoado de instruções a serem executadas uma após a outra. Chegamos a um ponto em que os sistemas operacionais estão prontos e o hardware também está pronto, só faltam as aplicações.

Máquinas com múltiplos processadores já são realidade há um bom tempo e o uso de vários núcleos por chip não é tão novo assim, mas este tipo de tecnologia estava limitado a certos nichos. A preocupação em utilizar o poder de vários processadores operando em paralelo só começa a se popularizar agora que a festa seqüencial acabou. Antes não fazia muito sentido dar-se ao trabalho de escrever programas paralelizáveis porque era possível fazê-los executar de forma mais rápida simplesmente enfiando mais alguns megahertz nos processadores. Porém agora o limite da freqüência, e principalmente da dissipação do calor associado, parece ter sido atingido e, por mais que esperemos, não vai dar mais para comprar processadores que operem a freqüências muito maiores que as atuais.

Meu palpite é que, de agora em diante, quem precisar melhorar a performance de suas aplicações utilizando todo o hardware disponível (o que não se aplica a todo mundo, afinal a “otimização prematura é a raiz de todo o mal”) vai precisar escrever programas paralelos. Na verdade, eu acho que as pessoas já estariam escrevendo programas paralelos há muito tempo se fosse mais fácil. Só que os ambientes para desenvolvimento mais populares de hoje não são muito amigáveis para este tipo de programa. As plataformas mais usadas ainda fazem uso de alguns conceitos que se mostraram bem difíceis de digerir, como threads e semáforos.

Isso quer dizer que precisamos descobrir novos modelos de pensamento se quisermos trabalhar com código concorrente e paralelo. Se você me permitir outro palpite, posso arriscar dizer que os modelos mais eficientes do futuro não vão ser tão seqüenciais quanto os atuais.