7 pontos por GN⁺ 2023-12-27 | 1 comentários | Compartilhar no WhatsApp
  • Se for difícil escolher um side project, projetos como editor de texto, jogo 2D, compilador e mini sistema operacional são bons pontos de partida, porque quanto mais vezes você os constrói, maior é a amplitude do aprendizado
  • O editor de texto leva você a implementar por conta própria a estrutura de armazenamento do documento, o comportamento do cursor, desfazer/refazer e quebra de linha, aprendendo estruturas de dados e abstração
  • Até um jogo 2D simples como Space Invaders revela a estrutura básica da programação de jogos, incluindo desenho na tela, tratamento de entrada, game loop, gerenciamento de estado de objetos, IA dos inimigos, som, shaders e rede
  • O compilador Tiny BASIC e o mini sistema operacional fazem você lidar diretamente com conceitos de baixo nível, como lexing, parsing, análise semântica e geração de código, ou compilação cruzada, bootloading, gerenciamento de memória e escalonamento
  • Planilhas e emuladores de console combinam a dificuldade dos projetos anteriores e evoluem até a etapa de criar até mesmo uma máquina virtual que imita o funcionamento real

Projetos que valem a pena criar repetidamente

  • Quando você precisa de um side project ou quer aprender uma nova linguagem de programação ou framework, fazer o mesmo projeto várias vezes ainda pode ensinar algo diferente a cada tentativa
  • Os projetos recomendados variam em dificuldade e área de aprendizado
    • Editor de texto: estruturas de dados, comportamento do cursor, desfazer/refazer, representação em tela
    • Jogo 2D: desenho na tela, tratamento de entrada, game loop, objetos e gerenciamento de estado
    • Compilador: lexing, parsing, análise semântica, geração de código
    • Mini sistema operacional: boot, gerenciamento de memória, escalonamento, sistema de arquivos
    • Planilhas e emuladores de console: combinam os conceitos dos projetos anteriores em uma estrutura maior

Editor de texto

  • O editor de texto é uma ferramenta usada todos os dias, mas se você o implementar diretamente sem usar um componente básico de caixa de texto, terá que lidar com os detalhes de movimento do cursor, seleção, inserção e exclusão
  • O maior desafio é como armazenar o documento de texto na memória
    • Um array simples tem desempenho ruim ao inserir texto em posições que não sejam o fim do documento
    • Estruturas para comparar incluem array, rope, gap buffer e piece table
  • O cursor não se move apenas para cima e para baixo
    • Ao ir para uma linha curta, ele vai para a posição possível e, quando depois encontra uma linha longa o suficiente, tenta voltar para a coluna original, um comportamento de memória de coluna
  • Depois do editor básico, você pode adicionar desfazer/refazer e quebra de linha
    • Desfazer/refazer leva a comparar abordagens como array de estados anteriores, padrão memento e padrão command
    • A quebra de linha força a separar a representação visual das linhas de texto da representação em memória
  • Materiais de referência

Jogo 2D - Space Invaders

  • Mesmo um jogo simples exige estruturas de dados e padrões de projeto próprios
  • Em vez de um grande engine de jogos, usar uma biblioteca básica de gráficos 2D como SDL, SFML ou PyGame evita que as partes mais interessantes fiquem escondidas
  • O jogo cria o efeito de movimento apagando a tela e redesenhando rapidamente cada elemento
  • O fluxo real segue uma estrutura que repete desenho, recebimento de entrada do usuário e processamento da lógica do jogo dentro de um game loop
  • O tratamento de entrada precisa considerar detalhes como primeiro pressionamento de tecla ou botão do mouse, manter pressionado, soltar e duplo clique
    • Se você ficar apenas verificando a entrada, o restante do jogo fica parado
  • O gerenciamento de objetos e estado do jogo também precisa ser tratado diretamente
    • O padrão factory pattern ajuda a criar inimigos que aumentam dinamicamente
    • É possível aplicar uma máquina de estados à IA dos inimigos
  • Depois do jogo básico, é possível adicionar menu de título, tela de game over, execução na mesma velocidade em computadores diferentes e uma IA inimiga mais interessante
  • Indo além, você pode implementar efeitos de shader, som e até multiplayer online
  • Materiais de referência

Compilador - Tiny BASIC

