컬쥐네 다락방

[프리코스 1주차] Random 함수에 관한 공부 본문

공부방/IT

[프리코스 1주차] Random 함수에 관한 공부

코딩하는 갱얼쥐 2021. 11. 26. 02:50

 1주차 프로그래밍 요구사항을 자세히 살펴보면 다음과 같은 사항이 있다.

  • JDK에서 기본 제공하는 Random, Scanner API 대신 camp.nextstep.edu.missionutils에서 제공하는 Randoms, Console API를 활용해 구현해야 한다.
    • Random 값 추출은 camp.nextstep.edu.missionutils.Randoms의 pickNumberInRange()를 활용한다.
    • 사용자가 입력하는 값은 camp.nextstep.edu.missionutils.Console의 readLine()을 활용한다.

평소 알고리즘 테스트에서 사용하던 Random()을 사용하는게 아니구나라는 생각에 missionutils가 뭔지 한 번 들어가봤다.

missionutils는 우리가 함수를 만드는 데에 큰 시간을 소비하지 않고 코드 컨벤션이나 다른 요구사항들을 지키기 위해 더 노력하라는 배려같이 느껴졌다! 두 배열을 이용해서 숫자가 배열에 존재하는지, 존재한다면 index가 같은지 비교해서 스트라이크와 볼 판정을 내려줘야겠다고 생각하고 있었는데, 함수를 보니 List을 반환하도록 만들어두신 함수가 있었다. 그런데 Random 값 추출은 pickNumberInRange()를 활용하라고 하셨는데, 그 함수는 pickUniqueNumbersInRange()라는 함수였다.. 기초부터 만들기를 원하시는 걸까요 ?  

 

일단 camp.nextstep.edu.missionutils의 내부를 살펴보면 유효성 검사를 하는 함수를 포함해 숫자를 뽑아내는 함수들이 있었다. 

private static void validateRange(final int startInclusive, final int endInclusive)

private static void validateCount(final int startInclusive, final int endInclusive, final int count)

두개의 int를 받아서 랜덤을 뽑아내는 범위의 유효성을 체크하는 함수, 뽑아내는 숫자 갯수의 유효성을 체크하는 함수였다.

첫 번째는 범위를 지정해줄 때 맨 앞의 숫자가 맨 뒤의 숫자보다 큰지, 맨 뒤의 숫자가 Integer의 Max보다 큰지, 숫자 범위가 Integer의 Max보다 큰지 검사하는 함수였다. 

음.. 마지막 에러가 발생하려면 첫 번째 숫자가 음수여야하는데, 숫자 야구에서는 항상 양수만 사용하기에 아마 다양한 과제에서 활용하시기 위해 만든 것 같다.

두 번째는 뽑아내는 숫자의 갯수가 0이하거나, 숫자 범위보다 크면 에러가 발생한다. 모두 다른 숫자로 구성해야해서 작성해놓으신 듯하다! 

 

맨 위부터 차례대로 읽어가는데, new Random()을 사용하지 않고 ThreadLocalRandom.current()를 사용해서 Rondom객체를 초기화하고 있었다. 

찾아보니 이건 스레드 별로 난수 생성을 고립시키는 클래스로 Java 7부터 생겼다고 한다! 

 

Random

Random은 seed를 AutomicLong으로 사용하기에 멀티 쓰레드의 요청에서 순서대로 처리하며 마치 동기화처럼 동작하기 때문에 비교적 느리다고 한다. 여기서 AutomicLong은 Long 자료형을 갖고 있는 Wrapping 클래스라고 한다. Thread-safe로 구현되어 멀티쓰레드에서 동기화없이 사용할 수 있다고 한다.

ThreadLocalRandom

ThreadLocalRandom은 AutomicLong을 사용하지 않고 Thread별로 seed값을 다르게 관리해서 Random보다 빠르면서도 Thread-safe하다고 한다. 

