Shared posts

05 Mar 19:21

Hans-Juergen Schoenig: max_connections – Performance impacts

It has always been commonly known that settings max_connections to an insanely high value is not too good for performance. Generations of system administrators have followed this rule. Just out of curiosity I thought I’d give it a try to see, which impact setting max_connections in PostgreSQL  really has. Again we have used the same […]
28 Feb 13:10

Hans-Juergen Schoenig: Adjusting maintenance_work_mem

After testing shared_buffers recently, I decided to do a little bit more testing on our new office desktop PC (8 core AMD CPU, 4 GHZ, 8 GB RAM and a nice 128 GB Samsung 840 SSD). All tests were conducted on the SSD drive. This time I tested the impact of maintenance_work_mem on indexing speed. To […]
26 Feb 14:39

sinceridade

by Francisco Nunes

Há pessoas muito sinceras somente quando podem falar pelas costas.

(Francisco Nunes)

Send to Kindle
26 Feb 14:11

Lembranças de morrer (Álvares de Azevedo) – trecho

by Francisco Nunes

Descansem o meu leito solitário
Na floresta dos homens esquecida
À sombra de uma cruz e escrevam nela:
- Foi poeta, sonhou e amou na vida.

Send to Kindle
25 Feb 13:04

discussão

by Francisco Nunes

A meta de uma discussão ou debate não deveria ser a vitória, mas o progresso.

(Joseph Joubert)

Send to Kindle
25 Feb 13:01

O último dos Apaches

by Helio Loureiro

apache-1

Na última edição da newsletter do site Netcraft, vi uma estatística sobre o uso do Apache webserver que me deu um frio na barriga. Assim como o clássico americano “o último dos moicanos”, parece que estamos vivendo tempos de extinção também de projetos open sources.

Não, o projeto Apache não está acabando.

apache-2

De acordo com as estatísticas de servidores web no ar, coletadas mensalmente pela Netcraft desde quando eu soube o que era Internet (na verdade, desde que eu soube o que era Linux), o uso do Apache nunca esteve num patamar tão baixo de utilização. Os dados se comparam com os de 1995! Ou seja, depois de quase 20 anos reinando como o melhor webserver de todos, desbancando até os servidores proprietários da época como o da NCSA (era o Netscape?) e da própria Sun, agora o Apache vê seu rival IIS pronto pra tirar seu pódio e se tornar o mais usado servidor web.

Parte da culpa disso, é claro, vem da adoção do cloud da Microsoft, o Azure. Tem também a parcela de crescimento do “new kid on the block” do pedaço, o nginx. Mas parece ser inevitável uma mudança no comportamento de uso dos servidores web, trocando o open source pelo proprietário.

As consequências podem ser as piores possíveis, indo da diminuição de contribuições ao projeto Apache, o que talvez leve a um total abandono de seu uso, até o risco de a Microsoft enfiar algum serviço proprietário web, como um protocolo fechado, que só funcione em servidores IIS/Azure com browser Internet Explorer (vide protocolo do Exchange Server com o Outlook, o MAPI). Esse risco sempre existe quando se trata de Microsoft, que não pensa duas vezes em criar barreiras de uso pra aprisionar ainda mais seus usuários.

Por outro lado, mostra também que a grande maioria dos desenvolvedores estão migrando pra web. E infelizmente trazendo as péssimas práticas que aprenderam nas escolas, aquelas que têm todo um parque de ferramentas e máquinas doados pela Microsoft.

É triste de ver…

O post O último dos Apaches apareceu primeiro em .

25 Feb 12:50

Hans-Juergen Schoenig: PostgreSQL 9.3 – Shared Buffers Performance (1)

A lot has been said about PostgreSQL shared buffers and performance. As my new desktop box has arrived this week I decided to give it a try and see, how a simple benchmark performs, given various settings of shared_buffers. The first thing to run the test is to come up with a simple test database. […]
21 Feb 13:07

8 elementos HTML que você não está usando (e deveria)

by Landon Schropp

Na web de hoje, a palavra semântica tem sido usada a torto e a direito. Mas o que ela realmente quer dizer? Por que é importante?

HTML semântico expressa o significado do documento. É menos sobre como o texto parece e mais sobre o que ele é. Uma boa marcação semântica ajuda tanto às pessoas como aos robôs a entenderem o conteúdo e o seu contexto.

Marcação semântica é muito mais acessível e fácil para leitores de tela interpretarem. É amigável ao SEO. Trabalha melhor em browsers modernos. Reduz a quantidade de código necessária para expressar o conteúdo e aumenta a clareza do código para outras pessoas que o precisem ler.

Ok, então conteúdo semântico é ótimo, mas como se usa isso? Uma das melhores formas para começar a escrever marcações melhores é deixar de lado as tags genéricas e usar, no lugar, elementos mais expressivos. Veja aqui oito deles, que você pode usar para melhorar o seu jogo.

<q>

Assim como o seu “primo” <blockquote>, a tag <q> é usada para fazer citações de texto.

Por que não usar apenas aspas? Porque elas nem sempre indicam uma citação. Elas podem ser usadas para ênfase, ironia, ou para identificar o nome de algo. Nesses casos, as aspas usadas diretamente no conteúdo são muito válidas. No entanto, se você está citando alguém, <q> deixa o que você quer falar totalmente claro.

<i> e <b>

No passado, <i> e <b> eram usados para identificar itálicos e negritos. Quando a ideia de separar o conteúdo semântico da apresentação começou a ganhar um impulso, usar <i> e <b> se tornou algo mal visto porque eles representam como o texto será mostrado, em vez do que eles significam. Eles foram substituídos por <em> e <strong>, que indicam um texto “enfatizado” e “fortemente enfatizado”.

Com o HMTL5, <i> e <b> agora têm uma representação semântica totalmente nova. A tag <i> é usada para texto que está em um tom diferente. É útil para coisas como pensamentos e termos técnicos. A tag <b> identifica texto que tem um estilo diferente do texto normal, mas não uma diferença semântica. De que forma é diferente de usar o <span>? O ponto chave é que o <b> comunica uma falta de sentido semântico.

<abbr>

<abbr> é usado para abreviações! Pode ser muito útil em documentos com várias abreviações, e ainda há um atributo opcional de título que contém a versão não abreviada do texto.

<abbr title="laugh out loud">lol</abbr>
<abbr title="I don't know">idk</abbr>
<abbr title="got to go">g2g</abbr>
<abbr title="talk to you later">ttyl</abbr>

<time>

Vamos observar um problema clássico de localização: datas. Nos EUA, por exemplo, 5 de outubro de 2013 é representado por 10/05/13. No Reino Unido, é 05/10/2013. Na Holanda, seria escrito assim: 05-10-13; na África do Sul, 2013/10/05 e na Rússia é 05.10.13. Com tantas possibilidades, é difícil para uma máquina ler corretamente as datas em todas essas diferentes localidades.

A tag <time> permite que você represente horas e datas em um formato compreensível pela máquina. O exemplo acima poderia ser escrito como <time datetime=”2013-10-05″>10/05/13</time>. Um parser HTML pode usar isso para determinar a hora exata que você quer, independentemente do format. A tag <time>  também permite usar um formato de 24 horas: <time datetime=”2013-10-05 22:00″>10/05/13 at 10 PM</time>;

<mark>

Você já fez algo assim?

<p>
  Trezentas páginas de um texto chato e inútil. <span class="highlight">A única coisa que você precisa mesmo saber e nunca mais vai achar se não grifar.</span> Mais texto chato.
</p>

Bom, agora você não precisa mais fazer isso. O HTML5 introduziu o elemento <mark>, que representa texto que foi grifado com um propósito referencial devido à sua importância em outro contexto.

<input>

Sim, <input>. Provavelmente você já usou <input type=”text”><input type=”submit”> e talvez até mesmo <input type=”hidden”>, mas e as outras formas? Com HTML5 os <input> podem ser usados com uma variedade de tipos, incluindo:

  • email
  • tel
  • number
  • range
  • date
  • time
  • search
  • color

Eles são ótimos, mas garanta que estão de acordo com os requerimentos do seu browser. Alguns tipos ainda não são suportados por todos os grandes navegadores.

<menu>

Você já fez uma marcação de menu com uma lista não-ordenada?

<ul class="menu-toolbar">
  <li class="new">New</li>
  <li class="open">Open</li>
  <li class="save">Save</li>
  <li class="quit">Quit</li>
</ul>

Bem, pare com isso! A tag menu tem exatamente esse propósito. O elemento <menu> representa uma lista não-ordenada de comandos. Ele tem um atributo type, que pode ser setado para popup ou toolbar.

<menu type="toolbar">
  <li class="new">New</li>
  <li class="open">Open</li>
  <li class="save">Save</li>
  <li class="quit">Quit</li>
</menu>

Bônus

A maioria dos desenvolvedores front end já usaram &nbsp; quando escrevendo HTML, mas muitos não sabem o real significado disso. Um espaço não-quebrável não vai quebrar em uma nova linha, então esses dois mundos ficarão juntos ao final de uma sentença. Isso é útil quando a quebra de palavras parece ser disruptiva. Alguns ótimos exemplos:

  • Unidades de tempo/medida: 12 m/s
  • Tempo: 8 PM
  • Nomes Próprios: Dairy Queen

Além disso, tenha certeza de ver também o hífen sem quebra (), que permite que você utilize um caractere de hífen, sem quebrar a linha.

Resumindo tudo

HTML está se tornando mais semântico a cada dia. Usar esses elementos é uma ótima forma de começar marcações mais limpas e acessíveis. Para ver todas as opções disponíveis, veja a Tabela Períodica de Elementos, a documentação da Mozilla Developer Network, ou, se você estiver com coragem, a especificação de HTML do W3C. Divirta-se!

***

Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em http://davidwalsh.name/8-html-elements

 

Mensagem do anunciante:

Aprenda WordPress de uma vez por todas com os cursos especializados em WP do Apiki WP Cursos. Conheça!

O post 8 elementos HTML que você não está usando (e deveria) apareceu primeiro em .

18 Feb 21:54

Dimitri Fontaine: Aggregating NBA data, PostgreSQL vs MongoDB

When reading the article Crunching 30 Years of NBA Data with MongoDB Aggregation I coulnd't help but think that we've been enjoying aggregates in SQL for 3 or 4 decades already. When using PostgreSQL it's even easy to actually add your own aggregates given the SQL command create aggregate.

Photo Credit: Copyright All rights reserved by Segward Graupner

