Artigo original: What you learn in a 4 year Computer Science degree
Escrito por: Colin Smith
Há algum tempo, escrevi um artigo sobre a necessidade de um diploma em ciência da computação para se conseguir um emprego em tecnologia. Achei que revisar a minha transcrição seria útil. Com sorte, discutir o que estudei ajudará as pessoas. Quero que todos possam tomar a decisão mais informada possível ao escolher seu caminho para seguir uma carreira em tecnologia.
Isenção de responsabilidade: este artigo foi escrito a partir de minhas lembranças das aulas e da perspectiva de um desenvolvedor para dispositivos móveis. Muitos dos tópicos dessas aulas podem ser especializados e transformados em uma carreira. Portanto, todos eles são importantes para alguém no mundo. Estou escrevendo da minha perspectiva e do ponto de vista de alguém que escolheu a carreira de desenvolvedor mobile.

Programação I, II
Essa foi a essência de tudo o que aprendi e me ajudou a programar. Essas são as aulas onde se aprende a programar. Antes de fazer essas aulas, eu mal tinha programado. Eu tentei obter uma vantagem inicial, mas não fui muito além dos loops.
Essas disciplinas começaram com a criação de um arquivo vazio e fazendo-o compilar em um IDE (usei o Code::Blocks na época). Trabalhamos até criar nosso próprio jogo de batalha baseado em texto. Olhar para o código que escrevi me deixa envergonhado. Percorri um longo caminho desde então. Aqui está o repositório, se você quiser rir (eu só uso um arquivo main.cpp com 1063 linhas de código).
Então, o que eu aprendi aqui? Ousaria dizer que "tudo". Esses cursos foram incrivelmente valiosos e me deram pelo menos 70% do conhecimento necessário para trabalhar profissionalmente como programador. Aprendi instruções if, loops, lógica booleana, criação de classes, criação de estruturas, criação de interfaces, polimorfismo, herança e muito mais. Também usei estruturas básicas de dados, como arrays e vetores.

Estruturas discretas em ciência da computação
Esta disciplina foi adicionada à lista para que as pessoas se acostumem com a lógica booleana, a qual vimos nas duas primeiras semanas de aula. Infelizmente, para nós, alunos desavisados, a disciplina se aprofunda muito, mas muito mais. Aqui estão alguns dos tópicos abordados: "lógica, conjuntos e operações de conjuntos, métodos de prova, definições recursivas, análise combinatória e teoria dos grafos".
Todas essas são coisas são úteis de se saber. A questão é que os alunos são incentivados a fazer essa aula cedo, geralmente junto com Programação I e II. Alguns desses tópicos são bastante avançados. Eu sofreria agora para usar métodos matemáticos de prova. Lembro-me de que realmente tive dificuldades naquela época. Além disso, eu apenas tive que pesquisar no Google o que é análise combinatória. Então, obviamente, não a uso muito.
O fato é que muitas coisas que foi ensinado neste curso não pareciam aplicáveis a uma carreira de ciência da computação na época em que fiz o curso. Agora, sei que a lógica, conjuntos e operações de conjuntos, definições recursivas e a teoria dos grafos podem ser úteis. Esse conhecimento, porém, me veio apenas com a retrospectiva de ser programador há alguns anos.
O que aplico diariamente na minha carreira atual é a lógica e talvez as operações definidas. As definições recursivas e a teoria dos grafos realmente só foram úteis para entrevistas. Cuidado, no entanto, em seguir isso à risca, porque sou um desenvolvedor para dispositivos móveis. Um desenvolvedor de back-end provavelmente achará a teoria dos grafos muito útil.

