É impossível agradar a todos, especialmente em sala de aula

Sempre gostei de trabalhar com a qualidade do código-fonte, onde nos últimos 10 anos, me tornei um fervoroso adepto das boas práticas do paradigma POO. Princípios S.O.L.I.D., Design Patternsrefactoring (especialmente para bad smells), TDD, integração contínua, métodos ágeis, e qualquer outro tema que priorize a qualidade do código-fonte. Esse tema sempre me motivou em todos os segmentos da minha carreira, como o post Você realmente cria Softwares no Paradima POO?, pesquisas no mestrado e constante avaliação crítica, seja do meu código-fonte ou dos colegas.

Contudo, em 7 anos de docência, nunca tinha recebido uma oportunidade de ministrar alguma disciplina onde eu pudesse ter total liberdade de abordar este assunto. O máximo que tinha conseguido foi a oportunidade de ministrar uma disciplina chamada “UML e Padrões de Projeto” no curso de Pós Graduação Lato Sensu em “Desenvolvimento Java”, onde eu podia abordar uma parte do assunto, mas não com foco total.

Com alguns meses de docência no IFTM, finalmente consegui ter a oportunidade de ministrar uma disciplina neste formato, da melhor forma possível: a disciplina “Programação Orientada a Objetos”(POO) do curso de Pós Graduação Lato Sensu em “Análise e Desenvolvimento de Sistemas Aplicados à Gestão Empresarial”. A disciplina possui 8 encontros com 4 horas cada. Por se tratar de um curso onde 100% dos alunos possuem graduação em cursos de computação e afins, podia assumir tranquilamente que todos conheciam herança, encapsulamento, polimorfismo, composição, sobrecarga, sobrescrita, e todos os outros conceitos básicos de POO. Seria necessário apenas doutriná-los, para mergulharem no paradigma, buscando evoluir drasticamente a qualidade do seu código-fonte, livrando-os das maldições procedurais.Além de tudo isso, este tipo de disciplina é interessante, porque a grande maioria conhece o básico, mas poucos conhecem profundamente. Por isso, fica mais fácil e interessante de se aprofundar, diferente de disciplinas onde todo o conteúdo tende a ser novidade. Além do que, com os anos de experiência em desenvolvimento de sistemas comerciais no mercado de trabalho, surge uma bagagem natural que pode ser bem explorada na disciplina, mostrando várias decisões ruins aplicadas no dia-a-dia.

A primeira aula foi no dia 14/03/2015. Todos os planos de aula, slides e exemplos do curso estavam preparados. Algum tempo antes, tinha comprado na casa do código três livros que envolvem POO para buscar a abordagem mais atual possível. Resgatei alguns livros que já tinha e fechei o conteúdo. Na primeira aula(clique para ver os slides), ficou claro que a turma era bastante heterogênea: alguns estavam no mercado programando a todo vapor, enquanto que outros trabalhavam com outros paradigmas, e alguns tinham alguns bons anos que não criavam uma linha sequer de código-fonte. Eu já esperava por isso, tanto que o material preparado da primeira aula ficou bastante didático e baseado em um overview e nivelamento, para começar a “tacar fogo” a partir da segunda aula. Obviamente coloquei materiais de pré-requisito da disciplina, além de diversos livros e links, tudo com o propósito de guiar o aluno para o melhor aproveitamento possível. Após a primeira aula, percebi que precisavam de um reforço extra, então resolvi criar dois vídeos no youtube para ajudá-los a resgatar os conceitos: poo básico parte 1 e poo básico parte 2. Também formalizei um horário de atendimento semanal com 1 hora e meia de duração, para que as dúvidas fossem sanadas neste horário.

Após essa aula, no primeiro atendimento da semana seguinte, ao conversar com alguns alunos, já percebi que o nivelamento não poderia se restringir à primeira aula, precisaria mostrar como os objetos resolvem coisas básicas como: criar telas funcionando, persistência no banco de dados,etc… as pessoas no geral até entendem os objetos, mas em exemplos acadêmicos. Não sabem ao certo como isso funciona no dia-a-dia. Por isso decidi refazer os meus planos de aula, e ministrar algumas “aulas passo-a-passo”, ou “aulas tutorial”. Esse tipo de ajuste é comum, podemos planejar uma aula perfeitamente, mas pelo fato de estarmos constantemente lidando com pessoas, é natural que cada turma tenha uma forma mais apropriada em absorver o conteúdo. Com isso, os objetos de aprendizagem tendem a variar com o perfil de cada turma.

Com isso, na segunda(clique para ver os slides) e terceira(clique para ver os slides) aulas, ministradas em 20 e 21/03/2015, adotei um formato passo-a-passo, mas tentei fazer isso de maneira elegante, tentando chegar em um meio termo, para prender a atenção de todos: fiz um passo-a-passo em sala de aula sobre como criar um sistema básico orientado a objetos, utilizando MVC para que o projeto tenha separação lógica de camadas, utilizando Java Swing com o matisse do NetBeans para a criação de telas, classes de domínio mapeadas com hibernate/jpa para persistência no banco de dados Java DB(Apache Derby), e o framework beans binding para efetuar a vinculação automática entre os campos da tela e os objetos do control. Eu particularmente não gosto de aulas “passo-a-passo ou tutorial”, mas reconheço que é bem produtivo no que diz respeito ao nivelamento dos alunos, pois agrega muita prática para os que pouco sabem do assunto, e para os que possuem maior conhecimento, pelo menos uma ou outra novidade irá surgir. Por exemplo, nenhum aluno desta turma conhecia o framework beans binding e a sua forma elegante de trabalhar com as vinculações de objetos. O objetivo desta aula era apenas que os alunos entendessem melhor como que os objetos trocam mensagens para resolver problemas, especialmente em sistemas comerciais. Aspectos como a criação das telas e a persistência foram itens que tomaram muito pouco tempo, em virtude da produtividade do NetBeans. Obviamente usei conceitos visando qualidade, como genéricos, interfaces, isolamento de código, pacotes, padrões Java EE como DAO, Facade, etc.. Na aula 3 ainda fiz um total desacoplamento da camada Model, colocando-a em outro projeto, e até em outra IDE (Eclipse), efetuando uma comunicação cliente-servidor, via RMI (Remote Method Invocation). Não sou fã do RMI, mas é um ótimo estudo de caso para ensinar  melhor o desacoplamento de classes, e até ajuda no entendimento de outros itens, como por exemplo, a geração e o entendimento de bibliotecas .jar, pois o servidor precisa gerar uma biblioteca para aplicações cliente. Como sabia que era muita informação e muito passo-a-passo prático em sala de aula, fiz 5 vídeos e publiquei para que conseguissem absorver melhor os conceitos em casa. MVC parte 1, MVC parte 2,MVC parte 3,MVC parte 4 e MVC parte 5. Eu adoro criar vídeos, mas toma bastante tempo, pois são várias horas consumidas para criar os vídeos e efetuar o upload destes, fora o tempo de preparação dos slides, consolidação do conteúdo, horários de atendimento e as aulas em si.

Como mudei os planos de aula, naturalmente o sistema de avaliações também iria sofrer um “refactoring“. 1 mês antes de iniciar as aulas, tinha planejado distribuir os 100 pontos da seguinte forma: 20 pontos para formalizar os requisitos de um projeto, e os demais 80 pontos para executá-lo. Observei que, como os alunos precisavam aprender boas práticas de POO rapidamente, um bom negócio seria pedir para estes realizarem leituras de artigos técnicos de revistas como Java Magazine, e efetuarem resumos, me entregando em datas estratégicas, ou seja, exatamente no dia destes conteúdos serem efetivamente ministrados. Com isso, na quarta aula, pedi a leitura de dois artigos técnicos, me entregando os resumos no dia da sexta aula, com 2 semanas de prazo. Os artigos foram: Entendendo o Encapsulamento em Java e Desenvolvendo Software Sólido. O professor ganha muito com essa abordagem, pois eleva o nível do conhecimento do aluno com material extra, e o aluno também ganha, pois o seu estudo é recompensado com pontos, neste caso, 25 pontos.

Para a quarta(clique para ver os slides) e quinta(clique para ver os slides) aulas, ministradas em 27 e 28/03/2015, percebi a chance de introduzir algumas boas práticas POO no projeto “passo-a-passo” que foi criado em conjunto com os alunos nas duas aulas anteriores. As estratégias do bom uso de herança e composição são clássicas do paradigma POO, então abordei estas no projeto, refatorando as camadas DAO e Control, primeiramente usando a estratégia de herança, e posteriormente a estratégia de composição, comparando ambas, elevando o nível da discussão em sala de aula. Tudo isso sem sair do passo-a-passo, efetuando um refactoring em conjunto com todos os alunos, o que soa bastante interessante, pois todos programam, e depois discutem a efetividade da solução, pensando no seu código-fonte. Obviamente não perdi a chance e continuei os vídeos, criando as MVC parte 6, MVC parte 7 e MVC parte 8 apresentando essas estratégias de refactoring criadas em sala. Nos vídeos, geralmente adiciono algo que não foi dito em sala, para incentivá-los a assistir.

Na sexta(clique para ver os slides) e sétima(clique para ver os slides) aulas, ministradas em 10 e 11/04/2015, assumindo que os alunos tiveram bastante prática com o conteúdo, além de terem lido e entregado os resumos dos dois artigos que pedi para serem lidos, resolvi modificar um pouco a estratégia: cessaram as aulas passo-a-passo, e entraram as aulas mais alto nível, com as partes teórica e prática, aproveitando inclusive alguns pequenos projetos já prontos, para que o código-fonte seja analisado, e pequenas mudanças sejam feitas em aula. Com isso, mais conteúdo pode ser ministrado em menos tempo: os princípios POO, especialmente os básicos como “Encapsule o que varia”, “Modelo anêmico”, “Programe para a interface e não para implementação”, “Evite Herança Favoreça Composição”, “Favoreça Imutabilidade”, etc… trouxeram uma discussão em alto nível, e a todo tempo, além dos novos projetos, o projeto passo-a-passo utilizando entre as aulas 2 até 5 não foi esquecido, onde os conceitos dos princípios eram confrontados com algumas decisões tomadas neste projeto, evidenciando boas e más escolhas. Na aula 7, isso ficou ainda mais evidente, pois o conceito de inversão de controle é imprescindível, e algumas más práticas adotadas no projeto passo-a-passo nos motivaram a refatorá-lo e aplicar este bom princípio. Uma boa vantagem de não abordar todas as boas práticas de uma vez em um projeto é que, os alunos geralmente só vêem o benefício quando já conhecem uma abordagem inferior, mas claro que isso tem um limite. Essa aula inspirou os vídeos MVC parte 9 e a MVC parte 10, que mostram na prática um pequeno refactoring realizado no projeto passo-a-passo, usando inversão de controle. Como sabia que a aula 8 que ainda seria ministrada possuiria grande foco em Design Patterns, pedi para lerem e efetuarem o resumo de um artigo que aborda este tema, que foi o Explicando Padrões de Projeto, valendo mais 25 pontos, ou seja, metade dos pontos da disciplina foram distribuídos no resumo destes 3 artigos. Este artigo teve o valor de 25 pontos porque existem 4 partes do mesmo na revista.

