30 Jan
Esses dias, quando estava instalando o plugin do Remember The Milk, eu notei uma coisa interessante. O site de busca do Google mostra o número de vezes que você clicou em um determinado link e a data do último clique.

Isso só funciona se você estiver logado, mas é bastante perturbador.
Não é por causa de questões de privacidade (não quer que o Google receba informações sobre onde você clica? não fique logado o tempo inteiro). É mais por questões computacionais.
Eu sei que o Google talvez possua a maior capacidade computacional do mundo. Muitos programadores muito bons trabalham na Google. Mas isso já é demais.
Para manter essa informação, ou ela está armazenada no cliente ou no servidor. Se estivesse no cliente (e fosse apenas para nos mostrar algo bonitinho no site) bastaria que você entrasse no site de busca de duas máquinas diferentes e o número de cliques não bateria. Não e isso que acontece. E o número de cliques inclusive influencia a ordem em que os sites estão listados. A primeira vez que acessei o remember the milk, ele era o terceiro na lista. Hoje é o primeiro.
Ou seja, a informação está no servidor. A Google guarda cada clique que damos no site. Mas como? Existem milhões de contas no google. Sei lá quantas buscas diárias a Google responde, mas só eu faço pelo menos 100 (se não tiver muito o que fazer no dia). Como você faz com que isso que parece apenas uma bobeira (mas na verdade é informação vital para o sistema de busca deles) seja escalável?
Eles têm que guardar isso em disco. Quantos sites eu já acessei hoje? Tudo guardado. No modelo mais minimalístico que consigo pensar, associado a minha conta existe algo que guarda a busca que fiz, o site que acessei, o número de vezes que acessei e a data do último acesso. Pode parecer pouco, mas quando você multiplica o acesso disso por N (para valores bem grandes de N) é algo absurdo.
É algo pra deixar qualquer um louco (ainda mais eu que adoro fazer otimizações de baixo nível).
Já estou melhor depois desse desabafo. Mas ainda assusta.
Posts Relacionados:
Assine nosso RSS feed!
23 Jan

Quem gosta de computação e pretende fazer um curso de graduação na área normalmente não sabe exatamente qual curso da área fazer. São muitas opções: ciência da computação, engenharia da computação, sistemas de informação, análise de sistemas… muitas opções mesmo!
Pois bem. Andei pesquisando sobre a abrangência de cada curso e faço o seguinte resumo:
Para tomar essa decisão, olhe com atenção as grades curriculares de cada curso. Essa grade também varia entre as faculdades, então olhe a grade das faculdades nas que você pretende fazer o curso. Dê uma olhada também nesses links:
Principalmente no segundo, que tem um comparativo mais detalhado entre esses cursos.
Veja a Wikipédia, também! Lá tem artigos para cada uma dessas áreas, com uma descrição bem precisa do que a cada uma se refere.
Posts Relacionados:
Assine nosso RSS feed!
21 Jan
Essa é mais uma feature que o Google possui que está acelerando o processo de calvicie em mim.
Todo mundo conhece o orkut. Aquele sistema bobo, sem muita utilidade concreta mas que faz um sucesso absurdo (Inclusive, existe uma comunidade do VidaGeek.net lá).
O que muitos não notam é um pequeno detalhe que aparece quando você está no perfil de outra pessoa. O Orkut mostra pra você o caminho mais curto entre você e essa outra pessoa (atravéz de amigos).

