Shared posts

29 Sep 15:07

PostgreSQL Indexes

Hello my dear friends. This is my new article in which I would like to to tell you about PostgreSQL indexes.

First of all what is Index?

For the beginning let us remind ourselves what is a table in relational database.

Table in a relational database is a list of rows, in the same time each row have cells. The number of cells and cell types in the row is the same as a scheme of a column (columns) in table. This list of rows has consecutively numbered RowId sequence number. So, we can consider table as list of pairs: (RowId, row).

Indexes are in the inverse relationship: (row, RowId). In index row must contain at least one cell. Obviously, if a row is not unique (two identical rows), these relations look like mapped RowId list.

Indexes

Index is an additional data structure, which can help us with:

  • Data search - all indexes support search values on equality. Some indexes also support prefix search (like “abc%”), arbitrary ranges search
  • Optimizer - B-Tree and R-Tree indexes represent a histogram arbitrary precision
  • Join - indexes can be used for Merge, Index algorithms
  • Relation - indexes can be used for except/intersect operations
  • Aggregations - indexes can effectively calculate some aggregation function (count, min, max, etc)
  • Grouping - indexes can effectively calculate the arbitrary grouping and aggregate functions (sort-group algorithm)

PostgreSQL Index Types

There are many types of indexes in PostgreSQL, as well as different ways to use them. Let’s review all these indexes.

B-Tree index

B-Tree is the default index that you get when you do CREATE INDEX. Virtually all databases will have some B-tree indexes. The B stands for Balanced (Boeing/Bayer/Balanced/Broad/Bushy-Tree), and the idea is that the amount of data on both sides of the tree is roughly the same. Therefore the number of levels that must be traversed to find rows is always in the same approximate number. B-Tree indexes can be used for equality and range queries efficiently. They can operate against all datatypes, and can also be used to retrieve NULL values. Btrees are designed to work very well with caching, even when only partially cached.

B-Tree

Advantages:

  • Retain sorting data
  • Support the search for the unary and binary predicates
  • Allow the entire sequence of data to estimate cardinality (number of entries) for the entire index (and therefore the table), range, and with arbitrary precision without scanning

Disadvantages:

  • For their construction is require to perform a full sorting pairs (row, RowId) (slow operation)
  • Take up a lot of disk space. Index on unique “Integers” weights twice more as the column (because additionaly RowId need stored)
  • Recording unbalances tree constantly, and begins to store data sparsely, and the access time is increased by increasing the amount of disk information. What is why, B-Tree indexes require monitoring and periodic rebuilding

R-Tree index

R-Tree (rectangle-tree) index storing numeric type pairs of (X, Y) values (for example, the coordinates). R-Tree is very similar to B-Tree. The only difference is the information written to intermediate page in a tree. For the i-th value of the B-Tree node we write the most out of the i-th subtree. In R-Tree it is a minimum rectangle that encloses all the rectangles of the child. Details can be seen in figure:

R-Tree

Advantages:

  • Search for arbitrary regions, points
  • Allows us to estimate the number of dots in a region without a full data scan

Disadvantages:

  • Significant redundancy in the data storage
  • Slow update

In general, the pros-cons are very similar to B-Tree.

Hash index

Hash index doesn’t store the values, but their hashes. Such indexing way reducing the size (and therefore increased speed and processing) of high index fields. In this case, when a query using Hash indexes will not be compared with the value of the field, but the hash value of the desired hash fields.

Because hash functions is non-linear, such index cannot be sorted. This causes inability to use the comparisons more/less and “IS NULL” with this index. In addition, since the hashes are not unique, then the matching hashes used methods of resolving conflicts.

Hash indexes

Advantages:

  • Very fast search O(1)
  • Stability - the index does not need to be rebuild

Disadvantages:

  • Hash is very sensitive to collisions. In the case of “bad” data distribution, most of the entries will be concentrated in a few bouquets, and in fact the search will occur through collision resolution.

As you can see, Hash indexes are only useful for equality comparisons, but you pretty much never want to use them since they are not transaction safe, need to be manually rebuilt after crashes, and are not replicated to followers in PostgreSQL (all this fixed in PostgreSQL 10).

Bitmap index

Bitmap index create a separate bitmap (a sequence of 0 and 1) for each possible value of the column, where each bit corresponds to a string with an indexed value. Bitmap indexes are optimal for data where bit unique values (example, gender field).

Bitmap indexes

Advantages:

  • Compact representation (small amount of disk space)
  • Fast reading and searching for the predicate “is”
  • Effective algorithms for packing masks (even more compact representation, than indexed data)

Disadvantages:

  • You can not change the method of encoding values in the process of updating the data. From this it follows that if the distribution data has changed, it is required the index to be completely rebuild

PostgreSQL is not provide persistent bitmap index. But it can be used in database to combine multiple indexes. PostgreSQL scans each needed index and prepares a bitmap in memory giving the locations of table rows that are reported as matching that index’s conditions. The bitmaps are then ANDed and ORed together as needed by the query. Finally, the actual table rows are visited and returned.

GiST index

Generalized Search Tree (GiST) indexes allow you to build general balanced tree structures, and can be used for operations beyond equality and range comparisons. The tree structure is not changed, still no elevators in each node pair stored value (the page number) and the number of children with the same amount of steam in the node.

The essential difference lies in the organization of the key. B-Tree trees sharpened by search ranges, and hold a maximum subtree-child. R-Tree - the region on the coordinate plane. GiST offers as values ​​in the non-leaf nodes store the information that we consider essential, and which will determine if we are interested in values ​​(satisfying the predicate) in the subtree-child. The specific form of information stored depends on the type of search that we wish to pursue. Thus parameterize R-Tree and B-Tree tree predicates and values ​​we automatically receive specialized for the task index (examples: PostGiST, pg_trgm, hstore, ltree, etc.). They are used to index the geometric data types, as well as full-text search.

Advantages:

  • Efficient search

Disadvantages:

  • Large redundancy
  • The specialized implementation for each query group are nessesary

The rest of the pros-cons similar to B-Tree and R-Tree.

GIN index

Generalized Inverted Indexes (GIN) are useful when an index must map many values to one row, whereas B-Tree indexes are optimized for when a row has a single key value. GINs are good for indexing array values as well as for implementing full-text search.

GIN index

Key features:

  • Well suited for full-text search
  • Look for a full match (“is”, but not “less” or “more”).
  • Well suited for semi-structured data search
  • Allows you to perform several different searches (queries) in a single pass
  • Scales much better than GiST (support large volumes of data)
  • Works well for frequent recurrence of elements (and therefore are perfect for full-text search)

Block Range (BRIN) Index (9.5+)

BRIN stands for Block Range INdexes, and store metadata on a range of pages. At the moment this means the minimum and maximum values per block.

This results in an inexpensive index that occupies a very small amount of space, and can speed up queries in extremely large tables. This allows the index to determine which blocks are the only ones worth checking, and all others can be skipped. So if a 10GB table of order contained rows that were generally in order of order date, a BRIN index on the order_date column would allow the majority of the table to be skipped rather than performing a full sequential scan. This will still be slower than a regular BTREE index on the same column, but with the benefits of it being far smaller and requires less maintenance.

More info about this index you can read in this article.

Partial Indexes

A partial index covers just a subset of a table’s data. It is an index with a WHERE clause. The idea is to increase the efficiency of the index by reducing its size. A smaller index takes less storage, is easier to maintain, and is faster to scan.

For example, suppose you log in table some information about network activity and very often you need check logs from local IP range. You may want to create an index like so:

CREATE INDEX access_log_client_ip_ix ON access_log (client_ip)
        WHERE (client_ip > inet '192.168.100.0' AND
                   client_ip < inet '192.168.100.255');

and such sql query will use such index

SELECT * FROM access_log WHERE client_ip = '192.168.100.45';

This index will remain fairly small, and can also be used along other indexes on the more complex queries that may require it.

Expression Indexes

Expression indexes are useful for queries that match on some function or modification of your data. Postgres allows you to index the result of that function so that searches become as efficient as searching by raw data values.

For example, suppose you doing very often search by first leter in lower case from name field. You may want to create an index like so:

CREATE INDEX users_name_first_idx ON foo ((lower(substr(name, 1, 1))));

and such sql query will use such index

SELECT * FROM users WHERE lower(substr(name, 1, 1)) = 'a';

Unique Indexes

A unique index guarantees that the table won’t have more than one row with the same value. It’s advantageous to create unique indexes for two reasons: data integrity and performance. Lookups on a unique index are generally very fast.

There is little distinction between unique indexes and unique constraints. Unique indexes can be though of as lower level, since expression indexes and partial indexes cannot be created as unique constraints. Even partial unique indexes on expressions are possible.

Multi-column Indexes

While Postgres has the ability to create multi-column indexes, it’s important to understand when it makes sense to do so. The Postgres query planner has the ability to combine and use multiple single-column indexes in a multi-column query by performing a bitmap index scan (“Bitmap index” for more info). In general, you can create an index on every column that covers query conditions and in most cases Postgres will use them, so make sure to benchmark and justify the creation of a multi-column index before you create them. As always, indexes come with a cost, and multi-column indexes can only optimize the queries that reference the columns in the index in the same order, while multiple single column indexes provide performance improvements to a larger number of queries.

However there are cases where a multi-column index clearly makes sense. An index on columns (a, b) can be used by queries containing WHERE a = x AND b = y, or queries using WHERE a = x only, but will not be used by a query using WHERE b = y. So if this matches the query patterns of your application, the multi-column index approach is worth considering. Also note that in this case creating an index on a alone would be redundant.

