domingo, 29 de dezembro de 2013

Utilizando concatenação de Strings com StringBuilder

Já vimos em posts passados a classe String é responsável pelo armazenamento de dados do tipo texto, isto é, guarda uma sequência de caracteres. Esta classe é java.lang.String e por incrível que pareça os objetos String são imutáveis, ou seja, depois que criado seu conteúdo jamais é alterado. Já vimos anteriormente, que na verdade quando fazemos s = "aa" e depois s = "bb", existem 3 objetos uma para cada string imutável e um objeto s que aponta primeiro para "aa" e depois para "bb". A classe é final, ou seja, não pode ser alterada por nenhuma outra classe.

Outra classe que permite manipular strings é StringBuffer (java.lang.StringBuffer) que é geralmente recomendada para armazenarmos um grande número de caracteres. Esta classe cria objetos mutáveis, ou seja, diferente de String, o seu valor (valor armazenado em sua instância) pode ser alterado,  pode ser alterado. Também é uma classe final. Esta classe tem outra característica importante: seus métodos são synchronized, assim pode ser utilizada em aplicações multithread sem qualquer alteração.

Existe ainda uma terceira classe - java.lang.StringBuilder - que implementa a mesma API de StringBuffer porém não é thread safe (seus métodos não são synchronized). Como é a mesma API apresentaremos neste post somente exemplos com StringBuffer.



Redução de Dimensões

Em implementação de aprendizado de máquina, normalmente tratamos com um volume de dados muito grande e a complexidade de qualquer classificador ou regressor depende do tamanho da entrada. Desta forma a complexidade de tempo e espaço tem relação direta com o número de exemplos de treinamento para o classificador ou regressor. Existem métodos que permitem selecionar os recursos, isto é, escolher um subconjunto de características importantes do resto, de forma que possamos tratar um volume menor de dados. Em métodos de projeção, estamos interessados ​​em encontrar um mapeamento das entradas no espaço n-dimensional original para um novo espaço k-dimensional (menor que n), com perda mínima de informação. Em álgebra linear, a decomposição em valores singulares ou singular value decomposition (SVD) é a fatoração de uma matriz real ou complexa que nos permite selecionar um subconjunto de vetores mantendo um valor grande da variação existente nos dados originais. É isto que veremos nos dois vídeos deste post.

Veja a sequência no segundo post.

quinta-feira, 26 de dezembro de 2013

Usando estilos de formatação para Strings

Vamos ver nestes dois vídeos como utilizar os recursos de formatação para criação de Strings (usando String.format) e para apresentação de Strings (utilizando System.out.printf).





Usando concatenação de String

Vamos ver agora como concatenar duas Strings. Em outro post mostrarei como realizar a mesma tarefa com StringBuilder. O Java recomenda a utilização desta segunda classe em strings mutáveis.


Operações básicas com String


Vamos ver alguns exemplos de operações com strings:
  • removendo espaços em branco com trim()
  • comparando strings com equals()
  • comparando strings sem case sensitive com equalsIgnoreCase()
  • comparando string em array com charAt()
  • achando parte em uma string com regionMatches()
Vamos conhecer um pouco das funções primeiro:

a) String.trim()
Se você já tiver uma string em uma variável a, chamando a.trim() será gerada uma cópia da string com os espaços em branco no início e no final da string removidos. Se este objeto a representa uma seqüência de caracteres vazia, ou se o primeiro e/ou o último caracteres têm códigos superiores a '\ u0020' (o caractere de espaço), então é simplesmente retornada uma referência para a. Isto é,
a = " abc ";
b = a.trim() // retorna uma nova string "abc"

a = "abc";
b = a.trim() // retorna uma referência para a, isto é, b == a

b) String.equals()
Compara a string a com a string passada como parâmetro. O resultado é true se o argumento não é nulo, é uma String e representa a mesma seqüência de caracteres.

c) String.equalsIgnoreCase()
Compara as strings sem considerar as letras em maiúsculas e minúsculas, isto é, retorna true se:

  1. String.equals() retorna true ou
  2. Como se tivesse aplicado Character.toUpperCase(char) para ambas as strings e daí String.equals() retorna true ou
  3. Como se tivesse aplicado Character.toLowerCase(char) para ambas as strings e daí String.equals() retorna true.
d) String.charAt(i)
Este método permite acessar o valor de char na posição i. O valor do índice i pode variar entre 0 e String.length() - 1.

e) String.regionMatches()
Este método testa se duas regiões das duas strings são iguais. Para isto devemos informar a posição onde começará a comparação na string original e também na string passada como parâmetro, bem como a quantidade de caracteres deve ser comparada. O resultado será verdadeiro se estas partes das strings representam sequências de caracteres idênticos.

Vamos ver no vídeo como utilizá-las

segunda-feira, 23 de dezembro de 2013

Usando Sockets para criar comunicação em Java - Parte 2 de 3

Continuando nosso post anterior, veremos neste post um exemplo de comunicação TCP usando socket. O exemplo é bem simples:
  1. um cliente conecta em um servidor
  2. o cliente envia para o servidor uma sequência de bytes fora de ordem
  3. o servidor recebe os dados, ordena e devolve ao cliente de forma ordenada.
