1. 정보모음에 소홀히 하지 말고 설명서를 읽음에 게을리 하지 말지어다. 오늘 필요 없는 정보는 내일 필요하리라. 가장 가치 있고도 저렴한 지식은 책 속에 있느니라. 서점과 동료의 책꽂이에 무엇이 꽂혀 있는지 때때로 살피어라. 무심코 흘렸던 종이 한 장이 너의 근심을 풀어 주었으리라. 설명서는 충분히, 꼼꼼히 읽을지어다. 모든 의문은 설명서를 안 보는데서 생기니라. 그렇더라도 모두 다 읽을 필요는 없느니라. 많은 정보가 능사는 아니니라. 정보의 가치를 찾는 법부터 배우라. 세상엔 너무나 많은 자료와 정보가 넘쳐난다.

알알이 모두 끌어 모을 생각을 하기 보단 정보를 하나로 꿰는 법부터 먼저 배우는것이 너의 근심에서 쉽게 벋어나게 하는 방법이 되리라. 일을 시작하기전에 필요한 정보를 꼼꼼히 먼저 챙기는 법부터 배워라. 너희는 먼저 개발 의뢰서를 꼼꼼히 읽을지어다. 만약 개발 의뢰서가 없다면 발주자에게 요구할 지어다. 개발 의뢰서 없는 프로그램은 존재하지 않으니라.


2. 너의 PC가 안전하다고 믿지 말지어다. 5분 후에 정전이 되고 내일 너의 하드가 맛이 가리라. 그러니 너의 소중한 소스코드는 정기적으로 여러 군데에 단계별로 백업해 두어라. PC는 평상시엔 안전하다. 그런 실수를 저지르는것은 네자신이거나 아니면 외부적인 요인에 기인한다. 항상 백업을 철저히 해두며 백업에 백업까지도 챙겨두라.그리고 백업을 했다면 리스트를 작성하라. 쓸데없는 백업은 백해 무익하나니 리스트를 항상 유지할 지어다. 너희는 노트를 옆에 끼고 살 지어다. 노트는 너의 생명이며, 너희가 기억하지 못하는 모든것을 상기시켜 줄지어다.


3. 변하는 수를 다룰 때에는 늘 조심할지어다. 정수가 절대로 그 한계를 넘지 않으리라 가정하는 것은 어리석음이라. 127 ,-128 ,255 ,32767 ,-32768 ,65535, 이 숫자들을 너의 골수에 새기어라. 0.0은 0이 아니니 실수는 원래부터 결코 정밀하지 않느니라. 부호 없는 것과 있는 것을 어울리거나 정수끼리 나눌 때에는 늘 조심하여라. 변수는 프로그램의 근원, 프로그램을 작성할때 가장 유의 할것이 바로 변수의 이름 짓기니라. 이름보고도 성격을 알 수 있게 해두라. 그러나 변수는 성질이 드러우니 변수에 성격을 부여할때는 조심스럽게 할지어다. 너희는 코딩하기 이전에 계획을 할 지어다. 이는 프로그래머가 코더가 아닌 것이니라.


4. 무슨 일을 반복시킬 때에는 처음과 끝에 유의할지어다. 너의 컴퓨터는 1보다는 0을 좋아 하니라. 배열의 첨자가 그 범위를 넘지 않을지 손 댈 때마다 따져 보아라. 수식에 1을 더하거나 뺄 때에는 늘 긴장하라. 너의 프로그램은 단지 한 번 덜해서 틀리고 한 번 더해서 다운되느니라. 프로그램을 작성할땐 계산, 판단, 비교를 그 모든걸 컴에게 되도록 맡기지말라. 네손으로 미리 계산하고 그 결과를 사용하는 방법이 최선이니라. 컴퓨터는 의지가 없나니 네가 잘못하든 잘하든 아무런 상관이 없느라. 너희는 머리가 악세사리가 아님을 기억하고 항상 생각하고 항상 노트에 적을 지어다.


5. 항상 모든 경우의 수를 고려하고 섣불리 생략하지 말지어다. 절대로 없어 나지 않을 일은 반드시 일어나고, 가장 드물게 일어날 일이 가장 너를 괴롭히리라. 그러하니 언제나 논리에 구멍이 없는지 꼼꼼히 따져 보고, if를 쓸때에는 else 부터 생각하라. 논리적인 오류는 성급함에서 생기나니 처음엔 항상 원리와 원칙을 지키라. 생각은 네가 하라 그리고 그 결과를 컴에게 시켜라. IF를 쓰기전에 규칙을 세우라. 먼저 IF의 결과에대한 규칙부터 세우고 따져라. 그리고 논리적인 계산을 IF문장안에서 하지 말라. 하나의 IF문장속에 수많은 논리연산은 버그의 원인이니라. 어느 정도의 프로그램에 대한 윤곽이 잡히면 프로토 타입을 만들지어다. 프로토타입은 프로그램에 대한 시뮬레이션이며 발주자의 요구를 빨리 수용 하는 방법이니라.

6. 함수 안에서 매개 변수값은 결코 믿지 말지어다. 지금 그 매개 변수가 결코 가질 수 없다는 값을 내일부터는 가지리라. 그러하니 매개 변수 값이 올바름을 항상 검사할지어다. 그렇더라도 처리 속도가 문제가 되는 경우는 예외이니라. 함수도 하나의 독립적인 프로그램이란것을 잊지말며, 네가 프로그램을 작성할땐 모든 함수가 돼도록이면 독립적으로 돌아가도록 할지어다. 함수의 매계변수는 항상 그옆에 작은 컴맨트와 초기화를 잊지말라. 처음부터 속도문제를 생각하지 말라. 모든 루틴을 최적화 할순 없다. 전체 프로그램중에 단 20%가 전체 실행시간에 80%를 점유한다. 프로토 타입에대한 발주자의 의견을 꼼꼼히 들을 지어다. 이는 발주자에 대한 신뢰도의 척도니라.

7. 오류를 알려 주는 기능은 있는 대로 모두 활용할지어다. 컴파일러의 경고는 모두 켜두어라. 경고는 곧 오류이니라. 오류를 알리는 함수의 결과를 확인하지 않는 우를 범하지 말지어다. 모든 파일 입출력과 모든 메모리 할당은 조만간 실패할 것이라. 컴파일러가 모든 경고기능을 동원해도 알려주지 않는 것은 많다. 중요한 건 오류가 생기기전에 규칙을 지켰는지 생각하라. 파일의 입출력과 메모리의 항당은 항상 쌍으로 생각해서 열었다면 닫아주고 활당받았다면 돌 려주라. 프로그램의 매인턴앤스를 게을리하지 말지어다. 이는 프로그램 만드는 일 보다 중요한 일이니라.

8. 한 번의 수정과 재컴파일만으로 연관된 모든 것이 저절로, 강제로 바뀌도록 할지어다. 어떠한 것을 수정했을 때에 연관된 것이 따라서 변하지 않는다면 그것이 곧 벌레이니라. 컴파일러로 하여금 매개 변수 리스트를 완전하게 검사하도록 하고 언젠가 손대야 하거나 따라서 변해야 하는 수치는 전부 매크로로 치환하며, 형 정의를 적극 활용하여라. 이미 완벽한 루틴을 손대지 말라. 프로그램이 무너지는 가장 첫번째이유는 도미노 현상 때문이나니 한번의 수정과 재컴파일로 쓸데없는것을 손대게 하지 말라. 컴파일러가 매개변수 리스트를 챙기지 말게 하라. 프로그램에 들어가기 전엔 미리 함수명과 매개변수 리스트를 만들어라. 너희는 프로그램의 도큐멘트를 만드는일에 게으르지말지어다. 이는 사용자가 너의 프로그램에 대해서는 바보이기 때문이니라.


9. 사용자가 알아서 잘 써 주리라고 희망하지 말지어다. 너의 프로그램은 항상 바보만이 쓰느니라. 사용 설명서를 쓸 때에는 결코 빠뜨리지 말아라. 빠뜨린 만큼 사용자는 너를 괴롭힐 것이니라. 사용자는 나쁜놈이다. 쓸데없는짓을 잘한다. 무식하다. 인간성도 더럽다. 대부분이 바보며 가끔 똑똑한 사람도 있는데 그 놈은 더 하다.모든것을 설명하지 말며 온갇기능을 가진 하나의 프로그램을 작성하려 들지 말라. 많은 기능이 필요한 프로그램은 나누어서 작게 따로 만들어주라. 너희는 공부하는데 게으르지 말지어다. 자고나면 새로운 하드웨어와 새로운 소프트 웨어가 나오기 때문이니라.


