Tuesday, March 31, 2009

Gravando Sons em Casa

Uma das coisas para as quais eu penso em usar o notebook é gravar minhas pirações no violão. E como eu não tenho condições de usar um estúdio profissional, é em casa que isso vai acontecer.



Pesquisando na net artigos sobre como gravar audio em casa (procure por home studio), eu achei algo realmente interessante. Parece ser um artigo, que pelo link, hospedado na USP. Bem, de tão bem escrito (ao meu ver), ele explica até o porque das pessoas cantarem bem melhor no chuveiro.



Bem, chega de encheção de saco, e vamos ao link. Só sei que eu já salvei uma cópia disso no meu pendrive, caso saia do ar... Aproveitem! :D

E eu sei tocar violão?

Cá estou eu, selecionando cifras do cifraclub, quando me veio a idéia de conseguir os quatro volumes da coletânia Um Barzinho, Um Violão. Eu acho que essa foi a melhor idéia que eu ja tive, musicalmente, em anos...



Foi pegar o primeiro volume da tal coletânia e eu vejo, nada mais, nada menos, que Oswaldo Montenegro cantando Chão de Giz. Eu disse Chão de Giz... Isso é mais clássico que BaVi! Como se não bastasse, ainda me vem a Luciana Mello cantando As Rosas Não Falam, e o Ed Motta com Azul Da Cor Do Mar. Passei os 50 minutos de download do segundo volume só ouvindo essas três músicas...



Baixado o segundo volume, a bomba. Toquinho tocando três de uma vez só: Esse Seu Olhar, Corcovado e Se Todos Fossem Iguais A Você. Abobalhado com o violão que esse cara toca, lá vai eu fuçar o resto desse volume, e acho, de novo, Ed Motta, cantando Caso Sério. Todo mundo sabe que Soul Music é um dos meus estilos favoritos... Tá, pra não dizer que não tem artista contemporâneo cantando, tinha Biquini Cavadão cantando Coleção. Meio lá meio cá a interpretação, mas tá valendo. Junto essas aí às outras, deixo o terceiro volume baixando, e vou dormir.



Lá pelas 3:28 da manhã, eu acordo com uma puta vontade de tirar água do joelho, fruto de um milk shake de 500ml e um "refrigerante levemente gaseificado" de uma marca qualquer ai. De volta, vejo que o terceiro volume já havia sido baixado. E lá vou eu fuçar de novo... E, de novo, uma surpresa. Pedro Mariano interpretando divinamente Se, do Djavan. Só pelo tamanho do arquivo (7 Mb), eu já sabia que já vinha chumbo grosso, e não estava enganado. Simples, mas realmente bonito... Pra terminar de sacanear, tinha Alcione cantando Wave, é mole?



E depois me dizem que eu sei tocar violão... E olha que eu nem falei em João Bosco nesse bolo. Eu vou dizer que sei tocar violão perto de caras como esses? Nem se eu fosse aluno do Yamandu Costa!

Monday, March 30, 2009

A quantas anda o meu jardim?

A cama é de solteiro, e está vazia... Mas não é nisso que ele pensa. O quarto é pequeno, bastante bagunçado, e parcamente iluminado pelos primeiros raios da manhã. Igualmente vazio, mas não é nisso que ele pensa.



O banho é quente, e não há pelos no sabonete. O box é aconchegante... Ele toma o seu banho sozinho, mas não é nisso que ele pensa. O ônibus chega, e a mesma dupla de cadeiras se encontra vazia. Senta-se à janela, coisa que ele raramente fazia, abaixa a cabeça e fecha os olhos... Sim, ele pensa em alguma coisa.



E do meio do nada, iluminada por luz vinda de sabe-se lá onde, aparece uma borboleta colorida. Ele estende o braço, a mão, e ela pousa suavemente em seu dedo indicador. Ele, então, aproxima a borboleta ao seu rosto, e a olha, pacientemente. E assim como ela surgiu, ela simiplesmente desaparece, como se fosse desmaterializada.



E então, ele se faz uma pergunta:

O que hei de ser, borboleta ou jardineiro? E se jardineiro eu houver de ser, a quantas anda o meu jardim?


Veja Também:

Cuidando do Jardim...

Advogados... Sempre eles...



Vê se pode? Não quis trepar normalmente de graça,  agora vai ter que pagar 800 mil libras por ter comido (ou não) o cú...



Conhece o A Vida Secreta?

Sunday, March 29, 2009

Acredite no amor

Não deixe de acreditar no amor, mas certifique-se de estar entregando seu coração para alguém que dê valor aos mesmos sentimentos que você dá, manifeste suas idéias e planos, para saber se vocês combinam, e certifique-se de que quando estão juntos aquele abraço vale mais que qualquer palavra... [Veríssimo, Luís V.]





Caro Veríssimo, é nisso que eu tenho pensado nas últimas semanas...

Friday, March 27, 2009

Pesquisando Notebooks - Parte 1

Acho que não é segredo de ninguém que eu estou pensando em comprar um notebook pra mim. Mais pensando em uma possível pos-graduação/mestrado do que mobilidade (se bem que ter um micro às mãos, quando o desktop estiver ocupado, vale a pena).





A idéia é conseguir um notebook com custo/benefício razoável, uma garantia boa, por algo entre R$3000,00 e R$4000,00. Pesquisei, e por hora me recomendaram Dell e HP. Aí vamos nós pesquisar reviews sobre os notebooks da Dell, e encontrei dois modelos que me agradaram, o Dell Vostro 1310, mais conhecido como "Vonstro", e o Dell Inspiron 1525.



Com nenhum dos dois, eu vou poder jogar, esse era um dos objetivos:

  • Poder de processamento para possíveis simulações de uma pós-graduação em sistemas distribuidos, inteligência artificial ou redes de sensores sem fio

  • Placa de video razoável para alimentar o vicio nerd em jogos :D

  • Espaço em disco para armazenamento de mp3, séries de TV, e-books e afins.



Daí, se eu fosse escolher um Dell XPS 1330, eu teria que juntar mais grana, muuuuuuito mais grana... Eis o dilema: se for um Dell, escolher um dos dois acima ou esperar mais? Outra coisa: sempre me falam muito bem da garantia dos notebooks da Dell. Pelo que eu li, é possível o cliente abrir o note e trocar peças sem perda da garantia...

Com os relacionamentos anteriores, aprendi...

É meio estranho... Depois de Fausto ter me redigido um puta "quem sou eu" pro meu perfil do orkut, eu vim reparar no que ainda está escrito no meu "com os relacionamentos anteriores, aprendi"...



Se manter firme, quando se tem certeza que está com a razão é mais sadio do que ceder, pra manter um relacionamento. Ter a sua consciência tranquila, sabendo que todo o esforço necessário foi feito, sem passar por cima do seu amor próprio, é ainda mais gratificante...



E sim... Treinar liberdade e desapego. Como diz o blogueiro, cada mulher é inesgotável. Não a liberdade mentirosa, aquela em que por mais solto que se deixe o fruto de desejo, o pensamento ainda lhe é preso. Quase sempre se ouvirá um "não é suficiente", nas entrelinhas. Talvez um desapego total e despretencioso, aquele onde, talvez, nem a saudade lhe bata à porta...



No final disso tudo... "A gente se sente livre, ético, e o escambal"...




E é aqui que eu volto a lembrar daquilo que eu li em algum lugar... Escrever coisas num blog que nem a gente mesmo tem condições de interiorizar. É meio um misto de razão e emoção, é uma confusão só, quando a mente diz e o coração não ouve... Mas qualquer dia desses eles se entendem. Assim espero...



Thursday, March 26, 2009

Outro teste

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce malesuada molestie orci. Integer justo. Aliquam eleifend nunc ac mi. Aenean quis nunc. Ut quis purus nec ipsum gravida vestibulum. Phasellus enim ante, aliquet eu, dictum a, dictum convallis, est. Sed odio velit, elementum at, dictum quis, aliquet quis, odio. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla consectetur elit vitae nunc. Maecenas eget felis eu tellus ultricies consectetur. Duis massa. Integer in purus vitae dui tristique commodo. Vivamus adipiscing sodales nunc. Suspendisse et lacus vitae est condimentum malesuada. Etiam felis metus, rhoncus at, ultrices vitae, tincidunt at, nulla. Vivamus viverra mi vel nunc. Etiam aliquet turpis quis tellus. Maecenas sit amet nulla cursus arcu tempus faucibus.


