개발 언어를 선택하는 5가지 기준


세상에는 수많은 프로그래밍 언어가 존재한다. 각 프로그래밍 언어는 자신만의 독특한 장단점을 가지고 있기 때문에 모든 프로젝트에 적합한 최고의 프로그래밍 언어는 존재하지 않는다. 결국 프로젝트의 요구 사항과 성격, 개발자의 자질, 여러 환경 요소를 모두 고려하여 가장 적절한 프로그래밍 언어를 고르는 일이 중요하다. 이 글에서는 프로그래밍 언어를 선택할 때 어떤 요소들을 고려해야 하는지 알아보자.

소프트웨어 개발자들은 성경에 나오는 바벨탑의 교훈을 잊어버린 걸까? 세상에 존재하는 수많은 언어 때문에 존재하는 불편함을 잘 알고 있는 프로그래밍 언어 개발자들이 왜 각자 문법과 어휘가 다른 수많은 프로그래밍 언어를 만들어 냈을까? 프로그래밍 언어는 단순히 의사소통을 하기 위한 수단만은 아니다. 소프트웨어는 세상에 산재하는 수많은 도메인(domain)의 문제를 풀어야 하고, 이 모든 문제들을 쉽게 풀 수 있는 최적의 언어는 존재하기 힘들기 때문이다. 소프트웨어 개발자들은 자신이 개발해야 하는 소프트웨어의 성격에 따라 프로그래밍 언어를 달리해야 한다. 시스템 소프트웨어를 작성한다면 C 언어와 어셈블리 언어가 적합할 것이며, 간단히 자신의 알고리즘을 테스트해보거나 프로토타이핑을 한다면 인터프리팅(interpreting)되는 스크립트 언어가 적합하다.

비교적 간단한 프로그램을 작성해보는 것이라면 사실 어떤 언어를 사용해도 무방하다. 하지만 비교적 큰 프로젝트의 산출물은 여러 가지 요소에 의해서 그 품질이 결정되는데, 여기에는 적절한 프로그래밍 언어의 선택이 중요하다. 따라서 프로젝트 초기에 프로젝트를 계획하면서 개발 도구와 환경을 결정할 때 프로그래밍 언어를 정하는 과정도 반드시 포함되어야 한다. 이 과정에서 여러 개의 프로그래밍 언어를 후보로 올려놓고, 프로젝트의 성격에 따른 여러 기준을 적용하며 의사 결정을 하게 된다. 프로그래밍 언어를 고르는데 있어서 절대적인 잣대는 없지만, 이 글에서는 이 과정에서 사용할 수 있는 몇 가지 유용한 판단 기준을 제공하고자 한다.

컴파일 vs. 인터프리터
숙련된 프로그래머 중에서 컴파일되는 프로그래밍 언어와 인터프리터되는 프로그래밍 언어의 차이점을 모르는 사람은 없을 것이다. 인터프리터되는 언어는 비교적 빠른 속도로 프로그램을 짤 수 있고, 결과를 쉽게 확인할 수 있다. 반면 컴파일되는 언어는 수행 속도가 빠르다. 프로그래밍 언어를 선택할 때 가장 먼저 적용해봐야 할 잣대 중에 하나는 해당 언어의 컴파일러나 인터프리터가 존재하느냐는 것이다.

경우에 따라서는 컴파일러와 인터프리터가 모두 존재할 수도 있고, 두 가지가 혼합된 형태일 수도 있다. 예를 들어 자바의 경우 자바 프로그램이 바이트코드(bytecode)로 컴파일되고, 자바 가상 머신(Java Vir tual Machine)에 의해서 다시 인터프리트되는 것이 일반적이다. 그러나 모바일 컨텐츠나 게임을 만들 때는 자바로 프로그램을 만들고 수행 속도 향상을 위해 타겟 플랫폼에 맞춰 미리 컴파일(AOTC, Ahead Of Time Compilation)하는 경우가 흔한데, 이는 자바 언어의 컴파일러라고 볼 수 있다. 비슷한 예로, 수행되기 직전에 머신 코드로 컴파일되는 JIT(Just In Time) 컴파일 방법도 있다.

같은 언어로 프로그래밍되더라도 컴파일러냐 인터프리터냐에 따라 성능과 사용성이 크게 달라진다. 일반적으로 컴파일되는 프로그래밍 언어는 두 가지 장점이 있는데, 하나는 수행 속도 향상이고 또 하나는 소스코드의 암호화(obfuscation)이다. 컴파일러가 인터프리터에 비해 같은 프로그램을 빠른 속도로 수행하게 만드는 것은 분명하다. 컴파일 시간은 런타임과 별도로 한 번만 수행되면 되기 때문에 각종 최적화(optimization) 기술을 적용하기가 유리하다. 물론 최근에는 자바 가상 머신(JVM)이 이런 컴파일러의 최적화 기술을 빌려와 동적으로 머신 코드를 생성하는 기술(adaptive compilation or HotSpot)을 도입했지만, 일부 최적화 기술은 그 특성상 많은 시간이 걸리기 때문에 같은 언어를 컴파일하여 얻어진 프로그램보다 빠를 수는 없다.

또 하나의 차이점은 소스코드를 얼마나 알아보기 힘들게 만들 수 있는가이다. 컴파일된 프로그램의 경우 해당 고급 언어의 특징이 거의 사라진, 기계어로 번역되어 있기 때문에 머신 코드를 바탕으로 원본 소스코드를 복원해 낼 수 있는 가능성은 거의 없다. 반면에 인터프리터되는 언어는 수행을 위해 소스코드가 건네져야 하므로, 소스코드 공개 의사가 없는 상업적인 프로젝트의 경우 해결하기 힘든 문제에 봉착할 우려가 있다.

필자도 프로젝트를 수행하면서 소스코드의 비밀 유지 때문에 많은 문제를 겪었다. 필자는 디지털 텔레비전을 위한 미들웨어 플랫폼을 만드는 일을 했었는데, 여기서 하드웨어와 운영체제를 바탕으로 시스템을 빌드하는 일은 C 언어로 했지만, 해당 플랫폼이 자바를 기반으로 하기 때문에 API를 자바 기반으로 작성해야 했다. 문제는 이를 배포하기 위해 바이너리를 줘야 하는데, C 언어로 컴파일된 바이너리는 문제가 없었지만 자바로 작성한 클래스를 배포할 때 문제가 생겼다.

자바의 경우 일단 한 번 바이트코드로 컴파일된 후에 자바 가상 머신 위에서 인터프리트되지만, 바이트코드는 가상 머신에서 동작하는 일종의 기계어임에도 불구하고 실제 기계어인 인텔이나 ARM, PowerPC 등의 어셈블리 언어에 비해서는 대부분의 자바 심볼(symbol)을 보존하고 있는 고급 언어라 할 수 있다. 시중에는 자바의 클래스 파일을 바탕으로 원래의 자바 소스코드를 복원해주는 디컴파일러(decompiler)가 많이 존재한다. 따라서 자바로 만든 프로그램을 배포할 때는 이를 컴파일하여 클래스 파일만 배포하더라도 누군가가 소스코드를 엿볼 수 있다는 불안에 시달려야 하는 것이다.

필자의 회사에서 시도한 첫 번째 방법은 자바 소스코드를 뒤죽박죽으로 만들어 주는 프로그램(Java Obfuscator)을 이용하는 것이었다. 이 프로그램은 원래 자바 프로그램의 의미를 훼손시키지 않고, 단순히 변수 이름과 클래스 이름을 a, b, c 등의 의미 없는 이름으로 바꾸어서 해당 프로그램을 해독하기 힘들게 만들어 준다. 그러나 이 방법도 완벽하진 않았다. 클래스와 변수 이름을 이상하게 바꿀 수는 있어도, 외부로 참조해야 하는 API의 이름을 바꿀 수는 없을 뿐더러, 비교적 제한된 애플리케이션 범주라면 숙련된 자바 프로그래머의 경우 바이트코드에서 복원된 소스코드를 읽는 것이 어렵지 않기 때문이다.

이 미들웨어는 결국 자바 클래스 파일을 JAR가 아닌 별도의 암호화 방법으로 압축했다. 그리고 이 클래스를 읽는 방법은 비밀에 붙인 채, C 언어로 암호화된 클래스 파일을 해석하여 원래의 클래스로 복원하여 자바 가상 머신에 로딩해 주는 방법을 사용하게 되었다. 이와 달리 일반적인 애플리케이션의 경우 인터프리팅되는 언어를 사용한 프로그램의 소스코드가 공개되지 않기를 바란다면, 이는 패키지로 만들어서 서버에서 수행한 후 결과만 웹 브라우저를 통해 알려주는 서블릿(servlet) 형태가 되어야 할 것이다.

결국 프로젝트에 있어서 성능이 중요하거나 소스코드 유출 방지가 높은 우선순위를 차지한다면, 인터프리터 언어가 주는 유용성, 개발의 편리성을 감안하더라도 치러야 할 대가가 크다는 사실을 알 수 있다. 따라서 특정 프로그래밍 언어를 선택하기 위해서는 해당 프로그래밍 언어의 컴파일러가 존재하는지, 혹은 인터프리터가 존재하는지를 확인해보는 것이 필요하다.

언어간 통합 문제
완벽한 한 가지 프로그래밍 언어는 존재하지 않는다고 말했다. 프로그래밍 언어가 가지는 각각의 특징 때문에 한 프로젝트 안에서 2~3개 이상의 프로그래밍 언어를 사용해야 할 경우는 생각보다 빈번하다. 이 경우 각각의 프로그래밍 언어가 가지는 특징도 중요하지만, 두 언어가 얼마나 유기적으로 잘 융합되어 하나의 시스템을 만들 수 있는지도 중요한 판단 기준이 된다. 대부분의 소프트웨어를 C++로 작성하고, 일부 테스트 프로그램과 간단한 유틸리티를 파이썬으로 작성했다면 언어간 통합은 큰 문제가 아닐 수도 있다. 그러나 시스템의 특성상 2가지 이상의 언어가 서로 유기적으로 얽혀서 구성되어야 하는 경우 두 언어간 통합이 원활하지 않다면 이는 프로젝트의 위기로 연결될 수도 있다.

필자는 프로그래밍 언어간 통합 문제로 크게 고생을 한 적이 있다. 이미 언급했듯이 필자가 참여했던 DTV용 미들웨어 프로젝트는, 셋탑 박스에 올라가는 실시간 운영체제(Real-time OS) 위에 미들웨어를 올리고 미들웨어 응용 프로그램을 위한 자바 API을 제공해야만 했다. 즉 자바 API는 자바로 작성하되, 셋탑 박스(STB)의 하드웨어 자원에 접근해야 하는 경우 C 언어를 사용할 수밖에 없었다. 또한 셋탑 박스 또한 임베디드 환경이기 때문에 메모리가 한정되어 있고, CPU 속도가 충분치 않아 자바로 수행할 경우 속도가 느린 모듈은 C 언어로 내리는 작업도 병행해야 했다.

자바의 경우 “한 번 작성하고 모든 곳에서 사용한다(Write Once, Run Everywhere)”는 모토에 따라 시스템 의존적인 C 언어와 통합할 이유가 없을 것 같다. 하지만 실제로 임베디드 시스템의 경우 자바를 사용하더라도 하드웨어가 제공하는 고유의 기능에 접근하기 위해서는 C 언어로 된 시스템 API를 호출해야 하기 때문에 C 언어와의 통합이 필수적인 경우가 많다. 자바도 이 필요성을 인지하고 JNI(Java Native Inter face)라고 하여, 자바 메쏘드를 C 언어로 작성할 수 있는 표준 인터페이스를 정의해 놓았다.

C 언어와의 통합을 위한 표준 인터페이스까지 존재하는 언어인 자바는 C 언어와 통합이 필요한 경우 이상적인 언어라고 판단할 수도 있다. 사실 다른 언어와의 인터페이스를 표준화하거나 구체적으로 명시한 언어조차 드문 상황이다 보니, 이 정도면 언어간 통합 문제를 어느 정도 해결해주고 있지 않느냐는 결론을 내릴 수도 있다.
그러나 실제로 자바와 C를 사용하여 프로젝트를 수행한 필자의 경험에 따르면, 언어간 통합은 절대로 쉬운 일이 아니었다. 자바에서 C 언어로 작성된 라이브러리를 로드하고 이 메쏘드를 부르는 것은 물론이고, C 언어로 작성된 자바 메쏘드에서 자바 객체의 필드에 접근하고 자바 메쏘드를 호출하게 만드는 일이 결코 간단하지 않았다. JNI 자체가 프로그래머의 실수를 유도하기 쉽게 만들어진 면도 많았고, 숙련된 프로그래머조차 버그 없이 한 번에 C와 자바를 통합하는 일은 힘들었다.

이는 어떻게 생각해보면 당연한 일인지도 모른다. C 언어에서 자바 메쏘드를 호출하고 객체를 사용하기 위해서는 기존의 C 언어에는 존재하지 않는 개념인 클래스나 객체, 필드, 메쏘드 등 객체지향 프로그램 언어의 특징을 C 언어의 구조체(struct)나 함수 포인터(function pointer) 등을 이용해 표현해줘야 하고, 이를 이용하는 것도 자바처럼 간단하지 않다. 자바에서 지원하는 예외 처리(exception handling) 방법도 C 언어에서 일일이 특정 함수를 호출하여 확인한 후 적절히 리턴해줘야 하고, 자바의 메모리를 접근하기 위해서도 가비지 콜렉터(garbage collector)와의 연관 관계를 생각해야만 한다. 즉 자바가 가상 머신 속에 감추어둔 내부 구조가 C 언어로 건너오면서 노출되는 것이다.

좀 더 일반적으로 말하면 두 언어를 연결하기 위해서는 두 언어 중 하나의 언어가 다른 언어의 기능을 흉내내줘야 한다. 프로그래밍 언어가 처음 만들어질 때부터 다른 언어와의 연관 관계를 생각하지 않았다면 이런 기능을 바라는 것은 힘들 수도 있다. 이상적인 관점을 버리고 특정 언어가 최소한 C 언어와 얼마나 잘 통합될 수 있느냐만 보는 것도 현실적인 접근 방법이다. 왜냐하면 대부분의 라이브러리가 C 언어로 작성되어 있기 때문이다. 파이썬이 태생부터 다른 언어와의 접착성(glue)을 강조하며 나타났던 것도 이런 생각이 깔려 있으리라 짐작 된다.

이 문제를 근본적으로 접근하여 해결책을 제시한 것은 마이크로소프트(MS)였다. MS가 닷넷 플랫폼에서 강조한 내용 중에 하나가 교차 언어(cross-language) 플랫폼인데, 이 개념의 핵심은 서로 다른 언어로 작성한 모듈이나 클래스를 서로 호출하여 사용할 수 있음을 의미한다. 대표적인 예로 VB.NET으로 작성한 클래스를 아무런 수정 없이 C#에서 사용할 수 있다는 점을 들 수 있다. 물론 서로 기본형(primitive-types)과 기능이 다른 프로그래밍 언어가 아무런 제약 조건 없이 서로를 호출해 사용할 수는 없기 때문에 CLS(Common Language Specification)를 만들어 이에 부합해야만 교차 언어를 사용할 수 있다. 그러나 닷넷이 언어간 통합 문제를 어느 정도 해결한 것은 분명해 보인다.

비슷한 움직임으로 썬(Sun)에서도 자바 외에도 자바 바이트코드로 변환되어 실행되는 프로그래밍 언어의 표준화 작업을 시작했다. 일례로 그루비(Groovy)는 바이트코드로 변환되어 실행되는 스크립트 언어인데, 자바와 그루비 모두 바이트코드 형태로 변환되기 때문에 그루비는 자바로 짠 라이브러리와 API를 마음대로 접근하여 사용할 수 있는 특성이 있다. 언어 간의 통합 문제가 점차 더 큰 요구 사항이 된다면, 이러한 시도는 점차 확대되리라 생각한다.

얼마나 객체지향적인가
지난달에 기고했던 ‘프로그래밍 언어론을 배우자’에서 프로그래밍 언어의 4가지 패러다임에 대해 설명한 바가 있다. 프로그래밍 언어는 크게 지시형(procedural) 언어, 객체지향 언어, 함수형 언어, 선언형 언어로 나뉘고 각 패러다임에 따라 언어의 특징이 크게 다르다고 이야기했다. 그러나 프로젝트를 위한 프로그래밍 언어를 선정하는 시점에 오면 판단 기준은 한 가지로 집중된다. 얼마나 객체지향적인가?

함수형 언어나 선언형 언어는 프로그래밍 방법론에 있어서 여러 가지 가치있는 시사점을 전달해주고, 기존의 지시형 언어와 객체지향 언어에 많은 영향을 미친 것이 사실이지만, 그 자체로 함수형, 선언형 언어는 비교적 도메인에 제한적이고, 실제로 프로젝트에 사용되는 일이 드문 편이다. 결국 C와 C++로 대변되는 지시형 언어와 객체지향 언어의 사이에서 어느 지점을 택할 것인가가 가장 현실적인 문제로 남게 된다.

객체지향 언어의 장점은 잘 알려져 있다. 데이터의 캡슐화(encapsulation), 코드 재사용(code reuse), 상속(inheritance), 다형성(polymorphism) 등 기존의 지시형 언어가 가지지 못한 여러 장점을 선사한다. 그러나 좀 더 객체지향적일수록 프로젝트에 적합하다는 일반론은 옳지 않다. 순수 객체지향(OO)을 표방하는 언어들이 비교적 느린 수행 속도로 악명 높고, 실제로 객체지향적일 필요가 없는 코드까지 객체지향적으로 사고하도록 강요하는 경우도 있다. 간단히 몇 가지 일련의 명령을 수행하고 싶은데도, 이를 추상화하여 클래스로 만들고 객체를 생성하고 메쏘드를 호출해야 하는 것은 분명 장점만은 아니다. 또 순수 객체지향 언어일수록 비교적 수행 속도가 느리다는 단점도 안고 있다.

반대로 객체지향 언어의 특징 중 일부만 빌려와도 크게 생산성이 향상될 수 있는 경우도 있다. 임베디드 시스템의 경우 칩셋(chipset) 회사들이 보통 컴파일러까지 제공한다. C++나 다른 고급 언어 컴파일러도 제공하면 좋겠지만, 칩셋 회사들의 특성상 보통 C 언어 컴파일러를 제공한다. 따라서 이런 임베디드 시스템에서 프로그래밍을 한다면 할 수 없이 C 언어를 사용해야 하는 경우가 많다. 팜과 같은 초창기 임베디드 시스템의 API를 보면 프리픽스(prefix)만 달리한 수많은 함수의 나열에 기겁한 경험이 있을지도 모른다. 비슷한 기능을 하는 함수들을 묶어서 네임 스페이스만 달리 줄 수 있었어도, 이런 환경에서 프로그래밍하는 개발자의 생산성을 훨씬 높아졌을지도 모른다.

