All Articles

10년 내에 프로그래밍 배우기

원글: https://norvig.com/21-days.html

작성일: 1998~2014

번역: keniallee at gmail.com

번역일: 2019-04-23

10년 내에 프로그래밍 배우기

피터 노빅

뭐가 그리 급한가?

서점에 가 보면 자바 24시간 완성how to Teach Yourself Java in 24 Hours과 비슷한 제목의, 며칠이나 몇 시간 내에 C, SQL, Ruby, 알고리즘을 공부하기 위한 책을 볼 수 있을 것이다. 아마존에서 [title: teach, yourself, hours, since: 2000] 같은 조건으로 검색을 하면 512개의 책이 검색된다. 상위 10권의 책 중 9권이 프로그래밍 서적이다 (나머지 하나는 부기에 관한 책이다). “Teach yourself”를 “learn”으로 바꾸거나 “hours”를 “days”로 바꿔도 검색 결과는 비슷하다.

우리는 여기에서, 사람들이 프로그래밍에 관심이 많거나 그게 아니라면 프로그래밍이 말도 안 되게 배우기 쉽다는 결론을 얻을 수 있다. Felleisen은 How to Design Programs이라는 책에서 이러한 경향을 언급하며 “나쁜 프로그래밍은 쉽다. 바보라든 멍청이든 21일이면 배울 수 있다”라고 이야기하고 있다. Abstruse Goose는 이 내용으로 만화를 그리기도 했다.

Teach Yourself C++ in 24 Hours 같은 책 제목이 과연  무엇을 의미하는지 한 번 생각해 보자:

  • Teach Yourself: 그럴듯한 몇몇 프로그램을 개발하고 결과물(성공과 실패 모두)에서 교훈을 얻기에 24시간은 너무나 짧은 시간이다. 숙련된 프로그래머와 일해 볼 기회를 갖거나 C++ 환경에서 개발을 하는 것이 어떤지 이해할 시간조차도 없을 것이다. 요약하면, 짧은 시간에 그리 많은 것을 배울 수 없을 것이다. 그러므로 이러한 책은 단지 피상적으로 언어에 친숙해질 수 있게 할 뿐, 깊은 지식을 다루지 않는다. Alexander Pope가 말했듯, 짧은 배움은 위험한 것이다.
  • C++: 24시간이면 (다른 프로그래밍 언어를 알고 있다면) C++ 문법 일부를 배울 수 있겠지만, C++ 언어를 다루는 법에 대해 그리 많은 내용을 배울 수는 없을 것이다. 요약하면, Basic 프로그래머가 이런 식으로 학습한다면 C++ 문법을 사용해서 Basic 스타일로 프로그램을 작성하는 법은 익힐 수 있겠지만, C++가 어떤 경우에 적합한지(혹은 적합하지 않은지)는 배울 수 없을 것이다. 그래서 어쩌라는 건가? Alan Perlis는 “프로그래머의 사고 방식에 영향을 주지 못하는 프로그래밍 언어는 배울 가치가 없다”고 말한 적이 있다. 이런 방식으로 C++ (혹은 가능성이 좀 더 높은 JavaScript나 Processing 같은 언어)를 약간만 공부해야 하는 경우를 한 가지 꼽자면, 이를테면 특정 업무를 수행하기 위해 이미 존재하고 있는 기존 도구와 상호작용하는 코드를 작성해야 하는 상황을 예로 들 수 있다. 하지만 이 경우에는 프로그래밍을 하는 법을 배운게 아니라, 단지 그 업무를 어떻게 수행하는지 배운 것 뿐이다.
  • in 24 Hours: 다음 단락에서 살펴보겠지만, 24시간은 충분치 않다.

10년 내에 프로그래밍 배우기