Por fim, na oitava e última aula(clique para ver os slides), ministrada em 17/04/2015, alguns bad smells e design patterns precisavam ser abordados. Nesta parte, nada de projeto passo-a-passo, só exemplos que justicam o uso dos design patterns, pois sempre defendi que inventar o uso de padrão em um problema é um grande indício de anti-pattern. Observei que, mesmo abordando apenas 6 padrões na teoria e prática, a aula ficou um pouco alto nível para alguns alunos, e mesmo assim, chegando em casa, resolvi criar 6 vídeos, buscando uma nova abordagem para explicar o conteúdo. Entendendo patterns parte 1,Entendendo patterns parte 2, Entendendo patterns parte 3,Entendendo patterns parte 4,Entendendo patterns parte 5 e Entendendo patterns parte 6 .

Finalizado o curso, formalizei um email nesta mesma aula, que os 50 pontos restantes seriam usados para criar um Sistema no formato do projeto passo-a-passo utilizado nas aulas 2 até 7, com apenas 3 requisitos básicos:

1 – Uso de 2 design patterns gof à escolha;

2 – Uso dos princípios POO e MVC;

3 – Pelo menos 3 tabelas.

A data de entrega foi marcada para 30 dias depois, ou seja, dia 17/05. O sistema é livre de linguagem, desde que esta seja Orientada a Objetos. Mas obviamente, foram feitos 18 vídeos durante o decorrer da disciplina com todo o material pronto em Java, apenas necessitando mudar o exemplo para entregar o trabalho. De qualquer forma, deixei livre porque soa muito mais interessante tanto para mim quanto para eles.

Com o curso finalizado, surgiu uma sensação imensa de dever cumprido, pois fiz da melhor forma possível, com poucos erros, e do jeitinho que gostaria de ter aprendido, seja em cursos de graduação ou pós graduação. Se ainda for levar em conta que ministrei a disciplina pela primeira vez, diria que foi um resultado muito positivo. Talvez a minha única auto-crítica é que eu deveria ter solicitado a leitura desses artigos logo na primeira aula, e infelizmente tive essa idéia apenas com o curso em andamento. Também recebi muitos elogios de outros professores, que perceberam claramente o esforço. Um colega por exemplo foi categórico em dizer que é rarísismo um professor produzir 18 vídeo-aulas em um curso de 1 mês.

Mesmo com todo esse feedback positivo, infelizmente, recebi alguns feedbacks não tão agradáveis. Alguns alunos reclamaram deste trabalho final, que eu deveria ter solicitado este no meio do curso, para me me entregassem no dia do término da disciplina, evitando deixar trabalhos em aberto com as aulas já encerradas (como se não tivessem acesso a horários de atendimento, email e vídeo aulas). Outros já reclamam que eu deveria ser mais autoritário, não permitindo interrupções de alunos, para que a aula seja mais produtiva. Outros reclamam que eu ministro conteúdo demais, cobro demais,etc.. Se a minha carreira de docente estivesse se iniciando exatamente neste curso, certamente estaria muito chateado e talvez até arrependido de ter me dedicado tanto. Mas, após alguns anos, aprendemos algumas coisas simples, que nos ajudam a seguir em frente produzindo cada vez mais:

1 – O conteúdo, as metodologias e os objetos de aprendizagem da aula sempre precisam ser adaptados e aperfeiçoados. Professores que ensinam hoje do mesmo jeito que 20 anos atrás estão fadados ao fracasso;

2 – É impossível agradar a todos, especialmente em turmas heterogêneas. Sempre vai ter o aluno que exige que o curso seja ministrado exatamente do jeito que ele quer, não se importando se os demais colegas irão ou não aprender;

3 – Descontração é muito importante em sala de aula, especialmente quando se trata de 4 horas seguidas. Breves intervalos em aula com relatos de experiências vividas no dia-a-dia, não só geram descontração como recapturam a atenção dos alunos que se perderam na aula;

4 – Professor não somente ensina, mas também aprende. Observe que, quando o docente possui muito apreço pelo conteúdo, qualquer informação pertinente que o aluno possa compartilhar, tende a ser muito bem vinda;

5 – O bom professor é aquele que cobra do aluno, que mostra caminhos, novas formas de se pensar, que exige excelência e dedicação. Observe que, isto não tem nada a ver com injustiça. Injustiça é um professor cobrar algo na prova que não ensinou, ou corrigir uma prova errada e não aceitar voltar atrás, ou exercer abuso de autoridade em sala de aula. Um professor pode perfeitamente bem exigir muito do aluno, e ser justo;

6 – Especialmente em disciplinas que envolvem programação: todo mundo gosta de falar de programação, mas poucos realmente gostam de programar. A grande verdade é que a maioria começa a carreira de programador já sonhando com o dia em que possivelmente serão coordenadores ou gerentes de projeto. Da mesma forma que todo mundo quer parecer inteligente, culto, articulado, mas poucos realmente se movem para isso. Qual é a moral da história? Se o docente exige que o aluno crie código-fonte, seja em sala de aula ou em casa, está destinado a ser criticado, por melhor que seja a aula.

7 – Todo mundo gosta de receber elogios, mas muito antes ser criticado fazendo o certo, do que ser o elogiado que deixa de fazer o certo.

Por fim, concluo tudo o que foi dito com um excelente pronunciamento do Professor Clóvis, da faculdade de Filosofia da USP.

Posted in Software Development | Leave a comment

A volta do Paradigma Funcional para criação de Softwares comerciais

De acordo com o Wikipedia (link), a Programação Funcional (ou FP, de Functional Programming ) é um paradigma de programação que trata a computação como uma avaliação de funções matemáticas , e que evita estados ou dados mutáveis, enfatizando a aplicação de funções, ao contrário da programação imperativa comumente encontrada em linguagens como Java e C# , que enfatizam mudanças no estado dos programas. Este paradigma nasceu de um modelo de computação criado por Alonzo Church na década de 30, e posteriormente, com a Linguagem de Programação Lisp, desenvolvida por John McCarthy no final da década de 50, ambos no século passado. Desde então, diversas novas Linguagens Funcionais foram criadas e aprimoradas, contudo, este paradigma têm obtido maior popularidade no meio acadêmico, enquanto que no meio comercial/industrial, têm pouco espaço se comparado com a programação imperativa, com suas linguagens estruturadas e orientadas a objetos. Por muitos anos, a indústria têm considerado as linguagens funcionais como ineficientes, sendo adequadas apenas para resolver exercícios acadêmicos, e como sua sintaxe e semântica são diferentes do que os programadores comerciais estão acostumados a usar, pouco foi feito para que estas ganhassem maior popularidade.

Contudo, de alguns anos pra cá, o que se tem visto no meio comercial/industrial é uma espécie de “resgate” ao paradigma funcional, com diversas linguagens implementando recursos clássicos deste paradigma, como cálculos lambda, closures, imutabilidade, entre outros. Novas linguagens como F#, Scala e Clojure foram criadas com foco no paradigma funcional para uso comercial, e até algumas das mais populares linguagens imperativas como Java e C# , têm incorporado em sua sintaxe diversos dos conceitos encontrados no Paradigma Funcional. Em 2009, Steve Vinoski publicou um artigo chamado “Welcome to the Functional Web” (link), alertando sobre a retomada da popularidade do uso de linguagens funcionais na Web, causada principalmente pela facilidade de se trabalhar com concorrência e expressividade, resultando em performance e eficiência. O objetivo deste resumo é enfatizar com exemplos práticos, os principais fatores que levaram este paradigma a retomar seu merecido espaço, principalmente no uso comercial.

1) Expressividade

Este talvez seja um dos itens mais conhecidos dos programadores comerciais, já que é do conhecimento de muitos que, caso sejam usados corretamente, recursos do Paradigma Funcional permitem fazer “mais com menos”, ou seja, menos linhas de código para se resolver o mesmo problema. Linguagens imperativas são conhecidas por serem “verbosas”, ou seja, é necessário escrever uma considerável porção de código para resolver determinado problema, enquanto que estes podem ser muito simplificados na Programação Funcional.

Considere o exemplo abaixo, escrito na Linguagem Java, versão 7.

ex1

Este código faz um loop em um vetor de itens, e verifica para cada item, se o usuário que é enviado por parâmetro o possui. Caso sim, adiciona este no vetor, devolvendo todos os itens que o usuário possui. Considere agora o código abaixo, que resolve o mesmo problema descrito acima, contudo escrito na Linguagem Java, versão 8.

ex2

Observe que, o código acima faz uso de operadores lambda (->) e closures, se tornando muito mais expressivo que o código anterior, ou seja, faz o mesmo com menos linhas de código. Isto soa fantástico levando em consideração que está sendo utilizada uma linguagem que desde o começo foi projetada para ser imperativa, e que devido ao seu compromisso em garantir compatibilidade com versões anteriores, está limitada no que diz respeito a inovação e evolução.

Ao considerarmos uma linguagem como Scala, que não tem tantas restrições quanto a linguagem Java, além de ter sido projetada como linguagem funcional, o mesmo problema pode ser resolvido de forma ainda mais expressiva. Segue exemplo abaixo:

def possui(user: User) = items.filter(user possui _)

2) Imutabilidade

A Imutabilidade é um recurso constantemente adotado em Linguagens Funcionais, e que de alguns anos pra cá, tem sido adotado em alguns recursos das Linguagens Imperativas. Está relacionada com o fato dos objetos e variáveis não poderem ter os seus valores alterados, obrigando o compilador a sempre devolver uma nova instância com a alteração requisitada do objeto, ao invés de alterar a instância original.

Por exemplo, considere o exemplo abaixo, escrito em Java:

ex3

A variável dataCompra recebeu uma data e foi enviada como parâmetro para se calcular a data de vencimento. Antes da execução do método, foi invocado um “print” na tela para garantir que o valor mostrado é exatamente o valor que foi instanciado, ou seja, 15/08/2014. Após executar o método, é possível garantir que o valor da variável dataCompra permaneça o mesmo? Segue abaixo o resultado:

ex4

Observe que a variável sofreu um efeito colateral, ou seja, o método conseguiu modificar o valor da variável, refletindo na execução externa do método. Neste caso, a data não é um objeto Imutável, mas sim Mutável. A grande questão da Imutabilidade é que objetos imutáveis são muito mais simples de manipular do que os mutáveis, tendo um comportamento bem mais previsível. Objetos imutáveis não sofrem efeitos colaterais, pois têm comportamento previsível em relação ao seu estado, evitando um imenso desperdício de tempo para descobrir e corrigir erros por causa de efeitos colaterais em objetos mutáveis.

