Nokia Developer Day

A @ttecnologia acompanhou de perto em São Paulo o evento Nokia Developer Day que ocorreu na última sexta-feira, dia 23/03 em São Paulo.

Publiquei em meu blog um resumo com todos os principais momentos do evento e novidades apresentadas pela Nokia, principais palestras ilustrando a utilização das tecnologias e ferramentas utilizadas no desenvolvimento de aplicativos Windows Phone 7.

Confira estas e outras novidades que o ecossistema criado pela parceria entre Nokia e Microsoft trouxeram para as empresas e desenvolvedores no Brasil.

 

Contratações em aberto no mês de março!

Estamos a procura de novas pessoas para nossa equipe. Desenvolvedores Web com foco em Java, VRaptor, JQuery e outras coisas legais. E desenvolvedores Mobile com foco em Windows Phone. E com a mentalidade que trabalhamos aqui. :-)

Já falamos algumas vezes sobre nosso jeito de contratar. Então qualquer dúvida, faça contato conosco

Uma coisa importante, é que contratamos apenas quando dói, fazendo referência ao livro rework. Então saiba que você está entrando no momento certo e que será valorizado e apoiado por todos da equipe desde o primeiro dia. 

--

Quem escreveu este post? Daniel Wildt é CTO da Trevisan Tecnologia e curte ajudar o time a melhorar continuamente. Site no danielwildt.com e twitter @dwildt.

TTLabs Summit Q2/2011 - Daniel Wildt manda dicas para apresentações

Palestrei sobre o método @Lessig@PresentationZen e @GuyKawasaki, mostrando dicas para melhorarmos nossas apresentações.

Confesso que tive uma ajuda para passar e fixar a mensagem. Foi uma técnica usada pelo @Peleteiro no Agile Weekend 2009, sobre os bebês focas.

Acho que funcionou! :-) 

Se você mudou sua técnica de apresentação, o que mudou? Mande seu comentário! 

--

Quem escreveu este post? Daniel Wildt é CTO da Trevisan Tecnologia e curte ajudar o time a melhorar continuamente. Site no danielwildt.com e twitter @dwildt.

A Importância do Uso dos Indicadores (BSC)

Passar de forma clara aos colaboradores seus objetivos organizacionais é um desafio para a maioria das empresas. As pessoas geralmente entendem o que a empresa busca, mas não entendem o caminho que deve ser percorrido para atingir tais metas. Normalmente, o caminho não está claro para todos.

A questão principal é: "Será que todos sabem claramente o que precisam fazer para que a empresa atinja suas metas? O caminho está claro para todos?"

 

Para auxiliar nesse processo de comunicação entre a empresa e seus colaboradores existe o Balanced Scorecard (BSC), que através de seus indicadores balanceados e estruturados para cada área da empresa, visa auxiliar os colaboradores nas tomadas de decisões para que os objetivos organizacionais sejam atingidos o mais rápido possível.

Maiores informações sobre o assunto poderão ser acessadas diretamente no blog Análise Ágil de Negócio, que possui o post completo sobre o uso de indicadores.

--

Quem escreveu este post? Emerson Schenatto é analista de negócio da Trevisan Tecnologia. Site eschenatto.blogspot.com e twitter @eschena.

Como vocês contratam?

Muitas vezes me perguntam como a gente faz a contratação aqui na empresa. Até fizemos no passado um podcast falando sobre contratações e eu mesmo fiz um post no meu blog sobre vagas de emprego e como elas devem ser legais. 

São com certeza pontos importantes, mas não são apenas estes que existem. 

No blog do udemy, achei legal um post sobre como atrair, contratar e manter as pessoas que vão trabalhar na sua empresa e nos seus produtos. 

