JavaRush /Java блогы /Random-KK /Ықтималдық теориясы тәжірибеде немесе сіз Random туралы б...
Viacheslav
Деңгей

Ықтималдық теориясы тәжірибеде немесе сіз Random туралы білесіз бе?

Топта жарияланған
Ықтималдықтар теориясы тәжірибеде немесе сіз Random туралы білесіз бе - 1

Кіріспе

Әлемде ықтималдық теориясын зерттейтін көптеген ғылымдар бар. Ал ғылымдар әртүрлі бөлімдерден тұрады. Мысалы, математикада кездейсоқ оқиғаларды, шамаларды және т.б. зерттеуге арналған жеке бөлім бар. Бірақ ғылымға бей-жай қарамайды. Бұл жағдайда адамдар кездейсоқ ойындарды ойнаған кезде сүйек лақтырудың қандай заңдылықтары бар екенін түсінуге тырысқанда ықтималдық теориясы қалыптаса бастады. Мұқият қарасаңыз, айналамызда кездейсоқ көрінетін нәрселер көп. Бірақ барлық кездейсоқ нәрсе мүлдем кездейсоқ емес. Бірақ бұл туралы кейінірек. Java бағдарламалау тілінде JDK бірінші нұсқасынан бастап кездейсоқ сандар үшін де қолдау бар. Java тіліндегі кездейсоқ сандарды java.util.Random класы арқылы пайдалануға болады . Тестілеу үшін біз tutorialspoint java онлайн компиляторын қолданамыз . Мұнда «кешектерді» немесе орыс тіліндегі текшелерді лақтыруға еліктеу үшін Random пайдаланудың қарапайым мысалы келтірілген :
import java.util.Random;

public class HelloWorld{
    public static void main(String []args){
        Random rnd = new Random();
        int number = rnd.nextInt(6) + 1;
        System.out.println("Random number: " + number);
    }
}
Бұл Random сипаттамасының соңы болуы мүмкін сияқты , бірақ бұл оңай емес. Java API ішінде java.util.Random класының сипаттамасын ашайық . Міне, біз қызықты нәрселерді көреміз. Random класы псевдокездейсоқ сандарды пайдаланады. Қалайша? Кездейсоқ сандар соншалықты кездейсоқ емес екен?
Ықтималдық теориясы тәжірибеде немесе сіз Random - 2 туралы білесіз бе

Псевдокездейсоқтық java.util.Random