그 예로 비교적 성공한 OS로 평가받고 있는 스마트폰용 운영체제 시스템인 심비안(Symbian)이 있다. 심비안 OS의 API가 C++로 작성되어 있어서 기존의 C 언어 API에 비해 비교적 정리가 잘 되어 있고 개발도 용이한 편이다. 그러나 이 성공이 C++ 언어 전체의 기능 때문만은 아니다. C++의 특성 중 일부인 클래스를 이용한 네임 스페이스 분리, 예외 처리 등만 C에 추가되었어도 비슷한 효과를 얻었을 것이다.

객체지향과 관련하여 또 하나 언급하고 싶은 것은, 객체지향 언어의 기능 중 일부는 아직도 완전한 동의 없이 서로 다른 방법으로 구현되고 있다는 점이다. 대표적인 예가 다중 상속(multiple inheritance)이다. 다중 상속은 말도 많고 탈도 많은 기능 중 하나이다. 잘 사용하면 강력한 기능이 되기도 하지만, 코드를 복잡하고 이해하기 힘들게 만드는 주범 중에 하나이기도 하다. 자바는 C++의 다중 상속이 마음에 들지 않아 이를 인터페이스로 대체했고, 또 루비를 비롯한 일부 언어는 믹스인(mix-ins)이라는 방법을 이용하여 코드를 조합하여 사용하기도 한다. 또 일부 언어는 일반적인 상속 관계와 코드 재사용을 구분하여 코드 상속(code inheritance)을 따로 지원하기도 한다. 언어를 선택할 때 이런 논쟁적인 부분을 해당 언어에서는 어떤 접근 방법으로 해결하고 있는지를 잘 살펴보는 것도 중요하다.

부수적인 조건이 아닌 안정성
보통 프로그래밍 언어의 안정성(reliability)은 부수적인 요건으로 여겨졌다. 하지만 프로그래밍 언어의 안정성은 개발 속도와 버그 발생률, 디버깅의 편의성, 테스트 등에 모두 영향을 미치는 매우 중요한 요건이다. 안정성이나 테스트의 편의를 결정하는 프로그래밍 언어의 특징은 타입 시스템(type system), RTTI(Run Time Type Inspection), 가비지 컬렉션 등을 들 수 있다. C 언어는 비교적 약한 타입 시스템을 가진 언어이다. C 언어에서 데이터 형은 어떤 다른 형으로도 캐스팅될 수 있고, 이 점은 C 언어의 강력한 장점이자 가장 큰 문제점이기도 하다. C 언어 타입 시스템의 약점은 개발 후반에 재앙으로 나타날 수 있는데, 이는 해결하기 힘든 버그 중에 하나이다.

임베디드 시스템 개발에 C 언어를 사용하는 예를 들어보자. 이 경우 C는 최선의 대안임이 분명하지만, C 언어의 특징 때문에 여러 가지 문제가 일어난다. C 언어에서 가장 흔히 하는 실수는 배열의 인덱스가 잘못되어 잘못된 메모리에 값을 쓰는 경우, 포인터 연산이 잘못되어 잘못된 메모리의 값을 읽거나 쓰는 경우다. 임베디드 시스템이 사용하는 OS는 대부분 메모리 공간이 하나로, 커널과 유저 모드의 구분이 없다. 즉 잘못된 메모리에 접근하더라도 세그먼테이션 폴트(segmentation fault)가 나지 않는다. 즉 커널 영역의 메모리 주소에 잘못된 포인터 연산으로 특정 값을 쓰더라도 그 시점에는 아무런 문제없이 넘어간다. 문제는 그렇게 바뀐 메모리 주소를 나중에 읽으려고 할 때 잘못된 값을 읽어 와서 프로그램이 이상 동작할 경우이다. 이 경우 문제 시점과 원인의 발생 시점이 다르기 때문에 그 원인을 파악하는 게 사실상 거의 불가능해 진다.

만약 C 언어가 아니라 자바처럼 메모리 포인터가 없고, 배열의 경우 항상 배열의 경계값 검사를 해주는 프로그래밍 언어를 사용했다면 저런 문제는 절대 발생할 수 없었을 것이다. 즉 프로그래밍 언어의 타입 시스템에 따라 어떤 종류의 프로그램 버그는 원천 봉쇄할 수도 있다는 이야기다. 이러한 점은 프로그래밍 언어를 선택할 때 반드시 고려해야 한다.

리플렉션(reflection)이라 불리는 언어의 기능은 테스트 프레임워크를 만드는데 많은 도움을 준다. 리플렉션은 런타임에 프로그래밍 언어의 타입을 동적으로 조사하고 이를 호출하여 사용할 수 있는 기능을 말한다. 즉 프로그램이 동작 중에 어떤 데이터 타입이 있는지 확인한 후에, 해당 메쏘드를 무작위로 불러보는 일이 가능해진다. 이 기능은 보통 자바로 작성된 API의 경우, API가 표준에 맞는 클래스 이름과 메쏘드 이름, 그리고 인자들을 가지고 있는지 동적으로 확인한다. 또 해당 시스템의 API를 무작위로 호출하여 시스템의 안정성을 테스트할 때 사용된다.

언어의 런타임이 가비지 컬렉션을 지원하느냐의 여부도 넓게 봐서 언어의 안정성에 포함된다. malloc/ free나 new/delete를 사용하는 프로그래밍 언어는 대부분 자원 관리를 적절히 하기 위해 엄청난 노력이 소요된다. malloc한 메모리는 반드시 어느 시점에서인가 free해줘야 하는데, 이를 여러 조건에 빠짐없이 처리해주는 것만으로 시스템의 복잡도가 상당히 올라감을 알 수 있다. 이를 실수하면 곧바로 메모리 누수(memory leak)로 이어지기 때문에 여간 신경쓰이는 일이 아니다. 가비지 컬렉션을 지원한다면 프로그래머를 이러한 자원 관리 문제에서 어느 정도 해방시키기 때문에 생산성이 향상되고, 자원 관리 문제로 인한 버그를 예방할 수 있는 장점이 있다.

얼마나 많은 라이브러리가 표준화되어 있나
프로그래밍 언어를 선택함에 있어서 가장 중요한 부분은 어쩌면 그 언어의 사용을 도와주는 얼마나 많은 지원이 있느냐 일지도 모른다. 여기서 지원은 각종 프로그래밍 언어 서적, 웹 사이트, 그 프로그래밍 언어를 사용하는 사람들의 숫자, 전문가, 바로 사용할 수 있는 라이브러리 등이다.

프로그래밍 언어도 네트워크와 마찬가지(network effect)로 사용하는 사람이 많을수록 그 언어를 사용하는 모든 사람이 이득을 얻는 특징이 있다. 사람들은 전문적인 지원이 없으면 그 언어의 선택을 꺼리는 경향이 있고 더 많은 사람들이 사용하는 언어를 선택하는 경향이 강하다. 컴퓨터 산업이 어느 정도 성숙되고 나서 상업적으로 성공한 언어가 대부분 MS나 썬과 같이 대기업의 전폭적인 지원이 있었다는 사실도 이를 보여준다. 수많은 책을 펴내고 그 언어의 사용을 장려하기 위해 여러 프로모션 정책을 펴는 것이 프로그래밍 언어의 성공에 있어서 생각보다 중요한 요소인 것이다.

이런 지원 중에서 가장 중요한 요소는 사용 가능한 라이브러리가 얼마나 많이 있느냐다. 자바의 성공은 자바 프로그래밍 언어의 특징에도 있었지만, 또 하나의 요소는 바로 사용 가능한(out-of-the-box) 표준 라이브러리가 언어의 런타임과 함께 배포되었다는 점이다. 프로그래밍 언어의 이러한 특징으로 인해 개발 작업은 새로운 것을 만들어내는 일에서 이미 작성된 라이브러리를 최대한 잘 활용하며 어떻게 조합하느냐로 바뀌었을 정도다. 이러한 변화를 잘 반영하는 말이 있다. 흔히 자바 프로그래밍을 처음 시작하는 사람에게 해주는 충고로 “어디에 있는지를 알아라!(Know Where)”라는 이야기를 많이 한다. 과거 프로그래밍은 언어의 기본적인 기능만으로 모든 것을 만들어 써야 하던 ‘Know What, Know How’의 시대였다면 현재의 프로그래밍은 자신이 사용하고자 하는 기능이 어떤 클래스에 어떻게 구현되어 있는지를 알고 이를 재빨리 찾아서 사용하는 것으로 바뀌었다. 따라서 얼마나 다양하고 많은 라이브러리를 제공하느냐는 프로그래밍 언어의 성패를 정하게 되었다.

여기서 주목해야 할 것은 단순히 얼마나 많은 라이브러리가 있느냐가 아니라 얼마나 많은 라이브러리가 표준화(standard library)되어 있느냐다. 사실 C 언어의 경우 정말 엄청난 양의 라이브러리가 존재하고, 상당수가 오픈소스로 존재하지만 서로 다른 컨벤션(convention)과 스타일을 사용하는 라이브러리를 자신의 구미에 맞게 요리하여 사용하기란 쉬운 일이 아니다. 남의 코드를 가져다 쓴다는 게 얼마나 어려운 일인지는 조그마한 라이브러리를 가져오려고 시도해 본 적이 있는 사람은 모두 공감할 것이다.

