Skip to content

Fechando o Circuito

É 1955. Você é cientista no laboratório de computação da Universidade de Michigan. O laboratório abre às seis da manhã, mas você chega às cinco e meia. Não por obrigação, não porque alguém mandou, mas porque você não consegue dormir por estar entusiasmado com o trabalho.

Três semanas. Três semanas é o tempo que você tem passado lendo o manual ténico do computador do laboratório. Um documento de 240 páginas escrito em "linguagem de engenharia", denso e cheio de termos ténicos como um contrato jurídico, cheio de diagramas de circuitos e tabelas de sinais elétricos que você precisa ler, reler e reler de novo até que você entenda como fazer um código funcionar nela, de acordo com as necessidades do seu laboratório. Você passa três semanas escrevendo código, testando, corrigindo, testando de novo. Três semanas nessa sala, desde manhã até à noite, com o mesmo barulho constante das máquinas ao fundo, um zumbido mecânico que você nem repara mais de tanto que já se acostumou ao ambiente.

Na sexta-feira anterior, às onze da noite, o programa que você estava escrevendo finalmente tinha funcionado. Você viu os primeiros caracteres saindo pela impressora, os resultados do cálculo aparecendo exatamente como deviam aparecer. Você ficou olhando para aquele papel por um tempo que provavelmente era longo demais para alguém observando você. Mas três semanas de trabalho estavam ali, naquelas linhas impressas. Você tinha o direito de olhar.

Na manhã de segunda feira, você entra no laboratório com um maço de cartões perfurados debaixo do braço - os computadores da época trabalhavam com cartões perfurados - eram o programa que você passou as três semanas anteriores construindo, e encontra dois técnicos desparafusando o computador do laboratório e o levando embora.

No lugar dele, ainda embalado parcialmente em plástico, há um computador novo. Mais moderno. Mais rápido. De outro fabricante.

Ninguém te avisou.

Você fica parado por um momento olhando para a máquina nova, e já sabe o que aquilo significa antes mesmo de alguém falar com você. Conhece esse sentimento. É o sentimento de que o chão sumiu. De que todo trabalho foi em vão.

Trocaram o computador porque esse novo é capaz de fazer os mesmos cálculos na metade do tempo. Mas isso significa que você teria que escrever um código novo do zero para esse computador.

Não importa que o código anterior estivesse correto. Não importa que os cálculos estavam certos. O computador novo não entende uma única instrução que você havia escrito. Ele é de um fabricante diferente, tem uma lógica diferente, espera sinais diferentes, numa ordem diferente. Tudo que você aprendeu sobre o computador antigo não serve para nada agora. O manual novo tem 280 páginas. Você vai ter que recomeçar do zero.

Você coloca os cartões em cima da mesa, puxa a cadeira, senta e fica olhando para o computador novo por um tempo que, desta vez, definitivamente é longo demais.


70 anos depois, numa tarde de terça-feira, um homem chamado Tomás está no Aeroporto Internacional de São Paulo esperando o embarque do seu voo. Ele viaja a trabalho três vezes por mês, e aprendeu faz tempo que depois de passar pela segurança e chegar no portão de embarque, os aeroportos são lugares para não pensar: você encontra uma cadeira, tira o celular do bolso, e deixa o tempo passar até a hora de embarcar.

O celular toca. É uma notificação da esposa.

Ele abre o Whatsapp e vê que é um vídeo de 2 minutos. O filho de 1 ano e 2 meses está de pé, no meio da sala, segurando o sofá com uma das mãos, e claramente prestes a soltar. A esposa filma em silêncio, sem se mexer, sem falar, para não assustar. E então o menino solta o sofá. Fica de pé sozinho por talvez dois segundos, com aquela expressão de absoluta concentração que crianças pequenas têm quando estão fazendo algo que exige todo o esforço que têm. E então dá um passo. E outro. E cai sentado no tapete com um baque macio, e olha para a câmera com uma cara de quem não tem certeza se deve rir ou chorar, e a esposa explode em gargalhadas atrás da câmera, e o menino decide que vai rir também.

Tomás assiste três vezes seguidas ali na cadeira do aeroporto, com a mala entre as pernas e o barulho de anúncios ao fundo, e na terceira vez, sai uma lágrima de seus olhos de um jeito que ele não estava esperando.


Em outro canto do país, no Rio de Janeiro, uma médica chamada Isabela abre no computador do consultório o resultado de um exame de ressonância magnética. A imagem carrega na tela, cinza e detalhada, e ela aproxima o rosto do monitor. Fica em silêncio por quase um minuto. O resultado é o que ela esperava. Não é o que esperava para o paciente.


É 00:43. Neo tem vinte e dois anos, mora sozinho num apartamento pequeno, e está deitado na cama com um fonte de ouvido velho que já perdeu metade do amortecimento da espuma. Ele coloca uma música que não houvia faz quatro anos. Os primeiros segundos tocam, e alguma coisa no peito aperta de um jeito que ele não saberia explicar se tentasse. É uma música que ele houvia numa época específica da vida, com pessoas específicas, num lugar que não existe mais exatamente como naquela época. A música não mudou, é a mesma. Ele que mudou. E os dois, a música e ele, estão se encontrando do outro lado de quatro anos como duas pessoas que se conheceram num lugar e se reencontram em outro, e precisam de um momento para se reconhecer.


Numa sala de aula de uma universidade federal, Mariana aperta Ctrl+S no documento onde está o terceiro capítulo da sua dissertação de mestrado. Oito meses de trabalho. Ela aperta quase por reflexo a cada frase que digita, como todo mundo que já perdeu alguma coisa importante uma vez e nunca mais esqueceu que precisa salvar. Dois segundos depois a energia do prédio cai. A tela escurece. Mariana fica olhando para o monitor apagado no escuro, e então sorri sozinha, aliviada de um jeito que só faz sentido para quem já perdeu algum trabalho e sabe exatamente de que tamanho é o alívio de saber que seu trabalho está a salvo.

O que você não viu acontecendo

Você deve ter percebido que essa seção começou de forma diferente das anteriores. Sem tabelas, sem conversões matemáticas. Só histórias. Isso foi intencional.

Estamos na última seção do capitulo, e eu queria que você chegasse até aqui com a mesma leveza de quem chegou à última página de um livro muito bom: não com a sensação que ainda tem muito pela frente, mas com curiosidade de quem quer saber como a história termina.

E tem algo escondido em todas essas histórias que contei. Um pai recebendo o vídeo dos primeiros passos do filho, uma médica abrindo um exame que vai mudar a vida de um paciente, um rapaz sendo levado de volta por uma música a uma época que não volta mais, uma estudante que salva o arquivo dois segundos antes da energia acabar...