The next step after thinking how obvious the queries written in the mentionned article would be to express in SQL was to actually load the data into PostgreSQL and write the aggregate queries, of course.

Loading the data

With the help of a little bit of Common Lisp code and using the mongo-cl-driver it was easy enough to parse the given BSON file. What was more complex was to actually understand enough of the data model to produce a relational design out of it, avoiding data redundancy as much as possible.

We call that step normalization in old-style relational databases, and the goal of that process is to avoid functional dependency so that the data is easier to understand, verify and process the data once loaded.

For instance, rather than have both scores from each team and a column won per team, which would be a boolean but is a number in the given BSON file, we store only the scores. Here's the main table definition of the stats we are going to be playing with, the game table:

create table nba.game (
  id          serial primary key,
  date        timestamptz,
  host        int references nba.team(id),
  guest       int references nba.team(id),
  host_score  int,
  guest_score int
);

As much of the aggregates in the referenced article are playing with statistics from teams who actually won the game, let's create a view to simplify our SQL queries thereafter:

create view winners as
  select id,
         date,
         case when host_score > guest_score
              then host
              else guest
          end as winner
    from game;

If you're not doing much SQL, remember that creating such a view is common practice in the relational world.

Running the Aggregates

Now that we have the extra useful view, it's possible to implement the first MongoDB query in SQL. First, let's have a look at the MongoDB query:

db.games.aggregate([
  {
    $match : {
      date : {
        $gt : ISODate("1999-08-01T00:00:00Z"),
        $lt : ISODate("2000-08-01T00:00:00Z")
      }
    }
  },
  {
    $unwind : '$teams'
  },
  {
    $match : {
      'teams.won' : 1
    }
  },
  {
    $group : {
      _id : '$teams.name',
      wins : { $sum : 1 }
    }
  },
  {
    $sort : { wins : -1 }
  },
  {
    $limit : 5
  }
]);

I don't know about you, but I have quite a hard time deciphering what that query is actually doing, and when the explanation text talks about using a 6-stage pipeline my understanding is that the application developper has been writing the execution plan of the query here. Let's ignore the query format itself, as it's obviously meant to be generated by a tool rather than typed by a human being.

Here's the same query in SQL, with the result this time:

  SELECT abbrev, name, count(*)
    FROM winners JOIN team ON team.id = winners.winner
   WHERE     date > '1999-08-01T00:00:00Z'
         AND date < '2000-08-01T00:00:00Z'
GROUP BY winner, abbrev, name
ORDER BY count(*) DESC
   LIMIT 5;

 abbrev |          name          | count 
--------+------------------------+-------
 LAL    | Los Angeles Lakers     |    67
 POR    | Portland Trail Blazers |    59
 IND    | Indiana Pacers         |    56
 UTA    | Utah Jazz              |    55
 SAS    | San Antonio Spurs      |    53
(5 rows)

Time: 8.101 ms

What we have here is a pretty basic query using a join, a where clause to restrict the data set we are playing with, a group by clause to define which data to computa the aggregates against, with an order by and a limit clause for presenting the result. To be realistic, if you've ever done any SQL at all, then you know how to read that query because you've been writing dozens of similar ones.

Here's, as in the original article, the same query against a much larger data set this time, with all games of the 2000s decade:

   SELECT abbrev, name, count(*)
     FROM winners join team on team.id = winners.winner
    WHERE     date > '2000-08-01T00:00:00Z'
          AND date < '2010-08-01T00:00:00Z'
 GROUP BY winner, abbrev, name
 ORDER BY count(*) DESC
    LIMIT 5;

 abbrev |        name        | count 
--------+--------------------+-------
 SAS    | San Antonio Spurs  |   579
 DAL    | Dallas Mavericks   |   568
 LAL    | Los Angeles Lakers |   524
 PHO    | Phoenix Suns       |   495
 DET    | Detroit Pistons    |   489
(5 rows)

Time: 24.713 ms

Correlating stats with wins

The goal here is to compute how often a team wins when they record more defensive rebounds than their opponent across the entire data set.

To be able to compute the percentage, we have to have a count of all registered games, of course. Then we are going to count how many times the winner team registered a greater team_stats.drb than the loser, and count how many times in SQL is usually written as a sum(case when <condition> then 1 else 0 end), which is what we're doing here:

select count(*) as games,
       sum(case when ws.drb > ls.drb then 1 else 0 end) as drb,
       sum(case when ws.drb > ls.drb then 1 else 0 end)::float / count(*) * 100 as pct
  from winlose wl
       join team w on wl.winner = w.id
       join team l on wl.loser = l.id
       join team_stats ws on ws.game = wl.id and ws.team = wl.winner
       join team_stats ls on ls.game = wl.id and ls.team = wl.loser;

 games |  drb  |       pct        
-------+-------+------------------
 31686 | 22292 | 70.3528372151739
(1 row)

Time: 276.669 ms

We note here than in the original MongoDB article the aggregation query is short of computing the percentage directly, apparently it's been done in the client tool, maybe using a spreadsheet application or something.

Defensive Rebounds and Total Rebounds Versus Win Percentage

Next, still following on our inspirational article Crunching 30 Years of NBA Data with MongoDB Aggregation, we’re going to compute what percentage of the time a team wins as a function of the number of defensive rebounds they recorded.

I'm not sure I understand what they achieve with averaging ones when a team wins and zero when a team loses, so I couldn't quite reproduce their result. Here's an approaching query tho:

with game_stats as (
    select t.id, count(*)
      from team t join game on game.host = t.id or game.guest = t.id
   group by t.id
)
select ts.team, round(avg(drb), 2) as drb,
       round(count(*) / gs.count::numeric * 100, 2) as winpct,
       count(*) as wins, gs.count as games
  from team_stats ts
       join game on game.id = ts.game
                and game.host = ts.team
                and game.host_score > game.guest_score
       join game_stats gs on gs.id = ts.team
group by ts.team, gs.count;

 team |  drb  | winpct | wins | games 
------+-------+--------+------+-------
    4 | 31.59 |  31.46 |  710 |  2257
    7 | 32.55 |  31.89 |  720 |  2258
   16 | 31.70 |  37.62 |  849 |  2257

I only pasted the first few lines of the result because I'm not sure how to make sense of it, really.

Interesting factoid

What I find most interesting in the following factoid proposed in the MongoDB article is the complete lack of the query you need to run in order to grab the matching data:

An interesting factoid: the team that recorded the fewest defensive rebounds in a win was the 1995-96 Toronto Raptors, who beat the Milwaukee Bucks 93-87 on 12/26/1995 despite recording only 14 defensive rebounds.

When doing the necessary query in SQL, using a Common Table Expression (the WITH syntax) and a Window Function for good measure, we get actually 4 different games with the minimum defensive rebounds in our history of NBA games, 14:

with stats(game, team, drb, min) as (
    select ts.game, ts.team, drb, min(drb) over ()
      from team_stats ts
           join winners w on w.id = ts.game and w.winner = ts.team
)
select game.date::date,
       host.name || ' -- ' || host_score as host,
       guest.name || ' -- ' || guest_score as guest,
       stats.drb as winner_drb
  from stats
       join game on game.id = stats.game
       join team host on host.id = game.host
       join team guest on guest.id = game.guest
 where drb = min;

-[ RECORD 1 ]----------------------------
date       | 1995-12-26
host       | Toronto Raptors -- 93
guest      | Milwaukee Bucks -- 87
winner_drb | 14
-[ RECORD 2 ]----------------------------
date       | 1996-02-02
host       | Golden State Warriors -- 114
guest      | Toronto Raptors -- 111
winner_drb | 14
-[ RECORD 3 ]----------------------------
date       | 1998-03-31
host       | Vancouver Grizzlies -- 101
guest      | Dallas Mavericks -- 104
winner_drb | 14
-[ RECORD 4 ]----------------------------
date       | 2009-01-14
host       | New York Knicks -- 128
guest      | Washington Wizards -- 122
winner_drb | 14

Time: 126.276 ms

To understand all there's to know about window functions, have a look at my article on the topic: Understanding Window Functions.

Total rebounds and wins

The next interesting aside is the following:

As an aside, the Cleveland Cavaliers beat the New York Knicks 101-97 on April 11, 1996, despite recording only 21 total rebounds. Inversely, the San Antonio Spurs lost to the Houston Rockets, 112-110, on January 4, 1992 despite recording 75 total rebounds.

Which we translate in SQL as the following query:

with stats as (
    select ts.game, ts.team, trb,
           min(trb) over () as min,
           max(trb) over () as max
      from team_stats ts
           join winners w on w.id = ts.game and w.winner = ts.team
)
select game.date::date,
       host.name || ' -- ' || host_score as host,
       guest.name || ' -- ' || guest_score as guest,
       stats.trb as winner_trb
  from stats
       join game on game.id = stats.game
       join team host on host.id = game.host
       join team guest on guest.id = game.guest
 where trb = min or trb = max;

-[ RECORD 1 ]--------------------------
date       | 1995-12-28
host       | Dallas Mavericks -- 103
guest      | Vancouver Grizzlies -- 101
winner_trb | 76
-[ RECORD 2 ]--------------------------
date       | 1996-04-11
host       | New York Knicks -- 97
guest      | Cleveland Cavaliers -- 101
winner_trb | 21
-[ RECORD 3 ]--------------------------
date       | 2007-01-29
host       | Utah Jazz -- 115
guest      | New Jersey Nets -- 116
winner_trb | 21

Time: 127.771 ms

Again it's easy enough in SQL to have more details about the aside presented in our source article, and we get a slightly different story.

Conclusion

It's quite hard for me to appreciate the work done in the MongoDB aggregation framework really, when we've been enjoying advanced aggregation and statistics in PostgreSQL for a very long time. With the addition of Window Functions and Aggregate Functions for Statistics it's possible to implement advanced analysis right into your SQL queries.

In next PostgreSQL release the set of analytical functions is going to expand again withe addition of both Ordered-Set Aggregate Functions (also known as inverse distribution functions) and Hypothetical-Set Aggregate Functions (also known as WITHIN GROUP).

PostgreSQL is YeSQL!

When the problem you have to solve involves analyzing data, one of the more advanced tooling you can find around certainly is the SQL language, in particular its implementation in PostgreSQL!

18 Feb 21:20

VPS vs Servidor Dedicado vs Servidor Cloud

by Pedro Pinto
Por João Simões para o Pplware Qual é a melhor opção para o meu negócio, ou para o meu cliente? Esta é uma questão cada vez mais programadores de pequenas e médias empresas ou freelancers, fazem acerca do alojamento das suas aplicações e/ou páginas web. Em primeiro lugar, é muito importante frisar que qualquer modelo […]
18 Feb 20:59

