Thoughts2014.06.16 16:38

파이썬도 공부하고, 컴퓨터 프로그래밍의 기본기를 배울 수 있게 하는 괜찮은 강의가 있어서 소개합니다. 프로그래밍 개론 격의 강의인데, 정작 OOP 개념을 잘 모르면 강의를 따라가기가 만만치 않습니다. 


제목은 "Principles of Computing" 입니다. 


https://www.coursera.org/course/principlescomputing


이런 분들께 추천합니다.


1. 파이썬 문법은 대충 알고 있는 분 (완벽하게는 몰라도 됨) 

2. 프로그래밍 개론 수업을 다시 한번 들어보고 싶은 분

3. 외국 대학에서 주관하는 온라인 개론 수업이 어떻게 진행되는지 알고 싶은 분

4. 프로그래밍과 관련된 여러 개념을 기본부터 다시 배우고 싶은 분

5. 영어 좀 되시는 분


이 중 1번과 5번이 안 되면 시작부터 무지 까입니다. (스스로 좌절하게 된다는 뜻) 그러니 파이썬 프로그래밍을 한 번도 해보신 적이 없거나, 파이썬의 객체지향 문법에 익숙치 않으시거나, 영어에 심각한 애로사항이 있으신 분은 듣지 않으시는 것이 낫습니다. 


물론, 돈 드는 강의 아니니까 둘러보는 건 언제나 OK.


다만, Coursera에서 주는 수료 인증서를 받으려면 돈을 내야 합니다. (ㅜㅜ)






저작자 표시 비영리 변경 금지
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

Thoughts2014.01.02 23:08

새해가 되면 누구나 계획을 세웁니다. 올해는 담배를 끊겠다, 올해는 술을 끊겠다, 올해는 영어공부를 하겠다, 올해는 새로운 프로그래밍 언어를 배우겠다.... 등등 셀 수 없이 많은 계획을 세우죠. 그러나 역시 개발자로서 가장 현실성 있는 계획은 아무래도 새로운 프로그래밍 언어를 배우는 것. 저는 올해 Julia라는 언어를 한 번 배워볼까 계획중인데요. 앞선 글에서도 밝혔듯이, 새로운 프로그래밍 언어를 배우는 것은 프로그래머에게 있어서 굉장히 중요합니다. 프로그래밍을 바라보는 시각의 지평을 넓혀주기 때문이죠.



여러분은 어떠십니까? 이 블로그를 방문하는 분들은 과연 올해에는 어떤 프로그래밍 언어를 배우려 하실지, 저도 사실 굉장히 궁금한데요. 여러분의 계획을 이 블로그를 찾는 다른 분들과도 한 번 나눠보지 않으시겠어요? 아래에 투표지를 마련했습니다. 결심을 공개하면 작심삼일의 위험을 피할 수 있다는 것을 명심하세요 (응?). 아 그리고, 하나만 고르지 않으셔도 됩니다. (수줍)


SEE ALSO: 파이썬을 배워야 하는 다섯가지 이유

SEE ALSO: 자바를 배워야 하는 다섯가지 이유


online poll by Opinion Stage


이 블로그를 찾아주시는 모든 분들께, 2014년 한해 동안 CODE의 FORCE가 충만하기를!



저작자 표시 비영리 변경 금지
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. 저는 컴전공자는 아닌데 요새 블로그하면서 html 과 ccs 같은거 배워보고싶네요 ㅋ

    2014.01.03 03:19 신고 [ ADDR : EDIT/ DEL : REPLY ]
  2. 염구나

    전 언어전환 이슈가 있어서 상반기에는 자바(스프링)을 배워야 할 것 같고 하반기에는 파이썬을 해볼까 생각 중입니다.

    2014.01.03 12:42 신고 [ ADDR : EDIT/ DEL : REPLY ]
  3. 명뷁

    음......... 매번 공부한다고 하고.. 안하내요 ㅎㅎㅎ;;

    전 JAVA와 안드로이드 등 을 좀더 공부해볼까합니다.

    2014.02.27 15:08 신고 [ ADDR : EDIT/ DEL : REPLY ]

Thoughts2013.12.11 17:07

좋은 개발자를 뽑기 위한 환경을 갖추었다고 칩시다. 그런데 대관절 좋은 개발자는 어떻게 알아볼 수 있을까요? 좋은 개발자와 그렇지 않은 개발자를 가려내는 것은 생각보다 어렵습니다. 



일단 개발자를 만났다면: 


1. 어떤 프로그램을 만들어 보았는지 물어보라.


만일 '재미삼아' 만들어 본 프로그램이 있다면, 그리고 그 프로그램을 아직도 유지보수하고 있다면, 혹은 그 프로그램을 공개 소프트웨어로 만들어 많은 사람들에게 배포해 본 경험이 있다면, 그 사람은 좋은 개발자일 가능성이 아주 높습니다. 


2. 어떤 프로젝트를 진행했었는지 물어보라. 


자신이 진행했던 프로젝트 이야기를 하면서 많은 개발자들은 자기 어필을 하려고 시도합니다. 가급적이면 그 이야기를 끝까지 들어주면서 그 개발자의 역할이 어느 정도였는지 파악하세요. 가능하면 무엇이 어려웠고, 그 어려움을 극복하기 위해 어떤 노력을 했는지 들어보세요. 그런 이야기를 듣다 보면, (1) 독야청청 독불장군형 개발자인지 (2) 협업 중심의 개발자인지 (3) 문제 방임형 개발자인지 (4) 문제 해결형 개발자인지 (5) 자기를 잘 포장할 줄 아는 개발자인지 (5) 말에는 별 소질이 없는 개발자인지 (6) 문제를 깊이있게 들여다보고 개발을 진행하는 사람인지 (7) 일단 만들어 보고 문제를 몸으로 이해하는 유형의 개발자인지 등등의 중요한 정보를 알아낼 수 있을 겁니다. 


3. 간단한 문제를 던져주고 어떤 접근법으로 풀 지를 물어보라.


