좋은 코드

예전에 어떤 버그하나를 추적하고 있었다. 문제를 이해하려고 관련된 코드를 쭉 읽어내려가다보니 어느순간 짜증이 솟구쳐 올랐다. <이거는 어떤 자식이 코드를 짰길래 이딴식이야!> 하며 git 히스토리를 열어보니… 그건 몇년전 나였다. 아마도 릴리즈가 급한 나머지 코드의 퀄리티에 신경 안쓰고 일단 돌아가는것에 집중했던 시기였던것 같다. 같은 코드를 오랫동안 만지는 여러 개발자들이 비슷한 경험을 하지 않았을까?

대부분의 사람들은 동작하는 코드를 만들수 있다. 어떤 사람들은 <빠르게> 동작하는 코드를 만들수 있다. 그보다 적은 수의 사람들은 <이해할수 있는> 코드를 만든다. 소프트웨어 회사의 매출은 동작하는 프로그램에서 나오지만, 회사의 진짜 자산은 (커피만 마시고) 코드를 만들어낼수 있는 프로그래머와 그 사람들이 수년간 만들어낸 지식의 총체인 방대한 코드베이스다. 예를들어 2015년 기준 구글의 코드베이스는 20억 라인이라고 한다. 단기간의 성공을 위해 우선 동작하는 프로그램을 만들수는 있지만 SW조직의 수명은 코드의 퀄리티에서 결정된다. 코드를 만들때는 각자 자기의 성을 짓는것과 같다. 그런데 몇년후 자신이 만든 성에 들어가서도 우리는 길을 잃는다. 현실에서 회사는 남이 만든 초가집을 성이라 우기며 아름다운 탑을 몇개 더 붙이라고 요구한다.

“Programs must be written for people to read, and only incidentally for machines to execute.”
“코드는 남들에게 읽히는게 목적이지만, 종종 컴퓨터가 실행하기도 한다”

예전엔 코드가 화려할수록, 복잡해 보일수록 뛰어난 것이라 생각했다. 그런데 이전 블로그에서 설명한대로 프로그래머의 자존심으로 채워진 화려한 코드는 스타트업 하나쯤은 쉽게 무너뜨릴수 있다. 수년간 더 여러 팀에서 일하고 난 지금은 좋은 코드를 이렇게 정의한다.

<당연하게 읽히는 코드>

이전 회사에서 테크 리드로 있으면서 많은 코드를 리뷰했다. 팀원은 이제 갓 대학을 졸업한 어린이(?)부터 20년 경력의 백전노장까지 다양하게 구성되어 있었는데, 그 중 J는 특히 코드 퀄리티에 관심이 많았다. 경험도 많고 듣기로는 인터뷰를 퍼펙트로 통과했을정도로 스마트한 친구였다. 이 친구가 짠 코드를 읽으면 <와우> 이런 감탄사는 나오지 않는다. 단지 코드의 처음부터 끝까지 논리의 흐름이 너무나 당연하게 읽힌다. 마치 J가 만든 성안에 처음 들어가 구석구석 살펴 보는동안 그가 옆에서 친절하게 길을 안내해주는 느낌이다. 그런데 <당연하게 보이는 코드>를 만드는게 사실은 가장 어려운 것이다. J는 스스로 길을 안내하는 코드를 만들기 위해 속도를 희생했다. 그는 어떤때는 좀 답답하게 느껴질정도로 코드를 천천히 만들었다. 어떤때는 괜찮아 보이는 코드들도 처음부터 다시 하겠다고했다. 그렇게 나온 코드는 너무나 당연히 읽히기에 쉽게 이해할수 있었고 고칠 부분이 거의 없었다. 당연히 버그도 나오지 않았다.

이와 반대로 이제 막 학교를 졸업한 어린이(?) 엔지니어들의 코드는 읽으면서 감탄사가 나온다. 여과해 <아 이딴식으로도 생각을 하는구나> 이 정도로 표현해야겠다. 그 코드는 분명히 목적대로 정확하게 동작한다. 유닛 테스트도 충실하게 채워서 논리의 부분 부분을 모두 커버한다. 그런데 아무리 읽어도 당연하지가 않다. 이상하다. 코드가 자신의 논리 흐름을 스스로 설명하지 못한다. 비유하자면 조그만 초가집에 리뷰하러 들어갔는데 그게 미로같은 동굴의 초입이었던거다. 거기에 더해 주니어는 승진 욕심에 코드를 시니어보다 더 빠른 속도로 만들어낸다. 몇년전 여름에 잠깐 일했던 인턴은 열성이 넘쳤다. 아마도 짧은 인턴쉽 기간동안 어떻게든 강한 인상을 남기고 싶었을것이다. 그래서 그 인턴은 석달 내내 코드를 만들어대며 리뷰를 요청했다. 계속 만들어내는 그 이상한 코드를 몇시간씩 리뷰하다가 이런 생각이 들었다.

147255590836907.jpg
(물론 이렇게 얘기하지 않았다)

그런데 <당연하게 읽히는> 에서 당연하다는 것이 몹시 주관적이다. 내게 당연한것이 다른 사람에겐 이상할수 있다. 하지만 경험상 어느정도 퀄리티를 갖춘 시니어로 구성된 팀이라면 한 시니어에게 당연해 보이는 코드는 다른 대부분 시니어에게도 자연스럽다. 주니어의 눈으로 보기에 자기들끼리 밀어주고 당겨주고 하는것처럼 보일수도있다. 하지만 그런것이 아니다. 코드의 퀄리티를 높이는 요소는 객관적으로 정의내리기 어렵지만, 경험자 사이에서 수렴되는 <보면> 알수있는 퀄리티의 요소가 있다. 평점 9점의 영화가 왜 훌륭한지 이유는 관객마다 조금씩 다를수 있다. 그런데 모든 사람들이 <아 좋았어> 라고 공감하는 퀄리티가 있는것이다.

가장 중요한 퀄리티는 <추상화> (Abstraction) 이다. 추상화의 가장 큰 오해중 하나는 <추상화 그림>처럼 현실을 모호하게 표현하는 것이라 생각하는것이다. 추상화의 본질은 감출것은 감추고, 드러낼것은 드러내는 것이다. 좋은 코드는 읽는 사람에게 가장 적절한 추상화의 단계 (level of abstraction)를 선사한다. Class, Function, Variable의 이름과 관계를 통해서 리뷰어가 읽으며 예측하고있는 단계의 추상화를 바로 그 순간 보여주는것이다. 성으로 들어가는 리뷰어가 문같은 형태를 찾고있는데 문의 열쇠를 보여주는 것은 리뷰어를 혼란스럽게 만들뿐이다. 좋은 추상화는 리뷰어가 문 앞에 다가간 그 순간에 문의 열쇠를 보여주는것이다. 성의 문을 하나 하나 열때마다 그 레벨에서 예측가능하고 익숙한 컨셉으로 논리의 방을 설명하는것이다. 추상화의 각 레벨에서 모두에게 <익숙한 컨셉>으로 설명하기 위해서는 많은 코드를 읽는것이 필요하다. 비슷한 유형의 문제에 대해 사람들이 공통적으로 동의하는 코드의 패턴이있기 때문이다. 나는 코미디언 <코난 오브라이언>을 좋아하는데 그의 팟캐스트를 듣다보면 항상 킥킥대던 그가 종종 진지한 주제로 대화할때가 있다. 그건 다른 코미디언이 호스트로 나오는 에피소드들이다. 코난과 다른 코미디언은 서로 뛰어난 코미디의 요소에 대해 진지하게 질문하고 탐색한다. 시대를 앞서간 코미디언들의 <익숙한> 패턴을 알고 싶어서 얼마나 연구했는지 서로 나누는 그 에피소드를 들으며 <직업>이 무엇인지 새삼 생각하게된다. 프로그래머가 새로운 것을 모두에게 익숙하게 설명하는 그 <당연함>의 이면에는 많은 시간 읽어내려간 방대한 코드의 양이 있다.

단계적 추상화를 마스터한 경험자와 초보의 가장 큰 차이는 논리의 흐름을 What 과 How로 설명하는 차이다. 좋은 코드는 추상화의 단계가 깊어질때마다 <이것은 무엇(What)입니다> 를 반복하고 주니어의 코드는 <이것은 어떻게(How) 돌아갑니다>를 반복한다. 주니어의 코드를 리뷰할때면 <이것은 귀가 쫑긋합니다> <이것은 짖습니다> <이것은 귀엽습니다> 와 같은식으로 여러개의 <How>를 붙여 무언가를 설명한다. 그럼 나는 <이거 개야?> 묻고 주니어는 그제서야 <아 개네!> 깨닫는다. 처음부터 대상이 개라고 설명했다면 나는 개의 동작과 특성에 익숙하므로 노력없이 논리를 이해했을것이다 (최악의 경우는 저렇게 설명해놓고 고양이라고 우기는 상황이다). 표현하고자 하는 논리를 모두에게 익숙한 컨셉 (What)들 사이의 관계로 설명하는것은 OOP에 좀 더 가깝다. 또한 논리를 <선언 (Declaration)>의 연속으로 표현하는 함수형 프로그램도 이에 가깝다. 그러나 <What>과 <How>중 무엇을 강조하는지는 OOP, 함수형 언어보다 코드를 만드는 사람의 경험과 내제된 퀄리티에 더 관계가 있다.

“Bad programmers worry about the code. Good programmers worry about data structures and their relationships.” – Linux Tovalds
“안좋은 프로그래머는 코드에 대해 걱정한다. 좋은 프로그래머는 데이터 구조와 관계에 대해 걱정한다” – 리누스 토발즈

끝으로 어느 팀이든 좋은 코드를 마스터한 시니어만으로 구성되지 않는다. 프로그래밍팀은 하나의 마을이다. 거기엔 아름답고 웅장하게 세워진 성도 있고 이제 첫 삽을 떠본 주니어가 만든 초가집도 있다. 시니어의 역할은 주니어의 초가집 엉성한 부분을 지적하는것에서 끝나지 않는다. 진짜 마스터는 계속해서 자기 성을 짓는 사람이다. 주니어가 지켜보며 영감 (inspiration)을 얻을만큼 계속해서 조금 더 아름다운 성을 만드는 사람이다. 주니어의 초라한 집에서 훗날 성이 될수 있는 재능을 발견해 용기를 주는 사람이다.

https://twitter.com/sm_park

코더

예전에 한 대기업 주재원분과 짧게 이야기 나눈적이 있었다. 내가 박사후에 계속 개발일 하고 있다고 했더니 <예? 코더요?> 하며 약간 그분 눈이 커진것을 놓치지 않았다. 도대체 코더가 어떻길래, 저 반응은 어떤 뉘앙스일까 살짝 마음에 걸렸다. 1년마다 다시 돌아오는 <잡스는 커녕!> 뉴스기사를 보고 그게 어떤 의미인지 조금 더 명확하게 다가왔다. (뉴스 기사)

기사의 도입부는 이렇다. “지난 6일 서울 관악구 서울대 공과대학에서 만난 하순회 컴퓨터공학부 학과장은 제 4차 산업혁명 시대에 고급 개발자 양성이 가장 중요한데도 현재는 부족한 개발자 인력을 채우기 급급해 ‘프로그래머’만 양성하고 있다고 진단했다. 여기서 하 학과장이 언급한 프로그래머란 단순 코더(Coder)에 가깝다. 고급 개발자가 프로그램 전반을 기획하는 설계자라면, 코더는 이를 실현하는 시공자에 해당한다.”

일단은 기사의 의도 자체가 <학교에 돈 좀 줘…제발> 인것은 기사에 쓰인 <공과대학 전경>이미지를 보면 알수있다 (골라도 저런 사진을…) 그렇다해도 코딩하는것을 천직으로 여기고 사는 나같은 사람은 이 기준으로 그럼 고급이냐 단순이냐 의문이 들수밖에 없다. 나뿐 아니라, 존경해 마지않는 <제프딘> <제임스고슬링> <크리스라트너>… 이 사람들은 분명히 고급일텐데 아직도 코딩을 하니, 이 비유대로라면 세계적인 건축 디자이너가 현장에서 공구리치고 있다는 얘기잖아?

문제는 소프트웨어를 <설계>한다고하니 자꾸 건축업계에서 메타포를 가져와 설명하려는데있다. 설계와 시공이 분리되어있고 고급진(?) 사무직과 현장직이 분리된 산업을 비유해 설명하니 자꾸 이 직업이 오해를 받는다. 내가 아는 뛰어난 개발자들은 모두 실제로 코딩한다. 처음 커리어를 시작할때도 그렇고 나이와 명성이 쌓인후에도 마찬가지다. 제프딘과 Sanjay의 협업에 대해 소개한 New Yorker 최근 기사는 구글의 탑레벨 임원인 그들이 매일 코딩한다는것을 잘 보여준다. 최근에 나는 회사를 옮기며 인터뷰를 했는데, 경력 10년에 어느정도 규모의 팀을 매니지했던 이전 역할과 상관없이 가혹한 코딩테스트를 거쳤다. 10년, 20년차의 경력만 내세우고 코딩을 소홀히 한 사람들은 <쏘리 쏘리> 연발하다 인터뷰를 마치기 십상이다.

그럼 프로그래머를 설명할 적당한 다른 직업은 없을까? 나는 개발자는 연예인에 좀 더 가깝다고 생각한다. 가수는 무대에서 노래를 불러야 가장 빛나듯이 개발자는 컴퓨터앞에서 코드와 싸울때가 가장 어울린다. 나이가 들어 무대뒤에 숨어서 후배들만 가르치려드는 가수보다는 계속 무대에 나와 조금 더 잘 하려고 애쓰는 사람을 아티스트라는 말로 표현한다. 아침마당에 나와 유연하게 허리 돌리는 사장님 박진영과 비의 퍼포먼스는 나이든 개발자가 지향해야 할 모델이다. 폴그레이엄은 에세이에서 개발자를 화가에 비유하기도 했다. 미술관의 주인공은 큐레이터가 아니고 아티스트인것을 잊지않았음한다.

기사에서는 고급개발자를 <양성>할수 있다고 주장했다. 개발자들 사이에서는 능력의 차이가 실제 크게 존재한다. 한때 10x 엔지니어라는 말이 유행했는데, 일반과 고급의 성능차이를 10배로 추정한다는 뜻이다. 나는 내 경험을 토대로 고급개발자의 조건을 세가지로 요약하려한다.

  1. 코딩이 뛰어나다면

코딩을 잘하는 사람은 많지 않다. 대충 경험상 네명중 한명정도 잘한다. 코딩은 엔지니어링 프로세스의 가장 중요한 한 부분이고, 좀더 넓게 표현하면 문제해결능력이 고급개발자의 조건에 가깝다. for-loop, if/else 등의 로직 연산으로 구성된 코딩은 사실 사람이 매일 수행하는 연산이다. 그래서 쉽게 보여 뛰어들수 있지만 일단 시작하면 죽을때가지 마스터할수 없는 수행의 길이다. 이 고난의 길에서 탁월한 기량을 보이는 사람은 두가지 정도로 나뉠수 있다. 첫째는 타고난 지능이다. 지금까지 학교졸업하고 막 직업전선에서 코딩을 시작한 여러명의 주니어들이 성장하는것을 지켜봤다. 그 과정에서 부인할수 없는것은 어떤 사람들은 불공평하게 똑똑하다는것이다. 브레인 자체의 배기량이 커서 한번에 처리하는 복잡도의 양이 다르다. 세상은 불공평하고 나 역시 불공평한 세상에 선택받지 못한자로 태어났다. 하지만 아직 찬스가 남아있는것은 두번째 이유 때문이다.

두번째 자질은 문제해결을 즐기는 사람이다. 많은 사람들에게 이 문제들은 괴로운 것이고 월급이라도 받아야 간신히 참여하는 노동인데 어떤 사람들은 그 과정 자체를 즐거워한다. 사실 똑똑한 것과 즐기는 것은 그 둘사이에 크게 연관성이 없다. 배기량이 조금 부족한 차를 몰아도 운전하는게 즐거워 매일 드리프트하다보면 배기량 큰차와 레이싱 붙어도 꿇리지 않는다. 내가 조립해놓은 생각의 조각들이 서로 맞물려 한치의 오차없이 돌아가는것을 지켜보는것은 세상에서 가장 즐거운 일중 하나이다. 나는 이번에 회사를 이직했는데, 지난주 회사를 나오며 약 반년간 작업한 결과물을 런치했다. 스케줄이 밀려 마지막날 금요일에 버튼을 눌러야했는데, 동료들에게 이걸로 나는 회사의 <레전드> 아니면 <빌런>으로 남을거라며 웃었다. 높은 확률로 서버가 터질수 있고 그 경우 회사의 매출에 직격탄을 맞는 백엔드 작업이다. 다행히 난 <레전드>로 마무리할수 있었다. 그 이유는 마지막날 새벽 3시까지 근심어린 눈으로 서버 그래프를 지켜볼 정도로 나는 이 문제를 내것으로 여기고 좋아했기 때문일것이다.

  1. 태도역시 겸손하다면

꽤 오래전 스타트업 직장에 정말 뛰어난 개발자 친구 C가 있었다. 수십만 라인의 코드를 몇달만에 만들어내는 어려서부터 코딩한 타고난 해커다. 제품 첫 버전의 거의 70%정도를 C 혼자 작성했다. 내가 처음 들어가 그 친구 코드의 이해안가는 부분을 질문했을때 흔쾌히 설명해준 다음 자신의 구현이 경쟁자에 비해 얼마나 빠른지 그래프까지 보여줬다. 경쟁 오픈소스 제품에 대해 설명할때면 다소 경멸띤 표정으로 얼마나 자신의 구현이 우월한지 설명하곤했다. 그런데 경쟁 제품이 시장에서 인기를 더 얻기 시작했다. 회사는 버전 2를 만들어야했고 가장 중요한 부분은 역시 C군에게 맡겨졌다. 다른 개발자들에겐 그 문제가 너무 어려울거라 생각했는지 C군은 문제를 독점했다. 그게 문제의 시작이었다. 버전 1에 비해 훨씬더 복잡한 스펙을 요구했던 버전 2는 C군에게도 버거운 문제였다. 하지만 그는 도움을 청하지 않았고 버전 2는 계속 지연됐다. 나중에는 문제가 지겨워졌는지 아프단 핑계로 한동안 회사에 나오지도 않아 그당시 우리 VP는 치킨누들수프를 끓여서 그 친구집으로 배달을 가곤했다. 스케줄보다 1년넘게 지연된 버전 2는 나온 후에도 버그 투성이였다.

코딩이 뛰어난데 겸손한 개발자 찾기는 정말 쉽지 않다. 어느정도 규모있는 팀에서 일하는 사람은 무슨 의미인지 알것이다. 경험상 두명중 한명꼴로 본받을만한 겸손함을 갖고있었다. 뛰어난 개발자는 높은 비율로 똑똑하기 마련이고 어려서부터 똑똑했던 사람에겐 겸손이 어려운 문제다. 하지만 똑똑한데 오만한 개발자는 팀에 있어서 독과 같다. 디자인, 코드 리뷰를 할때면 어느 순간 브레인의 배기량 자랑으로 변해버려 상대를 짓눌러버릴 방법을 찾는다. 오만한 시니어가 주도하는 팀은 각자도생하는 정글로 변해버린다. 정말 뛰어난 개발자는 혼자서 버전 1은 만들어낼수 있다. 하지만 궤도에 올라간 프로덕트를 우주로 끌어올리는건 팀이 함께 푸쉬하는 힘이다. 그리고 그팀을 만들어내는건 코어에 있는 능력을 겸손한 말로 전달하는 리드다. 겸손함의 핵심은 상대방과 팀을 돕기위해 자신을 내어주는 것이다.

  1. 그런데 커뮤니케이션도 잘하면