일련의 연구자들(Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973))은 체스, 작곡, 전보, 그림, 피아노 연주, 수영, 테니스, 신경심리학, 위상기하학 등 다양한 영역에서 전문성을 쌓는데 10여년의 시간이 걸린다고 주장했다. 단순히 했던 것을 반복하는 것이 아니라, 현재 자신의 능력을 약간 넘어서는 과제에 도전하고, 노력하고, 그 과정에서의 성과를 분석하며, 실수를 수정하는 것을 반복하고 또 반복하는 것이다. 요는, 의식적인 연습(deliberative practice)을 해야 하는 것이다. 지름길 같은 건 존재하지 않는다. 4살에 음악 신동 소리를 들었던 모차르트조차도 세계적인 수준의 음악을 작곡해내기 시작하는 데에는 13년 넘는 시간이 걸렸다. 다른 분야의 예를 들면, 비틀즈는 갑자기 연달아 히트곡을 내며 음악 씬에 등장하고 1964년에 에드 설리번 쇼에 출연한 듯 싶겠지만, 비틀즈는 1957년부터 리버풀과 함부르크의 작은 클럽을 전전하며 연주를 하면서 차츰 대중에게 알려졌다. 비틀즈에게 첫 번째 성공을 가져다준 음반 Sgt. Peppers는 1967년에 발매되었다.

Malcolm Gladwell은 이 개념을 (10년 대신 1만 시간을 제시했지만) 널리 퍼뜨렸다. Henri Cartier-Bresson(1908-2004)은 다른 기준을 제시했다. “사진 1만장을 찍을 때까지는 최악의 결과물을 얻을 것이다.” (그는 디지털 카메라가 등장해서 사진 1만장을 찍는 일이 1주일 안에 가능하리라는 것은 몰랐다) Samuel Johnson (1709-1784)은 “분야를 막론하고 탁월함이란 일생의 노력을 거쳐서만 얻을 수 있는 것이다. 댓가 없이 탁월함을 얻을 수는 없다.” 또한 Chaucer (1340-1400)는 “인생은 짧고, 재주를 익히는 건 오래 걸린다.”며 한탄했다. Hippocrates (c. 400BC)의 “ars longa, vita brevis”라는 격언은 “Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile”에서 온 것으로, 한국어로 옮기면 “인생은 짧고, 재주는 길며, 기회는 순간이며, 경험은 불안하고, 판단은 어렵다.”라는 의미이다. 물론, 정확한 하나의 기준이 있을 수는 없다. 다양한 기술(프로그래밍, 체스, 체커, 악기 연주 등)을 익히고 통달하는데 정확히 똑같은 시간이 소요되리라 가정하는 것은 말도 안 될 뿐더러, 사람에 따라서 학습 시간에도 차이가 있을 수 있다. K. Anders Ericsson 교수는 “분야를 막론하고, 뛰어난 재능을 가진 개인조차도 최고 수준의 기술에 도달하기 위해 많은 시간을 쓴다는 사실에 주목해야 한다. 1만 시간이라는 숫자는 단지, 타고난 재능을 가진 사람들도 최고 수준에 도달하기 위해 몇 년 동안 1주일에 10~20시간이란 시간을 투자해야 한다는 것에 대한 감을 주기 위한 숫자일 뿐이다.”라고 언급했다.

그래도 프로그래머가 되고 싶다면