보통 '코딩 인터뷰'를 진행하기도 하는데, 문법을 다 기억 못하거나 관련 자료를 찾아보면서 프로그래밍하는 사람도 많으니 코딩을 실제로 해 보라고 요구하기 보다는 어떤 접근법을 사용할 것인지 물어보는 것도 괜찮습니다. (물론 대부분의 외국 IT 업체는 종이에라도 프로그램을 만들어 보라고 요구하죠.) 답변을 들어보면 꽤 많은 정보를 얻을 수 있는데 (1) 예전에 이 개발자는 어떤 식으로 문제를 풀었는지를 알 수 있고 (2) 필요한 분야에 맞는 최신 지식을 많이 갖추고 있는지 알 수 있고 (3) 실질적으로 문제를 해결할 능력이 있는 지를 알 수 있습니다. 


덤으로, '당신의 해결방법에는 이러저러한 문제가 있을 것 같은데, 그건 어떻게 해결할 건가요?' 같은 질문도 던져 보면 좋습니다. 


4. 개발자의 입장에서 대화해 보라.


개발자의 입장에서 술 한잔 하면서 이런 저런 이야기를 하다보면, (결국에는) 일과 관련된 무용담을 털어놓게 되기 마련입니다. 가능하면 솔직하게 가감없이 자기 이야기를 먼저 하세요. '저도 그런 문제를 겪었었는데 저는 이렇게 해결했습니다' 같은 답변을 듣게 된다면, 아마 술이나 커피 값이 아깝지는 않을 겁니다. 


5. 옷차림에는 신경쓰지 마라.


허술한 옷차림을 하고 있는 개발자라면, 일 이외의 다른 문제에는 아예 관심이 없는 사람일 가능성이 있습니다. 의외로 갖춰입고 면접에 임한 개발자라면, 세상에 대한 열정이 가득한 사람일 가능성이 높습니다. 어느 쪽이라도 손해날 것은 없으니 웬만하면 옷차림은 신경쓰지 마세요. 


6. 회사 문화에 잘 동화될 만한 사람인지 알아보라. 


자만심, 아집, 편견 등등은 협력이나 조화같은 보편적인 가치에 굉장히 적대적인 속성들입니다. 이런 속성들을 갖춘 사람인지 살펴보시고, 능력이 기대치를 훨씬 상회하지 않는 한 그런 사람은 뽑지 마세요. 결국에는 팀이 아작납니다. 남 이야기를 잘 들으려 하지 않는 사람, 열 명이 아니라고 해도 자기 고집대로 하는 사람은 전부 이 부류에 넣을 수 있습니다. 냉소적이거나 빈정대는 습관이 있는 사람도 좋지 않습니다. 다른 사람 기분을 상하게 만드니까요. 


7. 가르칠 수 있을만한 사람인지 알아보라. 


즐겁게 배울 준비가 되어 있는 사람은 설사 배경지식이 부족해도 뽑아볼 만 합니다. 의외의 분야에 사람이 필요한데 거기 지원해 볼 생각은 있느냐, 같은 질문을 던져보고 반응을 보면 좋습니다. 물론 거짓된 반응을 보일 수도 있으니, 일정 기간 동안은 함께 일하면서 살펴볼 기회를 갖는 것도 좋습니다. 새로운 업무에 대한 파악 능력이 좋은 사람은 어떤 상황에 처하더라도 도움이 됩니다. 


8. 이전 직장에서의 평판을 알아보라. 


요즘은 전직을 통해 새로운 기회를 찾는 것이 보편화되고 있는 추세이므로, 직장을 많이 옮기는 것은 그다지 흠이 되지 않습니다. 오히려 전 직장에서 사람들과 어떻게 어울렸고, 어떤 리더십을 발휘했고, 어떤 결과를 만들어 낸 다음에 퇴사했는지를 알아보면 뽑는 사람 입장에서는 리스크를 줄일 수 있으므로 도움이 됩니다. 다만 너무 뒷조사하듯 할 필요는 없고, 그냥 아는 사람이 있다면 (이 바닥에서는 한 다리 건너면 다 아는 사람이죠) 한번 넌지시 물어보는 것으로 충분하겠죠. 


저작자 표시 비영리 변경 금지
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

Thoughts2013.10.11 08:30

