728x90
오랜 시간이 걸리는 새로운 일과 마주치면?
1. 맨손으로 힘들여 노가다를 한다.
2. 스크립트 언어를 이용해서 그 일을 자동으로 수행하는 툴을 작성한다.
3. 이미 작성되어 있는 툴을 찾기위해 여러 시간을 보낸다.
=== 잠깐동안 툴을 찾아보고 없으면 더이상 미련을 가지지 말고 간단히 스크립트 언어로 자동 수행 환경을 만들도록 하자.

새로운 툴을 발견하면?
원하는 만큼 알게될 때까지 만지작 거리지 말고 관련 문서를 정확하게 읽어보자.
읽으라고 친절히 설명서까지 만들어놨는데 쳐다보지도 않고 혼자 만지작 거리면서 모르겠다고 투정부리는 일은 하지말자.

툴에 구애받지 않는 실력을 가지는 것도 중요하지만 세상에는 툴이 엄청 많다. 똑똑한 툴을 잘 다루는 프로그래머는 더 똑똑한 프로그래머가 된다. C코드를 툴을 사용하지 않고 어셈블리어로 변환하는 사람이 있다면 정신과 상담이 필요하다.

* 어떠한 툴 들이 있는지 알아보고 어디서 구할 수 있는지 확인해보자. 지금 사용하지 않더라도 충분한 보험이 될 수 있다.

툴의 사용법
* 툴로 무엇을 할 수 있는지 알아둬라.
* 어떻게 조종하는지 배워라.
* 어떤 일에 좋은지 알아둬라. (어떤 일을 할 때 사용하면 유용한지)
* 어떤 문제점을 가지고 있는 확인하라.
* 더 많은 툴을 찾을 분명한 루트를 확보하라.
    메뉴얼, 릴리즈 노트, 온라인 지원, 툴 내부의 도움말 파일, man 페이지 등
* 새로운 버젼이 언제 나오는지 알아내라. (최신 버젼이 무조건 좋은 것은 아니다)
===== 하지만 지금 당장 할 일은 툴들의 정보를 공유하는 커뮤니티를 찾는 것일지도

소스코드 편집용 에디터를 선택할 때의 팁
* 포괄적인 문법 컬러링(여러 언어를 지원)
* 간단한 문법 체킹(강력하면 더 좋겠지만)
* 우수한 검색 / 변환 (찾기, 바꾸기 등이 앞뒤로 가능하도록)
* 키보드 매크로 기능(꽤 유용하다)
* 원하는 플랫폼에서 작동하는지(유닉스, 윈도우계열 등 작업환경에서 돌아가야 한다)

TIP 유닉스 계열에서 사용하는 소스 조작 툴
diff : 두 파일을 비교, 서로 다른 부분을 하이라이트 표시
sed : stream editor; 한줄씩 읽어서 변환하는 것을 원칙으로 하는 툴, 항목의 재정렬이나 global 검색이나 치환, 혹은 행 안에 패턴을 삽입할 때도 사용
awk : sed와 비슷한데 이건 text file을 대상으로 작업한다.
grep : 파일 내의 문자패턴을 검색
find/locate : 파일을 찾는다. 이름, 날짜, 그 밖의 기준을 가지고 검색
wc : 단어와 문자를 세는 일을 한다
sort : 원하는 정렬 기준에 맞추어 재정렬한다
paste, join, cut 등 유용한 것들 꽤 많다. 유닉스의 기본 철칙은 작은 툴들이 모여서 큰 작업을 한다는 것이다.

좋은 프로그래머
* 지루한 일을 반복하기 보다는 적절한 툴의 사용 방법을 배우려고 한다.
* 여러가지 toolchain의 모델을 알아두고, 각각을 힘들지 않게 사용할 수 있도록 한다.
* 편의를 위해 툴을 사용하지만 툴의 노예가 되진 않는다.
* 사용하는 모든 것을 교체 가능한 유용한 도구(툴)로 본다

나쁜 프로그래머
* 몇가지 툴의 사용법을 알고있지만, 모든 문제를 툴에 맞추어 생각하려고 한다.
* 새로운 툴을 배우기 위해 시간내는 것을 꺼려한다.(익숙한 것만 하려고 든다.)
* 어떤 개발환경을 사용하기 시작하면, 그것을 종교처럼 받들고 절대 다른 것의 사용을 시도하려고 들지 않는다.
* 가치있는 새로운 툴을 발견해도 자신의 툴박스에 추가하지 않는다.
728x90
728x90

에러나 예외를 일으킬 때 주의
* 청소는 했는가? - 리소스 누출(동적할당 등), 자료들의 모순상태 등을 확인. 어쩔 수 없이 제대로 청소되지 않는 상황이라면 반드시 기록을 남겨둬야 한다.
* 에러정보에 부적절한 내용을 담지 마라
* 올바른 exception을 사용 - 에러나 예외가 아닌 특이한 값을 return하지 마라. 즉 올바른 자료랑 예외상황을 섞어서 사용하지 말란 말이다.
* 정상적인 실행과정 중 절대 일어나지 말아야 할 진짜 프로그래밍 에러를 잡으려고 한다면 assertion의 사용을 고려해보라. 하지만 assertion은 완성본에 남아있으면 안된다. exception을 활용하는 것이 더 나을수도 있다.
* 사람들이 무시하지 않도록 만들어라.

일반적인 에러 체크 목록
* 함수의 모든 파라미터를 체크
* 관심 있는 실행 지점에서 불변조건(invariant)이 만족하는지 검사
* 외부에서 들어온 값은 사용하기 전에 모두 유효성 검사를 해라. 특히 파일로부터 얻어오는 자료와 사용자가 입력하는 자료는 유효성검사가 꽤 중요하다.
* 시스템 호출과 함수 호출에 있어서는 가능한 모든 호출에 대해서 리턴 상태를 체크

에러 관리하기
* 에러의 원인이 될만한 일은 피해라 - 리소스 할당 에러는 충분한 리소스를 미리 예약(pool)하면 피할 수 있다.
* 프로그램이나 루틴이 비정상적인 상황에서 어떤 동작을 할 것이 예상되는지 정하라(GIGO: Garbage In Garbage Out)
* 자신의 프로그래밍 습관을 체크 : 에러 처리 코드를 나중으로 미루지 마라.

실패 가능성이 있는 코드를 작성할 때는 에러 감지 코드와 에러 치리 코드도 함께 작성하라.

728x90
728x90

에러 처리하기

에러를 처리하기 전에 알아야 하는 것들:
* 에러가 어디서 나왔는가
* 당신을 무엇을 하려 했는가(무엇을 하다가 에러가 발생했는가)
* 일이 왜 잘못 되었나
* 에러가 언제 일어났나
* 에러의 심각성
* 에러를 고치는 방법

에러를 발견했을 때
1. logging (로그기록)
2. report(보고) (임베디드의 경우 보고대신 스스로 처리해야 할 때도 있다)
3. recovery(복구)
3. ignore(무시)
4. propagate(전파) : # 똑같은 에러정보를 전파, # 재해석 후 새로운 메시지를 전파

코드구현 테크닉



728x90
728x90

오류의 발생은 원인에 따라 세가지로 요약할 수 있다.
사용자 에러 : 정확히 다 잡기가 어려워 배포 후에도 발생할 수 있다.
프로그래머 에러 : 나와서는 안되는 에러
예외상황 : 프로그래머가 정상적으로 작성했고 사용자도 정상적으로 사용했다. 하지만 네트워크 연결이 이상할 수도 있고, 하드디스크나 메모리에 용량이 부족할 수도 있고 갑자기 전원이 나갈 수도 있다.

에러를 처리하는데 중요한 몇가지를 먼저 알아보자.
1. 발생은 하위 콤포넌트, 처리는 호출자(caller) : 즉 누군가 일을 잘못하면 시킨 사람이 책임진다는 뜻이다.
2. 잘못이 있을 때는 에러를 발생시켜야 한다.(그냥 뻗도록 해서는 안된다.)
3. 보고도리 수 있는 모든 에러를 감지한다.
4. 감지된 에러를 적절하게 처리한다.
5. 처리할 수 없는 에러는 다른 곳으로 전파한다.
에러 처리는 exception 처리와 거의 같게 취급하면 될 것 같다.

에러 리포트 메커니즘 ( 오류를 알리기 위한 방법 )
1. return값 : return되는 값이 boolean으로 함수의 성공, 실패를 알려주는 용도라면 적당하게 작동한다. 단, 에러의 종류는 알 수 없다. return 값이 필요한 함수에서 오류도 함께 return의 값으로 알려주려고 시도하는 경우도 있다. 가능은 하지만 권장하지 않는다. 그래도 꼭 해야 하겠다면 몇가지 방법이 있다.
  * return값을 좀더 복잡하게 만들어 원하는 결과와 오류정보를 둘다 가지고 있는 구조체나 객체를 return하는 방법 : 네트워크에선 가끔 이용되지만 일반적인 프로그래밍에선 사용되는 경우가 거의 없다.
  * 참조(reference)를 이용하여 파라미터를 통해 보내는 방법 : 이또한 보기에도 좋지 않고 직관적이지도 않다.
  * 오류의 범위를 지정 : return값이 0이상의 값만 의미가 있을 때(count등) 음수를 오류로 처리하거나 참조나 포인터일 경우 NULL을 에러로 처리하는 것이 가능하다.
어떤 방법을 사용하건 지저분해진다. 에러를 발생시키는 것도 어렵지만 처리도 지저분해진다.

2. 에러 상태 변수 : 특수한 값들을 에러로 define해놓는 방법이다. C언어에서 가끔 사용되는데 결국 이런 것도 전역으로 사용되며 프로그램이 실행되는 동안 내내 메모리에 올라가 있는 값이기 때문에 많으면 좋지 않다. 게다가 파일이 여러개면 제대로 확인하기도 어렵다.

3. exception(예외처리)
에러처리를 위해 만들어진 구문으로 throw-catch, throws구문을 이용하여 에러를 handler에게 보내는 방법이다. 에러처리 전문 문법이기 때문에 가장 깔끔하고 직관적이지만 모든 언어에서 지원해주는 것은 아니다. C언어에는 없고, C++, JAVA, .NET등에는 있다.
 * 종결모델(termination model) : 헨들러가 처리한 부분부터 다시 실행(C++, .NET, JAVA)
 * 재개모델(resumption model) : 오류가 발생한 부분으로 돌아가서 다시 실행
예외처리는 안전성에 몇가지 단계가 있다.
==== 기초보장(basic guarantee)
   exception이 발생해도 메모리 누수가 없도록 해야한다. 동적 할당을 받았다면 반드시 확인해보자.
==== 강력한 보장(strong guarantee)
   exception이 발생해도 프로그램의 상태는 아무것도 바뀌면 안된다. 전역변수도, 지역변수도 객체도 그 값을 그대로 유지하고 있어야 한다.
==== no throw(nothrow guarantee)
   operation이 exception을 던질 수 없도록 만든다. 3가지 보장 중 가장 강력한 방침인데 예외상황을 발생시키지 않는다. 가장 중요한 것은 소멸자에서 exception을 던지지 않는다는 보장이 있어야 한다는 것인데 객체지향언어에서 소멸자는 객체의 생명이 다할 때 자동으로 호출되며 exception이 발생했을 때도 스택이 풀리면서 호출된다. (C#에서는 소멸자에서 exception을 던지는 것이 의미가 있으며 그것을 인정한다)

4. signal
극단적인 에러 리포트 메커니즘으로 전기 신호로 에러를 발생시키고 시그널 핸들러를 설치해야 한다.

=======================================================================
exception을 무시하더라도 감지하는 코드는 만들어둬야 한다.
그래야 나중에 코드를 봤을 때 exception의 가능성이 있다는 것을 알 수 있다.
=======================================================================

728x90

+ Recent posts