sábado, 26 de dezembro de 2009

Torne-se líder em sete passos

PessoALL;

Novamente meu grande amigo André Dourado arrebenta nas escolhas de posts em seu blog. Confiram:

Conversando com alguns amigos, eles sugeriram que eu escrevesse sobre um tema que é essencial para qualquer tipo de empresa, estou falando sobre liderança. Existe milhares de livros sobre o assunto e enorme quantidade de sites que abordam o mesmo tema.

Poderia aqui comentar sobre vários autores e o que eles dizem a respeito, porém vou falar da minha experiência pessoal e o que aprendi com amigos, colegas de trabalho, com as equipes e empresas que tive a oportunidades de trabalhar.

Durante muito tempo trabalhei como vendedor e já de certa forma exercia em alguns momentos o papel de líder, mesmo que informalmente, sentia que minhas ações influenciavam alguns membros da equipe. Depois de vários anos na função resolvi mudar de empresa, junto com esta mudança veio a posição de supervisor de vendas e uma equipe de 18 pessoas para liderar.

Confesso que esta migração foi traumática, pois uma coisa é você ser responsável pelo seu resultado através do seu próprio esforço e outra coisa é você ter que contar com a boa vontade de um grupo de pessoas.

Bem, antes de dar continuidade quero fazer uma observação, grupo de pessoas é uma coisa e equipe é totalmente diferente:

Grupo de pessoas: Várias pessoas que trabalham na mesma empresa, porém cada um se preocupa com o seu próprio resultado;
Equipe: Várias pessoas que trabalham na mesma empresa e que além de se preocuparem com os seus resultados individuais, também estão preocupados e compromissados com o resultado total, estas pessoas se ajudam mutuamente.
Bem, voltando a liderança das 18 pessoas, foi um sufoco, pois cada um tinha um estilo de trabalho, cada um utilizava uma ferramenta de controle própria e a impressão que eu tinha é que eu era um intruso. Tentava ajudar de todas as formas mas naquele momento não tive a capacidade de me tornar um líder, fui apenas chefe, ou seja o grupo me respeitava hierarquicamente, tinham medo de serem demitidos.

Depois de algum tempo mudei de empresa novamente, desta vez tive uma equipe menor para conduzir eram apenas 10 pessoas, com o aprendizado da primeira experiência me saí um pouco melhor, mas mesmo assim me considerava chefe e não líder. Tive alguns problemas com os membros do grupo, demiti outros, porém entreguei o resultado. Para a empresa estava ok, pois o resultado vinha em primeiro lugar.

Depois de alguns anos mudei novamente de empresa e mais uma vez tinha uma equipe sob minha responsabilidade, cheguei com o mesmo tratamento da empresa anterior, porém comecei a notar que nesta empresa resultado e pessoas tinham o mesmo peso, notei que existia um tratamento diferenciado por parte dos gestores inclusive do meu próprio líder.

Depois de algum tempo percebi que dava para mudar o tratamento e atingir resultados, pois o meu líder agia desta forma e conseguia atingir os números, a partir daí mudei o meu tratamento e posso listar 7 passos do que você precisa a fazer para se tornar um líder:

Trate todos com respeito – Até aí não tem novidade, pois acredito que você já faça isto;
Ganhe respeito através dos exemplos e dos conhecimentos adquiridos – Mostre para a equipe que você conhece o seu negócio, visite clientes junto com os membros da sua equipe, ajude naquilo que for capaz;
Seja transparente – Você já ouviu aquela frase que tudo que é combinado não é caro? então, coloque isto em prática, combine todos os direitos e deveres de cada um e cumpra-os, passe para seu time qual é a meta da empresa, das demais áreas e como eles podem participar para que a empresa a tinja o resultado, isto é mostrar o valor de cada um dentro da equipe e da empresa;
Seja amigo dos membros da sua equipe – Aqui vem aquela pergunta: Como separar amizade dos negócios? Quando você é um lider amigo, você já conseguiu transmitir onde existe esta divisa, certamente não terá problemas com isso;
Seja Coach – Ensine o seu pessoal, não esconda nada, treine todos como se fossem ocupar a sua posição no dia seguinte, a maioria quer ser desenvolvido.
Promova seu pessoal – Quando a promoção é dentro do seu negócio não há problemas, mas quando você pensa em liberar o seu colaborador para ir para um outro departamento ou equipe….vem aquele pensamento: treinei, ensinei, agora que está pronto terei que abrir mão…lembre-se que você trabalha para a empresa e se você for fornecedor de pessoas qualificadas o mérito é seu, e quando você olha para dentro da equipe, esta ação não tem preço, pois eles sabem que podem contar com você da mesma forma que você conta com eles;
Trate como gostaria de ser tratado – este é o resumo dos tópicos acima;
Posso assegurar que seguindo os modelos acima você irá conseguir se transformar num líder, como também construirá uma equipe, junto com isto sempre vêm embutido os resultados esperados.

