그대가 엉터리 개발자라는 신호들

bloody의 이미지

http://www.zdnet.co.kr/column/column_view.asp?artice_id=20141024082051

크리스 웨넘은 '그대가 엉터리 개발자라는 신호들(Signs that you're a bad programmer)'이라는 제목의 글에서 여섯 가지 신호를 이야기했다. 스스로 개발자인 저자 자신의 경험을 토대로 쓴 글이라는데, 내가 겪은 경험과도 정확하게 일치한다.

이러한 신호를 이야기하는 것은 우리 주변에서 누가 엉터리 개발자인지 골라내자는 것이 아니다. 오히려 좋은 프로그래머가 되기 위해서 누구나 거쳐 가는 단계라고 보는 편이 정확할 것이다. 우리는 모두 한 때는 (어쩌면 지금도) 엉터리 개발자였다.

첫 번째는 코드를 머리로 돌릴 수 있는 능력의 부재다. 엄청난 분량의 코드를 생각만으로 돌릴 수 있는 사람도 있고, 아주 짧은 코드만 돌릴 수 있는 사람도 있는데, 어쨌든 코드를 머리로 돌리는 능력은 개발자에게 기본이다. 이것은 바둑을 두는 프로기사에게 바둑판 위에 놓이지 않은 미래의 수를 읽어내는 능력이 필요한 것과 마찬가지다.

90년대에 빌 게이츠는 마이크로소프트가 수퍼스마트(Supersmart) 프로그래머만을 고용하기를 원한다고 말한 적이 있다. 그 말을 듣고 한 기자가 게이츠에게 수퍼스마트가 어떤 사람이냐고 물었다. 그러자 그는 자기가 작성한 코드의 내용을 6개월이 지난 시점에서도 컴퓨터 없이 (마치 눈앞에서 코드를 보고 있는 것처럼) 설명할 수 있는 사람이라고 대답했다.

그 정도까지는 아니더라도 회사에서 코드리뷰를 하다보면 자기가 아침에 작성한 코드의 내용을 설명하지 못하는 프로그래머가 있음을 알게 된다. 이런 개발자가 다른 사람이 작성한 코드를 읽을 수 없음은 물론이다. 이러한 능력의 부재는 어떤 면에서 노력으로 해결할 수 있는 것이 아니다. 이것은 개발자에게 필요한 최소한의 재능을 갖추지 못한 사례에 해당하므로 하루라도 빨리 다른 일을 시작하는 것이 더 나을 가능성이 높다.

두 번째는 자기가 사용하는 언어의 프로그래밍 모델을 제대로 이해하지 못하는 것이다. 이런 현상은 오랜 개발 경험을 쌓은 개발자 중에서도 어렵지 않게 발견된다. 객체지향 패러다임이 탑재된 C++가 처음 등장했을 때 많은 개발자들이 C++를 이용해서 C 코드를 작성했다. 마찬가지로 오랫동안 자바 언어를 사용해온 개발자가 객체지향 패러다임을 전혀 이해하지 못하고 있는 경우가 생각보다 많다. 함수 패러다임은 말할 필요도 없다.

오래 전에 자바 개발자를 고용하기 위한 기술인터뷰를 수행했을 때의 일이다. 내가 멀티쓰레딩과 관련한 질문을 하자 쓰레드 같은 것은 EJB 컨테이너가 알아서 관리해 주기 때문에 자기는 그런 것까지 알 필요가 없다고 대답한 사람이 있었다. 이런 사람은 이력서에 개발 경력이 5년이든 10년이든 상관이 없다. 끊임없는 학습과 자유분방한 창의력을 요구하는 프로그래밍이라는 행위를 기계적인 코딩, 단순히 반복되는 잡무, 혹은 하기 싫지만 어쩔 수 없이 하는 회사일로 대하는 사람은 앞으로 20년 동안 경험을 쌓아도 기술적으로 변화가 있을 리 없기 때문이다.

세 번째는 학습능력의 부재다. 요즘처럼 정보가 홍수처럼 쏟아져 나오는 시대에 그 모든 내용을 미리 다 알고 있는 사람이 어디에 있겠는가. 수많은 오픈소스 라이브러리, 새로운 기술, 패턴, 사례를 모두 꿰차고 있는 사람은 어디에도 없다. 많은 것을 알고 있는 것처럼 보이는 사람은 그만큼 열의를 갖고 학습을 하기 때문이다. 인터넷 검색을 하고, 코세라 강의를 듣고, 유투브 채널에 가입하고, 세미나에 참여하고, 책을 구입해서 읽으며 쉬지 않고 공부를 한다. 여기에서 중요한 것은 공부를 통해서 습득한 지식의 분량이 아니다. 중요한 것은 공부를 하는 방법, 즉 메타 지식에 해당하는 학습능력 자체다.

좋은 개발자는 낯선 기술이 등장하면 호기심을 품고 즐거운 심정이 되어 이곳저곳 건드려보지만, 엉터리 개발자는 입을 씰룩거리며 낯을 가린다. 이제 겨우 하나를 익혔더니 또 공부를 해야 하냐며 푸념을 한다. 낯선 대상을 두려워하는 것이 아니라 사실은 학습이라는 행위 자체를 두려워하는 것이다. 프로그래밍이라는 행위가 끝없는 학습으로 이루어져 있음을 이해하지 못하기 때문이다.

웨넘이 네 번째로 거론한 내용은 포인터(pointer)에 대한 이해부족인데, C나 C++를 사용하지 않으면 요즘에는 포인터를 직접 다룰 일이 없으므로 넘어가자. 웨넘의 이야기를 최근의 추세에 맞게 재구성하자면 타입시스템(type system)에 대한 이해부족이라고 이야기해도 좋을 것이다.

다섯 번째는 재귀(recursion) 알고리즘을 이해하는 능력이 없는 것이다. 이것은 맨 처음에 보았던 머리로 코드를 돌리는 능력과 밀접한 관련이 있다. 재귀를 이용해서 정수의 팩토리얼 값을 구하는 정도는 대부분의 개발자가 어렵지 않게 이해한다. 피보나치수열까지도 괜찮다. 트리구조의 노드를 순차적으로 방문하는 알고리즘도 기본적인 것까지는 무리 없이 이해한다.

하지만 하노이의 탑과 같은 알고리즘이 등장하면 숨이 막히기 시작한다. 꼬리재귀(tail recursion)가 왜 효율적인지, 일반적인 재귀 알고리즘을 어떻게 꼬리재귀 알고리즘으로 변환할 수 있는지 등을 이야기하다보면 한계를 느낀다. 이런 사람들은 개발자가 되어서 실전에 배치되어도 운영체제의 루프백(loopback) 주소라는 개념을 이해하지 못해서 애를 먹는다. 재귀라는 알고리즘의 작동방식이 머릿속에서 그려지지 않는 탓이다.

마지막은 코드에 대한 불신이다. 엉터리 개발자들은 정작 믿지 않아야 하는 코드를 신뢰하고, 믿어도 좋은 코드를 불신한다. 유닛테스트 코드를 작성하라고 시키면 실제로 검사되어야 하는 코드를 테스트하는 것이 아니라, 언어자체의 문법이나 라이브러리 코드의 API를 확인하는데 시간을 보낸다. 버그 투성이인 자신의 코드에 애착을 품고, 철저하게 검증된 라이브러리 코드를 의심한다.

전부는 아니더라도 이러한 여섯 가지 중에서 한 두 항목에서 뜨끔한 기분을 느낀 사람이 있을 것이다. 다시 한 번 말하지만 이 글의 목적은 엉터리 개발자를 추궁하자는 것이 아니다. 좋은 프로그래머가 되기 위해서 우리가 밟아온 과정, 혹은 앞으로 밟아야 하는 과정을 환기하여 다 같이 행복한 프로그래밍을 하자는 것이 목적이다. 다음에 기회가 있으면 “그대가 훌륭한 개발자라는 신호들”에 대해서도 이야기하도록 하겠다.

yukariko의 이미지

저는 재귀를 좋아해서 나름 잘 사용한다고 생각하고 있었는데 글을 보니 뜨끔하는군요.
개인적으로 하노이 타워는 이해하기가 쉽지 않았습니다..

pchero의 이미지

우와.. 생각할 부분이 많네요. 스스로 부끄러워집니다. ㅠㅠ

---------------------------------
제일 왼쪽이 저입니다 :)

HDNua의 이미지

1. 저한테는 이런 수퍼스마트 머리가 없습니다. 제 약점이네요.

2. 스몰토크를 배우기 전까지만 해도 저는 객체 지향적이라는 말을 이해하지 못했었습니다.
이전에는 다형성과 상속이 있으면 객체지향적이다 이렇게 생각을 하고 있었는데, 스몰토크를 공부하면서 완전히 객체 지향적으로만 공부해보니
객체 지향적이라는 건 '모든 것은 객체고 메시지로 내용을 전달하는 패러다임'이었고 그에 따라 나온 것이 다형성과 상속이 된 것이었습니다.
지금 알고 있는 패러다임은 순차, 구조, 객체지향 이 세 개가 전부인데 다른 패러다임은 찾아보지 않았습니다만 저 세 개는 알고 있다고 자신합니다.

3. 프로그래밍 공부는 좋아합니다. 다행이네요.

4. 포인터는... 알고 있다고 생각합니다.

5. 재귀 알고리즘은 하노이 탑을 처음 배울 때 저도 어려웠습니다만, Compiler 프로젝트를 진행할 때
재귀 하향 파싱(Recursive descent parsing)을 엄청나게 사용해보면서 재귀가 무엇인지 보다 명확하게 이해하고, 올바른 사용법을 얻을 수 있었습니다.

6. ..정말 이런 사람이 있나요?

저는 이렇게 생각했습니다.