Media Log

그가 쓴 해커가 되는 방법이라는 글에서, 훌륭한 프로그래머가 되려면 얼마나 걸리냐는 질문에
얼마나 재능이 있고 열심히 공부하는지에 따라서 다르다. 만약 충분히 노력한다면 1년 반에서 2년 정도 사이에는 꽤 훌륭한 수준의 기술을 갖게 될 수 있다. 하지만 그게 끝이라고 생각해선 안된다. 훌륭한 프로그래머가 되기 위해서는 10년 정도가 걸린다.
만약 진정한 해커가 되고 싶다면 끊임없이 학습하고 기술을 다듬는데에 남은 인생 모두를 투자해야 한다.

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/240 관련글 쓰기

submit

유명한 리누스 토발즈와의 논쟁에서,

리누스 토발즈가 모놀리딕 커널을 계속 옹호하고, 이식성은 나중에 신경써도 된다고 말하자

당신이 제 학생이 아닌 것이 다행입니다. 그러한 설계로는 아마도 좋은 학점을 받지 못할 것입니다.
1991년 지금 시점에서, 386에서만 돌아가는 이식성 없는 새로운 OS를 설계하는 것은 당신에게 F를 안겨 줄 것입니다. 다만 기말 시험을 잘 본다면 이 과목은 통과할 수 있습니다.
잘은 모르겠지만 그래도 확신하건데, 아마도 이 논쟁은 타넨바움의 머리 속에서 가장 지워내고 싶은 기억 중 하나일 것이다.
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/239 관련글 쓰기

submit
MSDN에 따르면 구조체의 디폴트 패킹 값은 8이다. 간혹 32비트 운영체제에서는 4바이트이고 64비트 운영체제에서는 8바이트라고 주장하는 사람들도 있는데 디폴트 패킹 크기는 컴파일러가 결정하지 운영체제가 결정하는 것이 아니다. MSVC에서 디폴트 패킹을 8바이트로 정한 이유는(32비트 운영체제에서 조차) 기본 타입 중 가장 큰 타입이 8바이트이기 때문이다. 만약 이후에 16바이트 포인터나 INT128 같은 타입을 기본 타입으로써 사용하는 날이 온다면, 그 때는 디폴트 패킹 값도 16바이트로 변경될 것으로 예상한다.

여기에 패킹을 잘 이해하고 있는지 알아보기 위한 좋은 질문이 있다.

strcut X
{
  char c1;
  char c2;
  char c3;
  char c4;
  char c5;
  char c6;
  char c7;
};

struct Y
{
  char c;
  double d;
  int i;
};

디폴트 패킹 값인 8을 사용한다고 할 때 구조체 X와 Y의 크기는 각각 얼마일까?

잠시 생각해보고 아래를 클릭해서 답을 확인해보도록 하자.

더보기


구조체의 멤버들은 자신의 크기의 배수로 정렬되는 것이 좋다. char는 1의 배수, short은 2의 배수, int는 4의 배수, double은 8의 배수의 메모리 번지 주소에 위치하고 있을 때 우리는 해당 데이터가 정렬되어 있다고 말한다.
x86호환 아키텍쳐에서 윈도우즈 응용 프로그램을 만들 경우에는 정렬이 되어있지 않을 때 CPU가 메모리에 다시 접근하려고 시도하면서 성능이 떨어지게 된다. 다른 아키텍쳐에서는 응용이 크래시가 나거나 따로 예외 핸들링을 해주어야 할 수도 있다.

컴파일러는 데이터를 정렬시키기 위해서 구조체의 적당한 위치에 패딩을 집어넣는다. 조금 생각해보면 위 Y구조체에 마지막 4바이트 패딩은 필요가 없을 것 같다. 중간에 넣은 7바이트 패딩으로 인해 3개의 필드가 모두 잘 정렬이 된 것 같은데 말이다.
뒷 부분에 4바이트 패딩을 넣은 이유는 구조체가 배열에서 사용될 때 구조체의 멤버들이 메모리의 정렬된 위치에 올라가도록 하고 싶기 때문이다. 뒷 부분에 패딩을 넣지 않았으면 int나 double 타입이 자신의 타입에 맞게 정렬된 주소에 올라가지 못했을 것이다.