São situações que qualquer pessoa reconhece. E o que permitiu que todas elas fossem possíveis, é justamente o que estudamos no capitulo inteiro. Está acontecendo por baixo de tudo, invisível e silencioso sem as pessoas nem notarem: bytes sendo movidos de um lugar para o outro, bytes sendo lido e interpretados, bytes sendo transformados em imagem, em som, em texto guardado permanentemente num disco.

Mas quem move esses bytes? Quem decide o que cada sequência de bytes significa? Quem garante que o vídeo do filho chega como vídeo, e não como zeros e uns? Quem faz com que a música toque em vez de exibir uma tela de erro? Quem garante que o documento da Mariana esteja intacto quando ela religar o computador?

Essa pergunta ficou sem resposta no final da seção anterior.

E a resposta começa exatamente onde começamos no começo desta seção: naquela sala de 1955, onde você estava olhando para um computador novo que não entendia uma palavra do código que você já havia escrito. Porque o que você viveu naquela manhã não era um problema pessoal, nem um azar isolado. Era um problema que toda a computação vivia ao mesmo tempo, e cuja solução mudaria para sempre a forma como software (código que roda no computador) e hardware (as partes físicas do computador) se relacionam.

É hora de respondê-la.

Como os computadores funcionavam no começo

Os computadores de 1950 não tinham teclado. Não tinham mouse. Não tinham tela. Como você já viu na seção anterior, eram máquinas enormes que ocupavam salas inteiras, cheias de cabos, válvulas e componentes eletrônicos, e que se comunicavam com os programadores de uma forma diferente de tudo que você conhece hoje: por meio de cartões perfurados.

Cartões perfurados e operadores

Um cartão perfurado era exatamente o que o nome sugere: um retângulo de papelão rígido, mais ou menos do tamanho de uma nota de dinheiro, coberto de pequenos furos em posições específicas. Cada posição no cartão podia ou não ter um furo, e essa combinação de furos e ausência de furos representava informação - exatamente como zeros e uns representam informação dentro do computador, só que de forma física, que você podia segurar nas mãos. Um programa completo era um maço de cartões, às vezes dezenas deles, às vezes centenas, cada um representando uma linha de instruções para o computador. Você carregava o seu programa literalmente debaixo do braço.

Cartão perfurado para entrada de dados na primeira geração de computadores.
Cartão perfurado para entrada de dados na primeira geração de computadores. Pete Birkinshaw from Manchester, UK, CC BY 2.0, via Wikimedia Commons

Para executar um programa, você não simplesmente "abria" ele como faz hoje. Você entregava o seu maço de cartões para uma pessoa específica cujo trabalho era operar o computador. Essa pessoa se chamava operador.

O operador era o intermediário entre os pesquisadores e a máquina. Ele recebia os programas em forma de cartões, os carregava fisicamente no computador na ordem correta, iniciava a execução, aguardava o resultado ser impresso em papel, e então entregava o papel de volta ao pesquisador que tinha solicitado. Ninguém mais tocava no computador. Você entregava os cartões, esperava, e recebia um papel com o resultado.

Esse processo tinha um problema óbvio: você esperava muito. Se havia dez pesquisadores querendo executar programas naquele dia, o operador precisava processar cada um dos dez por vez. Enquanto seu programa não chegasse à frente da fila, você não tinha nada para fazer além de aguardar. Às vezes horas. E se o seu programa desse erro no meio da execução, você recebia de volta uma folha com uma mensagem de erro, precisava encontrar o problema, perfurar cartões novos com a correção, e voltar para o fim da fila.

Isso que era ser um programador naquela época.

Mas a espera do pesquisador, por mais frustrante que fosse, não era o maior problema. O maior problema estava no próprio computador.

O problema que ninguém conseguia ignorar

Entre a execução de um programa e o seguinte, o computador ficava completamente parado. O operador precisava descarregar os cartões do programa anterior, organizar o maço, pegar o próximo maço de cartões da fila, carregá-los na máquina, verificar se estavam na ordem certa, e só então iniciar a próxima execução. Durante esse tempo todo a máquina não fazia nada. O processador, o compoenente mais caro e mais poderoso do sistema, ficava parado esperando um ser humano terminar de manusear papelão.

E também não era só nas trocas entre programas. Mesmo que o computador tivesse em execução, o processador passava muito tempo sem trabalhar. Para entender por quê, pense no que acontecia quando um programa precisava imprimir um resultado.

A impressora era um dispositivo mecânico. Ela tinha partes físicas que se moviam: uma cabeça de impressão que percorria o papel, um mecanismo que avançava no papel linha por linha. Comparada ao processador, que operava em frações de segundo, a impressora era absurdamente lenta. Quando o programa enviada dados para ela, o processador precisava esperar a impressora terminar antes de continuar. E enquanto esperava, ele não fazia nada. Nenhum cálculo, nenhuma instrução útil. Ficava parado, aguardando um mecanismo mecânico terminar o seu trabalho em velocidade de mecanismo mecânico.

O mesmo acontecia com a leitura dos próprios cartões perfurados. O leitor de cartões era um dispositivo físico que precisava passar cada cartão por um sensor. Comparado ao processador, era lento da mesma forma que a impressora. O processador enviava um comando para ler o próximo cartão, e então esperava. E esperava. E esperava.

Num equipamento que custava o equivalente a vários milhões de reais de hoje, essa era a realidade: a parte mais cara e mais poderosa do sistema passava boa parte do seu tempo fazendo absolutamente nada, esperando por coisas mais lentas terminarem.

Como você já deve imaginar, inevitavelmente as instituições começaram a pensar: precisa existir uma forma melhor de organizar tudo isso.

O programa que gerenciava outros programas

O primeiro passo concreto veio em 1956, de uma parceria improvável. A General Motors, uma das maiores montadores de automóveis dos Estados Unidos, e a North American Aviation, fabricante de aviões e equipamentos aeroespaciais, eram clientes do mesmo computador: o IBM 704, um dos mais poderosos da época. As duas empresas enfrentavam o mesmo desperdício todos os dias, e decidiram tentar resolver o problema juntas.

Um homem e uma mulher trabalhando com um computador IBM-704, usado para realizar cálculos em pesquisas aeronáuticas.
Um homem e uma mulher trabalhando com um computador IBM-704, usado para realizar cálculos em pesquisas aeronáuticas. NASA, Public domain, via Wikimedia Commons

O que elas criaram foi um programa para o computador. Não só mais um programa, foi um programa especial. Não era um programa que fazia cálculos ou que processava dados de negócio. Era um programa cujo objetivo era gerenciar outros programas. Ele se chamou GM-NAA I/O, nome formado pelas iniciais das duas empresas mais a sigla de Input e Output, que em inglês é Entrada e Saída.