10. 매사에 겸손하고 항상 남을 생각할지어다. 가장 완벽한 프로그램일수록 가장 완벽하게 숨은 벌레가 있느니라. 네가 이 세상 최고의 프로그래머라고 떠들며 자만할 때, 옆집 곳간에서는 훨씬 더 뛰어난 것을 묵묵히 만들고 있느니라. 아무렴 프로그래밍은 혼자 잘나서 할 게 아니니, 너로 인해 다른 사람들도 더불어 잘 되면 그 얼마나 좋은 것이냐. 프로그래머는 논리적으 로 생각하여야 하지만 프로그램은 비논리적으로 작성하라. 프로그래머가 경지에 들면 누가 누가 잘하는지 알수가 없는 법, 또한 프로그래머로서의 '무지'에 대해서 잊지마라. 프로그래머의 '무지'는 생략하고, 선택하고, 단순화시키고, 명백하게하는 것이니라. 항상 새로운 아이디어와 새로운 생각으로 무장하라. 그리고 나누라 나누는곳에 기쁨있나니 너희는 모든 프로그램에 대해서 위의 프로시줘를 따를 지니라.
내용출처 : [기타] 인터넷 : http://www.beginninglinux.wo.to/
원문 :   D 프로그래밍 언어 소개
D 프로그래밍 언어 소개


음.. 요즘 D언어에 관심을 가지고 있습니다. 이름에서 알수 있듯이... B다음에 C다음에 C++다음에 만들어진 D언어입니다. 1.0이 나온게 몇년전이고 지금은 상당히 완성도를 가지고 있다고 하더군요.

그리고 예상과는 달리 사용자층도 꽤 만고 해서, D언어를 함 사용해 보기로 마음 먹고 위키를 만들었습니다.
위키의 주소는 http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/D 이고 앞으로 계속 수정되어 나갈 겁니다.




C 언어가 B 언어로부터 나왔다는 얘기는 아마 언뜻 들어서 다들 알고 있을 것 같다. 언어의 역사가 궁금하다면 언어의 역사 문서를 한번 보기 바란다.

C 도 나왔고, 객체지향을 적용한 C++도 나왔으니 이제 D 언어도 나오지 않을까 ? 라는 생각이 들어봄직도 할 거 같은데, 정말 D 언어가 나왔다. 물론 나온지는 꽤 되었고, 예전 부터 써봐야지 써봐야지 하면서 차일피일 미루어왔는데, 이번참에 직접 사용해 보기로 했다. 이 위키는 D언어를 잘 배워서 한번 써먹어 보자라는 취지로 만들었다.

관련기사
지 금, 세계는 대화 언어보다 프로그램 언어를 더 많이 가지고 있으나 프로그램 언어들은 계속 만들어지고 있다. 금주에 Digital Mars는 C/C++의 문제점과 약점을 해결한 D 언어를 발표했다. D는 C++ 컴파일러, Zortech C++의 자손이다. D는 무료이며 윈도우와 리눅스를 위한 표준 라이브러리이며 오픈 소스이다.

C/C++의 개선으로 D는 C 코드와 호환되며 콜 인터페이스 없이 어떠한 C API와도 인터페이스 가능하다. 그러나 D는 C 코드와 완전하게 후향적 호환은 안되며 자바와 Microsoft C#의 많은 기능을 추가로 한다. D는 2001년 이후 개발되었으며 오픈 소스 공동체의 입력물을 많이 사용하였으며 http://dmoz.org/Computers/Programming/Languages/D/에 자료가 많이 있다.

브라이트는 “D는 C++ 프로그래머의 경험에 의해 개발되었으며 많은 새로운 언어처럼 어느 특정한 플랫폼을 목적으로 설계되지 않았다. D의 개념은 빠르게 배우고 코딩하고 빠르게 디버깅하며 유지 보수하는 것”이라고 말했다.

Forrester Research 분석가인 제프 함몬드는 “D가 기반을 얻기까지에는 약간의 시간이 걸릴 것이다. D 언어가 성공하려면 D 언어 기술이 좋은 것 이외에도 그에 맞는 비즈니스 모델이 있어야 될 것”이라고 말했다. 마치 리눅스가 성공한 이유가 그 당시 다른 OS 가격이 너무 고가이어서 고객들이 선택했기 때문인 것처럼 필요한 비즈니스 모델이 중요하다.

출처 : http://www.internetnews.com

D 언어 소개

http://www.digitalmars.com/

C와 C++은 시스템프로그래밍에 있어서 강력함을 발휘 한다. 특유의 단순함과 중급언어라고 분류할 만큼 시스템에 가깝다는게 그 이유인데, 이 단순함은 요즘 같은 시대에 단점이기도 하다.

암 튼 이 두언어는 최신언어의 유행에 한참이나 뒤 떨어져 있다. 절차지향적이고 그다지 깔끔하지도 않으며, C++은 객체지향 적이긴 하지만 업계표준이며 모태라고 할 수 있는 C언어와의 호환성유지등의 문제로 현대언어들의 유행을 쫓아가지 못하고 있다.

물 론 현대언어의 유행이란 것이 모든 면에 있어서 좋은 쪽으로 흘러간다고 할 수는 없다. 그렇다면 C와 C++이라는 언어자체가 필요 없어질 것 아닌가. C와 C++이 유행을 따르지 않음으로써 구식언어라는 멍에를 지기는 했지만 여전히 시스템/네트워크 프로그래밍에 있어서, 속도와 성능,신뢰도 측면에서 높은 점수를 받고 있으며 실제로 널리 사용되고 있다.
Position
Dec 2007
Position
Dec 2006
Delta in PositionProgramming LanguageRatings
Dec 2007
Delta
Dec 2006
Status
1 1 Java 20.049% +0.14%   A
2 2 C 13.173% -3.44%   A
3 4 (Visual) Basic 10.219% +1.31%   A
4 5 PHP 8.393% -0.14%   A
5 3 C++ 7.871% -2.54%   A
6 7 Python 4.697% +0.93%   A
7 6 Perl 4.383% -2.01%   A
8 8 C# 3.994% +0.82%   A
9 11 Ruby 3.089% +0.76%   A
10 10 JavaScript 2.733% +0.17%   A
11 9 Delphi 2.673% +0.10%   A
12 14 D 1.633% +0.66%   A
13 13 PL/SQL 1.394% +0.05%   A
14 12 SAS 1.393% -0.84%   A
15 18 COBOL 0.894% +0.29%   A-
16 15 ABAP 0.875% -0.03%   A-
17 17 Lisp/Scheme 0.841% +0.20%   A-
18 20 Transact-SQL 0.817% +0.35%   A--
19 19 Pascal 0.791% +0.23%   A--
20 46 Lua 0.771% +0.67%   A-
출처 : http://www.tiobe.com/tpci.htm

D언어는 즉 시스템 프로그래밍을 위한 C/C++의 강력함과 최근의 언어들이 가지고 있는 Object orinted, template metaprogramming style 등의 multiparadigm을 지원하는 언어다.

D언어는 statically type를 지원하며 native 코드로 컴파일 되어서 실행된다.

D 언어 설치

Windows, Linux 모두에 대한 버젼이 있는데, 환경이 Linux인 관계로 Linux를 기준으로 설명하도록 하겠다.

  • http://www.digitalmars.com/d/download.html 에서 d 언어 컴파일러를 다운로드 받을 수 있다.
  • D언어 전용컴파일인 dmd와 GCC를 위한 GDC두가지 버젼이 있다.
  • gcc의 프론트엔드인 GDC를 받아서 테스트를 하기로 했다.
  • 다운로드 받은 다음에 /usr/local/gdc 에 압축을 풀었다.
  • 다음과 같이 LD_LIBRARY_PATHPATH 환경변수를 수정했다.

    # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/gdc/lib
    # export PATH=$PATH:/usr/local/gdc/bin

이제 wc의 d버젼을 가지고 테스트 해보았다.
import std.stdio;
import std.stream;
import std.date;

