Breno Ferreira

Opniões e códigos de um desenvolvedor de software .NET.

Minha experiência com um curso do Coursera

leave a comment »

Olá pessoal, tudo bem?

Recentemente, concluí o curso de Principios de Programação Funcional em Scala, do Coursera, e decidi escrever aqui como foi minha experiência com o curso.

Motivação

Decidi fazer o curso de Programação funcional com Scala no Coursera por dois principais motivos:
  1. Queria saber como seria a experiência de aprendizado online. Eu, como talvez a grande maioria das pessoas, sou um estudante tradicional, ou seja, sempre estudei dentro de uma sala de aula. Nunca participei de nenhum tipo de ensino a distancia, ainda mais online.
  2. Interesse em aprender sobre programação funcional. Sempre programei nos paradigmas tradicionais: imperativo e orientado a objeto. E recentemente passei a ter um grande interesse nesse paradigma, que apesar de não ser novo, passou a ter grande destaque na industria de software, e é cada vez mais relevante em alguns cenários de desenvolvimento de aplicações.
Por essas razoes, vi esse curso como a oportunidade perfeita de aprender algo novo, e ainda poder participar de uma experiência de aprendizado diferente.

Descrição do curso

O curso foi dividido num período de 7 semanas, e a cada semana, um tópico novo era abordado. Esses tópicos eram apresentados pelo professor em formato de vídeo aulas, e sobre cada tópico, havia um exercício que deveria ser feito para praticar os conceitos apresentados nas aulas.
A dificuldade do curso, na minha opinião, foi razoavelmente desafiadora. Os tópicos, apesar de não serem muito complexos, tinham exemplos e exercícios que não eram triviais, e exigiam um bom raciocínio e dedicação para bem compreende-los. Comparado com as aulas que tive na faculdade, o curso do Coursera foi consideravelmente mais desafiador. Isso, para mim, foi muito bom, pois exigiu um certo esforço e disciplina para concluir o curso com sucesso. E ainda foi possível ter uma ideia de como é o nível das aulas lecionadas em universidade estrangeiras, neste caso a EPFL da Suíça.

Conclusões

Ao meu ver, o ensino online, apesar de estar dando seus primeiros passos, é uma grande quebra de paradigma na educação. É um modelo de ensino bem diferente do tradicional, onde os alunos assistem aulas presenciais.
No modelo de ensino online, tive uma liberdade muito maior para conseguir assistir as aulas e fazer os exercícios conforme a minha agenda permitia.
Outro beneficio e que assistindo aulas online, caso eu não conseguisse entender logo de primeira o que o professor explicou, eu podia voltar o vídeo e assistir a explicação novamente. Havia também fóruns de colaboração entre os alunos, que eles podiam usar para tirar duvidas e discutir assuntos relacionados ao conteúdo das aulas. E é claro, sempre há o Google para alguns momentos de desespero.
Isso dava um dinamismo muito grande no processo de aprendizado, pois o aluno tinha ao seu dispor um conteúdo de qualidade, e também podia aprender de conforme suas necessidades.
Vale ressaltar que esse curso foi usado na própria universidade para os alunos matriculados. E o tempo na sala de aula era usado para que os alunos pudessem fazer os exercícios, tirar duvidas com o professor e interagir com os outros alunos.
Algumas pessoas dizem até que esse é o futuro das escolas. E de uma certa maneira, eu concordo. É muito melhor ter aulas com os melhores professores disponíveis, do que ter que se contentar com aquele professor que a escola te disponibiliza, que as vezes pode não ter uma didática boa ou não conhecer muito bem o assunto.
Esse video ilustra bem essa mudança de paradigma na educação. Ele não foca tanto no aspecto de educação online, mas sim, em uma mudança onde os alunos aprendem melhor quando eles estão a vontade, e conseguem colaborar com seus colegas.
Nesse curso que fiz, percebi que, maior que o objetivo de conseguir um certificado no final, o principal objetivo era aprender, e a colaboração com os outros estudantes e com acesso a material de várias fontes diferentes ajudavam e não eram coibidos pelo professor.

Links para outros sites de e-learning

Existem outros sites do mesmo tipo do Coursera, que disponibilizam conteúdo de universidades online. Os mais conhecidos são:

Edx: Esse site disponibiliza aulas de universidades como MIT, Harvard, Berkeley e outras. Os cursos são focados principalmente na area de TI.

Udacity: Aqui existem aulas focadas em Ciência da Computação com instrutores bem reconhecidos no mercado, alguns deles são professores de universidades conhecidas dos Estados Unidos, como Stanford. Um dos mais conhecidos é o de Inteligência Artificial, com um professor da Stanford e associado ao Google que desenvolveu o carro que se auto dirige.

Khan Academy: Talvez um dos pioneiros de aulas online. Começou a alguns anos com aulas de matemática, e hoje conta com um acervo de mais de 3000 videos sobre diversos assuntos, entre eles matemática, física, química, biologia, etc.. Os vídeos são sobre assuntos tanto de nível básico (Ensino Fundamental e Médio) até nível universitário.