Claro que é possível implementar Imutabilidade em Linguagens Imperativas, criando cópias defensivas de objetos, ou seja, os atributos podem ser encapsulados em uma classe, e toda vez que forem retornados, um novo objeto clone é retornado, ao invés do objeto original. Contudo, o que está sendo feito é um mero “Work Around” para resolver tal problema. O ideal é que a Imutabilidade seja nativa, como acontece por exemplo, na classe String da Linguagem Java.

Uma consequência interessante da Imutabilidade está no fato das variáveis não mudarem, ou seja, nascem e morrem com o mesmo estado. Programando no Paradigma Funcional, praticamente se extingue a necessidade do uso de variáveis globais, que podem interferir no retorno das funções. Na programação imperativa,a saída da função depende o argumento de entrada e o estado atual do programa. Na programação funcional, funções apenas dependem de seus argumentos de entrada. Em outras palavras, quando uma função for chamada mais de uma vez com o mesmo valor de entrada, esta sempre obterá o mesmo valor de saída, semelhante ao que acontece na matématica, uma vez que, por exemplo, sempre que a função na figura abaixo for chamada com entrada “5”, o valor retornado sempre será 27. Essa abordagem facilita bastante os testes dos sistemas, possibilitando automações, eliminando erros e redundâncias, deixando o código-fonte mais modular.

f(x)2

Caso tenha interesse em ler mais sobre Imutabilidade, o livro “Introdução à Arquitetura e Design de Software” aborda sobre o tema. Segue link

3) Concorrência

Dean Wampler escreveu em seu livro “Programação Funcional para Desenvolvedores Java” (link) que aprender a escrever software com concorrência
robusta não é mais algo opcional. Isso faz todo o sentido, quando olhamos para os processadores atuais, que possuem praticamente a mesma frequência dos processadores de 4 ou 5 anos atrás, contudo com mais núcleos, cache e otimizações. As fabricantes de processadores (AMD e Intel) tiveram que tomar este rumo com os processadores por um simples motivo: os antigos processadores estavam atingindo velocidades (ou frequências) muito altas e logo não haveria sistema de refrigeração eficiente o suficiente para que eles não chegassem a temperaturas tão altas. Com isso, os processadores multicore ganharam espaço, e a tendência é que cada vez mais núcleos sejam adicionados nos processadores.

Contudo, para usufruir de um processador multinúcleo, os Softwares devem ser projetados para executarem tarefas em paralelo, ou seja, multithread. Processadores com mais de um núcleo podem executar mais de uma thread simultaneamente, contudo, para se aproveitar deste benefício, deve-se ter o mínimo de travas (ou locks) possível, ou seja, quanto mais travas em threads originadas por áreas de regiões críticas, mais tempo as threads dos demais núcleos estarão paradas esperando que a execução dentro da região crítica termine. E regiões críticas são definidas porque é a solução a ser utilizada quando se manipula memória compartilhada.

Linguagens Funcionais oferecem nativamente uma alta escalabilidade com sincronização e concorrência multithreads, em virtude principalmente das variáveis imutáveis. Com a tendência de cada vez mais núcleos nos processadores, as linguagens serão obrigadas a oferecer a máxima escalabilidade possível para execuções multithreads.

Conclusão

Com novas linguagens funcionais para uso comercial, recursos de Programação Funcional sendo adotados em Linguagens Imperativas, e com esta série de vantagens, como por exemplo a concorrência, é inevitável que ao menos os princípios de Programação Funcional retomem o seu merecido espaço na criação de Softwares comerciais. IDEs como a versão 8.0 do NetBeans já estão utilizando Sistemas de Recomendação para sugerir ao Programador que modifique o código escrito para os princípios do Paradigma Funcional, seja sugerindo que um loop simples seja modificado para uma instrução Lambda, ou que atributos se tornem imutáveis utilizando o modificador final, como mostra a figura abaixo.

ex5

ex1

Posted in Software Development | Leave a comment

Xbox One perdendo para o Playstation 4 nos jogos Multiplataforma? Descubra quem é o vilão

Depois dos primeiros jogos lançados para ambos os consoles, temos percebido que o Xbox One fez um bom dever de casa com os gráficos dos seus primeiros jogos exclusivos, contudo têm sofrido problemas nos jogos multiplataforma, ou seja, resoluções e framerate geralmente inferiores às versões lançadas no Playstation 4. Mas se ambos os consoles possuem 8GB de RAM e processadores praticamente equivalentes, onde está o vilão? Nos parágrafos abaixo serão explicados os motivos.

O Hardware do Xbox one hoje tem duas grandes desvantagens em relação ao hardware do Playstation 4. A primeira é que embora ambos os consoles possuem 8GB de RAM, existe uma grande diferença de velocidade para a APU (CPU + GPU) buscar/gravar dados na RAM.

A velocidade em ambos os consoles é uma conta simples:

No PS4 é: barramento de 256 bits a 5500mhz (DDR5), logo 5500 X 256 = 1.408.000 gigabits por segundo. Dividindo por 8 (1 byte = 8 bits), temos 176 gigabytes por segundo.

No Xone é: barramento de 256 bits a 2133(DDR3), logo 2133 X 256 = 546.048 gigabits por segundo. Dividindo por 8 (1 byte = 8 bits), temos 68,25 gigabytes por segundo.

Se essa fosse a “conta final”, a Microsoft estaria em seríssimos apuros, pois na prática nunca iria conseguir renderizar todo esse “mundo” de 8GB (caso o jogo realmente tenha picos de 8GB) em uma taxa de quadros aceitável. Por isso, utiliza um chip gráfico chamado de ESRAM para tentar equilibrar o tempo de acesso com o Playstation 4.

A ESRAM é uma memória de 32MB que é utilizada para “cache” dos 8GB, ou seja, ela armazena as informações mais demandadas pela APU (CPU + GPU) no momento, para evitar que a APU seja obrigada a buscar as informações diretamente na RAM a sofríveis 68,25 gb/s. Caso a informação não esteja nos 32MB da ESRAM, um processo em segundo plano é iniciado para atualizar a ESRAM, a fim de minimizar ao máximo as buscas da APU diretamente na RAM.

Na prática, a ESRAM possui velocidade de 102GB/S para cada sentido, isto é, 102GB/S para ler a “demanda” da APU somados com 102GB/S para devolver algum dado solicitado anteriormente pela APU, ou seja, a ESRAM consegue ler e devolver ao mesmo tempo, totalizando 204GB/S. Lembrando que, como os 32MB são usados como cache, constantemente está sendo atualizado com as informações mais acessadas pela APU, gerando uma considerável melhoria de performance.

Contudo, embora a ESRAM melhore a situação do Xbox One, não se equipara com o tempo de acesso no PS4, pelos motivos abaixo:

1) A velocidade da ESRAM supera a GDDR5, mas a diferença é pequena para reverter a situação. Enquanto que a APU do Playstation 4 acessa todos os 8GB de RAM a 176GB/s, a APU do Xbox One acessa 32MB dos 8GB, ou seja, apenas 0.4% de toda a sua memória a 204GB/S, e 99,6% de sua memória a 68,25GB/S. Se para os jogos atuais que possuem picos de 2GB ou 3GB, já estamos vendo diferenças nas resoluções e framerate, imagina quando ambos os consoles utilizarem todos os 8GB de RAM. A diferença de performance pode refletir em sérios problemas ao Xbox One.

Colocando essa conta na prática, temos a situação abaixo:

Suponhamos que, a cada 10 informações demandadas pela APU do Xbox One, 5 estejam no cache, logo tem-se a média abaixo:

Média Xbox One = (204GB/S * 5) + (68,25 * 5) / 10 = 136,12GB/s que será o tempo médio de acesso

No Playstation 4, a conta é super simples, já que a cada 10 informações, todas terão tempo de acesso a 176GB/s.

Para o Xbox One “igualar” a média do Playstation 4, 8 a cada 10 informações buscadas pela APU vão precisar estar na ESRAM (32MB), o que na prática é muito difícil de se conseguir, levando-se em consideração que jogos atuais consomem entre 2 e 3 GB da RAM. Quando os jogos consumirem todos os 8GB, daí o Xbox One terá um problema mais sério, porque ao invés de 5 a cada 10 acertos, podemos ter por exemplo 3 a cada 10, diminuindo a média consideravelmente;

2) Por mais bem programado que seja, o cache sempre terá seus problemas. E se em determinado momento do jogo, as informações que a APU precisa são tão aleatórias que demandam constantes atualizações da RAM na ESRAM? Você nunca se questionou porque de vez em quando a execução de um jogo apresenta instabilidade na taxa de quadros?

3) É inevitável que a estrutura do PS4 simplificou ainda mais a programação, pois não se tem mais preocupação com bons algoritmos para cache e os testes de performance ficam um pouco mais simplificados.

A segunda grande desvantagem do Xbox One em relação ao Playstation 4 diz respeito à GPU. A GPU do Xbox One possui 768 processadores shader, enquanto que a GPU do PS4 possui 1152 processadores shader, ou seja, 50% a mais. Na prática, o PS4 possui muito mais poder para adicionar efeitos e maiores detalhes nos objetos.

Concluindo, óbvio que o Software que gerencia estes consoles serão otimizados, o firmware será otimizado, o Mantle está ganhando espaço, os processamentos dedicados ao Kinect serão opcionais para os desenvolvedores, consequentemente melhorando a performance. Mas pelo menos no que diz respeito ao Hardware, o Xbox One tem problemas se comparado ao seu concorrente, e não há o que fazer neste aspecto. Resta otimizar ao máximo o que pode ser otimizado.

Para maiores informações, segue abaixo um bom link:

http://www.extremetech.com/gaming/156273-xbox-720-vs-ps4-vs-pc-how-the-hardware-specs-compare

Posted in Software Development | Leave a comment

Compras no Paraguai (Cidade do Leste) – dicas, acertos e erros

É praticamente impossível viajar a passeio em Foz do Iguaçu sem tirar algum tempo para atravessar a ponte da amizade e fazer compras em Cidade do Leste, no Paraguai. Os preços geralmente são muito atraentes, e para aproveitar a ida, você acabará adquirindo tanto o que precisa como o que não precisa muito, para não perder a chance. Por isso elaborei este texto para tentar te auxiliar o máximo possível a fazer boas compras e evitar cair em possíveis roubadas. Este texto está separado em 3 partes: antes, durante e após as compras no Paraguai.

paraguai-foz-do-iguacu-shopping

1) Antes

Antes de ir ao Paraguai, o primeiro item relevante é saber que você estará em um lugar onde existe todo tipo de gente, todo tipo de preço e todo tipo de qualidade. Por isso é crucial levar anotado exatamente o que vai comprar, onde vai comprar e o valor que vai pagar. Existem bons sites para pesquisar preços e lugares, como comprasparaguai e comprasnoparaguai. É importante levar os preços anotados, pois caso o preço do produto sofra alteração, você tem mais argumentos para chorar um desconto, alegando que antes custava outro preço. Em alguns casos dá certo, em outros não.