Os pontos que mais valorizo quando vou fazer uma contratação são os seguintes:

  1. Sem pressa. Não devemos correr para buscar currículos. Devemos buscar experiências e isto deve aparecer desde o início da conversa. Antes, existia no nosso site um local para a pessoa mandar currículo, links para email de RH, tudo muito "fácil" e direto. Agora o que temos é um espaço para contato. E ele é proposital. Quero saber como a pessoa se apresenta. Quero saber como ela fala sobre o que quer e o que busca. Que redes sociais ou site referencia. Ou ela se limita a querer um local para poder anexar um arquivo ".doc"?
  2. Busque referências. Ao receber um contato, queira saber quem é aquela pessoa. Redes sociais, e aqui é onde o LinkedIn pode ser útil. Você certamente conhece alguém que já trabalhou ou trabalha com a pessoa. Só tem que tomar cuidado para não expor quem está buscando novas oportunidades por aí. Além disto, a questão é buscar referências entre equipe, amigos e conhecidos para novas pessoas na empresa, assim elas já estão vindo com um "voto de confiança". Hoje em dia só indico quem tenho certeza que pode fazer a diferença. Nem sempre foi assim. :-)  
  3. Seja realista. Você certamente possui um orçamento. Então não tente convencer a pessoa a reduzir os ganhos pela metade. Jogue com a realidade. Assim que surgir a oportunidade, tente entender o que a pessoa espera ganhar, o que ela está buscando. Seja tranquilo em falar sobre a grana que pode oferecer e benefícios que a empresa oferece. Você tem benefícios diretos (vales refeição, plano de saúde) e indiretos (treinamentos internos, dojos, ritmo saudável/sustentável e acesso a internet). Pode parecer loucura, mas deixar claro que não se gosta de horas extras, que se busca produtividade em equipe, e que a pessoa pode acessar a internet de vez em quando, ainda são exceções nas empresas de hoje.  
  4. Transpareça sua cultura. Deixe claro quem é seu time e a identidade que se tem. No que acreditam. Já tivemos casos aqui onde a pessoa agradeceu o convite para participar do processo de seleção, mas ela sentiu que não era um lugar confortável para trabalhar. Ela buscava uma hierarquia mais estruturada (somos flat até onde é possível), ou questões de crescimento, nome do cargo, necessidade de ter alguém cobrando suas tarefas (aqui buscamos equipes que se auto-organizam e auto-gerenciam).
  5. Queira a atitude da sua equipe. Mesmo que o candidato em questão seja um técnico excelente, com todas certificações e participações em eventos que podem ser um sonho, será que esta pessoa compartilha da atitude da sua equipe? Você não quer um herói. Ou quer? Pelo menos eu busco sempre alguém que vai somar na equipe. Que vai entrar para ensinar e aprender. Que tem humildade para perguntar e para ensinar quantas vezes tiver que ensinar. Isto é importante para questões de pareamento e transferência de conhecimento.
  6. Compartilhe a decisão. Eu muitas vezes tomava a decisão de contratação sozinho. Até tinha equipe participando das entrevistas, mas no final eu decidia se entrava ou não. E quando a pessoa "falhava" dentro da equipe, a culpa era minha. Então acabei diluindo a decisão deste processo, me tornando inútil nele na verdade e sendo apenas um facilitador. Hoje nas entrevistas temos de 3 a 7 pessoas participando por sessão de entrevista. O objetivo é a pessoa sendo entrevistada conhecer quem serão seus pares. E da mesma forma a equipe poder questionar e assim entender se o candidato é o que se busca ou não.  
  7. Teste tecnicamente e mentalmente. Você deve testar tecnicamente de alguma forma. A gente busca mandar algum problema que seria trabalhado em um Coding Dojo, para permitir que a pessoa teste e mostre skills com Unit Testing e possivelmente Test First (Test Driven Development) com alguma linguagem de nosso interesse. Normalmente as contratações tem base em Java, mas queremos pessoas com interesses em outras linguagens, exemplo Ruby, C# e Objective-c. Fora isto, buscamos testar como a pessoa escreve, e como ela estrutura seu pensamento. Como ela modela testes. Temos um questionário para isto, onde validamos conhecimento e comportamento em determinadas situações. Exemplo para relatar um defeito, relatar uma nova funcionalidade, e por aí vai. 

 

E como funcionam nossas rodadas de entrevista?

  1. Entrevista inicial + expectativa de $$$. Aqui se a expectativa da pessoa está fora do que podemos pagar, já alinhamos e encerramos o processo. 
  2. Questionário não técnico. Validar português e questões de escrita.
  3. Teste de código, usando problema de programação.
  4. Pareamento. O "pareamento" é normalmente usado quando a pessoa está desempregada, de férias ou possui alguma disponibilidade. O objetivo é que ela viva o nosso ambiente por algumas horas durante 1 ou 2 dias, para sentir a equipe mais de perto, participar de uma reunião diária ou de um coding dojo e assim poder conhecer melhor a equipe, ambiente, empresa, e por aí vai. 
  5. Nova entrevista + papo sobre $$$. Se chegou até aqui o objetivo é fechar. :-) 

 

Era isto. Queria compartilhar um pouco como é o nosso processo e pontos que acreditamos. E vocês, como vocês contratam?

--

Quem escreveu este post? Daniel Wildt é CTO da Trevisan Tecnologia e curte ajudar o time a melhorar continuamente. Site no danielwildt.com e twitter @dwildt.