Summary

Indexes are common way to enhance database performance. Index allows the database server to find and retrieve specific rows much faster than it can be without an index. But indexes also add overhead to the database system as a whole, so they should be used sensibly.

That’s all folks! Thank you for reading till the end.

20 Apr 20:36

Baji Shaik: Aha, you can count the rows for \copy command.

We all know that \copy command does not return anything when you load the data. The idea is to capture how many # of records got loaded into table through \copy command.
Here's a shell script that should work:
echo number of rows in input: $(wc -l data.in)
( echo "\copy test from stdin delimiter '|';" ; cat data.in ) | psql -v ON_ERROR_STOP=1
echo psql exit code $?

If the exit code printed is 0, everything went well, and the value printed by the first echo can be used to to indicate how many rows were inserted. If the printed exit code is non-zero, no rows were inserted, of course. If the exit code printed is 3 then the data being copied had some error.

From the docs: If the exit code printed is 1 or 2 then something went wrong in psql (like it ran out of memory) or the server connection was broken, respectively. Following facts play a role in the above script:

.) COPY (and hence \copy) expects the input records to be terminated by a newline. So counting the number of newlines in the input is a reliable way of counting the records inserted.
.) psql will exit with code 3 iff there's an error in script and ON_ERROR_STOP is set. 
Note: This seems to not apply to the `psql -c "sql command"` construct.

# Example clean input

$ pgsql -c "create table test(a text,b int);"
CREATE TABLE
$ cat data.in
column1|2
column1|2
column1|2
column1|2
column1|2
column1|2

$ echo number of rows in input: $(wc -l data.in); ( echo "\copy test from stdin delimiter '|';" ; cat data.in  ) | psql -v ON_ERROR_STOP=1 ; echo psql exit code $?
number of rows in input: 6 data.in
psql exit code 0

# Example malformed input
$ cat data.in
column1|2
column1|2
column1|2c
column1|2
column1|2
column1|2

$ echo number of rows in input: $(wc -l data.in); ( echo "\copy test from stdin delimiter '|';" ; cat data.in  ) | pgsql -v ON_ERROR_STOP=1 ; echo psql exit code $?
number of rows in input: 6 data.in
ERROR:  invalid input syntax for integer: "2c"
CONTEXT:  COPY test, line 3, column b: "2c"
psql exit code 3
 
I hope this helps someone.
19 Apr 14:28

Conheça as salas de aula móveis que produzem mais energia do que consomem

by Redação Hypeness
Se a ideia de uma sala de aula móvel já parece inovadora, então imagine se, além disso, ela ainda fosse capaz de produzir toda a energia que consome e um pouco mais. É o que acontece com essas salas pré-fabricadas, que utilizam janelas com orientação norte para otimizar a ventilação e a iluminação natural. O escritório […]
19 Apr 02:54

Trabalhadores terceirizados paralisam elevadores da Uerj

by Sintuperj


Trabalhadores e alunos tiveram que usar escadas para ter acesso aos 12 andares da Uerj na manhã desta segunda-feira (13/04). Os funcionários da Construir paralisaram suas atividades em resposta ao atraso do pagamento do mês de março, que deveria ter sido feito até o último dia 08 de abril.

Em entrevista, um trabalhador lotado no setor de manutenção da empresa Navele (outra firma que presta serviços terceirizados para a Uerj), que preferiu não se identificar, afirmou que a situação dos funcionários dessa empresa é ainda pior. Segundo ele, já são cinco meses sem receber.

19 Apr 01:29

Se você pudesse fazer apenas uma coisa para tornar um software melhor, o que seria?

by Jim Bird

O que temos que fazer para desenvolver um bom software são boas práticas técnicas – essa é a parte de engenharia da engenharia de software. Design. Codificação. Testes e Revisões.

Se você pudesse fazer apenas uma coisa para tornar um software melhor, o que seria? Onde é que você obtém o máximo de retorno para seus investimentos?

Integração Contínua – Fazendo o código rodar

A integração contínua é um lugar óbvio para começar. Você precisa construir o software e fazê-lo funcionar antes de poder fazer qualquer coisa útil com ele.

Faça com que os desenvolvedores se monitorem e se sincronizem com mais frequência. Construa o sistema com mais frequência – pelo menos uma vez por dia para começar, e então em cada verificação. O que significa simplificar e automatizar os passos para a construção do sistema. Certifique-se de que o sistema cria com êxito cada vez – sem erros ou avisos. O que significa que as pessoas podem executá-lo e experimentá-lo quando quiserem. Certifique-se de que ele será executado corretamente. O que significa a adição de testes e verificações, como parte das etapas de compilação e implementação. Construa radiadores de informação para que todos saibam o status da construção e quando a compilação é quebrada.

Você não pode ser Ágil sem Integração Contínua, e precisa de integração contínua no lugar antes que possa seguir para o caminho DevOps para Entrega Contínua ou implantação contínua.

E a Integração Contínua trabalha na entrega sequencial em cascata também. Os desenvolvedores nesses ambientes podem verificar mais códigos com menos frequência, mas ainda há um valor real em saber que você pode construir, executar o sistema e vê-lo trabalhar mais cedo do que tarde, especialmente em grandes sistemas empresariais e grandes programas, nos quais receber dependências funcionou e todas as peças que trabalham em conjunto são um desafio enorme.

Desenvolvedores testando o seu próprio trabalho – fazendo trabalho de código

Tornar os desenvolvedores responsáveis por testar o seu próprio trabalho, automatizando isso tanto quanto possível na Integração Contínua, é a única maneira de entregar software mais rápido e manter os custos baixos – depender demais de testes manuais e transferências para a equipe de teste te atrasar muito.

Quase todas as organizações com que conversei ao longo dos últimos anos estão colocando mais responsabilidades de testes nos desenvolvedores, e levando mais testadores para as equipes de desenvolvimento, seguindo o exemplo do Google e agora da Microsoft, para se tornarem “mais Agile”.

Isso significa que estão confiando mais nos desenvolvedores para escrever bons testes automatizados (testes unitários, regressão UI básica usando Selenium ou Watir) e fazer verificação de análise estática na Integração Contínua ou IDE do desenvolvedor para encontrar erros de codificação comuns e vulnerabilidades de segurança.

Mas existem limites para o que os desenvolvedores podem pegar em seus testes, mesmo os bons devs. Depois que você conseguir que os desenvolvedores escrevam testes (antes ou depois de se escrever o código, isso não importa, agora que TDD está morto), você vai acabar com testes de unitários, em sua maioria simples, ou testes de regressão UI que não se afastam muito do “caminho feliz“, provando que o código faz o que o desenvolvedor acha que deve fazer – porque é isso que eles precisam fazer: seu trabalho. Seus pressupostos e pontos cegos serão refletidos nos testes, bem como o código. Pouco ou nenhum teste negativo. Ou testes de usabilidade. Ou testes de segurança. Ou testes de estresse. Ou teste de integração em nível de sistema. Tudo isso ainda tem que ser feito por alguém – a menos que você espere que seus clientes encontrem seus erros para você.

Revisões de código ou emparelhamento – fazendo um bom código

Outra maneira de obter um código melhor é fazer com que os desenvolvedores façam revisões de código.

As revisões de código devem ser sobre, em primeiro lugar, encontrar problemas no código – verificar correções, proteção de codificação defensiva (tratamento de erros, contratos de API, segurança de thread e validação de dados), segurança (uso correto de bibliotecas de segurança para controle de acesso e codificação de saída, proteção de dados confidenciais, registro e auditoria…). E sobre como tornar o código melhor – mais compreensível, mais seguro e mais fácil de mudar.

As revisões de código são dispendiosas, então faça-as direito: à base de risco, leve, usando análise estática primeiro para capturar erros de baixo nível e práticas de codificação ruins para que os revisores possam dedicar o seu tempo à procura de problemas mais importantes.

Em vez de revisões de código, você pode tentar o emparelhamento como uma maneira de obter alguns pares de olhos sobre o código.

O emparelhamento não é a mesma coisa que as revisões – as metas e as prioridades são diferentes. Um bom revisor vai encontrar problemas, mesmo em um código desenvolvido por meio de programação em par, pois os revisores procuram coisas diferentes. Mas uma pesquisa mostra que a programação em pares disciplinada lhe dará uma estruturação melhor e um código mais limpo, com menos bugs. E o emparelhamento é uma maneira muito melhor para ensinar programadores sobre o que são os sistemas de revisões de código.

As desvantagens da programação em par? O custo de ter duas pessoas fazendo o trabalho de uma – uma boa dupla vai trabalhar mais rápido do que uma pessoa por conta própria, mas o membro da equipe menos experiente ou menos qualificado vai desacelerar o desempenho da dupla. O emparelhamento pode ser desgastante, o que significa que as pessoas não podem fazê-lo por muito tempo, antes que o seu trabalho se torne superficial ou tenso. E há os problemas sociais – as pessoas que gostam dele gostam muito, mas as pessoas que não gostam não vão fazê-lo de forma alguma.

Refatorando – escrevendo código – melhorando o design – continuando

E o design? Oficinas colaborativas de design? Revisões de design? Modelagem de ameaças no design para cuidar de riscos de segurança e operacionais?

Fazemos todas essas coisas. Mas à medida que continuamos a iterar no design e que nossa base de código cresce, a refatoração – manter e, às vezes, restaurar o design, e manter o código passível de manutenção – se torna cada vez mais importante.

