Arquivo da categoria: Programação

Vale a pena fazer o curso de machine learning do Coursera?

As plataformas de cursos online surgiram nos últimos anos para realizar o sonho de muita gente: poder assistir aulas formuladas pelas melhores universidades do mundo sem precisar sair de casa, enquanto come um Doritos e veste apenas uma cueca. Esse não era meu sonho, mas resolvi que deveria experimentar esse conteúdo pelo menos pela experiência.

Aprendizado de máquina é um assunto que me interessa, por isso resolvi me matricular neste curso gratuito do Coursera. Já havia estudado o assunto antes por conta própria através de livros e até usado um pouco da teoria na prática. Além de poder aprender mais algumas coisas e solidificar o que já tinha visto, essa foi a chance de conhecer e avaliar um conteúdo didático criado em Stanford. É o equivalente para um amante de café ter a chance de experimentar de graça aquele café que é considerado um dos melhores do mundo, feito com grãos retirados das fezes de um roedor que não lembro o nome.

Antes de saber se você deveria fazer este curso é uma boa ideia ter uma noção do que é aprendizado de máquina. E acho que a melhor forma de motivar alguém a conhecer melhor o assunto, é ter uma noção de suas aplicações práticas. Usando machine learning você pode criar software que reconhece objetos em imagens, detecta fraudes em operações financeiras, dirige um automóvel ou drone, avalia o crédito de pessoas, avalia a probabilidade de um paciente ter uma doença, prevê que um servidor pode sofrer uma falha, e muitas outras coisas que parecem mágica. Mas conhecendo melhor sobre o assunto você vai ver que essa lista que fiz é bem limitada.

Depois de se interessar pelo curso, sua preocupação pode ser em saber se você precisa ser um campeão de olimpíada de matemática para conseguir acompanhar o curso. Este é um assunto que usa muita matemática, mas o curso foi pensado para alunos que pelo menos consigam ler uma fórmula com somatórias, matriz e vetores. Existem até aulas opcionais com álgebra linear básica para ajudar com os conceitos que vão ser usados durante as aulas. E graças ao professor Andrew Ng, as aulas são muito didáticas a ponto de ele fazer todos os passos de cálculos necessários nos exemplos. Em casos em que seria necessário um conhecimento matemático maior, o professor dá uma explicação sobre a intuição do que está sendo feito, mas não é exigido que o aluno saiba resolver uma derivada ou decompor uma matriz, por exemplo. Mas minha opinião é que tendo uma base mais do que básica sobre cálculo e álgebra linear vai tornar o conteúdo muito mais fácil de assimilar e entender, sem deixar que alguns passos nos algoritmos pareçam ter aparecido por mágica.

Saber programar é um pré-requisito. Os projetos a entregar são programas escritos em Matlab ou Octave. Mas não é necessário conhecer uma dessas linguagens, pois algumas das aulas vão te ensinar o necessário para realizar todas as tarefas. Eu mesmo nunca havia usado essas linguagens. Apesar de não ser muito difícil de aprender, muitas vezes perdi muito tempo por detalhes da linguagem que causavam erros nas minhas tarefas. Mas o fato de que você só precisar programar o principal das tarefas, com o código que cuida de preparar os dados e mostrar resultados já pronto, facilitou e economizou muito meu tempo, considerando que é um curso que muita gente vai fazer no tempo livre. E o sistema de envio das tarefas com correção automática funciona muito bem. Você resolve cada passo do exercício, envia para o sistema e ele te diz se você acertou ou não.

Um ponto muito positivo é que todo o conteúdo, por ser ensinado pela mesma pessoa, tenta seguir mais ou menos a mesma notação do começo ao fim. Isso ajuda muito para comparar os algoritmos. Quando você tenta aprender cada uma dessas coisas por fontes diferentes, você acaba vendo notações diferentes que dependem da preferência do autor. É como tentar entender uma história que teve uma parte contada por uma pessoa e o final contada por outra, mas a que contou o final só se refere aos envolvidos por apelidos que você não conhecia.

O melhor do curso para mim são as ferramentas que ele ensina para que você entenda se sua solução de machine learning está funcionando bem, e o que você pode fazer para melhorá-la. É esse o conhecimento que eu esperaria de alguém que fosse usar esses algoritmos na prática.

Vejo poucos pontos negativos, que são pequenos perto das qualidades do curso. Algo que me incomoda um pouco são as questões que aparecem no meio dos videos. Muitas vezes eles nem estão testando se você entendeu a teoria que está sendo ensinada, mas verificando se você está acordado e prestou atenção na notação que o professor acabou de usar. Outra coisa que me fez falta, que se deve mais ao formato, é não ter um material que possa consultar facilmente depois. É impraticável procurar no meio dos videos algo que você não lembra direito onde viu, por isso recomendo anotar principalmente as dicas que são baseadas na experiência do professor Andrew.

Talvez algumas pessoas possam se sentir incomodadas pela falta de formalidade técnica que o assunto é tratado, mas considerando que aprendizado de máquina é uma área em que os métodos funcionam mesmo sem os matemáticos entenderem muito bem, acho que o conteúdo habilita alguém a se tornar um praticante. Um conhecimento mais formal seria necessário apenas para quem deseja se tornar um pesquisador na áreae nesse caso este curso funcione bem como uma introdução geral.