다음 Z구조체를 보자. 위의 Y구조체에서 double과 int의 위치만 바꾸었다. -위치만 바꾸었는데 패딩이 Y구조체와 다르게 들어가는 것에 대해서도 유심히 살펴 보아야 한다.
struct Z
{
    char c;
    // pad[3]
    int i;
    double d;
};

int _tmain(int argc, _TCHAR* argv[])
{
    // 다음 코드를 사용해서 어떻게 padding이 들어가 있는지 쉽게 확인해볼 수 있다.
    printf("position c:%d\n", FIELD_OFFSET(Z, c));
    printf("position i:%d\n", FIELD_OFFSET(Z, i));
    printf("position d:%d\n", FIELD_OFFSET(Z, d));
    printf("Total size:%d\n", sizeof(Z));
}
직접 코드를 실행시켜보는 것도 좋고, 아래 그림을 보고 이해해도 좋다. 이 구조체가 배열에서 사용될 때에는 아래와 같은 레이아웃을 갖게 될 것이다.

char는 1의 배수에, int는 4의 배수에, double은 8의 배수에 정렬되어져 올라가 있는 것을 주목하라. 진한 파란색으로 표시된 3바이트 패딩이 있기 때문에 가능한 일이다.

맨 처음 문제에서 X구조체의 크기가 8bytes가 아니라 7bytes인 이유는 모든 멤버가 char이기 때문이다. char는 1의 배수인 어느 주소에나 올라가도 되므로 padding을 집어 넣지 않아도 모든 멤버가 항상 자신이 원하는 주소에 올라가게 된다.
Y구조체가 Z구조체와 멤버 위치만 바꾸었는데 다른 레이아웃을 가지고 있는 이유도 그림을 그리면서 확인해보면 이해할 수 있을 것이다.

8로 패킹한다는 것은 구조체의 크기를 8의 배수로 맞추겠다는 것이 아니라, 크기가 8보다 큰 멤버가 있을 때는 정렬을 포기한다는 것을 뜻한다. 즉, 크기가 8보다 작은 타입에 대해서만 정렬하려고 시도하며, 이것은 다른 말로, 변수의 메모리 주소를 최대 8의 배수로 정렬한다는 뜻이 된다.
만약 패킹 크기를 4로 바꾼다면 double이나 int64_t 같은 타입들이 사용되었을 때 더 이상 정렬이 보장되지 않게 된다. 왜 디폴트 값을 8로 정했는지 이해가 되는가?

