Thoughts2010/07/21 09:59
[이전 글에서 계속...]

우리는 동시성이라는 화두를 두고 한참을 이야기했습니다. 물론 대부분은 동시성을 올바르게 처리하지 못해 겪었던 문제들이었습니다. 별다른 진전을 보지 못하자, 유식이 제안했습니다.

“어쩌면 우리가 동시성이라는 단어를 너무 거창하게 받아들이고 있는 것은 아닌지 모르겠어요. 좀 다른 각도에서 생각해 보면 어떨까요?”

“다른 각도라면...?”

“하나의 메시지가 어디로 와서 어디로 가는지에 한 번 초점을 맞춰서 생각해 보죠.”

“메시지라면 하나의 관리 명령 말인가요?”

“네. 장비에 전송해야 할 하나의 관리 명령. 하지만 그것 말고도 많습니다. 장비가 관리 소프트웨어에 비동기적으로 전송하는 메시지, 그리고 장비가 명령 실행 결과로 전송하는 응답 메시지 등등. 사실 우리가 생각하는 동시성이라는 것은 ‘동시 다발적으로 관리 소프트웨어에 쏟아지는 메시지’를 의미하는 것이 아니었나요?”

“그렇긴 하죠.”

유식은 뭔가 깨달았다는 표정으로 그림을 그리기 시작했습니다.

“자. 여기 메시지가 있습니다. 우선은 관리 명령이라고 해 보죠.”

그가 그린 것은 하나의 원이었습니다.

“이 메시지를 만들어 내는 것은 아마도 GUI일 것입니다. 이 메시지가 최초로 가 닿게 되는 곳은 어느 부분일까요?”

“GUI와의 연결을 관리하는 연결 관리자가 되겠죠. 3-tier 식으로 이야기하면 First Tier?"

"아마 그럴 겁니다. 그럼 그 다음 단계로 통과하게 되는 것은 어디죠?“

“뭘 자꾸 나한테 물어 잘 알면서. 아마도 Business Logic이 실행되는 Middle Tier가 되겠죠. MVC 식으로 이야기하면 Controller쯤 되겠군요.”

“그렇습니다. 그럼 이 메시지는 처리 결과로 전송 레이어를 거쳐 장비로 전송될 겁니다. DBMS에 뭔가를 기록할 일이 있다면 기록하면 될 거구요.”

“그렇다고 보면 되겠죠.”

“그렇다면 이 메시지가 통과하는 지점들을 따라 가다 보면 자연스럽게 동시성 문제가 불거지는 부분을 발견할 수 있게 되지 않을까요?”

“부수적으로는 시스템 구조까지도 어느 정도는 밝혀낼 수 있겠네.”

“그렇죠.”

“이런 걸 MDD(Message-Driven Development)라고 불러도 되려나?”

내 말에 그가 껄껄 웃었습니다.

“뭔가 이름을 붙여야 직성이 풀리신다면 그래도 좋겠죠.”

“결국 메시지를 통해 시스템 컴포넌트를 식별한다는 거니까, 그런 용어를 써도 되지 않을까 싶긴 한데... 아무튼 그건 그냥 농담이었고. 그럼 작업을 해 볼까요?”

그가 그리기 시작한 그림은 점점 복잡해졌습니다. 우리는 그 복잡한 그림을 단순화된 표기법으로 바꾸는 방법은 없을지 궁리하기 시작했습니다. 병행성이 문제가 되기 시작하는 부분을 표시할 수 있으면서도, 시스템 전체의 구조를 표시하는 다이어그램과 조화롭게 어울릴 수 있는 그런 표기법을요. 그 작업은 거의 사흘 동안 이어졌습니다.

사흘 동안, 우리는 오직 그 문제만을 생각했습니다. 사실 경험이 많은 개발자라면 별다른 고민 없이도 해결할 수 있는 문제였을지도 모르겠습니다. 하지만 그 당시 우리에게는 그 문제가 세상 어떤 문제보다도 어렵고 중요했습니다.

“이러다 UML처럼 이런 저런 기호들로 복잡해지는 건 아닌가 모르겠어요.”

그가 말했습니다. 나도 공감했습니다. 범용적으로 쓰일 새로운 언어 체계를 만드는 것은 우리의 애초 목적과는 거리가 멀었으니까요. 그도, 그리고 나도, 자리에 앉아 뭔가를 긁적거리는 시간이 늘었습니다. 머리를 긁적거리는 시간도 덩달아 늘었죠. 그리고 사흘 뒤에, 우리는 다시 마주 앉아 그다지 많은 말을 하지 않고도 하나의 그림을 그릴 수 있었습니다.

 “이 정도가 우리 한계겠죠?”

유식이 말했습니다. 나도 고개를 끄덕거렸습니다. 우리의 평범함이 그렇게 한심하게 느껴진 적은 없었습니다.

“적어도 한 가지는 확실해 졌네요. 우리는 새로운 체계를 만들어 낼 능력은 없는 사람들이라는 거.”

내가 말하자 그는 고개를 저었습니다.

“뭐 설마 그것 뿐이려구요. 아마 같은 생각이시겠지만, 이 그림을 통해 얻은 소득도 많잖습니까? 가령 이 플로우를 역으로 타도록 메시지 방향을 바꾸어야 할 때에는 무조건 새로운 쓰레드를 만들어야 하고, 사용자가 정의한 Business Logic으로 메시지를 튕겨 줘야 할 때도 새로운 쓰레드를 만들어야 한다는 뭐 그런 사소한 사실도 이 그림에 드러나잖아요. 그리고 그런 깨달음을 적을 수 있는 간단한 표기법을 얻었다는 것, 그 정도만 해도 꽤 많이 한 거 아닐까요?”

그의 말을 듣자 위안이 되었습니다. 적어도 우리가 쓸 데 없는 일을 하면서 사흘을 보낸 것은 아니었으니까요.

우리는 그림을 화이트보드에 옮기고 한참을 바라보았습니다. 그리고는 사진을 찍었습니다. 선들이 약간은 어지럽게 그어져 있었고, 식별된 시스템 컴포넌트의 모습이 두서없긴 했습니다만 적어도 우리는 올림푸스라는 신전을 지을 주춧돌은 놓은 셈이었습니다. 모두가 기껍게 보아주기를 기다리며, 우리는 사진 파일을 컴퓨터에 옮기고 메일에 첨부하여 ‘보내기’ 버튼을 눌렀습니다. 그리고는 서로를 바라보며, 멋쩍게 웃었습니다.

“갑시다. 술이나 한잔 하죠.”