훌륭한 코딩에 겸손함을 갖추고 있는 개발자가 주위에 있는지 생각해보라. 혹시 그 사람이 팀에 미치는 영향력이 생각보다 작다면 마지막 조건에 미달하기 때문일것이다. 커뮤니케이션과 코딩능력은 정말로 어울리지 않는 상극과 같은 조건이다. 왜 그런지는 나도 잘 모르겠다. 주변에 코딩 정말 잘하는데, 자신의 문제를 비지니스에 연결지어 효과적으로 설명하는 사람이 얼마나 되는지 생각해보라. 경험상 세명에 한명 꼴로 개발자의 커뮤니케이션이 좋았다. 야후의 Marisa Mayer는 이렇게 얘기했다.

“Beyond basic mathematical aptitude, the difference between good programmers and great programmers is verbal ability.” – Marissa Mayer

“기본적인 수학능력 이외에 괜찮은 프로그래머와 뛰어난 프로그래머의 차이는 말하는 능력이다”

나는 지난 몇년간 매니저 역할을 하면서 수도없이 많은 미팅을 했다. 사실 매니저 시작하며 제일 부담스러웠던건 내 떨어지는 영어실력과 발음이었다. 하지만 몇달 지나고나서 내 걱정은 기우였다는 것을 알았는데, 영어가 모국어인 사람들도 말을 엄청못한다는걸 깨달았기 때문이다. 1:1 미팅하면서 지금 해결하는 문제에 대해 질문하면 눈을 잘 못 마주치며 우물대는 사람도 있고, 전달해야 할 내용을 요약을 못해 코드 레벨 하나하나 다 설명해야 하는 사람도 있다. 커뮤니케이션을 잘하는 것은 말을 많이하는것이 아니다. 어떤 친구들은 말하는 것을 너무 좋아해 정보에 시그널 대비 노이즈가 너무 많다. 커뮤니케이션이 좋은 사람은 상대방에게 필요한 정보를 정황 (context)속에서 빨리 캐치해내고 상대의 언어로 해석해서 전달한다. 개발자와 PM/마케팅같은 비 개발자가 모이는 미팅에서 개발자가 사용하는 단어 하나하나를 유심히 살펴보라. 외계언어로 이야기하는 개발자에게 미소를 짓는 마케팅 부서 직원은 <이 외계인이 또…> 속으로 생각할런지 모른다.

코딩 잘하는 사람이 1/4, 겸손한 사람이 1/2, 마지막으로 커뮤니케이션 잘하는 사람이 1/3 비율로 존재한다면, 이 세가지를 모두 갖춘 사람은 1/24 비율이다. 이렇게 찾기 어려우니 고급 개발자인게 맞다. 그런데 이 세가지 조건중에 학교에서 양육할수 있는것은 무엇인지 생각해보라. 겸손을 학교에서 배울수 있을까? 다양한 직종의 사람들 틈사이에서 배워가는 커뮤니케이션 능력은 어떨까? 코딩의 영역 역시 학교는 정글에서 살아남는 도구 쓰는 능력을 가르칠뿐 실력 자체를 만들어주지는 못한다. MIT, 스탠포드, 아이비리그 학교의 졸업생들 많이도 일해봤지만, 흔히 이야기하는 학교의 네임밸류와 실제 코딩 능력은 크게 연관성이 없었다. 뛰어난 리더는 양육되는게 아니다. 혹시 가능하더라도 최소한 양육하는 스승이 뛰어난 모델이어야 하지않을까? 누군가가 <교수는 졸업하지 않기로 마음먹은 학생>이라고 이야기했는데…

코딩, 겸손, 커뮤니케이션을 마스터한 뛰어난 리더는 살면서 그렇게 하기로 스스로 깨달은 사람들이다.

https://twitter.com/sm_park

코딩 인터뷰 – part 5

온사이트의 마지막 세션을 마칠때쯤엔 대략 오퍼의 여부를 스스로 예상할수 있다. 파트 2에서 설명했던것처럼 한개 정도 부족한 세션이 있었다해도 나머지 문제들을 풀었다면 오퍼가 희망적이다. 회사들은 보통 인터뷰 다음날 인터뷰어들이 모여 debriefing 시간을 갖는다. 여기에서 리뷰들이 오퍼쪽으로 결정되면 리쿠르터는 지체없이 연락을 해온다. 인터뷰 후 결과가 나오기까지는 마치 예전에 대입시험 결과를 기다리는 그런 초조함이 있다. 내 경험상 오퍼가 나올때에는 인터뷰후 빠르면 24시간, 늦어도 3일안에 오퍼 소식을 들을수 있었다. 혹시 연락이 오지 않고 시간만 흘러갈때는 점점 오퍼의 가능성이 낮아진다. 이 경우 며칠후에 공손하게 확인하면 결과를 가르쳐준다. 리젝시에 한가지 꼭 시도하면 좋은것은 인터뷰의 피드백을 달라는 요청이다. 일반적으로 회사는 정책상의 이유로 인터뷰의 피드백을 공유하지 않는다. 그러나 종종 피드백을 짧게라도 이야기해주는 곳이있다. 이 피드백에는 내 예상과 다른 평가들이 있을수 있기때문에 다음 인터뷰를 준비하는데 아주 유용하다. 내 경우 첫 인터뷰에 안되고나서 코딩때문이라 생각했는데, 의외로 시스템디자인에서 부족했다는 피드백을 받았다. 결과가 안좋을때는 배울것을 한가지라도 건지고 툭툭 털어내는게 좋다.

오퍼가 나오면 이제 시작되는 것은 연봉과 Title, Benefit (보험, 휴가)등에 관련된 협상(negotiation)이다. 미국에서 비지니스 관계의 모든 딜은 철저하게 협상을 통해 이루어진다. 예전에 차를 한대사러 딜러샵에 간적있다. 전날밤 미리 여러개의 웹사이트에서 해당 차량의 가격 정보를 풍부하게 수집하고 딜러와 데스크를 사이에 두고 앉았다. <갑>의 위치에 있다고 생각한 나는 편안하게 내가 생각한 적정 가격을 제시했다. 딜러는 웃음기 없는 얼굴로 이렇게 되물었다.

“왜 그 가격이 타당한지 나를 설득시켜봐”

잡마켓에서 오퍼 이후의 협상도 마찬가지다. 목표하는 연봉이 있을경우 그 액수를 뒷받침할수 있는 논리적 이유가 있어야 한다. 그중 가장 효과적인것은 역시 다른 회사에서 제시하는 경쟁 오퍼다. 한개의 오퍼만 가지고 테이블에 올라오면 설득시킬 무기가 없다. 리쿠르터와의 대화는 그래서 이렇게 요약된다.

“잘 해 줄께. 근데 얼마까지 알아봤어?”

리쿠르터는 타 회사의 오퍼가 있을경우 이를 상세하게 적어가고 곧 이보다 조금 많은 금액으로 오퍼한다. 이쯤되면 보통 지원자 입장에서는 연봉과 상관없이 가고싶은 회사가 한곳 이미 정해져있다. 그래서 다른 곳의 오퍼는 원하는 회사의 오퍼를 올리기 위한 수단으로 사용해야한다. 그런데 리쿠르터 역시 매일 이런 딜을 하는사람들이기 때문에 본인이 top에 있는지 아니면 오퍼를 올리기 위한 마중물인지를 파악하려고 노력한다. 그래서 지원자는 끝까지 포커페이스를 유지하며 왜 그 회사가 top choice인지 이유를 댈수있어야한다. 지원자에게 최고의 전략은 second choice에서 오퍼를 맥시멈으로 끌어올리고, top에서 이를 이기게끔 만드는것이다.

소프트웨어 회사의 오퍼는 보통 이렇게 구성되어 있다.

  • 베이스 연봉
  • 보너스
  • 주식 (RSU)
  • 사이닝 보너스

주식과 보너스 역시 시간이 얼마 지나면 현금화 할수있기때문에 이를 모두 합산한 Total Compensation을 기준으로 협상하는것이 좋다. 사이닝 보너스는 일회성 금액이라 융통성이 있기때문에 회사들은 경쟁 오퍼를 죽이기위해 활용할수 있다. 그래서 오퍼가 여러개 있을때 사이닝을 최대한 잘 받는것도 좋은 전략이된다.

최근엔 보통 Glassdoor의 정보를 활용해 오퍼가 괜찮은지 여부를 평가한다. 그런데 내 경험에 Glassdoor의 연봉 정보는 시장 가격보다 좀 많이 낮은편이다. 아마도 오래된 정보가 쌓여있어서 그런게 아닌가 생각된다. 시장의 가격보다 대략 30%정도 디스카운트 되어있다고 생각하는게 좋다. 이보다 좀 더 정확한 정보는 paysa.com에서 얻을수 있다. 예를들어 시애틀 마이크로소프트의 시니어 엔지니어 경우 glassdoor에선 175K이 평균인 반면, paysa에서는 221K가 시장 가격으로 올라와있다. 경쟁 오퍼가 있다면 이보다 조금 더 올리는것도 어렵지 않으니, “얼마까지 알아봤어?”의 시장 원리를 최대한 활용하는것이 좋다.

이렇게해서 이번 인터뷰 시리즈를 마무리한다. 결과적으로 나 자신도 뜻밖의 결과인 Niantic Lab.으로 다음 회사를 결정했다 (나이엔틱은 포켓몬고를 만드는 증강현실 게임회사). 다른 몇개의 대기업에서 받은 오퍼가 괜찮고 한두개 회사는 일의 종류, 환경, 팀도 너무 마음에 들어 포기해야 하는게 아까웠다. 나이엔틱의 인터뷰 경험은 다른 대기업들과는 많이 달랐다. 높고 화려한 대기업 오피스들 사이에 낮고 오래된 건물이 있고, 어두컴컴한 복도 한켠에 회사간판도 없는 오피스… 문을 열고 들어가니 주성치 영화에 조연처럼 생긴, 머리카락 몇올없는 중국 아저씨가 웃으며 나를 맞았다. 아주 작은 사무실에 다닥다닥 붙어앉아 일하는 사람들. 오피스가 그래서인지 다소 창백해 보였지만 다들 눈은 초롱초롱 빛났다. 작년의 포켓몬고 열풍에 서버를 어떻게 감당했는지 물었더니 중국아저씨는 <그땐 3-4시간씩 자면서 다 막아냈지 껄껄껄>… 이 바닥 초 절정 고수의 아우라를 풍겼다. 인터뷰를 마치고 나오며 팬시한 대기업에서 못느낀, <여기에서 일하고싶다> 라는 열망이 생겼으니, 나도 어지간히 스타트업을 좋아하는가보다.