Simples e Útil: Visões Materializadas no PostgreSQL!

by Cláudio Leopoldino
Visões materializadas são recursos introduzidos na versão 9.3 do postgresql. Enquanto visões tradicionais reexecutam uma consulta sempre que são referenciadas, visões materializadas dispensam este esforço pelos seus dados já estarem guardados desde a sua criação ou do último refresh (atualização de visão). Pode-se dizer que uma visão materializada é um objeto que contém o resultado de uma consulta, facilitando o acesso aos dados nela contidos.

A principal justificativa para se utilizar visões materializadas é a aceleração de consultas em grandes massas de dados. É importante observar que em sistemas com pouco espaço em disco e discos lentos, visões materializadas podem ter pouco efeito ou até impacto negativo por sobrecarregar ainda mais o hardware.

No postgresql, a atualização de uma visão materializada é feita através do comando REFRESH MATERIALIZED VIEW, enquanto que a mudança do código da consulta da visão é feita através do comando ALTER MATERIALIZED VIEW. A exclusão de visões materializadas é feita com o comendo DROP MATERIALIZED VIEW.

Sintaxe básica:

CREATE MATERIALIZED VIEW nome_tabela
    [ (nome_coluna [, ...] ) ]
    [ WITH ( storage_parameter [= value] [, ... ] ) ]
    [ TABLESPACE nome_tablespace ]
    AS consulta
    [ WITH [ NO ] DATA ]

Exemplo 1: Criação de uma visão materializada simples

CREATE MATERIALIZED VIEW lista_tabelas AS
SELECT tablename FROM PG_TABLES ORDER BY tablename;

Exemplo 2: Refresh dos dados de uma visão materializada, pelo comando REFRESH MATERIALIZED VIEW.

REFRESH MATERIALIZED VIEW lista_tabelas;

Exemplo 3: Exclusão de uma visão materializada utilizando DROP MATERIALIZED VIEW. O comando drop view não exclui visões materializadas, e sim gera erro.

DROP MATERIALIZED VIEW lista_tabelas;

Exemplo 4: Criação de uma visão materializada sem dados. Neste caso, o comando REFRESH MATERIALIZED VIEW pode ser utilizado para popular a visão armazenada.

CREATE MATERIALIZED VIEW lista_tabelas_nodata AS
SELECT tablename FROM PG_TABLES ORDER BY tablename WITH NO DATA;

Exemplo 5: Criação de uma visão materializada simples, explicitando o tablespace utilizado

CREATE MATERIALIZED VIEW lista_indices TABLESPACE pg_default AS
SELECT schemaname, tablename, indexname, tablespace FROM PG_INDEXES;

Exemplo 6: Criação de uma visão materializada simples, utilizando o storage parameter fillfactor. São aceitos todos os tipos de storage parameters de uma tabela padrão, exceto OIDs, pois visões materializadas não apresentam identificador OID para cada registro.

CREATE MATERIALIZED VIEW lista_indices_fill50 WITH (fillfactor = 50) AS
SELECT schemaname, tablename, indexname, tablespace FROM PG_INDEXES;

Exemplo 7: Para saber quantas visões armazenadas você tem no seu servidor, utilize a visão PG_MATVIEWS.

SELECT * FROM PG_MATVIEWS;

Exemplo 8: Alteração de visão materializada. O comando ALTER MATERIALIZED VIEW apresenta uma sintaxe mais elaborada, merecendo mais espaço em um texto futuro.

ALTER MATERIALIZED VIEW lista_tabelas RENAME TO lista_relacoes;

* Conclusões

Visões materializadas são uma boa opção para aumento de performance sob certas condições.

Também facilitam a importação de visões materializadas disponíveis em outros SGBDs como ORACLE e SQL SERVER.

A implementação de visões materializadas é relativamente fácil e bastante útil.

Você já utilizou esta funcionalidade nos seus projetos? Qual foi a sua opinião?
Meu Blog de PostgreSQL - http://postgresqlbr.blogspot.com/ - Cláudio Bezerra Leopoldino
18 Feb 19:32

Sehrope Sarkuni: How I Write SQL, Part 1: Naming Conventions

Background

"There are only two hard problems in Computer Science: cache invalidation and naming things."

-- Phil Karlton

In this post I'll be going into the latter. Specifically, I'll describe naming conventions for database objects, why they are so important, and what you should and shouldn't be doing.

Warning! This is a fairly opinionated post and I welcome feedback from people suggesting alternatives.

Target Audience

Our company, JackDB, uses PostgreSQL internally to store persistent state and the naming conventions in this post were written with PostgreSQL in mind. Most of the recommendations should be equally valid for other relational databases such as MySQL, Oracle, or Microsoft SQL Server.

A lot of them will also apply to NoSQL databases, though not everything. For example, the suggestion below to use full english words goes against the recommended approach for naming fields in MongoDB. When in doubt, find a guide for your specific database type.

Why Naming Conventions Are Important

Names Are Long Lived

Data structures are meant to last much longer than application code. Anyone that has worked on a long running system can attest to that.

Well defined data structures and table layouts will outlive any application code. It's not uncommon to see an application completely rewritten without any changes done to its database schema.

Names Are Contracts

Database objects are referenced by their names, thus object names are part of the contract for an object. In a way you can consider your database table and column names to be the API to your data model.

Once they are set, changing them may break dependent applications. This is all the more reason to name things properly before the first use.

Developer Context Switching

Having consistent naming conventions across your data model means that developers will need to spend less time looking up the names of tables, views, and columns. Writing and debugging SQL is easier when you know that person_id must be a foreign key to the id field of the person table.

Naming Conventions

Avoid quotes. If you have to quote an identifier then you should rename it. Quoted identifiers are a serious pain. Writing SQL by hand using quoted identifiers is frustrating and writing dynamic SQL that involves quoted identifiers is even more frustrating.

This also means that you should never include whitespace in identifier names.

Ex: Avoid using names like "FirstName" or "All Employees".

Lowercase. Identifiers should be written entirely in lower case. This includes tables, views, column, and everything else too. Mixed case identifier names means that every usage of the identifier will need to be quoted in double quotes (which we already said are not allowed).

Ex: Use first_name, not "First_Name".

Data types are not names. Database object names, particularly column names, should be a noun describing the field or object. Avoid using words that are just data types such as text or timestamp. The latter is particularly bad as it provides zero context.

Underscores separate words. Object name that are comprised of multiple words should be separated by underscores (ie. snake case).

Ex: Use word_count or team_member_id, not wordcount or wordCount.

Full words, not abbreviations. Object names should be full English words. In general avoid abbreviations, especially if they're just the type that removes vowels. Most SQL databases support at least 30-character names which should be more than enough for a couple English words. PostgreSQL supports up to 63-character for identifiers.

Ex: Use middle_name, not mid_nm.

Use common abbreviations. For a few long words the abbreviation is both more common than the word itself. "Internationalization" and "localization" are the two that come up most often as i18n and l10n respectively. In these cases use the abbreviation.

If you're in doubt, use the full English word. It should be obvious where the abbreviation makes sense.

Avoid reserved words. Avoid using any word that is considered a reserved word in the database that you are using. There aren't that many of them so it's not too much effort to pick a different word. Depending on the context, reserved words may require quoting. This means sometimes you'll write "user" and sometimes just user.

Another benefit of avoiding reserved words is that less-than-intelligent editor syntax highlighting won't erroneously highlight them.

Ex: Avoid using words like user, lock, or table.

Here are the list of reserved words for PostgreSQL, MySQL, Oracle, and MSSQL.

Singular Relations

Tables, views, and other relations that hold data should have singular names, not plural. This means our tables and views would be named team, not teams.

Rather than going into the relational algebra explanation of why this is correct I'll give a few practical reasons.

They're Consistent. It's possible to have a relation that holds a single row. Is it still plural?

They're unambiguous. Using only singular names means you don't need to determine how to pluralize nouns.

Ex: Does a "Person" object go into a "Persons" relation or a "People" one? How about an "Octopus" object? Octopuses? Octopi? Octopodes?

Straightforward 4GL Translation. Singular names allow you to directly translate from 4GL objects to database relations. You may need to remove some underscores and switch to camel case but the name translation will always be straight forward.

Ex: team_member unambigously becomes the class TeamMember in Java or the variable team_member in Python.

Key Fields

Primary Keys

Single column primary key fields should be named id. It's short, simple, and unambiguous. This means that when you're writing SQL you don't have to remember the names of the fields to join on.

CREATE TABLE person (
  id            bigint PRIMARY KEY,
  full_name     text NOT NULL,
  birth_date    date NOT NULL);

Some guides suggest prefixing the table name in the primary key field name, ie. person_id vs id. The extra prefix is redundant. All field names in non-trivial SQL statements (i.e. those with more than one table) should be explicitly qualified and prefixing as a form of namespacing field names is a bad idea.

Foreign Keys

Foreign key fields should be a combination of the name of the referenced table and the name of the referenced fields. For single column foreign keys (by far the most common case) this will be something like foo_id.

CREATE TABLE team_member (
  team_id       bigint NOT NULL REFERENCES team(id),
  person_id     bigint NOT NULL REFERENCES person(id),
  CONSTRAINT team_member_pkey PRIMARY KEY (team_id, person_id));

Prefixes and Suffixes (are bad)

Relation Type Prefixes

Some (older) guidelines suggest naming tables with a TB_ prefix, views with a VW_ prefix, or stored procedures with a SP_ prefix. The rationale being that a programmer reading through some unknown SQL would immediately recognize this and know the object type based on the name. This is a bad idea.

Object names should not include the object type in them. That way you can change it later. A view that is replaced with a table maintains the original contract of a view (ex: you can SELECT from it). A dependent system would not need to be updated after such a change.

I've seen many such systems where at some point a view will become a table. Then you'll end up with code issuing INSERT statements into vw_foobar. There's even a really powerful feature of PostgreSQL that allows you do define DML rules on views (ie. you can INSERT/UPDATE/DELETE from them).

Adding object type prefixes adds extra typing now and extra confusion down the road.

Application Name Prefixes

Another (older) suggestion is to have a common prefix for all your database objects. For example, our app "Foobar" would have tables name Foobar_Users, Foobar_Teams, etc. Again, this is a bad idea.

All modern databases support some form of namespacing. For example, in PostgreSQL you can create schemas to group database objects. If you have multiple applications sharing the same database and want to prevent them from clobbering each other, use schemas instead. That's exactly what they are for!