Por tudo isso digo que vale muito a pena fazer o curso de machine learning oferecido pela Universidade de Stanford pelo Coursera. Valeria a pena mesmo se fosse pago, sendo grátis eu tenho a vontade de visitar meus amigos programadores e obrigá-los a assistir essas aulas.

Anúncios

Como escolher a melhor linguagem de programação para seu projeto

Você tem um novo projeto para começar, e com os ventos de esperança de código novo sem bugs antigos, vem também o peso de tomar uma decisão importante: qual linguagem de programação utilizar? Nesse caso, podemos generalizar a mesma questão para frameworks, bibliotecas e ambientes que você vai utilizar.

Novo projeto

Começando novo projeto

O primeiro impulso natural é partir para uma abordagem quase científica, que começa com a busca por “qual a melhor linguagem de programação” ou ainda “comparação java vs pascal vs resident evil”. A partir daí chegamos a tabelas de comparação, benchmarks, ou simplesmente artigos em defesa desta ou daquela linguagem. O que é ótimo porque podemos aprender com a experiência dos outros.

O próximo passo é misturar essa nova informação com a sua experiência de projetos passados e aulas na faculdade, carregar tudo no seu cérebro e processar levando em conta as seguintes heurísticas:

Linguagens da moda: tome cuidado para não se deixar seduzir pela atual linguagem que está na moda, que todos os “hackers legais” estão usando ou querendo usar. Nada contra usá-las em projetos pequenos, para aprender e descobrir por experiência própria quais seus pontos fortes e fracos, mas muitas dessas modas vêm e vão muito rápido. Imagine a dor de cabeça que vai ser se você precisar montar uma boa equipe que precisa conhecer uma linguagem que quase ninguém domina. E como explicar para seu chefe ou cliente que seu sistema tem um problema que depende de um patch de correção que nunca vai sair, porque o pessoal que mantinha a linguagem de programação que você escolheu resolveu montar uma banda.

Moda

Moda

Conforto: pergunte-se se você e o resto de sua equipe se sentem tranquilos para resolver qualquer problema que vá surgir usando essa linguagem, ou se só de pensar nisso começam a suar frio. A linguagem te faz se sentir o McGyver usando qualquer objeto para desativar uma bomba ou o Mr. Bean se atrapalhando com um guardanapo?

Nível de ajuda externa: se você tem alguma experiência na área, deve ter algumas histórias de bugs misteriosos para contar. Se você precisar de ajuda para resolver algum problema, você consegue encontrar uma solução só de procurar a mensagem de erro no Google? Existe uma comunidade de bons desenvolvedores envolvidos com a linguagem, respondendo sobre dúvidas em fóruns e blogs? Existe alguma empresa que dá suporte a sua empresa mesmo se for final da copa do mundo com show de Elvis Presley (que foi encontrado vivo)?

Equipe: caso você precise aumentar a equipe do projeto, é fácil encontrar mais profissionais que já saibam a linguagem? Ela é fácil de aprender? No geral, os programadores que usam essa linguagem de programação parecem ser espertos ou são do tipo de pessoa que acerta o sorvete na testa?

Equipe

Equipe

Tipo de sistema: algumas linguagens são ótimas para um certo tipo de aplicação e precisam de adaptações horríveis para serem usadas em outros contextos. Mesmo que você ame a linguagem, que seja ela que você gosta de abraçar numa noite fria de inverno, nem sempre vale a pena fazer a coitada se contorcer e se machucar para satisfazer seus desejos mais obscuros (estou treinando para escrever contos eróticos).

Levando tudo isso em consideração você não tem uma garantia de sucesso, porque a linguagem é só uma ferramenta. Mas pode dormir um pouco mais tranquilo, sabendo que você sendo responsável em relação a diversos riscos que muitos aventureiros não levam em consideração.

Mantendo a carreira atualizada mesmo sendo meio preguiçoso

“Você precisa se atualizar”. Este é o conselho de carreira mais repetido e menos discutível depois de “não estrangule seu chefe usando uma corrente feita de clipes”.  E essa cobrança por estar sempre por dentro de todas as tendências é muito maior em tecnologia. Tecnologia é uma das poucas áreas em que você pode entrar em coma e ao ser despertado descobrir que tudo o que você sabia nem é usado mais no mercado.

Acredito que ninguém se sinta muito motivado a estudar novas tecnologias e aprender novas habilidades só porque o mercado de trabalho fica repetindo isso em nossas orelhas. Algumas pessoas se motivam sozinhas a fazer isso, estão sempre fuçando nos frameworks da moda para fazer novos projetinhos, porque realmente gostam de lidar com tecnologias novas e ver o que podem fazer com seus novos brinquedos. Bom, eu não sou esse tipo de pessoa. E conheço muitas pessoas que gostam menos ainda de aprender algo novo. Como posso me manter motivado a me atualizar e não deixar minha carreira em TI entrar em coma?