https://twitter.com/sm_park

코딩 인터뷰 – part 4

예전에 구글에서 일하시는 한분이 본인은 시스템 디자인 인터뷰가 가장 어렵다고 이야기한적 있다. 코딩인터뷰의 경우 문제 set이 존재하기때문에 문제를 많이 풀어보면 되지만, 시스템 디자인은 질문을 예측하는것도 어렵고 정답이란것도 존재하지 않기때문이다. 구글에서 시스템 디자인 문제를 검색해봐도 결과에 정답은 나오지 않는다. 시스템 디자인은 대부분 스케일 문제를 다룬다. “수억명의 사람들이 너의 서비스를 사용한다면 너는 어떻게 이 문제를 해결할래?” 이런 질문에 경험에서 우러나오는 사골같은 답을 할수 있다면 얼마나 좋을까마는 사실 그런 시스템을 다 만들어본 엔지니어는 극히 소수일 것이다. 나 역시 시스템 분야로 PhD도 했고 수년간 같은 분야에서 다양한걸 만들었지만 여전히 이 질문은 어렵다. 그러나 디자인 인터뷰 역시 살아남는 방법은 있다. 그 방법이란 좀 싱겁지만…,

“공부를 많이하면 된다.”

우선 내가 그동안 받았던 디자인 질문들을 나열해보면 이렇다.

  • Queue 시스템을 디자인해라
  • Twitter를 디자인해봐라
  • TinyURL 디자인해봐라
  • Yahoo의 Stock Quote 시스템을 디자인해라
  • Elevator 시스템을 구현해봐라
  • Hadoop의 namenode를 새로 디자인해봐라
  • (AI 관련팀) 우리 시스템을 네가 디자인해봐라

4-5명과의 인터뷰중 시스템 디자인은 최소 한차례, 많게는 두세번 질문을 받게된다. 시스템 디자인에서 인터뷰어가 파악하고자 하는것은 크게 세가지로 볼수 있다:

  1. 커뮤니케이션을 잘 하는가?
  2. 문제를 정확히 알고있는가?
  3. 괜찮은 디자인을 할수있는가?

디자인 질문은 의도적으로 모호하게 주어진다. 예를들어 Queue 시스템을 디자인하라는 질문은 사실 밑도끝도 없다. <어떤 Application이 Queue를 사용하는가?>, <Queue에는 무엇이 들어가는가?>, <Producer/Consumer의 숫자는 몇개인가?> 등 디자인에 꼭 필요한 디테일이 빠져있다. 그래서 디자인 질문을 받았을때 처음 해야하는것은 <질문>이다. 여러번 충분한 질문을 통해서 인터뷰어가 생각하는 진짜 문제를 파악해내고 여기에서 Requirement를 알아내는것이 첫 단계에서 반드시 해야할 일이다. 이 과정에서 인터뷰어는 지원자의 커뮤니케이션 능력을 평가한다. 혹시 예전에 비슷한 시스템을 구현해본적이 있다고 질문을 생략한다면 이는 인터뷰가 망하는 길로 가는 지름길이다.

내가 받았던 디자인 질문중 특히 좋았던 것 한가지는 엘리베이터 시스템을 디자인하라는 것이었다. 무한하게 많은 수의 엘리베이터가 늘어서있다고 가정하고 사용자가 각 층에서 누르는 Up/Down 버튼에 맞추어 어떻게하면 최적의 서비스를 제공할수 있을까라는 질문이었다. 이 질문이 좋았던 이유는 엘리베이터라는 잘 알려진 문제가 그동안 생각하지 못했던 수많은 분산시스템의 컨셉을 드러내기 때문이다. 예를들어서,

  • Controller가 중앙에 한개 놓여있고 모든 엘리베이터가 통제에 따른다고 가정해보자. 그럼 Controller가 죽어버리면 엘리베이터의 Availability는 어떻게 될것인가?
  • 그럼 엘리베이터를 분산시스템으로 구현해보자. 엘리베이터 사이의 커뮤니케이션이 불안정할때 스케줄이 항상 정확할수 있을까? (CAPS theorem)
  • 엘리베이터는 사용자가 버튼을 누른 시간순으로 서비스를 제공한다. 그럼 엘리베이터의 시간은 모두에게 동일하게 흘러가는가? (Vector clock의 개념)

이러한 질문의 의도는 지원자가 시스템에서 발생하는 <문제> 혹은 <컨셉>을 다양하게 알고있는가를 파악하기 위한것이다. 가상의 문제에 대해 대화하면서 분산시스템의 클래식한 문제들 — vector clock, CAPS theorem, distributed consensus, quorum vote, data hashing등 — 을 연상해낼수 있는지를 보는것이다. 뛰어난 인터뷰어일수록 이런 질문을 던진다. 이런 문제에 답하기 위한 쉬운 방법은 없다. 아래에 달린 긴 리스트에서 보듯, 그저 다양하게 많이 아는 수밖에…

마지막으로 디자인 질문에서 파악하고자 하는것은 <괜찮은 디자인을 할수 있는가?> 여부이다. 복잡한 시스템에는 정답이 없다. 다만 괜찮은 답이 있을뿐이다. 여기에서 괜찮은 답이란 디자인의 각 단계에서 어떠한 선택을 해야할때 각 선택의 Trade-off 를 알고 있고, 자신의 선택을 논리적으로 방어할 수 있는 디자인이다. 즉 취할것은 취하고 버릴것은 버리되, 왜 그러한 선택을 하는지는 설명을 할 수 있어야 한다는 뜻이다. 예를들어 트위터를 디자인한다면,

  • Relational DB를 Shard해서 사용할것인가 아니면 Cassandra, Dynamo와 같은 분산 key-value DB를 사용할 것인가?
  • In-memory cache로 Redis 혹은 Memcached 를 사용할까?
  • Push model (모든 follower에게 tweet을 저장) 혹은 pull model (모든 following에게서 tweet을 읽음)을 사용할까?
  • Tweet의 아이디는 DB의 Sequential ID를 사용할까 아니면 snowflake와 같은 분산시스템을 따로 만들까?

코딩 질문이 한가지 질문에 optimal 알고리즘을 구현하기위한 것이라면 시스템 디자인은 시스템의 각 파트를 해결하기위해 제각각 여러개의 알고리즘을 끌어와서 큰 스케일에서 동작하는 그림을 보여주는 것이다. 그러므로 좋은 답을하기 위한 핵심은 얼마나 많이 그러한 알고리즘을 알고 있는가의 여부이다. 예를들어,

  • 어떻게 분산된 컴퓨터에 데이터를 나눌 것인가 —> Consistent hashing
  • 분산 컴퓨터들은 어떻게 자신이 담당할 문제의 영역을 선택할까? —> Paxos algorithm or zookeeper
  • 데이터가 복제되어있을때 어떻게 consistency를 보장할까? —> Quorum vote
  • 분산 컴퓨터가 어떻게 ID를 고유하게 만들까? —> Twitter’s snowflake
  • 데이터 통신의 보안은? —> PKI encyprtion

아래는 내가 그동안 공부했던것들중 인터뷰에서 가장 유용했던 자료들이다. 꼭 인터뷰가 아니더라도 최신의 시스템을 이해하는데 좋은 자료들이라고 생각해 여기에 공유한다. 가장 중요한 자료에는 별점 5개를 붙여놓았다.

[Designing Data-Intensive Applications]
시스템 디자인 준비하기에 가장 좋은 책. 아래의 레퍼런스 대부분 내용을 책 한권에 다 요약해 놨다. https://www.amazon.com/Designing-Data-Intensive-Applications-Reliable-Maintainable/dp/1449373321

[Distributed Systems]

[Distributed Key-Value Database]

[Sharding]

[Caching]

[Search]

[Distributed Consensus]

[Concurrency]

[Distributed Queue]

[그외]

코딩 인터뷰 – part 3

예전에 한 스타트업과 인터뷰를 한적이 있다. 첫 시간에 두명의 엔지니어가 함께 들어왔는데 한시간 내내 코딩이나 시스템디자인이 아닌 behavioral 인터뷰를 했다. 과거 직장동료와 충돌이 있었는지, 그런 상황에서 어떻게 문제를 해결했는지등 일반적인 질문이었다. 코딩 인터뷰를 기대했던 나는 약간 당황했고 답은 횡설수설이었다. 그리고 한시간을 마치자마자 리쿠르터가 들어와 나는 그 회사와 cultural fit이 맞지 않으니 집에가라는 결과를 받았다. 태연한척 걸어나왔지만 ‘내 인성이 그리 엉망진창이란 말인가?’ 모욕감이 며칠간 내내 머리를 맴돌았다. 최근에서야 깨달은것은 behavioal 인터뷰 역시 준비가 필요하다는 사실이다. (참고로 나는 그 스타트업이 잘될거라고 생각하지 않는다. 엔지니어를 인성만으로 거르는건 축구선수를 외모 보고 발탁하는것과 같다.)

테크 회사들의 개발자 인터뷰는 크게 1) 코딩, 2) 시스템 디자인, 3) behavioral 세가지 파트로 나눌수 있다. 코딩인터뷰의 경우 주어지는 문제에따라 최적의 알고리즘이 이미 알려져있기때문에 pass/fail 여부를 쉽게 가늠할수 있는반면 behavioral과 시스템 디자인은 정확하게 어디까지가 pass이고 fail인지를 나누는것이 쉽지 않다. 지원자 입장에서는 최대한 ‘잘’ 준비하는수밖에 없다. behavioral의 경우 회사에서 알고자하는것은 크게 두가지로 볼수있다:

1. 커뮤니케이션을 효과적으로 하는가
2. 이 녀석은 혹시 jerk (고문관)가 아닐까?

과거에 아무리 대단한 프로젝트를 많이했어도 몇분안에 그 경험의 핵심을 전달하는것은 코딩과 별개인 커뮤니케이션 능력이다. 영어에 native가 아닌 사람들에게는 특별히 준비가 필요한 영역이다. ‘jerk test’의 경우 가장 중요한것은 인터뷰 과정에서 이상 행동을 하지 않는것이다. 듣기로는 테크 인터뷰를 하면서 인터뷰어와 싸우려드는 사람들이 의외로 많다고한다. 혹시라도 자신에게 파이터 본능이 있다면 인터뷰 당일만큼은 날카로운 발톱을 최대한 숨기는것이 좋다.

Behavior인터뷰의 방법은 회사마다 다르다. 어떤 회사들은 코딩인터뷰 중간에 인성과 관련된 질문을 넣기도 하고, 다른 회사들은 점심 시간이나 하이어링 매니저와의 세션 전부를 인성과 관련된 질문으로 채워 넣는다. 다음은 내가 받았던 Behavioral 혹은 프로젝트 경험과 관련된 질문들이다.

  • 지금까지 해결한 기술적인 문제중 아주 어려웠던 것은 어떤것이 있는가? 어떻게 그 문제를 해결했는가?
  • 지금 회사를 왜 떠나려고 하는가? 왜 우리 회사를 선택했는가?
  • 프로젝트가 내가 원하지 않는 방향으로 진행되는 것을 경험한적이 있는가? 어떻게 대응했는가?
  • 프로젝트가 기술외의 문제 (사내 정치등)로 영향을 받은적이 있는가?
  • 팀을 리드해본 경험이 있는가?
  • 내가 담당하는 영역이 아닌 다른 사람, 부서의 문제를 해결한 경험이 있는가?
  • 직장동료와 충돌을 경험한적이 있는가? 그런 상황에서 어떻게 문제를 해결했는가?
  • 고객과 회사의 이해가 충돌하는 상황을 경험한적이 있는가? 나는 어떤 선택을 했는가?

이와같은 질문을 받았을때 그 자리에서 즉흥적으로 답을 만들어내는것은 생각보다 쉽지 않다. 과거의 경험을 바탕으로 최대한 긍정적인 면을 어필할수 있는 답을 미리 준비하는것이 필요하다. (To be continued…)

코딩 인터뷰 – part 2

온사이트 인터뷰

스크리닝에서 일단 지원자가 사람이라는게 판가름나면 그 다음은 <쓸모>있는 사람인지를 판단하는 온사이트 단계로 넘어가게된다. 폰스크린 마치고 짧게는 1시간 안에, 길게는 2-3일내로 온사이트 초청 이메일을 받게된다. 이때부터 리쿠르터가 지원자를 대하는 태도가 조금 달라지는걸 느낄수 있는데 미래의 동료가 될 가능성이 높기때문에 이메일과 전화통화에서 좀더 지원자를 배려해준다. 즉 이제 <사람 취급> 받는다는 뜻이다.

폰스크리닝이 예선전이었다면 온사이트는 이제 본선이다. 월드컵 예선에서 미얀마, 필리핀같은 array문제를 풀었다면 이제 본선에선 독일, 브라질같은 dynamic programming, graph search 문제도 만나게 된다. 더 쓰기전에 우선 내 경험을 좀 더 이야기하려고 한다. 나는 내 자신이 한번도 알고리즘에 소질이 있다고 생각한적이 없다. <알알못>같은 사람이다. 학부 시절에 알고리즘 수업에서는 C를 받았었고, 대학원 수업에서도 C를 받았다. 참고로 대학원 수업에서 B를 못받는건 교수에게 진상짓하는것과 같다. 박사학위를 했지만 시스템쪽 전공이라 알고리즘과는 관계가없고, 지난 몇년간 스타트업에서 일하며 제대로 코딩 인터뷰를 해본적도 없다.

내가 코딩 인터뷰를 돌파하기 위한 방법은 그래서 한가지였다. 멋있는 말로 하면 <photographic memory 능력을 사용하자> 이고, 쉽게 말하면 <답을 외우자>가 내 전략이었다. 코딩 인터뷰에는 분명히 문제 set이 존재한다. 어떤 경우엔 문제가 토씨하나 틀리지않고 그대로 나올때가있고, 응용이지만 결국 같은 알고리즘을 원하는 문제를 만날때도 있다. 코딩 인터뷰의 set을 공부하는 가장 좋은곳은 leetcode.com 이다. 이곳에서 Frequency 순으로 정렬해서 가능하면 많이 문제를 풀어보는것이 좋다. 나는 지난 3개월간 160개 정도의 문제를 풀었고 같은 문제가 나왔을때 한번도 실수 안할정도로 답의 코드 패턴을 외웠다.

사실은 인터뷰의 set을 푸는 그 과정이 쉬운것은 아니다. 한 문제를 풀어보려고 2시간 이상 씩씩대가며 모니터를 쳐다볼때도 많았다. 나는 내가 좀 지능이 모자라서 그런가 생각했는데, 최근 공부를 시작한 나보다 훨씬 똑똑한 동네 친구 역시 나처럼 2시간씩 씩씩대고 있다는 하소연을 들었다. 그런데 한가지 흥미로운 사실은, 공부를 시작할무렵 문제를 보면서 느낀, 마치 벽을 앞에두고 선듯한 막막함이 지금은 거의 사라졌다는 사실이다. 지금은 비슷한 문제를 보면 예전에 외웠던 알고리즘의 패턴이 자연스럽게 생각난다. 같은 문제에 대해 예전에는 두뇌가 불편해 했다면, 지금은 두뇌가 자연스럽게 받아들인다고 할까? 160개의 문제와 답의 알고리즘 패턴을 외우는 과정에서, 두뇌가 좀 더 알고리즘 문제에 적응되었기 때문일것이다. 그래서 <답을 달달 외우면 그게 실력이냐?> 누가 묻는다면, <하다보면 실력이 돼> 라고 답할수 있을것 같다.

다시 온사이트 이야기로 돌아가보자. 온사이트는 보통 4-6명의 인터뷰어와 1시간씩 돌아가며 문제를 푼다. 폰스크리닝과 확연한 차이점은 두뇌가 5시간 이상을 버틸 체력이 필요하다는 사실이다. 코딩을 격투기라고 생각하면 매 시간마다 새로운 도전자가 씨익 웃으며 링위로 올라온다는 뜻이다. 쉬는 시간도 주어지지 않고 <다음 인터뷰어를 소개하지~> 이렇게 계속해서 상대방만 턴을 바꾸게된다. 나는 3주간 10개의 온사이트를 집중해서 보았다. 처음 온사이트는 숨막히는 피곤함 뿐이었는데, 후반기로 갈수록 체력이 붙어 여유롭게 6시간을 버텨낼수 있었다. 특히 오퍼가 이미 나왔다면 <허허 어디 문제한번 봅세~> 이런 여유로움도 누릴수 있다.

폰스크리닝과 마찬가지로 매 시간마다 인터뷰어는 <너는 뭐했슴?> <우리팀에 질문있슴?> 이렇게 묻는다. 가능하다면 앞 부분의 이런 인트로는 짧게 하고, 문제를 푸는 시간을 최대한 길게 갖는것이 좋다. 4-5명과의 온사이트중 최소한 1명은 디자인 인터뷰를 담당한다. 시니어 레벨의 경우 2명 이상과 디자인 세션을 하는 경우도 있다. 또 점심식사를 겸해서 behavioral interview를 하는게 일반적이다 그래서 코딩은 온사이트에서 3회 정도 한다고 보면 일반적이다.

인트로가 끝나면 <자 오늘 내가 준비한 문제는…>, 이렇게 멘트를 날리며 인터뷰어는 문제를 화이트보드에 적는다. 이때 문제에 따라 몇가지 다른 시나리오가 생긴다.

  • 아는 문제: 경험상 절반의 문제는 leetcode 문제 set에서 그대로 나왔다. 이때 필요한 것은 출중한 연기력이다. 태연하게 ‘나는 저 문제를 모른다. 나는 저 문제를 모른다’ 머리속으로 되뇌인다음 1) 막막한 표정, 2) brute-force는 이렇게 하면 될건데 , 3) 아 이렇게 하면 더 빨리 되겠구나!, 이렇게 단계별로 연기해가며 차분하게 외운 코드를 화이트보드에 적으면 된다
  • 응용 문제: 경험상 1/4 정도의 문제는 이미 외우고있는 문제를 약간만 응용해서 답을 찾는 타입이다. 예를들어 graph search 문제는 무궁무진하게 응용이 가능한데, 몇개의 문제를 풀어봤으면 대략 문제 설명을 듣고나서 이건 graph 문제구나 라는 느낌이온다. 이 경우엔 연기가 필요없다. 자연스럽게 내가 아는 지식을 꺼내서 문제에 적용하는 것이기 때문에, 코딩만 실수없이 잘 마무리하면 된다.
  • 모르는 문제: 이런 경우가 없으면 좋겠지만 어떤 인터뷰어는 너무 부지런해서 공개안된 문제를 내곤한다. 경험상 1/4 정도의 문제는 처음 접해보는 것이었다. 이 경우 우선은 알고리즘 패러다임 (dynamic programming, graph, binary search, divide&conquor..) 혹은 자료구조 (priority queue, binary search tree, …) 중에서 하나라도 써볼수 있는게 있나 생각해야 한다. 그리고 최대한 막막하고 힘든 표정을 지으며 인터뷰어의 힌트를 유도해야 한다. 힌트를 얻고도 도저히 안되겠다 싶을때는 시간을 잘 고려해 brute-force라도 코드를 정확하게 끝까지 써내야 한다. 한 세션의 결과는 [pass, neutral, fail] 세가지중 하나인데, pass가 글렀으면 neutral로 승점 1점이라도 건져야한다.

지난 10회의 온사이트에서 나온 25개 문제를 카테고리로 나누면 다음과 같다:

  • Binary Search Tree or Binary Tree: 8회
  • Graph Search Problem: 3회
  • Dynamic Programming: 2회
  • Advanced(응용) Sorting: 3회
  • Hybrid Data Structure: 2회
  • Greedy Algorithm: 4회
  • String, sliding-window problem: 2회
  • Binary Search 응용: 1회

대부분 문제들은 leetcode의 medium difficulty 수준이라고 생각하면 되고, 종종 hard difficulty 문제가 나오는 경우도 있다. 내 경우 dynamic programming 문제중 하나는 아주 어려운것이었는데 마침 그 문제의 답을 며칠전 외운 상태였다. 그리고 그 인터뷰가 첫 오퍼였으니 어쩌면 인터뷰엔 운도 많은 작용을 한다.

코딩과 디자인 인터뷰 (다음 블로그 주제)를 4명과 했을경우 경험상 오퍼의 여부는 이렇게 가늠할수 있다:

  • 4명 PASS: 당연히 오퍼
  • 3명 PASS, 1명 Neutral: 오퍼
  • 3명 PASS, 1명 Fail: 리젝
  • 2명 PASS, 2명 Neutral: 리젝

즉, 한명에게라도 Fail수준의 인터뷰를 했으면 오퍼는 나오지 않았다. 그리고 2명이상 Neutral일 경우에도 오퍼는 나오지 않았다.

끝으로 코딩 인터뷰에 적합한 알고리즘 교과서는 Skiena의 Algorithm Design Manual을 추천한다. Cormen의 Introduction to Algorithm보다 쉬우면서 인터뷰에 충분한 내용은 모두 담고있다. 그리고 인터뷰 경험이 부족한 사람에겐 가상(mock) 인터뷰를 할수 있는 pramp.com 도 아주 유용했다. 코딩 인터뷰의 pressure를 훈련하기에는 mock 인터뷰만큼 좋은것이 없다.

(To be continued…)

코딩 인터뷰 – part 1

지난 두달간 무려 15개의 회사와 코딩 인터뷰를 했다. 혹 비슷한 과정을 겪게될 분들을 위해 그동안의 경험을 지극히 주관적인 관점에서 정리해보려고 한다.

미국의 소프트웨어 개발자 채용 과정은 사실 공정한 편이다. 채용 프로세스중 몇몇 역할을 우선 소개하자면,
  1. 리쿠르터: LinkedIn등을 통해 지원자와 처음 연락하는 것부터 오퍼의 마지막 단계까지 끌어주는 역할을 한다. 오퍼의 여부를 결정하는 사람은 아니지만, 오퍼에서 연봉등을 하이어링 매니저와 조율하기 때문에 중요한 역할을한다. LinkedIn으로 귀찮게 연락한다고 가볍게 여겨선 안된다.
  2. 하이어링매니저: 포지션을 오픈하고 채용 후에 보통 매니저 역할을 수행하게되는 사람이다. 곧 미래의 보스라고 생각하면 된다. 이 사람의 의견이 채용에 있어 가장 중요하므로 지원자 입장에선 높이 우러러보는 자세가 필요하다.
  3. 같은팀 개미 개발자: 오퍼를 받았을때 같은 팀에서 일하게될 개미 개발자들이다. 여기서 개미는 Principal 보다 낮은 직급으로 주로 코딩 인터뷰를 담당하는, 일개미 같은 개발자들을 말한다.
  4. 같은팀 왕고 개발자: 같은 팀에서 Principal 엔지니어 이상의 직급으로, 칠판에 그림만 그리고도 월급을 쓸어가는 사람들을 말한다. 참고로 대기업에서 Principal들은 보통 연봉이 30만불을 훌쩍 넘긴다. 이들의 역할은 주로 그림 그리는 것인만큼 인터뷰 역시 칠판에 그림 그리는 시스템 디자인을 주로 담당한다.
  5. 다른팀 왕고 개발자: 원래 아마존에서 시작했던 Bar-raiser 시스템이 여러 회사에 퍼지면서 다른팀의 왕고 개발자가 인터뷰에 들어올때가 있다. 이들은 보통 어려운 문제를 던져놓고 심드렁하게 앉아있는 경우가 많다. 지원한 팀에대해 질문을 하면 자기 팀이 아니라 당황해 하기때문에, 맘에 안들면 타이밍을 봐서 한번 물어보는것도 괜찮다.
채용 프로세스의 첫 단계는 리쿠르터와의 짧은 통화다. 내 레주메가 하이어링매니저 혹은 리쿠르터의 눈에 들었을땐 이메일로 전화 약속을 잡게된다. 통화시엔 레주메를 기준으로 과거의 경력을 짧게 소개하고, 왜 그 포지션에 지원하게 되었는지 설명한다. 하이어링매니저가 시켜서 전화를 걸어온 경우엔 거의 100% 전화 인터뷰를 잡자고 이야기하고, 혹 리쿠르터가 단독으로 연락을 해온경우 하이어링매니저의 레주메 심사를 더 통과해야 한다. 리쿠르터와의 통화는 거의 같은 패턴을 반복하므로 몇번 같은 통화를 하고나면 나중엔 유머사이트 보거나 애들 밥먹이면서 이야기하는 경지에 이르게된다. 혹 첫단계에서 현재 회사의 연봉을 묻는 리쿠르터가 있는데, 이 경우 어차피 오퍼 단계에서 필요한 정보이므로 알려주는것도 나쁘지 않다.

전화 인터뷰

리쿠르터와의 통화이후 며칠안에 전화 인터뷰가 잡힌다. 흔히 이것을 Phone Screening 이라 부르는데, 해석하자면 전화기 너머 상대가 스크리닝 (차양막, 모기장) 당해야 하는 벌레인가 아니면 온사이트 불러도 되는 인간인지를 판가름하는 지원자 입장에선 기분나쁜 단계다. 폰스크리닝의 상대로는 흔히 개미 개발자들이 출현하고, 혹 시니어 포지션으로 지원했을때는 그에 걸맞는 시니어 개미가 전화해 예우를 갖춰준다. 보통은 짧게 자신의 팀 소개를 먼저 하고, 그 다음엔 “너는 뭐했슴?” 묻는다. 여기서 주의할점은 이 질문의 역할은 지원자의 긴장을 풀어주기 위한것이지, 지원자의 화려한 전적을 듣고싶어 하는것이 아니라는점이다. 신바람나서 과거의 무용담을 끝도없이 늘어놓으면 나중에 시간이 부족해 “I’m sorry, I’m sorry…” 를 반복하다가 전화를 끊게되는 참담함을 겪을수 있으니 소개는 적당한것이 좋다. 또 인터뷰어는 흔히 “우리 팀에 질문 있슴?” 이렇게 묻는데, 코딩 문제 끝나고 나중에 묻겠다고 이야기하는게 낫다. 어차리 이런 잡담은 당락에 영향을 미치지 않고 오직 코딩 테스트가 결과를 결정하기 때문이다.

여러번 인터뷰후 한가지 파악한것은 폰스크리닝용 문제 타입이 있다는 사실이다. 우선 스크리닝 역할은 ‘멋진’ 인간인지를 판가름하는게 아니라 상대가 그저 인간인지를 알아내는데 있기 때문에 어려운 문제를 내선 곤란하다. 그리고 전화와 코딩 사이트의 텍스트 에디터로만 문제를 설명하는 한계때문에 문제 자체가 짧고 이해하기 쉬워야 한다. 아래는 실제로 폰스크리닝에서 받았던 질문들 혹은 같은 유형의 예제이다.

폰스크리닝 단계에서 주로 맞닥뜨리는 코딩문제의 패턴을 보면…
  • Array위에서 한개 이상의 variable을 가지고 놀수 있는가? (maximum-subarray, move-zeroes와 같은 문제)
  • LinkedList, Stack, Queue등을 이해하고 갖고 놀수 있는가?
  • 다양한 엣지 케이스를 잡아낼수 있는가? (Integer overflow, negative numbers 등등). 사실 이건 함정을 파놓고 기다리는 아주 짜증나는 타입의 질문인데 시애틀 M사 출신의 개발자들이 특히 많이 물었다.
  • HashMap이나 Set을 제대로 사용할줄 아는가? 두개 이상의 Map을 차분하게 사용해야 해결할수 있는 문제들이 많았다.
실용적인 질문을 한다고 알려진 몇몇 회사의 경우 (시애틀 A사, 캘리포니아 사과회사등), 코딩에 더해서 몇가지 시스템 지식문제를 내는 경우도 있었다. 예를들어
  • web browser로 google.com에 접속했을때 운영체제, 네트워크에서 벌어지는 모든 일들을 설명해봐
  • 프로그램이 execution될때 무슨 일이 일어나는지 Stack과 heap과 관련해서 설명해봐
  • virtual memory 설명해봐
  • Java가 C에 비해서 왜 느린지 설명해봐

(To be continued…)

스타트업 아이디어 – 좋은 글


Slava Akhmechet 이 쓴 좋은 에세이를 읽고나서 요약해봅니다. 원글은 이곳에서 찾을수 있습니다. http://www.defmacro.org/2015/02/25/startup-ideas.html

——————-

그동안 스타트업을 운영해보니 한가지 깨달아진게 있다. 혁신이 이루어지는 시장은 효율의 법칙이 지배한다는 점이다. 시장에 한개의 스타트업 아이디어가 열리면 이미 그 안에는 여러개의 스타트업들이 경쟁할 가능성이 많다. 그 반대의 경우도 성립하는데 어떤 시장에 스타트업이 없다면 그 시장은 스타트업이 가능할만한 환경이 아니라는 뜻이다.

보통 테크널러지 시장은 승자독식 방식이다. 새로운 문제를 해결한 첫번째 회사의 가치가 후발주자들 모두를 합친것보다 더 큰게 일반적이다 (예를들어 우버). 그래서 이미 어떤 회사가 시장에서 같은 문제를 해결했다면 당신이 그것을 대체하는건 거의 불가능이라고 보면된다.

흔히 알려진바대로 스타트업의 창업자는 자신이나 주변의 사람들이 가지고 있는 문제를 해결하는게 좋다. 그러나 이것은 아이디어를 걸러내는데 있어 효과적이지 않다. 시장은 효율적이기때문에 어떤 문제가 가치있고 해결할만하다면 이미 그 문제는 다른 회사에 의해 해결되었을 것이다. 반대 논리로 당신이 관심있는 어떤 문제가 해결되지 않았다면 구조적으로 그 문제의 해결이 불가능한 이유가 있을것이다. 

<다수의 법칙>으로 운영되는 투자자에겐 창업자들이 자신의 문제를 찾아서 해결하는 방식에 전혀 문제가 없다. 왜냐하면 포트폴리오 회사의 대부분이 실패해도 한두군데에서만 승자독식하는 회사를 건지면 되기 때문이다.

그러나 창업자들에겐 자신의 문제만 쫓는 방식은 효율적이지 않다. <다수의 법칙>이 그들 편은 아니기때문이다. 인생은 스타트업 아이디어를 여러개 시도해볼만큼 길지않다. 그래서 창업자들은 스타트업 아이디어를 좀 더 신중하게 걸러낼 필요가있다.

효율이 지배하는 시장이 이런식으로 스타트업이 나오는것을 막고있다면 그럼 어디에서 스타트업 아이디어를 찾아야할까? 모순같지만 그 해답은 초기단계에 문제를 찾아서 해결하려는 의지를 버리고 경제 환경(economic environment)이 변하는 흐름을 찾아내 이 변화가 여는 기회를 포착하는 것이다.

경제환경은 멈추어있지 않다. 사회의 도덕기준이 변하고 정치적 환경은 점차 자유로움을 더 추구하게된다. 개발도상국의 사람들은 점점 더 여유롭게된다. 기술의 발전은 조금씩 더딘것같지만 어느 시점 임계점을 넘어서면 사회에 의미있는 변화를 일으킨다 (예를들면 AI).

이런 환경의 변화는 스타트업이 일어날수있는 기회를 열어준다. 강조했듯이 기술회사는 승자독식이므로 환경의 변화를 제일 먼저 감지하고 시장에 어느정도 동작하는 솔루션을 제시하는 회사가 길게봤을때 새로운 시장을 지배할 가능성이 많다.

그래서 초기에는 “세상은 어떻게 변하고 있는가? 내가 그 변화에대해 할수있는건 무엇인가” 이 질문에 답을해야한다. 그리고 그 다음엔 관련된 문제를 찾아서 해결하는 방법을 생각해야한다.

스토리텔링

스타트업의 초기에는 수많은 사람과 대화해야한다 – 사용자, 투자자, 분야의 전문가, 초기 직원들, 그리고 기자들까지. 이 사람들의 가장 첫 질문은 “당신 스타트업은 무얼 하는건가요?”일것이고 당신의 스토리를 잘 전달하는게 첫번째 해결해야 할 문제다.

사람들은 스토리텔링에 반응하게끔 되어있다. 모든 스토리텔링엔 공통되는 구조가있다. 여기 픽사에서 사용하는 아주 간단한 스토리텔링의 법칙을 소개한다. 

Once upon a time there was ___. Every day, ___. One day ___. Because of that, ___. Because of that, ___. Until finally ___.

옛날옛날에 ___이 있었습니다. 매일 사람들은, ___ 을 했습니다. 그런데 어느날, ___. 그것때문에 사람들은 ___. 그리고 그것때문에 사람들은 ___. 드디어 사람들은 ___.

이 문장의 첫부분은 이미 정립된 환경이다. 세상은 이렇게 돌아가고있다고 정의하는 부분이다. 다음 부분(그런데 어느날)은 세상에서 일어나는 변화이다. 이런 변화는 당신의 스타트업과는 거의 관련이 없어야한다. 그런 변화는 당신이 스타트업을 하건 말건 일어나는 것들이다. 시장은 효율성을 따라 움직인다고 이미 이야기했다. 당신이 스타트업을 하지 않아도 그 변화에 대응하는 스타트업은 반드시 생겨날것이다. 그럼 당신의 목표는 그 시장에 어느정도 동작하는 제품을 제일 먼저 선보이는것이다. 결국에 그럼 당신이 시장을 장악하게 되어있다.

이 법칙에 맞추어 세상의 변화를 설명한 다음에야 당신의 제품과 회사에 대해 이야기 할수있다. 당신이 대응하는 여부와 상관없이 변화는 일어난다. 그저 당신이 그걸 제일 먼저 알아챘을뿐이다.

위 문장의 마지막 부분은 당신의 회사가 사람들의 삶을 어떻게 바꿀것인가 설명하는 것이다. 당신의 스타트업이 훗날 성장해 시장을 장악하게되면, 그 회사는 이제 다음번 환경의 변화를 일으키는 촉매가 된다. 이 방식으로 당신의 스타트업이 기술 혁신의 사이클을 완성하는것이다.

이게 성공적인 회사들이 스토리를 전달하는 방법이다. 사람들은 내연기관이 돌리는 차를 타왔다. 그러나 배터리 기술은 지속적으로 발전해 100% 전기 자동차를 가능케하는 수준에 이르렀다. 그러나 아직은 비싸기때문에 고급 차종으로 시작할것이다. 배터리기술이 좀 더 싸지면 보급형 차종으로 내려갈것이다. 그리고 결국에는 자동차 시장을 변혁해 길에는 전기차만 달릴것이다.

————————

역자주