3.2 레르나의 히드라

그 뒤로 참 많은 메일이 오고갔습니다. 평생 보낼 메일을 한 주간 몰아 보낸 것처럼 느껴질 지경이었으니까요. 덕분에 OLYMPUS의 구조는 빠르게 자리를 잡았습니다.

마련된 설계안을 회람하고 변경하고 구현 계획을 수립했습니다. 프로젝트 일정이 빠듯했기 때문에 가능한 한 빨리 구현에 착수해야 했습니다. 허동수는 일일 빌드 서버를 만들고 테스트 계획을 만드느라 분주했고, 박팀장은 갑과의 잦은 회의와 의견 조율로 자리를 비우기 일쑤였습니다. 저와 유식은 실제 코드의 뼈대를 만들어 나가기 시작했고, 남기수는 장비와 통신하는 프로토콜을 독자적으로 구현해 나가기 시작했습니다. 이선화는 평소대로 하던 일을 했구요.

그런데 저와 유식은 남기수의 독자 행동이 사실은 좀 불만이었습니다. 그가 코딩을 잘 하고 프로토콜 구현 경험이 풍부하다는 것은 알고 있었지만, 협의를 할 때에도 자기 일 생각에 빠져 말문을 잘 열지 않는 모습이 마뜩찮았던 것이죠. 그의 그런 태도 덕에, 우리는 그가 만들어 낼 라이브러리와 그 API를 사용하는 코드를 대체 어떻게 작성해야 할지 갈피를 잡지 못하고 있었습니다.

그러던 어느 날이었습니다. 유식과 그 문제로 갑론을박하고 있는 와중에 안이태 팀장이 찾아왔습니다.

“박팀장 어디 가셨나?”

“외근 나가셨는데요. 협의하실 게 있으셔서요.”

그렇게 대답하자 그는 잠시 망설이다 물었습니다.

“혼자 가셨나?”

“아뇨. 남기수씨랑 같이 나갔습니다.”

“... 그래?”

순간 그의 표정이 어두워졌습니다. 잠시 나를 물끄러미 바라보던 그는, 물었습니다.

“바쁜가보네?”

“네. 문제가 좀 있어서요.”

“어떤 문제지?”

그러자 유식이 ‘대체 당신이 그걸 왜 궁금해 하는 건데’ 하는 표정으로 그를 바라보더니, 대답했습니다.

“뭐... 사소한 문젭니다. 곧 해결 되겠죠.”

그러자 안팀장은 고개를 끄덕이며 가 버렸습니다. 그러자 유식이 나에게 묻더군요.

“안팀장님 박팀장님한테 너무 관심이 많으신 것 같지 않아요?”

그날 회식 자리에서 무슨 일이 있었는지 알고 있던 저로서는, 뜨끔한 질문이었습니다.

“글쎄요. 뭐 같은 회사에 있고 직위도 같으니까, 관심 갖는 게 당연하지 않을까요?”

모르는 척 눙치긴 했는데, 그래도 찜찜하긴 하더군요. 마침 그때 외근 나갔던 남기수씨와 팀장님이 돌아오는 소리가 들렸습니다.

“잘 다녀오셨어요?”

역시 맨 먼저 인사하는 것은 선화였습니다. 그러자 남기수가 대답했습니다.

“네. 별 탈 없이 잘 끝났어요. 별일 없었죠?”

“아까 안팀장님이 박팀장님 찾으시던데요?”

선화의 말에 박팀장의 표정이 눈에 띄게 어두워졌습니다. 그러더니 지갑을 챙겨 밖으로 나가시더군요.

“저 커피 한 잔만 사가지고 올게요. 한 시간 뒤에 미팅 있습니다, 잊지 마세요.”

밖으로 향하는 표정은 다시 밝아져 있었습니다만, 어쩐지 느낌이 좋지 않았습니다. 따라 나서 볼까 생각했지만, 어쩐지 그래서는 안 될 것 같았습니다. 하지만 사람이 하는 짓이 어디 머리로만 올바르게 다스려 지던가요. 저는 조심스럽게 박팀장의 뒤를 밟았습니다. 예감대로, 박팀장이 향하는 곳은 커피샾이 아니었습니다. 어딘가에 전화를 하던 그녀는, 전화기를 주머니에 넣고 잠시 한숨을 쉬더니 옥상쪽 계단으로 향하더군요. 저는 일부러 한 층 정도 간격을 두고 그녀의 구두소리에 귀를 기울였습니다.

일이 분이나 지났을까, 터벅거리는 슬리퍼 소리가 들리더니 멈췄습니다. 먼저 말을 꺼낸 것은 박팀장이었습니다.

 "당신, 내가 하는 일에 그만 신경 써줬으면 좋겠는데.”

뒤이어 들리는 목소리는, 역시 안팀장의 목소리였습니다.

“그런데 그게 내 마음대로 잘 되지 않아서 말이지.”

평소의 당당하던 목소리가 아니었습니다. 어쩐지 한 풀 죽어 있는 어조였죠.

“우리가 한때 부부의 연을 맺고 살았던 건 사실이지만, 서로 실수였다는 것 인정 했고, 같이 살기에는 너무 다른 사람들이라는 것도 인정 했잖아. 내가 당신 회사에 입사한 건 당신과 같이 일하고 싶어서가 아니었다는 것도 알고 있지 않아? 우리 헤어질 때 앞으로 어떻게 살 것인지에 대해서는 완전히 무관심해 지기로 했던 것 같은데.”

“그 때는 내가 쿨하게 굴었던 것 같은데, 지금은 당신이 쿨하게 구는 군.”

그녀와 그 사이에 무슨 일이 있었는지 확실히 알 수는 없었지만, 적어도 그녀와 그가 부부였다는 것. 그리고 지금은 헤어진 사이라는 것쯤은 분명해 지더군요. 충격이었습니다. 안팀장이 버젓이 버티고 있는 회사에 떳떳이 시험을 보고 들어와 팀장 자리까지 꿰차게 된 그녀의 의중이 무엇인지가 의아하긴 했지만 말입니다.

그 뒤로 그와 그녀는 한 십오 분 간, 그렇게 낮고 쿨한 말투로 이야기를 나눴습니다. 안팀장은 다시 시작하고 싶어 하는 눈치였습니다만, 그녀는 아니었습니다.

“우리는 이미 끝난 사이야. 다시 시작해도 다시 끝나게 될 거고.”

“... 남기수와는 어떤 사이지? 둘이 자주 붙어 다니던 데.”

