当前位置: 首页 > 科技观察

StackOverflow:七个你没见过的特别好的Java答案

时间:2023-03-13 00:24:21 科技观察

StackOverflow发展到现在,已经成为全世界开发者的金矿。它可以帮助我们找到对各个领域遇到的问题最有用的解决方案,我们也会从中学到很多新的东西。这篇文章是在我们回顾了StackOverflow上最流行的Java问题和答案后挑选出来的。即使您是经验丰富的开发人员,也可以从中学到很多东西。1.分支预测题链接:https://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-arrayA得票最多的JavaStackOverflow问题是:为什么处理排序的数组比处理未排序的数组快得多。要回答这个问题,需要用到分支预测。分支预测是一种架构,旨在通过在实际路径发生之前猜测分支的下一步来改进处理。这里的分支是一个if语句。这样,如果它是一个排序数组,那么分支预测就会发生,否则不会。StackOverflow上的回答者,链接:http://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array/11227902#11227902使用铁路和火车简要介绍概念。假设你在铁轨的交界处,必须决定火车要走哪条路。你会选择左手还是右手?您可以停下火车并询问司机它要去哪里,但这会减慢整个过程。所以只能猜对方向,那么怎么猜呢?最好的方法是观察火车每次经过时的当前路线,从而推断出正确的方向。这就是分支预测:识别一种模式并使用它。不幸的是,这个问题的提问者是分支预测失败的受害者。因为它的分支没有任何可识别的模式,所以预测的行为是随机的。2.Java中的安全问题链接:http://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords-in-java另一个流行的Java问题是:WhyisitinJava更喜欢使用char[]而不是String作为密码?其实原问题比较具体,就是在Swing中,密码控件有一个getPassword方法(返回的是char[],而不是getText()返回的String)。实际上,这并不奇怪——这是一个安全问题。字符串是不可变的,这意味着它一旦被创建,就不可能修改它。这也意味着您不能对GC之前的数据做任何事情。因此,只要有人能访问你的内存,String就有可能被他获取到。这就是使用char数组的原因。您可以明确清除数据或覆盖它。这样即使没有进行GC,密码等敏感数据也不会在系统中留下痕迹。3.异常链接:http://blog.takipi.com/the-top-10-exceptions-types-in-production-java-applications-based-on-1b-events/尽管许多开发人员倾向于忽略检查了异常处理,StackOverflow上关于异常的问题还是很多的。最常见的问题之一是:什么是NullPointerException以及如何处理它?我们对此并不感到惊讶,因为这个问题也是生产Java应用程序中的头号异常。实际上,当系统出现NullPointerException(或其他异常)时,我们可以发出警报。因为这种异常一般是因为业务代码的逻辑出了问题(笔者注)。4.为什么这段代码使用随机字符串打印出“helloworld”问题链接:http://stackoverflow.com/questions/15182496/why-does-this-code-using-random-strings-print-hello-世界问题给出了以下代码,打印“helloworld”。System.out.println(randomString(-229985452)+""+randomString(-147909649));publicstaticStringrandomString(inti){Randomran=newRandom(i);StringBuildersb=newStringBuilder();while(true){intk=ran.nextInt(27);if(k==0)break;sb.append((char)('`'+k));}returnsb.toString();}其实选择一组随机整数并不是随机的。给定一个种子参数(本例中为-229985452和-147909649),相同的种子每次随机生成相同的输出。Random(-229985452).nextInt(27)生成的前六个数:8、5、12、12、15、0Random(-147909649).nextInt(27)生成的前六个数:23、15、18,12,4,0这样,最后输出的就是“helloworld”。5.为什么减去两个时间戳(1927年)会得到一个奇怪的结果?问题链接:http://stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-resultpublicstaticvoidmain(String[]args)throwsParseException{SimpleDateFormatsf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");Stringstr3="1927-12-3123:54:07";Stringstr4="1927-12-3123:54:08";DatesDt3=sf.parse(str3);DatesDt4=sf.parse(str4);longld3=sDt3.getTime()/1000;longld4=sDt4.getTime()/1000;System.out.println(ld4-ld3);}据说最后的结果上面的代码应该是1,但实际输出是353,其实这是时区问题。1927年12月31日24:00,上海时间往后调了5分52秒,所以“1927-12-3123:54:08”发生了两次,Java将后面的时间实例化为本地时间。所以与前一秒的差异是353。我们需要指出,如果您尝试运行这段代码,结果不一定是353。JonSkeet指出了这一点,链接:http://stackoverflow.com/a/6841479/5982245在时区数据库项目的2014版本中,这个变化的时间点被改为1900-12-31,从而产生了344秒的差距。6.UncatchableChuckNorrisException链接:http://stackoverflow.com/questions/13883166/uncatchable-chucknorrisexception这里有一个很明显的问题:如果抛出异常,但是没有办法捕获,应用会Crash吗?或者如这个问题中所问:是否可以编写一段Java代码,以便无法捕获假设的java.lang.ChuckNorrisException。答案是肯定的,但有个“但是”。你可以编译一段代码抛出ChuckNorrisException,但是在运行时动态生成一个不继承Throwable接口的ChuckNorrisException类。当然,为了让它起作用,你需要关闭字节码验证。jtahlborn给出了完整的解决方案。链接:http://stackoverflow.com/a/13883510/59822457.HashTableHashTable是StackOverflow上流行的另一系列问题。许多用户想知道所有集合类之间的区别以及何时使用哪个集合。迭代顺序是主要考虑因素。使用HashMap会忽略所有的顺序信息,即获取元素的顺序与你插入元素的顺序无关;使用TreeMap将得到一个排序的迭代集;使用LinkedHashMap是一种FIFO顺序。如果您仍然对这些感到困惑,这里有一张相关图表(由RebelLabs制作。链接:http://zeroturnaround.com/wp-content/uploads/2016/04/Java-Collections-cheat-sheet.png。八.小结对于Java来说,关键不在于你知道多少,而在于你总能学到更多,StackOverflow不仅可以帮助我们解决一些代码上的问题,还可以帮助我们回过头来深入学习一些我们已经知道的东西。