<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>F monologue</title>
		<link>http://blog.fguy.com/</link>
		<description>fguy 의 블로그입니다.</description>
		<language>ko</language>
		<pubDate>Fri, 05 Feb 2010 11:25:14 +0900</pubDate>
		<generator>Tistory 1.1 (http://www.tistory.com/)</generator>
		<item>
			<title>CodeIgniter 살펴보기</title>
			<link>http://blog.fguy.com/entry/CodeIgniter-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0</link>
			<description>&amp;nbsp;지금 근무중인 회사에서 Old type PHP 를 사용하고 있어, 이를 개선하기 위해 PHP MVC Framework 도입을 고려하던 중 CodeIgniter 가 긍정적이라는 팀원들의 의견을 듣고 살펴보고 사내 위키에 게시하였다. 다음 내용이 그것이다. &lt;br /&gt;
&lt;br /&gt;---------------&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;이 페이지는 본인이 CodeIgniter 를 처음 사용해보고 작성한 것으로, 
이해부족으로 사실과 다른 내용이 있을 수 
있다.




&lt;h1&gt;&lt;a name=&quot;126984b266edd480_장점&quot;&gt;장점&lt;/a&gt;&lt;/h1&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;div&gt;
 PHP4에서 사용가능하다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 오픈 소스이다. &lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 MVC의 기본 개념에 충실한 것 처럼 보인다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 비교적 단순하고 읽기 쉬운 소스 코드 구조.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 &lt;acronym title=&quot;Hypertext 
Preprocessor&quot;&gt;PHP&lt;/acronym&gt; 모듈이나 다른 라이브러리에 대한 의존성이 적다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 충실한 공식 한글 자료.&lt;/div&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/div&gt;&lt;h1&gt;&lt;a name=&quot;126984b266edd480_단점&quot;&gt;단점&lt;/a&gt;&lt;/h1&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;div&gt;
 PHP4 호환을 위해 PHP5의 좋은 특징을 충분히 수용하지 
못했다.&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;div&gt;
 객체 참조&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 OOP를 위한 Access Modifiers 
(public/private/protected)&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 Test 를 지원하기 위한 interface 사용의 부재&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 가장 아쉬운 것은 예외 처리. &lt;acronym title=&quot;Hypertext Preprocessor&quot;&gt;PHP&lt;/acronym&gt;
 의 원시적 오류 처리는 골치 아프다.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 자유롭지 못한 라이센스. 소스코드 수정과 배포에 제약이 따른다. 
(배포버전의 license.txt 중)&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;div&gt;
 Any files that have been modified 
must carry notices stating the nature of the change and the names of 
those who changed them.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 Products derived from the Software 
must include an acknowledgment that they are derived from CodeIgniter in
 their documentation and/or other materials provided with the 
distribution.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 Persistence Layer 의 애매 모호함.&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;div&gt;
 단순히 DB Helper Classes. DB를 은닉하지 못함.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 Persistence 관련 코드는 가이드대로 사용하게 되면 
지나치게 DBMS에 의존적이 된다. &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;div&gt;
 Java 진영의 JPA 나 .NET의 Nhibernate 의 
경우는 DBMS 와 완전히 독립적인 코드 생성이 가능하다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 DBMS 가 변경될 경우나 스키마가 변경될 경우 코드내에서 해당 
부분을 찾아 일일히 수정해야 한다.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 Active Record 는 &lt;acronym title=&quot;Structured Query Language&quot;&gt;SQL&lt;/acronym&gt;
 을 제거해 DBMS 에 종속적이지 않고, 
단순화하려고 했으나, 구현을 단순화하기 위해 결국 &lt;acronym title=&quot;Structured Query Language&quot;&gt;SQL&lt;/acronym&gt;
 을 사용하는 것과 동등한 수준의 종속성이 발생하고 단순화되지도 않아 이도 저도 아니게 되어 있는 모습&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 Binding 시 Place Holder 로 의미 있는 값을 
사용할 수 없다. 단순히 ? 사용..NET, Java 진영의 ibatis 와 비교&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 디버깅이 어렵다. 무슨 일이 일어나는지 일일히 찍어보지 않으면 알
 수 없다. &lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 PEAR 와 중복된 라이브러리. PEAR와 거의 동일한 수준의 
OO 적이지도 않은 똑같은 것(PEAR 역시 4.x 호환)들을 왜 만들어 둔 것인가. PEAR는 &lt;acronym title=&quot;Hypertext Preprocessor&quot;&gt;PHP&lt;/acronym&gt; 패키지에 기본 포함 되어 있으므로 중복을 피할 수
 없다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 IDE 환경의 부재. 단순히 PDT의 Template 을 제공할 
뿐. &lt;acronym title=&quot;Hypertext Preprocessor&quot;&gt;PHP&lt;/acronym&gt; 언어의 한계이기도 하다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 어설픈 I18N. Locale 에 관한 고려가 없다. 반드시 
언어를 코드레벨에서 선택해 주어야 한다. 브라우저의 헤더에 따른, 또는 GeoIP 에 따른 자동 지원은 불가능하다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 디스크 단위의 Cache 모델. 서버가 여럿일 경우 오버헤드 및 
동기화에 문제 있을 수 있음.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 Log 가 파일로만 출력된다. 마찬가지로 서버가 여러대일 경우 
데이터 취합에 문제.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 Dispatch 모델에서 코드 중복이 발생할 여지가 있다. 동일한
 Action 을 View 만 다르게 한다던지 할 경우 Mapping을 위해 Controller Class를 추가해야만 한다. &lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 View 와 Controller 이 coupled 이다. 이상적인
 MVC 모델은 Controller 는 화면에 표시되는 것에 대해 전혀 관여하지 않는 것이다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 View Layer 가 독립적이지 않다. &lt;acronym title=&quot;Hypertext Preprocessor&quot;&gt;PHP&lt;/acronym&gt;
 언어의 한계 일수도 있겠으나, 굳이 View 
Layer 가 아니어도 사용자에게 출력을 제공할 수 있으므로 통일감을 잃을 수 있고, 실수를 유발할 수 있다. echo, 
print 등.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 관점 분리에 대한 배려가 적다. 예를 들어 Form 
Validation 은 Business Logic 에 전혀 포함되지 않아도 될 것이다.&lt;/div&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/div&gt;&lt;h1&gt;&lt;a name=&quot;126984b266edd480_정리&quot;&gt;정리&lt;/a&gt;&lt;/h1&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;div&gt;
 한정된 용도의 작은 웹사이트 개발에 용이할 것 같다. 확장을 위해
 신경써주어야 할 부분이 많다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 &lt;acronym title=&quot;Hypertext 
Preprocessor&quot;&gt;PHP&lt;/acronym&gt; 언어의 특징을 잘 살린 가벼운 MVC Framework 이나, &lt;acronym title=&quot;Hypertext Preprocessor&quot;&gt;PHP&lt;/acronym&gt; 4 까지만이다. &lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;div&gt;
 &lt;acronym title=&quot;Hypertext 
Preprocessor&quot;&gt;PHP&lt;/acronym&gt; 창시자인 Rasmus Lerdorf 가 &lt;acronym title=&quot;Hypertext Preprocessor&quot;&gt;PHP&lt;/acronym&gt; Framework 사용을 반대하면서, 굳이 
사용하려면 CodeIgniter 를 사용하라고 한 것은 &lt;acronym title=&quot;Hypertext Preprocessor&quot;&gt;PHP&lt;/acronym&gt;
 Framework 를 아예 사용하지 말라는 것을 역설적으로 표현한 것은 아닐까 싶다. (지능적 안티)&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;</description>
			<category>CodeIgniter</category>
			<category>MVC</category>
			<category>php</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/42</guid>
			<comments>http://blog.fguy.com/entry/CodeIgniter-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0#entry42comment</comments>
			<pubDate>Fri, 05 Feb 2010 11:06:14 +0900</pubDate>
		</item>
		<item>
			<title>스노보드를 타다가...</title>
			<link>http://blog.fguy.com/entry/%EC%8A%A4%EB%85%B8%EB%B3%B4%EB%93%9C%EB%A5%BC-%ED%83%80%EB%8B%A4%EA%B0%80</link>
			<description>&amp;nbsp;
올 시즌들어 처음으로 스키장에왔다. 오는 길에 정말로 많은 걱정을 하였는데 그 이유는 올초에 당한 큰 사고(손목 자뼈 노뼈 골절) 때문에 내가 과연 탈 수 있을까하는 걱정에서였다. &lt;br /&gt;
지금까지 총 7번 중급과 상급 슬로프를 내려오면서 한번도 넘어지지 않았다. 걱정에서 쏟은 노력이 아까우리만치....&lt;br /&gt;
&amp;nbsp;올해로 3년째 스키장을 다니고 있는데(부상으로 2년간은 띄엄띄엄)   어떻게 내가 이만큼 탈 수 있었을지 생각해보았다. 아마도 좋은 장비 때문은 아닐 것이다. 내가 가진 장비는 20만원이 채 안되는 가격에 데크, 바인딩, 부츠가 한세트이다.&lt;br /&gt;
&amp;nbsp;그 답은 바로 모든 넘어지는 법을 익혀서가 아닐까한다. 난 정말 지독히도 운동신경이 없어 다른 사람의 100배라고 해도 좋을만큼 넘어지고 또 넘어졌다.  그렇게 수련하면서 더 이상 넘어질 수단이 없을만큼 익힌것이다.&lt;br /&gt;
&amp;nbsp;이러한 경험은 비단 스노보드에서만은 아니다. 소프트웨어 개발에서도 우린 단단한 코드를 만들 수 있는 경지까지 이르려면 수많은 실패의 반복이 필수이다.&lt;br /&gt;
&amp;nbsp;TDD는 계속된 실패속에 답을 찾는 과정이다. 실패하는 코드를 먼저 작성하고 그것을 바르게 동작하도록 만드는 반복. 그 속에서 코드는 점점 견고해지는 것이고, 버그 없는 우수한 품질의 코드가 나오는 것이다. 다행히 TDD를 하는데는 스노보드를 연마하는 것처럼 고통을 수반하지는 않는다. &lt;br /&gt;
&amp;nbsp;아직 TDD를 시작하지 않았다면 이제라도 달리 생각해보자. 코드를 작성해나갈 수록 스노보드를 실수없이 타는 것만큼의 상쾌함을 느낄 수 있을 것이다.&lt;br /&gt;
&lt;br /&gt;- 곤지암리조트 슬로프 아래에서&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;img src=&quot;http://cfile6.uf.tistory.com/image/2074EA144B24504B7537A6&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
iPhone 에서 작성된 글입니다.</description>
			<category>TDD</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/40</guid>
			<comments>http://blog.fguy.com/entry/%EC%8A%A4%EB%85%B8%EB%B3%B4%EB%93%9C%EB%A5%BC-%ED%83%80%EB%8B%A4%EA%B0%80#entry40comment</comments>
			<pubDate>Sun, 13 Dec 2009 11:24:12 +0900</pubDate>
		</item>
		<item>
			<title>1분 경영을 읽고</title>
			<link>http://blog.fguy.com/entry/1%EB%B6%84-%EA%B2%BD%EC%98%81%EC%9D%84-%EC%9D%BD%EA%B3%A0</link>
			<description>&lt;a href=&quot;http://books.google.co.kr/books?id=3EmDMwAACAAJ&amp;amp;dq=1%EB%B6%84%EA%B2%BD%EC%98%81&amp;amp;ei=VXQTS-4GnIyQBO718IwM&quot; target=&quot;_blank&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfs15.tistory.com/image/34/tistory/2009/11/30/16/27/4b1373f38794f&quot; alt=&quot;사용자 삽입 이미지&quot; height=&quot;400&quot; width=&quot;270&quot;/&gt;&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;유능한 경영이란 무엇인지를 찾는 청년의 이야기를 통해 1분 경영의 방법을 전달 받을 수 있었다. &quot;1분 경영&quot;이란 1분이라는 상징적인 시간 만큼, 최소한의 노력으로 유능한 부하 직원의 능력을 신뢰하고 이를 최대한으로 이끌어 내는 경영방법을 말한다.&lt;br /&gt;나는 이 &quot;1분 경영&quot; 에 대해 찬사들로 가득차 있는 서평과 추천사와는 달리 조금은 비판적인 시각으로 접근해 보고자 한다. 책은 전반적으로 세 가지의 1분 비법으로 존경 받는 상사가 되는 법에 대해 서술하고 있다. 세가지 비법이란 1분 목표, 1분 칭찬, 1분 질책을 말한다. &lt;br /&gt;먼저 &quot;1분 목표&quot;의 내용 자체는 매우 훌륭해 보인다. 실행 가능한 단순 명료한 목표설정에 대해서는 전혀 이견이 없다. 관리자는 부하직원이 스스로 목표를 정할 수 있게끔 이끌어 주는 역할만 가지는 점도 좋다. 아마도 책의 내용을 단순화 하기 위하여 언급하지 않았겠지만, 아쉬운 부분이 몇가지 있다. &lt;br /&gt;첫째로 목표에 대한 가변성이다. 목표 자체는 업무의 방향성을 갖게해주는 목적이기때문에 가급적 변하지 않는 것이 중요하겠지만, 21세기 비지니스의 대부분이 시장상황에 따라 매우 유동적이기 때문에 이것에 대한 배려가 아쉽다. 그 다음은 목표 설정에서 팀에 관한 내용이다. 개인의 목표 설정도 물론 중요하지만, 개인의 한계를 초월하는 팀플레이에 대한 목표는 팀 구성원간의 협의가 반드시 필요하기 때문이다.&lt;br /&gt;&quot;1분 칭찬&quot;과 &quot;1분 질책&quot;은 비록 두가지로 나뉘어 있지만, 의도하는 바는 동일하다고 생각한다. 업무 태도에 대한 평가가 즉각 이루어짐으로서 부하직원이 목표를 달성하는 데 있어 진심으로 격려하는 것이다. 나는 다시 한 번 팀의 관점에서 생각해보게 되는 데, 이는 팀 단위의 회고에서 이루어지는 것이 어떨까 한다. 관리자가 의견을 전달하는 것도 도움이 되겠지만, 팀 전체의 의견은 보다 입체적이고 객관적일 수 있기 때문이다. &lt;br /&gt;이 책은 주로 관리자의 입장에서 쓰여져 있다. (본문에서도 언급되어 있듯이 manager는 경영자이기도 하나 관리자라는 의미도 있다. 실은 관리자라는 의미가 맞을 테지만, 아마도 흥행을 위해 경영이라는 억지 번역을 넣은 것 같다.) 우리 회사에서 나에게 이 책을 권한 것은 세월의 흐름에도 변함없는 진리가 담겨 있기 때문일텐데, 그럼에도 불구하고 약간의 부족한 부분이 보였다. 타사 입사시 비슷한 목적으로 교부 받아 읽게 되었던 동 저자의 &quot;겅호!&quot;나 &quot;펄떡이는 물고기처럼&quot;에서 그 부분에 대해 알고 있었으므로, 결과적으로 나에게는 큰 도움이 되었다.&lt;br /&gt;1분 경영에서는 유능한 직원이 제 능력을 발휘하기 위해 관리자의 간섭을 최소화하자는 의도가 보이는 데, 실은 이러한 것들을 극단적으로 경험해 본 적이 있다. 나는 아예 상하관계가 전혀 없는 조직에서 일해 본 적이 있다. 관리자의 역할이 거의 없었음에도 불구하고, 많은 성공을 이룰 수 있었던 원동력은 유능한 동료 간의 협력이 부족함을 채우고도 남을 정도였기 때문이다. 최근 많은 회사에서 수평조직문화 체계를 도입하고 있는데, 1분경영에서 얻을 수 있는 자기 관리를 위한 프랙티스는 이러한 조직에서도 유효할 정도로 유용해 보인다.&lt;br /&gt;&lt;br /&gt;</description>
			<category>켄블렌차드</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/39</guid>
			<comments>http://blog.fguy.com/entry/1%EB%B6%84-%EA%B2%BD%EC%98%81%EC%9D%84-%EC%9D%BD%EA%B3%A0#entry39comment</comments>
			<pubDate>Mon, 30 Nov 2009 16:30:33 +0900</pubDate>
		</item>
		<item>
			<title>프로그래머가 되기까지...</title>
			<link>http://blog.fguy.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EA%B0%80-%EB%90%98%EA%B8%B0%EA%B9%8C%EC%A7%80</link>
			<description>&lt;span style=&quot;font-weight: bold;&quot;&gt;취직&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
2000년 3월. &lt;br /&gt;
 나는 이제 막 3학년이 된  대학생이다. 실업계 고등학교를 중간 정도 성적으로 출석일수가 모자라 간신히&amp;nbsp; 졸업한 것 치곤, 비록 명문은 아니지만 4년제 대학교에 진학한 것을 다행이라 여기며 재학중이다. 그런데, 지금 상황이 좋지 않다. 직전 학기에는 한과목을 제외하곤 모두 F 학점을 받아 학사경고를 받았고, 수강신청은 했지만 등록금을 마련하지 못해서 수일 내로 등록을 하지 못하면, 이번 학기는 휴학을 해야 할 판이다. 하지만, 그간 학비로 사용하기 위해 이미 대학생 신분으로 대출 할 수 있는 한도까지 모두 끌어쓴 상황이다. 군대를 갈까도 생각 중이지만, 가출한 동생과 사업 부도로 고생하시는 아버지를 생각하면 그 것도 내키지 않는다. 아버지는 며칠째 집에 안들어오시고, 차비가 없어 집밖으로 나가지 못하고 있다. 배가 많이 고프지만 먹을 것이 없어, 이 곳, 50년도 더 된 남부민동 달동네 슬레이트 지붕 밑에서 몇 시간째 누워 있는 건지도 모를 만큼 멍하니 천장만 바라보고 있다. 낮이 지나고 잠 못드는 밤이 지나 다시 아침... 핸드폰이 울린다. 핸드폰 요금이 연체된 지 꽤 됐는데 아직은 안끊겼나 보다. &lt;br /&gt;
&lt;br /&gt;
 &quot;여보세요?&quot;&lt;br /&gt;
 &quot;안녕하세요. 중앙정보기술의 김성수 이사라고 합니다.&quot;&lt;br /&gt;
&lt;br /&gt;
중앙정보기술? 국가기관인가? 나한테 왜 전화한 걸까...&lt;br /&gt;
&lt;br /&gt;
 &quot;이번에 우리 회사에서 자바로 채팅 서비스를 만드는데, 아르바이트 해 볼 생각 없으신가 해서 전화드렸어요.&quot;&lt;br /&gt;
&lt;br /&gt;
회사였군. 그런데, 난 넷츠고에서 채팅을 해본적은 있어도 그걸 어떻게 만드는지는 전혀 아는바가 없었으며 프로그래밍이라곤 학교에서 C언어를 해본게 전부였다. C언어의 학점은 C0를 받았고 아마 내가 최하점이었을거다. 자바라면 HTML에 들어가는 자바(당시엔 자바스크립트와 자바가 다른 것인지 몰랐다.)를 복사해서 붙여넣기 해본 적이 있는 경험이 다였다.&lt;br /&gt;
&lt;br /&gt;
 &quot;저... 죄송한데, 저 그런거 할 줄 모릅니다.&quot;&lt;br /&gt;
 &quot;제가 강태훈씨 홈페이지를 봤는데 충분히 하실 수 있습니다. 단도직입적으로 말씀드리죠. 300만원 정도 드릴테니 한 번 해봅시다. 섭섭지 않은 금액일겁니다.&quot;&lt;br /&gt;
&lt;br /&gt;
그렇다. 300만원은 큰 돈이고, 난 무척이나 돈이 필요하고 무조건해야 할 것 같다. 홈페이지라면 1학년 2학기에 수업을 들으며 과제로 만들어 둔 개인신상에 관한 홈페이지 (야후에 사이트 등록)인데.. 거기에 적어둔 전화번호를 보고 연락한 것이었구나.&lt;br /&gt;
&lt;br /&gt;
 &quot;네. 그럼 해보겠습니다.&quot;&lt;br /&gt;
 &quot;그럼, 내일 오전 10시에 엄궁에 있는 부산벤처빌딩 207호에서 보겠습니다.&quot;&lt;br /&gt;
 &lt;br /&gt;
통화는 3분도 안걸렸고, 난 돈 벌 기쁨을 만끽하기도 전에 피곤해서 잠이 들었다. 저녁 늦게 깨서 긴장한 탓에 또 밤을 샜고, 옆집에 사는 동생에게 차비를 빌려 집을 나섰다. 외진 곳에 있어 찾긴 힘들었지만 제 시간보다 30분 정도는 일찍 도착해 입구를 서성였는데, 안경을 끼고 노인과 같은 인상의 경비쯤으로 보이는 아저씨가 나에게 말을 건냈다. 자신은 이 곳에 면접을 보러 온 사람인데 혹시 나도 그러하냐고 물었다. 이 아저씨는 나보다 다섯 살이 많은 이봉호씨. 일종의 면접은 한달정도 작업할 채팅사이트에 대한 개요만 듣고 별다른 질문 없이 통과하였고, 우린 다음주부터 출근하기로 하였다. 봉호씨는 정규직으로, 나는 아르바이트로...&lt;br /&gt;
&lt;br /&gt;
2000년 3월 27일. 첫 출근 날이다. 회사의 사정으로 채팅 건은 물건너 가게 되어, 이왕 이렇게 된 것 입사하는 것이 어떠냐는 제안을 받았다. 월급 50만원의 계약서를 보고 당황했다. 금액이 적어서가 아니라 등록금을 해결해 줄 수 있는 300만원의 금액은 아니었기 때문이다. 사장님께 상황을 설명 드렸더니, 파격적인 제안이 들어왔다. 이번 학기 등록금을 내줄테니 당장 계약서에 사인하라는... 얼떨결이었지만, 너무나 기뻤고 그간의 괴로움은 한번에 아주 작은 기억으로 사라져버렸다.&lt;br /&gt;
고용계약서를 작성하고, 곧바로 학교로 향했다. 직장생활을 하려면 휴학을 해야 되기 때문이다. 담당 교수님이신 손영선 교수님께 취직이 되었으니 휴학을 부탁한다고 말씀드리니, 너같은 꼴통이 무슨 취직이냐. 지금 사기당하는 것 아니냐. 라는 반응이었지만, 휴학계를 제출하고 왔다.&lt;br /&gt;
이렇게 해서 인원 10여명정도의 작은 회사인 중앙정보기술에서 나의 직장 생활은 시작되었다.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;서울로...&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;
 
&lt;/span&gt;&lt;/span&gt;입사는 했지만 아무것도 할 줄 아는 것이 없었다. 어디서 시작해야 할 지 감 조차 잡을 수 없었다.나보다 3개월정도 먼저 입사한 정원희(현. 유엔젤 과장), 김두성씨가 나에게 객체지향과 소프트웨어 공학 그리고 자바에 대해서 알려주려고 한달 정도 시도했지만, 기초가 전혀 없던 나에게는 무리였기에 결국 포기하고 나는 HTML 만 맡기로 하였다. &lt;br /&gt;
입사 한 지 1개월쯤 지나, 나와 원희씨, 두성씨, 디자이너인 전성현(훗날 NHN 동료)씨, 최대리, 전병관대리, 박연석 과장은 한달 계획으로 서울사무실로 출장을 가게 된다. &lt;br /&gt;
공군 KTX 전자교범 시안을 제작하기 위해서 간 것으로 기억되는데, 지금 생각해보면 굳이 서울로 갈 필요는 없었지 싶다. 아마도 회사 입장에서 투자를 유치하기 위해 서울에 사무실을 두는 것이 유리해서 였을 것이다. &lt;br /&gt;
 중앙정보기술 서울 사무실의 위치는 삼성동 테헤란로에 있는 대종빌딩 (포스코센터 맞은편)이었다. 앞에는 마이크로소프트와 드림위즈, 뒤로는 오라클, 컴팩 이 있는 닷컴붐의 중심지였던 것이다. 그 전까지 그저 등록금에 만족하고, 50만원 소득의 감동에 젖어 있었던 나는 이 곳에 있다는 사실만으로, 테헤란로에서 살아남고 싶다는 꿈을 가지게 된다. 비록 퇴근 후에는 8명이 10평남짓의 지하 원룸에서 합숙하고 있는 동남아 노동자 수준의 생활을 하고 있었지만...&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfile23.uf.tistory.com/image/1247C11F4ACC2910530837&quot; alt=&quot;&quot; filemime=&quot;&quot; filename=&quot;cfile23.uf@1247C11F4ACC2910530837.jpg&quot; height=&quot;204&quot; width=&quot;234&quot;/&gt;&lt;p class=&quot;cap1&quot;&gt;브레인업그레이드 &lt;/p&gt;&lt;/div&gt;&lt;br /&gt;
 
KTX 전자교범 시안은 결국 제안이 탈락해서 진행할 수 없게 되었고,&amp;nbsp; Brain Upgrade라고 이름 붙여진 새로운 프로젝트를 진행하기 위해 출장을 연기하였고, 이후로 퇴사일까지 서울에 머물게 되었다. 이 프로젝트는 당시 유행처럼 번지던 KMS (Knowledge Management Service) 를 ASP (Application Service Provider)로 제공하는 것이 목적이었는데, 우리는 특이하게 Web OS 형태의 UI로 서비스하려고 계획했다. 나는 여기서 바로 이 Web OS UI 를 구현하는 것을 맡았다. 지금에서 고백하는 데 이 UI는 webos.com 의 것을 거의 그대로 베낀 것이었다. JScript 와 HTC, CSS의 조합이었는데 현재의 Ajax 웹서비스와 비슷한 컨셉이었다. 이때의 경험이 현재까지도 나를 Java Script 전문가 (Lycos, USA 의 Leo. Shin 님께서 인정)로 유지시켜 주고 있다. 당시에는 내가 하고 있는 일이 얼마나 고난이도의 것인지를 알지 못하고, 그저 다른 사람들이 JSP로 서버사이드의 구현을 하는 것을 동경했었다. &lt;br /&gt;
 아직 시장에 출시되진 않았지만 그 해 8월, 바른손 그룹에서 이 프로젝트의 가능성을 높이 사서 우리 회사는 대단한 규모의 펀딩을 받게 된다. &lt;br /&gt;
 이후, 사명을 센트럴에스티(Central System Technology, 결국 중앙정보기술의 영문 버전 정도)로 개명하고 사무실은 좀 더 큰 곳인 바로 옆의 본솔빌딩 (이곳은 포스코 센터와 더 정면으로 맞은편)으로 옮기게 되었고 직원 수는 이후 200여명 까지 늘어나게 되었으며, 나는 연봉이 4배 정도까지 오르게 되었다. 그리고 이 시기에 지금의 와이프를 만났다.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfs14.tistory.com/image/2/tistory/2009/10/07/13/30/4acc196b6fbc6&quot; alt=&quot;이두만&quot; height=&quot;172&quot; width=&quot;210&quot;/&gt;&lt;p class=&quot;cap1&quot;&gt;센트럴에스티의 이두만 사장(오른쪽)&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;
 그렇지만, 경영진의 판단으로 브레인업그레이드는 시장에 출시하지 않고 사업을 다각화하다가 2001년 말쯤엔 투자금을 모두 날려버리고, 나는 약 3개월 동안 월급을 받지 못하다가 결국 회사를 떠나게 되었다.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;어헤드모바일&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
 내 월급 중 내 생활비를 제한 대부분은 대출금을 갚고, 가족의 생활비로 쓰였기에 저축해 둔 돈이 전혀 없어서 임금 체불은 치명적이었다. 차비가 없어서 능동 자취집에서 회사까지 걸어가기도 하였으며, 점심값이 없어 매일 삼각김밥과 컵라면만 원희씨에게 얻어먹고 있었다.&amp;nbsp; 아버지가 부산에서 사고를 당해 큰 수술을 할 때도 찾아갈 수 없었을 정도. &lt;br /&gt;&lt;br /&gt;
 결국 버틸 수 없어 이직을 결심하였다. 출근하여 신문을 펼쳤는데, 조선일보인터넷 대상 수상작들에 대한 내용이 있었다. 모바일 인터넷 부문 대상을 수상한것이 &quot;어헤드모바일&quot;의 &quot;친구찾기&quot;서비스였다. 당시 모바일 인터넷이라는 것이 웹 이후의 트렌드로 부상하고 있었기에 이것이구나 싶었다. 닷컴버블이 한창일 시기였기 때문에 더 좋은 대우로 갈 수 있는 곳이 있었으나 (프리챌에서도 러브콜이 있었다.), 나는 도전을 택하기로 했다. (그리고, 그동안 바로 앞에 있으면서 동경해온 포스코 센터에서 일하고 싶은 마음도 컸다.)&lt;br /&gt;
 LBS(Location Based Service, 위치기반 서비스) 중심의 회사였기 때문에 나는 그것을 할 수 있을 것이라 생각했으나, 기대와는 달리 첫 프로젝트로 LG텔레콤의 VOC (Voices of Customer)를 맡게 된다. 당시 어헤드모바일의 대표였던 이양동 사장은 LG인터넷의 CEO이기도 했기 때문에 LG텔레콤과 특수관계에 있어 이러한 프로젝트를 얻게 되었다. ASP 와 MS-SQL 기반의 웹 사이트를 개발하는 것이었는데, taeyo 사이트의 도움으로 간신히 모양은 갖출 수 있었다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;이후에도 LBS가 아닌 VOC와 비슷한 성격인 LG 텔레콤의 CSR이라는 프로젝트를 맡았다. 이번에는 LG텔레콤 사무실에 상주하며 개발하며, 좀 더 강도 높은 기술 수준이 요구되었는데, 기존의 아주 느린 오라클 기반 서비스를 개선해야 하는 것이었다. 사실 DB 모델링을 정식으로 해본 것은 그때가 처음이었는데, 센트럴에스티에서 다른 동료들이 ER-Win을 사용하는 것을 곁눈질 한 적이 있어, 그 때의 프랙티스를 적용해보았다. 그저 그런 수준의 정규화만 는데도 결과는 대성공이었다. 4~5초 걸리던 조회는 0.0x 초 대에 해결이 되었고, 이 일을 계기로 나는 어헤드모바일에서 두터운 신뢰를 얻게 되었다. 그 신뢰가 어느 정도 였냐면 내가 추천한 지인들이 있는데, 강혜진(고등학교 선배. 대학교 동기. 현. LG데이콤 대리)씨는 무면접으로 통과, 센트럴에스티에서 좀 더 고생하시던 정원희씨 또한 별다른 절차 없이 입사할 정도 였으며, CSR 프로젝트가 완료된 시점에서 사장님이 전직원을 모아두고, 앞으로 몇달치 월급은 강태훈씨가 벌어준 것이라며 축하해주기도 하였다.&lt;br /&gt;
 원희씨는 이 때도 새로운 기술에 대해서 공유하고, 또 내가 부족한 지식들에 대해 힌트를 주는 등 나에게 많은 도움을 주었는데, 지금 돌이켜보면 센트럴에스티의 동료들은 드림팀이라고 할 수 있을 정도로 기본적인
기술 수준과 배움에서 아주 뛰어났던 것 같다. 그저 그들과 함께 했던 것만으로도 나는 성공을 경험했으니...&lt;br /&gt;&lt;br /&gt;&amp;nbsp;
 CSR 프로젝트에서는 어두운 면도 있었는데, 바로 나의 경력을 속이고 일을 했던 것이다. 얼마 지나지 않아 LG텔레콤 직원에게 아직 학교를 졸업하지 않았음이 들통났을 때는 심한 소리를 듣기도 하였으며, 고졸, 전문대 출신들이 차별 받는 것을 목격하면서 대기업에서 학력의 벽이 얼마나 큰 지 실감할 수 있었다. &lt;br /&gt;&amp;nbsp;결국 나는 그간 간과했던 학사 학위라는 것의 중요성을 깨닫고, 최대한 빨리 졸업을 하기로 마음먹었다. 우리 학교는 산업대학교였기에 산업대학교간 전학이 자유로웠다. 서울산업대로 전학을 하려고 했는데 마침 그 학기 부터 주간학생이 야간으로 전학이 안되는 규정 때문에 계획은 실행할 수 없게 됐다. 주간으로 학교를 다니게 되면 생활비를 감당할 수가 없으니까...&lt;br /&gt;&amp;nbsp;&lt;br style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;부산으로...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;병역특례로 일하던 나는 LG텔레콤에서 불법파견 근무가 적발되어 이직을 명령 받게 된다. 이것이 기회다 싶어 2002년
2학기가 시작한 지 조금 지나 복학을 하였다. 이직 기간으로 6개월이라는 여유가 주어지기 때문에 그동안
한학기라도 마치며 부산에서 직장을 구할 생각이었다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;부산으로 향하게 된 더 큰 이유가 있는데, 몇달 전에 어릴 적에 경제적인 이유 때문에 떨어져 사시던 어머니가 돌아가시게 되었다. 어릴 적도, 또 당시까지도 무척이나 어렵게 살아왔지만 나를 잡아주었던 버팀목이 되주었던 어머니이다. 우리가 가난해서, 또 희망이 없어서 우릴 떠난 어머니에게 부끄럽지 않은 모습으로 당당히 성장한 나의 모습을 보여주며 당신의 품으로 돌아가리라고 마음 먹고 있었고, 이젠 그 모습에 다가갔다 생각 했을 때 쯤 세상을 떠나셨기에 나의 상실감은 이루 말할 수 없을 정도 였다. 나중에 안 사실인데 어머니 또한 경제적으로 기반을 다지신 뒤에 우리를 찾기 위해 식당 잡부에서 식당 주인이 되기까지 밤낮없이 일하셨다고 한다. 돌아가신 시점이 이제 막 어머니의 식당을 갖게 되어 개업하기 직전이었다. 그리고 동생과는 연락이 막 닿았고 나의 행방도 수소문하고 계셨고... 이러한 일을 겪었기에 남은 가족들의 소중함을 되새기며 그들과 함께하기 위해 부산행에 힘을 실었다.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;3년의 직장 생활을 거치면서 외형적으로는 많은 성장을 하였지만, 내가 느끼기에 달라진 것은 거의 없었다. 여전히 머릿속은
텅비어있고, 첫걸음때 처럼 남에게 의지하고, 스스로는 아무 것도 하지 못하며, 그저 운이 정말로 좋았고 치부를 들키지 않으며,
살얼음판을 걷듯이 간신히 살아남을 수 있었을 뿐이었다.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;복학한 학교는 신세계였다. 1, 2학년을 지나는 동안 열등생으로서 F학점을 면하는 정도에 만족하던 내가 별다른 노력 없이도 수업을 따라 갈 수 있다는 것에 놀랐다. 직장 생활을 하는 동안 그 때 그 때 위기를 면하기 위해 주워 듣고 익힌 것들이 이론적으로도 뒤떨어지는 것이 없다는 사실에 고무되었고, 내 인생의 키워드라 할 수 있는 &quot;자신감&quot;을 이 시기에 처음으로 만날 수 있게 되었다. 물론 내가 잘할 수 있는 과목(데이터베이스, Unix, Java 등)만 선택한 것이 작용했겠지만...&lt;br /&gt;&lt;br /&gt;&amp;nbsp;그렇게 한 학기를 마치고 겨울이 지나고 다시 봄이 오려고 하는 무렵. 아직 이직할 곳을 찾지 못했다. 서울과 부산은 나 같은 일을 하는 사람에겐 너무나 다른 환경이었다. 서울이 기회의 땅이라명 부산은 황야라고나 할까... 어딜가도 월급 100만원 이상 주겠다는 곳은 없었고, 심지어는 병역특례니까 무임금으로 일해 달라는 곳도 있었다. 그래도 계산해 보니 월급 100만원이면 학비와 생활비 정도는 감당될 것 같아 이직 만료 시한 막바지에 아슬아슬하게 부산 대연동 남구청 앞 얼핏 보면 빌라 주택같은 3층 건물에 위치한&amp;nbsp; &quot;애드뱅크&quot;라는 곳을 선택했다. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;애드뱅크&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;애드뱅크가 하는 일은 홈페이지 구축이었다. 출판물 디자인에서 출발한 회사로 인터넷 사업을 본격화한지는 얼마안 된 아주 자그마한 회사. 너무나도 가족적인 분위기에 감탄했는데, 정말로 가족이 운영하는 회사라는 건 조금 지나서 알게 되었다. 입사 면접 시에 보통 회사 와는 다른 전형 절차가 하나 있었는데,&amp;nbsp; 건물 한층 아래 맥주 집에서 취중면접을 하는 것이었다. 그만큼 회사가 인간적인 면모에 가치를 두었다.&lt;br /&gt;&amp;nbsp;나는 여기서 처음으로 내가 일을 주도하는 경험을 하게 된다. 프로그래머가 2~3명이긴 했지만 각자 맡는 일이 달랐기 때문에 개인에 주어진 프로젝트에서 프로그래밍 부문은 모두 전담해야 했기 때문이다. 그리고 프로그래머 수가 적었기 때문에 기술 전문가로서 협상에 참가할 수 있는 기회도 주어졌는데, 이 또한 다른 곳에선 할 수 없었던 경험이었다.&lt;br /&gt;&amp;nbsp;앞서의 회사에서 한 일들에 비하면 사소할 수도 있지만, 내가 주도권을 쥐고 다양한 시도와 개선을 할 수 있었던 점은 아주 값진 것이었고 훗날의 내 모습에 많은 변화를 가져다 준 계기가 되었다.&lt;br /&gt;&amp;nbsp;2004년 3월 20일 병역특례 복무만료가 되면서 회사를 떠나기로 하였다. 애드뱅크의 사장님은 나에게 박사학위까지의 학자금 지원과 연봉 250%인상등의 좋은 조건을 제시해주셨으나, 작은 현실에 만족하기엔 내 열정의 그릇에 맞지 않았기에 인사를 건내게 되었다.&lt;br /&gt;&amp;nbsp;애드뱅크를 맘편히 떠날 수 있었던 것은 재직 중 입사한 윤일(Ray yoon, 현. Yahoo!)씨가 프로그래머로서 굉장히 뛰어난 역량을 가지고 있었기 때문에 별 걱정없이 떠날 수 있었다.&lt;br /&gt;&amp;nbsp;윤일씨는 이후에도 계속 연락을 유지하며 지내고 있고, 신기술에 대한 얼리어댑터로서 본받을 점이 많은 분이다.&amp;nbsp; 이야기하는 김에, 애드뱅크에서 만난 한영훈(현. NHN)씨도 열정으로 가득찬 모습으로 나를 자극하고 감동받게 해주었던 기억을 전한다. 이전에 성인물을 다루는 음지의 회사에서 양심적으로 일하기로 마음먹고 &lt;br /&gt;&amp;nbsp;애드뱅크에 재직하는 동안에는 아무도 모르게 (그만큼 회사 일에 소홀하지 않았다는 이야기) 야간에 수업을 들어서, 퇴사 후에는 마지막 학기를 맞이할 수 있었다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;다음커뮤니케이션&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;지금까지 조금 지루한 과거사였다면, 이제부터가 나의 프로그래머서의 인생이 본격적으로 시작되는 시점이다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;마지막 학기는 몇학점 남겨놓지 않은 상황이고 졸업논문은 이미 다 써두었기 때문에 학기가 끝나는 시기에 맞추어 취직하고자 마음먹었다. 어헤드모바일로 다시 돌아갈까 하는 생각도 해보았지만, 재직중인 직원분으로부터 분위기가 좋지 않다라는 이야기를 듣고, 이왕 이렇게 된 것 신입의 마음으로 넓게 생각하고 다양하게 도전 해보고자 계획했다. 마침 대기업의 공채도 활발하고 해서 나는 여러 군데 입사지원을 하기로 한다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;대기업의 필수 조건은 토익이라고 해서 마음먹은 즉시 원서를 접수했는데, 이전의 모의고사에서 300점도 안되는 점수가 나왔기 때문에 첫시험에서 별다른 기대를 하지 않다가 정확히 600점이라는 점수를 받고서 대기업 지원의 자신감을 갖게 되었다. (당시 대부분 회사는 토익 점수 600점이 커트라인)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;내가 신입/경력 가리지 않고, 입사 원서를 넣은 곳은 1,000곳 정도 될 것이다. 국내에서 이름 들어보았을 모든 회사에는 빼놓지 않고 모두 지원했다. 그 결과, 서울에서 면접을 보기 위해 부산에서 서울까지 KTX 기차와 고속버스를 몇번을 탔는지도, 찜질방에서 며칠을 보냈는지도 기억나지 않을 만큼 많은 곳에 면접을 볼 수 있었다. 심지어는 하루에 4군데 면접을 보기도 했을만큼...&lt;br /&gt;&lt;br /&gt;&amp;nbsp;하지만&amp;nbsp; 합격한 곳은 단 두 곳. 먼저 발표 난 곳이 LG 전자였다. 여의도의 쌍둥이 빌딩에서 홈오토매이션 분야에서  일할 수 있는 기회였는데,  합격 소식을 전해들은 우리과 권순량 교수님께서는 만약 LG전자에 입사하면 학교 입구에 플래카드를 걸어주겠다는 약속까지 해주셨다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;그렇지만 아시다시피, 결국 난 다음커뮤니케이션을 선택하게 되었다. 그동안 웹 관련 분야에 종사해오면서 (적어도 내가 보기엔) 그 분야에서 기술적으로 다음이 가장 앞서 있었기에 동경해 왔고 , &quot;즐겁게 세상을 변화시키자!&quot; 라는 목표아래 즐겁게 일할 수 있는 다음이 나에게 더 맞을 것이라 생각되어 그런 결정을 내리게 되었다. 이 회사에 합격한 것은 그야말로 행운이었는데, 앞서도 여러번 이야기 했듯이 나는 정말 평균이하의 실력을 가진 둔재였기 때문이다.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;서류 통과를 의아하게 생각하며, 면접을 보기 위해 역삼동 데이콤빌딩에 있는 다음커뮤니케이션을 찾았다. 말끔한 대기실에 앉아 음료수를 마시며 면접관을 기다는 중, 앞에 있는 다음검색엔진 제품 포스터를 보고 있었다. 당시 검색엔진은 독일기술의 &quot;파이어볼&quot; 이라는 제품이었는데, 속으로 &quot;검색엔진 이름이 파이어볼? 불.....알? 하하..&quot; 하며 깔깔대고 있던 차에 면접관이 와서 당황한 나를 맞이한 건 유지형 팀장님. 면접실로 이동하여, 전형을 시작했다. 시험을 볼 것이란 얘긴 없었는데, 갑자기 시작하겠다며, 문제지를 꺼내는 지형님 (다음은 수평조직문화를 가지기 때문에 이름+님 의 호칭으로 부른다.). 조금은 당황하였지만, 그래도 짧으나마 경력도 있고, 전공자이기 때문에 어렵지 않게 통과할 것이라 예상했다. 문제는 자바 기초에 관한 것이 대부분이었는데, 예를 들면, 추상클래스와 인터페이스의 차이, syncronized 키워드, thread 에 관한 것들 등. 분명히 다 배웠던 것이고, 2001년에 SCJP자격증(이것도 행운)도 땄음에도 불구하고 내가 받은 점수는 &quot;0&quot; 점이었다. 단 한문제도 풀지 못한 것이다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;당연히 떨어진 줄 알았는데, 합격이라니... 아직도 내가 왜 합격하게 됐는지 모른다. 지형님께 어렵게 물어봤는데, 그저 열심히 하라는 말씀만 해주셨다. 후에 보게된 드라마 &quot;신입사원&quot;에서 얼마나 공감을 느꼈는지.... &lt;br /&gt;&lt;br /&gt;&amp;nbsp;무언가 오류가 있었을 지도 모르지만, 난 기회를 놓치지 않으려고 지금까지의 나와는 180도 달라진다. &lt;br /&gt;</description>
			<category>인생</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/38</guid>
			<comments>http://blog.fguy.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EA%B0%80-%EB%90%98%EA%B8%B0%EA%B9%8C%EC%A7%80#entry38comment</comments>
			<pubDate>Wed, 07 Oct 2009 13:51:00 +0900</pubDate>
		</item>
		<item>
			<title>켄트 벡과의 만남</title>
			<link>http://blog.fguy.com/entry/%EC%BC%84%ED%8A%B8-%EB%B2%A1%EA%B3%BC%EC%9D%98-%EB%A7%8C%EB%82%A8</link>
			<description>지난 수요일 저녁 8시에 강남역에서 xper에서 마련한 켄트벡과의 자리에 참가하게 되었다. 평소 xper news group 에서 많은 것을 얻고 있지만, 적극적으로 참여하지는 않았기에 이런 모임이 다소 어색하기도 했지만, 켄트벡을 만난다는 기대에 이내 즐거움으로 바뀌었다.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;8시를 막 넘긴 시간, 켄트벡과 창준님 그리고 켄트벡의 가족들 (신시아 안드레스, 조조, 린지, 포레스트)이 룸으로 들어왔다. 특별히, 신시아 안드레스(신디)는 Extreme Programming Explained 의 공동저자로 잘 알고 있던터라 반가움은 배가 되었다. 그녀는 심리학 석사로서 논리적 학문분야 종사자들이 이성적인 판단을 할 수 없다라는 사실에 기인한 연구를 다수 진행하였고, 이러한 이론이 켄트벡에게 많은 영감을 주었다고 한다. 가족들과 함께 온 것은 의외였지만, 아마도 그만큼 이 자리를 편하게 생각해서가 아닐까 한다. &lt;br /&gt;
 &lt;br /&gt;
 이렇게 해서 모두 모였지만, 막연히 만남의 자리라 어떻게 진행할런지에 대한 계획이 세워져 있지 않던 상태. 창준님께서 핑퐁 방식의 Q&amp;amp;A와 켄트벡 가족과 우리 들이 각각 조를 이루어 짧은 상황극을 하는 것 에 대한 제안을 주셨다. 켄트벡은 상황극은 약간 부담스러웠는지 핑퐁을 마음에 들어했고, 김치에 관한 질문을 우리에게 던지면서 시작되었다. 김치라는 주제로 꽤 많이 왔다 갔다 했는데, 미국에서도 이미 김치를 즐겨보았고 (아주 별로라고 한다.), 가족중에 6.25 참전용사가 있어서 한국에 관심이 많았다고 한다. 이후에 창준님께서 언급해주셨는데, 켄트벡의 저서 중에 김치에 관한 언급도 있었다고... &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;김치에 관한 설전이 끝난 후, 한 여성 참가자(외국에서 오신분이 계시다던데 아마 이분 인 듯)께서 켄트벡 가족이 홈스쿨링 하는 것을 아시고 신디에게 홈스쿨링에 관한 질문을 던지셨다. 인상적인 것은 신디의 말 중에 이런 부분이 있었다. &lt;br /&gt;
 &quot;우리는 아이들에게 있어서 자원 제공자 일 뿐입니다. 우리가 책이나 정보를 공급해 주면 아이들이 스스로 잘 해내고 있습니다.&quot;&lt;br /&gt;
 아동학을 전공한 와이프가 평소에 펼쳤던 지론과 유사했기에 마음에 와닿았고, 부모가 우월한 위치라고 생각하고 배움을 강요하는 우리네 여느 부모의 모습과는 달랐기에 약간의 자극을 받을 수 있었다. 내 경험에 비추어 볼 때 내가 스스로 무언가를 하기 전까지의 나는 아무 것도 해내지 못했다고 말할 수 있을 정도로 자신의 뜻에 의해 행동한다는 것이 중요하다는 것을 깨달았기 때문에, 켄트 벡과 신디의 아이들이 아주 좋아보였다. &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;몇 번의 핑퐁이 오가는 동안 인상 깊은 질문이 하나 있었다. 비 개발자로서 켄트벡의 명성을 확인하려 한 질문으로 보였는데, 내용은 이렇다. 자신 주변의 개발자들이 켄트벡이 프로그래밍을 잘하는 것보다 &quot;프로그래밍이란 이러한 것&quot;이라는 정의를 내린 것으로 켄트벡을 인용할 정도로 뛰어난 프로그래머로 유명하다는데, 이에 대해 그가 이러한 명성을 갖기 까지 어떠한 노력이 있었으며, 자신의 가치를 증명하기 위해 어떠한 방법을 사용했는 지에 관한 질문이다. (사실, 질문은 더 복잡했는데 내가 이해한 선에서 서술했다. 창준님이 벡에게 영어로 질문을 던질 때 난감하실 정도로 복잡했다 :) 질문에 대한 켄트벡의 답은 &quot;장님의 나라에선 애꾸가 왕이다&quot;라는 속담을 말하면서 시작되었다. 자신이 뛰어난 프로그래머는 아니며 훨씬 뛰어난 프로그래머가 많지만, 자신이 아주 작은 장점을 가졌기에 유명세를 탄 것은 아닌가라는 것이었다. 프로그래밍이 무엇이다 라는 것에 대해서는 이미 7년부터는 언급하지 않고 있으며, 대신에 자신이 프로그래밍을 어떻게 하고 있다라는 것을 알려오고 있다고 한다. 그러한 경험적 산물이 정의보다 더 큰 가치가 있음은 그를 아는 사람이라면 누구나 공감할 것이다. 또한, 이러한 겸손이 그를 더욱 우러러 보게 한다. &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;잠깐의 휴식 이후, 새로운 할거리를 찾는 도중에 창준님께서 아까 제안한 역할극을 조금 변형시켜 해보자고 제안하셨다. 방법은 다음과 같다.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;4~5명이 조를 이루어 10여분간 주제를 정한다.&lt;/li&gt;
&lt;li&gt;켄트벡 앞에서 주제에 대한 연극을 보여준다. (단, 이때 주제에 관한 직접적인 언급은 할 수 없다.)&lt;/li&gt;
&lt;li&gt;켄트벡이 연극을 주관대로 주제를 파악하여, 이에 맞는 대답을 해준다.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;공연과 켄트벡의 대답을 합쳐 3분을 넘을 수 없다.&lt;/li&gt;
&lt;li&gt;가장 잘한 조를 뽑아 켄트벡 저서의 한글 번역본 (국내출간분을 출판사에서 미국의 벡에게 보낸 것인데, 이를 다시 가져온 것)에 사인을 하여 부상으로 제공한다. (* 중요)&lt;/li&gt;
&lt;/ul&gt;
&amp;nbsp;모두 기억나진 않지만 인상적인 몇가지 상황과 켄트벡의 대답을 이야기 해보려고 한다. &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;첫번째 상황은 과중한 업무를 지시하는 상사를 보여주는 전형적인 한국의 회사 모습을 그렸다. 이에 대한 켄트벡의 의견은 &quot;몸이 힘들면 결코 영리해질 수 없다&quot; 였다. 충분한 휴식을 통해 더 큰 성과를 거둘 수 있다는 이야기였다.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;기억나는 다음 상황은 개인적으로 가장 인상 깊었던 조였는데, 신규 입사자가 XP 와 Agile 에 대한 의지가 매우 강한 경우, 기존 조직이 이에 대한 거부감이 클 경우 어떻게 대처해야 하는 지였다. 켄트벡이 답하길, 어떤 구체적인 실천방안 (예를 들면 TFD 같은...) 보다는 왜 그것을 해야하는 지에 대해서 집중하고, 보다 근본적인 원인에 대해서 도출한 이후에 그러한 프랙티스를 고려해 본다면 함께 일하는 사람들이 더욱 쉽게 받아들일 수 있다고 하였다. 이는 애자일이나 XP 진영에서 늘 강조하는 바이기도 하다.&lt;br /&gt;
&lt;br /&gt;
그리고 내가 연기했던 조에서는 &quot;켄트벡은 개인적인 시간을 갖기 위해 어떠한 노력을 하는가&quot; 라는 질문을 던지려고 켄트벡의 가족이 되어 그를 귀찮게 하는 모습을 그리고 그가 혼자만의 시간을 갈망한다는 내용을 전달하고자 했으나, 그는 우리 질문을 &quot;가족과의 시간을 방해하는 상황&quot;이라고 해석했다. 자신의 관점에서는 어떠한 업무 보다 가족이 우선이며, 그렇기에 그들과의 시간을 소홀히 하지 말라고 강조했다. 특히, 한국 사회에선 그럴 수 없는 상황이 당연시 되어 있는 분위기를 안타까워하기도 했다.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfs11.tistory.com/image/10/tistory/2009/09/08/10/06/4aa5ae02d7836&quot; alt=&quot;켄트백이 경품에 직접 사인하는 모습&quot; filemime=&quot;&quot; filename=&quot;4aa5ae02d7836A9.JPG&quot; height=&quot;375&quot; width=&quot;500&quot;/&gt;&lt;p class=&quot;cap1&quot;&gt;왼쪽부터 나, 린지, 조조, 신디, 켄트벡 &lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfs11.tistory.com/image/28/tistory/2009/09/08/10/07/4aa5ae3e92edc&quot; alt=&quot;켄트벡과의 기념촬영 시도&quot; filemime=&quot;&quot; filename=&quot;4aa5ae3e92edcAR.JPG&quot; height=&quot;375&quot; width=&quot;500&quot;/&gt;&lt;p class=&quot;cap1&quot;&gt;심하게 흔들린 기념사진 &lt;/p&gt;&lt;/div&gt;&lt;br /&gt;
이외에도 많은 이야기가 오고 갔으나 글로는 담아내기 힘든 부분이 아쉽고, 나는 사랑니발치에 따른 고통으로 켄트벡과 그리고 그에게 관심을 가진 참석자들과 더욱 많은 이야기를 나누지 못해 아쉽다.&lt;br /&gt;
2시간은 매우 짧았지만, 그의 통찰력을 실감할 수 있는 의미 있는 자리였다. 이러한 자리를 마련해 준 xper에게 감사한다. &lt;br /&gt;</description>
			<category>Cynthia Andres</category>
			<category>Kent Beck</category>
			<category>XP</category>
			<category>XPer</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/37</guid>
			<comments>http://blog.fguy.com/entry/%EC%BC%84%ED%8A%B8-%EB%B2%A1%EA%B3%BC%EC%9D%98-%EB%A7%8C%EB%82%A8#entry37comment</comments>
			<pubDate>Fri, 04 Sep 2009 02:21:25 +0900</pubDate>
		</item>
		<item>
			<title>단위테스트를 위한 주민등록번호 생성</title>
			<link>http://blog.fguy.com/entry/%EB%8B%A8%EC%9C%84%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%9C%84%ED%95%9C-%EC%A3%BC%EB%AF%BC%EB%93%B1%EB%A1%9D%EB%B2%88%ED%98%B8-%EC%83%9D%EC%84%B1</link>
			<description>최근 Service 개발에서 반복적인 Account 생성이 필요한 테스트 케이스가 있어서 작업 중 Remote Server에서 주민등록번호 Validation 을 하는 바람에 급히 검색하여 다음과 같은 내용을 알아내었다.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;예를 들어 640713-1018433 이 주민번호를 예로 들어보죠&lt;br /&gt;우선 주민등록번호 마지막자리수만 제외하고, &lt;br /&gt;각각의 자리수마다 다음과 같은 수를 곱하여 전체를 더한다. &lt;br /&gt;&lt;br /&gt;6 4 0 7 1 3 1 0 1 8 4 3 &lt;br /&gt;x x x x x x x x x x x x &lt;br /&gt;2 3 4 5 6 7 8 9 2 3 4 5 &lt;br /&gt;-----------------------&lt;br /&gt;+ + + + + + + + + + + + &lt;br /&gt;&lt;br /&gt;즉, (6*2)+(4*3)+(0*4)+(7*5)+(1*6)+(3*7)+(1*8)+(0*9)+(1*2)&lt;br /&gt;+(8*3)+(4*4)+(3*5) = 151 &lt;br /&gt;&lt;br /&gt;그러면 151 이란 수가 나온다. 이 151을 매직키인 11로 나누어 나머지만 취한다. &lt;br /&gt;&lt;br /&gt;151 / 11 = 몫: 13 &amp;lt;-- 버림 &lt;br /&gt;&lt;br /&gt;나머지: 8 &lt;br /&gt;&lt;br /&gt;마지막 단계로 매직키인 11에서 나머지 8을 빼면 3이란 수가 나오&lt;br /&gt;는데, 이숫자가 주민등록번호 마지막 자리의 숫자와 일치하면 대한민국 국민이다. &lt;br /&gt;&lt;br /&gt;11 - 8 = 3 --&amp;gt; 정상적인 주민등록번호임&amp;nbsp; 
&lt;/blockquote&gt;출처 : http://blog.naver.com/foenix/40040223161&lt;br /&gt;&lt;br /&gt;이 내용을 다음과 같은 메서드로 만들어 보았다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: java&quot;&gt;	public static String getSSN() {
		Random rand = new Random();
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(rand.nextLong());
		String s1 = new SimpleDateFormat(&quot;yyMMdd&quot;).format(cal.getTime());
		String s2 = null;
		
		while(s2 == null || s2.length() &amp;lt; 6) {
			s2 = Integer.toString(rand.nextInt(299999));
		}
		int sum = 0;
		for (int i = 0; i &amp;lt; s1.length(); i++) {
			sum += Integer.parseInt(String.valueOf(s1.charAt(i))) * (i + 2);
			int j = i &amp;lt; 2 ? i + 8 : i;
			sum += Integer.parseInt(String.valueOf(s2.charAt(i))) * j;
		}
		int bit = 11 - (sum % 11);

		return s1 + &quot;-&quot; + s2 + (bit == 10 ? 0 : bit);
	}
&lt;/pre&gt;</description>
			<category>java</category>
			<category>TDD</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/35</guid>
			<comments>http://blog.fguy.com/entry/%EB%8B%A8%EC%9C%84%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%9C%84%ED%95%9C-%EC%A3%BC%EB%AF%BC%EB%93%B1%EB%A1%9D%EB%B2%88%ED%98%B8-%EC%83%9D%EC%84%B1#entry35comment</comments>
			<pubDate>Tue, 16 Jun 2009 18:37:28 +0900</pubDate>
		</item>
		<item>
			<title>GAE Model Serialization/Deserialization</title>
			<link>http://blog.fguy.com/entry/GAE-Model-SerializationDeserialization</link>
			<description>GAE로 개발 중 Datastore record의 snapshot을 만들기 위해 Model class의 Instance 를 Serialize 하기 위한 방법을 모색하기로 했다.&lt;br /&gt;
&lt;br /&gt;
Model.to_xml()을 이용하여 serialize 는 하였으나, reverse method 가 없어서 직접 구현하던 중 누군가가 이미 해놓지 않았을까 해서 검색해보니 python doc 에서 pickle 이라는 library를 사용하면 손쉽게 구현할 수 있다는 사실을 알게 되었다&lt;br /&gt;
&lt;br /&gt;
더 찾아보니 appengine cookbook 에서 친절히 알려주는 recipe를 제공하더라.&lt;br /&gt;
&lt;br /&gt;
&lt;a title=&quot;[http://appengine-cookbook.appspot.com/recipe/pickledproperty/?id=ahJhcHBlbmdpbmUtY29va2Jvb2tylwELEgtSZWNpcGVJbmRleCI8YWhKaGNIQmxibWRwYm1VdFkyOXZhMkp2YjJ0eUZ3c1NDRU5oZEdWbmIzSjVJZ2xFWVhSaGMzUnZjbVVNDAsSBlJlY2lwZSI-YWhKaGNIQmxibWRwYm1VdFkyOXZhMkp2YjJ0eUZ3c1NDRU5oZEdWbmIzSjVJZ2xFWVhSaGMzUnZjbVVNMjIM]로 이동합니다.&quot; target=&quot;_blank&quot; href=&quot;http://appengine-cookbook.appspot.com/recipe/pickledproperty/?id=ahJhcHBlbmdpbmUtY29va2Jvb2tylwELEgtSZWNpcGVJbmRleCI8YWhKaGNIQmxibWRwYm1VdFkyOXZhMkp2YjJ0eUZ3c1NDRU5oZEdWbmIzSjVJZ2xFWVhSaGMzUnZjbVVNDAsSBlJlY2lwZSI-YWhKaGNIQmxibWRwYm1VdFkyOXZhMkp2YjJ0eUZ3c1NDRU5oZEdWbmIzSjVJZ2xFWVhSaGMzUnZjbVVNMjIM&quot;&gt;http://appengine-cookbook.appspot.com/recipe/pickledproperty/?id=ahJhcHBlbmdpbmUtY29va2Jvb2tylwELEgtSZWNpcGVJbmRleCI8YWhKaGNIQmxibWRwYm1VdFkyOXZhMkp2YjJ0eUZ3c1NDRU5oZEdWbmIzSjVJZ2xFWVhSaGMzUnZjbVVNDAsSBlJlY2lwZSI-YWhKaGNIQmxibWRwYm1VdFkyOXZhMkp2YjJ0eUZ3c1NDRU5oZEdWbmIzSjVJZ2xFWVhSaGMzUnZjbVVNMjIM&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</description>
			<category>Google App Engine</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/34</guid>
			<comments>http://blog.fguy.com/entry/GAE-Model-SerializationDeserialization#entry34comment</comments>
			<pubDate>Fri, 10 Apr 2009 22:39:55 +0900</pubDate>
		</item>
		<item>
			<title>Google App Engine Translation Funtion</title>
			<link>http://blog.fguy.com/entry/Google-App-Engine-Translation-Funtion</link>
			<description>&lt;br /&gt;
&lt;pre class=&quot;brush: python&quot;&gt;import urllib
import urllib
import os
import django.utils.simplejson as simplejson

os.environ[&quot;DJANGO_SETTINGS_MODULE&quot;] = &quot;django.conf.global_settings&quot;

TRANSLATE_URL = &#039;http://ajax.googleapis.com/ajax/services/language/translate&#039;

def translate(input_lang, output_lang, q):
	params = urllib.urlencode({&#039;v&#039;: &#039;1.0&#039;, &#039;q&#039;: q, &#039;langpair&#039;: &#039;%s|%s&#039; % (input_lang, output_lang)})
	response = urllib.urlopen(TRANSLATE_URL, params)
	data = response.read()
	response.close()
	decoded = simplejson.loads(data)
	return decoded[&#039;responseData&#039;][&#039;translatedText&#039;]
&lt;/pre&gt;</description>
			<category>Django</category>
			<category>GAE</category>
			<category>Google App Engine</category>
			<category>python</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/33</guid>
			<comments>http://blog.fguy.com/entry/Google-App-Engine-Translation-Funtion#entry33comment</comments>
			<pubDate>Thu, 02 Apr 2009 02:36:52 +0900</pubDate>
		</item>
		<item>
			<title>World of Warcraft 제작진에 내 이름이...</title>
			<link>http://blog.fguy.com/entry/World-of-Warcraft-%EC%A0%9C%EC%9E%91%EC%A7%84%EC%97%90-%EB%82%B4-%EC%9D%B4%EB%A6%84%EC%9D%B4</link>
			<description>&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;http://cfs10.tistory.com/image/3/tistory/2009/03/09/11/32/49b47fb7d3cb7&quot; alt=&quot;World of Warcraft ScreenShot&quot; filemime=&quot;&quot; filename=&quot;49b47fb7d3cb792.jpg&quot; height=&quot;312&quot; width=&quot;500&quot;/&gt;&lt;p class=&quot;cap1&quot;&gt;클릭하면 확대 &lt;/p&gt;&lt;/div&gt;&lt;br /&gt;
그동안 내 이름이 올라가 있는 지 미처 몰랐는데, 오랜만에 출근했더니 누군가 알려주더라.&lt;br /&gt;
&lt;br /&gt;
아직 한 일이 많진 않지만 내 이름 석자를 확인하니 왠지 뿌듯하고, 앞으로 더욱 분발해야 겠다는 각오를 다져보게 한다.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;</description>
			<category>Roll</category>
			<category>STAFF</category>
			<category>wow</category>
			<category>블리자드</category>
			<category>와우</category>
			<category>제작진</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/32</guid>
			<comments>http://blog.fguy.com/entry/World-of-Warcraft-%EC%A0%9C%EC%9E%91%EC%A7%84%EC%97%90-%EB%82%B4-%EC%9D%B4%EB%A6%84%EC%9D%B4#entry32comment</comments>
			<pubDate>Mon, 09 Mar 2009 11:50:36 +0900</pubDate>
		</item>
		<item>
			<title>JNDI DataSource Loading for TDD</title>
			<link>http://blog.fguy.com/entry/JNDI-DataSource-Loading-for-TDD</link>
			<description>Tomcat 등의 Servlet Container를 사용하여, 웹애플리케이션을 개발할 때, DataSource를 Servlet Container의 Context 에 JNDI Resource로 bind 하여 사용하는 경우가 많다. &lt;br /&gt;
&lt;br /&gt;test case를 실행하기 위해 JNDI remote provider 를 제공하는 application server (glassfish, jboss 등)를 사용할 수도 있으나, 이러한 것은 test의 원자성을 저해하기 때문에 test 환경 자체에서 JNDI resource를 생성할 수 있는 방법을 생각해 보았다.&lt;br /&gt;
&lt;br /&gt;&lt;a href=&quot;http://java.sun.com/products/jndi/&quot; target=&quot;_blank&quot;&gt;Sun에서 제공&lt;/a&gt;하는 File System Service Provider를 이용하는 것이다. 사용법은 매우 간단하다. 단순히 naming context의 initail context factory 를 com.sun.jndi.fscontext.RefFSContextFactory 로 지정하기만 하면 된다.&lt;br /&gt;
&lt;br /&gt;다음은 간단히 만들어 본 class 이다. 이 class는 context xml 파일을 읽어서 JNDI resource를 loading해 주는 역할을 한다. test를 수행하기 전에 JNDILoader.init()을 실행 해주면 다른 작업 없이 test case를 실행시킬 수 있을 것이다.&lt;br /&gt;
&lt;br /&gt;&lt;pre class=&quot;brush: java&quot;&gt;package com.fguy.test;

import java.io.File;
import java.io.IOException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class JNDILoader {
	private static final Logger LOG = Logger.getLogger(JNDILoader.class);

	private static final boolean initialized = false;
	private static final String CONTEXT_XML = &quot;WebContent/META-INF/context.xml&quot;;

	private JNDILoader() {

	}

	public static final void init() throws ParserConfigurationException,
			SAXException, IOException, DOMException, NamingException {

		if (!initialized) {
			Context context = getNamingContext();

			List&lt;string&gt; resourceNames = new ArrayList&lt;string&gt;();
			Map&lt;string, string=&quot;&quot; map=&quot;&quot;&gt;&lt;string,&gt;&amp;gt; references = new HashMap&lt;string, string=&quot;&quot; map=&quot;&quot;&gt;&lt;string,&gt;&amp;gt;();

			NodeList contextResourceNodeList = getContextResourceNodeList();
			for (int i = 0; i &amp;lt; contextResourceNodeList.getLength(); i++) {
				Node item = contextResourceNodeList.item(i);
				// print comment;
				if (LOG.isDebugEnabled()
						&amp;amp;&amp;amp; item.getNodeType() == Node.COMMENT_NODE
						&amp;amp;&amp;amp; item != null) {
					LOG.debug(item.getNodeValue());
				}

				// register to JNDI
				if (&quot;resource&quot;.equalsIgnoreCase(item.getNodeName())
						&amp;amp;&amp;amp; &quot;javax.sql.DataSource&quot;.equals(item.getAttributes()
								.getNamedItem(&quot;type&quot;).getNodeValue())) {
					NamedNodeMap attributes = item.getAttributes();
					String name = attributes.getNamedItem(&quot;name&quot;)
							.getNodeValue();
					Map&lt;string, string=&quot;&quot;&gt; reference = references.get(name);

					if (reference == null) {
						reference = new HashMap&lt;string, string=&quot;&quot;&gt;();
					}

					for (int j = 0; j &amp;lt; attributes.getLength(); j++) {
						String n = attributes.item(j).getNodeName();
						String v = attributes.item(j).getNodeValue();
						if (!&quot;name&quot;.equals(n)) {
							reference.put(n, v);
						}
						LOG.debug(attributes.item(j));
					}

					resourceNames.add(name);
					references.put(name, reference);
				}

				if (&quot;resourceparams&quot;.equalsIgnoreCase(item.getNodeName())) {
					NodeList parameters = item.getChildNodes();
					String name = item.getAttributes().getNamedItem(&quot;name&quot;)
							.getNodeValue();
					Map&lt;string, string=&quot;&quot;&gt; reference = references.get(name);

					if (reference == null) {
						reference = new HashMap&lt;string, string=&quot;&quot;&gt;();
					}

					for (int j = 0; j &amp;lt; parameters.getLength(); j++) {
						Node paramItem = parameters.item(j);
						if (&quot;parameter&quot;.equalsIgnoreCase(paramItem
								.getNodeName())) {
							NodeList children = paramItem.getChildNodes();
							String n = null;
							String v = null;
							for (int k = 0; k &amp;lt; children.getLength(); k++) {
								Node child = children.item(k);
								if (&quot;name&quot;
										.equalsIgnoreCase(child.getNodeName())) {
									n = child.getNodeValue();
								} else if (&quot;value&quot;.equalsIgnoreCase(child
										.getNodeName())) {
									v = child.getNodeValue();
								}
								LOG.debug(child);
							}
							reference.put(n, v);
						}
					}
					references.put(name, reference);
				}
			}
			for (String name : resourceNames) {
				Reference reference = new Reference(&quot;javax.sql.DataSource&quot;,
						&quot;org.apache.commons.dbcp.BasicDataSourceFactory&quot;, null);
				Map&lt;string, string=&quot;&quot;&gt; referenceMap = references.get(name);

				for (String key : referenceMap.keySet()) {
					reference
							.add(new StringRefAddr(key, referenceMap.get(key)));
				}

				context.rebind(&quot;java:comp/env/&quot;.concat(name), reference);
			}
		}
	}

	private static final NodeList getContextResourceNodeList()
			throws ParserConfigurationException, SAXException, IOException {
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.parse(new File(CONTEXT_XML));
		return doc.getFirstChild().getChildNodes();
	}

	private static final Context getNamingContext() throws NamingException {
		System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
				&quot;com.sun.jndi.fscontext.RefFSContextFactory&quot;);
		System.setProperty(Context.PROVIDER_URL, &quot;file:///tmp&quot;);

		return new InitialContext();
	}
}&lt;/pre&gt;</description>
			<category>datasource</category>
			<category>fscontrext</category>
			<category>java</category>
			<category>JNDI</category>
			<category>TDD</category>
			<category>tomcat</category>
			<author>fguy</author>
			<guid>http://blog.fguy.com/31</guid>
			<comments>http://blog.fguy.com/entry/JNDI-DataSource-Loading-for-TDD#entry31comment</comments>
			<pubDate>Tue, 04 Nov 2008 18:32:17 +0900</pubDate>
		</item>
	</channel>
</rss>