구조체를 만들 때는 어떻게 패킹이 될지 잘 예상해서 조각을 맞추듯이 만들어야지 아무 순서로나 마구 쑤셔넣는 것은 프로답지 못하다. 마이크로소프트에서 만든 거의 대부분의 구조체들은 이런 사소한 것들까지 잘 고려해서 만들어져 있다.
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/238 관련글 쓰기

  1. 황후순 at 2011/12/19 09:02 [edit/del]

    틀린 내용인거 같은데... double이 많을까요? Pointer가 많을까요?
    포인터가 32비트에서 4바이트고 64비트 8바이트라서 패킹을 각각 하고 있습니다. 구조체 크기랑은 별개의 이야기지요.메모리크기는 당연히 데이터 사이즈대로 나오겠죠. 패킹과 메모리사이즈는 별개의 얘기죠.
    단편화 생기는 과정을 만들어서 프로그램이 어떻게 죽는지 확인해보시기 바랍니다.
    필자는 ms vs compiler만 확인해보신 것이 아닌지... 메모리 패킹은 운영체제가 변경됨에 따라도 얼마든지 바뀔수 있으니 무조간 8바이트라고 단정하는건 문제가 됩니다.

    Reply
    • Favicon of http://www.benjaminlog.com BlogIcon 김재호 at 2011/12/19 10:10 [edit/del]

      패킹이랑 메모리 사이즈는 별개의 이야기가 아닙니다. 그리고 패킹은 운영체제와는 상관없는 이야기이고요.
      무조건 8바이트라고 단정한 것이 아니라 왜 기본값을 8바이트로 정했는가에 대해서 말해본거에요.

      프로그램이 어떻게 죽는지 확인해보라는 말을 조금만 더 자세히 설명해 주실수 있을까요? 무슨 이야기를 하고 싶으신건지 궁금하네요^^

  2. 김준홍 at 2012/09/25 01:21 [edit/del]

    안녕하세요
    C언어를 공부하고 있는 대학생입니다.

    위 글 너무 잘읽었습니다.
    구조체 접근제한과 패딩에 대해 자세한 설명 잘 읽었습니다.

    메모리 패딩에 대해 궁금한 점이 있어 이렇게 글을 남깁니다^^

    ----------------------------------------------------------
    #include <stdio.h>

    typedef struct A{
    char a;
    int b;
    char c;
    int d;
    }A;

    void main(void){
    printf("%d\n", sizeof(A));
    }
    ----------------------------------------------------------

    위 예제에서는 구조체에서 각각 a,b,c,d에 대해 int형이 최대 사이즈이므로
    4bytes 를 기준으로 a,b,c,d에 각각 4bytes씩 계산하여 16bytes 가 나오느데요..


    ----------------------------------------------------------
    #include <stdio.h>

    typedef struct A{
    char a;
    char c;
    int b;
    int d;
    }A;

    void main(void){
    printf("%d\n", sizeof(A));
    }
    ----------------------------------------------------------
    두번째에서는 조금 순서를 바꾸어서 c를 b위로 올려보았습니다.
    이경우에는 앞선 예제와 달리 char가 연속적으로 2개 있어서
    앞쪽에 패딩 바이트에 패킹되어 a, c가 4bytes로 묶이고, 나머지 b, d는 각 4bytes가 되어
    총 12 bytes로 결과가 나오는듯 합니다^^

    제가 궁금한 것은.. 구조체에서 선언하는 순서에 따라 메모리를 차지하는 크기가 다를 수 있다는 이야기인데,
    위 두번째 예제처럼 char나 int 혹은 short와 같이 변수들이 같은 타입끼리 연속적으로 있어야지만 패킹이
    되는 것인지 궁금합니다. 첫번째 예재처럼 char , int, char, int로 구조체를 구성하면 왜 각각에 대해 4bytes를 차지하게 컴파일러가 명령하는지 궁금합니다. 첫번째 예제에서도 빈공간의 패딩바이트를 활용해서 char끼리 같은 곳에 묶어서 위치시키면 더 효율적이게 되는게 아닌지 궁금하네요.

    wnshddl00@nate.com 으로 답변주시거나, 댓글 달아주시면 감사하겠습니다.

    Reply
    • Favicon of http://www.benjaminlog.com BlogIcon 김재호 at 2012/09/25 21:41 [edit/del]

      위 두번째 예제처럼 char나 int 혹은 short와 같이 변수들이 같은 타입끼리 연속적으로 있어야지만 패킹이
      되는 것인지 궁금합니다.
      -> 질문이 조금 잘못된 것 같은데, 같은 타입끼리 연속으로 배치해야 패딩이 들어가지 않는건지를 물어보신 거라면 답은 아니오입니다.
      char
      char
      short
      char
      char
      short
      이렇게 해도 패딩없이 구조체가 만들어집니다.

      첫번째 예제처럼 char , int, char, int로 구조체를 구성하면 왜 각각에 대해 4bytes를 차지하게 컴파일러가 명령하는지 궁금합니다.
      -> int 는 4바이트 변수 이므로 메모리의 4의 배수에 int 덩어리의 시작 부분을 놓기 위해서 char 뒤에 3바이트를 집어 넣습니다. 위에 이미지로 되어 있는 그림을 다시 한번 보시고 화살표가 가리키는 주소를 유심히 보시면 의문이 풀릴 걸로 생각이 드네요.

  3. 김준홍 at 2012/09/26 00:36 [edit/del]

    친절한 답변 너무 감사드립니다^^
    메모리 패딩에 대해 공부하려고 해도... 도저히 감이 안잡히네요 ㅠㅠ
    조금씩 순서만 바꿔도 사이즈가 달라지니까요.. ㅠ

    -----------------[A]---------------
    char a;
    int b;
    double c;
    ----------------------------------
    위 말씀해주신 예제처럼 이 순서 대로 구조체 내에 선언했을 경우 위 그림설명 처럼
    차례대로 4, 4, 8 bytes가 할당되어 16bytes 를 차지하는데요..

    순서를 조금 바꿔
    -----------------[B]---------------
    char a; // 8
    double c; // 8
    int b; // 8
    ----------------------------------
    이렇게 선언하면 24bytes가 잡히고, 또



    -----------------[C]---------------
    double c; //8
    char a;
    int b;
    ----------------------------------
    이렇게 선언하면 다시 16bytes 가 잡히네요....

    처음엔 구조체 내에서 제일 큰 기본타입의 변수를 기준으로 (위 예제에선 double 형)으로 메모리를 할당해주고,
    나머지 변수들에 대해 빈 패딩바이트를 활용하는 건줄 알았지만,,,
    꼭 그런것만이 아닌것 같다는 생각이 듭니다.

    왜 B번 예제에선 4, 8, 4 가 아니라 8,8,8 로 잡히며,
    C번 예제에선 왜 8, 4, 4 로 잡히는지 의문입니다.

    위에서 설명해주신 부분 3번은 읽었는데요...
    메모리에서 각타입에 대해 정렬된 상태로 활용하기 위함은 알지만,

    이처럼 순서에 따라 바뀌는 걸로 봐서,
    컴파일러가 코드를 읽을 때, 자신의 바로 다음 타입을 참고해서 패딩메모리 크기를 결정하는 것인지요?

    - 준홍드림.

    Reply
    • Favicon of http://www.benjaminlog.com BlogIcon 김재호 at 2012/09/26 01:51 [edit/del]

      어떻게 하면 '최소한의 패딩'으로 '모든 멤버들을 정렬'시켜(각 타입 크기의 배수의 주소에 배치시킨다는 뜻) 메모리에 올릴 수 있을지 위의 [B]와 [C] 예제를 가지고 고민해보시면 될 것 같네요.

      [B]에서는 두번째 double 타입을 8의 배수에 위치시키기 위해서 char 뒤에 7바이트를 넣을 수 밖에 없고, 세번째 int 뒤에도 4바이트 패딩을 넣어야 합니다.(B구조체가 배열로 사용될 때도 정렬을 보장하기 위해서)
      [C]에서는 double이 8을 차지했고 char가 1을 차지, 세번째 int를 정렬시키기 위해 char 뒤에 3바이트 패딩을 넣었을 꺼고, int뒤에는 패딩을 넣지 않아도 그 다음 자리가 8의 배수가 되므로 16바이트면 됩니다.

      제가 위에서 그린 것처럼 [B], [C]구조체가 배열에 들어있다 가정하고 그림을 그려보면 쉽게 이해되실꺼에요.

