JAVA/Effective Java

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

꾸준함. 2024. 3. 17. 02:48

무작위 정수를 생성할 때 많은 개발자들이 다음과 같이 개발합니다.

 

 

얼핏 보면 문제가 없어 보이지만 세 가지의 문제점을 내포하고 있는 코드입니다.

  • n이 크지 않은 2의 제곱수라면 얼마 지나지 않아 같은 수열이 반복됨
  • n이 2의 제곱수가 아니라면 몇몇 숫자가 평균적으로 더 자주 반환됨
  • rnd.nextInt()가 반환한 값을 Math.abs를 이용해 음수가 아닌 정수로 매핑하기 때문에 지정한 범위 바깥의 수가 종종 튀어나갈 수 있음
    • 혹여나 결과로 Integer.MIN_VALUE가 나왔고 이를 절댓값 씌웠을 때 오버플로우 발생 가능

 

1. n이 크지 않은 2의 제곱수라면 얼마 지나지 않아 같은 수열이 반복됨

 

 

코드 부연 설명

  • n을 2^10, 즉 1024로 설정하고 1024번의 반복을 통해 랜덤값을 생성했음에도 불구하고, 생성된 랜덤값이 균일하지 않음을 확인할 수 있음
  • 만약 랜덤값이 균일했다면 1부터 1024까지의 각 값이 1번씩 나왔을 것

 

2. n이 2의 제곱수가 아니라면 몇몇 숫자가 평균적으로 더 자주 반환됨

 

 

부연 설명

  • 이상적으로 동작한다면 약 50만개가 출력돼야 하지만
  • 실제로 돌려보면 2/3인 666,666에 가까운 값을 얻음
    • 무작위로 생성된 수 중에서 2/3 가량이 중간값보다 낮은 쪽으로 쏠린 것

 

3. 해결책

 

앞서 발생한 문제는 자바 7 버전부터 도입된 표준 라이브러리인 ThreadLocalRandom으로 대체하면 대부분 잘 작동합니다.

  • Random보다 더 고품질의 무작위 수를 생성할 뿐 아니라 속도도 더 빠름
  • 포크-조인 풀이나 병렬 스트림에서는 SplittableRandom을 사용

 

표준 라이브러리를 적극 활용하자

표준 라이브러리를 사용하면 다음과 같은 장점이 있습니다.

  • 표준 라이브러리를 사용하면 다른 개발자들의 경험을 활용 가능
  • 핵심적인 일과 크게 관련 없는 문제를 해결하느라 시간을 허비하지 않아도 됨
  • 별도로 노력하지 않아도 성능이 지속해서 개선됨
  • 기능이 점점 많아짐
  • 라이브러리를 사용하면 많은 사람들에게 낯익은 코드가 됨

 

1. 표준 라이브러리를 사용하면 다른 개발자들의 경험을 활용 가능

 

  • Random의 결함을 해결하려면 의사난수 생성기, 정수론, 2의 보수 계산 등에 조예가 깊어야 하지만 자바에서 제공한 표준 라이브러리인 ThreadLocalRandom에서 이미 해결했으므로 메서드의 동작 방식을 몰라도 해결 가능
  • 알고리즘에 능통한 개발자가 설계와 구현과 검증에 시간을 들여 개발했고, 이 분야의 여러 전문가가 잘 동작함을 대신 검증해 줬기 때문에 안심하고 사용해도 됨
    • 혹시 버그가 발생하더라도 다음 릴리즈에서 수정될 것이라고 기대할 수 있음

 

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

 

  • 표준 라이브러리는 사용자가 많고 사용자가 많을수록 레퍼런스가 풍부하기 때문에 문제 발생 시 해결 속도가 빠름

 

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

 

  • 사용자가 많고, 업계 표준 벤치마크를 사용해 성능을 확인하기 때문에 표준 라이브러리 제작자들은 더 나은 방법을 꾸준히 모색함
  • ex) 자바 플랫폼 라이브러리의 많은 부분이 수 년에 걸쳐 지속해서 재작성되었기 때문에 때로는 성능이 드라마틱하게 개선되기도 함

 

4. 기능이 점점 많아짐

 

  • 라이브러리에 부족한 부분이 있다면 stackoverflow 혹은 github issues에서 이야기가 나오고 논의된 후 다음 리리즈에 해당 기능이 추가되기도 함

 

5. 라이브러리를 사용하면 많은 사람들에게 낯익은 코드가 됨

 

  • 표준 라이브러리를 사용하는 개발자들이 많기 때문에 활용할수록 자연스럽게 다른 개발자들 입장에서 가독성과 유지보수 측면에서 좋은 코드가 됨

 

메이저 릴리즈를 주목하자

메이저 릴리즈마다 주목할만한 수많은 기능이 라이브러리에 추가되며 자바는 이를 웹페이지에 공시합니다.

  • 자바 개발자라면 한 번쯤 읽어보는 것을 추천
  • 너무 많아서 읽기 힘들더라도 java.lang.*, java.util.*, java.io.* 패키지들은 반드시 확인하는 것을 추천
    • 특히 java.util의 컬렉션 프레임워크와 java.util.concurrent 패키지는 알아두면 큰 도움이 됨

 

정리

  • 전문적인 기능을 요구할수록 라이브러리가 필요한 기능을 충분히 제공하지 못할 수도 있고 있지만 우선은 라이브러리를 사용하려 시도하는 것을 권장
    • 어떤 영역의 기능을 제공하는지 살펴보고, 원하는 기능이 아니라 판단될 경우 대안을 사용하는 것을 권장
    • 일반적으로 라이브러리의 코드는 개발자가 작성한 것보다 품질이 좋고 개선의 여지가 있음
    • 라이브러리 코드는 주목을 많이 받고 개발자 커뮤니티에서 문제점이 많이 거론되므로 코드 품질이 점차 좋아질 확률이 높음
    • 자바 표준 라이브러리에서 원하는 기능을 찾지 못하면, 그다음 선택지는 Guava와 같은 고품질의 서드파티 라이브러리 사용하는 것을 권장
    • 특별한 기능이 아니라면 누군가 라이브러리로 만들어 두었을 가능성이 높음

 

참고

이펙티브 자바

 

반응형