Commitment
Gerald Salancik defines commitment as the way to "sustain action in the face of difficulties."
— quoted from Managing Technical People, Watts S. Humphrey
Gerald Salancik defines commitment as the way to "sustain action in the face of difficulties."
— quoted from Managing Technical People, Watts S. Humphrey
Whatever failing prompted Cutler to mistreat people, his capacity for blocking out the ordinary distractions of life was his road to excellence. People rarely achieved greatness because they were too blinded by daily routine even to try anything extraordinary. For Cutler mediocrity was a failure of will, not talent.
커틀러가 사람들을 학대하게 만드는 것이 무엇이었든 간에, 그를 뛰어나게 만드는 것은, 바로 일상 생활에서 집중을 방해하는 것들을 차단해내는 능력이었다. 사람들이 훌륭한 무언가를 이루어내기 어려운 이유는, 반복되는 일상에 잠식되어, 더 이상 평범하지 않은 무언가를 시도하지 못하기 때문이다. 커틀러가 생각하기에, 뛰어남에 미치지 못하는 평범함이란, 그저 의지의 부족이지, 재능의 부족이 아니었다.
— quoted from Showstopper!, Pascal G. Zachary
The best teams I have worked in and with are those that defy the traditional roles and responsibilities. Putting up artificial walls between extremely closely related disciplines can only be detrimental to getting great team work. Any given set of devs, testers and PMs working on a feature have a different set of skills and experience they bring to the team. Putting in place a structured set of expectations denies this fact. If the developer is more senior and experienced in an area, then you may want them leading more of the design of the feature, not just the implementation. Likewise if the PM is very senior and an experienced software architect, you may want them to have more of an input in the actual implementation decisions.
내가 함께 일했던 최고의 팀들은 전통적인 역할과 책임에 반하는 팀들이었다. 서로 밀접한 관련을 갖는 분야들 사이에 장벽을 세우는 것은 팀워크에 방해가 될 뿐이다. 하나의 기능을 위해 모인 개발자, 테스터, PM들로 구성된 팀은 서로 다른 기술과 경험의 집합을 보유하고 있다. 정해진 역할과 책임을 강제하는 것은 이러한 사실을 부인하는 것이다. 개발자가 해당 분야에 있어서 경험이 깊다면, 구현 뿐만 아니라 좀 더 많은 기능 설계를 이끌어가기를 바랄 것이다. 마찬가지로, PM이 매우 숙련된 소프트웨어 아키텍트라면, 실제 구현 결정에 있어서 좀 더 관여하기를 원할 것이다.
— quoted from ‘Great teams have members that defy roles‘ by Brad Adams
"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
sticube http://sticube.clubbox.co.kr/
아프리카, 피디박스, 클럽박스 등을 서비스하고 있는 나우콤에서 sticube라는 파일 공유 서비스를 만들었다. 루리웹 게시물을 보다보면 종종 보이고 있는 듯.
10GB 용량, 10GB 트래픽 무료 지원에 더해, ‘위젯’이라는 컨셉에 초점을 맞추어서 깔끔하게 만든 것 같다. 수익은 용량과 트래픽 추가에 있는 듯 하고, 용량과 트래픽을 독립적으로 추가할 수 있게 되어있다.
플래시 기반이라, Firefox에서도 정상적으로 사용이 가능하다.
가장 중요한 것은 위젯 개념인데, 아래와 같은 형태의 ‘위젯’을 게시판이나 블로그에 마음대로 사용할 수 있고, 음악 플레이어를 기본적으로 지원한다.
기술과는 거리가 먼 사람들이 embed니 object니 배우는 것 보고 가슴이 아팠는데, 왜 지금까지 없었을까 싶은 상당히 편리한 도구다. 저작권 이슈가 가장 큰 문제이긴 한데, 지금까지의 노하우(?)를 바탕으로 정면 돌파하지 않을까 싶다.
특정 리눅스 배포판 (e.g. CentOS 5) 의 중요 파일에는 (e.g. /etc/sudoers) ext2의 immutable attribute가 설정되어 있다.
ext2 파일시스템 내부적으로는 ext behaviour control flags이라고 부르는 것으로 보인다.
lsattr, chattr을 사용해서 ext2 attributes를 조회하거나 설정할 수 있다.
대규모 장비에 대한 환경을 운영해야 한다면, immutable attribute를 활용해보는 것도 괜찮을 것 같다. (e.g. 계정 공통 bash이나 vim 설정)
@ 그나저나 요즘은 리눅스 커맨드도 위키피디아에 나오는군.
이번에 Ubuntu Karmic으로 업그레이드 하고 나서, Eclipse 3.5에서 다음과 같은 증상들이 관찰되었다.
이 문제는 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
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 디자인의 문제를 중점으로 다루고 있다. GFS 페이퍼를 읽었든지, GFS 클론을 프로덕션 환경에서 사용해봤다면, single-master 디자인이 어떠한 문제들을 가지게 될 지 쉽게 상상할 수 있을 것이다.
일단 초기 GFS에서 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이 file-count 문제를 해결하는 용도로도 사용될 수 있는 듯 하다.
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를 숨기는 방식으로 동작하도록 설계하는 경향이 있다고 한다.
GFS의 모델에서는 client가 write가 성공할 때까지 push하는 방식이므로, operation 중 client의 crash가 일어나면 indeterminate state가 될 수 있다고 한다. 처음에는 이런 현상은 크게 문제가 아닌 것으로 봤으나, 파일 길이 등이 서로 다르게 보이는 문제 등 혼란의 여지가 많았기 때문에, 점차로 inconsistent한 상태를 허용하는 time window를 줄여갔다고 한다.
여러 client가 동시에 로그를 append할 수 있도록 하는 RecordAppend 기능과 같은 경우, loose한 consistency 모델 하에서는 서로 다른 순서의 데이터나 중복 write된 데이터 등이 발생해, 혼란을 줄 수 있는 여지가 많아지면서, RecordAppend 기능이 처음에 의도된 이득보다는 오히려 손실이 많았다고 한다.
GFS의 recovery 메커니즘은 client가 write를 할 수 없도록 chunk를 lock하고 snapshot을 복제하는 방식으로 동작한다. 이러한 방식은 latency의 원인이 될 수 있다.
GFS의 일반적인 snapshot 기능은 초기의 다른 설계와는 달리 제대로 구현되어 있는 영역인 것으로 보이고, 구현에 있어서 많은 비용이 들어간 듯하나, 그리 자주 사용되지는 않는 듯하다.
한 5년 전에 모르는 것에 관한 글을 쓴 적이 있다.
그 땐 지금보다 모르는 것은 더 많았지만, 실은 모르는 것보다 아는 것에 더 익숙하다고 생각하던 시절이었다. 시간이 흐른 지금 돌이켜보면, 그 동안 더 많은 글을 읽고, 더 많은 사람들과 이야기를 했지만, 아는 것보다는 모르는 것에 더 익숙해지고 있는 나를 발견한다.
모르는 것은 불편하기 이전에 두려운 것이다. 모르는 것은 싸워야 하고 반대해야 하는 것이다. 모르는 것은 다른 사람들보다 뒤쳐지는 것이고, 남에게 흉을 보이고 약점 잡히기 쉬운 것이다.
그래서, 모르는 것을 인정하는 일이야 말로 용기 있는 일이다. 모르는 것을 인정하는 사람에게는 칭찬을 하고 박수를 보내야 마땅한 일이다.
실로 다행스러운 것은, 모르는 것은 인간에게는 실로 자연스러운 현상에 불과하다는 것이다. 모든 사람이 모든 것에 대해서 알 수는 없는 것이다. 이러한 사실은 내가 ‘모르는 것을 인정’하고 싶을 때, 망설이지 않도록 하는 데 자신감을 북돋아준다. 상상해보라. 나의 옆에 앉아있는 동료는 항상 모든 것에 대해서 알고 있다면 얼마나 무시무시하겠는가.
‘모르는 것’의 이러한 특성 때문에, ‘모르는 것을 인정’하는 일은 마치 인간이 언젠가는 죽는다는 사실을 인정하는 것에 비유해볼 수 있다. 인간이 자신의 죽음을 대면하는 것은 두려운 일이지만 용기 있는 일이다. 인간이 언젠가는 죽는다는 사실은 태어날 때부터 정해진 자연의 이치일 뿐이다.
이런 식으로 생각해보면, 모르는 것을 인정하지 않는 사람은 갓난아기나 미친 이에 지나지 않고, 모르는 것을 숨기는 사람은 바보나 겁쟁이에 불과하다.
Der Vogel kämpft sich aus dem Ei. Das Ei ist die Welt. Wer geboren werden will, muss eine Welt zerstören. Der Vogel fliegt zu Gott. Der Gott heisst Abraxas. – Demian
int a = strlen("123");
int b = strlen("123 ");
int c = strlen("123 12");
int d = strlen("123 123");
int e = strlen("123 123 ABC");
int f = strlen("123 ABC");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의 고려에서 제외됩니다. 즉, 위의 문제에서, "