기술서적 집필
두 번째로 집필한 ‘Do It! C++ 완전 정복’이 3년이 넘는 집필 기간을 거처 드디어 ’24년 3월 25일부터 판매가 되었다. 25살(고전 한국 나이) 직장 생활을 한 후 총 3개의 회사에 재직했는데 이 책은 그 모든 회사에 재직하면서 원고 작업을 한 놀라운 책이다. 덕분에 집필 허가를 위한 품의를 3개의 회사 모두에서 받는 기염을 토한 책이다. 이 글은 두 번째 집필 서적인 ‘Do It! C++ 완전 정복’을 집필한 계기, 집필 과정, 컨텐츠 구성/핵심과 소회 등을 정리한 글이다. 글을 읽고 책에 흥미가 생기셨거나 C++ 공부를 하시고 싶으신 분은 아래 링크를 통해 구매할 수 있으니 많관부
https://www.yes24.com/Product/Goods/125606390
막연한 희망과 무의식의 대면
소프트웨어 개발자 뿐 아니라 기술자들에게 또는 어느 분야에 종사하는 사람들에게는 해당 분야의 서적을 집필하는 것이 막연한 희망사항인 것 같다. 전자 매체가 대부분의 컨테츠를 소비 방식인 현시대에도 책은 아직도 그런 매체인 것 같다. 첫 번째 책인 ‘Do It! 강화 학습 입문’이 마무리 될 때 쯤 담당 편집자님과 이야기를 나누던 중에 C++ 입문서에 대한 이야기가 나누었고 이를 계기로 강화 학습 출판이 되고 얼마 후에 C++ 입문서에 대한 논의 및 출판 결정이 되었다.
신입생 시절에 후배들과 함께(벌써 24년전….) C/C++ 스터디 그룹을 2년여간 운영하면서 재미 있는 경험을 많이 했었다. 당시는 나도 부족한 경력이지만 후배들보다 조금 더 일찍 시작한 덕으로 그룹을 리딩을 하면서 정리도 하고 홈페이지도 만들고 게시판도 운영했다. 아마도 앞선 막연한 희망과 이런 경험이 C++과 관련된 책을 만들꺼라는 무의식이 있었던 것 같다. 외부나 내부 강연 때 내 소개에 늘 사용하는 PT를 보면 내가 얼마나 C언어에 대해서 애증을 가지고 있는지 알 수 있는 것 같다.
C언어를 처음 접한 것은 대학교 신입생 시절이었다. 학교에서 배우는 C언어 시간에 영어 원서로 “Hello, World!”와 아스타리스크의 기묘한 형태의 출력을 배울때까지는 꽤 재미 있었다. 하지만 구조체와 유니온이 나오면서 부터 혼란스러웠고, 급기야 포인터를 만나면서 좌절을 겪고 말았다. 그리고 그해 겨울 이화여대역에 있는 학원에서 C언어를 공부하면서 C언어를 이해하기 시작했다. 그것이 바로 저 유머의 진실이다! 당시 배웠던 책은 변수 선언 배우는 앞부분부터 메모리의 개념을 쉽게 설명했다. 동적할당이나 어려운 문법이 아닌 지역 변수를 선언하면 메모리에 공간을 점유하고 초기화를 하지 않으면 해당 영역에 있던 값들이 쓰레기로 출력된다는 정도의 지금 생각해 보면 당연한 이야기를 차근 차근 설명하였다. 유사한 설명이 지속적으로 반복 되다가 포인터 설명 부분에서 포인터라는 변수는 특별한 변수가 아니다. 앞에서 설명한 변수처럼 값을 저장하는 변수이고 다만 저장하는 값이 변수들이 점유한 메모리의 위치인 주솟값이다. 이렇게 설명이 되는 순간 포인터가 아주 쉽게 이해가 되었다. 당시 공부 했던 다른 책들은 포인터 설명에 가서야 메모리의 개념과 malloc 함수의 다양한 사용법만을 설명해서 매우 어려웠는데 책의 구성, 흐름과 철학이 이렇게 쉽게 이해를 만들어 낼 수 있다는 점이 너무 좋았다. 아마도 그때 느꼈던 쉬운 이해의 흐름을 이번 책의 객체 지향이 유지보수성으로 이어지는 책속에 보이지 않는 여정의 단초였을지 모르겠다.
책을 집필하기 위한 결정이 되었지만 그것 만으로 책을 쓸 수는 없으니 어떤 내용으로 책을 채울지 고민하기 시작했다. 어떤 책을 어떻게 쓸 것인가? ‘대학교 때 공부하기 시작해서 커리어 전 기간에 사용한 C++언어 이지만 내가 이 방대하고 복잡한 내용을 오류 없이 전달 할 수 있을까?’, ‘이미 많은 C++책들이 있는데 어떤 내용을 적어야 하지?’, ‘내가 C++언어 책을 쓸 자격이 있는걸까?’ 등등 수 많은 고민들이 올라 갔다 내려 갔다 하면서 머리 곳이 복잡해 졌다.
그 과정에서 큰 영감을 준 컨텐츠가 책에서도 밝혔지만 케이트 그레고리가 CppCon에서 발표한 <Stop teaching C> 이다.
강연의 내용만으로 책을 완성할 수는 없지만 방향성에 대한 커다란 영감을 받을 수 있었다. 그래서 그녀에게 메세지를 보내고 강연 내용에 대한 소개를 책에 넣어도 되는지 등을 문의 하고 허락을 받았다. (아래 그림 페이스북메세지 캡쳐 후 이어 붙이기함)
넘치는 초기 열정, 다듬어진 최종 목차
꿈과 희망이 가득찬 초기 파일럿 원고로 출판사와 협의 한 후 드디어 출판 계약을 맺었다. 그게 21년 10월이다. 첫 직장에서 출판 허락 품의를 받아서 출판사와 커뮤니케이션 하고 초기 원고를 만드는 동안 회사가 바뀌었다. (21년 7월 이직)
현재 목차와 비교 하면 초기 8장까지는 변동을 거치며 최종 16장으로 변경되면서 대부분 내용이 남아 있지만 9장부터는 거의 날아 갔고, 현재 9장인 객체 지향 프로그래밍 설계원칙(SOLID)가 초기 11장을 대체하였다.
목차가 조정이 된 이유들에는 여러가지가 있다. 우선 입문서 치고 내용이 너무 많고 입문자가 이해하기 어려운 수준이어서 제외하자는 논의가 되었다. 그 이후도 초고, 퇴고 및 편집 작업을 거치며 책이 완성이 되었다. 아래 목차의 왼쪽이 초기 목차 오른쪽이 최종 목차이다.
Do it! C++ 입문 (갸제 및 초기 목차)
01장 C++ 시작하기
01-01 C++ 언어
01-02 C++를 배워야 하는 이유
01-03 C++로 할 수 있는 것들
01-04 C++03/C++11/C++14/C++17/C++20 차이점
01-05 C++코드 동작 구조
01-06 C++ 공부를 위해 필요한 것
01-07 Visual Studio Code 설치
01-08 이 책을 활용해 C++ 공부하기
(Do It! C언어 입문과 어떻게 같이 갈꺼에요.)
01-09 소스 코드 작성 기준
02장 C++ 프로그래밍 시작하기
(Do It! C언어 입문 겹치는 내용 최대한 적게)
02-01 “Hello World!”
02-02 화면 출력 (cout, endl)
02-03 변수, 데이터 형식, 이름 만들기 규칙,
02-04 범위(Scope), Lvalue/Rvalue, 형식 변환(Type Casting)
02-05 키워드, 숫자, 문자열과 문자 리터럴, 사용자 정의 리터럴
02-06 표현식과 구문(if, while)
02-07 상수, 단항 연산자, 다항 연산자
02-08 전처리기
02-09 함수와 구조체
02-10 포인터와 메모리(new, delete)
02-11 원시포인터와 스마트 포인터
02-12 레퍼런스
02-13 값에의한 호출, 참조에 의한 호출, 주소값에 의한 호출
(Call by Value, Call by Reference, Call by Address)
03장 예외처리 및 디버깅
03-1 예외 처리
03-2 Try, Throw, Catch
03-3 C++ 예외처리 절차
03-4 예외처리의 예외처리 (noexcept)
03-5 미처 처리 되지 않은 예외처리 (set_terminate)
03-6 예외처리에 실패하지 않는 방법
03-7 어설션(Assertion)
04장 객체지향 프로그래밍
04-1 객체지향 프로그래밍(OOP)
04-2 객체 지향 프로그래밍 특징 1
추상화(Abstraction)와 은닉화(Encapsulation)
04-3 객체 지향 프로그래밍 특징 2
상속성(Inheritance)와 다형성(Polymorphism)
04-4 클래스와 객체
04-5 this 연산자
04-6 생성자와 소멸자
04-7 네임스페이스
04-8 객체 지향 프로그래밍 특징 요약하기
05장 템플릿
05-1 템플릿 정의 및 활용 법
05-2 클래스 템플릿
05-3 함수 템플릿
05-4 템플릿 특수화 (Template Specialization)
05-5 클래스 템플릿 (Class template)
06장 객체지향 자세히 알아 보기
06-1 연산자 오버로딩
06-2 다중 상속(Multi inheritance)과 조합(Composition)
06-3 접근 지정자 (private, public, protected)
06-4 가상 함수
06-5 추상 클래스
06-6 friend 키워드
06-7 static 클래스
06-8 연산자 오버로딩을 활용한 데코레이터 패턴
06-9 정적 클래스를 활용한 싱글톤패턴
06-10 추상 클래스를 활용한 템플릿 메서드 패턴
07장 STL(표준 템플릿 라이브러리)
07-1 STL 활용하기
07-2 iostream
07-3 string, random
07-4 Iterator
07-5 컨테이너 - array, list, queue, vector
07-6 알고리즘 - set, sort, map
07-7 유틸리티
08장 모던 C++
08-1 모던 C++ 이해하기
08-2 C++를 좀 더 C++ 답게
08-3 신규 자료형 (auto, enum, constexpr, nullptr, Uniform Initializer, function type)
08-4 정규표현식
08-5 foreach(range based for)
08-6 스마트 포인터
08-7 함수 객체
08-8 C++ 람다식
08-9 무브 시멘틱
09장 멀티쓰레드, Concurrent 프로그래밍
09-1 쓰레드와 프로세스
09-2 비동기 테스크
09-3 경쟁상태와 임계영역(mutax)
09-4 조건 변수로 경쟁 상태 해결 하기(std::condition_variable)
09-5 원시성 변수로 경쟁상태 해결 하기(std::atomic)
10장 C++ 실무 활용 하기
10-1 GPU를 계산에 활용하는 CUDA
10-2 CUDA 환경 설정 및 멀티쓰레드 활용
10-3 데이터 오프로딩 활용
10-4 딥러닝 프레임워크 Caffe
10-5 Caffe 환경 설정 및 활용
10-6 ImageNet 이미지 분류
10-7 게임 엔진 Unity
10-8 Unity 환경 설정 및 활용
10-9 ~(미정) 게임 만들기
10-10 C++로 코딩 인터뷰 준비하기
10-11 코딩 연습문제를 위한 LeetCode
10-12 LeetCode에서 C++ 예제 풀어 보기
11장 C++개발자로써 알아야 할 것들
11-1 클린 코드
11-2 리펙토링
11-3 Git과 코드 리뷰
11-4 디자인 패턴
Do It! C++ 완전 정복 (최종 목차)
첫째마당 C++ 프로그래밍 기초
01 C++ 프로그래밍 시작하기
01-1 C++ 언어 알아보기
01-2 개발 환경 준비하기
02 변수와 연산자
02-1 C++ 표준 입출력
02-2 데이터 형식
02-3 변수의 유효 범위와 형식 변환
02-4 키워드와 리터럴
02-5 표현식과 연산자
03 포인터와 메모리 구조
03-1 포인터와 메모리
03-2 함수와 구조체
03-3 정적 변수와 상수 변수
03-4 레퍼런스 변수
04 실행 흐름 제어
04-1 조건문으로 흐름 제어
04-2 반복문으로 흐름 제어
04-3 표현식과 구문의 차이
05 예외 처리하기
05-1 예외 처리 구문
05-2 예외 처리 생략과 실패 대응
둘째마당 객체지향 프로그래밍
06 객체지향과 클래스
06-1 객체지향 이전의 프로그래밍 패러다임
06-2 객체지향 프로그래밍
06-3 클래스와 인스턴스
07 객체지향 프로그래밍 특징
07-1 추상화와 캡슐화
07-2 상속성과 다형성
07-3 생성자와 소멸자
07-4 자신을 가리키는 this 포인터
07-5 함수와 연산자 오버로딩
07-6 접근 지정자와 프렌드
08 객체지향을 돕는 기능들
08-1 컴포지션과 어그리게이션
08-2 가상 함수와 동적 바인딩
08-3 추상 클래스와 정적 멤버
09 객체지향 설계 원칙
09-1 단일 책임 원칙(SRP)
09-2 개방폐쇄 원칙(OCP)
09-3 리스코프 치환 원칙(LSP)
09-4 인터페이스 분리 원칙(ISP)
09-5 의존성 역전 원칙(DIP)
10 템플릿
10-1 함수 템플릿
10-2 클래스 템플릿
셋째마당 라이브러리 활용
11 C++ 표준 라이브러리
11-1 표준 라이브러리 구성과 사용법
11-2 문자열 라이브러리
11-3 파일 시스템
11-4 기타 유용한 함수
12 STL의 컨테이너와 알고리즘
12-1 컨테이너와 반복자
12-2 알고리즘
넷째마당 모던 C++ 프로그래밍
13 모던 C++에 추가된 기능
13-1 C++ 버전별 주요 특징
13-2 현대적 관점의 C++
14 새로운 데이터 형식과 라이브러리
14-1 형식 연역, 열거형, 수학 상수, 널 포인터, 2진수 표현
14-2 상수 지정자 constexpr
14-3 function 객체
14-4 스마트 포인터
15 새로운 구문 1
15-1 튜플과 구조적 바인딩
15-2 범위 기반 for 문
15-3 제어문의 초기화 구문
15-4 람다 표현식
16 새로운 구문 2
16-1 폴드 표현식
16-2 3방향 비교 연산자
16-3 using 키워드
16-4 함수 키워드(default, delete, override, final)
초기 목차는 꽤나 높은 이해 수준을 요구 한다. 멀티쓰레드와 Concurrent 프로그래밍은 나도 경력이 꽤 쌓이기 까지 이해를 못했던 부분인데, 지금 생각해 보면 저 내용을 어떻게 입문자에게 설명하려고 했는지 의아하다. 10, 11장 내용은 절 하나 하나가 책 한권으로 만들 수 있는 내용이다. 실제로 그 중에 몇 개는 이미 시중에 책이 나와 있다. 하지만 다행스럽게도 편집자님의 만류로 제외되었는데 책의 포지션이나 집필 기간을 고려하면 적합한 선택이었던 것 같다.
그래도 게임 만들기라는 항목은 살리고 싶어서 책속에서 계속 사용되던 몬스터 예제의 가장 마지막 예제로 실제 게임을 구현해 보기도 했다. 책 마무리 되는 시점이 아니라 중간 시점에 개발한 코드라 최종 버전에 맞게 업데이트 해서 책 예제 제공 GitHub에 추후 공개할 예정이다. Player가 탈것을 바꿔타는 기능과 지형에 따라 몬스터의 체력, 공격력이 변경되는 코드 까지 구현이 되었다. (잘 안보이지만 배경이 4개로 나뉘어 있다.)
기나긴 집필 기간, 개발자 철학
책에 대한 논의가 시작된 것은 20년 가을쯤이고, 책에 대한 집필의 시작은 21년 여름, 계약이 21년 10월이다. 마지막으로 책 출간은 24년 3월이다. 응??? 정말 인고의 세월이다. 장장 2년 6개월만에 책이 완성이 되었다.
책이 출판되기 전에 나는 회사를 한 번 더 옮겼다. 이 와중에 담당 폅집자님도 출판사를 옮기셨다. 작가들도(2인 공동) 바빴다. 이직에 회사 업무에 전업 작가가 아닌 바쁜 회사원에게 원고 작업이란 수월한 일이 아니었다. 게다가 LLM을 필두로 한 각종 인공지능이 추세인 이 시대에 파이썬이 아닌 C++이라니, 여러 상황들로 얽힌 상황에서 우선 집필은 시작이 되었다.
새 책을 시작하면서 C++ 기본 문법 드라이하게 전달하는 것 말고도 작가들이 가지 있는 철학을 전달하고 싶었다. 그렇지만 기본이 중요하기 때문에 초기에는 표준 스펙문서를 기준으로 했으나, 언어의 스펙이 우리가 읽고 이해하기 매우 어려운 수준이어서 https://en.cppreference.com/w/ 를 기준으로 문법을 확인했다. 물론, 이해나 예시를 위해서도 많은 사이트를 참고하긴 했지만 기준은 cppreference를 기준으로 하였다. 강한 기본기 이외에 어떤 개발 철학으로 풀어갈지 고민을 꽤 많이했다.
고민 끝네 가장 큰 꼭지로 잡은 것이 “유지보수성”이다. 특히, 객체 지향 부분과 모던 C++에서 유지보수성 내용을 담기 위해 노력했다. 왜 하필 유지보수성인가? 라고 질문을 한다면 이렇게 답을 해 보고 싶다. 지금 나는 Software Archtect로 일을 하고 있다. 특히 System Software/Platform Architect이다. Architecture에서도 여러가지 중요한 요소들이 있는데 그 중 하나가 “유연한 확장성”이다. 유연한 확장성과 유지보수성이 무슨 상관이야? 궁금하는 사람도 많을 것 같다. 유연한 확장성을 뒷받침하는 가장 큰 개발 원칙이 유지보수성이다. 유지보수성은 수정된 기능의 영향도를 최소화 하면서(샷건 효과 방지) 새로운 기능을 빠르게 추가 하는 것이다.
책에 사용한 문장으로 말하자면 “수정에는 닫혀 있고, 확장에는 열려 있다.” 이다. 객체 지향의 원칙과 설계 원칙으로 높은 유지보수성을 구현함으로써 유연한 확장성을 가진 소프트웨어를 만들 수 있다는 것이 내 생각이다. 그래서 유지 보수성에 대한 이야기는 객체 지향 설명 초반인 다형성 설명에서부터 설명하고 있고, 입문자에게는 어려울 디자인패턴도 문법 설명과 함께 쉽게 풀어서 틈틈이 설명하였다. 그리고 SOLID 원칙은 아에 하나의 장으로 할당하여 구성하였다. 어그리게이션과 컴포지션은 입문자가 이해하기 어려울 수 있지만, 처음부터 습관을 들인다면 앞으로 프로그래밍을 업으로 하게 된다면 좋은 개발 습관을 가지게 될 것이라 생각했다.
그런데 C++에서 유지보수성을 높인다 한들 파이썬으로 개발할 때는 소용이 없다고 생각할 수 있다. 하지만 파이썬도 클래스를가지고 있고 디자인패턴이나 SOLID 원칙은 꼭 C++에만 국한된 설계, 구현 방식이 아니기 때문에 모든 언어를 사용할 때 도움이 될 것이다. 앞에서도 이야기 했듯이 Software Architecture에서도 활용되는 방식이다. C++은 유지보수성을 높일 수 있는 설계와 구현을 아주 구체적이고 세밀하게 할 수 있는 언어이고 C++을 통해서 설계 기법을 잘 배운다면 다른 언어도 적용할 수 있을 것이라 생각한다. 많이 배운것에서 적은 내용을 끄집어 내어 적용할 수는 있겠지만, 그 반대는 어려울 것이라 생각한다.
개발자 커리어로써의 저서
23년 LG 그룹에서 대학원생을 대상으로 하는 컨퍼런스인 2023 LG Tech Conference에서 지금 개발하고 있는 MLOps, ServiceOps 플랫폼에 대해서 발표를 한 적이 있다. (2024에는 데이터 민주화에 대해서) 산학 장학생을 대상으로 하는 세미나라 외부에 오픈되어 있지는 않아 아쉽기는 하지만 꽤 많은 대학원 생들이 세선을 신청해서 들어 주는 감사함이 있었다. 이걸 왜 이야기 하냐면 이 컨퍼런스와 관련하여 어느 분께서 이 컨퍼런스 발표가 개인에게 주는 의미에 대해서 질문했는데 나름 대답을 했지만 뭔가 대답의 아쉬움이 남았다.
이 책도 마찬가지 일 것 같다. 왜 이 책을 썼는지를 곰곰히 생각해 봤다. 커리어 관리에서의 이 책이 주는 의미와 앞으로의 커리어에서 이 책이 가지는 의미에 대해서 말이다.
기술 서적은 누군가에게는 직업을 영유하기 위한 수단이고, 누군가에는 목표이고, 누군가에게는 귀찮은 의뢰일 수 있다. 나에게는 커리의 긴 여정 중 중간 점검이라고 생각이 든다. 내 자신이 C++언어만을 사용한 것도 아니고 다양한 언어와 라이브러리를 사용하는 입장에서 C++언어는 이 수많은 다양성을 가질 수 있게 만들어준 뿌리 같은 언어이기 때문이다. 나는 소프트웨어 개발을 할 때 모르는 언어는 사용하지 못한다는 이야기를 좋아하지 않는다. 프로그래밍 언어라는 것이 근본적으로는 같고 사용의 편리, 목적이나 시대의 흐름에 맞게 바뀌고 유행을 탈 뿐이다. 언어적으로 심각한 문제가 있다고 하더라도 소프트웨어 특성상 개선이 될 것이다. 어셈블리 언어를 아직도 사용하는 것이 좋은 예라 생각한다. 아무튼 내 직업을 가지게 해준 근간이 되는 언어에 대해서 정리하고 재점검해 보는 마음으로 이 책을 집필 했다고 생각한다. 업무 틈틈히 포트폴리오를 정리하는 느낌으로 말이다. 이 정리는 다음 커리어로 이어갈 쉼과 에너지를 준다고 생각한다.
추가 작업
출간 후에 해야할 몇가지 작업들이 남아 있다. 출판사 차원에서 같이 해야 할일은 교재로 활용하기 위한 교안 작업이 있다. 상당한 분량의 교안을 만들어야 하기 때문에 꽤나 고난이 예상된다.
앞에서 본 몬스터 게임 예제가 책 후반 내용이 들어가 있지 않다. 후반 부분 문법들 추가 하고 소스코드 다듬어서 GitHub에 소스 코드와 설명들을 공개할 예정이다.
책의 분량 때문에 최종 원고에서 제외된 장과 절이 몇 개 있다. C++ 소개나 필요성들은 가장 초기에 엄청난 열정으로 작성하였으나 구성이나 분량의 이슈로 제외되었다. 이 내용은 이곳에 업데이트 할지 GitHub에 넣을지 고민 중이다. 그리고 모던 C++ 부분에서 난이도와 분량의 문제로 제외된 몇가지 항목인 동시성 프로그래밍, 정규식등은 GitHub에 내용을 추가할 예정이다.
마치며
책을 쓰는 시간으로만 3년에 가까운 세월을 보낸 것은 아니지만 정말 긴 시간을 거쳐 책을 완성하였다. 같이 고생해준 문작가님에게도 고맙고 음으로 양으로 도와 주신 분들에게도 고마음을 표한다. 책이 안 읽히는 시대에 책을 낸다는건 꽤나 묘한 느낌이지만 만들어진 책이 주는 기분은 꽤나 즐겁다.
오류가 없는 책을 만들기 위해서 꽤 많은 시간과 노력을 쏟아고 감수를 통해서 재점검 했지만 가벼운 오탈자부터 잘 못 알고 있던 부분이 있을 수 있다. 책을 읽는 독자분들은 너르신 아량으로 이해해주시고 알려 주시면 향후 증쇄 때 수정하도록 하겠다.
또 오랜 시간이 걸리겠지만, 다른 좋은 책의 작가로써 독자분들을 만나길 기대하며 글을 마친다.
PS. 관련하여 요청 사항이 있으신 분은 답글로 메일 남겨주시면 확인하겠습니다. (관리자 승인 후 답글이 등록되는 구조 입니다.)
안녕하세요! 이번에 Do it! C++ 완전 정복 책의 서평단을 하게 된 한 대학생입니다! 읽기 전에 이지스퍼블리싱 출판사 이곳저곳 둘러보다가 발견해서 여기까지 왔어요. 게임공학과에 다니고 있어서 이 책의 서평단 공지를 발견 했을 때 고민 없이 지원했습니다. 이 글도 감명 깊게 보고 갑니다 !
안녕하세요?
게임공학과라니 너무나 멋집니다! 잘 읽고 가감 없이 평가 부탁 드립니다. 🙂
공부도 응원합니다. 화이팅