int main (char[][] args)
{
int w_total;
int l_total;
ulong c_total;
int[char[]] dictionary;

writefln(" lines words bytes file");
foreach (arg; args[1 .. args.length])
{
int w_cnt, l_cnt;
bool inword;

auto c_cnt = std.file.getSize(arg);
if (c_cnt < 10_000_000)
{
size_t wstart;
auto input = cast(char[])std.file.read(arg);

foreach (j, c; input)
{
if (c == '\n')
++l_cnt;
if (c >= '0' && c <= '9')
{
}
else if (c >= 'a' && c <= 'z' ||
c >= 'A' && c <= 'Z')
{
if (!inword)
{
wstart = j;
inword = true;
++w_cnt;
}
}
else if (inword)
{ auto word = input[wstart .. j];

dictionary[word]++;
inword = false;
}
}
if (inword)
{ auto w = input[wstart .. input.length];
dictionary[w]++;
}
}
else
{
auto f = new BufferedFile(arg);
char[] buf;

while (!f.eof())
{ char c;

f.read(c);
if (c == '\n')
++l_cnt;
if (c >= '0' && c <= '9')
{
if (inword)
buf ~= c;
}
else if (c >= 'a' && c <= 'z' ||
c >= 'A' && c <= 'Z')
{
if (!inword)
{
buf.length = 1;
buf[0] = c;
inword = 1;
++w_cnt;
}
else
buf ~= c;
}
else if (inword)
{
if (++dictionary[buf] == 1)
buf = null;
inword = 0;
}
}
if (inword)
{
dictionary[buf]++;
}
}
writefln("%8s%8s%8s %s\n", l_cnt, w_cnt, c_cnt, arg);
l_total += l_cnt;
w_total += w_cnt;
c_total += c_cnt;
}

if (args.length > 2)
{
writefln("--------------------------------------\n%8s%8s%8s total",
l_total, w_total, c_total);
}

writefln("--------------------------------------");

foreach (word1; dictionary.keys.sort)
{
writefln("%3s %s", dictionary[word1], word1);
}
writefln(toDateString(getUTCtime()));
return 0;
}

컴파일과 실행은 매우 간단했다.
# gdc -o wc wc.d
# ./wc wc.d
lines words bytes file
114 234 2922 wc.d

--------------------------------------
2 A
1 BufferedFile
2 Z
....
Mon Jan 29 2007

'1.소프트웨어 이야기 > 09.ETC' 카테고리의 다른 글

URL Helper  (0) 2007.12.06
Manifest 적용하기..  (0) 2007.12.06
두 점 사이의 각도 구하기  (0) 2007.12.06

The Joel Test: 나은 코딩을 위한 12단계


글 : Joel Spolsky
번역 : B.K. Chung 정봉겸
감수 : Jang Han Goo 구장한
2000년 8월 9일

SEMA에 대해서 들어보신 적이 있습니까? 소프트웨어 팀이 얼마나 잘하는지를 재는 나름대로 복잡한 시스템입니다. 앗, 아니! 그 링크를 누르지 마세요. SEMA를 "이해"만 하는데 아마 6년정도가 걸릴것입니다. 그래서 소프트웨어 팀이 얼마나 좋은지 등급을 매길 수 있는 - 좀 무책임하고 되는대로의 - 자체적인 버젼의 테스트를 만들었습니다. 이 테스트의 장점은 3분정도밖에 걸리지 않는다는 것입니다. 절약되는 시간으로 의대에 가서 공부할 수도 있을 것입니다.

The Joel Test

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

Joel Test이 특별한 점은 각 직문에 예/아니오로 바로 대답할 수 있다는 것이다. lines-of-code-per-day(하루동안 산출되는 코드의 줄수)나 average-bugs-per-inflection-point(산출 시점의 평균 버그수) 같은 것은 알 필요가 없습니다. "예"에 해당 하는 질문에 1점씬 가산됩니다. 하지만 이 테스트는 핵 원자로에 사용하는 소프트웨어가 안전한지를 검사하는등 에는 사용하지 말아주십시오.

12점은 완벽, 11은 충분한 점수이지만 10점이나 그 이하는 심각한 문제가 있다는 신호입니다. 사실은 대개의 소프트웨어 회사 들이 2~3점을 받고 있고, 심각한 도움을 필요로 하고 있습니다. Microsoft같은 회사는 12점 만점을 받고 있습니다.

당연한 이야기지만 이것들만으로 성공과 실패를 가를 수는 없습니다. 특히, 아무도 필요없는 제품을 굉장히 훌륭한 소프트웨어 팀이 만들고 있다면, 역시나 아무도 원하지 않을 것입니다. 반대로 이런 방식을 따르지 않는 명인들이 세상을 바꾸는 소프트웨어 를 만드는 경우로 생각할 수 있겠습니다. 그러나, 이 12가지 이외의 요소를 모두 동등하게 놓고 본다면, 이들만 제대로 한다면 지속적으로 좋은 결과를 내는 잘 훈련된 팀이 될 것입니다.

1. Source Control(소스 컨트롤)을 사용하십니까?

상용 소스 컨트롤 패키지들도 사용해보았고, 무료로 사용할 수 있는 CVS도 사용해보았습니다. CVS는 무료이기는 하지만 충분합니다. 그렇지만 소스 컨트롤이 없다면 프로그래머들을 조율하는 일이 상당히 피곤할 것입니다. 프로그래머들은 다른 사람들이 어떤 것을 했는지 알 수 있는 방법이 없습니다. 이를 사용하면 실수를 쉽게 롤백할 수 있습니다. 소스 컨트롤의 다른 장점은 소스코드 자체가 모든 프로그래머의 하드디스크에 체크아웃(check out)되어 있다는 것입니다. 소스 컨트롤을 사용하는 프로젝트에서 코드를 날렸다는 이야기를 들어본 적이 없습니다.

2. 한번에 빌드를 만들어낼 수 있습니까?

" 최신의 소스로부터 몇단계를 거쳐서 완제품(shipping build)을 만들 수 있습니까?"라는 의미의 질문입니다. 잘 되어있는 팀인 경우라면 하나의 스크립트로 checkout부터 시작하여 각 소스를 리빌드(rebuild)하고 각 버젼, 언어, #ifdef같은 조건별로 실행파일을 만들어내어 마지막 CDROM 레이아웃, 다운로드할 수 있는 웹사이트를 만들어 내는 정도까지 되어 있을 수 있겠습니다.

만일 이 과정이 하나의 단계 이상을 거친다면, 여기서부터 에러가 발생할 확률이 생깁니다. 정해진 기일이 가까워질수록 "마지막" 버그를 수정하고 실행파일을 만드는 등을 위해 빠른 사이클을 필요로 할 것입니다. 코드를 컴파일하고 설치파일을 구성하는데에 20단계가 필요하다면 급박한 시간때문에 사소한 실수를 저지르게 될 것입니다.

필자가 마지막으로 근무했던 회사에서는 이런 이유로 WISE를 InstallShield(역자주 : 두 제품 모두 설치본을 만들기위한 도구 입니다.)로 교체하였습니다. 설치 과정을 스크립트를 통해서 NT 스케줄러로 밤새에 자동으로 실행하도록 하고자 하였는데, WISE는 스케줄러로 실행할 수 없던 이유입니다. (WISE의 친절한 분들이 최신 버젼에는 이것이 가능하다고 알려왔습니다.)

3. daily build(일별 빌드)를 만드십니까?

소 스 컨트롤을 사용하다 보면 누군가가 빌드를 실패하게 만드는 코드를 체크인 할 수 있습니다. 예를 들면, 새로운 소스파일을 추가해서 그 사람의 컴퓨터에서는 잘 컴파일되지만, 이를 코드 레파지토리(repository)에는 추가를 하지 않았을 수 있습니다. 이 사람은 이를 잊고 만족한 상태에서 컴퓨터를 잠그고 집에 돌아갑니다. 그렇지만 이로 인해 다른사람들은 작업을 할 수 없게 되고 결국 찝찝하지만 결과없이 집으로 돌아갈 수 밖에 없습니다.

모르는 사이에 빌드를 실패하는 이런 컴파일 오류가 나지 않도록 daily build를 만들게 됩니다. 큰 팀에서는 이런 경우를 위해서 daily build를 매일 오후 - 점심시간등 - 에 합니다. 사람들은 점심시간 이전에 될 수 있는 한 많이 체크인을 합니다. 점심을 먹으로 갔다가 다시 돌아오면 빌드는 이루어져 있습니다. 빌드가 실패하면, 사람들은 빌드가 성공한 이전 소스로 작업을 하면 됩니다.

엑셀팀에서는 누군가 빌드를 깨면 벌칙으로 다른 사람이 다시 깰때까지 빌드를 관리하도록 벌칙을 주었습니다. 이는 빌드를 깨면 받는 벌칙으로써 뿐만 아니라 모든 이들이 돌아가면서 빌드를 관리할 수 있게하여, 어떻게 돌아가는 지를 익히게 하는 방법으로써도 좋았습니다.

daily build에 관해 더 자세히 아시려면 저의 기사 daily builds are your friend를 읽으십시오.

4. 버그 데이타베이스를 가지고 있습니까?

뭐 라고 반박하셔도 확신합니다. 코드를 짜고 있다면 설령 혼자 짜더라도 정리된 버그 명세 데이타베이스를 가지고 있지 않다면 낮은 질의 코드로 제품을 출시할 것입니다. 많은 프로그래머들이 머리로 버그들을 모두 기억할 것이라고 생각합니다. 말도 안되는 이야기입니다. 제 경우에는 한번에 2~3개의 버그밖에 기억을 못하고, 다음날이 되거나 출시를 위해 급해지면 전부 잊어버리게 됩니다. 버그를 제대로 트래킹해야합니다.

