分类 默认分类 下的文章

java.lang.Object 的 hashCode 方法 注意事项

hashCode: digests the data stored in an instance of the class into a single hash value (a 32-bit signed integer);
Technically, in Java, hashCode() by default is a native method, it is implemented directly in the native code in the JVM.

主要用在 hashTable, hashSet, HashMap等需要hash值的数据结构(hash-based collections), 有了这种离散分布的hash值, 对比操作更快;

基本的要求规范是(The hashCode contract):
1) 一个对象如果没有变化, 那么它返回的hashCode值必须前后一致;
2) 两个对象如果是 equals = true, 那么他们的hashCode 值必须一样;

没有要求说, 不同的JVM实现, 必须返回一致的hashCode值. 即使同一段程序, 在不同的执行(Run)当中, 也可以返回不同的hashCode值;
不同的对象, 返回同样的hash值, 是可以接受的(当然最好(理想)的情况下, 是返回不一样的hashCode值);
返回同样 hashCode值的对象, 不要求必须 equals;

为什么: 两个对象如果是 equals = true, 那么他们的hashCode 值必须一样?

举一个反例: 假如2个对象实例是equals的, 但是hashCode值不一样, 那么把它们两个同时放到一个hashSet, 那么它们就占用2个位置了, 但是因为它们是equals的, 所以我们认为它们应该在这个hashSet中只占一个位置, 是同一个值.

一个重写的例子 (奇数->更好的离散型):
An object’s hashCode method must take the same fields into account as its equals method.

public class Employee {
    int        employeeId;
    String     name;
    Department dept;
 
    // other methods would be in here 
 
    @Override
    public int hashCode() {
        int hash = 1;
        hash = hash * 17 + employeeId;
        hash = hash * 31 + name.hashCode();
        hash = hash * 13 + (dept == null ? 0 : dept.hashCode());
        return hash;
    }
}

HashCode collisions

Whenever two different objects have the same hash code, we call this a collision. A collision is nothing critical, it just means that there is more than one object in a single bucket, so a HashMap lookup has to look again to find the right object. A lot of collisions will degrade the performance of a system, but they won’t lead to incorrect results.
But if you mistake the hash code for a unique handle to an object, e.g use it as a key in a Map, then you will sometimes get the wrong object. Because even though collisions are rare, they are inevitable. For example, the Strings "Aa" and "BB" produce the same hashCode: 2112. Therefore, Never misuse hashCode as a key

there’s one important detail in the hashCode contract that can be quite surprising: hashCode does not guarantee the same result in different executions.

Moreover, you should be aware that the implementation of a hashCode function may change from one version to another. Therefore your code should not depend on any particular hash code values. For example, your should not use the hash code to persist state. Next time you run the application, the hash codes of the “same” objects may be different.

java.lang.String 的hashCode 实现

public int hashCode() {
    if (hashCode == 0) {
        int hash = 0, end = offset + count;
        for (int i = offset; i < end; i++) {
            hash = (hash << 5) - hash + value[i];
        }
        hashCode = hash;
    }
    return hashCode;
}

参考:

  1. wiki
  2. The 3 things you should know about hashCode()

网站访问 -> 代理 ip 检测 -> 端口扫描 -> nmap

看网站的后台浏览记录, 最近发现经常有这么一个网址: mianfeidaili.ttju.cn, 入口是这个网址, 浏览页面竟然也是这个网址. 可以猜测这是一个网页代理, 因为是访问的这个页面, 所以入口和浏览页面的网址都是这个页面.

顺着这个网址找过去, 发现是个: "提供代理IP提取" 的网站. 百度了一下, 发现类似的网站都是提供代理 ip 地址的. 通过某些扫描软件, 发现某一网段, 或者某一运营商(电信,联通,移动)的 ip 段内的免费代理. 然后卖个用户, 用户可以用这些代理刷投票等.

ip 端检测方面比较出名的是 nmap, 它可以 1) 检测该 ip 是否有对应的主机, 该主机是否 up, 2) 那些端口是对外开放的, 是什么协议, 3) 对应的操作系统是什么.

路由器 repo 上竟然有 nmap 软件, 安装之后试了试, 基本的扫描主机还可以. 如果扫描端口什么的, CPU 就飙升了.

eric@home:/tmp/home/eric# nmap -PS21 223.166.19.225/29

Starting Nmap 5.35DC1 ( http://nmap.org ) at 2014-05-25 17:44 UTC
Nmap scan report for 223.166.19.225
Host is up (0.00070s latency).

Nmap scan report for 223.166.19.226
Host is up (0.0027s latency).
Not shown: 997 closed ports
PORT     STATE    SERVICE
23/tcp   filtered telnet
80/tcp   open     http
1900/tcp open     upnp

Nmap done: 8 IP addresses (2 hosts up) scanned in 2138.07 seconds

如上所示, 我扫描了一下我主机所在的 IP 段的一个非常小的部分. 共有8个 IP 地址, 有2个主机 up, 其中上面那个是我的路由器. 下面是另外一台在线的主机. 竟然开着80端口. 不过80端口返回403. 另外还开着1900, 是 upnp 协议.

NCR 访问 google.com 而不是 google.com.hk

为了搜个英文材料, google 总是自动跳转到 google.com.hk 即使点了右下角的 使用 google.com 仍旧跳转到 hk. 登录 google 帐号, 也不可以, 使用代理也不可以.

搜了一下, 如果访问 http://www.google.com/ncr 就能访问 google.com 的服务了.
据说这个 NCR 是 No Country Redirect 的意思.

goagent 代理访问 https 网站 出现的问题

遇到2种问题

  1. 证书不正确的问题

如下图, 报告证书不正确, 这种直接 继续 就好了

请输入图片描述
虽然能继续, 可是还有可能出现页面全乱掉的问题, 如下图. 原因是 CSS/JS 文件在 CDN 或者其它域名上, 所以找到 "其它" 域名, 在另外的窗口打开, 同上, 也点击 继续, 再回到原来页面刷新, 页面就恢复了.
请输入图片描述

  1. 证书不信任的问题 Error Type: HSTS failure

如下图, 浏览器认为不是真正的网站, 直接Block 了. 

请输入图片描述
点击详情, 如下图. 竟然说 facebook 要 chrome block 的, 那么也可以认为这是 chrome 对某些网站做的优化.(可是 chrome 并没有 block google 的 https 网站).
请输入图片描述
如何化解?
添加 goagent 的 CA 到系统信任的 CA 列表. 下图是我的 chrome 在 MAC 上面的操作. (chrome 是使用的系统根证书列表)
找到 chrome 设置, 然后是 https/SSL 管理证书
请输入图片描述
MAC 下自动打开 keychain, 导入证书到 system, 我这个截图有点问题, 实际是导入的 system 下面
请输入图片描述
导入的时候, 选择 always trust
请输入图片描述
导入之后, 重新打开这个证书, 点 Trust 下三角, 然后再次确认 always trust. 就可以了
请输入图片描述

Windows 下 终结 全角 半角 切换 问题

相信很多人都会遇到这个问题:
从来不会用到全角输入, 可是经常被切换到全角输入. 不经意的点到 shift + 空格, 就换全角了. 尤其这些在键盘飞奔的程序员.

一直用搜狗输入法, 看到搜狗输入法有很多快捷键, 包括我经常用, 却被搜狗占用的 Ctr + Shift + F. 总以为全角/半角 切换也是搜狗可以设置的. 不过从来没有找到过.

今天搜索终于找到, 原来这是 Windows 操作系统设置的快捷键, 可以通过修改注册表设置:

  1. 打开 注册表编辑器: Ctr + R, 输入 regedit, 点 ok, 打开注册表编辑器;
  2. 依次打开: HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\00000011
  3. 修改: Key Modifiers 为02 40 00 00
  4. 修改: Virtual Key 为31 00 00 00

重启机器, 生效.

上面是设置 全角/半角 切换为键盘 右边的 Ctr + 1 . 我想你很少会用到的.
请输入图片描述
请输入图片描述


2天之后的更新

上面的注册表设置在刚设置的当天管用, 也许重启机器/重新登录之后 Ctrl + Space 又回来了, 检查注册表, 发现没有变化.
现在发现必须还要更改另外一个快捷键:
请输入图片描述
请输入图片描述
如上, 修改2个地方之后, 就可以了.

感谢原作者的这篇更详细的, 带有说明的帖子:
http://wenku.baidu.com/link?url=4nnou9r5MPacphPa8S6C189zzVWlFKhl5X5GI2-8UkvVTQANKuN2kc-4pztHanTwRUjw9FDqJCuL5BiwNeRPjApMIWkzomWfkJrOk6EcDWS
微软官方关于 中文输入法半角/全角 注册表键的说明