Written by Breno Ferreira

05/12/2012 at 16:37

Posted in ELearning

Tagged with , ,

É tudo uma questão de mindset

leave a comment »

Há algum tempo atrás, não me lembro como, através de vários clicks em links no browser, me deparei com um livro na Amazon chamado “Mindset: The New Psychology of Success“. Na época, me lembro que estava influenciado por uma mudança de comportamento no trabalho em relação a agilidade no desenvolvimento de software, e o título me chamou a atenção.
Li a descrição do livro e alguns reviews e decidi comprar o livro, e hoje, estou escrevendo aqui algumas consideraçõe sobre o assunto principal do livro: como seu mindset altera a sua percepção sobre suas próprias habilidades.

O que é mindset?

Definição da Wikipedia:

“Na teoria de decisões e na teoria de sistemas gerais, um mindset é um conjunto de hipóteses, métodos ou notações utilizadas por uma ou mais pessoas que já está tão estabelecida que cria um incentivo poderoso para que essas pessoas continuem a adotar ou aceitar comportamentos, escolhas ou ferramentas já utilizadas”.

Ou seja, é a forma como você vê e aceita sua realidade ou a realidade do mundo ao seu redor, ou como você se comporta em relação a algum assunto ou coisa.

Tipos de mindset

Segundo o livro, há dois tipos de mindset: o mindset fixo (fixed-mindset) e o mindset construtivo (growth mindset). Esses dois tipos de mindsets alteram completamente como o indivíduo se comporta diante de várias situações.
O mindset fixo, é aquele em que o indivíduo aceita suas próprias habilidades em relação a algum assunto ou situação vivida. Por exemplo: pessoas com esses tipo de mindset aceitam que sua habilidade em alguma área de atuação é fixa, ou seja, ela nasceu com aquela habilidade e ela não pode ser modificada. É como uma espécie de síndrome do dom natural.
Já uma pessoa que possui o mindset construtivo não aceita que suas habilidades não são passíveis de melhoria. Na visão dele(a), só é possível ser bom em alguma coisa através de muito esforço, trabalho e dedicação.
Note a diferença principal nesses dois mindsets. No mindset fixo, a pessoa acha que ela nasce com toda a habilidade que lhe é possível. No mindset construtivo, isso não existe, e as habilidades melhoram na mesma medida em que o individuo se esforça e se dedica a tarefa em questão.

Como o mindset altera o comportamento do indivíduo?

A pessoa que tem o mindset fixo geralmente acham que se alguma tarefa requer esforço, isso significa que ela não é capaz de realizá-la. Isso acontece por que ela acha que como as possuem habilidades são fixas, se algum esforço é necessário para realizar alguma tarefa, isso a faz uma pessoa inferior.
Já a pessoa com um mindset construtivo só tem prazer em realizar alguma tarefa houver um desafio e ela tiver que se esforçar para concluí-la. Há uma constante busca em expandir o conhecimento e habilidades.

Exemplo

Um exemplo muito utilizado no livro sobre o mindset construtivo é o Michael Jordan. Ele só é considerado um dos melhores jogadores de basquete da história, por que ele treinou intensivamente durante muitos anos. E mesmo depois de ter atingido o ápice de sua carreira, ele conseguiu se manter no topo por que ele não diminuiu seu ritmo de treinos.
Há uma frase dele muito famosa que diz:

“Eu perdi mais de 9000 lances em minha carreira. Eu perdi quase 300 jogos. 26 vezes, me foi confiado a jogada da vitória e eu errei. Eu falhei várias e várias vezes na minha vida. E é por isso que eu obtive sucesso.”

No começo de sua carreira, ele foi rejeitado por diversos times por ser considerado baixo demais para praticar o esporte profissionalmente. E isso o motivou a praticar para que ele pudesse atingir seus objetivos. Pessoas com mindset fixo pensariam que os times que o rejeitaram perderam a oportunidade de ter um talento como o dele no time, mas a verdade é que, no começo da carreira, Michael Jordan não era o superstar que ele veio a se tornar.

Como a autora do livro descobriu a teoria dos mindsets?

A autora do livro começou a perceber como o mindset altera o comportamento das pessoas em um experimento com crianças. Nesse experimento, eram dados alguns quebra-cabeças para as crianças resolverem. Esses desafios começavam faceis, e iam ficando mais dificeis conforme eram sendo resolvidos.
As crianças com mindsets fixos se entusiasmavam com os problemas fáceis de resolver, mas conforme o nivel de dificuldade aumentava, e elas se encontravam incapazes de resolve-los, elas rapidamente desistiam e reclamavam que os desafios eram impossíveis de serem resolvidos.
Já as crianças com o mindset construtivo adoravam quando o quebra-cabeça era dificil, pois assim elas teriam um desafio a ser conquistado, e quanto mais dificil o problema, mais elas se esforçavam para resolve-lo.