Most people will not even need them though. It's far more common for a database to be used with a single logical data model than multiple, separate data models. Hence schemas will not be required. If you do need them, it should be fairly obvious.

The exception to this rule is if you are developing a database agnostic code base such as a framework or plugin. Supporting multiple namespacing methods is complicated so many frameworks instead rely on application name prefixing.

However, most people develop applications, not plugins or frameworks, and their applications will reside by themselves in a single type of database. Thus there is no reason to add application name prefixes to all your database objects.

Data Type Suffixes

Some guides (again generally older ones), suggest suffixing your column names with the data type of the field. For example, a text field for a name would be name_tx. There will even be extensive lists to translate from data types to suffixes, text -> tx, date -> dt, etc.

This is a bad idea!

Field data types can change. A date field could become a timestamp, an int could become a bigint or numeric.

Explicit Naming

Some database commands that create database objects do not require you specify a name. An object name will be generated either randomly (ex: fk239nxvknvsdvi) or via a formula (ex: foobar_ix_1). Unless you know exactly how a name will be generated and you are happy with it, you should be explicitly specifying names.

This also includes names generated by ORMs. Many ORMs default to creating indexes and constraints with long gibberish generated names. The couple minutes of time savings in the short run are not worth the head ache in remembering what fkas9dfnksdfnks refers to in the long run.

Indexes

Indexes should be explicitly named and include both the table name and the column name(s) indexed. Including the column names make it much easier to read through SQL explain plans. If an index is named foobar_ix1 then you would need to look up what columns that index covers to understand if it is being used correctly.

CREATE TABLE personx (
  id          bigserial PRIMARY KEY,
  email       text NOT NULL,
  first_name  text NOT NULL,
  last_name   text NOT NULL,
  CONSTRAINT person_ck_email_lower_case CHECK (email = LOWER(email)));

CREATE INDEX person_ix_first_name_last_name ON person (first_name, last_name);

Explain plans will now be easy to understand. We can clearly see that the index on first name and last name, ie. person_ix_first_name_last_name, is being used:

=# EXPLAIN SELECT * FROM person WHERE first_name = 'alice' AND last_name = 'smith';

                                          QUERY PLAN                                          
----------------------------------------------------------------------------------------------
 Index Scan using person_ix_first_name_last_name on person  (cost=0.15..8.17 rows=1 width=72)
   Index Cond: ((first_name = 'alice'::text) AND (last_name = 'smith'::text))
(2 rows)

Constraints

Similar to indexes, constraints should given descriptive names. This is especially true for check constraints. It's much easier to diagnose an errant insert if the check constraint that was violated lets you know the cause.

CREATE TABLE team (
  id          bigserial PRIMARY KEY,
  name        text NOT NULL,
  CONSTRAINT team_);

CREATE TABLE team_member (
  team_id     bigint REFERENCES team(id),
  person_id   bigint REFERENCES person(id),
  CONSTRAINT team_member_pkey PRIMARY KEY (team_id, person_id));

Notice how PostgreSQL does a good job of giving descriptive names to the foreign key constraints.

=# \d team_member
   Table "public.team_member"
  Column   |  Type  | Modifiers 
-----------+--------+-----------
 team_id   | bigint | not null
 person_id | bigint | not null
Indexes:
    "team_member_pkey" PRIMARY KEY, btree (team_id, person_id)
Foreign-key constraints:
    "team_member_person_id_fkey" FOREIGN KEY (person_id) REFERENCES person(id)
    "team_member_team_id_fkey" FOREIGN KEY (team_id) REFERENCES team(id)

If we try inserting a row that violates one of these constraints we immediately know the cause just based on the constraint name:

=> INSERT INTO team_member(team_id, person_id) VALUES (1234, 5678);
ERROR:  insert or update on table "team_member" violates foreign key constraint "team_member_team_id_fkey"
DETAIL:  Key (team_id)=(1234) is not present in table "team".

Similarly, if we try inserting an email address that is not lower case into the person table created above, we'll get a constraint violation error that tells us exactly what is wrong:

-- This insert will work:
=> INSERT INTO person (email, first_name, last_name) VALUES ('alice@example.com', 'Alice', 'Anderson');
INSERT 0 1

-- This insert will not work:
=> INSERT INTO person (email, first_name, last_name) VALUES ('bob@EXAMPLE.com', 'Bob', 'Barker');
ERROR:  new row for relation "person" violates check constraint "person_ck_email_lower_case"
DETAIL:  Failing row contains (2, bob@EXAMPLE.com, Bob, Barker).

Final Thoughts

If you're starting a new project then I suggest you follow the conventions outlined here. If you're working on an existing project then you need to be a bit more careful with any new objects you create.

The only thing worse than bad naming conventions is multiple naming conventions. If your existing project already has a standard approach to naming its database objects then keep using it.

Do you have something to add to this list, a way to improve some of these guidelines, or just think some of these are terrible? Let me know!

17 Feb 12:35

Craig Kerstiens: PostgreSQL 9.4 - What I was hoping for

Theres no doubt that the 9.4 release of PostgreSQL will have some great improvements. However, for all of the improvements it delivering it had the promise of being perhaps the most impactful release of Postgres yet. Several of the features that would have given it my stamp of best release in at least 5 years are now already not making it and a few others are still on the border. Here's a look at few of the things that were hoped for and not to be at least until another 18 months.

Upsert

Upsert, merge, whatever you want to call it, this is been a sore hole for sometime now. Essentially this is insert based on this ID or if that key already exists update other values. This was something being worked on pretty early on in this release, and throughout the process continuing to make progress. Yet as progress was made so were exteneded discussions about syntax, approach, etc. In the end two differing views on how it should be implemented have the patch still sitting there with other thoughts on an implementation but not code ready to commit.

At the same time I'll acknowledge upsert as a hard problem to address. The locking and concurrency issues are non-trivial, but regardless of those having this in there mostly kills the final argument for anyone to chose MySQL.

Better JSON

JSON is Postgres is super flexible, powerful, and generally slow. Postgres does validation and some parsing of JSON, but without something like PLV8, or functional indexes you may not get great performance. This is because under the covers the JSON is represented as text and as a result many of the more powerful indexes that could lend benefit, such as GIN or GIST, simply don't apply here.

As a related effort to this hstore, the key/value store, is working on being updated. This new support will add types and nesting making it much more usable overall. However the syntax and matching of how JSON functions isn't guranteed to be part of it. The proposal and actually work is still there and not rejected yet, but looks heavily at risk. Backing a new binary representation of JSON with hstore 2 would deliver so many benefits further building upon the foundation of hstore, JSON, PLV8 that exists today for Postgres.

apt-get for your extensions

I'm almost not even sure where to start with this one. The notion within a Postgres community is that packaging for distros is super simple and extensions should just be packaged for them. Then there's PGXN the Postgres extension network where you can download and compile and muck with annoying settings to get extensions to build. This proposal would have delivered a built in installer much like NPM or rubygems or PyPi and the ability for someone to simply say install extension from this centralized repository. No, it was setting out to solve the issue of having a single repository but would make it much easier for people to run one.

For all the awesome-ness that exists in extensions such as HyperLogLog, foreign data wrappers, madlib theres hundreds of other extensions that could be written and be valuable. They don't even all require C, they could fully exist in JavaScript with PLV8. Yet I'm on the fence encouraging people to write such because if no one uses it then much of the point in the reusability of an extension is lost. Here's hoping that there's a change of opinion in the future that packaging is a solved problem and that creating an ecosystem for others to contribute to the Postgres world without knowing C is a positive thing.

Logical replication

When I first heard this might have some shot at making it in 9.4 I was shocked. This is something that while some may not take notice of I've felt pain of for many years. Logical replication means in short enabling upgrades across PostgreSQL versions without a dump and restore, but even more so laying the ground work for more complicated architectures like perhaps multi-master. Yes, even with logical replication in theres still plenty of work to do, but having the groundwork laid goes a long way. There are options for it today with third party tools, but the management of these is painful at best.

In conclusion

The positive of this one is that the building blocks are in and its continuing to make progress. Its just that we'll have to wait about 18 months before the release of PostgreSQL 9.5 before its in our hands.

15 Feb 17:12

An AngularJS Style Guide and Best Practice for App Structure

by Naomi Black
Want to know more about AngularJS Best Practices, as we use them at Google?


UPDATE 4/19/2015: The most current and detailed Angular Style Guide is the community-driven effort led by John Papa and Todd Motto, which you can find at https://github.com/johnpapa/angular-styleguide. Please use this instead of the one mentioned below.

You can now find a published copy of Google's AngularJS Style guide at https://google-styleguide.googlecode.com/svn/trunk/angularjs-google-style.html. While this documents how we use AngularJS in production code at Google, you'll notice that the style guide is heavily biased towards JSCompiler optimizations and the needs of large code bases. We don't think this makes sense for all projects that use AngularJS, and we'd love to see our community of developers come up with a more general Style that's applicable to AngularJS projects large and small. Interested in helping or leading this project? Sign up here, and choose "Style Guide for Angular" and we'll be in touch.

We've also published some new Best Practice Recommendations for Angular App Structure. One of our goals is to come up with a recommendation that meets the needs of both large and small app developers, so that we can start developing tooling that makes development easier. If you're not using this recommended structure yet, don't worry. It's fine to keep doing what you're doing. At some point, we hope the efficiency gain of having more developer tools will make it worth your time to convert over.

14 Feb 12:01

Desmistificando URLs amigáveis com php e htaccess (apache)

by William Bruno

Boas!!
A quantidade de pessoas que perguntam como fazer URLs amigáveis no forum.imasters é enorme. Seja em WebStandars, SEO ou php, a dúvida é sempre a mesma.

É simples de fazer. Basta ir com calma e procurar entender tudo o que você está fazendo.

A reescrita é para o servidor, e não para você

As suas tags de link e a forma com que vc abrirá os seus conteúdos, você mesmo terá que alterar. Então onde você usava:

<a href="?page=contato">Contato</a>

Agora passará a escrever:

<a href="/contato">Contato</a>

E se precisar de mais parâmetros, indique-os:

<a href="/edit/user/1">Editar usuário</a>

Isso significa, que o servidor irá receber a requisição em /contato, ou /edit/user/1, e com a RewriteEngine, irá traduzir para o que vc realmente queria dizer, que era ?page=contato, ou ?action=edit&model=user&id=1.

Fica muito mais bonito depois de reescrito, mas para isso é necessário que as suas regras traduzam o amigável para a querystring.

