Mostrando postagens com marcador Programação. Mostrar todas as postagens
Mostrando postagens com marcador Programação. Mostrar todas as postagens

Como o SEO aumenta o ROI de links patrocinados

Atualmente, o marketing de busca é divido em duas frentes: SEO e Links Patrocinados. Mas a dúvida da maioria dos anunciantes é: se estou investindo em Links Patrocinados, por que preciso investir na otimização do meu site para as buscas orgânicas (SEO)?
Tela do Google mostrando os espaços correspondentes aos links patrocinados e à busca orgânica
Para responder a essa questão, primeiro vamos entender a importância e a composição do “coração” dos Links Patrocinados do Google, o Índice de Qualidade (Quality Score), que permite aos anunciantes pagarem um menor valor e conseguir posições melhores.

Não use jQuery! Não aprenda qualquer framework antes de...

...conhecer o mínimo da linguagem base em que esse framework foi escrito! E por isso que existem tantos desenvolvedores se enrolando... Tentam usar bibliotecas, frameworks e ajax antes de aprender o básico.

Aprender CodeIgniter, Kohana, CakePHP, Smarty…antes de aprender PHP é loucura! Ninguém faz curso de Zend Framework sem nunca ter programado PHP. Primeiro se aprende PHP e depois vai para um framework. Então, por que inverter os papeis com JavaScript?

Ok, a curva de aprendizado do jQuery, assim como dos demais frameworks, é menor, e se aparecer um problema?

Aí, aquele desenvolvedor que optou por começar com o framwork sem antes passar pela linguagem base começa a ter dúvidas básicas de programação. O framework não resolve tudo para ele. Só vai facilitar o trabalho se ele não se enrolar com os conceitos fundamentais.

Há gente pedindo plugin jQuery para descobrir o que está na URL. Ele não queria e nem precisava fazer um parser da querystring, só precisava saber o que estava lá. Não sabia da existência do document.location e das diversas propriedades desse objeto.

Outro programador não queria usar o document.createElement(), ele insistia em querer fazer com jQuery! OK, existe plugin pra isso, mas para quê? O método nativo da linguagem já é tão bom! Ao framework o que é do framework. Ficar inchando a página de plugins só vai aumentar o tráfego. Usar plugins e frameworks onde não é necessário só vai deixar a aplicação mais lenta!

Um outro caso: respondi uma dúvida de um desenvolvedor que era super simples, usando apenas JavaScript e eram três ou quatro linhas de código. Ele testou, disse que funcionou, e depois pediu para ver como ficaria aquilo em jQuery. Era idiota reescrever 4 linhas de JavaScript usando o framework e nem dava! Percebi que ele pensava: "JavaScript estava ultrapassado e ele pretendia fazer da forma moderna."

O mesmo ocorreu com AJAX: a dúvida estava resolvida, e o cara pediu para ver como ficaria em AJAX! E era tudo apenas JavaScript puro, não havia o menor motivo para ir no servidor e voltar. Nesse momento, começa a surgir uma confusão de papeis. Gente achando que AJAX é uma linguagem, que precisa enfiar jQuery em tudo...

Já vi tópico começar "sobre AJAX" e terminar apenas com PHP puro! O cara queria colocar uma requisição assíncrona onde não precisava. Completa inversão de valores e pura falta de conhecimento, certo?

É imprescindível aos desenvolvedores começarem a aprender linguagens server-side depois de terem algum contato com HTML. Precisamos de HTML para programar para a Web, é a linguagem padrão, que vai possibilitar todo o resto. O PHP, ASP, Java e afins, vai gerar HTML, mais cedo ou mais tarde.

Eis que começam a surgir dúvidas bobas. O programador vai fazer uma listagem de produtos para uma loja virtual e não sabe como colocar um produto do lado do outro. Isso é porque ele não sabe HTML, muito menos CSS! Sem entrar no mérito da divisão de trabalho, FrontEnd, BackEnd e outros mais, ao menos, um pouco da linguagem do outro, era bacana.

Em agências pequenas, ou como freelancer, muitas vezes acontece de o mesmo profissional fazer ambos trabalhos, Front ou BackEnd. Alguns passos são importantes e devem ser respeitados. Comece do básico, evolua, só depois vá para o hardcore!

Antes de tudo, você recebe aulas de Lógica de Programação e Programação Básica, certo? Deveria ser assim, mas assusta ver a quantidade de programadores que tem no mercado que não possuem essa base na formação.

Todo programador deveria obrigatoriamente estudar alguma linguagem de programação de baixo nível. Alguns programadores não conhecem as diferenças ou nem sabem que existem!

O conhecimento adquirido ao fazer algo em Assembly, por exemplo, é extraordinário. Se todos passassem por essa experiência, não teríamos tanto lixo sendo criado. Não precisa se tornar sênior, nem ser ótimo em HTML e CSS, nem defender tese de mestrado em lógica. Mas coisas como tipagem, declaração de variáveis, coletor de lixo e escopo... que faltam em vários programadores PHP e JavaScript. Há pessoas nos fóruns declarando uma function e achando que ela será executada só com isso, sem ele fazer uma chamada a ela.

Ponto importante: não ser dependente do framework. Aprenda a fazer com ele, mas sem também!

E se a sua empresa resolver mudar de paradigma, ou você mudar de trabalho e lá usarem outros, ou nenhum? Como fica?

Você novamente vai gastar um bom tempo reaprendendo outra ferramenta que poderia ser muito menor, se tivesse alguma idéia de como essas ferramentas fazem o que fazem.

A Inversão de Controle pode ser tua amiga. Há todos os "bons motivos" de se usar um framework e o principal ponto é: não comece por ele, vá aprendendo a base e evoluindo!

iMasters

10 códigos para usar no arquivo functions.php e melhorar seu painel de administração WordPress

Se você quer melhorar seus templates WordPress para torná-los mais interessantes e, acima de tudo, melhorar sua acessibilidade, navegabilidade e usabilidade (especialmente agora com a chegada do Google Panda), é extremamente importante ter alguns códigos à mão para usar no arquivo functions.php de forma a tornar o seu site mais atrativo e funcional.

01. Mostrar o botão "Todas as Opções"

Este truque é bastante interessante. Ele irá adicionar uma nova opção ao seu menu de “Opções” com um link para “all settings”, que vai te permitir ver uma lista completa de todas as opções do seu site, nomeadamente banco de dados etc. Este código torna o menu apenas visível a administradores.

// CUSTOM ADMIN MENU LINK FOR ALL SETTINGS
function all_settings_link() {
    add_options_page(__('All Settings'), __('All Settings'), 'administrator', 'options.php');
}

add_action('admin_menu', 'all_settings_link');

02. Remover notificação de updates para usuários

Este código permite que você remova as notificações de updates do WordPress para os seus usuários, sendo que essas notificações continuarão aparecendo para os administradores do site.

// REMOVE THE WORDPRESS UPDATE NOTIFICATION FOR ALL USERS EXCEPT SYSADMIN
global $user_login;

get_currentuserinfo();

if (!current_user_can('update_plugins')) { // checks to see if current user can update plugins
    add_action('init', create_function('$a', "remove_action('init', 'wp_version_check');"), 2);
    add_filter('pre_option_update_core', create_function('$a', "return null;"));
}

03. Modificar a logomarca de login e a URL da imagem

Com este código você poderá mudar facilmente a logomarca da página de login do seu WordPress, bem como a URL dessa imagem e o texto alt da logomarca.

// CUSTOM ADMIN LOGIN HEADER LOGO
function my_custom_login_logo() {
    echo '';
}

add_action('login_head', 'my_custom_login_logo');// CUSTOM ADMIN LOGIN HEADER LINK & ALT TEXT

function change_wp_login_url() {
    echo bloginfo('url');  // OR ECHO YOUR OWN URL
}

function change_wp_login_title() {
    echo get_option('blogname'); // OR ECHO YOUR OWN ALT TEXT
}

add_filter('login_headerurl', 'change_wp_login_url');
add_filter('login_headertitle', 'change_wp_login_title');

04. Customizar a ordem do menu de administração

Você poderá reorganizar a ordem dos elementos do menu de administração do seu WordPress. A única coisa que precisa fazer é clicar num link existente no menu de admin e copiar o URL antes do /wp-admin/. A ordem seguinte representa a ordem do seu novo menu de admin.

// CUSTOMIZE ADMIN MENU ORDER
function custom_menu_order($menu_ord) {
   if (!$menu_ord) return true;
   return array(
        'index.php', // this represents the dashboard link
        'edit.php?post_type=events', // this is a custom post type menu
        'edit.php?post_type=news',
        'edit.php?post_type=articles',
        'edit.php?post_type=faqs',
        'edit.php?post_type=mentors',
        'edit.php?post_type=testimonials',
        'edit.php?post_type=services',
        'edit.php?post_type=page', // this is the default page menu
        'edit.php', // this is the default POST admin menu
  );
}

add_filter('custom_menu_order', 'custom_menu_order');
add_filter('menu_order', 'custom_menu_order');

05. Remover itens desnecessários do Painel Admin

Remova vários itens do seu painel de controle que você não precisa.

add_action('wp_dashboard_setup', 'my_custom_dashboard_widgets');