Ela percebeu também que era relativamente simples deixar as crianças em um estado de mindset fixo ou construtivo. Bastava ter uma abordagem diferente quando a criança conseguia resolver um problema. Se ela quisesse colocar a criança em um mindset fixo, bastava dizer para a criança: “Parabéns, voce realmente é muito inteligente. Voce resolveu esse problema com muita facilidade”. Dizendo isso, ela induzia a criança a começar a achar que realmente ela era especial, e que basta ser inteligente para conseguir resolver o quebra-cabeça. O problema é que, quando a criança se deparava com um desafio dificil, ela começava a questionar as próprias habilidades e inteligencia, e ela passava a duvidar de si mesma e achar que sua inteligencia não é suficiente para resolver o problema.
Porém, ao adotar uma abordagem diferente e dizer para a criança ao resolver um problema “Esse problema foi bem dificil e voce deve ter se esforçado bastante para resolve-lo. Continue assim.”, a criança passava para um mindset diferente. Dessa maneira, a autora bota a criança em um mindset construtivo e ela começa a achar que para resolver os problemas, basta se dedicar que é possível resolver qualquer problema, e ela não irá desistir na primeira dificuldade encontrada.

Conclusão

Se somente através de trabalho arduo e dedicação que se supera os desafios da vida, e é somente mantendo esse mindset que, mesmo ao chegar ao topo, seja da carreira profissional, ou em algum esporte, ou seja lá o que for, que a pessoa se mantém no topo. É bem comum pessoas que, depois do sucesso, acham que não há mais nada a ser feito e algum tempo depois, iniciam sua decadencia.
Tendo isso em mente, pode se dizer que o maior inimigo de uma pessoa é o próprio sucesso. Saber lidar com o sucesso é dificil, e conseguir manter o mindset correto mesmo depois de atingir os objetivos é de extrema importancia. Afinal, qualquer pessoa que é arrogante o suficiente para achar que não há mais nada a aprender, inicia sua própria decadencia.

Written by Breno Ferreira

05/10/2012 at 10:13

Posted in Livro

Tagged with ,

Treinamentos de Windows Azure e Windows Phone 7 no RJ

with 3 comments

Olá pessoal,

Semana passada tive a oportunidade de ministrar treinamentos de Windows Azure e Windows Phone 7 no Rio de Janeiro, com o apoio do Microsoft Innovation Center – Petrópolis. Os treinamentos foram muito bons, e o pessoal gostou bastante.

Porém, como o treinamento foi presencial, muitas pessoas que gostariam de ter participado, não puderam, devido ao número limitado de vagas. Por isso, muitas pessoas me perguntam onde é possível achar material de estudo sobre essas tecnologias. Então vou colocar aqui algumas fontes que utilizei para estudar e aprender sobre esses assuntos:

Windows Azure

Para os interessados em aprender sobre o Windows Azure, recomendo acessar os links abaixo, eles são uma fonte bem valiosa de informação sobre a plataforma.

Learn Windows Azure Event – Channel 9: Esse foi um evento dedicado ao Windows Azure que ocorreu em Dezembro do ano passado, e contou com a presença do Scott Guthrie! Além dele, outras pessoas também do alto escalão da Microsoft estiveram presentes falando sobre a plataforma e apresentando os conceitos básicos. No total, são 29 vídeos sobre diversos assuntos, apresentando conceitos e demos sobre assuntos como Table Storage, Blobs, Service Bus, Access Control Services, Node.JS, Worker Roles, entre outros. Falaram até sobre Hadoop e Big Data.

Windows Azure Boot Camp: O treinamento foi feito nos moldes desse BootCamp, que é apresentado nos US e em outros lugares no mundo. E o portal possui os PPTs e os vídeos que são dados aos trainers que apresentão o BootCamp, numa espécie de Train-The-Trainer (TTT).

Windows Azure Training Kit: Esse Training Kit possui diversas Demos e Hands-On-Labs que permitem que voce pratique e desenvolva algumas aplicações para o Windows Azure. Possui o passo-a-passo de como executar as tarefas e é bem bacana para colocar na prática alguns dos conceitos aprendidos assistindo os videos acima.

O código de algumas das demos que eu apresentei no treinamento estão no GitHub, para voce poder ver a implementação de algumas features e recursos do Windows Azure.

Windows Phone 7

Windows Phone 7 DevCamp: Esse foi um DevCamp gravado na Nokia da Dinamarca e apresenta alguns conceios básicos sobre Windows Phone 7.

Silverlight.Net: Como o framework utilizado para desenvolver aplicações para Windows Phone é o Silverlight, eu recomendo fortemente que voce aprenda primeiro os conceitos básicos de Silverlight, como XAML, controles, Styles, MVVM entre outros. Assim voce irá entender melhor a plataforma e poderá desenvolver aplicações de maneira mais eficiente.

Windows Phone Training Kit: Training Kit nos mesmos moldes do Training Kit do Azure, com demos e labs para voce praticar.

Novamente, o código das demos apresentadas no treinamento estão no Github.