É fácil aprender as ferramentas de refatoração do seu IDE e as ideias básicas por trás do conceito. Mas não é fácil aprender como fazer a refatoração certa (embora você possa aprender muito em um curto período de tempo com o vídeo de Woody Zuill e Llewellyn Falco – “2 Minutes to Code Better“). Entenda por que algumas abordagens de refatoração são melhores que outras. Como poupar tempo refatorando. Como fazer isso com segurança.

Mariusz Sieraczkiewicz faz um bom trabalho explicando como e quando fazer “refatoração cotidiana” utilizando uma matriz construída sobre o trabalho de Michael Feathers em refatoração brutal e biologia do código:

  1. Comece lendo e anotando o código, talvez fazendo alguma refatoração do zero (rápida, descartável) para compreendê-lo melhor.
  2. Encontre nomes significativos para variáveis e condicionais.
  3. Extraia métodos para quebrar grandes pedaços de código e expressar o algoritmo.
  4. Livre-se da duplicação óbvia.
  5. Mova os métodos e extraia as classes para isolar as responsabilidades.

Concordo com Sieraczkiewicz que esses simples passos “curariam a maioria das bases de código neste planeta”. Ele, então, continua a descrevendo a “refatoração estratégica” maior e mais fundamental (aka “root canal“): refatoração para padrões, introdução de novas construções arquitetônicas. Trabalho que traz riscos e custos muito mais elevados. Esse é o lugar onde termina a refatoração, e o re-design e a re-arquitetura são iniciados.

O que você faria para tornar o código melhor?

A integração contínua recompensa rapidamente: a mudança na transparência e no foco da equipe é quase imediata.

Os testes do desenvolvedor são uma jornada, não um objetivo. Vai levar muito tempo para a maioria dos desenvolvedores ficar bom nisso e muito tempo para construir um bom conjunto de testes no qual você pode confiar. Quanto mais cedo você começar, melhor.

As revisões de código também podem levar muito tempo para recompensar. Os desenvolvedores – e gerentes – precisam arrumar tempo para que as revisões sejam feitas e construir a disciplina, e os desenvolvedores precisam de tempo para aprender a revisar o código corretamente, e como dar e aceitar críticas. Mas as revisões de código – ou o emparelhamento – vão te dar um código melhor.

A refatoração é mais um investimento de capitalização – você paga um pouco hoje para economizar muito no futuro.

Se existir só uma coisa que você pudesse fazer para tornar o software melhor, o que seria? Por onde você começaria?

***

Jim Bird faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://swreflections.blogspot.com.br/2014/12/if-you-could-only-do-one-thing-to-make.html

 

17 Apr 16:40

poesia

by Francisco Nunes

Send to Kindle
17 Apr 16:40

Tendências Web 2015 para desenvolvedores

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

Web Trends 2015

O mundo dos desenvolvedores web está cada vez mais inovador e fantástico. Em 2015 teremos ferramentas mais qualificadas e conceitos que nos ajudarão na jornada de desenvolver um material super satisfatório. Pois não trará vantagens somente para nossos clientes, mas também nos poupará tempo, e para quem trabalha nessa área sabe que tempo é MUITO PRECIOSO.

FLAT DESIGN

Sites com sombras, diversas fontes e cores para ressaltar o realismo da página ficou no passado, agora o que manda é a simplicidade. Design de empresas como Google, Twitter, Facebook e Windows 8 são exemplos fortíssimos de que isso deu certo e não vai sair de cena por muito tempo. Lembre-se: menos é mais!

flat-design

Pense que interessante seria se essa moda aparecesse nos tempos de IE6, quando transparencia, bordas arredondadas e gradientes não funcionavam. Era só colocar um botão com cor chapada de fundo, letra branca e pronto. Funcionaria em todos os browsers. Flat to save the devs.

MOTION UI

A moderna forma de atrair o interesse dos usuários de forma leve e dinâmica está em alta. Frameworks te ajudam na missão de implementar mais animação em suas páginas sem fazer com que seu site fique pesado. Visite Foundation for APPs ou Animate.css e veja os efeitos incríveis em ação.

motion-ui

Há um post aqui no Tableless que fala um pouco sobre as inspirações que o Material Design do Google teve em diversos designs.

RESPONSIVIDADE

A preocupação em se adaptar a todos os dispositivos utilizados pelos usuários hoje em dia está ficando cada vez maior entre as empresas, por isso, para não perder mais tempo, utilize de uma ajudinha amiga como Bootstrap, Foundation e o novo porém não menos interessante Semantic UI. Todos os frameworks são simples e contam com ótimos tutoriais disponíveis no próprio site.

design-responsivo

SINGLE PAGES

Já viu aqueles sites em que você tem todo conteúdo em uma só página? Pois é, as single pages estão entre as tendências web 2015 e com razão. Além de visualmente serem mais agradáveis, são super práticas para usuários que odeiam se perder em milhares de páginas só para achar tal conteúdo que havia se interessado. Essa tecnologia fica ainda mais legal quando aplicada em mobiles! Olha um exemplo bem legal aqui.

Single Pages

A ideia de Single Pages Application é bem interessante e cada vez mais há ferramentas que nos ajudam nesse trabalho. Veja por exemplo o caso do SennaJS, idealizado pelo nosso amigo Eduardo Lundgreen.

VÍDEOS

Os vídeos estão tendo muita receptividade pelos usuários hoje em dia e podem facilmente conseguir mais atenção para seu site se você utilizá-lo como forma de apresentação de sua empresa ou produto, por exemplo. Além de ser rápido e prático, é um meio de comunicação muito mais esclarecedor e satisfatório para o usuário que ao assistir irá receber e entender todo o assunto tratado.

Vídeos

Há outras formas de uso de vídeos por meio dos designers. Dá uma olhada em sites como Dadaab ou Barrel que fazem uso bem criativo de vídeos como parte do design do site.

Junte todas essas armas para montar o site dos sonhos de seu cliente. :)

---
Este artigo foi escrito por Paula Berrocal.

Visite o nosso site para mais posts sobre desenvolvimento web! Tableless.

17 Apr 13:02

Criptografia nacional pronta para funcionar em qualquer smartphone e tablet

by Augusto Campos

Enviado por zeuslinux (zeuslinuxΘyahoo·com):

“"A ZTEC, empresa de Brasília e credenciada como Empresa Estratégica de Defesa do Governo, desenvolveu o cartão MCI SD (Módulo Criptográfico Interno com interface SD), que funciona no lugar de um cartão de memória nos celulares e tablets e proporciona uma rede de comunicação criptografada.

Solução requer o sistema operacional Android. Isso porque, explica Raimundo Guimarães Saraiva Júnior, é necessário ter acesso ao código-fonte para blindar o modelo, o que não é permitido pelo iOS, da Apple, e pelo Windows, da Microsoft. Governo já está usando a ferramenta, mas o nome do cliente não pode ser revelado. Produção dos cartões será feita no Brasil, dentro de unidade própria da ZTEC.

"O importante dessa solução, que levou dois anos para ser feita na nossa área de Pesquisa e Desenvolvimento, é que os fornecedores de terceira camada, com hardware criptográfico, são de origem estrangeira e trazem os vícios de origem de segurança. Agora há software e hardware 100% nacional, aptos para proteger o Estado brasileiro e todo o mercado", explica o executivo da ZTEC, em entrevista exclusiva ao portal Convergência Digital. Vale lembrar que a camada 1 é de aplicação. A camada 2 é de Sistema Operacional blindado e a camada 3 é a de hardware criptogrado.

Guimarães Junior explica que já existia uma versão do MCI SD, mas ele não não possuia as dimensões atuais que permitem a inclusão dele em qualquer dispositivo móvel, como smartphones e tablets vendidos no mercado. "O cartão entra como se fosse um cartão de memória. É simples e fácil de manuseiar. Ele vai funcionar como um cofre guardando as chaves e os algoritmos criptográficos que a aplicação de segurança vai rodar", diz.

Para o executivo, o governo possui celulares especiais - desenvolvidos para os órgãos públicos, como o Zcell, da própria ZTEC, que já estão rodando o novo cartão. Há 200 celulares já em atividade em órgãos govenamentais, mas o nome da autarquia ainda não pode ser revelado. Mas a grande aposta, agora, é ampliar a presença no mercado privado de segurança.

Como o cartão se adequa a qualquer dispositivo, a expectativa é que se possa vender um solução de comunicação privada e criptografada. "Estamos unido software e hardware com segurança. Nossa ideia é vender num modelo de licenciamento na nuvem, para que os custos sejam adequados às empresas", projeta Raimundo Guimarães Saraiva Júnior.

Nos últimos dois anos, a ZTEC investiu cerca de R$ 4,5 milhões em Pesquisa e Desenvolvimento e, embora não revele a sua projeção de fabricação desses novos cartões, o executivo garante que a produção será local. "Temos estrutura. As empresas brasileiras de segurança não devem nada para as internacionais", completa"” [referência: convergenciadigital.uol.com.br]

O artigo "Criptografia nacional pronta para funcionar em qualquer smartphone e tablet" foi originalmente publicado no site BR-Linux.org, de Augusto Campos.

08 Apr 17:32

Operating Systems

One of the survivors, poking around in the ruins with the point of a spear, uncovers a singed photo of Richard Stallman. They stare in silence. "This," one of them finally says, "This is a man who BELIEVED in something."
05 Apr 23:53

Microsoft comemora hoje 40 anos! Parabéns

by Pedro Pinto
Foi a 4 de Abril de 1975 que Bill Gates e Paul Allen deram início a um projecto que resultou numa das principais empresas tecnológicas, a Microsoft. Passados 40 anos, a empresa de Redmond tem mais de 125 mil funcionários e o futuro (próximo) promete, uma vez que a empresa prepara-se para lançar mais uma […]
05 Apr 22:20

traduzir-se

by Francisco Nunes

Uma parte de mim
é todo mundo:
outra parte é ninguém:
fundo sem fundo.

uma parte de mim
é multidão:
outra parte estranheza
e solidão.

Uma parte de mim
pesa, pondera:
outra parte
delira.

Uma parte de mim
é permanente:
outra parte
se sabe de repente.

Uma parte de mim
é só vertigem:
outra parte,
linguagem.

Traduzir-se uma parte
na outra parte
– que é uma questão
de vida ou morte –
será arte?

(Ferreira Gullar)

Send to Kindle
05 Apr 20:40

DICÃO! Windows não é para casos de missão crítica, tipo basquete

by Carlos Cardoso

?????????????????????

Um dos grandes problemas do Windows era a quantidade de máquinas desatualizadas e vulneráveis. Avisos de atualizações eram sistematicamente ignorados por aquela praga chamada usuário. De todos os níveis, uma vez descobri que os servidores da empresa onde eu trabalhava tinham ZERO atualizações, a “lógica” do (ir)responsável era só atualizar quando saía Service Pack.

A Microsoft aliviou isso forçando as atualizações mais críticas, baixando mesmo contra a vontade do usuário, e tornando inevitável o boot. Só não contavam com o usuário pra transformar isso num problema.

Foi o que aconteceu dia 13, num jogo de basquete na Alemanha, entre os Paderborn Baskets e os Chemnitz Niners. O placar do estádio dos Paderborns era controlado por um laptop rodando Windows, e o estagiário responsável ignorou os avisos de atualização de sistema (diz ele que não viu nenhum, mas sabemos que é mentira) e foi adiando, com preguiça de rebootar.

Em um momento karmicamente murphyano, 10 minutos pra hora do jogo o laptop deu pau e resetou. Quando voltou do boot o Windows automaticamente começou a instalar a tonelada de atualizações que o estagiário tinha enrolado pra instalar.

As atualizações demoraram 25 minutos pra terminar. Só então o jogo começou. O time da casa venceu, mas o adversário entrou com uma reclamação, pois pela regra se o começo do jogo atrasar mais que 15 minutos a partida tem que ser remarcada. Com o placar de 69 × 62, eu acho que o choro é válido, vai que cola…

Esperemos que no próximo jogo o estagiário mantenha o Windows atualizado, tenha uma máquina de backup, ou os dois.

Fonte: SP.

The post DICÃO! Windows não é para casos de missão crítica, tipo basquete appeared first on Meio Bit.








05 Apr 19:44

Refatoração utilizando Strategy com PHP

by Eduardo Cesar Borsato de Oliveira

Neste artigo, vamos descrever um caso de uso e uma implementação do padrão Strategy em PHP, com o intuito de demonstrar como a linguagem tem avançado e melhorado nos últimos tempos, em detrimento de épocas onde era tido como “fraco” ou “incompleto”.

Atualmente, o PHP possui um excelente suporte á orientação a objetos, algo que há tempos atrás fazia muitos programadores sentirem certo “receio” quando iniciavam-se debates sobre o assunto relacionado à PHP.

Um problema, uma solução

Em um sistema desenvolvido para um laboratório de estatística foi solicitado o seguinte requisito:

  • É necessário que o sistema efetue o cálculo de médias com base nos valores informados pelos pesquisadores;
  • Inicialmente existirão 2 cálculos para média:
    • Cálculo da média aritmética, ao qual o pesquisador deverá informar os valores e o sistema, por sua vez, efetuará o cálculo devolvendo a média obtida;
    • Cálculo da média ponderada, onde o pesquisador deverá sempre informar a nota seguida de seu respectivo peso, e o sistema procederá efetuando o cálculo e retornando a média obtida.

A solução atual

O desenvolvedor responsável pela criação de tal requisito sugeriu a criação de uma classe que receberia os parâmetros necessários e realizaria os cálculos através de seus métodos para cálculos de média.

diagramaSolucaoAtual

Estudo da solução atual

O código da classe resolve o problema. A classe possui atributos internos utilizados para fazer o cálculo, métodos que adicionam e utilizam dados para o cálculo e dois métodos cada um com seu algoritmo de média respectivo. Contudo, essa classe viola alguns princípios SOLID, tais como o da responsabilidade única, onde uma classe deve ter um (e apenas um) motivo para mudar, e o fato de que temos os dois métodos de cálculos de média e os métodos que adicionam e recuperam os dados para os dois casos de média fazem com que a classe viole este princípio.

Outro princípio SOLID também é violado: o princípio de entidades abertas e fechadas (entidades de software – classes, módulos, funções etc – devem ser abertas para extensão, mas fechadas para modificação). Por exemplo, a necessidade de inserir um novo cálculo de média com novos métodos para adicionar e recuperar valores específicos a essa nova rotina de cálculo, seria um motivo para uma alteração na classe Média (Average) em um código já existente e funcional, que não deveria sofrer mais alterações após colocado em produção. Afinal, mexer em uma parte de código que já está funcionando aumenta os riscos de quebra do aplicativo.

Refletir sobre tais pontos é importante, pois não é desejável que, após implementar um novo requisito, os requisitos antigos deixem de funcionar por alguma falha de programação que possa ter ocorrido no código em funcionamento, enquanto o novo era implementado. Logo, é necessário preocupar-se com o design do código escrito e com a forma como ele pode escalonar para atender novos requisitos sem influenciar os já existentes.

Uma solução que não viole os princípios

A partir do momento que as fraquezas surgem em um código, tenhamos em mente os seguintes pensamentos:

“É necessário separar o cálculo de média ponderada e seus parâmetros de entrada, do cálculo de média aritmética e seus parâmetros de entrada”.

“Cada algoritmo de cálculo de média possui uma implementação diferente”.

Notar a violação dos princípios SOLID resultou em tais pensamentos, que por sua vez facilitam as coisas, definindo de forma clara o que precisa ser feito para melhorar o código.

A solução cabível para este problema engloba um padrão de desenvolvimento (design pattern) chamado Strategy, que é um design pattern comportamental: define uma família de algoritmos e encapsula cada uma deles, permitindo que sejam intercambiáveis.

Este padrão provê uma abstração do conceito que está envolvido no problema e uma separação das variadas formas de implementação que possa existir para o conceito em questão. Isso torna o código que resolve o problema mais flexível, tornando possível realizar a modificação do comportamento sem alterar código existente, apenas adicionando novas estratégias de uso.

Para o melhoramento do código, o uso desse padrão faz sentido, pois é preciso separar as responsabilidades para que o princípio da responsabilidade única não seja violado. Enxergar o conceito envolvido no problema e toda variação que possa existir para ele é importante nesse caso, para que não se viole o princípio de entidades abertas e fechadas; ou seja, o novo código deve ser capaz de suportar novas implementações sem que seja preciso alterar o código já funcional, apenas adicionando novas estratégias. Segue um diagrama de classe do padrão aplicado à solução:

Figura 2: Strategy representando a solução do problema

Figura 2: Strategy representando a solução do problema

O conceito principal por trás do problema são as médias. Existe uma família de médias: as aritméticas, as ponderadas, geométricas etc. Logo, temos diversos tipos de cálculo para uma determinada média, que no caso é utilizada de duas formas: para o cálculo de média aritmética e para o cálculo de média ponderada. Através do diagrama também fica notável como é feita a separação das responsabilidades e o encapsulamento dos algoritmos de cálculos em suas respectivas classes. Fica evidente também como se torna fácil adicionar um novo algoritmo de cálculo de média sem precisar alterar código existente e que já está funcionando.

Outro participante importante no padrão é o contexto, no caso, os valores (Values), que pode configurar todos os parâmetros que serão utilizados pelas estratégias. No exemplo, Valores (Values) é o contexto. Sendo uma classe abstrata, que define um método de chamada para estratégia e métodos para que se adicione e recupere parâmetros que serão usados para os cálculos.

Sendo assim, a classe Valores é estendida para Ponderada (Pondered) e Aritmética (Arithmetic). O fato de tal comportamento ser necessário neste exemplo, é que o cálculo de médias ponderadas e aritméticas possuem parâmetros de entrada diferentes.

Enquanto para o cálculo de média aritmética só são esperados os valores em si, para o de média ponderada já são necessários, além dos valores, seus respectivos pesos. Logo, fazê-lo de tal forma permite que isso aconteça sem sobrecarregar as responsabilidades de uma classe, no exemplo inicial a classe Média recebe os parâmetros para os dois métodos de cálculos além de possuir também suas implementações.

Na forma refatorada isso não acontece, pois seguindo o padrão Strategy foi possível abstrair um conceito do problema, no caso os cálculos de média e, posteriormente identificando as variadas implementações de algoritmos que existiam foi possível seguir com a implementação do padrão. Possuindo uma interface Media(Average), que seria o participante estratégia (Strategy), a partir daí tornou-se possível delegar a implementação de seu método de cálculo para cada classe que derivar dessa interface. As classes que derivam dessa interface são conhecidas como estratégias concretas (Concrete Strategy).