function my_custom_dashboard_widgets() {
    global $wp_meta_boxes;
    //Right Now - Comments, Posts, Pages at a glance
    unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now']);
    //Recent Comments
    unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_recent_comments']);
    //Incoming Links
    unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_incoming_links']);
    //Plugins - Popular, New and Recently updated WordPress Plugins
    unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_plugins']);

    //Wordpress Development Blog Feed
    unset($wp_meta_boxes['dashboard']['side']['core']['dashboard_primary']);
    //Other WordPress News Feed
    unset($wp_meta_boxes['dashboard']['side']['core']['dashboard_secondary']);
    //Quick Press Form
    unset($wp_meta_boxes['dashboard']['side']['core']['dashboard_quick_press']);
    //Recent Drafts List
    unset($wp_meta_boxes['dashboard']['side']['core']['dashboard_recent_drafts']);
}

06. Rodapé customizado no Painel Admin

Este truque permite colocar links no texto ou no rodapé do seu painel de administração do WordPress.

// customize admin footer text
function custom_admin_footer() {
    echo 'add your custom footer text and html here';
}

add_filter('admin_footer_text', 'custom_admin_footer');

07. CSS customizado no painel de administração

Poderá fazer as alterações que desejar ao css entre as tags.

/* Change WordPress dashboard CSS */
function custom_admin_styles() {
    echo '';
}

add_action('admin_head', 'custom_admin_styles');

08. Contagem de palavras em artigos

Este truque adiciona um contador do total de palavras publicadas junto da caixa "Right Now", que se encontra no início do painel de administração do WordPress. Muito útil se tiver curiosidade em saber quantas palavras já escreveu no seu site.

function post_word_count() {
    $count = 0;
    $posts = get_posts(array('numberposts' => -1, 'post_type' => array('post', 'page')));
    foreach ($posts as $post) {
        $count += str_word_count(strip_tags(get_post_field('post_content', $post->ID)));
    }
    $num =  number_format_i18n($count);
    // This block will add your word count to the stats portion of the Right Now box
    $text = _n('Word', 'Words', $num);
    echo "
{$num}{$text}
";
    // This line will add your word count to the bottom of the Right Now box.
    echo '

This blog contains a total of ' . $num . ' published words!

'; } // add to Content Stats table add_action('right_now_content_table_end', 'post_word_count'); // add to bottom of Activity Box add_action('activity_box_end', 'post_word_count');

09. Remover a barra de admin do WordPress 3.1

O novo WordPress 3.1 incluiu uma nova opção chamada Admin Bar. Essa barra para o administrador é adicionada ao topo do site quando você está logado. Se quiser removê-la permanentemente, use este truque!

remove_action('init', 'wp_admin_bar_init');

10. Adicionar links na barra de admin

Se você quiser usar a barra de admin, pode usar este truque para adicionar links para páginas ou opções que considera importantes de ter à mão.

function mytheme_admin_bar_render() {
    global $wp_admin_bar;
    $wp_admin_bar->add_menu(array('parent' => 'new-content', /* use 'false' for a root menu, or pass the ID of the parent menu */
                                  'id' => 'new_media', /* link ID, defaults to a sanitized title value */
                                  'title' => __('Media'), /* link title */
                                  'href' => admin_url('media-new.php'), /* name of file */
                                  'meta' => false /* array of any of the following options: array('html' => '', 'class' => '', 'onclick' => '', target => '', title => ''); */));
}

add_action('wp_before_admin_bar_render', 'mytheme_admin_bar_render');

iMasters

De quantos formatos eu preciso para vídeo HTML5?

A tag <video> no HTML5 é algo ótimo. Ela possibilita o playback de vídeos nativos em todos os browsers atuais, ao invés de depender de plugins, como o Flash. Ela abre a porta para vídeos web em dispositivos que não suportam o Flash. E ela também suporta codecs que antes a web não suportava.

Mas se você estiver publicando conteúdo em vídeo, isso pode ser confuso. Para, de fato, suportar vídeo web, quantas versões de saída você precisa criar? WebM, Ogg e MP4? Mas e o iPhone, ou o Android? E versões de bitrates reduzidas/completas?

Não existe uma resposta única para essa pergunta, então, aqui temos um guia simples para te ajudar a escolher as saídas para vídeos em HTML5.

Quais formatos web?

Existem três formatos de vídeo que funcionam nativamente em alguns browsers. Infelizmente, nenhum formato funciona em todos os browsers, então você precisa de pelo menos dois se você quiser ter um suporte significativo para vídeo em HTML5.

Minimamente, você deve usar MP4 + H.264, com AAC ou MP3. O vídeo MP4 roda nativamente no Safari, Chrome, e IE9 (Vista/Windows 7). Também é sua melhor opção para exibir vídeos, caso não tenha Flash, e eles rodam nativamente em muitos dispositivos (iOS, Android, Blackberry, PSP, Xbox, PS3, etc). Utilize o H.264 High Profile para melhor qualidade, e o Baseline Profile, se você quiser que o mesmo vídeo seja executável em dispositivos móveis.

Além disso, use o WebM + VP8, ou Ogg + Theora com áudio Vorbis para outros browsers. O WebM funciona no Firefox (versões posteriores a 4), no Chrome (vcersões maiores do que a 6, ou o Chromium), e no Opera (acima da versão 10.60), e o Ogg funciona no Firefox (a partir da 3.5), no Chrome (a partir da 3), e no Opera (versões posteriores a 10.54).

Se você escolher um, ou outro, qual deles deve usar: Ogg ou WebM?

Na nossa opinião, o WebM é o futuro do vídeo livre. O VP8 é um codec melhor que o Theora, e só vai melhorar a medida que a comunidade de vídeo fique por trás dele. Ter o Google no barco também não atrapalha. Portanto, apesar de o Ogg ser suportado por mais browsers, recomendo que você use, minimamente, MP4 + WebM, ou Ogg. Melhor ambos.

Quais dispositivos móveis?

Mais uma vez, não existe um único perfil para dispositivos móveis que funcione em todos eles. Na verdade, existem mais padrões variáveis para vídeos mobile, do que para vídeos web. Mas, felizmente, algumas receitas bem selecionadas podem cobrir a maioria dos dispositivos móveis modernos.

1. A maioria dos dispositivos móveis modernos suporta MP4/H.264. Isso inclui toda a série iOS (iPhone, iPod, iPad, Apple TV, etc), a maioria dos dispositivos Android, telefones Blackberry modernos etc. Para a maioria deles, tenha o cuidado de utilizar o H.264 Baseline profile. Use o 640×480, ou um menor para iOS e Android, e 480×360, ou menos, para suporte ao Blackberry.

Note que o mesmo arquivo que roda em um iPhone pode rodar na web, via HTML5 (alguns browsers), ou Flash. Então, se você quiser reduzir versões, use o mesmo arquivo. Mas pode ser que você esteja preso com o Baseline Profile para a maioria de dispositivos, e o Main/High fazem uma grande diferença, então, utilizar versões separadas de saída pode ser uma boa idéia, se você quer uma melhor qualidade para cada dispositivo.

2. Use 3GP/MPEG4 para dispositivos móveis mais antigos. A maioria dos Blackberrys e alguns Androids também suportam 3GP, e ele geralmente roda em iPhone/iPod também (uma vez que o iOS roda MP4/MPEG-4 e o 3GP é apenas um sub-conjunto do MP4).

3. Espera-se que o WebM chegue para o Android e outras plataformas móveis em até dois anos. Mas, por enquanto, use MP4 para melhor qualidade no Android.

Recomendação: No mínimo MP4, 640×480 ou 480×360. No máximo, três versões MP4 (480×360, 640×480, 720p + Main profile) mais uma, ou duas versões 3GP (320×240 e talvez 176×144). Veja neste artigo mais sobre configurações específicas de codificação.

E múltiplos bitrates?

Você deve utilizar múltiplos bitrates para entregar vídeos maiores para usuários com conexões rápidas de internet, e vídeos menores para usuários com conexões mais lentas? Se seus usuários estiverem assistindo a vídeos de alta qualidade na web, então a resposta é, provavelmente, sim. Considere usar 2-3 tamanhos e bitrates para conseguir isso, por exemplo, um vídeo com 640×360, e outro com 1280×720.

E o streaming?

Este guia não leva o streaming de vídeo em consideração. RTMP streaming (Flash), Smooth Streaming (Silverlight), e HTTP Live Streaming (iOS), todos eles pedem por vídeos especialmente preparados. Isso está além do escopo deste artigo.

TL;DR

* O mínimo para vídeo HTML5 é MP4 + WebM ou Ogg (ou ambos), usando a versão MP4 para Flash fallback.
* Para suporte móvel, uma saída H.264/MP4 pode te levar longe. 2-3 permitem melhor qualidade e maior compatibilidade.

Recomendações

Aqui estão algumas sugestões de configurações.

1. Suporte a tudo

* HTML5, Flash, Mobile: MP4/H.264, Baseline profile, 480×360 ou 640×480;
* HTML5: WebM ou Ogg.

2. Aumente a compatibilidade

* HTML5, Flash: MP4/H.264, High profile;
* HTML5: WebM;
* HTML5: Ogg;
* Mobile: MP4/H.264, Baseline profile, 480×360 ou 640×480.

3. Faça funcionar em qualquer lugar

* HTML5, Flash: MP4/H.264, High profile;
* HTML5: WebM;
* HTML5: Ogg;
* Mobile: MP4/H.264, Baseline profile, 480×360, para maior compatibilidade;
* Mobile: MP4/H.264, Main profile, 1280×720, para dispositivos iOS mais recentes (iPhone 4, iPad, Apple TV);
* Mobile: 3GP/MPEG4, 320×240 e/ou 177×144, para "não-smartphones"*.

iMasters

JavaScript e linguagens de pré-compilação

Eu sei que JavaScript não é uma linguagem que vai agradar a todo mundo, mas é a linguagem que roda nativamente em qualquer navegador com uma performance que não deixa nada a desejar. O que poderiam reclamar do JavaScript seria no máximo a sintaxe. Particularmente é questão de gosto.

Problemas? Todas as linguagens têm. Porém, como todas que têm uma boa comunidade ativa, ganham melhorias e novas características bem interessantes, assim como as APIs do HTML5 que já estão por aí e o ECMAScript 6 que vai trazer ótimas novidades.

Mesmo considerando toda a questão de gostos pessoais – e respeito muito isso – ainda acho que não podemos fugir da busca pela qualidade para atender uma vontade individual.

Ou seja, assim como para fazermos o melhor não deixamos de escrever em Java para apps de Android, em Objective-C para apps de iPhone, em Ruby para apps em Rails, utilizar qualquer outra pré-linguagem que compile para JavaScript para execução em navegador é algo que não parece ser a melhor opção.

A melhor linguagem que pode ser compilada para JavaScript é o próprio JavaScript. Tenho certeza das minhas interações pelo código e da qualidade do mesmo, assim como posso encontrar outro profissional bom na linguagem para entender o que está acontecendo. Estaríamos falando da mesma linguagem e a qualidade no código seria um facilitador para essa colaboração.

Outro ponto que acredito ser crucial: não somos únicos. Quando um programador sai da empresa, morre ou esteja em qualquer situação em que não escreva mais o código de determinada aplicação ele simplesmente não leva o código junto com ele, a menos que aquilo seja intencional.

O legado de um código é ensinar para uma pessoa nova aquilo o que está acontecendo. Se eu preciso de um novo profissional quando tenho um aplicativo em CoffeScript, qual linguagem eu devo exigir dele? CoffeScript, Javascript ou as duas?

O dia que encontrar um profissional que saiba apenas CoffeScript, vou acreditar que ele é totalmente incompleto e que teria o mesmo nível de quem somente aprendeu pseudo-código, sem me importar com o tempo que ele possui de experiência.

Como ele vai entender a real situação do meu aplicativo e todos os pontos que poderíamos melhorar? Como ele vai saber se tem ali um JavaScript bem escrito e funcional?

Em outras palavras, usar linguagens de pré-compilação me parece um verdadeiro "eXtreme Go Horse", do tipo que se funcionar, tudo bem, não se importando com o que estiver no meio do caminho.

iMasters

Upload progress bar com PHP 5.4

A versão 5.4 do PHP traz inúmeras atualizações e novas características, e dentre elas, está a possibilidade de monitorar o progresso do upload de arquivos via formulários, que antes só era possível mediante instalação de componentes PECL ou aplicando patches no código-fonte do PHP antes de compilá-lo.

Se você fizer uma consulta às configurações do PHP, verá que existem as novas session.upload_progress.enabled, session.upload_progress.cleanup, session.upload_progress.prefix, session.upload_progress.name, session.upload_progress.freq e session.upload_progress.min_freq. Estas variáveis definem o comportamento do PHP no momento da detecção e atualização das informações dos uploads de arquivos.

Para implementar uma barra de progresso que mostrará ao usuário as informações do upload depois que o formulário teve seu envio disparado, fiz algum código para exemplificar o processo. O código foi feito a partir de uma instalação "limpa" do Apache e do PHP.

upload.php (este é o arquivo que contém o formulário e as declarações de CSS e JavaScript necessárias, que podem estar em arquivos separados e chamados via SRC e HREF)
<?php

$is_PHP54_installed = ($x = @ini_get('session.upload_progress.name'));

?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PHP 5.4 Upload Progress Bar Demo<?php echo (!$is_PHP54_installed ? ' (will not working, installed PHP version is ' . phpversion() . ')' : '') ?></title>

<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<style type="text/css">
#upload_progress_status {
  display: none;
  width: 50%;
  margin: 20px 0px 0px 0px;
  overflow: hidden;
}