Todos os links que eu coloquei aqui estão em inglês. Caso o idioma seja um impecílio para voce, recomendo utilizar o Microsoft Virtual Academy, lá tem treinamentos em pt-BR, e o pessoal que produziu o conteúdo também são muito bons.

Abraços

Breno

Written by Breno Ferreira

02/04/2012 at 12:27

Posted in Treinamento

Tagged with , ,

Handwriting Recognition com HTML5 Canvas

leave a comment »

Olá pessoal,

Uma das grandes novidades do HTML5 é o elemento Canvas. Ele permite que uma determinada area da página seja utilizada para desenhar, renderizar imagens e gráficos. Algumas aplicações bem legais do elemento Canvas são o SketchPad, Cloth Simulation, e até jogos são possíveis. Se voce ainda não conhece como utilizar as APIs do Canvas, recomendo ir ao Mozilla Developer Network e ver como acessar as funcionalidades básicas.

Um uso bacana que pensei foi a possibilidade de fazer o reconhecimento de escrita utilizando o elemento Canvas. Isso seria bastante útil em dispositivos móveis com telas touch-screen como tablets e smartphones.

Como fazer?

Para fazermos o reconhecimento da escrita precisamos fazer duas coisas: guarder os dados de input do usuário, conforme ele vai “escrevendo”, em seguida, mandar esses dados para o servidor para realizar o processo de reconhecimento da escrita.

 Client-Side

Primeiramente definimos o elemento Canvas, e um botão que, quando clicado, irá enviar os dados para o servidor.

<canvas id="myCanvas"></canvas>

<button id="submitBtn">Submit</button>

Depois, definimos um objeto que irá ser responsável por desenhar os traços na tela.

board = {
    isDrawing: false,
    surface: null,

    setup: function () {
        var myCanvas = document.getElementById('myCanvas')
        myCanvas.width = window.innerWidth - 25;
        myCanvas.height = window.innerHeight - 25;
        this.surface = myCanvas.getContext('2d');
        this.surface.lineWidth = 5;
        this.surface.strokeStyle = '#0000ff';
    },

    beginDraw: function (x, y) {
        this.surface.beginPath();
        this.surface.moveTo(x, y);

        this.isDrawing = true;
    },

    draw: function (x, y) {
        this.surface.lineTo(x, y);
        this.surface.stroke();
    },

    endDraw: function () {
        this.isDrawing = false;
    }
};

Primeiramente, no método Setup() definimos algumas propriedades básicas do Canvas como altura e largura na tela, tamanho do traço a ser desenhado e sua cor, e guardamos uma referência para a superficie de desenho, chamando o método getContext(’2d’).

Em seguida, temos as funções beginDraw(x, y), draw(x, y) e endDraw(). Essas funções serão chamadas quando o usuário começar a escrever alguma coisa, enquanto ele estiver escrevendo, e quando ele terminar de escrever, respectivamente. Os métodos são bem simples, na função beginDraw, desloco o contexto de desenho para o ponto XY onde o usuário começou a escrever e seto um flag indicando que o usuário está escrevendo. Na função draw, traço uma linha até o ponto XY, e no método endDraw, simplesmente seto o flag para false, indicando que o usuário terminou de escrever.

Em seguida, associamos os eventos de input do usuário e chamamos as funções do objeto definido acima.

var strokesHistory = {
    Strokes: []
};

var currentStroke = {
    Points: []
};

board.setup();

var myCanvas = document.getElementById('myCanvas');

myCanvas.onmousedown = myCanvas.ontouchstart = function (e) {
    var xy = getInputCoordinates(e);

    currentStroke.Points.push({ X: xy.x, Y: xy.y });

    board.beginDraw(xy.x, xy.y);
};

myCanvas.onmousemove = myCanvas.ontouchmove = function (e) {
    if (board.isDrawing === true) {
        var xy = getInputCoordinates(e);

        currentStroke.Points.push({ X: xy.x, Y: xy.y });
        board.draw(xy.x, xy.y);
    }
};

myCanvas.onmouseup = myCanvas.ontouchend = function (e) {
    strokesHistory.Strokes.push(currentStroke);
    currentStroke = { Points: [] };
    board.endDraw();
};

function getInputCoordinates(e) {
    var x, y;

    if (e.changedTouches) {
        var touchData = e.changedTouches[0];
        x = touchData.clientX;
        y = touchData.clientY;
        e.preventDefault();
    }
    else {
        x = e.clientX;
        y = e.clientY;
    }

    return { x: x, y: y };
}

Repare que definimos callbacks para ambos os eventos do mouse e também para os de touch. Também criamos um objeto, strokesHistory, que guardará os dados de input (coordenadas X e Y dos traços) do usuário, assim, podemos enviar os dados para o servidor depois. Por fim, criamos uma função, getInputCoordinates(e), que retorna a coordenada XY de onde o usuário está escrevendo. A partir desse momento, o usuário já consegue escrever livremente com o elemento Canvas.

Por fim, quando o usuário clicar no botão, iremos enviar os dados via POST para o servidor, formatados como JSON. Note que iremos simplesmente exibir um alert com o resultado do reconhecimento.