Se você ainda está com dúvidas, tente, na pior das hipóteses você fará grandes amigos.

Fonte: Gravata Solta

quinta-feira, 17 de dezembro de 2009

Práticas de aplicativos web com Java

Amigos,
Achei um artigo sobre desenvolvimento Java muito legal, escrito pelo
Fernando Franzini.

No mundo conceitual da engenharia de software vemos inúmeras teorias, diretrizes, abordagens, idéias, teoremas etc... tudo isso relacionado com todas as partes envolvidas na produção de um sistema. Entretanto, na realidade nua e crua, vemos que a prática pode se distanciar um pouco desta almejada "Realidade Conceitual Ideal". Neste artigo, quero falar um pouco sobre práticas reais relacionadas a situações que eu tenho vivido na construção, teste e homologação de sistemas web usando java. Então vamos lá =).

Independente de qual filosofia, metodologia, abordagens ou frameworks que se possa usar no desenvolvimento do aplicativo web em java, nos últimos anos tenho sentido que não consigo fugir de dois problemas: consumo de memória e performance.

Consumo de Memória
Não é novidade para ninguém que, em java, a memória é automaticamente gerenciada através de um recurso chamado Garbage Collection, que a cada versão da JVM tem sido melhorado e incrementado. Este fato traz, para qualquer desenvolvedor, a falsa idéia de que ele pode deitar e rolar na implementação do sistema que o "Sr. pancudão coletor de lixo" vai limpar toda a sujeira que ele deixar para traz.

Na prática, percebo que os responsáveis pelos sistemas em geral - gerentes, projetistas, programadores etc., não tem colocado isso como um fator de preocupação nos ciclos de desenvolvimento, deixando "o pau torar" na programação. O resultado é que em ambiente de testes e homologação o sistema funciona lindo e maravilhoso, mas depois que entra em produção, mesmo após apenas alguns dias em que o serviço está no ar, começam as runtime exceptions apontando a falta de memória. E agora? O que fazer se o sistema está gastando mais memória do que a suportada pela configuração da JVM?

"O aumento de memória das máquinas e JVM,
ou mesmo o aumento de máquinas nos clusters,
não é a solução, e sim uma prorrogação do problema!"

Qualquer pessoa poderia facilmente sugerir que aumentássemos a memória da máquina e JVM. Entretanto, vemos que isso não é uma solução, e sim uma prorrogação do problema, porque quanto mais pessoas usando, ou quando novos processos forem acrescentados no sistema, maior será o gasto. Solucionar o problema seria perguntar para o sistema se ele não está gastando memória mais do que o necessário!!! Depois dessa certeza é que se delega mais memória para JVM, sendo que a aplicação realmente está precisando. Não quero entrar em detalhes sobre regiões de memória da JVM e nem sobre escalabilidade vertical e horizontal, pois fogem do escopo do artigo. A questão é que vejo muita gente tentando escalar a aplicação sem nem ao menos avaliar o seu consumo real.

Performance
A velocidade da aplicação em executar os processos e apresentar algum resultado está intimamente ligada com a experiência do usuário final, que vai passar horas e horas do seu dia ali na frente do sistema que foi maravilhosamente escrito para ele. Na prática, vejo que, novamente, os responsáveis pelos sistemas em geral - gerentes, projetistas e programadores, também não têm colocado isso como um fator de preocupação nos ciclos de desenvolvimento. O resultado é o mesmo de sempre, em ambiente de testes, homologação e durante algum tempo inicial de produção, o sistema funciona lindo e maravilhoso, mas depois de algum tempo começam as reclamações relacionadas com a lentidão crescente.

Seguem abaixo algumas das práticas que venho utilizando como se fosse uma "receita de bolo", mais ou menos um "pente fino" que é passado nas aplicações para corrigir as duas situações problemáticas acima citadas.

1. Acesso ao banco de dados - reduzir ao máximo o número de vezes que a aplicação faz acesso ao banco de dados.
Problema: Muitos programadores têm a mania de ir desenvolvendo classes, componentes e módulos sem antes e/ou durante fazer uma análise organizada de como estas partes do sistema estão fazendo estes acessos. Com isso, vemos como resultado aplicações com baixa performance devido aos vários e desnecessários acessos à base que se multiplicam na aplicação a medida do número de usuários simultaneamente conectados.