Mini sistema operacional

  • Os algoritmos e estruturas de dados de sistemas operacionais podem parecer abstratos ou inúteis em sala de aula, mas podem ser aplicados também em várias áreas, como jogos ou modelos de previsão do comportamento humano
  • Ao implementar um por conta própria, você passa a entender com mais profundidade o que acontece dentro de um sistema operacional
  • Por causa da dependência de hardware, há uma barreira inicial e uma curva de aprendizado, mas seguindo livros ou tutoriais é possível criar um OS inicializável capaz de executar programas feitos por você
  • Os tópicos de aprendizado são os seguintes
  • Materiais de referência

Projetos mais difíceis: planilhas e emuladores de console

  • Um aplicativo de planilha, como o Excel, combina os desafios do editor de texto com os do compilador
    • É preciso representar o conteúdo das células na memória
    • É preciso implementar um interpretador para a linguagem de programação usada nas fórmulas
  • Materiais de referência para planilhas
  • Um emulador de console de videogame é um projeto que reúne em um só lugar as dificuldades de implementar compiladores, sistemas operacionais e engines de jogo
  • Para emular um console real, é preciso escrever uma máquina virtual que se comporte como a CPU e os demais componentes de hardware
    • Nessa máquina virtual, é possível executar jogos feitos para aquele console
  • Como ponto de partida, recomenda-se emular o CHIP-8, um console virtual mais simples que consoles reais
  • Também é possível emular NES, SNES, Gameboy e Gameboy Advance, e há bastante documentação e emuladores open source, mas cada console tem particularidades interessantes
    • Certos jogos podem depender de bugs ou funcionalidades não documentadas de hardwares específicos
  • O PICO-8 se tornou um console “fantasy” lucrativo
  • Materiais de referência para emuladores

Projetos adicionais sugeridos

  • Ideias extras de projetos foram reunidas do Hacker News, Reddit, Twitter e email
    • banco de dados feito do zero
    • ray tracer
    • clone do MS Paint
    • editor de gráficos vetoriais
    • decodificador de imagens
    • aplicativo web de sala de chat
    • calculadora de dígitos de pi
    • utilitário geral de terminal como o grep
    • cliente e servidor FTP