결국 프로그래밍 언어 자체가 이미 표준화된 라이브러리를 매우 풍부하게 제공하여 대부분의 기능한 제3자를 통하지 않고서도 직접 프로그래밍할 수 있는 환경을 만들어 주는 것이 중요하다. MS와 썬은 이미 이런 방향으로 자신들의 언어를 개발하고 있고 많은 성공을 거두었다. 우리가 프로젝트에서 어떤 언어를 선택한다면 그 언어의 특징은 물론 그 언어의 표준 라이브러리가 얼마나 잘 정리되었는지도 반드시 고려해야 할 것이다.

절대 기준은 없다
앞에서 프로그래밍 언어의 선택 기준을 몇 가지 언급했지만, 사실 프로그래밍 언어를 선택하는 절대적인 기준이란 없다. 바꿔 말하면 거의 모든 요소를 고려해도 부족하다는 말이 될 수도 있다. 언어의 특징을 규정짓는 요소들, 예컨대 가독성, 이식성(portability) 등도 모두 언어를 선택할 때 고려해야 할 요소들이고 각각의 생산성에 어떤 식으로든 영향을 미친다. 중요한 점은 프로젝트 시작에 앞서 몇 가지 선택된 기준을 바탕으로 몇 개의 프로그래밍 언어를 평가한 후에 프로젝트 언어를 결정하는 신중함을 가지라는 점이다. 프로젝트 초반의 시간 절약은 나중에 더욱 큰 화살이 되어 돌아올 수 있음을 항상 명심해야 한다. [maso]
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by 홍반장

2006/05/11 11:03 2006/05/11 11:03
Response
No Trackback , No Comment
RSS :
http://tcbs17.cafe24.com/tc/rss/response/1754

책으로 출간 되었는데, 인터넷에 공개가 되어있군요.

잠깐 짬을 내서 읽어보았는데, 유용한 방법론이 여럿 보이네요.

혹시 아직 못 읽어보신 분들을 위해서 링크를 소개합니다.

http://wiki.kldp.org/wiki.php/DocbookSgml/Cathedral-Bazaar-TRANS



성당과 시장 저자 Eric Raymond

http://www.tuxedo.org/%7Eesr/writings/cathedral-bazaar/index.html
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by 홍반장

2006/01/09 11:49 2006/01/09 11:49
Response
No Trackback , No Comment
RSS :
http://tcbs17.cafe24.com/tc/rss/response/1508

http://wiki.kldp.org/wiki.php/HowToBeAProgrammer
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by 홍반장

2006/01/09 11:47 2006/01/09 11:47
Response
No Trackback , No Comment
RSS :
http://tcbs17.cafe24.com/tc/rss/response/1507

[컬럼]좌표를 잃지 않고 프로그래머로 살아남는 법


:: 번호:10 :: 글쓴이: 조성준 :: 등록일: 2002-02-22 00:42:36 :: 조회: 1111




출처 : http://maso.zdnet.co.kr/20010407/specplan/article.html?id=128&;page=1

오픈 소스와 함께하는 'Happy Hacking'

이 글은 컴퓨터 프로그래밍을 이미 자기 삶의 중요한 일부분으로 받아들였지만 잠시 주춤하고 있는 사람들과 프로그래머의 길 앞에서 그렇게 될 것인가 말 것인가 고민하고 있는 사람들에게 '삶의 과정으로서의 프로그래밍'이라는 관점을 갖고 작성했다. 이를 통해 프로그래밍하는 인간의 모습을 돌아보고 프로그래머로서의 인간 에너지를 충전시키는 시간을 제공하고 싶다.


이만용 (리눅스코리아 CTO ) 2001/04/13


필자는 이 글을 통해 지난 3-4 년간 프로그래머가 되고 싶어했던 사람들, 이미 직업으로서 프로그래밍을 하고 있다. 현재보다 더 나은 프로그래머가 되길 원했던 사람들이 필자에게 보낸 메일에 대한 답장 속에서 했던 이야기. 그리고 하고는 싶었지만 답장 메일로 적기에는 너무 길어 적지 못했던 마음속의 말들을 꺼내어 정리하는 시간을 갖게 되었다. 종종 일상의 지겨운 반복 속에서 좌표를 잃지 않기 위해 컴퓨터 앞을 떠나 편안하게 사색에 잠길 수 있기를 바라며 이야기를 시작한다.

원래 창조적인 지적 유희이며 그러해야 한다
필자에게 왜 프로그래밍을 하고 있냐고 묻는다면, 주저없이 '재미(fun)'라고 답할 것이다. 한 가지 덧붙이자면, 만약 프로그래밍보다 더 재미있는 일이 있다고 생각한다면, 역시 주저함 없이 프로그래밍 대신 그 일에 몰두할 것이다. 재미없는 일을 억지로 하면서 보내기에는 인생은 너무 짧지 않은가. 여러분이 이미 생계의 족쇄 속에 또는 사회적 위치 속에 결박당해 탈출할 수 없는 경우가 아니라면, 그리고 충분히 새로운 선택을 하여 재시도할 수 있는 사람이라면, 다시 한 번 진정으로 자신이 프로그래밍을 즐기고 있는지 생각해 보는 시간을 갖기 바란다. 꼭 프로그래밍을 해야 하는 절대절명의 이유란 없다. 앞으로 전개될 글을 읽기 전에 마음의 고리를 풀고 편안한 마음으로 자신의 사고가 흐르는 대로 방치하기 바란다.

꼭 프로그래밍만이 재미있다고 말할 수는 없지 않겠는가. 당연히 재미라고 하는 것이 인간의 다른 모든 행위로부터 프로그래밍을 구별해 주는 유일한 요소일 수는 없다. 이 세상에는 프로그래밍 이외에도 이미 사람이 재미를 느낄 수 있도록 해 주는 일이 헤아릴 수 없을 정도로 많듯이 말이다. 예전에도 그리고 지금도 수억의 인구가 회화, 악기 연주, 운동 등에서 즐거움을 느끼고 있다. 이 활동들은 새로울 것도 없지만, 여전히 재미있는 활동이다. 프로그래밍도 시간이 지남에 따라 훨씬 더 대중화하고 똑 같은 취급을 받을 것이다. 하지만 프로그래밍이 똑같이 재미있는 수많은 일 중 그냥 하나라고 말하기에는 너무 극단적이다. 어떤 점에서 프로그래밍이 주는 재미가 다른 재미와 같고 또한 다른 것일까.

프로그래밍은 이미 오랜 시간 동안 인간의 역사 속에서 사람들에게 재미를 제공했던 기존 활동과는 도구적 관점에서 다르다. 여기서 컴퓨터라고 하는 20 세기의 놀라운 발명품을 이야기하지 않을 수 없을 것이다. 책, 기관차, 전화와 같은 출판 기술, 증기 기관, 통신 기술이 인간 세상을 변화시킨 것처럼 컴퓨터가 현재의 인간 생활을 변화시켰다는 점을 부인할 사람은 없다.

인간은 그 동안 자신이 발견하거나 발명한 것을 즐기며, 도구를 통해 자신을 다시 변화시켜 왔다. 프로그래밍은 컴퓨터라고 하는 도구를 통해 그 안에서 인간의 상상력과 논리적 사고력을 실현해 내는 고급 유희다. 그러나 바로 이전 문장에서 표현했듯이, 인간이 지적 노력을 쏟아 지적인 재미를 만들어 내려고 하는 지적 유희라는 점에서는 그 이전의 모든 창조적 지적 유희와 하나도 다르지 않다. 여기서 필자는 다르다는 점보다 같다는 점을 강조하고 싶다.

채 다 배우기도 전에 쏟아져 나오는 프로그래밍 언어, 선택해 보지 못한 메뉴가 아직도 많은데 버전업돼 나오는 통합 개발 환경에 치여 살다 보니, 프로그래머인 우리 자신이 인간이 최근 만든 가장 놀라운 발명품을 사용해 가장 재미있는 창조적 지적 활동을 하고 있다는 사실을 너무도 쉽게 잊어버리는 모습을 목격할 수 있다. 그리고 현실 속에서는 이러저러한 언어, 도구에 지배받으며 지쳐 있는 불쌍한 자신을 쉽게 발견한다.

하지만 그 어떤 컴퓨터를 사용하든, 그 어떤 프로그래밍 언어나 도구를 사용하든 우리 프로그래머들이 본질적으로는 참 재미있는 일을 하고 있다는 사실을 망각하지 말아야 한다고 말하고 싶다. 그것도 매우 지적인 재미 말이다.

그러한 자기 만족감이 없이 버틸 수 있는 프로그래머가 있을까. 프로그래밍 언어책을 보다 며칠씩 이해되지 않던 부분이 갑자기 슬슬 풀려 나갈 때, 작지만 자기가 예상한 대로 모든 일이 척척 진행돼 나갈 때, 하루 종일 찾지 못했던 버그를 커피 마시다 갑자기 찾아냈을 때 느끼는 자신에 대한 대견스러움, 만족감을 느껴보지 않고 어떻게 프로그래머라고 말할 수 있을까. 이런 즐거움은 이성 친구, 애인, 가장 가까운 친구에게도 어떤 말로도 전달할 수 없는 매우 개인적인 차원인 것이다. 때로는 자신의 소스 코드와 프로그램을 이해하는 지구 반대편의 프로그래머와 더 진한 동질감을 느끼기도 하는 것 또한 프로그래머다.