Estruturas de dados
Esta disciplina foi boa, muito boa. As estruturas de dados são usadas em toda a programação de computadores e são a espinha dorsal da maior parte do código que as pessoas escrevem. Elas nos permitem armazenar dados de um modo útil para os programas que escrevemos. A capacidade de olhar para os dados e saber a melhor maneira de armazená-los para terem um bom desempenho em termos de tempo e espaço é uma habilidade muito útil de se ter.
Aprendi sobre arrays, pilhas, listas vinculadas, listas duplamente vinculadas, árvores, gráficos, heaps e todos os diferentes tipos de estruturas de dados (como árvores de autobalanceamento). Essa disciplina não apenas me ajudou a entender as estruturas de dados, mas também a organizar melhor os dados que eu estava armazenando.
A disciplina foi feita em C, o que a tornou ainda mais interessante. C pode ser muito meticuloso, mas também muito poderoso, se usado corretamente. Tive que ter muito cuidado com o modo como alocava e limpava a memória, o que também foi muito bom para ensinar sobre gerenciamento de memória.
Havia tantas coisas úteis nessas aulas que é difícil tratar de todas elas. Eu nem mencionei o fato de que este é um componente de conhecimento chave para entrevistas em tecnologia. Se você está inseguro em estruturas de dados, comece a revisar alguns princípios básicos, porque eles são muito importantes.

Análise de algoritmos
Esta disciplina foi um pouco útil. Algoritmos são úteis. Eles conduzem os melhores softwares do mundo e os tornam poderosos o suficiente para permanecerem relevantes no mundo moderno. Esta disciplina, porém, teve alguns problemas.
A parte mais útil dela foi aprender a notação Big O. A notação Big O permite que você avalie o código e entenda como ele funcionaria no tempo e no espaço. Em geral, se você estiver medindo o desempenho do código em uma empresa, usará um cronômetro para rastrear o tempo entre as interações. Isso permite que você veja o desempenho do seu software. Isso requer que você escreva o código e avalie os resultados posteriormente.
A notação Big O permite que você faça avaliações do desempenho do código apenas observando o código. Não quero entrar muito nisso, mas se você não conhece a notação Big O, leia esta postagem de blog (em inglês).
Os algoritmos reais que examinamos não eram tão úteis. Tudo o que me lembro é o problema da mochila e o problema do caixeiro-viajante. Eu também tive que escrever código para eles em grupos, o que não foi tão interessante porque havia uma pessoa no meu grupo que foi além do que foi planejado. Isso significa que acabei escrevendo menos código para a implementação final do que gostaria.
Uma compreensão básica de quais algoritmos famosos existem, sua finalidade e como são implementados pode ser útil (principalmente para entrevistas). A notação Big O é a chave aqui. É muito útil no trabalho e também é incrivelmente útil para entrevistas.

Desenvolvimento para a web
Esta disciplina era a que tinha mais habilidades que eram diretamente aplicáveis a um trabalho em tecnologia. Aprendi sobre HTML, CSS, JQuery, JavaScript, PHP e JSON. Aprendi como uma solicitação é enviada do front-end de um site para o back-end, como ela é processada no back-end e enviada de volta ao front-end com uma resposta. Aprendi como criar a UI (interface do usuário) e como interagir com uma camada de dados que, por sua vez, interage com a rede.
No final da disciplina, construí meu próprio site e tomei a iniciativa de aprender Angular. Usei o Angular para deixar meu site chamativo, o que acabou me rendendo meu primeiro estágio. Também adquiri um bom entendimento de como um site funciona internamente.
Esse conhecimento por si só foi ótimo, mas também aprendi como aprender uma linguagem, estrutura ou formato de dados desconhecido e trabalhar com eles na hora. Pesquisei muito no Google esses tópicos para ver exemplos concretos. Aprendi a usar a documentação e a investigação on-line para entender melhor um conceito que precisava aplicar diretamente em um curto espaço de tempo. Esta é uma habilidade chave para quem quer ser um programador experiente.

Introdução a bancos de dados
Eu aprendi principalmente SQL nesta disciplina. Tenho certeza de que examinamos alguns outros conceitos, como sharding e clustering, mas não me lembro deles. Às vezes, uso SQL em meu trabalho atual para executar consultas de dados para eventos que registrei. O SQL será parte integrante do seu trabalho ou você mal o usará. Se precisar, aprenda sobre ele e se torne um especialista. Se não o fizer, não se preocupe muito com isso.