머뭇거리다 건넨 그의 질문에 박팀장은 코웃음을 치며 대답했습니다.

“팀장과 팀원 사이야. 그 이상도 이하도 아니고. 나는 당신과 그 어린 나이에 헤어진 이후로 단 한 번도 누군가를 만나야겠다는 생각을 해 본 적이 없어요. 남자를 믿지 못하게 된 것은 물론이고.”

그리고 박팀장은 몸을 돌려 계단을 내려오기 시작했습니다. 저는 황급히 반대 방향으로 뛰었습니다. 발소리를 들키면 곤란하다는 생각에 발뒤꿈치를 최대한 들고서 말이죠. 복도에 아무도 없었기 망정이지, 누가 보았다면 저 인간이 왜 저렇게 엉거주춤한 자세로 뛰고 있나, 아마 꽤 궁금해 했을 겁니다.

자리로 돌아온 저는 최대한 숨을 고르며 붉어진 낯을 식히려 애썼습니다. 그러자 유식이 물었습니다.

“뭔 일 있어요? 왜 그렇게 숨을 헐떡대.”

“아... 별일 아닙니다.”

“별일 아니면 여기 이 별 일 좀 같이 보시죠.”

“뭔데요?”

그의 자리로 가자 그가 띄워놓은 몇 개의 터미널이 보였습니다. 유식은 vi 마니아라, Java 프로그래밍을 할 때를 빼고는 좀처럼 IDE 같은 통합 개발 환경을 사용하지 않았습니다.

“지난주에 2,000줄 정도 코딩을 했는데요. 오늘 테스트를 하려고 돌려 보니까 괴상한 오류들이 떠서요.”

“가만있자... pure virtual method called라는 오류가 뜨는군요? 이건 저도 예전에 한번 겪은 오류 같은 데요.”

“그래요?”

“네. 간단히 설명하자면 상위 클래스 객체가 미처 초기화되기 전에 하위 클래스 객체의 가상 함수(virtual method)가 호출되면 생기는 오류죠. 그건 아마 구글 신전에 가서 신탁을 받으셨으면 충분히 해결하실 수 있으셨을 텐데.”

그러자 그가 머리를 긁적거리며 말했습니다.

“그런데 오류가 그것뿐만이 아니라 서요.”

그랬습니다. 한 가지 오류를 수정하고도 화면에는 열 몇 가지 정도의 난해한 버그들이 보고되고 있었습니다. 컴파일 시간에 잡을 수 있는 오류였으면 덜 심각했을 터인데, 하필이면 프로그램 실행 도중에 나타나는 논리 오류였던 것이 문제였죠.

“그럴싸한데?”

갑자기 허동수의 걸걸한 목소리가 들려, 우리 모두는 화들짝 놀랬습니다.

“아니 언제 왔어요?”

유식이 묻자 그가 씨익 웃으며 말했습니다.

“재미있는 이야기들을 하시기에 궁금해서... 뭐가 문젠지 같이 좀 봐도 대겠습니꺼?”

그는 심심하던 차에 잘됐다, 하는 표정이었습니다. 그리고는 키보드를 빼앗더니, 익숙한 손놀림으로 vi를 구동시켜 코드들을 훑어보았습니다. 유식은 부끄러운 듯 얼굴을 붉히고 있었구요.

“테스트 코드가 없네예.”

“네, 아직 못 만들었습니다.”

뒤통수에 습진이라도 걸린 사람 마냥, 유식은 연신 머릴 긁적거렸습니다.

“자아. 그러면 기계적으로 클래스 하나 마다 하나씩 테스트 코드를 만들어 보입시더. 문제가 뭔지 잘 모를 때는 그게 제일이라예.”

“시간 너무 많이 걸리지 않을까요?”

내가 묻자 그가 대체 무슨 말이냐는 표정으로 나를 빤히 쳐다 보더니, 말을 이었습니다.

“이런 식으로 디버깅 하면 더 시간 많이 걸리는 거, 안 겪어 보셨습니꺼? 하긴 머, 테스트 코드를 작성 안해본 사람은 잘 모르제...”

그는 더 말 섞기 싫다는 표정으로 휠체어를 움직여 나와 유식 사이를 빠져 나가면서 한 마디 툭 던졌습니다.

“당장 CPPUNIT부터 설치하이소. 그리고 테스트 코드 다 작성한 다음에, 검사 맡으이소. 적어도 클래스 별로 하나의 테스트 프로그램은 있어야 합니더. 제가 시키는 대로 안 하면 팀장님한테 꼰지를 테니까 하시는 게 좋을 겁니더.”

그래서 유식은 시스템에 CPPUNIT을 설치했고, 소위 단위 테스트(unit test)라 불리는 코드들을 하나씩 하나씩 추가하기 시작했습니다. 2,000라인으로 불어나 있는 클래스들에 테스트 코드를 짜 넣는 것은 그다지 만만한 일은 아니었습니다. 하지만 유식은 별다른 불평 없이 그 일을 해 냈습니다. 그리고 매일 매일, 자신이 작성한 테스트 코드를 허동수에게 보여 주면서 의견을 구했습니다.

“잘 되어 가요?”

사흘 째 되는 날, 내가 유식에게 물었습니다.

“보시겠어요?”

유식이 겸연쩍은 표정으로 액셀 그래프를 보여주었습니다.

“무슨 차트인가요?”

“버그가 어떻게 줄어들었는지 보여주는 그래프예요.”

그의 쑥스러운 표정에서 짐작했던 대로, 버그는 많이 줄어들어 있었습니다. 아니, 거의 없어졌다고 봐도 과언이 아니었죠.

“테스트 케이스가 늘수록, 버그가 줄어들더군요. 결국 문제의 원인은 테스트 없이 코드부터 작성했던 탓이었던 거죠.”

단순한 결론이었습니다. 저는 문득, 레르나의 히드라 이야기를 떠올렸습니다. 헤라클레스는 에우리스테우스의 명을 받고 히드라를 죽이러 갔다가 난감함에 빠집니다. 히드라의 목은 50개였는데, 그 목을 다 베어야 히드라를 죽일 수 있었죠. 그런데 목을 하나 벨 때 마다, 그 자리에서 새로운 목이 두 개씩 돋아나는 겁니다. 결국 히드라의 목은 100개까지 늘어나게 되고 말죠. 전해지기로는 이올라오스의 도움으로 진짜 목을 찾아 벨 수 있었던 덕에 결국 히드라를 죽일 수 있었다고도 합니다만, 테세우스가 헤라클레스를 도와 목이 떨어져 나간 자리를 불로 지진 덕에 결국 100개의 머리를 다 자를 수 있었다는 말도 있습니다.

저는 테스트 케이스가 어쩐지 테세우스가 들고 있었을 횃불 같다는 생각을 했습니다. 초반에 해결하지 못한 버그는, 나중에 더 많은 버그로 불어나 돌아오는 경우가 많았으니까요.

“그런데 한편으로는 걱정이 좀 됩니다.”

유식이 말했습니다.

“뭐가요?”

“이 테스트 케이스들을 어떻게 유지하죠?”

“유지하다뇨? 내버려 둔다고 코드가 썩는 것도 아니잖아요.”

“지금 제가 작성한 코드가 확정된 코드가 아니잖습니까. 나중에 언제든 바뀔 수 있는데 그러면 테스트 코드도 그에 맞게 바꿔야 하는데, 지금 테스트 코드 양이 거의 실제 코드의 절반 수준이거든요.”

생각해 보지 못한 이슈였습니다. 그 때 허동수가 휠체어를 밀고 자리로 다가왔습니다.

“테스트 과정에서 구조가 좀 개선되지는 않았습니꺼?”

“음... 그랬죠. 구조적인 문제 때문에 생긴 버그도 있었으니까요.”

“그렇다면 코드를 나중에 수정할 확률도 떨어졌다고 봐야 하지 않겠습니꺼?”

“그러려나요?”

모두 잠깐 동안 입을 다물었습니다. 그의 말에 일리가 있었습니다. 테스트 코드를 작성하는 동안 유식의 코드는 분명 개선되었을 것이고, 테스트 코드에는 유식이 작성한 클래스들의 사용법이 녹아 들어가 있을 터이니, 나중에 코드 전반을 리팩터링하게 될 가능성은 떨어졌다고 보는 것이 타당했습니다.

“그래도 걱정되시긴 하지예?”

그가 물었습니다. 유식은 고개를 끄덕였습니다.

“그건 그때 가서 생각하입시더. 맘에는 안 드시겠지만...”

유식은 잠시 모두를 물끄러미 쳐다보더니, 말했습니다.

“불안은 영혼을 잠식하는 법이니까요.”

허동수는 잠시 벙 찐 표정으로 그를 바라보다가 소리를 꽥 질렀습니다.

“그건 또 대체 무슨 소린교?”

3.3 케리네이아의 암사슴

흐르는 강물이 바위를 만나면 잠시 쉬었다 돌아가듯 키보드를 만지는 우리의 손길도 잦은 회의에 멈출 때가 많았습니다만, 나름대로는 별 탈 없이 흘러갔습니다. 모든 프로그래머들이 바라는 하루가 있다면 이렇겠지요. 어떤 전화도 오지 않고, 어떤 메일도 오지 않으며, 어떤 손님도 오지 않는 평온한 하루. 마주해야 할 것은 오직 키보드와 마우스 그리고 모니터뿐이고, 마음에는 평화와 코드 말고는 다른 것이 없으며 마치 신의 은혜가 강림이라도 한 것인 양 컴파일러와 런타임 시스템은 문법 오류 말고는 다른 아무 것도 말하지 않는, 그런 날 말입니다.

하지만 제우스가 헤라와의 약속을 밥 먹듯이 어기는 것과 마찬가지로 여 선임은 때로 전화를 걸어 잊었던 무엇이 갑자기 생각나기라도 한 듯 아무렇지도 않게 새로운 요구사항을 이야기했고, 우리는 그 요구사항에 부응하기 위해 코드를 변경하고 또 변경해야 했습니다. 그리고 늦도록 가실 줄 모르는 9월의 더위 덕에, 우리의 야근과 냉커피는 풀가동중인 에어컨이 내뱉는 소음에도 아랑곳없이, 너무나 뜨뜻미지근했습니다.

그러던 어느 날이었습니다. 갑자기 남기수가 자리에서 일어나 소리를 질렀습니다.

“으아악!”

제일 먼저 그의 자리로 달려간 것은 유식이었습니다. 뒤이어 박팀장, 이선화, 그리고 허동수가 그의 자리로 달려갔습니다. 저녁 식사 후 밀려오는 졸음에 꾸벅 꾸벅 졸고 있던 제가 제일 마지막이었죠.

“무슨 일이죠?”

박팀장이 물었습니다.

“저, 저기...”

남기수는 모니터를 가리켰습니다. 그 순간, 모두들 웃음을 터뜨리지 않을 수 없었습니다. 그가 가리킨 곳에는, 큼지막한 나방 한 마리가 붙어 있었습니다.

”뭐꼬. 벌레 한 마리 때문에 이 난리를 피웠단 말인교?“

우리 모두에게는 벌레 한 마리일 뿐이었습니다만, 그에게는 아니었던 모양입니다. 큰 키에 어울리지 않게, 그는 사색이 되어 있었습니다.

“하긴, 벌레를 두려워하는 건 모든 프로그래머의 본성이지예.”

동수의 말에 선화가 깔깔대며 웃었습니다.

“그럼 동수씨도 무서워하는 벌레가 있으세요?”

“저는 다리 많은 건 다 싫어합니더. 지네, 돈벌레, 기타등등, 기타등등...”

그 말에 선화가 고개를 갸웃거렸습니다.

“돈벌레가 뭐에요?”

“머라카드라? 표준말로는 그리마라 하는 거 같더만... 하도 돈벌레라 캐싸서 글마 본 날에는 복권 한 장씩 삽니더. 하지만, 좋아는 안합니더.”

“그렇구나...”

그리고 선화의 뇌까림이 끝나기 무섭게, 나방은 휘릭, 하고 어디론가 날아가 버렸습니다. 그러자 허동수가 또 나직이 읊었습니다.

“자고로, 달을 가리키면 달을 봐야지 손가락은 뭐할라꼬 보노, 라고 했니더.”

그러자 남기수가 대체 뭔 소리냐는 표정으로 물었습니다.

“달을 보다뇨?”

“저기 터미널을 보이소. 프로세스가 죽었다, 하고 떡 하니 찍혀 있다 아인교?”

아닌 게 아니라 그랬습니다. 나방이 날아간 그 자리에 남은 것은, 실행 도중에 죽어버린 프로세스였습니다. 그 화면을 보더니 남기수가 머리를 긁적거렸습니다.

“그러게요. 장비와 통신하는 부분은 거의 완성했고 테스트도 다 되었는데, OLYMPUS쪽과 통신하는 테스트를 하고 있는 데 자꾸 죽습니다. 원인이 뭔지는 찾고 있는 데 아직 잘 모르겠어요.”

그 말을 듣자 박팀장이 난감한 표정으로 턱을 긁었습니다.

“이러면 곤란한데... 여 선임이 아까 전화를 했는데, 일주일 뒤에 지금까지 완성된 시스템을 좀 구경할 수 있느냐고 전화를 해 왔어요. 허동수씨. GUI쪽은 어떻게 되어 가고 있나요?”

“일단 용역을 맡은 친구들이 GUI 코드를 들고 왔는데예. 유식씨가 아래쪽에 가짜 코드를 붙여서 일단 시험은 가능하게 해놨거든예. 그러니까 남기수씨가 돌아가는 코드를 주기만 하면 거기에 붙여서 어떻게든 돌려는 볼 수 있는 상태고, 시험 결과도 나쁘지 않아서 몇 가지 손만 좀 더 보믄 됩니더. 버그 리스트는 엑셀로 만들어서 어제 팀장님께 보고 드린 대로고예.”

허동수의 일처리는 매끄럽고 빈틈이 없어 보였습니다. 역시 테스터답다고 해야 할까요. 문득 남기수의 얼굴에 당혹스러움이 비쳤습니다. 저로서는, 그의 심정을 알 것 같았습니다. 자신의 코드에서 생긴 문제를 남에게 보이기 싫다는 프로그래머 특유의 자존심이 그에게는 유독 강했으니까요. 우리 모두 그가 어떻게 일하는지 알지 못했고, 우리는 그가 보여주는 완성된 코드나 문서를 보고 그가 얼마나 빨리 일하는지, 그리고 얼마나 빈틈없이 일하는지 추측만 할 수 있을 뿐이었습니다. 그런데 불쑥 나타난 나방 한 마리 때문에, 그의 자존심이 무너져 내린 것이죠. 거기다 허동수와 은연중에 비교당하기 까지 했고요. 아, 우연의 힘이란!

“일주일 안에 OLYMPUS에 붙여서 돌릴 수 있겠어요?”

박팀장의 질문에 남기수는 표정을 가다듬었습니다. 한껏 싸늘해져 있었죠.

“그렇게 하겠습니다.”

그 순간 저는 직감했습니다. 그가 잠을 줄여서라도 어떻게든 문제를 해결하리라는 사실을요. 그리고 지금까지 해 왔던 그대로라면, 우리는 그가 어떻게 문제를 해결했는지 아마 영원히 알 수 없을 것이었습니다.

“남기수씨. 저 좀 잠깐 볼까요?”

박팀장이 남기수의 의자를 책상으로 밀어 넣고는 그의 팔을 잡아끌었습니다. 남기수는 ‘어어’ 하더니 저 버그는 어떻게 하고... 하는 표정으로 끌려갔죠.

저는 개발실 한쪽 벽으로 갔습니다. 거기에는 매주 누가 무슨 일을 했는지가 적혀 있었습니다. 그 아래에는 각자의 이름표가 붙어 있는 매직 팬이 서로 다른 색으로 놓여 있었고, 모두들 자기 일을 해치울 때 마다 해야 할 일 목록에 X표를 했습니다. 해야 할 일을 적는 것은 팀장과 팀원들이 상의해서 결정했습니다. 그러다 보니 그 목록은 꼭 가로로 누운 막대그래프 진도표처럼 변해 갔습니다.

그 진도표의 꼴찌를 달리는 사람은 남기수였습니다. 그의 칸에 할 일을 적는 것도 그였고 X 표를 하는 것도 그였는데, 그는 도통 팀장과 상의도 하지 않았고 할 일을 쪼개어 적지도 않았거든요. 그러니 진도를 확인할 방법이 없었습니다. 가끔 팀장이 내가 선 바로 그 자리에서 생각에 잠겨 있는 것을 보곤 했는데, 그녀도 아마 같은 것을 느꼈을 겁니다.

나는 커피를 타 들고 휴게실로 걸음을 옮겼습니다. 회의실에 앉아 이야기를 나누고 있는 박팀장과 남기수가 보였습니다. 박팀장의 손이 테이블 위에 깍지를 끼고 있는 남기수의 손목 위에 놓여 있었습니다. 순간 그런 생각이 들었습니다. 저것은 친밀감의 표시일까요, 아니면 단순히 당신의 심정에 공감한다는 뜻을 전하기 위한 여성 특유의 소통 방법일까요? 안팀장에게 던진 말을 되씹어보면 아마 후자일 겁니다. 하지만 저는 왜인지 그것이 남기수에 대한 박팀장의 호감의 표현이었으면 좋겠다는 생각이 들었습니다.

왜냐고요? 글쎄요. 왜 그런 생각을 했는지는 잘 모르겠습니다. 어쩌면 그녀의 포용력과 남기수의 외로운 성격이 잘 어울릴 거라고 느꼈는지도 모르죠. 아무려나, 박팀장이 누구에게나 호감을 주는 미인이긴 했지만, 어차피 제 일은 아니었습니다. 무심함이 저와 잘 어울리는 건 아니었지만, 그게 저에게도 좋았습니다.

저는 휴게실로 가야한다는 사실도 잊고 계속 복도를 걸었습니다. 복도 끝에는 창이 나 있었습니다. 창밖으로 물결처럼 넘실대는 차량의 흐름을 십분 쯤 바라본 뒤, 저는 다시 자리로 돌아와 모니터를 쳐다보았습니다. 새로운 메일이 한 통 와 있더군요.

- 대수씨. 회의실에서 기다리고 있을 테니 이 메일 보시는 대로 와 주세요.

박팀장의 메일이었습니다. 저는 바로 회의실로 향했습니다. 남기수는 이미 자리를 떴고, 박팀장이 제 몫의 커피까지 타 놓고 저를 기다리고 있었습니다.

“아... 커피 벌써 마셨는데.”

“괜찮아요. 제가 두 잔 다 마시죠. 커피 중독이거든요. 아무리 마셔도 끄떡없이 잠이 들 정도로.”

“그런데 무슨 일이신지?”

박팀장은 머그컵에 제 몫의 커피까지 붓더니 이야기를 시작했습니다.

“남기수씨가 여러 모로 팀원들과 잘 어울리지 못하고 있다는 사실은 대수씨도 알고 계시죠?”

“네. 알고 있습니다.”

“그래서 말인데, 대수씨가 기수씨와 공동으로 코딩 작업을 해 주셨으면 해요.”

“네?”

세상에 불가능한 일은 없겠습니다만, 불가능에 가까운 일은 꽤 많습니다. 코끼리를 냉장고에 집어넣는 것이나 일주일 동안 잠을 자지 않는 것, 그리고 소금을 설탕으로 바꾸는 것 등등이 그 좋은 예죠. 남기수와 공동으로 코딩을 하는 것도, 저에게는 어쩐지 바로 그 ‘불가능에 가까운 일’처럼 보였습니다. 같이 점심을 먹으러 가지 않으면 자리에 있는지 없는지 조차 알기 힘든 사내와 공동 작업이라니요?

“이 작업이 대수씨가 맡고 있는 일을 지연시킬 수 있을 것 같아, 두 주 이상의 여유를 더 드리던지, 아니면 유식씨에게 그 중 일부를 인계하려고 해요.”

“네에.”

박팀장의 뜻은 이미 확고해 보였습니다.

“그렇다면, 두주 정도만 시간을 더 주시죠. 유식씨도 이미 하고 있는 일이 많아서, 제 일 까지 넘기긴 그렇고요. 가능한 한 제가 두 업무를 다 보도록 하겠습니다.”

짧은 회의를 끝내고 남기수의 자리로 가 보니, 그는 굳은 얼굴로 턱을 괴고 앉아 키보드의 커서 키를 또각또각 매만지고 있었습니다.

“아, 오셨어요?”

저를 맞는 표정도 그다지 달갑게 보이진 않았습니다. 제가 먼저 운을 뗐습니다.

“박팀장님께 이야기는 들으셨죠? 저도 갑자기 떨어진 업무라 좀 당황스럽긴 합니다만, 기왕에 같이 작업하기로 했으니 잘 해 봅시다. 그런데 어떻게 공동작업을 하면 좋을까요?”

“그래서 제가 키보드를 하나 더 준비해서 연결해 두었습니다.”

그가 모니터 옆에 세워 둔 무선 키보드를 책상 위로 옮기더니, 저에게 같이 앉을 수 있도록 의자를 권했습니다. 바로 코드부터 들여다보자는 뜻인 듯 했습니다. 그래서 우리는 모니터 하나를 사이에 두고 별다른 말도 없이 코드를 살폈습니다. 프로젝트 빌드에 쓰이는 Makefile을 보았고, 코드 리스트를 보았고, 그가 작성해 둔 디버그 매크로를 보았고, 그가 만들어 둔 개발 문서를 함께 보았습니다. 설명이 필요할 때는 그에게 청했고, 별다른 설명이 필요 없을 때에는 제가 마우스를 움직여 필요한 파일을 열었습니다. 입을 열지 않는 그의 표정은 어쩐지 피곤해 보였습니다. 이렇게 해서 과연 문제가 해결될 수 있을까, 의아해 하는 듯도 싶었습니다.

그렇게 코드를 살피고 분석하기를 사흘이 지나자 그가 만들어 놓은 30개 정도의 헤더 파일과 소스 파일을 모두 일별할 수 있었습니다.

“그럼 이제 버그를 보여드릴까요?”

그가 말했습니다. 고개를 끄덕이자 그가 터미널 몇 개를 동시에 열어 프로세스를 실행시켰습니다. 화면에는 온갖 디버깅 정보들이 출력되기 시작했고, 그는 다시 하나의 터미널을 열어 그 프로세스들에 메시지를 쏘았습니다. 그러자 1분쯤 뒤에, 프로세스 중 하나가 뻗었습니다. SIGSEGV 시그널을 받았다는 메시지와 함께요.

“메모리 문제일 가능성이 제일 크군요.”

“그렇습니다. 그래서...”

그는 자신이 만든 Ruby 스크립트를 하나 보여 주었습니다. 그리고 설명을 시작했습니다.

“한 번 해제된 메모리를 두 번 해제하고 있지는 않은 것인지, 혹시 해제되지 않은 메모리가 남아 있지는 않은 것인지 살펴보려고 모든 new, delete 연산을 매크로로 감쌌습니다. new와 delete가 실행될 때 마다, 할당받은 메모리의 주소와 반환되는 메모리의 주소를 출력하죠. 그리고 Ruby 스크립트를 돌려서 한번 반환된 메모리가 또 다시 반환되는 일은 없는지 검사했습니다. 스크립트 자체는 버그가 없다는 것을 확인한 상태입니다.”

그는 실행 결과로 남은 로그에 그 스크립트를 돌려서 나에게 보여주었습니다. 할당되었다가 프로세스가 죽는 바람에 미처 반환되지 못한 메모리의 주소만이 출력될 뿐이었습니다. 프로세스가 죽기 전까지 실행된 시간을 감안하면, 동적으로 할당되는 메모리의 요구량은 극도로 낮아서, 과연 메모리 문제가 생길 수나 있는 것인지 의심될 정도였죠.

“프로세스들의 실행 속도가 너무 빨라서, 디버깅하기도 어려우셨겠어요.”

내가 묻자 그는 고개를 끄덕였습니다.

“거기다 프로세스들 마다 쓰레드를 몇 개 씩 띄우니까 더더욱 어려웠죠.”

“디버거를 한 번 붙여보는 것은 어떨까요?”

내가 제안하자 그는 그것도 해 봤다면서 직접 어떻게 했는지 보여주었습니다. 그는 프로세스 각각에 gdb를 붙인 다음에, malloc_error_break에 breakpoint를 건 다음 실행했습니다. 그리고 똑같이 실행하자 SIGSEGV 시그널이 뜨는 순간에 프로세스가 멈추면서 디버거도 실행을 중단했습니다.

“함수 호출 경로를 한 번 보죠.”

죽은 지점은 delete가 실행되는 지점이었습니다. 그러니까, 메모리가 반환되다가 죽었다는 이야기였습니다. 문제는, 디버거가 그 원인에 대해서 아무런 힌트도 주지 않고 있다는 점이었습니다. 우리는 SIGSEGV가 발생한 문제의 파일을 열었습니다.

“메모리 할당하는 곳은 바로 위에 있고, 두 줄 아래에서 그 메모리를 다 쓴 다음에 반환했는데 프로세스가 죽는다... 이거 이상하군요.”

그도 당최 이유를 알 수 없다면서 고개를 내저었습니다.

“좀 쉬었다 할까요?”

내가 묻자 그도 흔쾌히 자리에서 일어났습니다. 우리는 휴게실로 가서 자리에 앉았습니다. 원래는 흡연실을 겸하고 있었는데, 건물 전체가 금연 구역으로 지정되면서 이제 담배를 피우려는 사람은 모두 옥상으로 가야 했습니다.

“여기는 그래도 시원해서 좋네요.”

그가 커피를 한 모금 삼키며 말했습니다.

“저랑 붙어 있으려니까 더우시죠?”

그러자 그가 키들거렸습니다.

“혼자 있을 때 보다는 덥긴 하죠. 그런데, 저랑 일하기 불편하지 않으세요?”

그도 자신의 문제가 뭔지 잘 알고 있는 듯 했습니다. 그래서 이렇게 말해주었습니다.

“유식씨가 썰렁한 농담할 때가 사실 더 힘듭니다.”

그 말에 그는 너털웃음을 터뜨렸습니다.

“죄송합니다. 저도 제 문제가 뭔지 잘 아는데, 쉽게 고쳐지질 않네요. 제가 좀 이기적인 성격인가 봅니다.”

“프로그래머들은 대부분 혼자 일 하는 걸 좋아하죠. 그냥 경험 부족이라고 생각하세요. 스스로를 이기적으로 생각하는 건 어쩐지 좀 아니다 싶습니다.”

그러자 그는 갑자기 예전 여자 친구 이야기를 꺼냈습니다. 그를 처음으로 이기적인 사람으로 불렀던 여자. 그는 한참동안이나 그 때 이야기를 풀어놓았습니다. 그가 그렇게 말을 많이 하는 것은, 술 취했을 때 빼고는 처음인 것 같았습니다.

“그래서 가끔, 제 자신이 정말로 이기적인가 생각해보게 돼요.”

그의 말에, 어쩐지 아무런 대답도 할 수 없었습니다. 나는 이기적일까요 이타적일까요? 그런 질문에 자신 있게 답을 할 수 있는 사람은 몇이나 될까요? 어쩌면 우리가 겪는 이기와 이타의 문제는 단순히 기술적인 문제는 아닐까요? 많은 사람들이 다른 사람들과의 관계에 있어서 문제를 겪곤 합니다. 그리고 그런 문제는 좀처럼 가볍게 풀리지 않습니다. 어쩌면 고르디우스의 매듭보다 더 풀기 어려운 매듭일 지도 모르죠.

“어쩌면, 단순히 연습이 부족해서 일수도 있다는 생각, 안 해 보셨나요?”

내가 묻자 그는 무슨 소린가, 하는 표정으로 나를 바라보았습니다.

“스스로 이기적이라고 생각하는 사람보다, 남을 이기적이라 비난하는 사람들이 더 많습니다. 그리고 그렇게 행동하는 사람조차도, 이기적이라고 비난받으면 화를 내죠. 모든 사람들이 ‘이기적’이라는 단어를 부정적으로 느낀다는 뜻입니다. 그런데 말이죠, 이렇게 생각해 봅시다. 바이러스 백신도 만들어 내는 세상인데, 왜 모든 사람들이 싫어하는 ‘이기심’은 세상에서 사라지지 않는 걸까요?”

“왜 그런 건데요?”

“바이러스를 치유하는 방법은 발견되었지만, 이기심을 치유하는 방법은 발견되지 않았거나, 쓰이지 않고 있기 때문이죠.”

“그래서 기술적인 문제라고 말씀하신 건가요?”

“네. 이기적으로 굴지 않을 방법만 체득하면, 적어도 이기적이라 비난 받는 일은 피할 수 있다는 것이죠. 그러다 보면 정말로 마음속의 이기심까지 버리게 될 수도 있겠고요.”

이 사람이 대체 무슨 소리를 하는 거지? 남기수의 표정은 어느 새 그렇게 변해 있었습니다. 저는 속내를 숨길 줄 모르는 그가 어쩐지 마음에 들었습니다. 단순히 팀원으로서가 아니라, 코드를 나눌 수 있는 동료로서요.

우리는 그 자리에 한참 동안 앉아서 이런 저런 이야기를 나누었습니다. 화제는 어느새 이기심의 문제에서 우리가 매만지던 코드 쪽으로 돌아가 있었습니다. 저는 물었습니다.

“그런데, 그 버그가 최초로 발견된 건 언제부터인가요?”

“확실히 기억나진 않습니다만, 코드가 Windows에서도 돌아갈 수 있도록 변경하는 작업이 끝난 뒤부터였던 것 같습니다.”

“메모리 디버깅을 위한 매크로를 삽입한 것이 그 버그 때문이었나요?”

제 질문에 그는 잠깐 생각하더니, 고개를 저었습니다.

“아뇨. 처음에는 코드를 Windows에 어떻게 포팅할 까 고민하다가 Cygwin 플랫폼 위에서 컴파일하고 돌려봤었거든요. 그런데 이상한 예외가 자꾸 뜨더군요. 메모리 문제가 아닐까 고민하다가 메모리 디버깅 매크로를 만들어 넣은 겁니다. 그런데도 그 예외는 사라지지 않았어요. Cygwin 내부에서 발생하는 예외였는데, 도무지 해결할 방법이 없어서 결국 Win32 API를 직접 호출하는 쪽으로 방향을 틀었죠. 그 작업은 일주일 만에 끝났고, Windows 포팅도 성공적으로 끝났죠. SIGSEGV 시그널이 터지기 시작한 건 그 뒤입니다.”

우리는 자리로 돌아갔습니다. 저는 물었습니다.

“그러면 아까 그 코드를 매크로 삽입 이전 코드로 돌려 놔 봅시다.”

우리는 SIGSEGV 시그널이 발생한 부분의 코드만 이전 상태로 돌렸습니다. 그런 다음에 컴파일을 하고, 다시 프로세스를 띄우고 테스트를 시작했습니다.

“이번엔 죽질 않는데요?”

그랬습니다. 삼십분이 넘게 테스트를 했는데, 일이 분이면 발생하던 시그널이 더 이상 뜨질 않았습니다.

“정말 그런데요. 그럼 UNDO해서 매크로가 들어있던 코드로 다시 복구해 보겠습니다.”

남기수의 손가락이 키보드를 몇 번 오락가락하자, 코드는 다시 원래 상태로 돌아갔습니다. 다시 테스트를 시작했고, 이번에는 SIGSEGV 예외가 떴습니다.

“뭐가 문제였는지 찾은 것 같군요.”

내가 말하자 그도 고개를 끄덕였다.

“매크로에 버그가 있었다면 매크로를 사용한 모든 부분에서 같은 예외가 떴을 테니, 매크로 자체에는 버그가 없다고 믿어도 되겠죠?”