O funcionamento dele até que era simples, mas revolucionário: em vez de o operador carregar um programa por vez e esperar cada um terminar antes de carregar o próximo, O GA-NAA I/O permitia que todos os programas do dia fossem carregados de uma vez só, num único grande lote de cartões. A partir daí, o próprio sistema executava um programa, passava automaticamente para o seguinte quando terminava, e assim por diante, sem parar, sem esperar o operador, sem pausa entre um e outro.

Pela primeira vez na história, um computador estava gerenciando a si mesmo.

Dica de nomenclatura

O GM-NAA I/O inaugurou uma forma completamente nova de trabalhar com computadores, que ganhou um nome que existe até hoje: processamento em lote, do inglês batch processing.

Se você alguma vez ver esse termo por aí, já sabe de onde vem. O nome vem exatamente da ideia central: em vez de o operador carregar um programa por vez, ele agrupava todos os outros do dia num único lote de cartões, carregava tudo de uma vez só, e o sistema se encarregava de executar cada um em sequência, sem precisar de mais nenhuma intervenção humana até o final.

O tempo que antes era desperdiçado nas trocas manuais entre programas desapareceu. A IBM (a fabricante do computador) percebeu imediatamente o potencial e, ao longo dos anos seguintes, foi desenvolvendo e distribuindo seus próprios programas semelhantes para os seus clientes, tanto para computadores que já estavam em uso quanto para os novos que saíam de fábrica. As outras fabricantes seguiram o mesmo caminho. Em poucos anos, o processamento em lote deixou de ser uma solução criativa de duas empresas e se tornou o padrão esperado de qualquer computador vendido para uso institucional.

Vale notar

Naquela época, nenhum fabricante vendia software separadamente: o modelo de negócio era vender o hardware, e qualquer software vinha junto, sem custo adicional, como parte do pacote. Quem já tinha um computador recebia do fabricante os novos sistemas por meio de fitas magnéticas ou cartões perfurados enviados pelo próprio fabricante, carregava no computador, e passava a tê-lo disponível. Quem comprava um computador novo recebia tudo junto desde o início.

Havia ainda um outro caminho para que esses sistemas chegassem aos laboratórios: comunidades de usuários organizadas por fabricante, onde compartilhavam entre si os programas que desenvolviam.

Em 1955, alguns usuários de computadores da IBM fundaram um grupo chamado SHARE, com o objetivo de compartilhar programas e sistemas entre as instituições. Os usuários de computadores da Unicav tinham o USE, de Univac Scientific Exchange. Existiam várias comunidades diferentes.

O próprio GM-NAA I/O foi distribuido pelo SHARE antes mesmo de a IBM desenvolver suas próprias versões equivalentes. Era uma espécie de comunidade de troca, onde quem resolvia um problema compartilhava a solução com todos os outros que tinham o mesmo computador.

Foi um avanço enorme. Mas à medida que os laboratórios e empresas em todo mundo começaram a trabalhar dessa forma, ainda tinha um outro problema que o processamento em lote não resolvia.

Mesmo com o GA-NAA I/O gerenciando a fila, quando um programa começava a rodar, ele ainda tomava o computador inteiro para si. Todos os outros programas do lote ainda ficavam esperando. Todos os outros pesquisadores ficavam esperando. Se o seu programa levava quatro horas para terminar, quatro horas era o tempo que todo o resto ficava na fila, sem poder fazer nada.

O fato de boa parte do tempo o processador não estar realmente trabalhando começou a se tornar frustrante para os pesquisadores. Como você já sabe, ele ficava grande parte do tempo esperando outras coisas como a impressora e o leitor de cartões. O programa mais lento do sistema não era o programa em si, era o hardware físico ao redor dele. E enquanto esse hardware trabalhava em velocidade de hardware físico, o processador ficava parado.

A pergunta que começou a incomodar cada vez mais pesquisadores era simples: se o processador ficava parado enquanto um programa espera pela impressora, por que não aproveitar esse tempo para adiantar outro programa?

Se o processador fica parado enquanto o programa A espera pela impressora, por que não aproveitar esse tempo para adiantar o programa B? E quando o programa B ficar esperando o leitor de cartões, por que não voltar para o programa A? E assim por diante, alternando entre os programas nos momentos em que cada um estivesse esperando por alguma coisa?

Num computador que processa milhares de operações por segundo, essas alternâncias poderiam acontecer tão rapidamente que cada pesquisador teria a sensação de que o computador estava trabalhando só para ele, quando na realidade estaria atendendo a dezenas de pessoas ao mesmo tempo.

A ideia que parecia impossível

Em 1959, um cientista da computação chamado John McCarthy (não o confunda com o John McAfee) colocou essa ideia no papel de forma detalhada, numa proposta que circulou pelo MIT e que parecia, para muitos que a leram na época, otimista demais para ser viável. McCarthy ficou famoso anos depois por criar o termo "inteligência artificial", mas essa proposta anterior foi igualmente importante para a história da computação.

A ideia de McCarthy era a seguinte: em vez de um programa ocupar o computador inteiro enquanto rodava, o sistema daria a cada programa uma fatia minúscula de tempo, algumas frações de segundo, e então passaria para o próximo, e para o próximo, e assim por diante em ciclo contínuo. Isso aconteceria tão rapidamente que cada pesquisador teria a sensação de estar usando o computador sozinho, quando na realidade dezenas de pessoas estariam compartilhando o mesmo hardware ao mesmo tempo.

Para um pesquisador sentado num terminal, a experiência seria completamente diferente de tudo que existia até então. Em vez de entregar cartões para um operador e esperar horas, ele digitaria um comando e receberia uma resposta em segundos. Erraria, corrigiria na hora, testaria de novo. O ciclo de trabalho que antes levava um dia inteiro poderia ser comprimido em minutos.

Era uma ideia elegante. E era, também, extremamente difícil de implementar.

Esse conceito ficou conhecido como tempo compartilhado, do inglês time-sharing. O nome descreve exatamente o que acontece: vários usuários compartilhando o tempo de um único computador.

Mas entre escrever uma proposta e construir um sistema que realmente funcionasse dessa forma, havia um abismo enorme de problemas técnicos para resolver. Como garantir que uma fatia de tempo terminasse exatamente quando deveria, sem que o programa em execução pudesse simplesmente ignorar o sinal e continuar rodando? Como o sistema saberia em que ponto de cada programa tinha parado, para retomar exatamente de onde deixou quando chegasse a próxima fatia? E se um programa tentasse acessar a memória que estava sendo usada por outro programa enquanto estava fora de execução?

Em 1961, dois anos depois da proposta de McCarthy, uma equipe do MIT colocou essas questões à prova com um sistema real. Eles o chamaram de CTSS, de Compatible Time-Sharing System, e o fizeram rodar num IBM 7094, um dos computadores mais poderosos disponíveis na época.

O CTSS permitia que até 32 pesquisadores se conectassem ao mesmo computador ao mesmo tempo, cada um por meio de um terminal próprio, e trabalhassem de forma completamente independente. Cada um digitava comandos, executava programas, recebia respostas. Para cada um deles, a experiência era a de ter um computador inteiro à sua disposição, respondendo imediatamente a cada solicitação, quando na realidade o processador estava alternando entre todos os trinta e dois em frações de segundo.

O impacto foi imediato. Pesquisadores que antes precisavam agendar tempo de máquina com dias de antecedência, preparar os cartões com cuidado, entregar para o operador e esperar horas para ver o resultado, agora simplesmente sentavam num terminal e começavam a trabalhar. Erravam, corrigiam, testavam de novo, tudo em tempo real. Não é que a produtividade tenha aumentado "um pouco". Aumentou de uma forma que as pessoas que viveram essa transição descreviam como uma mudança de paradigma completa na forma de trabalhar.

Mas o CTSS também revelou algo que a proposta original de McCarthy não tinha antecipado completamente. Quando um único pesquisador usava o computador por vez, o mundo era simples: era ele e a máquina, e tudo que estava no computador era dele. Mas quando trinta e dois pesquisadores passaram a usar o mesmo computador ao mesmo tempo, cada um com seus próprios programas e seus próprios dados, uma série de perguntas novas apareceu que simplesmente não existiam antes.

O que impedia um programa de ler os dados que outro programa tinha deixado na memória? Se dois pesquisadores quisessem salvar um arquivo com o mesmo nome ao mesmo tempo, o que acontecia? Se um programa tivesse um erro grave e travasse, isso derrubava o computador inteiro e interrompia o trabalho de todos os outros trinta e um pesquisadores? Como organizar os arquivos de dezenas de pessoas no mesmo disco de forma que cada um encontrasse os seus sem ter acesso acidental aos dos outros?

Cada uma dessas perguntas escondia um problema técnico real, e nenhuma delas tinha uma resposta óbvia. O CTSS conseguiu contornar algumas delas de forma rudimentar (ou seja, com algumas gambiarras), mas ficou claro rapidamente que contornar não era suficiente. Resolver essas questões de forma robusta e definitiva exigia construir algo muito mais completo do que uma fila de execução inteligente. Exigia um sistema inteiro de coordenação.

E foi para construir esse sistema que surgiu, em 1964, o projeto mais ambicioso da história da computação até aquele momento.

Multics: a ambição que quase funcionou

Em 1964, três instituições decidiram construir esse sistema juntas: o MIT, os Bell Labs (o laboratório de pesquisa da empresa de telecomunicações AT&T) e a General Electric, que fabricava computadores na época. O projeto que eles criaram se chamou Multics, de Multiplexed Information and Computing Service, que em português significa algo como "Serviço de Informação e Computação Multiplexado".

O nome não diz muita coisa. O que o Multics queria ser diz tudo.

A ideia era construir um sistema tão completo, tão robusto e tão bem pensado que resolvesse de uma vez por todas cada um dos problemas que tinham aparecido desde o GM-NAA I/O. Não uma solução parcial, não uma série de contornos improvisados como o CTSS tinha feito. Uma fundação sólida sobre a qual toda a computação pudesse ser construída por décadas.

Para isso, o Multics introduziu uma série de ideias que eram completamente novas na época e que usamos até hoje sem perceber. Uma delas era a organização dos arquivos em pastas dentro de pastas - a estrutura que você usa toda vez que arrasta um documento para uma pasta no seu computador. Antes do Multics, os arquivos de um computador compartilhado eram todos jogados num único lugar, como uma pilha de papéis sem nenhuma organização. O Multics introduziu a ideia de que arquivos poderiam ser organizados em grupos, e que esses grupos poderiam conter outros grupos, criando uma hierarquia tão profunda quanto necessário.

Outra ideia do Multics era o controle de quem podia acessar o quê. Num computador compartilhado por dezenas de pesquisadores, não fazia sentido que qualquer um pudesse ler ou modificar os arquivos de qualquer outro. O Multics introduziu um sistema de permissões: cada arquivo tinha um dono, e o dono podia definir quais outros usuários tinham permissão de ler, modificar ou executar aquele arquivo.

Havia ainda outras inovações, cada uma resolvendo um dos problemas que o CTSS tinha deixado em aberto. O projeto era extraordinariamente ambicioso. E era, também, extraordinariamente difícil de construir.

Os anos foram passando e o Multics não ficava pronto. O que parecia razoável de implementar no papel revelava camadas inesperadas de complexidade na prática. A equipe cresceu, o orçamento cresceu, os prazos foram sendo empurrados para frente. Quando partes do sistema finalmente começaram a funcionar, eram lentas demais para o hardware disponível na época. O que tinha sido projetado para ser a fundação perfeita estava se tornando um exemplo clássico de projeto que tenta resolver todos os problemas ao mesmo tempo e acaba não resolvendo nenhum completamente.

Em 1969, cinco anos depois do início do projeto, os Bell Labs tomaram uma decisão: chega. Eles se retiraram do Multics, encerraram o envolvimento da AT&T, e mandaram seus engenheiros para outros projetos.

Dois desses engenheiros se chamavam Ken Thompson e Dennis Ritchie.

Unix: o sistema que nasceu por acidente

Ken Thompson tinha 27 anos quando os Bell Labs saíram do Multics. Ele tinha passado anos imerso no projeto, conhecia cada canto do sistema, e a saída repentina o deixou numa situação curiosa: sem um sistema operacional para usar.

Isso era mais frustrante do que parece. Thompson tinha desenvolvido um jogo chamado Space Travel que rodava no Multics - um jogo simples que simulava o movimento dos planetas do sistema solar e permitia que você pousasse uma nave em cada um deles. Com a saída do Multics, ele não tinha mais onde rodar o jogo. E Thompson não era o tipo de pessoa que aceitava esse tipo de situação passivamente.

Num canto dos Bell Labs havia um computador pequeno e praticamente esquecido, um PDP-7 da DEC, que estava acumulando poeira sem nenhum uso real. Thompson pediu para usá-lo. E então, em vez de simplesmente portar o jogo para rodar diretamente no hardware, ele fez algo mais ambicioso: começou a escrever um sistema operacional simplificado para o PDP-7. Um sistema enxuto, sem as pretensões do Multics, que simplesmente funcionasse.

Dennis Ritchie logo se juntou ao projeto.

Em 1969, Thompson escreveu o núcleo do sistema em três semanas. Era rudimentar comparado ao Multics, mas funcionava. E funcionava bem o suficiente para rodar o Space Travel.

Em 1970, o sistema precisava de um nome. O grupo de pesquisa dos Bell Labs tinha um senso de humor particular, e o nome que escolheram foi uma brincadeira direta com o Multics: trocaram o prefixo Multi, que significa muitos, pelo prefixo Uni, que significa um, sugerindo algo mais simples e focado. O sistema se chamou Unix.

