Archive for the Atividades profissionais Category

Por que eu escolhi ser programador / Saber programar em uma ou várias linguagens?

Posted in Atividades profissionais, Temas polêmicos on 02/09/2012 by Allan Taborda

O post de hoje possui dois assuntos, ambos voltados ao desenvolvimento de software. O primeiro é sobre por que eu escolhi ser programador (e por que talvez seria bom você escolher essa profissão). O segundo é sobre saber programar em uma ou em mais linguagens de programação.

Antes de eu entrar na FATEC de Praia Grande e cursar o curso de Tecnologia em Informática com Ênfase em Gestão de Negócios, eu pensava em ser professor de matemática e dar aulas em escolas públicas e particulares, da quinta série até o ensino médio, ou ser técnico de computadores, dando manutenção em PCs, consertando-os, montando-os, resolvendo pepinos no sistema operacional, etc, já que eu tinha feito um curso de hardware numa escola profissionalizante. Aí eu acabei passando no único vestibular que eu tinha feito, que era o da FATEC de Praia Grande (passei em décimo segundo lugar entre 254 candidatos, mesmo sem ter estudado para a prova) e cursei aquele curso, no período da tarde.

No curso, aprendi muitas coisas, como o uso e administração de banco de dados, com ênfase no Oracle e sua linguagem PL/SQL; análise de sistemas, que engloba a elaboração dos requisitos do programa, dois casos de uso e criação de diagramas diversos, incluindo o diagrama UML; lógica de programação e estrutura de dados, ambas as matérias usando a linguagem de programação C++ como base; linguagem de programação Java, tanto para desktop quanto para web; gerência de projetos, com ênfase na metodologia PMI; matérias teóricas acerca de sistemas de informação; planejamento de negócios, onde aprendi a elaborar um plano de negócios a fim de montar um negócio próprio; etc, além de matérias menos importantes, como filosofia, recursos humanos, cálculo numérico, computação gráfica, matemática (matrizes e vetores), estatística, marketing, inglês e espanhol, e outras.

Um profissional formado no curso que eu fiz pode atuar em diversas áreas relacionadas ao conteúdo do curso explanado no parágrafo anterior. Pode atuar tanto na área de gestão de negócios (a metade do curso é formado por matérias relacionadas a gestão de negócios) quanto em profissões voltadas à informática, como programador, analista de sistemas, administrador de banco de dados, etc. Para cada profissão, o profissional deve, além de usar o conhecimento obtido no curso, se aprofundar na área buscando conhecimento de outras fontes (cursos específicos, principalmente), uma vez que o curso de Tecnologia em Informática com Ênfase em Gestão de Negócios (que atualmente chama-se Informática para Gestão de Negócios e teve algumas alterações a fim de melhorar o mesmo) não ensina tudo (nem existe curso que ensine tudo), mas dá uma boa base para ir começando e depois se aprofundar na profissão escolhida.

Dentre essas profissões relacionadas, eu escolhi ser programador. Como no curso houve uma ênfase maior na linguagem de programação Java, foi natural eu escolher programar nessa linguagem. Posteriormente, me aprofundei nos meus conhecimentos em Java obtendo a certificação SCJP (fiz um post sobre a obtenção dessa certificação neste blog inclusive) e estudando por conta própria por livros e tutoriais na Internet. Pretendo no futuro tirar mais certificações Java (a próxima será a SCWCD, que agora é OCWCD, uma vez que a Sun foi comprada pela Oracle), além de fazer cursos com conhecimentos mais avançados.

Mas por que eu decidi ser programador, e não analista de sistemas ou administrador de banco de dados, por exemplo?

O principal motivo é que programar é uma coisa que me dá prazer (tá, sexo também me dá prazer, mas acho muito perigoso trabalhar como profissional do sexo, além da concorrência estar brava nesse ramo). Eu sinto prazer em criar aplicações (e também alterar aplicações já existentes, melhorando-as) e vê-las funcionando bem, fazendo o que foram projetadas para fazer. Gosto tanto de programar que programo não apenas profissionalmente, como também por hobby, desenvolvendo meus projetos pessoais de software, como o Robowebert Player e o AOPT, ambos já citados aqui neste blog.

Outro motivo é a grande quantidade de vagas de emprego existentes no mercado de trabalho. Devido à escassez de profissionais qualificados em desenvolver softwares (e para piorar a situação, há os qualificados que não sabem programar direito), aliada à alta demanda por esses profissionais, uma vez que milhares de sistemas precisam ser desenvolvidos do zero ou alterados a fim de ficarem aos gostos dos clientes, os profissionais que se qualificam têm praticamente emprego garantido (apesar do primeiro emprego como programador ser um pouco mais difícil de se conseguir, devido à falta de experiência e ao fato do fato da maioria dos empregadores exigir experiência anterior, mas há quem contrate programadores sem experiência, além de ser possível obter experiência por conta própria, desenvolvendo sistemas como autônomo, ou começar como estagiário), com um salário maior do que muitas profissões por aí (a não ser que comece como estagiário), ainda que o mesmo não seja tão grande nos primeiros empregos.

Um outro motivo, este um pouco polêmico, pois não é um consenso entre os programadores, é o salário, que eu acho que é um bom salário. Eu não vou dizer o quanto eu ganho, mas é o suficiente para pagar minhas contas e juntar um pouco na poupança. Mas há os que acham que não ganham um bom salário, agora vai saber que salário eles ganham… Já vi gente achar um valor que era mais ou menos o que eu ganhava aviltante (vai saber quais são as necessidades de dinheiro do cara, como ele administra o dinheiro dele…), já vi gente exigindo salários muito altos e irreais e já vi gente se contentando com um pouco mais da metade do que eu ganho atualmente para fazer a mesma coisa que eu faço.

Um programador de início de carreira não vai ganhar um salário tão alto, mas a medida que ele vai ganhando experiência, seu salário vai aumentando, seja com aumento salarial dado pela empresa onde trabalha ou quando esse programador muda de emprego, sendo contratado por uma outra empresa que paga um salário maior do que a empresa anterior, visto que agora possui mais experiência profissional do que quando entrou no emprego anterior.

Ainda na questão do salário, a relação esforço/remuneração, em minha opinião, é melhor do que a de outras profissões relacionadas à informática, como a de técnico de computadores, que é uma relação bem ruim, pois um técnico ganha muito menos e se esforça muito mais do que um programador (eu ensaiei ser técnico e vi o esforço que era, além de assuntar quanto um técnico ganhava), ou a de administrador de servidores.

Um programador, por saber programar, caso tenha alguma necessidade não suprida por algum programa de computador existente, pode criar o seu próprio programa que satisfaça essa sua necessidade, sem depender de algum outro programador ou empresa que desenvolva esse programa. Pode também alterar um programa já existente, adaptando-o às suas necessidades.

São basicamente esses cinco motivos de por que eu escolher ser programador. Talvez haja mais algum outro que eu não me lembre, mas o mais importante é isso.

Emendando um assunto no outro, existe a questão de saber programar em uma ou em mais linguagens de programação. O que seria melhor para o profissional de desenvolvimento de software, saber apenas uma ou saber um monte delas?

No mercado de trabalho, há vagas para trabalhar como programador de várias linguagens de programação, algumas tendo mais vagas que outras (Java, C# e VB.net costumam ter muitas vagas). Sabendo mais de uma, teoricamente, o programador possuirá mais chance e mais qualificação no mercado de trabalho.

Já vi alguns afirmarem que o melhor é saber várias linguagens, pois o mercado de trabalho pode mudar e uma outra linguagem passar a ser mais usada que outra, ou porque sabendo várias, o programador tem mais chance de ser contratado, ou outros motivos. Mas há um porém de saber várias linguagens de programação: você acaba dividindo seus estudos entre várias e não aprofunda seus conhecimentos em nenhuma, muitas vezes sabendo apenas o básico de cada uma delas. Aí não vai adiantar nada saber mais de uma e não saber programar direito em nenhuma, cometendo erros de, por exemplo, na linguagem Java, comparar Strings com dois sinais de igual ao invés de usar o método equals (eu já cheguei a, neste blog, dedicar dois posts para enumerar erros irritantes cometidos por programadores Java, e talvez eu dedique outros no futuro) ou não saber usar uma biblioteca na qual o uso da mesma é melhor do que uma outra que é mais simples e mais arcaica, mas que é a única que o programador sabe (por exemplo, o programador não saber JPA e fazer a persistência dos dados no banco de dados com JDBC, que é bem mais trabalhoso).

Muitas vagas para se trabalhar programando em uma linguagem requerem conhecimentos específicos em frameworks e bibliotecas e um profissional que não se aprofunda nessa linguagem terá menos probabilidade de saber esses conhecimentos específicos.

E não apenas os estudos são divididos entre várias linguagens de programação: a experiência profissional pode acabar também sendo dividida. Há vagas que requerem um ou mais anos de experiência com a linguagem em questão. Se você dividiu sua experiência profissional entre várias linguagens, irá demorar mais para obter os anos de experiência em cada uma das linguagens.

Então o programador deve saber apenas uma linguagem e se aprofundar somente nela? A resposta é: Não. Apesar de as linguagens de programação não ficarem obsoletas e deixarem de ser usadas da noite para o dia e de haver muitos sistemas legados, feitos em linguagens antigas, como Cobol e Clipper, que demandam manutenção por serem usados até os dias de hoje, pode ocorrer de, no futuro, uma determinada linguagem outrora popular deixar de ser tão usada (foi o que ocorreu com o Delphi, por exemplo, que era uma linguagem muito popular aqui no Brasil, mas atualmente não é tão usada pelas empresas ao implementar sistemas novos, a não ser uma ou outra empresa). Além disso, há softwares que são melhor implementados usando determinadas linguagens do que outras devido a particularidades dessas linguagens.

O que eu aconselho é se aprofundar em uma em específico e, após estar bem aprofundado nessa linguagem, começar a aprender uma segunda linguagem (ou até uma terceira linguagem, caso deseje aprender duas de uma vez, aí depende de você), mas sem se estagnar na primeira, pois as plataformas de desenvolvimento de software estão em constante evolução, mesmo linguagens antigas, como C e C++. Se você sabe lógica de programação, já é meio caminho andado para se aprender uma linguagem nova e sua sintaxe (a outra metade do caminho são os conhecimentos específicos que estão além da sintaxe da linguagem). Aí, com o tempo, você vai se aprofundando nessa segunda (ou terceira) linguagem, podendo, dependendo de seus conhecimentos, atuar profissionalmente utilizando as mesmas.

O ideal é saber pelo menos umas duas ou três, mas se você é iniciante no desenvolvimento de software, uma já é mais que o suficiente.

Antes que me perguntem, além do Java, que a linguagem na qual eu programo profissionalmente, eu sei um pouco de C e C++ (estou aprendendo ambas ao mesmo tempo por serem semelhantes, apesar de que, por falta de tempo momentânea, parei de estudá-las), JavaScript (inclusive usando a biblioteca JQuery, a uso bastante no ambiente de trabalho na interação do usuário com o navegador, se bem que JavaScript não é bem uma linguagem de programação como Java, C# e outras), PL/SQL (também não é bem uma linguagem de programação como Java, C# e outras, mas dá para programar nela, tal qual JavaScript, é uma linguagem do banco de dados Oracle) e um pouco (muito pouco) de Delphi/Lazarus. Pretendo me aprofundar nessas linguagens e aprender outras no futuro.

Por hoje é só, até o próximo post.

Minha experiência com um MacBook Pro

Posted in Atividades profissionais, Temas polêmicos on 29/07/2012 by Allan Taborda

Quem me conhece, sabe que eu não sou fã da Apple e de seus produtos. Sempre critiquei a postura dessa empresa com relação às suas restrições absurdas de design e usabilidade, além de suas políticas restritivas tanto em seus produtos, como no que entra ou não na app store do iPhone por exemplo, quanto com relação às ameaças desleais aos seus concorrentes, processando a todo custo os mesmos por violação de supostas patentes, não com intenção de ganhar dinheiro em cima, como faz a Microsoft, mas com a intenção de eliminar os concorrentes do mercado. Isso sem contar nos erros de projeto que têm ficado cada vez mais frequentes, como iPad que esquenta muito e iPhone que pega fogo e tem problema de sinal caso segurado pelo usuário da maneira tradicional (e a Apple, na maioria das vezes, não admite as falhas, fazendo de conta que não existem).

Eu sempre critiquei a Apple (na verdade, nem sempre, só passei a criticar após conhecer melhor a empresa e ouvir falar mais de seus produtos e ver como eles realmente eram, antes disso, eu até achava legal a empresa devido a comentários de terceiros e, devido a esses comentários, tinha uma imagem positiva da Apple), mas até então nunca tive que usar um produto da empresa por um tempo prolongado. Minhas experiências anteriores com produtos da Apple se resumiam a duas vezes que usei o iPad, uma vez a primeira versão do tablet, na Saraiva, localizada no Shopping Metrô Santa Cruz, e a outra vez o iPad 2, na Fast Shop, próxima ao Metrô Carandiru. Nas duas vezes, eu abri alguns programas (não vi nada de mais nos mesmos), mas não consegui fechar nenhum deles por não descobrir de jeito nenhum como fazer isso. Na primeira vez, eu tentei até acabar a bateria do bagulho, na segunda o iPad tinha acesso à Internet e pesquisei no Google como fechar os programas e vi que existem tutoriais completos apenas para fechar programas no iPad (algo que deveria ser simples, como clicar num ícone de fechar o programa), mas acabei achando o tutorial demasiadamente complicado e desisti. O iPhone eu nunca usei (me parece que é praticamente o mesmo sistema operacional do iPad), o iPod menos ainda, e o MacBook eu tinha olhado por cima duas vezes em lojas de eletrônicos e não vi nada de mais, mas também não deu para tirar nenhuma conclusão, a não ser que o sistema operacional parece um “Linux com um ambiente gráfico diferente”.

Dos produtos Apple, o que eu tinha uma imagem menos negativa era justamente o MacBook, bem como o iMac (a diferença é que um é desktop e outro é notebook, mas ambos são “computadores tradicionais” da Apple). Eu tinha uma imagem menos negativa principalmente pelo fato de eu não ser fã de smartphones e tablets, independente de ser da Apple ou não, e ser mais fã de computadores tradicionais (desktops e notebooks). Mas, como eu já havia dito, nunca havia usado um computador da Apple por um tempo prolongado.

Nesta última semana, comecei a trabalhar numa nova empresa. Quando eu comecei a trabalhar, não havia um computador para mim, então a empresa teve que comprar um novo (que não é da Apple e provavelmente virá com Windows). Enquanto o novo computador não chegava, eu usei um outro pertencente a um colega que estava de férias no momento. Este outro computador era um MacBook Pro, o único computador da Apple da empresa (acredito eu). Este MacBook Pro possuía processador Core 2 Duo 2,53 GHz e sistema operacional MacOS X (sistema operacional exclusivo dos computadores da Apple), versão 10.6. Eu aceitei usar aquele notebook e passei a semana toda trabalhando no MacBook Pro. Para quem não sabe, eu sou programador Java. Agora, irei contar como foi essa minha experiência com o MacBook Pro. Vou adiantando desde já que não foi uma boa experiência.

Eu até estou conseguindo realizar meu trabalho, mas com um rendimento bem abaixo do que eu costumo ter quando uso um computador normal, com Windows ou Linux. Não devido a “mudar a cor do pasto”, porque eu costumo me adaptar bem a alterações de interface, como quando eu passei a usar o Gnome no lugar do KDE como ambiente gráfico do Linux e quando testei outros ambientes gráficos e sistemas operacionais, mas devido a vários problemas de usabilidade que encontrei.

Um dos problemas era que os programas tinham teclas de atalho diferentes do que costuma ser o padrão dos programas Windows/Linux. Muitas vezes, as teclas de atalho envolviam o uso de uma tecla que só existe no Mac, a tecla Command, a maioria das vezes substituindo a tecla Ctrl, apesar do Macbook ter a tecla Ctrl, que é usada em outras combinações de atalhos.

Além disso, algumas teclas tradicionais não possuem o mesmo comportamento como em outros computadores, como por exemplo a tecla End, que, quando pressionada, deveria fazer o cursor ir para o fim da linha, mas no MacOS X, faz o cursor ir para o final do documento ou não tem efeito algum. Talvez até exista uma maneira de como fazer o cursor ir para o final da linha (uma combinação de teclas talvez), mas não consegui descobrir e nem pesquisei como (isso é uma coisa que deveria ser algo intuitivo de ser feito).

Ainda com relação às teclas, apesar do MacOS X instalado no equipamento ser em português do Brasil, os dois teclados (o do notebook e outro USB, provavelmente o dono do equipamento não gostava do teclado do mesmo e plugou um USB, também da Apple, feito de alumínio) não possuíam teclas de acentuação e a tecla C cedilha, fazendo com que, quando eu precisasse acentuar as palavras, eu tinha que recorrer ao corretor ortográfico (quando tinha no programa em questão) e torcer para que o corretor corrigisse corretamente, quando não corrigia corretamente, ou quando não tinha corretor ortográfico, eu jogava a palavra no Google para ver se aparecia resultado escrito com acentuação correta ou copiava e colava o caractere acentuado de outro lugar, ou escrevia sem acento mesmo. Na verdade, até tinha alguns acentos no teclado, como o acento circunflexo na tecla 6, ativado em conjunto com a tecla Shift (nos teclados tradicionais, padrão ABNT2, a tecla 6 possui o trema), mas quando pressionadas as teclas com acentos, tanto antes quanto depois da letra a acentuar, o acento não ficava sobre a letra, ou seja, não servia para nada.

O teclado de alumínio USB tinha teclas de funções até o F19 (no do MacBook, só havia até o F12, como os teclados tradicionais). Para que serviam essas teclas de funções extra eu não sei, mas o que tinha de teclas de função de mais, tinha de teclas essenciais de menos. Por exemplo, não havia, além dos acentos e C cedilha, teclas como a Insert e a Print Screen. A tecla Backspace estava com o nome de “Delete”, apesar de ter outra tecla Delete, que era a Delete normal.

O principal problema de usabilidade do sistema operacional era a alternância falha entre os programas abertos, usando as teclas Command e Tab (equivalente à combinação entre as teclas Alt e Tab nos PCs normais). Mesmo quando um programa era fechado, ele ainda constava na lista de programas a alternar, atrapalhando a alternância entre programas e obrigando o usuário a clicar mais vezes no Tab ou a clicar no ícone presente no dock (uma barra de ícones que fica na parte de baixo da tela, com um efeito visual quando se passa o mouse sobre o mesmo). Além disso, o MacOS X trabalha com o conceito de alternância entre programas como um todo, com todas as suas janelas abertas (independente de quantas sejam), não das janelas individualmente, o que atrapalha a alternância entre as mesmas.

Parece que, mesmo após um programa ser fechado, ele continuava aberto em partes, constando na lista de programas a alternar e no menu da barra superior (no MacOS X, os menus ficam integrados à barra superior ao invés de ficarem localizadas nos próprios programas, algo aceitável, porque não atrapalha a usabilidade, apenas se muda o lugar do menu). Para fechar o programa completamente, tinha que se clicar na opção correspondente na barra de menus, e isso não funcionava para todos os programas.

Ainda sobre os programas abertos, não há como saber que programas estão abertos ou não, pois o dock exibe tanto os programas abertos quanto os fechados e não há uma barra de tarefas informando quais são os programas abertos, como ocorre nos outros ambientes gráficos. Só se sabe quais estão abertos minimizando todos eles.

O menu do MacOS X não possui uma lista dos programas instalados. Quando eu precisei de uma calculadora (e a mesma não estava presente no dock), recorri à busca presente no menu. Só depois que eu descobri que, para ver quais eram os programas instalados, tinha que abrir o gerenciador de arquivos, chamado de Finder. É como ter que abrir o Windows Explorer para saber quais são os programas instalados no Windows ou ter que abrir o Nautilus para saber quais são os programas instalados no Linux (ou FreeBSD, ou outro sistema que utilize o X Window System) com Gnome.

O programa responsável por editar arquivos TXT é o Editor de Texto (o nome é esse mesmo), apesar disso, caso o Editor de Texto seja aberto sem abrir um arquivo TXT existente, não há a opção de salvar o arquivo no formato TXT. O Safari, o navegador web padrão do MacOS X, possui problemas de usabilidade diversos, como não ter barra de status ou algo equivalente informando o destino de um link e não ter como voltar ou avançar mais de uma página no histórico de navegação (pelo menos, tinha o Firefox instalado).

Com relação ao hardware, o touchpad (área onde o usuário movimenta o mouse deslizando o dedo, presente na grande maioria dos notebooks) não possuía os dois botões relativos ao clique com os botões esquerdo e direito. O teclado presente no notebook possuía teclas com iluminação embaixo (não vi vantagem nenhuma nisso, a não ser se eu fosse usar o MacBook no escuro). O mesmo teclado possuía um botão que sugere que, ao ser pressionado, o drive de CD abriria (como ocorre nos outros notebooks que possuem essa tecla), apesar disso, aquele MacBook não possuía drive de CD e aquele botão não tinha efeito algum.

Havia um mouse sem fio da Apple (com conexão via bluetooth), o Magic Mouse, que era a única cousa que eu gostei naquele equipamento por possuir, além do scroll vertical, um scroll horizontal, devido ao mouse não possuir uma rodinha, mas sim um sensor no qual o usuário passa o dedo no sentido horizontal ou vertical e faz o efeito do scroll. Apesar disso, uma vez ou outra o scroll horizontal atrapalhava, mas algo totalmente aceitável, nada que comprometa o trabalho.

Pontos positivos do MacBook Pro: o mouse (que na verdade nem faz parte do MacBook, é um acessório externo). Pontos negativos do MacBook Pro: todo o resto. De zero a dez, eu dou nota 1,5 para este que está sendo até o presente momento o pior computador no qual eu já usei até hoje.

Eu, sinceramente, esperava mais do MacBook Pro, ainda mais que muito se ouve que os produtos da Apple, incluindo o MacOS X, são mais fáceis e mais intuitivos de se usar (algo que eu não vi naquele equipamento, muito pelo contrário, o sistema não era lá muito intuitivo, talvez seja porque uma mentira dita muitas vezes acaba sendo aceita como verdade). Para piorar, um MacBook Pro é muito mais caro do que um notebook de configuração similar fabricado por outro fabricante. Não sei o que os fãs da Apple e usuários do MacBook veem no mesmo, caso alguém tenha algo a dizer em defesa desse computador, escreva seu comentário na seção de comentários, expondo seu ponto de vista e/ou defendendo o computador da Apple.

Atualização em 05/08/2012: Após conversar com o dono do MacBook que eu havia usado (desde essa última semana, já estou usando o novo computador que já chegou, e veio com Linux, mais precisamente um Debian Testing customizado), ele me explicou umas coisas sobre o mesmo.

Sobre a acentuação nas palavras, realmente não há como teclar acentos como costuma-se teclar em outros sistemas operacionais, e nem dá para alterar o layout do teclado, mas há teclas de atalho que geram acentos, como por exemplo, Option + C que gera um C cedilha e outras combinações envolvendo a tecla Option com outras letras que geram acentos e, em seguida, o usuário tecla a tecla desejada. Apesar de ser pouco prático, como ele já se acostumou a gerar acentos dessa forma, ele nem acha ruim.

Sobre a tecla Home ir para o início do documento ao invés de ir para o início da linha, me foi explicado que, para ir ao início da linha, tecla-se Command + seta para a esquerda. Isto porque a Apple possui um ponto de vista diferente do que as teclas Home e End deveriam fazer. Como as funções de ir para o início e o final da linha são mais usadas do que as de ir para o início e o final do documento, creio que este ponto de vista acaba por fazer o uso do teclado um pouco menos prático, visto que usa-se mais a ida do cursor para o começo ou o final da linha do que do documento, ou seja, o segundo é que deveria ter combinações de teclas para essas funções, não o primeiro.

Sobre o MacBook não possuir drive de CD, ele possui sim um drive de CD, mas é diferente de qualquer drive de CD que eu já vi. Ele não possui uma bandeja, e sim uma fenda (que eu pensei que seria apenas uma fenda por onde o notebook dissipava calor), onde se introduz o CD ou o DVD (e por onde pode entrar poeira, já que a fenda nunca fica fechada). Aí, para ejetar a mídia óptica, aperta-se o botão do teclado, que também existe no teclado plugado na USB. Sobre o MacBook não possuir botões no touchpad, na verdade ele tem sim, mas não estão visíveis.

Sobre fechar completamente os programas, de fato eles ficam abertos mesmo após clicar no X, em estado de repouso, mas podem ser fechados pelo item correspondente do menu, como eu havia dito no post, ou com a tecla de atalho Command + Q.

Achei essa página acerca das teclas de atalho dos computadores da Apple, para caso alguém fique perdido tendo que usar um desses:

http://support.apple.com/kb/HT1343?viewlocale=pt_BR&locale=pt_BR

Erros irritantes cometidos por programadores Java, parte 2

Posted in Atividades profissionais on 15/10/2011 by Allan Taborda

Este é o segundo post sobre erros irritantes cometidos por programadores Java. No primeiro post, citei seis erros relacionados a comparações entre valores e objetos. Neste segundo post, irei falar sobre outros nove erros também muito comuns, mas que devem ser evitados a todo o custo.

A numeração dos erros começa do 7 porque está continuando a numeração anterior, que parou no 6. Se houver um terceiro post sobre erros irritantes cometidos por programadores Java (e tá na cara que irá ter, pois há outros que deixarei para posts futuros, já que este ficou muito grande), a numeração começará do 16, continuando a numeração deste post.

7) Usar um loop com um contador (variável crescente de um em um) para iterar pelos valores de um List, acessando-os pelo método get: Seria o famoso for(int c = 0; c < list.size(); c++) valor = list.get(c); apesar de haver variantes ligeiramente diferentes, como decrescendo o contador ou usando o loop while e uma variável a parte como contador. Essa maneira de iterar pelos valores funciona bem para arrays, mas pode causar perda de performance em Lists, ou até comportamentos inesperados na lógica da iteração, caso objetos sejam removidos do List. Somente itere por um List dessa forma caso o mesmo seja com certeza um List baseado em array, como o ArrayList ou o Vector, e que não haja jeito do List ser baseado em outra implementação, como o LinkedList, que é baseado em lista encadeada, não em array, o que causaria perda de performance pelo fato de todos os objetos, desde o começo (ou o fim, o que estiver mais próximo) do List até a posição acessada, serem acessados, já que não há como acessar um objeto diretamente, a não ser que o objeto seja o primeiro ou o último da lista. E nunca remova valores do List, pois os valores seguintes serão recuados em uma posição, fazendo a iteração “comer” um valor a cada remoção de objeto do List. A não ser que o contador seja decrementado a cada remoção de objeto.

A maneira correta de se iterar por um List, bem como qualquer outra coleção do Java Collections Framework, é usando o loop for incrementado, algo como for(String s : list) valor = s; ou usando um Iterator, que pode ser obtido invocando o método iterator das coleções do Java. Na Internet, há vários exemplos ensinando a usar o Iterator e seus métodos, não é nada complicado. O Iterator possui a vantagem de permitir a exclusão de objetos usando o método remove.

8) Remover objetos de uma coleção sem ser pelo método remove da classe Iterator: Caso remova um objeto da coleção sem ser pelo Iterator, no caso de loops idiotas que citei no erro 7, a iteração pode “comer” um valor (a não ser que o contador seja decrementado) e, caso ocorra na maneira correta de iterar por uma coleção, será lançada uma ConcurrentModificationException, pois o Java não terá como saber qual a sequencia correta da iteração.

9) Suprimir o tratamento de uma Exception verificada: Se uma determinada Exception é verificada (isto é, que não extende a classe RuntimeException e, por isso, necessita que a mesma seja tratada num bloco try-catch), logo ela necessita que ela seja tratada de alguma forma. Ela é verificada por algum motivo, se ela não precisasse ser tratada, ela seria uma Exception não verificada.

Suprimir o tratamento de uma Exception verificada pode fazer com que um erro que ocorra no programa passe despercebido, ferrando com a lógica do bagulho. Se uma Exception é verificada, deve ser tratada, nem que seja para mostrar uma mensagem de erro.

10) Usar objetos sincronizados desnecessariamente: Objetos sincronizados seriam os pertencentes a classes sincronizadas, isto é, que foram implementadas de modo que os objetos delas podem ser acessados por threads simultânas sem ocorrer inconsistência nos valores dos mesmos. Exemplos de classes sincronizadas são a Vector, a Hashtable e a StringBuffer. Acontece que essas classes possuem performance inferior em relação às suas contrapartes não sincronizadas (ArrayList, HashMap e StringBuilder, em relação às três que citei). Somente se houver acesso concorrente que tais classes devem ser usadas.

11) Concatenar Strings com sinal de adição: A cada vez que uma String é concatenada com outra, mesmo se existir mais de uma concatenação em uma mesma linha, uma nova String será criada, poluindo o pool de Strings com Strings desnecessárias. Vale lembrar que, uma vez que uma String é criada no pool, ela só sairá de lá quando o programa for encerrado. Use a classe StringBuilder para concatenar Strings, passando-as como parâmetro do método append e depois pegando o resultado da concatenação pelo método toString. Isto evita lixo no pool de Strings e faz a concatenação ter performance melhor.

Pior que simplesmente concatenar Strings com sinal de adição, é passar duas ou mais Strings sendo concatenadas com sinal de adição como parâmetro no método append da classe StringBuilder. Se já está usando StringBuilder, por que vai concatenar com sinal de adição, se poderia passar cada uma das Strings separadamente pelo o método append?

12) Programar de forma procedural: Java é uma linguagem orientada a objetos, não é uma linguagem procedural, onde o código descreve um procedimento do início ao fim, num bloco enorme de código. Mas ainda assim, há programadores que não separam os códigos responsáveis por cada tarefa em métodos distintos e botam tudo num método só, programando de forma procedural no Java e não aproveitando a orientação a objetos, que tem como principal finalidade (ou uma das principais finalidades) o reaproveitamento do código. Colocar tudo num método só acaba prejudicando a manutenebilidade do código, fazendo-o ser um código de manutenção mais difícil, além de prejudicar seu posterior reaproveitamento.

13) Repetir o mesmo código várias vezes em um programa: Isto prejudica a manutenebilidade e a possibilidade de reaproveitamento do código. Se isto estiver acontecendo, é melhor escrever um método com o código e chamar este método em todos lugares onde o código repetido estava. São para isto que os métodos servem.

14) Não separar o código do software e misturar código de telas gráficas com código de acesso a banco de dados e com código de outras regras de negócio: Isto prejudica bastante a manutenebilidade e a possibilidade de reaproveitamento do código, ao ponto deste, em muitos casos, virar um lixo. Aí, quando precisa dar manutenção no programa, é aquela tristeza. Mexe numa coisa e estraga outra, pois uma coisa tá colada na outra. Vai tentar aproveitar um código em outro lugar e não dá, pois o mesmo tá acoplado com outra parte que não tem nada a ver.

O código de um software deve ser sempre separado em pelo menos três camadas: a de negócios, que contém a regra de negócios do programa; a de persistência, que contém o código relativo a acessos ao banco de dados; e a de apresentação, que contém o código das telas gráficas (ou o código relativo à geração do HTML, caso este seja uma aplicação web). O software pode ser separado em apenas duas camadas, caso este não possua acesso a banco de dados (por exemplo, uma calculadora). E somente se o software for muito pequeno que o código pode ficar tudo junto (por exemplo, um programa que calcula o índice de massa corporal, que faz apenas isso, um único cálculo, seria só uma tela pequena com dois campos para informar peso e altura e outro para exibir o IMC e um cálculo a ser feito).

15) Usar classes e métodos depreciados ou obsoletos: Se estão marcados como depreciados (isto é, com a anotação @Deprecated), significa que seu uso é desencorajado e que há alternativas melhores de se chegar a mesmo resultado, com outros métodos e classes. Os métodos depreciados só continuam existindo por questões de retrocompatibilidade com aplicações antigas, da época que estes métodos não estavam depreciados, e não devem ser usados em novos códigos.

Classes nas quais não foram marcadas como depreciadas mas que sabe-se que são obsoletas (como as classes StringTokenizer e Stack, onde consta no próprio Javadoc das classes que as mesmas são obsoletas) devem ter seu uso evitado, pois há alternativas melhores a elas. A StringTokenizer, por exemplo, ficou obsoleta após passas a existir o método split da classe String, que é mais simples. Já a Stack foi substituída pelas classes que implementam a interface Deque, que possui métodos equivalentes aos da Stack e possuem performance melhor por não serem sincronizadas.

Bom, por hoje é só, mas futuramente, irei escrever pelo menos mais outro post acerca de erros cometidos por programadores Java, que será a continuação deste aqui, assim como este post foi a continuação do outro post, que foi a parte 1.

Erros irritantes cometidos por programadores Java, parte 1

Posted in Atividades profissionais on 03/09/2011 by Allan Taborda

No post de hoje, eu irei falar sobre alguns erros muito comuns cometidos por programadores Java ao codificarem seus programas. São erros estúpidos que costumam me irritar bastante quando vejo um no meio do código. São erros que podem provocar desde o desperdício de recursos (memória, principalmente) até comportamentos inesperados que podem resultar em erros nos aplicativos.

A intenção era de colocar outros erros além desses seis, mas o post acabou ficando muito comprido e os outros erros ficarão para futuros posts. Então, acabei por colocar neste post apenas erros relacionados a comparações de igualdade.

Este post (e os próximos com a mesma temática deste) tem por finalidade alertar programadores (tantos os iniciantes como os experientes, que, como todo ser humano, também cometem erros) para que estes deixem de cometer esses erros. Seguem os erros abaixo:

1) Comparar Strings com dois sinais de igual (==): Esse é um dos erros muito comuns cometidos pelos programadores Java. Comparar Strings com == presumindo que comparações de Strings iguais (com a mesma sequencia de caracteres) feitas dessa maneira sempre retornará true (ou seja, que a condição é verdadeira) pode provocar erros de lógica, pois a comparação pode muito bem retornar false (ou seja, que a condição é falsa). Isto porque comparar Strings com dois sinais de igual (ou melhor, comparar qualquer objeto com dois sinais de igual) significa que você está verificando se as duas referências aos objetos apontam para o mesmo objeto, ou seja, você está verificando se os dois objetos (as duas Strings, neste caso) são, na verdade, o mesmo objeto. Como novas instâncias da classe String podem ser criadas com o comando new (assim como qualquer instâncias de qualquer classe), e o comando new sempre resulta na criação de um novo objeto, e como não dá para garantir que uma String vinda vai saber de onde é uma String declarada com um literal de String (uma String que é declarada com seu valor entre aspas) ou resultante de um comando new, então não é garantido que uma comparação com dois sinais de igual irá retornar true caso as Strings sejam iguais.

Ao invés de comparar Strings com dois sinais de igual, o correto é comparar as Strings com o método equals. Basicamente, pega-se uma das Strings e chama-se o método equals nessa String, passando como parâmetro a outra String, que vai ser comparada com a primeira a fim de verificar se ela é igual à outra. Caso as Strings sejam iguais, ainda que sejam objetos diferentes, o método equals retornará true.

Objetos String até podem ser comparados com dois sinais de igual, desde que tanto a String da esquerda do == quanto a String da direita, ou devem ser literais de String, ou devem ser String resultantes de uma chamada do método intern de outra String, ou então deve ser uma referência cujo valor foi sabidamente atribuído (e sem ter jeito de não ser) ou a um literal de String, ou a uma String resultante de uma chamada do método intern de outra String. O método intern sempre retorna uma String do pool de Strings da máquina virtual igual à String de onde o método foi chamado, ou a mesma String, caso ela seja uma String do pool de Strings.

2) Comparar números encapsulados por objetos numéricos wrappers com dois sinais de igual (==): É o mesmo problema de comparar Strings com dois sinais de igual, já que os objetos podem ser diferentes. Com números inteiros até o 128 não há problema, pois números até o 128 são armazenados num pool de inteiros pela máquina virtual (poucos programadores sabem disso), entretanto, como não é garantido que um objeto de uma classe wrapper de um tipo numérico representa um número menor ou igual a 128, é melhor não arriscar e fazer a comparação com o método equals. Ou então pegar os valores resultantes de chamadas aos métodos da própria classe wrapper que retornam o número propriamente dito (armazenado em um tipo primitivo, não em um objeto), como o método intValue, que retorna um número inteiro de 32 bits (o popular int), e fazer a comparação com dois sinais de igual, pois daí você estará comparando os valores numéricos em si, que não são objetos. Utilizar os métodos que retornam números em tipos primitivos permite que sejam feitas comparações entre objetos wrappers de tipos diferentes, como Integer e Long, por exemplo.

3) Comparar dois objetos de uma classe implementada pelo programador com o método equals, mas sem sobrescrever o mesmo: O método equals pode ser chamado a partir de qualquer objeto e tem por finalidade verificar se o conteúdo do objeto em questão é igual ao conteúdo do objeto passado como parâmetro. Em classes escritas pelo programador que estão sujeitas a terem seus objetos comparados entre si a fim de verificar se são iguais, o programador deve sempre sobrescrever o método equals, implementando um algoritmo que efetue a comparação dos atributos da classe em questão, verificando se o conteúdo dos atributos é igual ao conteúdo dos atributos do objeto a comparar.

Caso o programador não sobrescreva o método equals padrão que é herdado da classe Object (a classe mãe de todas as outras classes Java, que possui métodos comuns a todas elas), a comparação é feita com a implementação padrão provida pela classe Object, que… Adivinhem! Compara os objetos com dois sinais de igual! Ou seja, compara se os dois objetos são, na verdade, o mesmo objeto. Aí, caso os objetos tenham os mesmos valores em seus atributos, a comparação poderá retornar false, caso os objetos sejam diferentes.

4) Sobrescrever o método equals, mas não sobrescrever o método hashCode: caso desses métodos seja sobrescrito, o outro também deve ser, pois o contrato de ambos os métodos (não irei explicar aqui o que é um contrato de um método, caso não saiba, acho que o Google pode lhe ajudar, assim como me ajuda quando eu não sei algumas coisas) diz que, caso a comparação entre dois objetos pelo método equals retorne true, o retorno do método hashCode de ambos deve ser igual. Atenção: isto não significa que objetos com valores diferentes não devem ter o mesmo hashCode. sobrescrever o método equals e não sobrescrever o método hashCode pode resultar em resultados imprevisíveis caso o objeto em questão seja utilizado em alguma classe que chame ambos os métodos internamente, como as classes do Java Collections Framework, que são as populares coleções do Java (classes ArrayList, LinkedList, HashSet, HashMap, etc).

5) Armazenar um objeto de uma classe implementada pelo programador em uma coleção ou um Map sem implementar os métodos equals e hashCode dessa classe: as classes do Java Collections Framework fazem uso massivo desses dois métodos a fim de saber se um objeto possui os mesmos valores de outro, principalmente as classes que implementam a interface Map (HashMap, TreeMap, LinkedHashMap, ConcurrentHashMap, etc), que usam o valor retornado pelo método hashCode para posicionar o objeto dentro do mapa de objetos que foram postos dentro do Map. Caso um dos dois métodos deixe de ser implementado, um objeto da classe em questão pode se perder dentro do Map (entrar e não sair mais), já que, na hora de recuperar o objeto, é verificado o retorno do método hashCode a fim de saber onde o objeto está em relação ao mapa, além de eventualmente (dependendo das implementações dos Maps e de quais métodos forem chamados) haver comparações com o método equals a fim de saber se um determinado objeto é igual a outro. Isso vale para todas as classes do Java Collections Framework, mesmo para Lists (ArrayList, LinkedList, Vector, etc), uma vez que alguns métodos fazem uso do equals e do hashCode em seus objetos armazenados, como o método contains, que verifica se um objeto está contido na lista comparando cada um com o método equals.

6) Comparar String ou números encapsulados por objetos numéricos wrappers ou qualquer objeto usando um ponto de exclamação e um sinal de igual (!=): um ponto de exclamação e um sinal de igual é o contrário de dois sinais de igual, ou seja, verifica se dois objetos (ou dois tipos primitivos) são diferentes. Do mesmo modo que comparações com == presumindo que isto faz comparar se o valor dos objetos é igual podem zicar com o funcionamento de um programa, comparações com != presumindo que isto faz comparar se o valor dos objetos é diferente também não é uma boa ideia, apesar de que objetos cujas comparações entre si com o método equals retornem false são sempre objetos diferentes. Isto porque, do mesmo modo, presume-se que comparações com != entre objetos iguais retornem false, quando podem acabar retornando true na hipótese dos objetos serem diferentes. Neste caso, usa-se o método equals com um ponto de exclamação à esquerda do objeto cujo método equals está sendo chamado. Isto faz com que o retorno do método equals seja “invertido”, ou seja, faz retornar false quando o método retorna true e vice-versa. Aliás, o ponto de exclamação à esquerda de qualquer método que retorne um valor boolean (true ou false) sempre “inverte” o retorno desse método.

Bom, por hoje é só, mas futuramente, escreverei melo menos mais um post acerca de erros cometidos por programadores Java, que será a continuação deste aqui.

AOPT – Ferramenta de persistência do Allan

Posted in Atividades profissionais on 19/10/2010 by Allan Taborda

Desde 2007, eu estava com um projeto em mente, mas que, até então, eu estava relutando em iniciá-lo e deixando-o indefinidamente para depois. É um projeto de uma ferramenta de persistência de dados em Java (que terá versão para C++ e outras linguagens no futuro) chamada AOPT (Allan’s Object Persistence Tool, ou ferramenta de persistência de objetos do Allan). Eu já tinha em mente mais ou menos como ele iria ser, embora alguns detalhes eu não tinha certeza de como seria feito Cheguei a citar a intenção de desenvolver o AOPT no meu TCC que fiz para a faculdade, ainda em 2007.

No último fim de semana, tive um momento de inspiração e tomei coragem para implementar o AOPT e definir o que estava faltando na especificação deste. Em pouco tempo, eu já tinha um código funcional com a primeira parte do AOPT já implementada, que salvava e recuperava dados em XML, de três formas diferentes: o XML bruto gravado no disco, o XML compactado com GZip e também gravado no disco e o XML armazenado num banco de dados relacional (eu usei o HSQLDB, mas pode ser qualquer banco).

O AOPT consiste numa ferramenta de persistência que salva os dados em arquivos XML (um arquivo para cada tabela/objeto) e que permite a recuperação desses dados posteriormente. Diferente da proposta inicial, que previa que apenas objetos pudessem ser persistidos, o AOPT permite também a inserção direta dos dados em mapas do tipo chave-valor (usando a interface java.util.Map, nesta implementação em Java). Na verdade, os objetos são traduzidos pelo AOPT em mapas chave-valor e então estes são salvos em XML. O salvamento dos dados pode ser feito de imediato (ao inserir um objeto), com uma chama explícita ao método de salvar todos os objetos ou de tempos em tempos (como no Prevayler). E a recuperação dos dados pode ser feita utilizando APIs semelhantes às do banco de dados orientado a objetos Db4o e das ferramentas de persistência Prevayler e Perola, permitindo, dependendo de como o AOPT estiver configurado, buscar os dados a partir dos XMLs salvos ou a partir da memória (o chamado modo de prevalência de dados, à la Perola e Prevayler).

Ou melhor, o AOPT consistirá nisso após tudo o que eu desejar implementar estiver implementado, por enquanto, há só um esqueleto básico funcional do AOPT. No futuro, eu implementarei mais algumas partes essenciais e então eu hospedarei o AOPT no Sourceforge.

Mais para o futuro, quando eu souber programar em C++ (estou estudando por conta própria a linguagem C, e depois estudarei C++), implementarei o AOPT nesta linguagem. O AOPT em C++ talvez não terá todos os recursos da versão Java (os que são específicos dessa linguagem, como o mapeamento automático de objetos, visto que isto faz uso de reflections, a não ser que exista reflections no C++), mas implementará, pelo menos, a especificação básica do AOPT e terá compatibilidade de banco de dados com a versão Java, visto que o formato XML é independente de linguagem, bastando um parser disponível para a linguagem desejada).

É possível que o AOPT seja usado na camada de persistência do Robowebert Player, o player de áudio que estou desenvolvendo e que já citei aqui neste blog. Vale lembrar (isto se eu já tiver falado disso aqui no blog, nos posts que fiz sobre o player) que o Robowebert Player permitirá a escolha de como será feita a persistência dos dados, se será com Db4o, banco relacional ou outra forma, como o AOPT.

Assim que tiver mais notícias acerca do desenvolvimento do AOPT, eu postarei aqui neste blog.

Dia 25, estarei mudando de emprego, a fim de obter uma maior experiência profissional, além de começar a trabalhar com carteira assinada. Estou bastante entusiasmado com esse meu novo emprego, que, assim como anterior, também fica situado na capital paulista e também é para ocupar um cargo de desenvolvedor Java.

Neste fim de semana, irei postar dois sonhos que tive no meu outro blog, o blog dos Sonhos do Allan.

Até o próximo post (ou o próximo post do outro blog)!

Mais sobre o Robowebert Player

Posted in Atividades profissionais, Lazer, Música on 12/07/2010 by Allan Taborda

Nesses meses nos quais fiquei sem postar no blog, eu não tive vontade e inspiração para escrever algo interessante aqui, então eu acabei não postando nada nesse tempo. Cheguei a iniciar um post acerca dos meus gostos musicais, mas não acabei concluindo-o, apesar dele já estar bem extenso.

Há um ano atrás, escrevi um post sobre o tocador de áudio em Java que eu estava desenvolvendo em meu tempo livre, o Robowebert Player. Eu ainda desenvolvo o player no meu tempo livre, e ele evoluiu bastante desde aquele post até agora, ainda mais que ele é o meu player principal para ouvir música.

Como eu havia adiantado no último post, ele já possui suporte ao preenchimento automático da playlist. Este é, na minha opinião, o recurso mais importante implementado até aqui, de grande importância nas vezes que eu escuto música, pois gosto de escutar músicas variadas, mas não gosto de ter que ficar populando a playlist com músicas manualmente ou com playlists pré-definidas. Este preenchimento automático consiste em sortear uma música contida em uma das pastas previamente cadastradas em um arquivo de configuração (que é editado manualmente, mas posteriormente eu irei implementar o suporte ao acesso ao banco de dados e então a lista de pastas passará a estar no banco). A cada vez que uma música termina, esta é removida da playlist e, caso a playlist tenha menos do que um determinado número de músicas (definido nas configurações do player), o randomizador (como é chamado o sistema que sorteia as músicas) sorteia uma ou mais músicas, até a playlist atingir o número estipulado de músicas. Na maioria das vezes, ao acabar uma música, esta música sai e outra é adicionada ao final da playlist.

Também adiantei no último post que o player passou a permitir configurações personalizadas. Algumas dessas configurações podem ser alteradas pela própria interface do player, clicando no checkbox correspondente, por exemplo. Outras só podem, pelo menos até o momento, serem alteradas editando manualmente o arquivo de configuração. Para gerenciar essas configurações, de início eu usei a classe Properties, do pacote java.util, mas depois fiz a minha própria implementação da classe que guarda as propriedades, com recursos extras, como o de salvar as propriedades no disco assim que uma propriedade é alterada e métodos próprios para salvar e recuperar valores numéricos e booleanos, além de manter as propriedades em ordem alfabética e usar a codifcação UTF-8 ao salvar o arquivo. Essa classe que gerencia as propriedades poderá ser usada em outros programas que por ventura eu possa desenvolver.

Por falar nas configurações, recentemente eu passei a separar as configurações referentes ao funcionamento do player das configurações referentes à interface gráfica, em arquivos diferentes.

Na interface, os botões, com exceção dos que servem para subir e descer uma música na playlist, foram todos para a parte de baixo da tela, num total de dez botões. O botão de tocar agora também é o de pausar e continuar e o botão de adicionar também adiciona playlists salvas, além das músicas. Há um botão também para ativar e desativar o randomizador de músicas. O analizador de espectro ganhou mais espaço com a saída dos botões da parte superior esquerda da tela. Além disso, o tamanho da tela foi ajustado para ficar do tamanho adequado para monitores maiores (se bem que estou pensando em alterar isso novamente, fazendo o tamanho da tela se adequar melhor ao tamanho do monitor) e a tabela que mostra a playlist na memória foi ligeiramente modificada, tendo sua última coluna diminuído de tamanho e centralizada.

Foram feitas modificações no suporte aos metadados das músicas (informações de artista, nome da música, álbum, ano, etc). Agora foi adicionada a biblioteca JAudioTagger, que é usada na leitura dos metadados dos arquivos de áudio no formato FLAC, que antes não havia suporte à leitura dos metadados. Na verdade, o JAudioTagger é usado para ler os metadados de qualquer arquivo de áudio, com exceção dos áudios em MP3, OGG e Monkey’s Audio (os dois primeiros porque o código antigo, baseado em um pedaço do JLGui, que é outro player de áudioem Java (ver o post publicado há um ano atrás para mais detalhes), possui uma performance melhor na leitura das informações, e o último pelo fato do JAudioTagger não possuir até o momento o suporte a este formato de áudio).

Houve também modificações internas no player, como a inclusão de um pool de threads (usado em todo o player sempre que uma thread é criada, com exceção do motor de execução de áudio, que gerencia a thread princial manualmente), a criação de uma classe com métodos estáticos contendo as rotinas mais usadas e de uma interface contendo valores constantes (e as classes que vão usar esses valores implementam a interface), além de outras alterações internas no código.

Outras coisas que foram implementadas: o suporte ao formato de playlist conhecido como SMIL, usado no Windows Media Player, a geração de logs com os erros ocorridos internamente, a possibilidade do “Look and Feel” do player ser alterado (só há duas opções, por enquanto), dois novos painéis modais para a escolha das músicas manualmente (que podem ser escolhidos pelas configurações do player), suporte ao salvamento do estado do player (ele pode ser fechado e reaberto posteriormente, sem que o conteúdo da playlist e o estado interno do randomizador sejam perdidos), o início da implementação de uma interface em modo texto para o tocador de áudio, uso do KJDSS 1.3 (última versão da biblioteca do analisador de espectro até o momento, com a possibilidade de usar o analizador de espectro antigo aterando uma configuração), modificações nessa biblioteca, dentre outras coisas implementadas.

Ainda faltam muitos recursos dos que eu gostaria de adicionar a este player, como cronômetro, a possibilidade de se voltar ou avançar para um ponto qualquer no meio da música e a alteração dos metadados das músicas. Pretendo também traduzir a interface do player para outros idiomas, usando uma biblioteca de gerenciamento de traduções também escrita por mim e que ainda não está pronta.

Estou pensando em, ainda esse ano, disponibilizar o código do player no Sourceforge.net, ainda não o fiz por falta de tempo, ainda mais que, para isso, terei que elaborar um texto em inglês apresentando o software. Mas, para aqueles que pedirem, eu posso estar enviando o código por e-mail.

Por hoje é só, até a próxima vez.

Meu novo emprego em São Paulo

Posted in Atividades profissionais on 27/07/2009 by Allan Taborda

Depois de meses procurando um emprego, enviando currículos e até participando de entrevistas, finalmente consegui um emprego como programador Java.

Logo no início desse mês, fui chamado para fazer umas provas a fim de averiguar se eu possuía o conhecimento teórico necessário para preencher a vaga. Fiz a prova em questão no dia 6.

Posteriormente, me chamaram para a segunda fase do processo de seleção, onde fiz uma entrevista de emprego e um teste prático. A entrevista e e este teste foram feitos no dia 10 de julho.

No dia 13, recebi um e-mail me convocando para ir no dia seguinte na empresa a fim de fazer a entrevista final de contratação. A essa altura, eu já estava com quase certeza que eu iria ser contratado. Em tal entrevista, me foram feitas algumas perguntas adicionais, me falaram como seria o cargo na empresa, as condições de trabalho e mais algumas outras coisas. Eu aceitei tais condições e fui informado que eu havia sido contratado para a vaga. Comecei a trabalhar no dia seguinte.

Nos três primeiros dias de trabalho, tive que ir e voltar de São Paulo, foi bastante corrido pelo fato de acordar de madrugada e voltar só de noite, pois o ônibus demora muito, principalmente o ônibus da volta.

Mas a partir dessa última semana, passei a ficar hospedado na casa da Tia Carmen, apesar dela morar um pouco longe do serviço (tenho que pegar ônibus e Metrô, inclusive com baldeação na estação Sé) e de não haver acesso à Internet na casa dela. Mas agora está sendo melhor do que subir e descer todo o dia, inclusive mais barato do que se eu tivesse contratado o ônibus fretado (que vai ficar mais caro do que já tá graças ao prefeito burro daquela cidade).

Nos fins de semana (ou melhor, ao término do expediente das sextas-feiras), eu retorno a Praia Grande para passar o fim de semana. Então, retorno a São Paulo na segunda-feira de manhã, já descansado.

Mas infelizmente, esta semana, acabei pegando uma gripe e passei este fim de semana meio mal, mas já estou recuperado para voltar ao trabalho. Por falar nisso, está havendo uma epidemia de gripe na capital paulista, pelo que vi no telejornal (também, né, com um monte de gente tossindo e espirrando nas estações do Metrô sem pôr a mão na boca e com todo aquele aperto principalmente na estação Sé, ainda mais com este clima frio, não tem como não pegar gripe).

Vou encerrando este post por aqui, ainda mais que eu já escrevi o que eu tinha que escrever e eu já deveria estar dormindo para amanhã eu acordar cedo para ir a São Paulo trabalhar. Até o próximo post (sabe-se lá quando será postado).

Observação: a Tia Carmen em questão é a mesma na qual eu sonhei no dia 30 de Março de 2004, sonho este postado no meu outro blog (o que eu escrevo meus sonhos) no dia 10 de Abril do mesmo ano, ainda no antigo endereço no Blig (ainda antes do blog ser transferido para o UOL Blog), na época que meus relatos de sonhos eram pequenos. Quem quiser conferir o sonho em questão, pode acessá-lo em http://sonhosdoallan.blig.ig.com.br/2004/04/ola-internautas-hoje-eu-irei.html

Robowebert Player, tocador de áudio em Java

Posted in Atividades profissionais, Lazer, Música on 03/07/2009 by Allan Taborda

Tenho desenvolvido nesses últimos meses (desde Fevereiro, para ser mais exato) um player de áudio escrito em Java no qual eu batizei de Robowebert Player. Ele reproduz áudio nos formatos MP3, OGG, Speex, FLAC e Monkey’s Audio, além dos formatos padrão do Java (AIFF, WAV e alguns outros). Suporta a leitura e salvamento de quatro formatos de playlists: M3U, PLS, XSPF e um formato próprio que estou desenvolvendo, chamado de RWPF. Além disso, possui um analisador de espectro, que é aquele monte de barrinhas que ficam subindo e descendo enquanto a música toca, além de controle de volume e de balanço, repetição de músicas, visualização dos metadados das músicas e uma barra de progresso meio capenga.

Tudo começou quando eu pesquisei pela Internet como fazer para tocar sons com Java. Encontrei um pequeno tutorial de como tocar arquivos MP3 usando a biblioteca JLayer, disponibilizada no site JavaZOOM.net e desenvolvi um minúsculo player que tocava apenas MP3 e que em sua interface possuía apenas três botões, um para selecionar a música, um para tocar a música e o último para parar de tocar a música. O player e mais a tela gráfica tinham cerca de umas cem linhas de código (ou nem isso). Com certeza, deve ser o menor player de MP3 da história.

Aí eu tive a ideia de desenvolver um player maior, que tocasse outros formatos de áudio além do MP3. Pensei em criar um subsistema para cada formato que o player fosse suportar. Entretanto, percebi o quanto isso iria ser difícil, pois a API da biblioteca JOrbis (biblioteca de suporte ao formato OGG) é completamente diferente da API do JLayer, além de mais complexa e de mais baixo nível.

Então, acessando o site do JavaZOOM acima citado, vi que os próprios desenvolvedores do JLayer desenvolveram um player em Java chamado JLGui, que suportava MP3, OGG e outros formatos de áudio. Era basicamente um clone do WinAmp e suportava os skins feitos para este. Resolvi testá-lo e não gostei muito de sua confusa interface, que além de confusa, a metade desta insistia em ficar na frente de todas as outras janelas. Para complicar, o player em si tinha uns bugs idiotas.

O JLGui é licenciado sob a LGPL, uma licença livre que me permite modificar o software de acordo com minhas necessidades. Entretanto, o código-fonte desse player é extremamente confuso, macarrônico e de extrema dificuldade de manutenção, além de ter sua camada de apresentação (o código responsável pela tela gráfica) colada na camada de negócios (o código responsável pela regra de negócios). Ou pior: todas as partes do player são coladas em várias outras partes.

Só para se ter uma ideia, se eu quisesse adicionar o suporte ao formato de playlist XSPF a este player, eu teria que fazer toda uma reengenharia no programa inteiro, praticamente.

A única parte que não era colada a nenhuma outra era o motor de execução de áudio, que foi concebido para ser aproveitado em outros softwares que desejassem tocar áudio com uma API de alto nível. Tal motor de execução era mantido em uma biblioteca separada chamada BasicPlayer.

O BasicPlayer utiliza uma API comum para todos os formatos de áudio baseada na API Java Sound, que usa Service Providers (bibliotecas especiais) que proveem o suporte aos formatos de áudio sem alterar o código-fonte que reproduz a música. Nas minhas pesquisas iniciais, eu já havia visto algo sobre a API Java Sound, entretanto, vi que ela era bastante confusa e de baixo nível. Já o BasicPlayer era de alto nível.

O que resolvi fazer? Criar um player que utilizasse o BasicPlayer como motor de execução de áudio. Aproveitei a interface simplória do minúsculo player que eu havia feito e a adaptei no BasicPlayer. A partir daí, fui implementando outras funcionalidades básicas, como controle de volume e de balanço e o botão de pausar e continuar a reprodução do áudio.

Aí o player foi evoluindo: passou a trabalhar com uma playlist na memória e a salvar e carregar um formato próprio de playlists baseado em XML, ganhou também botões de voltar à música anterior, voltar ao começo da música atual e ir para a próxima música.

Resolvi implementar o suporte à visualização dos metadados dos arquivos de áudio. O primeiro lugar onde pesquisei como fazer isso foi no macarrônico código do JLGui. Essa parte do código do JLGui não estava tão macarrônica e ligada às demais partes do player como as outras (só um pouco), então eu resolvi pegar este código e adaptá-lo ao meu próprio player, fazendo alterações diversas a fim de retirar completamente a dependência das outras partes do JLGui.

Já com o suporte aos metadados das músicas e mesmo com a interface estando muito tosca, disponibilizei o player (ainda sem nome naquela época) para alguns membros da comunidade Linux versus Windows do Orkut para ver o que eles achavam. Eles emitiram suas opiniões e o que eles gostariam de ver no player.

A partir daí, continuei a adicionar outros recursos ao player e a mudar um pouco sua interface (que ainda está tosca, mas menos do que antes). O último recurso adicionado até o momento foi o analizador de espectro, provido pela biblioteca KJ DSS.

O código-fonte do meu player, ao contrário do código do JLGui, é bastante claro e simples. O suporte à playlist na memória, por exemplo, é implementado por uma classe que gerencia um simples ArrayList contendo os objetos File, que provém acesso aos arquivos de áudio no HD. Já o JLGui implementa a mesma coisa com algumas classes, uma delas responsável por cada música na playlist (e que contém parte do código para manipular playlists no formato M3U – e manipular mal), outra cheia de métodos e mais uma interface gigantesca, além de mais algum código macarrônico colado na interface gráfica e em mais não sei onde.

Pelo fato da camada de apresentação ser completamente desacoplada da camada de negócios, será possível escrever telas gráficas alternativas ao visual atual do meu player. Inclusive, estou planejando para o futuro uma interface totalmente diferente e inovadora além da que já existe, além de uma interface alternativa usando a SwingWT, implementação alternativa (e mais leve) da API Swing baseada na biblioteca SWT.

No link abaixo, uma screenshot de como está o visual do meu player atualmente:

http://img30.imageshack.us/img30/4513/rwplayer.png

Ainda falta a grande maioria dos recursos que desejo implementar no meu player, como biblioteca de mídia, playlists dinâmicas, execução aleatória de músicas contidas numa playlist, edição de metadados das músicas, internacionalização e uma penca de outras coisas. O player vai ficar o bicho.

Entretanto, irei disponibilizar uma segunda versão pública com apenas alguns desses recursos, quando eu achar que ele está bom o suficiente para ser usado pelo público geral, ainda que incompleto. Irei disponibilizá-lo no SourceForge.net, onde já mantenho hospedado outro software que desenvolvo, o CapeTrivia.

Meu Player será licenciado sob a GPL 3, ou melhor, o código que escrevi está sob esta licença. O subsistema de leitura de metadados está sob a LGPL 2.0 pois não posso alterar a licença dessa parte, já que não fui eu que escrevi. E as demais bibliotecas estão nas suas respectivas licenças, todas compatíveis com a GPL 3.

Por falar em licenças, eu acabei tendo umas dúvidas com relação à compatibilidade destas, ainda mais por causa da biblioteca que provê o suporte ao formato de playlist XSPF (JSpiff) estar na licença Apache 2.0 e haver código LGPL 2.0 no player. Resolvi mandar um e-mail para o Richard Stallman, presidente da Free Software Foundation (ou melhor, dois e-mails, o outro foi depois da resposta que ele me mandou). A troca de e-mails com o Stallman merece um post à parte (no próximo deste blog, quem sabe), mas resumidamente, ele respondeu que as licenças são todas compatíveis entre si.

Escolhi o nome Robowebert Player a fim de homenagear um antigo personagem das minhas histórias infantis de quando eu era criança e que eu mesmo inventei, o Robowebert. Este era um robô gigantesco ao estilo do Megazord dos Power Rangers que possuía vários componentes integrados e recursos diversos e que tinha a finalidade de lutar contra inimigos gigantescos que ameaçavam a cidade de Pret-a. O Robowebert era controlado pela Darker Webert, uma mulher que combatia o crime naquela cidade fictícia e que vivia cheia da grana. Ela também merece um post à parte, pois teve uma importância histórica na minha infância.

Não há uma previsão de quando a próxima versão pública (e desta vez disponível ao público geral e não só a alguns membros da Linux versus Windows) será disponibilizada, mas espero ver o Robowebert Player na próxima versão estável do Debian, codinome Squeeze, a ser lançada provavelmente no ano que vem.

Atualização: escrevi um novo post sobre o Robowebert Player, que pode ser visto em: https://irmaodamara.wordpress.com/2010/07/12/mais-sobre-o-robowebert-player/

Finalmente consegui a certificação SCJP 6.0!

Posted in Atividades profissionais, História on 05/05/2009 by Allan Taborda

Enfim, no último dia 15 de Abril, fiz a prova a fim de obter a certificação SCJP 6.0 e passei no exame, com um percentual de acertos de 81% (59 questões respondidas corretamente, das 72 questões da prova).

Meu resultado detalhado foi:

Declarações, Inicialização e Escopo: 91%

Controle de Fluxo: 81%

Conteúdo da API: 80%

Concorrência: 87%

Conceitos OO: 70%

Coleções / Genéricos: 80%

Fundamentos: 81%

Tudo começou há um ano atrás, quando o David Muinos, um dos principais desenvolvedores do Perola (uma ferramenta de persistência de dados), me deu a idéia de eu obter a SCJP. Então, eu procurei saber mais acerca dessa certificação e me informei numa página do site da Sun Microsystems o que era a ditacuja e o que caía na prova. Além disso, perguntei a um ex-colega de faculdade, o Roberto Tengan (que havia obtido a SCJP 5.0 há algum tempo atrás), como ele havia procedido a fim de obter a certificação e ele me respondeu por e-mail, com todos os detalhes.

No site da Sun, eu vi que já havia disponível uma nova versão da SCJP, a 6.0, e resolvi que esta seria a melhor escolha, pois era a versão mais atual, ainda que a prova só estava disponível no idioma inglês (ao contrário da versão 5.0, que estava disponível em português).

Na ância de fazer a prova o mais rápido possível, comprei logo o voucher (cupom que dá direito a fazer qualquer certificação de Java da Sun) por R$330,00 ligando no número 0800 55 78 63, daí a atendente dá as instruções de como proceder (basicamente, ela pergunta o e-mail e o resto é feito tudo por e-mail). Depois que chegou o boleto bancário, paguei-o e então me enviaram um e-mail com o número do voucher.

Eu pretendia fazer a prova em poucos meses, mas devido a meu estágio, esforços para conseguir um emprego e principalmente por causa dos meus estudos para esta certificação, a data da prova foi adiada por vários meses, até que o final do prazo se aproximou, faltando apenas dois meses para terminá-lo (depois do prazo, o voucher expira).

Então, eu decidi por marcar a data exata da prova para o dia 15 de Abril e intensifiquei ainda mais meus estudos, lendo a versão em inglês do famigerado livro da Kathy Sierra e do Bert Bates que eu peguei emprestado. Embora eu não fale inglês, eu consigo ler normalmente textos nesse idioma, inclusive entendendo o que está escrito.

Li o livro inteiro em cerca de três semanas. Era para eu ter terminado a leitura em menos tempo, mas aconteceram uns imprevistos que me desvirtuaram dos meus estudos, incluindo a confecção de um software que minha amiga Mara encomendou (que eu tive que parar o desenvolvimento no meio para poder prosseguir com meus estudos, mas depois da certificação eu consegui terminá-lo). Terminei de ler um dia antes da prova.

No dia seguinte, acordei cedo. Isso não significa que eu dormi o suficiente, uma vez que eu demorei muito a pegar no sono (isso sempre ocorre às vésperas de algo importante, como uma entrevista de emprego). Dormi apenas 3 horas.

A prova havia sido marcada para às 13:15, então eu vi que dava tempo de fazer mais um exame simulado (já havia feito dois, obtendo um bom íncice de acertos).

Mas aí minha mãe, que ia me levar de carro até a Tecnoponta (escola profissionalizante que aplica a prova aqui na Baixada Santista), em Santos, ficou me pressionando para eu ir logo, pois não sabia quanto tempo iria demorar para chegar ao local.

A metade das questões daquele simulado eu respondi de qualquer jeito e correndo, e eu acabei tirando uma nota ruim, errando questões fáceis. Tirei 60% de acertos, 5% abaixo do mínimo necessário para a aprovação. Fiquei um pouco preocupado e um pouco mais nervoso.

Engoli o almoço com medo de me atrasar, ainda mais que minha mãe me pressionava cada vez mais para ir mais rápido, pois segundo ela (que conhece o caminho até Santos e teoricamente sabia quanto tempo demorava a ida até aquela cidade), poderia não dar tempo de chegar no horário marcado. Eu e minha mãe saímos de carro às 10:20 e, antes do meio-dia, chegamos.

Entrei no prédio e subi até o sétimo andar, onde ficava a Tecnoponta, que estava em reforma, com uma sala de aula cheia de bugigangas e um pedreiro lixando e pintando o teto. Lá, me informaram que eu havia chegado cedo demais e que eu tinha que esperar até às 13:15. Minha mãe me apressou tanto para eu ter que esperar no espaço reservado aos alunos no intervalo das aulas (se bem que não tinha ninguém além de mim). Fiquei andando e tomando café expresso de uma máquina que tinha no local.

Chegando a hora marcada, procedi como havia sido informado no e-mail que recebi no dia que marquei a prova pela Internet, no site da Prometric (empresa que aplica a prova, sendo a Tecnoponta um local credenciado por esta), mostrando um documento com foto, no caso, meu RG.

Entretanto, a moça me informou que eu precisava também apresentar o CPF, ainda que não falava nada de CPF no e-mail que eu havia recebido. Naquela hora, fiquei bastante preocupado, uma vez que talvez eu não fizesse a prova por não ter apresentado o CPF. Já preparava meu discurso de que ia processar a Prometric e a Tecnoponta por não ter avisado sobre a necessidade de apresenta o CPF e pelo fato do RG ser suficiente para me identificar, quando me liberaram de apresentar o CPF, para meu alívio.

Então, a moça que havia me pedido o CPF (uma moça bonita, mas que estava com uma cara bastante séria, como se eu tivesse cometido um crime inafiançável) pediu para eu segui-la até o local da prova, que ficava em outro andar, em um “lugar secreto”, onde ficava umas salas de aula onde estava tendo aula de algum curso, com umas alunas muito bonitas, como deu para ver pela janela. Basicamente, o local do exame era outra sala de aula, só que um pouco menor.

Chegando lá, ela me falou como eu devia proceder, inclusive disse para eu não sair do local da prova sem o papel impresso com o resultado do exame e que, em caso de emergência, que era para usar um telefone que estava no canto e ligar para o ramal informado.

E então eu comecei a fazer o exame, que foi aplicada em um computador rodando o software da prova certificatória. No início, havia umas perguntas sobre se eu trabalhava para a Sun ou para a Prometric, se eu permitia que meus dados pessoais fossem usados não sei de que forma pela Sun com fins de não sei o quê, etc, perguntas que, segundo a prova, não contava no resultado do exame. Depois, havia um texto que explicava como interpretar as questões (por exemplo, não interpretar a numeração das linhas como parte do código). A partir desse texto, o cronômetro do tempo de prova começou a ser contado. Na minha opinião, deveriam contar a partir da primeira questão, e não a partir desse texto.

A prova poderia ser feita em, no máximo, três horas e meia, bastante tempo. Fiz a prova com calma (apesar de tudo o que aconteceu, inclusive momentos antes do exame), lendo as questões atenciosamente e só depois respondendo.

Eu esperava que a prova fosse mais difícil, mas no fim, a maioria das questões estava bem fácil, algumas com respostas óbvias, principalmente as de competar os espaços em branco. As questões com mais de uma resposta certa informavam o número de respostas certas que tinha que marcar (diferente das provas simuladas, que falavam para responder todas que se aplicam). E a única questão que eu marquei para revisão foi a questão 46, que era uma sobre qual o conteúdo da String após um monte de operações com StringBuilder.

Com 40 minutos sobrando, terminei a prova e confirmei as respostas (após rever a questão 46, gastando vários minutos nela). Daí, o software da prova certificatória tentou imprimir o resultado na impressora. E advinha o que aconteceu? A impressora deu pau!

Peguei o telefone de emergência e liguei para o ramal que estava escrito na folha de rascunho (que eu usei para calcular o resultado da questão 46 e mais a ordem de um array em outra questão sobre ordenação). Minutos depois, chegou aquela moça bonita que me pediu o CPF e eu expliquei o ocorrido. Ela tentou imprimir uma segunda via, mas a impressora continuou a se negar a funcionar.

Daí ela chamou o técnico que cuida dos equipamentos e, vários minutos depois, ele chegou e tentou descobrir o que havia acontecido. Instantes depois, ele descobriu o problema: a impressora estava desligada. Não só isso: o computador no qual a impressora estava conectada também estava desligado.

Depois de ligar os equipamentos, finalmente o resultado do exame foi impresso. E então, eu soube que eu havia sido aprovado (se bem que eu meio que já sabia durante a prova).

E moça falou para eu voltar ao sétimo andar para lá carimbarem o papel impresso. Entrei no elevador e acabei indo para o andar errado, pois havia me esquecido de apertar o botão 7. Fui parar no térreo. Mas depois eu subi de volta e carimbaram o resultado do exame.

Na volta para casa, minha mãe errou o caminho e o carro acabou preso num congestionamento no centro de São Vicente,, após andar em círculos. Mas depois de bastante tempo, finalmente conseguimos chegar em casa.

Durante o tempo que fiquei esperando, fazendo prova e esperando solucionarem o problema da impressora, minha mãe ficou no carro lendo livro e fazendo as unhas.

E essa foi a conturbada história da minha certificação SCJP 6.0 (história essa com final feliz). Futuramente, penso em fazer as certificações SCWCD, SCBCD, SCDJWS, SCEA e SCJD, não necessariamente nessa ordem, e ainda não escolhi qual eu vou fazer primeiro, mas muito provavelmente irei fazer a SCEA por último.

Por hoje é só! Até o próximo post, que provavelmente deve ser menor do que este!

Procurando um emprego como programador Java

Posted in Atividades profissionais on 15/02/2009 by Allan Taborda

Ultimamente, tenho procurado um emprego como programador Java na cidade de São Paulo. Diariamente, mando currículos para as vagas que vão aparecendo no site APInfo.com, um site de anúncios de vagas de emprego e de postagem de currículos para profissionais da área de informática.

Dentre as várioas empresas para onde mandei currículos, algumas fazem contato comigo (por e-mail e algumas poucas vezes por telefone), fazem algumas perguntas sobre pretensão salarial, disponibilidade de início e outras coisas. Até o momento, uma empresa já me chamou para fazer a entrevista, que ocorreu no último dia 5 de fevereiro.

Naquela ocasião, fiz uma prova de Java (com as primeiras questões fáceis, mas com as questões posteriores um pouco mais difíceis, que eu acho que eu devo ter me saído bem), uma redação com o tema “como eu sou” e a entrevista propriamente dita.

Fui para São Paulo pegando um carro que vai até o terminal Jabaquara, às 8:00. O carro demorou um pouco para ir, pois ficou pegando uns passageiros adicionais, mas depois foi e chegou à capital com antecedência, dando tempo mais do que o suficiente para enfrentar a longa fila para comprar os bilhetes do metrô. Cheguei às 9:20 mais ou menos. A entrevista estava marcada para as 11:00.

Depois de comprar os bilhetes de ida e de volta, que custam cada um o mesmo preço de um bilhete de ônibus municipal aqui em Praia Grande, R$2,40 (não por lá o metrô ser barato, mas por aqui o ônibus ser caro), peguei o metrô e andei duas estações, parando na estação São Judas.

No dia anterior, eu já havia dado uma olhada no mapa dessa parte da cidade através do Google Maps, então foi fácil andar da estação até o prédio onde fica situada a empresa de recrutamento que ia fazer a entrevista. Chegando lá, havia todo um esquema de mostrar o RG para liberar o acesso ao interior do prédio, algo bem sofisticado, com catraca eletrônica de cartão inclusive, semelhante aos sistemas para guardar veículos em alguns estacionamentos.

Subi o elevador e cheguei no local da entrevista. Cheguei um tanto adiantado. Me mandaram fazer uma prova com 16 questões aproximadamente. Após a prova, fiz a redação, numa folha de papel sulfite. Após a redação, finalmente fiz a entrevista. A entrevistadora me fez várias perguntas. Eu pensei que ela fosse fazer um determinado tipo de perguntas, mas acabou fazendo outras mais informais do que costuma-se fazer em entrevistas de emprego.

Terminada a entrevista, eram umas 13:00 e eu já estava morto de fome. Fui almoçar em um restaurante situado na mesma avenida de onde ficava o prédio onde eu fui. Era um restaurante de comida por quilo. Peguei 700 gramas de comida, mais ou menos. Comi um pouco de lasanha, feijão (que tinha mais bacon gorduroso do que feijão), uns bolinhos de queijo (eram tipo uns kibes), um pedaço de carne e alface, além de um suco de maracujá, que eu pedi posteriormente, para ajudar a empurrar o final do almoço que não queria ir.

Depois do almoço, aproveitei que havia uma loja da Kalunga e comprei 100 mídias DVD, pagando com o cartão de crédito. O preço era o mesmo da loja on-line da Kalunga, só que sem o frete. A moça do caixa era muito bonita. Aliás, eu vi muitas mulheres bonitas em São Paulo, principalmente nas estações do metrô (especialmente na fila para comprar os bilhetes) e no restaurante de comida por quilo.

Depois, eu voltei à estação São Judas, andei os dois pontos até a estação Jabaquara e daí peguei um outro carro que foi até Praia Grande, parando na porta de casa. Antes de entrar no carro, cheguei a ver uns aviões da Gol e da TAM voando bem próximo de onde eu estava. Deve haver um aeroporto por perto do terminal Jabaquara.

Na volta a Praia Grande, o carro que eu estava foi parado pela polícia rodoviária, mas depois que o motorista deu algum dinheiro para o guarda (o que eu suspeito ter acontecido, pelo que vi), o carro prosseguiu até seu destino. Cheguei em Praia Grande ainda de tarde, bastante cansado, ainda mais que eu não havia dormido direito na madrugada e ainda tive que acordar às 6:00.

Até o momento, não obtive resposta acerca do resultado da entrevista e dos testes que eu fiz. Por enquanto, ainda vou continuar mandando os currículos. Uma hora, eu farei uma entrevista e serei selecionado para ocupar uma vaga de emprego como programador Java. Isto se eu não trabalhar na empresa na qual já fiz a entrevista, pois ainda poderei ser chamado por aquela empresa.

Mudando de assunto, no último dia 12 de fevereiro, reinaugurei o blog dos Sonhos do Allan, agora aqui no WordPress. No antigo blog, agora há um aviso do novo endereço, que é http://sonhsodoallan.wordpress.com e neste novo blog, já fiz o meu primeiro relato de sonho, um onde eu fui atingido por uma lixeira. Vale a pena conferir.

Estudando para a certificação SCJP 6.0

Posted in Atividades profissionais on 24/10/2008 by Allan Taborda

Após a conclusão do meu estágio, passei a dedicar meus esforços para obter a certificação Sun Certified Java Programmer 6.0 a fim de me tornar um programador Java certificado. Estou estudando como nunca as APIs do Java, lendo o Javadoc do Java 1.6 (tudo em inglês, mas dá para ler numa boa quase que como se estivesse em português) e aprendendo o uso de classes e interfaces, com seus respectivos métodos, que antes eu não sabia, mas precisarei saber para fazer a prova certificatória (e estes novos conhecimentos me serão muito úteis quando eu precisar deles a fim de programar alguma determinada rotina que precise destas APIs).

A última parte que eu estudei até o momento foi o pacote java.util.concurrent e suas classes e interfaces, ainda não terminei de ver tudo, mas já deu para sacar como são usadas as APIs de concorrência do Java, além das coleções que suportam concorrência e seus respectivos usos.

Ainda falta uma boa quantidade de APIs a estudar, mas no ritmo que estou estudando, em poucas semanas eu terei visto tudo o que preciso saber. Estou me guiando no que preciso saber por esta página, que informa o que cai na prova certificatória:

http://www.sun.com/training/catalog/courses/CX-310-065.xml

Além de ler o Javadoc do Java 1.6, estou lendo também outros materiais disponíveis na Internet e o livro Java Como Programar Sexta Edição, que, embora aborde o Java 1.5, provê uma base sobre vários conhecimentos necessários à certificação (e o que ficar faltando, eu pego pela Internet, material de estudo é o que não falta).

Pretendo fazer a prova certificatória em Dezembro, no mais tardar em Janeiro. Até lá, terei não só aprendido o necessário para a certificação como também terei feito algumas provas simuladas disponíveis na Internet (os chamados “mocks”) a fim de avaliar se estou mesmo pronto para a prova. O prazo máximo para eu efetuar o teste é em maio de 2009.

Acessando o site da Prometric, empresa responsável pelas provas certificatórias do Java, vi que eu poderei fazer a prova em Santos. Há um lugar por lá que também aplica a prova (no caso, a Tecnoponta, um centro de formação profissional), então, não precisarei ir até São Paulo apenas para fazê-la.

Estou confiante que irei passar no teste e serei um programador Java certificado pela Sun. Até lá, continuarei estudando a fundo nas APIs do Java.

Concluí meu estágio!

Posted in Atividades profissionais on 02/10/2008 by Allan Taborda

Ontem, concluí o desenvolvimento do sistema que eu estava desenvolvendo no estágio que, como eu já informei aqui, é um sistema web que tem por finalidade registrar as reservas de equipamentos (notebooks, projetores, retroprojetores, etc) e de salas (laboratórios de informática, salas de aula, auditório) para os professores ministrarem suas aulas. Falta apenas eu apresentar o sistema já pronto na reunião do Centro de Informática e instalá-lo no servidor da Intranet da FATEC (e instalar também o Tomcat e o JDK 1.6, caso não estejam instalados), de onde será acessado pelo navegador web. Após o dia de hoje, meu estágio estará concluído, uma vez que já cumpri as 400 horas mínimas já faz algum tempo e meu estágio estava dependendo apenas da conclusão do sistema para terminar.

Este sistema, posteriormente, será disponibilizado como software livre pela GNU General Public License versão 2 no Sourceforge.net para que outras faculdades (ou quaisquer instrituições onde se reservam equipamentos e salas) também possam utilizar o sistema. Antes disso, farei algumas pequenas modificações neste a fim de possibilitar seu uso por estas outras instituições, como a possibilidade de alterar o nome exibido na assinatura dos e-mails, que, por enquanto, está como “Centro de Informática – FATEC Praia Grande”, uma outra faculdade que onde este sistema seria implantado poderia incluir seu nome ao invés do da FATEC. Talvez eu faça outras alterações a fim de melhorar suas funcionalidades e talvez eu até lance versões posteriores, com mais recursos.

A partir da semana que vem, iniciarei meus estudos para obter a certificação Sun Certified Java Programmer 6.0, talvez eu faça a prova ainda esse ano, caso contrário, no começo do próximo ano eu farei.

Até o próximo post e espero que o pessoal do Centro de Informática goste do sistema que eu fiz…

Últimos dias do meu estágio

Posted in Atividades profissionais on 26/08/2008 by Allan Taborda

Meu estágio, finalmente, está em sua reta final, faltam apenas cinco dias úteis para eu concluí-lo, o sistema que estou desenvolvendo nele está quase pronto, falta basicamente o sistema de envio de e-mails aos usuários em determinados eventos, o sistema de logs para anotar o que os usuários administrativos fazem e a persistência dos dados, onde será usada a ferramenta de armazenamento em memória Perola, ferramenta essa de fácil utilização, bastando apenas seguir alguns passos básicos. Além dessas três coisas, falta também alguns ajustes, como o tema visual do sistema, correções de problemas e insersão de partes que estão faltando.

Creio que dê tempo de eu terminar tudo até a segunda que vem, mas, caso não dê tempo, eu poderei prorrogar meu estágio por mais alguns dias, entretanto, isto significará custos, não para a faculdade, mas para mim, já que o estágio é voluntário e sou eu quem pago a condução e o almoço, um custo de R$ 7,65 por dia. Ou seja, eu pago para estagiar (ainda que a faculdade seja pública) e se a conclusão do sistema atrasar, quem perderá vai ser meu bolso que custeará o atraso.

Mas tenho fé que o sistema irá ficar pronto a tempo e funcionando bem. A parte principal já funciona bem e foi declarada estável, falta só funcionalidades “periféricas”, não tão importantes num contexto geral.

Desde semana passada, eu estava pretendendo postar sobre uma pegadinha que acabou sendo feita no Centro de Informática da FATEC, a “pegadinha das BSODs”, acabou sendo muito engraçado o que aconteceu quando um dos principais PCs daquele recinto passou a ter comportamentos assustadores. Tal pegadinha será relatada provavelmente no próximo post, pois por agora meu tempo está demasiadamente curto.

Até a proxima blogada, espero que na semana que vem ou um pouco depois!

Sistema de reserva de equipamentos que estou desenvolvendo

Posted in Atividades profissionais on 09/07/2008 by Allan Taborda

Olá, pessoal! Como eu já disse neste blog, estou estagiando na FATEC de Praia Grande, desenvolvendo um sistema web para registrar as reservas de equipamentos e salas da faculdade. Essa já é a terceira semana de estágio e eu já implementei quase que a primeira parte completa. Na fase de análise do software, ele foi dividido em mais de vinte casos de uso.

O primeiro caso de uso, que é o de agendar eventos (reservas), está quase que completamente implementado e ele está demandando bastante tempo para ser feito, pois é o mais complexo. Inclusive, essa parte do sistema está sendo mais complexa do que eu imaginava, principalmente porque o sistema prevê a recorrência de eventos, ou seja, o evento (uma aula cujo professor precisará de um notebook e de um projetor para exibir a matéria, por exemplo) pode acontecer várias vezes por um certo período de tempo (todas as quartas, uma vez por mês, todas as segundas e quintas, uma vez a cada três semanas na quinta e na sexta, a cada dois meses, todas as terceiras quartas-feiras do mês e outros períodos), e esse período de tempo pode durar até uma data pré-estabelecida, um certo número de recorrências ou até mesmo pode não terminar nunca, recorrenco até o evento ser excluído do sistema. Sem contar que o sistema não pode deixar um equipamento (um notebook, por exemplo) ser reservado para dois eventos que ocorrem simultaneamente. Em outras palavras, ao agendar o evento, o sistema tem que verificar em todos os eventos cadastrados se algum deles, em algum dia, no horário marcado e na duração marcada, têm reservado previamente a mesma sala ou algum dos até três equipamentos que podem ser reservados para um mesmo evento (e a situação se complica quando a recorrência de um evento não tem data de término prevista).

A boa notícia é que essa parte complexa já foi implementada e o que falta para concluir o primeiro caso de uso seria terminar as páginas JSP e terminar de implementar o fluxo alternativo do caso de uso (por exemplo, o que acontece se o evento a ser registrado usa o mesmo equipamento que um outro evento já registrado, num mesmo dia e horário e como o sistema deve proceder).

E o segundo caso de uso é até parecido com o primeiro, o segundo caso é o de solicitar agendamentos de evento, ou seja, quando um professor acessa o sistema pede que um evento seja agendado. A página JSP e o código necessário para o caso de uso funcionar é tão parecido com o do primeiro caso de uso que provavelmente eu até reaproveite o código existente, fazendo algumas alterações necessárias. E os demais casos de uso acredito que serão bem mais fáceis de implementar.

A respeito do banco de dados a ser utilizado, eu pretendia usar o MS SQL Server, que já é usado no servidor do Centro de Informática, mas o sistema está ficando tão orientado a objetos (até a recorrência é representada por uma classe, ou melhor, algumas classes que extendem a classe abstrata de recorrência, cada uma implementando um tipo de recorrência) que provavelmente não irá compensar o uso de banco de dados relacional e nem mesmo o uso de frameworks ORM como o Hibernate, que não dispensa o mapeamento das classes para tabelas. Muito provavelmente, irei usar alguma solução de armazenamento de dados orientada a objetos, talvez o Db4o, o Prevayler ou o Perola (esse último tem maior chance de ser usado).

O desenvolvimento do sistema tem também enfrentado algumas dificuldades não somente de implementação, mas também por outros inconvenientes técnicos, como a lentidão do notebook que uso no estágio (tem três SGBDs instalados: MySQL 5.0, MS SQL Server Express 2005 e Oracle Express 10, eu tenho que ficar matando alguns processos antes de abrir o Eclipse 3.4 com todos os plugins para desenvolvimento web, que é o Eclipse mais pesado de todos, isto sem contar o fato do notebook ter apenas 512 MB de memória) e os diversos vírus que aparecem e que contribuem com a lentidão do notebook velho (lembrando que o notebook está com o Windows XP instalado). Ontem, escaneei o HD do notebook com o Symantec AntiVirus Corporate Edition (outro troço pesado rodando na máquina) e este pegou mais de 40 arquivos mal-intencionados, a maioria sendo o vírus W32.Gammima.AG e trojans. E depois que eu escaneei, apareceram mais vírus! Só não formato o notebook e ponho Linux porque o notebook não é meu, é da FATEC!

Por hoje, é só! Dentro de alguns dias, estarei postando novamente, com probabilidade alta de eu escrever novamente sobre o meu estágio! Tchau e até o próximo post (embora eu tenha usado o método GET no servlet que implementei para fazer funcionar o Ajax do JSP que pega os nomes dos professores dinamicamente)!

Meu estágio na FATEC

Posted in Atividades profissionais on 23/06/2008 by Allan Taborda

Olá, internautas! Desde a última sexta-feira, eu estou estagiando na FATEC de Praia Grande a fim de cumprir as 400 horas de estágo requeridas. O estágio é a única coisa que falta para eu concluir o curso superior em Tecnologia em Informática com Ênfase em Gestão de Negócios. Não é um estágio remunerado, pois nesses últimos meses, não consegui nenhum, pois as vagas anunciadas por aí pediam conhecimentos demais e exploram o estagiário, entretanto, a faculdade concedeu-me este.

Na primeira reunião do Centro de Informática que eu participei, viu-se que havia a necessidade de se desenvolver um novo sistema de reserva de equipamentos e salas da faculdade, pois o antigo estava capenga, com algumas deficiências. Então, fiquei responsável por desenvolver este sistema, que será uma aplicação web em Java com banco de dados MS SQL Server, que é o gerenciador de banco de dados usado no Centro de Informática. Confesso que será a primeira vez que desenvolvo uma aplicação web para valer, inclusive com frameworks Java e tudo mais, até então, eu só havia desenvolvido para valer em desktop. Esta será uma excelente oportunidade de aprimorar meus conhecimentos de desenvolvedor Java.

Devido a este estágio, passo a maior parte do dia na FATEC, oito horas por dia de estágio e mais o intervalo para o almoço, só volto para casa à noite e ainda assim tenho bem pouco tempo, o tempo dá só para tomar lanche e ficar bem pouco tempo na fretne do PC lendo e-mails e fazendo outras coisas, como postar neste blog. Só tenho tempo agora no fim de semana.

Este sistema que irei fazer será bem completo, nos dois dias que estou estagiando, já levantei mais de 25 casos de uso e dez páginas de documentação, e amanhã continuarei a fazer mais documentação, a parte de análise. Irei começar a implementar talvez no final da semana ou na próxima.

Apesar de ficar tanto tempo estagiando, até que não tá muito puxado meu serviço, eles deixam dar uma olhada nos e-mails, tomar cafezinho, e no primeiro dia, até comi uns negócios num coffee-break que fizeram de manhã, inclusive morangos e umas bolachas waffer esbagaçadas, que pareciam ser fim de estoque de supermercado falido, tudo soltando, mas tava bom mesmo assim.

Bom, tenho que ir dormir, numa próxima oportunidade, escreverei mais acerca do estágio! E até a próxima blogada!