프로그래머를 위한 안전띠
spatialguy의 얼음집: "소년이여 신화가 되어라!"의 ruby on rails에서 test를 쓰지 않으면, 실제로 반도 안 쓰는 것 에서 트랙백.
요즘의 프로그래머들이 다뤄야하는 현실의 문제는 매우 복잡하다. 뭐하나 간단(?)한 것만 짜려고해도,
- 네트웍 통신: 수많은 예외사항 (예기치않은 연결 종료, 과부하로 디바이스 드라이버 사망, DNS 주소 문제, 인터페이스 선택 문제)이 한 가득
- 암호화된 통신: 민감한 정보나, "내가 누구다!"라고 주장하는 것에 대한 challenge등등
- DB: 대부분의 시스템에는 보이던, 그렇지 않던 뒷단에는 거의 DB가 있다
- 분산된 부하 관리: 한 두대의 머신으로는 보통 감당 안되는 부하들을 처리해야 한다
등등, 산적한 현실의 벽과 싸워야 한다. 그리고 발 한 번 헛디디면, 언젠가 터지는 버그가 안에 곱게(…) 자리잡게 된다.
이런 복잡한 프로그래밍 환경과 맞서는 방법으로 최근…이라기보단 이미 좀 된 과거부터 대세(…이 단어는 싫어하지만)가 된 것 중 하나인 테스트 주도 개발이다. 여기에서 사용되는 개념이,
- 반복가능하고, 될 때까지(regression) 재실행되는 자동화된 테스트들
- 자동화된 테스트들을 도와주는 프레임웍 — xUnit 처럼 테스트 준비(setUp), 실행, 종료 처리(tearDown)를 도와주는 것들. ((여기서 setUp/tearDown 되는 부분을 fixture라고 부르기도 한다)
- DB나 네트웍 등을 테스트하기 쉽게해주는 가짜 디바이스 드라이버나 DB 테스트 유닛들
- 특정 형태/순서로 값을 되돌려주거나 미리 입력된 상태로 반응하는 가짜 객체(mock-object)들
정도가 있다. Spat. 군이 언급한게 이런거고, 이런 안전띠(?)없이 프로그래밍 하는 일은 장인의 반열에 오르지 않고서야 쉬운 일이 아닐 거다. 비슷한 이유로 이클립스에는 대부분의 개발환경에서 xUnit 류를 실행하는 실행옵션들이 존재 한다 — 예를 들어 python 개발 환경인 pyDev의 실행 옵션은 python, pyUnit, jython 환경들이 있다. MS의 VS도 Team System 이상의 팩키지에는 테스트 용 환경들이 있고, 기업 환경급에서 널리 쓰이는 개발도구들은 이런 자동화된 각 여러 테스트 단계들을 잘 지원하는 것들이 여럿 나와 있다.
즉, RoR은 요즘 나온 환경이라서 저게 보이기 쉬운 곳에 있는 것 뿐이고, 현존하는 주요 언어들 — 한참된 C++부터, 몇 년 안된 python이나 ruby, C#에 이르기까지 — 은 TDD용 환경에 해당하는 test, testUnit, test-fixture, mock-object 같은 것들을 잔뜩 껴안고(?)있다. …다만 안 쓰는 사람들이 많은게 문제지 (…)
덤으로 소스 코드를 분석하거나, "이게 좀 이상한거 같다" 하는 식으로 보고하는 도구들 — covertura라거나 vtune이라거나 소스코드 복잡도 분석툴들 — 도 언어마다 잔뜩 있다. 그리고 이런 류의 툴은 사용자 수나 기업환경에서 많이 쓰이는 애들에 더 많이(비싼걸로) 존재하기도 한다…
ps. 덤으로 웹 응용 쪽에서 사용하는 breakpoint에 대한 얘기를 했는데, 이걸 데스크탑 응용이나 서버 응용 쪽에서 놓고 보면 코어 덤프, 로그 등등이 되겠지…
부끄러운 일, 부끄러워 해야만하는 일
좀 분에 넘치는 주제이긴한데, 그래도 좀 연관이 있는 예를 하나 들어보자. 내가 그렇게 concrete한 수학적 지식을 가지고 있진 못해서 좀 많이 부끄럽지만 일단 글을 써본다. 대략 대학 1학년 수준의, 혹은 공학수학 초급 지식 정도면 일단은 알아볼 수 있는 내용이긴하다 :$
3차원 공간에서 어떤 사물을 나타날 때 정지해있는 단순한 상태라도 이걸 설명하기 위해선 적어도 두 가지 요소가 필요하다. 사물의 현재 위치와 방향에 해당하는 2가지 벡터가 있어야하는데 , 일단 이 두 가지만 가지고도 몇 개의 상태 — 그러니까 한 순간과 그 다음 순간, 또 다음 순간과 그 또 다음 순간… — 을 표현하고, 그 사이를 잇는 많은 연결점? 연결상태? 들을 그리는게 가능하다. 그리고 이렇게 “이어서 그리는 것”은 컴퓨터 공학의 여러 분야 — 그래픽스, 애니메이션, 게임, 가상 현실… — 에서 꽤나 중요한 문제이기도 하다.
위치를 부드럽게 이어서 사이의 위치들을 알아내는 것은 Catmull-Rom Spline이라거나 혹은 그외의 방법들(B-Spline … NURBS 같은 것들) 을 사용해서 그런대로 쉽게 알아낼 수 있다.
근데 순간 순간의 방향들은 어떻게 “연결해서 추정” 할 수 있을까? 고등학교 수학시간에 조금 관심을 가지고 들여다봤으면,
x + yi, where (x^2 + y^2) = 1
꼴로 표현되는 제한된 복소수 (complex number) 가 2차원 평면 상의 회전에 대응된다는 것을 볼 수 있었을거다. 그리고 방향을 “표준벡터 (x, y) = (1, 0)에 대응되는 녀석을 특정 각도 만큼 회전된 것이다!” 라고 생각하면 방향도 이런 복소수를 써서 표현할 수 있다.
이와 비슷한 개념이 3차원의 방향 에 대해서도 적용될 수 있는데, 1843년에 해밀턴 경 이 발견한 4원수;Quaternion 중 특수한 형태 — 4차원 단위구 위에 있는 quaternion만 해당 — 가 그런 도구로 사용될 수 있다.
즉,
w + xi + yj + zk
라는 식으로 표현되는 일종의 4차원 수인데, 이 녀석이 아주 멋진! 성질을 가지고 있다. 위에서 언급한 특수한 형태의 사원수들은 3차원 공간에서의 방향 혹은 회전에 대응되는데 사원수들을 Catmull-Rom Spline 해버리면 방향의 중간값들을 추정할 수 있게 된다.
19세기에 발견된 수학이 21세기의 컴퓨터 그래픽스, 컴퓨터 애니메이션, 컴퓨터 게임에서 쓰이는 아주 요긴한 도구가 되는 것이다
그리고 실제 산업에 끼친 영향의 값어치를 따지면 자동차 수십만대로는 세지도 못할걸 :p
이런 식으로 컴퓨터공학, 컴퓨터과학, 좀 더 좁게 보면 컴퓨터 그래픽스나 병렬처리 같은 분야에서는 길게는 수백년 전에 발견?된 수학들로부터 굉장히 많은 것들을 빚지고 있다. 즉 지금의 번영, 문명, 지식들이 있게 해준 단단한 토대 중 하나는 이 “수학”이다.
다음 아고라에서 청원이 진행되고 있긴하지만 3주로 예정된 서명기간 동안 천명이 좀 안되는 사람들만이 조용히 서명하고 있는 상태다. 그리고 참 착찹한 일이지만, 이대로면 그대로 통폐합되고 묻혀 사라질 것만 같다.
실용주의 정부 — 개인적으론 반어법 혹은 모순어법이라고 느껴지는 명칭이지만 — 의 관점에서 보기엔 수학이라는 학문은 그리 실용적인 것이 아니었나 보다. 하지만 수 년, 혹은 수 십년, 길게는 수 백, 수 천 년의 미래를 봤을 때는 이명박 정부의 모든 관료들이 하는/하려는 일보다, 국가수리과학연구소가 통폐합되지 않고 지켜져서 얻을 수 있는 가치가 많을 것 같다.
진정 실용정부가 되려면 자신들의 이익말고 미래도 좀 내다봐야하지 않겠나.
숙련자와 초짜의 차이
Signal vs. Noise 에서 스크랩 - Christopher Alexander on the difference between a fifty-year-old carpenter and a novice.
건축이나 모터싸이클 수리 같은 아날로그 시대부터의 전통이 있는 분야가 컴퓨터 공학의 프로그래밍 쪽의 메타포로 자주 사용되는데 그 중 자주 인용되는 크리스토퍼 알렉산더의 “A Pattern Language”에서 따온 부분이 37 Signals에 있더라.
Along the way, he compares the work of a fifty-year-old carpenter with the work of a novice. The difference: The experienced craftsman plans less because he has learned to do things in a way that lets him make small mistakes. This gives his work “unconcerned simplicity.”
숙련된 목수는 조금만 계획한다 — 왜냐하면 일 자체를 거의 실수하지 않는 방향으로 하는 법을 알기 때문에.
이게 바로 “unconcerned simplicity” 다.
초보/초심자들이 일 — 예를 들어 프로그래밍이라거나 :p — 을 할 때 계획을 세우려고 하는 것은 “실수 했을 때 바로 잡지 못할 까 두려워하기 때문” 이라는 것. 지금의 내게 딱 맞아 떨어지는 느낌 -_-;;
이렇게 하면 잘 안될지도 모르는데, 저렇게 하면 나중에 고칠 수 없을텐데?하면서 시간을 소모하고 있는 것. 숙련된(장인?) 목수는 일단 일을 시작해도 나중에 삽질한걸 덮을 수 있다는걸 알기 때문에 대범하게 작업할 수 있고, 나같은 초짜들은… Orz
뭐 별 수 있나, 더 경험하고, 더 생각하고, 더 공부하는 수밖에…
프로그래머의 일상: 2008년 5월 29일
빌드 서버 설정 삽질기
남는 듀얼 코어 머신(Conroe 6600) 한 대를 빌드 머신으로 쓰기로 하고 점심 먹고 설정을 시작.
- 장비 소유자를 변경하고, MAC 주소 발급을 기다림
- 뭔가 부팅이 되었다 말았다해서 일단 불필요해보이는 것들 — 어쨰서인지 달려있는 PC4200 메모리 1기가와 DVD드라이브 떼버렸음. 그래도 6400U로 2기가 남아있음 — 을 제거. 부팅은 잘되네
- MAC 주소 발급되자 필요한 것들을 네트웍 인스톨 시작
- VS 2005 SP1 설치, python, cruisecontrol.net, IIS, … 및 각종 GNU binutil 설치
- CruiseControl.net이 뜨길 거부한다. IIS설정 문제는 아니었고, 어째서인지 VS 2005가 설치되고 나니 잘 뜸. 이유가 뭘까…
- VS 2005 서비스 팩이 설치되기를 거부. 맞는 버젼이 없다네…
- 일단 빌드 머신으로 제대로 동작하나 테스트 시작. 빌드가 되긴하는데 전부 다 되는게 아니라 일부 라이브러리가 빌드 에러를 내뱉는다
- 재부팅
- VS 2005 서비스팩 설치됨. 대체 재부팅에 무슨 마력이… 이것도 원인이 뭘까 -_-;;;
- 빌드 안되던 녀석들도 빌드 성공
여기까지 대략 3시간 반 -_-;;
프레스캇 (intel 640) -> 콘로 6600으로 바뀌었고, HDD도 IDE->SATA2, 램도 두 배 상승. 덕분에 일부 빌드는 3배나 빨리 빌드되고, 대부분 2배 이상 빨라졌음. 이러니 CI나 빌드 자동화 얘기하는 책에선 빌드 머신에 돈 좀 들이라고 말하는건가… 피드백 받는 주기가 훨씬 빨라졌으니…
소스코드 인코딩 문제 발생
빌드는 되는데 일부 테스트가 실패한다 — 바꾼게 없는데 Orz.
테스트 로그를 보니 문자열이 깨져서 생기는 문제 같았다 — wide char로 선언하는 L”…” 꼴이 제대로 해석이 안된듯. 기존 빌드 머신이랑 차이를 비교해보니 locale이 다르네. 둘 다 windows server 2003 ENU지만 하나는 한국어 로케일, 하나는 영문 로케일(후자가 새 머신). 그래서 아예 저 문자열을 wchar_t str[] = { 0xd55c, 0xae00, 0×00 }; 하는 식으로 때웠음. 근데 이것도 좀 귀찮은 일이라, 저걸 가지고 assertEqual 류 호출 할 때는 L”\u0xd55c” 하는 식으로 비교했다… 아무래도 소스코드 인코딩이 UHC였다가 latin1으로 해석해서 생긴 문제였던 것 같다.
근데 이게 좀 짜증나는게 VS 2003에서는 인코딩 자체를 상당히 명시적으로 주고 그러기 쉬운데, VS2005는 또 그게 아니거든 Orz. 언제 회사에서 MSDN가지고 VS2008을 써봐야할듯…
Windows/linux의 service 를 다루는 차이
Windows에서 서비스라고 부르는 / linux 혹은 *nix 계열의 OS들에선 daemon 이라고 부르는 사용자와 직접 대화(?)하지 않고 컴퓨터가 켜지면 시작되서 끝날 때 까지 조용히(?) 돌고 있는 프로세스들이 있다. 이걸 관리하는 관점이 양쪽이 좀 다른데, (+그리고 헷갈려)
- Windows 에서는 services.msc 라는 관리자 페이지를 통해서 서비스를 켜고, 멈추고, 재시작한다. 반면에 *nix에서는 /etc/init.d/서비스이름 start/stop/restart 를 사용한다. 서비스 자체를 관리하는 명시적인 주체가 *nix에서는 존재하지 않는다 물론 양쪽 모두 KILL 신호를 보내서 죽이는게 가능하다…
- 설정 파일을 다시 읽는 법이 표준화되지 않은 Windows — 거의 개별 프로세스 재량에 맡김. SIGHUP 을 통해 설정 파일을 다시 읽는 *nix. 사실 이건 프로그래밍 모델에 가까운 얘기인데 — 즉 우열의 문제랑은 좀 거리가 있다 — *nix 세계에서 서비스 설정파일을 다시 읽는 것은 아주 잘 지켜지는 관례로 SIGHUP 시그널을 받으면 설정을 다시 읽는다! 라는 것으로 되어있다. Windows 에선 이런 관례가 없는지 보통은 그냥 서비스 재시작으로 때운다
- Windows 에서 서비스를 추가할 때에는 instsrv.exe 를 쓰거나해서 registry도 수정해줘야 한다 — 자세한 설정은 거의 registry에서 해야. 반면에 *nix 는 데몬 추가/설정 자체가 shell에서 실행시킨다는 느낌이라 rc.d 에 추가하는 것 외에는 별게 없음
뭔가 양쪽다 중앙 집권화를 적당히 하다만 느낌이고 안된 부분이 서로 달라서 양쪽 왔다갔다 하면서 쓸 때 헷갈리는 느낌 — 내 경우엔 윈도우에서 주로 삽질하지만;
ps. init의 경우 SIGHUP을 받으면 설정을 다시 읽는 것 마찬가진데, SIGKILL을 받으면 전체 서버가 재시작(…)하게 된다. 심심한 서버 관리자는 재부팅해야할 일이 있을 때 재미로 해볼 수도 있긴한데 추천은 안한다. 비슷하게 Windows도 커널 서비스를 실행해주는 svchost.exe 를 죽이다보면 OS가 재시작된다는 메시지를 볼 수 있다(…이런건 묘하게 비슷하다)
Windows 서비스 등록이 안된다는 보고에 대한 디버깅
전에 작성한 서버 프로그램이 서비스로 제대로 등록안된다고 해서 디버깅을 하는데, 프로세스가 읽어들이는 설정 파일에 상대 경로가 몇 개 있더군. 이걸 수정하니 종료. 아무래도 이건 shell script로 실행하는 것 에 익숙해져서 그런건가 -_-;; — 물론 그 쪽 세계에서도 경로 속이기(우선순위로) 문제 때문에 절대 경로를 쓸 것을 권장하긴 한다. 하지만 CWD의 상대 경로가 잘 안되는건 Orz
ps. 이유는 모르겠지만 (심지어 설명 페이지에도 제대로 설명이 없음), instsrv.exe/srvany.exe 에 대한 경로가 절대 경로가 아니면 실행도 되고, 화면 출력도 제대로 된 것 같이 나오고하는데, 서비스는 등록되지 않는 괴악한 일이 생긴다. 이걸로 작년 2월인가 3월에 삽질해본 기억이 있는데…
WordPress 5주년
rein’s world를 운영할 수 있게 해주는 블로깅 툴인 WordPress가 2003년 5월 27일의 첫 번째 릴리즈 (0.7 버젼) 이후 5 년이 경과했다고 합니다. 첫 버젼의 간략한 기능 목록을 보면,
- 인용문 텍스쳐라이즈.
- WordPress Link 기능
- XHTML 1.1 지원
- 좀 더 지능적인 줄 쪼개기 기능
- 새 관리자 인터페이스와 포스팅 요약 직접 입력
- 새로운 기본 템플릿
이었다. 요즘 볼 수 있는 일상적인 블로깅 툴의 느낌?
5년이 지났고 :p 이 이후로 변한 것들을 간략히 세어보면,
- 블로그 각 기능 — 머릿/꼬릿말, 사이드 바, 댓글, 본문, 본문 요약, 카테고리, 태그, 달력, 통계, 갤러리 … — 에 대한 사용자 혹은 플러그인에서 수정할 수 있는 부분들에 대한 지원
- 태그 지원 및 기존 태그 플러그인들과의 통합(2.3버젼부터)
- 몇 번의 관리자 기능 업데이트 (1.5, 2.0, 2.5, … )
- 갤러리 기능 통합 (2.5)
- 미디어 (사진, 플래쉬, 동영상, 팟 캐스트 … ) 관리 기능 (이것도 여러 버젼에 걸쳐서)
- 특정 기능에 특화 가능한 템플릿 — 팟 캐스트, 이미지 갤러리, 컨택트 폼 등 다양한 형태로 WP가 개조되어 사용되고 있다
등등 수 많은 기능들이 있고 아직도 변하는 중입니다.
수 많은 사람들이 원하는 수 많은 이상향들을 누군가가 수정해서 손에 쥐게 해줄 수 있다는 점에서 개별 사용자가 조작할 여지가 많은 — 그리고 플러그인들로 이를 지원하는 — 툴이란 점에서 WordPress는 앞으로도 매력적인 툴이길 기원합니다 ![]()
ViEmu, Refactor++ 충돌 중
회사에서 VS2005를 사용해서 프로그래밍하게 되는데, 프로그래밍 자체를 *nix (정확히는 Solaris)에서 배웠던 rein에게 가장 편했던 editor는 vi/vim 인지라 -_-;; viemu 를 한 달간 테스트해보고, 현재는 구입해서 사용하고 있다.
Refactor++ 소개글을 읽고 지난 주 후반부에 좀 써봤는데 — extract method 같은 리팩터링 된 후의 인자 이전될 갯수/이전될 방식 같은걸 visual 하게 보여줘서 좋았음 — 어째서인지 viemu가 제대로 동작하질 않는 것.
대략,
- vimeu 기본 모드(편집 모드)에서 a,i,o 류로 입력 모드로 들어가면 다시 편집 모드로 돌아 올 수 없다
- shift + esc가 esc의 대체키로 지정되어있는데 이걸 사용하면 편집 모드로 돌아옴
같은 현상이 있어서 뭔가 했는데, viemu 포럼을 검색해보니 Refactor++에서 esc를 잡아먹는다고(…)
Orz를 외치고 Refactor++을 꺼둔 상태; 나중에 필요할 때 가끔 켜서 쓰던가해야지 ㅠㅠ
ps. viemu–Refactor++과의 호환 DLL이란게 있어서 뭔가 했는데, Refactor++의 일부 동작 후에 자동으로 편집모드->입력모드로 바꿔주는 기능이었다. 결국엔 도움이 안되는군;;
Python + Psyco
취미 생활로 하는 일 중에 하나가 프로젝트 오일러 라고 부르는 프로그래밍/수학 문제 웹사이트의 문제들을 푸는 것인데.
프로젝트 오일러에선,
- 2의 1000 제곱의 각 자리수 합을 구하라
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9로 만들 수 있는 사전식 순열 (lexicographic permutation) 중 백만번째로 나오는 것은 무엇인가
- 오일러 파이 함수 (euler phi-function)의 값이 n의 permutation인 것을 조사하라
- 다음과 같은 상황의 최단경로를 구하라
라는 식의 약간의 수학 + 알고리즘 문제들을 잔뜩 가지고 있다. 작년 초에 python에 좀 더 익숙해질 겸, 머리도 식힐 겸 — 프로그래머 스럽지아니한가 :$ – 시작했는데, 작년 말부터 좀 뜸하다가 요즘 다시 손을 대기 시작했다. Python을 사용해서 이런 문제를 풀면 얻게 되는 이익은,
- 큰 수를 쉽게 다룰 수 있다 — 기본적으로 자릿수 제한이 없는 정수를 쓸 수 있다
- list를 다루는게 매우 자연스럽다 — 기본적인 자료구조형인 list, map(dictionary)이 언어의 기본 자료형임
- OOP를 쓸 수 있다 — 유리수나 continued - fraction 같은 자주 쓰이는(…) 부분을 분리할 수 있다
- 언어 자체가 가벼운 코드로 많은 일을 할 수 있다 — 현존하는 스크립트 언어들의 특징이기도한…
인데, 사실 문제도 꽤 있다. 작년에 풀었던 문제 중에 python으로 2시간 10분 가량 돌려서 결과가 나왔던 문제가 있는데, 나중에 GMP 를 써서 해보니 1분 안쪽으로 줄어들더라고(…). 백배도 넘는 실행 시간 차이를 본 순간 -_-
이런 문제를 극복할 수 있는 — 적어도 일부 영역에서는 – 수단이 python에는 있다. 프로젝트 오일러를 주로 할 때에는 생각 못하고 있었는데, 최근 저걸 다시 생각해내고 넣어가면서 몇 개 테스트 해봤는데, 보통 4배에서 10배정도 가속되더라. 즉 전에 수 분 정도 걸린던게 수 초 ~ 수십 초 수준으로 실행속도가 빨라진 것.
바로 pysco 라는 x86 용의 파이썬 라이브러리덕분인데, 아주 간단한 코드만으로도 상당한 효율을 볼 수 있다. 예를 들어, 원래 코드의 앞 부분에 다음과 같은 부분만 들어가면된다.
import psyco
psyco.full()
…대략 이것만으로 프로젝트 오일러를 풀면서 작성했던 코드들이 수 배 향상된 속도로 동작하는 걸 확인할 수 있었다. 입사시험 문제의 일부로 사용한 문제들을 python으로 풀어보는데, 같은 코드를 C++로 작성해서 비교해봐도 8~20배 안쪽의 차이로 동작하는걸 확인할 수 있었다.
물론 psyco의 동작자체가 완전히 JIT는 아니고, 타입에 따라 별도의 특수화 코드를 생성해내는 방식이라 상당히 많은 메모리 (10~100배 정도? 내가 경험해본건 대략 10~30배) 를 사용해서 속도를 올리는 방식이라 매우 큰 코드 블럭에서는 약간 부적당할지도 모른다. 그 경우엔 위 처럼 psyco.full() 로 최적화 하는게 아니라 프로파일링 + 부분최적화 할 수 있는 수단을 제공해준다. 이건 프로젝트 오일러 문제 풀 수준의 코드에선 별로 볼 일이 없어서 잘 모르겠지만[...]
완전히 새로운 VM 구현도 아니고, 인터프리터 구현도 아닌, 그렇지만 간단히(?) 라이브러리 임포트 + 몇 줄 추가로 상당한 효율을 얻을 수 있다는 점에서 python의 매력이 점점 강해진달까 :$
간단한 프로그램을 만들 때 뭔가 어정쩡한 편리함/속도인 C#/Java를 쓸 일이 점점 더 줄어드는 기분…

7 comments