트위터를 다양한 용도로 사용하는 사람들이 많습니다만(http://mashable.com/2013/10/10/twitter-creative-uses/), 오늘 소개해드릴 사용법은 그 가운데서도 가장 '기술적'인 사용 방법이라고 할 만 합니다. 이 기술은 센서와 네트워크, 그리고 트위터를 조합한 기술입니다. 화분에 언제 물을 주는 것이 좋을지 잘 모르시겠다구요? 그럼 이 키트를 화분에 설치해 보세요. 이른바 Botanicalls Kit입니다. (http://www.botanicalls.com/kits/)



Botanicalls KitBotanicalls Kit



이 기술은 원래 휴대전화와 연동하여 화분에 물을 줘야 하는 시점이 되면 휴대전화로 메시지를 보내주는 기술이었는데, 지금은 트위터 메시지를 보내줍니다. (헐)






자세한 기술적 사항이 궁금하신 분들은 이 링크를 방문해 보시면 되겠습니다. (http://www.botanicalls.com/archived_kits/twitter/) 그러나 기술개요가 궁금하신 분들을 위해서 간단히 요약해보자면 (1) 센서를 이더넷 포트가 달린 네트워크 카드에 연결하고(사실은 아두이노 카드입니다) (2) 센서와 네트워크 카드를 연결하고 (3) 네트워크 카드를 프로그래밍합니다. 따라서 약간의 아두이노 지식이 필요한데요.



내 집 프로그래밍하기!내 집 프로그래밍하기!



아두이노 지식을 활용해서 화분과 소통하고 싶으신 분들은, 인사이트에서 출간된 아두이노 관련 서적들을 살펴보시는 것이 어떨까요? 아래 링크에서 구경하실 수 있습니다. http://www.insightbook.co.kr/?s=%EC%95%84%EB%91%90%EC%9D%B4%EB%85%B8



저작자 표시 비영리 변경 금지
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

Thoughts2012.01.10 15:41
프로그래밍이라는 행위는 여러가지로 글쓰기와 유사합니다. 아무것도 없는 것에서 무언가를 만들어 내기 위해 글자를 쉼없이 타이핑 해 넣어야 한다는 행위적인 유사성 뿐 아니라, 그 결과가 팔려야 하고, 잘 팔리기 위해서는 많은 사람들의 리뷰와 교정을 거쳐야 하고, 최종적으로는 디자인을 덧입히는 패키징 과정을 거쳐야 한다는 점에서도 비슷합니다. 

영작문 기술에 대해 심각하게 고민해 본 사람이라면 한 번쯤은 읽어보았을 책 가운데, The Elements of Style이라는 책이 있습니다. 이 책은 흔한 문법 오류를 바로 잡는 법부터 시작해서, 좋은 글을 쓰기 위해 지켜야 하는 규칙들도 이야기합니다.

이 책의 2장, Elementary Principles of Writing의 첫 절, "Choose a Suitable design and hold to it"을 인용해보겠습니다. (번역은 완전하지 못하며, 군데군데 오류가 있을 수 있습니다.)



A basic structural design underlies every kind of writing. Writers will in part follow this design, in part deviate from it, according to their skills, their needs, and the unexpected events that accompany the act of composition.

모든 종류의 글쓰기는 기본적인 구조 설계를 전제한다. 작가는 부분적으로는 이 설계를 따르기도 하고, 부분적으로는 자신의 기술과 필요, 그리고 작문 도중에 발생하는 예상치 못한 사건들 때문에 그 구조로부터 이탈하기도 한다.

Writing, to be effective, must follow closely the thoughts of the writer, but not necessarily in the order in which those thoughts occur. This calls for a scheme for a procedure. 

효과적으로 글을 쓰려면 작가의 생각에 가깝게 따라가는 것이 좋겠지만, 그렇다고 생각이 떠오르는 순서를 그대로 따라야 한다는 것은 아니다. 그래서 절차적인 방법이 필요하다. 

In some cases, the best design is no design, as with a love letter, which is simply an outpouring, or with a casual essay, which is ramble. But in most cases, planning must be a deliberate prelude to writing. The first principle of composition, therefore, is to foresee or determine the shape of what is to come and pursue that shape.

무설계가 최선의 설계인 경우도 있다. 연애편지처럼 흐르는대로 쏟아내거나, 격식을 차릴 필요 없는 에세이 같은 경우가 그에 해당한다. 하지만 대부분의 경우, 글쓰기 전에는 의식적으로 계획을 먼저 세워야 한다. 그러므로 글쓰기의 첫 번째 원칙은 최종 결과물의 형태를 예측하고 결정한 다음, 그 형태를 추구하는 것이다.

A sonnet is built on a fourteen-line frame, each line containing five feet. Hence, sonneteers know exactly where they are headed, although they may not know how to get there. Most forms of composition are less clearly defined, more flexible, but all have skeletons to which the writer will bring the flesh and the blood. The more clearly the writer perceives the shape, the better are the changes of success.

어떤 구조를 따르고, 최종 결과물의 형태를 예측한 다음 그 형태를 빚어낼 수 있도록 노력해야 한다는 것은, 프로그램의 구조 설계와 그에 필요한 요구사항들을 연상시킵니다. 

자신의 기술과 필요에 따라 처음에 정했던 구조를 이탈하기도 한다는 대목은, 코드를 리팩터링하다보면 초기 구조에서 점차로 이탈하여 새로운 구조가 만들어지기도 하는 것과 비슷합니다. 

보통 글쓰기를 예술적 창조의 영역에 놓습니다. 그렇다면 프로그래밍은 같은 영역에 둘 수 있을까요?

프로그래밍 결과로 만들어지는 코드는 그 자체로 음미할 대상이 아니라는 점에서, 작문과 같은 영역에 놓을 수는 없겠습니다. 우리는 소스 코드를 음미하는 것이 아니라, 결국 최종적으로 만들어진 바이너리를 평가하게 되죠. 

하지만 우리가 글쓰기를 하면서 자기 성찰에 따르는 즐거움을 누리듯, 프로그래밍을 하면서도 같은 기쁨을 느끼곤 한다는 점을 염두에 둔다면, 적어도 프로그래밍을  사적인 예술의 영역에 놓을 수도 있겠습니다. 예술은 기본적으로 즐거움에 관한 것이니까요. 

그러니, 데드라인이 가까와 올 때 까지는 우리 모두, 스스로를 예술가라고 생각하도록 합시다. :-)


저작자 표시 비영리 변경 금지
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. 데드라인.. 없었으면 좋겠어요 ㅠㅠ

    2012.01.12 00:36 신고 [ ADDR : EDIT/ DEL : REPLY ]
  2. dhyi123

    잘 짜여진 코드를 보면서 아름답다 생각하는 것은 저뿐이 아닐 것 같은데요.
    고객이 정해진 상황이라면 예술작품도 데드라인이 있을 것 같습니다.

    2012.01.12 12:11 신고 [ ADDR : EDIT/ DEL : REPLY ]
  3. 두루

    자신의 미학적 기준으로 창조물을 만든다면 예술행위 맞는데, 아니면 애매~~ㅋㅋ 그래함의 말대로 얼마나 물자체들과 공감하느냐(혹은 할 수 있느냐)가 관건일 텐데,,, 젊었을 때 프로그래밍 좀 배울 걸,,,하는 아쉬움,, 이구~~

    2012.01.16 10:51 신고 [ ADDR : EDIT/ DEL : REPLY ]

Languages/Objective-C2011.01.20 17:35
UIScrollView를 사용하여 Zooming, 페이지 단위 스크롤링을 고려하려면 주의해야 할 것이 있습니다. 그건 바로 "하나의 UIScrollView 하위 클래스에 Zooming 기능과 스크롤링 관련 기능을 동시에 우겨넣으면 안된다"는 것이죠.

같이 우겨넣어 프로그래밍을 할 수 있을지도 모르겠습니다만, 아마 "굉장히" 프로그래밍하기 어려울 겁니다.

그럼 확대/축소도 되고 좌우로 스크롤링도 되는 PDF 뷰어 같은걸 구현하려면 어떻게 해야 하나요?

가장 간단한 방법은 스크롤 뷰를 중첩(nesting)하는 겁니다. 안쪽 스크롤 뷰에는 확대/축소 기능을 넣고, 바깥쪽 스크롤 뷰에는 좌우 스크롤 기능을 구현하는 것이죠.

확대 축소 기능에 대해서는 지난번 글에 잠깐 다루었는데, 좌우 스크롤 기능과 함께 사용하려면 지난번 글처럼 기능을 무조건 단순화 하면 곤란합니다. 좌우 스크롤하려면 다음과 같은 요구사항을 만족해야 하기 때문이죠.

(1) 끊김없는 좌우 스크롤
(2) 다음번에 나타날 화면의 caching
(3) 페이지 단위 좌우 스크롤

(3)번은 만족시키기가 간단합니다. 스크롤 뷰의 pagingMode를 YES로 설정하면 되거든요. 그렇게 하면 화면 크기를 (엄밀하게 말하면 스크롤 뷰의 bounds 속성 값) 페이지 크기로 인식하고 스크롤을 합니다.

(1)을 할떄는 생각할 것이 좀 많습니다. '끊김 없는'이라는 것은 '좌우 스크롤을 할 때 멈칫 거리는 일이 없어야 함'을 의미하거든요. 모든 페이지를 하나의 스크롤 뷰의 서브 뷰로 몽땅 다 로딩해 버린다음에 스크롤 하면 별문제겠습니다만 그렇게 하는 건 오버헤드가 너무 큽니다. 그러니 보통은 좌우 스크롤을 구현할 때 이렇게 해야 하죠.

a. 스크롤 뷰의 contentSize는 스크롤 뷰 안에 '모든 페이지'를 우겨넣는다고 가정하고 잡습니다.

그래야 하는 이유는? 그래야 스크롤 뷰가 '어디서부터 어디까지 스크롤 해야 하는지' 제대로 인식할 수 있기 때문이죠.

b. 스크롤 뷰 안에 컨텐트를 (그러니까 서브 뷰들을) 추가할 때에는 딱 세 개 (혹은 다섯 개?) 만 합니다.

화면에 보이는 것은 그 중 가운데고, 왼쪽 오른쪽에 있는 것들은 각각 손가락을 오른쪽으로 긁었을 때, 왼쪽으로 긁었을 때 화면에 나타나야 하는 것들이죠.

c. 스크롤 뷰가 실제로 스크롤 되면, 위의 세 개 뷰 중에 왼쪽에 있는 것을 오른쪽으로 옮기고, 가운데 있는 것은 오른쪽, 맨 오른쪽에 있는 것은 폐기처분하거나 (release) 아니면 맨 왼쪽으로 돌려서 재활용합니다. (재활용 할 때에는, 재활용 한 뷰에 '그려졌던' 내용이 잠시라도 화면에 다시 표시되는 일이 없도록 주의해야 합니다.)

이렇게만 하면 서브뷰 딱 세 개만 가지고도 가로 방향 스크롤을 구현할 수 있습니다. (세로 방향도 마찬가지.) 굉장히 간단하게 들리는데, 무슨 문제가 있나요?

보통 '왼쪽으로 스크롤이 일어났다' 아니면 '오른쪽으로 스크롤이 일어났다'는 뭘 가지고 판단하나요? 스크롤 뷰의 delegate 함수 중에 scrollViewDidEndDecelerating 함수를 구현해서 할 수도 있겠지만, 테스트 해 본 바에 따르면 굉장히 페이지를 빠른 속도로 넘기는 경우에 문제가 발생할 가능성이 있습니다.

그래서 보통은 스크롤 뷰의 contentOffset.x 값이 오른쪽이나 왼쪽 페이지의 중간 지점을 넘어갔을 때 '스크롤이 일어났다'고 판단하게 되는데, 그러면 그 때 무슨 일을 해야 하느냐 하면 앞서 말한 대로 페이지들의 위치를 옮기고 재배치하는 등의 작업을 해 줘야 하거든요.

근데 재배치 될 뷰 안의 drawRect나 drawLayer 함수 안에서 뭔가 굉장히 많은 일을 하게 되면 바로 그 순간에 스크롤이 멈칫거리는 현상이 발생하게 됩니다. (Apple의 이미지 스크롤 관련 예제에서도 동일한 문제가 발생해요.) PDF 페이지를 렌더링 하는 것도 PDF 파일에 따라서는 막대한 오버헤드를 유발하기 때문에 마찬가지죠.

이 문제를 극복하기 위해서는 drawRect는 가급적 피하고 drawLayer를 쓰며, layer 클래스로는 CATiledLayer를 쓰는 것이 바람직합니다. CATiledLayer는 렌더링을 할 때 쓰레드를 만들어서 백그라운드에서 렌더링을 하기 때문에, drawLayer가 스크롤을 멈칫거리게 한다던가 하는 일이 적어요.

물론 화면에 뜨는 스피드는 좀 느려지긴 합니다. 이런 trade-off에 대해서는 개발자가 적절히 생각하고 선택을 해야겠죠. (저는 못해 드립니다. ㅎㅎ)
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

Thoughts2009.05.23 14:28
최근에 굉장히 오랫동안 몸이 안좋았습니다. 부산에 차를 몰고 다녀온 이후로 안좋았으니 대략 보름 정도입니다. 체력 저하의 결과로 기분이 굉장히 우울해졌습니다. 우울증을 의심할 정도였으니 굉장히 우울했던 셈이죠.

우울함은 보통 다음과 같은 감정들과 함께 나타납니다.

  • 분노
  • 억측
  • 집착
  • 망상

보통 이런 상태는 집착 -> 억측 -> 망상 -> 분노 -> 우울의 단계를 거쳐 진화하고 순환합니다. 그리고 보통 이런 상태에서는 집착이나 억측의 대상이 되는 무언가에 자연스럽게 몰입되는 경우가 일반적입니다. 그런 몰입 대상이 없는 상태에서 우울함이 계속 반복되는 경우도 있는데, 그 때는 '나는 우울하다'는 생각 자체가 몰입 대상이 되기도 합니다.

따라서 우울함이 오래 지속되면 '우울하다는 생각'이나 '나를 우울하게 하는 무엇'에 대한 생각이 머리속을 떠나지 않는 일이 자주 생깁니다. 그러므로 본인 스스로는 '아무 일도 할 수 없는 상태이다'라고 느끼고 있더라도, 실제로 두되는 혼자서 무언가를 아주 열심히 하고 있다고 보아야 합니다. 우울할 때 몸이 평소보다 훨씬 더 피곤하게 느껴지는 것은 아마 그 때문일 것입니다. 부정적인 몰입은 감정의 상태를 해칠 뿐 아니라, 신체의 상태도 해칩니다.

이런 상태의 고리를 끊으려면 머리가 혼자서 열심히 하고 있는 부정적 몰입활동의 고리를 끊어야 합니다. 부정적 몰입도 결국 고도의 정신 활동의 일종이므로, 그런 활동의 고리를 끊으려면 새로운 활동도 그만큼 고도의 정신 활동이어야 아마 효과가 좋을 것입니다.

이런 활동의 후보로는 다음과 같은 것들이 있습니다.

  • 글쓰기
  • 프로그래밍
  • 음악

본인이 이미 익숙해서 별다른 주의를 기울이지 않아도 할 수 있는 활동은 효과가 별로 없습니다. (가령 걷기 같은 것이 그렇습니다.) 그러므로 가능한한 창조적인 활동이 효과가 좋습니다. 음악도 그냥 '악기를 두드리기'만 해서는 효과가 없고, 그 악기로 '무언가를 창조'하는 것일 때 효과가 좋습니다.

그런 면에서 보자면 프로그래밍은 우울함의 고리를 끊는 데 꽤 효과가 좋습니다. (저도 효과를 봤습니다.)

일단 프로그래밍은 '아무리 익숙하더라도 계속해서 주의를 기울여야 하는' 활동입니다. 무의식적으로 진행할 수 있는 부분이 그렇게 크지 않습니다. 그리고 프로그래밍은 무언가를 만들고 결과를 확인해야만 하는 활동입니다. 다른 예술적 활동들에 비견할 수 있을지는 모르겠습니다만, 만든다는 측면에서 보자면 분명 창조성이 있습니다. 무언가를 '창조'하려면 본인의 '주도적 생각'이 뒷받침되어야 합니다. 그러므로 단순 반복적인 활동이 되기 어렵습니다.

다만 프로그래밍은 하루 종일 할 수 있는 활동이 아니므로, 퇴근 이후나 주말 같은 때는 다른 활동을 병행해야 합니다. 상대방이 있을 때는 대화를 많이 하는 것도 효과적인데, 특히 말을 많이 하면 좋습니다. 말을 적게 하고 듣기를 많이 할 경우에는, 듣는 동안 다른 생각이 끼어들어 원래 우울한 상태로 돌아갈 가능성이 높아집니다.

이런 식으로 자신의 감정을 계속해서 관찰하고 통제하는 것은 굉장히 피곤한 일이므로, 밤에는 의외로 쉽게 잠들 수 있습니다. 우울함의 고리를 끊는 데는 숙면이 특히 중요한데, 잠을 많이 자지 않으면 체력이 떨어지므로 자신의 감정을 계속해서 관찰하고 통제할 수가 없습니다. 통제력을 상실하게 되면 음주나 흡연과 같은 다른 수단의 힘을 빌리게 되는 일이 잦아지는데, 그러다 보면 자기 모멸감이 심해져 오히려 역효과가 나게 됩니다.

하지만 잠이 오지 않는 데 잠을 자려고 애쓰는 것 만큼 힘든 일도 없으므로, 그럴 때는 의사의 도움을 받아 수면 보조제 같은 것을 처방받는 것도 괜찮겠습니다. (저 같은 경우에는 수면 보조제를 받아두었다는 사실을 의식하는 것 만으로도 쉽게 잠들 수 있는 때가 많았습니다.)

신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. 저랑 비슷하시네요ㅋㅋ
    프로그래머들 다들 비슷한거 같아여
    글쓰기, 프로그래밍, 음악.
    ㅎㅎ
    좋은건지 나쁜건지 ㅎㅎ

    2009.06.14 23:37 신고 [ ADDR : EDIT/ DEL : REPLY ]

Extremely Agile/General2009.01.15 23:07

사람들이 살아가고 지식을 나누는 방법에는 지식간 경계를 뛰어 넘는 어떤 공통점 같은 것이 있습니다. 보통 XP에서 많이 하는 것으로 알려져 있는 짝 프로그래밍(Pair Programming)도 예외는 아닙니다. 많은 프로그래머들이 "지나치게 급진적"인 것으로 생각하는 이 프로그래밍 기법은, 사실 다른 쪽에서는 그다지 새로운 것이 아닐 수도 있습니다.

책을 통해 기타를 배운다면 결국 완벽한 4분음표와 2분음표로 동요나 칠 수 있을 겁니다. 그러나 대부분의 기타리스트들처럼 친구들이 치는 것을 보고 들어 기타를 배운다면, "Smoke on the water", "Sunshine of your love", "Black bird" 같은 모든 곡을 다 칠 수 있을 정도로 진일보할 겁니다. 즉, 무슨 뜻인가 하면 악보를 몰라도 기타는 칠 수 있다는 말입니다.

- 천재반 기타, p63




가끔 짝 프로그래밍이 두 사람의 기타리스트가 앉아 음악을 연주하는 잼 세션과도 비슷하지 않을까, 하는 생각을 해 봅니다. 기타 대신 키보드를 두드린다는 차이만 있을 뿐이죠. 두 사람이 서로의 기량에 대해 좀 더 열린 마음을 가질 준비만 되어 있다면 결과물의 품질은 아마 더 좋아질겁니다.

비단 짝 프로그래밍이 아니더라도, 마음을 좀 느슨하게 먹으면 일이 잘 풀리는걸 경험하기도 합니다. 제가 최근에 까칠함 대신에 친절함을 모토로 삼아보자고 마음을 먹었는데, 뭔가 얻어먹을 일이 좀 많아지더군요. :-P

신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. 짝 프로그래밍에 대해 간단히 이해할 수 있는 좋은 포스팅인 것 같습니다.^^
    아직 프로그래밍 방법론에 익숙하지 않은 초보 학생이지만 관심 갖고 앞으로
    많은 내용 보면서 공부 하고 싶습니다.^^

    2009.05.17 08:15 신고 [ ADDR : EDIT/ DEL : REPLY ]

Languages/Erlang2008.09.22 17:19

앞선 글을 통해 Erlang에서 병렬 프로그래밍이 어떻게 이루어지는지 대략이나마 감을 잡으실 수 있었을 거라고 믿습니다. 다시 정리해보자면, 얼랭에서 병렬 프로그램은 프로세스의 집합으로 만들어지고, 프로세스 끼리 메시지를 주고받아 통신하는 방식을 사용해 구현됩니다. 메시지를 보낼때는 Pid ! Message 이런 형식으로 보내고, 받는 쪽에서는 receive 를 사용해 메시지를 받아 처리합니다.

그러면 지금부터는 앞선 글에서 만든 프로그램을 진짜 클라이언트/서버 모델을 만족하도록 바꿔 보겠습니다. 클라이언트가 서버에게 요청을 보내면, 서버는 그 요청을 해석해서 클라이언트에게 답을 보내주어야 합니다. 다음의 코드를 보시죠.

-module(concur).
-export([start_server/0, send_request/2, send_stop/1]).

start_server() -> spawn( fun loop/0 ).

loop() ->
    receive
        {request, Pid, L} ->
            Result = odds_and_evens_acc(L),
            Pid ! {response, self(), Result},
            loop();
        stop ->
            exit
    end.

send_request(Pid, L) ->
    Pid ! {request, self(), L},
    receive
        {response, _SPid, {{odd, Ov},{even,Ev}}} ->
            io:format("odd: ~p, even: ~p~n", [Ov,Ev])
    end.

send_stop(Pid) -> Pid ! stop.

odds_and_evens_acc(L) ->
    odds_and_evens_acc(L, 0, 0).

odds_and_evens_acc([H|T], Odds, Evens) ->
    case ( H rem 2 ) of
        1 -> odds_and_evens_acc(T, Odds + H, Evens);
        0 -> odds_and_evens_acc(T, Odds, Evens + H)
    end;
odds_and_evens_acc([], Odds, Evens) ->
    { {odd, Odds}, {even, Evens} }.

클라이언트/서버 모델을 따르는 통신을 하기 위해, 서버에게 보내는 메시지의 형식이 좀 바뀌었습니다. 메시지가 투플 형태로 간다는 것은 종전과 똑같습니다만, 그 투플의 두 번째 항목에 요청을 보내는 클라이언트 프로세스의 PID가 들어간다는 점이 달라졌습니다. 이 PID가 있어야 서버는 어느 클라이언트에게 응답을 보내야 할 지를 알 수  있죠. 서버는 요청이 오면 odds_and_evens_acc를 호출해서 결과를 계산한 다음에, 요청을 보낸 프로세스에게 응답을 전송합니다. 전송되는 응답 투플 맨 앞에는 '응답'임을 알리기 위해 response라는 아톰이 들어가고, 투플 두번째 항목에는 서버 프로세스의 PID가 들어가고(self()를 호출하면 자기 자신의 PID를 얻을 수 있습니다) 세 번째 항목에는 보낼 계산 결과값이 들어갑니다. 

클라이언트는 서버에게 요청을 보내기 위해 send_request 함수를 이용해야 합니다. 이 함수의 첫번째 인자로는 서버의 PID가 오고, 두 번째 인자로는 리스트가 전달됩니다. send_request는 해당 인자들을 사용해 서버에 메시지를 전송한 다음, 스스로 receive를 통해 그 서버가 보내는 응답을 전송받습니다. 그런 다음 응답을 해석해 화면에 결과값을 뿌리죠. (서버가 보내는 PID는 사용하지 않을 것이기 때문에 _SPid와 같은 이름의 변수를 썼다는 것에 주의합시다. _가 앞에 붙는 변수는 설사 이후의 코드에서 사용되지 않아도 컴파일러가 ok합니다.)

위의 코드는 다음과 같이 사용합니다.

14> c(concur).
{ok,concur}
15> Pid = concur:start_server().
<0.90.0>
16> concur:send_request(Pid, [1,2,3,4,5,6]).
odd: 9, even: 12
ok
17>

이렇게 해서 클라이언트/서버 모델을 따르는 간단한 예제까지 만들어 봤습니다. 이해하기 쉬우셨는지 모르겠군요. 다음 글에서는 실제로 메시지 송수신 과정에서 발생할 수 있는 문제에 대처할 수 있는 코드를 만드는 방법을 포함해, 조금 더 심화된 주제들을 살펴보겠습니다.

머리가 터질거같은 상태에서 억지로 글을 쓰다보니 더 이상 길게는 못쓰겠군요. 머리 터질때 코드 작성하는 일 말고는 할 수 있는게 없는 저 자신도 참 한심하기 짝이 없습니다만....




신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

Thoughts2007.10.26 13:38
LP냐 CD냐. 이 주제는 꽤나 해묵은 주제죠. :-) 그리고 사실 이미 시장은 CD쪽으로 거의 다 넘어가 있습니다. CD때문에 LP도 죽었고, 테이프도 죽었습니다. CD는 테이프정도의 휴대성에, LP 이상의 음질을 제공하는 괜찮은 기록 매체이죠. 다만 문제는 가격입니다.

