Google Summer of Code 2009

Aqui no Vetta Labs são desenvolvidos vários projetos da Novamente, e com isso temos bastante contato com o Singularity Institute for Artificial Intelligence (SIAI). Desde o ano passado o SIAI é um participante do Google Summer of Code, um programa que paga bolsas (US$ 4000) para estudantes do mundo todo trabalharem em projetos de código aberto e software livre durante o as férias do verão americano (daí o nome).

Os estudantes são orientados por mentores ligados às  organizações participantes. No GSoC 2008 fui mentor do projeto OpenBiomind-GUI, que desenvolveu uma interface gráfica para um conjunto de ferramentas open source para bioinformática. Outro colega, Lúcio de Souza Coelho, também participou como mentor. Foi uma experiência muito interessante e gratificante.

E agora foram abertas as inscrições para o Google Summer of Code 2009! Estudantes no final da graduação e em pós-graduação podem participar, submetendo propostas baseadas nas idéias sugeridas pela organização, que incluem projetos em inteligência artificial e robótica  (OpenCog), processamento de linguagem natural (Link Grammar e RelEx), bioinformática e outros temas.

As propostas são avaliadas pelos mentores e outros membros do grupo, e as melhores são aceitas no programa. Ano passado houve 70 propostas para 11 vagas. A data limite para submissão de propostas é 3 de Abril.

A página principal do GSoC tem todas as informações necessárias:

http://socghop.appspot.com

A página do SIAI no Google Summer of Code, especificamente, é a seguinte:

http://socghop.appspot.com/org/show/google/gsoc2009/opencog

Biotecnologia, Desenvolvimento, Inteligência Artificial, Linguagem Natural 1 Comentário

1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5,00 out of 5)

Software livre no seu carro: “Veneno” open source

Não preciso nem dizer que o Brasil tem tradição em automobilismo – nem que for pra lembrar das incontáveis manhãs de domingo com Fórmula 1. O que acho mais interessante é que nosso tesão por motorsports independe de suporte formal: apesar de alguns esforços heróicos não temos grandes equipes em categorias de ponta.

Mas isso nunca é problema quando se tem alguma criatividade. O extremo mais precário é um dos meus exemplos preferidos: são comuns em cidadezinhas do interior os “jericos” – carros inteiros construídos a partir de sucata, usando motores estacionários (feitos para serrarias, máquinas agrícolas pequenas, etc.). Daí para competições rústicas envolvendo esses carros, jipes e fuscas é um passo.

(Foto: Marco Antonio Teixeira)

(Foto: Marco Antônio Teixeira)

Algumas soluções técnicas pouco convencionais (gambiarras mesmo) fizeram história no automobilismo brasileiro. Em 1969, os jovens Emerson e Wilson Fittipaldi disputaram os Mil Quilômetros da Guanabara ao lado de lendas como Ford GT40 e Alfa P33, a bordo de um Fusca de 400 cavalos, vindos de dois motores acoplados por uma junta elástica de borracha!

(Foto: obvio.ind.br)

Nos anos 1970 e 1980, qualquer um que pensasse em esportivo no Brasil tinha que falar do Opala, e necessariamente do “veneno” – modificações no motor como troca de carburador, bicos injetores e comando de válvulas para deixar o motor seis cilindros do que hoje é um dos maiores clássicos brasileiros ainda mais bravo e, obviamente, divertido.

Opalão SS 9 Silver Star

(Foto: Opala Club de Bragança Paulista)

A chegada da injeção eletrônica ao Brasil com o Gol GTI, em 1989, foi o início de uma grande mudança: agora um programa de computador, sensores e atuadores eletrônicos passariam a ditar o comportamento (e o consumo) do motor, e a era do veneno clássico, dos carburadores Quadrijet e de tantos outros truques começava a terminar.

Só que a história não acaba aqui! No início dos 1990 tomava força também, no mundo todo, uma outra revolução: a do software livre e aberto. Programadores de computador, cientistas da computação, hobbyistas e entusiastas chegavam à conclusão de que o código-fonte dos programas não devia ser trancafiado a sete chaves numa catedral, mas sim compartilhado e melhorado de forma cooperativa e distribuída.

Essa cooperação e o livre fluxo de informação levava ao desenvolvimento de programas e sistemas mais robustos, seguros e eficientes. E o que isso tem a ver com carros esportivos ? A resposta é simples: já que o software domina o seu carro, domine o software e você vai conseguir um “veneno” que de virtual não tem nada!

Provavelmente o exemplo mais famoso disso é a MegaSquirt, um sistema completo de injeção eletrônica, com todos os sensores e um microprocessador de 8 ou 16 bits que controla os bicos injetores e ignição das velas, baseado em software livre. A Mega Squirt é comprada pelo correio, aos pouquinhos, montada nos mais diferentes tipos de carros, e configurada de diversas formas conforme os objetivos da preparação, na melhor tradição DIY (Do It Yourself, “faça você mesmo”):

Componentes da MegaSquirt

(Foto: Marcelo Garcia)

Para “conversar” com a MegaSquirt e fornecer uma interface para o piloto / mecânico / programador / usuário, usa-se um outro software livre, o MegaTunix, originalmente desenvolvido para o Linux e hoje disponível em diversos sistemas operacionais, incluindo o Windows.