“Estou super atualizado, já fiz os módulos 1 e 2 de datilografia.”

Torne seu trabalho mais fácil.

Sempre que estou aprendendo algo novo, meu principal objetivo é encontrar alguma ferramenta que transforme uma tarefa que eu levaria semanas e ficaria maluco em um passatempo agradável que leva alguns dias ou horas (ok, é um exagero, mas esse é meu objetivo). Ferramentas, frameworks, bibliotecas, linguagens são criadas para resolver problemas que as pessoas reconhecem que existem e se repetem.

Exercite outras partes de seu cérebro

Por mais que muitas pessoas não enxerguem, desenvolver software é uma disciplina que envolve muita criatividade. Criatividade para resolver problemas, para modelar soluções. E para alimentar sua criatividade você precisa de ideias diferentes, não ficar no marasmo de apertar sempre os mesmos botões. Uma das formas de se expor a ideias diferentes em nossa area é conhecer outros projetos, novas tecnologias. Às vezes o cara que projetou essa nova linguagem de programação que todos estão falando fez algo que ia te facilitar a resolver aquele problema que você quebrou a cabeça para resolver mais ou menos. E isso pode acontecer mesmo que você não vá usar essa nova linguagem.

Mantenha o motor do aprendizado aquecido

Se você parou de estudar por mais de um mês, deve saber como é difícil tentar aprender qualquer coisa nova. É como se a parte de nosso cérebro responsável pelo aprendizado funcionasse como um motor de carro velho. Você precisa colocar ele para funcionar senão ele nunca mais liga e você precisa vender ele no ferro velho (o motor do carro velho, não o cérebro). Por isso acho bom não parar nunca, com o medo de acabar parando para sempre.

Se esses itens não te motivam a continuar aprendendo, lembre-se também que você pode parar de receber o cheque no final do mês se não se atualizar, o que deve ser a pior forma de aprender uma lição.

Grails & Groovy: primeiras impressões

A maior certeza que você pode ter, se for seguir carreira como programador, é que você vai usar muitos frameworks e linguagens de programação diferentes. Alguns você vai odiar de coração, mas vai ser obrigado a usar. E quando um colega seu citar o nome dessa ferramenta, você provavelmente reagirá como se sua mãe tivesse sido xingada. Mas também haverá os frameworks e linguagens que você vai odiar menos, e que talvez, por comparação com o que você já usou no passado, você chegue até a gostar.

COBOL: não gostei

COBOL: não gostei

Alguns, como eu, nunca ficam muito satisfeitos e sempre estão a procura da solução perfeita. A resposta à pergunta mais levantada por quem precisa parir um projeto: “o que vamos usar?” Esses sujeitos estão sempre experimentando coisas novas, procurando alguma solução que não tenha os problemas que as outras tinham, e quem sabe um dia encontrar o cálice sagrado das soluções de sistemas. E eu TALVEZ tenha encontrado algo bem próximo disso e que por acaso tem o nome de Grails (se você não entendeu está na hora de entrar num curso de inglês – aí CCAA, olha a oportunidade que vocês perderam de fazer merchandising no blog).

Não vou dar o veredito final porque ainda usei muito pouco Grails, em um projeto pequeno, em que um dos maiores objetivos era aprender Grails e Groovy. Mas para vocês terem uma idéia, o projeto envolvia integração com uma interface Flex (o RIA da Adobe) e usava JMS (o padrão de Mensageria Java). E mesmo assim, escrevi muito pouco código, quase nada de configuração e nenhum SQL (sim, o projeto tem banco de dados). Acho que o fato de eu ter tido pouco trabalho fazendo isto já mostra um pouco o porquê de eu ter achado o framework tão bom.

Grails: o logotipo foi o que menos gostei.

Grails: o logotipo foi o que menos gostei.

Outro motivo para não bater o martelo é que ainda não parei para aprender Ruby on Rails. Está na minha lista de “coisas a fazer (ou não)”, mas da forma como é aclamado pelos rubistas, deve realmente ser muito bom. Bom, se bem que “Crepúsculo” é aclamado por muita gente e eu não estou a fim de ver um filme que mistura Malhação com vampiros emos. Mas o fato de Grails ter sido inspirado em Rails não me permite ignorar sua existência.

Minha experiência com o framework foi curta, mas espero poder usar eventualmente para outras coisas. Por enquanto ainda não usaria para um projeto principal, mas para algo menor não teria dúvidas. Seguem abaixo minhas observações sobre Grails:

  • a linguagem Groovy: não gostava muito de linguagens dinâmicas, mas talvez isto tenha sido por conta do período em que usava PHP. Groovy é uma linguagem muito agradável de usar (pelo menos te garanto que é MUITO mais agradável que Java) e que da mesma forma que Perl, te dá diversas formas de se fazer a mesma coisa. E assim como Ruby, te dá a opção de extender a definição de qualquer classe (como adicionar métodos a uma classe da API padrão por exemplo) e de usar closures (que a grosso modo funciona como os ponteiros para métodos e funções existentes em outras linguagens). Me agrada muito a implementação da linguagem, que te poupa de fazer checagens bobas como verificar se o objeto é nulo, ou concatenação de strings, tornando o código mais legível e mais fácil de escrever.
  • plataforma Java: isto é mais vantajoso para quem já trabalha com Java, mas de certa forma é vantajoso para todos pelo tamanho da comunidade Java. O Grails e o Groovy foram contruídos sobre a plataforma Java. Dessa forma, um código escrito em Java é aceito como código em Groovy, o que pode tornar o aprendizado um pouco mais fácil. Um código escrito em Groovy tem total interoperabilidade com código em Java, permitindo que você tenha um projeto com partes escritas em uma linguagem e partes escritas na outra. Tanto que você pode utilizar qualquer coisa que você já podia utilizar em Java (bibliotecas, frameworks, etc). Isso foi aproveitado pelos idealizadores de Grails, pois o framework tem como seus alicerces dois frameworks Java muito populares: Spring e Hibernate.
  • GORM: é o responsável por mapear seus objetos para os registros no banco de dados (daí a sigla ORM – Object-Relational Mapping), e utiliza o Hibernate por baixo do capô. Este é o melhor ORM que já vi, pois de fato torna o trabalho muito mais fácil. Como eu disse, não escrevi uma linha de SQL e também não encostei em nenhum XML de configuração para fazer o GORM funcionar. Utilizar o GORM é basicamente como eu gostaria que fosse utilizar um banco de dados orientado a objetos. Se GORM fosse uma mulher eu casava. Ah, mulher gostosa, claro.
  • plugins: Grails tem uma boa variedade de plugins para extender sua funcionalidade. O que mais me impressionou é a facilidade de se instalar um plugin em um projeto. É tão fácil quanto instalar algo usando apt-get, basta um comando (traduzindo para quem só usa Windows: é fácil pra caralho!). Em um projeto não Grails, normalmente acrescentar uma tecnologia nova, como funcionalidade de web-services ou um motor de busca, sempre gera um certo stress, a ponto de gerentes com mais experiência alocarem um bom tempo na agenda do projeto para a tecnologia ser incorporada sem problemas. Em Grails, você instala o plugin e usa o resto do tempo que seu gerente alocou para ficar pedindo convite para o novo Orkut! SE não fizerem um plugin para isso.
  • ambientes: o framework já vem preparado para rodar sua aplicação nos ambientes de teste, desenvolvimento ou produção, facilitando a configuração para essa divisão por estágios. E não só isso, quando você faz o download do Grails ele já vem com um banco de dados (HSQLDB) e servidor web (Jetty) para que você possa sair escrevendo código sem se preocupar em montar o ambiente na sua máquina.
  • testes: a parte de testes automatizados (tanto unitários quanto funcionais) faz parte do framework, o que faz com que ele reforce o uso dessas boas práticas.

Se você se interessou em aprender mais, a InfoQ tem um livro gratuito (gratuito de verdade) chamado Getting Started with Grails. Para mais conteúdo, eu recomendo um livro não-gratuito chamado Beginning Groovy and Grails: From Novice to Professional. E para trocar experiências, já existe um fórum de Grails e Groovy brasileiro: o Grails Brasil.

Metodologias ágeis X Metodologias tradicionais

Existem infinitas formas de se contruir sistemas de software, e todo mundo que trabalha com isso procura pela galinha dos ovos de ouro, a metodologia perfeita para se construir software perfeito, no menor prazo possível, e que no final clientes e desenvolvedores são felizes para sempre.  É óbvio que isso só existe em contos de fadas. Mas nos corredores de empresas de software e em alguns botecos estranhos você deve ouvir calorosas discussões de defesa sobre a metodologia X ou o processo Y. E nos últimos anos (nos últimos 10 anos mais ou menos) a batalha da vez acontece entre as metodologias ágeis contra as metodologias iterativas mais tradicionais.

Usar cascata já era!

Usar cascata já era!

As metodologias iterativas mais utilizadas são o RUP e suas variantes (para criar uma variante, adicione o sufixo UP no final de uma palavra legal). Dão muita ênfase ao processo, ao controle do andamento do projeto através de delivarables (que normalmente são diagramas de diversos tipos, como diagramas de classes ou diagramas de interação). São muito utilizadas em fábricas de software, em projetos que envolvem muitos desenvolvedores, e não são sinônimos, mas estão sempre de mãos dadas com siglas como CMMi, e PMI. Se os gerentes da empresa gostam dessas duas siglas, tem pouco cabelo e estão na área há mais de 20 anos, é alta a probabilidade de que utilizem uma metodologia iterativa tradicional. Surgiram em resposta às metodologias em cascata, que já foram predominantes.

As metodologias ágeis são uma tentativa de refinar as metodologias iterativas, tirando o foco do processo em si e dando mais ênfase à contribuição das pessoas, dos integrantes do projeto. Trazem alguns conceitos que as diferenciam radicalmente das metodologias antecessoras, como deixar o cliente participar mais próximo ao processo, iterações extremamente curtas e grande ênfase em testes automatizados. Por outro lado, pesquisadores e mesmo defensores dessas práticas não recomendam times muito grandes para um projeto (e alguns propõem dividir o projeto em subprojetos e trabalhar com equipes menores). Os métodos mais conhecidos nesta categoria são Extreme Programming (mais carinhosamente conhecido como XP) e Scrum.

