GN⁺: 모든 프로그래머가 도전해야 할 프로젝트들 (2019)
(austinhenley.com)텍스트 에디터
- 텍스트 에디터는 매일 사용하지만, 실제로 어떻게 작동하는지 알고 있는가? 기본적인 기능을 구현하는 것부터 시작.
- 텍스트 문서를 메모리에 어떻게 저장할지가 가장 큰 도전. 배열 사용은 성능 문제가 있으며, 이를 해결하기 위한 다양한 데이터 구조 학습 필요.
- 텍스트 커서의 동작 방식 학습, 기본 에디터 구현 후에는 undo/redo와 단어 자동 줄바꿈 기능 구현에 도전.
2D 게임 - 스페이스 인베이더스
- 간단한 게임이라도 특별한 데이터 구조와 디자인 패턴 필요. 게임 디자인과 아트에 집중하기보다는 게임의 전체적인 구현에 초점.
- 화면 그리기, 게임 루프, 사용자 입력 처리, 동적 객체 생성 및 관리, 게임 로직 적용 등의 학습.
- 기본 게임 구현 후에는 타이틀 화면 메뉴, 게임 오버 화면 추가, 다양한 컴퓨터에서 동일한 속도 유지, AI 적용 등으로 확장 가능.
컴파일러 - Tiny BASIC
- 컴파일러 구현은 프로그래밍에 대한 깊은 이해를 요구하는 프로젝트. Tiny BASIC과 같은 간단한 언어로 컴파일러 작성을 시작.
- 코드를 토큰화하는 방법(lexical analysis), 파싱(구조 확인 및 트리 생성), 의미 분석, 코드 생성 등의 과정을 학습.
- 기본 컴파일러 구현 후 표준 라이브러리 추가, 최적화 단계 추가, 오류 메시지 개선 등으로 확장 가능.
미니 운영 체제
- 운영 체제의 기본 개념은 다양한 분야에 적용 가능. 운영 체제 구현을 통해 하드웨어에 대한 이해 증진.
- 하드웨어에 의존적인 학습 곡선이 있지만, 책이나 튜토리얼을 따라하면 부팅 가능한 OS를 만들 수 있음.
스프레드시트
- 스프레드시트 애플리케이션은 텍스트 에디터와 컴파일러의 도전을 결합. 셀 내용을 메모리에 표현하는 방법과 수식을 위한 프로그래밍 언어의 인터프리터 구현을 학습.
비디오 게임 콘솔 에뮬레이터
- 에뮬레이터 작성은 컴파일러, 운영 체제, 컴파일러 작성의 도전을 하나로 결합. 실제 게임을 에뮬레이터로 플레이하는 것은 보람찬 경험.
- 실제 비디오 게임 콘솔을 에뮬레이트하는 것은 해당 CPU 및 기타 하드웨어 구성 요소처럼 작동하는 가상 머신 작성을 의미.
GN⁺의 의견
- 프로그래밍 기초를 다지는 데 있어 텍스트 에디터나 간단한 게임 구현은 실제로 사용하는 소프트웨어의 내부 작동 원리를 이해하는 데 큰 도움이 됨.
- 컴파일러나 운영 체제와 같은 복잡한 프로젝트는 프로그래밍 언어와 컴퓨터 아키텍처에 대한 깊은 이해를 요구하며, 이는 고급 소프트웨어 엔지니어링 기술을 개발하는 데 필수적.
- 이러한 프로젝트들은 프로그래머가 새로운 언어나 프레임워크를 배우거나, 기존 지식을 심화시키는 데 있어 흥미롭고 도전적인 경험을 제공함.
Hacker News 의견
-
텍스트 편집기, 컴파일러, 운영 체제, 레이트레이서와 같은 프로젝트를 진행하는 것이 프로그래밍 실력을 향상시킬 수 있지만, 소프트웨어 엔지니어링 능력을 향상시키는 것은 아님. 실제로 이러한 프로젝트는 "여기서 발명되지 않음(Not Invented Here)"이라는 재앙적인 원칙을 내포하고 있어 소프트웨어 엔지니어링에 있어서는 역효과를 낼 수 있음.
- 라이브러리에서 가져올 것인지, 직접 작성할 것인지 결정하는 능력
- 프로젝트 요구 사항에 맞는 고품질 라이브러리 및 프레임워크 식별 능력
- 최적화가 가치 있는 곳과 그렇지 않은 곳을 결정하는 능력
- 몇 년 후에도 여전히 읽을 수 있는 코드 작성 능력
- 프로젝트를 대규모 복잡한 시스템으로 생각하며 소프트웨어 및 비소프트웨어 의존성 고려 능력
- 대안적인 도전으로 웹 검색 엔진 만들기를 제안. 문자열 매칭 알고리즘 등은 이미 다른 사람들이 해결했으므로, 실제로 작동하는 검색 엔진(및 크롤러)을 만드는 것이 목표임.
-
UI/웹 기반 프로젝트로는 다음과 같은 것들을 추천함:
- Unity나 Unreal을 사용한 간단한 비디오 게임 (게임에서 30-60fps가 중요하기 때문에 다른 곳에서도 성능이 좋은 인터페이스를 만드는 데 도움이 됨)
- React와 유사한 간단한 자바스크립트 프레임워크 (데이터 흐름 및 이벤트 처리 이해에 도움이 됨)
- XMLHTTPRequest 주위에 http 라이브러리 래퍼 (fetch가 존재하지만, HTTP 요청을 처음부터 어떻게 보내고 읽는지 이해하는 것은 CORS 문제, OPTIONS 요청 등을 디버깅할 때 도움이 됨)
-
미니 운영 체제에 대한 긍정적인 의견. 애플리케이션 개발자로서 운영 체제의 기능(메모리 관리, 파일 시스템 등)에 의존하고 있으며, 어떻게 이런 것들이 뒤에서 작동하는지 궁금해질 것임. xv6를 사용하여 여가 시간에 다양한 프로세스 스케줄링 알고리즘을 학습하고 구현하는 것은 매우 유익하고 재미있는 경험임.
-
물리적인 것에 손을 대보고 싶은 욕구, 예를 들어 로봇이나 자동 조종 장치가 있는 드론, 프로그래밍 가능한 GNC 매개변수를 가진 우주 비행기의 비행 역학에 대한 정확한 시뮬레이션 등. "Fundamentals of Astrodynamics"라는 책을 가지고 있으며 이번 휴가 시즌에 이를 활용하고 싶음. GNC(유도, 항법 및 제어)에 대한 좋은 정보를 얻고 싶음.
-
개인적인 취향과 상황에 따라 다르지만, 아이디어를 찾고 있다면 좋은 시작점이 될 수 있는 목록. Sinclair ZX Spectrum을 사용하여 음악 스태프 편집기와 트래커, 2D 게임(스페이스 인베이더) 등을 만들었음. 첫 번째 컴퓨터(386)로는 허프만 압축기, B-Tree 인덱스, OOP 폼 생성기, 다이얼업용 이메일 체커, 수동 파서 등을 만들었음.
-
텍스트 편집기에 대한 논의: 텍스트 문서를 메모리에 어떻게 저장할지가 가장 큰 도전임. 배열을 사용하는 것이 첫 번째 생각이었지만, 문서의 끝이 아닌 곳에 텍스트를 삽입할 때 성능이 매우 나쁨. 하지만 자바스크립트 문자열을 사용하고 2년 이상 편집기를 사용하는 동안 성능 문제가 없었음. 물론 다른 많은 문제들이 있었음, 예를 들어 긴 수평선을 렌더링하는 것은 최적화 접근 방식이 단일 라인 렌더링이 저렴할 것이라고 가정했기 때문에 문제가 됨.
-
간단한 장난감 레이트레이서를 시도해보는 것도 좋은 생각임. 비트맵 그래픽의 구와 확산 및 반사 반사를 수행하는 레이트레이서를 만드는 것은 프로젝트를 너무 복잡하게 하지 않는 한 상대적으로 제한된 프로젝트가 될 수 있음.
-
스페이스 인베이더를 작성하기 위해 "팩토리 패턴"이 필요하다고 생각한다면, 문제가 있는 것임. 원래 게임에서 그런 디자인 개념이 사용되었다고 확신할 수 없음.
-
배열을 데이터 구조로 사용하는 텍스트 편집기에 대한 의견. 타이핑하는 동안 빠른 속도가 필요하며, 한 줄만 변경하면 됨. 새로운 줄을 입력할 때, 엔터를 누른 후 배열을 재구성하는 데 필요한 추가 지연은 수백만 줄에 대해서는 눈에 띄지 않음. 텍스트 편집기의 더 도전적인 부분은 사용자가 보는 것만 렌더링하는 것을 확실히 하는 것임.