1 comentários

 
GN⁺ 2023-12-27
Opiniões no Hacker News
  • Criar um editor de texto, um compilador, um sistema operacional ou um ray tracer pode fazer de você um programador melhor, mas não necessariamente um engenheiro de software melhor
    Pelo contrário, pode até piorar suas habilidades de engenharia de software ao internalizar a doutrina desastrosa do “Not Invented Here”
    Hackers ficam obcecados por teoria avançada, como Big O, estruturas de dados e HoTT, mas quase não se discute nem se pratica o que é essencial na engenharia de verdade: “decidir o que fazer por conta própria e quando usar uma biblioteca”, “identificar boas bibliotecas e frameworks”, “julgar onde vale a pena otimizar”, “escrever código que continue legível daqui a alguns anos” e “enxergar o projeto como um grande sistema complexo, incluindo dependências de software e não software”
    Por isso, proponho um mecanismo de busca na web como projeto alternativo. Algoritmos de correspondência de strings e afins já foram feitos por outras pessoas, então não se preocupe com isso; no começo, mesmo que ele só dê suporte a uma parte da web e a 1 usuário simultâneo, basta “simplesmente” criar um mecanismo de busca e um crawler que funcionem de verdade

    • Não entendo por que um mecanismo de busca exigiria de modo especial “habilidades reais de engenharia”, como escolher bibliotecas ou identificar oportunidades de otimização
      Um editor de texto, um compilador, um sistema operacional ou um ray tracer também podem treinar exatamente todas essas atividades
      Falando como alguém que já trabalhou em um ray tracer usado em vários longas-metragens, todos os itens citados acima também se aplicaram àquele projeto
      No fim, a diferença parece estar mais entre fazer algo pequeno e divertido ou aplicar as mesmas restrições destruidoras de alma de um trabalho corporativo pago e remover toda a diversão
    • Esse conselho soa razoável, mas há um problema quando se constrói software apenas com blocos de construção prontos
      Primeiro, esses blocos prontos, em geral, são muito mais frequentemente ruins; como resultado, o software também reflete essa ruindade, e a vida deixa de ser usar software para virar manter e apaziguar essas coisas ruins
      Segundo, mesmo que os blocos sejam de boa qualidade, eles limitam os tipos de software que você pode usar. O ideal é imaginar o comportamento desejado, escrever software para fazê-lo e, nesse processo, criar os blocos
      Se você usar apenas blocos prontos, uma boa parte dos softwares excelentes nem poderá ser criada, e acredito que esse também seja o motivo de não haver tantos softwares excelentes ao nosso redor
      Se você estiver criando “um software quase igual ao que sempre vimos”, o segundo problema se aplica menos, e o primeiro talvez seja administrável porque você usa principalmente o caminho feliz. Mas esse tipo de software logo será usado por IA, não por pessoas
    • É parecido com dizer a um estudante de instrumento musical para não praticar escalas ou estudos porque há outras habilidades necessárias em uma orquestra
      Essas habilidades também são importantes, mas em algum momento é preciso desenvolver a base, e tornar-se um programador melhor certamente ajuda em todo o conjunto de habilidades listado acima
    • O texto disse programador, não engenheiro de software
      Pessoalmente, engenharia de software é o que faço para pagar as contas, enquanto programação foi algo que comecei porque era divertido
      Os projetos deste texto são do tipo que eu gostaria de fazer por diversão, se tivesse tempo
  • Do ponto de vista de UI/Web, além de uma planilha, que é muito útil para entender sistemas de fluxo de dados, eu recomendaria estes itens
    Criar um videogame simples em Unity ou Unreal ajuda a entender restrições de desempenho em jogos, onde 30~60 fps são importantes, e também ajuda a criar interfaces rápidas em outros lugares, inclusive na web
    Criar um framework JavaScript simples parecido com React ajuda a entender fluxo de dados e tratamento de eventos
    Criar sua própria biblioteca HTTP que encapsule XMLHTTPRequest faz você entender desde o início como enviar e ler requisições HTTP, mesmo que hoje exista fetch, o que ajuda depois na depuração de problemas de CORS ou de requisições OPTIONS

    • Para esse uso, Godot talvez seja uma alternativa melhor que Unity ou Unreal. Além de você não precisar cair em uma licença proprietária, também consegue ver o que acontece por dentro
  • Isso também foi discutido na época
    Challenging projects every programmer should try - https://news.ycombinator.com/item?id=21790779 - dez. de 2019 (297 comentários)
    Há também um texto relacionado
    More challenging projects every programmer should try - https://news.ycombinator.com/item?id=25489879 - dez. de 2020 (223 comentários)

    • O link externo do segundo texto retorna 404
  • +1 para um mini sistema operacional
    Desenvolvedores de aplicações dependem de muitos recursos do sistema operacional, como gerenciamento de memória e sistemas de arquivos, e em algum momento acabam se perguntando: “como essas coisas funcionam por trás?”
    Por isso, no meu tempo livre, mexi no xv6(https://github.com/mit-pdos/xv6-public)
    Aprender em um livro-texto vários algoritmos de escalonamento de processos é totalmente diferente de implementá-los por conta própria, e aprendi muito
    Como desenvolvedor de apps móveis, a chance de esse conhecimento ter relação com meu trabalho é praticamente 0, mas com certeza é divertido

  • Ter desenvolvido um jogo 2D sem engine foi a experiência mais humilhante que me fez perceber o quanto os computadores ficaram absurdamente rápidos
    Mesmo fazendo algo que você tem certeza de que seria lento demais, até no Game Boy há um milhão de operações por segundo, então simplesmente roda. Um milhão era um número maior do que eu imaginava
    Você começa pensando: “Espera, você procura e desenha todos os sprites toda vez? Não há nenhum cálculo diferencial esperto que saiba apenas o que precisa mudar, nem um segundo buffer que consulte o frame anterior para reduzir trabalho?”; aí fica ainda mais surpreso ao ver jogos muito mais complexos que de fato passaram a usar essas técnicas

    • Mesmo antigamente havia truques interessantes, tanto no lado das aplicações quanto do hardware, para ajudar com esses problemas
      Por exemplo, um atlas de sprites é uma forma típica de usar esse tipo de estrutura de dados. Como não há motivo para enviar vários sprites que normalmente são renderizados de uma forma previsível a cada vez, basta enviar uma imagem grande e amostrar partes dela
      Pelos padrões de hoje, isso está certo. Hardware comercial de entrada, mesmo que nem seja um PC gamer, consegue lidar com quase tudo de uns 15 anos atrás com renderização burra do tipo desenhar a cena e redesenhar
    • Comecei fazendo jogos 2D no TRS-80 Color Computer, e isso me deu uma boa compreensão básica de computadores
      Como era só hardware puro e assembly, era preciso fazer tudo manualmente: gráficos, som, entrada, gerenciamento de memória etc.
      Acho que uma introdução ideal seria um ambiente simplificado em que um programador iniciante pudesse lidar com tudo isso e criar um jogo 2D, mas sem o peso excessivo necessário para fazê-lo funcionar
  • Se você acha que precisa do padrão Factory para criar Space Invaders, há algo errado
    Acho muito improvável que o original tivesse esse tipo de conceito de design

    • É o resultado de 30 anos de programação orientada a objetos e design patterns
      Quando o cérebro é infectado por isso, ele começa a procurar maneiras de espalhar a infecção
    • Em nenhum lugar do texto se diz ou se sugere que o padrão Factory seja necessário para implementar Space Invaders
      Será que lemos textos diferentes?
  • Tenho vontade de fazer algo muito mais físico, como simulações precisas de dinâmica de voo de robôs, drones autopilotados ou espaçonaves com parâmetros GNC programáveis
    Tenho o “Fundamentals of Astrodynamics”, de Bate, Mueller e outros, e queria fazer alguma coisa nesta temporada de férias
    Falo de simulação porque o resto parece caro demais. Tenho muito interesse no lado GNC de robôs, e adoraria recomendações de bons materiais

    • https://ksp-kos.github.io/KOS/ Talvez Kerbal Space Program não simule aerodinâmica de forma tão realista quanto você quer, mas parece que muita gente se diverte escrevendo software GNC nele
    • Um robô de duas rodas com autoequilíbrio parece um projeto divertido e relativamente seguro
      Algo como um Segway que consiga ficar parado no lugar sem cair ou sair voando da mesa
      Imagino que você precisaria de um microcontrolador, uma IMU, controladores de motor de passo, motores, rodas de LEGO e talvez um pedaço de madeira
      Não fiz isso pessoalmente, então minhas suposições podem estar bem erradas
    • Fico curioso para saber o que você pretende fazer com “Fundamentals of Astrodynamics”
      Gostaria de ouvir mais sobre o conteúdo do livro e que tipos de projetos poderiam ser feitos com ele
    • Mesma sensação. Quase todos os meus projetos pessoais têm algum elemento de hardware
      Depois de lidar com software o dia inteiro, é muito bom trabalhar voltado a um objeto físico
  • Acho que um pequeno ray tracer de brinquedo também é um ótimo exercício para tentar
    Basta lidar com esferas e algumas fontes de luz, reflexão difusa e especular, e gerar gráficos em bitmap
    Se você não deixar crescer demais, pode ser um projeto com escopo relativamente bem delimitado

  • É uma lista interessante e, embora dependa da inclinação e da situação de cada pessoa, é um bom ponto de partida se você está procurando ideias
    Eu não diria que todo programador precisa tentar alguma coisa específica; vou apenas listar o que eu escolhi fazer pessoalmente
    No Sinclair ZX Spectrum, fiz editores e trackers de pauta musical muito rudimentares, e, como jogo 2D, fiz um Space Invaders com apenas um invasor
    Aquele computador nem era meu. No meu primeiro computador, um 386, fiz um compactador Huffman, um índice B-Tree que era mais rápido que DBase/Clipper, um gerador de formulários orientado a objetos e vários programas de fundo para DOS, um dos quais acabou sendo usado depois no processo de instalação de uma grande empresa
    Alguns anos depois, fiz um verificador de e-mail para dial-up, um parser manual para destaque de sintaxe e até algo parecido com uma planilha, e continuo fazendo isso até hoje. Com certeza devo ter deixado algo de fora

  • Uma boa lista. Seria ótimo mantê-la como uma lista viva, para que possa evoluir junto com o tempo
    Eu gostaria de acrescentar duas coisas
    Criar um memcached leve exige uma mistura de algoritmos fundamentais e boas práticas de design de sistemas. É um problema “simples”, mas exige pensar bem por vários ângulos, como invalidação, concorrência e gerenciamento de memória
    Também é uma boa ideia criar o seu próprio Docker. Não é tão complicado quanto parece e oferece a oportunidade de entender os fundamentos da programação de sistemas operacionais, algo que engenheiros hoje em dia não usam muito no trabalho cotidiano