$('#submitBtn').click(function () {
    $.post('/api/recognition/recognize',
            { strokes: JSON.stringify(strokesHistory)},
            function (result) {
                alert(result);
            });
});

Server-Side

No lado do servidor, iremos criar uma WebAPI, novo recurso do ASP.NET MVC 4. Caso voce ainda não conheça como funciona essa nova feature, o Elemar Jr. tem um post no seu blog explicando bem sucintamente o que é o ASP.NET WebAPI e como funciona.

Iremos chamar nosso Controller de RecognitionController, e nele teremos uma Action que aceita o verbo POST.

public class RecognitionController : ApiController
{
    [HttpPost]
    public HttpResponseMessage<String> Recognize(string strokes)
    {
        var strokePointsData = JsonConvert.DeserializeObject<dynamic>(strokes);

        var strokeCollection = GetStrokeCollectionFromPoints(strokePointsData);

        var inkAnalyzer = new InkAnalyzer();

        inkAnalyzer.AddStrokes(strokeCollection);

        var analysisStatus = inkAnalyzer.Analyze();

        if (analysisStatus.Successful)
        {
            var recognizedString = inkAnalyzer.GetRecognizedString();
            return new HttpResponseMessage<string>(recognizedString);
        }
        else
            return new HttpResponseMessage<string>("Data not recognized");
    }
}

O processo de reconhecimento é bem simples. Utilizamos uma API do Windows Presentation Foundation (WPF) chamada InkAnalyser, que, dado como input dados (coordenadas) de traços escritos pelo usuário, ela devolve uma String reconhecida no processo de análise. Porém, como estamos enviando os dados formatados como JSON, precisamos converter para uma estrutura de dados requerida pelo InkAnalyser. O método abaixo irá converter os dados deserializados do JSON para um objeto do tipo StrokeCollection.

private StrokeCollection GetStrokeCollectionFromPoints(dynamic strokePoints)
{
    var strokeCollection = new StrokeCollection();

    foreach (var stroke in strokePoints.Strokes)
    {
        var points = new StylusPointCollection();

        foreach (var point in stroke.Points)
        {
            var x = (float)point.X;
            var y = (float)point.Y;

            points.Add(new StylusPoint(x, y));
        }

        strokeCollection.Add(new Stroke(points));
    }

    return strokeCollection;
}

Agora se executarmos a aplicação, poderemos escrever alguma palavra no canvas (seja com o mouse, ou em algum dispositivo touch-screen), e clicarmos no botão no canto inferior esquerdo e esperar o resultado do reconhecimento.

 

O código dessa aplicação está no Github.

Abraços

Breno

Written by Breno Ferreira

14/03/2012 at 20:01

Primeiros passos com NodeJS

leave a comment »

Olá pessoal.

Hoje irei falar sobre um assunto um pouco diferente do que costumo escrever por aqui. Não é um assunto relacionado (nem tanto) ao mundo Microsoft. Irei falar hoje sobre uma tecnologia que tem gerado um “buzz” bem grande recentemente e que vem chamando a atenção de muitos desenvolvedores. Trata-se de Node.JS, ou simplesmente Node.