ThreadLocalRandom의 current를 살펴보면 

public static ThreadLocalRandom current() {
        if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
            localInit();
        return instance;
    }

최초에는 localInit()이 호출되고, 동일 스레드가 호출되면 바로 instance를 반환한다. 최초로 호출되면 seed값이 존재하지 않아서 localInit이 호출되는 모양이다.

 

다른 Random관련된 녀석들

 

SplittableRandom

java 8에서 생긴 녀석인데, 격리된 병렬처리에 특화된 녀석이라고 한다.

Thread safe하지 않기때문에 사용할 때 주의해야한다고 한다.

SecureRandom

Random의 경우에는 LCG(Linear Congruential Generator) 알고리즘을 사용하는데, 얘는 CSPRNG(cryptographically strong pseudo-random number generator) 알고리즘을 사용한다고 한다... 

NativePRNG, NativePRNGBlocking, NativePRNGNonBlocking, PKCS11, SHA1PRNG, Windows-PRNG 등 다양한 알고리즘이 있는데, 알고리즘을 선택할 수 있어서 ThreadLocalRandom이나 Random보다 더 좋은 품질의 무작위 수를 만들어 낸다고 한다... 얘도 thread safe하다.

 

일단 이번에 사용될 녀석들은 아니기에 여기까지만.. 

 

이 ThreadLocalRandom을 이용한 함수들이 여러개 있는데,

public static int pickNumberInList(final List<Integer> numbers)

public static int pickNumberInRange(final int startInclusive, final int endInclusive)

public static List<Integer> pickUniqueNumbersInRange(
        final int startInclusive,
        final int endInclusive,
        final int count
    )
    
public static <T> List<T> shuffle(final List<T> list)

이름만 봐도 무슨 목적을 가지고 만드셨는지 파악이 가능하다..! 

처음은 List에서 숫자를 랜덤으로 뽑는 함수. 리스트에서 랜덤으로 뽑을 일은 야구 게임에서 필요 없을 듯하다! 만약 쓴다면 1~9까지의 숫자 리스트에서 하나씩 뽑아서 중복 확인 후 리스트로 만드는 방법도 있을 듯하다.

두 번째는 범위 내에서 랜덤으로 숫자 하나를 뽑아내는 함수. 요구사항으로 적어주신 함수다. 위 함수가 List에서 숫자를 뽑아낸다면 이건 범위에서 숫자를 뽑아낸다. 

세 번째는 범위 내에서 Unique한 숫자로 이루어진 List를 반환하는 함수. 만약 두 번째 함수를 사용하라는 요구 사항이 없었다면 이 함수를 사용해서 손쉽게 만들었을 것 같다. 아마 기초부터 만들지만 답안을 주신 느낌.

네 번째는 세 번째 함수에서 범위 안의 숫자로 이루어진 List를 섞어주고 원하는 갯수만큼만 잘라내는 함수였다.Collections.shuffle()을 사용하면 List의 숫자를 섞을 수 있고, .subList()를 사용하면 List를 잘라낼 수 있는 것 같다.이건 알고리즘 테스트에서도 사용될 여지가 있어보인다! subString만 사용해봤는데 List도 가능했다.

 

 

코드 출처:https://github.com/woowacourse 

(공개된 코드지만 혹시 몰라서 함수 내부는 기록하지 않았다. 궁금하다면 우테코 깃헙으로..! )

참고 자료:https://namocom.tistory.com/733

http://dveamer.github.io/backend/JavaRandom.html

 

'공부방 > IT' 카테고리의 다른 글

우아한 테크코스 4기 프리코스 후기  (0) 2021.12.14
Index와 SQL 기초  (0) 2021.10.25
머신 러닝 기초  (0) 2021.10.18
AL/ 머신러닝 / 딥 러닝 이란?  (0) 2021.10.17
운영 체제 공부 - 작성중  (0) 2021.08.11
Comments