기본 콘텐츠로 건너뛰기

4월, 2007의 게시물 표시

The Joel Test: 나은 코딩을 위한 12단계 - 06/07/27 14:00

The Joel Test: 나은 코딩을 위한 12단계   -   06/07/27 14:00 글 : Joel Spolsky 번역 : B.K. Chung 정봉겸 감수 : Jang Han Goo 구장한 2000년 8월 9일 SEMA 에 대해서 들어보신 적이 있습니까? 소프트웨어 팀이 얼마나 잘하는지를 재는 나름대로 복잡한 시스템입니다. 앗, 아니! 그 링크를 누르지 마세요. SEMA를 "이해"만 하는데 아마 6년정도가 걸릴것입니다. 그래서 소프트웨어 팀이 얼마나 좋은지 등급을 매길 수 있는 - 좀 무책임하고 되는대로의 - 자체적인 버젼의 테스트를 만들었습니다. 이 테스트의 장점은 3분정도밖에 걸리지 않는다는 것입니다. 절약되는 시간으로 의대에 가서 공부할 수도 있을 것입니다. The Joel Test                    Source Control(소스 컨트롤)을 사용하십니까? 한번에 빌드를 만들어낼 수 있습니까? daily build(일별 빌드)를 만드십니까? 버그 데이타베이스를 가지고 있습니까? 새로운 코드를 작성하기 전에 버그들을 잡습니까? up-to-date(최신) 스케줄을 가지고 있습니까? spec(설계서)를 가지고 있습니까? 프로그래머들이 조용한 작업환경을 가지고 있습니까? 돈이 허락하는 한도내의 최고의 툴들을 사용하고 있습니까? 테스터들을 고용하고 있습니까? 신입사원들은

++ 숙련공에서 마스터로 - 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플랫폼은

rule of three (세 법칙)

Accelerated C++에서 발췌 (페이지 315~316) 클래스 T의 객체에 대한 모든 복사본이 제대로 처리되도록 하려면, 다음과 같은 것들이 필요하다. T::T() //하나 또는 그 이상의 생성자, 인자를 가질 수도 있음. T::~T() //소멸자 T::T(const T&) //복사생성자 T::operator=(const T&) //대입연산자 일단, 이러한 연산들을 정의했다면, 컴파일러는 각 타입의 객체가 생성되고, 복사되고, 대입되고, 소멸될 때마다 그것들을 사용하게 된다. 객체는 암묵적으로 생성되고, 복사되고, 소멸될 수 있다는 것을 명심해야 한다. 묵시적으로든 명시적으로든, 컴파일러는 적합한 연산을 호출할 것이다. 복사 생성자, 소멸자 및 대입 연산자는 밀접하게 연관되어 있기 때문에, 그들 간의 관계는 세 법칙(rule of three) 이라고 알려져 있다. 만약 여러분의 클래스에 소멸자가 필요하다면, 아마 복사 생성자와 대입 연산자도 필요할 것이다. 예) T::T(const T& rhs) { ... ///< do something } T& T::operator=(const T& rhs) { if(this != &rhs) { ... ///< do something } return *this; }

일일 빌드 수행하기

우선 아래의 배치파일을 이용해서 빌더시의 날짜와 시간을 구합니다. @ECHO OFF @TITLE Backing up source safe databases FOR /F "tokens=2-4 delims=/ " %%i IN ('date /t') DO SET DATE=%%i-%%j-%%k FOR /F "tokens=1-3 delims=: " %%i IN ('time /t') DO SET TIME=%%i-%%j-%%k SET DATETIME=%DATE%-%TIME% 출처 : http://www.codeproject.com/tips/autovssbackup.asp 배치파일로 안되는게 없구만... 그 다음으로 빌드용 배치파일을 예를 들어 아래와 같이 작성합니다. call datetime.bat VC6.0일 경우 : msdev "Admin\Admin.dsw" /MAKE "Admin - Win32 Release" /REBUILD >> "Batch_Build_Result\Admin(%datetime%).log" 여러가지 빌드 옵션들: Win32 Debug Win32 Unicode Debug Win32 Release MinSize Win32 Release MinDependency Win32 Unicode Release MinSize Win32 Unicode Release MinDependency .NET 2003일 경우 : SET DEVENV="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe" %DEVENV% /rebuild release &qu

