Fork me on GitHub

Keep Learning Conhecimento nunca é o bastante

Flickr
Ver todas »
Nouvel an chinois, Paris 2012La ciudad de la luz IIVisit Tour EiffelParis CatacombsPont RoyalSt-Germain-des-Pres

O poliglotismo “cria” bons desenvolvedores?

Não.

Vejo algumas concepções falaciosas em nossa comunidade que há muito já foram superadas em outras profissões. Uma delas é que dominar mais ferramentas torna o profissional melhor. Será mesmo?

Estudamos tanto lógica para aprender a programar e nos esquecemos de uma armadilha lógica básica: confundir causa e efeito com correlação. Ou, pior, caímos na falácia do Efeito pela Causa e acabamos invertendo as coisas. O fato é que quanto melhor o profissional, mais ferramentas ele vai querer explorar.

Explico: um bom desenvolvedor vai querer aprender mais linguagens para aumentar seu repertório de soluções. Um péssimo desenvolvedor pode aprender 20247232 linguagens e o máximo que conseguirá é ser um péssimo desenvolvedor em 20247232 linguagens. Causas: dedicação e proficiência. Efeito (um deles): desejo de expandir o conhecimento. E, assim, temos um ciclo virtuoso.

Não me entenda mal: eu acredito que conhecer várias linguagens é algo muito positivo. Mas também vejo acontecer um tipo de “pressão social” por isso, como se não pudessem haver preferências e predileções. É o mesmo tipo de pressão social que rola se você falar que não gosta de “The Beatles”. As pessoas vão te olhar feio, pode ter certeza (os caras foram – ou ainda são – muito fodas e mudaram muita coisa, só não fazem o meu estilo, então por favor não arranquem meu couro – e olha eu com medo da pressão). ;)

Em geral, quando eu digo que acho legal conhecer e brincar com várias linguagens mas que prefiro, de longe, desenvolver com Ruby, muita gente já “olha torto”. Veja bem, eu não quero dizer que vou escolher Ruby pra tudo for desenvolver – isso é ser cego. O que eu quero dizer é: se eu estiver num “empate técnico” durante a escolha de linguagem, vou preferir Ruby sempre (hoje, pois o futuro não se sabe, não é?). Além disso, quase sempre que eu for programar algo por diversão, vai ser nessa linguagem.

Acredito que há ótimos desenvolvedores monoglotas (que logo sentem a necessidade de expandir seu vocabulário) e péssimos desenvolvedores poliglotas. E vice-versa. Não é um requisito, é uma opção. Como diz aquela famosa frase: “Você pode escrever Fortran em qualquer linguagem”.


Android e iOS são realmente competidores?

Acredito que não. Pelo menos, não diretamente.

Escrevi um pouco sobre isso aqui: Oceano Azul vs Oceano Vermelho: Android vs iOS (meu Tumblr, onde passarei a concentar os textos não relacionados à programação)


Review: MacBook Air 13”

Bom, já são duas semanas utilizando essa belezinha, então resolvi escrever sobre minhas experiências com o novo MacBook Air. Em geral não costumo fazer isso, mas esse brinquedo é tão empolgante que não resisti.

Meu modelo tem a seguinte configuração: tela de 13”, processador Core 2 Duo 2.13 Ghz, 4 Gb de RAM DDR3 e flash storage de 256 Gb.

Meu computador anterior era um MacBook Aluminum 13” (daquele modelo que depois virou Pro quando o MacBook voltou a ser de plástico) com processador Core 2 Duo 2.4 Ghz, 2 Gb de RAM DDR3 e HD de 250 Gb.