많은 사람들이 LP냐 CD냐 라는 주제를 놓고 설왕설래 했던 기억이 있습니다. LP가 선사하는 추억의 사운드를 선택할 것이냐 (감정적인 선택이죠) 아니면 CD가 주는 명료하고 정확한 음질을 선택할 것이냐 (이성적 선택입니다)를 두고 많은 사람들이 이야기를 해 왔고, 그 탓인지는 모르겠으나 상당수 음악 애호가들은 집에 CD 시스템과 LP 시스템을 같이 구비해두고 있습니다. 사실 음악 애호가라면 집에 LP 판들도 상당수 있을 것인데, CD 듣자고 그 판들을 전부 갈아엎을 수는 없지 않겠어요?

하지만 테이프냐 CD냐, 하는 문제에 대해서는 그다지 이야기되었던 바가 없었던 것으로 기억합니다. 그도 그럴 것이, CD랑 테이프는 '적어도' 음질의 문제에 있어서는 호불호의 문제를 이야기할 만큼 대등하지 않거든요. 음질은 확실히 CD쪽이 더 낫습니다. 그 음질은 오래 들어도 바래지 않지요.

하지만 많은 사람들이 CD 시스템으로 이행하면서 테이프 시스템들을 내다 버릴때, 한가지 간과한 사실이 있었어요. 기본적으로 테이프는 휴대를 위한 매체였습니다. 워크맨을 가지고 다니면서 이어폰으로 음악을 들을 때, 사람들은 음질 문제에 있어서 그다지 스트레스를 받지 않았어요. 테이프의 부피때문에 주머니에 이 테이프 저 테이프 가지고 다닐 수 없는 문제는 물론 있었습니다만, 그런 문제는 CD에 있어서도 마찬가지였습니다. 그리고 그런 문제를 해결하는 방법은 본질적으로는 MP3의 그것과 같았죠. 공 테이프를 마련해서, 듣고싶은 음악을 쭈욱 녹음한 다음에 그걸 들고다니는 겁니다.