Engenharia de software I, II
Outra disciplina da qual não consigo me lembrar. Acredito que examinamos vários conceitos amplos nesta aula. Cobrimos os métodos de gerenciamento de projetos Scrum e Waterfall. Examinamos testes e todos os diferentes tipos de testes que existem. Cobrimos alguns conceitos de usabilidade e acessibilidade. Na verdade, era apenas um apanhado de conceitos que não se encaixavam em suas próprias classes.
Devido à natureza de colcha de retalhos da disciplina, eu realmente não internalizei nenhum dos conceitos muito bem. Foi bom ter uma visão geral básica dos conceitos abordados, mas gostaria que mais tempo fosse gasto em tópicos individuais importantes, como testes.

Arquitetura de computadores e a linguagem Assembly
Lembro-me vividamente desta disciplina. Ela aborda como um computador funciona e como as instruções da máquina são enviadas e processadas pelo computador. Também escrevemos algum código em MASM, que é uma linguagem Assembly que interage muito de perto com o código de máquina.
A maioria das linguagens de programação que usei até fazer este curso eram linguagens de alto nível. As linguagens de alto nível tendem a estar mais próximas da linguagem humana do que do código de máquina. O MASM está muito próximo do código de máquina e eu diria que está mais próximo da linguagem de máquina do que da linguagem humana.
A parte mais importante da disciplina é ter uma ideia do que acontece com seu código quando ele é compilado. Compreender as diferentes unidades lógicas em um computador e como seu código é tratado por elas foi muito interessante de se aprender.
Para fins práticos, não acho que esta aula tenha sido muito importante para contribuir para minha carreira em tecnologia. Não usei muito do conhecimento que adquiri na disciplina durante minha carreira até agora.

Sistemas operacionais
Serei honesto, estou tendo muita dificuldade em me lembrar o que aprendi nesta disciplina. A única coisa de que me lembro é criar um programa de mensagens que usava programação de soquetes em C para comunicação. Também aprendi como abrir arquivos e manipular pastas usando scripts.
Quero ser sincero sobre o que me lembro da minha graduação e o fato é que não me lembro muito dessa disciplina. Eu simplesmente não usei muito do conhecimento adquirido com ela em minha carreira atual.

Introdução a redes de computadores
Esta disciplina foi muito útil. Examinou como as redes de computadores funcionavam. Isso incluiu passar por protocolos de rede como HTTP, HTTPS, TCP, IP, FTP, IMAP, POP3, SSH e DNS. Pude aprender para que serve cada um desses protocolos, como são implementados e entendi a razão de terem sido criados.
Os protocolos de rede que mencionei acima são usados para funções críticas no software moderno. Isso inclui tratamento de e-mails (POP3 e IMAP), envio de solicitações de rede entre client e servidor (HTTP, HTTPS) e tratamento de dispositivos com segurança por meio de uma rede (SSH). Isso realmente dá uma compreensão de como a internet funciona e de como os dispositivos em todo o mundo podem interagir uns com os outros.
Não é apenas fascinante. Pode ser muito útil. Usei o que aprendi nesta disciplina para depurar problemas que encontrei quando recebia erros da rede. Consegui identificar os problemas que estava encontrando e ajudar o desenvolvedor de back-end com o qual estava trabalhando a encontrar o bug do lado deles.

Introdução à engenharia de usabilidade
Esta disciplina abordou como criar uma aplicação intuitiva, mas também como tornar uma aplicação ou um site acessível. Acessibilidade refere-se a tornar um software utilizável para qualquer pessoa, incluindo pessoas com deficiência. Isso abrange coisas como uso de texto em fala e design de software que não depende totalmente de elementos de áudio.
Os tópicos abordados foram úteis se você nunca ouviu falar sobre acessibilidade antes. Pelo menos, faz considerar essas coisas ao projetar software. Também me levou a realmente começar a pensar sobre a experiência do usuário e sobre como ela é importante para um bom software. Se ninguém estiver usando a funcionalidade principal da sua aplicação porque é confusa, seu software acabará perdendo todos os seus usuários.
Embora o conhecimento fosse interessante, as implementações específicas de como você criaria um software utilizável e acessível dependem da plataforma. Por exemplo, a Apple tem seu próprio conjunto de diretrizes de interface do usuário (em inglês) que descrevem princípios gerais de design e detalhes específicos de como você deve projetar um software que será executado em qualquer uma das plataformas da Apple.
Por causa das informações específicas necessárias por plataforma, não tenho certeza se essa disciplina foi incrivelmente útil. Foi uma boa introdução, mas acabei tendo que aprender as diretrizes de interface da Apple, que abordaram todos os tópicos vistos na disciplina.