Veremos duas variações do servidor. A primeira realiza um loop while, o servidor bloquea esperando uma conexão, quando recebe a conexão, o servidor processa (e enquanto isto não aceita outras conexões). A segunda versão, cria uma thread para cada conexão, assim pode receber conexões simultâneas de diversos clientes.


Usando Sockets para criar comunicação em Java - Parte 1 de 3

Neste post e nos próximos dois mostrarei como é feita a comunicação via socket em Java. Apresentarei as classes neste primeiro post:

Para TCP utilizaremos basicamente:

  • java.net.ServerSocket: cria um socket de comunicação TCP para o lado servidor
  • java.net.Socket: cria um socket de comunicação (pode ser utilizado por ambos os lados)

enquanto para UDP utilizaremos

  • java.net.DatagramSocket: representa um socket para enviar e receber datagrama (pacotes UDP). Deve ser utilizado para enviar e/ou receber os pacotes pela rede. Estes pacote são dirigidos e encaminhados individualmente. Os diversos pacotes enviados a partir de um computador podem ser encaminhados de forma diferente e pode chegar em qualquer ordem no outro computador.
  • java.net.DatagramPacket: esta classe representa um datagrama (isto é, o dado que queremos transmitir ou que recebemos). O serviço de entrega é sem conexão, ou seja, a mensagem é encaminhada a partir de um computador para outro baseado somente na informação contida dentro dele. A entrega de pacotes e sua ordem não são garantidos.




Nos dois posts seguintes veremos um exemplo de comunicação TCP e outro em UDP.

domingo, 22 de dezembro de 2013

Usando a classe InetAddress para ver endereços IP

A classe InetAddress é utilizada pelo Java para representar um endereço de Internet ou endereço IP, que consiste em um número de 32-bit ou 128-bit sem sinal. Esta arquitetura é definida pelas RFC 790: Assigned Numbers, RFC 1918: Address Allocation for Private Internets, RFC 2365: Administratively Scoped IP Multicast e RFC 2373: IP Version 6 Addressing Architecture.

Uma instância de InetAddress consiste em um endereço IP e seu nome de host correspondente (se fez a resolução do nome). Veremos no vídeo como esta classe se comporta. Devemos notar que existem diversos métodos estáticos e métodos que se comportam como factories que facilitam o tratamento deste tipo de informação. A classe InetAddress não tem construtores visíveis. Para criar um objeto InetAddress, você tem que usar um dos métodos disponíveis de fábrica. Os métodos tipo factory são uma convenção em que métodos estáticos em uma classe que retornam uma instância da classe InetAddress.


sábado, 5 de outubro de 2013

Counting Sort

Normalmente estamos acostumados com algoritmos de ordenação como o MergeSort e QuickSort que funcionam em tempo de execução da ordem de O( lg(n) ) ou até mesmo outros como BubbleSort, Insertion Sort ou Selection Sort, que chegam a tempos de ordenação da ordem de O( n² ). Estes algoritmos são normalmente ensinados nos cursos de graduação. Daí acostumamos com tempos de ordenação grandes e esquecemos que existem algumas situações onde conseguimos tempos de ordenação da ordem de O( n ).

O Counting Sort é utilizado para ordenar vetores de tipos inteiros onde os valores contidos no vetor estão em um intervalo [min, max].  Para ser executado, faz uso de 2 arrays auxiliares, mas com isto consegue um bom tempo de ordenação.

Vamos ver um vídeo com a demonstração deste tipo de ordenação:

domingo, 1 de setembro de 2013

Por que devemos conhecer algoritmos

Existem diversos livros sobre algoritmos no mercado. Somente como exemplo mostro alguns abaixo:


 

 

O conhecimento de algoritmos é importante para podermos criar bons programas. Vamos mostrar no vídeo a seguir que utilizar uma aproximação errada por gerar um programa fácil de ler porém extremamente ineficiente. O melhor exemplo disto é a implementação do cálculo do número da série de Fibonacci.

Pesquisa de bits

Vamos ver neste post duas formas de pesquisa que apresentam vantagens diferentes dependendo do tipo de dados que estamos utilizando. Consideraremos como exemplo a avaliação de uma sequencia de bits. Esta sequencia será passada para o programa como um vetor de inteiros, desta forma queremos achar o primeiro a[i] cujo valor é igual a 1, isto é, que divide o array em duas partes, a inferior contendo "0"s e a superior contendo "1"s.

O primeiro tipo de pesquisa que iremos utilizar é denominado busca linear ou busca sequencial. Este tipo de pesquisa é aplicado em vetores ou listas de modo sequencial, i. e., elemento por elemento, do menor para o maior (ou vice-versa). Deste modo o tempo de execução é função do do número de elementos. Num vetor ordenado, essa não é a pesquisa mais eficiente. No nosso caso veremos que se esperamos que existam poucos bits "0", esta será a melhor opção.