Uma dica importante é sempre fazer os planos B para o que vai comprar. Suponhamos que você vai comprar uma máquina fotográfica, e ao pesquisar nos sites acima, tenha anotado que vai comprar o item abaixo:

Camera Sony DSC WX-50 16.2 3D na loja megaeletronicos por 104 dólares

É bem possível que você chegue na loja e o item esteja em falta. Daí você vai virar para o vendedor e pedir alguma outra câmera que tenha funcionalidade semelhante, certo? O nosso amigo vendedor simplesmente vai te mostrar as câmeras que estão à venda e te dizer para escolher outra máquina, ou seja, o fluxo de vendas ali é muito rápido, os vendedores não se importam muito em conhecer os produtos para tentar vendê-los, eles apenas emitem os pedidos de venda. Por isso é importante efetuar boas pesquisas em casa, caso o seu produto favorito esteja em falta, você já tem anotado outro correspondente, que custa tal preço em tal lugar.

E por último, se você vai para o Paraguai com tudo anotado, seja o que vai comprar, onde vai comprar e o que vai pagar, precisa saber antecipadamente onde é confiável comprar. Você vai encontrar textos de diversos blogueiros alegando que pelo menos um item que você comprar no Paraguai não vai funcionar. Esta frase é verdade apenas para quem se arrisca comprando em lugares menos confiáveis. Por isso, fiz uma lista de algumas lojas que passaram pelo meu “pente fino”, ou seja, que possuem bom preço e qualidade. Apenas para dar um pouco mais de credibilidade na minha lista, eu sou do tipo de pessoa que tem paciência de perguntar o preço do mesmo produto em 30 lojas antes de comprar, por isso pode acreditar, lá dentro do Paraguai as lojas que serão mencionadas abaixo são bastante competitivas em preço, e possuem confiabilidade acima da média.

Dica: na maioria das lojas mencionadas abaixo, você pode baixar a lista de preços no site, onde esta contém todos os preços em Dólar de todos os produtos que a loja em questão vende. Usei muito estas listas de preços para ver exatamente o que cada loja vendia, e até para conhecer produtos novos.

a) Megaeletronicos (http://www.megaeletronicos.com) – excelente loja, com preços extremamente competitivos e alta confiabilidade. O foco desta loja é basicamente celulares, câmeras, cartões de memória, filmadoras, receptores, entre outros. Para comprar celular e câmera digital, não achei lugar melhor e mais barato do que esta loja;

b) Master10 (http://www.master10.com) – a mais completa loja de informática do Paraguai. Vende excelentes mochilas da Targus, memórias, processadores, placas mãe, notebooks. Esta loja também possui ótimos preços nos SSDs e placas de vídeo;

c) Alborada (http://www.alboradainfo.com/empresa.php) – outra ótima loja de informática do Paraguai. Quando fui, os preços de HDs externos nesta loja eram imbatíveis.

d) Charme (http://www.charmeperfumeria.com/charme/) – excelente perfumaria, com ótimos preços e alta confiabilidade. Perfumes como Dolce Gabbana, Animale e 212 estavam com preços muito competitivos nesta loja;

e) Macedônia (http://www.macedonianet.com.br/home/) – outra ótima opção para comprar perfumes. Esta loja tem mais respaldo que a Charme, porém os preços geralmente são um pouquinho mais caros;

f) Play Game (http://www.playgame.com.py/empresa) – loja especializada em games. Para o que eu estava buscando em games, achei os preços ótimos e o acervo da loja é bem grande;

g) World Music (http://www.worldmusic.com.py/?cont=contacto) – ótima loja para comprar instrumentos, amplificadores, pedais ou acessórios. Comprei minha placa de aúdio externa lá, e quase caí de costas quando ouvi o preço de um cubo Fender que estava interessado, o preço estava excelente.

Existem diversas outras lojas decentes para roupas, calçados, relógios, entre outros. A melhor dica que posso dar é buscar comprar em lojas que são especializadas no que você está buscando. Lá no Paraguai é muito comum ver lojas que vendem de tudo, perfumaria vendendo eletrônicos, loja de eletrônicos vendendo tênis, etc… além de ser mais caro, não possuem skill no assunto e não testam, logo não compre! Se quer perfume, vai em uma loja específica de perfumes, é mais barato e mais confiável. Se quer um HD externo, vá em uma loja específica de informática, é mais barato e mais confiável. Se quer um jogo de videogame, vá em uma loja específica de games, etc..

Observação: lojas como compubras, monalisa e navenet também são confiáveis, só não estavam muito competitivas em preço, para pelo menos para os produtos que eu estava procurando.

2) Durante

O horário comercial em Cidade do Leste é das 07:00 até às 16:00. Lembrando que o fuso horário do Paraguai é 1 hora a menos em horário normal, e 2 horas a menos em horário de verão. Para atravessar a divisa dos dois países pela Ponte da Amizade e ir até lá, você pode ir de carro, de van, de coletivo, de táxi ou a pé. Caso esteja hospedado em um hotel na região central de Foz do Iguaçu, a melhor opção é ir de coletivo (mesmo estando de carro). Basta pagar R$ 4,00 e o coletivo atravessará a ponte e te deixará lá dentro da cidade, no meio das lojas. Você provavelmente não vai esperar muito, a cada 10 minutos passa um coletivo para o Paraguai. Caso esteja hospedado em um hotel mais afastado onde não passa coletivo, e caso você não esteja de carro, a melhor opção é ir de van. As vans buscam e deixam no hotel, e geralmente cobram cerca de R$ 25,00 por pessoa, para ida e volta. Mas cuidado, escolha vans que fornecem a opção de um horário flexível de retorno, pois algumas marcam um horário fixo de retorno, e pode ser pouco ou muito tempo para você. Caso esteja de carro e hospedado onde não passa coletivo para o Paraguai, vá de carro até a ponte da amizade, deixe-o em algum estacionamento (cerca de R$ 15,00 para estacionar) e atravesse a ponte a pé. Caso queira atravessar a ponte da amizade e entrar de carro no Paraguai, só faça isso se conhecer algum lugar de confiança por lá para deixar o carro, caso contrário poderá ter problemas.

Bom, já dentro do Paraguai, a realidade é que mesmo com um mapa nas mãos, você vai se perder facilmente no meio de tanta gente e loja. Quando menciono “se perder”, não estou dizendo que você não saberá voltar ao Brasil, pois tudo o que você vai comprar não estará distante mais do que 4 ou 5 quadras. Mas se perder no sentido de não saber onde ficam as lojas que está buscando para comprar os produtos que anotou (só para você ter uma idéia, nessas 4 ou 5 quadras devem ter pelo menos 500 estabelecimentos comerciais). Por isso, é importante primeiramente saber por alto onde ficam as lojas que você vai buscar seus produtos, por exemplo: as lojas master10 e alborada ficam no Shopping Lai Lai, as lojas Charme, World Music e Play Game ficam na Galeria Jebai Center, etc.. isso é importante porque se precisar perguntar a alguém, poucos sabem qual loja é a World Music, mas todos sabem onde fica a Galeria Jebai Center. Por falar em perguntar, uma dica extremamente importante: NÃO CONVERSE COM NINGUÉM NAS RUAS. Se precisar de informações, entre em alguma loja e pergunte a algum funcionário. As pessoas que estão nas ruas não são nem um pouco confiáveis, e se você falar que quer comprar algo, vão querer te levar em alguma loja que eles possuem parceria, para tirar o percentual deles. Para isso, vão ficar andando junto com você, te incomodando, e se visualizarem você comprando em loja concorrente, podem gritar, xingar, etc.. por isso finja que não existe gente na rua, não fale nada com eles (se não conseguir, fale apenas “não, obrigado”). E claro, não compre nada nas ruas, absolutamente nada. Valorize seu dinheiro, não seja excessivamente presunçoso em comprar algo um pouco mais barato nas ruas para depois o produto em questão não funcionar ou se estragar facilmente.

Sobre a confiabilidade dos produtos, os perfumes geralmente vêm lacrados em caixa e plástico, agora pelo menos os eletrônicos devem ser testados, todos sem exceção. Depois que você paga e retira o produto, além deste, eles te entregam um recibo de entrega, e não falam mais nada. Pergunte para o entregador onde testa o produto (geralmente o local para teste é em frente o local da entrega) e vá lá testar, não se dê por convencido enquanto não ver seu produto funcionando certinho. Lojas como master10 e megaeletronicos geralmente concedem 3 meses de garantia, mas como um turista vai fazer para ir lá e trocar se for preciso? Mesmo com 3 meses, a loja está em outro país, não vão buscar sua mercadoria no Brasil. Outro detalhe relevante sobre lojas é que, se a loja te oferecer entregar a mercadoria no seu hotel em Foz do Iguaçu, fique com os dois pés atrás. Não estou dizendo apenas por causa da mercadoria, que você vai pagar e testar apenas em Foz, mas sim por causa da procedência da loja, que está te oferecendo algo ilegal. Se ela faz isso, não é difícil presumir que pode vender porcaria que não funciona ou com qualidade duvidosa.

Provavelmente na primeira vez em que você for no Paraguai, vai ficar lá por pelo menos umas 4 horas, pois mesmo com tudo anotado, você vai passear, olhar bastante, se perder no meio de tanta loja, perguntar muitos preços, etc.. por isso, se precisar tomar água ou ir no banheiro, vá na loja megaeletrônicos, que possui bebedor e banheiro decentes. Evite comprar água, refrigerante ou comida no Paraguai, você vai perceber que exceto algumas lojas (megaeletronicos, monalisa e shopping del este), não estará em um ambiente nada higiênico. Leve umas barrinhas na sua bolsa para comer caso sinta fome.

Outra dica é com relação à moeda para pagar as suas compras. Geralmente, as lojas aceitam receber tanto em Dólar quanto em Real. Então você pode comprar Dólar nas casas de câmbio do Brasil (não compre Dólar no Paraguai em hipótese alguma) e pagar nesta moeda lá dentro do Paraguai, ou se preferir, pagar na nossa moeda (Real). A minha experiência foi que, em alguns casos compensou pagar em Real e em outros compensou pagar em Dólar. Isso ocorreu devido ao fato de cada loja possuir o seu valor de câmbio, por exemplo, a loja Charme fazia a conversão do Dólar para Real por R$ 2,08, enquanto que a Master10 fazia a conversão por R$ 2,12. Como o câmbio em Foz do Iguaçu estava R$ 2,10 (loja de câmbio do Shopping JL Cataratas), compensava pagar em Real na loja Charme, e pagar em Dólar na Master10. Mas se você for comprar pouco, acho que vale a pena pagar tudo em Real mesmo, pois se você terminar todas as compras e sobrar Dólar na sua carteira, você provavelmente precisará vendê-lo depois para as casas de câmbio, e lá em Foz do Iguaçu estas estavam comprando o Dólar por R$ 2,02, ou seja, para cada Dólar devolvido, você iria perder 8 centavos.