Curabitur congue aliquet mauris. Quisque et enim. Aenean quis ligula. Duis et ipsum. Ut sed mi. Donec eu ante. Nullam velit neque, ullamcorper in, adipiscing sed, tincidunt vitae, dui. Sed ligula enim, tincidunt at, faucibus nec, venenatis eu, nisl. Etiam bibendum, nisi mollis iaculis tempus, sem est porttitor diam, aliquam egestas libero turpis id nulla. Nullam sem. Integer urna dui, scelerisque eget, rutrum non, dictum sed, eros. Aliquam id orci vel metus rutrum commodo. Vestibulum pharetra, ligula at sagittis luctus, nibh ante aliquam sapien, at venenatis ligula eros cursus nibh. Suspendisse nec nunc. Vivamus turpis ipsum, aliquam sed, faucibus non, rutrum nec, risus. Maecenas iaculis elit dictum lacus. Ut non diam et nunc volutpat commodo. Vivamus in dolor. Pellentesque dolor elit, vehicula vel, feugiat quis, adipiscing eget, ante. Donec posuere felis id felis.

Aliquam neque nibh, gravida vitae, placerat in, pharetra sit amet, lorem. Curabitur arcu lorem, scelerisque eu, fringilla id, tincidunt ac, ipsum. Ut a quam. Nunc ac ligula. Nulla et elit. Quisque purus. Pellentesque risus augue, fermentum id, imperdiet nec, blandit nec, nisl. Donec hendrerit facilisis est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam non dui.

Etiam dapibus. Pellentesque at erat. Sed viverra. Donec sit amet elit vel lectus facilisis lacinia. Maecenas eleifend mauris sed ligula. Mauris urna. Donec cursus. Duis at mi. Nunc massa lorem, commodo at, elementum a, pretium eget, mauris. Quisque consequat dictum ligula. In odio urna, consequat pellentesque, venenatis mattis, tincidunt sit amet, lorem. Duis elementum consequat nisl. Donec sit amet lectus eget enim interdum convallis.

Etiam commodo, diam non eleifend fringilla, dolor ligula blandit nisl, vitae vehicula nibh leo sit amet dui. Mauris non nisi. Nunc eu felis. In magna dolor, fringilla id, tristique eu, tincidunt vitae, mi. Vivamus tempor adipiscing velit. Duis ac turpis vitae sapien ullamcorper dapibus. Nullam ornare nisi. Aenean at massa. Etiam porta, diam sit amet scelerisque mattis, nunc neque ornare eros, sit amet convallis risus sapien eu erat. Nunc blandit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In hac habitasse platea dictumst. Morbi aliquet ipsum et dolor. Praesent id neque. Integer semper ultrices massa. Fusce odio. Sed euismod. Pellentesque faucibus lectus dignissim elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Teste

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce malesuada molestie orci. Integer justo. Aliquam eleifend nunc ac mi. Aenean quis nunc. Ut quis purus nec ipsum gravida vestibulum. Phasellus enim ante, aliquet eu, dictum a, dictum convallis, est. Sed odio velit, elementum at, dictum quis, aliquet quis, odio. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla consectetur elit vitae nunc. Maecenas eget felis eu tellus ultricies consectetur. Duis massa. Integer in purus vitae dui tristique commodo. Vivamus adipiscing sodales nunc. Suspendisse et lacus vitae est condimentum malesuada. Etiam felis metus, rhoncus at, ultrices vitae, tincidunt at, nulla. Vivamus viverra mi vel nunc. Etiam aliquet turpis quis tellus. Maecenas sit amet nulla cursus arcu tempus faucibus.


Curabitur congue aliquet mauris. Quisque et enim. Aenean quis ligula. Duis et ipsum. Ut sed mi. Donec eu ante. Nullam velit neque, ullamcorper in, adipiscing sed, tincidunt vitae, dui. Sed ligula enim, tincidunt at, faucibus nec, venenatis eu, nisl. Etiam bibendum, nisi mollis iaculis tempus, sem est porttitor diam, aliquam egestas libero turpis id nulla. Nullam sem. Integer urna dui, scelerisque eget, rutrum non, dictum sed, eros. Aliquam id orci vel metus rutrum commodo. Vestibulum pharetra, ligula at sagittis luctus, nibh ante aliquam sapien, at venenatis ligula eros cursus nibh. Suspendisse nec nunc. Vivamus turpis ipsum, aliquam sed, faucibus non, rutrum nec, risus. Maecenas iaculis elit dictum lacus. Ut non diam et nunc volutpat commodo. Vivamus in dolor. Pellentesque dolor elit, vehicula vel, feugiat quis, adipiscing eget, ante. Donec posuere felis id felis.

Aliquam neque nibh, gravida vitae, placerat in, pharetra sit amet, lorem. Curabitur arcu lorem, scelerisque eu, fringilla id, tincidunt ac, ipsum. Ut a quam. Nunc ac ligula. Nulla et elit. Quisque purus. Pellentesque risus augue, fermentum id, imperdiet nec, blandit nec, nisl. Donec hendrerit facilisis est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam non dui.

Etiam dapibus. Pellentesque at erat. Sed viverra. Donec sit amet elit vel lectus facilisis lacinia. Maecenas eleifend mauris sed ligula. Mauris urna. Donec cursus. Duis at mi. Nunc massa lorem, commodo at, elementum a, pretium eget, mauris. Quisque consequat dictum ligula. In odio urna, consequat pellentesque, venenatis mattis, tincidunt sit amet, lorem. Duis elementum consequat nisl. Donec sit amet lectus eget enim interdum convallis.

Etiam commodo, diam non eleifend fringilla, dolor ligula blandit nisl, vitae vehicula nibh leo sit amet dui. Mauris non nisi. Nunc eu felis. In magna dolor, fringilla id, tristique eu, tincidunt vitae, mi. Vivamus tempor adipiscing velit. Duis ac turpis vitae sapien ullamcorper dapibus. Nullam ornare nisi. Aenean at massa. Etiam porta, diam sit amet scelerisque mattis, nunc neque ornare eros, sit amet convallis risus sapien eu erat. Nunc blandit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In hac habitasse platea dictumst. Morbi aliquet ipsum et dolor. Praesent id neque. Integer semper ultrices massa. Fusce odio. Sed euismod. Pellentesque faucibus lectus dignissim elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

SCJP - 05 - Exceções e Assertivas

Ando meio sem estímulo pra continuar lendo, mas como terminei o capítulo 5 faz alguns dias, estou devendo os posts/resumos pra mim mesmo :) Sendo assim, a gente continua, pontuando coisas não muito vistas e/ou importantes no que se refere a manipulação de exceções.





Nós, como bons garotos de programa, já sabemos que exceções interrompem o fluxo normal de um programa. Sabemos que é possível envolver o código passível de exceções com um bloco try/catch, ou simplesmente deixar que o método chamador cuide da exceção por nós.



try {
//codigo que gera exceção
} catch (SomeException1 ex) {
//codigo que trata exceção
} catch (SomeException2 ex) {
//codigo que trata exceção
}


public void metodo() throws SomeException{
//codigo que gera exceção
}


O primeiro ponto importante a ser lembrado é que o código que trata a exceção (o catch) é analisado na ordem em que ele é declarado, ou seja, de cima para baixo. Imagine que uma exceção A seja superclasse de uma exceção B, e que as duas estejam sendo tratadas num bloco try/catch.



try {
//alguma coisa
} catch (A a) {
//outra coisa
} catch (B b) {
//qualquer coisa
}


Se A tiver sido posicionada antes de B, ocorre um erro de compilação, cuja mensagem informa que o código que trata a exceção B nunca será alcançado. Porque? Widening... Todas as vezes que a exceção B for lançada, será tratada pelo código mais geral, ou seja, aquele que trata A, justamente porque a análise feita para encontrar um manipulador de exceções adequado é top-down.



Outra coisa curiosa é o bloco do finally. Ele é executado se a exceção for capturada ou não. Ele é executado mesmo se dentro do catch houver um return. Querem testar?





class TesteException extends Exception{}

public class Principal {

public void teste(boolean excecao) {
try {
if (excecao) {
throw new TesteException();
}
} catch (TesteException tex) {
System.out.println("retornando...?");
return;
} finally {
System.out.println("um momento por favor");
}
}

public static void main(String[] args) {
Principal p = new Principal();
p.teste(false);
System.out.println("agora sim");
p.teste(true);
System.out.println("agora sim");
}
}


Lembre-se que nem o catch, nem o finally são obrigatórios, mas não deve haver um bloco try sem um catch ou um finally. Se não houver um try, e o código for passível de exceções verificadas (aquelas que não herdam de RuntimeException), tais exceções devem ser declaradas na interface publica do método, atravéz da palavra chave throws.