O que é Node.JS

Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. (Fonte: http://nodejs.org/).

Duas coisas na descrição chamam a atenção:

Built on Chrome’s JS Engine (V8): Node permite que aplicações que rodem no server-side sejam construidas utilizando como linguagem o Javascript. Isso mesmo, Javascript. Isso é possível por que o Node interpreta seu código utilizando a engine de Javascript criada pelo Google, o V8. Talvez voce pense que Javascript é uma linguagem exclusiva para o mundo client-side, rodando em páginas web dentro do browser, mas com Node, suas habilidades adquiridas escrevendo código no lado do cliente poderão ser usadas no lado do servidor (a não ser que a única coisa que voce faz é amarrar eventos e Ajax simples via Jquery).

Fast e Scalable: A fundamental diferença entre Node e outros web-frameworks (além da linguagem, é claro), é que Node utiliza uma outra forma de tratar requests que chegam ao servidor. Frameworks como RubyOnRails, ASP.NET MVC, PHP (Zend, Cake, etc.), Django e outros, rodam sobre um WebServer, como Apache ou o IIS. E esses webservers utilizam Threads para tratar os requests. Então, para cada request que chega, o servidor aloca uma Thread (geralmente de uma ThreadPool) para tratar aquele request. Enquanto o processamento daquele request não terminar, aquela Thread fica “travada”, não podendo responder a outros requests. Por exemplo, muitas aplicações web implementam o que chamamos de Request-Database-Response, ou seja, um request chega, procuramos alguma informação no banco de dados e retornamos uma resposta pro cliente. Porém, o gargalo dessa execução está justamente na espera pelo banco de dados responder com as informações requeridas. Enquanto o BD não retorna, a Thread alocada ficará travada.

O Node por sua vez, utiliza um outra maneira de tratar requisições. Ele utiliza um recurso chamado Evented IO, que não faz uso de Threads, mas sim de uma pilha de eventos que são executados. Isso funciona da seguinte maneira: quando uma requisição chega ao servidor, o framework começa a tratar a requisição. A partir do momento que alguma operação de IO (seja para fazer alguma query no banco de dados, ler um arquivo, etc.) é executada, ela é executada de maneira assíncrona, e um evento (ou callback) é registrado. Enquanto essa operação de IO está executando, o processo do Node volta a ser capaz de continuar tratando outras requisições, resultando no que chamamos de Non-Blocking-IO. Quando a operação de IO anterior terminar, o callback registrado é colocado na pilha de execução e quando chegar sua vez, ele será executado, continuando a execução do request anterior, podendo assim, devolver uma resposta para o cliente. Em código, seria algo parecido com isso:

function EventLoop(){
	while (true){
		var callback = executionStack.Pop();
		callback();
	}
}

//called whenever an async IO operation is performed
function PushToExecutionStack(callback){
	executionStack.Push(callback);
}

Esse é o ingrediente fundamental que possibilita que aplicações escritas com Node sejam rápidas e escaláveis. Como o servidor nunca fica bloqueado esperando uma requisição terminar, ele pode servir milhares de requisições.

Mas por que Javascript?

Javascript é uma das poucas linguagens que, naturalmente, não oferece um modelo de programação síncrono. O conceito de callback é algo tão natural em Javascript, e todos estão tão acostumados a esse modelo de programação (ninguém faz AJAX de maneira síncrona, certo?) com essa linguagem, que Javascript é uma linguagem muito apropriada a esse modelo de programação orientado a eventos.

Exemplo

Abaixo temos um exemplo que cria um servidor que escuta na porta 8080 e que quando uma requisição chega, retorna o conteúdo do arquivo index.html.

var http = require('http');
var fileSystem = require('fs');

var server = http.createServer(function(req, resp){
	fileSystem.readFile('./index.html', function(error, fileContent){
		if(error){
			resp.writeHead(500, {'Content-Type': 'text/plain'});
			resp.end('Error');
		}
		else{
			resp.writeHead(200, {'Content-Type': 'text/html'});
			resp.write(fileContent);
			resp.end();
		}
	});
});

server.listen(8080);

console.log('Listening at: localhost:8080');

Primeiramente, chamamos a função require(‘http’) que carrega o módulo HTTP do Node. Com esse módulo, podemos chamar a função createServer, que recebe como parâmetro um callback, que será chamado toda vez que um request chegar para ser executado. A função de callback tem dois parâmetros, request e response. O parâmetro request possui os dados sobre o request, como headers, querystrings, content, etc.. O parâmetro response pode ser usado para enviar uma resposta para o cliente.

Na função responsável por tratar os requests, utilizamos a API do FileSystem para lermos o conteúdo do arquivo index.html, e novamente, passamos um callback que será chamado quando a leitura do arquivo terminar, e esse callback será chamado, devolvendo o conteúdo do arquivo, ou um erro, caso algum tenha ocorrido. Enfim, retornaremos uma resposta ao cliente, seja ela uma mensagem de erro, ou o conteúdo do arquivo. Fazemos isso chamando o método writeHead e write do objeto response. O método writeHead escreve um Header, nesse caso, passamos o Status-Code de 200 ou 500 e Content-Type sendo text/plain. O método write escreve o conteúdo da resposta, nesse caso o conteúdo do arquivo index.html

Note que, enquanto a leitura do arquivo está sendo feita, o processo do Node é capaz de continuar tratando outras requisições que chegarem.

Para executar essa aplicação, salve o código com algum nome, por exemplo “server.js”, e rode o seguinte comando no Terminal: node server.js. O código completo voce pode ver aqui. Não esqueça de criar o arquivo index.html com algum HTML de exemplo.

Era isso pessoal, até a próxima.

Breno

Written by Breno Ferreira

27/02/2012 at 14:00

Posted in Node.JS

Tagged with ,

Async no C# 5–Advanced

leave a comment »

Olá pessoal, tudo bem?

Há algum tempo atrás, eu postei aqui no blog sobre assincronia no C# 5. Hoje irei continuar falando sobre o assunto, porém, irei abordar alguns conceitos um pouco mais avançados para que voce consiga entender melhor como as coisas funcionam e tirar melhor proveito dessa nova funcionalidade da linguagem.

Under the Covers

Acho que sempre é bom saber o que acontece por debaixo dos panos, então, quando abri o código que o compilador do C# gera quando utilizamos o await, vi o seguinte trecho de código:

Esse código:

var webClient = new WebClient();
var html = await webClient.DownloadStringTaskAsync("http://www.bing.com");
return html;

Vira este código:

private struct <DownloadBingHomePageHTMLAsync>d__3 : <>t__IStateMachine
{
	private int <>1__state;
	public AsyncTaskMethodBuilder<string> <>t__builder;
	public Action <>t__MoveNextDelegate;
	public WebClient <webClient>5__4;
	public string <html>5__5;
	private object <>t__stack;
	private object <>t__awaiter;
	public void MoveNext()
	{
		string result;
		try
		{
			int num = this.<>1__state;
			TaskAwaiter<string> taskAwaiter;
			if (num != 1) //if execution of async method is not finished (State == 1 means that the execution is running)
			{
				if (this.<>1__state == -1)
				{
					return;
				}
				this.<webClient>5__4 = new WebClient();
				taskAwaiter = this.<webClient>5__4.DownloadStringTaskAsync("http://www.bing.com").GetAwaiter(); //start the async operation, and get the TaskAwaiter
				if (!taskAwaiter.IsCompleted) //if the async operation is not completed
				{
					this.<>1__state = 1; //set the state to "Running"
					TaskAwaiter<string>[] array;
					(array = new TaskAwaiter<string>[1])[0] = taskAwaiter;
					this.<>t__awaiter = array;
					Action action;
					if ((action = this.<>t__MoveNextDelegate) == null)
					{
						Task<string> arg_9A_0 = this.<>t__builder.Task;
						action = new Action(this.MoveNext); //define a delegate to the method itself.
						((<>t__IStateMachine)action.Target).<>t__SetMoveNextDelegate(action);
					}
					array[0].OnCompleted(action); //use that delegate (which points to the method itself) as a method which will be called when the async operation completes
					return;
				}
			}
			else //if the async is complete
			{
				taskAwaiter = ((TaskAwaiter<string>[])this.<>t__awaiter)[0]; //get the TaskAwaiter
				this.<>t__awaiter = null;
				this.<>1__state = 0; //set the state to "Initial"
			}
			string arg_110_0 = taskAwaiter.GetResult(); //get the result of the async operation from the TaskAwaiter
			taskAwaiter = default(TaskAwaiter<string>);
			string text = arg_110_0; //continue with the execution of the code that was defined after the "await" keyword (in this case, return the html as a String)
			this.<html>5__5 = text;
			result = this.<html>5__5;
		}
		catch (Exception exception)
		{
			this.<>1__state = -1;
			this.<>t__builder.SetException(exception);
			return;
		}
		this.<>1__state = -1; //set the result to "Complete"
		this.<>t__builder.SetResult(result);
	}
	[DebuggerHidden]
	void <>t__IStateMachine.<>t__SetMoveNextDelegate(Action param0)
	{
		this.<>t__MoveNextDelegate = param0;
	}
}

É um trecho de código bem extenso, como voce pode ver. Adicionei alguns comentários para que voce possa entender melhor, mas irei explicar melhor o que acontece.
Para cada await que adicionamos ao nosso código, o compilador cria uma estrutura de máquina de estados, responsável por coordenar a operação assíncrona e dar continuidade a execução do código.

Dentro da estrutura, há um método chamado MoveNext que possui toda a lógica. Basicamente ele é chamado quando há uma keyword await. Quando este método é chamado, ele verifica se a operação assíncrona já foi iniciada. Como ainda não foi, ele inicia a execução assíncrona, e então seta o estado para “Running“. Então ele guarda uma referencia para um Awaiter que será usado para definir um callback que será chamado quando a operação assíncrona terminar. Esse callback é definido para a própria função (MoveNext). Quando a operação termina, o método MoveNext() é novamente chamado, mas dessa vez ele verifica que o estado é “Running”, então com a referencia para o Awaiter ele pega o resultado retornado pela operação assíncrona e continua com a execução do código.

Tasks & Threads

Outro conceito bem importante de saber ao usar Tasks e Async é que essas Tasks não adicionam Threads adicionais. Ou seja, voce não precisa se preocupar com acesso concorrente, locks entre outros problemas inerentes a programação paralela. É claro que a operação assíncrona poderá ser executada em uma Thread separada (caso contrário é quase impossível executar um código de maneira assíncrona), mas nenhuma Thread extra será criada. O async e await são simplesmente syntax-sugars para callbacks. Podemos ver isso no código a seguir:

private Task<String> DownloadStringAsync(string uri)
{
    var webclient = new WebClient();

    var downloadTaskCompletionSource = new TaskCompletionSource<String>();
    var downloadTask = downloadTaskCompletionSource.Task;

    webclient.DownloadStringCompleted += (sender, e) =>
        {
            downloadTaskCompletionSource.SetResult(e.Result);
        };

    webclient.DownloadStringAsync( new Uri(uri));
    return downloadTask;
}

string str = await DownloadStringAsync("http://www.google.com");

No código acima, utilizamos a classe TaskCompletionSource, que pode ser usada para devolver uma Task associada à uma operação assíncrona. Neste caso, a Task será usada simplesmente para representar a operação assíncrona e dar ao usuário o poder de setar Continuations. Não há nenhuma Thread adicional envolvida.

UI, Libs & Synchronization Contexts

Quando escrevemos código assíncrono antigamente, as vezes tínhamos que nos preocupar com execução de código em Threads apropriadas. Por exemplo: quando executamos método assíncrono na camada de apresentação, por exemplo em Silverlight, WPF, etc., quando o callback do método assíncrono era chamado para tratarmos o resultado, precisávamos trocar o contexto das Threads caso fosse necessário fazer alguma atualização na interface. Para fazermos isso, era utilizado um SynchronizationContext (em Silverlight ou WPF era mais conhecido pela propriedade Dispatcher) que era responsável por enfileirar um delegate para execução na UI Thread (Thread responsável por renderizar os elementos de interface e tratar qualquer interação com o usuário).

Por padrão, quando utilizamos a keyword await, esse processo de troca de contexto de Threads é feito de maneira automática, ou seja, quando a operação assíncrona terminar, ele automaticamente utiliza o SynchroniationContext padrão para voltar para a Thread ideal. Isso é muito bom quando estamos desenvolvendo nossas aplicações que possuem algum tipo de UI (User Interface), como na maioria dos casos. Mas se estivermos desenvolvendo alguma biblioteca reutilizável, esse comportamento pode não ser o mais apropriado. Primeiro que essa troca de contexto tem um custo de performance que pode não ser apropriado, segundo que seu uso pode vir a ter alguns efeitos colaterais indesejados. Imagine o seguinte:

async Task AsyncOp()
{
	Task.Delay(1000); //simulate asynchronous operation
}

var task = AsyncOp();
task.Wait();

Esse código irá causar um deadlock. Porque? Acontece que quando chamamos o método Wait() de uma Task, ele bloqueia a Thread até a operação da Task terminar. Mas quando a operação assíncrona terminar e ele passar pelo await, ele vai tentar voltar para a UI Thread, que vai estar bloqueada, então temos um deadlock.
Para isso não acontecer, basta chamarmos o método ConfigureAwait(Boolean continueOnCapturedContext) da Task, e passarmos o valor false. Assim, ele irá continuar a execução da operação assíncrona na mesma Thread, sem troca de contexto.

async Task AsyncOp()
{
	Task.Delay(1000).ConfigureAwait(false); //simulate asynchronous operation
}

var task = AsyncOp();
task.Wait();

Bem, era isso pessoal. Até a próxima ;)

