Java HashMap 源码分析 01
本系列旨在深入研究 Java HashMap 的底层实现,在 JDK 9 中,HashMap 是一个拥有两千四百多行的大类,为了实现易用,强大,并且可靠的哈希表,里面有相当多的内容,希望通过这一系列文章,能对 HashMap 的实现有深入的理解。
哈希表
在具体讨论 HashMap 之前,我们先来看看哈希表这种数据结构。我们知道,数据结构是存储数据的方式,例如数组、链表这些简单的结构,而不同的数据结构对数据访问、查找、新增、删除、修改等操作的开销则存在差异,并且这种差异可能会非常巨大,于是使用不同的数据结构进行同样的编程活动,其性能差别也是非常大的,所以对数据结构的合理选择对程序的性能就至关重要。
像数组这种结构,在不考虑其容量大小的情况下,其数据访问、修改的时间复杂度为常数级 ...
点我阅读更多...
算法题:棋盘行走
在象棋规则里面,马总是按日字对角移动,现在假设有一个横向 m 条线,纵向 n 条线的棋盘,马
位于交点 (x,y) 上。如果要让马走完棋盘上的每一个点,请问有多少条路线?
这里我们先理一下思路,在棋盘上的每一个点,棋子都有 0 种,1种或者多种移动方法,如果把当前所在的点,作为一个节点,那么下一步选择要走的点其实就是在选择子节点
比如上图的马,就有6种走法,等价于有6个子节点,所有可能的移动路径用节点连接起来就成了一个图结构。棋子的每一条移动路径,都可以用图中的一条路径来表示,于是我们的问题就变成了搜索图的每一条路径,如果该路径上的节点与棋盘上的点一一对应,那么这就是一条符合条件的路线。
现在我们来考虑一下数据结构的问题。首先把棋盘上所有的点表示出来,每个点都可以用一个节点对...
点我阅读更多...
算法题:背包问题
质量约束
背包问题也是一道经典的动态规划问题,它有许多表述形式,什么劫匪小偷抢超市啦,出去旅行要打包啦,简单来说,背包问题给出了一序对集合 \(R^n=\{t_i=(w_i, v_i)\mid i=1,2,,,n\}\) ,其中 \(w_i\) 是物品总重量,\(v_i\) 是物品价值,要求从中选取总重量不超过 \(W\) 的物品,使得物品总价值 \(V\) 尽可能的大。
由于上述问题中有 \(n\) 件物品,所以将该问题定义为 \(Q^n\),假设 \(V^n\) 是该问题最优解的总价值,显然 \(V^n\) 的值与 \(R^n\) 和 \(W\) 都相关,即
\[V^n = f(W, R^n)\]
现在我们稍微缩小问题的规模,若已经从物品列表中拿取了 \(t_j\),并从限...
点我阅读更多...
Java 类运行时动态编译技术
从 JDK 1.6 开始引入了用 Java 代码重写的编译器接口,使得我们可以在运行时编译 Java 源码,然后用类加载器进行加载,让 Java 语言更具灵活性,能够完成许多高级的操作。
从源文件到字节码文件的编译方式
对于一个 java 源文件
//Example.java
public class Example{
@Override
public String toString() {
return "hello java compiler";
}
}
传统的编译方式是使用命令行在当前目录下运行
javac Example.java
然后在同一目录下生成 Example.class 字节码文件。而使用 Java API 来编译类文件则稍微有点复...
点我阅读更多...
Java 中的动态代理
动态代理需求的出现
代理是一种设计模式,其作用是对原方法进行增强,并且不具侵入性。比如一个接口提供某个服务
public interface Service{
public void serve(String[] args);
}
然后有一个类实现此服务
public class ServiceImpl implement Service{
@Override
public void serve(String[] args){
System.out.println("serving..." + Arrays.toString(args));
}
}
但如果我们想在正式调用服务之前或之后做一些额外工作,比如参数校验、资源关闭等等。若不使用代理,那么就...
点我阅读更多...