Skip to content
Permalink
master
Switch branches/tags
Go to file
3 contributors

Users who have contributed to this file

@Clemensss @flybonzai @alexcamargos

Ensine ciência da computação a si mesmo

This document is a Portuguese translation of TeachYourselfCS, written by Ozan Onay and Myles Byrne. For more information about this translation, please refer to the end of this document.

Essa versão está desatualizada

Se você for um engenheiro autodidata ou graduado de alguma bootcamp, você deve a si mesmo aprender ciência da computação. Felizmente, você pode se dar uma educação de primeira classe sem ter que investir anos e uma pequena fortuna num diploma 💸.

Há muitos recursos por aí, mas alguns são melhores do que outros. Você não precisa de mais uma lista de “200+ cursos online gratuitos”. Você precisa de respostas para essas perguntas:

  • Quais assuntos você deve aprender, e por quê?

  • Qual o melhor livro ou série de video aulas para cada assunto?

Esse guia é a nossa tentativa de responder de uma vez por todas essas perguntas.

TL;DR: (Resumo)

Estude todos os assuntos abaixo, mais ou menos na ordem apresentada, usando ou o livro sugerido ou as video aulas, idealmente os dois. Tente dedicar 100-200 horas de estudo para cada um dos tópicos e revisite os seus favoritos durante a sua carreira 🚀.

Assunto Por que estudar? Melhor livro Melhores videos
Programação Não seja a pessoa que “nunca entendeu de verdade” algo como recursão. Structure and Interpretation of Computer Programs Brian Harvey Berkeley CS 61A
Arquitetura de Computadores Se você não tiver um modelo mental sólido de como um computador realmente funciona, todas as suas abstrações de alto nível serão frágeis. Organização e projeto de computadores: a Interface Hardware/software Berkeley CS 61C
Algoritmos e Estrutura de Dados Se você não entender como usar as estruturas de dados mais essenciais como pilhas, filas, árvores, e grafos, você não vai conseguir resolver problemas complexos. The Algorithm Design Manual aulas do Steven Skiena
Matemática para CC Ciência da computação é basicamente um ramo da matemática aplicada, então aprender matemática te dará uma vantagem competitiva. Mathematics for Computer Science Tom Leighton MIT 6.042J
Sistemas Operacionais A maior parte do código que você escreve é processado por um sistema operacional, então é uma boa entender como os dois interagem. Operating Systems: Three Easy Pieces Berkeley CS 162
Redes de Computadores A internet aparentemente é importante: descubra como ela funciona e desbloqueie todo o seu potencial. Redes de Computadores e A Internet - Uma Abordagem Top-Down Stanford CS 144
Bancos de Dados Dados são essenciais para a maioria dos programas, mas poucos entendem como bancos de dados realmente funcionam. Readings in Database Systems Joe Hellerstein Berkeley CS 186
Linguagens e Compiladores Se você entender como linguagens e compiladores funcionam, você vai melhorar sua habilidade de programar e vai aprender linguagens com mais facilidade. Compiladores: Princípios, Técnicas e Ferramentas Curso do Alex Aiken na Lagunita
Sistemas Distribuídos Atualmente, a maioria dos sistemas são sistemas distribuídos. Sistemas Distribuídos: Princípios e Paradigmas MIT 6.824

Por que aprender ciência da computação?

Existem dois tipos de engenheiro de software: Os que entendem ciência da computação bem o suficiente para conseguir realizar tarefas desafiadoras e inovadoras, e aqueles que estão familiarizados com as ferramentas e conseguem fazer o suficiente.

Os dois dizem ser engenheiros de software, e os dois começam com salários parecidos no início das carreiras. Mas os engenheiros do tipo 1 crescem e acabam trabalhando em projetos mais gratificantes e bem remunerados, seja em trabalhos comerciais ou em projetos de open-source inovadores, na liderança técnica ou na maior qualidade nas contribuições individuais.

O sistema global de SMS produz em média 20 bilhões de mensagens por dia. Whatsapp faz 42 bilhões. Com 57 engenheiros. pic.twitter.com/zZrtSIzhlR

— Benedict Evans (@BenedictEvans) 2 de Fervereiro, 2016

Engenheiros do tipo 1 acham novas maneiras de aprender informática a fundo, seja por meios convencionais ou através do incessante aprendizado ao longo de suas carreiras. Engenheiros do tipo 2 geralmente ficam na superfície, estudando ferramentas e tecnologias específicas ao invés de fortalecer o seu conhecimento fundamental, apenas melhorando suas habilidades quando novas tecnologias surgem no mercado.

No momento, o número de pessoas entrando na indústria cresce rapidamente, enquanto o número de graduandos de ciência da computação é essencialmente estático. Esse superabastecimento de engenheiros do segundo tipo está começando a reduzir suas oportunidades de emprego, e os deixando de fora dos trabalhos e serviços mais gratificantes da indústria.

KKKKK a mas eles estavam….pic.twitter.com/XVNYlXAHar

— Jenna Bilotta (@jenna) 4 de Março, 2017

Guia dos assuntos

Programação

A maioria dos cursos universitários de ciência da computação começam com uma introdução a programação. Os melhores cursos não tentam só atender as necessidades dos inexperientes, mas também os que não aprenderam conceitos benéficos e modelos de programação quando aprendendo a programar pela primeira vez.

Nossa recomendação padrão para esse tema é o clássico Structure and Interpretation of Computer Programs (em português: Estrutura e Interpretação de Programas de Computador), que está disponivel online de graça (em inglês), tanto como livro, como também numa série de video aulas do MIT. Mesmo que essas video aulas sejam ótimas, nossa sugestão é: Brian Harvey’s SICP lectures (para o curso 61A na universidade Berkeley). Elas são mais refinadas e melhor direcionadas para novatos do que as do MIT.

Recomendamos estudar os primeiros três capítulos do SICP, fazendo todos os exercícios. Para prática adicional, faça alguns problemas simples como os achados no exercism ou no the huxley.

Aos que acharem SICP muito dificil, recomendamos: How to Design Programs. Para aqueles que acharam muito fácil: Concepts, Techniques, and Models of Computer Programming.

Arquitetura de computadores

Arquitetura de computadores é um importante primeiro contato com a computação por baixo da camada de software. Na nossa experiência, é umas das áreas mais negligenciadas por engenheiros de software autodidatas.

The Elements of Computing Systems (Os Elementos de Sistema de Computação), também conhecido como “Nand2Tetris” (do Nand para o Tetris), é um livro ambicioso, que tenta dar ao leitor um entendimento fundamental de como tudo funciona num computador. Cada capítulo gira em torno da construção de uma pequena peça do sistema, desde escrever o funcionamento de portas lógicas em HDL (hardware description language), uma CPU e um assembler, até uma aplicação do tamanho de um jogo de tetris.

Nós recomendamos ler os primeiros seis capítulos do livro, completando os projetos associados a cada um. Você irá desenvolver um entendimento sobre a relação entre a arquitetura de uma máquina e o software que nela roda.

A primeira metade do livro (e todos os projetos e software necessários) estão no site oficial Nand2Tetris. Também está disponível como um curso no Coursera.

Na busca pela simplicidade e coesão, Nand2Tetris deixa de ir muito a fundo nos assuntos. Em especial, o pipelining e a hierarquia de memória são dois conceitos muito importantes na arquitetura de computadores modernos, mas os dois não aparecem muito no texto.

Quando você se sentir confortável com o conteúdo do livro, nossa próxima sugestão é o Organização e projeto de computadores: a Interface Hardware/software , um texto excelente. Nem todas as seções são essenciais, sugerimos o seguinte curso da Berkeley para leituras específicas. As anotações e vídeo aulas estão disponíveis no Internet Archive.

Elements of Computing Systems

Hardware é a plataforma

— Mike Acton, Diretor Engenheiro na Insomniac Games (watch his CppCon talk)

Algoritmos e Estrutura de Dados

Concordamos com o senso comum de que, familiaridade com algoritmos e estrutura de dados são um dos aspectos mais empoderadores da educação de ciência da computação. Essa área também desenvolve a sua capacidade de resolver problemas, uma habilidade que vai ser útil para todas as áreas.