Uma outra pesquisa é a busca binária, onde o tempo de pesquisa é logaritmo em relação ao número de elementos. Este tipo de pesquisa segue o paradigma de dividir e conquistar um vetor ordenado. Funciona mediante sucessivas divisões do espaço de busca, comparando o elemento buscado (ou chave - no nosso caso o primeiro elemento com bit 1) com o elemento no meio do subvetor pesquisado. Este procedimento é facilmente implementado recursivamente.

Vamos ver nosso exemplo:


sábado, 17 de agosto de 2013

Algoritmos para verificação em redes de computadores - Parte II

O segundo algoritmo que vou mostrar é o código de Hamming.

Este código é gerado por operações lineares sobre blocos de dados e foi desenvolvido por Richard Hamming. É muito utilizado no processamento de sinal e nas telecomunicações. Também devido à sua simplicidade é utilizado em memórias de computador tipo ECC.

Para um bloco de dados constituído por n bits (ou palavra), o código de Hamming é obtido inserindo pontos de controle, denominados bits de paridade, como mostrado na tabela abaixo. Para uma palavra de comprimento n bits, são inseridos um número fixo k bits de paridade, ficando a palavra de código com um comprimento N= n + k. A composição do código final é feita de acordo com a montagem das paridades abaixo:

Vamos ver um exemplo real para entender melhor. Veja no vídeo como é feito o algoritmo que implementa o código de Hamming (7,4), ou seja para palavras de 4 bits, gera um código final de 7 bits.


domingo, 4 de agosto de 2013

Algoritmos para verificação em redes de computadores - Parte I

Estou estudando sobre a operação de redes de computadores e me deparei com alguns algoritmos bastante interessantes que são utilizados pelos protocolos de comunicação para garantir que durante a transmissão de dados sejamos capazes de detectar erros de transmissão e até mesmo de corrigi-los.

Neste post vou descrever dois deles:
  • O CRC (Cyclic redundancy check) que permite detectar erros de transmissão e que já vamos achar pronto sua implementação em Java, basta saber chamar as classes corretamente.
  • O Código de Hamming que permite detectar e corrigir erros nos bits transmitidos
O CRC (verificação de redundância cíclica) é um código capaz de detectar erros. Utiliza uma técnica polinomial que gera um valor (com poucos bits de tamanho se comparado com bloco de dados que queremos verificar). Este valor é utilizado para verificar se houve erro na transmissão de dados. A fórmula indicada abaixo é complicada, mas por incrível que pareça pode ser implementada em hardware com componentes comuns.

CRC_{32}(x) = x^{32} + x^{26} + x^{23} + x^{22} + x^{16} + x^{12} + x^{11} + x^{10} + x^{8} + x^{7} + x^{5} + x^{4} + x^{2} + x^{1} + x^{0}


Além disto o CRC apresenta boa eficiência em detectar erros causados por ruído em canais de transmissão. Vamos ver como implementá-lo em Java.


sábado, 3 de agosto de 2013

Outras experiências com Java IO e NIO

Vamos ver neste post alguns exemplos utilizando IO com Java. Nesta sequência de cinco vídeos vamos ver algumas opções de utilização de java.io.

No vídeo #1 vamos criar duas classes. A primeira JavaIoStream será a classe com método main() que irá chamar todas as demais classes dos nossos exemplos, desta forma, ela é basicamente uma classe com um método estático que instancia as demais classes. Note que não precisamos fazer a importação das classes pois todas pertencem ao mesmo pacote.

Utilizamos neste vídeo a classe EscrevendoByteStream que utiliza basicamente duas classes:

  • java.io.FileInputStream: que permite criar um fluxo de entrada de dados (input stream) que nos permitirá ler os dados de um arquivo determinado na criação da classe;
  • java.io.FileOutputStream: que permite criar um fluxo inverso de dados ou seja permite escrever em um arquivo os dados que são enviados para a stream.

O nosso exemplo é bastante simples. Criamos uma stream de entrada e uma de saída, encaminhamos todo o conteúdo da primeira para a segunda. Pronto! Temos uma cópia fiel do arquivo original.

É importante destacar que são verificadas duas exceções nesta classe:

  • java.io.FileNotFoundException: que acontece quando tentando ler um arquivo e ele não existe;
  • java.io.IOException: uma exceção mais genérica que acontece durante a leitura e gravação do arquivo, como por exemplo se o arquivo estiver corrompido. É possível fazer um tratamento mais refinado, porém para o nosso exemplo, isto basta.



No vídeo #2 melhoramos um pouco a nossa classe EscrevendoByteStream, criando uma nova classe EscrevendoByteStream02. Note que não estamos herdando nada da primeira classe. Usamos o código original como base para fazer algumas melhorias:

  • utilizamos um recurso do Java 7 denominado try...with resources. Como ele podemos criar um try que inicializa os recursos e na saída do try estes recursos são automaticamente fechados e liberados, poupando nosso esforço como programadores
  • no exemplo original a leitura era feita byte a byte. É possível melhorar a performance lendo um bloco de dados. Na verdade, a melhoria é basicamente no loop. Normalmente os sistemas operacionais já leem um bloco de dados do disco e armazenam em buffer, assim a leitura no Java de um bloco de dados, faz um acesso ao sistema operacional que lê um bloco inteiro do disco e depois as leituras dos demais caracteres é feita deste buffer que já está em memória.
  • notem no nosso exemplo que mantive as chamadas para o método close dos streams. Faça um teste retirando esta chamada, você verá que não será gerado erro. Isto porque o try...with resources já fecha os recursos abertos automaticamente.