Estude expressões regulares

O arquivo .htaccess que é uma “configuração” externa do apache, acessível da sua aplicação, desde que liberado na configuração do servidor, te possibilita a configurar diversas coisas do ambiente. E as RewriteRules fazem ainda mais sentido, e serão mais poderosas se vc souber Expressões Regulares.

Ahh página em branco, erro 500

São duas as possibilidades, ou a sua hospedagem não suporta configuração via htaccess (muito difícil), ou vc cometeu algum erro de sintaxe, e quebrou o servidor, lembra que o htaccess é um arquivo externo de configuração do apache ? pois é, faça algo errado, que vc terá um 500 na tela.

Não é necessário re-startar o servidor após escrever suas regras, mas cuidado com o cache do teu browser, pois uma regra bem escrita pode parecer ainda não estar funcionando, se o chrome cachear a requisição, e continuar te devolvendo erro.

Mãos na massa

Comece, e para isso vc precisa “ligar” a engine de reescrita:

RewriteEngine On

Lembrando que ela já deve estar instalada no apache, a linha acima, apenas “avisa” que vc irá utilizá-la. O meu arquivo para saber se está funcionando e receber a requisição será o teste.php, com o seguinte conteúdo:

<?php 
var_dump($_GET);

O que eu quero é acessar a url /edit/user/1, e receber o seguinte no GET:

array(3) {
  ["action"]=>
  string(4) "edit"
  ["model"]=>
  string(4) "user"
  ["id"]=>
  string(1) "1"
}

Ok, vamos lá.

Primeiro devo identificar as partes da minha URL. /edit/user/1 é composto por um grupo de letras, seguido por uma barra, outro grupo de letras, outra barra e um número.
Simples!

A Expressão Regular para isso é: ([a-z]+)\/([a-z]+)\/([0-9]+)
Básico não ? apenas escapei as barras com barras invertidas, para não quebrar a sintaxe da ER.

O que eu quero realmente receber na aplicação é teste.php?action=$1&model=$2&id=$3, sendo cada $n, o número do grupo em sequência ao que foi casado pela ER anterior.

Sintaxe da regra

Bem simples, é composta por 3 partes:

RewriteRule <regular expression> <url to translate> [FLAGs]

Aplicando ao caso acima, fica:

RewriteRule ^([a-z]+)\/([a-z]+)\/([0-9]+)$ teste.php?action=$1&model=$2&id=$3 [NC,L]

Adicionei ^ no início da ER, para indicar que a requisição deve começar com aquele padrão, e $ para indicar que ali a ER acaba, e não deve casar nada mais diferente disso.
Utilizei as flags [NC] para ignorar sensitive case, então se a url for: http://wbruno.com.br/EdIt/uSeR/1 a ER continua funcionando, e [L] para dizer que se a ER casar, essa é a última regra a ser testada, e deve processá-la, e não continuar procurando mais ERs e ver se outra abaixo dela também casa.

E para /contato, a minha ER fica simplesmente:

RewriteRule ^([a-z]+)\/?$ teste.php?page=$1 [NC,L]

note que os padrões não são conflitantes, então podem coexistir no mesmo htaccess.

Funcionando:
http://wbruno.com.br/scripts/edit/user/1
http://wbruno.com.br/scripts/fale-comigo

Não redirecione tudo para a index

Alguns frameworks e alguns preguiçosos têm a mania de fazer coisas parecidas com isso:

RewriteRule . /index.php [L] #retirei esse do wordpress :p

e ai parsear toda a URL do lado da aplicação.
Eu não aconselho, pois vc terá deixado tudo mais lento, uma vez que um trabalho que deveria ser feito no servidor, foi delegado a aplicação, e agora você é dependente de reescrita, e se por algum motivo ela não for suportada na hospedagem, não irá funcionar sem ela.

Dá para entender o motivo do WP utilizar, pois são tantos padrões, e tantas opções de URL amigável que vc pode configurar, que para a app é até mais simples parsear nela, mas na sua, evite usar. Eu pelo menos prefiro trabalhar assim. =)

E ai ? entendeu #comofas?

Complemento

http://moz.com/blog/htaccess-file-snippets-for-seos

Este conteúdo Desmistificando URLs amigáveis com php e htaccess (apache) foi postado originalmente em Desenvolvedor NodeJS - William Bruno.

13 Feb 12:56

Afinal, usar ou não seletores IDs no css ?

by William Bruno

css

Eu uso. #prontofalei. Lógico que uso, e vou continuar usando.

Eu tenho motivos para usar. Identifico os elementos únicos no meu documento com ID.

Eu não uso IDs por performance

É trabalho das engines dos browsers deixarem os seletores rápidos, tanto que hoje em dia usar classes ou id no css, é praticamente a mesma coisa em termos de performance.

Saber disso é um alívio, pois podemos usar classes livremente, mas isso não quer dizer que devemos parar de usar IDs.

Eu sei usar a cascata

Outro argumento que não faz sentido é dizer que usar seletores IDs faz com que vc brigue por especificidade. Oras, veja bem: usar ID não significa que vc não sabe usar mais nada.

Eu não uso declarações do tipo #menu li, no meu css, mas sim: .menu-item, e ai fica:

<ul id="menu">
    <li class="menu-item">Item 1</li>
    <li class="menu-item">Item 2</li>
    <li class="menu-item">Item 3</li>
</ul><!-- #menu -->

A especificidade que uso nos meus arquivos css não passa de 1,1,0 (#id .class). Sendo que a especificidade que mais uso é 0,1,0 (.class) e 0,2,0 (.class .class).

Então usar IDs com moderação, com o propósito para o qual foi inventado, não te atrapalha em nada com a cascata ou com a especificidade.

Referências contra

Encontrei esses 2 links “famosos” sobre por que vc não deveria usar seletores ID no teu css.

http://oli.jp/2011/ids/
http://screwlewse.com/2010/07/dont-use-id-selectors-in-css/

Referências a favor

E felizmente, também encontrei este outro, dizendo pq vc não deveria se preocupar com isso.

http://2002-2012.mattwilcox.net/archive/entry/id/1054/

They are also, oddly enough, perfectly correct to use as long as they’re only ever one instance of that ID on any given page.

Este conteúdo Afinal, usar ou não seletores IDs no css ? foi postado originalmente em Desenvolvedor NodeJS - William Bruno.

13 Feb 12:55

Delegate Events no JavaScript

by William Bruno

É engraçado procurar os termos: delegate events e delegate javascript e então comparar os artigos escritos em inglês com os escritos em português.

Artigos em inglês

Mostram como o delegate funciona por baixo dos planos, mostrando códigos.

Artigos em português

Apenas comparam as funções .bind(), .live(), .delegate() e .on(). Teve só um que só citou como funciona.

A idéia é delegar a responsabilidade de escutar eventos a um ou mais elementos, ao elemento pai daquele elemento.

Isso é muito útil por diversos motivos.

Evitar sobrecarga de manipuladores no DOM

Imagine uma lista de itens, com mais de 20 tags LI. Colocando um evento click em cada tag LI, temos 20 listeners do evento, um para cada tag. Isso deixa o processamento da página lento, pois apesar de todas as otimizações dos motores, imagine com mais elementos, qntas vezes é necessário aplicar o addEventListener..

Atrelar eventos em elementos criados dinamicamente

E aqui, podemos citar duas situações em que isso ocorre. Seja quando duplicamos uma linha de uma tabela, ou adicionamos mais inputs a um formulário, ou quando trazemos via ajax um html, e o inserimos dinamicamente no DOM.

Por esses elementos não existirem ainda no DOM no momento em que o DOMContentLoaded foi disparado, então o listener do evento não foi atrelado a eles. E é ai que o delegate ajuda a dar vida as funções que precisamos.

O mesmo trabalho do .live(), e do .on() do jQuery quando aplicado com a sintaxe do .delegate(). Só que com javascript puro, por baixo dos panos, e entendendo o que está acontecendo.

Como funciona?

Aproveitando o eventBubble do javascript, em que um click em um elemento filho, dispara um click no elemento pai, usamos para testar se o alvo do click, foi o elementos que estamos procurando.

A função .live() fazia um delegate diretamente no objeto document, pois o click de todos os elementos da nossa página, propaga até chegar no root. Dessa forma era super simples de usar (não era necessário indicar qual o pai do elemento).

Não é uma boa prática esperar tantos eventos em um só manipulador, e o live foi depreciado do core do jQuery.

Nativamente

Eu estendi o prototype do objeto Element para criar nativamente suporte ao delegate, deixando uma sintaxe prática, com apenas as linhas de código abaixo:

Element.prototype.is = function(elementSelector) {
    switch(elementSelector[0]) {
        case ".":
            var er = new RegExp(elementSelector.replace(".", ""));
            return this.className.match(er);
            break;
        case "#":
            return this.getAttribute("id") === elementSelector.replace("#", "");
            break;
        default:
            return this.tagName === elementSelector.toUpperCase();
            break;
    }
};
Element.prototype.delegate = function(eventName, elementSelector, cb) {
    var $this = this;

    $this.addEventListener(eventName, function (evt) {
        var $this = evt.target;

        if ($this.is(elementSelector)) {
            cb.call($this, evt);
        }
        if ($this.parentNode.is(elementSelector)) {
            cb.call($this.parentNode, evt);
        }
    });
};

A forma de uso é simplesmente:

document.getElementById('menu').delegate('click', 'li', function(event){
    console.log(this.innerHTML);
});

=)

Este conteúdo Delegate Events no JavaScript foi postado originalmente em Desenvolvedor NodeJS - William Bruno.

13 Feb 12:53

Produtividade: Faça uma coisa por dia, apenas uma, todo dia

by William Bruno

checklist-produtividade
Quantas pequenas ou grandes “coisas”, você já deixou de fazer ? Prometeu que ajudaria alguém, ou que investiria um tempo naquele projeto pessoal, e foi empurrando, adiando, até que já faz mais de um mês e ainda não terminou (e outras nem começou ainda)..

A sensação de chegar ao final do dia e pensar que eu não fiz nada de útil, que apenas fui levado pela rotina estava me incomodando a um ponto que eu não poderia mais deixar isso acontecer.

Foi ai que resolvi pensar como programador, e resolver um problema grande fatorando em diversos problemas menores.

Uma coisa por dia

E tudo começa com a iniciativa. A vontade de fazer.
O significado de “uma coisa por dia” é fazer algo todo dia. E não passar nenhum dia sem ter feito qualquer coisa que te deixe feliz, que te faça sentir realizado ao deitar a cabeça no travesseiro.