Desenvolvimento de software para dispositivos móveis e para a nuvem
Esta seção será curta. Eu já era um engenheiro de mobile quando fiz este curso. Eu construí uma aplicação móvel de baixa qualidade em algumas horas para terminar minha graduação o mais rápido possível. A essa altura, eu já havia alcançado meu objetivo de conseguir um emprego como engenheiro de software, mas só precisava ter meu diploma de ciência da computação, pois estava quase no final do curso. Meu coração não estava interessado em aprender naquele momento.
Dito isso, não acho que esta disciplina foi bem conduzida. Ela foi preguiçosamente projetada. Eles encorajaram as pessoas a escrever código para uma aplicação de telefone Windows para esta classe. A demanda por esses trabalhos é muito menor do que outros. Acho que só foi incentivado porque o ambiente é mais fácil de configurar e o código pode ser escrito em JavaScript e se assemelha ao desenvolvimento para a web.
Além disso, ficou claro para mim que a pessoa que ministrava a disciplina não conhecia todas as plataformas de aplicações móveis. Fomos obrigados a escrever uma pequena parte do back-end, mas eu realmente não queria. Acabei falsificando uma solicitação da web lendo do disco e retornando uma resposta padrão após alguns segundos. Isso funcionou porque só tive que enviar uma demonstração e o código-fonte. Tenho a sensação de que a pessoa que avaliou apenas olhou para a demonstração.
No geral, a disciplina ensinou tecnologia desatualizada e não utilizada, não foi avaliada adequadamente e realmente não ofereceu muita orientação. Esta não foi uma disciplina muito boa.

Projeto final de criação de software
Falando em tecnologia desatualizada, este projeto exigia que construíssemos uma GUI para acessar um banco de dados usando curses (texto em inglês). Não escolhemos qual seria o nosso projeto principal: ele foi atribuído a nós. Todos tinham que fazer o mesmo projeto. Também foi feito em grupos de 3. Então, realmente cobrimos apenas uma pequena parte do projeto. Esta foi uma aula muito mal-administrada.
A interação com o professor era praticamente inexistente. Eu não tinha interesse no projeto e o que estávamos aprendendo parecia absolutamente inútil. Para criar interesse em um tópico, você precisa permitir que as pessoas tenham algum livre arbítrio quando se trata de escolher o que aprender. Não ter escolha em seu projeto final é simplesmente bobo. Esse projeto é inútil para a maioria das carreiras e não faz sentido fazer com que as pessoas o façam.
A disciplina deveria ter feito com que todos os alunos apresentassem uma proposta com estimativas aproximadas de um cronograma de quando terminariam cada subparte do projeto. Isso causa duas coisas: fazer com que as pessoas comecem a praticar a estimativa de trabalho e permitir que trabalhem naquilo em que estão interessadas. A disciplina teria sido 100 vezes melhor desse modo.

Considerações finais
Eu poderia não ter feito boa parte das disciplinas e ainda ser o engenheiro de software que sou hoje. Acho que perder algumas dessas disciplinas pode deixar uma grande lacuna no seu conhecimento como desenvolvedor. As disciplinas que eu acho que todo engenheiro de software deve ter algum conhecimento a respeito são Estruturas de Dados e Algoritmos.
As outras disciplinas dependem da carreira que você escolher. Se você decidiu entrar no desenvolvimento de software embarcado, deve aprender sobre arquitetura de computadores. Se você decidir se tornar um engenheiro de front-end, deve aprender sobre redes de computadores.
A principal conclusão aqui é que um bom engenheiro está constantemente aprendendo. Se você está perdendo algum conhecimento que sabe que seria útil e aplicável em seu trabalho, faça uma aula para obter esse conhecimento. É assim que você melhora a escrita de um bom código. Aprenda sempre.
Gostou do que leu? Confira outros artigos do mesmo autor (em inglês)
Starting a tech career from nothing.
Tips for your first tech interview.