范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

初看一脸懵逼,看懂直接跪下

  你好呀,我是歪歪。
  我最近在 stackoverflow 上看到一段代码,怎么说呢。
  就是初看一脸懵逼,看懂直接跪下!
  我先带你看看 stackoverflow 上的这个问题是啥,然后引出这段代码:
  https://stackoverflow.com/questions/15182496/why-does-this-code-using-random-strings-print-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 的构造方法时,给定了一个"种子"(seed)参数。比如本例子中的:-229985452 或 -147909649。
  那么 Random 将从指定的种子值开始生成随机数。
  而每个用相同的种子构造的 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 是一个伪随机算法,而构建的时候指定了 seed 参数的就是一个更加伪的伪随机算法了。
  因为如果我可以推测出你的 seed 的话,或者你的 seed 泄露了,那么理论上我就可以推测出你随机数生成序列。
  这个我已经在前面的代码中演示了。 再看看问题
  在前面稍微解释了 "seed" 的关键之处之后,我们再回过头去品一品这个问题,大概就能看出点端倪了。
  主要看这个循环里面的代码。
  首先 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 --> h
  5 + 96 = 101 --> e
  12 + 96 = 108 --> l
  12 + 96 = 108 --> l
  15 + 96 = 111 --> o
  23 + 96 = 119 --> w
  15 + 96 = 111 --> o
  18 + 96 = 114 --> r
  12 + 96 = 108 --> l
  4 + 96 = 100 --> d
  现在,对于这一段谜一样的代码为什么输出了 "hello world" 的原因,心里是不是拨开云雾见青天,心里跟明镜儿似的。
  看穿了,也就是一个小把戏而已。
  然后这个问题下面还有个评论,让我看到了另外一种打开方式:
  你能指定打印出 hello world,那么理论上我也能指定打出其他的单词。
  比如这个老哥就打了一个短语:the quick browny fox jumps over a lazy dog.
  如果从字面上直译过来,那么就是"敏捷的棕色狐狸跨过懒狗",好像也是狗屁不通的样子。
  但是,你知道的,我的 English 水平是比较 high 的,一眼就看出这个短语在这里肯定不简单。
  于是查了一下:
  果然是有点故事的,属于 tricks in tricks。
  你看学沙雕技术的时候还顺便丰富了自己的英语技能,一举多得,这一会还不得在文末给我点个赞、点个"在看"啥的?
  看完这个老哥的 quick brown fox 示例之后,我又有一点新想法了。
  既然它能把所有的字母都打出来,那我是不是也能把我想要的特定的短语也打出来呢?
  比如 i am fine thank you and you 这样的东西。
  而查找指定单词对应的 seed 这样的功能的代码,在这个问题的回答中,已经有"好事之人"帮我们写出来了。
  我就直接粘过来,你也可以直接拿去就用: public static long generateSeed(String goal, long start, long finish) {     char[] input = goal.toCharArray();     char[] pool = new char[input.length];     label:     for (long seed = start; seed < finish; seed++) {         Random 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("Sorry :/"); }
  那么我要找前面提到的短语,就很简单了:
  而且运行的时候我明显感觉到,在搜索"thank"这个单词的时候,花了很多时间。
  为什么?
  我给你讲一个故事啊,只有一句话,你肯定听过:
  只要时间足够漫长,猴子都能敲出一部《莎士比亚》。
  我们这里 generateSeed 方法,就相当于这个猴子。而 thank 这个单词,就是《莎士比亚》。
  在 generateSeed 方法里面,通过 26 个字母不断的排列组合,总是能排列出 "thank" 的,只是时间长短而已。
  单词越长,需要的时间就越长。
  比如我来个 congratulations,这么长的单词,我从 00:05 分,跑了 23 个小时都还没跑出来:
  但是理论上来讲只要有足够长的时间,这个 seed 一定会被找到。
  至此,你应该完全明白了为什么前面提到的那段代码,使用随机字符串的方式打印出了 hello world。
  源码
  你以为我要带你读源码?
  不是的,我主要带你吃瓜。
  首先,看一下的 Random 无参构造函数:
  好家伙,原来也是套个了个"无参"的壳而已,实际上还是自己搞了一个 seed,然后调用了有参构造方法。
  只是它构建的时候加入了"System.nanoTime()"这个变量,让 seed 看起来随机了一点而已。
  等等,前面不是还有一个"seedUniquifier"方法吗?
  这个方法是这样的:
  好家伙,看到第一眼的时候我头都大了,这里面有两个"魔法数"啊:
  181783497276652981L
  8682522807148012L
  这玩意也看不懂啊?
  遇事不决,stackoverflow。
  一搜就能找到这个地方:
  https://stackoverflow.com/questions/18092160/whats-with-181783497276652981-and-8682522807148012-in-random-java-7
  在这个问题里面,他说他对这两个数字也感到很懵逼,网上找了一圈,相关的资料非常的少。但是找到一个论文,里面提到了其中一个很接近的"魔数":
  论文中提到的数是这样的:
  看到没有?
  这 Java 源码中的数字前面少了一个"1"呀,咋回事呢,该不会是拷贝的时候弄错了吧?
  下面的一个高赞回答是这样的:
  "看起来确实像是拷错了。"
  有点意思,你要说这是写 Java 源码的老哥 copy 代码的时候手抖了,我就来劲了。
  马上去 Java Bug 的页面上拿着那串数字搜一下,还真有意外收获:
  https://bugs.openjdk.java.net/browse/JDK-8201634
  在这个 bug 的描述里面,他让我注意到了源码的这个地方:
  原来这个地方的注释代表着一个论文呀,那么这个论文里面肯定就藏着这个数的来源。
  等等,我怎么感觉这个论文的名字有点像眼熟啊?
  前面 stackoverflow 中提到的这个链接,点进去就是一个论文地址:
  你看看这个论文的名称和 Java 这里的注释是不是说的一回事呀:
  那必须是一回事啊,只是一个小写一个大写而已。
  所以,到这里实锤了,确实是最开始写 Java 这块源码的老哥 copy 数字的时候手抖了,少 copy 了一个 "1"。
  而且我甚至都能想象到当时写这部分源码的时候,那个老哥把"1181783497276652981"这个数字粘过来,发现:哎,这前面怎么有两个 1 啊,整重复了,删除了吧。
  至于把这个"1"删除了之后,会带来什么问题呢?
  反正这里关联了一个问题,说的是:并发调用 new Random() 的随机性不够大。
  这我就没去研究了,有兴趣可以去看看,我只负责带你吃瓜。
  所以,基于这个"瓜",官方修改了一次这个代码:
  刚好我这里有 JDK 15 和 JDK 8 版本的代码,我去看了一下,还真是差了一个 "1" :
  而且关于随机数,现在一般很少用 Random 了吧。
  直接就是上 ThreadLocalRandom 了,它不香吗?
  什么,你说不会?

快来围观华为的卖车逻辑续航1000公里21。68万元起售,首款开卖车型不是极狐,资本市场已应声上涨每经记者孙磊每经编辑裴健如店内人头攒动,围观着陈列的三辆新车,店外也不时有人驻足,向店内观望。如果这一幕出现在4S店,并不会令人十分奇怪,但如今这一幕出现在华为线下的体验店,意味着两千多亿填了海,美国半导体业接连受挫,中国芯片的春天来了长久以来,芯片研发和制造都被西方牢牢掌握,此前知名调研机构Gartner的数据显示,全球十大芯片巨头中,美国就占据了一半。但美国也有自己的苦恼,就是产业空心化十分严重,虽然芯片的设损失47亿元?台积电传来新消息,失去华为不良反应出现本文原创,请勿抄袭和搬运,违者必究损失47亿元?台积电是全球第一个率先进入到5nm量产工艺的芯片巨头,在5nm高端制程领域,尽管三星后来也成功突破,但相比之下台积电的产能和工艺水准特斯拉又被盯上!刹车失灵T恤连夜上架销售,多人下单购买,活广告要满街走?律师构成侵权今年的上海车展,最热闹的莫过于特斯拉展台。一位身着白底红字印着刹车失灵字样T恤衫的女子,爬上展台一辆特斯拉车顶,将特斯拉刹车失灵喊上了热搜(详见现场!特斯拉上海车展遭维权,车主站车给特斯拉底气的马斯克,和他背后不得不说的明星女人们今日头条发布,严禁抄袭,违者必究!前言最近,特斯拉非常的火,相信大家都非常的清楚。特斯拉目前作为新能源车的大佬,他的一举一动都受到很多人的关注。近日特斯拉因为车展上面闹剧,引起了很上海车展特斯拉维权者道歉,方式会变维权不变,特斯拉绝不妥协消费者也绝不妥协4月19日,上海车展的特斯拉维权事件在网上闹得沸沸扬扬。在经过一波三折的舆论战后以女车主被警方拘留5日为结尾。4月20日上午,一位微博ID安保佳的用户发文称她是当日在现场的维权者之一加9Pro深度评测哈苏定制有那味儿了早在一加9系列发布之前,就传出一加可能要和哈苏联名,但无论是作为普通消费者还是一名专业科技数码从业人员都很相信哈苏会和一加走在一起,毕竟上一次哈苏和手机联名还是几年以前的摩托罗拉了比缺芯更可怕!四大外资垄断中国制造业命脉,中企将如何逆袭?科技的实力决定了一个国家的综合实力强弱,任何的世界强国都必须在科技领域拥有绝对的话语权,这一点始终有不会改变。随着我们国家的崛起,在科技领域我国也晋升到了世界的前列,然而尺有所短寸赛力斯华为联合销售新车?赛力斯是何许人也?最近一周,让爱国的年轻人一个新潮的消息就是,4月19日第十九届上海国际车展,华为携手汽车品牌赛力斯推出华为智选生态新品类产品赛力斯华为智选SF5。塞力斯,华为上海车展赛力斯华为联合20210420互联网新闻华为旗舰店今起开始卖车今日头条1。华为旗舰店开始卖车首辆车为赛力斯华为智选SF54月19日,华为终端官方正式宣布,将正式开启汽车售卖业务,首款车型为赛力斯华为智选SF5。目前,该车已经上线华为消费者官网华为太厉害了!被美国制裁下还能发布麒麟990A!这芯片啥来头?最近华为又发布了一款名为麒麟990A的芯片,其CPU大核采用自研的泰山V120Lite架构,小和采用A55架构NPU则采用达芬奇架构,2个大核1个小核,GPU采用G76架构。和麒麟
走向胜利2021宝德计算机誓师大会圆满完成走向胜利2021宝德计算机誓师大会新春新事新希望,合心合力创辉煌!2021年1月11日,走向胜利2021宝德计算机誓师大会在深圳华侨城洲际大酒店盛大召开。本次大会邀请各大银行中介机前路共飞腾!宝德受邀参加2020飞腾生态伙伴大会2020年12月29日,飞腾生态伙伴大会隆重举行。大会以芯科技新生态共飞腾为主题,吸引了包括两院院士政府领导业内专家行业协会用户单位软硬件厂商系统集成商媒体等1500余人参会,参会工程师改变未来世界宝德工程师大会圆满完成2月3日,工程师改变未来世界第一届宝德工程师大会隆重举行。深圳市宝德投资控股有限公司董事长李瑞杰宝德计算机副董事长兼执行总裁马竹茂宝德速必拓总经理董卫屏宝德计算机高级副总裁沈健宝德又一大亮点!交通执法的好帮手在智能交通时代,随着云计算与物联网的普及,交通车辆移动执法监控领域也有了全新的改变,交通执法有了电子警察,可谓开了天眼。其中最典型的例子就是宝德双路服务器助力上海某人工智能公司智慧众里寻它,宝德服务器助力图像识别研究随着信息技术的发展,人们已进入了大数据时代,构建集群对海量数据进行分布式计算与存储已成为一种共识,图像识别领域也同样如此。图像识别指用视觉传感器(摄像头)和计算机来模拟人眼和大脑,吹响数字经济时代的冲锋号2021宝德X86生态伙伴大会在深召开当前,全球经济越来越呈现数字化特征,人类社会正在进入以数字化为主要标志的新阶段。数字经济,已经成为世界的主要经济形态,也成为推动我国经济社会发展的核心动力。作为多样性算力的主要提供这家公司要搞大事这家公司要搞大事审核状态已通过类别企业新闻发布人100137055发布时间202110230856比亚迪入股!一则公告让投资者直呼王炸,这家公司要搞大事?公告显示,本次重组交易对方班班有个图书角班班有个图书角审核状态已通过类别企业新闻发布人100137055发布时间202110190912比亚迪慈善基金会携手宁泉资产在云南蒙自启动班班有个图书角公益助学项目2021年10月我今天看到的10张好照片(180)GabrieleGalimberti这是这一系列的第180次推送。很久没看纪实摄影,今天推送一组国家地理摄影师GabrieleGalimberti先生的作品。这首先当然是因为逐相君巨蟒吐信,火龙喷火,今天厦门的火烧云和七彩祥云太调皮了5月26日傍晚,中国厦门,海边再现七彩祥云。文图逐相君今天傍晚五点多,厦门潮水退到最低点。逐相君原本是要上天台俯拍一下在海边赶海的密集人群,然后就下楼到海滩上跟拍赶海的盛景。我也好我今天看到的10张好照片(182)EddieWrey这是这一系列的第182次推送。逐相君每次会推送10张我今天看到的好照片。在你参观照片之前,我不愿意给照片加任何文字阐释。这可能会是一种干扰。废话不说,一起逐相Ed