메모리 릭을 제거 하자 ( 펌 )

에스카플로네 | 에스카 http://blog.naver.com/redkain/70006086810 릭을 제거 하자 #1 프로그램을 개발 하면서 많은 어려움 중에 하나가 메모리 릭을 찾는 문제라 생각이 됩니다. 특히 필자는 메모리 릭 조차 해결 안하고, 필드로 출시했던 경험들도 있는데요.. 물론 사용에 문제는 없었습니다... 하지만,,, 정말루 정말루 이제는 이러면 안된다고 생각합니다.. 철든거 같습니다 ⌒⌒ 본 컬럼에서는 Microsoft Visual Studio .NET에서 제공하는 강력한 릭 찾는 디버깅 팁 몃가지를 설명합니다. 먼저 예제 작성을 하겠습니다. 비주얼 스트디오 2003을 실행시킨후에 새프로젝트를 클릭해주세요. Win32 콘솔 프로젝트를 선택후 확인 버튼을 클릭합니다. 기본 소스에서 메모리 릭을 표시하기 위하여, 몃 가지 작업이 필요합니다. MFC 사용이나 MFC 프로젝트 이용시에는 아래 설정이 필요하지 않습니다. 아래 설정은 출력창에 메모리릭이 발생했을 경우 표시하여 주는 기능을 합니다. 아래 헤더와 Define을 추가합니다. 반드시 순서를 지켜야합니다. #define CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> 덤프를 보고자하는 위치에서 아래 함수를 호출합니다. 아래 함수는 메모리릭이 발생한 위치를 덤프하여, 출력창에 표시합니다. _CrtDumpMemoryLeaks(); 아래는 완성된 전체 예제 입니다. #include "stdafx.h" // 아래 헤더가 추가 되었습니다. #define CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> void alloc() { // 여기서 메모리를 할당하고, free를 하지 않아 메모리 릭을 유발 합니다.

신입 개발자를 위한 CRT 이야기

VECTOR SPACE | vector3 http://blog.naver.com/vector3/60036721563 신입 개발자를 위한 CRT 이야기 신영진 pop@jiniya.net CRT란 C Runtime Library를 말한다. C Runtime Library란 각종 C언어의 표준 함수들을 포함하고 있는 거대한 라이브러리다. printf, scanf, atoi, fgets등의 C언어를 처음 익힐 때 배웠던 함수들이 이 라이브러리에 모두 포함되어 있다. 기본적으로 Visual C++에는 총 세 가지 종류의 CRT가 포함되어 있다. 단일 스레드(ML), 다중 스레드(MT), 다중 스레드 DLL(MD)이 그것이다. 이 세 가지도 각각 릴리즈 버전과 디버그 버전이 존재하기 때문에 정확하게는 총 여섯 가지가 있는 셈이다. 동일한 함수를 구현하고 있는 라이브러리를 여섯 가지나 만들어둔 이유는 베스킨라빈스에 아이스크림이 서른 가지가 넘게 있는 이유와 동일하다. 그때그때 상황에 맞게 골라서 쓰기 위해서이다. 당연히 베스킨라빈스의 아이스크림이 모두 맛이 틀리듯이 이 CRT들도 종류에 따라서 미묘한 차이가 있다. <표 1>에는 각 CRT의 종류별 특징이 나와있다. 디버그 CRT의 경우는 ASSERT 경고문이 포함되어 컴파일 되었다는 특징을 추가적으로 가지고 있다. 표 1 CRT 종류별 특징 CRT 라이브러리 특징 단일 스레드 libc.lib 단일 스레드 전용으로 설계된 CRT 다 . 멀티 스레드에 비해서 빠르다 . 이 스레드에 포함된 일부 함수들은 멀티 스레드에서는 정상적으로 동작하지 않는다 . Visual Studio 2005 부터는 더 이상 단일 스레드 CRT 를 지원하지 않는다 . 멀티 스레드 libcm

Preventing AutoCAD from entering a zero doc state

Preventing AutoCAD from entering a zero doc state Published date: 2005-03-04 ID: TS46546 Applies to: AutoCAD® 2005 Issue How do I prevent AutoCAD from entering a zero document state? Solution When AutoCAD is in a zero document state, you have very limited access to AutoCAD's functionality. In addtion, there are additional complications. One straightforward method of solving this problem is to prevent AutoCAD from entering the zero document state. You can plant an AcApDocManagerReactor and override documentToBeDestroyed(), and call AcApDocManager::appContextNewDocument{}. But this combination will not work because using document manipulation functions within a reactor callback is unsafe. You cannot determine what state AutoCAD is in. A workaround, is to install a timer. Make a reasonable estimate about how long it will take AutoCAD to close a drawing, then set the timer accordingly. Within the timer callback function, you can safely create a new drawing.The fol

CSaveStatus

대화상자에서 작업을 하다 AutoCAD에서 작업을 하기 위해 포커스를 AutoCAD에 주고 AutoCAD에서의 작업이 끝이나면 다시 포커스를 대화상자에 주는 식의 코딩을 합니다. 물론 대화상자는 모달리스형식으로 생성을 해야되겠죠. 아래와 같은 대략적인 코드가 될것입니다. m_bFocus = FALSE; .... /// AutoCAD에서의 작업 m_bFocus = TRUE; 일반적으로 위는 잘 작동합니다. 하지만 코드 중간에서(AutoCAD에서의 작업) 함수를 빠져나가는 부분이 있다면 그 부분마다 m_bFocus = TRUE라는 코드를 삽입해줘야 합니다. 이 얼마나 지저분하고 손이 많이 가는 작업입니까? 피곤할 노릇이죠. 그래서 클래스로 m_bFocus의 값을 저장해 두었다가 함수를 빠져 나갈때 즉 클래스의 소멸자에서 m_bFocus에 저장해 두었던 값을 되돌려주는 클래스 를 만들게 되었습니다. template<class T> class CSaveStatus { CSaveStatus(const CSaveStatus<T>&){} public: CSaveStatus(T& t) : unnamed(t) { value = t; } CSaveStatus<T>::~CSaveStatus() { unnamed = value; } private: T& unnamed; T value; };

CDocData

CDocData는 objectarx wizard로 프로젝트를 생성하면 자동으로 생성해주는 클래스입니다. 일반적으로 프로그래밍에서 Document에 연관된 데이터를 유지 관리하는데 사용합니다. 지금 진행중인 프로젝트에서 AutoCAD가 불규칙적으로 강제 종료가 되는 현상이 발견되고 있었습니다.(몇년전부터 쭉 진행중인 프로젝트라...) 도대체 아무리 코드를 뒤져봐도 그 원인을 파악할 수가 없었습니다. 이 프로젝트는 회사내부에서 사용하기 위해 진행중인 프로젝트라 이 문제를 눈감고 지나쳤습니다. 제가 만든 프로그램으로 사용자의 불만은 있었지만(프로그램이 불안정하다) 그럭저럭 2개의 프로젝트를 진행했습니다. 이 번에 다시 프로그램을 업데이트 할 일이 생겨서 지난번에 지나쳤던 문제를 해결하리라 마음먹고 이틀의 시간을 버그를 수정하는데 할애를 했습니다. ADSN의 글을 읽는동안 CDocData는 map에서 관리하고 있는데 이것은 내부적으로 STL의 Tree형식으로 데이트를 관리합니다. 그래서 Tree의 밸런스를 맞추기 위해 데이터를 복사를 해서 Tree의 균형을 맞춘다고 합니다. 그러니 CDocData는 복사 생성자를 지원했어야 했습니다. 저의 CDocData 클래스는 복사 생성자도 지원하지 않고 소멸자에서 열심히 메모리 할당한 멤버 변수들을 열심히 메모리 해제를 하고 있었습니다. 그러니 어떻게 되겠습니까? 최종적으로 Tree에 생기는 CDocData의 포인터 멤버변수는 쓰레기 값을 가리키게 되고 이것을 가져다 쓰는곳에서는 필연적으로 에러가 발생될것입니다. 위의 원인은 제가 C++ 프로그래밍을 할때 기본적으로 지켜야할 원칙을 지키지 않았기 때문에 발생한 문제입니다. 클래스에는 기본적으로 복사 생성자를 만들어 줘야 합니다. 그렇게 하고 싶지 않으면 복사생성자를 protected나 private으로 정의해서 원칙적으로 클래스 복사가 되는것을 막아줘야 합니다.

자동 업데이트

