클린코드 46

클린 코드 독서일지 - Day 47 (完)

다중 스레드 코드 테스트 다중 스레드 코드에서 버그가 있다는 사실을 증명하는 테스트 케이스는 짜기 어렵다. => 동시 갱신 문제가 발생하는 문제는 너무 드물게 발생해서 대개는 테스트로 발견하지 못함. 테스트로 버그를 더 잘 찾아내기 위한 아이디어들 몬테 카를로 테스트 : 테스트로 버그를 더 잘 찾아내기 위한 아이디어. 조율이 가능하게 유연한 테스트를 만든 후 임의로 값을 조율하면서 반복해 돌린다. 시스템을 배치할 플랫폼 전부에서 테스트를 반복해서 돌린다. 부하가 변하는 장비에서 테스트를 돌린다. 그러나 위의 조치를 취하더라도 코드에서 스레드 문제를 찾아낼 가능성은 매우 낮음 스레드 코드 테스트를 도와주는 도구 IBM의 ConTest : 스레드 코드에 보조 코드를 더해 실패할 가능성을 높여주는 도구. 스레..

클린 코드 독서일지 - Day 46

작업 처리량 높이기 URL 목록을 받아 네트워크에 연결한 다음 각 페이지를 읽어오고 분석하여 통계 보고서를 출력하는 코드를 짠다고 가정. 작업 처리량 계산 - 단일스레드 환경 편의상 다음과 같이 가정 페이지를 읽어오는 평균 I/O 시간 1초 페이지를 분석하는 평균 처리 시간 0.5초 처리는 CPU를 100% 사용하고 I/O는 0% 사용 => 스레드 하나가 N페이지를 처리하면 총 실행 시간은 1.5초*N 작업 처리량 계산 - 다중 스레드 환경 여러 스레드를 사용하면 프로세서를 사용하는 페이지 분석과 I/O를 사용하는 페이지 읽기를 겹쳐 실행할 수 있음 => 단일스레드의 세 배의 처리율로 처리 가능 데드락 다음 네 가지 조건을 모두 만족하면 데드락이 발생 상호 배제 : 여러 스레드가 한 자원을 공유하나 그 ..

클린 코드 독서일지 - Day 45

라이브러리를 이해하라 Executor 프레임워크 애플리케이션에서 스레드를 사용할 때 Executor 클래스를 고려하면 좋다. Executor 프레임워크는 스레드 풀을 관리하고 풀 크기를 자동으로 조정하며 필요하다면 스레드를 재사용함. Future도 지원 -> 독립적인 연산 여럿을 실행한 후 모두가 끝나는 것을 기다릴 때 유용 스레드를 차단하지 않는 방법(논 블로킹) 최신 프로세서는 차단하지 않고도 안정적으로 값을 갱신함 => 흔히 CAS라 불리는 연산 덕분(데이터베이스 분야에서 낙관적 잠금이라는 개념과 유사) synchronized 키워드가 언제나 락을 거는 것과 다르게, CAS 연산은 스레드가 같은 값을 수정해 문제를 일으킬 때를 감지하여 이럴 경우에만 갱신이 성공할 때까지 재차 시도함 ⇒ 락을 거는 ..

클린 코드 독서일지 - Day 44

가능한 실행 경로 다음의 incrementValue 메서드가 있는 IdGenerator 클래스가 있다고 하자. public class IdGenerator { int lastIdUsed; public int incrementValue() { return ++lastIdUsed; } } 스레드 하나가 IdGenerator 인스턴스 하나를 사용한다고 가정하면 가능한 실행 경로+결과는 하나다. 하지만 만약 IdGenerator 인스턴스를 스레드 두 개가 호출한다면 다음 결과들이 모두 가능하다. 스레드 1이 94를 얻고, 스레드 2가 95를 얻고, lastIdUsed가 95가 됨 스레드 1이 95를 얻고, 스레드 2가 94를 얻고, lastIdUsed가 95가 됨 스레드 1이 94를 얻고, 스레드 2가 94를 ..

클린 코드 독서일지 - Day 43

N7: 이름으로 부수 효과를 설명하라 함수, 변수, 클래스의 이름에 부수 효과를 숨기지 않는다. => 여러 작업을 수행하는 함수일 경우, 하는 일을 모두 기술하는 이름을 사용한다. 테스트 T1: 불충분한 테스트 테스트 케이스는 잠재적으로 깨질 만한 부분을 모두 테스트해야 한다. => 테스트 케이스가 확인하지 않는 조건이나 검증하지 않는 계산이 있다면 그 테스트는 불완전하다. T2: 커버리지 도구를 사용하라! 커버리지 도구를 사용하면 테스트가 불충분한 모듈, 클래스, 함수를 찾기가 쉬워진다. 대다수 IDE는 테스트 커버리지를 시각적으로 표현하여 테스트가 빠뜨리는 공백을 알려준다. T3: 사소한 테스트를 건너뛰지 마라 사소한 테스트는 짜기 쉽고, 제공하는 문서적 가치는 구현에 드는 비용을 넘어선다. T4: ..

클린 코드 독서일지 - Day 42

자바 J1: 긴 import 목록을 피하고 와일드카드를 사용하라 ex) import package.*; 긴 import 목록은 읽기에 부담스러우며, 명시적인 import문은 강한 의존성을 생성함 J2: 상수는 상속하지 않는다 상수는 상속 대신 static import를 사용한다. J3: 상수 대 Enum public static final int보다 enum을 사용하라. enum은 이름이 부여된 열거체로, 메서드와 필드도 사용할 수 있는 훨씬 유연하고 서술적인 도구이다. 이름 N1: 서술적인 이름을 사용하라 소프트웨어 가독성의 90%는 이름이 결정한다. 서술적인 이름을 신중하게 골라야 함 N2: 적절한 추상화 수준에서 이름을 선택하라 구현을 드러내는 이름은 피하고 작업 대상 클래스나 함수가 위치하는 추상..

클린 코드 독서일지 - Day 41

G26: 정확하라 코드에서 뭔가를 결정할 때는 정확히 결정하고, 결정을 내리는 이유와 예외를 처리할 방법을 분명히 알아야 한다. -> 모호성과 부정확은 제거해야 함 G27: 관례보다 구조를 사용하라 설계 결정을 강제할 때는 규칙보다 관례를 사용한다. 명명 관례도 좋지만 구조 자체로 강제하면 더 좋다. ex) switch/case 문보다 추상 메서드가 있는 기초 클래스가 더 좋다. G28: 조건을 캡슐화하라 부울 논리는 이해하기 어려우므로 조건의 의도를 분명히 밝히는 함수로 표현하라. ex) if(timer.hasExpired() && !timer.isRecurrent()) -> if(shouldBeDeleted(timer))로 변경 G29: 부정 조건은 피하라 부정 조건은 긍정 조건보다 이해하기 어려우므..

클린 코드 독서일지 - Day 40

G15: 선택자 인수 선택자 인수 : 함수나 메서드의 인수 중 하나가 다른 인수들의 처리 방식을 결정하는 역할을 하는 것. 선택자 인수는 목적을 기억하기 어려울 뿐 아니라 각 선택자 인수가 여러 함수를 하나로 조합함 ex: calculateWeeklyPay(false) 같은 함수의 boolean 인수 일반적으로 인수를 넘겨 동작을 선택하는 대신 새로운 함수를 만드는 편이 좋다. G16: 모호한 의도 코드를 짤 때는 의도를 최대한 분명히 밝힌다. 행을 바꾸지 않고 표현한 수식, 헝가리식 표기법, 매직 번호 등은 모두 가독성을 흐림 => 피하는 게 좋음 G17: 잘못 지운 책임 코드를 배치할 때는 독자가 자연스럽게 기대할 위치에 배치한다. ex) PI 상수는 삼각함수를 선언한 클래스에 배치 기능을 개발에 편..

클린 코드 독서일지 - Day 39

냄새와 휴리스틱 다양한 코드 냄새(코드를 좋지 않게 짠 경우)와 코드를 짜면서 사용하는 기교, 휴리스틱을 소개한다. 아래의 경우들은 모두 바람직하지 않은 관습들의 나열임 주석 C1: 부적절한 정보 소스 코드 관리 시스템, 버그 추적 시스템, 이슈 추적 시스템 등 다른 시스템에 저장할 정보는 주석으로 적절치 않음 C2: 쓸모 없는 주석 오래된 주석, 엉뚱한 주석, 잘못된 주석은 더 이상 쓸모가 없음 => 쓸모 없는 주석은 코드와 무관하게 따로 놀며 코드를 그릇된 방향으로 이끎 C3: 중복된 주석 코드만으로 충분한데 구구절절 설명하는 주석은 불필요함 C4: 성의 없는 주석 문법과 구두점을 올바로 사용하고, 간결하고 명료하게 작성한다. C5: 주석 처리된 코드 주석 처리된 코드는 아무도 그 쓰임을 모르며, 매..

클린 코드 독서일지 - Day 38

SerialDate 클래스 리팩터링 작업 정리 주석 개선 enum을 독자적인 소스 파일로 옮김 정적 변수와 정적 메서드를 위치와 연관성에 따라 새 클래스로 옮김 일부 추상 메서드를 클래스로 끌어올림 enum 변경 새 메서드를 생성해 중복을 없앰 숫자 1을 다른 변수 혹은 상수로 변경 리팩토링을 통해 테스트 커버리지가 증가하고, 버그를 고치고, 코드 크기를 줄이고 코드를 명확하게 함.