프로그래밍에서 성공하기 위한 방법을 여기 제시한다:

  • 프로그래밍에 흥미를 가지고, 재미로 이것저것 시도하라. 계속해서 재미를 느낄 수 있어야 10년/1만 시간을 투자할 마음이 생길 것이다.
  • 프로그램을 작성하라. 가장 좋은 학습 방법은 직접 해보며 배우는 것이다. 좀 더 구체적으로는 “특정 분야(도메인)에서의 최고 수준의 기량은 장기간의 경험으로 저절로 체득되는 것이 아니다. 다만, 이미 충분한 경험이 있는 개인조차도 개선을 위한 의도적인 노력을 통해 기량의 수준을 높여갈 수 있으며” (p. 366) “효율적인 학습에는 특정 개인에게 맞춰진 적절한 난이도의 과제, 유용한 피드백, 반복, 실수의 교정이 필요하다.” (p. 20-21) 이러한 관점에서 인식의 실제: 일상의 정신, 수학, 문화라는 책이 참고가 될 것이다.
  • 다른 프로그래머와 대화하라; 타인의 프로그램 코드를 읽어라. 책을 읽거나 강의를 듣는 것보다 타인의 프로그램을 읽는 것이 더 중요하다.
  • 원한다면, 대학에 4년(혹은 그 이상을 대학원에)을 투자하라. 학위를 요구하는 직업을 얻거나, 해당 분야에 대한 깊은 이해를 얻는데 도움이 될 것이다. 하지만 학교에 있는 것이 재미가 없다면, 독학이나 일을 통해서도 (상응하는 노력을 들인다면) 비슷한 경험을 할 수 있다. 어쨌든, 혼자 하는 독서만으로는 충분하지 않다. New Hacker’s Dictionary 의 저자인 Eric Raymond는 “컴퓨터 과학 교육은 전문 프로그래머를 양성할 수 없다. 붓과 안료에 대해 공부한다고 전문 화가가 될 수 없는 것과 같다.”이라고 말했다. 내가 고용했던 최고의 프로그래머 중 한 명은 고등학교 졸업장만 갖고 있었다. 그는 여러 훌륭한 소프트웨어를 만들었고, 자신의 뉴스그룹을 갖고 있으며, 자기 소유의 나이트클럽을 살 정도로 스톡 옵션으로 돈을 많이 벌었다.
  • 다른 프로그래머와 함께 프로젝트에 참여해라. 프로젝트에서 가장 뛰어난 프로그래머로서, 가장 떨어지는 프로그래머로서도 참여해보아야 한다. 뛰어난 프로그래머일때에는 프로젝트를 이끄는 능력과 자신의 비전을 통해 타인에게 영감을 주는 능력을 시험해 볼 수 있다. 처지는 프로그래머 입장일 때에는, 대가들이 어떻게 일하는지, 그리고 대가들이 무엇을 싫어하는지 (당신에게 그런 일을 시킬 것이므로) 배우게 될 것이다.
  • 이미 있는 프로젝트에 참여해라. 다른 사람이 작성한 프로그램을 이해해보라. 원 작성자가 없을 경우, 프로그램을 이해하고 고치는데 무엇이 필요한지를 알아보라. 어떻게 프로그램을 설계해야 나중에 코드를 유지보수하는 사람이 쉽게 유지보수할 수 있을지 생각해 보라.
  • 최소한 6개의 프로그래밍 언어를 익혀라. 클래스 추상화class abstractions에 중점을 둔 언어 중 하나 (Java, C++ 같은), 함수형 추상화functional abstraction에 중점을 둔 언어 중 하나 (Lisp, ML, Haskell 같은), 문법 추상화syntactic abstraction를 지원하는 언어 중 하나 (Lisp 같은), 선언적 명세declarative specifications를 지원하는 언어 중 하나 (Prolog, C++ 템플릿 같은), 병렬화parallelism에 중점을 둔 언어 중 하나 (Clojure, Go 같은)를 포함시켜라.
  • “컴퓨터 과학”이란 단어에 “컴퓨터”가 들어 있음을 기억해라. 명령 하나를 실행하고, 워드(역주: 프로세서에서 기계어 명령어/연산을 통해 레지스터register로 옮길 수 있는 최소의 데이터 단위)를 메모리에서 꺼내오고 (캐시 미스가 났을 때와 그렇지 않을 때 모두), 디스크에서 연속적으로 워드를 읽을 때, 디스크의 헤드를 옮길 때(seek) 시간이 얼마나 걸리는지 기억하라. (해답)
  • 언어 표준화 활동에 참여하라. ANSI C++ 위원회도 좋고, 프로젝트의 코딩 스타일 (들여쓰기에 공백 2칸을 사용할지 4칸을 사용할지 같은)을 정의하는 일도 좋다. 이런 활동을 통해 다른 사람들이 프로그래밍 언어의 어떤 점을 좋아하는지, 얼마나 감정적이 되는지 알 수 있을 것이다. 어쩌면, 왜 그렇게 감정적이 되는지에 대한 이유도 약간이나마 이해할 수 있을 것이다.
  • 언어 표준화 활동에서 최대한 빨리 빠져나오는 방법에 대해 고민하라.

이를 고려해보면, 책을 읽고 독학하는 것만으로 어느 수준까지 도달할 수 있는지에 대한 의문의 여지가 있다. 내 첫 아이가 태어나기 전, 나는 How To  류의 책을 죄다 읽고도 감을 못 잡는 초보자 신세였다. 30개월 후, 두 번째 아이의 출산 즈음이 되었다. 책 내용을 다시 떠올리기 위해 내가 저 책들을 다시 읽었을까? 아니었다. 나는 내 개인적인 경험에 의존하고 있었고, 이 경험이야말로 전문가가 쓴 수천 페이지의 책들보다 더 유용했으며 나에게 확신을 주었다.

Fred Brooks는 No Silver Bullet 이라는 에세이에서 훌륭한 소프트웨어 설계자를 찾는 3가지 지침을 설명했다:

  1. 체계적으로 최대한 빠르게 최고 설계자를 확인하라.
  2. 유망한 후보의 경력 개발을 책임지는 경력 멘토를 임명하고, 경력 파일을 관리하라.
  3. 설계자를 양성하는 기회를 제공하여 서로 대화하고 자극이 되도록 하라.

위 계획은 훌륭한 설계자가 되기 위한 필수적인 자질을 가진 사람들이 이미 어딘가에 존재하고 있다는 것을 가정하고 있다; 나머지 일은 그러한 필수적인 자질을 가진 사람들을 잘 구슬러 내는 것이다. Alan Perlis는 이를 좀 더 간명하게 설명했다: “누구든 조각하는 법을 배울 수 있다: 미켈란젤로는 어떻게 조각하면 안되는지를 배워야 했을 것이다. 훌륭한 프로그래머도 마찬가지다.” Perils는 훈련 과정을 초월한 훌륭한 자질을 가진 사람들에 대해서 이야기하는 것이다. 하지만 이러한 자질은 어디에서 오는 것일까? 이러한 자질은 선천적인가? 꾸준히 계발될 수 있는 것인가? Auguste Gusteau (Ratatouille 에 등장하는 요리사)는 “누구나 요리를 할 수 있지만, 두려움 없는 자만이 위대해질 수 있지”라고 말했다. 나는 훌륭한 자질이 의도적 수련에 인생의 많은 시간을 기꺼이 투자하고자 하는 태도에서 온다고 생각한다. 하지만 어쩌면 두려움 없는이야말로 이러한 태도를 잘 요약한 것일 수도 있다. 혹은 Gusteau의 비평가인 Anton Ego의 말대로, “모두가 위대한 예술가가 되는 건 아니지만, 위대한 예술가는 어디에서든 나올 수 있다.”

그러니 가서 Java/Ruby/Javascript/PHP 책을 사라; 분명 그 책에서 뭔가를 얻을 수 있을 것이다. 하지만 그 정도로 24시간/21일 내에 갑자기 당신의 삶이 바뀌거나, 프로그래머로서의 전문성이 바뀌지는 않을 것이다. 24개월 동안 지속적인 개선을 위해 열심히 노력하는 것은 어떨까? 음, 그렇다면 당신은 성장하기 시작할 것이다…


참고

Bloom, Benjamin (ed.) Developing Talent in Young People, Ballantine, 1985.

Brooks, Fred, No Silver Bullets, IEEE Computer, vol. 20, no. 4, 1987, p. 10-19.

Bryan, W.L. & Harter, N. “Studies on the telegraphic language: The acquisition of a hierarchy of habits. Psychology Review , 1899, 8, 345-375

Hayes, John R., Complete Problem Solver Lawrence Erlbaum, 1989.

Chase, William G. & Simon, Herbert A. “Perception in Chess”Cognitive Psychology , 1973, 4, 55-81.