자신에 대해 대견스러워하는 마음, 무엇보다 자신이 설계한 대로 컴퓨터가 작동하는 것을 보는 즐거움, 컴퓨터를 통해 자기만의 세계가 창조되는 즐거움을 느끼지 못한다면 앞으로 하는 모든 이야기는 별 의미가 없다. 취미로든 직업으로든 왜 프로그래밍을 선택했는지 그리고 왜 수많은 책과 읽을거리와 투쟁하고 있는지 자기 확신을 갖자. 아무리 생각해 봐도 프로그래밍은(유일하지는 않아도) 꽤 매력적인 고급 활동이다. 재미있는 일을 재미있게 하지 못한다면 그것은 큰 문제가 아닐 수 없다.


프로그래밍의 본래 의미를 찾는다
대학생 친구들을 위한 언어 교재를 만들면서 자주 등장하는 외래어 표현을 정리하고 있었다. 그런데 바로 프로그램(program)이라는 말 그 자체가 우리에게 시사하는 바가 많다는 사실을 발견했을 때 마치 보물을 발견한 양 즐거워 한 적이 있다.

'program'이라는 단어는 'pro'와 'gram'의 합성어다. 여기서 'pro' 는 '어떤 일을 하기 전에...' 라는 'before' 의 의미를 갖고 있으며 'gram'은 '무엇인가를 쓰다' 즉 'write'의 의미를 갖고 있다. 따라서 program은 쓰거나 만드는 행위라기보다 '쓰기 전에 하는 일' 즉 계획적인 사고 행위를 가리킨다.

현실적으로 우리가 우리 자신을 설계자나 기획자라고 생각할 수 있는 여유는 거의 없는 것 같다. 우리가 매일 확인할 수 있는 자신의 모습은 특정 언어나 특정 제품, 특정 프로젝트의 노예로 전락해 있는 초라한 모습이지 않은가. 프로그래밍은 어느 새 밤을 세며 코딩하는 중노동과 동일시돼 버렸다. 그래서인지 요즘 미국이나 한국 젊은이를 대상으로 한 설문조사를 보면 그래픽 디자이너가 되고 싶다는 답변이 프로그래머가 되고 싶다는 답변보다 월등히 많다고 한다. 이미 프로그래머란 컴퓨터 분야 중 가장 선호하는 직업이 아닌 것이다.

프로그래밍 작업의 특성이 무엇을 이뤄내기 전에 먼저 머리 속에서 설계하는 정신적 유희라는 본질적인 의미를 자꾸만 잊게 하는 그 무엇을 갖고 있다고도 볼 수 있다. 프로그래머를 계속해서 괴롭힐 동전의 양면적 특성이 존재하는 것이다. 계획과 함께 실천이 있어야만 완성되는 것이 프로그래밍의 중요한 특성이다.

설계한다는 점에서 프로그래머는 건축가와 유사한 점이 많다. 아무리 작은 프로그램을 만들지라도 프로그래머의 머리 속에는 이미 어느 정도의 프로그램 진행 과정에 대한 설계가 먼저 이뤄진다. 그러나 건축가가 실제 건물을 만들지는 않는다. 건물을 직접 만드는 일은 건축 노동자들의 몫이다. 이렇게 건축이라는 영역에서 건물을 설계하는 일과 짓는 일은 완벽히 분리돼 있다. 그러나 프로그래머는 결국 자기 손으로 건물까지 지어야 한다는 점에서 크게 다르다. 상상만 하고 코드를 입력해 실행 프로그램을 만들어내지 않으면 아무 것도 하지 않은 것과 같다. 그런 점에서 프로그래머는 어떻게 보면 화가나 조각가에 더 가깝다. 자기 내면에 비춰진 이미지에서 그치는 것이 아니라 캔버스나 대리석에 실체를 구현해야 하며, 생각하는 주체와 그것을 실현해 내는 주체가 같다.

프로그래머인 우리가 결국 C, C++, 자바 등 특정 언어를 배워 우리의 아이디어를 실행 가능한 소프트웨어로 만들어내야 한다는 사실은 분명하다. 그러나 그렇다고 해서 프로그래밍이 언어를 잘 구사하는 것만으로 끝날 일은 아니다. 그림만 잘 그린다고 해서 화가라고 말하지 않는 것과 같다.

시작은 언어 대신 사고력 부터
그렇다 해도 여전히 훌륭한 프로그래머가 되기 위한 시작은 언어가 아니라 사고 능력이라는 점을 지겹도록 강조하고 싶다. 프로그래밍 언어책을 붙들고 공부한다고 해서 자연스럽게 프로그래밍을 잘 하게 되는 경우는 없다. 만약 그랬다면 이 글을 쓰고 있어야 할 이유조차 없었을 것이다. 언어 공부가 자연스럽게 자신을 프로그래머로 만들어 주지는 않는다. 이 사실은 독자 여러분이나 필자나 말하지 않아도 알고 있다.

또한 그렇다고 해서 무조건 명상에 잠긴다거나 순서도 그리는 일을 다 마치고 나서 언어를 배우고 프로그래밍하는 것도 아니다. 원래 생각하는 과정과 도구를 사용해 실현하는 과정이 떨어져 있는 것도 아니다. 인간은 자유로운 상태에서 생각하며 도구를 사용하고, 도구를 사용하며 생각한다.

인간의 놀라운 점 중 하나는 도구를 사용함으로써 자신의 사고 능력을 발전시키고 그 발전된 사고 능력으로 도구를 개선하거나 새로운 도구를 만들어 가는 무한 사이클을 이어간다는 것이다. 여러 가지 관점에서 설명할 수 있겠지만 필자가 강조하고자 하는 면은 다음과 같다. 생각하지 않으면서 언어를 사용하고 코딩하는 것은 계속 제자리를 맴도는 것과 같다. 생각없는 코딩은 생각하는 사람의 사고 능력에 아무런 영향도 미치지 않는다. 아니, 오히려 악영향을 미치기도 한다. 생각없는 반복적 행동은 오히려 생각을 굳게 만들어 반복적 행동을 또 다시 만들어 낼 가능성이 높다. 극단적으로 말해서 생각없이 코딩하느니 너무 지겨워서 다시 생각을 하고 싶을 정도로 빈둥대거나 잠을 푹 자두는 것이 현명한 일이다(필자는 실제로 그렇게 하고 있다).

인간의 다른 지적 노동과 마찬가지로 현명한 반복만이 현명함을 낳는다. 학문이라는 것이 마치 강을 거슬러 올라가는 것과 같다는 옛말이 있는데, 사실 이보다 더 끔찍하다고 생각한다. 아무 생각없는 반복은 또 다른 생각없는 반복만을 낳을 뿐이며, 현명하게 반복할 수 있다는 사실을 잊게 만든다. 자연스럽게 어떻게 프로그래밍을 배워나가야 하는지 얘기를 이어나가고자 한다.


프로그래밍, 어떻게 배워나가야 하나
'닭이 먼저냐 달걀이 먼저냐' 하는 전통적인 질문이 여기서도 그대로 적용된다. 똑똑해지려면 똑똑하게 배워야 한다. 현명해지려면 현명하게 배워야 한다.

어떻게 똑똑하게 배울 수 있는가
반대로 설명하는 것이 좋겠다. 프로그래밍은 매우 지적인 유희라고 앞서 몇 번이고 반복한 바 있다. 현재 대부분의 프로그래머 지망생이 학습하는 방법은 크게 다르지 않다. 학습이 매우 단순 반복적이다. 단순 반복에 의해 지적인 성장이 이뤄진다고 생각하는가. 게다가 학습 과정이 지겹기 때문에 유희적인 측면도 이미 상실한 지 오래다. 무엇보다도 몇 번의 반복 속에 자기 자신을 지치게 만들면 이미 게임은 끝난 것이다(물론 꾹 참고 꾸준히 하면 언젠가 길이 보일 것이라고 얘기할 수도 있다. 그러나 이렇게 말해 버리면 역시 이 글의 의미가 완전히 사라진다).

똑같은 책, 똑같은 도구를 갖고 배우는데 서로 다른 결과물이 나온다면, 조금만 논리적으로 생각해 봐도 차이를 결정짓는 것은 책이나 도구가 아니라 다른 곳에 있다는 결론을 내리게 된다.

여기서 프로그래밍 학습에 있어 가장 중요한 부분이라고 말할 수 있는 언어 선택 및 학습 과정에 대하여 짚고 넘어가겠다. 먼저 거의 대부분 첫 번째 언어를 잘못 선택함으로써 프로그래밍의 본격적인 재미를 느끼기도 전에 탈락한다. C/C++/자바는 원래부터 만만한 언어가 아니다. 현실적으로 많이 사용하고 있는 이 언어를 많은 사람들이 배우기 어렵다고 말하는데 그 대답은 당연하다. 이 전문언어는 매우 다양한 일을 해낼 수 있는 다목적 언어이며 전문 프로그래머의 경험 속에서 진화해 온 언어이기 때문에 어렵다. 그냥 열렬한 컴퓨터 사용자였다가 갑자기 자기 손으로 프로그램을 만들고 싶다고 해서 제일 먼저 덤빈 언어가 C, C++, 자바와 같은 전문 언어라면 여러분은 열 명 중 여덞, 아홉은 탈락할 것이다.

필자 나이의 다른 프로그래머와 마찬가지로 필자의 첫 번째 언어는 베이직이었다. 필자는 아직도 이 언어에 대한 향수를 갖고 있을 정도로 좋아한다. 이제 생각해 보니 행 번호 개념과 GOTO 문이 유치하게 느껴질 정도로 까마득하지만, 사용자에서 프로그래머가 되기 위한 첫 번째 단계에서는 매우 유용한 중간 단계라고 생각한다. 베이직은 필자에게 인간의 논리가 아니라 컴퓨터의 논리 입장(물론 이것도 창조한 사람이 만들어낸 것이지만)에 서서 자연스럽게 프로그래밍하는 것을 가르쳐 주었다. 지금은 전혀 사용하지 않지만 매우 중요한 언어임에 틀림없다.


단순 조급증에서 벗어나야 한다
프로그래머가 되고 싶어하는 수많은 사람을 처음부터 확실하게 걸러내 준 악습 중 하나는 프로그래머가 되려면 마치 C, C++, 자바 중 하나로 꼭 시작해야 한다는 강박 관념이다. 사람들의 책꽂이에는 최소 2~3 권의 C/C++/자바 책이 꽂혀 있다. 모두 1/3도 보지 않은 채 방치되고 있을 것이다. 바이블에 해당하는 몇 개의 책을 구입했다가 포기하고 결국에는 '며칠 내에 완성하기', '그냥 따라하기'라는 유혹적인 제목의 책을 마지막에 구입한다. 하지만 '21 일 완성하기'를 21일 안에 끝내는 사람은 거의 보지 못했다. 원래 어려운 것을 쉽게 설명하는 일은 더 어렵다.

현실에서 가장 널리 사용하고 있는 매우 현실적인 언어가 C, C++, 자바이기 때문에 처음에 언어를 배울 때부터 이 언어로 시작하면 뭔가 큰 이득이 될 것이라고 생각하는 것이 바로 앞서 표현한 단순 조급증이다. 물론 뭔가에 빨리 도달하고 싶겠지만 생각처럼 되지 않는다. 오히려 꽃도 피워보지 못하고 초반전에서 프로그래머의 세계로부터 탈락하는 지름길을 선택하게 된다.

꿋꿋하게 버텨 살아남은 한두 명도 결국에는 잘못된 믿음의 피해자가 된다. 그들은 어렵게 어렵게 배운 C, C++, 자바로부터 벗어나려고 하지 않는다. 마치 이 세상에 그 세 가지 언어만 있는 것처럼 살아가는데, 사실 살아남기는 했어도 어처구니없게도 언어라는 도구의 노예가 되어 버리고 만다. 이들의 프로그래머적 성장은 이미 끝나버렸다.

상처받은 사람들을 위한 언어, 파이썬
물론 사회적으로 준비가 잘 되어 있는 것은 아니다. 서점에 가봐도 C와 C 유사 언어 외에 다른 언어에 대한 훌륭한 책이 많지도 않다. 여러 가지 언어를 잘 구사하는 훌륭한 프로그래머도 많지 않고 강사는 거의 없다고 봐도 무방하다. 현재 훌륭한 정보의 대부분은 인터넷에 뿔뿔이 흩어져 있고 대부분 영어로 작성돼 있는 것이 현실이다.

이런 상황 속에서도 지금 막 프로그래머가 되고 싶어하는 사람들을 위한 첫 번째 언어로서, 그리고 기존 언어를 모두 맛보고, 패배감을 가진 사람들이 자신을 재정비하고 다시 프로그래밍의 즐거움 속으로 빠져들기 위한 재충전용 언어로 '파이썬'이라는 언어를 권하고 있다.

아직 첫 번째 교육 언어로 채택하기에는 훌륭한 서적과 과정이 나와 있지 않은 상황이어서 필자가 처음 시작했던 베이직보다는 어려울 것이다. 그러나 다른 언어에 의해 상처받은 사람들을 치유하는 치료용 언어로서는 상당한 효과를 볼 수 있다. 이 언어를 통해 언어가 중요한 것이 아니라 인간의 사고력을 풍부하게 발휘하는 것이 중요하다는 사실을 배울 수 있다.

여러분이 오히려 컴퓨터 언어를 단계적으로 여러 가지 배워감에 따라 자신이 진정 원했던 결과를 더 빠르게 그리고 더 견고하게 세워 나갈 수 있다는 사실을 느끼길 바란다. 언어는 결국 교체 가능한 도구라는 사실을 알게 되고, 여러분의 필요에 따라 새롭게 배우고 구사할 수 있다는 자세를 갖추는 것이 중요하다. 또한 2~3 가지 언어를 구사할 수 있어야 한 가지 언어만 알았을 때보다 훨씬 더 심도깊게 언어를 사용할 수 있다는 사실도 깨닫게 될 것이다.


다양한 오픈소스의 세계
컴퓨터 언어를 배우는 플랫폼도 중요하다. 필자로 하여금 C, C++, 자바 이외에도 이 세상에는 수많은 언어가 있으며 수많은 새로운 아이디어가 있다는 사실을 일깨워 준 것이 바로 리눅스와 오픈소스 세계다. 오픈소스는 필자에게 프로그래머로서의 새로운 의지를 수혈해 준 주역이다. 여기서 파이썬을 포함해 LISP, 펄, Ada 등등 많은 언어를 접할 수 있었으며, 여러 번의 외도(?)를 통해 오히려 이미 알고 있던 C 언어를 훨씬 더 잘 이해하고 어디에 어떻게 적절하게 사용해야 할 지 알게 되었다. 무엇보다 각 언어마다 나름의 이유가 있으며 그 창조자의 생각을 어느 정도 이해할 수 있다는 즐거움도 만끽할 수 있었다. 다양한 욕구를 가지고 있는 독자라면 리눅스에서 다양한 오픈 소스 언어를 만나 보기 바란다. 그리고 여러분이 눈길을 주기를 기다리는 어마어마한 분량의 소스 코드가 널려 있다. 또한 멋진 것은 매우 초보적인 소스 코드부터 매우 전문적인 소스 코드까지 선택의 폭이 넓다는 것이다.

한편, 윈도우 플랫폼에서는 좋으나 싫으나 마이크로소프트의 제품 정책에 따를 수밖에 없으며(그나마 예외는 자바 정도) 따라서 제품의 노예가 되어버리기 쉽다. 예를 들어 현재 프로그래머 사이에 논란이 되고 있는 C# 이라는 언어는 새롭게 출현해야 할 정당한 논리적 이유없이 자바와의 전쟁 속에서 나온 사생아라는 지적이 나오고 있다. 직업적 프로그래머라면 새로운 언어와 규칙을 배워야 하는 수고를 마다해서는 안되겠지만, 프로그래머가 되어 볼까 생각하는 사람들에게는 짜증나는 현실이다.

조금이나마 다행스러운 것은 오픈소스 진영이 매우 성숙해 훌륭한 소프트웨어의 대부분이 윈도우와 매킨토시 등 리눅스/유닉스가 아닌 플랫폼에서도 동작한다는 사실이다. 여러 플랫폼에서 동작하는 멀티 플랫폼 언어나 도구를 사용하는 것도 현명한 선택 중 하나다.

웹 프로그래밍 언어에만 집착하지 말자
마지막으로 언어 선택에 있어 웹 프로그래밍과 관련한 PHP, ASP, JSP에 대한 의견을 개진하고자 한다. 결과를 즉시 확인할 수 있으며, 현재 유행하는 개발 영역의 언어이기 때문에 많은 사람들이 쉽게 시작하고 있지만, 이 언어들은 모두 실용 언어로서 인간에게 프로그래밍하는 더 좋은 방법을 알려주지는 못한다. 따라서 전문 프로그래머가 되려면 이 언어에만 집착해선 안된다. 또한 프로그래밍 본연의 지적 유희를 즐기려는 취미 프로그래머도 역시 이 언어에만 집착해선 안된다. 실전의 전문 프로그래머는 이들의 한계를 분명히 인식하면서 사용한다. 실용 언어와 함께 일반 언어도 동시에 익혀 나감으로써 프로그래밍 사고력과 실용성을 모두 성취할 수 있기를 바란다.


직업적 프로그래머가 되고 나면
프로그래밍이란 생계와 결부되는 매우 실용적인 영역임에도 불구하고 의도적으로 이 이야기를 지금까지 피해 왔다. 직업으로 프로그래밍을 하고 있는 사람은 이 글을 읽으며 무슨 지적 유희냐고 화를 내고 있을 지 모른다. 실전에 들어가면 프로그래머의 생활이란 다음과 크게 다르지 않다.

* 자바 프로그래머로 입사했는데(사실 이 말 자체가 우습다. 프로그래밍 언어 중 자바도 구사할 수 있는 프로그래머라고 표현해야 한다) 실제 프로젝트는 별로 사용해 본 적 없는 C++로 해야 한다고 팀장이 전달한다. 자기가 잘 모르는 언어로 프로그래밍을 해야 한다는 부담감 때문에 매일 짜증내면서 어쩔 수 없이 새롭게 책을 구입해 쫓기듯 학습한다.

* 쉬엄쉬엄 컴퓨터 앞에 앉아 이런 생각 저런 생각을 하면서 코드만 작성하고 만들어내기만 하면 되는 줄 알았는데, 거의 대부분의 시간을 보고서와 설명서를 쓰는 데 허비하고 있다. 과연 내가 프로그래밍을 하고 있는지 문서 작성을 하고 있는지 한탄스러울 때가 많다.

* 열심히 만들었더니 주문한 고객의 마음이 또 바뀌어 모든 부분을 일일이 다 고쳐야 하는 일이 다반사다. 창조적이라기 보다는 코딩 막노동(?)이라는 느낌이 들면서 자신이 한심하게 느껴지기 시작한다.

* 거의 대부분의 시간을 버그 잡느라고 머리털 빠지고 있다. 재미없는 디버거와 함께 하는 시간이 코드 짜는 시간보다 월등히 많다.

이런 현실적인 문제들을 하나씩 짚어 가기 전에 필자는 독자 여러분에게 이 세상에 재미를 느끼게 해 주는 수많은 일들이 있는데 프로그래밍을 자기 직업으로 삼은 이유가 무엇이냐고 우선 반문하고 싶다. 마음속으로 자기만의 답을 생각해 보고 앞서 나열한 네 가지 문제를 하나씩 다뤄보자.


새로운 언어를 적극 받아들이자
번 문제를 살펴보자. 회사나 팀장의 요구가 부당하다고 생각할 지 모르지만, 자신이 모르는 다른 언어로 프로그래밍해야 한다는 요구가 무조건적으로 틀린 것은 아니다. 사실 여러분이 직업적 프로그래머로서 직장 상사나 팀장에게 '나는 이 언어밖에 못합니다'라고 말하는 것은 프로그래머로서의 자신의 진짜 가치를 고백하는 것이나 다름없다. 굳이 사회적으로 통용되는 표현을 쓰자면, 한 가지 언어만을 전문으로 구사할 수 있다고 말하는 사람은 그 언어만 다룰 수 있는 기능사일 뿐이다. 기술자라면, 아니 진짜로 프로그래머라면 새로운 언어를 배워야 한다는 것이 짜증나는 일이라고 단언해서는 안된다. 새로운 언어를 배워 나가는 것은 전문 프로그래머의 일상 업무이다.

물론 지금 당장은 답답할 지 모른다. 그러나 필자의 논지에 수긍한다면 어떤 언어든 자기가 구사할 줄 아는 언어의 전부가 아니라 그 중 하나일 뿐이어야 한다. 팀장의 요구가 없다 하더라도 사실 유행에 따라 어쩔 수 없이 또 다시 끌려가야 하는 경우도 있지 않은가. 원래부터 피할 수 없는 일이므로 적극적으로 받아들이자.

문서화는 결코 어려운 일이 아니다
번 문제를 살펴보겠다. 필자도 보고서를 쓰거나 설명서를 쓰는 작업은 태생적으로 싫어한다. 그러나 보고서나 설명서를 쓰는 작업 자체가 프로그래머의 몫이 아니거나 또는 무가치한 일로 보는 입장에는 동의할 수 없다. 물론 형식화한 보고서, 설명서를 쓰는 것은 매우 지겹고 화나는 일이다.

보고서와 설명서를 쓰는데 많은 시간이 걸리는 이유는 두 가지를 들 수 있다. 원래 문서화 작업이라고 하는 것이 생각보다 시간이 많이 걸리는 작업이다. 우리의 머리 속에 있는 것을 글로 표현한다는 것이 쉽지 않다는 사실은 어렸을 때부터 독후감 쓰는 일이 쉽지 않다는 경험으로부터 잘 알고 있을 것이다. 글로 표현한다는 것은 자유롭게 흘러가는 생각을 그대로 반영하는 것이 아니라 한 번 더 숙고해 체계화하는 과정이기 때문이다(필자 또한 지금 이 원고 쓰는 일을 흔쾌히 승낙해 놓고서는 얼마나 후회하는지 모른다).

그러나 무엇보다도 자신이 글을 쓰는 일에 익숙하지 않다고 스스로를 묶어 버림으로써 문서 작업을 싫어하고 집중할 수 없게 되는 수도 있다. 자기 최면을 통해 집중하지 않음으로써 여러분은 자기가 싫어하는 일에 더 많은 시간을 할애할 수밖에 없고 그 만큼 여러분이 원하는 작업에 필요한 시간을 허비하고 있다.
리눅스나 오픈소스라고 해서 마냥 코딩만 하고 문서화는 전혀 안한다고 생각하면 오산이다. 최소한의 README, 잘 만들어진 문서가 없는 오픈소스 소프트웨어는 초보 프로그래머의 작품일 뿐이다. 이미 수준 높은 품질의 아파치, 삼바, 리눅스 커널을 보면 상당히 친절한, 하지만 작성한 사람 입장에서는 많은 노력을 들인 문서들이 포함돼 있다는 사실을 알게 될 것이다.

문서화 또한 현명한 대처가 필요하다. 막무가내로 불필요한 분량의 문서를 요구하는 팀조직이 있다면 매우 고루한 조직임에 분명할 것이다. 이러한 조직에 대해 말할 수 있는 해결책은 없다. 그 조직은 여러분이 선택한 것이다. 너무 불합리한 경우가 아니라면, 문서화 작업을 소프트웨어 디자인의 일부로 여기는 능동적인 자세가 필요하다.
코딩을 할 때 소스 코드에 주석(comment)을 넣지 않는 것은 전문 프로그래머로서의 자질이 없음을 단적으로 보여 주는 것이므로 주의하자. 직업적 프로그래머라면 어떤 일이 있어도 소스 코드는 주석으로 시작해서 주석으로 끝나야 한다.

문서화란 어떻게 보면 그렇게 어려운 것도 아니며 프로그래밍의 필수 과정이기도 하다. 기본적으로 소스 코드의 주석, README, INSTALL, 그리고 TODO(앞으로 할 일), 각 버전간의 변경 사항을 적는 Changes 문서는 모든 문서화의 기초가 된다. 아직 직업 프로그래머로 취업하지 않는 예비 프로그래머는 지금부터라도 이를 습관화하기 바란다.
많은 사람들이 오해하고 있는 것을 하나 지적하고자 한다. 대부분 프로그래밍을 코딩에 쏟은 시간만 갖고 평가하려는 경향이 있다. 그러나 앞서 'program'의 어원을 알아보면서 확인한 것처럼, 프로그래밍에서 가장 중요한 것은 계획이다. 계획하고 기획한 것을 좀 더 구체적인 방법으로 설계하고 언어를 통해 구현하고 중간 과정을 기술하는 모든 행위가 프로그래밍이다.


'간략한' 프로그램을 위해 노력하자
번 문제로 넘어가겠다. 일단 계획이 서면 거침없이 코드를 작성하고 고치지 않을 것 같지만 몇 명의 천재적인 프로그래머를 제외하고(실제로 그런 사람이 있는지 궁금하다. 자기가 수없이 반복하면서 얻은 경험에 의지해 거침없이 하는 것은 아닐까?) 거의 모든 프로그래머는 그런 식으로 프로그래밍하지 않으며 할 수도 없다. 열심히 프로그래밍했다고 생각했는데 일 년이 지나 소스 코드 개수와 줄 수를 세 보고나면 자괴감에 빠질지도 모른다.. 실제로 우리는 끝없이 고치고 고치고 또 고친다. 그러면서 소프트웨어가 견고해 지는 것이다.

그리고 현실 세계에서 고객의 요구는 첫 번째로 중요하다. 그들의 요구가 변화하는 것은 당연하다. 훌륭한 프로그래머는 고객이 처음부터 정확한 요구 사항을 제시하도록 유도하고 변화의 폭이 제어할 수 있는 범위 안에 들 수 있도록 잘 안내한다.
소프트웨어의 기능을 잘 구분하고 반복적인 패턴을 함수/라이브러리/모듈화하지 못하는 초보 프로그래머는 똑같은 소스 코드를 여기 저기 복사해서 쓰게 되는데, 이 때는 소프트웨어를 고치는 일이 곤역스러울 수밖에 없다.

전문 프로그래머라면 반복적인 패턴을 훨씬 더 많이 찾아내고 압축하는 기술을 가꿔 나가야 한다. 다시 한 번 말하지만 반복적인 경험에서는 얻을 것이 별로 없다. 그 수많은 경험 중에서 문제 해결을 위해 고민한 시간만이 소중한 경험이다.
고객의 변덕에 따라 짜증이 날 정도로 많이 고쳐야 한다면, 그것은 오히려 여러분에게 더 많은 경험과 사고가 필요하다는 증거이다. 같은 일을 하더라도 지난번보다는 더욱 더 간략하게 프로그램을 작성할 수 있도록 노력하라.

디버깅은 불필요한 일이 아니다
번 문제를 생각해 보자. 우리의 예상과 달리 프로그래밍 중에서, 특히 프로그래밍의 일부분인 코딩 중에 새로운 코드를 만들어 내는 시간보다는 기존의 코드를 개선하거나 잘못된 코드를 찾아내는 일에 절대적으로 많은 시간을 쏟는다고 한다.

필자의 경우도 예외는 아니었다. 그러나 경험을 토대로 스타일을 바꿔나가기 시작했다. 필자가 제일 많은 시간을 쏟는 부분은 자료 수집과 연습 코드 부분이다. 필자의 경우에는 무조건 책이나 웹을 통해 관련 자료를 수집하고 재빨리 훑어 내려간다. 다 이해하지 못해도 상관없다는 듯이 읽어 내려간다. 특히 요즘은 노하우보다 노웨어가더 중요하다고 말하지 않는가. 이미 많은 문제의 일부분을 다른 사람이 해결했을 가능성이 높다. 이를 반복할 필요는 없다. 현 시대에서 요구하고 있는 프로그래머의 자질 중 하나는 처음부터 다시 만드는 것이 아니라, 기존의 것을 취사 선택해 창의적으로 결합시키는 능력이다.

그 다음에는 짧은 연습 코드를 많이 작성한다. 핵심적인 부분에 대한 연습 코드를 몇 번 작성하다 보면 프로그램의 절반이 끝났다고 해도 과언이 아니다. 개인적으로 자료 수집과 연습 코드, 특히 연습 코드에 신경을 많이 쓰는데 이렇게 함으로써 프로그래밍 과정에서 절대 빠질 수 없는 디버깅(debugging)을 최대한 피할 수 있다고 생각하기 때문이다.

하지만 어떤 식으로든 디버깅 과정을 피할 수 있다고 생각하지 말라. 사실 버그를 얼마나 빨리 잡는가, 그 짜증나는 시간을 어떻게 빨리 마칠 수 있는가는 그가 얼마나 유능한 프로그래머인지 판단할 수 있도록 해 주는 잣대이다. 디버깅이 마치 불필요한 과정이라고 생각하지 말았으면 한다. 여러분이 만든 버그야 어떻게 잘 피할 수 있을 지 몰라도 실전에서는 남이 만들어낸 버그를 찾아야 할 때가 많다. 그런데 남이 만들어낸 버그를 잘 찾는 사람이란 결국 알고 보면 자기 자신도 똑같은 버그를 만들어 보았고 고통스러운 시간을 통해 버그를 찾아낸 경험이 많은 사람이다.

디버깅에서 중요한 자세는 절대 짜증내지 말고, 적군을 무찌르겠다는 식의 투지를 갖고 단시간 안에 돌파하는 것이다. 만약 한 가지 방법이 실패했다면, 잠시 먼 발치에서 새로운 구상을 한 뒤, 다시 전투적으로 임한다. 지루하게 디버깅을 하면 시간도 많이 걸리고 정신도 피폐해진다.

결론적으로 정도의 차이가 있을 뿐, 여러분이 현실 세계에서 당면하고 있는 모든 문제는 피해야 할 어떤 일이 아니라 사실 프로그래밍이라고 하는 전체 과정에 원래부터 속해 있던 일부라는 사실을 인식하고 이에 대해 짜증을 내는 수동적인 방식이 아니라 좀 더 현명하게 그리고 적극적으로 자기만의 해결책을 찾아나가길 기대하겠다.


몇 가지 실천안
다음 실천안은 여러분이 좀 더 프로그래밍을 즐길 수 있고 직업적으로도 유능함을 발휘할 수 있게 되길 바라며 마음속에 떠도는 생각을 아주 간략하게 정리해 본 것이다.

◆ 프로그래밍이란 절대 코딩이 아니다. 먼저 생각하고 만든 것을 정리하고 문제점을 해결해 나가는 모든 과정이 프로그래밍이다. 이 점을 자기 자신에게 충분히 납득시켜야 한다. 코딩은 프로그래밍의 일부이다.
◆ 각 언어는 모두 나름의 탄생 이유가 있으며 그 언어를 만든 사람의 아이디어가 담겨 있다. 언어를 먼저 선택하려 하지 말라. 유능한 프로그래머는 절대 한 가지 언어에 집착하지 않는다.
◆ 언어를 처음 배울 때에는 그에 걸맞게 쉬운 언어부터 시작하라. 실전에서 사용하는 언어를 먼저 배워두면 더 이득이 될 것이라고 생각하지 말라. 전문 프로그래머가 되려면 최소한 세 개 이상의 언어를 익혀야 한다. 물론 세 가지 언어를 똑같이 잘 할 필요는 없다. 자기 주 종목 언어를 갖지 말라는 말이 아니다.
◆ 책을 다 읽고 나서야 프로그래밍할 수 있다고 생각하지 말고 배운 만큼만 갖고도 연습 코드를 작성할 수 있어야 한다.
◆ 언어 그 자체는 여러분의 상상력을 키워주지 않는다. 상상력은 여러분 스스로 인생의 모든 영역에서 듣고 배우면서 채워야 한다. 언어는 상상력을 실현할 도구만 제공할 뿐이다. 과학과 수학에 관심을 가져 보라(그렇다고 해서 A 등급을 맞을 만큼 잘 할 필요는 없다).
◆ 주석 및 문서화 버릇을 들이자. 프로그래밍의 귀찮은 일부가 아니라 매우 중요한 핵심 부분이다.
◆ 언어책이 줄 수 있는 지식의 양은 딱 그 만큼이다. 여러분의 상상력과 프로그래밍 능력을 살찌워주는 것은 다른 사람, 다른 프로그래머다. 적극적으로 프로그래밍 사용자 모임 또는 뉴스그룹에 참여해 남을 돕고 남으로부터 도움을 받는 것이 자기 계발의 원천이다.
◆ 자기가 습득한 지식은 자신만이 볼 수 있는 형태든 아니면 홈페이지를 통해 누구나 볼 수 있는 형태든 상관없이 정리하는 습관을 갖자. 무엇이든 막상 글로 적으면 자신이 얼마나 피상적으로 알고 있는지 각성하게 되고 지식을 좀 더 견고하게 만들게 된다.
◆ 현실은 현실이다. 영어를 잘 못하고 두려워하는 사람이 최고의 프로그래머가 되기는 거의 불가능하다. 여러분이 한국어만 하면 한국 프로그래머의 지식만 습득할 수 있을 뿐이다. 영어를 두려워하지 않는다면, 그 대가는 전세계 프로그래머의 지식 습득이 된다(영어를 잘 하는 방법은 영어를 잘 하는 사람에게 물어보라).

아무튼 여러분이 프로그래밍의 본질을 재확인하고 프로그래밍하는 그 과정을 즐길 수 있는 사람이 될 수 있기를 바라며 글을 마친다.
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by 홍반장

2005/11/03 13:35 2005/11/03 13:35
Response
No Trackback , a comment
RSS :
http://tcbs17.cafe24.com/tc/rss/response/1369

eXtreme Programming

http://xper.org/wiki/xp/

한국 eXtreme Programming 사용자 모임
Korea eXtreme Programming Users' Group

XP, ExtremeProgramming은 AgileMethodology의 하나로, 소프트웨어 개발에 있어서 단순성(simplicity), 소통(communication), 피드백(feedback), 용기(courage)의 네가지 가치 추구를 통해, 고객의 비지니스 가치 실현을 최고의 목표로 하는 실천적인 개발 방법론이다.

RefactorMe and SignalToTheTop^



마소 용어 사전 vol 2 익스트림 프로그래밍(XP)은 최근 개발방법론 중에서 급부상하고 있는 애자일 소프트웨어 개발론(Agile Software Development)의 하나로, 단순성, 상호소통, 피드백, 용기 등의 원칙에 기반해서 "고객에게 최고의 가치를 가장 빨리" 전달하도록 하는 경량 방법론이다. 요구사항 등의 변화가 자주, 많이 있거나 개발자가 소규모(10명 내외)이고 같은 공간을 사용하는 경우에 높은 효과를 볼 수 있다고 알려져 있고, 다른 규모나 원거리 XP 등의 적용이 꾸준히 시도되고 있다. --김창준


KentBeck과의 인터뷰에서 김창준 : XP를 예컨대 경영자 같은 사람에게 몇 분 만에 설명한다면 어떻게 하겠습니까. 그런 사람들에게 수년 간 XP를 설명해 왔으니 이제는 '진화된' 간략한 소개를 할 수 있을 것 같군요.

KentBeck : 당신이 이 소프트웨어가 했으면 하는 모든 것(우리는 이걸 '스토리'라고 부릅니다)을 적을 수 있다고 상상해 보세요. 각각의 스토리는 신기하게도 구현하는 데 일주일이면 됩니다(분명 작은 이야기들이겠죠). 만약 20개의 이야기(스토리)를 가진 프로젝트가 얼마나 걸릴지 알고 싶다면, 답은 20주입니다. 만약 15주 후에 그 프로젝트가 완료되길 바란다면, 당신은 가장 중요한 열다섯 개의 이야기만 고르면 됩니다. 만약 유의미한 열다섯 개의 이야기를 추려낼 수 없다면 당신은 지금 당장 프로젝트를 취소하는 게 좋을 겁니다(아니면 기적을 바라며 기도하든지요).


1주일에 한번씩 당신은 구현할 이야기 하나를 선택합니다. 1주일에 한번씩 당신은 그 주의 이야기와 동시에 이전의 이야기 모두를 포함하는, 출하 가능한 완전한 시스템을 얻게 됩니다. 만약 6주 후에 새로운 이야기를 발견한다면, 당신은 얼마든지 다음주의 이야기로 그것을 선택할 수 있습니다만, 또 다른 이야기 하나는 구현될 수 없다는 것을 기억하세요.


12주 후에 출하할 것을 결정한다면, 당신은 가장 중요한 열두 개의 이야기가 구현될 것을 보장 받습니다. 당신은 나머지 모든 것은 덜 중요하다고 결정한 것이죠.


[From 마이크로소프트웨어 2001년 12월호 ]
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by 홍반장

2005/10/28 05:34 2005/10/28 05:34
Response
No Trackback , No Comment
RSS :
http://tcbs17.cafe24.com/tc/rss/response/1355

« Previous : 1 : ... 3 : 4 : 5 : 6 : 7 : Next »

블로그 이미지

- 홍반장

Archives

Recent Trackbacks

Calendar

«   2024/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
Statistics Graph

Site Stats

Total hits:
179938
Today:
84
Yesterday:
243