Continuando com o Dólar, uma boa dica é comparar o preço do Dólar vendido nas casas de câmbio da sua cidade com os preços vendidos nas casas de câmbio de Foz do Iguaçu, pode-se encontrar diferenças de até 10 centavos. Se houver diferenças desta natureza, vale a pena já ir para Foz com os dólares na carteira. Também consulte o preço do Dólar nos sites das lojas do Paraguai, geralmente é mostrado na tela inicial o valor de câmbio que cada loja está aplicando. Segue abaixo os dados da casa de câmbio do Shopping de Foz para consultas:


Frontur Turismo e Câmbio (Loja 04)
Av. Costa e Silva, 185 – Loja 125 – Cataratas JL Shopping – Polo Centro – CEP: 85.863-000
Telefone: 3027-6965 / Site: http://www.frontur.com.br

Caso você seja uma pessoa que não está muito acostumada a andar com dinheiro na carteira, não se preocupe tanto com isso no Paraguai, todo mundo que está por lá anda com dólares e mais dólares na carteira, e nem por isso é tão perigoso. Apenas siga regras básicas de segurança: carteira no bolso da frente, leve apenas identidade e dinheiro, deixe o restante no hotel, não ande fora do centro comercial de Cidade do Leste, evite ir e voltar a pé pela ponte (prefira coletivo ou van), não vá para o Paraguai com camisetas de times de futebol ou roupas chamativas.

Por último, lembre-se: você está em outro país, não precisa se comportar como se estivesse com medo de tudo, mas evite problemas, fale apenas o essencial e somente dentro de lojas.

3) Depois

Agora é a hora da verdade: você fez suas comprinhas, e quer voltar com elas para o Brasil, certo? Acontece que tem uma tal de Receita Federal que faz fiscalização em pelo menos 3 lugares: na Ponte da Amizade, na rodovia perto de Foz (entre São Miguel do Iguaçu e Medianeira) e no Aeroporto de Foz. E a Receita Federal pode te obrigar a pagar impostos caso o somatório dos itens comprados excedam o valor máximo da cota por pessoa, e se não pagar, as mercadorias serão confiscadas. Por isso, serão explicados os procedimentos, e o que deve ser feito para não se dar mal. Para tentar entender melhor como funciona a fiscalização, eu cheguei até a ir na Receita Federal de Foz do Iguaçu para perguntar e ter todas as informações certinhas para não correr maiores riscos, e poder ajudar quem deseja ir e efetuar suas compras.

Duas observações relevantes:

a) As dicas que serão mencionadas abaixo são úteis apenas para quem vai efetuar compras como Turistas. Uma coisa é você levar um eletrônico de presente para o seu pai, ou um perfume pra sua mãe, outra é trazer encomendas para os outros. Evite ao máximo fazer isso, você pode entrar em uma fria e ainda ser obrigado a ressarcir a pessoa que o encomendou. Entenda que sacoleiros correm muitos riscos de perder mercadoria, essa é a vida deles. Se quiser entender melhor, vá até a Receita Federal de Foz do Iguaçu, todo dia têm pelo menos 1 ônibus parado por lá cheio de sacoleiros que tiveram suas mercadorias confiscadas. E estes ficam lá esperando para tentar retirá-las, mesmo se for preciso pagar um valor alto de imposto. Você é apenas um turista, então compre como um turista;

b) Tome muito cuidado com dicas de terceiros sobre a Receita Federal, impostos, cotas. Algumas das leis que vou mencionar abaixo são novas, e existe muita gente desinformada, você faz uma pergunta e cada um concede uma resposta diferente. Por isso é extremamente importante compilar todas as informações abaixo e entender direitinho como funcionam as regras, e obviamente tirar suas dúvidas em fontes mais confiáveis, como o próprio site da Receita Federal – Link;

Primeiramente, a cota para comprar isento de imposto no Paraguai, na Argentina, ou em qualquer outro país por via terrestre, é de 300 dólares por pessoa. Essa cota só pode ser utilizada 1 vez por mês. Menores de 14 anos não possuem direito à cota, ou seja, se foram para o Paraguai o papai, a mamãe e duas crianças, esta família só poderá comprar 600 dólares isentos de impostos. E o pior, cada produto pertence apenas a uma pessoa, ou seja, se você comprou um notebook de 600 dólares, mesmo que sua esposa não tenha comprado absolutamente nada, você precisará pagar o imposto sobre o excedente da sua cota, pois não tem como alegar que o notebook é seu e dela. O cálculo do imposto é simples, é cobrado basicamente 50% sobre o valor excedente, ou seja, se comprou um notebook de 600 dólares, pagará 150 dólares de imposto (50% sobre os 300 dólares que excederam da sua cota) apenas sobre este notebook. O imposto pode ser pago no Banco do Brasil ali pertinho mesmo da ponte da amizade, a Receita Federal vai emitir um documento chamado DBA (Declaração de Bagagem Acompanhada) para este produto, e o mesmo será liberado. Com isso, caso seja parado na alfândega do Aeroporto ou nas rodovias, basta apresentar a DBA do produto, que este estará absolutamente legalizado. Quando o valor total das suas compras não excedem os 300 dólares, não é necessário emitir DBA para os produtos, pois se o somatório das suas compras está dentro da cota, é automaticamente considerado legal no Brasil. Geralmente os funcionários da Receita Federal possuem uma tabela de preços, então eles conseguem saber se você está ou não dentro da cota, por isso se por exemplo, você comprou um HD externo e uma placa no Paraguai, e o total não excede os 300 dólares (segundo os valores da tabela da Receita), caso seja parado, basta dizer na Alfândega ou na rodovia que não excedeu os 300 dólares, por isso não precisou fazer o documento DBA. Também é extremamente importante levar nota fiscal dos produtos de valor que você comprou no Brasil e porventura estejam incluídos na sua bagagem, ou seja, se implicarem com seu ultrabook caríssimo que você comprou no Brasil, leve nota fiscal para evitar ficar sem ele.

Então, a lógica da Receita Federal é bem simples: você pode ir no Paraguai à vontade e quantas vezes quiser, pode comprar qualquer produto que te interessar, desde que não seja nada ilícito (consultar site receita, Link) ou em quantidades que não qualifiquem revenda. E de brinde, deverá pagar 50% de imposto sobre o que exceder da sua cota mensal de compras, que é de 300 dólares. E é exatamente esse o problema, pois os turistas brasileiros geralmente vislumbram com os preços e querem comprar bem mais do que 300 dólares, mas ao mesmo tempo não querem pagar o bendito imposto para a Tia Dilma. Então o que você verá abaixo são dicas e o que fazer para conseguir trazer um pouquinho a mais e pagar menos impostos.

Observação: os turistas gringos que vão para Foz passeiam apenas em destinos turísticos como as cataratas, a itaipu, o parque das aves e o templo budista. O Paraguai em nada interessa para eles, pois eles não são trouxas como nós brasileiros de pagar o absurdo de imposto que pagamos sobre os produtos.

Bom, voltando ao assunto, os espertinhos provavelmente já devem ter raciocinado algo do tipo: então basta eu ir no Paraguai um monte de vezes e trazer apenas 300 dólares toda vez? A resposta é não, pois a cada vez que você voltar do Paraguai, a Receita Federal irá te cadastrar eletronicamente, para caso você voltar novamente dentro do mês, eles saberão que você já comprou, por isso irá cobrar o imposto sobre toda a sua mercadoria. Por exemplo, suponhamos que você vá hoje no Paraguai e compre um HD externo de 130 dólares. Ao passar na Ponte da Amizade, a Receita Federal vai te parar, ver que você tem apenas um HD e que está dentro da cota. Logo, vão pedir apenas que você vá até um balcão ao lado e efetue seu cadastro. O rapaz vai pedir sua identidade e te cadastrar. Agora suponhamos que você volte daqui 20 dias e compre uma placa de 160 dólares. A Receita vai fazer o mesmo procedimento, pedir apenas para você cadastrar. Contudo, ao visualizarem que você já foi cadastrado dentro do mês, vão alegar que você já usou a cota e consequentemente irão cobrar 80 dólares de imposto sobre esta placa, sem dó nem piedade. Mesmo se você alegar que tinha gasto até então apenas 130 dólares dentro do mês, isso não irá importar, se foi cadastrado significa que usou a cota, não importa o valor. Você só se livrará do imposto se por um bug do sistema o seu cadastro não foi feito, ou se o sistema estiver fora do ar.

Baseado no que foi dito, então o ideal é não ser parado pela Receita Federal na Ponte da Amizade, logo não ser cadastrado? A resposta é sim e não. Se você for cadastrado, o lado ruim é que se você voltar a comprar dentro de 30 dias, obrigatoriamente pagará imposto, mesmo se estiver dentro da cota. Agora o lado bom é que se for parado pela Receita Federal na rodovia ou na alfândega, dizer que foi cadastrado é um bom argumento, pois vão conferir no sistema que você foi cadastrado, logo você terá ao menos um voto de confiança que as mercadorias compradas foram verificadas pela Receita Federal na Ponte da Amizade. Então o que muitos turistas fazem é dividir suas compras em 2 ou 3 idas no Paraguai, e deixar para ser cadastrado apenas na última compra, tentando passar a primeira ou a segunda vez na ponte da amizade sem ser parado, voltando de táxi ou van, que são parados em menor quantidade. Se você atravessar a Ponte da Amizade de coletivo ou a pé, caso esteja com sacolas de eletrônicos, certamente será abordado pela Receita Federal, precisará cadastrar e consequentemente pagar o imposto, caso tenha excedido o limite mensal de compras.

Sobre a abordagem da Receita Federal na Ponte da Amizade, geralmente vão ver as suas sacolas, se forem poucos os itens comprados e com valor muito baixo, geralmente eles deixam passar, agora se notarem que as compras foram de maior valor, por exemplo, visualizarem um videogame, alguns jogos e perfumes, eles certamente vão pedir apenas para cadastrar, e se visualizarem muitos eletrônicos caros, como 2 notebooks e 3 videogames, certamente vão somar o valor de todos os itens e calcular o imposto para você pagar (e também irão te cadastrar). Com isso, podemos perceber que se você for um pouco discreto, nenhum fiscal da Receita Federal vai ficar com uma calculadora na mão somando tudo e vendo se suas compras excederam, eles apenas olham por alto o que você comprou. Os fiscais da Receita Federal também não costumam olham muito o que tem em bolsas de mulheres, caixas e mochilas, eles olham bem por alto apenas o compartimento principal de cada um. O que os turistas mais espertos geralmente fazem é dividir as compras nas sacolas, ou seja, se comprou um celular, joga a caixa fora lá no Paraguai mesmo e coloca no bolso da calça. Se comprou uma máquina fotográfica, joga a caixa fora, compra uma bolsinha pra ela e fica com ela na mão. Se comprou perfume, joga a caixa fora e coloca na bolsa da mulher. Se vai comprar tênis, leva um bem velho, compra o novo e já calça ele (jogando o velho fora), se vai comprar um relógio, coloque no braço. Tudo isso será considerado como uso pessoal e não entrará na cota. Apenas não abuse, colocando 10 perfumes na bolsa e 2 relógios no braço, pois podem notar e incluir o excedente na cota. Coloque alguns eletrônicos na mochila, outros em sacola mesmo. Se comprou muitos itens pequenos, coloque dentro de uma caixa, para parecer um item apenas. Se você não estiver com um volume de itens muito chamativo, os funcionários da Receita Federal não vão ficar abrindo caixa, ou olhando mochilas em detalhes ou abrindo bolsas de mulheres. Eles apenas olham o que tem nas sacolas e nos compartimentos principais das mochilas e fazem algumas perguntas, como “você é de foz?” (praticamente tanto faz a resposta, vão mandar cadastrar), “quanto você comprou?”(geralmente respondem 300 e poucos dólares, mesmo que a compra tenha ficado o dobro ou o triplo deste valor). Geralmente também não implicam muito com perfumes e roupas, desde que você não traga em grandes quantidades. Com isso, às vezes você comprou até mais de 1000 dólares, e dividiu tanto as suas compras que o fiscal da Receita Federal vai julgar que você comprou pouco, logo apenas vai te cadastrar. Agora, se você comprou um eletrônico caro e que não cabe no bolso (por exemplo um Notebook), e conseguiu passar da Ponte da Amizade sem pagar o imposto, você poderá correr maiores riscos, pois se for parado pela Receita Federal nas rodovias ou na alfândega, você não conseguirá argumentar que está dentro da cota. Claro que você vai jogar a caixa fora, encher o notebook de fotos, colocar seu perfil de usuário, etc… mas e se o funcionário da Receita não for com a sua cara, e exigir a DBA do produto ou a nota fiscal provando que foi comprado no Brasil? Nesse caso, talvez seria interessante considerar pagar o imposto do produto. Comprar alguns eletrônicos baratos é até tranquilo, porque você divide eles em vários lugares dando a impressão que não gastou tanto, agora comprar um único eletrônico que todo mundo sabe que é caro e ainda por cima não é pequeno, certamente é mais arriscado.

Observação: pode ser esdrúxulo ou até desonesto da minha parte em falar que você vai comprar um celular, jogar a caixa fora, ligá-lo e colocar no bolso, mas entenda uma coisa: a Receita criou as regras para inibir revenda, se você joga a caixa fora e começa a usar o produto, fica muito claro para a Receita que você não irá revender, que é para você. Agora se você leva o produto na caixa, não tem como ela saber se é para você ou se você vai revender, por isso vai tributar.

Agora, se você preferir trazer um monte de coisas do Paraguai e voltar de Táxi para correr menos riscos de ser parado, você pode até vencer a barreira da Ponte da Amizade, mas lembre-se, ainda têm a Receita Federal na estrada e na Alfândega do Aeroporto, e lá eles não mandam pagar imposto, eles “apenas” confiscam os produtos. A Receita Federal que fica na estrada, entre São Miguel do Iguaçu e Medianeira é bem rígida. Com exceção da bolsa da mulher e o bolso da sua calça, eles olham praticamente tudo, seja mala, sacola, compartimentos do seu carro, colocam as malas no chão, reviram. Claro que eles não chegam com calculadora somando, mas se ficar muito explícito que você excedeu demais a cota e não pagou imposto, vão confiscar. Agora se você não foi parado pela Receita nos primeiros 60 km de estrada saindo de Foz do Iguaçu, pode ficar mais tranquilo que o restante do caminho é mais monitorado pela Polícia Rodoviária, que até pergunta e revira suas coisas, mas procuram apenas sacoleiro, bandido e quem está ilegal com o carro e/ou a habilitação. Por isso, deixe alguns produtos com caixa, outros sem, coloque alguns perfumes na mala, outros na bolsa, outros em sacola, divida as coisas e os deixe com dúvida se aquilo é novo ou não. De forma alguma acumule as compras em apenas um lugar, e também deixe algumas poucas caixas, porque ninguém vai acreditar que você foi passear em Foz e não trouxe nada do Paraguai. Lembrando, ir no Paraguai não é ilegal, comprar no Paraguai não é ilegal, ilegal é exceder a cota sem pagar imposto, ilegal é trazer muitas unidades do mesmo produto, ilegal é trazer armas, drogas, pneus, excesso de cigarros e bebidas, etc.. e se for somar o que você comprou centavo por centavo, vão ficar meia hora apenas te fiscalizando, por isso olham apenas por alto para ter certeza que você não é sacoleiro, nem bandido e nem turista que excedeu muito a cota.

E se por acaso você for parado na rodovia, aja com naturalidade e tente ser sincero em tudo o que perguntarem para evitar levantar suspeitas, o que fica ainda pior. Lembre-se que dividir mercadorias nas bagagens e no carro não é o mesmo que esconder, por isso não esconda as compras, não tenha comportamentos de sacoleiro, senão os fiscais da Receita Federal irão te tratar como um deles, o que poderá ficar pior. Por exemplo, se comprou dois jogos de 50 dólares cada, coloque-os na bolsa ou na porta do carro, pois dificilmente olham essa parte do carro, focam mais no bagageiro. Mas se virem e perguntarem, responda que comprou, mas fale um preço um pouco mais baixo. Se te perguntarem de onde vêm e para onde está indo, responda a verdade, porque vão ficar dando sequência nas perguntas para ver se você sustenta o que disse antes, e se desconfiarem, aí irão olhar tudo e colocarem um olhar ainda mais clínico em você e nas suas coisas. Só para dar um exemplo, na volta de Foz, fui parado pela Polícia Rodoviária em Maringá. O policial apenas perguntou de onde eu vinha, pediu os documentos, e pediu para eu abrir o bagageiro. Se convenceu de que eu era turista e deixou eu ir. Depois disso, chegamos até Presidente Prudente e paramos para dormir por lá, e seguimos viagem no outro dia. Ao chegar em São José do Rio Preto, fomos novamente parados pela Polícia Rodoviária. O policial me perguntou de onde eu estava vindo, e respondi sem pensar “Presidente Prudente”. Daí ele perguntou o que eu fui fazer nesta cidade, se estava visitando alguém ou algo do tipo. Enrolei um pouco para responder, e respondi que parei lá apenas para dormir, porque estava voltando de Foz. No mesmo instante em que disse isso, o policial guardou a minha habilitação e o documento do veículo no seu bolso, e revirou todo o carro, bolsa, mala, ele até levantou o banco de trás para conferir a numeração do chassi, porque como eu não respondi inicialmente que era Foz, ele desconfiou que eu estava escondendo algo. Enquanto ele fazia isso, o outro policial começou a me questionar o que fui fazer em Foz, perguntou dos passeios, etc.. e como viram que eu conseguia articular bem as respostas, já que eu não estava mentindo, foram aos poucos ficando mais calmos. No final, vendo que eu era apenas um turista assustado no meio da estrada, o policial “nervosinho” ficou todo “amiguinho”, viu o volante que comprei no Paraguai e até perguntou quanto eu paguei, como vou montar o cockpit dele para jogar, por quanto achei no Brasil, se era bom mesmo, etc… Por isso é bom ser sincero e objetivo.

Concluindo, devo dizer que por um lado é muito bom ir no Paraguai, você provavelmente vai pagar metade do preço vendido pela internet no Brasil em praticamente tudo o que precisar comprar. Por outro lado, se você conhece bem alguma área, seja informática, games, roupas, perfumes, ou qualquer outra coisa, você saberá o que é original e o que é pirata, com isso ficará revoltado como eu fiquei, ao ver alguns produtos originais no Paraguai custando metade do preço praticado no Brasil, e fará as mesmas perguntas que eu fiz: por que pagamos o dobro do preço no Brasil se é exatamente a mesma mercadoria? Se tivéssemos um pouquinho mais de consciência na carga tributária exorbitante que pagamos, e com isso cobrássemos mais o governo, quem sabe todo esse sofrimento para comprar o que você precisa por um preço um pouco mais justo poderia ser evitado.

Obs: Por favor, não enviem perguntas envolvendo revenda! Nestes casos, sua pergunta não aparecerá no blog, tampouco será respondida.

Posted in Software Development | 340 Comments

SSD: um excelente upgrade para Desenvolvedores de Software

Não é do meu costume escrever textos envolvendo hardware e/ou manutenção de computadores, visto que para quem trabalha com criação de Software, esta área é praticamente uma abstração. Mas, tendo em vista o meu recente êxito por ter feito um bom upgrade em meu PC, não podia deixar de compartilhar.

Há algum tempo atrás, após uma série de lentidões e constantes quedas de frames (em jogos) com um hardware defasado, resolvi fazer um upgrade. Foram gastos R$ 2281,82 com praticamente o que tinha de melhor em processador, memória e placa mãe (para computadores pessoais), conforme mostra a figura abaixo.

1

Contudo, após a instalação destes componentes, o resultado percebido não compensou o investimento. É óbvio que em algumas áreas como jogos, o resultado foi bom, porque aumentou o frame-rate dos jogos mais pesados (lembrando que cálculos de I/A e física são feitos pela CPU e não pela GPU), mas para o restante dos aplicativos, especialmente aqueles que envolvem desenvolvimento de sistemas, como Eclipse, NetBeans e Visual Studio, o ganho de performance foi de pequeno para médio, pois algumas lentidões e “travadinhas” permaneceram. Aliado a este fracasso, já ouvi de alguns colegas de profissão relatos de pouca melhoria de performance em upgrades deste porte, seja em PCs desktop ou com aquisições de notebooks mais potentes.

Baseado no que foi relatado, restou a alternativa de efetuar um upgrade no velho vilão de latência, conhecido por muitos como HD (Hard Disk). Upgrades em HDs geralmente são feitos para aumentar o espaço, raramente usuários comuns pensam em efetuar novas aquisições visando performance nestes dispositivos. Contudo, é do conhecimento de muitos que o HD é um dispositivo mecânico e que o seu tempo de acesso é infinitamente inferior ao da memória RAM, tendo como consequência uma série de latências para buscar blocos de dados. Se a partição do HD estiver desfragmentada, então o tempo é ainda pior. Com isso, restaram duas alternativas: ou buscar um HD com rotação maior, ou procurar um novo dispositivo. HDs com rotações maiores (15.000 RPM por ex) geralmente são utilizados quase que exclusivamente em servidores, pois são muito caros. A alternativa então foi utilizar um novo dispositivo, chamado de SSD.

O SSD é basicamente um dispositivo que armazena os dados em chips de memória FLASH, assim como os pendrives, contudo existem algumas diferenças, pois o SSD utiliza o barramento SATA (assim como os HDs), ao invés das entradas USB, como é utilizado pelos pendrives. Com isso o SSD possui velocidade superior aos pendrives, pois o barramento USB trafega tanto dados quanto a energia de alimentação para o dispostivo conectado, ao contrário do SATA que trafega exclusivamente dados. E o SSD também possui performance geralmente superior aos HDs, pois os dados não são gravados e acessados de forma mecânica, gerando latências e fragmentação. Existem outras vantagens dos SSDs como economia de energia, menor barulho, maior resistência à quedas, etc.. Após algumas pesquisas de preço e marcas, foi realizada a compra do SSD, como mostra a figura abaixo. A princípio alguns podem se assustar por APENAS 120 gb de dados custarem R$ 522.62, mas pelo menos por enquanto, o SSD ainda não é um dispositivo para substituir completamente o HD em computadores pessoais, este o substitui apenas para armazenar as instalações dos aplicativos (Windows/Linux, Office, Photoshop, Java, Eclipse, Visual Studio, etc..). Arquivos como fotos, vídeos, músicas, dentre outros, devem permanecer em um HD com maior capacidade de armazenamento. Por isso, cada um deve analisar a quantidade de espaço necessário para armazenar os arquivos de instalação dos seus devidos aplicativos, e comprar um SSD com tamanho compatível.

2

Outro fator relevante na compra do SSD é analisar a capacidade de leitura/escrita do mesmo. Caso o leitor não possua um PC com SATA 3, SSDs que lêem apenas em SATA 2 geralmente são mais baratos, pois possuem menor velocidade na leitura/escrita. Também é importante buscar avaliar os benchmarks dos SSDs na Internet, existe uma considerável discrepância de performance entre diversas marcas de SSDs.

A figura abaixo mostra os benchmarks realizados em um PC com quatro dispositivos de armazenamento conectados neste. Esta figura contém quatro colunas, separando cada um destes dispositivos. A primeira coluna mostra o SSD adquirido conforme mostra a figura acima, a segunda mostra um HD de 1TB 7200 RPM instalado diretamente no computador pelo barramento SATA 3, a terceira mostra um HD externo de 2 TB 7200 RPM conectado em uma entrada USB 3.0, e a quarta mostra um HD de 1 TB 7200 RPM conectado em uma entrada USB 2.0 . O Software utilizado foi o CrystalDiskMark. Foram realizados 5 tetes para cada um dos dispositivos, e o número final mostrado em cada quadro é uma média dos resultados. A massa de dados para o teste ocupava 100 MB. A primeira linha considera a leitura/escrita sequencial, ou seja, como se os HDs não possuíssem fragmentação. A segunda linha considera a leitura/escrita em blocos do tamanho de 512kb, a terceira com blocos de 4kb, e a quarta com os mesmos 4 kb, mas com uma fila de 32 atividades de input/output a serem realizadas. Com isso, percebe-se que da primeira até a quarta linha são quatro cenários distintos para os dispositivos.

Untitled-1

Ao analisar os números, fica nítico que o SSD é muito superior a todos os HDs em leitura (Read MB/S). Em escrita (Write MB/S) este fica no mesmo ritmo do cenário perfeito dos HDs (sequencial). Contudo, percebe-se que em cenários mais desfavoráveis (terceira e quarta linhas), o SSD é amplamente superior. Outro detalhe que vale a pena ser mencionado é a impressionante diferença entre o HD conectado em USB 3.0 comparado ao outro HD conectado em USB 2.0.

Claro que os resultados acima são apenas números, mas na prática isso significa que durante a execução das aplicações mais pesadas, seja uma IDE ou um jogo, os tempos de carregamento serão bastante minimizados. Caso o leitor já tenha experimentado jogar alguns títulos em cartucho, como foram nos saudosos tempos de Snes, Sega Genesis ou Nintendo 64, se lembrará que os jogos praticamente não possuíam carregamentos, ou loadings. A história não é muito diferente aqui, o carregamento é muito mais rápido. Não se trata apenas de carregamentos rápidos na inicialização do Windows ou de algum outro aplicativo pesado, mas sim de qualquer carregamento que envolva o dispositivo no qual estão as instalações dos aplicativos, seja na abertura, execução ou encerramento do aplicativo. E estes carregamentos acontecem a todo instante, tendo em vista que Sistemas Operacionais gerenciam a memória por segmentação/paginação, ou seja, a todo instante alguma informação é carregada dos HDs (ou SSDs) para a memória RAM, e não apenas quando os aplicativos são inicializados.

E quanto a instalação dos SSDs, esta parte é bastante trivial tanto em computadores desktop quanto em PCs. O SSD possui tamanho 2.5, o mesmo de HDs para notebooks e consoles, facilitando a troca. Algumas marcas de SSDs ainda vêm com um adaptador para instalação no PC, como mostra a figura abaixo (seta azul marcando o SSD instalado, cor vermelho).

4

Para notebooks, trocar o HD geralmente é simples, visto que não precisa desmontá-lo todo para tal finalidade, como mostra a figura abaixo.

5

Concluindo, o upgrade do SSD não é para quem apenas utiliza navegador, office, dentre outros programas relativamente leves. Este upgrade é para quem utiliza aplicativos mais pesados, como um emulador de Android, ou um Autocad, dentre vários outros. E está claro que este upgrade é tão ou mais importante do que apenas processador/memória/placa mãe. Após a aquisição do SSD, fiz um post no GUJ (Grupo de Usuários Java) compartilhando os resultados deste investimento, e dentre vários comentários, acho que vale destacar o do usuário s4nchez, que trabalha no Reino Unido e possui um depoimento interessante, validando o que foi dito aqui. Segue abaixo:

6

Segue abaixo um vídeo com o comparativo. . E aí, vale ou não o investimento?

Posted in Software Development | 2 Comments

Um encontro da teoria com a prática na ciência da computação – parte 2

Dando continuidade ao artigo já publicado um encontro da teoria com a prática no curso de ciência da computação, será apresentado um novo cenário onde, embora os conceitos aplicados sejam simples, estes também contribuem para a proposta de aperfeiçoar o entendimento referente à aplicabilidade da teoria ensinada em cursos de graduação que envolvem Computação.

Recentemente, foi solicitado que nossa equipe realizasse uma migração de dados, onde esta deveria ser importada para o banco de dados da empresa, contemplando algumas tabelas que se encontravam no servidor de um determinado fornecedor. Com isso, foram recebidos alguns arquivos com extensão txt, onde cada um destes envolvia uma tabela que deveria ser importada.

Para exemplificar melhor, um dos arquivos recebidos, intitulado compras.txt diz respeito a tabela compras do banco de dados. Dentro deste arquivo, cada linha representa uma linha da tabela mencionada, sendo que para identificar o conteúdo de cada coluna, o arquivo utiliza o caractere delimitador §. Desta forma, o conteúdo do arquivo possui um formato semelhante ao mencionado logo abaixo:

cpf_cliente§conta§valor_comprado§vencimento
05069358674§40582§99.50§2012-09-30

Antes de importar os dados em ambiente de produção, obviamente estes deveriam antes ser validados em ambiente de teste. Contudo, há um pequeno detalhe: alguns destes arquivos possuem tamanho consideravelmente grande. Somente o arquivo mencionado de compras possui tamanho de 18 GB, com cerca de 135 milhões de linhas. Dado o imenso volume de dados a ser importado, concluiu-se que seria necessário trabalhar em ambiente de teste apenas com uma amostra, ou seja, ao invés de importar para este ambiente todas as 135 milhões de compras, deveriam ser importadas apenas as compras referentes a uma amostra de dez mil contas selecionadas para validação. Para isso, estas contas foram colocadas em um arquivo, e deveria ser gerado um novo arquivo contemplando apenas as compras destas.

Ao analisar a solução empregada, foi adotada uma alternativa simples, onde primeiramente importava a amostragem de contas em uma lista, como mostra o código abaixo, escrito na linguagem VB.NET:

Dim arquivoContas As System.IO.StreamReader
arquivoContas = System.IO.File.OpenText(“c:\contas.txt”)

Dim listaContas As List(Of String) = New List(Of String)

Dim linhaArquivoContas As String = arquivoContas.ReadLine

While Not linhaArquivoContas Is Nothing
listaContas.Add(linhaArquivoContas)
linhaArquivoContas = arquivoContas.ReadLine
End While

Após este procedimento, foi realizado um loop no imenso arquivo de compras, verificando para cada uma das 135 milhões de linhas, se a conta de cada linha está na lista de contas importada no código apresentado acima. E caso sim, esta linha precisa ser salva em um novo arquivo. O código abaixo mostra o procedimento realizado

Dim cp1252 As Encoding = Encoding.GetEncoding(1252)
Dim arquivoSaida As System.IO.StreamWriter
arquivoSaida = New System.IO.StreamWriter(“c:\COMPRAS_AMOSTRA.txt”, False, cp1252)

Dim arquivoCompras As System.IO.StreamReader
arquivoCompras = System.IO.File.OpenText(“C:\COMPRAS.txt”)

Dim linhaArquivoCompras = arquivoCompras.ReadLine

While Not linhaArquivoCompras Is Nothing
Dim numeroConta As String = linhaArquivoCompras.Split(“§”).GetValue(1)
If listaContas.Contains(numeroConta) Then
arquivoSaida.WriteLine(linhaArquivoCompras)
End If
linhaArquivoCompras = arquivoCompras.ReadLine
End While
arquivoSaida.Close()

Ao analisar a resposta, a execução do código estava devolvendo a saída esperada, contudo após 2 horas de processamento, apenas 18 das 135 milhões de linhas haviam sido lidas. Caso o processamento continuasse linear a este tempo, este processo gastaria cerca de quinze horas para ser concluído. E ainda precisavam ser importados mais alguns arquivos de tamanho proporcional a este, como extratos, pagamentos, entre outros. Estava claro que, embora fosse necessário efetuar este processamento apenas uma única vez, o desempenho se encontrava em um estado crítico e ninguém iria querer esperar alguns dias apenas para ser gerada uma amostra de testes. E importar toda a base de dados para ambiente de teste também estava fora de cogitação. Ao depararmos com este código, rapidamente foi percebido que, para cada uma das 135 milhões de linhas a serem importadas, este método contains() faz uma busca ao tradicional estilo “tentativa-erro” nas 10 mil contas, ou seja, o número de comparações é consideravelmente alto.

Para resolver o problema, foi necessário lançar mão de um simples conceito ensinado em cadeiras como Estrutura de Dados ou Análise de Algoritmos, que é a busca binária. Empregando este, basta ordenar a lista das contas uma única vez (por se tratar de apenas 10 mil contas, o algoritmo de ordenação empregado praticamente não terá impacto na solução), e após isso, buscar o elemento nesta lista ordenada quebrando a lista recursivamente. Em uma linguagem de alto nível como VB.NET, a implementação está pronta, bastando ordenar a lista com um método como listaContas.Sort() , e após isso, substituir a implementação do loop While por:

While Not linhaArquivoCompras Is Nothing
Dim numeroConta As String = linhaArquivoCompras.Split(“§”).GetValue(1)
Dim index As Integer = listaContas.BinarySearch(numeroConta)
If index > 0 Then
arquivoSaida.WriteLine(linhaArquivoCompras)
End If
linhaArquivoCompras = arquivoCompras.ReadLine
End While

Com esta simples modificação, o processamento diminuiu de quinze horas para apenas meia hora, viabilizando rapidamente todos os arquivos, contemplando as amostras desejadas. É óbvio que algumas linguagens podem não possuir esta facilidade dos métodos prontos, contudo é consideravelmente simples criar métodos de ordenação e busca binária.

É óbvio que muitos podem argumentar que nunca precisaram de soluções desta natureza, mas é necessário analisar as possibilidades de entrada referente a cada caso, além de possíveis restrições de processamento, especialmente em casos onde as buscas de dados precisem funcionar em dispositivos móveis. No problema citado, caso a entrada fosse menor, da grandeza de apenas alguns milhares de linhas, provavelmente muitos não se importariam em utilizar a pior solução, pois esta perderia poucos segundos em relação à melhor solução, o que em um cenário como o mencionado é irrelevante. Mas, em entradas maiores, bons algoritmos certamente farão uma grande diferença, como foi apresentado. Por isso que, mesmo com tantas soluções e componentes prontos, em muitos cenários o domínio dos conceitos será primordial, e este tipo de profissional sempre será cobiçado.

Concluindo, pode-se ver mais uma vez que, conceitos aprendidos nos cursos de graduação envolvendo computação são e sempre serão muito úteis na resolução de diversos problemas de mercado, destacando profissionais que valorizaram os fundamentos teóricos. Este artigo obviamente não teve nenhuma intenção no ensino da técnica busca binária, que é simples e bastante disseminada em qualquer graduação decente de computação, mas apenas em evidenciar como esta poderia ser utilizada em casos onde o seu uso faria toda a diferença.

Posted in Software Development | 2 Comments

Um encontro da teoria com a prática na ciência da computação

Em cursos de exatas, como Ciência da Computação ou Sistemas de Informação, é comum encontrar alunos e ex-alunos efetuando diversas críticas sobre alguma teoria específica, que tenha demandado alto esforço para ser dominada. As maiores críticas normalmente são direcionadas a aplicação prática desta teoria, ou seja, é comum ouvir frases como: “por que sofrer com essa teoria se nunca vou precisar disso na prática?”. Fazendo uma analogia com este pensamento, confesso que, nos meus tempos de graduação em Engenharia de Computação, possuía certa dificuldade para entender o motivo de este curso incluir disciplinas envolvendo química, até que um dia fui escalado para apresentar um seminário sobre o processo de dopagem de semicondutores para fabricação de chips, onde fui obrigado a aprender sobre ligações químicas e consequentemente, reconhecer meu erro. Contudo, neste post, a intenção é apresentar um cenário mais prático, vivenciado em uma das empresas que trabalhei. Até hoje utilizo a experiência que será relatada abaixo como referência para as turmas da disciplina “Sistemas Operacionais”.

Certa vez, um dos meus empregadores precisava de um sistema que efetuasse uma busca de clientes, onde esta seria parametrizada por alguns filtros, como estado, cidade, bairro, etc.. . Após o retorno dos clientes filtrados, o sistema deveria disponibilizar um botão para gerar um mapa onde, ao ser clicado, este seria gerado no estilo Google Maps, marcando todos os clientes filtrados em sua exata localização. Para ilustrar melhor o problema, o mapa mostrado por este sistema era semelhante ao da figura abaixo, contudo, para cada cliente retornado no filtro, seria mostrado um ponto vermelho no local onde o cliente se encontra, ao invés de um único ponto, como mostra a figura. Aliado a isso, ao colocar o cursor do mouse sobre este cliente, seria mostrado algumas informações como Curva ABC em que este se encontrava, compras no mês corrente, etc… Com isso, foi contratado uma empresa terceira para desenvolver o sistema em Java, e outra para nos fornecer as coordenadas dos clientes mediante Web Service, ou seja, o endereço seria enviado por parâmetro e a Web Service retornaria a latitude e longitude deste.

Após a entrega do projeto mediante uma das empresas terceiras, deu-se início aos testes. Ao aplicar um filtro marcando apenas a cidade de Uberlândia, foram retornados cerca de mil clientes. Após clicar no botão para gerar o mapa, o sistema gastou cerca de meia hora para mostrá-lo com todos os mil pontos, referente aos clientes desta cidade. Obviamente, a primeira reação foi de incredulidade, pois poderiam ser aplicados outros filtros, como a cidade de São Paulo, ou o Distrito Federal, que gastariam um tempo consideravelmente maior para serem gerados. As funcionalidades pedidas no sistema, como dados apresentados no mapa, aplicação de filtros, layout, estavam absolutamente perfeitos em relação ao que foi acordado, o único problema era o desempenho, que inviabilizava o projeto.

Ao conferir o código fonte, foi constatado que a lentidão se encontrava em uma parte semelhante ao trecho abaixo:


List clientes = clienteDao.getClientesByParams(filtros);
for (Cliente cliente: clientes) {
     cliente.setCoordenadas(WebService.getCoordenadas(cliente));
}

Baseado no código fonte acima, pode-se constatar que a lentidão não estava na geração do mapa, ou na marcação dos pontos, mas sim na busca das coordenadas pela WebService. Cada uma das iterações deste loop gastava cerca de 2 segundos, ou seja, o tempo para gerar o mapa era linearmente proporcional a quantidade de clientes da lista. Caso o filtro retornasse poucos clientes, o mapa era gerado rapidamente, contudo para filtros mais abrangentes, o tempo para gerar era longo. A primeira reação ao ver este código fonte é a de questionamento do porque este ser sequencial, ao invés de paralelo, ou seja, multithread. Por que enviar apenas uma requisição por vez, sendo que poderiam ser enviadas diversas em paralelo? Apesar de óbvio, infelizmente o conceito de programação multithread não é tão difundido quanto imaginamos. Já aconteceram casos em que, empresas que venciam cotações pediam para retirar a parte multithread do projeto, com desculpas de que não haveria tantos ganhos de performance. Baseado no que foi dito, o código fonte foi modificado para algo abaixo:


List clientes = clienteDao.getClientesByParams(filtros);
List coordenadas = criaListaCoordenadas(clientes);
for (Coordenada coordenada: coordenadas) {
     Thread thread = new Thread(coordenada);
     thread.start();
}
public class Coordenada implements Runnable {
     private Cliente cliente;
     public Coordenada(Cliente cliente) {
         this.cliente = cliente;
     }
     public Cliente getCliente() {
         return cliente;
     }
     public void run() {
         cliente.setCoordenadas(WebService.getCoordenadas(cliente));
     }
}

Nesta mudança, cada objeto da classe Coordenada será uma thread, e para cada cliente retornado o filtro, será criado um objeto desta classe, associando-o ao cliente. Ao executar o projeto com estas modificações, sistema gerou várias mensagens de erro, uma para cada thread, alegando estouro de requisições. Ao analisar o log, foi constatado que, a empresa terceira que fornecia as coordenadas não suportava o volume de requisições simultâneas demandadas, ou seja, aceitava apenas algumas requisições simultâneas. Então, chegou-se a conclusão que era necessário criar uma espécie de funil, ou seja, o sistema até poderia disparar várias threads simultaneamente, mas apenas algumas destas poderiam estar simultaneamente efetuando requisições no servidor. Para tal atividade, foi utilizado um conceito ensinado nas disciplinas envolvendo Sistemas Operacionais, chamado semáforo. Para alguns alunos de cursos voltados à Computação, juntamente com grafos e árvores, semáforo é dos conceitos mais difíceis para se aprender e aplicar na prática. Mas, neste cenário, resolveu perfeitamente o problema proposto, como será mostrado no código fonte abaixo.


List clientes = clienteDao.getClientesByParams(filtros);
List coordenadas = criaListaCoordenadas(clientes);
Integer numeroRequisicoesSimultaneas = 50;
Semaforo semaforo = new Semaforo(numeroRequisicoesSimultaneas);
for (Coordenada coordenada: coordenadas) {
     Thread thread = new Thread(coordenada);
     thread.start();
}
public class Coordenada implements Runnable {
     private Cliente cliente;
     private Semaforo semaforo;
     public Coordenada(Cliente cliente,Semaforo semaforo) {
         this.cliente = cliente;
         this.semaforo = semaforo;
     }
     public Cliente getCliente() {
         return cliente;
     }
     public void run() {
        semaforo.down();
        cliente.setCoordenadas(WebService.getCoordenadas(cliente));
        semaforo.up();
     }
}

public class Semaforo {
     private int numeroThreadsSimultaneas;
     public Semaforo(int numeroThreadsSimultaneas) {
         this.numeroThreadsSimultaneas = numeroThreadsSimultaneas;
     }
     public void down() {
         synchronized (this) {
             while (numeroThreadsSimultaneas <= 0) {
                try {
                     wait();
                 } catch (InterruptedException ex) {
                }
            }
            numeroThreadsSimultaneas–;
        }
     }
     public void up() {
         synchronized (this) {
             count++;
             if (count == 1) {
                notifyAll();
             }
         }
     }
}

Analisando o código fonte acima, a classe Semaforo foi inicializada com o valor 50, que diz respeito ao número de requisições simultâneas que o sistema permitirá. Para cada Thread que for iniciada, quando o método down() for invocado, o semáforo decrementará em 1, e quando o método up() for invocado, o semáforo será incrementado em 1. Quando o valor do semáforo chegar em 0, o “funil” será fechado, ou seja, caso seja invocado o método down(), a thread que estará invocando este método será bloqueada. Já com valor 0 e o método up(), as threads que foram bloqueadas serão acordadas para tentarem novamente passar pelo “funil” e, posteriormente, invocar a WebService. Desta forma, é possível garantir que apenas 50 requisições estarão simultaneamente requisitando as coordenadas pela WebService. Com isso, utilizando o semáforo e limitando em 50 requisições simultâneas, a mesma busca por Uberlândia que antes demorava meia hora, após a aplicação deste conceito, o tempo foi decrementado para cerca de 30 segundos, viabilizando o projeto e deixando o cliente satisfeito.

Concluindo, foi possível demonstrar que, com um pouco de domínio do conceito, e uma certa capacidade de associá-lo com os problemas enfrentados no mercado de trabalho, é possível resolver problemas práticos relativamente mais complexos do que o comum, e quem sabe com isso, obter algum destaque e promoção, além da imprescindível satisfação pessoal em conseguir provar para si mesmo que o aprendizado valeu a pena, tornando-o alguém que faz alguma diferença.

Posted in Software Development | 11 Comments