Skip to content

아이템 59. 라이브러리를 익히고 사용하라 #142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
JoisFe opened this issue Mar 6, 2023 Discussed in #136 · 0 comments
Open

아이템 59. 라이브러리를 익히고 사용하라 #142

JoisFe opened this issue Mar 6, 2023 Discussed in #136 · 0 comments
Labels
9장 일반적인 프로그래밍 원칙 이펙티브 자바 9장 (일반적인 프로그래밍 원칙)

Comments

@JoisFe
Copy link
Member

JoisFe commented Mar 6, 2023

Discussed in https://github.com/orgs/Study-2-Effective-Java/discussions/136

Originally posted by JoisFe February 22, 2023

아이템 59. 라이브러리를 익히고 사용하라

  • 무작위 정수 하나 생성 하는 코드를 만들어보자
    static Random rnd = new Random();
    
    static int random(int n) {
        return Math.abs(rnd.nextInt()) % n;
    }
  • 위 코드는 세가지 문제가 있음
  1. n이 그리 크지 않은 2의 제곱수라면 얼마 지나지 않아 같은 수열이 반복
  2. n이 2의 제곱수가 아니라면 몇몇 숫자가 평균적으로 더 자주 반환
  3. n 값이 크면 이 현상이 더 두드러짐

예시 코드

  • 신중히 선택한 범위에서 무작위 수를 백만개를 생성한 후 그 중 중간 값보다 작은 게 몇개 인지 출력
static int random(int n) {
        return Math.abs(rnd.nextInt()) % n;
    }
    public static void main(String[] args) {
        int n = 2 * (Integer.MAX_VALUE / 3);
        int low = 0;

        for (int i = 0; i < 1000000; ++i) {
            if (random(n) < n / 2) {
                ++low;
            }
        }

        System.out.println(low);
    }
image
  • random 메서드가 이상적으로 동작한다면 약 50만 개 출력되어야 함
  • 실제로 666,666에 가까운 결과를 확인할 수 있음
  • 무작위로 생성된 수 중 2/3 가량이 중간값보다 낮은 쪽으로 쏠렸음
  • 가장 위 코드의 3번째 문제점 즉 지정한 범위 '바깥'의 수가 종종 튀어나올 수 있음
  • rnd.nextInt()가 반환한 값을 Math.abs를 이용해 음수가 아닌 정수로 매핑하기 때문

위 문제의 해결법?

  • 의사난수 생성기, 정수론, 2의 보수 계산 등 조예가 깊어야 함
  • 이러한 개념들을 알기엔 쉽지 않음

다른 해결법

  • Random.nextInt(int)가 이미 해결
  • 이 메서드의 자세한 동작 방식은 몰라도 됨 (궁금하다면 API 문서나 소스코드를 보면 됨)
  • 이 메서드 경우 알고리즘에 능통한 개발자가 설계와 구현과 검증에 시간을 들여 개발
  • 이 분야의 여러 전문가들이 잘 동작함을 검증함
  • 또한 해당 라이브러리가 릴리스된 후 20년 간 수백만의 개발자들이 열심히 사용했지만 버그가 보고된 적 없음
  • 만약 버그가 발견되더라도 수정될 것

표준 라이브러리 사용의 장점

1. 표준 라이브러리를 사용하면 그 코드를 작성한 전문가의 지식과 앞서 사용한 다른 프로그래머들의 경험을 활용할 수 있음

Random 의 문제점

  • 자바 7 버전 부터는 Random을 더 이상 사용하지 않는 것이 좋음
  • ThreadLocalRandom으로 대체하면 대부분 잘 동작
  • Random 보다 더 고품질의 무작위 수를 생성, 속도도 더 빠름
  • 포크-조인 풀이나 병렬 스트림에서는 SplittableRandom을 사용하는 것을 추천

2. 핵심적인 일과 크게 관련 없는 문제를 해결하느라 시간을 허비하지 않아도 된다.

3. 따로 노력하지 않아도 성능이 지속해서 개선 됨

  • 사용자가 많고 업계 표준 벤치마크를 사용해 성능을 확인할 수 있기 때문에 표준 라이브러리 제작자들은 더 나은 방법을 꾸준히 모색함
  • 자바 플랫폼 라이브러리의 많은 부분이 수 년에 걸쳐 지속해서 다시 작성되며 때론 성능이 극적으로 개선

4. 기능이 점점 많아짐

  • 라이브러리에 부족한 부분이 있다면 개발자 커뮤니티에서 이야기가 나오고 논의된 후 다음 릴리스에 해당 기능이 추가되곤 함

5. 표준 라이브러리를 활용해 작성한 코드가 많은 사람에게 낯익은 코드가 됨

  • 자연스럽게 다른 개발자들이 더 읽기 좋고 유지보수하기 좋고 재활용하기 쉬운 코드가 됨

그럼에도 불구하고 직접 구현하는 경우

  • 위 표준 라이브러리 사용의 많은 장점들이 있음에도 많은 프로그래머가 직접 구현해서 하는 경우가 많음

대부분 라이브러리에 그런 기능이 있는지 모르기 때문

  • 라이브러리가 너무 방대하여 모든 API 문서를 공부하기 벅차겠지만 자바 프로그래머라면 적어도 java.lang, java.util, java.io 와 그 하위 패키지들에는 익숙해져야함
  • 다른 라이브러리 경우 필요할 때마다 익히면 됨

라이브러리가 필요한 기능을 충분히 제공하지 못하는 경우

  • 더 전문적인 기능을 요구할수록 이러한 현상이 발생할 가능성이 큼
  • 우선은 라이브러리를 사용하려고 시도하는 습관이 중요하다
  • 만약 라이브러리에서 원하는 기능을 제공하지 못한다면 대안을 사용
  • 자바 표준 라이브러리가 가장 높은 우선순위로 두고, 원하는 기능을 찾지 못한다면 고품질의 서드파티 라이브러리를 찾자 (구글의 Guava가 대표적인 예)

정리

  • 표준 라이브러리 사용의 장점들을 보면 이미 잘 만들어진 바퀴를 사용하면 되지 바퀴를 만들려고 고생할 필요가 없다. 라는 명언이 생각이 났는데 책에서도 이 예시를 들었음
  • 아주 특별한 나만의 기능이 아니라면 누군가 이미 라이브러리 형태로 구현해 놓았을 가능성이 큼
  • 그러니 해당 기능을 제공하는 라이브러리가 있는지 없는지 먼저 찾아보자
  • 코드 품질에도 규모의 경제가 적용 됨 즉 라이브러리 코드는 개발자 각자가 작성하는 것 보다 주목을 훨씬 많이 받으므로 코드 품질도 그만큼 높을 가능성이 큼
@JoisFe JoisFe added the 9장 일반적인 프로그래밍 원칙 이펙티브 자바 9장 (일반적인 프로그래밍 원칙) label Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
9장 일반적인 프로그래밍 원칙 이펙티브 자바 9장 (일반적인 프로그래밍 원칙)
Projects
None yet
Development

No branches or pull requests

1 participant