O nome era uma piada interna. O impacto seria global.

Unix: a filosofia que moldou o mundo

O Unix não era o sistema operacional mais poderoso de 1970. Não era o mais rápido, não tinha os recursos mais avançados, não tinha a ambição arquitetural do Multics. O que ele tinha era algo diferente, algo que os outros sistemas não tinham na mesma medida: uma filosofia clara sobre o que um sistema operacional deveria ser.

Thompson e Ritchie construíram o Unix em torno de algumas ideias simples. Cada ferramenta do sistema deveria fazer uma coisa só, e fazê-la bem. Ferramentas simples deveriam poder ser combinadas para resolver problemas complexos. E, a mais importante para o que estamos construindo aqui: os programas não deveriam precisar saber como o hardware funciona por dentro. Eles deveriam simplesmente pedir ao sistema operacional o que precisam, e o sistema operacional se encarregaria de todos os detalhes.

Essa última ideia é a resposta direta para o problema que você viveu naquela sala de 1955. Num mundo com Unix, quando o hardware muda, apenas o sistema operacional precisa ser atualizado. Os programas continuam funcionando exatamente como antes, porque eles nunca falaram diretamente com o hardware. Eles falavam com o Unix. E o Unix se entendia com o hardware no lugar deles.

Mas o Unix tinha um problema prático: estava escrito de uma forma que o prendia ao PDP-7. Se os Bell Labs quisessem rodar o Unix em qualquer outro computador, o sistema inteiro precisaria ser reescrito do zero para aquele hardware específico. Era exatamente o mesmo problema que você viveu em 1955, agora aplicado ao próprio sistema operacional.

Dennis Ritchie resolveu esse problema criando uma linguagem de programação nova. Uma linguagem que ficasse próxima o suficiente do hardware para ser eficiente, mas que não estivesse amarrada a nenhum computador específico. Qualquer computador que pudesse executar programas escritos nessa linguagem poderia rodar o Unix, bastava recompilar o código. Essa linguagem se chamou C, e é a avó direta de praticamente todas as linguagens de programação modernas, incluindo Rust.

Em 1973, o núcleo do Unix foi reescrito em C. Era a primeira vez na história que um sistema operacional não estava fundamentalmente amarrado ao hardware para o qual havia sido criado. O Unix podia viajar.

E viajou.

Ao longo dos anos 1970, o Unix se espalhou pelas universidades americanas de uma forma que ninguém planejou completamente. A AT&T, por razões legais relacionadas ao seu monopólio de telecomunicações, estava impedida de comercializar software. Isso significava que ela distribuía o código-fonte do Unix para universidades e instituições de pesquisa gratuitamente, ou quase isso. As universidades recebiam não apenas o sistema rodando, mas o código completo de como ele havia sido construído. Podiam estudar, modificar, melhorar.

Uma geração inteira de cientistas da computação aprendeu como sistemas operacionais funcionam por dentro lendo e modificando o Unix. As ideias de Thompson e Ritchie - a filosofia de ferramentas simples e combináveis, a separação clara entre o sistema operacional e o hardware, a liberdade de estudar e modificar o código - se tornaram a base sobre a qual toda a computação moderna seria construída.

Quando as restrições legais mudaram nos anos 1980 e a AT&T tentou comercializar o Unix, as universidades que tinham passado anos estudando e modificando o código não queriam voltar para um sistema fechado que não poderiam mais abrir. A tensão entre o Unix comercial e as comunidades acadêmicas que haviam crescido ao redor dele criou uma pressão por alternativas. E em 1991, essa pressão encontrou uma saída inesperada.

Linux: o sistema operacional que o mundo usa sem saber

Em agosto de 1991, um estudante finlandês de 21 anos chamado Linus Torvalds postou uma mensagem num fórum de discussão online que começava com uma frase que ficaria famosa na história da computação. Traduzida livremente, ela dizia: "Estou fazendo um sistema operacional livre, só um hobby, não vai ser grande coisa nem profissional como o GNU/HURD."

Torvalds estava cursando ciência da computação na Universidade de Helsinki e tinha ficado frustrado com os sistemas operacionais disponíveis para o computador que havia comprado. Ele queria um sistema parecido com o Unix, mas que fosse completamente livre: livre para usar, livre para estudar, livre para modificar, livre para distribuir. E como não existia exatamente o que ele queria, ele decidiu construir.

O que começou como um hobby de um estudante universitário em Helsinki se tornou, ao longo dos anos seguintes, o projeto de software colaborativo mais bem-sucedido da história. Programadores de todo o mundo foram contribuindo com melhorias, correções e novas funcionalidades. O sistema cresceu, amadureceu, e foi sendo adotado em contextos cada vez mais críticos.

Hoje, o Linux está em praticamente todo lugar, na maior parte das vezes completamente invisível. Os servidores que hospedam boa parte da internet rodam Linux. Os supercomputadores mais poderosos do mundo rodam Linux. Os roteadores que conectam redes entre si geralmente rodam Linux. A grande maioria dos smartphones do planeta roda Android, que é construído sobre o Linux. A nuvem - todos esses serviços online que guardam suas fotos, seus emails, seus documentos - roda em servidores Linux.

O macOS da Apple e o iOS dos iPhones têm raízes diretas no Unix, através de um projeto chamado BSD que também nasceu das universidades americanas nos anos 1970. O Windows tem uma história diferente, mas incorporou ao longo das décadas muitos dos conceitos que o Unix popularizou.

Toda a computação moderna carrega, de alguma forma, o DNA das ideias que Thompson e Ritchie colocaram num computador empoeirado num laboratório de pesquisa em 1969. Um sistema que nasceu porque um engenheiro queria um lugar para rodar um jogo.

O que um sistema operacional realmente faz

Ao longo de toda essa história, desde o GM-NAA I/O até o Linux, uma palavra apareceu repetidas vezes sem nunca ter sido explicada com cuidado: sistema operacional. Você já sabe de onde veio, sabe quem o construiu e por quê. Mas o que ele realmente faz, no dia a dia, enquanto você usa o computador?

A resposta mais simples é essa: o sistema operacional é o programa que fica entre o hardware e todos os outros programas. Ele é o único que conversa diretamente com o hardware. Todos os outros programas conversam com ele.

Mas essa resposta, apesar de correta, não diz muita coisa por si só. Vale a pena entender o que isso significa na prática.

O intermediário que você nunca vê

Quando você abre um programa no seu computador, clicando duas vezes num ícone, o que acontece nos primeiros instantes é inteiramente responsabilidade do sistema operacional. Ele localiza o arquivo do programa no disco, copia os bytes desse arquivo para a memória RAM, e só então passa o controle para o processador, que começa a executar as instruções. Sem o sistema operacional fazendo esse trabalho, o programa simplesmente não abriria.