submit
프로 당구 선수에게 가장 굴욕적이고 부끄러운 순간이 있다면 바로 키스를 내는 일일 것이다. -아마추어 세계에서는 삑사리를 내는 것일지도 모르지만. 축구 선수에게는 알까기를 당하는 것, 농구에서는 블록킹을 당하는 순간일지도 모르겠다.

만일 프로그래머에도 이런 순간을 하나 꼽으라면 나는 버그 관리 시스템에서 이슈를 해결 처리 했는데 재등록이 되거나 그로인해 다른 버그를 유발하는 것이라 생각한다. 버그가 재등록된다는 것은 제대로 테스트 해보지 않았다는 것이고 다른 버그를 유발 시켰다면, 앞뒤 로직을 충분히 검토하지 않고 버그가 발생한 바로 그 곳만 바라보고 버그를 수정했다는 뜻이다. 부끄러워하고 반성해야 한다.
뒤돌려치기(우라마시)를 치는데 그냥 운에 맡기고 친 후 쫑이 날 수도 있는게 당연하다고 생각한다면 절대 당구 실력이 늘지 않는다. 프로그래머에게도 마찬가지라고 생각한다.

갑자기 이런 이야기가 생각이 난 것은 레이몬드 첸의 한 포스트를 읽고 나서였는데, 옛날 처음에 회사에 들어갔을 때의 내 모습이 떠올랐기 때문이다. (그냥 글을 읽는 중에 그런 일들이 떠올랐던 것 뿐, 지금 말하는 이야기가 레이몬드 첸이 말한 요지과 관련이 있는 것은 아니다.)