Lave, Jean, Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life, Cambridge University Press, 1988.


해답

일반 PC에서 다음과 같은 작업을 수행할 때 드는 대략적인 시간:

명령 수행 1/1,000,000,000 초 = 1 나노초
L1 캐시 메모리에서 데이터 가져오기 0.5 나노초
분기 예측 실패branch misprediction 5 나노초
L2 캐시 메모리에서 데이터 가져오기 7 나노초
Mutex 락/언락 25 나노초
주 메모리에서 데이터 가져오기 100 나노초
1Gbps 네트워크에 2KB 전송 20,000 나노초
메모리에서 1MB를 순차적으로 읽기 250,000 나노초
디스크 헤드를 옮겨 데이터 읽어오기(seek) 8,000,000 나노초
디스크에서 1MB를 순차적으로 읽기 20,000,000 나노초
미국에서 유럽으로 패킷을 보내고 응답 받기 150 밀리초 = 150,000,000 나노초

부록: 언어 선택

어떤 프로그래밍 언어를 먼저 배워야 하는지에 대한 질문을 받았다. 정답은 없지만, 다음과 같은 점을 고려하자:

  • 친구를 이용하라. “윈도우, 유닉스, 맥 중 어떤 운영체제를 사용해야 하죠?” 같은 질문을 받았을 때, 나는 보통 “친구가 사용하는 운영체제를 쓰세요”라고 답한다. 친구에게 배움으로써 얻는 이점은 OS나 프로그래밍 언어 사이에 존재하는 고유한 차이점을 상쇄한다. 학습을 계속했을 때, 나중에 활동하게 될 프로그래머 커뮤니티에서 만날 미래의 친구도 염두에 둘 필요가 있다. 선택한 언어가 급속히 성장중인 커뮤니티를 갖고 있는가, 아니면 하락세인 커뮤니티를 갖고 있는가? 정보를 얻을 수 있는 책, 웹 사이트, 온라인 포럼이 있는가? 포럼의 사람들이 마음에 드는가?
  • 단순화하라. C++, Java 같은 프로그래밍 언어는 코드의 런타임 효율성에 신경을 쓰는 숙련된 프로그래머들이 모인 대규모 팀 개발을 위해 설계된 언어이다. 그 결과, 이들 언어는 그러한 상황에 맞게 설계된 복잡한 구성요소들을 갖고 있다. 프로그램을 배우는 입장에서는 이러한 복잡성이 꼭 필요하지 않다. 신참 프로그래머로써 배우고 기억하기 쉽게 설계된 언어를 배워도 좋다.
  • 즐겨라. 피아노 연주를 배울 때 어떤 방식을 선호하는가? 일반적인 방법, 건반 하나하나 누르며 각 음을 듣는 대화식interactive 방법, 혹은 곡 하나를 끝마쳤을 때만 그에 해당하는 음을 들을 수 있는 일괄 처리식batch 방법이 있다고 해 보자. 당연하지만, 피아노 학습에는 대화식 방법이 적합하며, 프로그래밍에도 그렇다. 대화식 모드가 있는 언어를 고르고 사용하자.

이러한 기준을 따르자면, 내가 첫 프로그래밍 언어로 추천하는 언어는 Python이나Scheme이다. 대안으로는 Javascript가 있다. 초심자용으로 잘 설계된 언어는 아니지만, Khan Academy’s tutorial 같은 온라인 튜토리얼이 많이 있기 때문이다. 하지만 각자의 상황에 따라 더 좋은 선택지가 있을 수도 있다. 10세 이하라면 Alice, Squeak, Blockly를 선호할 수도 있다. (이보다 나이가 많더라도 말이다). 중요한 것은 당신이 언어를 고르고 시작하는 것이다.


부록: 책과 기타 학습 리소스들

어떤 책과 웹 페이지를 통해 학습해야 하는지에 대한 질문을 받았다. “혼자 하는 독서만으로는 충분하지 않다”는 점을 기억해야겠지만, 다음과 같은 리소스를 추천할 수 있겠다: