본문 바로가기

프로그래밍&IT/학습, 책

[클린 코드] 7. 동시성, 개선, 휴리스틱

 

Ch13. 동시성

객체는 처리의 추상화, 스레드는 일정의 추상화 - 제임스 O 코플리엔

 

  • 동시성과 깔끔한 코도는 양립하기 어렵다.
  • 이 장에선 여러 스레드를 동시에 돌리는 이유를 논한다.
  • 동시성은 결합 (coupling)을 없애는 전략. what과 when을 분리하는 전략.
  • 동시성은 다소 부하를 유발 / 복잡 / 동시성 버그는 재현하기 어렵다.
  • 구현하려면 근본적인 설계 전략을 재고해야 한다.

동시성 방어 원칙

* 단일 책임 원칙 (Single Resp0onsibility Principle, SRP)

 : 주어진 메서드/클래스/컴포넌트를 변경할 이유는 하나여야 한다 > 동시성은 복잡성 하나만으로도 분리할 이유가 충분

  • 동시성 코드는 독자적인 개발, 변경, 조율주기가 있다.
  • 독자적인 난관이 있으며 다른 코드에서 겪는 난관과 다르며 훨씬 어렵다.
  • 보호할 임계영역을 잊지 말것
  • 스레드는 가능한 독립적으로 구현
  • 각 언어가 제공하는 클래스를 검토
  • 실행 모델을 이해하라.

기본 용어

  • 한정된 자원
  • 상호 배제 (한 번에 한 스레드만 공유 자료, 자원을 사용할 수 있는 경우)
  • 기아 (Starvation) : 한 스레드나 여러 스레드가 오랫동안 혹 영원히 자원을 기다린다. 항상 짧은 스레드에게 우선순위를 준다면, 긴 스레드가 기아 상태에 빠진다.
  • 데드락 : 여러 스레드가 서로가 끝나기를 기다린다.
  • 라이브락 : 락을 거는 단계에서 각 스레드가 서로를 방해한다

실행 모델

  • 생산자-소비자 : 하나 이상 스레드가 정보를 생성해 버퍼나 큐에 넣는다. 여기서 대기열은 한정된 자원.
  • 읽기-쓰기
  • 식사하는 철학자. 여러 프로세스가 자원을 얻으려 경쟁하기에 주의하지 않으면 다양한 문제가 발생한다.
  • 동기화하는 메서드 사이에 존재하는 의존성을 이해하라. 공유 객체 하나에 메서드 하나만 사용
  • 동기화하는 부분을 작게 만들기
  • 올바른 종료 코드는 구현이 어렵다.
  • 다중 스레드를 고려하지 않은 순차 코드부터 제대로 만들자

 

Ch14. 점진적인 개선

프로그래밍은 과학보단 공예.craft에 가깝다. 깨끗한 코드를 짜려면 먼저 지저분한걸 짠뒤에 정리해야 한다

초안을 만들고 이를 계속 고쳐 최종안을 만들듯이.

 

Ch15. JUnit / Ch16. SerialDate 리팩터링 제외

 

Ch17. 냄새와 휴리스틱

  • 주석 : 부적절한 / 쓸모없는 / 중복된 / 성의없는 / 주석처리된 코드
  • 환경 : 여러 단계로 테스트하고 빌드한다.
  • 함수 : 너무 많은 인수 / 출력인수 / 죽은 함수
  • 일반 : 한 소스 파일내 다양한 언어를 지원하는데, 이상적으론 파일 하나에 언어 하나만 사용하는 방식이 좋다 / 당연한 동작을 구현
  •  추상화 수준을 올바르게. 모든 저차원 개념은 파생클래스에 넣고 모든 고차원 개념은 기초 클래스에 넣는다. 기초 클래스는 구현 정보에 무지해야 한다 / 기초 클래스가 파생 클래스에 의존하지 않도록 / 과도한 정보 / 부적절한 static 함수 / if - else 나 switch - case 보단 다형성을 사용하라 / 조건을 캡슐화 / 부정조건은 피하라. if(!IsOK()) -> if (IsOK) / 함수는 한 가지만 해야 한다 / 함수는 추상화 수준을 한 단계만 내려가야 한다 / 설정정보는 최상위 단계에 둬라 / 상수는 상속하지 않는다
  • 이름 : 서술적인 이름. a1, a2같은거 쓰지 말라는 / 적절한 추상화 수준에서 이름을 선택.
  • 테스트 : 불충분한 테스트 / 실패패턴 살피기

 

휴리스틱?

  • 문제를 해결하거나 결정을 내릴 때 사용하는 경험적인 방법이나 전략을 의미.
  • 정확하거나 최적의 답을 보장하지는 않지만, 제한된 시간과 자원 내에서 현실적이고 실용적인 해결책을 빠르게 찾을 수 있도록 도와준다