Quando você aperta uma tecla no teclado, o sinal elétrico gerado pela tecla não chega diretamente ao programa que está em primeiro plano na sua tela. Ele chega primeiro ao sistema operacional, que identifica qual tecla foi pressionada e decide qual programa deve ser notificado. Só então o programa recebe a informação de que algo foi digitado.

Quando você salva um arquivo, o programa que você está usando não sabe nada sobre como o disco funciona por dentro: onde os bytes serão gravados fisicamente, como o disco organiza os dados, como garantir que nada será corrompido se a energia cair no meio da gravação. Tudo isso é responsabilidade do sistema operacional. O programa simplesmente diz "salve isso com esse nome" e aguarda. O sistema operacional cuida do resto.

Quando você tem dois programas abertos ao mesmo tempo, como um navegador e um editor de texto, e alterna entre eles, não é mágica que faz os dois parecerem funcionar simultaneamente. É o sistema operacional dividindo o tempo do processador entre eles em fatias tão rápidas que a diferença é imperceptível. Cada programa recebe sua fatia, executa algumas instruções, e então pausa enquanto o outro recebe a dele. O ciclo acontece tantas vezes por segundo que do seu ponto de vista os dois estão rodando ao mesmo tempo.

E quando um programa tem um erro grave e trava, é o sistema operacional que detecta o problema e encerra aquele programa sem deixar que o erro se espalhe para os outros. Você fecha a janela do programa travado, e o restante do computador continua funcionando normalmente.

Tudo isso acontece de forma completamente invisível. Você não pensa no sistema operacional enquanto digita um documento ou assiste a um vídeo, da mesma forma que não pensa nos músculos das suas mãos enquanto segura uma xícara de café. A invisibilidade é, de certa forma, o maior sinal de que ele está funcionando bem.

Chamadas de sistema: como os programas pedem ajuda

Para que os programas possam pedir essas coisas ao sistema operacional, existe um mecanismo formal com um nome técnico que vale conhecer: chamada de sistema, do inglês system call.

Uma chamada de sistema é simplesmente um pedido formal que um programa faz ao sistema operacional. Quando um programa precisa ler um arquivo do disco, ele não acessa o disco diretamente. Ele faz uma chamada de sistema: avisa ao sistema operacional que precisa ler aquele arquivo, passa as informações necessárias, e aguarda. O sistema operacional executa a operação com todos os detalhes de baixo nível que só ele conhece, e devolve o resultado ao programa.

O programa nunca precisou saber qual modelo de disco está instalado no computador. Nunca precisou saber como aquele disco específico organiza os dados internamente. Nunca precisou saber nada além de "preciso ler este arquivo". O sistema operacional absorve toda essa complexidade.

É exatamente isso que resolveu o problema que você viveu em 1955. Naquela época, o seu programa precisava conhecer cada detalhe do hardware com o qual queria se comunicar. Quando o hardware mudava, o programa quebrava. Com o sistema operacional no meio, o programa não fala mais com o hardware. Fala com o sistema operacional, usando uma linguagem padronizada que não muda quando o hardware muda. Quando uma impressora nova é instalada, o programa continua fazendo exatamente o mesmo pedido de sempre. O sistema operacional é que se adapta ao novo hardware.

Os sistemas operacionais que você conhece

Os sistemas operacionais têm nomes. Você provavelmente já ouviu vários deles sem necessariamente saber que eram sistemas operacionais.

O Windows é o sistema operacional da Microsoft e domina o mercado de computadores pessoais há décadas, especialmente no ambiente corporativo e nos computadores voltados para jogos. O macOS é o sistema operacional da Apple para seus computadores, conhecido pela integração próxima com o hardware que a própria Apple fabrica. O Linux, que você acabou de conhecer a história, está presente em servidores, supercomputadores, roteadores e na maioria dos dispositivos que fazem a internet funcionar. O Android, o sistema da maioria dos smartphones do mundo, é construído sobre o núcleo do Linux. O iOS, o sistema dos iPhones, tem raízes no Unix assim como o macOS.

Cada um tem suas características, sua filosofia, seu público. Mas todos existem pelo mesmo motivo: ser o intermediário entre o hardware e os programas, absorver a complexidade do hardware e oferecer uma interface estável e previsível para tudo que roda sobre eles.

Drivers: quando o sistema operacional encontra um hardware novo

O sistema operacional não nasce sabendo como conversar com todos os dispositivos que existem. Seria impossível. Há milhares de fabricantes no mundo produzindo dezenas de milhares de modelos diferentes de impressoras, placas de vídeo, teclados, mouses, câmeras, discos externos, fones de ouvido, controles de videogame. Nenhuma equipe de desenvolvimento, por maior que fosse, conseguiria escrever e manter suporte a tudo isso.

A solução que surgiu foi dividir essa responsabilidade.

O sistema operacional define um conjunto de regras: "se você escrever um componente de software que siga estas regras, eu sei como usar o seu dispositivo". Esses componentes de software têm um nome: drivers, que em português às vezes são chamados de controladores.

Um driver é um programa pequeno e especializado, escrito geralmente pelo próprio fabricante do dispositivo. Ele conhece todos os detalhes de como aquele hardware específico funciona por dentro: quais comandos aceita, em qual sequência, com qual timing, quais mensagens de erro pode retornar. Quando o sistema operacional precisa usar o dispositivo, ele se comunica com o driver usando as regras padronizadas que definiu. O driver, por sua vez, traduz esse pedido para os comandos específicos que aquele hardware entende.

Quando você compra uma impressora nova e liga ela no computador pela primeira vez, o sistema operacional detecta que um dispositivo novo foi conectado, mas ainda não sabe como falar com ele. É por isso que muitas vezes aparece uma mensagem pedindo para instalar o driver. Ao instalar o driver, você está essencialmente ensinando o sistema operacional a falar com aquela impressora específica. A partir desse momento, qualquer programa do sistema pode mandar imprimir sem saber absolutamente nada sobre aquela impressora. O programa pede ao sistema operacional, o sistema operacional fala com o driver, e o driver fala com a impressora.

Se a impressora quebrar e você comprar outra de um fabricante diferente, você instala o driver novo. Nenhum dos programas que você usa precisa ser atualizado. Eles continuam fazendo exatamente os mesmos pedidos de sempre. Só o driver mudou, e essa mudança é completamente invisível para todo o resto.

É a mesma separação de responsabilidades que o Unix introduziu como filosofia: cada coisa fazendo uma coisa só, com fronteiras claras entre elas.

Nem todo computador tem sistema operacional

Até aqui, falamos de computadores como se fossem sempre aqueles que você usa no dia a dia: notebooks, desktops, celulares. Mas o conceito de computador é muito mais amplo do que isso, e entender onde o sistema operacional aparece e onde ele não aparece ajuda a entender melhor o que ele realmente é.