Uma das funções mais divertidas do MegaTunix é emular os caríssimos “relógios autometer” (mostradores incluindo conta-giros, termômetros, razão ar/combustível, etc.): tudo é mostrado no monitor de um notebook ou palmtop, e o usuário pode definir exatamente qual o visual ele quer.

MegaTunix / MegaSquirt

MegaTunix rodando em notebook conectado à MegaSquirt

(Foto: Marcelo Garcia)

E é a flexibilidade do código aberto que permite que sistemas assim sejam tão interessantes. O Marcelo Garcia, que forneceu fotos e consultoria para esse artigo, dá um exemplo da liberdade a que se tem acesso: ele conta que é possível, usando bastante engenhosidade, um fogão, multímetro e outros truques, atualizar o firmware da MegaSquirt para que ela usasse sensores de temperatura de qualquer carro em qualquer motor. Uma mão na roda para quem tem carros antigos (dos quais não se encontram mais peças originais) ou exóticos (cujas peças custam uma fortuna).

Calibrando sensores de temperatura no fogão

Calibrando sensores de temperatura no fogão

(Foto: Marcelo Garcia)

É claro que há limites para o que é possível fazer com software; nem o hacker mais brilhante do mundo vai fazer seu Uninho 1.0 rodar 25 km/l ou andar junto com o Opalão seis cilindros do seu tio. Mas saber que o “veneno” feito-em-casa ainda existe apesar de todas as inovações tecnológicas das últimas décadas é muito, muito bacana – e dá um outro sentido à expressão computador de bordo!

Automação, Desenvolvimento, Inovação, Processamento de Sinais 8 Comentários

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

Groovy, outro sabor na JVM

(Nota do editor: Ainda na série “try a little help from my friends”, a contribuição do nosso amigo Wilson Freitas)

Desde que comecei a trabalhar com linguagens fortemente tipadas, passei a tratar tipagem estática como um dogma. Simplemente não fazia sentido usar uma linguagem que não verificasse os tipos em tempo de compilação. Com o tempo algumas linguagens começaram a despontar na mídia: Ruby e Python são duas que despertaram minha curiosidade. Mas a enorme inércia de anos e anos trabalhando na plataforma Java tratou de matar minha vontade de aprender (mais) uma linguagem de programação.

Quando falo de anos trabalhando com Java, não estou me referindo apenas à linguagem, mas a todo o mundaréu de frameworks e especificações tais como Hibernate, Struts, Spring, Jakarta*, EJB, JNDI, JMS, e mais trocentas mil coisas que não cabem neste post. É muito difícil para um profissional abrir mão de toda essa parafernália que gastou anos aprendendo pra começar a trabalhar com uma linguagem completamente nova, tendo que descobrir como fazer aquelas coisas que em Java estão “na ponta da língua”.

Então, um belo dia eu vi um artigo qualquer sobre uma tal de Groovy. A princípio achei que era mais uma linguagem: “putz, pra que o povo inventa tanta linguagem!”, mas algumas coisas me chamaram a atenção:

  • Assim como Ruby, Groovy é uma linguagem dinâmica que permite malabarismos impensáveis em Java.
  • Groovy tem um interpretador que gera Java byte code sob demanda, que em seguida é executado por uma JVM comum, o que permite criar scripts que podem ser executados diretamente na linha de comando.
  • Groovy é um “sabor” de Java. A sintaxe é muito parecida, o que a torna muito fácil para quem já está acostumado com o velho Java.
  • Como no final das contas tudo é byte code, classes Java podem ser instanciadas em código Groovy e vice versa, ou seja, todos os milhares de trecos que já foram escritos em Java podem ser usados dentro de código Groovy.

Estas características do Groovy me convenceram que valia a pena estudar a linguagem, que vem sendo a minha porta de entrada para o paradigma de linguagens dinâmicas. Ainda não estou usando o Groovy no desenvolvimento em si, mas como uma ferramenta de apoio a algumas tarefas do dia a dia, como processamento de arquivos em lote por exemplo.

Não vou alongar este post enumerando as features do Groovy, mesmo porque elas podem ser facilmente encontradas no site oficial, vou me limitar a mostrar dois trechos de código, um em Groovy e outro em Java, que executam a mesma tarefa, que é aplicar um filtro uma lista de mapas, gerando uma segunda lista com os itens filtrados.

código JAVA

import java.util.*;

public class ExemploJava {

public static void main(String[] args) {
  new ExemploJava().rodarExemplo();
}

public void rodarExemplo(){
  List<Map<String, Object>> personagensLost =
  new ArrayList<Map<String,Object>>();

  personagensLost.add(obterPersonagem("Kate", 28));
  personagensLost.add(obterPersonagem("Jack", 38));
  personagensLost.add(obterPersonagem("Desmond", 39));
  personagensLost.add(obterPersonagem("Hurley", 27));
  personagensLost.add(obterPersonagem("Locke", 50));
  personagensLost.add(obterPersonagem("Walt", 12));

  List<Map<String, Object>> personagensFitrados =
  new ArrayList<Map<String,Object>>();
  for (Map<String, Object> personagem : personagensLost) {
   Integer idade = (Integer)personagem.get("idade");
   if(idade >= 20 && idade <= 30){
    personagensFitrados.add(personagem);
    System.out.println(String.format(
     "Personagem [%s] filtrado",
     personagem.get("nome")));
   }
  }
 }

private Map<String, Object> obterPersonagem(String nome, Integer idade) {
  Map<String, Object> mapa = new HashMap<String, Object>();
  mapa.put("nome", nome);
  mapa.put("idade", idade);
  return mapa;
 }
}

