기본 콘텐츠로 건너뛰기

++ 숙련공에서 마스터로 - 06/07/27 13:40

++ 숙련공에서 마스터로  -  06/07/27 13:40

" 쉬운 정답 같은 것은 없다.
도구든, 언어든, 운영체제든, 프레임워크든, 방법론이든 상관없이 최고의 해결방안 같은 것도 없다.
오직 특정한 환경 조건의 집합마다 각 집합에 가장 적절한 시스템들이 있을 뿐이다."
- 앤드류 헌트, 데이비스 토머스

XX 회사의 프로그래머 P모씨, 그는 경력 5년차의 숙련공이다. 볼것, 못볼것 가리지 않고 봤으며, 해보지 않은 노가다가 없다.
이제는 어떤 노가다라도 아무생각없이 뚝딱뚝딱 해치울 수 있는 경지에 올랐다.
그러든 어느날, 수년간 동고동락하면서 노가다를 했던 사수 M모씨가 진급하면서 "안뇽! 나 이젠 개발 안해" 라는 말을 남기고 관리자의 세계로 차원이동해 버렸다.
혼자 남겨진 P모씨, 3년차와 신입 직원을 데리고 개발을 책임져야 하는 상태다.

고민하던 P모씨가 내린 결론은 개발 프로세스를 정립하는 것이다.
그러나 도무지 어디서부터, 무엇을, 어떻게 시작해야하는지 막막하다.
주위엔 천상 노가다꾼들이라 조언을 해줄 사람도 없다.
결국 why? 라는 물음에 답할 수 없다면, 시작도 할 수 없다는 사실을 깨닫는다.
프로젝트에 가장 잘 아는 사람은 P모씨 자신이며, why? 라는 물음에 답할 수 있는 사람도 P모씨 밖에 없다는 것을 안 것이다.
다행이 P모씨는 답을 할 수 있었다. 이는 몇달전에 일어난 악몽같은 사건에서 시작한다.

몇 달전, XX회사의 YY제품은 다수의 플랫폼에 포팅을 진행하면서 안정성을 획득하였다.
출시 및 배포한 이후에 6개월 이상 이상없이 작동중이다. 비록 고객의 잦은 요구사항 변경으로 코드가 조금 꼬인점은 있지만, 더이상 고객은 기능에 대해선 불평하지는 않는다.
그러던 중, 윗선에서 C8플랫폼에 제품을 포팅하라는 지시가 떨어진다.
C8플랫폼은 다른 플랫폼과 유사한 환경이기 때문에 P모씨는 자신있게 작업에 착수한다.
아뿔사, 컴파일 및 링크 과정부터 문제가 발생한다. 컴파일러, 써드파티 라이브러리, 비지니스 로직까지 문제가 발생하지 않는 곳이 없다.
일주일간의 노가다로 컴파일에 성공했지만 이젠 실행시에 프로그램이 죽어버린다. 도무지 원인을 알 수가 없다.
어느 시점에서 메모리를 덮어쓰고, 특정시점이 되어서야 죽는 악명높은 버그가 발생한 것이다.
시간은 흘러 한달이 다되어간다, 잦은 밤샘작업으로 몸은 몸대로 축나고, 고객과 윗선의 신뢰도는 낮아졌으며, 팀원의 사기도 극도로 낮아진 상태다.
고민하던 P모씨는 극단의 결단을 내린다. 각 서브 시스템에대한 단위테스트를 실시하여 하부구조의 무결성을 확보한 이후에 비지니스 로직에 대한 단위테스트를 실시하였다.

결국 총 한달이 걸린 악몽같은 디버깅 사건에서 단위테스트를 작성하는데 이틀이 걸렸고, 프로그램이 죽는 이유를 알고 나서 버그를 수정하는데 걸린 시간은 30분에 불과하였다.
이후 P모씨는 모듈을 추가/수정할땐 항상 단위 테스트를 수행 하고, 매일 같이 전체 소스코드의 빌드 및 테스트를 수행하여, 시스템의 무결성을 확보 할것을 맹세하였다.
다른 시스템에 포팅을 하더라도 어느부분에 이상이 있는지 즉시 알 수 있을 것이다.

조엘테스트

(http://korean.joelonsoftware.com/Articles/TheJoelTest.html)를 해본 P모씨는 자신의 생각이 맞다는 확신을 할 수 있었다.
  1. Source Control(소스 컨트롤)을 사용하십니까?
  2. 한번에 빌드를 만들어낼 수 있습니까?
  3. daily build(일별 빌드)를 만드십니까?
  4. 버그 데이타베이스를 가지고 있습니까?
  5. 새로운 코드를 작성하기 전에 버그들을 잡습니까?
  6. up-to-date(최신) 스케줄을 가지고 있습니까?
  7. spec(설계서)를 가지고 있습니까?
  8. 프로그래머들이 조용한 작업환경을 가지고 있습니까?
  9. 돈이 허락하는 한도내의 최고의 툴들을 사용하고 있습니까?
  10. 테스터들을 고용하고 있습니까?
  11. 신입사원들은 면접때 코드를 직접 짜는 실기시험을 봅니까?
  12. hallway usability testing(무작위 사용성 테스팅)을 하십니까?

P모씨의 팀의 점수는 2-3점에 불과하였다. 조엘에 따르면 세계 표준은 2-3점이라니,
웃고 넘기기엔 서글프다는 생각이 든다.
어쨌든 P모씨는 매너리즘을 떨쳐내고, 어느때보다 활기차게 공부를 한다. 그가 선택한 책음 다음과 같다.
  1. Code Complete
  2. Refactoring
  3. GoF Design Pattern
  4. Pattern-Oriented Software Architecture
  5. 실용주의 프로그래머
  6. 실용주의 프로그래머를 위한 단위 테스트
  7. 실용주의 프로그래머를 위한 프로젝트 자동화
  8. 서브버전을 이용한 실용적인 버전관리

1-4 번은 시간을 두고 점진적으로 공부 및 적용해야 할 것들이지만, 5-8번은 숙련공이라면 누구나 해봤을 노가다를 줄여주는 방법들로 가득차 있으며 즉시 적용가능한 것들이 많았다.
그래도 곧바로 시작하기엔 막연한점이 있었으나 리누스와 에릭 레이몬드의 교훈을 떠올린 P모씨, hellow world 프로젝트를 5-8번으로 적용해본다.
이후엔 계산기 프로그램같이 간단한 프로젝트를 몇가지 시뮬레이션 해본 P모씨가 디자인한 개발 시스템은 다음과 같다.

A. 버젼 관리 시스템(SVN)
B. 이슈 트래커(trac)
- 로드맵/마일스톤/릴리즈 관리
- 티켓(이슈)관리 - 기능의 추가,변경,개선 및 버그수정 등등..
- SVN 브라우징
- 위키
C. 개발 플랫폼
- 유닉스: GCC + gmake + CPPUNIT + shell script + perl + vi
- 윈도: MSYS + MingW + gmake + CPPUNIT + shell script + perl + vi
MSYS + VC++ + gmake + CPPUNIT + shell script + perl + vi
D. C++ Framework
- 코딩 스타일
- 플랫폼 추상화 / Eror Handling / UnicodeString / Memeory Management / Filesystem / Stream / Thread / Logging / Date & Time

마지막으로 P모씨는 개발자 K씨의 하루 일과를 시뮬레이션 해본다.

E. 개발자 K씨의 하루일과
- 메일확인, 전날밤 예약작업으로 걸어논 일일빌드 및 단위테스트가 깨졌다면 메일로 로그파일이 날라올것이다.
- 이슈트래커에 접속하여 로드맵/마일스톤/이슈/SVN의 변경사항을 체크한다.
- 자신에게 할당된 이슈를 처리한다.
아마도 이작업들은 기능추가, 기능변경, 버그수정, 단위테스트, 릴리즈 등 여러가지가 있을것이다.
- 단위테스트 프로그램을 작성하고 자동빌드 및 단위테스트를 수행한다.
- 이상이 없다면 SVN에 commit 하고, 이슈 트래커에 보고한다.

여기까지 진행한 P모씨는 개발 프로세스의 실체가 눈에 보일듯하다.
결국 K씨의 하루일과에서 사용된 각 단위작업을 수행하기위해 처리해야할 절차와 규칙을 기술한 매뉴얼, 그리고 그것들을 자동화해줄 스크립트를 작성한것을 개발 프로세스라고 부를 수 있음을 알았다.
what과 how에 대한 답인것이다.

F. 개발 프로세스 매뉴얼
- 생략

이제 P모씨는 YY제품에 대해서 지속적인 기능 추가와 변경으로 소스 코드가 꼬인것과, 전체 프로그램의 속도가 떨어진것을 만회하기 위해 리팩토링을 단행하여 차기버젼을 출시할 생각이다.
설계는 명확한편이고, 개발도중 요구사항 변경은 차차기 버젼으로 미루어 줄것을 저쪽 세계의 M모씨로부터 확답을 받은 상태다.
로드맵과 마일스톤 이슈를 이미 작성했으며 실제 구현만 하면 되는 상태다.
비록 P모씨가 디자인한 개발프로세스는 초기버젼이라 조악한 상태이지만 몇 달전과 비교했을땐 확실히 개선된 상태다.
그리고 이번 프로젝트가 끝나고 나면 더욱 개선될것을 확신하고 있다.

이상 관을 보고 눈물을 흘린 후, 심기일전하여 숙련공에서 마스터로의 서원을 세우고 용맹 정진을 위한 첫 걸음을 시작한 P모씨를 인터뷰한 J기자였습니다.
프로그래밍 세계에서 마스터의 실체가 무엇인지는, 비전문가인 J기자는 잘 모르겠습니다.
하지만 마스터들의 도구는 숙련공의 도구와 분명히 틀립니다.
항상 날카롭게 날이 서있으며, 한번 휘둘러 끝을 냅니다.
마스터들은 도구를 예술적으로 사용할 수 있습니다.
비록 도구를 잘 사용한다고 해서 마스터라고 부를 수 있는것은 아니지만, 숙련공이 마스터가 되기위한 첫걸음임에는 분명해 보입니다.

인터뷰

J기자:
원본인 P모씨가 작성한 글이 조잡하기에 이글도 조악해보입니다. 어떻게 생각하십니까?

P모씨:
이 거 모자이크+음성변조 되는거죠? 사실 저, 아는거 개뿔도 없습니다.
본문에 나오는 C8플랫폼에 이가 갈려 고민하던 중 우연히 같은 고민을 하시는 heavyman님의 글을 본거죠..
답변을 가장해서 고수님들의 조언을 듣고자 하는 낚시 글입니다. ^^

J기자:
한 달간의 디버깅 지옥에서 얻은것이 있다면 무엇입니까?

P모씨:
막바지에 이르자 눈에 다래끼가 나더군요. 그 이후로 조금만 무리하면 다래끼가 재발합니다. 이거 산재맞죠?

J기자:
몇 가지 책을 추천하셨는데, 그중에 하나를 꼽으라면 어떤것을 꼽겠습니까?

P모씨:
"실용주의 프로그래머"를 번역한 김창준씨는, 우리나라에서 XP의 전도사 격입니다.
그분이 쓰신 "어떻게 공부할까? 프로그래머를 위한 공부론" 이라는 인터넷 문서를 추천합니다. 좀 오래되긴 했지만 유용합니다.
물론 책으로는 "실용주의 프로그래머"를 추천합니다.
프로그래밍 세계에 실용주의를 전파한 경전이며, 전 기꺼이 교도가 되었습니다. "숙련공에서 마스터로" 이 문구는 이책의 부제이기도 합니다.

J기자:
마지막으로 할 말씀은 없으십니까?

P모씨:
사실 기술문서 보다는 리더쉽 관련 교육이 도움이 됬습니다.
제가 쓴글은 개발(구현)에만 치중한 것이 사실입니다. 가장 중요한 것들이 빠진셈이죠. 문제는 그것이 무엇인지 감이 않 잡힌다는 겁니다. 그것을 가르쳐줄 마스터가 주위에 없습니다.
중세유럽의 장인제도는 apprentice, journeyman, master 로 구성됩니다.
그들은 한 작업장(workshop)에서 수업을 했습니다. 이는 프로그램을 개발하는 사무실에서 그대로 재현됩니다.
문제는 대한민국에서 마스터들은 다들 다른 세계로 차원이동 했다는 겁니다.
부실한 제품이 대량생산되는 주요한 원인중 하나라고 봅니다. 과연 그들은 어디에 있는 건가요?

J기자:
별 내용 없네요? 어쨌든 잘 들었습니다. 수고하셨습니다.

댓글

이 블로그의 인기 게시물

80040154 오류로 인해 CLSID가 {xxxx-...}인 구성 요소의 COM 클래스 팩터리를 검색하지 못했습니다.

원문보기 .NET 으로 만든 응용프로그램에서 com 객체를 호출한 경우 Windows7 64bit 에서 제목과 같은 에러가 발생했다. Win32 COM 과 .NET 프로그램간의 호환성 때문에 생긴 문제였다. 원인은 .NET 실행시 JIT 컴파일러에 의해 최적화된 기계어로 변환되기 때문.. Win32 COM은 컴파일시.. Win32 COM에 맞춰 빌드 속성에서 하위버전으로 맞춰 컴파일을 다시하는 방법도 있지만 메인 프로젝트가 .NET이라면 참조되는 모든 프로젝트를 다 바꿔야할 노릇.. 또 다른 방법은 COM+를 이용하여 독립적으로 만드는 것이다. 분리시키는 방법은 아래 주소해서 확인할 수 있다. http://support.microsoft.com/kb/281335 나의 경우는 Win32 COM DLL을 64비트 .NET 프로그램에서 참조하니 COM 객체를 제대로 호출하지 못하였습니다. 그래서 .NET 프로그램의 Target Machine을 x86으로 설정하니 제대로 COM 객체를 호출하였습니다.

[Pyinstaller] 실행 파일 관리자 권한 획득하기

고객사에서 일부 사용자에게서 프로그램 오류가 발생한다며 아래와 같이 에러 캡처를 보내왔습니다. 프로그램에서 로그를 남기기 위해 로그 파일을 생성하는데 권한의 문제로 로그 파일을 생성하지 못해 프로그램 오류가 발생한 것 같습니다. 처음에는 Python 코드에서 관리자 권한을 요청하는 코드를 넣으려고 했는데, 실제로 Stackoverflow를 찾아보면 이런 내용이 나옵니다. 프로그램이 관리자 권한으로 실행되지 않았다면 관리자 권한으로 다시 프로그램을 실행시키는 코드입니다. import os import sys import win32com.shell.shell as shell ASADMIN = 'asadmin' if sys.argv[-1] != ASADMIN: script = os.path.abspath(sys.argv[0]) params = ' '.join([script] + sys.argv[1:] + [ASADMIN]) shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params) sys.exit(0) 하지만 개인적으로 이런 방식은 마음에 들지 않았고 조금 더 찾아보니 Pyinstaller로 exe 파일을 만들 때 옵션을 설정하여 관리자 권한을 요청하도록 할 수 있다고 합니다. --uac-admin을 옵션에 추가하면 프로그램 실행 시 관리자 권한을 요청할 수 있습니다. pyinstaller.exe --uac-admin sample.py 하지만 안타깝게도 이 방식은 원하는 대로 동작하지 않았습니다. 마지막으로 manifest 파일을 이용하여 시도해보았습니다. spec 파일을 이용하여 pyinstaller로 빌드하면 <실행 파일 이름>.manifest 라는 파일이 생성됩니다. 파일에서 아랫부분을 찾아볼 수 있습니다. <security> <re

초간단 프로그램 락 걸기

프로그램에 락을 걸 일이 생겨났다. 하드웨어 락을 걸면 쉬울텐데 그 정도는 아니고 프로그램의 실행 날짜를 제한 해 달라고 한다. 그래서 파일(license.lic)을 가지고 락을 걸리고 결정을 했다. 요구 사항은 아래와 같다. 1. license.lic 파일이 없으면 프로그램을 실행 할수 없게 한다. 2. 지정한 날짜를 넘어서는 프로그램을 실행 할수 없게 한다. 3. 사용자가 시스템 날짜를 되돌렸을때 인식하여 프로그램을 실행 할수 없게 한다. 음.... 1.번 문제는 사용자가 프로그램을 실행하기 위해서 license.lic 파일을 받아야만 한다. license.lic 파일에는 최근 실행 날짜/종료날짜 이런식으로 적도록 한다.(물론 내용은 암호화 한다.) 최근 실행날짜는 프로그램이 실행때마다 업데이트 하도록 하고 시스템 날짜와 비교하여 시스템 날짜가 최근 실행 날짜보다 이전의 날짜면 시스템 날짜를 되돌렸다고 인식하도록 한다.(3.번 문제 해결) 시스템 날짜와 종료 날짜를 비교하여 시스템 날짜가 종료 날짜를 넘으면 프로그램을 실행 할수 없도록 한다.(2.번 문제 해결)