您的位置 首页 > 德语常识

一脸懵逼二脸懵逼的动态表情包,一脸懵逼二脸懵逼表情包

你好,我是伟伟。

我最近在stackoverflow 上看到了一些代码。我应该说什么?

一脸懵逼二脸懵逼的动态表情包,一脸懵逼二脸懵逼表情包

第一次看到的时候我很困惑,但是当我明白的时候,我跪下了!

首先,我将向您展示stackoverflow 上的这个问题是关于什么的,然后我将引导您查看这段代码。

https://stackoverflow.com/questions/15182496/为什么-这样做-这个代码-使用-随机-字符串-打印-hello-world

问题很简单,就一句话。

有人可以解释一下吗?为什么这段代码使用随机字符串打印hello world?

代码也很简单,我们就把它拿出来运行一下。

public class MainTest { public static void main(String[] args) { System.out.println(randomString(-229985452) + ' ' + randomString(-147909649)); } public static String randomString(int i) { random ran=new Random(i); StringBuilder sb=new StringBuilder(); while (true) { int k=ran.nextInt(27); if (k==0) Break; sb.append((char) ('`' + k)); } return sb.toString(); }}您也可以将上面的代码直接粘贴到您的执行环境中并运行它,看看是否也打印了hello world。

让我问你一个问题。即使给了您一个代码,您第一次看到Hello World 时是否会感到困惑?

喜欢的答案

高赞的回答也很简单,就两句话。

请让我翻译一下。这位朋友说:

当您调用Random 的构造函数时,它会被赋予一个“种子”参数。例如,本例中为-229985452 或-147909649。

然后随机生成从指定种子值开始的随机数。

所有使用相同种子构造的Random 对象都会根据相同的模式生成数字。

你没看清楚吧?

没关系。我将向您展示一些代码。然后你就会突然明白上面这段话在说什么了。

public static void main(String[] args) {randomString(-229985452); System.out.println('------------');randomString(-229985452);} private static void randomString (int i) { Random ran=new Random(i); System.out.println(ran.nextInt()); System.out.println(ran.nextInt()); System.out.println(ran.nextInt() )); System.out.println(ran.nextInt()); System.out.println(ran.nextInt());} 这是在我的机器上运行此代码的结果:

如果你选择它并运行它,结果肯定会像这样。

为什么这个?

答案在Javadoc 中。

如果使用相同的种子创建两个Random 实例,并对每个实例进行相同的方法调用序列,则将生成并返回相同的数字序列。

在上面的代码中,两个-229985452是相同的种子,三个nextInt()调用是相同的调用序列。

因此,它生成并返回相同的、看似随机的数字。

程序中的典型用法是:

使用new Random() 时,未指定任何值。

我们都知道Random是一种伪随机算法,任何在构造过程中指定种子参数的算法都更像是伪随机算法。

因为如果我能猜到你的种子,或者如果你的种子被泄露,我理论上就能猜到随机数生成序列。

我们在前面的代码中演示了这一点。

我们再来看这个问题,简单地解释了“种子”的要点之后,我们回到品尝一品的问题,我想我们会得到一些提示。

主要看这个循环里面的代码。

首先,nextInt(27) 检查当前返回的数字k 必须是[0,27) 之间的数字。

如果返回0,则如果不为零则循环退出。接下来,进行类型转换。

下一步是将其转换为char 类型。

当您看到转换为char 类型的数字时,您会自动想到ASCII 代码。

从ASCII码表中我们可以看出“96”就是这里的符号。

因此,下面的代码的范围是[96+1, 96+26]。

''+k

它是[97,122],对应于ASCII码a到z。

现在我们再次反汇编上面的演示代码。

首先new Random(-229985452).nextInt(27)的前五个返回值为:

new Random(-147909649).nextInt(27)的前五个返回值为:

因此,如果查看ASCII码表,就可以看到相应的字符。

8 + 96=104 -- h5 + 96=101 -- e12 + 96=108 -- l12 + 96=108 -- l15 + 96=111 -- o23 + 96=119 -- w15 + 96=111 -- o18 + 96=114 -- r12 + 96=108 -- l4 + 96=100 -- d

现在,为什么这个神秘的代码会输出“hello world”呢?这让我感觉自己站在镜子里,就像云已经散去,我可以看到蓝天。

一旦你明白了,这只是一个小技巧。

然后这个问题下面有一条评论显示了另一种打开方式。

如果您可以指定hello world 的输出,理论上您也可以指定其他单词的输出。

例如,这个人输入了短语“一只敏捷的棕色狐狸跳过一只懒狗”。

直译是“敏捷的棕色狐狸跳过了懒狗”,但这似乎没有任何意义。