O chip que controla o timer do micro-ondas é um computador. O controlador dentro de um cartão de crédito é um computador. O sistema que gerencia os freios ABS do seu carro é um computador. O termostato inteligente na parede é um computador. A câmera de segurança na esquina é um computador. Esses sistemas são chamados de sistemas embarcados ou sistemas embutidos: computadores que estão integrados dentro de um dispositivo maior, invisíveis ao usuário, com uma função muito específica e limitada.

Em sistemas embarcados simples, não há sistema operacional. O programa que roda neles é único, foi escrito diretamente para o hardware específico daquele chip, e executa uma única tarefa sem parar. Um termostato, por exemplo, pode ser controlado por um microcontrolador que fica em ciclo eterno: mede a temperatura atual, compara com o valor que o usuário configurou, decide se liga ou desliga o aquecedor, aguarda alguns segundos, e recomeça. Não há outros programas rodando ao mesmo tempo. Não há usuários com permissões diferentes. Não há arquivos para organizar nem hardware variado para gerenciar. O programa fala diretamente com o hardware porque não há nada mais complexo para coordenar.

Um sistema operacional num microcontrolador com dois kilobytes de memória e uma única tarefa seria como contratar um gerente de hotel para administrar um quarto de pensão com uma cama só. Os recursos que o sistema operacional consome em memória e processamento seriam um desperdício absurdo para um dispositivo tão simples.

Sistemas operacionais aparecem quando há complexidade suficiente para justificá-los. Quando vários programas precisam rodar ao mesmo tempo. Quando diferentes usuários têm diferentes permissões. Quando há uma variedade de hardware para gerenciar. Quando o sistema precisa ser atualizado, expandido, ou usado de formas que não foram completamente previstas quando foi construído.

Isso tem uma relevância direta para você como futuro programador em Rust. Rust é uma das poucas linguagens modernas usada tanto para escrever programas que rodam sobre um sistema operacional quanto para escrever código que roda diretamente no hardware, sem nenhum sistema operacional no meio. Os dois mundos existem, e você vai se deparar com os dois ao longo deste livro.

Arquivos e extensões

Você já entendeu o que é um arquivo: um conjunto de bytes guardados no disco com um nome, que o sistema operacional trata como uma unidade. Mas há algo sobre arquivos que ainda não foi explicado, e que responde diretamente à pergunta com que começamos esta seção.

Quando você clica duas vezes num arquivo, como o sistema operacional sabe o que fazer com ele? Como ele sabe que deve abrir uma foto no visualizador de imagens, e não num editor de texto? Como sabe que um arquivo de música deve ser aberto num tocador de áudio?

A resposta está num detalhe do nome do arquivo que você provavelmente já reparou sem ter pensado muito a respeito: o ponto e as letras que vêm depois dele.

foto.jpg. musica.mp3. documento.pdf. codigo.rs.

A parte depois do último ponto, chamada de extensão, é uma convenção que o sistema operacional usa como dica sobre o tipo de conteúdo que aquele arquivo contém. .jpg indica uma imagem no formato JPEG. .mp3 indica áudio no formato MP3. .pdf indica um documento PDF. .rs indica código-fonte em Rust.

Com base nessa dica, o sistema operacional sabe qual programa abrir quando você clica duas vezes no arquivo. Ele mantém uma tabela de associações: "arquivos com extensão .jpg devem ser abertos com o visualizador de imagens", "arquivos com extensão .mp3 devem ser abertos com o tocador de áudio", e assim por diante. Você pode até alterar essas associações se quiser que um tipo específico de arquivo seja sempre aberto com um programa diferente do padrão.

Mas há algo importante a entender sobre a extensão: ela é apenas uma dica. Ela não define o que está dentro do arquivo. Os bytes dentro do arquivo continuam exatamente os mesmos independentemente de qual extensão o arquivo tem.

Se você pegar uma foto chamada foto.jpg e renomeá-la para foto.txt, os bytes dentro do arquivo não mudam. A foto continua lá, intacta. O que mudou foi apenas a dica que o sistema operacional usa para decidir como abrir o arquivo. Agora ele vai tentar abrir aquele arquivo com um editor de texto, que vai mostrar uma tela cheia de símbolos sem sentido, porque um editor de texto não sabe interpretar bytes no formato de imagem JPEG. O conteúdo está intacto. A interpretação mudou.

Isso é exatamente o que esteve no centro de tudo que aprendemos neste capítulo. Bytes são bytes. O significado deles não está nos bytes em si. Está no contexto ao redor deles. A extensão de um arquivo é uma das formas que o sistema usa para estabelecer esse contexto.

Pastas: dando estrutura ao disco

Os arquivos se organizam em pastas, também chamadas de diretórios, que por sua vez podem conter outras pastas, formando aquela estrutura em árvore que você usa toda vez que organiza documentos no computador. A pasta "Documentos" contém outras pastas, cada uma contendo arquivos e possivelmente mais pastas. Você pode ir descendo nessa hierarquia tão fundo quanto precisar.

Essa estrutura, como você já sabe, foi uma das ideias que o Multics introduziu e que o Unix herdou. Antes dela, todos os arquivos de todos os usuários ficavam num único lugar no disco, misturados, sem nenhuma separação. A hierarquia de pastas foi a solução que permitiu que muitas pessoas usassem o mesmo computador sem que seus arquivos virassem uma bagunça impossível de gerenciar.

O sistema operacional mantém um mapa interno de tudo isso, chamado de sistema de arquivos, que registra cada arquivo que existe no disco: seu nome, sua extensão, em qual pasta está, onde exatamente seus bytes estão gravados no disco físico, quando foi criado, quando foi modificado pela última vez. Quando você pede para abrir um arquivo, é consultando esse mapa que o sistema operacional sabe onde encontrá-lo.

Fotos, músicas e vídeos: o que realmente está dentro

Agora que você entende o que é um arquivo, o que é uma extensão, e como o sistema operacional usa essas informações para decidir como interpretar os bytes, chegou o momento de abrir os três tipos de arquivo que apareceram lá na primeira seção deste capítulo: a foto, a música e o vídeo.

Uma foto

Cada pixel de uma imagem na tela é formado por três componentes de cor: vermelho, verde e azul. Para cada componente, um byte guarda a intensidade daquela cor, de 0 a 255. Três bytes por pixel. Uma foto tirada com um celular moderno pode ter doze milhões de pixels, o que daria trinta e seis milhões de bytes, ou seja, trinta e seis megabytes, só para guardar os valores brutos de cor de cada pixel.

Mas quando você olha para o tamanho de uma foto no seu celular, ela não tem trinta e seis megabytes. Tem três, quatro, talvez cinco megabytes. A diferença está na compressão.

Formatos como JPEG analisam os valores de cor de todos os pixels e aplicam algoritmos matemáticos para representar a mesma imagem com muito menos bytes. A lógica é que pixels vizinhos tendem a ter cores parecidas: numa foto de um céu azul, milhões de pixels têm valores de azul muito próximos uns dos outros. Em vez de guardar o valor exato de cada pixel individualmente, o JPEG guarda uma descrição eficiente das variações de cor ao longo da imagem inteira.

Além disso, a compressão JPEG descarta algumas informações que experimentos mostraram que o olho humano dificilmente percebe em condições normais de visualização. Pequenas variações de cor em certas regiões da imagem, detalhes em áreas de transição suave entre cores, nuances que estão abaixo do limiar de percepção humana. O resultado é uma imagem visualmente quase idêntica à original, mas representada com uma fração dos bytes.

Quando você abre a foto num visualizador, o programa lê os bytes do arquivo, executa o processo inverso do algoritmo de compressão, reconstrói os valores RGB de cada pixel, e os envia para serem exibidos na tela. Esse processo acontece em frações de segundo, completamente invisível.

Uma música

O som é produzido pelo movimento do ar. Quando uma corda de violão vibra, ela cria variações de pressão no ar ao redor, e essas variações chegam ao ouvido e movem o tímpano, que o cérebro interpreta como som. Uma onda sonora é contínua, existe no mundo físico como uma variação suave e ininterrupta de pressão.

Um computador, porém, só trabalha com números discretos. Para guardar som, é preciso medir o valor da onda em instantes muito próximos entre si e registrar cada medição como um número. Esse processo se chama amostragem, e cada medição individual é uma amostra.

A quantidade de amostras capturadas por segundo determina a qualidade do áudio. Uma gravação de qualidade CD usa 44.100 amostras por segundo, para cada canal de áudio. Como a maioria das gravações tem dois canais, o esquerdo e o direito, isso significa 88.200 amostras por segundo. Cada amostra ocupa 2 bytes. Um segundo de áudio sem compressão ocupa pouco mais de 170 kilobytes. Um minuto, cerca de 10 megabytes. Uma hora de música sem compressão ocuparia mais de 600 megabytes.

Assim como nas imagens, formatos como MP3 e AAC aplicam compressão. A compressão de áudio é baseada em décadas de pesquisa sobre como o ouvido humano funciona: quais sons conseguimos perceber com clareza, quais são mascarados por sons mais altos que ocorrem ao mesmo tempo, quais frequências somos mais e menos sensíveis. Com base nesse conhecimento, a compressão descarta partes do áudio que a maioria das pessoas em condições normais de escuta simplesmente não perceberia que faltam.

O resultado é um arquivo muito menor, com qualidade perceptivelmente similar para a grande maioria das pessoas na maioria das situações de escuta.

Um vídeo

Um vídeo é uma sequência de fotos exibidas rápido o suficiente para o olho humano perceber como movimento contínuo, acompanhada de áudio sincronizado.

O olho humano começa a perceber movimento contínuo a partir de aproximadamente 24 imagens por segundo. A maioria dos vídeos usa 24, 30 ou 60 imagens por segundo, dependendo do uso. Um vídeo em alta definição, com resolução de 1920 por 1080 pixels, a 30 imagens por segundo, teria, sem compressão, mais de 180 megabytes por segundo. Um filme de duas horas ocuparia mais de 1 terabyte. Seria impossível de transmitir por qualquer rede convencional e impraticável de guardar num disco comum.

Formatos modernos de vídeo como H.264 e H.265 aplicam compressão em duas dimensões ao mesmo tempo. Dentro de cada imagem individualmente, de forma parecida com o JPEG. E entre imagens consecutivas: se o fundo de uma cena não muda de uma imagem para a próxima, não há razão para guardar o fundo de novo. O formato registra apenas as diferenças entre imagens consecutivas, e reconstrói cada imagem completa a partir dessas diferenças quando necessário.

O resultado é que um filme inteiro de alta qualidade cabe em poucos gigabytes. O que seria impossível de guardar ou transmitir sem compressão torna-se completamente cotidiano com ela.

Fechando o circuito de vez

Você começou este capítulo numa sala de 1955, olhando para um computador novo que não entendia uma palavra do seu código. E agora você sabe por que aquele momento era tão frustrante, e o que a computação fez para que nunca mais precisasse acontecer.

O sistema operacional é a resposta para o problema que você viveu naquela manhã. Ele é o intermediário que liberou os programas de precisar conhecer o hardware. Ele é o motivo pelo qual Tomás pode receber um vídeo no aeroporto sem saber nada sobre como bytes viajam por redes. O motivo pelo qual Isabela pode abrir uma imagem de ressonância magnética sem saber nada sobre como aqueles bytes foram comprimidos e armazenados. O motivo pelo qual Neo pode ouvir uma música sem saber nada sobre amostragem de áudio. O motivo pelo qual Mariana pode apertar Ctrl+S e confiar que o seu trabalho estará lá quando ela voltar.

Uma foto, uma música, um vídeo, um documento de texto: dentro do computador, todos são a mesma coisa. Sequências de bytes, guardadas em arquivos, organizadas em pastas, gerenciadas por um sistema de arquivos, interpretadas por programas que sabem o que fazer com aqueles bytes específicos, coordenados pelo sistema operacional que faz tudo funcionar junto.

O significado não está nos bytes. Nunca esteve. Está no contexto ao redor deles. Está na extensão do arquivo que diz ao sistema operacional como interpretá-los. Está no programa que os lê, sabendo qual algoritmo aplicar. Está no sistema operacional que coordena tudo isso, gerencia o hardware por meio de drivers, organiza os arquivos no disco e garante que cada pedaço de informação chegue ao lugar certo.

É isso que o capítulo inteiro estava construindo. E agora você tem todas as peças.

No próximo capítulo, vamos dar o passo seguinte. Você aprendeu como o computador representa e armazena informação. Agora vai aprender como ele age sobre ela. Vai aprender o que é um algoritmo, como decisões são tomadas dentro de um programa, e como essas decisões se encadeiam para transformar dados estáticos em comportamento. O Capítulo 2 começa com uma pergunta simples que tem uma resposta muito mais rica do que parece: o que é um algoritmo?

Antes de avançar

Você consegue responder:

  1. Por que antes dos sistemas operacionais existirem, cada programa precisava ser reescrito do zero quando o hardware mudava?
  2. O que foi o processamento em lote e qual problema ele resolveu?
  3. O que é um driver e por que ele existe?
  4. Se você renomear um arquivo de foto.jpg para foto.txt, o que acontece com os bytes dentro do arquivo?
  5. Por que um vídeo em alta definição não ocupa centenas de gigabytes mesmo sendo formado por milhares de imagens?

Se consegue responder as cinco, você terminou o Capítulo 1.