e o código equivalente Groovy

def personagensLost = [
 [nome:"Kate", idade:28]
 ,[nome:"Jack", idade:38]
 ,[nome:"Desmond", idade:39]
 ,[nome:"Hurley", idade:27]
 ,[nome:"Locke", idade:50]
 ,[nome:"Walt", idade:12]
]

def personagensFiltrados =
 personagensLost.findAll{ (20..30).contains(it.idade) }

personagensFiltrados.each {
  println "Personagem [${it.nome}] filtrado"
}

Ao comparar as duas versões desse programa, o que mais me chama a atenção não é a diferença de linhas de código, mas sim a clareza do Groovy em comparação com o Java. O fato de listas e mapas serem construções nativas da linguagem tornam as tarefas relacionadas a estas estruturas de dados muito mais simples, e o código mais inteligível.

Obviamente eu poderia usar uma lib como commons collections para filtrar os elementos da lista na versão Java, mas minha idéia aqui é comparar as linguagens usando apenas as APIs comuns, incluídas com o development kit padrão. Eu inclusive criei um método privado para reduzir o volume de código Java, mas mesmo assim, a diferença de linhas de código é grande. Não significa que isso vai ocorrer para todos os casos, nem significa que Groovy Rocks e Java Sucks. O que quero mostrar é que o Groovy é uma ferramenta extremamente útil para profissionais proficientes em Java que querem enveredar pelo mundo das linguagens dinâmicas, sem ter que abrir mão do SimpleDateFormat quando ele for necessário.

Wilson Freitas é arquiteto de sistemas com 12 anos de experiência em desenvolvimento de software. Atualmente trabalha na Vetta Technologies. Bacharel em Ciência da Computação pela UFBA.

Desenvolvimento 1 Comentário

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

“Serve o vinho celeste, Ganymede”

Jupiter: …”Pour forth heaven’s wine, Idaean Ganymede, And let it fill the Daedal cups like fire.” Percy Bysshe Shelley, Prometheus Unbound

Na mitologia grega, Ganimedes era um príncipe troiano, filho de Tros, cuja beleza arrebatou Zeus (ou Júpiter na mitologia romana) de tal forma que ele mandou uma águia (ou se transformou em uma, dependendo da versão) para raptá-lo e levá-lo para o Olimpo. Lá, tornou-se um dos amantes de Zeus e copeiro dos deuses. Ganimedes também é a maior lua de Júpiter e a maior do sistema solar e foi a terceira descoberta por Galileu Galilei.

Agora, além desses significados, Ganymede (Ganimedes em inglês) também denomina a nova versão anual dos projetos da Eclipse Foundation lançada ontem, dia 25 de junho. Precedida por Europa e Callisto, ela é uma coleção de 23 projetos distintos, cujas novas versões são lançadas de forma coordenada, para evitar incompatibilidades entre eles e facilitar a vida dos usuários.

Apesar do Eclipse poder ser usado para o desenvolvimento em C, C++, Ruby e Python, o lançamento dessa nova versão é particularmente relevante para a comunidade de desenvolvimento Java, posto que o Eclipse tornou-se uma das IDEs mais utilizadas pelos desenvolvedores dessa linguagem. Algumas mudanças mais visíveis estão na IDE, como melhorias na área de assistência de contexto (as teclas Ctrl+Espaço), novos tipos de refactoring, uma nova interface para atualização de plugins, dentre outras novidades além de correções de bugs da versão anterior. Porém, há atualizações igualmente interessantes em outras áreas, como as novas versões da ferramenta de relatório BIRT e do Mylyn, um plugin de interface focada em tarefas (task-focused interface) e que faz integração entre a IDE e ferramentas de rastreamento de issues como o Bugzilla e o Trac, e novas adições como o Rich Ajax Platform (RAP), que permite a construção de aplicações Web baseadas em AJAX usando o mesmo modelo de desenvolvimento de aplicações RCP. Porém, nem tudo são flores: o suporte nativo ao sistema de controle de versão Subversion, outra adição bastante esperada, não está totalmente “transparente” como o do CVS. Para ativá-lo, é necessário que o usuário faça o download de componentes localizados em servidores fora da Eclipse Foundation, sendo que um deles possui versão compilada apenas para Win32 (no caso o conector JavaHL).

Para aqueles que querem instalar a nova versão, basta visitar o site do Eclipse Ganymede, onde também se encontra a lista com as mudanças ocorridas. E “deixa-o encher as taças como fogo”. :-D

Paulo Ferreira de Moura Junior, é arquiteto de sistemas com passagem em empresas como a Borland do Brasil e Vetta Technologies. Bacharel em Ciência da Computação pela UFMG, trabalha atualmente na Geolabs.

Desenvolvimento 0 Comentários

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

E o anti-iPhone?

E a Apple anunciou o iPhone 3G, baixou o preço de compra (mas a AT&T, que tem exclusividade nos EUA, aumento o preço dos planos, então no balanço ficou mais caro) e diz que fechou com parceiros em 70 países. A Claro vai vender o iPhone 3G no Brasil até o fim do ano. Ainda não se sabe quanto vai custar, se vem com fidelização obrigatória até a terceira geração e outros detalhes. Mas os viciados em gadgets estão em polvorosa. E tem muita gente de olho nas possibilidades de desenvolver software para o iPhone. Não é à toa. É um aparelho com potencial revolucionário, e já tem até fundo de capital de risco dedicado exclusivamente a financiar empresas que desenvolvam para o iPhone. O nome? iFund, claro…

Há quem diga que até o fim do ano que vem a Apple deve vender 15 milhões de iPhones no mundo todo. Não é pouco, mas é menos de 1.5% do número de telefones celulares vendidos por ano no mundo. Em 2007, foram vendidos 1.15 bilhões de telefones. Pode ser revolucionário com 1.5% de market share? Claro que pode, afinal é um produto high end e que atrai early adopters de tecnologia.

Mas esses números mostram uma outra possibilidade. De acordo com a venerável The Economist, ainda esse ano teremos mais de 3.3 bilhões de usuários de telefonia celular no mundo. Ou seja, mais da metade da população do mundo terá um celular. A expectativa da Portio, uma empresa britânica especializada em pesquisa de mercado celular e wireless, é que a penetração chegue a 75% da população mundial até 2011. Sabe aquela história que até servente de pedreiro tem celular hoje em dia? Pois é, daqui a pouco os serventes de pedreiro da África também vão ter.

Claro que a imensa maioria desses usuários está na chamada “base da pirâmide”. Gente pobre, pobre mesmo, com o aparelho mais barato possível e plano pré-pago. A inclusão dessa numerosíssima base da pirâmide no mercado de consumo é um dos grandes desafios de estratégia corporativa e de marketing desse começo de século, e os celulares mostram algumas idéias interessantes de como isso pode acontecer.

Um exemplo que eu adoro é o M-PESA, desenvolvido pela Vodafone e pela Safaricom, uma operadora no Kênia. É um sistema simples de mobile banking, no qual você transfere dinheiro via SMS. Sistemas de pagamento via celular como o Oi Paggo estão se popularizando no Brasil, e o Banco do Brasil já tem uma iniciativa de mobile banking. Mas o potencial transformador do M-PESA é que ele funciona com quem não tem conta no banco. Com quem é pobre e excluído demais pra isso.

Uma combinação óbvia de mobile banking e base da pirâmide é usar mobile banking para microcrédito. Reduz burocracia, permite uma dispersão maior dos fundos, e tem um mecanismo interessante de incentivo ao pagamento — pode-se deduzir uma fração de cada recarga do plano pré-pago feita pelo devedor. Se ele não pagar o empréstimo, o celular é bloqueado.

Essa é só uma possibilidade. Eu acho que, embora o iPhone seja um produto interessante e com grande potencial para inovação, o pessoal que pensa em criar startups devia olhar também pra base da pirâmide. É um mercado grande demais e, finalmente, os estrategistas corporativos estão inventando maneiras para deixar de ignorá-lo.

Desenvolvimento, Inovação, Mobile 5 Comentários

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

“Mas pra quê serve esse checklist, mesmo?”

Faz um certo tempo que li um artigo muito interessante do Jason Cohen no CM Crossroads com o título “Checklists – You build me up just to knock me down”. Resumidamente, o autor trata da construção de checklists de revisão de código mais eficientes e para isso ele cita algumas “regras do dedão”, como:

  • 10 itens no máximo, porque mais do que isso atrapalha e torna o preenchimento cansativo para o revisor. Para ratificar esse valor, ele cita George Miller [1], autor do famoso estudo sobre a capacidade cognitiva humana de processamento de informação que propõe como limite sete mais ou menos dois.
  • Nada de itens genéricos ou óbvios como “o código faz o que é esperado” ou “o código está legível”, pois a revisão é feita justamente para encontrar esse tipo de problema.
  • Nenhum item que possa ser detectado de forma automática via ferramentas como PMD, FindBugs, Checkstyle, dentre outras.
  • Verificar coisas fáceis de esquecer, como fechamento de conexões de banco.
  • Construir o checklist de forma empírica, com os erros mais freqüentes da equipe para uma determinada tecnologia.
  • Sempre atualizar o checklist e remover os itens que não são mais relevantes.

Apesar de tratar de revisão de código, essas dicas podem ser empregadas em outros checklists, como de revisão de modelo de arquitetura, de especificação de caso de uso, plano de projeto, etc. Porém, uma coisa que me chamou a atenção no artigo foi algo não abordado por ele: a função do checklist. Qual é a utilidade daqueles papéis ou planilhas que, em muitas vezes, são preenchidos de forma “automática” e sem muita atenção?

A primeira e mais óbvia é de guia. Como não se pode contar com o “bom-senso” do revisor na inspeção do artefato, o checklist serve como um roteiro a ser seguido durante a verificação, uma base de critérios a serem inspecionados que asseguram a qualidade do artefato desenvolvido.

A segunda função, menos evidente, é a de contrato. Ao preencher o checklist, o revisor atesta que os pontos citados foram verificados e que o artefato está de acordo com o padrão estabelecido. Essa função pode não ser muito clara em grande parte das inspeções, mas ela fica evidente em “pré-verificações”, ou seja, naquelas em que o revisor é o próprio autor do artefato. Recordo-me de um checklist de término de implementação, utilizado em um dos projetos no qual trabalhei, e que funcionava da seguinte forma:

  • ao final da implementação de um caso de uso, o desenvolvedor preenchia um checklist contendo algumas verificações a serem feitas no caso de uso, como se o fluxo principal era seguido corretamente, se não havia mensagens sem tradução na interface, se os botões funcionavam corretamente, dentre outras;
  • se o desenvolvedor detectasse algum problema, ele retornava à codificação para corrigir o problema encontrado.
  • se nenhum dos problema listados fosse encontrado, o desenvolvedor entregava o checklist preenchido para o testador, atestando que o código estava pronto para ser testado;
  • o testador verificava novamente os itens do checklist e se aparece alguma não-conformidade, um bug era criado na ferramenta de controle de issues e o desenvolvedor era “amigavelmente advertido” pelo gerente do projeto. :-D

Problemas encontrados pelo testador em um dos itens do checklist eram como uma quebra de contrato entre o desenvolvedor e o testador, passível de retaliação. Lembro-me que antes desse processo ser implementado, os testadores reclamavam do grande volume de erros “bobos” encontrados durante os testes; depois do checklist, o número desses casos caiu sensivelmente (ah, as maravilhas do behaviorismo… :-D)

A terceira, mais sutil ainda, é a de evidência. Durante o processo de certificação de CMMI nível 3 da Vetta Technologies, os checklists de inspeção de código e de verificação de artefatos serviram não só como evidência de que esses procedimentos eram aplicados nos projetos mas também como comprovação que eram feitos de maneira uniforme, definida e documentada. Ou seja, algo que fazíamos de uma forma praticamente natural (e que muitos encaravam como apenas uma mera formalidade) foi de grande utilidade nesse processo.

Sendo assim, da próxima vez que for preencher um checklist, pense no que está fazendo: dependendo da função, a “mera formalidade” pode acabar em um belo “puxão de orelha”. :-D

[1] George Miller também é conhecido por ser um dos responsáveis pela criação do Wordnet, banco de dados lexical e semântico da língua inglesa bastante usado em projetos de processamento natural de linguagem e correlatos.

Paulo Ferreira de Moura Junior, bacharel em Ciência da Computação pela UFMG, é arquiteto e líder técnico da Vetta Technologies.

Desenvolvimento 0 Comentários

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

O fenômeno Twitter

Twitter é a mais nova revolução da Web 2.0. Não tão nova assim em tempo de internet, mas explosiva do mesmo jeito. É uma combinação de rede social e micro-blogging.

Você pode escrever micro-posts (o limite é 140 caracteres). Seus amigos recebem seus posts e podem respondê-los. É altamente viciante (um motivo pelo qual optei por me abster). Você pode enviar posts pela interface web, por aplicações desktop, ou via SMS. A opção de postar pelo celular e o limite de tamanho dos posts encorajam uma comunicação frequente e espontânea, parecida com a de mensagens instantâneas como MSN e Google Talk.

Um diferencial é que seus posts também vão (se você permitir, claro) para uma grande linha do tempo pública. Quando os posts de todo mundo são agregados dessa forma, muitas vezes surge um Zeitgeist instantâneo: tópicos que dominam a atenção coletiva dos Twitters em um dado momento.

No bom espírito Web 2.0, o Twitter disponibiliza uma bela API. Essa API, combinada com a linha do tempo pública, levou a diversas aplicações divertidas. Por exemplo, o Twitterverse é uma tag cloud que mostra as palavras mais frequentes na linha do tempo na última hora. Já o TwitterBuzz mostra os sites mais linkados na linha do tempo. E tem usos mais especializados. O Politweets mede a popularidade dos pré-candidatos a presidente dos EUA com base no número de posts (também chamados de tweets). E os candidatos mais antenados com a internet usam o Twitter para enviar propaganda.

O Twitter também tem utilidade pública. Os bombeiros de Los Angeles começaram a usar o Twitter para postar alertas e coordenar atividades via celular no combate aos incêndios florestais de outubro do ano passado, e ainda usam o Twitter até hoje. Outra aplicação legal (essa eu quero aqui pro Brasil com urgência) é o Commuter Feed, que recebe mensagens de motoristas e posta informações em tempo real sobre o trânsito em diversas áreas metropolitanas dos EUA.

Ah, e o Twitter é escrito em Ruby on Rails ;-)

Desenvolvimento, Inovação, Mobile, Web 2.0 4 Comentários

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

Escalabilidade transparente

Escalabilidade é um conceito importante em qualquer sistema web, embora eu ache que às vezes as pessoas se preocupam demais com isso. A grande maioria das aplicações web simplesmente não precisam escalar muito. Existe, então, um trade-off entre tempo de desenvolvimento e o esforço extra necessário para planejar e implementar sua arquitetura de forma a escalar da melhor maneira possível. Quando você não precisa lidar com enormes volumes de dados e usuários simultâneos, muitas vezes a decisão correta, do ponto de vista de negócio, é minimizar o tempo de desenvolvimento e arcar com algum custo extra de hardware caso preciso. Hardware que fica mais barato a cada dia.

Existem outras alternativas, que tentam garantir que sua aplicação é escalável sem cobrar um preço caro em termos de tempo e esforço de desenvolvimento. Um ponto chave é minimizar o compartilhamento de dados entre componentes da sua aplicação. Se você não compartilha nada, fica mais fácil escalar. Esse modelo, chamado de “shared nothing”, é encorajado por diversos frameworks para desenvolvimento web, e é praticamente obrigatório quando se desenvolve com Ruby on Rails, por exemplo.

Quando sua aplicação segue o modelo “shared nothing”, você pode obter escalabilidade simplesmente usando os serviços da Amazon. Precisa de mais servidores web? Adicione instâncias à sua conta da Elastic Computing Cloud. Precisa de mais servidores de banco? A mesma coisa, mas as instâncias são configuradas de outra forma (que você pode definir, através de uma imagem de máquina virtual). Espaço em disco? Sem problema. Tudo sobe e desce de forma quase instantânea. Um grande avanço comparado ao processo tradicional de estimar suas necessidades de hardware e comprar os servidores com alguma antecedência — ou sair correndo para apagar o incêndio quando ele estoura.

Pois agora tem gente que acha que mesmo serviços como os da Amazon são muito complicados. Estão querendo transformar escalabilidade em algo totalmente transparente para o desenvolvedor. Um exemplo disso é a Heroku, que lançou recentemente um serviço de escalabilidade automática. Você registra sua aplicação (Ruby on Rails) com eles e eles cuidam de escalar usando os serviços da Amazon. Você não precisa se preocupar com a monitoração dos seus nodos de processamento, decidir quando adicionar ou remover nodos, etc. Você pode até desenvolver sua aplicação usando um IDE web que eles oferecem.

Claro que um serviço desses tem suas desvantagens. Em primeiro lugar, você perde em flexibilidade: vai ter que usar as versões de Ruby, Rails e bibliotecas que a Heroku suporta. Não há como integrar facilmente sua aplicação com sistemas legados. E assim por diante.

Mesmo assim, é mais um grande avanço em uma das tendências-chave por trás da Web 2.0: a redução de barreiras de entrada. Cada vez que um obstáculo técnico ao sucesso de um produto web é removido, fica mais fácil e barato desenvolver novos produtos inovadores. Sob essa ótica, viva a escalabilidade transparente!

Desenvolvimento, Internet, Web 2.0 0 Comentários

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

Ruby On Rails

Quem trabalha com “Desenvolvimento Web” quase certamente já ouviu falar de Ruby On Rails. Assim como muitas tecnologias, RoR (pra encurtar) gerou muito hype nos últimos meses e, consequentemente, uma legião de fanboys que pregam fervorosamente que RoR é a melhor coisa que já inventaram desde o pão-fatiado. :-)

O quê

Mas em que consiste exatamente o tal “Ruby On Rails”? Traduzindo diretamente do site oficial:

Ruby On Rails é um framework web de código aberto que é otimizado para a satisfação do programador e produtividade sustentável. Ele permite que você escreva código elegante ao favorecer convenção ao invés de configuração.

E ainda:

Ruby On Rails é um framework completo para desenvolvimento de aplicações web de acordo com o padrão Model-View-Controller (ou MVC).

Até aí, nenhuma novidade. Antes da popularização de RoR, já existiam diversos outros excelentes frameworks como ASP.NET, a pilha Servlets+JSP+Struts+Hybernate e PHP/Zend, só pra citar alguns. O diferencial de RoR está justamente na adoção da metodologia de desenvolvimento de software “Ágil”, ao focar as funcionalidades do framework nas necessidades diretas dos desenvolvedores e diminuir tanto quanto possível o tempo gasto com instalação e configuração do ambiente.

Por esse motivo, RoR se tornou especialmente popular entre desenvolvedores e empresas que adotam processos semelhantes ao “Extreme Programming”, onde a elaboração rápida de um protótipo e a constante refatoração do código são essenciais. RoR realmente prima nestes casos. Chega a ser assustador a facilidade com que se gera o esqueleto e o protótipo de uma aplicação MVC, ou o número ínfimo de linhas de código que são necessárias para implementar funcionalidades relativamente sofisticadas.

Porquê

Descontando um pouco do exagero típico dos fanboys, é fácil notar com pouco tempo de uso porque Ruby On Rails se popularizou tão depressa.

  • Convenção ao invés de Configuração: Levante a mão quem nunca perdeu pelo menos umas 2 horas de trabalho tentando instalar ou configurar uma aplicação/sistema/etc e descobriu no fim do dia que o problema era um “;”, ou um path errado. Pois é, RoR procura acabar com essa dor-de-cabeça ao eliminar tanto quanto possível os malfadados arquivos de configuração através da adoção de uma série de convenções que permite integrar as diferenças partes do framework sem praticamente nenhuma intervenção direta do desenvolvedor.As convenções englobam todo tipo de aspecto de uma aplicação web: o nome dos modelos e tabelas relacionais associadas; o nome da colunas das tabelas que constituem chaves primárias e estrangeiras; o nome dos arquivos e das classes que implementam cada camada da estrutura MVC; o nome e identificador dos campos HTML e diversas outras.
  • ActiveRecord: Active record é um design pattern utilizado para acessar bancos de dados e fazer o mapeamento Objeto-Relacional. O padrão em si é bem mais antigo do que RoR, mas a implementação utilizada em RoR em específico prima pela qualidade e é um dos pontos fortes e mais badalados do framework. A extensa utilização de instrospeção, tanto do lado da estrutura relacional, quanto da parte das classes e objetos torna praticamente desnecessário escrever mais do que meia dúzia de linhas de código para se fazer o mapeamento de uma classe/tabela.
  • ActionView: Da mesma forma que o módulo ActiveRecord é responsável pela implementação dos modelos, ActionView é o módulo responsável pela implementação das visões. O diferencial está no fato de este módulo ser fortemente influenciado pela metodologia ágil: quase todas as funcionalidades tipicamente utilizadas para construção de uma interface web podem ser adicionadas através de uma API concisa e intuitiva. Mesmo as tendências mais recentes das aplicações Web modernas — como Javascript, DHTML e AJAX — estão fortementes integradas ao framework. Em RoR, usa-se apenas uma linha de código para adicionar funcionalidades relativamente complexas como “atualizar uma tabela/list assincronamente” ou “adicionar um campo de texto com auto-sugestão” (no estilo Google Suggest))
  • Plugins: Outra grande vantagem de Ruby On Rails é sua extensibilidade. Devido à sua crescente popularidade, existem hoje literalmente centenas de plugins (normalmente gratuitos) disponíveis para os desenvolvedores incrementarem suas aplicações conforme as necessidades individuais de cada projeto — permitindo assim que uma gama enorme de problemas sejam rapidamente resolvidos sem necessariamente tornar o core do framework demasiadamente inchado. Mas cuidado: em alguns casos, é preciso ficar atento para não se perder mais tempo escolhendo o melhor plugin que implementa uma deterinada funcionalidade do que efetivamente instalando e utilizando o plugin. :-)
  • Ruby: Flamewars discutindo qual a melhor linguagem são quase tão antigas quanto a própria computação — portanto não vou me alongar demasiadamente nesse tópico — mas é inegável que parte da atratividade de RoR advém da linguagem Ruby. Pra quem ainda não conhece, sugiro o tutorial rápido do site oficial, ou ainda o divertidíssimo“Guia Pungente”, por “Why The Lucky Stiff”.

Por que não

Nenhuma boa análise técnica estaria completa sem uma seção de “Contras”, e esse post não poderia ser diferente.

  • Performance: Um dos compromissos que precisam ser feitos para se tirar proveito da elegância e agilidade de se utilizar uma linguagem como Ruby é o desempenho. Por ser uma linguagem dinamicamente tipada que executa sobre uma interpretador (pra lá de ineficiente, diga-se de passagem), Ruby On Rails é inegavelmente um framework com overhead alto. Muita gente vai argumentar que baixa performance não é tão crítico se sua arquitetura tem boa escalabilidade, e outros ainda irão citar diversas técnicas para minimizar esse overhead, mas ainda assim, em alguns casos a recomendação é deixar de usar justamente as funcionalidades que tornam o framework interessante.Por outro lado, as comunidades por trás de Ruby e RoR estão cientes desse problema e tem trabalhado para atenuá-lo. A versão 2.0 de RoR, por exemplo, já apresenta significantes melhorias, e a próxima grande revisão da linguagem Ruby que deve ser lançada ainda nessa década também promete ganhos substanciais de performance, graças à utilização de um nova máquina virtual.
  • Código legado: Uma das máximas de RoR — “Convenção ao invés de configuração” — perde seu appeal quando consideramos sistemas legados. Nesses casos, é provável que sua base de dados ou suas classes existentes não tenham adotado as mesmas convenções utilizadas por RoR. Com isso, é necessário adicionar diversas diretrizes no código para sobrescrever os valores e padrões utilizados pelas tais convenções. Não chega a ser a mesma dor-de-cabeça de se editar um “hibernate.cfg.xml” ou um “web.xml”, mas é possível que você acabe sendo forçado a escrever alguns trechos de [gasp!] SQL. :-)
  • Documentação: Algumas tecnologias promissoras perdem momento devido à carência de documentação. Ruby On Rails sofre do problema inverso: excesso de documentação. Hoje em dia é natural utilizar a Internet para buscar por trechos de código, recomendações, receitas ou (no caso de RoR) plugins para se solucionar um problema específico ou implementar corretamente uma funcionalidade. O problema é que, frequentemente, a documentação ou plugin encontrados estão defasados por terem sido escritos/implementados com foco em uma versão do framework que já está deprecada. Como o desenvolvimento de RoR é muito dinâmico — a versão 1.0 foi lançada em Dez/05; a versão 1.1 em Mar/06; a 1.2 em Jan/07; e a 2.0 em Dez/07 — e não existem garantias de compatibilidade, muitas vezes torna-se difícil encontrar a solução correta para a versão específica do framework que você está utilizando.

Pra finalizar

Se você se é desenvolvedor Web, mora em Belo Horizonte, se interessou por Ruby On Rails e gostaria de saber mais a respeito, o Instituto Turing está oferencendo um curso intensivo à partir do dia 14 de abril. Para maiores informações, mande e-mail para cursos@institutoturing.org.

Desenvolvimento, Internet, Web 2.0 3 Comentários

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

Uso compulsivo de memória

As vezes escutamos afirmações do tipo: “Vazamentos de memória são comuns em linguagens baixo nível. Coisas do passado. Linguagens modernas estão livres desse pesadelo.” Quem acredita nisso também deve acreditar em coelhinho da Páscoa, Papai Noel e certamente em “almoço grátis”. Linguagens “modernas” que utilizam gerenciamento próprio do espaço de memória no processo (como Java e .Net) também podem produzir vazamentos de memória ou sofrer com o mau uso da memória. Claro que não tão frequentes quanto em C ou C++, mas essas linguagens também permitem a construção de sistemas ou componentes com um consumo de memória sempre crescente, contra a vontade do desenvolvedor.

Lembro-me de que nos longínquos anos 90, quando falavam de Java a performance era o ponto mais questionado. Com o passar do tempo e a evolução do hardware, esse ponto foi deixado de lado. Hoje o comentário sobre sistemas em Java mais comum é que “consomem muita memória”. Mas algumas vezes, isso apenas mascara para o cliente o verdadeiro problema: vazamento de memória.

Durante minhas experiências profissionais já vi soluções brilhantes (e outras nem tanto) para vazamentos de memória. Algumas específicas para uma ou outra arquitetura ou ambiente, outras genéricas (de uso geral). Fazendo uma analogia com o mundo palpável, vamos supor que um vazamento de memória seja uma torneira gotejando sobre um balde. Se o balde entornar, o cliente pode ficar muito bravo. Vamos então a alguns exemplos de soluções para nossa torneira:

  • Aumento de memória: No mundo das grandes corporações, a primeira e mais comum solução é aumentar o tamanho do balde! Isso é fácil, barato, e de rápida implementação e de resultado instantâneo: O que demorava 1 semana, agora demora 1 mês;
  • Restart da aplicação: Outra solução comum, quase tanto quanto a anterior nas grandes empresas. Durante a noite, quando geralmente o gotejar é mais lento, você pega o balde, corre e joga a água fora em um lugar apropriado. Um ponto importante é que tem que ser rápido o suficiente pra fazer o trabalho entre uma gota e outra. Caso contrário algumas gotas caem no chão. Mas o cliente pode nem perceber o piso molhado.
  • Bloquear o acesso ao módulo: se não for uma torneira útil, você pode simplesmente fechar o registro para esta tubulação. Se alguém precisar da torneira, que use a de outro lugar.
  • Liberação de memória logo após a alocação: Isso só é possível em alguns ambientes e sistemas (por exemplo, os feitos em C). É difícil de imaginar, mas existe! Trocamos o balde por cachorro, treinado, jeitoso e delicado (por exemplo um dog alemão) pra beber as gotas de água que goteja. O cão pode ficar ali durante horas. E funciona bem. Mas ele vai sair do lugar, pra realizar outras necessidades, ou porque deu vontade mesmo. Que a água vai pingar no chão vai, mas ninguém saberá exatamente quando nem quanto.
  • Resolver o vazamento de memória: Essa é a última solução. Muita gente acredita que a hora do bombeiro é cara, outros acham que a torneira já está muito velha mesmo, e a solução seria trocar todo o encanamento. As vezes a solução não compensa mesmo. Mas algumas vezes a torneira está vazando por um motivo simples : não foi fechada direito. Outros casos podem ser mais complicados: seu mecanismo interno está estragado, foi montada com peças de má qualidade ou foi montada com peças de boa qualidade, mas foi montada de forma errada.

Para resolver vazamentos ou mau uso de memória uma ferramenta de qualidade é indispensável. Depois de entender o fluxo de execução do sistema ou componente, a utilização de ferramentas de profiling nos dá o “mapa da mina”. Dentre as existentes, duas que merecem destaque são:

- YourKit: para sistemas desenvolvidos em Java e C#, uma ferramenta de grande utilidade é um profiler como o YourKit, já comentado em um post anterior. O YourKit possui um recurso excelente pra procurar por vazamentos de memória e mesmo analisar sua utilização após o start: é possível criar snapshots da memória do processo para uma posterior verificação. Sem degradação da performance do sistema, este recurso em algumas situações pode ser usado inclusive no ambiente de produção.

- Valgrind: é a ferramenta indicada para uso em sistemas desenvolvidos em C e C++. Com ele são detectados os pontos onde memória ou objetos alocados e “esquecidos” na memória, e também a distribuição do uso memória pelos objetos e módulos do sistema. Além de vazamentos de memória, é possível detectar um mal uso da memória do sistema. Mas o Valgrind é uma ferramenta pesada, impossível de ser utilizada em ambientes de produção.

Embora algumas vezes a correção do problema não é viável, sua identificação sempre é. Depois da compreensão do funcionamento de um módulo e o uso correto de ferramentas de análise de memória é possível identificar qualquer vazamento de memória. Mas qual decisão tomar com essa informação? Solucionar o problema, utilizar um “ajuste técnico de contorno” ou simplesmente deixar como está ? Isso já é trabalho da gerência.

Desenvolvimento, Memória 1 Comentário

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

« Previous Entries