CPU 바운드 작업 CPU 바운드 작업은 주로 계산이 많이 필요한 작업으로, CPU의 처리 능력이 주요 병목 지점이 되는 상황입니다. 이러한 작업들은 주로 CPU 연산이 많이 필요하며, I/O 작업이 상대적으로 적은 경우입니다. CPU 바운드 작업에서는 CPU의 성능이 주요 제약 요소가 되므로, 다중 코어를 활용하여 병렬처리를 하는 것이 성능 향상에 도움이 될 수 있습니다. 계산적인 작업: 수학적 계산이 많이 필요한 작업은 CPU 바운드 작업에 해당합니다. 예를 들어, 대규모 행렬의 곱셈, 복잡한 수학적 함수의 계산 등이 여기에 속합니다. 이미지/비디오 처리: 이미지나 비디오 처리 작업 중에서 CPU를 많이 사용하는 작업은 CPU 바운드 작업에 해당할 수 있습니다. 예를 들어, 이미지 필터링, 변환, 비..
Enum 특징 JVM에서 인스턴스를 단 한 번만 생성하기 때문에 인스턴스의 제어가 용이 Enum 상수가 프로그램 내에서 오직 한 번만 생성되고, 그 이후에는 항상 동일한 인스턴스를 참조 JVM에서 스레드 안전(thread-safe)하게 초기화 자동으로 직렬화되며, 역직렬화될 때도 항상 동일한 인스턴스를 반환 Enum Singleton Pattern Enum의 특징을 활용해서 각 Enum 상수에 대해 특정 비즈니스 객체를 생성하도록 코드를 작성해서 싱글톤으로 생성된 비즈니스 객체를 재사용할 수 있도록 구현한다. 구현 객체 생성을 Enum에 위임해서 Client에서는 Interface를 통해서 사용할 수 있다. Calculator enum에 비즈니스 객체를 생성하는 요소 public enum Calculat..
함수 추출하기 '목적과 구현을 분리'하는 방식 함수의 목적이 눈에 확 들어오고, 본문 코드에 대해서는 더 이상 신경 쓸 일이 거의 없다. 함수를 짧으면 캐싱하기가 더 쉽기 때문에 컴파일러가 최적화하는 데 유리할 때가 많다. #AS-IS function printOwing(invoice) { printBanner(); let outstanding = calculateOutstanding(); console.log('고객명: ${invoice.customer}'); console.log('채무액: ${outstanding}'); } #TO-BE function printOwing(invoice) { printBanner(); let outstanding = calculateOutstanding(); prin..
리팩터링을 제대로 하려면 불가피하게 저지르는 실수를 잡아주는 견고한 Test suite가 뒷받침돼야 한다. 컴파일할 때마다 테스트를 함께하면 디버깅 시간이 크게 줄어든다. 테스트 스위트는 강력한 버그 검출 도구로, 버그를 찾는 데 걸리는 시간을 대폭 줄여준다. 테스트를 작성하기 가장 좋은 시점은 프로그래밍을 시작하기 전이다. 기능을 추가해야 할 때 테스트부터 작성한다. 원하는 기능을 추가하기 위해 무엇이 필요한지 고민하게 되고 구현보다 인터페이스에 집중하게 된다는 장점 TDD(Test Driven Development) 처음에는 통과하지 못할 테스트를 작성하고, 이 테스트를 통과하게끔 코드를 작성하고, 결과 코드를 최대한 깔끔하게 리팩터링하는 과정을 짧은 주기로 반복한다. 테스트-코딩-리팩터링 실패해야 ..
리팩터링 정의 소프트웨어의 겉보기 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법 여러가지 리팩터링 기법을 적용해서 소프트웨어를 재구성한다. 리팩터링하는 동안에는 코드가 항상 정상 작동하기 때문에 전체 작업이 끝나지 않아도 언제든 멈출 수 있다 누군가 "리팩터링하다가 코드가 깨져서 며칠이나 고생했다"라고 한다면, 리팩터링한 것이 아니다 두개의 모자 소프트웨어를 개발할 때 목적이 '기능 추가'냐, 아니면 '리팩터링' 이냐를 명확히 구분해 작업 기능을 추가할 때는 '기능 추가' 모자를 쓴 다음 기존 코드는 절대 건드리지 않고 새 기능을 추가하기만 한다. 리팩터링할 때는 '리팩터링' 모자를 쓴 다음 기능 추가는 절대 하지 않기로 다짐한 뒤 오로지 코드 재구성에만 전념한다...
Future의 단순 활용 비동기 계산을 모델링하는데 사용 Future는 계산이 끝났을 때 결과에 접근할 수 있는 참조를 제공 시간이 걸릴 수 있는 작업을 Future 내부로 설정하면 호출자 스레드가 결과를 기다리는 동안 다른 작업을 수행 Callable 객체 내부로 감싼 다음에 ExecutorService에 제출 ExecutorService executor = Executors.newCachedThreadPool();//스레드 풀 생성 Future future = executor.submit(new Callable() {//Callable을 스레드풀에 제출 public Double call() { return doSomeLongComputation();//시간이 오래걸리는 작업을 다른 스레드로 비동기 실..
리팩터링이란 겉으로 드러나는 코드의 기능은 바꾸지 않으면서 내부 구조를 개선하는 방식으로 소프트웨어 시스템을 수정하는 과정 버그가 생길 가능성을 최소로 줄이면서 코드를 정리하는 방법 리팩터링한다는 것은 코드를 작성하고 난 뒤에 설계를 개선하는 일 프로그램이 새로운 기능을 추가하기에 편한 구조가 아니라면, 먼저 기능을 추가하기 위한 형태로 리팩터링 후 원하는 기능을 추가한다 리팩터링 전에 제대로 된 테스트부터 마련한다 테스트는 반드시 자가진단하도록 만든다 테스트를 작성하는데 시간이 좀 걸리지만, 신경써서 만들어두면 디버깅 시간이 줄어서 전체 작업 시간은 단축된다 리팩터링은 프로그램 수정을 작은 단계로 나눠 진행한다 그래서 중간에 실수하더라도 버그를 쉽게 찾을 수 있다 컴파일-테스트-커밋 간단한 수정이라도 ..
스레드와 높은 수준의 추상화 단일 CPU가 여러 사용자를 지원할 수 있는데 이는 운영체제가 각 사용자에 프로세스를 할당하기 때문 두 사용자가 자신만의 공간에 있다고 생각할 수 있도록 가상 주소 공간을 각 프로세스에 제공 운영체제는 주기적으로 번갈아가며 각 프로세스에 CPU를 할당함 프로세스는 운영체제에 한개 이상의 스레드로 같은 주소 공간을 공유하는 태스크를 동시에 실행 네 개의 코어를 가진 CPU에서 이론적으로는 병렬로 실행하여 실행 속도를 네배 향상시킬 수 있음 자바 스트림으로 병렬성을 달성 long sum = Arrays.stream(stats).parallel().sum(); 스트림을 이용해 스레드 사용 패턴을 추상화 Executor와 스레드 풀 Java 5는 Executor 프레임워크와 Thre..
Executor In Java, the Executor framework provides a simple and flexible interface for asynchronous task execution. It is part of the java.util.concurrent package and is commonly used to manage and control the execution of tasks concurrently. The primary interface in the Executor framework is the Executor interface, and there are several implementations available. Basic Usage of Executor import j..