도프텍과 P&ID 프로젝트를 수행중이다. 나와 도프텍의 프로그래머는 프로젝트를 수행하는 사람들이 사용할 프로그램 작성을 맡고 있다. 도프텍에서 전화상으로 기능을 요구하면 그 기능을 구현하여 프로젝트 게시판에다 간단한 업데이트 사항과 함께 프로그램을 올려두고 다시 전화로 프로그램이 업데이트 되었다고 알리고 설치하도록 한다. 이런 절차로 프로그램을 작성하고 있는데, 현재 프로젝트 특성상 기간이 너무 촉박해 하루에도 몇번씩 프로그램 업데이트 요구가 들어 오고 있다. 매번 프로그램을 수정하여 게시판에 올리고 전화로 알려주는것은 너무 번거러웠다. 또 이런 방식의 문제는 일반 사용자들이 업데이트를 제대로 하지 않는다는 것이다. 그리고선 프로그램이 제대로 작동하지 않는다고 불평을 하기 시작한다. 이런 프로그램의 업데이트 절차를 줄이기 위하여 자동 업데이트 기능을 프로그램에 넣기로 결정하고 인터넷을 뒤져 몇개의 소스를 구한뒤 그들을 결합하여 초간단 자동 업데이트를 만들었다. 이렇게 함으로써 프로그램을 업데이트하는 수고를 조금이라도 덜수 있지 않을까 생각한다. <프로그램 동작 설명> 서버에서 업데이트 항목을 적은 xml 파일을 다운로드한다. <updates> <package version="1.1.1.2"> <files src="" dest="" message=""></files> ... </package> <package version="1.1.1.1"> </package> </updates> install된 package의 버전을 구한다.  이런 구조를 사용해서 install된 package보다 버전이 높은 p

HTTP를 이용한 File DownLoad

난 언젠간 이 나라를 떠날거다.. | 축복 http://blog.naver.com/maxpayne909/60035555909 Http프로토콜을 이용한 파일 다운로드 //-------------------------------------------------------------------------------------// // Function : GetFile // Parameter: LPCTSTR url, LPCTSTR filename // Return : CString // - 성공하면 "YES" 실패하면 에러메시지를 반환 // Note : url의 파일을 받아서 filename에 저장한다. // LPCTSTR url - http프로토콜을 이용해 받아올 파일의 전체경로 // LPCTSTR filename - 파일을 저장할 local경로 //-------------------------------------------------------------------------------------// CString CInternetImageCtrl::GetFile(LPCTSTR url, LPCTSTR filename) { HINTERNET hInternet, hURL; // 연결 hInternet = InternetOpen( L"HTTPFILE", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if ( hInternet == NULL ) return L"인터넷이 연결되어 있지 않습니다."; // url hURL = InternetOpenUrl( hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0); if ( hURL==NULL ) { InternetClos

How to remove anonymous groups with ARX?

Published date: 2005-02-08 ID: TS27355 Applies to: AutoCAD® 2005 Issue How do I remove anonymous groups from my drawing using ObjectARX? Solution When an end user creates a 'group' in AutoCAD, it may be an anynonmus group. However, all group (anonymous or otherwise) are stored in the Named Objects Dictionary under the key 'ACAD_GROUP'. If the group is anonymous, AutoCAD assigns it a value such as '*A1', '*A2' and so on. Although to the end user it's anonymous, the goup has a unique key name in the AutoCAD database. Users may add or remove entities from groups so it is possible to have empty groups. To remove an anonyomus group, consider the following code fragment - rmvAnonGrp(). Before running the code given below, creat few unnamed groups(anonymous groups). // Remove anonymous groups. // Note: No error cheking in following code void rmvAnonGrps() { // TODO: Implement the command Acad::ErrorStatus es; AcDbDictionary *

AcDbSmartObject