但你也知道,我的英语水平比较高,所以我一眼就看出这句话远不简单。

所以我检查了以下内容:

果然是有一点故事,属于诡计中的诡计。

在学习沙雕技术的同时,我还提高了英语水平,所以我能够一石二鸟。文章末尾可以加“赞”或“查看”吗?

读完这个人简单的棕色狐狸的例子后,我有了一些新的想法。

是否可以输入所有字符,甚至我需要的特定短语?

我很好,谢谢你,你等等。

诸如查找与给定单词相对应的种子等功能的代码已经由“好人”在该问题的答案中编写。

只需将其粘贴到此处,但您也可以按原样使用它。

public static longgenerateSeed(String goal, long start, long finish) {char[]input=goal.toCharArray();char[]pool=newchar[input.length];label:for(long seeds=start;seed finish;seed++) {随机Random=new Random(seed); for (int i=0; i input.length; i++) pool[i]=(char) (random.nextInt(27) + '''); if (random .nextInt( 27)==0) { for (int i=0; i input.length; i++) { if (input[i] !=pool[i]) continue label; } return Seed; } } throw new NoSuchElementException ('对不起:/');} 那么如果你想找到上面的短语,就很容易了。

当我跑步时,我明显感觉到我花了一段时间才找到合适的词来表达“谢谢”。

为什么?

请让我谈谈。只有一句话。你可能听说过它。

只要时间足够长,猴子就能敲出:010到30000之间的数字。

这里的generateSeed方法就对应了这只猴子。谢谢这个词是《莎士比亚》。

使用generateSeed方法,通过连续组合26个字符,您总是可以及时串出“谢谢”。

单词越长,花费的时间就越长。

例如,“恭喜你,这么长的单词从00:05 已经跑了23 个小时了,我还是看不懂。”

但理论上来说,只要你有足够的时间,你一定会找到这个物种。

至此,你应该完全明白为什么上面的代码使用随机字符串打印hello world 了。

源码,可以看源码吗?

不是,我主要是带她出去吃瓜。

首先,我们来看看Random 无参数构造函数。

事实上,我自己创建了种子并调用了参数化构造函数。

只是变量“System.nanoTime()”是在构建时添加的,因此种子看起来有点随机。

等等,之前不是有一个“seedUniquiifier”方法吗?

就是这样:

我第一眼看到的时候就头晕了。其中涉及两个“神奇数字”。

181783497276652981L8682522807148012L

你不也明白这一点吗?

待定,堆栈溢出。

只需搜索,您就会找到这个地方。

https://stackoverflow.com/questions/18092160/whats-with-181783497276652981-and-8682522807148012-in-random-java-7

对此,他表示自己也对这两个数字感到困惑,并在网上进行了搜索,但几乎没有找到相关信息。然而,我发现一篇论文提到了一个非常接近的“神奇数字”。

论文中列出的数字是:

你可以看到我吗?

这段Java源代码中的数字开头少了一个“1”,这到底是什么?是不是我复制的时候弄错了?

以下是评价较高的答案:

“看来是误抄了。”

这有点有趣,当我告诉他这是编写Java 源代码的人时,他很兴奋,因为他复制代码时双手在颤抖。

如果你立即进入Java Bug 页面并搜索一串数字,你会发现一些意想不到的东西。

https://bugs.openjdk.java.net/browse/JDK-8201634

在描述这个错误时,他提请我注意源代码中的以下位置:

原来,这里的注释代表的是一篇论文,而这个数字的来源应该隐藏在这篇论文中。

等等,为什么这篇论文的名字听起来很耳熟?

点击上述stackoverflow上的链接即可获取论文地址。

检查一下这篇论文的名字和关于Java的评论是否相同。

一定是一样的。只有一个小写字母和一个大写字母。

这是真实的故事。第一个编写Java源代码的人在抄写数字时手抖,抄下来少了一个“1”。

当我写这部分源代码时,有位老大爷贴上了数字“1181783497276652981”,然后说:“哎呀,前面怎么有两个1?这是重复的,删掉吧。我什至可以想象他意识到,“拜托。”

如果删除这个“1”会出现什么样的问题呢?

无论如何,问题就在这里。这意味着对new Random() 的并发调用不够随机。

我不会做任何研究,所以如果你有兴趣,请去做,我唯一的责任就是带你出去吃瓜。

于是,在这个“瓜”的基础上,官方又改了一次代码。

我这里正好有JDK 15和JDK 8版本的代码,于是我看了一下,发现居然有“1”:的区别

当谈到随机数时,现在已经很少使用Random 了。

只需使用ThreadLocalRandom。是不是很美妙?

什么,你说不?

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023