Software Development

엔지니어와 비즈니스

"None of us knew anything about the PC industry," said Rob Short. "We thought we were the hotshots–and knew what was going on–because we understood the technology. But we didn’t see what was happening in the PC business."

“우리들 모두는 퍼스컴 업계에 대해 아무 것도 몰랐습니다. 기술을 이해하고 있으니까 그것이 전부인 듯 자신만만하게 상황을 잘 알고 있다고 우리 스스로 생각하고 있었을 뿐입니다. 그러나 퍼스컴 업계에서 무엇이 일어나고 있는지 우리는 사실 아무것도 모르고 있었습니다.”

— quoted from Showstopper!, Pascal G. Zachary

엔지니어와 비즈니스 더 읽기"

Eclipse behavior problems in Ubuntu Karmic

이번에 Ubuntu Karmic으로 업그레이드 하고 나서, Eclipse 3.5에서 다음과 같은 증상들이 관찰되었다.

  • 몇몇 대화 창에서 마우스 클릭으로는 버튼이 동작하지 않는 문제
  • Synchronize View에서 Synchronize 버튼들이 보이지 않는 문제

 

이 문제는 GTK 2.18의 버그로 인한 것으로 알려져 있다.

 

workaround는 eclipse 실행 시, GDK_NATIVE_WINDOWS 환경 변수를 true로 설정해주는 것이다.

e.g. cd $HOME/local/eclipse/bin; GDK_NATIVE_WINDOWS=true ./eclipse > $HOME/eclipse.log 2> $HOME/eclipse.err

Eclipse behavior problems in Ubuntu Karmic 더 읽기"

GFS: Evolution on Fast-forward

GFS: Evolution on Fast-forward by Marshall Kirk McKusick, Sean Quinlan

FreeBSD의 McKusick이 GFS tech leader 였던 Sean Quinlan을 인터뷰한 acmqueue 기사.(McKusick은 ‘The Design and Implementation of the 4.4 BSD Operating System’의 저자로 FreeBSD 계의 인물이고, Sean Quinlan은 Sawzall 페이퍼에 이름이 올라가있다.)

GFS 페이퍼가 발표된 지 이미 6년이 다 되었는데, 그 동안 GFS에 어떤 변화가 있었는지, 구글의 엔지니어링 방식은 어떠한 지를 부분적으로나마 엿볼 수 있는 글이다.

이 인터뷰에서 GFS가 진화해나가고 있는 모습을 보는 것도 의미가 있겠지만, 일반적인 엔지니어링의 양상을 보여주는 것도 시사하는 바가 있다고 생각한다.

  • 초기 시스템 설계에서는 설계의 단순함이나 짧은 개발기간을 위해 설계의 완결성을 일부 희생할 수 있다.
  • 설계의 결함으로 인한 시스템 문제는 시스템이 실제로 적용되면서, 스케일이 커지면서, 여러 가지 용도가 생겨나면서 드러난다.
  • 시스템 문제를 해결하는 방법은 여러 가지가 있다. 단기간의 튜닝을 해서 시스템의 수명을 연장할 수도 있고, 시스템의 배치 등을 조정함으로써 해결할 수도 있고, 시간과 비용을 들여 설계의 결함을 해소하는 새로운 시스템을 설계할 수도 있다.
  • 시스템이 더욱 넓은 범위에서 사용되면서, 설계의 초점은 처음의 것과 전혀 다른 것 (심지어는 완전히 반대의 것)으로 변화할 수 있다.
  • 초기 시스템 설계에서 유용하다고 생각했던 기능들이 오히려 부작용을 낳거나 쓸모가 없는 경우가 있다.

어떤 시스템의 엔지니어링에 있어서, 변화하는 요구사항에 얼마나 적극적이고 효율적으로 대응해나가느냐가 성공의 관건이 아닌가 싶다.

간단히 이 인터뷰 내용을 한번 정리해본다. (정리하다 보니, GFS 페이퍼를 읽은 지 너무 오래되어 GFS에 관한 세부사항이 잘못될 수 있으리라고 생각된다.)

single-master 디자인

이 인터뷰에서는 주로 single-master 디자인의 문제를 중점으로 다루고 있다. GFS 페이퍼를 읽었든지, GFS 클론을 프로덕션 환경에서 사용해봤다면, single-master 디자인이 어떠한 문제들을 가지게 될 지 쉽게 상상할 수 있을 것이다.

일단 초기 GFS에서 single-master 디자인을 선택한 것에 대해서는, 분산 파일시스템이라는 커다란 시스템을 설계하는 입장에서 초기에 디자인 문제들을 단순화하는 것, 그리고 개발기간을 단축하여 단시간 안에 많은 사용자들이 사용할 수 있었던 것으로부터 이득을 볼 수 있었다고 이야기하고 있다.

bottleneck on single-master

single-master 디자인은 초기에 예측한 사용 시나리오나 규모에서 크게 문제가 되지 않을 것으로 생각했으나, 곧 master에서 유지해야 하는 메타데이터가 증가하면서, 메타데이터 operation이 bottleneck이 되기 시작했다고 한다.

구글에서는 하나의 바이너리가 충분히 잘 동작하기만 한다면, scale 하도록 만드는 일에 좀 더 치중을 하지만, GFS의 메타데이터 문제의 경우, 예외적으로 master의 튜닝에 많은 노력을 들였다고 한다. 물론, 약간의 노력으로 이를 상회하는 효과를 얻을 것이란 느낌으로 튜닝을 진행하였으며, 일정 범위 내의 로드에서, single master가 bottleneck이 되는 현상을 줄여 single-master GFS의 수명을 연장할 수 있었다고 한다.

file-count problem (a.k.a. small-file problem)

GFS는 원래 크롤과 인덱싱과 같은 대용량 파일의 저장을 위해 만들어진 시스템이다 보니, 원래의 페이퍼에서도 chunk의 크기는 64MB다. GFS가 성공한 시스템이 되고, 여러 사용자들이 여러 용도로 사용하게 되면서, 많은 수의 작은 파일들을 저장하는 경우들도 생겨나기 시작했다고 한다. 자연스레 master가 메타데이터를 유지해야 하는 파일의 수가 증가하다 보니, master의 메모리가 차버리는 문제가 발생했다.

이 문제를 해결하기 위해 메타데이터를 여러 master에 분산할 수 있는, distributed master 시스템이 기존의 single-master와 완전히 별도의 시스템으로 개발되었고, distributed master는 여러 종류의 용도에 대응하기 위해, 평균 1MB의 파일들에 맞추어 디자인되었다고 한다.

BigTable

BigTable은 현재 크롤과 인덱싱 용도에 점점 많이 사용되고 있으며, 프론트엔드 애플리케이션에도 많이 사용되고 있다고 한다. 특히, 많은 수의 작은 데이터를 가지고 있는 애플리케이션은 BigTable을 사용하는 경향이 있다고 한다. BigTable이 file-count 문제를 해결하는 용도로도 사용될 수 있는 듯 하다.

latency-sensitive applications

batch efficiency에 초점을 맞추어 디자인 된 GFS는 latency의 면에서 여러 가지 약점을 가지고 있다. Quinlan은 대표적인 사례로 pullchunk (chunk의 replication)에 따른 latency나 master의 failover 시간에 따른 downtime, 수천 개의 operation을 queue에 한꺼번에 넣고 나서 처리를 시작하는 (아마도 MapReduce) 메커니즘 등을 들고 있다.

이러한 문제들을 해결한 사례로는 BigTable을 들고 있다. BigTable의 transaction log의 write가 지연 또는 실패할 경우 latency가 발생하는데, 항상 2개의 로그에 쓸 수 있도록 준비하고, 나중에 replay가 필요할 경우 이를 merge한다는 것이다. BigTable과 같은 GFS 애플리케이션들을 설계할 때, 이와 같이 기본적으로 latency를 숨기는 방식으로 동작하도록 설계하는 경향이 있다고 한다.

consistency

GFS의 모델에서는 client가 write가 성공할 때까지 push하는 방식이므로, operation 중 client의 crash가 일어나면 indeterminate state가 될 수 있다고 한다. 처음에는 이런 현상은 크게 문제가 아닌 것으로 봤으나, 파일 길이 등이 서로 다르게 보이는 문제 등 혼란의 여지가 많았기 때문에, 점차로 inconsistent한 상태를 허용하는 time window를 줄여갔다고 한다.

여러 client가 동시에 로그를 append할 수 있도록 하는 RecordAppend 기능과 같은 경우, loose한 consistency 모델 하에서는 서로 다른 순서의 데이터나 중복 write된 데이터 등이 발생해, 혼란을 줄 수 있는 여지가 많아지면서, RecordAppend 기능이 처음에 의도된 이득보다는 오히려 손실이 많았다고 한다.

snapshot

GFS의 recovery 메커니즘은 client가 write를 할 수 없도록 chunk를 lock하고 snapshot을 복제하는 방식으로 동작한다. 이러한 방식은 latency의 원인이 될 수 있다.

GFS의 일반적인 snapshot 기능은 초기의 다른 설계와는 달리 제대로 구현되어 있는 영역인 것으로 보이고, 구현에 있어서 많은 비용이 들어간 듯하나, 그리 자주 사용되지는 않는 듯하다.

GFS: Evolution on Fast-forward 더 읽기"

Octal Escape Sequences

object님이 적으시며 좌절하신 코드 문제.

int a = strlen("123");
int b = strlen("123");
int c = strlen("12312");
int d = strlen("123123");
int e = strlen("123123ABC");
int f = strlen("123ABC");

C/C++ 프로그래밍 언어 표준을 뒤지며 나름대로 language lawyer로서의 자부심을 가지고 있었는데, 한 순간에 그러한 생각을 깨뜨린 문제네요. 물론 농담이고요. 이런 것을 프로그래밍 실력과 직접적으로 연결해서 생각하지는 않지만, 프로그래머 만이 가질 수 있는 일종의 취미 정도로 생각해주시면 좋을 것 같습니다.

NoSyu님이 컴파일 결과에 따른 답과 나름대로의 해석을 하셨기에 정답은 나온 셈이지만, 이런 문제는 역시 컴파일러의 구현 뿐만 아니라, 표준 문서를 뒤져보아야 하는 문제겠죠.

제가 가지고 있는 C 표준 문서는 ISO/IEC 9899:1999, 소위 C99라고 불리는 문서입니다.

Character constants에 관한 항목은 6.4.4.4인데요. backslash를 이용한 escape sequence는 크게 4가지로 나뉘고, 그 중의 하나가 octal escape sequence입니다. 논의의 간소함을 위해 여기서는 octal escape sequence와 hexadecimal escape sequence만 보도록 하죠.

octal-digit:
0 1 2 3 4 5 6 7
octal-escape-sequence:
 octal-digit
 octal-digit octal-digit
 octal-digit octal-digit octal-digit
hexadecimal-digit:
0 1 2 3 4 5 6 7 8 9
a b c d e f
A B C D E F
hexadecimal-escape-sequence:
x hexadecimal-digit
hexadecimal-escape-sequence hexadecimal-digit

이러한 문법에 따르면 다음과 같은 사실들을 알 수 있습니다.

1. octal escape sequence에는 각각 8진수를 표현하는데 사용할 수 없는 문자는 파싱 단계에서부터 octal escape sequence의 고려에서 제외됩니다. 즉, 위의 문제에서, "ABC"의 경우, ‘A’, ‘B’, ‘C’는 octal-digit가 아니므로, ""만이 octal-escape-sequence로 파싱되고 결과적으로 { ‘’, ‘A’, ‘B’, ‘C’, ‘’ }로 해석되는 것입니다.

이러한 행동은 C89에서 변화된 것으로 보이는데요. 마찬가지 이유로 “78”의 해석은 { ‘7’, ‘8’ }로 되지만, 예전에는 0 prefix에 따르는 2개의 digit를 해석하는 구현의 책임 (implementation-defined)이었고, “78”은 “100”(078 = 0100)으로 해석되기도 한 모양입니다. C89 이전의 머나먼 옛날의 이야기이니, 현 시대의 컴파일러에서 이러한 동작은 신경 쓰지 않아도 될 것 같습니다.

2. octal-escape-sequence에서는 3개까지의 octal-digit를 허용합니다.

예를 들어, “123”는 어떨까요? octal-digit 3개 까지만 허용하므로 일단 ‘3’은 배제하고 “12” “3”으로 해석되겠네요. 그러면 “12”는?

다시 C99 문서로 돌아가보면,

Each octal or hexadecimal escape sequence is the longest sequence of characters that can constitute the escape sequence.

라는 얘기가 있습니다.

즉, “12”는 { ‘’, ‘1’, ‘2’, ‘’ }나, { ‘1’, ‘2’, ‘’ }로 해석되는 것이 아니라, 가장 긴 매치에 해당하는 { ‘12’, ‘’ }로 해석된다는 것입니다. 사실 octal escape sequence에 대해서 알고 나면, 상식적인 이야기라고 볼 수 있겠습니다.

한편, { ‘1’, ‘2’, ‘’ }을 표현하고 싶다면 어떻게 해야할까요? 이것은 C/C++의 편리한 String Concatenation 문법을 사용하면 됩니다. 즉, “1” “2”라고 하면 되겠죠.

3. octal-escape-sequence에서 ‘’ prefix가 요구되지 않습니다. 이것은 그 동안 제가 몰랐던 중요한 사항 중 하나네요. 즉, ‘12’나 ‘12’나 동등한 의미를 가진다는 것입니다. 아마 그 동안 코드를 보면서 그러한 경우를 봐왔을 텐데 조금 더 세심하게 보지 않았던 것 같네요.

재미있는 문제를 제공해주신 object님, 그리고 assembly까지 확인해주신 NoSyu님께 감사드립니다. :)

Octal Escape Sequences 더 읽기"

Learning Rails + Heroku

팀의 프로세스에 딱 들어맞는 작업 관리 도구가 없어서, 팀의 작업 관리 방식을 반영한 도구를 만들고 싶습니다.

사실, 그리 복잡한 요구사항을 가지고 있는 것이 아니기 때문에, Rails Scaffolding을 약간 수정하는 수준으로 생각되어, 일단 Rails로 시도해보려고 계획했습니다. 그러한 계획 하에, 얼마 전, 오랜만에 집에서 Virtual Box에 Linux + Rails 환경을 구축하여 개발을 시작했는데요. Rails 1와 Rails 2 사이의 간극 때문에 포기하고 말았습니다. 의외로 Rails 2.x에 대한 문서도 그리 많지 않은 것 같고, 국내에 나와있는 Rails 2 도서도 없어서 쉽지 않더군요.

Learning Rails그러다 우연히 Safari Books Online에서 Learning Rails를 발견하고는 주말에 심심해서 읽어보게 되었는데요. 기존 버전의 Rails를 사용해 본 경험이 약간 있어, 예제 실행과 Rails 2에서 달라진 점에 주력해서 읽었고, Learning Rails를 읽는 데에는 이틀 정도 밖에 걸리지 않았습니다.

Learning Rails는 Learning 시리즈에 속한 다른 책들처럼 초심자용으로 Agile Web Development with Rails (이하 AWDR)의 도입부의 내용 정도로 생각하시면 될 것 같습니다.

특히, 다양한 예제를 통해 Rails의 다양한 기능들을 훑어볼 수 있도록 해주는 점이 마음에 듭니다. AWDR은 뒤쪽으로 가면서 예제도 없고 지루한 설명으로 바뀌어 버리는데, Learning Rails가 물론 분량상 AWDR의 내용을 모두 커버하지는 않지만, 그러한 면에서 초심자가 읽기에는 훨씬 좋은 것 같습니다.

책 자체가 작을 테니 들고 다니기에도 좋을 것 같고요.

Learning Rails가 좋았던 또 다른 하나는 바로 Heroku 환경에 대해서 각 예제를 실행하는데 필요한 설명들이 포함되어 있다는 것입니다. 덕분에 Heroku라는 편리한 환경을 통해 쉽게 공부할 수 있었습니다.

Heroku란 한마디로 말하자면 Rails 개발 환경을 포함한 Rails 프로젝트 호스팅이라고 말할 수 있습니다. (Heroku Feature)

herokugarden

별도로 Rails 개발 환경을 셋업 할 필요 없이 바로 프로젝트를 시작하고, 어디서든 접근해 개발과 테스팅을 할 수 있다는 것은 대단히 편리합니다. 웹 상의 IDE도 큰 불편함이 없을 정도로 훌륭할 뿐만 아니라, Rails 콘솔이나 Generate 스크립트 실행, 플러그인이나 gem 설치까지도 지원하기 때문에, 웬만한 Rails 개발은 거의 다 해볼 수 있습니다. (HerokuGarden에서는 현재 플러그인 설치에 약간 문제가 있는 상태라 git을 사용해서 올려야 하긴 합니다.)

지금 Heroku를 사용하려고 시도해보시는 분들은 HerokuGarden으로 가게 될 텐데, 원래의 Heroku가 HerokuGarden으로 이전하면서 Heroku/HerokuGarden 두 사이트 체제로 되어있고, 신규 가입은 HerokuGarden에서만 받고, Heroku는 초대 기반의 Private Beta 상태입니다.

어제 Heroku Invitation을 받았는데, 현재의 Heroku에서는 IDE 기능을 빼고 원래 지원하던 git 기능을 통해서 클라이언트에서 작업하는 것을 기본으로 하고 있는 것 같습니다. 그 때문인지, ‘git을 사용하고 있기 때문에’라는 이유가 들어가는 것 같고요. 그래도 HerokuGarden은 계속 지원할 예정이라고 하니 안심하셔도 될 것 같습니다.

Since you’re currently using git to update your Heroku app testflakes, you should switch from HerokuGarden to Heroku.com. The version of our platform that’s running on Heroku.com will be the basis of our upcoming launch, and it’ll be a much better home for your app. It works almost exactly like Heroku Garden with the following enhancements:
* Improved reliability
* Better performance
* A vastly improved API and gem for managing your apps
* Automated nightly backups of data and code that can be downloaded via the gem
* Support for cron jobs
Unlike HerokuGarden, Heroku.com does not offer the web based code editor. However, since you’re already using git, this shouldn’t affect you at all. In fact, we think you’ll love the simplicity and reliability of working with our new heroku gem.

Rails나 Rails 2를 처음 배워보시려는 분들은 Learning Rails와 Heroku로 한번 시작해보세요. 배움의 문턱을 한층 낮추어줄 수 있는 도구들이 될 수 있지 않을까 싶습니다.

Learning Rails + Heroku 더 읽기"

Flex

Silverlight  2에 관한 글에서, 팀 내에서 Flex를 사용해 개발된 애플리케이션이 있다고 언급한 적이 있다. 이 후로, 팀 내에서 복잡한 데이터를 보여 주기 위한 애플리케이션을 만들 때 Flex를 사용하기 시작했고, 추가적으로 무려 3개의 애플리케이션이 더 만들어 졌다.

이렇게 팀 내에서 많이 사용하기 시작한 기술이기도 하지만, Silverlight 2의 경쟁 상대가 Flex이다 보니 그 동안 Flex에 대해 자세히 알고 싶은 바램이 있었다. 운이 좋게도, 얼마 전 회사에서 Flex에 대한 교육이 추가로 실시된다는 소식을 듣고 바로 신청해 들을 수 있었다.

첫 번째 느낌은 Silverlight와 Flex은 본질적인 차이라고 말할 만한 것이 거의 없다고 말할 수 있을 정도로 유사한 기술 스택과 기능 들을 가지고 있다는 것이다.

  • Markup과 Programming Language, 공통적으로 배포되는 런타임을 통한 애플리케이션 구현
  • Container 개념과 기본적으로 제공되는 Control들
  • Layout 메커니즘
  • Event 개념
  • Style 개념
  • 기존의 Control을 확장하는 메커니즘과 Custom Control 작성
  • 외부 데이터를 사용하기 위한 라이브러리 지원
  • 웹 애플리케이션과 데스크탑 애플리케이션 작성

두 번째 느낌은 Silverlight나 Flex 모두 전통적인 UI 프레임워크로서의 방식을 따르고 있다는 것이다. 아마 HTML과 XML이 성공한 후에 도입되기 시작한 사용자가 작성하는 UI Markup 개념은 제외해야겠다. 이 외의 개념들은 모두 GUI가 보편화된 이후에 생긴 MFC, Swing 등의 프레임워크와 같은 방식과 요소들에서 익숙하게 봐 왔던 것들이다.

Silverlight나 Flex 자체는 하위 수준의 프레임워크로서 Document-Model이나 MVC와 같은 방식을 강제하는 정도의 수준은 아니다. 그러한 상위 수준의 프레임워크는 외부에서 착실히 만들어 지고 있다.

NHN의 사내 기술 교육은 아직 다양하지는 않지만, 경험이 많은 실무자가 교육을 하다 보니, 교육의 만족도가 상당히 높은 편이다. 단순히 웹에서 문서를 보거나 책을 보고 따라 하는 수준을 넘어서는 경험에서 우러나오는 지식이나 팁과 같은 것을 얻을 수 있다.

강사 분도 말씀하셨지만, Silverlight나 Flex나 전반적으로 어떠한 요소들을 가지고 있는지 이해하는 것이, 이 기술들을 배우기 시작하는 데에 중요한 요소다. 세부적인 사항들은 단기간에 배우기 보다는 실제로 사용해 보면서 익힐 수 밖에 없기 때문이다.

웹 시대를 살아가는 개발자로서, Silverlight든 Flex든 튜토리얼이나 책, 좋은 강의로부터 배울 기회가 생긴다면 간단한 애플리케이션을 만들 수 있을 정도로는 익혀 두는 것이 좋다고 생각한다.

Flex 더 읽기"

Dreyfus Model

모든 관리자의 이상

관리자의 입장에서 가장 예뻐 보이는 동료는 누구일까?

여러 가지 답이 있을 수 있겠지만, 그 중 하나는 아마도, ‘주어진 업무를 수행할 때, 업무의 목표가 무엇인지 정확히 이해하고 수행하는 사람’이다. ‘상위 조직의 목표까지 고려해서, 원래 업무의 방향을 수정하거나, 업무의 우선순위를 조정하거나, 적절한 새로운 업무를 추진할 수 있는 사람’이라면 더할 나위 없을 것이다. 역설적이게도, 어떻게 보면 관리가 필요하지 않은 사람이 바로 관리자의 이상형이다.

세상은 완벽하지 않다. 모든 동료들이 위에서 얘기한 조건을 만족하기란 어려운 일이다.

관리자 M이 보기에 동료 A는 지시하지 않은 세부 사항까지 알아서 척척 처리해, 손이 닿지 않는 곳의 가려움에서 벗어나는 기쁨을 안겨 주는 반면,  동료 B는 완료했다는 일이 처음부터 업무를 처리할 방식을 세세하게 다시 설명해 주어야 할 정도로 엉망이어서, 그 사람 얼굴만 보면 짜증이 나고, 잠도 안 올 정도로 고민거리다.

왜 그럴까? 동료 B는 멍청해서? 게을러서? 여자 친구랑 헤어져서? 에어컨이 고장 나서?

그런 것은 아닌 듯 하다. 동료 B는 업무 시간에 집중해서 성실하게 일하며 책임감도 높다. 여자 친구가 없으니 헤어질 일도 없다. 관리자 M의 옆자리니까 에어컨이 고장 난 것도 아니라는 것을 안다.

업무 경험이 많고 세심한 관리자 M이 보기엔, 한마디로 딱 잘라 말할 수는 없지만, 동료 A와 동료 B와 얘기를 해보면, 둘 사이에는 업무를 대하고 처리하는 방식에는 본질적인 차이가 있다.

관리자 M이 한마디로 딱 잘라 말할 수 없는 것을, 어떤 똑똑한 사람이 딱 잘라 말한 것 중 하나가 바로 Dreyfus Model이라는 것이다.

드라이퍼스 모델 (Dreyfus Model)

드라이퍼스 모델은 철학자 드라이퍼스 (Hubert L. Dreyfus)가 그의 저서 Mind Over Machine의 도입부에서 제안한 기술 습득의 5단계 모델이다1. 요즘 읽고 있는 Andy HuntPragmatic Thinking & Learning의 2장에 소개되어 있다. 이 책의 내용과 Mind Over Machine의 발췌 부분, 전문가 시스템 비판이란 글을 이용해서, 핵심적인 내용만 간단하게 요약해 보자.

Stage 1: Novices

경험이 없기 때문에, 상황에 상관 없이 적용할 수 있는, 다시 말하면, 상황에 따라 적절하지 않을 수 있는, 조리법(recipes) 즉, context-free한 규칙이 주어졌을 때 효과적으로 과업을 수행할 수 있다.

Stage 2: Advanced Beginners

여러 가지 상황에서 의미를 가지는 요소에 대해 인지하게 되고, 이러한 요소를 context-free한 규칙에 더해서 활용하게 된다.

Stage 3: Competent

경험이 쌓이면서, 고려해야 할 요소들이 폭발적으로 증가한다. 불가피하게, 상황 하에서 어떤 요소를 중요하게 고려해야 할 지를 선택한다. 이러한 상황에 대한 모델 하에서, 상황을 분석하고 규칙에 따라 행동을 선택한다. 자신이 선택한 결과 – 성공이나 실패에 대해 책임감을 느낀다.

결과적으로 스스로 문제를 해결(troubleshoot)할 수 있다.

Stage 4: Proficient

Competent 단계에서 경험한 성공과 실패를 바탕으로, 상황에 따라 어떤 요소를 중요하게 고려해야 할 지를 결정한다.

어떤 요소들이 더 중요하고, 어떤 요소들이 무시해도 되는가는 경험이 추가됨에 따라 직관적으로 변화한다. 반면에, 실제로 어떤 행동을 해야 할 것인가에 대해서는 분석적인 사고를 필요로 한다.

Stage 5: Expert

의식적인 사고나 규칙의 필요 없이, 직관적으로 어떤 요소를 중요하게 고려해야 할 지와 어떤 행동을 해야 할 것인가를 안다.

드라이퍼스 모델의 적용

드라이퍼스 모델이 실제로 적용된 것은 간호(Nursing) 분야였고, 자신이 간호사였던 간호 연구자 Patricia Benner가 1984년에 From Novice to Expert: Excellence and Power in Clinical Nursing Practice라는 책으로 정리해 내놓으면서였던 것 같다.

프로그래밍 분야에서 드라이퍼스 모델의 적용에 관한 좀 더 구체적인 예는 Debugging: From Novice to Expert라는 논문에 정리된 다음 표를 참고하면 좋을 듯 하다. (via 드라이퍼스 모델)

debugging

Closing

동료 A와 동료 B의 ‘본질적인 차이’란 무엇인가? 동료 A는 아마도 Competent 이상일 테고, 동료 B는 Advanced Beginner 이하일 것이다. 이것이 ‘본질적인 차이’에 대한 본질적인 대답은 아니다.

드라이퍼스 모델이 제시하는 것은 겉으로는 5단계의 구분이지만, 마치 무협지의 주인공처럼 Novice가 어느 날 갑자기 기연을 얻어서 Expert가 될 수 없다는 사실을 내포하고 있다. 즉, 한 단계 높은 숙련도에 이르기 위해서는 충분한 경험과 고민, 트레이닝, 그리고 그것들을 위한 시간이 필요하다는 것이다.

드라이퍼스 모델이 5단계의 구분에서 제안하는 중요한 요소는 바로 직관이라는 요소다. 인간은 구체적인 경험으로부터 직관을 얻을 수 있고, 이것은 컴퓨터와 같은 기계로 추론해 내는 것은 대단히 힘들다는 것이다. 물론 이것은 인간에게도 쉽지는 않으며, 위에서 언급한 것들을 필요로 한다.

대학교 CS 과정에서 프로그래머의 생산성은 10배 이상까지 차이 날 수 있다는 사실을 배운다. 이러한 사실은 프로그래머라면 누구나 현장에서 느낄 수 있다.

하지만, 관리자로서 그러한 사실을 접하는 것은 완전히 다른 경험이다. 프로그래밍 과업의 결과물의 양적 또는 질적인 차이에서 뿐만 아니라, 업무를 얼마나 깊이 이해하고, 어떤 목표를 추구하는가, 그에 따라 어떤 과정을 선택하는가와 같은 일하는 방식의 문제로까지 확장되는 것이다.

당연하기도 하지만, 실제로 그렇다는 것을 깨닫고 나서 놀랐던 사실들이 있다.

  • 일하는 방식에 있어서의 Competent 이상의 능력을 가진 사람은 정말로 소수에 불과하다.
  • 특정 스킬, 이를테면 코딩 스킬이 뛰어나다고 해서, 반드시 커뮤니케이션 방식에 있어서
    뛰어난 것은 아니다.
    즉, 스킬에 따라 숙련도는 다르다.
  • 경력이 오래 되었다고 해서, 반드시 일하는 방식에 있어서 뛰어난 것은 아니다. 반대로, 경력이 짧아도 일하는 방식이 뛰어난 경우가 있다.

개인 간의 차이는 생각보다 컸고, 기대하는 스킬과 실제 스킬의 차이의 간극도 역시 생각보다 컸다.

이제 나의 고민은, 관리자로서, 어떻게 하면 동료들이 한 단계 더 높은 스킬 숙련도에 이를 수 있도록 도와 줄 수 있는 가이다2. 우선, 자신과 함께 일하는 동료들의 주요 스킬의 숙련도가 어느 단계인가 파악해보자.


1 그의 저서나 이 모델에 관한 권위 있는 텍스트를 접해 본 적은 없으므로, 정확히는 알 수 없지만, 이러한 모델은 과학적인 검증을 거쳤다기 보다는, 인공 지능의 한계를 지적하기 위한 논의를 진행하기 위한 개념적인 모델일 뿐인 것으로 보인다.

2 Andy Hunt의 책에서도 언급하고 있지만, 모든 팀원이 Competent 이상의 단계가 되어야 할 필요는 없다. Andy Hunt는 숲을 보는 사람이 있으면, 나무를 보는 사람도 있어야 한다고 얘기한다. 나도 그러한 생각에 동의한다.

Dreyfus Model 더 읽기"

Subversion pre-commit hook

SubversionRepository Hook이라는 메커니즘을 가지고 있다.

pre-commit hook을 사용해, commit하는 내용이나 사용자에 따라, commit할지 말지 여부를 결정하거나, 내용을 수정할 수 있으며, post-commit hook을 사용하면, 모든 commit에 대해 메일을 보내거나 통계를 업데이트할 수 있다.

pre-commit hook을 등록 할 때는 다음 세 가지를 신경 쓰면 된다.

  1. 실행 가능: Subversion repository의 hooks/pre-commit 파일을 액세스하는 프로그램 (e.g. 웹 서버)이 실행 권한을 가질 수 있도록 해야 한다.
  2. exit code: exit code에 따라 commit 여부가 결정된다. 0이라면 commit 성공, 1이라면 commit 실패.
  3. stderr: 표준 에러로 출력한 메시지가 클라이언트의 에러 메시지로 출력된다.

예를 들어, 공백만 있는 commit log와, 특정 author에 의한 commit을 막으려면 다음과 같은 pre-commit hook 스크립트를 사용하면 된다

#!/bin/sh
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook
$SVNLOOK log -t "$TXN" "$REPOS" | grep "[^[:space:]]" > /dev/null
if [ $? -ne 0 ]; then
echo -n 'EMPTY commit log is NOT ALLOWED' 1>&2
exit 1
fi
$SVNLOOK author -t "$TXN" "$REPOS" | grep -v -e "^public$" > /dev/null
if [ $? -ne 0 ]; then
echo -n 'USER public is NOT ALLOWED' 1>&2
exit 1
fi
exit 0

이러한 hook들은 shell script로만 한정되는 것은 아니므로, python이나 외부 프로그램을 실행하는 스크립트 등의 방식을 활용할 수 있다.

Subversion repository에 강제하고 싶은 규칙이 있다면, Subversion의 pre-commit hook을 활용해 보자.

Subversion pre-commit hook 더 읽기"

NHN DeView 2008

어제 (토요일), 양재 AT센터에서 개발자를 대상으로 한 NHN의 공개 컨퍼런스, NHN DeView 2008이 있었습니다.

nFORGE

여러 주제에 대한 발표들이 있었지만, 가장 중요한 것은 아무래도 nFORGE를 중심으로 한 사내에서 만들어 진 소프트웨어들의 오픈 소스화가 아닌가 싶네요.

제가 일하는 팀의 동료 분들이 만든 소프트웨어인 sysmondist도 이번 오픈 소스 프로젝트 공개 대상이어서 부스에서 수고하시는 동료 분들을 응원하기 위해서 오후에 잠시 들렀습니다. 여러 분들이 관심을 가지고 진지하게 질문하는 모습을 보면서 기분이 참 좋았습니다.

대규모 장비 운영에 좀 경험이 있는 분이면, SNMP와 RRD 기반의 Cacti와 같은 도구들은 한번 쯤 보셨겠죠. 요즘은 Nagios, Munin, Ganglia 등이 많이 얘기가 되고 있죠. 이런 도구들을 사용해 보고, 정말로 사용하기 편리한가, 필요한 정보를 좋은 방법으로 보여 주고 있는가, 대규모의 장비를 모니터링 할 수 있는가라는 질문을 해보면, 분명 부족한 점들이 있습니다. 팀에서 사용하는 장비만도 수백 대~수천 대에 이르기 때문에 이러한 소프트웨어에 대한 필요성이 더욱 절실했었죠. 그러한 배경에서 팀 내 개발자 분들의 노력으로 외부에 내놓아도 좋을 만한 결과물인 sysmondist와 같은 소프트웨어들이 나왔고, 현재는 사내의 여러 팀에서도 사용하기 시작했습니다.

많은 장비를 운영하시는 분들이 한번 쯤 관심을 기울여야 할 소프트웨어라고 생각합니다.

‘웹 환경과 한글’ 발표 그리고 개발자용 한글 폰트 제작

Deview 컨퍼런스에 들른 김에 발표도 하나 듣고 왔는데, 김승언 실장님의 ‘웹 환경과 한글’이라는 발표였습니다.

보통 사람들이 잘 알기 힘든, 굴림체의 기원, 폰트의 분류 (비트맵/벡터 폰트, 포스트 스크립트/트루 타입/오픈 타입 폰트), 폰트의 안티알리아싱, 클리어타입, 매뉴얼 힌팅과 같은 얘기를 들을 수 있었습니다.

얼마 전 NHN에서 공개했던 나눔 글꼴에 관한 얘기도 있었는데,  나눔 글꼴 작업에서 뭉침 현상을 해결하기 위해서 문자 하나하나 마다 힌팅 정보를 추가하는 매뉴얼 힌팅 작업에 비용이 많이 들었다는 사실이 흥미로웠습니다.

앞으로 제목 서체 (2009), 스크립트용 서체 (2010), 중제목용 서체 (2011)도 제작 및 공개할 예정이라고 하네요.

가장 즐거웠던 소식은 바로 개발자용 폰트 개발이었습니다.

개발자용 폰트는 특성상 고정 폭 (모노 스페이스) 폰트여야 하는데요. Windows에서 제공하는 예쁘지도 않은 고정폭 한글 폰트 이외에 개발자들이 사용할 수 있는 고정 폭 폰트는 거의 없다시피 합니다. 개발자용 폰트기 때문에 문자의 구분이 확실히 눈에 띄도록 하는 데에도 신경을 많이 쓰고, 한글 뿐만 아니라 영어, 중국어, 일본어를 지원할 거라고 합니다.

2009년 1월 22일에 NHN Developer Center를 통해 공개할 예정이라고 합니다. 벌써 두근두근하네요.

NHN DeView 2008 더 읽기"

Zend Framework Project Directory Structure

Zend FrameworkConvention over Configuration 방식을 여러 부분에서 채용하고 있지만, 프로젝트의 디렉터리 구조에서는 그렇지 않다.

최근에 유행하는 Rails나 Django와 같이, 프로젝트를 생성하는 도구를 제공하지 않는다는 사실이나, 디렉터리 구조의 Convention이 존재하지 않고, 여러 안들을 제안한다는 사실로부터 이를 알 수 있다. 게다가, Zend에서도 기본적으로 디렉토리 구조는 사용자의 요구에 따라 유연하게 할 수 있는 것을 중요하게 생각하는 듯하다.

이러한 상황 하에서, 공식적으로 Zend가 제안하는 디렉토리 구조는 크게 두 가지라고 생각된다. 튜토리얼에 해당하는 Quick Start 문서에서 제안하는 디렉토리 구조와, Zend_Controller 레퍼런스 문서에서 제안하는 Moduler 디렉토리 구조가 그것이다. 소규모 프로젝트에서는 Quick Start 문서의 것을 채택하는 것이 좋다고 생각한다.

한편, Zend Framework를 처음으로 사용해 본 것은 작년 이 맘 때였는데, 현재 Zend Framework 안정 릴리즈의 버전이 1.6.2인데, 당시의 버전이 1.0.2 였다. 그 동안 많은 변화가 있었겠지만, 라이브러리만 업그레이드해도 당시에 개발한 내용이 아직 동작한다는 것이 신기할 정도.

QuickStart 문서의 내용도 당시와는 많이 달라졌는데, 부트스트랩 방식이나 디렉토리 구조 등이 많이 달라졌다. 기능도 추가할 겸 둘러보다가 디렉토리 구조를 현재의 방식에 맞게 다듬게 되었다.

부트스트랩 방식과 디렉토리 구조에서 크게 달라진 점을 정리해 보면 다음과 같다.

  1. controllers, models, views 디렉토리가 application 디렉토리 밑으로 들어갔다. 이를 통해 Moduler 디렉토리 구조와 호환되고 필요할 때 전환도 쉬워 진 것 같다.
  2. library 디렉토리에 Zend Framework 라이브러리를 포함하도록 한다. 프로젝트가 좀 더 독립적으로 배포될 수 있다. 또한, 외부의 Zend Framework 라이브러리를 참조하기 위해서 PHP include path가 수정되어야 하고, 결과적으로 부트스트랩에 영향을 미치는데, 이를 통해 부트스트랩을 수정해야 하는 일이 줄어들어, 설정이 단순화되었다.
  3. html 디렉토리가 public 디렉토리로 변경되었다. 단순히 이름의 변경이지만, 좀 더 성숙되어 가는 느낌이랄까.

결과적으로는 다음과 같은 디렉토리 구조가 된다.

image 

QuickStart 문서의 디렉토리 구조를 기본으로 하는 프로젝트 생성 도구를 예전에 만들었었는데, 새로운 디렉토리 구조에 따라서 다시 만들어 봐야 할 것 같다. 예전보다는 많이 깔끔해 져서, 사실 Quick Start 문서에서 제공되는 프로젝트를 그대로 풀어서 해도 상관은 없지만 말이다.

Zend Framework Project Directory Structure 더 읽기"