Mesmo tanto tempo depois da definição de métodos ágeis, da publicação do Manifesto Ágil, e de tanta gente pregando e achando que métodos ágeis são legais, porque é que isso não é ainda utilizado em larga escala? Entre alguns motivos estão:

  • Burocracia como requisito: existem clientes que pedem pela burocracia, pelo processo mais rígido. Só contratam empresas que tenham fábrica de software com CMMi nível 50, e fazem questão de saber que foram definidos 432 diagramas, mesmo que nunca vá parar para dar uma olhada para eles.
  • Maturidade: obviamente existe um número muito maior de projetos bem sucedidos utilizando metodologias que existem a mais tempo. Não precisa ser um gênio para perceber isso. Por isso, mais gente que conhece e tem experiência com esses processos. Processos mais novos são obviamente mais atrativos para algumas empresas picaretas oferecerem serviço de desenvolvimento de software.
  • Nível técnico da equipe: no caso de muitos gerentes, ao mesmo tempo que métodos ágeis são vistos como processos que exigem ninjas-Mcgyver-programadores, eles acham que suas equipes são formados por macacos bonobos. Ou para diminuir os custos, realmente tentam contratar macacos bonobos a preço de banana. Quando você acredita que tem uma equipe não muito capacitada, acaba querendo ter mais controle sobre o processo. Quanto menos a mão de obra precisar pensar, menor o seu risco, você só bota um monte de especificações para eles executarem e dá choquinho se eles fizerem errado (não me apedrejem, essa é a visão dos caras de gravata).
  • Medo: meio que resume os outros itens. Mas basicamente, as pessoas preferem não mexer em time que aparentemente está ganhando. Você sabe que a metodologia B.A.T.A.T.A. vai te entregar um sistema. Pode demorar, custar caro e ficar cheio de problemas, mas vai entregar um sistema. Preferem não arriscar.

Se nenhuma dessas razões acima perturba sua área de desenvolvimento, acho que posso assumir que a razão para que vocês não tenham considerado Agilizar seus processos é o simplesmente não conhecer muito bem o que são métodos ágeis. Vou tentar entregar o caminho das pedras abaixo.

Mitos e concepções erradas

A primeira coisa que muita gente pensa quando ouve falar de métodos ágeis é que não existe documentação para o software sendo desenvolvido, que o processo é um oba-oba em que vale tudo e as pessoas saem fazendo as coisas que querem, praticamente uma suruba no escuro.

É verdade que métodos ágeis na verdade não chegam a ser métodos e nem processos, mas sim conjuntos de diretrizes para se chegar a um bom resultado final, e por isso, não existe o passo 32 do processo que exige que você desenhe um diagrama UML usando 3 cores diferentes coloridos com crayon. Mas diagramas e documentação existem, mas são ditados pelo bom senso. Você gera um documento para comunicar algo para outros seres humanos, para deixar algo mais claro no design para outros seres humanos entenderem. Você não gera um diagrama que ninguém vai ler mas que você foi obrigado a gerar para não tomar choquinho do seu gerente de projeto. Mas o lado ruim disso é que bom senso é um conceito bem pouco formal. Ou seja, se seu time tiver um “bom senso” ruim (existe isso? ou seria mau senso?) você está lascado.

Por causa dessa percepção que as pessoas tem de que as coisas podem meio que ser feitas de qualquer jeito com métodos ágeis, existem muitos casos reportados de projetos fracassados utilizando essas metodologias, o que acabou espantando ainda mais as empresas grandes em relação a sua adoção. Mas também existem casos conhecidos de muito sucesso como a Primavera Systems e o Salesforce.com, que utilizavam anteriormente processos iterativos tradicionais.

Conheça as histórias de sucesso e de fracasso. Provavelmente se alguém olhar para a porcentagem de projetos tradicionais que fracassam e olhar para a mesma estatística no caso de metodologias ágeis, vai chegar a conclusão de que a competência do time é mais importante que o processo utilizado.

Maiores vantagens

  • Iterações curtas. Você entrega versões funcionais do sistema com mais frequência, em espaços mais curtos de tempo (que podem ser poucas semanas, ou um mês). Assim seu cliente corre menos risco, porque sabe sempre como está o andamento do projeto, e pode te dar muito mais feedback. Todo mundo fica feliz.
  • Diminuição dos custos de comunicação. É o tipo de custo que as pessoas dificilmente colocam no papel. Mas olhe para métodos mais dirigidos por especificações e diagramas. Todos esses artefatos são feitos com o objetivo de comunicar alguma coisa (pelo menos deveria ser esse o principal objetivo de um diagrama). O problema é que ao mesmo tempo, as pessoas utilizam exatamente os mesmos diagramas como documentação de longo prazo. O resultado disso é que durante o processo são gerados muitos documentos e diagramas que não são utilizados para comunicar nada, apenas para registrar como as coisas deveriam ser. E no final de tudo, tente descobrir se seu software realmente está seguindo toda aquela documentação gerada. É mais fácil construir outro sistema.
  • Levar em consideração que as coisas vão mudar ao longo do caminho. Enquanto você está especificando o sistema, as coisas estão mudando, e quem sabe aquilo que você bolou só vai servir para forrar galinheiro. Então você faz iterações curtas, para que essas mudanças tenham o mínimo de impacto no projeto. Você controi testes para garantir que mudanças futuras sejam mais seguras de fazer através de refatoração do código. E você tenta sempre resolver o problema que você tem na mão, não fica tentando criar a super solução genérica para casos que você nem sabe se vão aparecer. O último ponto é algo extremamente útil quando você tem na equipe pessoas que gostam muito de modelagem de arquitetura de sistemas, e que gostam de bolar coisas extremamente complicadas. O cliente não vai pagar mais pelo software que tiver a arquitetura mais bonita. Mas vai ficar mais feliz pelo software entregue mais cedo.

Algumas práticas são boas de qualquer jeito

Mesmo que você não vá adotar um processo ágil, existem práticas bem difundidas pela comunidade que DEVERIAM ser adotadas independente do processo utilizado. Repare que coloquei DEVERIAM em maiúsculas e negrito de propósito. Deveria ser lei, obrigação, sujeito a 30 açoitadas em praça pública para quem não seguisse essas práticas.

Testes automatizados. Automatize o máximo de testes que puder. Sim, vai dar mais trabalho. Não, não vai acabar com todos os bugs. Mas mais tarde, quando você precisar fazer uma refatoração mais radical, ou resolver algum bug ou alteração que surgiu, você não precisa mais ter medo e suar frio. Com um clique em um botão você sabe se quebrou alguma coisa (dependendo de quanto os seus testes são bons, claro). É infinitamente mais útil você ter um negócio que te dá essa informação sobre seu software do que pilhas e pilhas de qualquer tipo de documentação e especificação. Tente usar um UML para descobrir se você pode fazer uma alteração nas suas classes de objetos. Incontáveis vezes pude resolver problemas muito rapidamente simplesmente porque gastei algumas horas a mais escrevendo testes. Lembre-se, testes são como remédio ruim. Na hora que você está tomando vai reclamar, mas vai agradecer pelos benefícios no futuro.

Integração contínua. Pode ser visto como uma extensão dos testes automatizados. Automatize a integração e o build do seu software. Não deixe para descobrir no dia da entrega que o negócio não funciona (ou só funciona se o seu código e o do Juca estiverem separados).

Iterações curtas. Entregue versões do seus sistema com mais frequência e descubra mais cedo se você está indo na direção certa. É muito melhor quando isso acontece depois de duas semanas do que três meses depois. E se quer realmente saber se é possível cumprir seu prazo, você precisa deixar que os desenvolvedores, as pessoas que botam a mão na massa, estimem o tempo. Eles tem mais noção que você (que quer o prazo para ontem) e seu cliente (que quer o prazo para duas semanas atrás).

Gostei, como posso saber mais sobre isso?

Como literatura, acho que o melhor começo é o livro do Kent Beck, Extremme Programming Explained, um dos primeiros livros lançados sobre o assunto. Depois que você ler o livro do Beck, e quiser um livro mais prático, direto e DE GRAÇA, eu recomendo o Scrum and XP from the Trenches, do Henrik Kniberg.

Abaixo uma rápida e divertida introdução a Scrum:

Em breve vou fazer um post sobre ferramentas gratuitas para gerenciamento de projetos ágeis.

Me desculpem, mas só consigo links e vídeos bons em inglês. Se alguém tiver sugestões em português ou mesmo vídeos legendados, por favor me indiquem que eu coloco aqui.

Clusters de aplicações Java

Ao criar sistemas utilizados por milhares (ou milhões) de usuários diariamente, o arquiteto da solução precisa sempre se fazer algumas perguntas (ou pelo menos deveria):

Minha solução é capaz de suportar o número esperado de usuários?

O que fazer se o sistema não der conta da demanda de usuários?

E se um servidor sair do ar enquanto usuários estão acessando o sistema?

Não pensar nestas questões pode custar muito caro quando o sistema entra em produção. Se o sistema não aguentar a demanda de usuários e a equipe responsável não pensou em alguma forma para aumentar a capacidade do sistema de forma rápida, só resta colocar uma plaquinha “Em manutenção” e aguentar os esporros do chefe. Se o servidor tem algum problema e sai do ar enquanto estava em produção, isso pode gerar desde um aborrecimento com os clientes até perda de dados importantes. De qualquer forma, isso se traduz em prejuízos.

O quanto os seus servidores aguentam?

O quanto os seus servidores aguentam?