나는 프로그램을 디버그 하다가 널 포인터 접근 등의 예외로 프로그램이 크래시 된 것을 확인하였으면 해당 부분을

if (ptr)
{
 // *ptr을 사용
}

등으로 널 포인터 체크를 추가하여 수정하고는 이슈를 완료시키곤 했다. 하루에 버그를 10개 넘게 고친 날도 많았다.

꼭 널 포인터만의 이야기를 하는 것은 아니다. 버그가 발생한 앞뒤 로직을 충분히 점검하지 않고, 그 곳만 쳐다본채 코드를 수정하는 것에 대한 문제점을 이야기 하고 있는 것이다. 그 때 그 버그들이 정말 고쳐진 건지 아직도 모르겠다.
부작용도 많았지만, 또 어떻게 어떻게 메꾸어 내었고, 이슈 해결량이 많았기 때문에 나는 생산성이 좋다는 평가를 받았다. 지금 생각하면 부끄러운 일이다. 나는 그냥 버그를 숨겼을 뿐이다. 

언제부턴가 그런 것이 잘못된 것이라는 것을 깨닫게 되었다. 아마도 나의 스승(?)이 일을 처리하던 모습을 유심히 관찰하면서였던 것 같다.
그 이후로는 버그가 발생했을 때 항상 전후 함수들을 모두 따라가보면서 로직들을 점검하고 어디가 문제인지, 널 포인터 체크를 추가해서 버그를 해결해도 되는건지, 또는 널 포인터가 들어오게 하는 것이 잘못인지 등을 꼼꼼히 따져보고 코드를 작성하는 습관을 들이게 되었다.

이런 습관을 들인 후에는 버그가 재등록이 되거나 다른 버그를 유발하는 일이 점점 줄어갔다. 예전처럼 하루에 버그를 10개 넘게 고치지는 못하지만 지금도 여전히 생산성이 좋다는 평가를 받는다. 다시 재등록 되는 버그에 대한 작업을 할 필요가 없기 때문이다. 코드를 추가할 때마다 다른 버그가 발생해서 고치고 또 고치고 하면서 시간을 보내는 경우를 본 적이 있는가? 주위를 유심히 잘 살펴본다면, 얼마나 그런 경우가 많은지에 대해서 놀라게 될 것이다. 어쩌면 여러분 자신일지도 모른다.
하루에 버그를 1개를 고치더라도, 코드를 10줄을 작성하고 퇴근하더라도 제대로 하는 것이 더 프로젝트를 빠르게 진행하는 길이라는 것을 이제는 확실히 알고 있다.

만일 여러분이 팀장이나 프로젝트 관리자라면, 10분만에 버그를 고치는 사람에게는 칭찬을 해줄 것이 아니라, 혹시 저런 문제가 있는 것은 아닌지 잘 관찰해봐야한다. 그리고 만일 어떤식으로든 가르침을 주어 변화시킬 수 있다면 여러분 또한 멋진 스승이고 멘토이다.
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/236 관련글 쓰기

submit

파이썬 프로그래머가 자바 프로그래머보다 똑똑하다. - 위대한 해커에서
이 말을 하고 그는 전 세계의 수 많은 자바 프로그래머들에게 엄청난 욕을 먹었다.
이후에 이에 대해 약간의 변명을 하기도 했다. 변명도 재미있다. 일리있다.
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/235 관련글 쓰기

  1. 초보 at 2011/12/14 18:27 [edit/del]

    저 분이 폴그레이엄 이신가요?
    너무 멀쩡하게 생기셨는데요.

    ps. 하신 말씀에는 전적으로 동의합니다.

    Reply
    • Favicon of http://www.benjaminlog.com BlogIcon 김재호 at 2011/12/15 00:31 [edit/del]

      글 쓸 때는 아주 직설적인데 대화하는 모습을 보면 매너도 너무 좋고 푸근한 사람 같아보이더라구요. http://www.youzin.com/blog/?p=3024 이것도 한번 보세요.

submit