Written by Breno Ferreira

03/01/2012 at 20:48

Posted in C#

Tagged with ,

Unit Test Framework para Windows Phone 7 Mango

with 3 comments

Olá pessoal,

Recentemente comecei a desenvolver uma aplicação para Windows Phone 7 e, como uma boa pessoa, comecei a escrever testes. Mas, quando fui rodar os teste, descobri que o MSTest, framework de testes da Microsoft que vem nativamente no Visual Studio, não suporta código feito para o Window Phone 7.

Então comecei a caçar algum framework na internet, e achei esse do Jeff Wilcox. Ele foi feito, originalmente para Silverlight, mas também possui suporte para Windows Phone 7, inclusive para o SDK novo do Mango.

Para utilizá-lo é bem simples, basta fazer o download dos bits aqui. Depois de baixado o framework, crie no Visual Studio uma “Windows Phone Application” e referencie as duas dlls abaixo:

Silverlight Unit Test Framework DLLs

Depois disso, no arquivo MainPage.xaml.cs do projeto de teste, adicione o seguinte trecho de código:

public MainPage()
{
	InitializeComponent();

	this.Loaded += (sender, e) => SetupTestUI();
}

private void SetupTestUI()
{
	var testPage = UnitTestSystem.CreateTestPage() as IMobileTestPage;
	BackKeyPress += (x, xe) => xe.Cancel = testPage.NavigateBack();
	(Application.Current.RootVisual as PhoneApplicationFrame).Content = testPage;
}