버그 데이타베이스는 복잡할 수도 있고, 간단할 수도 있습니다. 최소한으로 갖추어야할 요소는 다음과 같습니다:

  • 버그를 완벽하게 재현할 수 있는 과정
  • 버그가 없었다면 이루어졌어야할 결과(동작)
  • 버그로 인하여 생긴 결과(동작)
  • 누가 이 버그에 할당되어 있는지
  • 고쳐진 버그인지 아닌지

버그 데이타베이스를 사용하지 않는 이유가 제품들이 너무 복잡해서라면, 이것들을 포함한 5컬럼의 테이블을 만들어서 사용하기 시작하세요.

버그 트래킹에 관해 더 읽으려면, Painless Bug Tracking을 읽으세요.

5. 새로운 코드를 작성하기 전에 버그들을 잡습니까?

마 이크로소프트 Windows용 Word의 첫 버젼은 죽음의 프로젝트였습니다. 끝이 없었습니다. 계속해서 스케줄을 펑크냈습니다. 팀 전체는 말도 안되는 시간동안 일했고, 계속해서 연기되고 또 연기되었습니다. 그 스트레스는 엄청났습니다. 빌어먹을 제품이 몇년 후에 출시되었을때, 마이크로소프트는 팀 전원을 Cancun으로 휴가보내고, 이 원인을 분석하기 시작했습니다.

그들이 깨닫게 된 것은 프로젝트 매니저들이 스케줄을 너무 강요하였기 때문에 프로그래머들은 코딩을 빨리 할 수 밖에 없었습니다. 게다가 버그를 고치는 단계는 스케줄에 아예 존재하지 않았습니다. 결과적으로 질이 아주 나쁜 코드를 만들게 되었습니다. 버그 갯수를 줄이려는 노력은 전혀 하지 않았습니다. 한 프로그래머는 텍스트의 높이를 계산하는 루틴 대신에 "return 12;"로 대체하여 버그 리포트로부터 이 값이 어떤 영향을 주었는지를 알고자 했습니다. 스케줄은 단지 버그일 수 밖에 없는 기능들을 모아 놓은 체크리스트였습니다. 나중에 이 상황을 "무한 결함 방식(infinite defects methodology)"이라고 이름지었습니다.

문제를 해결하기 위해서 마이크로소프트는 반대의 "무결함 방식(zero defects methodology)"라는 방식을 체택했습니다. 많은 프로그래머들은 경영진들의 명령에 의해서 버그 갯수를 줄일 수 있다고 생각했음직한 이 방식의 이름 탓에 이를 비웃었습니다. 하지만 실제로는 "무결함(zero defects)"이라는 이름은 주어진 시간에 가장 우선순위가 높은 것은 코딩하기전에 버그를 잡는 것이란 사실을 지칭하는 말이었습니다. 이유는 다음과 같습니다.

일반적으로 버그를 고치지 않고 방치하는 시간이 길어지면 길어질수록 고치는데 더 많은 시간과 금전이 요구된다는 것입니다.

예를 들면, 오타나 문법오류등은 컴파일러가 쉽게 잡아서 고치는데도 별로 문제가 되지 않습니다.

만일 버그가 처음 실행시에 발생하여 보이게 되면, 모든 코드가 머릿속게 생생하게 존재하기에 바로 고칠 수 있을 것입니다.

며칠전에 작성한 코드에서 버그를 찾게 되면 이를 고치기 위해 조금 시간이 더 걸릴 것입니다. 아마도 코드를 다시 보게 되면 대부분의 내용이 기억나고 적정한 시간내에 버그를 고칠 수 있을 것입니다.

하 지만 몇달전에 작성한 코드에서 버그가 발견된다면 이미 그 코드에 관해서 많은 것이 이미 생각나지 않을 것이고, 고치기도 상대적으로 힘들 것입니다. 그때쯤 되면 다른 사람의 코드를 수정하고 있는 와중일지도 모르고, 그사람은 Aruba로 휴가를 떠나있을지도 모릅니다. 이렇게 된다면 버그를 고치는 것은 기술을 익히는 것같이 되어버릴 것입니다. 천천히 꼼꼼하게 그리고 주의 깊게 코드를 살펴봐야 하고, 물론 문제를 해결하는데에 얼마나 걸릴지 정확하게 판단하기 힘든 상황이 될 것입니다.

게다가 이미 출하된 코드에서 버그를 발견한다면, 이를 고치는데에 큰 대가를 치뤄야할지도 모를 것입니다.

이 렇게 시간이 적게 들기 때문이라는 이유가 하나의 이유가 됩니다. 또다른 이유는 버그를 수정하는데 걸리는 시간을 예상하는 것보다는 새로운 코드를 작성하는데 걸리는 시간을 예상하기가 훨씬 쉽기 때문입니다. 예를 들면, 내가 당신에게 리스트를 소트하는 코드를 만드는데 얼마나 걸리냐고 물어본다면, 꽤 정확한 대답을 할 수 있을 것입니다. 그렇지만, 질문을 바꿔서 당신의 코드가 Internet Explorer 5.5만 설치되어있으면 동작하지 않는 버그를 고치는데 걸리는 시간을 묻는다면, 문제가 무엇인지도 모르는 상황이기 때문에 얼마나 걸릴지 추측하지도 못할 것입니다. 3일이 걸릴 수도 있을 것이고, 운좋으면 2분이 걸릴 수도 있을 것입니다.

이것이 의미하는 바는 고쳐야할 버그가 많이 존재하는 상태의 스케줄이라면 그 스케줄은 정확할 수가 없다는 것입니다. 그렇지만 이미 알고있는 버그들은 모두 고친 상태라면 그 스케줄은 상대적으로 상당히 정확하게 지킬 수 있는 스케줄일 것입니다.

버그 갯수를 0에 가깝게 하는 또하나의 좋은 점은 경쟁에서 훨씬 빠르게 대응할 수 있다는 것입니다. 어떤 프로그래머들은 이를 두고 제품을 바로 출하할 수 있는 항상 유지하는 것이라고 이야기합니다. 경쟁자가 고객들을 가로채갈만한 굉장히 좋은 기능을 새로 만들었다면 축척된 많은 버그를 수정할 필요없이 바로 이 기능을 추가할 수 있을 것입니다.

6. up-to-date(최신) 스케줄을 가지고 있습니까?

비즈니스에 당신의 코드가 조금이라도 중요한 부분이라면, 코드가 언제쯤 완성될 수 있는지를 아는 것 또한 중요하다는 것은 당연할 것입니다. 프로그래머들은 엉터리 스케줄을 만드는데 악명이 높습니다. "언젠가는 될꺼야!"하고 외칩니다.

불 행하게도 그런 식으로는 해결할 수 있는것은 없습니다. 비즈니스에는 코드를 출하하기 전에 데모, 전시회, 광고등등 미리 많은 것들을 판단하여 결정해야합니다. 이를 할 수 있는 단 한가지 방법은 스케줄을 가지고 이를 계속해서 현실적으로 최신내용으로 유지하는 것입니다.

스케줄을 가져야하는 또다른 중요한 이유는 이를 통해서 어떤 기능이 필요한지를 결정하게끔 만들어준다는 것입니다. 때문에 어떤 기능이 덜 중요한지 결정해야하고 featuris 가 되기 전에 이들을 포기하도록 합니다.

스케줄을 관리하는 것이 어려울 필요는 없습니다. 제 글Painless Software Schedules 에 좋은 스케줄을 만드는 간단한 방법을 설명하였습니다.

7. spec(설계서)를 가지고 있습니까?

스펙을 만드는 것은 이빨을 쑤시는것과 같습니다: 모든 사람들이 좋다고 인정하지만, 아무도 하지 않습니다.

왜 그런 현상이 일어나는지는 정확히 모르겠습니다만, 아마도 프로그래머들이 문서를 만드는 것을 굉장히 싫어하는데에 기인하는 것 같습니다. 그 결과로, 프로그래머밖에 없는 집단에서 한가지 문제를 해결하고자 하면, 이들은 문서를 만들기 보다는 코드로 자신들의 의견을 표명하려 합니다. 스펙을 먼저 만들기보다는 차라리 코드를 짜서 보여주는 것을 택한다는 것입니다.

설계 단계에서 문제를 발견하면 몇줄을 고쳐서 이를 수정할 수 있습니다. 그렇지만 코드가 짜여진 상황이라면 이 문제를 수정하는 댓가는 감정적으로나(코드를 그냥 버리는 것을 좋아하는 사람은 없습니다) 시간적으로나 훨씬 높게 되고 더 힘든 작업이 되어버립니다. 스펙을 통해서 만들어지지 않은 소프트웨어는 대개 설계가 잘못되어 스케줄을 엉망으로 만들어놓습니다. Netscape에서도 이런 문제로 인해 브라우저의 초기 네개의 버젼이 너무 엉망이 되어 결국 관리자들이 멍청하게도 코드를 전부 버리고 다시 짜도록한 결정을 내려버리게 되는 상황이 벌어졌습니다. 거기다 한술 더 떠서 Mozilla에서 이런 실수를 다시 반복하여 겨우 Alpha 단계에 가는데 몇년이라는 시간이 걸리게 되었습니다.

필자의 지론은 이 문제는 프로그래머들이 문서를 작성하는데 거부감이 없도록 작문 강의를 듣도록 보내는 것으로 해결할 수 있다는 것입니다. 다른 해결책이라면 스펙같은 문서 작성에 능숙한 관리자를 두는 것입니다. 두 경우 모두 "스펙없는 코드는 금물"이라는 간단한 규칙을 따라야 할 것입니다.

저의 4부짜리 글에 스펙 작성하는 요령에 대해 이야기했습니다.

8. 프로그래머들이 조용한 작업환경을 가지고 있습니까?

지식 근로자에게 공간, 조용함, 프라이버시를 줌으로해서 많은 생산성 향상을 얻는다는 것은 이미 증명된 사실입니다. 소프트웨어 관리의 고전인 Peopleware에서는 이 생산성 향상에 대해 자세히 기술합니다.

문 제는 여기에 있습니다. 지식 근로자는 "in the zone"상태라고도 하는 "flow"상태에 들어섬으로써 가장 최상의 상태가 되어 일에 완벽히 집중하고 외부에 개의치 않게 됩니다. 완벽한 집중으로 시간 가는 것을 잊고 좋은 결과를 내게 됩니다. 이때에 바로 대부분의 생산적인 일들을 처리하게 됩니다. 작가, 프로그래머, 과학자 그리고 심지어 농구선수들까지도 "in the zone"상태가 있음을 이야기할 것입니다.

문제는 "zone"으로 들어가는 것이 쉽지 않다는 것입니다. 측정해보면, 최상의 생산성으로 일을 하기 위해서는 평균 15분이 걸립니다. 하지만 어떤 경우에는 피곤하고 이미 많은 일을 한 상태에서 "zone"상태에 들어가지 못하고 다른 일을 하거나 웹서핑이나 테트리스로 시간을 허비하게 될 수도 있습니다.

또다른 문제는 "zone"상태에서 빠져나가는 것이 매우 쉽다는 것입니다. 잡음, 전화소리, 점심식사, 잠시 스타벅스에 5분간 갔다오는 것 그리고 특히 동료에 의한 방해등에 의해 바로 "zone"에서 빠져나가게 됩니다. 동료가 1분이라는 짧은 시간 동안이라도 질문을 하여 "zone"상태에서 빠져나간다면 다시 되돌아가기 위해서 30분이 넘는 시간이 걸려 전체 효율에 치명적인 영향을 미칠 수 있습니다. 카페인 가득한 닷컴 회사들이 좋아하는 합숙소같은 곳에 옆의 마케팅 부서에서 계속해서 오는 전화에 대고 소리지르는 그런 시끄러운 환경이라면 계속된 방해로 지식 근로자들의 생산성은 추락하여 "zone"상태에 절대 이르지 못할 수도 있습니다.

프 로그래머들에게 있어서 특히 어렵습니다. 생산성은 단기적인 기억력으로 한번에 얼마나 많은 작은 세부사항들을 다루느냐에 달려있습니다. 어떠한 방해도 이런 세부사항들을 잊어버리게 할 수 있습니다. 일을 다시 재개하면 그것들을 다시 기억하지 못하여 (사용하던 지역변수나 검색 알고리즘을 만들던 중에 어디에서 멈줬었는지등) 다시 찾아보게 되고, 이로 인해 다시 속도가 붙을때까지 느려지게 됩니다.

직관적으로 계산해보면 다음과 같습니다. 만일 프로그래머가 단 1분이라도 방해를 받아서(명백한 근거에 의해) 15분의 생산성을 날려버린다고 합시다. 철수와 영희 두 프로그래머가 낮은 칸막이로 주욱 늘어선(a standard Dilbert veal-fattening farm) 열린 사각 파티션 옆자리에 앉아 있다고 합시다. 영희가 strcpy함수의 유니코드 버젼 이름을 잊었습니다. 30초면 찾아볼 수 있겠지만, 철수한테 물어보면 15초가 걸립니다. 그래서 바로 옆에 앉아 있는 철수에게 묻습니다. 철수는 산만해지고 - 영희의 15초를 아끼기 위해 - 15분을 낭비하게 됩니다.

이번에는 벽과 문으로 나뉘어진 별도의 사무실로 가정을 합시다. 여전히 영희는 함수를 기억하지 못합니다. 다시 찾아보는 것으로 30초를 보낼 수 있을 것이고 옆 방에 있는 철수에게 물어보기 위해서 (일반적인 프로그래머의 평균 물리적인 건강상태를 봐서는 쉽지 않은) 일어나서 걷는 것을 포함한 45초를 보낼 수 있을 것입니다. 결국 찾아보는 것을 선택하여 30초를 보내게 되지만 철수의 15분을 벌어주게 됩니다. 대단하죠!

9. 돈이 허락하는 한도내의 최고의 툴들을 사용하고 있습니까?

컴 파일 되는 언어로 코드를 작성하는 것은 여전히 아무 PC에서 할 수 없는 것 중의 하나입니다. 컴파일을 하는데 몇초 이상 걸린다면 최상의 기종을 사용함으로써 시간을 절약할 수 있을 것입니다. 15초 이상 걸린다면 지루해서 그 시간동안 The Onion을 읽게 될 것이고 너무 재미있는 관계로 거기에 빠져 수시간의 생산성을 날려버릴 것입니다.

모니터 하나로 GUI코드를 디버깅한 것은 불가능하지는 않지만 고통스러운 작업입니다. GUI코드를 작성하고 있다면, 2대의 모니터로 훨씬 쉬운 작업을 할 수 있을 것입니다.

대 개의 프로그래머들은 아이콘이나 툴바를 위해 비트맵을 수정해야하고 대부분의 프로그래머 역시 좋은 비트맵 에디터를 가지고 있지 않습니다. 마이크로소프트에서 기본적으로 제공하는 Paint 프로그램으로 비트맵을 수정하는 것은 웃긴 일이지만 대부분 이렇게 하고 있습니다.

필자의 가장 최근 직장에 서 시스템 관리자가 계속해서 자동적으로 스팸을 보냈습니다. 이유인 즉슨 220MB이상의 하드드라이브를 사용하고 있다는 것이었습니다. 필자는 요즘 HD가격을 본다면 이 공간의 환산된 가격은 내가 이용하는 화장실 휴지보다 싸다는 것을 지적했습니다. 디렉토리를 정리하기 위해 10분을 허비하는 정도로도 큰 생산성 저하일 것입니다.

"최고의 개발팀은 절대 그들의 프로그래머들을 고문하지 않습니다!" 후진 제품으로 인한 작은 불편함이 쌓여서 프로그래머들이 불만에 찰 수도 있습니다. 그리고 그로 인한 불만에 찬 프로그래머는 비생산적인 프로그래머이기 쉬울 것입니다.

이런 것들을 모두 종합하면 프로그래머들은 최고/최신의 것들로 쉽게 매수된다는 뜻이 됩니다. 이는 높은 연봉을 주는 것보다는 훨씬 싼 방법일 것입니다!

10. 테스터들을 고용하고 있습니까?

팀 이 최소한 2~3명의 프로그래머에게 테스팅만 전담하는 테스터가 할당되어 있지 않다면, 버그가 많은 제품을 출하하고 있거나 시간당 $100짜리 프로그래머에게 시간당 $30의 일을 시키는 낭비를 하고 있는 것입니다. 테스터를 고용하는 것이 낭비로 생각하는 것은 정말 잘못된 계산을 하고 있는 것이며, 많은 사람들이 이를 깨닫지 못하고 있는데에 놀랍니다.

이에 관해 더 자세히 알고자 한다면 Top Five (Wrong) Reasons You Don't Have Testers 를 읽으십시오.

11. 신입사원들은 면접때 코드를 직접 짜는 실기시험을 봅니까?

마법사를 고용하는데 그의 마법을 보지 않고 고용하시겠습니까? 당연히 그렇지 않겠죠.

결혼식에 요리사를 고용하는데 요리사가 만든 요리의 맛도 모르고 고용하시겠습니까? 그렇지 않을것입니다.(역자주: 실제로 결혼식장 요리사의 맛을 보는 비유는 우리나라에 맞지 않을 것 같네요. 이 문구의 뜻만 이해하세요)

하 지만 현실에서는 매일 인상적인 이력서나 면접에서 맘에 든 이유로 고용하는 일들이 일어납니다. 혹은 ("CreateDialog()와 DialogBox()의 차이점은 무엇입니까")등의 문서만 보면 알 수 있는 사소한 질문으로 채용하기도 합니다. 프로그래머를 채용하는데 있어서 중요한 것은 그런 사소한 것들을 얼마나 많이 외웠느냐가 아니고 코드를 잘 작성할 수 있느냐입니다. 혹은 "아하!"류의 질문으로 채용하기도 합니다. "아하!"류의 질문이란 답을 알면 간단하지만 모르는 경우에는 절대 맞출 수 없는 질문을 이야기합니다.

제발 이런 방식을 그만 두십시오. 면접때 무얼해도 상관없지만 반드시 코드를 작성하도록 해야합니다.(더 많은 것을 알고 싶다면 Guerrilla Guide to Interviewing를 읽으십시오)

12. hallway usability testing(무작위 사용성 테스팅)을 하십니까?

무작위 사용성 테스트(hallway usability test)는 복도를 지나가는 다음 사람을 붙잡고 방금 짠 코드를 사용하게 하는 방식입니다. 5명에게 이 테스트를 한다면 95%의 사용성 문제에 대해 배울 수 있을 것입니다.

좋은 사용자 인터페이스 설계는 생각처럼 어려운 것이 아니고 사용자들이 당신의 제품을 구입하고 사용하게 하는데 있어서 절대적으로 중요합니다. 짧은 프로그래머 입문서로 UI 설계에 관해 필자가 쓴 무료 온라인 책을 읽어보실 수 있습니다.

하지만 사용자 인터페이스에서 제일 중요한 것은 많은 사람들에게 당신의 프로그램을 보여주면(5~6명이면 충분합니다) 제일 큰 문제점을 빠른 시간에 발견할 수 있다는 것입니다. Jakob Nielsen의 글에서 그 이유에 대한 설명을 찾을 수 있습니다. UI 설계 경험이 별로 없다고 하더라도 - 비용이 전혀 들지 않는 - 무작위 사용성 테스트를 한다면 당신의 UI는 훨씬 좋아질 것입니다.

Joel Test를 사용하는 4가지 방식

  1. 자신이 속한 소프트웨어 팀의 점수를 매기고 그것에 대해 언급할 수 있도록 결과에 대한 이유를 필자에게 알려주십시오.
  2. 프로그래머 팀의 관리자라면, 당신의 팀이 최대한 잘 운영될 수 있는지 확인할 수 있는 지표로 사용하십시오. 12점을 받기 시작하면 프로그래머들을 간섭없이 그냥 두고 비즈니스쪽 사람들이 그들을 간섭하지 못하게 하는데에 모든 시간을 할 수 있습니다.
  3. 프 로그래머 일을 맡을지를 결정해야하는 상황이라면 그 팀의 친한 사람에게 이 테스트 결과가 어떤지를 물어보십시오. 결과 점수가 너무 낮다면 이를 고칠 수 있는 권한을 받을 것인지를 확인하십시오. 그렇지 않으면 불만과 스트레스에 빠질 것입니다.
  4. 프로그래밍 팀을 평가하여야 하는 투자자이거나 당신의 회사가 다른 소프트웨어 회사와 합병을 한다면 이 평가가 급한대로 괜찮은 지표가 될 것입니다.
이 기사는 영어로 The Joel Test: 12 Steps to Better Code 라는 이름의 기사가 원본입니다.

'0.일상다반사 > 09.다른이 생각' 카테고리의 다른 글

프로그래머 10계명  (0) 2007.12.06
사용자 요구사항과의 괴리..  (0) 2007.12.06
개발자의 마음 가짐  (0) 2007.12.06



사용자 요구사항을 맞추는건 참 어렵다...

[이미지 출처] 인터넷에서 구함.. 저작권에 문제가 되면 알려 주시면 출처 밝히겠습니다.
[개발자의 마음 가짐세]

항상 프로그래밍에 대해서 열린 마음(Open Mind)을 가져라. 새로운 아이디어를 거부하는 것은, 개발 능력 발전에 매우 유해한 행위이다.

자만심을 죽여라. 자만심은 어느 정도 경력이 있는 고참 개발자에게 가장 나쁜 것이다. 자만심은 자기 파괴적이며, 팀 이익을 위배한다. 당신이 어떤 개발 능력을 가지고 있던 간에, 당신보다 우수하지는 못할지라도, 당신만큼 뛰어난 다른 개발자들이 여럿 있다는 사실을 명심하라. 그런 개발자들은 자신만의 특수한 기술을 가지고 있지만, 당신의 개발 실력에 찬사를 표시할 것이다. 만일 당신이 자만심을 고수한다면, 다른 팀원(혹은 다른 개발자)들이 형편없다고 격하시키면서 그 자만심을 유지하려 할 것이다. 특히 당신이 팀장(Team Leader)이라면 더욱 그러할 것이다.

자만심이 강한 팀장은, 대부분, 팀원(혹은 다른 개발자)들을 교육하기를 꺼려하고, 팀원(Member)들을 도우려 하는데에도 인색하다. 단지 팀원들은 모조리 바보다라고 생각한다. 실력이 뛰어난 팀원들을 자신의 경쟁상대로만 간주하고, 거리를 멀리 하려 한다. 모든 팀에는 어느 정도 이런 유형의 행위가 발생한다. 팀장과 팀원간의 이런 특성을 깨닫는 것이, 좋은 팀을 만드는 첫걸음이다.

만일 그러하지 않았다면 다음과 같은 목표를 세워라.

1. 나의 팀을 더 뛰어나게 만들어라. 팀원들이 일을 잘하면, 결국 나도 잘하는 것이다.(팀장으로서의 능력이 뛰어남을 인정받게 되는 것이다)

2. 고참의 정도나 입사 기간이 아니라, 개발자들을 공로(성과)로 경쟁하게 하라.

[동료 코드 리뷰(Peer Review)]

동료들의 코드를 정기적으로 리뷰하라. 다른 팀원들이 당신의 코드를 리뷰하게 하는 것 뿐만 아니라, 당신 또한 다른 팀원의 코드를 리뷰해야 한다.

다른 사람의 코드를 봄(review)으로 해서, 더 나은 코딩 방법을 자주 찾을 수 있을 것이다. 당신이 비록 고참의 위치에 있다해도, 다른 사람들의 코드를 보는 것은, 다른 방법을 찾아내는 것만큼이나 유용하다.

다른 사람의 코드를 보는 것을 필수적으로 행하라. 종종 다른 사람의 시야가 당신이 잊은 무엇을 찾을 수 있으며, 다른 방법을 제시할 수 있고, 실수를 찾을 수도 있다. 때로 당신은 특별한 작업에 시달려서 매우 침체될 수 있으며, 이 때문에 다른 대안을 간과하는 경우가 발생한다.

그 작업과 거리가 먼 사람이 코드를 리뷰함으로써, 문제를 단순화하고 더 빠르고 좋은 방법을 찾을 수 있는 경우가 자주 있다.(이 말은 때로는 다른 사람의 시야가 나보다 더 해결책을 잘 찾아낼수도 있다는 것이다. 바둑이나 장기에서, 실제 대전자보다 관전하는 사람이 훈수를 더 잘 한다는 말과 비슷한 의미이다).

고참 개발자는 다른 사람에게, 심지어 신참 개발자에게라도, 자신의 코드 보여주기를 습관화할 필요가 있다. 다음과 같은 두가지 이유 때문에 그러하다.

1. 진행중인 작업과 다소 거리가 있는 다른 사람을 위해 코드 리뷰를 위해서
2. 코드 리뷰어 교육을 위해서

결국 모든 코드 리뷰어들은 팀원들이기 때문이다. 당신이 팀원들을 더 잘 교육할 수록, 당신 자신의 일에 더 몰두할 수 있으며, 더욱 고차원적인 일을 할 수 있는 여유가 생길 것이다.

[항상 배울게 있다]

매우 경력이 화려하고 뛰어난 개발자라해도, 다른 사람에게서 뭔가 배울 것이 항상 있다. 나는 모든 것을 다 알고 있다 혹은 나는 어떤 다른 개발자보다도 뛰어나다고 스스로 단정을 내려버리는 것 만큼, 당신의 경력과 개인적 발전에 저해되는 행위는 없을 것이다.
히스토그램에 대하여 궁금해하시는 회원님들이 계셔서 이두형과장께 허락받고 옮겨왔습니다. 도움이 되었으면 합니다.
출처:  http://www.zuikouser.com/bbs/zboard.php?id=pds&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=134

DSLR카메라로 촬영을 한 다음 촬영한 이미지를 보면서 info를 클릭하면 그 이미지의 농도분포를 알려주는 그래프가 보입니다.
이 것을 히스토그램이라고 하는데 이를 지원하는 이유는 LCD에 출력된 화상이 절대 결과물의 상태와 상이하기 때문에 이미지를 보며노출 적용 여부를 확인하기 위함입니다. 즉 시각적인 판단 보다는 원본의 물리적인 데이터를 보여준다고 보면 되겠죠.

1. 아래 첫번째 이미지와 같이 가로는 밝고 어두운 농도 구역을 의미하고 세로축은 분포량을 의미합니다.
두번째 코스모스 이미지를 보면 전체적으로 눈에 띠는 검은색이나 흰색이 별로 없고 전반적으로 중간색조의 농도들이 많이 분포되어 있음을 알 수 있습니다. 그러나 자세히 보면 완전 검은색과 완전 흰색이 있긴 하죠?
그렇다면 그래프는 첫 이미지와 같게 형성될겁니다. 왼쪽 하단부는 완전 검은색 존이고 오른쪽 끝은 완전 하얀색 존이므로 분포 곡선은 좌우에 양 끝에서부터 형성됩니다.
또 전체적으로 중간색조가 많으니까 중간색 영역부분으로 갈 수록 분포도가 크게 형성되겠죠.
이제 이해하셨는지요...


2. 파도치는 장면을 찍은 두 사진의 분포를 보면 밝은 쪽의 그래프가 높고 두껍게 형성되어 있습니다. 눈으로 봐도 밝은 색조의 농도가 많은 사진이쟎아요...
단지 차이가 있다면 오른쪽 사진에는 암부의 농도분포도 크게 자리잡고 있습니다.
그게 당연하다고 느끼신 회원님들은 이미 히스토그램에 대하여 이해를 하신 것입니다.


3. 이번 경우는 상대적으로 암부에 톤이 집중되는 이미지 입니다. 이미지를 볼 때 밝은 영역과 어두운 영역이 어느 정도 일까?하고 살펴보시기 바랍니다.
왼쪽의 단풍 이미지의 오른쪽 끝엔 약간의 빈 공간이 있습니다. 이는 제일 하얀색이 이미지에 없다는 것을 의미합니다. 오른쪽 송수관쪽엔 끝에 하얀색 농도가 분포되어 있는 것을 알 수 있지요?
이제 그래프의 느낌이 이미지와 통하는지요?


4. 지금까지의 설명을 토대로 아래 이미지를 보면서 다시 한번 분석해 봅시다.
왼쪽의 사진은 노츨이 약간 부족되어 있습니다. 빛이 부족하게 들어가니까 이미지에 하얀색이 없어 오른쪽 끝부분이 빈공간으로 남겠죠.
그래서 이를 카메라에서 확인한 다음 노출을 더 주어 두번째 사진을 찍습니다.
그리고 히스토그램을 보니 이전 이미지보다 오른쪽 밝은 부분이 더 늘어나 있습니다.
전 여기까지 만족을 했구요...만일 더 밝은 부분이 있기를 바란다면 좀더 노출을 주어야갰지요.
그러나 너무 과도하게 노출을 더하면 반대로 이미지에 검은색이 없어지겠죠.
그렇게 되면 사진이 밋밋해 질꺼라고 판단했기에 그 정도로 만족을 한겁니다.


5. 마지막 이미지들도 같은 이야기 인데 왼쪽은 본래 피사체의 암부와 명부의 차이가 약했고 노출도 약간 부족되어 칙칙합니다. 그래서 콘트라스트를 강하게 +2로 증가시켰습니다.
그리고 노출도 약간 늘려줬구요. 이렇게 하니 원래 밋밋했던 피사체의 톤이 확장되면서 그래프의 좌우에 모두 분포된 이미지를 만들 수 있었습니다.


여기까지 응용할 수 있다면 히스토그램이 왜 필요한지 아셨을 꺼예요...

원래 피사체 상태가 검은색은 없거나 흰색이 없는데 노출만으로 그래프 분포를 모두 확장할 수는 없습니다.
콘트라스, 채도까지도 관계가 있거든요.

정리하면 히스토그램은 피사체와 노출의 상호 관계를 그래픽적으로 판단하게 해주는 도구일 뿐입니다.
그래서 LCD를 믿지 못해도 그래프로 노출 상태를 어찌할 것인지 방향을 잡을 수 있게해주는 것이죠.

전 가끔은 흰색을 질감이 존재하면서 가장 밝게 묘사하기를 바랄 때가 있습니다.
이때 노출을 조절한 다음 힛스토그램으로 확인을 합니다. 가장 밝은 영역이 오른쪽 끝에서부터 시작되도록요.....
오른쪽 끝부분의 농도분포가 너무 커지면 지나쳐 하얀색의 질감이 날라갈 수 있겠죠...
[초급] OpenCV 를 이용한 영상 이진화(Binarization) 강좌
 
오 늘은 손쉽게 구현할 수 있는 영상 이진화(Binarization)에 대해서 설명해 드리도록하겠습니다. 영상 이진화란 RGB 값으로 다양하게 분포되어 있는 색상값을 0 과 1 만의 값으로 표현하는 것 입니다.실제적으로는 RGB 컬러 영상에을 흑백(Gray channel)영상으로 바꾼뒤 특정 임계값(Threshold)을 기준으로 초과값은 255 로, 이하 값은 0 변환하게 되지요. 아래 T9-camera 윈도우 영상과 T9-output 윈도우 영상을 보시면쉽게 이해가 가실 겁니다. T 값 128 을 기준으로 초과값은 255 로 변환되어 흰색으로 보여지고 있고 이하 값은 0 으로변환되어 검은색으로 보여지고 있습니다.
 
 
- 실행 결과

소 스 코드가 다소 길어 졌지만 크게 보면 카메라를 입력 받는 소스에서 이진화 함수인 cvThreshold() 함수가 추가된 것 밖에는 없습니다. 이 함수를 사용할 때 주의해야 할 것은 항상 흑백 이미지로 변환해서 넣어 주어야 한다는 것.

  cvThreshold(gray, output, threshold, 255, CV_THRESH_BINARY); 

위 함수는 입력된 gray 이미지에서 threshold 값을 초과한 값은 255 로 변환하고 이하는 0 으로 변환하여output 이미지를 만들어 냅니다. 이와는 반대로 적용되게 한다거나 일정 값 이하는 0 으로 변환하고 초과되는 값만 보여주는등의 옵션이 있습니다. 옵션을 변화 시켜가며 변화되는 모습을 익혀 보도록 합시다.

  CV_THRESH_BINARY        : threshold 값 초과는 255, 이하는 0

  CV_THRESH_BINARY_INV  : threshold 값 초과는 0, 이하는 255

  CV_THRESH_TRUNC         : threshold 값 초과는 threshold, 이하는 그대로

  CV_THRESH_TOZERO       : threshold 값 초과는 그대로, 이하는 0

  CV_THRESH_TOZERO_INV : threshold 값 초과는 0, 이하는 그대로

이 번 프로그램에는 Trackbar 가 추가되었는데 이는 나중에도 유용하게 쓰이므로 잘 익혀 두시기 바랍니다. 아래 함수는"T9-camera" 이름의 윈도우에 0 부터 255 범위를 같는 "T" 이름의 Trackbar 를 붙입니다. Trackbar의 초기 위치는 threshold 값이 결정하며 bar 를 조절하여도 그 값은 threshold 변수에 들어가게 됩니다. 그리고현재는 NULL 로 되어 있지만 이부분에 함수명을 적으면 bar 가 변경될 때마다 해당하는 함수를 호출하게 됩니다. 이 함수는반드시 int 형 변수 하나를 가지고 있어야 하고 이 변수에 Trackbar 의 값이 넘어 오므로 함수에서 값을 가지고영상처리를 해주면 됩니다.

  cvCreateTrackbar("T", "T9-camera", &threshold, 255, NULL);

cvCvtColor() 함수는 Color 변환을 해주는 함수입니다. 아래 함수는 RGB 채널을 가지고 있는 image 를Gray 채널로 바꾸어서 gray 에 넣어주는 역할을 합니다. 마지막 인자는 Color 변환 모드인데 여기에도 다양한 옵션이존재하므로 필요한 모델을 사용하시면 됩니다.

  cvCvtColor(image, gray, CV_RGB2GRAY);

  CV_RGB2GRAY  : 흑백으로 변환
  CV_RGB2YCrCb : 주로 Skin Color 모델을 할때 변환( 손 제스쳐 인식, 얼굴 인식 )
  CV_RGB2HLS
  CV_RGB2HSV
  CV_RGB2Lab
  CV_RGB2Luv
 

- 소스 코드(압축 파일 첨부)

 
#include <cv.h>
#include <highgui.h>

 
void main()
{
    int i, threshold = 128;
// 임계값(Threshold) 설정

    IplImage* image = 0;
    IplImage* output = 0;
    IplImage* gray = 0;
 
    CvCapture* capture = cvCaptureFromCAM(0);
// 카메라 연결

    cvNamedWindow( "T9-camera", 0 ); // 원본 영상을 띄울 윈도우
    cvNamedWindow( "T9-output", 0 );
// 결과 영상을 띄울 윈도우

    cvCreateTrackbar("T", "T9-camera", &threshold, 255, NULL); // "T9-camera" 윈도우에 bar 를 붙이고 threshold 값을 변화 시킴
                                                                                         
// 이름은 "T" 를 붙이고 0 부터 255 사이의 범위값을 가짐

    while(1) {
        cvGrabFrame( capture );
        image = cvRetrieveFrame( capture );
        cvShowImage( "T9-camera", image );

        if(!output){
            gray = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1); // 흑백 이미지 생성
            output = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1); // 흑백 이미지 생성
        }

        cvCvtColor(image, gray, CV_RGB2GRAY); // 컬러를 흑백으로 변환
 
        if( cvWaitKey(10) >= 0 )
            break;

        // 영상의 각 픽셀(x,y) 값이 threshold 값의 초과는 255 로, 그 이하는 0 으로 변환

        cvThreshold(gray, output, threshold, 255, CV_THRESH_BINARY);
        output->origin = image->origin; // 방향이 뒤집어 진것을 바로 잡아줌
 
        cvShowImage( "T9-output", output );
    }
    cvReleaseImage( &gray );
    cvReleaseImage( &output );
    cvReleaseCapture( &capture );
    cvDestroyWindow( "T9-output" );
    cvDestroyWindow( "T9-camera" );
}

초급] OpenCV 초보를 위한 강좌 - 2편 : 카메라 입력받기

이번 강좌에서는 OpenCV 를 이용하여 간단하게 카메라 영상을 입력받아 IplImage 형 구조체에 넣고 출력 윈도우의크기를 조절해서 화면에 보여주는 작업을 할 것입니다. 1편을 통하여 기본적인 셋팅 방법은 습득 하셨을테니 바로 아래와 같은소스코드를 작성한 후 컴파일 해 봅시다.

 
- 소스 코드(압축 파일 첨부)
 
#include <cv.h>
#include <highgui.h>

void main()
{
    IplImage* image = 0;
    CvCapture* capture = cvCaptureFromCAM(0);
    cvNamedWindow( "T9-camera", 0 );

    cvResizeWindow( "T9-camera", 320, 240 );

       
    while(1) {
        cvGrabFrame( capture );
        image = cvRetrieveFrame( capture );

        cvShowImage( "T9-camera", image );
 
        if( cvWaitKey(10) >= 0 )
            break;
    }

    cvReleaseCapture( &capture );
    cvDestroyWindow( "T9-camera" );
}

 
- 소스 설명

일 단 OpenCV 를 사용하기 위하여 영상처리 관련 라이브러리를 사용하기 위해 <cv.h> 를 include하고 영상을 캡쳐 받고 윈도우로 보여주기 위해 <highgui.h> 를 include 하지만 사실 카메라 영상만 입력받아 화면에 보여줄 것이라면 <highgui.h> 만 include 해도 됩니다.

  #include <cv.h>         // 영상 처리를 위한 header
  #include <highgui.h> 
// 카메라로 영상을 입력받거나 이미지를 읽어들이고 화면에 보여주기 위한 header

 다음은 IplImage 구조체로 image라는 포인터를 생성하여 앞으로 이 것으로 이미지를 받고 처리하게 됩니다. IplImage 의 구조체는 이미지에 관련된 다양한정보를 가지고 있으며 char 형 imageData 를 가지고서 이미지에 직접적인 접근을 할 수 도 있습니다.

 
  IplImage* image = 0;

cvCaptureCAM() 함수를 이용 0번째 연결된 카메라로부터 컨트롤을 얻어 옵니다. 숫자를 넣는 부분에 카메라의 인덱스 번호를 넣으면 현재 2 대 까지 연결이가능하며 이렇게 연결된 capture 는 끝나기 전에 cvReleaseCapture() 함수로 release 해 주어야 합니다.

  CvCapture* capture = cvCaptureFromCAM(0);  // 0 번째 연결된 카메라로부터 컨트롤을 얻어 옵니다.

 cvNamedWindow() 함수는 "T9-camera" 라는 타이틀의 윈도우를 생성합니다. 두번째 인자 값은 고정된 윈도우(0)를 생성 하거나 보여질 이미지의 크기에 맞게 자동 조절 윈도우(1)를 생성 할 수 있습니다. 두 번째 인자를 0 으로 하고 아래 문장을 추가하면 윈도우 크기를 자유롭게 조절 할 수 있습니다. 이것은 입력 소스를 조절하는 것이아니라 출력 창의 크기를 조절 하는 것이므로 화면의 크기를 키울 경우 사각 픽셀이 보이는 현상이 나타납니다.

  cvNamedWindow( "T9-camera", 0 );            // T9-camera 라는 이름의 윈도우를 생성, 0 은 고정된 윈도우를 생성
  cvResizeWindow( "T9-camera", 320, 240 );  // T9-camera 라는 이름의 윈도우 크기를 조절 width = 320, height = 240

 그리고카메라로 부터 매 프레임을 받아오기 위해서 while(1) 문으로 무한 loop 을 돌립니다. 이 무한 loop 는 if(cvWaitKey(10) >= 0 ) 문장을 통해 'ESC' 키가 눌려지면 종료하게 되고 종료되지 않는다면 다음과같은 작업을 반복하게 됩니다. cvGrabFrame( capture ) 함수는 카메라로 부터 입력된 영상의 한 프레임을 잡고,cvRetrieveFrame( capture ) 함수는 잡은 프레임으로부터 이미지를 얻어 냅니다. 이 두 함수는 함께 쓰이며카메라로부터 영상을 받아 이미지에 넣는 과정이라고 보시면 됩니다. 다음으로 cvShowImage( "T9-camera",image ) 함수는 image 를 "T9-camera" 라는 타이틀의 윈도우에 뿌려주게 되는데 해당 타이틀의 윈도우는cvNamedWindow() 함수로 이전에 미리 만들어 두어야 합니다.

  while(1) {
      cvGrabFrame( capture );                    // 카메라로부터 한 프레임을 잡습니다.

      image = cvRetrieveFrame( capture );    // 잡은 프레임으로부터 IplImage 형 구조를 리턴 받아 image 에 넣습니다.

      cvShowImage( "T9-camera", image );  // "T9-camera" 윈도우에 image 를 보여줍니다.
 

      if( cvWaitKey(10) >= 0 )
          break;
  }

 

마지막으로 capture 를 release 하여 카메라와의 연결을 종료하고 윈도우를 소멸시키면 프로그램은 안정적으로 종료됩니다.

  cvReleaseCapture( &capture );
  cvDestroyWindow( "T9-camera" );

다음은 cvNamedWindow() 함수와 cvResizeWindow() 함수를 이용하여 윈도우 창의 크기를 변화 시켜 출력한 결과 화면입니다.

>> 소스코드 결과 화면

     cvNamedWindow( "T9-camera", 0 ) 함수에서 두번째 인자가 '0' 이고
     cvResizeWindow( "T9-camera", 320, 240 ) 함수를 추가 한 경우

>> cvNamedWindow( "T9-camera", 0 ) 함수에서 두번째 인자가 '0' 일 경우

>> cvNamedWindow( "T9-camera", 1 ) 함수에서 두번째 인자가 '1' 일 경우


- 주요 함수

A.윈도우 관련

  cvNamedWindow( "T9-camera", 0 );
  cvShowImage( "T9-camera", image );
  cvDestroyWindow( "T9-camera" );

 
B.카메라 영상 캡쳐 관련

  CvCapture* capture = cvCaptureFromCAM(0);
  cvGrabFrame( capture );
  image = cvRetrieveFrame( capture );

  cvReleaseCapture( &capture );

Copyrights (c) 2005 OpenCV.co.kr. All rights reserved.

Media System Lab., Yonsei University
by Dong-Chul Kim, e-mail: opencv at opencv.co.kr

- T9T9.com

+ Recent posts