A primeira reação das pessoas quando falei que ia utilizar um MacBook Air como único computador é de espanto. As razões, em geral, são:

  • “Não tem drive óptico!”: bom, eu usei o drive óptico do meu MacBook apenas uma vez, para instalar o Snow Leopard. Como agora o sistema e o iLife vêm num USB stick, não há necessidade de uma peça que só vai tomar espaço.
  • “Mas o processador é fraaaaaco!!”: não, não é. Pode não ser um i7 de 3.06 Ghz, mas há pouco mais de um ano eu usava um Core Duo de 2.0 Ghz e isso não me impedia de fazer nada. Um Core 2 Duo de 2.13 Ghz está ótimo. Um detalhe importante: essa versão possui 6 Mb de cache L2, o dobro dos Core 2 Duo normais.
  • “4 Gb de RAM é pouco!”: de forma alguma. A não ser que você goste de deixar todos os programas que usa durante a semana abertos o tempo todo, é o suficiente. 2 Gb sim seria um pouco apertado, mas não impraticável. Nessas duas semanas ainda não vi a máquina esgotar essa memória e partir apenas para swap. Uma coisa que me ajuda é que uso programas leves, não uso IDEs, nem nada da Adobe Creative Suite e raramente deixo o browser com mais de 3 abas abertas (forcei o hábito de ler as coisas na hora ou salvar no Delicious pra depois). Também faço isso e isso.
  • “256 Gb é muito pouco! Não cabem todas as minhas fotos, músicas, filmes e seriados!”: também não cabem as minhas. Pra carregar tudo isso num notebook eu precisaria de um HD de mais de 700 Gb pra ainda ter jogos do Steam e tudo mais. Ou seja, já uso HD externo pra essas mídias e para backup e vou continuar usando. No storage do Air ficam apenas os jogos, documentos, projetos e músicas (já que no iPhone com 16 Gb não cabem todas). Se precisar carregar mais do que isso, não teria problema em deixar na mochila um HD compacto e leve pra quando fosse necessário. Com os preços de SSD caindo, isso vai ser ainda mais confortável (e rápido!) em breve.
  • “Mas não dá pra expandir o hardware!! E se eu quiser colocar 300.000.000 Gb de RAM???”: bom, eu nunca expandi nenhum Mac que tive. Com certeza não é uma máquina pra quem sempre faz isso.
  • “São poucas portas de expansão! Não tem Firewire nem Ethernet”: realmente. Como eu nunca usei essas portas quando tive, não me fazem falta. Tem até um leitor de cartão SD que também nunca usei e trocaria por uma USB se pudesse, mas não senti falta de mais portas.

Nós geeks temos a tendência de achar que um bom computador precisa ter gazilhões de gigahertz de processamento, bazigalhões de gigabytes de memória, storage infinito e dezenas de milhares de portas de expansão. Claro, são coisas legais, não nego. Mas estão longe de necessárias para mim, pelo menos não tudo socado numa máquina em que o objetivo é ter mobilidade sem comprometer conforto e desempenho.

Meu tempo de comprar componente por componente, montar e “overclockar” tudo que era possível (processador, gpu, ram, vram etc) já se foi. Hoje meu foco é em coisas que “apenas funcionem”, ou seja, appliances. Não quero ficar expandindo meu hardware nem sendo hackerzinho instalando task managers e outras firulas no meu celular. Nesse sentido é inegável que a Apple manda muito bem.

Além disso, fica claro que não é uma máquina para todo mundo. Seria uma experiência horrível fazer produção de vídeo profissional nela, por exemplo.

Para o meu uso, foi uma excelente escolha. O peso é um fator importante pois faço tudo a pé ou utilizando transporte público. Nesse caso não tinha como ser melhor: em apenas 1.3 kg é, com certeza, a máquina mais rápida que já utilizei.

Na GoNow fizemos alguns testes comparando o Air com um Pro 15” de última geração e o Air deixou seu irmão maior comendo poeira. Por exemplo, para rodar uma suíte de testes escritos com RSpec, o Air levou 3 segundos e o Pro sequer tinha subido o environment da aplicação nesse tempo. Rá, a felicidade. ;)

Tudo isso deve-se ao flash storage. Retirando do sistema o HD, o componente mais arcaico e lento dos computadores atuais, as coisas tendem a melhorar muito. Como desenvolvedores para web sabemos que, quase sempre, o gargalo de performance de um sistema acaba sendo I/O e isso não é diferente nos computadores. Um processador Xeon 8-core 2.4 Ghz pode ser estupidamente rápido, mas ainda vai ter que esperar (muitas vezes, ocioso) o leeeento HD buscar os dados necessários. Numa matemática tosca, 1 segundo perdido nessa operação já torna “irrelevante” a ultra-power velocidade do processador.

Claro que em tarefas 100% dependentes de processamento (como codificar um vídeo no Handbrake), quanto mais rápido o processador, melhor. Como esse tipo de tarefa não ocupa sequer 1% do meu uso cotidiano, não sinto falta. E, novamente, por isso gosto de appliances: um dispositivo focado para cada tarefa. Para vídeos, por exemplo, dispenso conversões usando um WD TV Live.

Para uma análise bem completa do novo Air, veja o review do AnandTech (infelizmente não testaram a versão “no talo” do Air 13”, mas o ganho visto em outros benchmarks é de, em média, 15%). A parte que fala do storage é especialmente animadora (note que o importante é leitura e escrita randômica, já que leitura/escrita sequencial é um cenário ideal e raro). Para ter uma ideia, o modelo WD VelociRaptor é o HD de desktop mais rápido existente hoje.

A bateria é excelente. A Apple passou a utilizar uma nova metodologia de testes de bateria e afirma que o Air de 13” tem autonomia de 7 horas nesse teste (mais pesado que o teste anterior). No meu uso cotidiano, em média, consigo esse tempo mesmo. Quando estou tranquilo apenas ouvindo música e navegando por algum site, a duração chega em 10 horas tranquilamente (sim, já cronometrei).

Coisas que são foda PARACARÁLEO:

  • Sem vidro em frente à tela: bye bye reflexos que dão enxaqueca e atrapalham o uso;
  • Resolução da tela (1440×900), a mesma do atual MacBook Pro 15”;
  • Flash storage;
  • Os speakers e o processamento de som (utilizando um fone pela conexão de saída) são os melhores que já vi num MacBook (mesmo com o espaço pra speakers sendo bem reduzido);
  • Flash storage;
  • Ótima duração de bateria;
  • nVidia 320M (já joguei Left 4 Dead 2, Day of Defeat e Civ V);
  • Já falei do flash storage?
  • É muito mais confortável digitar nele: a base é bem mais baixa que nos outros MacBooks, fazendo com que o punho fique em posição natural, sem flexão, eliminando a necessidade de apoiar a mão numa posição desconfortável quando prolongada.

Coisas que poderiam ser melhores:

  • A Apple poderia ter utilizado USB 3.0, reforçaria ainda mais todo o argumento da mobilidade do Air;
  • Teclado sem iluminação (é algo bacana, até achei que ia MÓRRER sem, mas já acostumei)

Conclusões:

A máquina é excelente. De longe o melhor computador que já usei. Não vejo hoje outra máquina disponível com o mesmo nível de mobilidade, qualidade de design e construção, tela excelente, nenhum compromisso em termos de conforto e performance tão boa.

Parte filosófica: costumo buscar uma “veia minimalista” na minha vida, embora (ainda) não possa me chamar de minimalista (para clarificar: estou falando sobre estilo de vida, não sobre design). Nesse sentido procuro consumir com mais consciência e ter produtos mais simples e focados (e somente quando necessário), que consumam menos energia, evitando desperdício.

Não posso negar que, às vezes, o lado consumista insano fala mais alto mas, em geral, vem dando certo. O MacBook Air vem de encontro com essa filosofia: é leve, consome pouca energia, ocupa pouco espaço, não faz barulho e devo utilizá-lo por uns 3 anos facilmente, já que minha necessidade de poder bruto é baixa. E, claro, também satisfaz o lado consumista, afinal é uma linda peça de design industrial. ;)

Como disse, não é uma máquina para todo mundo. Se você precisa de mais poder de processamento e um drive óptico, considere colocar um SSD no seu MacBook Pro. Sim, eu sei que é caro. Também sei que o benefício é monstruoso.

Sobre o irmãozinho mais novo, o MacBook Air 11”: com certeza é uma ótima pedida para quem busca uma segunda máquina potente e muito portátil, para reuniões, viagens e afins, também sem compromissos em termos de conforto (leia-se, boa resolução de tela e teclado full-size).

THE ALMIGHTY MACBOOK AIR OMGBBQ!!1!1!

THE ALMIGHTY MACBOOK AIR OMGBBQ!!1!1!


Back-end caching com Ruby, parte 1 – Introdução

Depois de pesquisar muito código e dar duas palestras em que falei um pouco sobre o tema, posso afirmar com convicção que caching é um dos aspectos mais negligenciados pelos desenvolvedores em nossa comunidade – não por preguiça ou algo do tipo, mas por falta de prática e exposição ao assunto.

Resolvi contribuir para que o assunto seja mais discutido escrevendo alguns posts. Como a parte de cache em front-end já é mais difundida, vou focar no back-end.

Para começar, precisamos clarificar essa distinção importante: front-end cache e back-end cache. O primeiro tipo é o mais comum de encontrar em tutoriais e posts em blogs. Trata-se do cache de camadas relacionadas à interface da aplicação. No Rails, por exemplo, engloba: page, action e fragment cache. Já o segundo tipo, em geral, envolve fazer cache de resultados de operações pesadas (como queries complexas a banco de dados) utlizando algum storage como memcached. É desse tipo que vamos falar.

Sabemos que, quanto mais cedo no ciclo do request for feito o cache, mais eficiente ele é. Daí o cache no front-end ser o que traz mais retorno. No entanto, há momentos em que não é possível utilizar cache no front-end. Além disso, há situações em que outros tipos de cache são necessários, por exemplo quando utilizamos um back-end comum para a aplicação web e API (com clientes mobile e desktop, por exemplo) e queremos ter o benefício de desempenho do cache nessa parte também.

De modo geral, o que precisamos para o caching no back-end é um storage e um cliente para ele. Um dos storages mais comuns (em diversas plataformas) é o memcached – tão comum e consistente que vários frameworks o suportam out of the box, como é o caso do Rails.

Vamos a um simples exemplo utilizando a gem memcached para o caching de um cálculo feito em cima do resultado de uma hipotética query a um banco de dados.

Primeiro, vamos iniciar um servidor do memcached localmente:

$ memcached -vv -l 127.0.0.1 -p 11211

Isso vai iniciar o servidor localmente na porta 11211 em modo very verbose para que possamos acompanhar o que está acontecendo.

Agora, vamos ao código:

require "mysql"
require "memcached"
 
connection = Mysql.real_connect("127.0.0.1", "root", "pass", "my_database")
 
results = connection.query("select * from amazingly_big_table where non_indexed_column = 'some_value'")
 
some_calc = 0
 
# no inject on Mysql::Result :(
results.each do |row|
   # do some processing using some_calc
end
 
puts some_calc

Toda vez que esse código for executado, a query irá ser feita no banco de dados e o resultado será calculado novamente. Nesse exemplo, vamos adicionar cache para evitar que isso ocorra tantas vezes:

require "mysql"
require "memcached"
 
connection = Mysql.real_connect("127.0.0.1", "root", "pass", "my_database")
cache = Memcached.new("localhost:11211")
 
some_calc = cache.get "some_calc" #busca o valor no cache
 
unless some_calc #caso não esteja em cache
  results = connection.query("select * from amazingly_big_table where non_indexed_column = 'some_value'")
  some_calc = 0
 
  # no inject on Mysql::Result :(
  results.each do |row|
    # do some processing using some_calc
  end
 
  cache.set "some_calc", some_calc, 3600 # coloca o valor no cache por 3600 segundos
end
 
puts some_calc

As linhas importantes aqui são as que manipulam o cache. No caso do memcached (e na grande maioria dos outros storages para cache) utilizamos o esquema de chave-valor. Armazenamos um valor em uma determinada chave, que deve ser conhecida para que possamos recuperar os dados. O memcached também suporta um time to live, que é um tempo em que o dado deve ser mantido no cache. Após esse tempo, ele é considerado expirado e não será encontrado quando tentarmos um get.

Dessa forma, nosso resultado permanecerá em cache por 3600 segundos. Durante esse tempo, toda vez que o código for executado, o valor será trazido do memcached e mostrado ao final, sem execução da query e do cálculo novamente.

No terminal podemos ver a saída do memcached, mostrando quando armazenamos e buscamos o valor:

memcached

Bom, para começar é só isso. Bem simples e não lá muito útil, mas precisamos começar do mais básico, certo? :)

No próximo artigo vou mostrar alguns exemplos mais práticos, utilizando frameworks como Rails e Sinatra. Após isso vamos explorar áreas como: expiração de dados e coleções interdependentes, dog pile effect e outras coisas interessantes.


Slides (com algumas anotações) da minha palestra na RubyConf Brasil

No último dia 26 palestrei na RubyConf Brasil, em São Paulo, falando sobre uma miscelânea de dicas e técnicas para otimização de aplicações Rails e formas de tornar o código de uma aplicação mais flexível e mais fácil de manter.

Os slides (em pdf) podem ser baixados aqui: Coisas que aprendi e quero passar adiante

Obrigado a todos que estiveram presentes e fizeram críticas e elogios.

Sinta-se à vontade para comentar a apresentação.


← Anterior Próxima →