Aumentar capacidade de processamento sem aumentar memória ou adicionar servidores? Processamento assíncrono!

Quando desenvolvemos uma solução de software, queremos que ela tenha desempenho, seja escalável, tenha disponibilidade, e que principalmente que ela consiga garantir qualidade na experiência que o usuário vai ter usando o produto em questão. 

Aí alguns já parquem para a parte técnica, querendo usar resquehornetQamazon sqs,msmq, entre outros. Mas antes precisamos entender contexto, e saber qual é a solução que melhor pode nos atender neste contexto. Uma simples simulação de fila de jobs em banco de dados pode ser uma solução útil e funcional. O ponto é que quando começamos a falar de mensageria, e processamento assíncrono, não é apenas o processamento de filas que aparece.

Temos uma série de operações que podemos realizar com filas, sejam em processos de transformação, tradução, redirecionamento, quebrando grandes mensagens em pequenos batches de processamento, enfim. Entram os Enterprise Architecture Patterns. Que são importantíssimos quando estamos pensando em requisitos não funcionais de aplicações. 

Quero abrir o assunto mensageria neste post, e falar de algumas soluções que estamos colocando em teste dentro do time. O processamento de jobs e novos testes de escalabilidade. Queremos ganhar em desempenho, mas sem nos preocupar com infra estrutura. Apesar de podermos ser elásticos ou ganhar em escala horizontal com novos nós de processamento, queremos poder continuar com a mesma infra estrutura e otimizar recursos computacionais.Note o uso correto da palavra recurso. :-)

Então nós próximos posts, eu vou tratar de dois tópicos:

  • Processamento de Jobs e formas de tratar isto em um aplicativo web. Neste caso vou brincar com o Quartz. A galera da Caelum já fez um post bem legal sobre o assunto. 
  • Amazon SQS, que é o serviço de filas da Amazon. Também vou falar de soluções mais tradicionais para isto, exemplo HornetQ da JBoss.  

Para entender um pouquinho do quanto é difícil :-) usar o SQS, depois de fazer download doClient Java da Amazon, eu tive que fazer o seguinte para testar:

  1. criar uma instância do AmazonSQSClient.
  2. criar uma fila. Depois de criar uma fila, recebemos de volta uma URL para poder acessar a fila em questão. Duas linhas de código são necessárias para isto.
  3. enviar uma mensagem, usando um comando sendMessage, passando por parâmetro a URL da fila em questão, e o texto. Passe o que você quiser, mas normalmente enviamos um documento XML ou JSON para servir de idioma da fila. Cada fila possui uma expectativa de conteúdo, e cada aplicativo cliente sabe o que esperar dentro da fila.
  4. receber a mensagem, e neste caso importante garantir a questão de escala. Podemos fazer uma requisição indicando o número máximo de mensagens que queremos recuperar da fila em questão. Exemplo, no máximo 10. Imaginando que você tem muito trabalho para fazer em várias filas diferentes, esta abordagem permite que possamos realizar um pouco de processamento, mas sem ficar "trancado".
  5. excluir a mensagem da fila depois de processar. Toda mensagem possui um ID e é através dele que podemos requisitar que a mensagem seja removida da fila. Funciona como um "ack". 
  6. depois de "limpar" a fila, consumindo todas mensagens, no meu exemplo eu removo a própria fila, criada no passo 2. Para isto tem um comando deleteQueue, onde passo a URL da fila que desejo remover. 

Então é por aí. Em 6 passos, e algumas linhas de código podemos fazer um exemplo bem legal brincando com o SQS. Lembrando que sempre que você trabalhar com Amazon Web Services, remova o que você criar para não ser tarifado.  

--

Quem escreveu este post? Daniel Wildt é CTO da Trevisan Tecnologia e curte ajudar o time a melhorar continuamente. Site no danielwildt.com e twitter @dwildt.

Armazenando arquivos no AWS/S3

Um dos serviços legais que o AWS possui é o S3 (Simple Storage Service), o serviço de armazenamento. 

O S3 é focado e ideal quando precisamos gravar um arquivo apenas 1 vez, e ler várias vezes. Ele não garante que se você atualizar um objeto com a mesma chave, que ao ler, a última versão será recuperada.

O benefício é que pagamos por Gb hospedado nos servidores da Amazon. 

Ainda podemos escolher o tipo de redundância que queremos ter. Se o dado que você armazena por lá é uma cópia de uma informação que você possui em outros servidores, e pode facilmente "recriar", é possível armazenar os documentos usando Reduced Redundancy Storage (RRS), e os preços neste caso são diferentes.

Estou testando algumas bibliotecas Java para acessar o S3. Uma que vou testar JetS3t.

O legal é que todo serviço da Amazon possui uma API, então tudo o que podemos fazer manualmente, podemos fazer programando. E para alguns serviços certar funcionalidades só vão aparecer se estivermos programando. Então mão na massa. 

Para começar, no melhor estilo observar, copiar e criar, comecei testando uma API biblioteca de apoio que me chamou a atenção por poder rodar tanto em JavaSE como JavaME. Esta lib é bem legal, mas possui algumas limitações, como não poder escolher a região do S3 onde se quer armazenar a informação (ele sempre vai no Standard) e não estar pronto para tornar o objeto público. Nada que um pequeno hacking no fonte não resolva. Ainda assim o exemplo é importante para aprender o básico das requisições. 

O que se precisa para poder programar este exemplo? Bom, (a) de uma conta no AWS, e (b) access keys para poder chamar as requisições. 

Neste meu exemplo faço um upload e um download de uma imagem, fazendo a operação completa... criar bucket, enviar arquivo, baixar arquivo, remover arquivo, remover bucket. 

Bucket... é o nome que o AWS dá para a nossa área. Um bucket possui um nome único e único em todo o S3. Verifiquei isto quando fui criar um bucket "teste" e ele já existia. :-)

Aqui se tem uma ideia meu exemplo, que usei para testar a história toda. 

 

String accessKeyId = "access-key-da-aws-da-sua-conta";
String secretKey = "secret-key-da-aws-da-sua-conta";
S3 s3 = new S3(S3.HTTPS_URL, accessKeyId, secretKey);
String bucketName = "danielwildt" + System.currentTimeMillis();
s3.createBucket(bucketName);
String fileName = "/users/dwildt/pasta/arquivo-para-teste.jpg";
String fileNameDecode = "/users/dwildt/pasta/arquivo-para-teste-back.jpg";
String key = "pasta/nome-arquivo-no-aws.jpg";
String data = readFileAsString(fileName);
s3.putObjectInline(bucketName, key, data);
S3Object s3Image = s3.getObject(bucketName, key);
saveImageFromString(s3Image.getData(), fileNameDecode);
s3.deleteObject(bucketName, key);
s3.deleteBucket(bucketName);

 

Então esta lib que testei é capaz de fazer estas operações. Ela também consegue listar objetos. O S3 tem uma regra que ele apenas lista 1000 objetos por vez, e funciona em um processo de paginação. Esta biblioteca não tem este poder. No meu caso eu não tenho este "problema", pois eu preciso apenas enviar e recuperar objetos. E eu sempre sei o nome do objeto que quero buscar. 

Bom, próximos passos? Faça download da biblioteca de exemplo. Ainda não parei para subir este meu fonte de teste, mas em breve coloco ele no github. Uma dica é que para fazer a chamada do "putObjectInline" é necessário fazer um encode dos dados do arquivo. Teste enviar sem fazer isto para ver o erro. Isto é importante para qualquer situação futura. No exemplo abaixo tem um pedaço de código que faz isto. 

 

private String readFileAsString(String filePath) {
  //... tratamento de exceções e etc... 
  byte[] buffer = new byte[(int) new File(filePath).length()];
  FileInputStream f = new FileInputStream(filePath);
  f.read(buffer);
  String encodedImage = Base64.encodeBytes(buffer);
  //... tratamento de exceções e etc... 
  return encodedImage;
}

 

--

Quem escreveu este post? Daniel Wildt é CTO da Trevisan Tecnologia e curte ajudar o time a melhorar continuamente. Site no danielwildt.com e twitter @dwildt.

Conectando em instâncias AWS/EC2 - erro "Permission Denied (public key)"

E vamos para mais um artigo sobre Amazon Web Services! A propósito, já viu que tem um fórum em português de AWS? 

Quando queremos conectar em uma instância EC2 que criamos, acessamos o console do EC2, e selecionamos a instância que queremos conectar (na área Instances). Com isto nas ações da instância (Instance Actions), aparece o menu "Connect". Ao fazer isto vai aparecer algo como:

ssh -i nome-arquivo.pem root@id-da-instancia.compute-1.amazonaws.com

O arquivo .pem é da chave de acesso. Você fez download dele quando criou a sua instância. 

O usuário de login pode modificar. Exemplo, usando os AMIs padrões da Amazon o usuário será ec2-user, se você usar uma AMI Ubuntu, normalmente o usuário será ubuntu, se usar alguma AMI da Bitnami, o usuário será bitnami. Nas Red Hat AMIs, normalmente será usado root. 

Depois o endereço da instância é o endereço atual da mesma. Lembre que sempre que você para e inicia uma instância ela ganha um novo endereço. Para manter sempre o mesmo endereço você precisa ter um Elastic IP associado. 

Bom, vamos a situação... quando fiz acesso via SSH recebi um "Permission Denied (public key)". Revisei tudo que tinha feito, olhei na internet e depois voltei a revisar o meu passo a passo. 

O ponto é que sempre que criamos uma instância, temos que selecionar um Security Group.

Manualmente eu sempre tomei cuidado de criar security groups separados para cada tipo de instância. Só que neste teste que acabou "gerando" a mensagem de erro, eu criei a instância usando o ec2 console tools.

O ponto foi que o security group que estava sendo usado pela instância criada, não estava com a porta 22 liberada! Como eu sempre liberei a porta nos security groups, nunca tinha visto esta mensagem de erro. Por isto que eu sempre falo da importância do Test First, onde podemos ver uma falha, aprender e evoluir.  

Então qual foi a solução? Adicionar a porta de SSH, no caso a porta 22. E também aproveitei para adicionar a porta 80 que eu iria precisar usar. Este teste envolvia um servidor LAMP (Linux, Apache, MySql, PHP). Coloquei uma imagem com as configurações do security group. Com isto garanto que apenas o acesso via SSH e o acesso HTTP está funcionando para a instância em teste. 

Security-group

--

Quem escreveu este post? Daniel Wildt é CTO da Trevisan Tecnologia e curte ajudar o time a melhorar continuamente. Site no danielwildt.com e twitter @dwildt.

Amazon Web Services (aws) - Criando um storage usando Red Hat Enterprise Linux (RHEL)

Fizemos um post falando sobre como usar storages na Amazon. Naquele teste usamos o Linux da Amazon. Fazendo um novo teste usando Red Hat Enterprise Linux (RHEL), o resultado não foi o mesmo. Mostro aqui alguns detalhes para podermos fazer o attachment corretamente.

Ao ver os filesystems disponíveis não temos nada disponível:

# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/xvde1            5.7G  1.9G  3.8G  34% /
none                  296M     0  296M   0% /dev/shm

 

No teste foi feito um attachment em /dev/sdj, mas ao buscar nas partições ou através de um fdisk, ela não aparece.

# cat /proc/partitions
major minor  #blocks  name
 202       65    6291456 xvde1
 202      464    1048576 xvdad

Como comentado, o mesmo no fdisk:

# fdisk -l
Disk /dev/xvde1: 6442 MB, 6442450944 bytes
...
Disk /dev/xvdad: 1073 MB, 1073741824 bytes
...

A diferença em questão é que aparece um filesystem com 1GB que foi o espaço que tinha alocado para fins de teste. Então o /dev/xvdad é o que estamos procurando. Vamos seguir nos passos do post anterior, agora com a identificação que encontramos.

mkfs -t ext3 /dev/xvdad
echo "/dev/xvdad  /bkp  ext3     noatime  0 0" >> /etc/fstab
mkdir /bkp
mount /bkp

E para fechar executamos um df para ver o que temos definido:

# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/xvde1            5.7G  1.9G  3.8G  34% /
none                  296M     0  296M   0% /dev/shm
/dev/xvdad           1008M   34M  924M   4% /bkp

Era isto. O filesystem /dev/xvdad está montado em /bkp. 

Este ponto de dúvida eu tinha levantado no fórum da AWS, que já deixo como dica para trocar ideias com a comunidade. Aproveitei para explicar por lá o que eu tinha feito.  

E para fechar, fica a dica deste artigo do José Papo sobre o que é cloud computing. Neste post achei uma referência muito legal, sobre o que realmente precisamos estar atentos! Em saber diferenciar virtualização de cloud computing. Até a próxima! 

--

Quem escreveu este post? Daniel Wildt é CTO da Trevisan Tecnologia e curte ajudar o time a melhorar continuamente. Site no danielwildt.com e twitter @dwildt.

uMov.me completa 1 ano!

Não tem como deixar de falar sobre o primeiro ano do uMov.me. No dia 11 passado completamos 1 ano do lançamento público do uMov.me

Nossa equipe tem trabalhado diariamente para desenvolver um produto excelente, que os usuários tenham orgulho de usar. Nós temos orgulho de fazer! 

Deixamos alguns posts relacionados ao evento:

a) Release em português!

b) Infográfico também em inglês