그러므로 CD로 테이프를 대체하는 것은 휴대성이라는 관점에서 본다면 그다지 올바른 선택이 아닌 셈이에요. CD가 테이프보다 더 나은 부분이 없거든요. MP3 시스템이 등장하고 나서야 확실히 더 나아지죠.

CD가 테이프 시장까지 말아먹은 덕에, 많은 자동차 오디오 시스템에서도 테이프가 배제되기에 이릅니다. (제 차도 그렇습니다.) 예전엔 몰랐는데, 그렇게 되고 보니 불편한게 좀 있더군요. 제 차에 설치된 오디오 시스템이 그렇게 좋은 것이 아니다보니, CD를 집어 넣으면 '예전에 재생되던 마지막 위치'를 전혀 기억하지 못합니다. (좋은 시스템은 기억할 수도 있나요? 잘 모르겠군요. 좋은 시스템을 써 본 적이 없어서 ㅋㅋ) 요즘 차를 타고 다니면서 오디오북을 듣고 있는데, 이게 생각 외로 불편하더군요. 오디오북을 듣는 와중에 다른 씨디를 갈아 끼울 수가 없는 겁니다. -_-; 갈아 끼웠다가 다시 오디오북 씨디를 넣으면... 네 그렇습니다. 처음부터 다시 플레이하기 시작하죠. -_-;