Existem centenas de livros por aí, mas o nosso favorito é o The Algorithm Design Manual(Manual de Design de Algoritmos) do Steven Skiena. Ele claramente ama o que ensina, e quer muito te ajudar a entender. Uma mudança que achamos bem-vinda, se comparar com os textos mais recomendados do Leiserson, Rivest & Stein, ou Sedgewick. Os dois últimos tendem a ser muito voltados a provas rigorosas para aqueles aprendendo com o objetivo de resolver problemas.

Aos que preferem vídeo aulas, o Skiena coloca as suas online. Nós também adoramos o curso do Tim Roughgarden, disponível na Stanford Lagunita, ou no Coursera. Se você prefere o estilo do Skiena ou do Roughgarden, é uma questão de gosto.

Para prática, nossa abordagem preferida para estudantes resolverem problemas é o Leetcode. Tende ter problemas interessantes com soluções e discussões decentes. Eles também te ajudam a testar seu progresso utilizando perguntas comuns em entrevistas técnicas das empresas mais competitivas. Recomendamos resolver 100 problemas aleatórios como parte do seu estudo.

E por fim, recomendamos A Arte de Resolver Problemas como um excelente guia para resolução geral de problemas; é útil tanto para ciência da computação assim como para matemática.

The Algorithm Design Manual Arte de Resolver Problemas

Eu tenho um método que eu recomendo extensivamente - chamado pense antes de escrever

— Richard Hamming

Matemática para ciência da computação

De certa forma, ciência da computação é uma ramo da matemática aplicada. Enquanto muitos engenheiros de software tentam, e de certa forma conseguem, ignorar-lá, nós te encorajamos aceitá-la. Fazendo isso com sucesso, você irá ganhar uma grande vantagem competitiva sobre os que não.

A área mais relevante para CC é o que é chamado de “matemática discreta”, onde “discreto” é o oposto de “contínuo”, e é uma coleção de tópicos de matemática aplicada fora do cálculo. Dada essa definição super vaga, não vale a pena estudar tudo relacionado ao tópico. Um guia mais realístico é construir um entendimento útil da lógica, combinatória e probabilidade, teoria dos conjuntos, teoria dos grafos, e um pouco de teoria dos números para criptografia. Álgebra linear também é um adicional que vale a pena, dada a sua importância em computação gráfica e machine learning.

Nosso ponto de partida sugerido para matemática discreta são as anotações feitas por László Lovász Professor László Lovász fez um ótimo trabalho fazendo o conteúdo acessível e intuitivo, serve como melhor ponto de partida do que textos mais formais.

Para estudos mais avançados, sugerimos Matemática para ciência da computação, as anotações (do tamanho de um livro) para o curso do MIT de mesmo nome. As aulas também estão disponíveis online de graça, e são nossas vídeo aulas recomendadas para matemática discreta.

Para álgebra linear, nós sugerimos começar com os vídeos a essência da álgebra linear uma série de vídeo aulas incríveis e com legendas disponíveis em português. Depois disso use o livro do Gilbert Strang e a série de vídeo aulas.

Se você não acredita que a matemática é simples, é só porque você não entende o quão complicada a vida é.

— John von Neumann

Sistemas Operacionais

Operating System Concepts e Modern Operating Systems são os livros “clássicos” quando se trata de sistemas operacionais. Os dois foram criticados pela sua escrita e estilo, e por ser o tipo de livro que tem 1000 páginas e tem suas edições revisadas depois de alguns anos para que você compre a nova edição.

Operating Systems: Three Easy Pieces é uma boa alternativa que está disponível online de graça. Nós gostamos da estrutura do livro e achamos que os exercícios valem a pena.

Depois do OSTEP, encorajamos você a explorar as decisões de design de sistemas operacionais específicos, usando os livros do estilo “{nome do SO} internals”, como, por exemplo, Lion's commentary on Unix, The Design and Implementation of the FreeBSD Operating System, e Mac OS X Internals.

Uma ótima maneira de consolidar o seu entendimento é ler o código fonte de um kernel pequeno e adicionar novas funcionalidades. Uma ótima escolha é xv6, um porte do unix V6 para ANSI C e x86 mantido para um curso no MIT. OSTEP tem um apêndice de xv6 labs, cheio de ideias incríveis para possíveis projetos.

Redes de Computadores

Já que a maioria do desenvolvimento de software acontece nos servidores e clientes, uma das áreas mais valiosas da ciência da computação são redes de computadores. Nossos alunos autodidatas que estudam redes metodicamente sentem que eles finalmente entendem conceitos, termos e protocolos que estavam ao redor deles por anos.

Nosso livro favorito do assunto é Redes de Computadores e A Internet - Uma Abordagem Top-Down. Os pequenos projetos e exercícios no livro valem muito a pena serem feitos, nós gostamos particularmente do “Wireshark labs”, que eles deixam online.

Para os que preferem vídeo aulas, sugerimos o curso _Introduction to Computer Networking , disponível no MOOC lagunita.

O estudo de redes se beneficia mais através de grandes projetos do que através de pequenos exercícios. Alguns possíveis projetos são, por exemplo: um server HTTP, ou um chat baseado em UDP, uma mini stack de TCP, um proxy, ou um balanceador de carga, e uma hash table distribuída.

Você pode olhar para uma bola de cristal e ver o futuro. O que a internet vai ser no futuro vai ser definido pelo que a sociedade decidir.

— Bob Kahn

Computer Networking: A Top-Down Approach

Banco de Dados

Requer mais esforço aprender sobre sistemas de banco de dados do que a maioria dos outros tópicos. É uma área de estudo ainda muito imatura, com incentivos comerciais muito fortes para manter boas ideias em segredo. E ainda, muitos possíveis autores de livros didáticos preferem se juntar a uma ou criar uma empresa.

Dadas a circunstâncias nós sugerimos autodidatas ignorarem os livros e começar com a CS 186, o curso de banco de dados da Berkeley e começar a ler artigos logo após.

Um artigo em especial vale a pena ser mencionado a novos estudantes, o “Architecture of a Database System” que unicamente dá uma visão abstrata de como sistemas de gerenciamento de banco de dados relacionais (SGBD) funcionam. Isso serve como esqueleto para futuros estudos.

Readings in Database Systems mais conhecido como “The Red Book” é uma coleção de artigos compilados e editados por Peter Bailis, Joe Hellerstein e Michael Stonebraker. Para os que já progrediram além do nível da CS 186, o Red Book deve ser a sua próxima parada.

Se você insiste em usar um livro introdutório, sugerimos Database Management Systems por Ramakrishnan e Gehrke. Para estudantes mais avançados o clássico Transaction Processing: Concepts and Techniques vale a pena, mas nós não incentivamos usá-lo como primeiro recurso.

É difícil consolidar os conceitos sem escrever uma quantidade considerável de código. Os alunos do CS 186 adicionaram recursos ao Spark, que é um projeto razoável, mas sugerimos escrever, do zero, um simples sistema de gerenciamento de banco de dados relacional. Não será cheio de recursos, mas será esclarecedor mesmo escrevendo a versão mais rudimentar de cada componente de um SGBD típico.

Por fim, a modelagem de dados é um aspecto negligenciado e mal ensinado sobre o trabalho com bancos de dados. Nosso livro sugerido é o Data and Reality: A Timeless Perspective on Perceiving and Managing Information in Our Imprecise World.

Linguagens e Compiladores

A maioria dos programadores aprende linguagens específicas, enquanto a maioria dos cientistas da computação aprendem sobre linguagens. Isso dá ao cientista da computação uma vantagem distinta em relação ao programador, mesmo no domínio da programação! Seu conhecimento é generalizado; eles são capazes de entender o funcionamento de uma nova linguagem mais profunda e rapidamente do que os que aprendem linguagens específicas.

O texto introdutório padrão é o Compiladores: Princípios, Técnicas e Ferramentas, comumente chamado de "o Livro do Dragão" (Dragon Book). Infelizmente, ele não foi feito para auto-estudo, mas sim para que os professores escolham conteúdo suficiente para 1-2 semestres de curso. É essencial, então, que você escolha os tópicos a dedo, ou de preferência com a ajuda de um mentor.