Não são só as exceções que alteram o fluxo de execução. Você pode fazer certas suposições, e caso elas sejam falsas, lançar algo semelhante a uma exceção, parando o fluxo de execução do programa. Isso é possível com assertivas :)



void metodo() {
//algum código util (ou nao)

assert(x >= 0);

//código que assume que x seja positivo
}


Caso x seja negativo, um AssertionError (subclasse de Error) é lançado. Note que, assim como nos if, while, do, e for, a única coisa que vai entre os parêntesis do assert() é uma condicional. Qualquer coisa diferente disso gera erro de compilação. No máximo, é possivel colocar uma mensagem de erro que possa ser exibida junto com o estado atual da pilha de chamadas:



//exibindo uma string, ou qualquer coisa que 
//possa ser convertida para uma string
assert(x >= 0) : "x é negativo: " + x;


An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. [Javadoc 1.6]


As assertivas só funcionam se você habilitá-las em tempo de execução, através de parâmetros passados à JVM.



java -ea pacote.Classe


ou



java -enableassertions pacote.Classe


Apesar das assertivas serem desabilitadas por padrão, é possível desabilitadas através de comandos como



java -da pacote.Classe


ou



java -disableassertions pacote.Classe


E a partir daí, é possível habilitar as assertivas em somente uma classe específica



java -ea:pacote.qualquer.Classe pacote.Principal 


Ou em um determinado pacote (e subpacotes)



java -ea:pacote.subpacote... pacote.Principal
Ou quem sabe ainda habilitá-las no geral, e desabilitalas apenas para um determinado pacote



java -ea -da:pacote.subpacote... pacote.Principal


Só fique atento para as seguintes regras:

  • Não use assertivas para validar parâmetros de métodos publicos. Como métodos públicos são a sua interface para o "mundo externo", você precisa garantir qualquer restrições quanto aos argumentos por si só.




  • Você pode usar assertivas para validar parâmetros de métodos privados. Isso parte da premissa que você pode controlar os pontos dos quais este método pode ser chamado, e a partir daí, fazer suposições coerentes.




  • Nunca use assertivas para validar parâmetros de linha de comando. Se realmente precisar validá-los, use exceções ao invés disso. Você pode pensar como se fosse algo semelhante ao primeiro item.




  • Nunca use expressões que possuam efeitos colaterais. Isso pode se referir a atribuições booleanas, métodos que retornem um booleano, coisas semelhantes.




  • Use assertivas, mesmo que em métodos públicos, para checar por código que nunca será alcançado. Note que isso é diferente do primeiro item. Um exemplo bastante simples é:



    switch(breguessu){
    case 2:
    case 4:
    case 6:
    case 8:
    case 0: break;
    default: assert(false); //assumindo que nunca
    //vai passar aqui
    }





Thursday, March 19, 2009

Lorem Ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce malesuada molestie orci. Integer justo. Aliquam eleifend nunc ac mi. Aenean quis nunc. Ut quis purus nec ipsum gravida vestibulum. Phasellus enim ante, aliquet eu, dictum a, dictum convallis, est. Sed odio velit, elementum at, dictum quis, aliquet quis, odio. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla consectetur elit vitae nunc. Maecenas eget felis eu tellus ultricies consectetur. Duis massa. Integer in purus vitae dui tristique commodo. Vivamus adipiscing sodales nunc. Suspendisse et lacus vitae est condimentum malesuada. Etiam felis metus, rhoncus at, ultrices vitae, tincidunt at, nulla. Vivamus viverra mi vel nunc. Etiam aliquet turpis quis tellus. Maecenas sit amet nulla cursus arcu tempus faucibus.


Curabitur congue aliquet mauris. Quisque et enim. Aenean quis ligula. Duis et ipsum. Ut sed mi. Donec eu ante. Nullam velit neque, ullamcorper in, adipiscing sed, tincidunt vitae, dui. Sed ligula enim, tincidunt at, faucibus nec, venenatis eu, nisl. Etiam bibendum, nisi mollis iaculis tempus, sem est porttitor diam, aliquam egestas libero turpis id nulla. Nullam sem. Integer urna dui, scelerisque eget, rutrum non, dictum sed, eros. Aliquam id orci vel metus rutrum commodo. Vestibulum pharetra, ligula at sagittis luctus, nibh ante aliquam sapien, at venenatis ligula eros cursus nibh. Suspendisse nec nunc. Vivamus turpis ipsum, aliquam sed, faucibus non, rutrum nec, risus. Maecenas iaculis elit dictum lacus. Ut non diam et nunc volutpat commodo. Vivamus in dolor. Pellentesque dolor elit, vehicula vel, feugiat quis, adipiscing eget, ante. Donec posuere felis id felis.

Aliquam neque nibh, gravida vitae, placerat in, pharetra sit amet, lorem. Curabitur arcu lorem, scelerisque eu, fringilla id, tincidunt ac, ipsum. Ut a quam. Nunc ac ligula. Nulla et elit. Quisque purus. Pellentesque risus augue, fermentum id, imperdiet nec, blandit nec, nisl. Donec hendrerit facilisis est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam non dui.

Etiam dapibus. Pellentesque at erat. Sed viverra. Donec sit amet elit vel lectus facilisis lacinia. Maecenas eleifend mauris sed ligula. Mauris urna. Donec cursus. Duis at mi. Nunc massa lorem, commodo at, elementum a, pretium eget, mauris. Quisque consequat dictum ligula. In odio urna, consequat pellentesque, venenatis mattis, tincidunt sit amet, lorem. Duis elementum consequat nisl. Donec sit amet lectus eget enim interdum convallis.

Etiam commodo, diam non eleifend fringilla, dolor ligula blandit nisl, vitae vehicula nibh leo sit amet dui. Mauris non nisi. Nunc eu felis. In magna dolor, fringilla id, tristique eu, tincidunt vitae, mi. Vivamus tempor adipiscing velit. Duis ac turpis vitae sapien ullamcorper dapibus. Nullam ornare nisi. Aenean at massa. Etiam porta, diam sit amet scelerisque mattis, nunc neque ornare eros, sit amet convallis risus sapien eu erat. Nunc blandit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In hac habitasse platea dictumst. Morbi aliquet ipsum et dolor. Praesent id neque. Integer semper ultrices massa. Fusce odio. Sed euismod. Pellentesque faucibus lectus dignissim elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Wednesday, March 18, 2009

Quem sou eu?

A primeira pessoa com quem falei no CEFET, isso por si só já é um título e tanto... Aos poucos fui conhecendo a sua complexidade de raciocínio e sua simplicidade ao conduzir a vida. É um cara muito inteligente, atencioso, e de humor afiado. Consegue ser receptivo sob novas circunstâncias e empático com os problemas alheios.



A verdade é q o segredo da nossa longa amizade é o fato de eu me identificar com ele em 2 pontos... Somos similares, por sermos similares, somos incomuns. Pessoas anti-convencionais, de pensamentos subversivos e desafiadores. Formadores de opiniões, ações e tendências. Manipuladores do nosso destino...



Um detalhe q devo ressaltar nele, algo digno de minha inveja e admiração mútuas... É sua capacidade de se integrar e de se entregar ao momento. Ele por vezes é tão verdadeiro e intenso, q sua personalidade é algo raro no mundo. Uma pessoa q conjuga o pensar e o sentir com tanta harmonia merece a glória da eternidade.



Sfohart – True Powerful Mage. Nem Merlin é páreo... ahauhauhauahuahuahuahauhahau




Daeh Ero-Senin, Master of Spartan Mages...

Valeu mesmo! \o/

SCJP - 05 - Controle de Fluxo: ifs, switchs e loops

É, o capítulo 4 passou voando... E daqui a pouco eu vou precisar parar e fazer os exercícios, reler meus posts e fixar tudo o que eu li, afinal de contas, a gente já andou um bocado, não é verdade?





Comando IF

Em relação aos if's, eu acho que não tem quase nada a ser comentado. A não ser aquela velha dúvida que bate quando temos um if-else aninhado:



if (cond1)
if (cond2) ; // alguma coisa
else ; // alguma outra coisa


A que if pertence o else? Essa é uma dúvida bastante comum, mesmo quando a gente termina as aulas de compiladores da faculdade. A resposta é aparentemente simples:



A cláusula else pertence ao if mais interno que ainda não tenha um else.


Fica mais fácil de entender se você seguir as "boas práticas": use sempre o par de chaves {}:



if (cond1) {
if (cond2) {
; // alguma coisa
} else {
; //alguma outra coisa
}
}


Comando SWITCH



Quanto ao switch... Deixa eu ver... Já sabemos que aquilo que vai entre o par de parêntesis do comando deve ser um valor numérico (byte, short, int), um caractere (char), ou um enum. Erros de compilação ocorrem ao tentar usar um long, float ou double. Autoboxing também funciona aqui, ou seja, é válido usar Byte, Short, Integer e Character.



Atente para os tipos usados no switch e nos case's. Eles devem ser compatíveis. O seguinte código causa erro de compilação, por possível perda de precisão:



byte g = 1; 
switch(g) {
case 64:
case 128:
}


O valor 128 já não é mais um byte (-128 a 127), não dá pra fazer um narrowing aqui... Repetir o mesmo valor para um outro case também gera erro de compilação.



O engraçado é que nós temos aquele modelo padrão de switch: os case, com um break ou não (depende só se você quiser que ele execute os case's seguintes em sequência - fall-through - ou não), e o default (ou não) no final. Se você manter em mente que os case's e o default do switch são apenas pontos de entrada para a execução do comando, você pode pensar em coisas como:



int x = 2; 
switch (x) {
case 2: System.out.println("2");
default: System.out.println("default");
case 3: System.out.println("3");
case 4: System.out.println("4");
}


Loops



Uma das coisas mais interessantes que eu vi sobre os loops em java é a maneira de sair de loops aninhados. Eu sempre lembro de Cláudia Gama (ex-professora de introdução à lógica de programação da UFBA) nas aulas de Pascal:



Não use GOTO!


loopDeFora:
for (algo;algo;algo) {
for (algo;algo;algo){
if (algo) {
break loopDeFora;
}
}
}


A mesma coisa vale para o comando continue. E isso não é válido apenas para loops aninhados do mesmo tipo, também funcioina para combinações de for-while e while-for (tive preguiça de testar se funciona com os laços do tipo do)







E o tempo realmente cura?

Dizem que o tempo é a cura pra tudo. Talvez o tempo seja o patrono de todas as curas, maior até que a penicilina, que as planas medicinais tão usadas pelos indígenas, que a resa das rezadeiras... Engraçado...





Até outro dia eu vivia lendo no msn o nick de uma amiga minha, uma frase aprecida com esta:



O tempo não cura tudo. Aliás, o tempo não cura nada, o tempo apenas tira o incurável do centro das atenções. [Martha Medeiros]


E é aí que a gente se pega em contradição. Porque nada, em questão de sentimento, tem cura... Você não sofre mais, não chora mais, não lembra mais, mas quer queira, quer não, ficou marca. E essa marca você carregará pelo resto da sua vida...



E eis que agora não é mais dor. É saudade... E o paleativo da vez é a lembrança. Das coisas boas, é claro. E daqui a algum tempo, a lembrança empoeira, fica jogada no canto do quarto da bagunça, já que um outro novo emplasto faz mais efeito...





Monday, March 16, 2009

SCJP - 04 - Operadores - Notas Mentais

E finalmente eu terminei de ler o maldito capitulo 3. Caraca... Até a autora fala que o capítulo é um monstro (de chato)! E de cara, e ja inicio o capitulo 4 lendo uma coisinha que eu não tinha prestado atenção antes.





Operadores de atribuição compostos são aqueles que combinam atribuição e algum outro operador aritmético/lógico, tais como |=, *=, /=, +=, -=, etc. Nós já sabemos, desde do ensino fundamental, que existe uma certa ordem de precedência nos operadores matemáticos, aquelas coisas básicas sobre divizão e multiplicação virem primeiro que adição e subtração...



int a = 10;
a = a + 10;


O trecho de código acima é equivalente, em termos de efeito, ao código abaixo:



int a = 10;
a += 10;


Entretanto, analise o código abaixo:



int a = 10;
a *= 2 + 3 // isso não é "a = a * 2 + 3"...


É... isso mesmo... isso não é uma expressão do tipo a = (a * 2) + 3. O que acontece é que a expressão do lado direito do operador composto é sempre avalidada primeiro. É mais correto pensar no trecho de código acima como uma expressão do tipo a = a * (2 + 3). Estranho, não?



Também tem algo que eu não sabia até então. O operador instanceof pode gerar erro de compilação. Como?



class Teste {}

public class Principal {
public static void main(String[] args) {
Teste teste = new Teste();
Principal principal = new Principal();

if (teste instanceof Principal) {
System.out.println(
"teste instanceof Princiipal");
}
}
}


É, eu acho que você também pensou que era possivel usar instanceof de qualquer maneira... Mas analisando o erro de compilação gerado (aff, compile e veja! :D), você nota que o operador instanceof só pode ser usado quando o objeto referenciado pertencer à mesma hierarquia de classes que o tipo a ser testado.





Usar instanceof com o literal null sempre resulta em false, para qualquer classe ou inferface.


Também tome cuidado com os operadores de circuito longo, aqueles que não seguem a tal avaliação preguiçosa. São eles o | e o & (favor não confundir com operadores bit a bit - eles não estão na SCJP 6). Tem muita pegadinha que pode ser feita a partir daí. Principalmente quando a gente pensa em envolver operadores pré e pós fixados, e outras coisas que demandam atenção... O próprio livro traz exemplos não tão triviais assim:





int z = 5;
if(++z > 5 || ++z > 6) z++;


a fração ++z > 6 não é avaliada, pq o operador || é de circuito curto. Logo, z é igual 7 após esse trecho.





Sunday, March 15, 2009

SCJP - 03 - Overloading e Autoboxing

É, tem mais pegadinhas. Não fique pensando que ia se livrar fácil daquelas coisas, porque se dá pra complicar ainda mais, é isso que eles vão fazer. Conhece a Lei de Murphy?





Float f  = Float.parseFloat("3.14f");
Double d = f; //FAIL


Float f  = Float.parseFloat("3.14f");
Double d = (Double) f; //FAIL


Não vá achando que é possivel transformar um wrapper em outro. Isso não rola. Não há herança entre eles. Não é possivel fazer um cast entre eles. Dá merda. Tentar fazer isso na passagem por parâmetro então, nem se fala. Mas isso funciona:



Float f  = Float.parseFloat("3.14f");
Object o = (Float) f; //OWNED!


Porque E já que a gente começou a falar de passagem por parâmetro...



Widening: quando a gente transforma uma variável primitiva de um tipo "menos abrangente" para um "mais abrangente".

Boxing: quando a gente "encapsula" um literal em um wrapper.



public class Principal {
public static void teste(Integer i) {
System.out.println(
"Integer");
}

public static void teste(long l) {
System.out.println(
"long");
}

public static void main(String[] args){
int i = 10;
teste(i);
}
}


Quem ganha? Widening. O programa exibe:

long


public class Principal {
public static void teste(int x, long y) {
System.out.println(
"int, long");
}

public static void teste(byte... z) {
System.out.println(
"byte...");
}

public static void main(String[] args){
byte i = 10;
teste(i,i);
}
}


Quem ganha? Widening. O programa exibe:

int, long


public class Principal {
public static void teste(Byte x, Byte y) {
System.out.println(
"Byte, Byte");
}

public static void teste(byte... z) {
System.out.println(
"byte...");
}

public static void main(String[] args){
byte i = 10;
teste(i,i);
}
}


Quem ganha? Widening. O programa exibe:

Byte, Byte


Mas porque? Simples. Em ordem de "custo de implementação", o compilador prefere:

  • Widening

  • Autoboxing

  • Lista variável de parâmetros



Mais pegadinha. Isso compila?



public class Principal {
public static void teste(Integer i) {
System.out.println(
"Integer");
}


public static void main(String[] args){
byte i = 10;
teste(i);
}
}


NEGATIVO. Não é possivel fazer um box e um widening (ou vice versa). Quem diz isso é o compilador, então eu não tenho culpa de nada.



Friday, March 13, 2009

SCJP - 03 - Wrappers e Autoboxing

Talvez seja nesse item que eu tenha visto a pior pegadinha em java até agora... Eu juro que se uma questão dessa me fosse feita, eu iria errar feio. Onde ja se viu uma coisa dessas?





Bem, vamos fazer uma breve introdução (lá ele) sobre o assunto. Os Wrappers são aquelas classes com nomes de primitivas em java: Integer, Boolean, Float, Long, Double, Short, Byte, Character (e não Char). Elas são usadas pra envolver as primitivas, e utiliza-las em lugares onde só se manipulam objetos, como coleções, por exemplo. Você pode ter um Integer como chave, num par chave-valor comumente utilizado num HashMap<Integer,Object> da vida.



Essas classes possuem uma série de métodos utilitários, vistos rapidamente a seguir:



  • valueOf: Existem normalmente 3 métodos com essa assinatura, todos eles estáticos. A função desse método é devolver uma referência a um objeto, cujo valor é o passado por parâmetro:



    Integer i1 = Integer.valueOf(10);
    Integer i2 = Integer.valueOf("10");
    Integer i3 = Integer.valueOf("1000",7);


    A primeira e a segunda linha são autoexplicativas, mas a terceira implica em dizer que a string "1000" vai ser interpretada na base 7, e não na base decimal (padrão, como na segunda linha).



    Uma exceção para os tipos não numéricos (Boolean e Character): Boolean não precisa de "base", e Character não tem como ser analisada a partir de uma String.




  • parseXxx: Para cada wrapper numérico, existe um método que dá uma instância do objeto em questão, cujo valor é obeito analisando a String passada por parâmetro. Ex.:



    Double double = Double.parseDouble("3.1417f");



  • toString: Mais que intuitivo. Mas, também tem 3 versões, duas delas estáticas:



    Integer i = new Integer(10);

    System.out.println(i.toString());
    System.out.println(Integer.toString(10));
    System.out.println(Integer.toString(12345,6);


    Novamente, a última linha indica que o valor 12345 vai ser exibido na base 6.




  • toXxxString(): Existem 3 métodos na maioria das classes wrapper, que retornam uma string representando o valor primitivo em questão transformado para a base descrita na assinatura do método. São elas toBinaryString(), toOctalString() e toHexString(). O engraçado é que Double tem toHexString(), mas não possui as outras duas. Character não possui nenhuma das três.



Bem, pra começar a falar de autoboxing, olhe ai embaixo:



Integer i = 10;


Viu? Sério? Poha man, mangueie não... A variável i não é primitiva. É uma referência a um objeto... E você a inicializou com um literal... E ai? Viu agora? :D Então... A JMV automaticamente "encapsulou" o literal 10 dentro de um objeto do tipo Integer pra você (boxing).



Integer i = 10;
i++;
System.out.println(i);


Viu de novo? Sério? Tá de sacanagem né? Você não viu lá o operador de pós-incremento usado numa variável de referência? Então, a JMV "desencapsula" (unboxing) o objeto inteiro, aplica o operador de pos-incremento na primitiva resultante, depois "reencapsula" (boxing) de novo e reatribui o novo objeto à variável de referência. O que? Eu não te contei? Ops, foi mal... Assim como as Strings que nós vimos em algum outro post, todos os wrappers são imutáveis. Se você altera o valor de um deles, um novo objeto é criado na heap. Se você não reatribui o novo objeto gerado à sua variável de referência, a alteração que você fez será perdida.



E agora, finalmente, a sacanagem.



Integer i1 = 1234;
Integer i2 = 1234;

if (i1 != i2) {
System.out.println("objetos diferentes");
}

if (i1 == i2) {
System.out.println("objetos iguais");
}

if (i1.equals(i2)) {
System.out.println("objetos com o mesmo conteudo");
}


Por onde vocês acham que vai passar? Certo quem disse que passa pelo != e não pelo ==. Agora altere ambos os valores para 123. E agora? Acertou quem disse que passa pelo == e não pelo !=. Mas por que? Pegadinha dos sacanas da Sun?



A fim de economizar memória, duas instâncias do mesmo tipo e com o mesmo valor primitivo, para os seguintes wrappers (criados através de boxing), serão sempre == :



  • Boolean




  • Byte




  • Character entre \u0000 e \u007f (007f é 127 em decimal)




  • Short e Integer, entre -128 e 127






Agora me digam, QUEM vai se apegar a um detalhe desses? É ou não é uma pegadinha bem sacana? E mais uma coisa: não vá pensando que os wrappers são inicializados que nem as primitivas: o valor padrão deles é null também.





SCJP - 03 - Blocos de Inicialização



Bem, de novo, essa é uma das coisas que nós, programadores auto-didatas, não estamos muito acostumados a ver. Eu mesmo só inicializava as variáveis de instância ou dentro do construtor, ou logo depois de declaradas...







class Exemplo {
public static final int CONSTANTE = 0;
public String frase;

public Exemplo() {
this.frase = "Você tem mais o que fazer?";
}
}


Mas, ainda assim, eu já tinha ouvido falar dos blocos de inicialização. A novidade, pra mim, é saber que existem blocos de inicialização estáticos e de instância.



class Exemplo {
static {
System.out.println(
"static initialization";);
}

{
System.out.println(
"instance initialization";);
}
}


Tão vendo, né? Nada de parâmetros, nada daquela frescura de chamada a super(), nada de um monte de coisa. Aliás, podem existir mais de um bloco de inicialização, tanto estático quanto de instância. A ordem de execução é sempre top-down (de cima pra baixo) para cada tipo de bloco de inicialização, mas cada tipo ocorre em determinado momento.



Um bloco estático de inicialização é executado apenas uma vez, quando a primeira classe é carregada (tradução acochambrada do livro). Mas quando é que isso ocorre mesmo? Bem, resolvi testar. Criei duas classes em pacotes diferentes, cujo código fonte eu vou colar ai pra vocês.



package teste.idiota;

public class Teste {

static {
System.out.println(
"static initalization");
}

public Teste() {
System.out.println(
"constutor de Teste");
}
}




package teste;
import teste.idiota.Teste;

public class Principal {

public Principal() {
System.out.println(
"constutor de principal");
}

public static void main(String[] args) {
Principal principal
= new Principal();

System.out.println(
"ei, funcionou?");
}
}


E então, qual a saída do programa? Se vc disse que vai executar o bloco estático da classe Teste, você errou. Agora crie mais duas classes com o seguinte codigo fonte:



package teste.idiota;

public class Teste2 {

static {
System.out.println(
"---------------");

System.out.println(
"teste2 static initalization (1)");
}

{
System.out.println(
"---------------");

System.out.println(
"teste2 instance initalization (1)");
}

public Teste2() {
System.out.println(
"constutor de Teste2");
}

static {
System.out.println(
"teste2 static initalization (2)");

System.out.println(
"---------------");
}

{
System.out.println(
"teste2 instance initalization (2)");

System.out.println(
"---------------");
}

}



package teste;
import teste.idiota.Teste2;

public class Principal2 extends Teste2{

static {

System.out.println(
"---------------");

System.out.println(
"principal2 static initalization (1)");
}

{

System.out.println(
"---------------");

System.out.println(
"principal2 instance initalization (1)");
}


public Principal2() {
super();
System.out.println(
"constutor de Principal2");
}

public static void main(String[] args) {
Principal2 p
= new Principal2();

System.out.println(
"---------------");

Principal2 q
= new Principal2(
"Construtor com argumentos de Principal2");

System.out.println(
"---------------");

System.out.println(
"ei, funcionou?");
}


static {
System.out.println(
"principal2 static initalization (2)");

System.out.println(
"---------------");
}

{
System.out.println(
"principal2 instance initalization (2)");

System.out.println(
"---------------");
}

}



Analizem a saída de texto. Mas notem que Principal2 é instanciada duas vezes, usando construtores diferentes. E prestem bem atenção na ordem das saídas de texto. Isso me faz concluir que os blocos estáticos são executados apenas uma vez, na primeira instanciação de uma classe, enquanto que os blocos de instância são executados todas as vezes que você instanciar a classe.



Todo bloco estático é executado antes da chamada ao construtor da superclasse, enquanto que os blocos de instância são executados logo após essa chamada. Um import sem uso não faz com que estes blocos sejam executados, pelo menos no nosso primeiro teste. Construtores sobrecarregados "compartilham" blocos de inicialização de instância.



Mas você vai me perguntar: pra que p*** servem os blocos de inicialização? Definitivamente, não me pergunte. Devem servir pra alguma coisa. Dizem que eles servem, entre outras coisas, pra inicializar um singleton, mas isso você também pode fazer usando um construtor privado...



Wednesday, March 11, 2009

[O Menino Amarelo] - O recepcionista.



Era uma vez um menino amarelo. E o menino amarelo gostava de frequentar lugares diferentes. Tá, tá bem, quase nunca ele faz isso por conta própria, mas sempre é válido conhecer lugares diferentes, não é verdade? Enfim, certa vez, o menino amarelo foi experimentar uma tal de cadeira erótica, sob recomendações muito bem feitas. Embrenhando-se no meio da selva de pedra, entre bares, bêbados e piriguetes de plantão, eis que ele chega são e salvo.





Entrando no recinto, um recepcionista o atende. Bem, este iria embora dali a alguns minutos, seu expediente estava quase acabando. Perguntado sobre quantas horas desejaria ficar, o menino amarelo responde em alto e bom som: 3 horas. Pega as chaves, e ainda olhando de relance pra coisas bizarras, como a rosa que vira calcinha, lá foi ele subindo as escadas.



Um quarto simples, pra não dizer demasiado humilde, com cama redonda e chuveiro pseudo-quente. Homem realmente não repara tanto em defeitos assim, mas isso, por hora, não vem ao caso. Entre estripolias e pausa pra boquinha, passaram-se duas horas. E no final dessas duas horas, alguém bate à porta.



"Ué, eu não chamei nenhuma participante a mais... É brinde do hotel?" Pensa o menino amarelo. Até que uma voz masculina surge atrás da porta. "Não, negativo, eu não pedi um participante a mais, e se isso for brinde do hotel, eu recuso!" Pensa consigo mesmo, de novo, o menino amarelo.



- Senhor? acabou o tempo...

- Mas como assim acabou o tempo? Eu pedi três horas!

- Perdão senhor, o outro recepcionista não me alertou desse detalhe...



E lá se vai o empata-foda do turno. Pronto, adeus concentração. E olá olhos aguçados para mais defeitos. "Eita, tem alguma coisa me coçando... Ah achei, ta aqui, voando bem na minha frente. Porra, até mosquito aqui tem!" E com as duas mãos, estapeou a muriçoca, que esvaiu-se em sangue. "Eita poooooooha, tem uma baratinha andando ali no chão! Véio, que poha é essa?"... Corre, corre, menino amarelo, pega o seu chinelo e pisa em cima da barata!



Depois de brincar mais um pouco, rindo muito por dentro, acabam-se as três horas. Chegando à recepção, o que se vê é uma ameba super desenvolvida, fundida geneticamente com células de pus, acometidas de febre amarela, dengue, rubéola e cachumba (tá, coloca meningite e leptospirose no meio, pra ficar parecida com o samba). Sim, era com isso que se parecia o recepcionista de plantão. E naquele mesmo instante, iniciou-se um trololó sobre a atuação quase exótica do recepcionista, que deve ter tomado curso de atendente de lan house. Poha, passou do tempo, paga adicional! "Mas é que quando passam da hora, a gente fala do adicional, e só querem pagar pelas horas normais, sem o atraso".



E diante de uma das folhas de sugestão, uma caneta se movia avidamente, rabiscando tudo com zero, zero, zero, zero... Aquela noite realmente vai pra história...



SCJP - 03 - Atribuição, conversão e Inicialização

Putz... Eu ainda tô no terceiro capitulo! Eita troço chato sô! Tentei fuçar alguma coisa interessante pra postar nas 19 primeiras paginas do capitulo, e achei pouca coisa válida :( Bem, eu já havia começado a falar algo, muito por cima, nesse post. Mas aqui é a seção mais apropriada para se falar dessas coisas.





Algumas coisas que a gente deve sempre ter em mente:

  • literais do tipo inteiro, ou seja, coisas como 1, 2, 100, etc, são sempre transformados automaticamente pra o tipo primitivo int (como nós ja vimos no post citado).




  • literais do tipo ponto flutuante, ou seja, coisas como 3.1415, 6.02E24, 1.618 e afins são sempre transformados automaticamente para o tipo primitivo double.




  • conversões de tipos menos abrangentes para tipos mais abrangentes podem ser feitas de modo implícito pelo compliador (e isso é conhecido como widening.




  • conversões de tipos mais abrangentes para tipos menos abrangentes devem ser feitas de modo explícito. Esse tipo de conversão é chamada de narrowing. Não fazer isso implica num erro de compilação, com mensagem do tipo "possível perda de precisão".



    Vamos tentar ser um pouco mais claros... Os seguintes trechos de codigo geram erro de compilação:



    int a = 0;
    byte teste = a;


    double a = 0.0;
    float b = a;



Claro que vocês sabem como se faz uma conversão de tipo (casting) em java, né? Ah bom :D



int a = 0;
byte teste = (int) a;


double a = 0.0;
float b = (float) a;


Oh tio... Se essas conversões automaticas ai são feitas com os literais, como eu inicializo eles então? Para valores inteiros, ou seja, para os short, byte, int e long (esqueci de algum?), tudo é feito normalmente, tomando cuidado apenas com a faixa de valores que cada um desses tipos primitivos suporta.



short a = 127;
byte b = '\"';
int c = 123456789;
long d = 12212321321321321;


Mas com os numeros de ponto flutuante, a coisa ja muda de figura. Observe o codigo abaixo:



float a = 3.14F; //não gera erro de compilação...
double b = 3.14; //também não gera erro de compilação...
float c = 3.14; //gera erro de compilação...
float d = b; //eu preciso mesmo falar alguma coisa? oO


Bem, e se você não inicializar suas variáveis? Bem, se você nunca usar uma variável declarada, com certeza o Eclipse vai te dar um alerta, com aquela linha amarela embaixo da variavel e a mensagem "variable never is read" ou algo parecido. Caso contrário, a depender do escopo (e não deve ser a primeira vez que você ouve falar nessa palavra mágica), o compilador age de uma forma. Se as variáveis em questão forem variáveis de instância (primitivas ou de referência), elas são inicializadas com valores padrão. Algo parecido com:



byte varByte     = 0;
short varShort = 0;
int varInt = 0;
long varLong = 0;
float varFloat = 0.0;
double varDouble = 0.0;
Object varObject = null;

Object[] arrayObject = null;


Quando você instancia um array de objetos, todos os seus elementos também recebem valores default, a menos que você os inicialize explicitamente.



Agora... Quando suas variáveis forem locais, independente de serem primitivas ou de referência, elas realmente precisam ser inicializadas. Não sou eu quem estou dizendo, é o compilador quem reclama, então se isso é inconveniente pra você, vai reclamar com a mãe do nerd que criou a linguagem, ok? :) Com os arrays locais, você deve instanciá-lo (com certeza), como qualquer outra variável de referência, mas não necessariamente inicializar os seus elementos: pelo menos isso é feito também de modo implicito.



E agora, pra você parar de me encher o saco sobre o tamanho desse post, vamos falar bem rápido sobre atribuições. Primeiro, abra este link e dê uma lida rápida. Se quiser, apenas olhe para as figuras. Pronto? Ok.



int a = 1;
int b = a;


Quando você atribui uma variável primitiva a outra, ocorre uma deep copy. O valor da primitiva à esquerda é copiada e colada na área de memória ocupada pela primitiva da direita. Então, quando vc altera o valor da primitiva da direita, nada acontece com a primitiva da esquerda.



Object a = new Object();
Object b = a;


Quando você atribui uma variável de referência a outra, ocorre uma shallow copy. O valor da referência da direita (que no final das contas é um endereço de memória - a localização do objeto na heap) é copiado e colado na area de memória ocupada pela variavel de referência da direita. No final da atribuição, ambas as variáveis estão referenciando o mesmo objeto, então quando você altera o objeto referenciado pela variavel da direita, isso reflete no objeto referenciado pela variavel da esquerda (são o mesmo, até você alterar a referência de um deles).



String a = "Vai catar coquinho, seu nerd!";
String b = a;


Por incrível que pareça, não, isso não é uma shallow copy. É uma lazy copy. Sim, isso mesmo. A princípio, elas apontam para a mesma string (shallow copy). Mas quando você usa qualquer uma das referências para alterar a string, a JVM faz uma deep copy, ou seja, atualiza aquela referência para um novo objeto na heap. Não acredita em mim? então tá. Use o depurador da sua IDE pra avaliar o endereço de memória da variável de referência antes e depois de você mexer nela :)



Tuesday, March 10, 2009

Internet, Relacionamento e Fidelidade.



Já há alguns anos o comportamento das pessoas na internet é tido como campo de pesquisa. Com o advento das redes sociais virtuais, tais como o orkut, o sonico, facebox e tantos outros, pessoas se conhecem, trocam informações e interesses. É extremamente fácil encontrar pessoas de divesos lugares do planeta, e manter contato das mais diversas formas e níveis de intimidade. E não só atrávés destas, afinal, mensageiros instantâneos e correios eletrônicos dão um grau ainda maior de interpessoalidade: um contato mais frequente e direto é possível, sem dificuldade alguma.





Entretanto, as relações interpessoais reais também tem sofrido mudanças de valores. Termos como relacionamento aberto, swinger, poliamor e alguns outros tem aparecido desde o surgimento dos hippies, nos anos 80. As mudanças de valores entre gerações têm se tornado ainda mais aceleradas e radicais do que algumas décadas atrás. E no centro da discussão, a fidelidade. Até onde o contato interpessoal, seja ele virtual ou real, pode ser considerado uma violação à fidelidade?



Servindo-se do anonimato ou não, hoje muitas pessoas utilizam a internet como meio de acesso à pornografia, antes obtida apenas através de fitas de vídeo e revistas masculinas. Até mesmo um flerte pode ser engatado entre duas pessoas, através dos tais mensageiros instantâneos ou correios eletrônicos. Não é tão dificil assim encontrar pessoas que se conheceram e iniciaram um namoro real através de um contato inicial pela internet. Mais fácil ainda é encontrar pessoas que têm ou já tiveram um relacionamento virtual.



E é aí que se acirra a discussão. Algumas pessoas consideram que há traição apenas quando há envolvimento sentimental. Outras, quando há o toque, o jogo de sedução, o beijo, o abraço, o sexo. E há outras (a maioria, de fato), que considera uma troca de mensagens com conteudo insinuativo, sensual ou erótico, um motivo de traição em qualquer relacionamento amoroso. Isso leva a algumas pessoas a exigirem o compartilhamento de senhas de todos os meios de comunicação a que se tem acesso, o que não garante o monitoramento do cônjugue, já que também é extremamente fácil abrir uma segunda conta em qualquer um destes serviços e continuar o contato iniciado anteriormente.



E então, qual a solução? Com certeza, alimentar desconfiança eterna em relação ao cônjugue faz com que o relacionamento se torne extremamente superficial, com tendência a ciumes infundados, brigas, discussões e à tão falada "infidelidade preventiva", aquela em que um trai primeiro pela possibilidade de traição por parte do outro. Um voto de confiança é necessário pra que haja um mínimo de intensidade nesse relacionamento, afinal de contas, não há envolvimento sem entrega.





Fontes de Pesquisa:

Infidelidade na Internet - Por Aline Feltrin

A infidelidade conjugal ganha nova face - Sharon Jayson

Internet e Infidelidade - Rosana Ferrari

Monday, March 9, 2009

Logoterapia

Graças à Bruna Sayuri (Sayuri-san), eu pude ler um pequeno trecho de texto que me deixou bastante feliz. Eu tinha mostrado o artigo da UFSC citado neste post, e ela me veio com isso :) E antes de exibir o tal trecho, eu vou citar algumas referências, pra gente poder compreender melhor de onde isso veio.







Viktor Emil Frankl (Viena, 26 de março de 1905 — 2 de setembro de 1997) foi um médico e psiquiatra austríaco, fundador da escola da Logoterapia, que explora o sentido existencial do indivíduo e a dimensão espiritual da existência. [Wikipedia]



A Logoterapia é um sistema teórico – prático de psicologia, criado pelo psiquiatra vienense Viktor Frankl, que se tornou mundialmente conhecido a partir de seu livro "Em Busca de Sentido" (Um Psicólogo no Campo de Concentração) no qual expõe suas experiências nas prisões nazistas e lança as bases de sua teoria. De acordo com Allport, "trata–se do movimento psicológico mais importante de nossos dias". [Wikipedia]



E então, o trecho:



Amor é a única maneira de captar outro ser humano no íntimo da sua personalidade. Ninguém consegue ter consciência plena da essência última de outro ser humano sem amá-lo. Por seu amor a pessoa se torna capaz de ver os traços característicos e as feições essenciais do seu amado; mais ainda, ela vê o que está potencialmente contido nele, aquilo que ainda não está, mas deveria ser realizado. Além disso, através do seu amar a pessoa que ama capacita a pessoa amada a realizar estas potencialidades. Conscientizando-a do que ela pode ser e do que deveria vir a ser, aquele que ama faz com que estas potencialidades venham a se realizar.



Na logoterapia o amor não é interpretado como mero fenômeno de impulsos e instintos no sentido de uma assim chamada sublimação. O amor é um fenômeno tão primário como o sexo. Normalmente sexo é uma modalidade de expressão do amor. O sexo se justifica e é até santificado no momento em que, porém apenas enquanto for veículo do amor. Desta forma o amor não é entendido como mero efeito colateral do sexo, e sim é entendido como um meio de expressar a experiência daquela união chamada de amor.



A terceira forma de encontrar um sentido na vida é sofrendo.



[FRANKL, Vicktor E. Em busca de sentido: um psicólogo no campo de concentração. Petrópolis: Editora Vozes, 1991.]


Pra quem se interessou...

Link Direto

Abram na página 64







SCJP - 03 - Heap and Stack

Bem amigos da... E continuamos a nossa série de postagens sobre Java e a SCJP. Hoje, uma pergunta simples e bastante comum a todos os autodidatas que estudam Java: Que diabos é heap e stack?



Colé di mermu véio, tá me tiranu é? Ó paí ó...


Calma, calma... Primemiramente, temos que explicar que heap nada tem a ver com aquele neo-hippie saudosista, eternamente parado nos anos 80. E stack não é aquela peça de madeira usada nas cercas das fazendas. Confesso que eu mesmo nunca havia atentado para a existência e diferença entre essas duas terminologias, apesar de entender o que acontece, já de outras linguagens.





Quando você chama um método, o seu código e as variáveis locais (incluindo os parâmetros formais) vão para a stack. Se você criar uma função recursiva sem condições de parada, o que você terá é uma StackOverflowException como resultado, ou seja, a stack cresceu tanto que invade uma área que não lhe pertence.



Também explode um tipo de erro bastante comum em java:

java.lang.OutOfMemoryError: Java heap space


Esse ai acontece quando você instancia objetos demais. Imagine você e seu trabalho de teoria dos grafos. Você precisa implementar adição, remoção e até soma de grafos. Conforme você vai instanciando nós do grafo, eles são mantidos em memória numa área diferente da stack, porque não são variáveis locais. Até que lá pelo 15.000º nó, você vê o erro acima explodir no seu console :)



Em suma, o que você precisa lembrar é:



  • Variáveis de instância e objetos são mantidos na heap.

  • Variáveis locais e métodos são mantidos na stack.



Ah, mas se eu fizer um código do tipo:

public void metodo() {
...
Cachorro cachorro = new Cachorro();
...
}


O que vai pra stack e o que vai pra heap



Primeiro, lembre-se que cachorro é uma variável que aponta para uma área de memória. Depois, lembre-se que, por ser variável, cachorro também precisa ocupar uma área de memória. Logo, cachorro está na stack, e referencia um objeto na heap. Isso sem falar que o código fonte do método metodo também vai para a stack.

Sunday, March 8, 2009

[UFSC] Término de um relacionamento amoroso



Psicologia é realmente algo fascinante. Eu nunca pensei que alguém fizesse um estudo sobre os sentimentos predominantes num término de relacionamento, por mais curto que seja. E o pior disso tudo, é que eu nunca me imaginei fazendo esse tipo de pesquisa na internet.



Pois é, meus caros. Eu acabei de achar esse artigo na internet. O artigo é sério, endosado pela Universidade Federal de Santa Catarina, ou seja não é fruto de álcool e teclado. O artigo fala sobre manifestação física dos sentimentos, sobre um luto profundo criado durante o processo, e até sobre quem sofre mais ou menos com a separação.



Entretanto, eu não li menções sobre o que se sente quando não há necessariamente uma fase de ofensas, como motivo para o encerramento da relação. Isso me faz pensar que a tal sensação de alívio, por parte de quem toma a iniciativa do término, não é totalmente verdadeira. De resto, concordo com praticamente tudo o que foi discutido nesse artigo, não que eu já não tenha vivido isso na pele, mas porque é algo fruto de metodo científico :)



A todos vocês, uma boa leitura.



Link Direto



Friday, March 6, 2009

Reforma Ortográfica dói no bolso...

Quando eu estudava no CEFET-BA (que não sei porque inventaram de mudar o nome para IFBA), alguém me deu a dica de procurar livros de literatura nos sebos da vida.







Sebo é o nome popular dado a livrarias que compram, vendem e trocam livros usados. [Wikipedia]




Mas não confunda: O nome da rádio é... Pau de Sebo não tem nada a ver com uma pilha de livros usados.




Funciona assim: se você não tem grana nem pra comprar um chiclete mascado, você leva alguns dos livros que possui em casa até um sebo, procura algum livro do seu interesse, e troca o que você quer por aqueles que você levou. Você também pode comprar o livro que procura por um preço bem abaixo da média, afinal de contas, é um livro usado. Fiz isso no período do terceiro ano do colegial, aquela fase chata que a gente tem que ler Machado de Assis, Jorge Amado, e tantos outros ilustres escritores brasileiros. Um livro desses numa livraria qualquer custava os olhos da cara...