Quando eu comecei, fiz um checklist inicial de coisas que eu já deveria ter terminado, e de outras futuras. Adicionei tantos itens, e percebi que eu realmente não estava fazendo direito nem o que eu queria, e nem as coisas que me levarão a atingir o meu objetivo pessoal e profissional.

Chega!

Eu me vi assumindo mais responsabilidades do que era capaz de dar conta, e isso me fazia deixar de fazer os compromissos assumidos anteriormente, e não ter nem ânimo de começar os novos. É um ciclo, onde de tanta coisa para fazer, vc não faz nada.

Não assuma nada novo até ter resolvido o que você já se dispôs a fazer.

Por que deixamos de fazer?

Já parou para pensar nesse por quê? Os motivos são muitos, desde falta de ânimo até não lembrar. Por isso que a idéia de se controlar, e agendar tudo o que importa, faz tanta diferença.

Mas não olhe para a lista depois dos itens estarem completados, não importa quantos você já fez, importa quantos você ainda tem para fazer, e como você se sente no final do dia.

Falta de tempo ou de dinheiro também são “desculpas” recorrentes. Nisso eu percebi que na verdade, o real problema era a falta de organizar o tempo e o dinheiro.
Não é que eu precise de um aumento de salário, mas sim que eu necessito gastar melhor e controlar com o que gasto. O mesmo vale para “o tempo”.

Lógico que um aumento é bem-vindo, mas se eu não sei administrar o meu dinheiro atual, também não saberei administrar se eu receber mais.

“Tempo” pode ser um pouquinho mais complicado, porque certamente você vai alegar que o dia de 24 horas não é suficiente. Mas lembre-se de quantos dias e quantas horas vc ficou sem fazer nada, ou dormiu mais do que precisava e queria…

Assuma compromissos com você mesmo

Tanto faz a ferramenta, o que importa mesmo é o comprometimento. Se você vai se organizar com um lápis e papel, com um checklist no cloud, com um app de produtividade ou se vai utilizar alguma metodologia, nada importa mais do que o comprometimento com você mesmo.

Estou usando o Reminder que integra meu Mac com o iPhone. Agendo um dia e horário para uma tarefa, e sou lembrado quando ela chega.

Já coloquei coisas como: levar o lixo para fora, colocar tal item dentro do carro, escrever um post de review sobre um livro, alimentar a planilha de controle de gastos (esta está agendada para repetir toda sexta-feira)…

Re-agende

Comecei a aplicar realmente dia 6 de fevereiro. Ainda assim, já houveram tasks que eu tive que re-agendar para o dia seguinte. E nele eu realmente fiz, pois o checklist não me deixou esquecer o que eu tinha para fazer.

Sinta-se realizado

Todos temos mais de uma coisa para fazer por dia. E não é disso que estou falando. Estou falando em fazer uma coisa que te deixe feliz, que te faça terminar o dia com o sentimento de dever cumprido. Que te agregue felicidade.

Apenas acordar, ir trabalhar, almoçar, voltar para casa e dormir, não é nem de longe tudo o que quero da minha vida.

Acorde cedo

E acorde com o pensamento: meu dia vai ser ótimo hoje. Tenho tantas coisas para fazer, mas sei quais e em qual ordem irei completá-las. Sei que é possível, e isso me fará melhor e mais próximo do meu objetivo.

=)

E você ? Está feliz com o que tem feito ?
Quer tentar seguir essa minha idéia ? se precisar de algo, pergunte-me como.

Referências

365 nuncas: Faça uma coisa diferente todo o dia do ano
Publicitário cria projeto pra fazer uma coisa boa por dia durante 21 dias

Este conteúdo Produtividade: Faça uma coisa por dia, apenas uma, todo dia foi postado originalmente em Desenvolvedor NodeJS - William Bruno.

13 Feb 12:44

Por melhores condições…

by ProgramadorREAL

tirinha1163

13 Feb 12:38

Microsoft abraça movimento Open Science

by Carlos Cardoso

MSRC_P1080461

Existe um problema sistêmico no mundo científico. Você só tem reconhecimento se sua pesquisa for publicada, e em veículos respeitáveis. O Jornal de Medicina Astrológica Homeopática de Rorainópolis não tem o mesmo peso que a Lancet ou a Nature. Como resultado essas revistas ganham muito poder. Fazem mil exigências, incluindo exclusividade, e disponibilizam por trás de PayWalls.

Um artigo menor no Journal of Investigative Dermatology por exemplo custa US$ 32,00. Uma assinatura da revista sai por US$ 853,00. Essa é UMA publicação. Imagine quantas você tem que assinar se quiser se manter em dia com o que é produzido em sua área.

Há revistas que disponibilizam as pesquisas gratuitamente, mas em muitos casos até isso só acontece depois de pelo menos seis meses. Como resultado é comum um “mercado negro” de trabalhos científicos, com gente perguntando em redes sociais quem tem acesso a determinados papers, que são baixados em PDF e “ilegalmente” enviados via e-mail.

Um movimento contra isso é o Open Science, que se propõe a disponibilizar gratuitamente todo o material de pesquisas científicas, em muitos casos até os dados brutos. Agora a Microsoft Research aderiu ao projeto. Um braço de pesquisa espalhado por vários países, a MSR em 2010 tinha orçamento de US$ 9,5 bilhões. Como comparação o Orçamento do Ministério de Ciência, Tecnologia e Inovação (quaaa) para 2013 foi de… US$ 4,24 bilhões. Sim, além de uma bebida energética ter um programa espacial melhor que o do Brasil, uma empresa de software investe em ciência mais de duas vezes que o nosso país.

As pesquisas de cientistas da MS Research são normalmente apresentadas em seminários e veiculadas em revistas e jornais de suas áreas, e eles continuarão tendo o direito de enviar sua pesquisa para esses veículos, MAS agora a Microsoft Research incluiu uma licença dizendo que podem publicar os trabalhos em veículos gratuitos.

Ou seja: o sujeito pode ganhar seus créditos entre os colegas enviando um artigo pra Gazeta Biomédica de Asgard, mas quem não tem dinheiro pra pagar por ele, poderá acessar legalmente o mesmo texto em outro lugar.

É uma grande iniciativa da Microsoft, aprovada pela imensa maioria dos pesquisadores, que também não estão satisfeitos com conteúdo científico estar tão mais eficientemente bloqueado do que qualquer filme de Hollywood. Esperemos que ela ajude a mudar esse cenário, pois ciência só funciona se for de livre e fácil acesso, podendo ser estudada, questionada, replicada e se for o caso, desmentida ou aprimorada.

Fonte: TV.

The post Microsoft abraça movimento Open Science appeared first on Meio Bit.








13 Feb 12:34

Google já vê 3% dos usuários em IPv6

by Antonio M. Moreiras

google-ipv6

A percentagem de usuários que o Google vê usando IPv6 é de 3%. Pode parecer pouco, mas em setembro de 2013 era de apenas 2%. Isso mostra que o uso do protocolo tem se acelerado. O gráfico original pode ser encontrado em:

http://www.google.com/intl/en/ipv6/statistics.html

De onde vem esse crescimento? O Google já está preparado para o IPv6 há algum tempo. O que ele consegue medir é a quantidade de acessos que seus usuários fazem usando IPv6. Mais usuários com IPv6 significa que mais provedores de acesso estão habilitando essa tecnologia. No Brasil, os maiores provedores ainda não estão usando o novo protocolo, embora alguns estejam fazendo testes localizados. Temos "movimento", contudo, na área acadêmica e em provedores médios e pequenos. Por exemplo, nas medições em: http://www.worldipv6launch.org/measurements/ vemos a Fundacao Parque Tecnologico Itaipu com quase 80% de sua rede pronta para o IPv6, o POP-BA da RNP com 51,3% e o provedor Maxiweb com 48,76%. Leslie Daigle, da Internet Society, previu em artigo recente que a adoção de IPv6 chegará a dois dígitos (pelo menos 10%) ainda em 2014. Vendo essa tendência de crescimento, e toda movimentação dos provedores, ela provavelmente tem razão!
09 Feb 18:48

Milhões de sites estão vulneráveis por causa do… Apache?

by Pedro Pinto
Maioria dos servidores web estão desactualizados Tudo o que é site/serviço online necessita de um servidor web que é responsável por gerir todos os pedidos HTTP/HTTPS (geralmente originados nos browsers dos clientes) e por enviar a respectiva resposta (que na prática é enviar o conteúdo solicitado do site). Neste segmento dos servidores Web, o Apache […]
09 Feb 18:15

Android tem 10 milhões de aplicações maliciosas

by Pedro Pinto
Em finais de Janeiro de 2014, a Kaspersky Lab havia já acumulado cerca de 200.000 amostras únicas de malware para dispositivos móveis, mais 34% desde Novembro passado, já que o número de programas maliciosos móveis registados há apenas dois meses era de 148.000 amostras. Estes dados confirmam o crescente interesse por parte dos cibercriminosos em […]
05 Feb 17:55

ART vai substituir Dalvik já no Android 4.5

by Hélder Ferreira
Com o Android 4.4, a Google introduziu várias novidades e melhorias para tornar o Android mais estável, seguro e funcional. Uma dessas novidades foi o novo Android Runtime, o ART, que veio melhorar como as aplicações funcionam. Esta nova máquina virtual do Android, apesar de ter sido desenvolvida durante 2 anos, é ainda experimental e […]
05 Feb 17:41

Qual a dose certa de JavaScript

by diego@tableless.com.br (Tableless.com.br)

Para uma linguagem de programação que começou de maneira tão despretensiosa, o JavaScript ganhou muito espaço. É bem verdade que alguns navegadores não dão suporte à linguagem, mas estes possuem propósitos particulares ou estacionaram em alguma era que não esta.

O navegador Chrome deve muito da sua popularidade pela rapidez com que interpreta JavaScript e a Mozilla há pouco removeu a opção de desabilitar a linguagem no Firefox. Os fabricantes de navegadores bem sabem, querendo ou não, a internet como conhecemos tem o JavaScript como uma de suas principais dependências.

O dilema é como melhor aplicar e o quanto tornar dependente nossa aplicação de código escrito em JavaScript. Qual a dose certa?

Manifesto

O The Web Standards Project fez bastante barulho há algum tempo e trouxe consigo o Manifesto do JavaScript. Segundo o texto, a função do JavaScript é melhorar a usabilidade das páginas através da adição de interatividade. O que nos leva a algumas premissas:

  • Cliente não deve assumir o papel do servidor. O JavaScript não deve ter a função de fazer uma série de requisições em Ajax e montar a página toda no front-end.
  • O JavaScript deve ser não obstrusivo. A experiência do usuário não deve depender do correto funcionamento e suporte de JavaScript. Mesmo que perdendo usabilidade, todas as funcionalidades devem sempre estar disponíveis.

A prática

Performance

O documento de HTML deve ser entregue para o usuário com conteúdo e o carregamento do JavaScript postergado ao máximo: para o fim do <body>. A não ser que você tenha ótimos motivos (por favor, liste nos comentários), reserve a função de gerar o documento para o servidor da sua aplicação. Falando em comentários, saiba até que o carregamento assíncrono deles não é algo a se orgulhar se o motivo for unicamente limitações de infra estrutura. Em defesa a nós bloqueiros, o Disqus tem uma boa pitada de rede social e isto já nos vale como desculpa para seu uso.

Voltando ao ponto, o Twitter já aprendeu na própria pele que a performance no front-end está fortemente ligado a quanto do trabalho é deixado para o navegador. Sua infra pode ter várias APIs fantásticas e dignas mas a função de consolidar as informações não é do navegador do usuário.

Só me deixe esclarecer um detalhe, nada contra bibliotecas e frameworks JavaScript, eles são bastante úteis e devem entrar em ação assim que todo o conteúdo já tiver sido carregado. Interações mais complexas podem ter sua usabilidade aprimorada drasticamente se realizadas em uma única página com auxílio de JavaScript.

JavaScript não obstrusivo

O assunto não é nenhuma novidade e caso desconheça The seven rules of unobtrusive JavaScript é um bom começo. Sejamos práticos e vamos pegar como exemplo âncoras que removem algum registro da sua base de dados. Sem JavaScript, o clique na âncora não vai resultar em uma requisição de DELETE, mas sim levar para uma representação do registro que obrigatoriamente deve conter um formulário que permita esta ação. Tudo bem se o usuário precisa navegar para outra página e dar alguns cliques a mais, mesmo com perda de usabilidade, a funcionalidade está lá e pode ser alcançada sem dependência de JavaScript. Caso não tenha compreendido o exemplo das âncoras e sua requisição, confira esta postagem sobre REST.

Escrever seu código de maneira que não seja obstrusivo é possível na maioria das aplicações. Mas e para aplicações de tempo real, por exemplo, como é possível? Algumas funcionalidades podem não ser possíveis sem o devido suporte computacional, não tem jeito. O que nos resta são os paliativos. Uma aplicações de tempo real pode ter uma meta refresh no <head> ou um botão para atualizar, não é o ideal, mas é o mínimo.

Mesmo assim, desculpa, mas não acho prático que por criar código exclusivamente não obstrusivo se deixe de fazer jogos e outras aplicações utilizando WebSockets e WebGL. Mas são poucas as aplicações que estão neste seleto grupo. Por fim, os conceitos por trás de JavaScript não obstrusivo são bastante relevantes e respeitá-los ao máximo continua sendo uma boa prática para tornar sua aplicação acessível a qualquer suporte computacional.

Acessibilidade

Este tópico está fortemente relacionado com a escrita de JavaScript não obstrusivo: a partir do momento que sua aplicação não depende exclusivamente de JavaScript, o conteúdo estará sempre acessível. Jamais diria que não tem importância seguir esta prática, mas isto soa muito como um plano B. Quero dizer, existe a possibilidade do JavaScript falhar, demorar para carregar (mais sobre este assunto em breve) ou simplesmente não ter o devido suporte. Mas, que tal nos preocuparmos em garantir acessibilidade quando o plano A está sucedendo e criar aplicações acessíveis quando o JavaScript está sendo interpretado a todo vapor.

A especificação WAI-ARIA dita como é possível tornar aplicações ricas acessíveis. Como estamos nos preocupando com aspectos práticos, vamos a este exemplo de modal do Bootstrap. Comece reparando como a modal não é aberta por uma âncora e sim por um botão, seu conteúdo não está em uma página alternativa ou seção do mesmo documento, não há razão para utilizarmos uma âncora. No elemento da modal, os atributos de role e aria-hidden auxiliam a indicar o tipo de conteúdo e se este está disponível. A função do JavaScript aqui, além de mostrar a modal, é garantir o correto valor para o atributo aria-hidden e assegurar que o foco seja direcionado para o elemento da modal assim que ativada.

Coleções de componentes de interfaces como a jQuery UI são razoavelmente acessíveis. O calcanhar de Aquiles parece residir nas famosas tabs. Inclusive, existem alguns forks deste widget da jQuery UI tentando atingir melhores níveis de acessibilidade por manter o histórico de navegação, indicar o foco adequadamente e possibilitar melhor navegação através do teclado. Utilizar os atributos WAI-ARIA corretos nem sempre é o bastante.

Conteúdo que pode sofrer atualização

A especificação de boas práticas de uso de WAI-ARIA nos deixa ainda um recurso pouco comentado e, na minha opinião, de vital importância em uma aplicação rica. São atributos com a função de permitir que a aplicação seja cortês com o usuário: o atributo aria-live, por exemplo, permite indicar se modificações no conteúdo do elemento devem ser notificadas ao usuário.

Utilizando novamente o exemplo dos comentários, veja quanto é relevante indicar de forma acessível que novos comentários estão disponíveis. Sempre contamos com o estímulo visual que pode, por diversos motivos, não ser notado pelo usuário. Faz todo sentido em aplicações com algum tipo de comportamento assíncrono poder indicar quais regiões podem sofrer atualizações.

Modularização

Já escrevi por aqui que modularização nos permite reduzir a complexidade, separar interesses e manter o código de maneira simples. Mas ainda, digamos que sua aplicação esteja com uma grande quantidade de código a ser baixada. Caso seu código seja modularizado seguindo AMD, pacotes de módulos podem ser carregados sob demanda.

Pensando em uma single page app de e-mail, nem sempre que utilizar a aplicação o usuário pode querer escrever mensagens ou gerenciar as configurações. Não há necessidade em fazer o download e processamento de uma grande quantidade de código responsável por funcionalidades que são de uso esporádico na sua aplicação. Algumas heurísticas interessantes podem ser utilizadas para condicionar o carregamento dos pacotes sem onerar o usuário com o mal visto “carregando”. Por exemplo: o usuário leu mais de duas mensagens, é provável que queira escrever alguma; o usuário aproximou o mouse do botão de configurações, a ação pode estar sendo considerada.

Versione o seu produto

Claro que a web é de todos e estamos aprendendo a possibilitar que diferentes suportes computacionais possam partilhar de um mesmo documento. Mas sejamos honestos, aplicações ricas, a despeito de todos os seus esforços, podem, por culpa da banda de internet ou capacidade de processamento, ter uma experiência miserável em alguns dispositivos.

Caso não haja saída e os muitos recursos sejam o diferencial do seu produto, uma versão fit da sua aplicação com uso limitado de JavaScript pode ser a solução. O Gmail já segue esta estratégia há muito tempo e até o momento não me parece uma má jogada. Nunca esqueça que o essencial é garantir uma experiência adequada para o usuário.

Note ainda que esta prática não entra em desacordo com a premissa de escrever JavaScript não obstrusivo. Pelo contrário, o que estamos oferecendo é um fluxo alternativo onde as funcionalidades principais do produto estão disponíveis mesmo que com uma usabilidade mais pobre. Uma versão alternativa da aplicação pode ainda se valer da modularização do seu código e se você for bem esperto, irá reaproveitar muita coisa.

Palavras finais

Levando em conta qualquer aplicação, saiba que é difícil avaliar pela quantidade de linhas o quão adequado é um código JavaScript. Se você compreendeu bem os exemplos e conceitos do texto, vai notar que não há nenhuma relação entre a dose certa e esta outra medida.

Em uma única sentença, a dose certa de JavaScript é aquela em que a experiência do usuário é glorificada. Isto vai depender muito dos objetivos da sua aplicação e na maneira que você escreve código. Tudo isto irá afetar a acessibilidade, usabilidade e performance.

Aprenda a pensar e planejar a sua aplicação como um todo, apenas JavaScript não será sua salvação nem sua completa derrota. Saiba que as vezes a acessibilidade só pode ser alcançada com a ajuda de alguns atributos no HTML. O segredo é estudar alternativas, experimentar soluções e mensurar resultados.

O post Qual a dose certa de JavaScript foi originalmente publicado em Tableless.

03 Feb 01:57

TOP 5 – Ferramentas para gerir Bases de Dados

by Pedro Pinto
Como sabemos, as bases de dados são normalmente o repositório de toda a informação de muitas aplicações e sites. O MySQL é provavelmente o motor de base de dados mais usada em todo o  mundo, dando suporte aos mais diversos serviços. Tudo o que é plataformas open source como é o caso do wordpress, Joomla […]
03 Feb 01:43

Mini-curso dominando o terminal do linux

by elcio

É hoje à noite

DURAÇÃO: 2h

Aprenda os fundamentos do terminal do Linux, domine os comandos mais comuns mas, além disso, aprenda um novo jeito de pensar. Automatize tarefas e coloque seu computador para trabalhar por você.

Por que estamos oferecendo esse curso?

Durante os últimos anos eu tenho ensinado milhares de técnicos, programadores e webdesigners a ser mais produtivos. Treinei equipes inteiras de empresas como iG, Terra, Yahoo!, Locaweb, Magazine Luíza e Editora Abril. Além disso, tenho sido chamado para palestrar em grandes eventos técnicos em todas as regiões do Brasil.

Mas sinto que o Brasil (e provavelmente o mundo) tem uma carência enorme de conhecimento em computação. E essa carência não poderá ser preenchida apenas ensinando mais a quem já é especialista no assunto. Por isso, fiquei muito feliz quando o Maudy, do Ubuntu Dicas, me convidou para ensinar os segredos do terminal do Linux a iniciantes. E o resultado disso é esse curso que você poderá assistir hoje, quinta-feira, dia 30, às 20h.

Temos sentido, tanto na comunidade Ubuntu Dicas quanto no mercado em geral, um grande interesse dos usuários iniciantes em aprender os segredos do terminal do Linux. É uma ferramenta fantástica de automatização de tarefas, capaz de fazer seu computador trabalhar por você. E também é a porta de entrada para uma série de novos conhecimentos e, inclusive, para um novo jeito de pensar.

Por que você deve dominar o terminal?

Eu comecei minha carreira como programador Windows. Como todo usuário experiente de Windows, eu dominava uma porção de truques avançados do próprio Windows e de seus programas. Foi nessa época que comecei a estudar Linux. Um dia meu chefe na época apareceu com uma tarefa desafiadora para mim. Todos os dias chegava, no mesmo horário, um CD com imagens vindas das filiais. Sim, em CD, naquela época fazer esse tipo de coisa pela Internet ainda era muito lento. E essas imagens deviam ser preparadas para publicação no site. Não era uma tarefa complexa, precisava basicamente redimensionar as imagens e copiá-las para a pasta certa através de um programa de FTP.

Eu resolvi o problema usando um recurso do Photoshop para processamento em lote, chamado “batch” na versão em inglês. Criei uma action no Photoshop para ser executada com o recurso de batch e, todos os dias, quando o CD chegava, eu copiava o conteúdo para uma determinada pasta, abria o Photoshop, executava o processamento em lote e aguardava o Photoshop terminar. Ao final, abria um programa de FTP e copiava os arquivos para o servidor do site.

Era uma tarefa enfadonha, repetitiva e aquilo começou a me deixar desanimado. Eu passava as tardes me sentindo mal, antecipando o momento em que eu teria que parar meu trabalho para copiar as imagens e ficar olhando o Photoshop trabalhar.

Felizmente, foi nessa época que eu comecei a aprender Linux. E com um bocado de estudo e um pouco de esforço cheguei a uma sequência de comandos que resolvia o problema:

cd imagens_filiais/entrada
for i in *.jpg;do  
  convert -thumbnail 300x300 $i $i
done
mv entrada `date +%Y%m%d`
cd ..
rsync -razv . servidor:imagens_filiais/

Uma simples sequência de sete linhas. Claro, você pode achar esses comandos assustadores, e pensar que dá mais trabalho digitar isso tudo do que simplesmente copiar a pasta, renomear, executar a action no Photoshop, abrir o programa de FTP e copiar os arquivos. Acontece que só foi necessário digitar esses comandos uma vez. Criei um arquivo com essa sequência de comandos e, cada vez que o CD de imagens chegava, eu copiava as imagens para a pasta entrada e executava um único comando. Consegue imaginar meu alívio e alegria ao conseguir me livrar dessa tarefa repetitiva, colocando o computador para trabalhar para mim?

Não se assuste com os comandos. Eu também tinha medo deles e não entendia nada quando os vi pela primeira vez. Mas eles são simples, acredite. Muito simples. Se você entender os conceitos fundamentais, vai entender esses comandos e qualquer outro com que tiver que lidar, com facilidade. E é fácil entender, você vai ver.

Você vai gastar duas horas estudando hoje e com certeza, vai economizar muito mais do que duas horas na primeira tarefa repetitiva que chegar às suas mãos. E vai parar de ter medo do terminal.

Por que você deveria se inscrever para esse curso agora?

Por que o curso, com interação ao vivo, vai estar disponível apenas hoje, dia 30/01. Além disso quem se inscrever até lá vai receber também a apostila do treinamento e um bônus especial, preparado com carinho para quem quer avançar na automatização de tarefas. Esta é então uma chance única, uma oferta que não estará disponível depois de quinta-feira. Depois disso você poderá adquirir apenas o acesso à gravação do curso. A apostila estará disponível exclusivamente para quem adquirir o acesso até às 20h.

Nós temos tanta certeza que você vai gostar do curso que, para que você tenha certeza ao se inscrever, oferecemos a exclusiva garantia completa: se você assistir o treinamento ao vivo e, por qualquer motivo, não estiver satisfeito com o que aprendeu, você pode simplesmente escrever para a gente e obter seu dinheiro de volta. Todo o seu dinheiro de volta, sem letras miúdas, sem perguntas, basta mandar um e-mail.

Para quem é esse curso?

Se seu trabalho envolve lidar com arquivos em um computador e realizar tarefas que podem ser automatizadas, esse curso é para você. Se você apenas navega na internet, escreve textos e planilhas, por favor, não se inscreva. Mas se você precisa lidar com tarefas como capturar dados da internet, lidar com arquivos em grandes volumes, tratar texto, imagens, vídeos ou áudio, administrar servidores ou qualquer outra tarefa repetitiva que possa ser automatizada, você PRECISA fazer esse curso.
Eu tenho certeza que, se você trabalha assim com um computador, vai recuperar o tempo investido em estudar em no máximo uma semana.

Inscreva-se

Elcio Ferreira é sócio-diretor da Visie Padrões Web, empresa especializada no desenvolvimento de sites, sistemas web e aplicativos móveis. Já treinou e auxiliou equipes de desenvolvimento de centenas de equipes em empresas como Globo.com, Editora Abril, iG e Terra. Trabalhando com web há mais de quinze anos, Elcio é nome de referência no Brasil em padrões web e tecnologias abertas para a internet, sendo membro do grupo de trabalho de acessibilidade do W3C. Durante o ano de 2011, ministrou os treinamentos oficiais de HTML5 na sede do W3C Brasil.

O post Mini-curso dominando o terminal do linux apareceu primeiro em fechaTag.

03 Feb 01:10

Yahoo Mail tem comprometimento de contas em massa

by Ricardo Fraga

Na última quarta-feira, escrevi um texto falando sobre um bug no Gmail que fez com que o serviço de e-mail do Google excluísse uma mensagem ao invés de outra e, nos comentários, um dos leitores falou algo que me preocupa (e acredito que a outras pessoas também) muito: a confiança que depositamos em serviços online. Uma vida digital inteira nas mãos nos servidores de uma só empresa. Sempre que algo dá errado, a preocupação volta ou se maximiza.

Nesta quinta-feira, o Yahoo publicou um post em seu blog Tumblr através do qual a empresa afirma que, recentemente, um ataque coordenado foi realizado contra um número não informado de contas do Yahoo Mail. Eles afirmam que, após a descoberta, medidas no sentido de proteger as contas dos usuários foram tomadas, enviando uma mensagem (via e-mail ou SMS) informando sobre o problema e solicitando que todos alterassem as suas senhas o mais brevemente possível, além de recomendar que a segunda etapa de verificação fosse ativada em suas contas.

A empresa garante que, pelo o que eles conseguiram apurar, não houve qualquer comprometimento direto dos sistemas do Yahoo. Isso quer dizer que, apesar de os hackers terem tido acesso aos dados de conexão, tais informações foram obtidas através de “um banco de dados de terceiros”, uma vez que eles não têm “qualquer evidência de que eles [os dados] foram obtidos diretamente dos sistemas do Yahoo”.

Uma dica que sempre dou é: cuide da sua conta online como se ela fosse a sua conta bancária. Mantenha os dados de recuperação (e-mail, respostas secretas, números de telefone…) sempre atualizados, utilize senhas fortes, ative a 2SV se o serviço tiver, faça backup, tenha uma conta reservada sempre sincronizada… Sabe aquele ditado velho e idiota “não adianta chorar pelo leite derramado”? Pois é.

The post Yahoo Mail tem comprometimento de contas em massa appeared first on Meio Bit.








03 Feb 00:01

Conhecendo o comando netstat

by Deividson Ludolf

Assim como o comando lsof (já abordado, clique aqui.), o netstat pode exibir portas abertas no sistema, bem como soquetes de comunicação abertos por aplicativos. Também é possível exibir a tabela de roteamento utilizando o comando netstat. Então, vamos conhecer esta ferramenta!

Para exibir uma listagem das conexões IP e mostrar o PID, o nome do programa e o nome do usuário que abriu o soquete de comunicação:

# netstat -apne –inet

Este comando também coloca a saída no modo extenso (opção -e), que oferece mais informações sobre cada registro. Outra maneira de exibir todas as portas que o sistema mantém em escuta (LISTENING)  é com o comando a seguir:

# netstat -lenv -inet

Para visualizar os soquetes que utilizam o protocolo TCP, utilize:

# netstat -lentv -inet

Para visualizar a tabela de roteamento do sistema utilizamos a opção -r:

# netstat -r -n

O post Conhecendo o comando netstat apareceu primeiro em .

30 Jan 16:44

Stack Overflow agora em português

by diego@tableless.com.br (Tableless.com.br)

Eu uso o Stack Overflow quase que diariamente. É um lugar onde tiramos dúvidas o tempo inteiro e praticamente é tão importante para desenvolvedores quanto o Google é para o mundo inteiro.

Hoje, eles anunciaram a versão em português do site. Eu canso de ouvir queixas de desenvolvedores que tem problemas com inglês. Eles sabem que precisam aprender, mas não há tempo para se dedicar. Por isso a versão em português do site ajuda um monte de desenvolvedores a tirarem suas dúvidas com a comunidade.

Quando o Gabe, representante do Stack em português me procurou falando sobre a novidade, fiquei super empolgado por que o Stack Overflow é um site importante para a comunidade e ter sua versão em português é fazer com que a comunidade brasileira fique um pouco mais perto das comunidades lá fora.

O interessante é que o Stack Overflow em português é a primeira versão internacional já feita. Já foram respondidas mais de 6.5 milhões de perguntas ao longo de 5 anos.

“Não estamos fazendo uma tradução do conteúdo do Stack Overflow. Esta é uma comunidade totalmente nova, criada para atender um dos maiores e mais ativos grupos de desenvolvedores do mundo.” Joel Spolsky, CEO do Stack Exchange. “

Se você não conhece o Joel Spolsky, conheça-o já. Ele trabalhou na Microsoft quando ela tinha “só” 5000 empregados. Ele praticamente fez o Excel.

O Stack Overflow original (em inglês) é o maior site de perguntas e respostas de programação da internet. É 100% gratuito, construído e gerenciado pelos próprios usuários. É a primeira (e maior) comunidade na Rede Stack Exchange, que conta com mais de 100 sites, dedicados a diferentes assuntos e comunidades.

Alguns dados sobre o Stack Overflow:

  • Mais de 2,4 milhões de usuários cadastrados
  • Mais de 36 milhões de visitantes únicos por mês
  • Aproximadamente 8 mil novas perguntas por dia

No Stack Overflow você quase sempre consegue a melhor resposta, e ela quase sempre aparece no topo.

Quanto mais você contribui, mais o site confia em você e o Brasil conta com uma das maiores e mais fortes comunidades de desenvolvimento do mundo. Isso sem falar em todos os programadores de Portugal, Moçambique, Angola e outros países lusófonos, que também podem participar.

Se você é um programador que fala português, você pode criar sua conta ou fazer o tour (e ganhar sua primeira medalha no site!)

O post Stack Overflow agora em português foi originalmente publicado em Tableless.