Já houve um tempo em que os sistemas rodavam apenas em um servidor, e para aumentar sua capacidade bastava adicionar mais memória RAM, ou colocar uma CPU mais turbinada. Mas hoje a ordem de grandeza para quantidade de usuários que podem acessar um sistema Web, por exemplo, é muito maior. E difícil de prever com exatidão. Desse jeito você tem como alternativas:

  • comprar um mega servidor caríssimo, que pode receber grandes quantidades de RAM e CPU. Não é a solução ideal porque servidores caríssimos são… bem, caríssimos. Ou seja, você pode acabar gastando muito mais do que precisaria de verdade. Ou mesmo comprando um, ele pode não dar conta do recado, porque mesmo mega servidores caríssimos tem limite máximo de memória e CPU. Mas a maior desvantagem é que se você tem apenas um servidor, e ele quebra, pode começar a enviar currículos, porque você está ferrado.
  • colocar seu sistema para rodar em cluster. Em um cluster você pode rodar seu sistema em vários servidores, pode dividir a carga entre esses servidores. Se a carga aumenta acima do esperado, não é coisa do outro mundo adicionar outro servidor para aumentar a capacidade do cluster. Se um servidor cai, você tem vários outros para continuar atendendo os usuários. O maior problema dessa brincadeira é que a complexidade para montar, configurar e manter essa arquitetura é bem maior.

A discussão a seguir se aplica a clusters de aplicações Java, mas clusters em outros ambientes não são tão diferentes. A limitação da discussão a Java se deve apenas ao fato de que quero falar um pouco sobre uma solução que encontrei para este ambiente. Se conhecerem soluções boas para outros ambientes, por favor, comentem neste post.

Clusters para Java

Todos os servidores de aplicação J2EE do mercado possuem uma implementação de cluster. O grande problema é que não existe um padrão para isso, então cada um implementa de uma forma. Isso é chato para os desenvolvedores que precisam absorver muito conhecimento complicado para configurar um servidor com que não estão acostumados a lidar. É mais caro, porque a empresa precisa investir muito mais para que os arquitetos de soluções conheçam bem como funcionam as soluções de cluster de cada fornecedor com quem trabalham. Para um panorama sobre clusters de aplicações J2EE, dê uma olhada neste artigo do TheServerSide.

Além de serem complicados, eles não são nem um pouco “Plug ´n Play”. Se você não desenhou seu sistema para funcionar na arquitetura de cluster proposta pelo seu fornecedor, provavelmente terá que redesenhar muita coisa. Imagine, por exemplo, aquela sua classe Singleton, que coordena várias operações. Ela não vai mais ser Singleton com o cluster, porque você acaba com uma instância em cada servidor, o que significa que você vai ter que bolar uma forma desses objetos funcionarem da mesma forma que o seu Singleton fazia. Ter que rearquitetar partes grandes de um sistema é uma tarefa trabalhosa e bastante arriscada. Se você está nesta situação, meus pêsames.

Essas arquiteturas de cluster também acrescentam muito overhead na performance do sistema como um todo. A comunicação que eles precisam fazer entre si e com bancos de dados, só para manter o conjunto consistente, pode tornar as respostas do sistema muito mais demoradas. Você sempre vai ter algum overhead quando utiliza um cluster, mas dependendo da arquitetura, o remédio pode sair pior que a doença.

Outro ponto de overhead de performance é o banco de dados. Quando o banco de dados começa a ser utilizado para persistir os dados de um servidor de aplicação apenas para que os outros servidores tenham acesso a esses dados (que neste caso seria mais para manter a consistência do cluster), o cluster começa a abusar demais do banco de dados. O banco de dados deveria servir para armazenar os dados da aplicação, e não passar a maior parte do tempo cuidando do estado do cluster. Armazenar esse tipo de informação em um banco de dados relacional é como tentar almoçar utilizando uma metralhadora AR-15 no lugar de garfo. É uma ferramenta com muito mais recurso do que o necessário para a tarefa, o que acaba acrescentando muito mais overhead. Mas é uma das soluções preferidas, por pura falta de solução mais segura, rápida  e mais simples (ou desconhecimento de uma solução assim).

Seus problemas acabaram… acho

A melhor solução que encontrei até agora foi o Terracotta. Terracotta é um software open-source e gratuito para facilitar o trabalho de tornar uma aplicação Java mais escalável. É o tipo de coisa que eu não entendo como pode ser de graça (bom, eu entendo, eles vendem serviços em cima disso, mas preciso dizer que não entendo para que vocês tenham uma noção do quanto eu acho esse negócio FODA). Definitivamente é uma solução que eu indicaria para quem precisa de mais escalabilidade com menos custo (e alguém quer menos escalabilidade com mais custo?). E não é um projeto open-source de garagem, é uma empresa financiada, com alguns clientes na lista da Fortune 500. Entre seus clientes estão a JPMorgan, a Adobe, a BBC e a Hitachi.

Console de administração

Console de administração

O Terracotta pode ser visto mais simplesmente como uma solução para compartilhar objetos entre servidores. Cada nó de aplicação em um cluster Terracotta pode acessar todos os objetos que estão no pool de objetos do cluster. Quando um objeto é criado em um servidor, e está configurado para ser compartilhado no cluster, os outros servidores podem enxergá-lo e acessá-lo, como se estivesse na memória local. É como se cada servidor estivesse fornecendo mais memória ao cluster, uma arquitetura conceitual muito mais simples do que os quebra cabeças complicados que chamamos de cluster de aplicações.

Se você só tirava notas de C para cima no colégio, deve estar pensando “mas se todos os servidores tem acesso a todos os objetos compartilhados, essa arquitetura não é escalável nem aqui, nem na China! Para cada servidor acrescentado eu ia precisar de muito mais memória em cada nó do cluster!“. Calma, que os arquitetos do Terracotta pensaram nisso. Cada nó pode acessar todos os objetos do cluster, mas ele só carrega esses objetos na memória quando necessário (o que é milhares de vezes mais rápido do que pegar essas informações em um banco de dados). Assim cada servidor acaba utilizando apenas a memória para os objetos que realmente está utilizando.

Quem tirava C+ na maioria das matérias deve perguntar “mas qual a diferença, em termos de performance, entre essa forma de sincronização para os clusters tradicionais?“. Em comparação a arquiteturas que fazem persistência dessas informações em banco de dados, não há nem o que discutir. Como o Terracotta armazena as informações em memória, ele responde muito mais rápido do que um banco de dados pensando em fazer a query. Além disso, quando dados de um objeto são atualizados em um servidor, apenas os campos que foram alterados são propagados para o cluster. Em clusters tradicionais, objetos inteiros são trafegados, mesmo que só 1% deles tenham sido alterados.

Os alunos nota B sempre me perguntam “E isso é seguro?“. O framework reforça que os acessos aos dados compartilhados tenham algum controle para sincronizar o acesso, garantindo consistência entre os nós. Um servidor pode tentar acessar um objeto, mas enquanto outro servidor estiver alterando esse objeto, o primeiro servidor deve esperar sua vez. Além da redundância de dados que existe entre os nós do cluster, em um sistema com Terracotta você deverá ter um ou mais servidores Terracotta, que fazem a sincronização da memória dos servidores de aplicação. Além disso, o servidor Terracotta armazena em disco as informações do cluster, de forma mais eficiente quen um banco de dados, mas tão seguro quanto. É possível ainda configurar facilmente vários servidores Terracotta em um mesmo cluster, assim, se um servidor desses sai do ar, o cluster continua operando normalmente.

Tudo parece resolvido, mas os alunos nota A com certeza não vão sossegar se eu não responder “Quanto trabalho vou ter usando isso?“. Perceba que é a pergunta mais esperta de todas. Esse, acho que é o ponto mais positivo da solução. Dependendo do que você usa em sua aplicação, é possível que não precise mexer em nenhuma linha de seu código para fazê-lo funcionar em cluster com Terracotta. Basta a configuração. Nem mesmo a sincronização de acesso aos dados vai exigir uma alteração de código, pois além de reconhecer a sintaxe de sincronização de threads do Java, os acessos podem ser configurados no arquivo de configuração do Terracotta. Nem mesmo as classes precisam ser serializáveis para participar do cluster (exigência normal em outras soluções). E existem diversos pacotes de integração para frameworks existentes (como Hibernate, Struts, Spring, etc.).

Nem tudo são flores

Umas dicas para enfrentar o caminho das pedras:

  • O processo para instrumentalizar as classes para o cluster pode ser meio doloroso. O ideal é colocar como classe instrumentalizada, no arquivo de configuração, apenas as classes que devem ser utilizadas pelo cluster. Se você não conhece muito bem sua aplicação, o processo consiste em rodar sua aplicação com o Terracotta, até que ocorra um erro dizendo que você deveria colocar a classe X na sua configuração. Se você tiver um sistema muito grande, esse processo manual pode tornar inviável ficar escolhendo as classes certas (você pode mandar instrumentalizar tudo de uma vez). E é bom que você tenha bons testes funcionais do seu sistema, que exercitem todo seu código, porque você não quer descobrir que deixou de instrumentalizar alguma classe depois que o sistema estiver em produção.
  • Se não existir o pacote de integração para algum framework que seu sistema utiliza, e esse framework precise de acesso ao cluster, você pode ter um trabalho extra para fazê-lo funcionar com o Terracotta. O que exige que você tenha um conhecimento um pouco maior sobre esse framework (o que normalmente não é o caso).

Ainda fiz poucos testes com o Terracotta. Até onde vi, me agradou bastante. Não chega ainda a ser uma solução perfeita, mas está em um bom caminho. Ainda preciso fazer um teste de carga, para sentir a performance. Vou continuar acompanhando o progresso da ferramenta. E acho que para quem está precisando de uma solução para aumentar a escalabilidade, disponibilidade e performance de um sistema, vale a pena dar uma olhada no Terracotta. Quem sabe você nem precise mais usar aquelas licenças de Oracle RAC que você precisou se prostituir para conseguir.

Gostaria muito de ver soluções parecidas para .Net ou outros ambientes. Agora com a computação em nuvem na moda, algo muito desejável é simplificar um pouco a loucura que é um sistema distribuído.

Atualização: Postei uma pergunta no fórum do Terracotta e em 2 horas tive respostas de 2 engenheiros! Um deles me respondeu em menos de 30 minutos. Acho que nem com suporte técnico via telefone fui atendido tão rápido.