사실 폴그레이엄도 스타트업 아이디어 블로그에서 외부에서 주어지는, 그래서 한편으론 창업자들이 어쩔수 없는 환경의 변화를 언급했다 (http://paulgraham.com/startupideas.html). 창업자들은 본인이 갖고있는 문제를 해결해야하고 처음엔 같은 문제를 경험한 소수의 그룹에만 솔루션이 어필한다는 것이다. 즉 구덩이를 좁지만 깊게 파 들어가야한다는 점이다. 그러나 폭발적인 성장이 이루어지려면(구덩이가 옆으로 넓어지려면) 외부적인 환경이 때마침 도와주어야 가능해진다. Slava는 이런 외부적인 변화까지도 예측하는것이 필요하다고 설명한다. 

위의 픽사 스토리텔링 공식에 맞추어 몇개의 성공 사례를 적어보았다. 간결하지만 정말 잘 예측하는 공식이다. 혹시 스타트업 아이디어를 갖고있다면 여러분도 이 공식에 한번 맞추어보는게 어떨까?

테슬라: 옛날옛날에 내연기관 자동차가 있었습니다. 매일 사람들은, 기름을 넣은 자동차를 탔습니다. 그런데 어느날, 배터리 가격이 충분히 싸졌습니다. 그것때문에 사람들은 비싼 전기차를 타기 시작했습니다. 그리고 그것때문에 사람들은 보급형 전기차를 타기 시작했습니다. 드디어 사람들은 전기차만 타기 시작했습니다.

인스타그램: 옛날에 디지털카메라가 있었습니다. 매일 사람들은 사진을 찍어 컴퓨터로 옮겼습니다. 그런데 어느날, 아이폰이 나왔습니다. 그것때문에 사람들은 전화기로 사진을 찍기 시작했습니다. 그리고 그것때문에 사람들은 사진을 인터넷에 공유하기 시작했습니다. 드디어 사람들은 매일 사진을 인터넷에 올리고 있습니다.

우버: 옛날에 택시가 있었습니다. 매일 사람들은 택시를 타고 목적지로 이동했습니다. 그런데 어느날, 스마트폰으로 사람들이 자신의 위치를 알릴수 있게되었습니다. 그것때문에 사람들은 자동차를 자신이 있는곳으로 불렀습니다. 그리고 그것때문에 자동차를 더이상 소유하지 않았습니다. 드디어 사람들은 이동할때 우버만 사용하게되었습니다.

스냅챗, Musical.ly: 옛날에 메신저가 있었습니다. 매일 사람들은 텍스트 메시지와 주위 경관 사진을 서로 교환했습니다. 그런데 어느날, 스마트폰이 좋은 품질의 프런트 카메라를 달았습니다. 그것때문에 사람들은 셀피를 찍기 시작했습니다. 그리고 그것때문에 셀피와 비디오를 교환하게 되었습니다. 드디어 사람들은 텍스트대신 미디어로 대화하게되었습니다. 

리더와 말

올해는 7명의 우주인이 목숨을 잃은 우주 왕복선 챌린져호 폭발 30주년이었다. 1986년 1월 28일 챌린져호의 발사과정은 CNN등 미디어에 생중계되었는데, 발사된지 채 몇분이 지나지 않아 폭발해 그날 미국인들은 우주인 7명의 죽음을 실시간으로 목격해야했다. 우주인 중에는 민간인 신분의 고등학교 선생님이 포함되어 있어서 전국의 학교들에서 아이들이 그날 발사를 시청하고 있었다.

CNN live 영상. 폭발은 1:30초 지점.

생중계로 우주인의 죽음을 목격해야했던 국민에게 레이건대통령은 6시간만에 급히 담화를 발표했다. 그런데 이날 레이건의 담화는 전 국민의 심금을 울리며, 훗날 <20세기 최고의 대통령 연설>로 꼽히는 명문이 되었다. 그날 연설의 일부분을 발췌해본다.

“I want to say something to the schoolchildren of America who were watching the live coverage of the shuttle’s takeoff,” Reagan said. “I know it is hard to understand, but sometimes painful things like this happen. It’s all part of the process of exploration and discovery. It’s all part of taking a chance and expanding man’s horizons. The future doesn’t belong to the fainthearted; it belongs to the brave. The Challenger crew was pulling us into the future, and we’ll continue to follow them.”

“챌린져호의 발사를 지켜보았던 아이들에게 해주고 싶은말이 있습니다. 이런 고통스런 일이 어떻게 일어났는지 이해하기 힘들다는걸 알고 있습니다. 그러나 이런 사고는 탐험과 발견을 하는 과정중 한부분입니다. 인류가 작은 가능성을 가지고 세상을 확장해하는 과정중 한부분입니다. 미래는 두려워하는 사람들에게 열려있지않습니다. 미래는 용감한 이들이 소유하는 것입니다. 챌린져호의 우주인들은 우리를 미래로 한걸음 더 당겨주었습니다. 우리는 그들의 발자취를 따라갈 것입니다.”

그리고 레이건은 현재 모든 미국인들의 뇌리에 남아있을 아름다운 표현으로 연설을 마무리한다.  2차대전중 비행사고로 사망한 미국 시인 John Gillespie Magee의 시에서 인용한 것으로 알려진 문장은 이렇다.

“… waved goodbye and slipped the surly bonds of Earth to touch the face of God.”

“(우주인들은)… 작별인사를 마치고 이 강한 중력의 속박을 벗어나 손을 내밀어 신의 얼굴을 만졌습니다.”

우리에게 이렇게 큰 충격을 준 역사적 사건은 세월호일 것이다. 생중계로 300명이 넘는 학생들의 죽음을 목격해야했던 국민은 몇날 며칠간을 속으로 울어야했다. 하지만 리더 박근혜는 국민 앞으로 나와 아무런 말도 하지않았다. 심각한 트라우마로 고통받는 국민을 향해 그가 했다고 <전해지는>얘기들은 “왜 구하지 못했느냐?”  “경제가 걱정된다”는 단편적인 감정의 표현일 뿐이다. 사고후 34일만에 정치적 압력에 떠밀려 담화를 발표했고 그마저도 <특검>, <처벌>, <부패>등 닳아빠진 표현으로 가득한 수준낮은 연설이었다. 34일을 준비한 말중 유일하게 사람들의 기억에 남아있는 표현은 겨우 이런것이다.

그래서 고심 끝에 해경을 해체하기로 결론을 내렸습니다.

레이건과 그 보좌진은 단 6시간만에 역사에 남을 말을 준비해 미 국민을 위로했다. 박근혜와 (최순실을 위시한) 보좌진은 34일간을 미루어놓은 말로 국민을 절망하게했다. 지난 대선전 부모님과 논쟁하면서 나는 절대 박근혜는 안된다고 했는데 그 이유는 하나 <말을 지독하게 못한다>였다. 말을 못하니 글을 못쓰는것은 말할 필요조차없다. 말을 못하는 것은 그 사람안에 표현할만한 지식이 없고, 그 빈약한 지식마저 정리가 되어있지않기 때문이다.

우리 부모님은 <말만 잘해서 무엇하냐?> 라고 고집을 꺾지 않으셨다. 그것은 틀리다. 리더에겐 말이 전부다. 잘 준비된 연설은 국민의 감정을 흔들어야하고, 즉흥적으로 기자나 시민들과 소통하는 말은 그 안에 통찰(insight)이 담겨있어야 한다. 리더의 머리 안에 아무리 대단한 내용이 담겨져있어도 표현하지 못하면 가치가 없다. 그러나 더 두려운점은 사실 표현하지 못하는 이유가 리더의 머리안에 내용이 없다고 암시하기 때문이다. 권위와 통제로 리더의 말을 따라가던 시대는 우리도 이미 몇십년전에 끝났다. 사람들을 웃게하고, 울게하고, 움직이게 하는 리더의 툴(tool)은 단 하나 <말>이다. 이점에서 박근혜는 한 국가의 리더로서 전혀 자격이 없다.

끝으로 미국의 이번 대선에서 인종주의자 도널드 트럼프를 가장 강력하게 막아냈다고 평가받는 미셸오바마의 <말>을 인용하며 나의 말을 마친다.

“I wake up every morning in a house that was built by slaves, And I watch my daughters, two beautiful, intelligent, black young women, playing with their dogs on the White House lawn.”

“나는 오늘 아침 그 옛날 흑인 노예들이 지었던 집에서 아침을 맞았습니다. 그리고 두 딸들 – 아름답고 지적인 두 흑인 아이들- 이 백악관의 잔디밭에서 강아지와 뛰어노는것을 봅니다.”

미셸오바마의 DNC 연설. 1분 지점부터 하이라이트.

https://twitter.com/sm_park

How you know – 번역과 생각

최근들어 나 자신을 돌아보며 발견한 사실은 더이상 긴 글을 읽지 않는다는 것이다.

지금은 하루중 많은 시간을 트위터의 짧은 글, 페이스북의 사진들, 동영상을 즐기는데 소비한다. 물론 짧게 짧게 전파되는 트위터는 정보를 발견(discovery)하는데 최고의 툴이다. 그러나 그 툴 자체에 중독돼 링크의 목적지가 담고있는 유용한 정보들, 어쩌면 내 삶의 방향을 바꿀지도 모를 그런 내용들은 놓치고 있는지 모른다.

이제 페이스북에 긴 글을 올려서는 반응이 별로 없다는것도 알았다. 나 역시 누군지도 모르는 <페친>이 like한 유머스런 동영상에 손이가지 내 지인이 몇시간동안 생각하고 올렸을 긴 글을 파싱할 엄두는 나지 않는다. 짧은 글, 동영상은 탄산음료같은 짜릿한 맛은 있을지 몰라도 우리의 사고와 행동을 변화시키는 그런 실제적인 영양가치는 없다.

이번에 번역하는 Paul Graham의 How You Know를 읽고나서 이 생각이 더 분명해졌다. 내가 읽는 글들은 비록 얼마후엔 그 내용이 잊혀질지라도 그 글이 남겨놓은 <세상을 바라보는 모델>은 계속해서 나의 행동과 가치관을 결정할 것이다. 140자 트윗들로만 내 머릿속 모델이 채워진다면 10년후에 나는 얼마나 정신없는 사람이 되어있을까?

How You Know 

http://paulgraham.com/know.html

나는 Villehardouin의 연대기를 그동안 두세번은 더 읽은것 같다. 그런데 그 책에서 읽었던 내용을 기억해서 요약하라면 한 페이지를 간신히 채울수 있을까싶다. 내 책장에 꽂혀있는 몇백권의 책들에 시선이 옮아가면 덜컥 불안한 마음이든다. 이렇게 많은 책을 읽고도 기억을 다 못한다면 나는 왜 그리 시간을 낭비했던 것일까?

몇달전에 Constance Reid가 쓴 힐버트의 전기를 읽다가 이렇게 불안한 마음에 답이 될수있는 한 구절을 찾았다. 거기엔 이렇게 적혀있다:

힐버트는 수학강의들이 사실들만 나열하지, 학생들이 문제를 스스로 정의하고 해결하는 훈련이 없는점에 질색했다. 힐버트는 학생들에게 문제를 잘 정의하는것이 이미 절반의 해답이다라고 이야기하곤했다.

이 말은 나 역시 그동안 중요하다고 느꼈던 부분인데 힐버트가 그렇게 이야기했다는걸 읽으니 내 생각에 더 확신이 생겼다.

그런데 난 처음에 어떻게 그런 생각(문제가 절반의 답이다)을 갖게된 걸까? 내 자신의 경험에 더해 그동안 읽었던 글들을 통해서일것이다. 그런데 지금은 그런 글을 읽었던 바로 그 순간은 전혀 기억에 없다. 힐버트가 이렇게 얘기했다는 구절도 결국엔 잊고말것이다. 그러나 힐버트의 예화는 <그 생각이 맞다>는 내 믿음을 증가시켰고, 후에 힐버트의 말은 잊더라도 그 확인된 믿음은 여전히 내 안에 남아있을 것이다.

읽기와 경험은 우리가 세상을 바라보는 모델을 훈련시킨다. 읽었던 바로 그 순간, 정확한 내용은 잊을지라도 읽기가 우리의 모델링에 남겨놓은 영향은 여전히 지속된다. 그래서 마치 우리의 마음은 소스코드는 잃어버렸지만 컴파일된 프로그램과 같다. 우린 마음이 동작하지만 왜 그렇게 움직이는지는 모른다.

Villehardouin 연대기를 읽고나서 내 마음속에 남겨지는것은 정확한 내용이 아니라 십자군, 베니스, 중세문화, 포위전쟁등에 대한 내 마음의 모델이다. 내가 아주 집중해서 읽지 않더라도 책이 내게 끼치는 영향이 결코 작지 않다는점은 분명하다.

나 뿐 아니라 많은 사람들이 읽은것들을 너무 쉽게 잊어버린다고 걱정한다. 그런데 읽기가 실제로 이렇게 우리 생각에 중요한 영향을 미친다는걸 발견하면 모두 나처럼 놀랄것이다.

그리고 때로는 잊는다는것이 어떤면에서 다른 중요한 작용을 한다는것도 알게된다.

예를들어 어떤 경험을 하거나 어떤 책을 읽는다면 그 경험은 바로 그 순간의 두뇌 상태에 따라 컴파일되어 기억에 남는다. 그렇다면 같은 책을 다른 시점에 읽으면 그 책은 다르게 컴파일될것이다. 즉 다시 말해서 좋은 책들은 여러번 읽는것이 가치가 있다는 뜻이다. 그동안 책을 다시 읽을때마다 사실 기분이 좋지는 않았다. 마치 나무를 잘못 잘라서 다시 작업해야 하는 목수의 마음이랄까… 그런데 읽을때마다 다르게 컴파일된다면 어쩌면 <이미 읽었는데>라는건 맞지않는 표현일지도 모른다.

좀더 나아가서 이게 꼭 책에만 국한된게 아닐지도 모른다. 기술이 발달할수록 우리가 가지고있는 과거의 경험을 다시 재생할수 있게될 것이다. 오늘날엔 사람들이 즐기기 위해서, 즉 여행 사진을 다시 본다든지, 아니면 두뇌의 버그를 고치기 위해서 (Stephen Fry가 노래를 못하게 만들었던 어렸을적 트라우마를 기억해낸것처럼) 예전의 경험을 다시 들추어본다. 그러나 경험을 기록하고 다시 재생하는 기술이 발달하면 사람들은 마치 읽은 책을 다시 읽는것처럼 예전의 기억들을 다시 현실에서 재생하고 그것들에서 다시 배우게 될런지도 모른다.

어쩌면 우리는 단순히 기억을 재생하는것뿐 아니라 기억을 다시 정렬하고 고칠수있게 될런지도 모르겠다. 미래엔 그럼 사람들이 세상을 바라보는 모델 자체도 바꿀수 있게될것이다.

https://twitter.com/sm_park