JavaRush /Java блогу /Random-KY /Ыктымалдуулук теориясы практикада же Random жөнүндө билес...
Viacheslav
Деңгээл

Ыктымалдуулук теориясы практикада же Random жөнүндө билесизби

Группада жарыяланган
Ыктымалдуулук теориясы практикада же Random жөнүндө билесизби - 1

Киришүү

Дүйнөдө ыктымалдуулук теориясын изилдеген көптөгөн orмдер бар. Ал эми orмдер ар кандай бөлүмдөрдөн турат. Мисалы, математикада кокустуктарды, чоңдуктарды ж.б. изилдөөгө арналган өзүнчө бөлүм бар. Бирок orмге жеңилдик берилбейт. Бул учурда, адамдар кокустук оюндарын ойногондо чүкө ыргытууда кандай үлгүлөр бар экенин түшүнүүгө аракет кылганда, ыктымалдуулук теориясы калыптана баштаган. Жакшылап карасаңыз, айланабызда туш келди көрүнгөн нерселер көп. Бирок бардык кокустуктар толугу менен кокустук эмес. Бирок бул тууралуу кийинчерээк. Java программалоо тor JDK биринчи versionсынан баштап кокус сандарды да колдойт. Javaдагы кокус сандар java.util.Random классын колдонуу менен колдонулушу мүмкүн . Сыноо үчүн биз tutorialspoint java онлайн компиляторун колдонобуз . Бул жерде орус тorндеги кубдарды же кубиктерди ыргытуу үчүн 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 классынын documentациясында айтылгандай, эгер 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());
}
Демейки конструктор бит боюнча эксклюзивдүү ЖЕ операциясын колдонот . Жана бул үчүн учурдагы убакытты жана кээ бир үрөнүн билдирген узун колдонот :
private static long seedUniquifier() {
	for (;;) {
		long current = seedUniquifier.get();
		long next = current * 181783497276652981L;
		if (seedUniquifier.compareAndSet(current, next))
			return next;
	}
}
Бул жерде дагы бир кызыктуу нерсе, seedUniquifier алуу ыкмасына ар бир чалуу seedUniquifier маанисин өзгөртөт . Башкача айтканда, класс кокустук сандарды мүмкүн болушунча натыйжалуу тандоо үчүн иштелип чыккан. Бирок, documentтерде айтылгандай, алар " криптографиялык жактан коопсуз эмес ". Башкача айтканда, криптографиялык максаттар үчүн колдонуунун кээ бир максаттары үчүн (паролду түзүү ж.б.) ылайыктуу эмес, анткени туура мамиле кылуу менен ырааттуулук болжолдонууда. Интернетте бул тема боюнча мисалдар бар, мисалы, бул жерде: “ Javaдагы кийинки Math.random() ды болжолдоо ”. Же, мисалы, булак codeу бул жерде: " аялуу алсыз крипто ". java.util.Random (кокус сандар генератору) белгилүү бир "жарлыкка" ээ, башкача айтканда , Math.random аркылуу аткарылуучу чалуунун кыскартылган versionсы:
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

Кооптуу Random Java

SecureRandom классы java.util.Random субклассы жана java.security пакетинде жайгашкан . Бул эки класстын салыштыруусун " Java.util.Random менен java.security.SecureRandom ортосундагы айырма " макаласынан окуса болот . Эмне үчүн бул SecureRandom мынчалык жакшы? Чындыгында, ал үчүн кокус сандардын булагы "негизги энтропия бассейни" сыяктуу сыйкырдуу нерсе. Бул плюс да, минус да. Мунун кемчorктери тууралуу макаладан окуй аласыз: “ Java.security.SecureRandom коркунучтары ”. Кыскача айтканда, Linux өзөктүк кокустук сандар генератору (RNG) бар. RNG системадагы кокустук окуялардын негизинде толтурулган энтропия бассейнинин маалыматтарынын негизинде кокус сандарды жаратат, мисалы, клавиатура жана диск убакыттары, чычкандын кыймылдары, үзгүлтүктөр жана тармак трафиги. Энтропия бассейни жөнүндө көбүрөөк маалымат материалда сүрөттөлгөн " Linux ичиндеги кокус сандар (RNG) же кантип "толтуруу" /dev/random жана /dev/urandom ". Windows системаларында, sun.security.provider.SecureRandom ичинде ишке ашырылган SHA1PRNG колдонулат. Java-нын өнүгүшү менен SecureRandom да өзгөрдү, бул тууралуу толук сүрөт алуу үчүн “ 2016-жылдын апрелиндеги Java SecureRandom жаңыртуулары ” деген серептен окуу керек .
Ыктымалдуулук теориясы практикада же Random жөнүндө билесизби - 4

Multithreading же Цезарь сыяктуу болуңуз

Эгер Random классынын codeун карасаңыз , эч нерсе кыйынчылыкты көрсөтпөйт. Методдор синхрондуу деп белгиленген эмес . Бирок бир БИРОК бар: бир нече жипте демейки конструктор менен Random түзүүдө , биз алардын ортосунда бир эле мисалдын үрөнүн бөлүшөбүз , анын жардамы менен Random түзүлөт . Жана ошондой эле жаңы кокус сан алынганда, мисалынын ички AtomicLong да өзгөрөт . Бир жагынан логикалык көз караштан алганда мунун эч кандай жаман жери жок, анткени... AtomicLong колдонулат . Башка жагынан алып караганда, сиз өндүрүмдүүлүктү кошкондо, бардыгы үчүн төлөшүңүз керек. Жана бул үчүн да. Ошондуктан, жада калса java.util.Random үчүн расмий documentтерде мындай деп айтылат: " 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 баалуулуктарынын жаралышына да таасирин тийгизди . Мисалы, 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