quinta-feira, 28 de abril de 2011

Java 7: Modificações na Linguagem, em Detalhes e Exemplos

O JDK 7 é certamente uma das grandes novidades no universo Java, e essa versão da tecnologia está prestes a ser lançada. São muitas as modificações em relação à versão anterior, que podem ser divididas nas seguintes categorias: Máquina Virtual, Linguagem, Class Loader, Internacionalização, I/O e Rede, Segurança e Criptografia, JDBC, Camada Cliente e Gerenciamento (JMX e MBeans). Segundo o planejamento do projeto, o lançamento da versão final acontecerá no final de julho, mas já foram liberadas versões para testes por desenvolvedores e usuários finais, o JDK 7 Developer Preview referente ao milestone 12 do projeto. Essa versão pode ser instalada em Windows e Linux e todas as novas funcionalidades podem ser testadas. Mas, é claro, o Preview ainda não está pronto para uso em ambientes de produção, pois é garantida a presença de diversos bugs!
Nesse artigo serão discutidas especificamente as alterações feitas na linguagem de programação (sintaxe e semântica) que estarão disponíveis no JDK 7. As mudanças dizem respeito à JSR 334: Small Enhancements to the Java Programming Language, implementadas através do projeto Coin, um subprojeto do OpenJDK (veja mais sobre o Coin na seção de links ao final do artigo). Nas próximas seções, vamos apresentar cada uma das alterações que compõem a JSR 334, seguindo uma ordem crescente de complexidade. Os exemplos apresentados são sempre classes completas, com método main(), permitindo o teste direto e facilitando experimentações pelos leitores.

Separador de dígitos em literais numéricos

Com o objetivo de facilitar a leitura no código de literais numéricos longos, a partir do JDK 7 é possível utilizar o caractere "_" (sublinhado) como separador de dígitos. Dessa forma, um número como 99999999, por exemplo, pode ser escrito como: 99_999_999. Durante a compilação, o sublinhado é ignorado e o número é interpretado normalmente como se o separador não existisse. Apesar de a ideia ser interessante, é possível utilizar declarações que podem mais confundir do que ajudar, tais como:
  • 99_99
  • 9_9_9_9
  • 9_____999
Isso acontece porque a única restrição para o uso do separador de dígitos é de que não seja nem o primeiro e nem o último caractere. Vale citar que também é possível utilizar o separador em literais numéricos de ponto flutuante (double e float), como por exemplo:
  • 12__3.45___6D
  • 53_333.2397
A classe a seguir mostra como o separador pode ser usado em um programa.
public class SeparadorLiteraisNumericos {
2   public static void main(String[] args) {
3   byte b = 1_2_7;
4   int v1 = 999_999;
5   int v2 = 100_000 - 1_000;
6   Integer i1 = new Integer(12_12_12_1);
7   Integer i2 = new Integer(1_2_1_2_1_2_1);
8   double f = 123_456.3_4_1;
9
  System.out.printf("O valor de b e': %d\n", b);
1 0
1  System.out.printf("O valor de v1 e': %d\n", v1);
1
2  System.out.printf("O valor de v2 e': %d\n", v2);
1
3  System.out.printf("i1 e i2 são iguais?: %b\n", i1.equals(i2));
1
4  System.out.printf("O valor de f e': %.4f\n", f);
1
5  }
116 }
Ao executar esse programa, a seguinte saída é obtida:
O valor de b é: 127
O valor de v1 é: 999999
O valor de v2 é: 99000
O valor de f é: 123456
i1 é igual a i2?: true
.341 0

Literais Binários

Até a versão 6 do Java, era possível trabalhar com literais inteiros definidos como octais, decimais e hexadecimais. A partir da versão 7 também é possível trabalhar com literais binários. Para a grande maioria das aplicações comerciais isso pode não trazer grandes ganhos, mas em sistemas nos quais são frequentes as operações envolvendo bits, isso pode ser realmente útil. A sintaxe da nova declaração é simples, bastando iniciar o literal com 0b (zero e a letra 'b') seguido por uma sequência de 0s e 1s. Por exemplo:
  • 0b1100
  • 0b01
  • 0b1101