Mas, e por que a reforma ortográfica acaba com o bolso da gente? Simples. Quais as chances de você achar um livro, revisado para a reforma ortográfica, num sebo da vida? Quem realmente precisa desses livros segundo a tal reforma ou vai desembolsar uma graninha, ou vai esperar alguém comprar pra "tirar chéroquis"... Depois eles fazem campanhas e mais campanhas pra combater a pirataria...



Thursday, March 5, 2009

Massoterapia e música

Você já experimentou aquela massagem feita justo na sexta feira, último dia da semana, no começo do dia, na sua empresa? Aposto que a galera faz fila, e briga pra receber uma massagem dessas não é? E aquelas músicas então? Nooooosa, ajudam pra caramba a tirar o estresse da semana não é?



Estava ontem conversando com uma amiga minha massoterapeuta, Vanessa Machado, carioca. Ela estava procurando algum programinha conversor de wma para mp3, e me falou das músicas que ela gostava de usar quando trabalhava: normalmente músicas com sons da natureza. Realmente, era esse tipo de música que eu ouvia no jornal A Tarde, todas as quintas feiras pela manhã, no meu tempo de estagiário. Eu acho que a maioria das pessoas relaxa mais com o som de rio, de pássaros cantando ao fundo, e algo de teclado. Também existem outras composições com sons de chuva, golfinhos, e tantas outras coisas que a gente até perde a conta...