#upload_progress_status .bar,
#upload_progress_status .bar .progress {
  display: block;
  line-height: 20px;
  overflow: hidden;
}

#upload_progress_status .bar {
  border: 1px solid #000;
}

#upload_progress_status .bar .progress {
  width: 0%;
  background-color: #000;
  color: #fff;
  font-size: 12px;
  font-weight: bolder;
  text-align: center;
}

#form {
  display: block;
}

#loading {
  display: none;
}
</style>

<script type="text/javascript">
<!--
  $j = jQuery;

  upload_progress_status_timer = <?php echo (int)(@ini_get('session.upload_progress.min_freq')) * 1000 ?>;

  upload_progress_status_load = function () {
    try { upload_progress_status_load_XMLHTTP.abort(); } catch (e) {}

    upload_progress_status_load_XMLHTTP = $j.ajax ({ url: "upload_progress_status.php",
      dataType: "json",
      error: function () {
        setTimeout(function () { upload_progress_status_load(); }, upload_progress_status_timer);
      },
      success: function (info) {
        var ups = $j("#upload_progress_status"),
          bu = $j("#upload_progress_status .bytes_processed"),
          cl = $j("#upload_progress_status .content_length"),
          et = $j("#upload_progress_status .elapsed_time"),
          pbp = $j("#upload_progress_status .bar .progress");

        if (info != null) {
          ups.show();

          bu.html(info.bytes_processed_human);
          cl.html(info.content_length_human);
          et.html(info.elapsed_time_human);
          pbp.stop().animate({ width: info.uploaded }, upload_progress_status_timer).html(info.uploaded);

          if (!info.done) setTimeout(function () { upload_progress_status_load(); }, upload_progress_status_timer);
          else ups.hide();
        }
      }
    });
  }

  form_loading = function () {
    $j("#form").hide();
    $j("#loading").show();
  }
-->
</script>
</head>
<body>
<div id="form">
  <form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post" enctype="multipart/form-data"<?php if ($is_PHP54_installed) { ?> onsubmit="form_loading(); upload_progress_status_load()"<?php } ?>><?php
  if ($is_PHP54_installed) { ?><input type="hidden" name="<?php echo $x ?>" value="demo" /><?php }

  for ($k=0; $k<=4; $k ) {
    ?>File <?php echo $k 1 ?>: <input type="file" name="files[<?php echo $k ?>]" size="30" /><br/><?php
  }

  ?><input type="submit" value="Send files" />
  </form>

  <?php if (count($_FILES)) echo '<pre>' . print_r($_FILES, true) . '</pre>' ?>
</div>

<div id="loading">Sending...</div>

<div id="upload_progress_status">
  <div class="bar"><div class="progress">0%</div></div>
  <span class="bytes_processed">0</span> of <span class="content_length">0</span><br/>
  <span class="elapsed_time">00:00</span> elapsed time
</div>
</body>
</html>

upload_progress_status.php (este é o arquivo que retornará ao JavaScript as informações do progresso do upload)
<?php

@session_start();

function get_user_readable_filesize ($fs) {
  $fsl = array('bytes', 'KB', 'MB', 'GB', 'PB', 'YB');
  $y = 0;
  while ($fs >= 1024) {
    $fs /= 1024;
    $y ;
  }
  return number_format($fs, $y ? 2 : 0, '.', '') . ' ' . $fsl[$y];
}

if (($info = @$_SESSION[ini_get('session.upload_progress.prefix') . 'demo'])) {
  $info['content_length_human'] = get_user_readable_filesize($info['content_length']);
  $info['bytes_processed_human'] = get_user_readable_filesize($info['bytes_processed']);

  $info['elapsed_time'] = time() - $info['start_time'];
  $info['elapsed_time_human'] = sprintf('%02d', (int)($info['elapsed_time'] / 60)) . ':' . sprintf('%02d', (int)($info['elapsed_time'] % 60));

  $info['uploaded'] = number_format(($info['bytes_processed'] * 100 / $info['content_length']), 2, '.', '') . '%';

  $x = $info['files'];
  unset($info['files']);
  $info['files'] = $x;
}

echo @json_encode($info);

?>
Acrescentei alguns itens no array de informações, que originalmente não existem nas que o PHP cria, como o cronômetro do upload, as informações de tamanho total e já enviado em um formato mais legível, e a porcentagem do total de dados já enviados.

Você pode customizar os arquivos, adicionando estilos CSS, eventos JavaScript, valores de retorno JSON, enfim, o que sua criatividade e necessidade exigirem. O essencial está na variável de sessão que está declarada no arquivo upload.php e no campo hidden declarado no formulário. São eles que tornam possível o monitoramento do progresso do upload no PHP 5.4.0 ou superior.

Como verificar se a pessoa curtiu sua fan page no Facebook

Se você já reparou que há fan pages no Facebook que permitem o acesso a certos conteúdos somente para quem clicou no botão "curtir" da página, mas sempre quis implementar isso nas suas páginas, pois saiba que este é um processo bem simples.

O Facebook envia a você um cabeçalho chamado "signed_request", que é codificado em base64. O que é preciso fazer é decodificar este string, e a função abaixo faz o processo.
function parsePageSignedRequest() {
 if (isset($_REQUEST['signed_request'])) {
  $encoded_sig = null;
  $payload = null;
  list($encoded_sig, $payload) = explode('.', $_REQUEST['signed_request'], 2);
  $sig = base64_decode(strtr($encoded_sig, '-_', '+/'));
  $data = json_decode(base64_decode(strtr($payload, '-_', '+/'), true));
  return $data;
 }

 return false;
}

Depois, em qualquer lugar do código HTML da sua página, execute o seguinte condicional abaixo. Dentro do if e do else, exerça sua criatividade, mostrando ou ocultando o que você quiser aos fãs, ou que ainda não são fãs, de sua página.
if (($signed_request = parsePageSignedRequest())) {
 if ($signed_request->page->liked) {
  echo "Obrigado por curtir nossa página! Receba informações exclusivas através do Facebook!";
 } else {
  echo 'Curta nossa página para receber informações exclusivas!';
 }
}

WordPress: 10 dicas para o arquivo .htaccess

O arquivo .htaccess é o arquivo que controla o webserver Apache e é extremamente útil, permitindo realizar uma série de tarefas bem interessantes e favoráveis ao seu site. Nunca se esqueça de que, antes de editar o seu arquivo .htaccess, você deverá sempre fazer um backup dele para evitar problemas futuros.

Remover o www na url

Por razões de otimização para buscadores (SEO), você poderá remover (ou usar sempre) o prefixo www nos endereços URL do seu site. O seguinte truque permite remover esse prefixo www da URL, e redirecionar qualquer URLs com www para a versão não-www automaticamente.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^meusite.com$ [NC]
RewriteRule ^(.*)$ http://meusite.com/$1 [L,R=301]

Prevenir hotlinking

O hotlinking é uma má prática, que consiste em outros blogueiros utilizarem imagens do seu site no site deles, consumindo a sua banda. Quando alguém puxa uma imagem sua, essa pessoa está consumindo a sua banda para proveito próprio. Para prevenir esse abuso, utilize este truque no seu arquivo .htaccess substituindo as URL pelos seus próprios endereços.
RewriteEngine On
#Replace ?mysite.com/ with your blog url
RewriteCond %{HTTP_REFERER} !^http://(.+.)?meusite.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
#Replace /images/nohotlink.jpg with your "don't hotlink" image url
RewriteRule .*.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]

Redirecionar todos os feeds para o Feedburner

A maioria dos sites usa o Feedburner para distribuir os feeds RSS para os seus leitores. Se você usa o WordPress, você deverá redirecionar todos os seus feeds (rss, atom etc) para o seu feed do Feedburner. Modifique as linhas 2 e 3 do código, e depois copie e cole no seu arquivo .htaccess.
<IfModule mod_alias.c>
 RedirectMatch 301 /feed/(atom|rdf|rss|rss2)/?$ http://feedburner.com/seufeed/
 RedirectMatch 301 /comments/feed/(atom|rdf|rss|rss2)/?$ http://feedburner.com/seufeed/
</IfModule>

Criar páginas de erro customizadas

Cansado daquelas páginas de erro padrão que seu site apresenta? Crie alguns arquivos .html com o aspecto e o design que você deseja, carregue-os para o seu servidor, e adicione o seguinte truque no seu arquivo .htaccess:
ErrorDocument 400 /errors/badrequest.html
ErrorDocument 401 /errors/authreqd.html
ErrorDocument 403 /errors/forbid.html
ErrorDocument 404 /errors/notfound.html
ErrorDocument 500 /errors/serverr.html

Forçar o download de arquivos específicos

Quando você oferece alguns arquivos como mp3s, arquivos de Excel ou PowerPoint, ou mesmo um Ebook Grátis para download, você poderá forçar o download sem que tenha de aguardar pela decisão do browser sobre o que fazer. Este truque força o download de arquivos .xls e .eps a partir do seu servidor. Poderá editar o código para o tipo de arquivos que desejar.
<Files *.xls>
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</Files>
<Files *.eps>
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</Files>

Registrar erros de PHP

Este truque é uma forma interessante de registrar erros dos seus arquivos PHP num arquivo de registro (log). Comece criando um arquivo do tipo php_error.log e coloque-o no seu servidor, e depois copie e cole para dentro do seu arquivo .htaccess. Não se esqueça de modificar a localização do arquivo de registros na linha 7 do código.
# display no errs to user
php_flag display_startup_errors off
php_flag display_errors off
php_flag html_errors off
# log to file
php_flag log_errors on
php_value error_log /location/to/php_error.log

Remover extensão de arquivos nas urls

As extensões de arquivos podem ser extremamente importantes para desenvolvedores, mas não existe interesse nenhum em você mostrar a extensão de um determinado arquivo para os seus usuários. Este truque irá remover a extensão .html de qualquer arquivo html que você tenha em seu servidor. Obviamente, este truque pode ser facilmente adaptável a outro tipo de extensões, como por exemplo as extensões PHP.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html
# Replace html with your file extension, eg: php, htm, asp

Prevenir listagem de diretórios

Em seu servidor, quando um determinado diretório não contém um arquivo index, o Apache mostra automaticamente uma listagem de todos os arquivos presentes nesse diretório. Se você tiver uma pasta com imagens em seu servidor, se alguém acessar o endereço dessa pasta, poderá ver todo o conteúdo que você tem lá dentro. Se não quer que ninguém veja os arquivos que estão no seu servidor, copie e cole o seguinte de código para dentro do seu arquivo .htaccess.
Options -Indexes

Reduzir o peso das páginas

Você sabia que é possível enviar informação comprimida para os seus usuários, a qual é descomprimida pelo cliente do próprio usuário? Este código irá provavelmente poupar ocupação da banda e reduzir drasticamente o peso das suas páginas.
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/javascript text/css application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch bMSIE !no-gzip !gzip-only-text/html

Adicionar UTF-8 aos arquivos automaticamente

De forma a evitar problemas de codificação, você pode forçar um determinado tipo de codificação diretamente a partir do seu arquivo .htaccess. Você pode garantir que todos os seus arquivos HTML irão ser renderizados corretamente, mesmo que se esqueça de adicionar uma diretiva às suas páginas HTML.
<FilesMatch ".(htm|html|css|js)$">
AddDefaultCharset UTF-8
</FilesMatch>

Dica bônus: não se esqueça de fazer um backup do seu arquivo .htaccess antes de editar!

iMasters

Você realmente precisa de um aplicativo mobile?

Muitas empresas estão investindo em aplicativos mobile. De bancos a fabricantes de sabão, todo mundo quer ter sua bandeira fincada nas lojas de aplicativos mobile. Esse movimento tem um quê de “corrida do ouro”, com muita gente desenvolvendo aplicativos mobile porque todo mundo está fazendo, sem uma definição clara de objetivos e, o que é mais importante, sem um estudo de alternativas para se atingir esse objetivo.

Existe uma alternativa às aplicações mobile: são os sites mobile. Recomendo que a empresa avalie, antes de iniciar a construção de uma aplicação mobile, se seu problema não pode ser resolvido por um site mobile.

Sites mobile são multiplataforma. Já aplicativos para iPhone não rodam em Android, aplicativos para Blackberry não rodam em Windows Phone. Desenvolver um aplicativo que funcione nessas quatro plataformas significa desenhar uma vez só, porém construir quatro vezes, em linguagens de programação diferentes, com APIs diferentes.

Disponibilizar seu aplicativo nas diversas lojas mobile também significa encarar várias exigências burocráticas.

Um bom site mobile, por outro lado, funciona nas quatro plataformas citadas acima, e tem grande chance de funcionar em qualquer outra, sem esforço extra.

Sites mobile usam uma base de código que é aproveitada para desktops. Se você já tem um site ou aplicativo web que atende as suas necessidades, provavelmente, para ter um site mobile, será preciso mexer apenas no que os desenvolvedores chamam de "camada de apresentação". Caso você não tenha um site ou um aplicativo web e decida construí-lo mobile, vai aproveitar boa parte do seu investimento, se no futuro decidir tê-lo também funcionando em computadores.

Com HTML5, sites mobile podem executar quase tudo o que uma aplicação mobile faz, incluindo acessar o GPS, ler a orientação do dispositivo (se o telefone está em pé ou deitado), guardar dados no telefone, desenhar gráficos, transições, animações, tocar áudio e vídeo, e até funcionar offline.

Quando você precisa de um aplicativo? Existem situações em que construir um aplicativo é essencial:

Está desenvolvendo um jogo pesado

Ainda é muito difícil, com HTML5, construir interfaces tridimensionais, com gráficos de alta qualidade, muito movimento, respostas rápidas e interação com som.

Precisa interagir com o telefone

Não há uma maneira de um site mobile ler a agenda de contatos do telefone, ou as fotos da galeria, por exemplo. Embora existam maneiras de, por exemplo, disparar uma ligação telefônica a partir de um link ou botão.

Necessita de interação precisa com o acelerômetro

Sites mobile, hoje, apenas sabem se o telefone está em pé ou deitado, e mais nada. Não dá para fazer um aplicativo controlado pelo acelerômetro, assim como uma corrida em que o volante é o próprio telefone.