O que que isso tem de assustador? É apenas uma busca em um grafo… Com milhões de vértices. Faça um programa simples que faz uma busca em um grafo com milhões de vértices e você vai entender do que estou falando. Demora muito mais do que uma requisição no Orkut pode demorar.
Ou seja, tudo isso está pré-calculado. Quando você acessa o perfil de outra pessoa, o algoritmo já rodou e ele simplesmente recupera a informação e devolve para você.
O jeito mais simples de fazer isso? Um Floyd-Warshall modificado (para não levar o peso das arestas em consideração), com complexidade O(n^3) rodado quando algum usuário se cadastra no Orkut ou sai dele.
Isso não funciona. Com a quantidade de usuários que o orkut tem, ele teria saido do ar há muito tempo se fosse desse jeito. Uma estratégia lazy (rodar apenas de tempos em tempos) também não ajuda muito, pois ocupa muito espaço em disco (quando o orkut foi criado, ele manteve vários milhares de usuário apenas com um computador comum como servidor).
O que é mais possível, então? Uma boa Heurística. Hoje mesmo eu notei que têm alguns profiles que eu entro e não aparece a sequência de usuários. Portanto, o que deve ser feito é estabelecer um limite na profundidade da busca, baseado nos seus amigos e nas comunidades em que você participa. Isso reduz de milhões de usuários para milhares de usuários. Mesmo assim ainda acho que é um esforço computacional muito grande e provavelmente deve ser rodado de forma lazy (especialmente se você lembrar que já está sendo usada uma heurística e nem sempre vai aparecer o caminho).
Posts Relacionados:
Assine nosso RSS feed!
18 Jan
Quando estamos programando, é muito comum precisarmos de um tipo booleano. Infelizmente o padrão Ansi C (isoc89) não possui um tipo primitivo para representar verdadeiro ou falso.
Qual a solução? Dentre várias, uma das mais perigosas e mais comum é essa:
typedef int bool;
#define TRUE 1
#define FALSE 0
Primeiro, como ela funciona:
Em C, como não existe boolean, qualquer inteiro diferente de 0 é considerado como verdadeiro e 0 é considerado falso. Portanto, nada mais lógico que pegar 0 e definir como falso e um outro número qualquer e definir como verdadeiro.
Qual o problema? Em 95% das aplicações que você normalmente faz, isso é uma solução perfeita, porque você sempre usa os operadores booleanos que encerram em curto-circuito (&& e ||).
A coisa muda totalmente de figura quando você usa os operadores bitwise (&, | e ^) para gerar condições booleanas. Isso é comum quando estamos usando funções que possuem efeitos colaterais (isso não é considerado uma prática muito boa, mas tem muita gente que usa isso ainda).
Imagine que você está usando uma função sua que produz efeitos colaterais e uma de uma biblioteca qualquer que também têm efeitos colaterais. As duas devolvem um inteiro diferente de 0 se bem sucedidas.
Como você é uma pessoa disciplinada, para garantir a consistência do seu sistema, quando você quer valores booleanos, você só atribui TRUE ou FALSE.
Se o código for esse, sem problemas:
if (sua_funcao() && funcao_da_lib())
faz_algo();
Mas isso é ruim, pois você precisa que as duas funções sejam executadas (mesmo se a sua falhar). O que você faz?
if (sua_funcao() & funcao_da_lib())
faz_algo();
Arranca um & de lá e passa 20 horas debuggando. Porquê? Simples. Por algum motivo estranho, o cara que escreveu a biblioteca que você está usando resolveu devolver 2 como verdadeiro. Olha que legal que fica se você substitui os valores devolvidos (em caso de sucesso) no lugar das funções:
if (1 & 2)
faz_algo();
Como dois não é impar, a função faz_algo() não será executada (causando uma grande dor de cabeça em você).
Mesmo você sendo o programador mais disciplinado da face da terra, não dá pra evitar problemas assim. Não dá pra ter controle sobre o código dos outros.
Para evitar esse tipo de problemas, eu costumo definir minhas constantes assim:
#include <limits.h>
typedef unsigned int bool;
#define TRUE UINT_MAX
#define FALSE 0
Isso protege contra todos os problemas? Não. Mas evita alguns que podem dar muita dor de cabeça. Isso porque tendo todos os bits setados como 1, quando usar o operador bitwise & ele só vai dar false se o outro valor não possuir nenhum bit setado para 1 (que é exatamente o que queremos).
Mas ainda bem que no padrão isoc99 existe o tipo bool. Vai evitar muitos problemas. Mas até ele ser realmente adotado ainda vai algum tempo.
Posts Relacionados:
Assine nosso RSS feed!