Enfim, resolvi pesquisar esse tipo de música e trouxe algumas sugestões. A primeira delas é o cd Melodias da Natureza - Vol. 1, do Kenio Fuke, pela gravadora Lua Music. Existem alguns outros álbuns desse artista, como o Música, Natureza & Cia. - Vol. 2, pela gravadora Azul Music. É só dar uma procurada que se encontra mais coisa sobre ele.



Pesquisando mais um pouco, a gente acha o álbum A Tranquilidade dos Sons da Natureza, do Corciolli. Pesquisar outros álbuns dele fica mais fácil, já que ele possui site próprio.



Pra terminar, e não encher muito o seu saco, tem o álbum Passarinhos - Sons Naturais, de Mad Goodall, pela gravadora Azul Music. Só possui duas músicas, de mais ou menos meia hora - acho que esse é o tempo padrão de atendimento para cada massoterapeuta.



Se de repente eu souber de mais alguma sugestão, eu volto e coloco aqui pra quem tiver interesse... Vai que eu descolo uma massagem "di grátis" não é mesmo?



Veja também:

Como baixar cds inteiros de música na internet



Wednesday, March 4, 2009

SCJP - 02 - Mais sobre Construtores

Dessa vez a gente vai sacanear! :D Vamo lá experimentar mais uma das coisas que talvez eu nunca tivesse parado pra pensar, descritas no livro da certificação. Antes de mais nada, precisamos lembrar que:



O compilador sempre irá inserir uma chamada a super(), como primeira instrução de qualquer construtor, a menos que já exista uma chamada a this().




Agora olhem a seguinte sacanagem:



class Teste {
Teste(String teste){
this();
}

Teste() {
this("teste");
}
}

public class Principal {
public static void main(String[] args) {
Teste teste = new Teste();
}
}


Vocês podem até compilar... O livro fala que talvez o compilador java deixe isso passar. Se isso acontecer, eu não aconselharia a tentar rodar isso não... Logo de cara, a gente olha o código e pensa: puts, que coisa idiota! claro que isso é um loop infinito! Mas logo depois a gente para e lembra daquela premissa: nada é o que parece ser.



Daí a gente lembra que o compilador insere coisas implicitamente, como primeira instrução de cada construtor. Opa, exceto se já houver uma chamada a this()! Bem, como não existem outros construtores na classe, e todos eles tem uma chamada a this(), o compilador não pode fazer nada. E como ambos os construtores chamam um ao outro, nós, novamente, pensamos: puts, que coisa idiota! Isso é um loop infinito! Tá, tá, não necessariamente um loop infinito, mas uma recursão que só acaba com um estouro de pilha.



Mesmo que houvesse um terceiro construtor, que não fizesse uso da chamada this() (e como consequência, fizesse uso de uma chamada a super(), explicitamente ou não), se um dos dois outros construtores fossem utilizados na instanciação de objetos, o mesmo pau aconteceria.



Testei aqui com o java 6. Sem parametros. Não compilou. Dai eu decidi usar alguns parametros pra testar:



javac -source 1.5 Principal.java
javac -source 1.4 Principal.java


O resultado foi sempre o mesmo, exibido abaixo:







Tuesday, March 3, 2009

SCJP - 02 - Construtuores



Eu não sabia que era possível enumerar tantas regrinhas envolvendo construtores... Passando o lho por cima, a gente nota que muitas delas já são mais do que batidas no nosso cotidiano. Então eu resolvi pular algumas delas e escrever um post sobre coisas que eu testei, vindas do limbo.





Segue um techo de código. Copie e tentem compilar. Alguém me diz o porquê do erro tão bizarro?



class Base {
private String teste;

public Base(String teste){
this.teste = teste;
}

public String getTeste() {
return teste;
}
}

class Derivada extends Base {
private Integer i;

public Derivada(Integer i) {
this.i = i;
}

public Integer getI() {
return i;
}
}

public class Principal {
public static void main(String[] args) {
Derivada derivada = new Derivada(1);

System.out.println(
derivada.getI());

}
}






Por incrivel que pareça, isso não tem absolutamente nada a ver com erro de digitação. Agora, alterem o construtor da classe Derivada, conforme abaixo:



public Derivada(Integer i) {
super("teste");
this.i = i;
}


Agora, o código compila. Mas... Por quê?



Resposta: Ambas as duas classes não possuem construtor padrão. Sim, e daí? O compilador insere implicitamente uma chamada a super() como primeira instrução de qualquer construtor, a menos que já exista uma chamada a this(). O método super() chama o construtor sem argumentos da superclasse, enquanto que o método this() chama o construtor sem argumentos definido na própria classe. Logo, a chamada a super() feita implicitamente dentro do construtor de Derivada não surte efeito, porque a classe Base também não tem construtor padrão.



Mas... se o compilador java é algo tão robusto, por que, então, ele não detectaria esse tipo de erro? O compilador gera um código semelhante ao abaixo:



class Derivada extends Base {
private Integer i;

public Derivada(Integer i) {
super();
this.i = i;
}

public Integer getI() {
return i;
}
}


E então, ao tentar fazer referência ao trecho de código que realiza a invocação equivocada, o compilador utiliza o seu código, não o gerado por ele. É ai que fica parecendo que é o "{" que não consegue ser interpretado pelo compiilador...



Então, por via de regra: sempre que você definir um construtor não padrão na sua classe, implemente um construtor sem argumentos. Se você não implementar nenhum construtor, o compilador implementará um construtor padrão pra você.



  • O construtor padrão tem o mesmo modificador de acesso da classe.

  • O construtor padrão não possui lista de argumentos.

  • O construtor padrão tem uma chamada ao construtor da superclasse (super()).



Depois dessa explicação furada, dêem uma olhada na pagina 138 do livro da certificação, versão em inglês. Vejam que naquela situação, a chamada a super() é feita explicitamente, tornando o erro gerado pelo compilador um pouco mais legível:



public Derivada(Integer i) {
super();
this.i = i;
}




Agora sim parece ser mais óbvio dizer que o compilador tentou chamar super() e não achou um construtor sem argumentos na superclasse. O mais estranho disso tudo é que o livro da SCJP diz que é óbvio concluir que construtores não são herdados. Eu juro que não vi obviedade nenhuma nisso... Eu demorei pra concluir que, pelo fato de construtores não possuirem um tipo de retorno, nem poderem ser utilizados dentro de métodos, eles não podem ser considerados métodos, e daí concluir que eles não são herdados. Acho que nem a propria Sun explica isso direito :(



Monday, March 2, 2009

SCJP - 02 - Interfaces

Mais uma vez, tem coisas que a gente ja faz no automático. Estamos acostumados a só definir alguns métodos numa interface, e implementá-los numa classe qualquer, algo do tipo:



interface Testavel {
public void testar();
}

class Rodavel implements Testavel{
public void testar() {
System.out.println("teste");
}
}


Dos posts anteriores, nós sabemos que:



  • Classes não podem estender mais de uma classe pai.

  • Classes podem implementar mais de uma interface.



Mas acontece exatamente o contrário com as interfaces. Interfaces podem sim extender mais de uma interface pai, mas não podem implementar qualquer interface.



interface Inflavel {
public void encher();
}

interface Brinquedo{
public void jogar();
}

interface Bola extends Inflavel,Brinquedo{
public void estourar();
}


Assim, a primeira classe não-abstrata que implementar a interface Bola, deverá implementar os métodos definidos em Bola, e nas interfaces que ela estende: Inflável e Brinquedo. No mais, todas as regras referentes a sobrecarga, sobrescrita e herança continuam funcionando.