그는 대답없이 코드를 뚫어지게 쳐다보았습니다. 나도 함께 바라보았습니다. 저기 어딘가에 그가 저지른, 아니 우리가 미처 알아채지 못한 버그가 숨어 있을 터였습니다.

아주 어렸을 때, 소풍을 가면 꼭 보물찾기를 했습니다. 선생님은 보물이 숨겨진 곳의 단서를 주었고, 우리는 선생님이 신호를 보내자마자 보물을 찾기 시작했는데, 나는 단 한 번도 보물을 찾은 적이 없었습니다. 상품은 언제나 다른 친구들의 몫이었죠. 그 시절을 반추해 보면, 지금 내가 코드 사이에 숨겨져 있는 비합리의 흔적을 따라 버그를 찾는 직업을 가지게 된 것은 신기한 일이었습니다. 나에게는 그런 재능이 없다고 봐야 옳았으니까요. 그 시절, 친구들은 나에게 이야기했습니다.

“이거 같이 먹을래? 너는 하나도 못 찾았잖아.”

딱하다는 듯이 나를 보는 친구들의 말에 나는 언제나 고개를 저었습니다. 내 안의 자존심은 친구들의 호의를 사심 없이 받아들이는 것을 결코 허락하지 않았습니다. 친구들이 손을 내밀면, 나는 언제나 씩씩거리다 울음을 터뜨렸습니다.

“내가 찾을 거란 말이야!”

그 시절의 나를 떠올리자, 입가에 절로 미소가 피어올랐습니다. 남기수에게도 그런 어린 시절이 있었을까요? 그는 보물을 찾아 친구와 나눌 줄 아는 아이였을까요, 아니면 나처럼 자존심에 몸을 떨다 눈물을 흘리고는 선생님의 품에 안기고 마는 아이였을까요?

“씨팔...”

그가 나직이 중얼거렸습니다. 나도 거의 동시에 문제를 알아차렸습니다.

“아래쪽에서는 DEL_ARR 매크로를 썼는데, 위에서는 NEW 매크로를 썼군요.”

“그러네요. 그러니까 그 말은...”

“new[]를 했을 때만 delete[]를 해야 하는데, new를 하고는 delete[]를 해 버렸다는 뜻이죠. 우리가 코드를 원래 상태로 돌려 놨을 때에는 그 짝을 잘 맞췄는데, 매크로 코드를 넣을 때는 짝을 잘 맞추지 못했다는 뜻이죠.”

“왜 그런 일이 벌어졌을까요?”

“NEW(TYPE, ...)와 NEW_ARR(TYPE, SIZE) 매크로를 인자가 딱 두 개인 상황에 적용했을 때는, 컴파일러가 어떤 오류도 내질 않거든요.”

결국, 타이핑 실수였습니다. 컴파일러의 한계를 올바르게 알지 못하고 매크로를 작성한 것도 실수의 원인이었죠. 그가 나를 보며 멋쩍게 웃었습니다. 나도 같이 웃었습니다. 우리는 한참을 넋 놓고 그렇게 앉아있었습니다.

네메아의 사자를 퇴치하고 레르나의 히드라를 죽인 헤라클레스에게 주어진 세 번째 과제는 케리네이아의 암사슴을 생포하는 것이었습니다. 헤라클레스는 1년 동안이나 그 사슴을 쫓았지만 잡지 못했습니다. 결국 지친 사슴이 잠시 쉬는 틈을 타, 사슴의 다리뼈와 근육 사이에 독이 묻지 않은 화살을 쏘아 사슴을 생포하죠.

그 사슴은 아르테미스 여신의 것이었습니다. 헤라클레스는 솔직하게 아르테미스 여신에게 사정을 설명하고 용서를 구합니다. 에우리스테우스 왕에게 사슴을 보여주고 나면, 원래 있던 곳에 풀어놓을 것이라는 말과 함께요. 아르테미스는 헤라클레스를 용서하고 그가 노역을 마칠 수 있도록 배려합니다.

세상에 무서울 것이 없는 헤라클레스조차도 신 앞에서는 겸손했습니다. 어쩌면, 우리가 마주하는 모든 버그는 자존심을 온전히 내버릴 수 있어야 해결될 수 있는 것인지도 모르겠다는 생각이 들었습니다. 프로그래머에게 자신이 만든 코드는 자식과도 같습니다. 작가에게 자신이 쓴 글은 자식이나 마찬가지입니다. 하지만 자기 품 안에서 오냐오냐 키운 자식은 올바르게 성장하지 않습니다. 남에게 끊임없이 부탁하고 조언을 구해야 그나마 바르게 크는 것이 자식이라는 존재죠.

그날, 저와 남기수는 코드를 나누는 방법, 자존심을 버리고 남의 말에 귀를 여는 법을 배웠습니다. 따지고 보면 세상의 문제를 푸는 방법이 전부 한 길로 통해 있을 터인데, 우리는 참으로 힘겹게 그 방법을 배운 셈입니다.

저는 박팀장을 만나 문제가 풀렸음을 보고했고, 그녀는 일이 빨리 풀려 다행이라고 미소 짓는 것으로 수고했다는 인사를 대신했습니다. 저는 다시 제 일로 돌아왔습니다. 나흘 정도 일정이 늦춰지긴 했지만, 만회할 수 없는 수준은 아니었습니다. 설사 감당 못할 문제가 생기더라도, 제 곁에는 손만 내밀면 나를 도와줄 동료들이 있었으니까요.

[다음 글에서 계속...]

'Thoughts' 카테고리의 다른 글

아버지는 프로그래머  (2) 2010/08/01
나름 즐거웠던 서해안 휴가  (4) 2010/07/30
프로그래머 31  (5) 2010/07/21
진로  (2) 2010/06/28
올림푸스 E-PL1, 생애 첫 하이브리드 카메라.  (6) 2010/04/30
세이브온 호텔 예약  (0) 2010/04/08


Posted by 이병준

TRACKBACK http://www.buggymind.com/trackback/283 관련글 쓰기

댓글을 달아 주세요

  1. 덧글을 남겨주세요. 감사합니다. ^^

    2010/07/21 13:05 [ ADDR : EDIT/ DEL : REPLY ]
  2. KETTLE

    매번 너무 기다려져요.

    나중에 책으로 출간하세요 꼭 살께요~

    2010/07/28 18:02 [ ADDR : EDIT/ DEL : REPLY ]
  3. duru

    슬슬 먼가를 시작해야 할 거 같은 예감이...ㅋㅋ

    2010/08/04 14:01 [ ADDR : EDIT/ DEL : REPLY ]