Os dígitos são alinhados à direita na área de memória, independentemente do tipo (byte, short, etc), ou seja, 0b11 é igual a 3, 0b101 é igual a 5 e assim por diante.
O código a seguir simula um log de estados de um sensor. Os estados possíveis que o sensor pode assumir são definidos pelos seguintes padrões binários: 01 indica que o sensor está desligado; 10 indica que está ligado e 11 indica que está em alarme. Para simular esses estados foi criado o método lerEstado que devolve aleatoriamente um inteiro com esses valores possíveis de estados além de um valor 0b00 indicando que não foi possível fazer a leitura (SEM_LEITURA). No método main() é executado um laço que lê o estado atual até que seja obtido o valor inválido e imprime uma mensagem informando o estado atual. Nesse programa simples, cada estado é representado por uma constante que depois será utilizada para indexar um array de mensagens.
1  public class GerenciadorSensor {
2   private static final int SEM_LEITURA = 0b00;
3   private static final int DESLIGADO = 0b01;
4   private static final int LIGADO = 0b10;
5   private static final int ALARME = 0b11;
6
  private static final String[] MENSAGENS = {"não disponível", "desligado", "ligado", "alarme"};
7   8
public static int lerEstado() {
9   
return (int)(Math.random()*0b100);
1 11  } 12
public static void main(String[] args) {
13 
4  System.out.printf("Os estados possíveis são: %s(%d) %s(%d), %s(%d), %s(%d)\n\n",
1
5  MENSAGENS[SEM_LEITURA], SEM_LEITURA, MENSAGENS[DESLIGADO], DESLIGADO,
116  MENSAGENS[LIGADO], LIGADO, MENSAGENS[ALARME], ALARME); 17 
int st = lerEstado();
18 
while (st != SEM_LEITURA) {
1
0  System.out.printf("O estado do sensor é: %s\n", MENSAGENS[st]);
2
1  st = lerEstado();
222  } 23  }
24  }
Uma saída possível para esse programa é:
Os estados possíveis são: não disponível(0) desligado(1), ligado(2), alarme(3)
O estado do sensor é: desligado O estado do sensor é: ligado
O estado do sensor é: alarme O
O estado do sensor é: desligado O estado do sensor é: alarme estado do sensor é: desligado
do
O estado do sensor é: deslig a
Observe que no main() são utilizadas as constantes de estados (inicializadas com valores literais binários), para acessar as posições do array contendo as mensagens.
E combinando o novo tipo binário com a nova sintaxe de separadores de dígitos, podemos ter:
private static final int SEM_LEITURA = 0b0_0;
private static final int DESLIGADO = 0b0__1;
private static final int LIGADO = 0b1_0;
private static final int ALARME = 0b1___1;

Variáveis do tipo String em comandos switch

Uma alteração muito útil na linguagem é que agora podem ser utilizadas Strings em comandos switch. Observe o programa a seguir, que recebe parâmetros de configuração através da linha de comando e executa ações específicas para cada parâmetro.
1  public class StringNoSwitch {
2   public static void main(String[] args) {
3   for (String param : args) {
4   switch(param) {
5   case "-test":
6   System.out.println("O programa está sendo executado em modo teste");
7   break;
8   case "-silent":
9   System.out.println("O programa envia poucas informações na saída padrão");
10  break;
11  case "-verbose":
12  System.out.println("O programa envia muitas informações na saída padrão");
13  break;
14  default:
15  System.err.printf("Parâmetro %s não reconhecido\n", param);
16  System.exit(-1);
17  } 18  } 19  }
20  }
Note que no switch da linha 5 é utilizada uma variável do tipo String para selecionar entre os vários casos de teste de condição. Apesar dessa ser uma alteração simples, esse recurso simplifica o código evitando uma estrutura complexa composta por varios ifs encadeados.

Inferência na Criação de Objetos de Tipos Genéricos

O suporte para tipos genéricos (ou parametrizados) é certamente um aliado do desenvolvedor, facilitando tanto a codificação quando a depuração. Com esse recurso, como sabemos, é possível informar tipos como parâmetros para classes e interfaces, fornecendo informações adicionais que permitem ao compilador detectar erros em tempo de compilação, que sem o uso dos tipos genéricos seriam detectados somente em tempo de execução.
Apesar das vantagens dos Generics, com esse recurso a linguagem também ganhou em complexidade. Veja um exemplo na classe InferenciaGenerics abaixo:
import java.util.*;
public class InferenciaGenerics {
public static void main(String[] args) {
Map<Integer, Set<Integer>> mapOfIntegers = new HashMap<Integer, Set<Integer>>(); 
  Integer aKey = 10;
new HashSet<Integer>();
  Set<Integer> aSet =
mapOfIntegers.put(aKey, aSet);
  }
}
No Java 7 é possível usar uma sintaxe mais enxuta para a criação dos objetos Map e Set acima, através da omissão dos tipos, com uma notação que foi apelidada de diamond:
import java.util.*;
public class InferenciaGenerics {
public static void main(String[] args) {
Map<Integer, Set<Integer>> mapOfIntegers = new HashMap<>();
Integer aKey = 10;
  Set<Integer> aSet = new HashSet<>();
mapOfIntegers.put(aKey, aSet);
}
}
Com essa sintaxe, os parâmetros de tipos usados na construção dos objetos são inferidos a partir dos parâmetros definidos na referência para esse objeto. Ou seja, em uma declaração Tipo<t1, t2, ..., tk> ref = new Tipo<>(), o compilador entenderá que new Tipo<>() deverá ser substituído por new Tipo<t1, t2,..., tk>().
Além disso, também é possível adiar a criação do objeto do tipo HashSet (aSet), fazendo-o na última linha da seguinte forma:
  mapOfIntegers.put(aKey, aSet = new HashSet<>());
Neste caso, os parâmetros do tipo são inferidos a partir daqueles usados na declaração da variável aSet. Note que a seguinte sentença não compila:
  mapOfIntegers.put(aKey, new HashSet<>()); //gera erro de compilação

Simplificação na Invocação de Métodos Varargs

Em Java, arrays e tipos genéricos não combinam muito bem. Observe o seguinte exemplo:
import java.util.*;
public class TesteVarargs {
3   public static void main(String[] args) {
4   Set<Integer> aSet = new HashSet<Integer>();
List<Set<Integer>> listOfSets = Arrays.asList(aSet);
6  }
7  }
Quando o programa acima é compilado com o Java versão <= 1.6 através do comando  javac -Xlint:unchecked Varargs.java, o compilador gera o seguinte warning:
TesteVarargs.java:10: warning: [unchecked] unchecked generic array
creation of type java.util.Set<java.lang.Integer>[] for varargs parameter
List<Set<Integer>> listOfSets = Arrays.asList(aSet);
^
Repare, no entanto, que não há nada de errado ou estranho com esse programa. Mas porque o compilador emitiu esse warning? Na verdade, o que acontece é que antes de o compilador gerar o bytecode é feita uma conversão no programa que literalmente modifica a linha 5, que fica assim internamente:
List<Set<Integer>> listOfSets = Arrays.asList(new Set[]{aSet});
Note que nessa conversão o Set usado para construir o array não contém mais a informação de tipo (em Java não é permitida a criação de um array usando generics) o que provoca o warning. Generalizando, esse warning é gerado sempre que é feita a chamada para um método com uma sintaxe do tipo a seguir:
<T> Tipo<T> metodo(T... params)
Aqui T e Tipo são dois tipos que podem ser parametrizados e, na ocasião da chamada do método em questão, as instâncias representadas pelo array params também estão com tipos genéricos. No exemplo apresentado, T é Set<Integer>enquanto que Tipo<T> é List<Set<Integer>>.
Uma forma de evitar esse warning é incluindo a anotação @SuppressWarnings("unchecked") no método, ou na linha imediatamente antes daquela onde o compilador indicou o warning. Apesar de resolver o problema, isso é um tanto inconveniente porque polui o código sem necessidade, visto que a chamada do método não pode gerar problema em relação à tipagem (heap pollution seria o termo usado aqui).
Observe que no exemplo apresentado não há nada que possa ser feito para evitar esse warning, a não ser adicionar a anotação. Assim, seria interessante que em casos desse tipo o compilador pudesse entender que a chamada não pode gerar problema. Para resolver essa situação foi criado no Java 7 a anotação @SafeVarargs.
A função dessa anotação é informar ao compilador que a operação de conversão forçada de arrays com tipos genéricos é segura, ou seja, que não acontecerá o heap pollution. Quando usada na declaração de um método com a sintaxe citada, essa anotação desonera as classes que chamam esses métodos da necessidade de utilizarem @SuppressWarnings. Isso é o que acontece, no JDK 7, com o método asList() da classe Arrays, como é mostrado a seguir, e também com alguns outros métodos da API.
@SafeVarargs
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
É importante observar que agora a responsabilidade de informar ao compilador para não gerar o warning é da classe que fornece a implementação e não da classe cliente que a usa.

Gerenciamento Automático de Recursos & Multicatch

Duas novidades que vão facilitar muito a vida do desenvolvedor Java são o gerenciamento automático de recursos e o "multicatch". Utilizaremos um exemplo para mostrar essas novas funcionalidades.
Suponha que precisamos de um programa que primeiro leia um arquivo texto contendo nomes de classes, com um nome por linha incluindo o pacote; e depois para cada linha, carregue e crie um objeto da classe fornecida, usando os metodos Class.forName () e Class.newInstance() da API de Reflection. Suponha também que os devidos tratamentos de erros sejam feitos.
Para fazer a leitura do arquivo seriam normalmente utilizados um FileReader e um BufferedFileReader, mas para esse exemplo foi criada uma classe que especializa BufferedReader, com o objetivo de simplesmente mostrar quando o método close() é chamado. O código dessa classe é apresentado a seguir:
1  import java.io.BufferedReader;
2  import java.io.IOException;
3  import java.io.Reader;
4  
public class MyBufferedReader extends BufferedReader {
5   
   public MyBufferedReader(Reader r) {
6
   super(r);
7
   }
89  
public void close() throws IOException {
10 
1  System.out.println("fechando o BufferedStream");
1
super.close();
1 13  }
14  }
Aqui está a classe responsável por solucionar o problema:
1  import java.io.FileReader;
2  
public class GerenciadorRecursosMultiCatch {
3   
   private static void instantiate(String className) throws Exception {
4
   try {
5
   Class<?> clazz = Class.forName(className);
67   Object o = clazz.newInstance();
etName()); 9   10  }
8   System.out.println(o.getClass().
gcatch (ClassNotFoundException e) {
11  System.err.println("Classe nao encontrada: " + className);
12  throw e;
13  } catch (InstantiationException e) {
14  System.err.println("Nao foi possivel instanciar a classe: " + className);
15  throw e;
16  } catch (IllegalAccessException e) {
17  System.err.println("Nao foi possivel instanciar a classe: " + className);
18  throw e;
19  }
20  }
21  22
 public static void main(String[] args) throws Exception {
23  MyBufferedReader br = new MyBufferedReader(new FileReader("classes.txt"));
24  try {
25  String line;
26  while ((line = br.readLine()) != null)
27  instantiate(line);
28  } finally {
29  br.close();
30  } 31  }
32  }
O main() é responsável basicamente por ler o arquivo classes.txt. O conteúdo de cada linha é passado para o método instantiate(), que tentará carregar a classe e criar uma instância.
Suponha que o arquivo classes.txt contenha somente a linha: java.util.ArrayList. Ao executarmos o programa acima, é obtida a seguinte saída:
java.util.ArrayList
fechando o BufferedStream
Caso alguma linha do arquivo classes.txt contenha o nome de uma classe que não exista no Java, como por exemplo: java.util.ArrayList1, a seguinte saída é obtida:
Classe nao encontrada: java.util.ArrayList1
fechando o BufferedStream
java.lang.ClassNotFoundException: java.util.ArrayList1 at java.net.URLClassLoad
Exception in thread "main "er$1.run(URLClassLoader.java:202)
...
Observe no método main() o uso do finally na linha 28. Nele, é chamado o método close() da instância de MyBufferedReader, com o objetivo de liberar os recursos alocados para usar o arquivo classes.txt. Note também que, tanto executando o programa com sucesso quanto em situações de erro, a mensagem: "fechando o BufferedStream" aparece. Ou seja, o finally é executado e os recursos são liberados corretamente em ambos os casos.
Essa abordagem no uso do finally é muito comum quando trabalhamos com acesso a banco de dados, manipulação de arquivos e IO em geral, entre outras situações. São em casos como esses que é necessário que o programa adquira recursos do SO quando necessário e os libere posteriormente.
Para tirar esse trabalho do desenvolvedor, o Java 7 traz o gerenciamento automático de recursos. Observe o código a seguir que demonstra essa funcionalidade no método main(), substituindo o mesmo método do exemplo anterior (classe GerenciadorRecursosMultiCatch):
22  public static void main(String[] args) throws Exception {
23  try(MyBufferedReader br = new MyBufferedReader(new FileReader("classes.txt"))) {
24  String line;
25  while ((line = br.readLine()) != null)
26  instantiate(line);
27  } 28  }
29  }
Com a mudança, a declaração e a inicialização do MyBufferedReader são feitas no próprio try. Isso determina que a instância terá seu método close() chamado automaticamente, de forma semelhante àquela obtida quando usamos o finally. Isso certamente evita confusões e erros na hora de liberar recursos.
Mas como o Java sabe quais classes podem ser usadas para fazer esse tratamento? A resposta é que agora existe a interface java.lang.AutoCloseable, com um único método: void close() throws Exception. Com isso, qualquer classe que implementa essa interface pode ser passada para o try, e o método close() será chamado corretamente. Em decorrência da chamada implícita do close(), esse try deve fazer parte de outro try contendo um catch para Exception; ou então o método deve lançar Exception.
Ao executar o programa de exemplo, após a modificação do método main(), você verá que ainda será mostrada a mensagem "fechando o BufferedStream", mesmo sem a chamada explícita do método close().
Continuando com o mesmo exemplo, passamos à demonstração do recurso de multicatch, que permite a um catch tratar múltiplas exceções. Dessa forma, quando existem vários catch fazendo um mesmo tratamento para exceções diferentes, é possível juntá-los em um único catch. Utilizando a nova sintaxe no método instantiate(), o trecho relevante do exemplo fica da seguinte forma:
4  private static void instantiate(String className) throws Exception {
5   try {
6   Class<?> clazz = Class.forName(className);
7   Object o = clazz.newInstance();
getName()); 9   10  }
8   System.out.println(o.getClass()
.catch (ClassNotFoundException e) {
11  System.err.println("Classe nao encontrada: " + className);
12  throw e;
13  } catch (InstantiationException | IllegalAccessException e) {
14  System.out.println("Nao foi possivel instanciar a classe: " + className);
15  throw e;
16  }
17 }
Como estávamos fazendo o mesmo tratamento para as exceções InstantiationException e IllegalAccessException, juntamos as duas exceções num só catch. Repare que as exceções são separadas por um caractere pipe, '|'. A sintaxe do multicatch é definida da seguinte forma:
try {
// código
} catch (Exceção 1 | Exceção 2 | ... | Exceção n variável) {
// tratamento da exceção
}
Aqui, Exceção 1 | Exceção 2 | ... | Exceção n são exceções (classes que herdam de java.lang.Exception) e variável é a variável na qual será atribuída a instância da exceção que foi lançada por alguma instrução no bloco try. A forma como é feito o tratamento da exceção no bloco exception continua igual ao que era feito antes dessa modificação de sintaxe.

Conclusões

Neste artigo foram apresentadas as mudanças na linguagem Java que estarão presentes no JDK 7. Essas mudanças foram propostas pelo projeto Coin, um subprojeto do OpenJDK, através da JSR 334. Entre as mudanças propostas, as que podem ser consideradas mais significativas são o suporte a strings na expressão do switch, o gerenciamento automático de recursos e, com o objetivo de reduzir a verbosidade da linguagem, os recursos de inferência de tipos genéricos e o multi-catch. O código fonte dos programas utilizados como exemplo estão disponíveis no Github.
Uma nota final: apesar de o itens apresentados nesse post estarem de acordo com o que foi sugerido na versão atual da JSR 334 e também em conformidade com a implementação disponível no OpenJDK, é possível que ainda ocorram pequenas mudanças até a finalização da especificação.

Links Úteis

Sobre o Autor

Wellington Pinheiro (@wrpinheiro) trabalha com desenvolvimento de sistemas desde de 1997, utilizando diversas plataformas e linguagens. Atuando como desenvolvedor e/ou arquiteto, já criou software em diversas grandes empresas, como Procwork, Toyota, Honda, CPqD, Orbitall, Universidade Metodista, entre outras. Atualmente, trabalha também como instrutor dos cursos da Academia do Java na YAW (empresa parceira da Globalcode) e da disciplina de Arquitetura de Software do curso de Pós Graduação em SOA no IBTA. Bacharel em Matemática e Mestre em Ciência da Computação pelo IME/USP, tem interesse especial em linguagens de programação, sistemas distribuídos e teoria da computação.

quarta-feira, 13 de abril de 2011

Como criar um widget com músicas do Grooveshark e inserir em seu site


Nível: Intermediário
Aplicativo necessário: Grooveshark
Passos: 10
Grooveshark é um dos principais sites para se ouvir música de graça na internet. Milhares de artistas possuem suas músicas cadastradas em seu vasto repertório musical, e é possível criar playlists, conhecer o gosto musical de seus amigos, ouvir as músicas mais quentes do momento - de acordo com o estilo - e muito mais.
Além de todas estas opções, o Grooveshark permite que você crie widgets e insira suas músicas favoritas em seu site. Para isso, basta criar uma playlist ou escolher uma faixa e criar um player para postar em qualquer página da internet.
Quer saber como? Basta seguir o passo a passo abaixo:
Passo 1. Acesse o Grooveshark e crie uma playlist ou encontre uma música que você deseja inserir no widget.
Passo 2. Assim que escolher uma faixa, clique em “Opções (1)”, “Compartilhar música (2)” e, por fim, em “Widget (3).
Widget para uma música (Foto: Reprodução/Camila Porto)Widget para uma música (Foto: Reprodução/Camila Porto)
Widget para uma playlist (Foto: Reprodução/Camila Porto)Widget para uma playlist (Foto: Reprodução/Camila Porto)
Para compartilhar toda a playlist, clique em “Reproduzindo agora/Incorporar músicas”.
Passo 3. Ao abrir a janela do widget um código será exibido. Se quiser utilizá-lo sem personalizações, basta copiá-lo e inserir em seu site, no HTML dele. Para personalizar o player, clique em “Personalizar”.
Passo 4. A versão gratuita do Grooveshark permite a utilização de apenas dois modelos de player: o Chamaleon, para playlists; e o Single Song, para apenas uma música. Escolha o modelo de acordo com a sua necessidade.
Passo 5. Depois de escolher o modelo de player, use o quadro “Stylize and Customize” para realizar suas modificações no tamanho e cores. Todas as modificações podem ser vistas automaticamente no modelo no lado direito do quadro de personalização.
Janela de personalização de cores (Foto: Reprodução/Camila Porto)Janela de personalização de cores (Foto: Reprodução/Camila Porto)
Passo 6. Depois de personalizar o player, clique em “Next Step” para continuar.
Passo 7. Na página seguinte, insira ou remova as músicas da playlist. Digite o nome da música em “Search for a Song” para procurá-la na base de dados do Grooveshark.
Adicionando ou removendo músicas (Foto: Reprodução/Camila Porto)Adicionando ou removendo músicas (Foto: Reprodução/Camila Porto)
Passo 8. Ao encontrar a música, clique no símbolo de “+” ao lado dela para adicioná-la ao player.
Passo 9. Assim que concluir a criação do widget, clique em “Finish” para acessar as opções de compartilhamento.
Passo 10. Copie e cole o código fornecido pelo Grooveshark em seu site ou compartilhe o player nas redes sociais.

Como criar um feed para seu blog


Nível: Básico
Material/Aplicativos necessários: Conta no Google e um blog cadastrado no Blogger
Número de passos: 3
Você, internauta atento, certamente já ouviu falar em "feeds de notícia". Eles são usados para acompanhar os novos posts de um blog ou site sem que você seja obrigado a acessá-lo; ou seja, blogueiros que não têm um feed para seus visitantes assinarem estão perdendo uma grande chance de ter uma quantidade maior de acessos ao seu conteúdo.
Uma forma de colocar um feed no blog é indo na página "Design" do seu Blogger e inserir o gadget "Links de inscrição". Já resolveria o seu problema. Porém, optando pelo serviço ofertado no site "Feed Burner", você tem como escolher um endereço fixo para o seu feed - e nem é tão mais complicado assim. Veja só:
Passo 1. A primeira coisa a fazer é ir ao site Feed Burner e logar com sua conta do Google;
Passo 2. Na tela seguinte, você vai ler a frase: "Burn a feed right this instant. Type your blog or feed address here". Digite o link do seu blog e clique em "Next";
Passo 3. Agora você escolhe em "Feed Address" o melhor link para seu feed. Clique no "Activate Feed" e depois, se não souber inglês, vai apenas clicando em "Next" até acabar;
Pronto. Seu Feed de notícias RSS está feito! Basta colocar o link (http://feeds.feedburner.com/linkquevcescolheu) no seu blog para as pessoas assinem e vejam o conteúdo no seu feed reader predileto.
Na tela inicial do FeedBurner, você tem acesso a várias informações, dentre elas, a quantidade de pessoas que assinaram seu feed  (Foto: Reprodução/Fabricio Janssen)Na tela inicial do FeedBurner, você tem acesso a várias informações, dentre elas, a quantidade de pessoas 

No setor de TI, certificação vale mais que faculdade

Para conseguir um emprego no setor de TI, ter uma certificação vale mais que o diploma de graduação e é fator decisivo na hora das empresas escolherem os seus novos funcionários.
Isso acontece porque as empresas são avaliadas por padrões internacionais que exigem que elas tenham funcionários com certificações nas suas folhas de pagamento. Não pense que faculdade não conta no seu currículo, longe disso! Estudar, se relacionar  e ter novas experiências nunca é demais em qualquer carreira.
Mas cuidado, a certificação garante o emprego mas não a evolução na carreira, portanto, estar sempre atualizado com as tendências mundiais é uma questão de sobrevivência neste setor. Se você pretende seguir uma carreira de TI, prepare-se para estudar o resto da vida (neste caso, praticamente qualquer carreira que seguir, terá que estudar para se manter bem colocado).
O setor de TI no brasil está muito aquecido, vivendo o seu melhor momento nos últimos tempos, mas a falta de profissionais especializados é um fator preocupante para as empresas e isso faz com que os salários fiquem bem atrativos.
Além da escassa mão de obra qualificada, as exigências de conhecimentos muito específicos dos profissionais também garantem bons salários e até mesmo acima da média para o setor.
Só não se ache a última bolacha do pacote pedindo salários exorbitantes. Tenha em mente que uma carreira não é feita somente de salário!
FONTE: PROFISSIONAIS TI

Vantagens do JQuery

Atualmente quem trabalha com web se vê cada vez mais necessitado de utilizar e aprender novas ferramentas.
Muitas podem ser consideradas supérfulas, porém, algumas são essenciais pra quem deseja fazer um bom trabalho e uma delas é a jQuery.
jQuery pode parecer complicada e até ser muito código para aprender à primeira vista, mas como o próprio slogam diz: “write less, do more”.
Vou apresentar agora 5 motivos para você aprender jQuery e finalmente ajudar a tornar a web um  lugar melhor: 
1 – Produza mais – jQuery te permite fazer coisas que normalmente se digitaria muito pra fazer usando javascript comum. Com o objeto jQuery ($) podemos selecionar muitos objetos da página ao mesmo tempo e tratá-los de acordo com nossa vontade. Veja alguns exemplos:
Ao levar o mouse no link com id “palavra”, tornar visível a div com id “dica”:
objlink = document.getElementById("palavra");
objlink.onMouseOver = function(){
document.getElementById('dica').style.visibility = 'visible';
}
 
O mesmo código em jQuery:
$('a#palavra').mouseover(function(){
$('div#dica').show();
});
2 – Efeitos especiais – A biblioteca jQuery já vem com muitos efeitos prontos, além dos que você já pode utilizar, tais como o método animate(), show(), hide(), fadeIn() e fadeOut(). Utilize esses métodos pra dar um ar mais profissional ao seu site.
3 – Modularização – jQuery oferece um grande suporte à modularização, graças à possibilidade de criar plugins. Com isso podemos facilmente aproveitar nossos códigos mais utilizados, como também utilizar centenas de plugins prontos disponíveis na net, o que nos poupa um grande tempo.
4 – Validações de formulários – Quem trabalha com web sabe que não existe coisa mais chata que validar grandes formulários. Imagine dizer para o usuário que cada um dos 60 campos do formulário é obrigatório, que alguns precisam validar email e outros precisam validar se o formato é um telefone válido. Isso parece ser uma grande dor de cabeça, mas graças à alguns plugins do jQuery, tudo isso pode ser resolvido com algo em torno de 5 ou 6 linhas de código.
5 – Trabalhe com ajax – jQuery oferece um grande suporte para trabalhar com ajax. Podemos utilizar as funções post() e ajax() para realizar solicitações assíncronas, tudo isso com suporte à callback, ou seja, suporta a chamada de uma função assim que tal evento ocorrer. Exemplo: ao término da solicitação, chamar um alert();

terça-feira, 12 de abril de 2011

Gerencia de Progetos

Todas as empresas, mesmo as pequenas, usam alguma ferramenta para gerenciar a produção e os prazos dos seus projetos. Nem que seja tudo organizado em uma pasta cheia de planilhas do Excel, atualizadas diariamente, até um super gerenciador de tarefas extremamente caro, que só falta realizar o seu trabalho para você. Alguns utilizam softwares apropriados para seu trabalho, e dali extraem relatórios de produção. Algumas empresas, de todo o tipo (mas principalmente de Tecnologia da Informação), preferem usar gerenciadores de projeto. Uma ferramenta muito eficaz se usada com sabedoria.
Alguns desses gerenciadores são voltados para calcular o trabalho dispensado em cada projeto, outros para relacionar custos e horas trabalhadas, outros para controlar a demanda de trabalho, outros dividem os projetos em pequenas tarefas, etc. Esses sistemas são largamente usados na área de Tecnologia da Informação, mas também são muito úteis para órgãos públicos de todo o tipo e empresas que trabalham exclusivamente com prazos, não importando a área.
É impossível falar em gerenciadores de projeto sem falar de métodos de administração de projetos. Temos muitos métodos documentados que mostram como direcionar a equipe e qual linha de acompanhamento seguir (PMBOK, Cobit, Scrum, etc), e o software de gerenciamento podem ser adaptáveis ou não ao método adotado pela empresa. Então, é indispensável definir o melhor jeito de tornar as coisas ágeis e simples para seus funcionários e colegas. Depois de definido o método usado, é hora de gastar no mínimo um mês avaliando os gerenciadores disponíveis no mercado.
Existem muitas opções open source, mas nem sempre eles são as opções mais indicadas – o que parece ser uma economia agora, pode se tornar uma dor de cabeça de atrasos e acúmulo de backlog. Sou entusiasta das soluções free, mas infelizmente a área dos gerenciadores de projetos não é prioridade da comunidade do software livre. Analise as opções do mercado e utilize-as na fase de teste; mas utilize mesmo, teste o sistema a fundo. Eu sei que dá um pouco de trabalho, e faz-nos gastar um tempo que não temos, mas vale à pena testar. E é muito melhor se você pedir para os colegas testarem junto, pois esses sistemas são feitos para a equipe se comunicar e se atualizar junta, então é sempre bom levar o software à exaustão de acessos simultâneos, e explorar ao máximo os recursos de comunicação entre os usuários, para ver se funcionam mesmo.
Nessa fase de avaliação, ressalto alguns itens importantíssimos para serem observados:
  • Usabilidade: é fácil entender o funcionamento do sistema? É possível sair usando-o de primeira? Ele é óbvio? O fluxo de trabalho é facilmente entendido só ao tentar usar o software?
  • Hierarquia: o modo de permissão de acesso a usuários ao sistema é adaptável? Corresponde ao modo de trabalhar do grupo? Garante segurança das informações?
  • Informação: o software que você está testando consegue manter a equipe bem informada de tudo o que está acontecendo? Ele permite que todos os usuários se situem na exata fase do projeto em que estão? Todos conseguem ficar atualizados sobre o projeto sem acessarem-no, só com e-mails enviados automaticamente pelo software?
  • Stakeholders: os clientes podem acompanhar os projetos periodicamente através do sistema?
  • Controle de riscos: é possível prever os riscos do projeto? Há uma interface de alerta a respeito de alguma indeterminação de retorno financeiro nos cálculos sobre o investimento do projeto?
  • Calendário: é possível criar um cronograma agendado de trabalho que opere com mudanças freqüentes de prazos? Esse recurso possibilita a visualização de atrasos e adiantamentos em algum relatório?

Na minha opinião estritamente pessoal, prefiro os gerenciadores que operam direto no navegador dos usuários, como se fosse um site ou uma intranet que permitisse a administração dos projetos. Também é muito importante, a nível bem gerencial, o uso de gráficos que mostre o valor-hora relacionado aos recursos usados nos projetos, desde os funcionários envolvidos até as aquisições materiais e terceirização de serviços. Existem alguns gerenciadores que agregam as habilidades administradoras dos gerentes: controlam as horas trabalhadas dos colaboradores, independente de estarem em um projeto ou não, agendam as atividades das equipes, facilitam a montagem de um workflow, agregam o registro de demanda de serviço – e não só de projetos -, e permitem vários tipos de consulta.
Os gerenciadores são grandes facilitadores se usados com sabedoria, torno a dizer.
Depois de escolhido o melhor software, é hora de implementá-lo e aderir o seu uso à cultura da empresa. Essa é a parte mais espinhosa, principalmente porque os gerentes e funcionários normalmente não estão habituados a descrever suas atividades diárias, e nem a ler com atenção o que lhes é proposto, bem como aprender a usar uma nova ferramenta – o que torna o uso do gerenciador muito difícil nas primeiras semanas. Uma grande campanha de conscientização é necessária neste momento. Um e-mail de explicação ou até uma palestra, ou um curso de capacitação, são imprescindíveis nessa hora delicada. Por isso é importante lembrar que durante uma fase confusa ou de excesso de trabalho, a implantação de um gerenciador só atrapalharia o trabalho. Esse tipo de solução deve ser integrada na rotina das pessoas de modo suave, para que o esgotamento diário não sirva de argumento contra o uso do software, ou pior ainda; para que não torne o gerenciador o grande vilão da gestão.
Em suma, a equipe que trabalha bem com o gerenciador de projetos só agrega benefícios a si: organização, agendamento, controle de gastos, comunicação, e gerenciamento otimizado. O gestor também se dará conta das maravilhas que um simples programa de computador pode fazer para facilitar sua vida. A boa visualização do que está acontecendo dentro da corporação, ou do setor, é um recurso excelente para administrar bem uma equipe.
Abaixo seguem links de softwares gerenciadores de projetos que eu recomendo – mas não atenha-se somente a estes, procure mais.