Se você optar por usar o Dragon Book para seus estudos, recomendamos seguir alguma série de vídeo aulas para ajudar com a estruturação do aprendizado, depois ir mergulhando mais profundamente no livro conforme necessário. Nossa recomendação de curso online é o do Alex Aiken, disponível na plataforma MOOC da Stanford Lagunita.

Como possível alternativa ao Dragon Book sugerimos Language Implementation Patterns por Terence Parr. Ele é escrito mais diretamente para o engenheiro de software praticante que pretende trabalhar em pequenos projetos de linguagem como DSLs, o que pode torná-lo mais útil para você. É claro que, para isso, ele sacrifica bastante profundidade.

Para projetos, sugerimos escrever um compilador para uma linguagem didática simples como COOL, ou para um subconjunto de uma linguagem que lhe interesse. Quem achar esse projeto muito difícil pode começar com o Make a Lisp, que te ajuda em cada etapa do projeto.

Compiladores: Princípios, Técnicas e Ferramentas Language Implementation Patterns

Não seja um programador padrão. Construa ferramentas para usuários e outros programadores. Tome nota histórica da indústria têxtil e siderúrgica: você quer construir máquinas e ferramentas, ou quer operar essas máquinas?

— Ras Bodik no início de seu curso de compiladores

Sistemas Distribuídos

Os computadores têm aumentado em número, e com isso eles também têm se espalhado. Enquanto que antigamente empresas adquiriam mainframes cada vez maiores, hoje em dia é típico que mesmo aplicações muito pequenas rodem em várias máquinas. Sistemas distribuídos é o estudo de como raciocinar os trade-offs envolvidos com a execução disso, uma habilidade cada vez mais importante.

Nosso livro sugerido é o Sistemas Distribuídos: Princípios e Paradigmas de Maarten van Steen e Andrew Tanenbaum. A terceira edição está disponível online de graça, graças à generosidade de seus autores. Como sistemas distribuídos são um campo em constante mudança, nenhum livro didático servirá como guia definitivo, mas esse dá a melhor descrição dos assuntos mais fundamentais e consolidados que já vimos.

Um bom curso que tem alguns vídeos online é 6.824 do MIT (um curso de pós-graduação), mas infelizmente as gravações têm péssima qualidade de áudio, e não está claro se as gravações foram autorizadas. [Atualização @ Mar 2020: os vídeos da palestra oficial do curso já foram publicados!]

Não importa a escolha do livro ou de outros recursos, o estudo de sistemas distribuídos exige a leitura de artigos. Uma boa lista pode ser achada aqui, e te incentivamos a participar do seu Papers We Love local.

Perguntas frequentes

E quanto a IA/Computação Gráfica/etc.?

Nós tentamos limitar nossa lista para tópicos que nós achamos essenciais para todos os engenheiros de software, independentemente da especialidade. Com essa fundação, você estará numa posição muito melhor para simplesmente usar livros e ler artigos sem precisar de algum tipo de guia. Aqui nossos pontos de partida para essas “eletivas”:

  • Inteligência artificial: faça curso introdutório da Berkeley. Vendo os vídeos e completando os projetos excelentes de pacman. E use o livro Artificial Intelligence: A Modern Approach por Russell e Norvig.

  • Para machine learning: o curso do Andrew Ng na coursera. Seja paciente, e tenha certeza que você entende o fundamental antes de ir atrás de novos conhecimentos como deep learning.

  • Para computação gráfica faça o curso 184 de CC da Berkeley e use Computer Graphics: Principles and Practice como livro.

Quão rígida é a sequência sugerida?

Realisticamente, todos os assuntos possui um nível significante de conhecimento compartilhado, e se auto referenciam. Por exemplo, a relação entre matemática discreta e algoritmos: Aprender matemática antes te ajudaria a analisar e entender seus algoritmos com mais profundidade, mas aprender os algoritmos servem de grande motivação e familiarização para a matemática discreta. Idealmente, você vai revisitar esses tópicos muitas vezes ao longo da sua carreira.

Sendo assim, nossa sequência sugerida está aí mais para te ajudar a começar… se você tiver razões convincentes para escolher outra sequência, só vai. Os pré-requisitos mais significativos, na nossa opinião, são: arquitetura de computadores antes de sistemas operacionais ou banco de dados, e redes de computadores e sistemas operacionais antes de sistemas distribuídos.