No vídeo #3 tratamos de utilizar "character streams". A primeira vista parece que é uma opção pior que aquelas dos vídeos #1 e #2, porém veremos que as classes java.io.BufferedReader e java.io.BufferedWriter apresentam recursos adicionais para tratamento de caracteres que permite codificar os dados de acordo com um charset ou convertê-lo de um charset para outro. Estas opções não conseguimos fazer com FileInputStream/FileOutputStream que tratam com os dados brutos.

Se vocês compararem os exemplos verão que o processo é semelhante. 



Neste vídeo (#4) mostramos que é possível trabalhar com buffer. No nosso exemplo a chamada foi feita em duas linhas, mais por questões didáticas:

FileReader fr = new FileReader(entrada);
BufferedReader fin = new BufferedReader(fr);

mas poderia ter sido feita em uma linha

BufferedReader fin = new BufferedReader(new FileReader(entrada));

O mesmo valor para a saída.


Continuando a explorar os recursos de FileReader, vamos ver como obter realizar um pré tratamento dos dados de entrada utilizando a classe java.util.Scanner. No nosso exemplo #5, utilizaremos esta classe para obter os valores de um arquivo separados por vírgulas, também chamado de CSV. Note que basta definir o delimitador para poder trabalhar com um arquivo separado por espaços, ou por tabulações ou por ponto e vírgula. A classe Scanner é muito versátil e voltaremos a ela em outro post.


segunda-feira, 17 de junho de 2013

Spring - Parte 3

Vamos continuar a explorar o constructor injection. Neste post vamos entender um pouco mais o que as tags do arquivo de configuração XML.

Veremos que a resolução dos argumentos do Construtor é feita de acordo com o tipo do argumento. Por exemplo na nossa classe Quadrado o construtor é

public Quadrado(Point p, int lado)

os argumentos são Point p e int lado. Como os dois tipos são diferentes, é fácil para o Spring saber qual é o ponto p e qual é o lado (inteiro).

Se existir qualquer ambiguidade nos argumentos do construtor, a ordem em que os argumentos são definidos no construtor é considera de acordo com a ordem pela qual estes argumentos são fornecidos no arquivo de configuração. Por exemplo, para a classe java.awt.Point o construtor é

Point(int x, int y) 

os dois argumentos são inteiros, portanto o Spring utiliza a ordem para definir os argumentos. Assim no arquivo de configuração

<bean class="java.awt.Point"> 
  <constructor-arg value="250" />
  <constructor-arg value="100" />
</bean>
o primeiro argumento x é atribuído o valor 250 e segundo argumento y é atribuído o valor 100.
Se invertermos as duas linhas

<bean class="java.awt.Point"> 
  <constructor-arg value="100" />
  <constructor-arg value="250" />
</bean>

o primeiro argumento x é atribuído o valor 100 e segundo argumento y é atribuído o valor 250.

Vamos ver neste post 2 vídeos:

a) Tags para criação do bean

b) Exemplo de utilização

domingo, 16 de junho de 2013

Spring - Parte 2

O framework do Spring trabalha com o conceito de Injeção de Dependência (DI - Dependency Injection) o que diminui o acoplamento entre as classes.

Existem três formas para realizar DI:

  • Injeção por construtor (Constructor Injection)
  • Injeção por setter (Setter Injection)
  • Injeção por interface (Interface Injection)

A injeção por setter é a forma mais utilizada e trataremos dela com mais detalhes em outros posts. A injeção de interface não é implementada por Spring e por este motivo não falaremos mais dela.

Neste vídeo conheçaremos a ver a primeira opção - Constructor Injection. Particularmente eu não utilizou muito esta opção, pois temos muito mais flexibilidade com o setter injection e algumas vezes pode haver confusão com os argumentos na construção.

Neste caso os objetos são instanciados mediante a configuração dos argumentos passados para o construtor do objeto a ser criado.

Espero que o exemplo apresentado o vídeo tenha deixado claro a vantagem da injeção de dependência, uma vez que pudemos variar a posição (e também poderíamos ter alterado o tamanho) do quadrado na tela somente trocando o arquivo de configuração. Com a DI, não houve necessidade de alteração na classe e de geração de novo bytecode quando na verdade somente precisávamos alterar alguns parâmetros.

É importante destacar ainda que criamos um objeto tipo java.awt.Point de dentro do arquivo de configuração, que foi injetado no Quadrado. Esta classe não precisou de nenhuma linha em Java para ser criada.

Existe muita discussão sobre o uso de DI, um resumo pode ser visto na figura abaixo. Trataremos deste assunto novamente quando já tivermos visto mais sobre Spring.


sexta-feira, 31 de maio de 2013

Usando canvas (ou java.awt.Graphics) - Parte 4

Vamos agora ver como desenhar quadrados, retângulos e outras figuras com 4 lados (quadriláteros):


Usando canvas (ou java.awt.Graphics) - Parte 3

Vamos ver agora como desenhar círculos no canvas em continuação ao post anterior:



Usando canvas (ou java.awt.Graphics) - Parte 2

Continuando o post anterior, vamos ver agora como desenhar um ponto na tela:



Usando canvas (ou java.awt.Graphics) - Parte 1

Se você quiser fazer um jogo em Java outra aplicação gráfica que contenha interação com imagens, figuras e animações, você irá precisar de acessar objetos que não são swing ou awt.

Para isto temos que interagir com a classe Graphics.

A classe Graphics do java.awt é uma classe base (abstrata) para todos os contextos gráficos que permitem um aplicativo desenhar os componentes que são utilizados em vários dispositivos, bem como em imagens fora da tela. Encapsula as informações sobre o estado necessário para as operações de processamento básicas que Java suporta.

Neste primeiro post vamos preparar nosso ambiente, isto é, criar as classes básicas que nos permitirão fazer os desenhos na tela. Veja o vídeo:


quinta-feira, 30 de maio de 2013

Injeção de dependência em Spring

O Spring é um framework que permite uma melhor programação e fornece um modelo de configuração para aplicações empresariais em Java. Segundo a própria Springsource, o objetivo é que as equipes possam se concentrar na lógica de negócios em nível de aplicativo, sem vínculos desnecessários para ambientes específicos de implantação.

As principais características do Spring Framework são:

  • Injeção de dependência utilizando configuração XML e/ou baseada em anotações;
  • Suporte avançado para programação orientada a aspectos com variantes baseadas em proxy e em AspectJ
  • Suporte para transações declarativas, caching declarativo, validação declarativa e formatação declarativa
  • Abstrações para trabalhar com especificações comuns do Java EE (JDBC, JPA, JTA e JMS)
  • Suporte a Hibernate e Quartz
  • Fornece um framework para aplicações web MVC, RESTful e webservices
  • Fornece ambiente para realização de testes de unidade e de integração
  • Suporte a ambiente de cloud computing como Heroku, Google App Engine, Amazon Elastic Beanstalk eVMware's Cloud Foundry

Vamos ver neste vídeo um pouco de injeção de dependência:
 


Fazendo um programa com JDBC - Parte 5

Oi Pessoal,



Continuando a saga da construção de uma aplicação utilizando somente JDBC com MS Access apresento agora Parte 5. Você pode buscar a parte anterior no link.

Vamos ver agora como implementar a classe Contato. Nosso desenvolvimento agora busca conseguir colocar as classes relacionadas abaixo funcionando em conjunto, sendo os dados persistidos (gravados) no banco de dados:
Nosso objetivo neste post é ver como fazer as principais relações entre as telas que permitem cadastrar um contato bem como trocar a senha do usuário logado no sistema.

As interações que verificaremos são:

Vamos ao nosso vídeo:




Se você já acabou de assistir, deve ter percebido o trabalho que gerar uma aplicação completa em JDBC é trabalhosa. Uma aplicação JDBC-ODBC com MS Access é ainda pior, pois tem algumas classes úteis que não são implementadas pelo driver como por exemplo PreparedStatement.


segunda-feira, 27 de maio de 2013

Fazendo um programa com JDBC - Parte 4

Continuando nosso desenvolvimento em JDBC achei que valia a pena discutirmos dois tópicos antes de terminar a programação. Este post pode ser lido como uma continuação de Fazendo um programa com JDBC - Parte 3 ou como uma parte independente.

Primeiro apresento um vídeo tratando dos 4 comandos SQL para manipulação de dados - SELECT, INSERT, UPDATE e DELETE que em português representando o chamado CRUD.



O desenvolvimento que estamos realizando neste blog é bastante básico mas é interessante destacar que para um projeto comercial precisamos preocupar com mais do que fazer o programa funcionar. Um ponto importante e bastante negligenciado principalmente por programadores iniciantes é a possibilidade de ataque aos mecanismos de acesso da aplicação. Uma das formas negligenciadas é o chamado SQL INJECTION.

Veja o vídeo e me diga se você não consegue identificar uma forma de burlar o login simples que fizemos no post anterior.



quinta-feira, 23 de maio de 2013

Fazendo um programa com JDBC - Parte 3

Agradeço ao colega Thiago Aderaldo pela dica deste post. Normalmente devemos utilizar PreparedStatement para executar comandos SQL que são repetidos diversas vezes como por exemplo a atualização da data do último login do usuário que vimos no nosso post anterior.

Porém no caso do MS Access com JDBC esta funcionalidade não está disponível e obtemos um erro ao tentar utilizar.

Vamos ao vídeo


Apesar disto, sigam sempre o conselho do Thiago. Se puderem, usem PreparedStatement para comando repetitivos. Se você estiver utilizando um bom banco de dados, como Oracle, este é o comando certo para utilizar.

quarta-feira, 22 de maio de 2013

Fazendo um programa com JDBC - Parte 2

Continuando o post da Parte 1 vamos ver agora como resolver alguns problemas que criamos na primeira parte. Neste vídeo faremos:

  • criaremos as duas outras tabelas no MS Access necessárias para o funcionamento do programa, são elas Contatos e Comentários
  • criaremos as relações entre as tabelas, ou menor, definiremos as regras de integridade indicando quais são as chaves estrangeiras de cada tabela
  • no programa anterior, o acesso ao banco de dados ficou todo misturado com a parte de interface com usuário na nossa tela de login, iremos neste post fazer a separação entre a tela de login e o acesso a tabela de usuários
  • faremos com que a data de último login seja registrada no banco de dados, toda vez que o usuário realizar um login. Esta é a principal novidade no que diz respeito ao acesso JDBC, pois agora estaremos utilizando um comando UPDATE. Anteriormente vimos como utilizar o SELECT


Deste vídeo uma atividade importante é a separação que conseguimos fazer da interface gráfica e do objeto que acessa o banco de dados. Com este tipo de separação podemos ter este objeto agora em um servidor de aplicações e a interface em um cliente, gerando facilmente uma aplicação em três camadas. Da forma que a aplicação foi desenvolvida na primeira parte de tutorial, não conseguiríamos fazer mais que duas camadas.

sexta-feira, 17 de maio de 2013

Configurando CLASSPATH

Um dos erros que acontece quando tentamos ativar a classe servidora com RMI, como por exemplo no nosso post Acessando arquivos e diretórios remotos via RMI decorre da definição da variável de ambiente CLASSPATH. Se o caminho para a classe não estiver configurado pode ser que rmiregistry não consiga localizar a STUB.

Como ainda não coloquei nada a este respeito no blog, vou aproveitar para apresentar para vocês o básico de configuração do CLASSPATH no vídeo abaixo:


quarta-feira, 15 de maio de 2013

Acessando arquivos e diretórios remotos via RMI

Continuando a série de artigos sobre uso de RMI para acessar informações remotamente que começamos em Utilizando RMI para comunicação remota. Neste post iremos ver como acessar arquivos e diretórios remotamente, inclusive como ler e escrever arquivos remotamente.

É interessante ver que depois das partes específicas da comunicação RMI, ao conseguirmos o acesso ao objeto que implementa a interface remota, as operações são simplesmente a execução dos métodos como se o objeto estivesse na máquina local.

Em função do tamanho da apresentação dividi os vídeos em duas partes:
  1. na primeira parte mostro como criar a interface remota, a classe que implementa esta interface e a classe básica do cliente
  2. na segunda parte mostro a classe servidora e fazemos diversos testes na classe cliente.
 Destaco duas tarefas importantes que você tem que fica atento:
  • a necessidade de rodar rmiregistry para permitir o registro da classe e garantir a comunicação
  • voce tem que gerar uma classe stub que é compilada via rmic a partir da classe que implementa a interface remota
Parte 1

Parte 2

domingo, 12 de maio de 2013

Fazendo um programa com JDBC - Parte 1

Vamos ver como utilizar o JDBC-ODBC para acessar um banco de dados em Microsoft Access que nos permitirá persistir os dados. Nosso exemplo será um programa simples de contatos com 3 tabelas conforme explicado no vídeo. Como será um processo um pouco longo, dividi a construção deste projeto simples em algumas partes.

Nesta primeira parte veremos duas tarefas:
  1. como realizar a conexão com o banco de dados
  2. como realizar uma consulta SQL no banco de dados para validar o login de um usuário

sábado, 11 de maio de 2013

Explicando tipo de drivers JDBC


Existem diversas implementações de drivers JDBC, estas implementações são colocadas em 4 categorias ou tipos:

  • Type 1: são drivers que implementam a API JDBC como um mapeamento para outra API como por exemplo ODBC (Open Database Connectivity). Os drivers deste tipo são dependentes de uma biblioteca nativa limitando sua portabilidade. A ponte JDBC-ODBC é um exemplo deste tipo e em função do ODBC só roda em ambiente Windows que tenha o ODBC e seus drivers instalados.
    • O Java considera a ponte JDBC-ODBC como uma solução de transição, não sendo suportada pelo Java.
    • Este tipo de driver deve ser utilizado somente em situações onde não exista um driver JDBC tipo 2, 3 ou 4.
  • Type 2: são drivers escritos parcialmente em linguagem Java e em código nativo. Estes drivers utilizam uma biblioteca para a parte cliente específica para a fonte de dados que conectam, limitando por esta razão sua portabilidade para os ambientes onde o código nativo roda.
    • Um exemplo deste tipo é o driver OCI (Oracle Call Interface) para bancos de dados Oracle.
  • Type 3: são drivers que utilizam um cliente totalmente Java e se comunicam com um  servidor middleware que utilizar um protocolo independente, desta forma o cliente é puramente Java e pode ser portado para todos os ambientes onde roda a JVM. Cabe ao middleware realizar a comunicação com o banco.
  • Type 4: são drivers Java puros e que implementam o protocolo de rede para uma fonte de dados, desta forma o cliente conecta diretamente ao banco.





Veja o vídeo para mais detalhes....

quinta-feira, 9 de maio de 2013

Instalando o Java 7, o SDK do Java e o Netbeans 7.3

Oi Pessoal,

Aproveitei que resolvi reinstalar do zero minha máquina de desenvolvimento e refiz meu vídeo ilustrando como são instalados os Java JRE 7, JDK 7 e o Netbeans 7.3. O vídeo com todo o processo pode ser visto abaixo:


Este é um post com informações básicas para quem está querendo iniciar em Java e precisa montar um ambiente de desenvolvimento.

segunda-feira, 6 de maio de 2013

Lendo um QrCode em Java

Oi Internautas!

Em atenção ao nosso colega Igor Farias estou escrevendo este post. Ele é tipo uma continuação do post  Gerando QrCode em Java que você pode achar neste blog. O Igor perguntou como fazer para ler um qrcode que geramos na classe do post anterior.

Vou mostrar no vídeo uma classe simples que permite ler o qrcode e interpretar os dados. Vamos a ela:

As bibliotecas necessárias para a criação do código estão aqui.

domingo, 28 de abril de 2013

Utilizando RMI para comunicação remota

O RMI denominado Remote Method Invocation é uma interface de programação Java que permite a execução de chamadas remotas entre aplicações desenvolvidas em Java. A comunicação é feita na forma cliente-servidor. O servidor cria o acesso aos objetos remotos, isto é, aos objetos que serão acessados remotamente pelos clientes. O cliente se associa ao servidor em uma operação denominada bind. A conexão é feita utilizando um URI.

Faremos uma demonstração de como podemos acessar um objeto simples remotamente no vídeo abaixo:

domingo, 21 de abril de 2013

Usando funções trigonométricas

Existe diversos usos para funções trigonométricas. Neste post vamos ver somente como usá-las usando as relações básicas do triângulo entre os catetos e hipotenusa e entre os ângulos do triângulo.

Vamos ao vídeo:

sábado, 20 de abril de 2013

Gerando números aleatórios

O Java nos fornece uma função muito boa para gerar número aleatórios. Na realizada a sequência é semi aleatória.

Esta função é Math.random() e vamos vê-la no vídeo a seguir:

Diversas funções de Java Math

Vou aproveitar este post para colocar diversos vídeos que trabalham com o java.Math para operar com números.

1-) Obtendo o valor da exponencial de um número com Math.exp() e os logarítmos com Math.log() e Math.log10()

2-) Achando o valor absoluto de um número com Math.abs()

3-) arredondando um número para cima com Math.ceil(), para baixo com Math.floor() e o arredondamento estatístico com Math.round()

4-) Achando o máximo de dois números com Math.max() e o mínimo com Math.min()

5-) Obtendo a raiz quadrada com Math.sqrt() e elevando um número x a uma potência a com Math.pow(x,a)


Cronometro em Java

Neste post estarei comentando uma postagem do colega Hyago Henrique da comunidade Java Brasil. Ele está desenvolvendo uma classe de cronômetro que utiliza as classes Timer e TimerTask do Java para apresentar na console a contagem. Vamos ver a utilização desta classe em um vídeo:


A classe alterada é :



sexta-feira, 12 de abril de 2013

Fazendo um chat em java - Parte 3

Nesta parte vamos ver como montar o cliente para nosso servidor de chat em Socket. Nossa aplicação como é um pouco mais complicada e queremos desacoplar os dados e operações.

Vamos criar:
  • uma interface para o cliente do chat - InterfaceCliente.java
  • a implementação desta interface para socket - ClienteSocket.java
  • a interface com o usuário utilizando javax.swing- SwingChat
  • para permitir uma operação melhor da escrita das mensagens enviadas pelo servidor na tela do cliente utilizamos um padrão de projeto denominado Algoritmo.


terça-feira, 9 de abril de 2013

Implementando REST utilizando restlet

Restlet é uma plataforma para desenvolvimento de aplicações REST em Java que é leve, completa, relativamente fácil de usar e de código aberto.

O desenvolvimento com Restlet é adequado tanto para servidor e quanto para aplicativos no cliente (seja web ou Java SE).

O framework Restlet possui uma API que suporta os conceitos de REST e facilita o tratamento das chamadas, tanto para cliente e servidor de aplicações. Os "restlets" não são específicos ao protocolo HTTP e podem ser chamados programaticamente. Ele suporta o protocolo de transporte da Internet, ou seja HTTP e HTTPS, e ainda implementa protocolos adicionais como FTP, SMTP, XML, JSON, Atom, e WADL.

Além de na própria plataforma Java EE, o framework Restlet pode ser usado em aplicações Java SE, em sistemas baseados no Google App Engine (GAE) e no Google Web Toolkit (GWT), e em aplicações para Android.

Vamos dar uma olhada no nosso vídeo:

sábado, 6 de abril de 2013

Pacotes em Java


Vamos ver neste post algo bem básico da programação Java ... o uso de pacotes.
Um pacote Java é um mecanismo da linguagem que permite a organização de classes Java em namespaces. Um pacote fornece um namespace exclusivo para os tipos que ele contém.