Pretende cobrar por seu aplicativo

Existem alternativas para se cobrar pelo acesso à aplicação ou vender conteúdo dentro dela, e fazem todo o sentido se seu aplicativo for realmente multiplataforma, acessível do computador e do celular. Se você pretende cobrar pelo uso do próprio aplicativo, é bom avaliar se usar as lojas de aplicativos, em que o usuário compra com um clique, já tendo seu cartão de crédito cadastrado, é a melhor solução. Nesse caso, as lojas de aplicativo também vão dar visibilidade ao seu aplicativo.

Seu aplicativo precisa rodar em background

Se seu aplicativo precisa de um serviço rodando em segundo plano, você não conseguirá fazer isso com um site. Por exemplo, se seu aplicativo deve avisar o usuário cada vez que ele se aproximar de um local específico, mesmo que ele esteja fazendo outra coisa no telefone ou esteja com o telefone no bolso.

Há, por outro lado, uma diversidade de situações em que um bom site mobile pode substituir, com vantagens, um aplicativo. Por exemplo, quando o aplicativo só acessa seu site, como fazem muitos aplicativos de internet banking, que são exatamente iguais ao site mobile do banco. Mesmo que seu site seja um aplicativo web razoavelmente complexo, com animações, gráficos e interações, é muito provável que seja possível fazê-lo funcionar em dispositivos móveis, atendendo a uma variedade de plataformas com um único esforço de investimento.

Avalie alternativas antes de construir um aplicativo mobile. Talvez você possa, com um site mobile, atingir um público muito maior, com um investimento menor, e ainda tenha uma drástica redução nos custos de manutenção e atualização do aplicativo.

iMasters

A importância de adotar os padrões e recomendações do W3C ao construir um website


A diferença entre um cara que programa e um programador

O ato de escrever códigos faz com que você seja um cara que programa, mas não necessariamente um programador. Digamos que ambos cumprem o papel e resolvem o problema. E a diferença está na forma de pensar deles.

Existem diversas maneiras de se chegar a um mesmo resultado. Algumas mais claras, diretas, outras mais bonitas, elegantes, às vezes nebulosas, cheias de voltas e emaranhados, boas ou ruins. Apesar do peso de subjetividade que esses termos carregam.

Um bom código é aquele que, chega onde deve chegar, sendo este legível aos envolvidos, e aqueles que não sabem do que se trata.

* Bom em performance;
* Sem rotinas confusas ou desnecessárias(as famosas gorduras);
* Bem indentado e organizado.

Apenas isso. Simples e objetivo. Toda a comunidade, conhece ou deveria conhecer os conceitos que citei. (Keep It Simple, Faça o Simples que Funcione, Você não vai precisar disso, Don’t Repeat Yourself...)

“Um CQP [Cara Que Programa], não leva ou nem sempre leva em consideração estas ‘máximas’.” Já um VP [Verdadeiro Programador], possui esses conceitos incorporados a ele. Na forma de pensar, na maneira de codificar. Para um Programador, é natural, para o CQP, ainda não é.

Todos sofremos pressão, temos prazos apertados, e situações difíceis pra lidar... este é o nosso mundo. A agência ou a empresa, pode lhe dizer que é tranquilo, que são pacientes, que os prazos são legais, e tudo mais, porém, faz parte da arte de programar nos deparamos com algo urgente e impossível, para ontem!

Um programador resolve da melhor forma possível, enxergando na frente, o outro faz apenas para se ver livre, e entregar logo. O erro aqui, é que depois aquele monstrinho volta, e nem sempre podemos ou temos tempo de refazer ou corrigir. E quando surgem as cabeças dos nossos monstros. Duas, Três, Sete... a tendência é piorar. Começou errado, por preguiça, falta de conhecimento, mal planejamento, ego...

Um CQP, acha que sabe tudo, ou não se importa de não saber, e nem tenta. Um VP, tenta saber, sempre busca melhorar, aceita analisando as críticas recebidas, e gosta do que faz. Fazer bem feito lhe deixa feliz, o contrário lhe incomoda.

O melhor programador não é aquele que complica mais. Códigos de linguagens alto nível, devem ser escritos por humanos e para humanos. As máquinas entendem, tanto códigos bem escritos, quanto códigos ruins, mas e você no futuro? E o outro programador?

Acho que todos nós já demos continuidade no trabalho de alguém. Já vimos scripts porcos, e outros bem feitos. Quando alguém pegar um trabalho nosso, vamos tentar ser aquele que não será xingado, e nem fez o outro programador perder horas e horas, entendendo as loucuras que fizemos.

Faça-se essa pergunta. O que você é? Qual dos dois?

iMasters

Adobe lança o Edge, ferramenta que cria animações no padrão HTML5


A Adobe liberou segunda-feira (1°) uma versão de prévia do Edge, uma ferramenta voltada especificamente para criar animações no padrão HTML5 e que pode ajudar a diminuir a onipresença do Flash na web.

Além do HTML5, o Adobe Edge utiliza outros padrões web como CSS3 e JavaScript para criar as animações. Os interessados em testar o Adobe Edge podem baixá-lo no Adobe Labs ou esperar a versão final, que será lançada no ano que vem.

O programa parece ser um ótimo plano de contingência se o as habilidades do HTML 5 passarem a ser mais vantajosas e mais adotadas do que as do Flash.

Veja uma animação feita com HTML, JS & CSS.

O Adobe Edge está disponível para OS X e Windows e também deve ser utilizado em jogos.

iMasters

Fale menos, codifique mais

"Só o código importa". Essa frase nem sempre disse tanto quanto diz hoje em dia. Sua simplicidade desafia a compreensão de um profissional que vivenciou e ainda vivencia projetos de software nos quais o código é apenas mais uma das coisas que podem dar errado. Em um contexto no qual passamos boa parte da graduação aprendendo a montar diagramas e no mercado em que os profissionais passam o dia montando documentos, essa frase realmente não pode fazer sentido.

Teorias e soluções são comprovadas com código

Uma coisa comum em projetos é que, ao nos depararmos com um problema, teorizamos sobre as possíveis soluções. Soluções que podem ser desde um simples design de classes até um projeto secundário que vai revolucionar o mundo. A questão é: documentos e diagramas aceitam qualquer coisa, o código, não.

Nenhuma solução é válida até que se prove sua viabilidade no código. Felizmente, na área de desenvolvimento, o custo para se criar uma prova de conceito não é alto. Podemos passar trinta minutos discutindo possíveis soluções para um problema em um quadro branco ou folha de papel e já partir para construção do seu código.

Prolongar o tempo da solução fora do código é prejudicial, pois somente o código fornece o feedback necessário para uma avaliação. Na prática, o ideal é ficar o menor tempo possível com uma solução fora do código.

O código traz resultados. Documentos, não.

Sabe o que você consegue quando gasta tempo confeccionando documentos e diagramas? Documentos, diagramas e nenhum software funcionando. Em um contexto no qual o objetivo é conseguir o software funcional rápido, tudo que não for essencial deve ser descartado ou simplificado, pois não há tempo a perder.

Software não é um fim, mas sim um meio. O objetivo do time de desenvolvimento não é desenvolver um requisito, mas sim entender a necessidade do cliente e atendê-la com uma solução de software. Apesar dos conceitos parecerem semelhantes, na prática são completamente diferentes.

Artefatos válidos são artefatos úteis. A utilidade do artefato está na informação em si, não no seu formato ou nas assinaturas de aprovação do requisito no fim da página. Reduzir o tempo de confecção de artefatos e investir em codificação é certamente uma das melhores práticas para se obter resultados rápidos.

Nenhum documento diz mais sobre o software do que seu próprio código

Uma linguagem de programação é tão útil para registrar uma informação quanto qualquer outro documento, com a vantagem de nunca ficar desatualizada.

Geralmente documentos são gerados para expressar regras de negócio que seriam difíceis de entender no próprio código, além de outras razões burocráticas. Meu ponto não é contra documentações, mas sim a favor de um código expressivo, que não necessite de artefatos externos para ser compreendido.

É claro que, até o código ser produzido, podemos precisar de documentos auxiliares para expressar as regras que devemos codificar. Porém, depois de escrito, o código passa a ser a única referência confiável sobre aquela regra. Muitas empresas acreditam que uma boa documentação irá auxiliar na passagem de conhecimento entre programadores, mas nada é tão útil quanto um código expressivo e com testes unitários que não só expressem a intenção do código, mas também garantam que o mesmo está funcionando corretamente.

É possível ter um código expressivo. Investir na qualidade do código traz mais resultados do que gastar tempo na confecção de artefatos para traduzi-lo.

O código levanta questões sobre o domínio

Construir software é expressar através de código as coisas como elas de fato acontecem, ou seja, as imperfeições e as indefinições do ambiente do cliente ficarão explicitas no momento da codificação, o que levanta a questão: o que fazer nesse momento?

A comunicação entre cliente e time de desenvolvimento não é uma via de mão única, sendo totalmente plausível existirem questionamentos sobre o processo do cliente, afinal, tudo é passível de melhoria.

O time de desenvolvimento não pode ser omisso ao encontrar deficiências no domínio. Uma coisa que não funciona na vida real também não vai funcionar no software, podendo inclusive potencializar problemas que não eram tão evidentes quando o processo era feito manualmente.

Convenções e regras de criação de código podem auxiliar na detecção de falhas em um processo.

O código mostra o nível de experiência de um profissional

Não importa quantas certificações ou quantos anos de experiência um profissional tenha. O código que ele produz é a uma das maiores evidências de sua competência.

Alguns minutos de codificação ao lado de um profissional dizem muito sobre ele. Essa percepção foi a grande responsável por introduzir técnicas como Pair Programming e Coding Dojos em processos de seleção.

Conclusão

Em um cenário em que a entrega de software funcionando é o maior objetivo, o código se torna o bem mais precioso do projeto. O código é capaz de provar teorias, mostrar a experiência de um profissional, documentar uma regra e ainda trazer propostas de melhoria para o ambiente no qual será inserido.

iMasters

Contratando desenvolvedores: você está fazendo errado

Texto original em Inglês de Udo Schroeter disponível em http://devinterviews.pen.io

Quando Evan Carmi postou sua experiência em uma entrevista de emprego no Google (http://ecarmi.org/writing/google-internship) no HN, eu me lembrei dos meus dias iniciais. Em mais de uma década de entrevistas para empresas startups de TI, não fizemos nenhum progresso. Eu fui parte do problema por alguns anos. Eu simplesmente copiava um mecanismo de contratação que parecia padrão na época e, ao fazer isso, falhei miseravelmente no que dizia respeito ao principal objetivo que uma empresa deve ter ao contratar desenvolvedores. Hoje, as primeiras páginas de tecnologia estão cheias de esforços de Larry Page para transformar a empresa, mas acredito que os problemas de performance em empresas focadas em desenvolvimento podem estar atrelados a seu DNA devido a um processo falho de contratação.

Como nós fazíamos

Meu co-fundador e eu estávamos administrando uma pequena loja de desenvolvimento web na Alemanha. Começamos literalmente do porão da casa de nosso amigo. Com o tempo crescemos, e nos mudamos para um escritório de verdade. No início foi fácil encontrar novos colaboradores, nós podíamos apenas pedir para nossos amigos virem trabalhar para nós. Claro que esse modelo não funcionava em grande escala, mas ele fazia uma determinada função muito bem: garantia que contratássemos pessoas que eram boas para a empresa, tanto no sentindo pessoal quanto no profissional. Até que chegou o dia em que tivemos que preencher posições para as quais precisávamos trazer pessoas de fora.

Uma das características do serviço regional de desemprego na Alemanha é que eles te enviam uma pilha enorme de CVs, poucas horas depois de você ter falado com eles no telefone. Eu fiquei felizmente surpreso que não tivemos que contratar uma agência para fazer isso. Juntamente com os CVs que já havíamos recebido de pessoas que se inscreveram para a posição através de nosso site, agora tínhamos que fazer uma triagem. No final das contas, concordamos sobre 12 os melhores e os convidamos para uma entrevista. Essa é a parte em que tudo deu errado.

A entrevista padrão para desenvolvedores

Um candidato chegaria, normalmente usando seu melhor terno e sua melhor gravata, e nós sentaríamos para ter uma conversa. Essa conversa era algo essencialmente parecido com um exame oral de faculdade. Eu pediria a ele para codificar algoritmos para todos os problemas de CS bonitinhos, e obteria respostas com vários níveis de qualidade. Alguns deles atiravam suas respostas prontas em uma velocidade absurda. Eles estavam preparados exatamente para aquele tipo de entrevista. Outros se renderiam à pressão, quase incapazes de conseguir terminar a entrevista.

Para ser sincero, quando começamos a fazer isso, eu tinha que dar uma olhada nesses quebra-cabeças antes, principalmente para garantir que eu não passaria vergonha. Este deveria ter sido o primeiro sinal de que talvez não estivéssemos testando as habilidades mais relevantes para nossos requisitos. Se essas dúvidas passaram pela minha cabeça, eu deveria tê-las deixado de lado rapidamente. Afinal de contas, era a maneira como todo mundo fazia entrevistas.

Claro que optamos por contratar o funcionário com as respostas mais inteligentes. Inevitavelmente, outras posições se tornaram disponíveis, e nós repetimos o processo inúmeras vezes, por todo o tempo de vida da empresa. Se isso soa familiar para você, certamente você não está sozinho.

Performance real de trabalho

Mas como medimos o trabalho dos candidatos que selecionamos? A verdade é que tivemos resultados bastante variados. Muitos deles estavam dentro da média, muito poucos eram excelentes e alguns eram simplesmente horríveis em suas posições. Portanto, a entrevista não tinha nenhum efeito real sobre a qualidade das pessoas que estávamos selecionando, e receio que esse processo pode ser sido mais favorável à seleção de pessoas ruins.

O que de bom e de ruim isso significa nesse contexto? Vamos dar uma olhada em alguns benchmarks que considero importantes:

Cultura da Organização: Olhando para trás, uma das qualidades mais importantes que um novo funcionário deve ter é compatibilidade com o espírito das pessoas que já trabalham na empresa. A entrevista padrão teve o pior desempenho nesse quesito, por razões óbvias. É difícil julgar a personalidade das pessoas em entrevistas, porque elas não são exatamente elas mesmas naquele momento. Na verdade, são incentivadas a não serem elas mesmas.

Competência em Programação: De alguma maneira, contrariando minha intuição, os exemplos de códigos feitos durante a entrevista foram um indicador ruim da real competência no trabalho. Projetos do mundo real raramente consistem em implementar buscar binárias sem acesso a um analisador ou literatura. O que aconteceu foi que os empregados que se deram melhor nos exemplos de código nem sempre eram capazes de trazer seu conhecimento teórico para soluções práticas. Ter candidatos escrevendo algoritmos sortidos no whiteboard é um método que beneficia pessoas com ótima memória a curto prazo, que vêm preparadas exatamente para esses tipos de perguntas. No nosso caso, precisávamos de codificadores engenhosos, que escrevessem softwares organizados, estáveis e elegantes – e o processo de entrevista não estava os selecionando.

Gerenciamento de Projetos: Pessoas que foram bem na entrevista não são, necessariamente, bons colegas de equipe ou até bons apresentadores perante os clientes. Esse resultado foi surpreendente para mim. Acontece que aguentar uma entrevista por uma hora é uma habilidade completamente diferente de, digamos, ser bom em coordenar seus colegas de trabalho ou a pessoa que paga suas contas. A performance da entrevista também não indicava a habilidade de escrever uma boa documentação, ou como se comportar em comunicações online.
O resultado

O resultado de um processo seletivo como esse pode ser um dos fatores responsáveis pela perda do espírito de startup da empresa e sua alma criativa. Esse foi, definitivamente, o caso da nossa empresa. Como CEO, a maior falha foi certamente minha. No entanto, ter as pessoas erradas para o trabalho foi em grande parte a causa da incapacidade da empresa de entregar a quantidade e a qualidade necessárias para se sustentar. As brigas internas envenenaram nossos times. A incompetência era mascarada com boas capacidades de apresentação e puxação de saco. Boas pessoas deixaram a empresa porque elas odiavam essa nova atmosfera.

Apesar de eu ter dispensado várias pessoas por razões distintas ao longo dos anos, no final das contas, eu tive que fazer o discurso mais difícil da minha vida na manhã em que dissolvi a empresa.

Claro que esse é um exemplo extremo. A maioria das empresas prospera, apesar disso tudo. Mas eu ainda acredito que podemos melhorar muito as chances de encontrar os candidatos certos, ao mudar radicalmente a maneira como fazemos entrevistas. E, no nosso caso, isso provavelmente teria feito toda a diferença do mundo.
Uma alternativa

Como seria, então, uma entrevista para desenvolvedores? Simples: elimine a parte dos exames completamente da entrevista. Em vez disso, pergunte questões em aberto, que convidem seus candidatos a elaborar sobre seu trabalho de programação.

Qual foi o último projeto no qual você trabalhou no seu último emprego?

Me conte sobre seus projetos preferidos.

Em que projetos você está trabalhando no seu tempo livre?

De quais comunidades online hackers você participa?

Me conte sobre alguns pontos (técnicos/de programação) pelos quais você se sente entusiasmado.

Essas questões foram formuladas para revelar bastante sobre a pessoa que você tem na sua frente. Elas podem te ajudar a decidir se o candidato está interessado nas mesmas coisas que você, se você gosta do seu jeito de pensar e onde seus interesses reais estão. É mais difícil para eles conseguirem a vaga na malandragem, porque o entrevistador pode investigar questões mais profundas à medida que eles vão se apresentando.

Mas e a habilidade de codificação? Bom, pegue alguns minutos após a entrevista para dar uma olhada em alguns códigos que o candidato escreveu. Talvez para um projeto open source, talvez eles tenham que te enviar algo que não é publico, não importa. Olhar para a produção real do código pode te falar muito mais do que as linhas artificiais escritas no whiteboard.

Tenho certeza de que você pode criar outras questões e outras maneiras de engajar o entrevistado. Nesse ponto, qualquer ideia já indicaria uma melhora.

Ditados

A maioria das pessoas é rápida ao defender seu status quo, e com certeza essa é uma posição gratificante de se segurar. É livre de riscos e você sempre pode recorrer ao argumento “muitas pessoas inteligentes, ricas e bem sucedidas fazem as coisas do jeito antigo, então meu dinheiro está no que eles estiverem fazendo”.

"Legal, mas isso não funciona pra empresas grandes de sucesso. Sua idéia não é escalável."

Claro que é escalável. Em termos de esforço por entrevista não é diferente. Não existe razão por que isso não deveria funcionar em empresas grandes. No final das contas, o entrevistado sempre toma uma decisão pessoal e subjetiva. Estou meramente sugerindo uma maneira que entregue informações mais relevantes para aquele objetivo.

"Os melhores programadores não executam projetos em seu tempo livre" ou: "As pessoas mais talentosas que conheço trabalham de 9 às 5 E então vão para casa assistir futebol/estar com suas famílias/ou qualquer outra coisa."

Essa não é minha experiência. Não estou dizendo que um bom programador não deveria ter uma vida. Mas eu acredito que uma certa quantidade de entusiasmo por programação é necessária. E, realmente, se você tem uma ótima habilidade, não usá-la parece um grande desperdício para mim.

"No meu tempo livre, estou trabalhando pelo próximo milhão da minha empresa. Oh, quando não estou trabalhando para minha empresa? Estou com minha família e amigos." (verbete de http://news.ycombinator.com/item?id=2385148)

isso é ótimo, essas pessoas podem de fato me mostrar algo em que elas estavam trabalhando. No entanto, eu consideraria a falta de hobbies um problema para alguns trabalhos de desenvolvimento.

Pensamentos finais

Na minha experiência, a entrevista tradicional para desenvolvedores é insuficiente para encontrar bons candidatos. Enquanto os exercícios típicos de whiteboard se relacionam de alguma maneira com a competência em CS, eles são um indicador limitado de performance real de programação.

Discordo do processo e acredito que temos feito as entrevistas dessa maneira por anos simplesmente porque assim elas são mais fáceis de administrar, mas os dados gerados por essas entrevistas são amplamente irrelevantes – para não falar outra coisa. Nós, como parte da indústria, deveríamos apresentar questões mais personalizadas nas entrevistas, completamente focadas nas habilidades do candidato. Também acredito que é mais produtivo julgar a produção de código em oposto a quebra-cabeças modulares abstratos que não têm conexão real com o trabalho em si.

Mais importante, estou convencido de que conhecer a personalidade real do desenvolvedor é tão importante quanto checar sua competência profissional, porque uma escolha errada pode destruiu o time inteiro.

iMasters

Verdades não tão conhecidas sobre programação

Este artigo é a tradução de um excelente texto escrito por David Veksler, no qual ele conta o que sua experiência como programador lhe ensinou.

O texto original pode ser encontrado aqui.

A tradução segue abaixo:

* Um programador gasta cerca de 10% a 20% do seu tempo escrevendo código. Normalmente escreve entre 10 e 12 linhas por dia, que estarão presentes no produto final independentemente do seu nível de perícia ou experiência. Bons programadores gastam cerca de 90% do seu tempo pensando, pesquisando e experimentando maneiras de encontrar a solução ótima. Os programadores ruins gastam quase 90% do tempo debugando e fazendo alterações muitas vezes aleatórias na tentativa de "fazer funcionar".

* Um bom programador é dez vezes mais produtivo do que um programador comum. Um excelente programador é entre 20 e 100 vezes mais produtivo do que um convencional. Não é um exagero. Estudos desde os anos 60 têm mostrado isso consistentemente. Um mau programador não é só improdutivo - além de não concluir o trabalho com êxito, gera dores de cabeça e trabalho extra para outras pessoas consertarem.

* Excelentes programadores gastam pouco do seu tempo escrevendo (código que de fato estará no resultado final). Os programadores que gastam muito do seu tempo escrevendo provavelmente não estão encontrando e utilizando soluções existentes para problemas antigos. Bons programadores são ótimos em reconhecer e em reutilizar padrões comuns e não têm medo de refatorar seu código constantemente, a fim de atingir a solução ótima. Programadores ruins escrevem código que falha em integridade conceitual, não-redundância, hierarquia e padrões, tornando complicada a refatoração, fazendo com que seja mais fácil jogar fora todo o trabalho e recomeçar.

* Software, como qualquer coisa, obedece às leis da entropia. Contínuas mudanças levam ao desgaste do software e de sua integridade conceitual planejada originalmente. A entropia é inevitável, no entanto, programadores que falham ao estabelecer a integridade conceitual criam sistemas que se desgastam tão rapidamente, que muitas vezes se tornam inúteis e caóticos demais mesmo antes de serem concluídos. Possivelmente, o motivo mais comum para falha em projetos é o rompimento da integridade conceitual devido à entropia descontrolada (o segundo mais comum é a entrega de um produto diferente do que o cliente esperava). A entropia desacelera exponencialmente o desenvolvimento e é o principal motivo para deadlines desesperadoras.

* Um estudo realizado em 2004 revelou que 51% dos projetos falham ou irão falhar em alguma funcionalidade importante e que 15% simplesmente vão falhar como um todo, o que é um grande avanço desde 1994, quando 31% dos projetos falhavam criticamente.

* Embora muitos softwares sejam desenvolvidos em equipe, não se trata de uma atividade democrática. Geralmente somente uma pessoa é responsável pelo “design” do sistema e o resto do time o completa com detalhes.

* Programar é um trabalho pesado. É uma atividade mental intensa. Bons programadores pensam sobre seu trabalho 24/7. Eles escrevem seu código mais importante no chuveiro, sonhando etc., porque o trabalho mais importante é feito longe do teclado. Projetos não são concluídos mais rapidamente gastando mais tempo no escritório ou adicionando pessoas novas ao projeto.

"Um excelente operário pode ser duas ou até três vezes mais produtivo que um operário comum, já um bom programador pode fazer com que seu trabalho seja mais do que 10 mil vezes mais produtivo do que um programador comum" Bill Gates

iMasters

O problema da viseira (parte 2: plugando a mente)

O artigo anterior tratou do "problema da viseira", que consiste no fato de que muitas pessoas acham que a universidade é suficiente para a formação profissional, que o que se aprende é o que existe de melhor e mais útil na sua área. Na prática, sabemos que não é bem assim.

Depois de arrancar o que o impedia de enxergar além do que colocam exatamente a sua frente, o próximo passo é se conectar para enxergar além do alcance da própria visão. É hora de plugar sua mente na rede.

A internet é cheia de porcaria e de conteúdo de origem duvidosa. De fato. Por isso, a intenção é guiar vocês a se conectarem direito. Apenas ter acesso à grande rede não significa muita coisa.

Onde obter informações?

Temos a nossa disposição algumas ferramentas que ajudam a nos conectar a outras pessoas. A primeira, e uma das mais importantes atualmente, é o Twitter. Você pode seguir qualquer pessoa, ela não precisa aceitar sua amizade, e a partir disso você passa a receber tudo que ela deseja compartilhar. Pensamentos, textos, vídeos, imagens. Vale muito a pena seguir alguns perfis, o aprendizado é grande, você pode ter acesso a materiais geniais a que pessoas igualmente geniais têm acesso.

Para área de informática, recomenda-se algumas pessoas: @mauriciojr, @dttg, @rafaelcaricio, @alganet, @thiagoarrais, @tapajos, @henriquebastos, @gchapiewski, @dhh, @AkitaOnRails, @thiago_silva, @viniciusteles, @fnando, @osantana, @allisson, @mariacarol, @jonnyken, @srlm.

E os feeds? Eles estão se tornando secundários. Praticamente todos os perfis sugeridos acima possuem um blog e eles vão publicar os links de suas postagens no Twitter. Um leitor de feeds organiza melhor os posts que o Twitter, então se você quiser usar um, assine os blogs dos perfis acima.

Agora você está imerso em várias novas fontes de informação, mas não podemos nos esquecer de duas que existem há muito tempo, mesmo antes da internet. A primeira: livros. Eles são ótimos, não os abandone. A segunda: pessoas. Uma conversa pode valer muito mais que dezenas de posts num blog ou centenas de tweets.

É importante deixar claro que essas fontes de informações são dinâmicas, mas, com o tempo, alguns temas vão perdendo a importância na sua vida e outros aparecerão. Continue andando em frente. É fácil apagar um feed e assinar outro, você pode deixar de seguir uma pessoa e resolver acompanhar outra. As fontes não são para sempre, e você não precisa ficar amarrado ao que tem hoje.

iMasters

O problema da viseira (parte 1: as fontes de informação)

A graduação de computação é certa ou errada? Não sou o primeiro a perguntar isso, nem serei o último. Ela me foi útil, consigo perceber sua influência na minha formação facilmente. Mas sempre faltou algo. É ainda mais fácil perceber o vazio ao terminar o curso.

Durante a graduação, eu fiz coisas que nem todo mundo faz. Aprender tecnologias por fora, criar projetos, só um louco para arranjar tempo entre trabalhos, churrascos e pesquisas. Eu aprendi Delphi, HTML, CSS, JavaScript e PHP por curiosidade, obtive a certificação Zend Certified Engineer, criei softwares por pura vontade de fazer algo que outras pessoas pudessem usar. Eu gostaria que mais alunos seguissem um caminho menos trivial.

Todos querem seguir um caminho diferente? Não, é normal. Eu só acho que todos deveriam vivenciar uma cultura de criação na universidade. De criação de produtos reais. Não estou dizendo para jogar pesquisas científicas fora, longe disso, elas podem ser um grande impulso. Eu só não concordo com pesquisar para no final engavetar.

Faltava para mim o conhecimento de tecnologias novas que estivessem sendo usadas. Eu fui atrás, até hoje faço isso. A universidade não poderia ter me mostrado?

O primeiro passo para despertar essa inquietação é tomar consciência de que você não sairá pronto da graduação. Esse conceito de "pronto" nem deveria existir. Se você também gosta de criar suas coisas e tem interesse em fazer algo útil para as pessoas, então corra atrás. Leia, estude, codifique, converse, conheça pessoas com interesses parecidos. Procure saber se existe um "hora extra" na sua cidade.

Não apresentar algumas tecnologias não é o ponto mais grave, pois é impossível mesmo ter aulas de tudo que estiver sendo usado no mundo da computação. O grande problema em alguns alunos é o que eu vou chamar de "problema da viseira" (do cavalo). Não estou comparando ninguém ao animal, foque na viseira. Muita gente acha que a universidade é suficiente e o que você aprende é o que existe de melhor e mais útil na sua área. Isso limita demais a visão das pessoas, inclusive de pessoas inteligentes e com bastante potencial.

Arranque sua viseira fora e entre no maravilhoso mundo da internet. Parece tolo dizer isso, já que todo estudante de computação conhece a internet. Mas será que é assim mesmo?

A internet hoje é em tempo real, as coisas aparecem e desaparecem rapidamente, não deixe a correnteza passar sem que você pesque alguns peixes. Junte uma base sólida da graduação e o que há de mais novo que ótimos resultados poderão aparecer.

iMasters

E-commerce e a Realidade Aumentada

Já imaginou se o mundo físico e o mundo virtual se misturassem, e dessa união surgisse um novo ambiente? Essa é a proposta da Realidade Aumentada, que vai ao encontro das intenções do e-commerce, que surgiu com o intuito de tornar virtual uma operação física.

No entanto, essa transformação do processo de compra em uma operação online deixa algumas lacunas não preenchidas na experiência de compra do internauta. A falta de contato físico com determinados tipos de produto pode causar receio em efetuar a compra via internet.

Produtos como livros e CDs são chamados commodities, por não terem diferença alguma entre um exemplar e outro. Em outras palavras, não é preciso experimentar vários exemplares de um livro ou de um CD para escolher o ideal. Todos possuem o mesmo conteúdo e o mesmo nível de usabilidade e aderência ao comprador.

Por outro lado, existem produtos cujo processo de compra envolve mais do que o produto em si. É levada em conta sua utilização dentro de determinado contexto, ou junto ao consumidor. Como exemplos dessa categoria temos os produtos ligados à decoração e ao vestuário.

Falando em decoração, imagine que você queira pintar a sua casa. Nem todos possuem a capacidade de olhar uma sala vazia e com paredes brancas e imaginá-la pintada e decorada. Essa questão dificulta o processo de compra de produtos nessa área e, geralmente, recorre-se a um profissional de decoração, que vai até a loja com você, te mostra as cores, texturas objetos etc. Mas, em um mundo online, não se pode experimentar, testar.

Nesse contexto, a Realidade Aumentada tem como função auxiliar o consumidor no processo de escolha do produto, dando a ele mais segurança para efetuar a compra.

A Suvinil é um exemplo de empresa que anteviu essa tendência e lançou, em seu site, um aplicativo que simula as cores das tintas nas paredes da casa do usuário, basta que ele envie a foto do cômodo para fazer a simulação.

Outra categoria que enfrentou dificuldades e vem se adaptando a elas desde sua inserção no comércio eletrônico é a de vestuário.

A primeira opção que as lojas virtuais dessa categoria encontraram foi a de expressar em centímetros as medidas de seus produtos, uma vez que não existe um padrão entre o que é P, M, G ou GG. Uma alternativa eficaz, mas que foi complementada pela Realidade Aumentada.

Confira no vídeo abaixo a solução de realidade aumentada desenvolvida pela Zugara, uma empresa norte-americana especializada no desenvolvimento de softwares deste tipo.

O recurso de Realidade Aumentada pode atuar como um forte motivador de consumo, sobretudo para segmentos que demandam uma experiência mais próxima com o produto.

O e-commerce, em sua essência, é a reprodução, em ambiente virtual, de um processo tipicamente físico. Desde seu surgimento, as lojas virtuais buscam tornar a experiência da compra online o mais próxima possível de como ela seria pessoalmente. Essa é justamente a proposta da Realidade Aumentada e, por isso, ela deve ser vista como o próximo passo a ser dado em direção a um mercado virtual com cada vez menos lacunas separando-o do mercado físico.

iMasters

is_utf8 - Como verificar se um string está codificado em UTF-8

Quando você usa uma mescla de arquivos PHP com envios de formulários usando jQuery.ajax(), é quase impossível precisar quando o envio dos dados é feito pelo usuário através do submit normal da tag FORM ou se vem através do JavaScript.

Como o jQuery converte os dados do formulário para o formato UTF-8 antes de enviá-los, é necessário usar a função utf8_decode para utilizar os dados do formulário enviados.

Como, às vezes, pode haver arrays extensos, com muitos itens e índices, há duas funções interessantes para resolver esse problema, e são a solução para muitas dores de cabeça.
function is_utf8 ($str) {
    $len = strlen($str);

    for ($i=0; $i<$len; $i++){
        $c = ord($str[$i]);

        if ($c > 128) {
             if ($c > 247) return false;
            elseif ($c > 239) $bytes = 4;
            elseif ($c > 223) $bytes = 3;
            elseif ($c > 191) $bytes = 2;
            else return false;

            if (($i + $bytes) > $len) return false;

            while ($bytes > 1) {
                $i++;
                $b = ord($str[$i]);
                if ($b < 128 || $b > 191) return false;
                $bytes--;
            }
        }
    }

    return true;
}

function array_utf8_decode ($a) {
    foreach ($a as $k => $v) {
        $a[$k] = is_array($v) ? array_utf8_decode($v) : (is_string($v) && is_utf8($v) ? utf8_decode($v) : $v);
    }

    return $a;
}

$_POST = array_utf8_decode($_POST);
$_GET = array_utf8_decode($_GET);

Me vê um site especial de carne com Twitter, por favor!

Agora tudo é pedido com a maior naturalidade, como se você estivesse em uma feira, frente à frente ao programador, e aqueles vários sites fritando no óleo quente.

Brincadeiras à parte, por mais que desenvolver sites seja "commodities", dá muito trabalho fazer algo com qualidade e que agrade em demasia quem vai navegar, quem desenvolve e quem compra o serviço. Um bom projeto Web tem, no mínimo, quatro fases maiores.

Planejamento

Muitos ainda acham que durante esta fase ninguém trabalha, no entanto, planejar é entender o público-alvo, definir objetivos, estratégias e a tecnologia a ser utilizada. Conforme diz sabiamente Steve Krug no livro "Não me faça pensar", em vez de ficar discutindo o que o usuário prefere na interface, ou o que cada um prefere, é melhor fazer testes como ou com usuários potenciais.

Geralmente, nesse momento, deve-se contemplar um bom briefing e muito estudo, pois daqui sairá toda a forma de navegação do projeto que é chamada de wire-frame, como neste exemplo. O wire-frame/planejamento norteará todas as próximas fases, ou seja, é o melhor momento de errar, corrigir, revisar e corrigir novamente.

Criação

Ter um site bonito é fundamental! Mas, bonito pra quem? Isso não é gosto pessoal? Com base no que foi feito anteriormente, os designers de plantão podem "viajar", criar um conceito mirabolante, pintar, desenhar imergir no mundo da "arte for web". É bom lembrar que, para criar, todos os padrões de usabilidade devem ser colocados em prática, pois sabemos que não adianta ter o site mais lindo do mundo sem uma comunicação efetiva e estimulante para o usuário.

Programação

Mãos à obra! É o momento de pegar tudo aquilo que foi feito até agora e codificar. Sim, você entendeu certo: transformar a mais bela arte em código não é uma tarefa nada fácil e exige uma trabalhão!

Nesta etapa é importante uma ótima sinergia entre programadores e criadores, já que é um momento em que tudo tem que se transformar em páginas navegáveis, com menus funcionais, animações bem feitas e tudo abrindo corretamente em todas as últimas versões dos navegadores existentes. Pasmem, um bom programador, ou uma boa equipe de acordo com o tamanho do projeto, deve testar todo o site em browsers diferentes e se certificar de que tudo correu bem.

Homologação e publicação final

No ambiente de aprovações, o projeto é passado por uma bateria de testes, correções e até mesmo um pente fino no conteúdo para chegar ao tão esperado momento de colocar o site no ar.

Parece fácil? Bom, pra quem trabalha com isso e conhece de verdade, entende como deve ser valorizado um projeto com qualidade. Programadores, designers, redatores, arquitetos de informação, "searchs", "motions" etc. sabem que, pra fazer bonito, é necessário muito estudo e experiência.

Lembre-se: na próxima vez em que for à "feira", considere que existe um prazo razoável para o site ficar pronto com qualidade, pois todo mundo conhece a história do "barato e rápido que saiu caro". Afinal, bons profissionais devem ser muito bem remunerados, e isso não muda em nenhuma área.

iMasters