Assim sendo, cada classe que implementar a interface Média deve implementar o seu método de cálculo da maneira que for necessário. O interessante é que, é possível ter agora, de forma separada e organizada, as mais variadas implementações de cálculo de média existente. A responsabilidade em lidar com os parâmetros necessários para cada estratégia de cálculo de média ficou por conta do contexto, como cada tipo de cálculo de média requer parâmetros de entrada diferentes, ter classes que saibam como fazê-lo para cada caso torna-se necessário.

Ao observar o código inicial e refletir sobre o que alguns princípios SOLID propõe, tornou-se possível identificar os principais pontos de melhorias que, para serem colocados em prática, fizeram o uso de um padrão que permitiu à nova implementação, a não violação dos princípios adicionando mais flexibilidade e organização ao código.

unnamed

iMasters PHP Experience 2015 – 25 de abril, em São Paulo.

Mensagem do anunciante:

Em apoio à evangelização do WordPress, os cursos da Apiki são gratuitos para que você possa se especializar na plataforma que mais cresce no mundo. Vagas limitadas, Inscreva-se agora.

05 Apr 19:21

Norte-americano cria arte de rua que só pode ser vista quando chove

by Redação Hypeness
Toda criança já brincou de escrever mensagens secretas com suco de limão. A tinta “invisível” era revelada com o calor, deixando as letras em um tom castanho. O artista norte-americano Peregrine Church decidiu levar as mensagens secretas para um outro nível: ele criou um tipo de arte de rua que só pode ser enxergada quando […]
05 Apr 19:15

Opportunity

We all remember those famous first words spoken by an astronaut on the surface of Mars: "That's one small step fo- HOLY SHIT LOOK OUT IT'S GOT SOME KIND OF DRILL! Get back to the ... [unintelligible] ... [signal lost]"
05 Apr 19:13

GVT agora é quase Vivo (ou vice-versa)

by Emanuel Laguna

Laguna_GVT_triplexer

Na presente quarta-feira (25/03) o Conselho Administrativo de Defesa Econômica (CADE) julgou a compra da GVT pelo grupo Telefónica. Nosso órgão antitruste teve que intervir para evitar propriedades cruzadas entre a Vivendi e a Telefónica. Na prática, estavam em jogo os ativos das operadoras TIM Brasil e Vivo em nosso país.

A Anatel já havia autorizado a aquisição, impondo a saída da operadora espanhola do controle acionário da Telco, dona da Telecom Italia. Para aprovar a compra bilionária, o CADE deu prazo de quatro meses para que o grupo Telefónica venda as ações que possua na TIM Brasil. Não tão urgente seria o processo contrário, ou seja, a Vivendi vai precisar se desfazer gradualmente da participação que ainda manterá na Telefônica Brasil, participação acionária essa adquirida pela venda da GVT.

Laguna_Telefonica_predio

Todos os serviços da Telefônica no Brasil estão sob a marca Vivo (crédito: Info)

Enquanto forem mantidas as participações acionárias cruzadas, Telefónica e Vivendi não poderão exercer quaisquer poderes políticos na Telecom Italia e na Telefônica Brasil, respectivamente. Tampouco poderão “acessar ou compartilhar, direta ou indiretamente, informações confidenciais, estratégicas e concorrencialmente sensíveis entre quaisquer empresas ou entre os responsáveis pela administração e representação das empresas do Grupo Telefónica, da Vivendi e da Telecom Italia”. Basicamente uma separação completa entre os negócios brasileiros e os não brasileiros.

Amos Genish, fundador da GVT, é o mais cotado para assumir assumiu o comando da Telefônica no Brasil. Paulo Cesar Teixeira, CEO da Vivo, deixa a companhia. Antonio Carlos Valente, que estava à frente do comando da Vivo, será o presidente do Conselho de Administração da nova empresa.

As empresas também se comprometeram a manter a média nacional mensal de velocidade de acesso à banda larga contratada pelos clientes atuais da GVT em pelo menos 15,1 Mb/s. No Estado de São Paulo, a média mensal deve atingir ao menos 18,25 Mb/s.” — Exame

Interessante notar que a média da GVT é bastante superior à nacional, que é de três megabits por segundo (3 Mb/s). A média mundial de velocidade de acesso à internet é de 4,5 Mb/s e o Brasil ocupa o 89º lugar do mundo nesse quesito. Isso considerando 142 países no último trimestre de 2014.

Concentração na TV paga?

Embora a aquisição da GVT pela Vivo pareça algo ruim ao mercado brasileiro, os negócios de ambas as empresas são em sua maioria complementares. Na telefonia fixa e banda larga, a GVT só concorreria com a Telefônica em São Paulo. Muito provável que a GVT agora vá utilizar a infraestrutura da Telefônica em tal mercado, deixando a marca Vivo para o setor de telefonia mobile mesmo.

O problema maior seria a Vivo TV, serviço de televisão por assinatura disponível em cidades como São Paulo, Curitiba e Florianópolis: em tais mercados a GVT TV incorporaria um concorrente. Sem a possibilidade de a Vivo TV se expandir nacionalmente, ficamos presos às mesmas quatro operadoras nacionais de televisão paga: SKY, Oi TV, Claro TV e GVT TV.

Enfim, particularmente fico aliviado por saber que a possibilidade de a TIM Brasil desaparecer do mercado é remota, pelo menos diante de tantas imposições do CADE. Só espero que a fusão entre GVT e Vivo não piore os serviços de ambas as companhias.

Fonte: Tele Síntese.

The post GVT agora é quase Vivo (ou vice-versa) appeared first on Meio Bit.








02 Apr 23:49

Filho de catadora passa em 1º lugar em escola federal estudando com livros achados pela mãe no lixo

by Redação Hypeness
Um exemplo de perseverança e luta, o garoto Thompson Vitor, 15 anos de idade, filho de uma catadora de lixo e de família simples, passou em primeiro lugar no exame de seleção Instituto Federal do Rio Grande do Norte (IFRN), onde irá cursar Multimídia este ano. A história deste jovem nos ensina a não desistir dos nossos sonhos independentemente […]
02 Apr 23:43

Rajeev Rastogi: Index Scan Optimization for ">" condition

In PostgreSQL 9.5, we can see improved performance  for Index Scan on ">" condition.

In order to explain this optimization, consider the below schema:
create table tbl2(id1 int, id2 varchar(10), id3 int);
create index idx2 on tbl2(id2, id3);

Query as:
                select count(*) from tbl2 where id2>'a' and id3>990000;

As per design prior to this patch, Above query used following steps to retrieve index tuples:

  • Find the scan start position by searching first position in BTree as per the first key condition i.e. as per id2>'a'
  • Then it fetches each tuples from position found in step-1.
  • For each tuple, it matches all scan key condition, in our example it matches both scan key condition.
  • If condition match, it returns the tuple otherwise scan stops.


Now problem is here that already first scan key condition is matched to find the scan start position (Step-1), so it is obvious that any further tuple also will match the first scan key condition (as records are sorted).

So comparison on first scan key condition again in step-3 seems to be redundant.

So we have made the changes in BTree scan algorithm to avoid the redundant check i.e. remove the first key comparison for each tuple as it is guaranteed to be always true.

Performance result summary:



I would like to thanks Simon Riggs for verifying and committing this patch. Simon Riggs also confirmed improvement of 5% in both short and long index, on the least beneficial data-type and considered to be very positive win overall. 
02 Apr 23:38

Internet Explorer dá lugar para o sucessor

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

internet-explorer

Não é de hoje que a Microsoft tem mudado sua forma de pensar em vários assuntos ligados ao desenvolvimento web. Agora, a última novidade, é que você vai parar de ouvir o nome Internet Explorer nos próximos anos.

A Microsoft revelou que está planejando uma nova marca e um novo nome para um browser para Windows 10. O codenome do browser é Projeto Spartan. O novo browser Spartan será o browser padrão no Windows 10. Em Janeiro a Microsoft já tinha comentado sobre o novo motor de renderização que irá fazer parte deste novo browser e muito possivelmente no IE também.

Spartan é um browser desenhado para trabalhar entre os diversos dispositivos que rodam Windows 10, desde aparelhos com mouse até touch, gestos, vozes, controles, sensores etc.

1541.project-spartan-diagram

A ideia do Internet Explorer é que ele seja usado apenas para motivos de legado e compatibilidade. Não está ainda muito claro como o IE fará parte do Windows 10 ou se ele será apenas direcionado para versões corporativas. O que eles deixam claro é que o Internet Explorer não fará mais parte do futuro da Microsoft.

7041.psatwjpb-image4

O que o novo browser e o novo motor de renderização significa para os Devs?

  1. O novo motor Spartan será default no Windows 10, no Spartan e possivelmente no Internet Explorer. O motor será interoperável e o suporte e o roadmap pode ser visto aqui: http://status.modern.ie
  2. Os sites serão renderizados pelo novo motor, usando os padrões modernos. Os comportamentos específicos do Internet Explorer não serão suportados no novo motor. Se seu site depende do IE para funcionar, a Microsoft encoraja fortemente que você mude para os padrões mais modernos. Isso quer dizer que os famosos Hacks e possivelmente o prefixo -ms- não funcionarão.
  3. O objetivo da Microsoft é a interoperabilidade com os browsers mais modernos. Você pode testar o novo motor via http://remote.modern.ie.

A ideia é não ficar em pânico. Eu aconselho esquecer o Spartan até que ele comece a pipocar no seu analytics e ainda assim mantenha em mente a compatibilidade de dois IEs antigos. Eu sempre suporto o IE mais novo, no caso hoje o 11, e duas versões anteriores, ou seja, o IE 10 e 9.

Se for para melhorar nossa vida, mesmo que seja daqui há alguns anos, não importan, eu voto pelo sucesso do novo Spartan.

---
Este artigo foi escrito por Diego Eis.

Visite o nosso site para mais posts sobre desenvolvimento web! Tableless.

30 Mar 21:23

Vírus em Linux: é possível ou você que está usando de forma errada?

by Helio Loureiro

Estava para comentar sobre vírus para Linux, um assunto espinhoso, faz um certo tempo – ao menos desde o início do ano. Agora consegui um momento livre para fazer isso.

A pergunta que surge de tempos em tempos é clara: EXISTEM VÍRUS PRA LINUX?

As respostas variam. Defensores de Windows dizem que com toda certeza existem. Mostram receitas esotéricas sobre como isso é possível e sempre voltam com a famosa frase “nenhum sistema é infalível”, ou algo parecido com isso.

Os defensores de Linux, eu me incluo nesse grupo, dizem que é impossível. Linux não é Windows. Não foi feito sobre a mesma plataforma furada da Microsoft, que é cheia de buracos, e até provavelmente com alguns toques da NSA para ajudar. Se o usuário do Linux tem algum problema, o motivo é que não sabe atualizar sua distro.

Mas isso não explica a quantidade de problemas que têm aparecido sobre malwares em plataformas Linux, inclusive Android.

O problema é o Windows. Não que o Windows tenha criado uma geração de vírus, mas ele cunhou fortemente o conceito errado de que tudo é vírus. Qualquer problema, malware, tudo é vírus. E também foi graças ao Windows que o conceito “se não funcionar, reinstala, se está lento, reinstala, e se quer mudar o wm, reinstala” se fortaleceu. Isso se faz bem claro nos usuários que, para trocar o Unity no Ubuntu, reinstalam o sistema inteiro. Em geral, com alguma refisefuqui.

Vírus é um pedaço de código que altera binários ou arquivos, e que se executa cada vez que esse programa é chamado ou aberto, no caso de arquivos.

Claramente isso não é possível no Linux por um simples motivo: quem executa o programa é o usuário, e quem é o “dono” do binário é em geral o root.

Mas os problemas existem. E muitos. Existem os usuários que teimam em trabalhar como root no sistema, para “facilitar as coisas” – em geral, os mesmos que reinstalam os sistema inteiro para apenas trocar o wm (window manager). Existem também os “programas de terceiros”, como o plugin flashplayer, que não recebem as devidas atualizações de segurança. Felizmente, esses “programas de terceiros” não causam danos ao sistema como um todo, mas infelizmente podem fazer estrago o suficiente com o usuário, como permitir que suas credenciais de banco sejam roubadas. Basta ver os recentes problemas do Java da Oracle. Recentes? Melhor dizer “contínuos”.

E dá para viver sem esses “aplicativos de terceiros”? Até dá, mas não é muito fácil. Alternativas existem, como pepperflashplugin em vez do flash da Adobe, não usar acrobat reader ou seu plugin, mais os modos nativos do Firefox e do Chrome/Chromium pra renderizar pdf etc. O problema não são os “aplicativos de terceiros”, mas se esses terceiros tratam os usuários de Linux com respeito, atualizando a cada falha encontrada. Um bom exemplo dessa prática é o “steam”, de jogos.

O problema então é o usuário, sempre?

Não. Novamente o problema vem do Windows. Ou melhor, da ideia de vírus que veio com o uso do Windows. Quando discutimos o conceito de vírus, sempre nos vêm a imagem de um desktop. Daí os argumentos de problemas de segurança no Linux são apenas falta de atualização. Isso não é verdade.

O outro lado do problema apareceu bem recentemente durante os ataques de DDoS do grupo LizzardSquad contra as redes de jogos PSN e Xbox Live. Foram usados roteadores caseiros, desses que usamos para ter acesso wi-fi às nossas redes dentro de casa. O artigo não diz, mas acredito que câmeras IPs também foram usadas.

Esse tipo de problema não é novidade. Foi discutido durante um dos YSTS, acho que o de 2013, do qual participei. Fabricantes, em geral na China, criam seus produtos para rodar Linux, mas não dão nenhuma manutenção. São sistemas customizados a ponto de ser impossível rodar uma alternativa como dd-wrt/open-wrt. Esses sistemas rodam kernels Linux muito, mas muito velhos. Daí que as explorações de vulnerabilidades, não vírus, ficam fáceis. Nesse ponto, temos que dar o braço a torcer para os usuários do Windows. Defender Linux nessas condições é quase como apontar o dedo para as máquinas Windows comprometidas que rodam a versão XP. O agravante é que o usuário se torna refém do fabricante, pois, diferentemente dos computadores, esses sistemas embutidos não permitem que qualquer um atualize como quiser, quando quiser, com a distro que mais gostar.

Então, da próxima vez que ler sobre “vírus pra Linux”, antes de cair na gargalhada, pense nesses roteadores e câmeras IPs. Pense se esses sistemas rodando um Linux 2.4.20 podem ter sua segurança facilmente comprometida. Depois lembre que o Windows, até hoje, pode ser comprometido acessando uma página web. Foi corrigido? Espere algumas semanas que sempre aparece de novo.

Ah, o Windows…

Mensagem do anunciante:

Conheça as soluções de servidores para VoIP da Under para pequenas, médias e grandes empresas. Veja os planos.

27 Mar 21:05

pessoas

by Francisco Nunes

As pessoas raramente são sempre o que são.

(Francisco Nunes)

Send to Kindle
27 Mar 20:43

Crie layouts simples. SEMPRE!

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

“Sempre que você tiver duas alternativas para explicar alguma coisa, a explicação mais simples é provavelmente a mais correta”.

Essa citação é a famosa teoria ‘Navalha de Occam‘ de Guilherme Occam, um frade franciscano inglês, também teólogo, filósofo e lógico.

Podemos dizer que o conceito desse pensamento é irmão do título desse artigo. Quanto mais simples for a mensagem, maior a chance dela atingir as pessoas. A questão que eu trago aqui é que o simples não é sinônimo de fácil como muitos pensam.

Quanto custa um site simples?

É muito comum chegar na minha caixa de e-mail pedidos de orçamentos genéricos com a recorrente pergunta: “Quanto custa um site simples?” Como se o fato de pedir algo ‘simples’ estivesse diretamente ligado a ‘orçamento barato’! Já são quase 7 anos trabalhando como freelancer para perceber que isso é uma regra! Todos que usam essa frase querem desconto, não algo realmente simples porque querem passar uma mensagem simples para os usuários do seu site. Preço eu discuto num outro artigo, prometo. O que eu quero discutir aqui hoje é o conceito do simples e como ele é poderoso na comunicação.

Antes do layout, o conteúdo

Como princípio básico, eu construo os meus layouts o mais simples possível para os usuários. Mas para chegar numa interface simples é preciso muito convencimento e poder de argumentação com os clientes. 100% dos que eu atendi nesses anos, jamais criou o seu próprio conteúdo de comunicação sem que eu brigasse pelo usuário!

"Don't be evil" - Frase conceito do Google usada como norte em todos os projetos.

“Don’t be evil” – Frase conceito do Google usada como norte em todos os projetos.

Claro, que eu sou um tipo de profissional que se posicionou no mercado para atender pequenas e médias empresas. Estruturas que não possuem departamento de comunicação. Normalmente eu falo diretamente com o dono da empresa e é aí que mora o problema, porque a maioria das vezes ele não tem capacidade para gerar essa comunicação e pior, ainda acha a contratação de um profissional de planejamento e criação de conteúdo, caro e desnecessário, uma vez que ninguém melhor do que ele entende do próprio negócio.

Por mais que eu concorde com esse último argumento, isso não significa que ele sabe como se comunicar com o seu consumidor para falar sobre a sua empresa, marca, serviço ou produto. E sem a comunicação adequada, não há arquitetura de informação bem feita e consequentemente o ‘site simples’ contratado lá atrás no formulário, vira algo ‘simplista’, inadequado, capenga!

Antes de rabiscar o layout, é preciso muita pesquisa e planejamento

A prova disso é que se você pedir para um empresário responder junto com ele uma simples matriz de Análise SWOT sobre a sua empresa, ele será incapaz de responder de forma equilibrada a maioria dos tópicos. Ora vai superestimar alguns pontos, como subestimar outros. O resultado dessa estratégia é criar uma interface que efetivamente não comunica, não atrai, e não interage com o consumidor/usuário.

crie-layouts-simples-sempre-002

Aliás, interagir é um verbo que dificilmente os pequenos e médios empresários gostam de conjugar. O foco mesmo é a concorrência em todas as análises e tomadas de decisões. Para quase todas as perguntas a resposta é sempre a mesma. “Deixa eu ver como o meu concorrente está fazendo no site dele.” E assim, adeus diferencial.

Mas e o conceito do simples?

"Design é função, não forma" (Steve Jobs)

“Design é função, não forma” (Steve Jobs)

Bom, segundo Steve Jobs, “Design é função, não forma“. Ou seja, se um site não possui uma utilidade, deixa de ser necessário, e óbvio que o layout será inútil para o usuário. Cabe ao empresário pensar antes de contratar um profissional, e fazer as seguintes perguntas para sim mesmo:

  • Porque a minha empresa precisa de um site?
  • Como eu posso melhorar a relação dos nossos consumidores com a minha empresa?
  • Quanto eu estou disposto a ouvir e interagir com os nossos consumidores?
  • Como eu posso agregar mais valor dos meus serviços/produtos?
  • Entre outras tantas!…

Baseado nas respostas desse empresário, certamente ele terá um perfil desse projeto bem mais adequado à realidade. E de posse do conceito desse projeto, de preferência documentado, ele terá condições de selecionar o tipo de profissional que tem condições técnicas de atendê-lo, e tenho certeza, que só assim, o design simples será criado, pois será focado no usuário e não no preço.

Caso contrário, será apenas mais um site inútil na web e teremos um empresário que vai continuar achando que a Internet não serve para o seu negócio.

---
Este artigo foi escrito por @cristianoweb.

Visite o nosso site para mais posts sobre desenvolvimento web! Tableless.

27 Mar 12:18

O robô da NET me atendeu muito bem

Reclamar e falar mal das empresas é fácil, sai naturalmente. Mas é importante elogiar quando merecido.

Ontem deu chuva forte em Joinville e minha internet caiu. Liguei pra NET no 106 21, e sem precisar digitar ou falar absolutamente nada, obtive todas as informações que eu precisava em menos de um minuto. Repito: não digitei nem falei nada, somente fiquei ouvindo, do início ao fim da ligação.

Quem me atendeu, como de costume, foi o robô da NET: um “cara legal”, que conversa contigo em tom descontraído (sem gerundismo) e te apresenta as opções do menu. É uma voz gravada, claro, mas é feito de maneira que soa natural, com simpatia. Liga lá e confira.

Infelizmente não gravei a ligação, mas foi mais ou menos assim:

Você está na NET. Eu identifiquei o telefone de onde você está ligando, então já vou procurar o seu cadastro. Tec tec tectec tec [digitando]. Pronto, achei.

Sem perder tempo, ele já sabe quem eu sou e onde fica minha casa. É massa o barulhinho de teclado enquanto ele procura, altos efeitos especiais :)

Vejo que a sua região está passando por problemas técnicos, e você deve estar sem sinal de TV e de internet.

Ele descreveu o meu problema, me dando a tranquilidade que não é algo isolado de minha casa. Ufa, não precisarei chamar um técnico.

Nossas equipes já estão trabalhando para resolver o problema e a previsão de retorno do sinal é às 22:30.

Essa é a informação mais importante que eu queria saber. Show!

Isso é tudo o que sabemos no momento, inclusive em nossa central de atendimento.

Ou seja, nem perca tempo querendo falar com um de nossos atendentes humanos, pois eles não saberão nada além disso.

Te avisaremos via SMS se houver alguma novidade sobre o assunto.

Por essa eu não esperava, excelente.

Anote o número de protoc…

Aqui desliguei, pois já soube o que eu queria. Mas pensando agora, coitado do robô, desliguei na cara dele :/

Fiquei bastante impressionado com o atendimento automatizado, e ao mesmo tempo, personalizado. A Mog ficou me olhando sem entender porque eu estava com aquela cara de bobo-alegre, desligando o telefone sem ter falado nada.

Comecei a explicar, mas achei melhor simplesmente ligar de novo pra NET, pra que ela ouvisse a mesma mensagem. E não é que dessa vez foi diferente? Começou igual, até a parte de achar o meu cadastro. Então seguiu mais ou menos assim:

Vejo que você já nos ligou hoje para falar de problemas técnicos. A previsão de retorno do sinal não mudou, continua para às 22:30.

OK robô da NET, você é o cara, virei teu fã :)

Obs.: o sinal voltou antes do prazo.

27 Mar 03:00

Expressões regulares em bancos de dados SQL

Você sabia que é possível usar as poderosas expressões regulares em suas queries SQL no banco de dados?

O operador LIKE até quebra um galho para pesquisas mais simples, com seus metacaracteres % e _. Mas para ir além e fazer pesquisas realmente complexas, você precisará de toda a gama de metacaracteres das expressões regulares.

As expressões não fazem parte do padrão SQL (ainda), mas alguns bancos de dados já se adiantaram e passaram a suportá-las. Porém, pela falta do padrão, cada banco implementou de seu próprio jeito, o que gerou uma diferença na sintaxe de uso. Nos exemplos seguintes, serão mostradas as sintaxes dos principais bancos.

Suponha que temos um banco de dados com uma tabela chamada veiculos, que traz vários dados sobre cada veículo. A placa do veículo, por exemplo, deve estar no formato AAA-9999. Este é um formato simples, que conseguimos representar com a expressão regular ^[A-Z]{3}-\d{4}$. Para listar todos os veículos cujas placas estão no formato correto:

-- Listar os veículos cujas placas estão no formato AAA-9999

-- MySQL, MariaDB, SQLite
SELECT * FROM veiculos WHERE placa REGEXP '^[A-Z]{3}-\d{4}$';

-- PostgreSQL
SELECT * FROM veiculos WHERE placa ~ '^[A-Z]{3}-\d{4}$';

-- Oracle
SELECT * FROM veiculos WHERE REGEXP_LIKE(placa, '^[A-Z]{3}-\d{4}$');

As coisas ainda estão um pouco bagunçadas, não? Enquanto o SQLite e o MySQL usam o operador REGEXP, o PostgreSQL usa o operador ~ e o Oracle usa uma função REGEXP_LIKE(). Mas tudo bem, use essa colinha para lembrar.

Para fazer uma expressão negada, basta colocar NOT antes do operador, ou no caso do PostgreSQL, usar !~. Voltando ao exemplo anterior, agora buscando os veículos cujas placas não seguem o padrão:

-- Listar os veículos cujas placas NÃO estão no formato AAA-9999

-- MySQL, MariaDB, SQLite
SELECT * FROM veiculos WHERE placa NOT REGEXP '^[A-Z]{3}-\d{4}$';

-- PostgreSQL
SELECT * FROM veiculos WHERE placa !~ '^[A-Z]{3}-\d{4}$';

-- Oracle
SELECT * FROM veiculos WHERE NOT REGEXP_LIKE(placa, '^[A-Z]{3}-\d{4}$');

E aí, já está tendo ideias?

E que tal se eu te contar que além de pesquisas, você também pode fazer alterações usando expressões regulares? Aí sim, o negócio começa a ficar muito interessante!

O exemplo anterior listou todas as placas que estão fora do padrão AAA-9999. Lembre-se, o usuário é criativo na hora de digitar dados, então é comum encontrarmos placas em formatos variados, como AAA 9999, AAA.9999, AAA:9999, AAA9999, …

Em geral, é a aplicação quem faz a limpeza destes dados na hora de mostrá-los na tela, removendo os caracteres indesejados e formatando no padrão correto. Mas você já pode fazer isso na própria consulta SQL, usando substituição de texto com expressões regulares:

-- Mostra o valor original e o formatado como AAA-9999

-- MariaDB
SELECT
  placa AS placa_original,
  REGEXP_REPLACE(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\\1-\\2') AS placa_ok
FROM veiculos;

-- PostgreSQL
SELECT
  placa AS placa_original,
  regexp_replace(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\\1-\\2') AS placa_ok
FROM veiculos;

-- Oracle
SELECT
  placa AS placa_original,
  REGEXP_REPLACE(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\1-\2') AS placa_ok
FROM veiculos;

Que tal ir um passo além, e já corrigir estes dados diretamente no banco de uma vez? Assim, eles já estarão sempre corretos e ninguém mais precisará se preocupar em formatá-los posteriormente.

Primeiro, você aplica a técnica do exemplo anterior, de usar o SELECT para mostrar o valor original e o novo, e vai com calma, ajustando sua expressão regular até ela ficar perfeita, formatando corretamente 100% dos casos. Depois, você utiliza a mesma expressão no UPDATE, corrigindo de uma vez todos os dados:

-- Corrigir todas as placas para o formato AAA-9999

-- MariaDB
UPDATE veiculos
SET placa = REGEXP_REPLACE(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\\1-\\2');

-- PostgreSQL
UPDATE veiculos
SET placa = regexp_replace(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\\1-\\2');

-- Oracle
UPDATE veiculos
SET placa = REGEXP_REPLACE(placa, '^([A-Z]{3})[.: ]?(\d{4})$', '\1-\2');

Se você também já perdeu muito tempo de vida fazendo faxina nos dados do banco, sabe que poder usar expressões regulares nestes casos NÃO TEM PREÇO.

E assim amiguinhos, vamos aos poucos resolvendo os problemas causados por pessoas toscas, sistemas toscos e migrações toscas :)

Se você quiser saber mais sobre expressões regulares e como usá-las em bancos de dados, leia meu livro Expressões Regulares - Uma abordagem divertida.

23 Mar 21:03

Rajeev Rastogi: Overview of PostgreSQL Engine Internals

POSTGRESQL is an open-source, full-featured relational database. This blog gives an overview of how POSTGRESQL engine processes queries received from the user.
Typical simplified flow of PostgreSQL engine is:

SQL Engine Flow

As part of this blog, I am going to cover all modules marked in yellow colour.

Parser:
Parser module is responsible for syntactical analysis of the query. It constitute two sub-modules:
1. Lexical scanner
2. Bison rules/actions

Lexical Scanner:
Lexical scanner reads each character from the given query and return the appropriate token based on the matching rules. E.g. rules can be as follows:

   

    Name given in the <> is the state name, in the above example <xc> is the state name for the comment start. So once it sees the comment starting character, comment body token will be read in the <xc> state only.

Bison:
Bison reads token returned from scanner and matches the same  against the given rule for a particular query and performs the associated actions. E.g. the bison rule for SELECT statement is:

       

So each returned token is matched with the rule mentioned above in left-right order, if at any time it does not find matching rule, then either it goes to next possible matching rule or throws an error.

Analyzer:
Analyzer module is responsible for doing semantic analysis of the given query.  Each raw information about the query received from the Parser module is transformed to database internal object form to get the corresponding object id. E.g. relation name "tbl" get replaces with its object id.
Output of analyzer module is Query tree, structure of same can be seen in the structure "Query" of file src/include/nodes/parsenodes.h

Optimizer:
Optimizer module also consider to be brain of SQL engine is responsible for choosing the best path for execution of the query. Best path for a query is selected based on the cost of the path. The path with least cost is considered to be a winner path.
Based on the winner path, plan is created which is used by executor to execute the query.
Some of the important decision points are taken in terms of below methods:

  1. Scan Method
  • Sequential scan: Simply read the heap file start to end so it is considered to be very slow if many records to be fetched.
  • Index scan: Use a secondary data structure to quickly find the records that satisfy a certain predicate and then corresponding to that it looks for other part of the record in Heap. So it involves extra cost of random page access.
  • Join Method
    • Nested Loop Join: In this join approach, each record of outer table is matched with each record of inner table. The simple algorithm for the same is:
                   For a NL join between Outer and Inner on Outer:k = Inner:k:

                                         for each tuple r in outer:
                                                 for each tuple s in Inner with s.k = r.k:
                                                            emit output tuple (r,s)

                                Equivalently: Outer is left, Inner is right.

                                            
                                      


      • Merge Join: This join is suitable only sorted record of each participating table and only for "=" join clause. The simple algorithm for this join is:
                           For both r in Outer, s in Inner:
                                                if r.k = s.k:
                                                      emit output tuple (r,s)
                                                      Advance Outer & Inner
                                                 if r.k < s.k
                                                      Advance Outer
                                                 else
                                                      Advance Inner
                               
                                    
                                         

        • Hash Join: This join does not require records to be sorted but this is also used only for "=" join clause.
                               For a HJ between Inner and Outer on Inner:k = Outer:k:
                                       -- build phase
                                      for each tuple r in Inner:
                                           insert r into hash table T with key r.k
                                      -- probe phase
                                     for each tuple s in Outer:
                                           for each tuple r in bucket T[s.k]:
                                           if s.k = r.k:
                                                emit output tuple (T[s.k], s)

                                      
                                          
        3. Join Order: It is mechanism to decide the order in which table has to be joined.

         Typical output of the plan is:
          postgres=# explain select firstname from friend where age=33      order by firstname;
                                  QUERY PLAN
        --------------------------------------------------------------
         Sort  (cost=1.06..1.06 rows=1 width=101)
           Sort Key: firstname
           ->  Seq Scan on friend  (cost=0.00..1.05 rows=1 width=101)
                 Filter: (age = 33)
        (4 rows)
          Executor:
          Executor is the module, which takes output of planner as input and transform each node of plan to state tree node. Then in turn each node gets executed to perform the corresponding operation. 
          The state tree nodes execution starts from root and to get the input, it keep going to child node till it reaches the leaf node. So finally leaf node executed to pass the input to upper node. Out of two leaf nodes, first outer node (i.e. left node) gets evaluated.
                   At this point it uses the interface from storage module to retrieve the actual data.

          Typically execution process can be divided as:
          • Executor Start: Prepares the plan for execution. It process each node of plan recursively and generate corresponding state tree node. Also it initializes memory to hold projection list, qualification expression and slot for holding the resultant tuple. 
          • Executor Run: Recursively process each state tree node and each resultant tuple is send to front-end using the register destination function.
          • Executor Finish: Free all the allocated resources.
          One of the typical flow of execution is as below:
          So in above flow, Execution starts from Merge Join but it needs input to process, so it flow towards first left child node, take one tuple using index scan and then it request for input tuple from right child node. Right child node is Sort node, so it request for tuple from its child, which in turn does the sequence scan. So once all tuple is received at Sort node and tuples are shorted, then it passes the first tuple to its parent node.

          Reference:
          Older papers from PostgreSQL.  
          22 Mar 18:39

          Homem capta primeiras imagens da nova ilha que emergiu no Pacífico

          by Redação Hypeness
          Poucos dias após relatarmos as cinco ilhas que podem desaparecer do mundo se continuarmos tratando o planeta da mesma forma (conheça todas aqui), eis que surge uma novidade: foi encontrada uma nova ilha no Pacífico Sul. Após a erupção de um vulcão submarino no arquipélago de Tonga, na Polinésia, emergiu a formação de 500 metros […]
          22 Mar 18:30

          ocupação

          by Francisco Nunes

          Falta de ocupação não é repouso. Uma mente absolutamente vazia vive angustiada.

          (William Cowper)

          Send to Kindle
          20 Mar 14:03

          What Your Email Domain Says About You

          by DOGHOUSE DIARIES

          What Your Email Domain Says About You

          This is obviously to say nothing of what precedes the @ symbol.

          If an incomplete sentence lands in a forest

          — Ray Yamartino (@rayyamartino) March 20, 2015
          20 Mar 13:52

          Yahoo vai nos livrar das senhas, mas há um porém.

          by Carlos Cardoso

          a113-terminator

          Eu tenho um problema sério de senhas. Bem antes de ter idiotas todo dia tentando invadir minhas contas achando que minha senha do Gmail é “vendramini”, eu já era paranóico. WarGames, Quebra de Sigilo, os seriados da infância, tudo contribuiu para que minhas senhas fossem seguras. Em alguns casos em nem sei a senha, guardo em arquivos offline.

          Esta é uma senha típica que uso.

          t5ffT$G(15IwxN*JUp7dWqF"Jt2GUQmCUp+

          Aí eu vou instalar um equipamento novo, não tem como conectar e copiar o arquivo, sou obrigado a digitar essa desgraça.

          A proposta do Yahoo, que já está rolando nos EUA, se propõe a resolver isso, de uma forma bem criativa. A idéia é simples: você usa aquela senha monstruosa para entrar no Yahoo, se autentica, prova que você é você.

          Daí vai nas configurações de segurança e habilita “Senhas On-Demand”. Insere seu número de celular, confirma e pronto.

          Quando você for usar um computador suspeito (e todos são) em um evento, na casa de um conhecido, num hotel, acesse o Yahoo com seu username e clique “envie minha senha”.

          O sistema mandará um SMS para seu celular com uma senha temporária de uso único. Você a digitará e pronto, seu acesso garantido, sua senha de verdade protegida, pois nunca passou pela rede suspeita.

          De um certo ponto de vista é melhor, ou pelo menos mais prático do que a autenticação em dois níveis. É algo que eu gostaria de ver nos principais serviços online, e o único porém da idéia é que para nós que moramos no mato (da linha do Equador pra baixo) é complicado confiar nas operadoras de celular, corre risco do código não chegar nunca.

          Fonte: WC.

          The post Yahoo vai nos livrar das senhas, mas há um porém. appeared first on Meio Bit.








          18 Mar 13:55

          Primeira geração do Moto X começa a receber Android 5.0 Lollipop

          by Ronaldo Gogoni

          moto-x-2013

          Vamos combinar que a Motorola não está com muita pressa para atualizar seus dispositivos mobile, e olha que ela possui poucos em linha atualmente. Em novembro último ela prometeu que todos os seus dispositivos receberiam o Android 5.0 Lollipop o quanto antes e bem, já estamos em março e meu Moto Maxx ainda está no 4.4.4 KitKat.

          Bom, quem estava perdendo as esperanças nessa história toda eram os donos da primeira geração do Moto X, já que a empresa havia notificado que houveram problemas de compatibilidade. Pois agora esses usuários podem se alegrar, pois a atualização está chegando. A informação vem de Juliano Carvalho, engenheiro da Motorola que comentou sobre o update em uma postagem do Google+.

          A liberação do update está seguindo o mesmo molde da atualização do primeiro Moto E e do Moto Maxx: ela será liberada em caráter de testes (o que é compreensível, se considerarmos que houveram problemas para adaptar o Android de pirulito para o primeiro Moto X) e num primeiro momento apenas alguns usuários serão contemplados; portanto não estranhe se seu smartphone não for elegível logo de cara, a atualização poderá aparecer nas próximas semanas.

          Dito isso, sejamos realistas: é bem provável que as primeiras gerações do Moto X, Moto G e Moto E não recebam mais nenhuma atualização, ficando os três aparelhos presos no Android 5.0.2. Ao que tudo indica não há planos para disponibilizar o Android 5.1, que corrige uma série de bugs e adiciona novos recursos.

          É importante notar que apesar de estar demorando um bocado, a Motorola está trabalhando para entregar os updates e eles irão aparecer de qualquer forma. Afinal, sem nenhum aviso a empresa atualizou recentemente o RAZR i, um aparelho com mais de dois anos de idade para o Android 4.4.2 KitKat.

          Com isso toda a linha Moto está na teoria recebendo o update para o Android 5.0.2 Lollipop, embora ainda deva demorar um pouco para todo mundo poder usufruir da mais recente versão do robozinho.

          Fonte: G+.

          The post Primeira geração do Moto X começa a receber Android 5.0 Lollipop appeared first on Meio Bit.