재수가 없어서인지는 몰라도 제 오디오북 씨디는 트랙 하나의 길이가 삼십분이 넘습니다. 그러니 그런 일이 생기면, 듣던 위치를 찾기 위해 차를 세우고 한참 삽질을 해야 합니다. 오디오북 씨디가 아니라 테이프를 들을 수 있는 환경이었다면? 네. 아마 그런 일은 생기지 않았겠죠. 테이프는 그 구조상 '재생을 멈춘 위치를 항상 기억할 수 밖에 없도록 생겨먹은' 매체이니까요.

EIKI 7070 CD/Tape Player

EIKI 7070 CD/Tape Player


결국 '더 좋은 음질'을 위해 휴대성과 편의성의 일부를 포기한 셈입니다. 그렇다면 음질 면에서는 과연 100% 만족스럽나요? 제가 주로 음악이나 오디오북을 듣는 차량 안은 음악을 듣기에 그다지 만만한 공간이 아닙니다. 외부의 소음이 100% 차단되지도 않고 (차단되면 위험하겠죠?) 너무 소리를 올리면 뒷자리쪽 어딘가에서 음이 찢어지는 것이 느껴질 정도로 부실한 공간이에요. 어차피 차 안은 '그저 적당한 수준으로' 음악을 들을 수 있으면 상관없는 공간이었다는 것이죠.

그러니 적어도 차 안을 기준으로 본다면, 테이프가 CD로 대체된 것은 대부분의 가난한 오너 드라이버들에게는 그다지 이득이 없다고 봐야 할 것 같기도 해요. CD나 MP3 시스템 같은 것을 차 안에 둬 봐야, 어차피 운전하면서 이런 저런 조작을 하기도 난감한 노릇이고, 고작 할 수 있는 것이 좋아하는 음반이나 오디오북을 선택해서 틀어놓는 것이고보면, 뭐 테이프 정도도 충분하지 않느냐, 그런 것이죠.

소프트웨어 프로젝트를 진행할 때에도 비슷한 일이 벌어지곤 합니다. 프로젝트 전반기에 사용자 요구사항을 어느정도 고정시킬 수 있다고 생각하고 작성한 유스케이스는 나중에 저 같은 이상한(?) 사용자가 등장하게 되면 조금씩 어긋나기 시작합니다. 일단 그런 일이 벌어지기 시작하면 해결책은 하나 뿐입니다. 저 같은 사용자를 무시하거나, 아니면 요구사항 문서를 무시하거나. 어느 쪽으로 가더라도 그다지 좋은 일은 못되죠. 제 차 안에 달린 CD 플레이어는 저라는 사용자를 무시하고 설치된 솔루션이라고 봐야겠네요. ㅋㅋ

그래서 저는 그놈만 보면 마음이 좀 불편해요. 기능도 그만하면 충분하고, 외관도 그럴싸하고, 사용자 인터페이스도 이것 저것 풍부한 편입니다만, 제 기본적인 필요를 충족하기에는 뭔가가 좀 모자라거든요.




신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

Thoughts2007.10.24 00:02
오늘 출간된지 이틀밖에 안된 따끈따끈한 책을 받았습니다. 바로 "컴퓨터 프로그램의 구조와 해석(Structure and Interpretation of Computer Programs. SICP로 줄여서 부르기도...)"의 2판입니다. 인사이트에서 내놓은 번역본입니다.

책을 받자마자 지하철 안에서 25페이지 가량을 읽어보았습니다. 이 책에 대한 평가가 칭찬 일색이라 첫 페이지를 넘기는 순간 뭔가 압도되는 느낌을 받지 않을까, 내심 기대를 했었습니다. 하지만 25페이지까지는 전혀 그런 기분을 느낄 수 없더군요. -_-; 왜 그런가 잠깐 생각을 해 봤는데... 적어도 28페이지까지 이 책은 여타의 C 책이나, 여타의 Java 책이나, 여타의 C++ 책이나, 여타의 Ruby 책과 전혀 다를 바가 없습니다. 사실 40페이지까지도 계속 그런 식입니다. Scheme(Lisp의 후손 쯤 되는)이라는 언어의 문법에 대해서만 설명하고 있거든요.

진짜 재미있는 부분은 41페이지 부터입니다. 책의 일부분을 잠깐 인용해보죠.

스스로 새로운 무언가를 만들어 내는 일을 할 때에는 언제나 그러하듯이, 프로그램 짜는 일을 하는 사람이라면 어떤 일을 하고 나서 어떤 결과가 나올지 머릿 속에 그려낼 줄 알아야 한다. 전문 사진작가가 되려면, 담고 싶은 장면을 잡아내는 눈이 있어야 하고, 노출이나 현상 조건에 따라 어떤 곳이 얼마나 나올지 미리 헤아릴 줄 알아야 한다. 그런 다음에야, 사진의 틀을 잡고 모자란 빛을 더하고 조리개를 맞추고 사진을 떠내는 따위 일을 어떻게 할지 계획을 세워, 바라던 효과를 얻어낼 수 있다. 프로그램 짜는 일도 이와 똑같다. 어떤 일을 하기 위해 어떤 프로세스를 밟아야 할 지 미리 정해놓으려고 짜는 게 프로그램이다. 그러므로 전문가가 되려면, 여러 가지 프로시저(절차)가 만들어 내는 프로세스(과정)을 미리 그려낼 수 있도록 공부해야 한다. 이런 기술을 깨닫고 익힌 다음에야 생각한 대로 돌아가는 프로그램을 어떻게 짜는 지 배울 수 있다.

돌이켜 생각해보건대, 제가 들었던 프로그래밍 언어 관련 수업에서 이런 말을 들었던 적은 단 한번도 없었던 것 같아요. 어떻습니까. 위의 한 단락만 봐도 이 책을 왜 읽어야 하는지, 느낌이 좀 오지 않으시나요?

하지만 이 책에는 여러가지 진입장벽이 있습니다. 우선 Scheme(혹은 Lisp) 라는 '생소한' 언어에 대한 알러지 반응이 그것이죠. 이 언어는 우선 널리 사용되는 언어가 아닙니다. C/C++/Java/Ruby 등등의 절차형 언어의 후손들과는 아주 다른 모습을 하고 있죠. 예전에 논문 자격시험 보겠다고 멋모르고 프로그래밍 언어 과목을 신청했다가 (지금 생각해보면 얼마나 오만한 선택이었던지 ㅋㅋ) Erlang이라는 언어를 일주일 만에 떼야 하는 난감한 상황에 처했던 적이 있었거든요. (Erlang이 Scheme과 아주 비슷합니다) Erlang[각주:1]이 제가 알던 프로그래밍 언어들과는 아주 달라서, 무척 혼이 났었습니다. 하지만 다르다는 것 뿐이지, Erlang이라는 언어가 다른 언어에 비해서 특별히 어렵거나 하지는 않습니다. 오히려 배워야 할 문법적 구성물들은 단순하고 간단한 편이죠. '뭔가 색다른 언어'에 대한 호기심이 왕성한 편인 독자라면, 이 책을 한번 읽어보는 것도 좋겠습니다.

사용자 삽입 이미지

두 번째 진입장벽은, 이 책에 담긴 내용들에 대한 '신화'에 가까운 부풀려짐이죠. 사실 이 책에 담긴 내용은 프로그래머라면 한번쯤 고민해봐야 할 그런 내용들에 불과합니다. 다만 어렵게 느껴지는 것은, 우리가 그동안 세상이 어떻게 돌아가는지를 살펴보느라 너무 바빠서 (돌이켜보면 세상은 얼마나 빠르게 변해 왔습니까? 웹 개발에 사용된 프로그래밍 언어만 따져봐도 bash, Perl, C/C++/Java, PHP, 그리고 최근에는 Ruby까지... 언어가 아닌 개발 프레임워크까지 계산에 넣는다면 JSP, Rails, Spring 등등...) 본질적인 문제들에 눈을 돌릴 여유가 없었기 때문일 거에요. 그러니 '프로그래밍의 본질'이 무엇인지에 대해 진지하게 성찰해보고 싶은 사람이라면, 이 책을 일독해 보는 것이 좋겠습니다.

+ + +

이건 어디까지나 사견입니다만, 저는 이런 책일 수록 화장실이 어울린다고 생각합니다. 화장실에 대한 세간의 선입견이 좀 드러워서 그렇지, 사실 화장실은 굉장히 고즈넉할 뿐 아니라 (뿌지직거리는 소리만 빼면), 세상사의 구질구질함에서 한발짝 비켜설 수 있는 유일한 공간이기도 합니다.

불가에서도 이야기하는 내용입니다만, 세상은 곧 우(곧, 근심)입니다. 따라서 세상사라는 것은 곧 근심의 원인이자 근심 그 자체일 수 밖에 없습니다. 그러니 불가에서 화장실을 해우소라고 부르는 것은 굉장히 의미심장합니다. 먹고 사는 문제는 사실 세상사와 밀접한 관련이 있거든요. 먹고 살려면 불가피하게 세상에 발을 담구게 됩니다. 불가도 결코 그런 문제에서 자유롭지 않죠. 그런데 유일하게 '화장실'에서는, 그런 먹고사는 문제(곧, 근심)를 버릴 수 있습니다. 어떻게? 배설을 통해서.

그러니까 저는 이런 책일 수록 화장실이 어울린다고 생각합니다. 세상사에서 한발 비켜서서 모든 근심을 버릴 수 있는 곳에서 (세상이 어떻게 돌아가건 상관하지 않으며) 오직 프로그래밍이라는 것의 본질적인 문제에 대해서 고민해 본다는 것, 멋지지 않습니까?

다만 한가지 유의할 점.

화장실에 너무 오래 앉아있으면 치질에 걸릴 수 있습니다.



  1. Ericsson에서 개발한, 선언적/함수형 프로그래밍 언어. [본문으로]
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^

  1. 서평 재밌게, 잘 보고 갑니다.
    저도 화장실에서 보는 책이 꼭 있는데 - 설득의 심리학 같은.- 화장실만큼 정말 집중 잘되고 머리에 쏙 들어오는 곳이 없더군요
    요즘은 게으름으로 인해, 지하철 출퇴근길에 책을 주로 읽습니다. 지금 읽고 있는 책 마치면 꼭 한번 읽어 보고 싶네요 ^^;

    2007.10.24 12:40 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 와주셔서 감사합니다. 저는 요즘 화장실에서 "솔라리스"라는 SF 소설을 읽고 있습니다. :-)

      2007.10.24 17:07 신고 [ ADDR : EDIT/ DEL ]
  2. emilie

    잘 봤습니다. 구해서 읽어봐야겠네요 ^^

    2007.10.25 14:42 신고 [ ADDR : EDIT/ DEL : REPLY ]
  3. 명저라길래 원서를 주문해놨습니다. 이제 보니 이 책은 곁에 두고 꾸준히 봐야 되는 것이었군요. 이거 화장실에서 꼬부랑 말을 접하면 응가도 곱게 나오지 않겠는데요. :)

    2007.10.25 22:46 신고 [ ADDR : EDIT/ DEL : REPLY ]