Pacotes Java podem ser armazenados em arquivos compactados (são arquivos com extensão JAR), permitindo as classes e interfaces sejam recuperadas como um grupo, organizando as classes que pertencem à mesma categoria ou fornecem funcionalidade semelhante.

Para quem está começando este vídeo é bastante importante. Para aqueles mais habituados a linguagem pode ser uma boa recordação. Vamos ver no vídeo um pouco mais sobre este tópico:

segunda-feira, 1 de abril de 2013

Usando HashMap em Java

A classe HashMap é equivalente à classe HashTable, porém HashMap não é sincronizada, ou seja, múltiplos threads podem alterar o mapeamento concorrentemente.

HashMap também admite valores nulos.

Vamos ver nossa classe no vídeo:

sexta-feira, 29 de março de 2013

Usando HashSet em Java


Uma estrutura de dados tipo HashSet é uma implementação como uma tabela hash para um conceito de conjuntos, assim os seus elementos são armazenados em uma posição derivada de seu conteúdo (hash map). Esta classe permite o elemento null.

As estruturas em hash oferecem performance de tempo constante para as operações básicas (add, remove, contains e size), desde que a função hash apresente uma boa distribuição dos elementos.

Vamos ver no vídeo a seguir como utilizar esta importante classe de dados.



terça-feira, 26 de março de 2013

Gerando QrCode em Java

QR Code é um código de barras bidimensional (no formato de um quadro) que pode ser facilmente escaneado principalmente por smartphones (celulares) equipados com câmera. Assim o código pode ser  convertido em diversos tipos de informação como por exemplo:
  • um texto,
  • um endereço URI,
  • um número de telefone,
  • uma localização georreferenciada,
  • um e-mail,
  • um contato (no formato vCard)
  • um SMS, etc.
Vamos fazer uma classe simples com javax.swing que recebe os dados de um campo texto e transforma este conteúdo em um código QR. Para isto estamos utilizando uma API de kenglxn que encapsula bem os recursos para geração do QR Code. Você pode achar os arquivo no site.

Vamos ver a construção da nossa classe:


QR quer dizer "Quick Response".

As bibliotecas necessárias para a criação do código estão aqui.

sábado, 23 de março de 2013

Utilizando Executors

Desde o Java 5 temos uma classe denominada java.util.concurrent.Executors. Esta classe permite gerar e gerenciar de uma forma mais fácil threads, que são o mecanismo básico (juntamente com socket) para nosso programa de chat no servidor.

Vamos ver como isto funciona.


sexta-feira, 22 de março de 2013

Ler o conteudo de um diretório utilizando DirectoryStream

Vamos ver mais uma classe de Java NIO - DirectoryStream.

Na verdade DirectoryStream não é uma classe, mas uma interface, isto quer dizer que ela não pode ser instanciada (não dá para usarmos o operador new) e sua função é de definir os métodos que devem ser implementados por outra classe que a estende (implementa).

No nosso caso, estamos utilizando Files.newDirectoryStream é uma factory que retorna um objeto que implementa esta interface. O Java implementa três versões deste método:
  • newDirectoryStream(Path):
    • abre o diretório especificado e permite varrer todas as suas entradas
    • o único parâmetro é um Path
  • newDirectoryStream(Path, DirectoryStream.Filter<>)
    • equivale ao primeiro caso, porém passamos também um filtro, que restringe a somente as entradas que passarem neste filtro.
  • newDirectoryStream(Path, String)
    • equivale ao segundo caso acima, porém o filtro é passado como uma String que deve possuir um formato do tipo GLOB.
Vamos a nossa classe:

terça-feira, 19 de março de 2013

Recursividade - Parte 2 ou MergeSort

O merge sort é um algoritmo de ordenação que utiliza recursividade em uma estratégia do tipo dividir-para-conquistar que consiste em
  • Dividir: o conjunto de dados em vários subconjuntos e ordenar esses subconjuntos através da recursividade, isto é, por divisão sucessiva até que o problema fique simples (veja no vídeo)
  • Conquistar: após todos os subconjuntos terem sido ordenados ocorre a união das resoluções em um subconjunto maior até que tenhamos todos o conjunto original ordenado.
No vídeo fica claro que a execução é feita em 3 passos:
  1. Dividir os dados em subconjuntos pequenos;
  2. Classificar as duas metades recursivamente aplicando o merge sort;
  3. Juntar as duas metades em um único conjunto já ordenado.



Como este algoritmo do Merge Sort usa a recursividade em alguns problemas esta técnica não é muito eficiente devido ao alto consumo de memória e tempo de execução. As principais recomendações para tornar este algoritmo mais eficiente são:
  • como o merge sort não é muito eficiente para pequenos conjuntos, devemos utilizar um outro método para subconjuntos com 10 ou menos elementos
  • verificar se o conjunto de dados já está ordenado
  • reduzir o tempo de ordenação eliminando a necessidade de cópia para a estrutura de dados auxiliar.
Vamos ver a nossa classe:


Você vai encontrar diversas informações úteis sobre este algoritmo no site do prof Sedgewick.