Solução: Analisar quantas vezes a aplicação está acesssndo o banco, o porquê do acesso, e assim tentar uma forma de evitar este acesso. Neste momento, muitos profissionais pecam por não conhecerem recursos básicos de banco de dados e de SQL-ANSI, principalmente pelas propagações de frameworks ORM. Qualquer meio é válido, alguns recursos usados para alcançar isso são o uso de VIEWS, JOIN e SUBQUERYS. Todos os programadores têm que possuir um lema em mente: "O acesso remoto é que mais degrada a performance de uma aplicação e o acesso ao banco de dados é um deles, então eu tenho que fazer de tudo para evitar ou minimizar ao máximo."

2. Índices adequados - Criar índices para as todas as tabelas que sofrem consultas na aplicação.
Problema: Muitos programadores não têm o mínimo de fundamentos de banco de dados, criando bases sem nenhum índice de busca para as tabelas que sofrem alto número de SELECT WHERE CAMPO. A questão problemática é que quando uma tabela sem índice sofre um SELECT WHERE CAMPO, o registro é buscado, na maioria das vezes, da pior e mais demorada forma possível, que é o "seqüencialmente". A pior notícia é que isso é um problema cumulativo, ou seja, quanto mais registro existente, mais demorada fica a consulta. Já tive experiências de diminuir o tempo de um procedimento de fechamento mensal em 50% do tempo, pelo simples ato de criar os índices nas tabelas usados pelo processo.

Solução: Para cada SELECT que o programa faz, em cada tabela, verifique os campos de busca colocados no WHERE e, assim, crie um índice para cada um deles.

3. Consultas Gigantescas - Sistemas que permitem o usuário consultar e trazer do banco de dados um alto número de registros.
Problema: Algumas situações comumente ocorrentes em sistemas no modelo desktop, ou mais conhecido como "FAT CLIENT", não se encaixam em aplicativos web. Um destes casos é quando sistemas permitem aos usuários filtrar e trazer do banco de dados consultas com um alto número de registros complemente desnecessário. Em casos em que o modelo era desktop, isso não acarretava problemas devido à própria natureza da solução. Entretanto em sistemas web, onde recursos de execução são limitados e o numero de acesso simultâneos é ilimitado, o sistema estará gastando um alto e precioso numero relevante de memória.
Explicando de forma prática, eu já peguei sistemas nas redondezas onde os programadores juniores estavam replicando a arquitetura que continha uma camada de persistência CRUD. A questão problemática era que o framework replicava um método que sempre retornava todos os registros existente. Isto estava sendo propagado para todo o sistema e seus processos relacionados. Se paramos para analisar, mecanismos de busca são disponibilizados ao usuário para que ele tenha autonomia de buscar registros individuais ou grupos lógicos deles. Qual seria o motivo, ou o que poderia fazer um usuário com 500 linhas de resultados de uma consulta? Que ser humano na face da terra gostaria de visualizar 500 registros em uma olhada? Mesmo que a regra de negócio ainda apoiasse o caso, o usuário final, sendo um humano comum, não teria tamanha visibilidade para isso.

Solução: Os processos do sistema em questão devem ser analisados e devem ser implementadas validações lógicas corretas, que não permitam executar consultas que retornem uma alto número de registros no banco de dados. Duas práticas neste tópico são bem comuns - o uso sistemático de paginação, e a implementação de filtros inteligentes, baseados em regra do próprio negócio, que não deixassem a ocorrência de grandes intervalos. Como tudo na vida, existem exceções, e podemos, sim, encontrar situações em sistemas que teriam a necessidade de consultar grandes volumes de registros, mas isso já está mais que comprovado que é uma porcentagem pequena e restrita do total da automação.

4. Ordenação de Tabelas - Ordenar as tabelas em memória usando java ao invés de usar ORDER BY.
Problema: Uma funcionalidade muito comum é disponibilizar a ordenação das tabelas apresentadas na aplicação pelas suas próprias colunas. A questão problemática é quando a aplicação efetua um acesso ao banco a cada ordenação requisitada. Ou seja, o programador usa o recurso de SELECT ORDER BY para fazer a ordenação.

Solução: Transformar as linhas da tabela em objetos java e, assim, ordená-los usando recursos do JSE, evitando gasto com tempo, acesso ao banco e recursos de memória. Esta solução pode ser facilmente implementando com a interface Comparable.

5. Usar Pool de conexões - usar a abordagem de Pool como paradigma de acesso ao banco de dados.
Problema: Eu realmente não sei o motivo, mas já peguei alguns aplicativos web por aí que abrem e fecham objetos de conexão com o banco de dados a cada requisição. Ou seja, a cada pedido enviado ao web container, no mínimo 2 chamadas remotas são efetuadas, uma autenticar o usuário/senha e outra para efetuar a comando SQL desejado. Esta opção é uma das piores gafes que um programador web pode fazer para deixar o sistema com a pior performance possível, sem falar que o sistema pode "baleiar" o banco quando o número de acesso simultâneos exceder a capacidade de resposta do determinado banco de dados.

Solução: Na web existe uma única solução comprovada que é o uso efetivo da abordagem de Pool de conexões. No momento da disponibilização - deploy da aplicação, o sistema deve abrir um numero X de conexões com o banco de dados que sera posteriormente usado em toda a aplicação. Esta abordagem mistura o conceito de compartilhamento e concorrência, sendo que pedidos em tempos diferentes reutilização a mesma conexão e pedidos simultâneos usarão diferentes conexões. Este numero X deve ser levantando e configurada de forma parametrizada de acordo com o perfil da aplicação e do modo/quantidades que os usuários estarão gastando conexões durante utilização do sistema.

6. Usar Cache - Cachear informações que sofrem alto índice de acesso e baixa ocorrência de alteração.

Problema: Sistemas em geral implementam administração de informações na qual poderíamos classificar em 2 tipos: dados de manutenção/parâmetros e de processos:

a. Manutenção/Parâmetros - informações que os sistemas têm que guardar, usadas como parte do processo, que não possuem um fim nelas mesmas. Estes tipo de formação frequentemente sofre um baixo índice de manutenção e um alto número de acesso. Ou seja, no escopo da aplicação, estes dados raramente são alterados e muitos usados.

b. Processos - informações resultantes de processos com regras de negócio do escopo da aplicação. Estes podem ou não sofrer alterações e podem ou não ser altamente acessados. Tudo depende da natureza do negócio da aplicação. A situação complicada seria o sistema fazer um acesso ao banco de dados a cada momento que diferentes usuários (concorrentes ou não) necessitam usar informações de manutenção, que na grande maioria dos casos são iguais. Ou seja, teríamos vários usuários acessando o banco de dados repetidas vezes para pegar as mesmas informações, gastando assim tempo e memória de forma desnecessária.

Solução: Analisar cuidadosamente e cachear as determinadas informações que se encaixam de alguma maneria no perfil de dados de "Manutenção/Parâmetros". Conceitualmente, é fácil visualizar o mecanismos de cache: o primeiro usuário que necessitar da determinada informação efetuará um acesso ao banco e cacheará os dados em algum lugar na memória, fazendo com que os próximos usuários não precisem gastar tempo e memória repetindo o ciclo. O cache é atualizado quando estes dados forem atualizados de alguma maneira no sistema, bem como o perfil deles já mostrou que seria um caso difícil de acontecer.
A prática do cache, entretanto, não é algo simples ou trivial, demandando tempo e esforço para ser implementado. Eu poderia sugerir implementações prontas como o EhCache, ou serviços de cache disponibilizados pelos frameworks ORM. Veja que a utilização só vale a pena se os dados realmente possuírem um alto índice de acesso. Com esta abordagem, a aplicação consegue reduzir em média até 40% o acesso ao banco de dados. Uma sugestão bem simples e que deu bastante resultado é simplesmente implementar um mini cache usando o "application context" da aplicação que, com algumas classes estáticas, se consegue cachear/alterar estes dados, reduzindo em um porcentagem considerável o acesso ao banco de dados.

7. Controlar a criação de objetos: controle efetivo da criação de objetos durante a execução do programa.
Problema: Algo que precisamos sempre lembrar durante a programação é que o operador new aloca fisicamente o objeto da memória, gastando espaço no HEAP da aplicação. A primeira questão problemática é que percebo que os programadores usam o new de forma displicente, sem nem ao menos parar para pensar em que contexto da aplicação está usando. Tudo é motivo para fazer um new, eu já vi casos em que para reiniciar o estado do objeto, o programador dava um new na referência.

Solução: O programador tem que sair desse comodismo e começar a analisar todos os seus new! Duas perguntas resolvem o problema: 1. Por que estou alocando esse objeto? 2. Quantas vezes esse código vai ser executado? Estas duas perguntas vão consciencializar o programador daquela situação, levando-o no mínimo a tomar uma das duas decisões abaixo:

- Reutilizar Objetos - ao invés de ficar sempre fazendo new, ele pode aumentar a visibilidade do escopo daquele objeto e assim reusá-lo, restartando seu estado.

- Reduzir o Escopo - reduzir o escopo dos objetos vai deixá-los disponíveis mais rápido para o coletor de lixo. Se for preciso, use escopos lógicos menores com { }. Esta solução é uma das mais difíceis a serem implementadas, porque invadem a "cultura" do programador de se autocriticar. Mas quero animá-los dizendo que a batalha da economia de memória e performance se ganha na somatória de detalhes!

8. Controlar objetos String - controlar o gasto com os objetos Strings.
Problema: Outra coisa que sempre precisamos lembrar é que os objetos String chamados de "wrappers" são imutáveis, ou seja, uma vez instanciados eles nunca mudam. Qualquer operação com a String gerará uma terceira String. O problema aqui é o uso abusivo, desnecessário e inconsciente das String durante a execução do programa.

Solução: Segue a mesma idéia do tópico 5. O programador deve analisar a questão da necessidade e entender o porquê daquele uso. Duas opções surgem para contornar a situação:

- usar final static para as Strings que se encaixam no contexto de estáticas (SQLs, mensagens). Ou seja, somente será gasto um objeto para todas as execuções do programa.

- usar StringBuffer/StringBuilder para as String que sofrem alterações constantes ou para situações de manipulação de arquivos.

9. Aumentar as configurações de memória da JVM
Problema: Mesmo depois de todas as precauções tomadas, a aplicação ainda pode gastar mais memória do valor default previamente configurado na JVM.

Solução: Neste casos, é preciso fazer um estudo, apurando a média de memória gasta pela aplicação, usando alguma ferramenta de profile e, assim, configurar um adequado número razoável de memoria.

Fonte:
IMaster

terça-feira, 15 de dezembro de 2009

Grandes frases ditas por jogadores de futebol...

'Chegarei de surpresa dia 15, às duas da tarde, vôo 619 da VARIG.'
(Mengálvio, ex-meia do Santos, em telegrama à família quando em excursão à Europa)

'Tanto na minha vida futebolística quanto com a minha vida ser humana.'
(Nunes, ex-atacante do Flamengo, em uma entrevista antes do jogo de despedida do Zico)

'Que interessante, aqui no Japão só tem carro importado.'
(Jardel, ex-atacante do Grêmio)

'As pessoas querem que o Brasil vença e ganhe.'
(Dunga, em entrevista ao programa Terceiro Tempo)

'Eu, o Paulo Nunes e o Dinho vamos fazer uma dupla sertaneja.'
(Jardel, ex-atacante do Grêmio)

'O novo apelido do Aloísio é CB, Sangue Bom.'
(Souza, meio-campo do São Paulo, em uma entrevista ao Jogo Duro)

'A partir de agora o meu coração só tem uma cor: vermelho e preto.'
(Jogador Fabão, assim que chegou no Flamengo)

'Eu peguei a bola no meio de campo e fui fondo, fui fondo, fui fondo e chutei pro gol.'
(Jardel, ex- jogador do Vasco e Grêmio, ao relatar ao repórter o gol que tinha feito)

'A bola ia indo, indo, indo... e iu!'
(Nunes, jogador do Flamengo da década de 80)

'Tenho o maior orgulho de jogar na terra onde Cristo nasceu.'
(Claudiomiro, ex-meia do Inter de Porto Alegre, ao chegar em Belém do Pará para disputar uma partida contra o Paysandu, pelo Brasileirão de 72)

'Nem que eu tivesse dois pulmões eu alcançava essa bola.'
(Bradock, amigo de Romário, reclamando de um passe longo)

'No México que é bom. Lá a gente recebe semanalmente de 15 em 15 dias.'
(Ferreira, ex-ponta esquerda do Santos)

'Quando o jogo está a mil, minha naftalina sobe.'
(Jardel, ex-atacante do Vasco, Grêmio e da Seleção)

'O meu clube estava a beira do precipício, mas tomou a decisão correta, deu um passo a frente.'
(João Pinto, jogador do Benfica de Portugal)

'Na Bahia é todo mundo muito simpático. É um povo muito hospitalar.'
(Zanata, baiano, ex-lateral do Fluminense, ao comentar sobre a hospitalidade do povo baiano)

'Jogador tem que ser completo como o pato, que é um bicho aquático e gramático.'
(Vicente Matheus, eterno presidente do Corinthians)

'O difícil, como vocês sabem, não é fácil.'
(Vicente Matheus)

'Haja o que hajar, o Corinthians vai ser campeão.'
(Vicente Matheus)

'O Sócrates é invendável, inegociável e imprestável.'
(Vicente Matheus, ao recusar a oferta dos franceses)