java.util.Random сыныбына арналған құжаттамада егер Random даналары бірдей тұқымдық параметрмен жасалса және даналарда бірдей әрекеттер тізбегі орындалса, олар бірдей сандар тізбегін қайтаратынын айтады. Егер мұқият қарасақ, Random-да тұқым ретінде ұзақ мән алатын конструктор бар екенін көреміз :
Random rnd1 = new Random(1L);
Random rnd2 = new Random(1L);
boolean test = rnd1.nextInt(6) == rnd2.nextInt(6);
System.out.println("Test: " + test);
Бұл мысал шындықты қайтарады, себебі екі дананың тұқымы бірдей. Енді не істеу керек? Әдепкі конструктор мәселені ішінара шешеді. Төменде Random конструкторының мазмұнының мысалы келтірілген :
public Random() {
	this(seedUniquifier() ^ System.nanoTime());
}
Әдепкі конструктор биттік эксклюзивті НЕМЕСЕ операциясын пайдаланады . Және бұл үшін ағымдағы уақытты білдіретін long және кейбір тұқымды пайдаланады :
private static long seedUniquifier() {
	for (;;) {
		long current = seedUniquifier.get();
		long next = current * 181783497276652981L;
		if (seedUniquifier.compareAndSet(current, next))
			return next;
	}
}
Мұндағы тағы бір қызық нәрсе, seedUniquifier алу әдісіне әрбір шақыру seedUniquifier мәнін өзгертеді . Яғни, сынып кездейсоқ сандарды мүмкіндігінше тиімді таңдауға арналған. Дегенмен, құжаттамада айтылғандай, олар « криптографиялық қауіпсіз емес ». Яғни, криптографиялық мақсатта пайдаланудың кейбір мақсаттары үшін (пароль жасау және т.б.) ол жарамайды, өйткені дұрыс көзқараспен реттілік болжанады. Интернетте осы тақырып бойынша мысалдар бар, мысалы, мына жерде: “ Java тіліндегі келесі Math.random() болжау ”. Немесе, мысалы, бастапқы codeы мына жерде: " Осалдығы әлсіз крипто ". java.util.Random (кездейсоқ сандар генераторы) белгілі бір «төте жолға» ие , яғни Math.random арқылы орындалатын қоңыраудың қысқартылған нұсқасы:
public static void main(String []args){
	int random_number = 1 + (int) (Math.random() * 6);
	System.out.println("Value: " + random_number);
}
Бірақ мұқият қарасаңыз, дәл сол Random ішінде отырады:
public static double random() {
	return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
private static final class RandomNumberGeneratorHolder {
	static final Random randomNumberGenerator = new Random();
}
JavaDoc « криптографиялық қауіпсіз жалған кездейсоқ сандар генераторы » үшін SecureRandom класын пайдалануға кеңес береді .
Ықтималдық теориясы тәжірибеде немесе сіз Random - 3 туралы білесіз бе

Қауіпсіз кездейсоқ Java

SecureRandom класы java.util.Random ішкі сыныбы болып табылады және java.security бумасында орналасқан . Осы екі сыныптың салыстыруын « Java.util.Random және java.security.SecureRandom арасындағы айырмашылық » мақаласынан оқуға болады . Неліктен бұл SecureRandom соншалықты жақсы? Ол үшін кездейсоқ сандардың көзі «негізгі энтропия пулы» сияқты сиқырлы нәрсе болып табылады. Бұл плюс және минус. Мұның кемшіліктері туралы мақаладан оқи аласыз: « java.security.SecureRandom қауіптері ». Қысқаша айтқанда, Linux ядросының кездейсоқ сандар генераторы (RNG) бар. RNG энтропия пулынан алынған деректер негізінде кездейсоқ сандарды жасайды, олар жүйедегі кездейсоқ оқиғалар негізінде толтырылады, мысалы, пернетақта мен дискінің уақыттары, тінтуірдің қозғалысы, үзілістер және желілік трафик. Энтропия пулы туралы қосымша ақпарат « Linux жүйесіндегі кездейсоқ сандар (RNG) немесе /dev/random және /dev/urandom «толтыру» жолы » материалында сипатталған . Windows жүйелерінде SHA1PRNG пайдаланылады, ол sun.security.provider.SecureRandom ішінде жүзеге асырылады. Java-ның дамуымен SecureRandom да өзгерді, ол туралы толық суретті көру үшін « 2016 жылдың сәуіріндегі Java SecureRandom жаңартулары » шолуында оқуға тұрарлық.
Ықтималдықтар теориясы тәжірибеде немесе сіз Random - 4 туралы білесіз бе

Көп ағынды немесе Цезарь сияқты болыңыз

Random класының codeын қарасаңыз , ештеңе ақаулықты көрсетпейді. Әдістер синхрондалған деп белгіленбеген . Бірақ бір БІРАҚ бар: бірнеше ағындардағы әдепкі конструктормен Random жасағанда , біз олардың арасында бірдей дана тұқымын бөлісеміз , ол арқылы Random жасалады . Сондай-ақ жаңа кездейсоқ сан алынғанда, дананың ішкі AtomicLong мәні де өзгереді . Бір жағынан, логикалық тұрғыдан алғанда, бұл жерде ештеңе жоқ, өйткені... AtomicLong қолданылады . Екінші жағынан, сіз бәрін, соның ішінде өнімділікті төлеуіңіз керек. Және бұл үшін де. Сондықтан, тіпті java.util.Random үшін ресми құжаттамада былай делінген: " java.util.Random даналары ағынды қауіпсіз. Дегенмен, бір java.util.Random данасын ағындар бойынша бір мезгілде пайдалану қайшылықтарға және соның салдарынан нашар өнімділікке тап болуы мүмкін. Қарастырыңыз. оның орнына көп ағынды дизайнда ThreadLocalRandom пайдалану ». Яғни, көп ағынды қолданбаларда Random бірнеше ағындардан белсенді түрде пайдаланған кезде ThreadLocalRandom сыныбын қолданған дұрыс . Оның қолданылуы әдеттегі Random қолданбасынан біршама ерекшеленеді :
public static void main(String []args){
	int rand = ThreadLocalRandom.current().nextInt(1,7);
	System.out.println("Value: " + rand);
}
Көріп отырғаныңыздай, біз оған тұқым көрсетпейміз . Бұл мысал Oracle: Concurrent Random Numbers ресми оқулығында сипатталған . Осы сынып туралы толығырақ шолудан оқи аласыз: " Java тіліндегі ThreadLocalRandom нұсқаулығы ".
Ықтималдықтар теориясы тәжірибеде немесе сіз Random - 5 туралы білесіз бе

StreamAPI және Random

Java 8 шығарылымымен бізде көптеген жаңа мүмкіндіктер пайда болды. Stream API қоса. Және өзгерістер кездейсоқ мәндердің генерациясына да әсер етті . Мысалы, Random класында , немесе сияқты кездейсоқ мәндері бар ағынды алуға мүмкіндік беретін жаңа әдістер бар . Мысалы: intdoublelong
import java.util.Random;

public class HelloWorld{
    public static void main(String []args){
        new Random().ints(10, 1, 7).forEach(n -> System.out.println(n));
    }
}
Сондай-ақ SplittableRandom жаңа класы бар :
import java.util.SplittableRandom;

public class HelloWorld{
    public static void main(String []args){
        new SplittableRandom().ints(10, 1, 7).forEach(n -> System.out.println(n));
    }
}
SplittableRandom және басқа сыныптар арасындағы айырмашылық туралы толығырақ мына жерден оқи аласыз: " Java тілінде кездейсоқ сандарды жасаудың әртүрлі тәсілдері ".

Қорытынды

Менің ойымша, бұл қорытынды жасауға тұрарлық. Пайдаланылған сыныптар үшін JavaDoc бағдарламасын мұқият оқып шығу керек. Бір қарағанда, Random сияқты қарапайым нәрсенің артында қатал әзіл ойнай алатын нюанстар бар. #Вячеслав
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION