阅读更多

3顶
2踩

编程语言
原文来自:DZone
译文来自:后端技术杂谈

StackOverflow(后边简称so)发展到目前,已经成为了全球开发者的金矿。它能够帮助我们找到在各个领域遇到的问题的最有用的解决方案,同时我们也会从中学习到很多新的东西。这篇文章是在我们审阅了so上最流行的Java问题以及答案后从中挑出来的。即使你是一个有丰富经验的开发者,也能从中学到不少东西。

分支预测

SO上最多投票的一个Java问题是:为什么处理一个排序数组要比非排序数组快的多。为了回答这个问题,你需要使用分支预测(branch prediction)。分支预测是一种架构,旨在通过在真实的路径发生前猜测某一分支的下一步来提升处理过程。

分支在这里即一个if语句。这样的话,如果是一个排序数组,那么分支预测将会进行,否则不会进行。Mysticial(so上的一个回答者)试图使用铁路和火车来简单介绍这个概念。假设你在铁轨连接处要决定火车要走哪条路,你会选择左边还是右边?你可以拦住火车,然后问司机该往那里,但是这样会让整个过程变慢。因此你只能去猜正确的方向,那么如何去猜呢?最好的办法就是通过观察目前这个火车每次经过时的路线,推测出正确的方向。

这就是分支预测:识别模式并使用它。

不幸的是,这个问题的提问者是分支预测失败的受害者。因为他的分支没有任何可以识别出的模式,所以预测出的行为是随机的。

Java中的安全

另一个流行的Java问题是:为什么在Java中有关密码的地方更加喜欢使用char[]而不是String?其实原始的问题更加具体一些,就是问的在Swing中,password控件有一个getPassword方法(返回char[]而不是getText()返回的String)。

其实这里不用惊讶-这是一个安全问题。String是不可变的,意味着一旦它被创建了,那么你就不可能去修改它。这也意味着在GC之前,你对这些数据不能做任何处理。因此,只要有人能够访问你的内存,那么String就有可能被他获取到。

这也就是为什么要使用char数组。你可以显示地清除数据或者覆盖它。这样密码这种敏感数据即使GC还没有进行也不会再在系统留下痕迹。

异常

即使很多开发者倾向于忽略对受检异常的处理,SO上仍然有很多关于异常的问题。其中一个最流行的问题是:什么是NullPointerException,我该怎么处理它?对此,我们并没有感到惊讶,因为这个问题也是在生产环境的Java应用中排名第一的异常。

实际上,当NullPointerException(或者其他exception)在系统出现的时候,我们可以发出一个告警。因为这种异常一般情况下都是业务代码逻辑有问题造成(笔者注)。

为什么这段代码使用随机字符串打印出了”hello world”
问题链接:http://stackoverflow.com/questions/15182496/why-does-this-code-using-random-strings-print-hello-world

这个问题给出了下面的代码,并打印出了”hello world”
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();
}

其实,选择一组随机的整数并不是随机的。给定一个seed参数(在这个例子中是-229985452和-147909649), 那么每次随机,同样的seed则会产生同样的输出。

Random(-229985452).nextInt(27)产生的前六个数字:8, 5, 12, 12, 15, 0

Random(-147909649).nextInt(27)产生的前六个数字:23, 15, 18, 12, 4, 0

这样,最终输出的就是”hello world”。

为什么两个时间戳相减(in 1927)得出一个奇怪的结果?

问题链接:http://stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result
public static void main(String[] args) throws ParseException {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    String str3 = "1927-12-31 23:54:07";  
    String str4 = "1927-12-31 23:54:08";  
    Date sDt3 = sf.parse(str3);  
    Date sDt4 = sf.parse(str4);  
    long ld3 = sDt3.getTime() /1000;  
    long ld4 = sDt4.getTime() /1000;
    System.out.println(ld4-ld3);
}

按说上面的代码最后的结果应该是1,但实际的输出却是353。其实,这是一个时区的问题。1927年12月31号24:00,上海时间往回调整了5分钟52秒,因此”1927-12-31 23:54:08”发生了两次,Java将后面一次实例化成了本地的这个时间。因此和前一秒的差距成了353。

我们需要指出,如果你试着来运行这段代码,结果并不一定是353。Jon Skeet指出了这一点,在时区数据库项目2014版中,这个改变的时间点改到了1900-12-31,因此成了344秒的差距。

无法被捕获的ChuckNorrisException

问题链接:http://stackoverflow.com/questions/13883166/uncatchable-chucknorrisexception

这里有一个很明显的问题:如果有exception被抛出,但是没有任何办法去catch,那么应用会崩溃吗?或者如这个问题所问:是否可以写一段Java代码让一个假设的java.lang.ChuckNorrisException无法被捕获。

答案是可以,但是这里有一个”但是”。你可以编译一段代码抛出一个ChuckNorrisException,但是在Runtime时动态生成一个并不继承于Throwable接口的ChuckNorrisException类。当然,为了让这个过程可以进行,你需要关闭掉字节码验证。jtahlborn给出了完整的解决办法。

哈希表

哈希表是另外一个在SO上流行的问题系列。许多用户都想要知道所有集合类之间的区别,什么时候该使用哪种集合。

迭代顺序是主要考虑的因素。使用HashMap则忽略了所有的顺序信息,也就是获取元素的顺序和你插入元素的顺序是没有任何关系的;使用TreeMap则会得到一个排序好的迭代集合;使用LinkedHashMap则是一个FIFO的顺序。

如果你还是对这些感到困惑,这里有一个相关说明的图表可以参考(Rebel Labs制作)。



总结

对于Java,其实关键的不在于你懂多少,而是在于你可以一直学到更多的东西。StackOverflow不仅在code上的一些问题可以帮助我们,也有助于我们回过头来去深入地学习一些我们已经知道的知识。
  • 大小: 436.2 KB
3
2
评论 共 3 条 请登录后发表评论
3 楼 lizhuang 2016-08-15 16:31
错别字好多
2 楼 yqbjtu 2016-08-15 15:37
为什么两个时间戳相减(in 1927)得出一个奇怪的结果?

在jdk7上测试结果是1, 我是北京时区
1 楼 Kevin.Y.S 2016-08-15 09:21
这是啥、、、、

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • python实现点对点聊天程序

    主要为大家详细介绍了python实现点对点聊天程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  • Java通过socket进行内网穿透简单实现(附源码)

    Java通过socket进行内网穿透简单实现需求背景需求背景1分析需求背景2分析 需求背景 ##背景1,如图,需要实现家里电脑能访问公司的Git代码服务器,实现从家里就能提交git代码的目的。 ##背景2,如图,有内网1和内网2,2个内网里面的2台机器如192.168.56.101,172.168.201.20两台,都不能上网,需要实现能互相通信。 需求背景1分析 对于背景1的需求,属于较常用的内网穿透功能,网上有开源的方案如go语言实现的frp,本次为了学习,通过Java的socket编程,进

  • 深入浅出讲解 NAT 和 UDP/TCP 点对点通讯

    深入浅出讲解 NAT 和 UDP/TCP 点对点通讯 转自:http://blog.csdn.net/g_brightboy/article/details/12704933 一、什么是NAT?为什么要使用NAT? NAT是将私有地址转换为合法IP地址的技术,通俗的讲就是将内网与内网通信时怎么将内网私有IP地址转换为可在网络中传播的合法IP地址。NAT的出现完美地解决了lP地址不足的

  • C#的内网穿透学习(附源码)非常详细,零基础入门到精通,收藏这一篇就够了

    一个外部主机(hostAddr:port3)能够发包到达iAddr:port1的前提是:iAddr:port1之前发送过包到hostAddr:port3.(双方需要各自知道对方转换后的外网ip+端口,然后一方先发一次尝试连接,另一方在次连接过来的时候就能直接连通了。这只是单向的内去外,那反过来,如果外网的设备需要主动访问我局域网里的某一个设备是无法访问的,因为这个时候还没做nat转换所以外网不知道你内网设备的应用具体对应的是哪个端口,这个时候我们就需要内网穿透了,内网穿透也叫NAT穿透;

  • 搭建内网穿透工具-ngrok

    由于某些内部网络的站点需要外部调用或者访问,则需要一个外网能够访问内网的方法,而内网穿透就是这个方法之一。

  • 分享一个支持TCP&UDP穿透的商业应用的P2P组件

    这些源码非常有参考价值, 实际的商业应用可以借鉴。 注意, 虽然是简化版本, 但udp&tcp穿透, 数据交互是完全完整的, 穿透这块经过本人几个项目的 总结, 代码已经变得非常简单, 全部穿透的逻辑代码不到1000行(有的项目P2P模块上W行代码^-^)。 实际游戏运营的穿透率是70%左右。 编译和运行 1. 先编译include/herm. 2. 编译tcp_relayd&ud

  • .NET(C#):使用UPnP来穿透NAT使内网接口对外网可见

    如果服务器和客户端都在内网环境下,即双方都通过NAT来接触外网,那么此时客户端是无法直接和服务器交流的。 解决方案可以是: 1:把服务器部署在不存在NAT的公网环境下。 2:使用常见的NAT穿透方法比如UDP打洞,或者STUN协议,但是这些方法都需要另一个已知的部署在公网环境下的服务器。 3:就是这篇文章主要讨论的方案,即不需要部署任何公网环境下的服务器,通过路由器支持的U

  • NAT 打洞

    由于 ipv4 地址数量的有限性,导致实际网络部署模式中存在大量的 NAT 网络。对于 NAT 内部的主机,可以主动发起去公网的流量,但对于位于不同 NAT 内的两台主机而言,想要直接进行点对点的连接,就需要用到打洞技术了。

  • NAT的完全分析及其UDP穿透的完全解决方案

    NAT的完全分析及其UDP穿透的完全解决方案 一:基本术语防火墙防火墙限制了私网与公网的通信,它主要是将(防火墙)认为未经授权的的包丢弃,防火墙只是检验包的数据,并不修改数据包中的IP地址和TCP/UDP端口信息。网络地址转换(NAT)当有数据包通过时,网络地址转换器不仅检查包的信息,还要将包头中的IP地址和端口信息进行修改。以使得处于NAT之后的机器共享几个仅有的公网

  • C# socket nat 映射 网络 代理 转发

    using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace portmap_net {     ///     /// 映射器实例状态  

  • NET的基本原理与配置

    目录 一、NAT的概述 NAT的工作原理 NAT功能 NAT的优缺点 NAT转换过程 二、静态NAT和动态NAT 1.静态NAT 2.动态NAT 三、PAT端口复用 PAT端口复用 PAT的作用 PAT的类型 四、PAT的配置 NAPT NAT server 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一、NAT的概述 NAT(Network Address Translation)又称为网络地址转换,用于实现私有网络和公有网.

  • NAT穿透技术详解(udp打洞精髓附代码)

    以前自己写的代码都只是在本地进行c/s通信,今天想写一个可以跨越外网的c/s通信,这里我就用udp实现一个点对点的不同外网的通信。用到的技术就是nat穿透技术,这里最直接使用的就是udp打洞技术。文中如有表述不清楚,欢迎提问。如果你需要nat穿透技术的详解点这里:nat穿透浅析需要的设备:一个已知的外网服务器S(ip+port),两个位于不同外网的客户端A, B首先要知道udp打洞的流程:1.A客...

  • FRP的UDP协议内网穿透方案/穿透多个内网机器/账户无效问题

    通过Frp以UDP方式远程访问内网机器

  • P2P 之 UDP穿透NAT的原理与实现(附源代码)

    原创:shootingstars参考:http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt论坛上经常有对P2P原理的讨论,但是讨论归讨论,很少有实质的东西产生(源代码)。呵呵,在这里我就用自己实现的一个源代码来说明UDP穿越NAT的原理。首先先介绍一些基本概念: NAT(Network Addre

  • 价值46万p2p金融平台源代码(php)

    P2p金融平台源码,文件太大无法直接将源代码上传,只能将下载地址写到百度网盘里面,供大家下载

  • P2P 穿透原理及使用指南

    P2P 技术可以说目前比较流行的技术无论在视频直播还是在远程控制方便,看完本文后你可以详细了解 P2P 技术原理帮助你解决一些困扰! 本场 Chat 内容如下: P2P 技术与普通并发服务器的对比及优缺点; P2P 技术原理; P2P 客户端及服务器选用、搭建及使用; P2P 优化方向。 ...

Global site tag (gtag.js) - Google Analytics