Quem é o público alvo deste guia?

Nós temos em mente que você é um engenheiro de software, graduando de bootcamp ou um estudante de ensino médio precoce, ou um universitário procurando uma educação complementar. A decisão de quando embarcar nessa jornada é inteiramente pessoal, mas a maioria das pessoas tem algum benefício por ter alguma experiência profissional antes de se aprofundar nos tópicos de ciência da computação. Por exemplo, nós percebemos que estudantes amam aprender sobre banco de dados se eles já trabalharam profissionalmente na área, ou redes de computadores se eles já trabalharam num projeto web ou dois.

Como isso se compara ao currículo da Open Source Society ou do freeCodeCamp?

O OSS guide tem muitos assuntos, sugerem referências inferiores para grande parte, e não dão nenhum raciocínio ou guia sobre o por quê e quais aspectos dos cursos em particular são valiosos. Nós nos esforçamos para limitar os cursos que você realmente precisa saber e para te ajudar a entender o por quê de cada curso.

freeCodeCamp foca mais na programação e não na ciência da computação. O porquê de você querer aprender ciência da computação veja acima.

E a linguagem X?

Aprender uma linguagem em particular, é uma coisa totalmente diferente de aprender sobre uma área da ciência da computação - uma linguagem é muito mais fácil, e menos significativo. Se você já é proficiente em algumas linguagens, nós sugerimos seguir o guia e ir colocar o aprendizado de novas linguagens no meio, ou simplesmente deixar para depois. Se você aprendeu programação bem, e especialmente se você aprendeu sobre compiladores, você vai levar não mais de uma semana para aprender os fundamentos de uma nova linguagem.

E a tecnologia X que está na moda?

Nenhuma tecnologia é tão importante que aprender a usá-la deve ser parte dos fundamentos da sua educação. Por outro lado, é muito bom que você está animado para aprender essa coisa nova. O truque está em trabalhar de trás para frente da tecnologia em particular até os fundamentos e conceitos, e aprender aquilo bem antes de ver como a sua tecnologia se encaixa no panorama geral.

Por que ainda estão recomendando “dragon book”?

O “Dragon book” ainda é um dos melhores recursos para compiladores. Tem uma má fama, especialmente por colocar muita ênfase em certos tópicos que não são tão importantes hoje em dia. Mas o livro não foi idealizado para ser lido por completo, mas dar material suficiente para um instrutor conseguir montar um curso. Similarmente, um autodidata pode escolher sua própria aventura com o livro, ou melhor ainda seguir sugestões de professores em seus resumos/guias de leitura.

Como posso conseguir livros baratos?

Graças a generosidade dos seus autores, muitos dos livros que sugerimos são achados de graça online. Para os que não são, nós sugerimos comprar edições usadas. Como regra geral, se existe varias edições de um livro, é muito provável que as edições mais antigas ainda sejam perfeitamente adequadas. É muito difícil que a nova versão seja 10x melhor que as mais velhas, mesmo que a diferença de preço seja.

Quem fez isso?

Esse guia foi escrito por Ozan Onay e Myles Byrne, instrutores na Bradfield School of Computer Science em São Francisco. É baseado na nossa experiência ensinando os fundamentos da ciência da computação para centenas de engenheiros (muitos autodidatas) ou graduados de bootcamps. Muito obrigado a todos os estudantes pelo feedback contínuo sobre meios para o aprendizado autodidata. Obrigado também a Alek Sharma, Omar Rayward, Ammar Mian and Tyler Bettilyon, pelo feedback sobre o guia.

Quem é o tradutor?

Iae galera, meu nome é Clemens Schrage, eu sou estudante de ciência de computação da UFAL (Universidade Federal de Alagoas). Se vocês tiverem alguma sugestão para ajudar na tradução, eu acharia irado, só fazer um pull. Eu realmente não sei escrever direito e isso aqui tá uma bagunça. Espero que eu tenha ajudado quem quer que esteja lendo isso, porque o texto original me ajudou bastante. Abração ae galera.