Agora é só começar a escrever seues testes!

[TestClass]
public class AdditionTests
{
	[TestMethod]
	public void TwoPlusTwoEqualsFour()
	{
		var result = 2 + 2;
		var expected = 4;
		Assert.AreEqual(expected, result);
	}

	[TestMethod]
	public void FivePlusFiveEqualsTen() //example of a failing test
	{
		var result = 5 + 4;
		var expected = 10;

		Assert.AreEqual(expected, result);
	}
}

Para rodar os testes, recomendo executar o projeto sem o debugger attachado (Ctrl+F5), pois toda vez que um Assert falhar, ele irá lançar uma “AssertFailedException”, fazendo com que o debugger do Visual Studio pare a execução e exiba os detalhes da exception lançada, conforme a imagem abaixo.

Após executar os testes, ele irá mostrar os resultados, dizendo quais teste passaram, e quais falharam. Basta clicar nos links que ele irá mostrar detalhes maiores sobre cada item, até chegar em uma visão detalhada sobre um teste em particular.

Como vimos, é bem simples escrever e executar testes para aplicações Silverlight no Windows Phone 7. Está longe do ideal, pois ao rodar os testes quando o emulador do WP7 está fechado, demora um pouco para vermos o resultado. Mas com o emulador já aberto, conseguimos visualizar os resultados bem rapidamente.

Abraços

Breno

Written by Breno Ferreira

06/12/2011 at 09:19

Posted in WP7

Tagged with , ,

Follow

Get every new post delivered to your Inbox.