개발자들은 스타일에 관한 이야기를 하는 것을 좋아합니다. 이 문제는 마치 "무엇이 진정한 하나의 에디터일까"에 대한 이야기처럼 자주 입에 오르내립니다. 마치 이견이 있는 것처럼 말이죠. 답은 이맥스입니다. - Effective STL에서 컨테이너들의 범위 멤버 함수를 사용하는 것은 단일 요소 멤버 함수를 사용하는 것보다 모든 면에서 좋기 때문에 이견이 있을 수가 없다는 것을 설명하면서.
나는 비록 Vim을 더 좋아하지만 스캇 마이어스의 이 말을 듣고 이맥스를 배우고 싶다는 욕구가 미친듯이 몰려왔었던 때가 있었다. 비록 실패로 끝나고 말았지만.
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/234 관련글 쓰기

  1. Favicon of http://hisjournal.ner BlogIcon 6l4ck3y3 at 2011/12/09 13:02 [edit/del]

    답은 vim 이죠 ;)

    Reply

submit

앤드류 타넨바움이 그에게 유닉스를 다시 만들 수 있다면 무엇을 다르게 만들고 싶으냐고 질문하자
creat를 create로 바꾸고 싶다.
책을 보면서 너무 웃기긴 했는데 한참 웃다가 무슨 뜻일까 곰곰히 생각을 해봤다.
유닉스 설계는 지금 다시 봐도 세련되어서 딱히 바꾸고 싶은 것이 없다는 뜻일까, 아니면 10년이 넘는 시간이 지나도록 creat라는 작명이 다른 결정들을 다 제쳐두고 후회할만큼 계속 가슴을 후벼파서 한 말일까.

아무래도 후자라고 생각한다.
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/233 관련글 쓰기

  1. Favicon of http://barosl.com/ BlogIcon 랜덤여신 at 2011/12/19 00:29 [edit/del]

    엌ㅋㅋ 전 creat가 특이해서 괜찮던데 말이죠. 이왕 굳어진 것 한 글자라도 절약할 수 있으니 더욱 좋고요. 아버지의 생각은 좀 달랐군요.

    Reply
    • Favicon of http://www.benjaminlog.com BlogIcon 김재호 at 2011/12/19 01:44 [edit/del]

      ㅋㅋ 아버지 정말 재밌지 않나요? 타넨바움은 진지하게 물어본 걸텐데 진지하게 저런 대답을 하다니.

  2. Favicon of http://talkprogram.tistory.com BlogIcon 로로님 at 2012/01/17 00:19 [edit/del]

    ㅋㅋㅋㅋㅋㅋㅋ뿜엇네요 ㅋㅋㅋ

    Reply

submit


나는 TeX의 마지막 버그를 1985년 11월 27일 발견해서 제거했다고 믿는다. 그러나 아직도 코드 내에 약간의 버그라도 있다면 그것을 처음으로 발견해서 알려준 사람에게는 기꺼이 20.48 달러를 드리겠다. 이것은 이전 금액의 두 배이다. 나는 이 상금을 매년 두 배로 늘릴 계획이다. 나는 정말 자신이 있다.

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/232 관련글 쓰기

  1. 크누스형님 at 2011/12/05 17:22 [edit/del]

    캬아 정말 대단한 자심감이네요ㅋ 존경스럽습니다

    Reply

submit


훌륭한 프로그램을 짜려면 똑똑한 머리, 감각적인 눈, 그리고 묵직한 엉덩이가 있어야 한다. 이 규칙들은 눈과 머리만으로는 결코 이해할 수 없다. 직접 부딪혀 봐야 비로소 몸에 스며드는 것을 느낄 수 있을 것이다. - TCPL 특별판 67 페이지에서

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/231 관련글 쓰기

  1. fullc0de at 2011/12/20 23:23 [edit/del]

    오~ 이말 정말 와닿네요.. ㅎㅎ

    Reply

submit



그 해 여름 나는 단 두가지 일만 했다. '아무것도 하지 않는다.'와 '719페이지 분량의 '운영체제:디자인 및 실행'을 읽는다.' - 리눅스 그냥 재미로 에서
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

http://www.benjaminlog.com/trackback/230 관련글 쓰기

  1. kwon at 2011/12/05 20:50 [edit/del]

    새로운 카테고리가 생겼네요~~~
    단 두가지만 했다니... 멋지네요.. 부럽고 존경스러운 토발즈씨(?)~~

    Reply

submit