엔터티의 속성을 변경하고자 할 경우, 엔터티를 AcDb::kForWrite로 열어서 속성을 변경시킵니다. 하지만 막상 도큐먼터를 락걸지 않고 여는 바람에 autocad가 에러를 내며 튕겨버립니다. 이런 현상을 프로그램을 실행시켜보아야만 락을 걸지 않고 열었다는 것을 알게 됩니다. 자주 이런 실수를 되풀이 해서 겪다보니 조그마한 클래스를 하나 만들었습니다. 생성자 인자로 열기 모드를 받아 쓰기모드이면 도큐먼트를 락겁니다. 소멸자에서는 쓰기모드로 연 엔터티일 경우에 락을 해제하고, 엔터티를 닫아 줍니다. #ifndef __ACDB_SMART_OBJECT_H__ #define __ACDB_SMART_OBJECT_H__ ////////////////////////////////////////////////////////////////////////// #define USES_OKEYS Acad::ErrorStatus __es #define ARXOK(what) if ( (__es =(what)) != Acad::eOk ) throw acadErrorStatusText (__es) #define ARXNULL(what) if ( (what) == NULL ) throw "" #define ARXCLOSE(what) if ( what != NULL && what->objectId () != AcDbObjectId::kNull ) { what->close () ; }\ else if ( what != NULL ) { delete what ; what =NULL ; } #define ARXERROR(msg) acutPrintf("%s/%d : %s\n",__FILE__,__LINE__,msg); template<class T> class AcDbSmartObject { public: explicit AcDbSmartObject(const AcDbObjec

intersect ellipse with line

(1) 일반적인 타원의 방정식 = $\frac{(x - h)^2}{m} + \frac{(y - k)^2}{n} = 1$ (2) 선의 방정식 = $y = sx + t$ (2)의 식을 (1)에 대입하여 풀면 $$ x^2(n+ ms^2) + x(2sm(t-k)-2hn) + ((h^2-m)n + m(t-k)^2) = 0 $$ 이것은 2차 방정식이 된다. 이차 방정식은 근의 공식을 통하여 풀이가 가능한데.. $(n+ ms^2)$를 a로 두고 , $(2sm(t-k)-2hn)$를 b로 두고 $((h^2-m)n + m(t-k)^2$를 c로 두면 x의 값은 아래와 같이 구할 수 있다. 근의 부호 판별($sqrt(b^2 – 4ac)$)을 통하여 교차점이 두개가 있는지 혹은 하나 인지 혹은 교차하지 않는지 판별할 수 있다.

[공유] 사원수(Quaternion)

출처 What Can I Do For U? | happypcb 원문 https://blog.naver.com/happypcb/90005534378 Quaternion 개발관련/수학 2006/04/01 11:54 쿼터니언(사원수). 이 놈을 제대로 알지도 못하면서 너무 오랫동안 써왔다. 오일러각 표현 처럼 짐벌락 문제가 없기 때문에 캐릭터 애니메이션 부터 아크볼까지 많은 부분에서 사용되는 사원수. 단지 회전축과 회전량을 표현한다는 것만 알고 있었을 뿐 D3DX 에서 제공하는 함수들만 사용하면서 그냥 그런 블랙박스였다. -_-; 이렇게 원리를 모르고 사용하는 것에 대한 문제점은, 단지 정형화된 사용법에만 익숙해지고 새로운 응용법이나 약간만 꼬아놓아도 이해를 하지 못한다는 것이다. 이렇게 얇팍해서는 안된다. 최근에 이것저것 공부하면서 이제서야 사원수에 대해서 조금 알 것 같은데 간단하게 여기에다가 정리해 보도록 한다. 사원수의 연산 및 성질 등등은 인터넷이나 각종 책을 찾아보면 너무 잘 나와있으므로 생략하고, 도대체 사원수가 기하학적으로 무슨 뜻인지. 어떻게 회전이 일어나는 것인지에 대해 의미론적으로 혼자 정리해봤다. 일단 사원수는 다음과 같이 정의된다. 식(1) $$Q = q_0 + q_1*i + q_2*j + q_3*k$$ 위의 정의에서 i, j, k 는 허수이고 $q_0~q_3$ 는 실수이다. 즉, 허수부 3개와 실수부 1개로 이루어져 있다. 이것은 기하학적으로, Q가 단위 사원수 일때(Q 의 $q_0~q_3$ 으로 이루어진 벡터의 길이가 1) 다음과 같이 표현할 수 있다. 식(2) $$Q = sin(theta)*U + cos(theta)$$ 자아, 과연 식(1) 과 식(2) 모두 쿼터니언을 표현하는 거라는데 두 개가 겉보기엔 전혀 틀리구만 도대체 뭐가 같다는 걸까. 내가 헷갈렸던.. 식(2) 에서 U 는 벡터를 의미한다. 무슨 벡터인가 하면 사원수 Q로 어떤 점을 회전 변환 시킬 때 회전 축이 되는 단위