注释:
原子性: 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
可见性: 可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值.
有序性: 即程序执行的顺序按照代码的先后顺序执行.
指令重排序(有序性): 处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。
a) HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结构是一个数组,数组中的每一项是一条链表.
b) HashMap的实例有俩个参数影响其性能: “初始容量” 和 装填因子.
c) HashMap实现不同步,线程不安全。 HashTable线程安全.
d) HashMap中的key-value都是存储在Entry中的.
e) HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals方法保证键的唯一性.
f) HashMap是采用拉链法解决哈希冲突的。
注释:
解决冲突主要有三种方法:定址法,拉链法,再散列法。
1.链表法是将相同hash值的对象组成一个链表放在hash值对应的槽位;
2.用开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。 沿此序列逐个单元地查找,直到找到给定的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。
3.拉链法解决冲突的做法是: 将所有关键字为同义词的结点链接在同一个单链表中 。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0…m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。
a) 继承不同:
public class Hashtable extends Dictionary implements Map
public class HashMap extends AbstractMap implements Map
b) Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了.
c) Hashtable 中, key 和 value 都不允许出现 null 值。 在 HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null 。当 get() 方法返回 null 值时,即可以表示 HashMap 中没有该键,也可以表示该键所对应的值为 null 。因此,在 HashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey() 方法来判断.
d)两个遍历方式的内部实现上不同。Hashtable、HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式.
e)哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值.
f) Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数.
注释:
HashSet子类依靠hashCode()和equal()方法来区分重复元素。 HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值的,会去判断当前Map中是否含有该Key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同.
类的加载是由类加载器完成的,类加载器包括:根加载器( BootStrap )、扩展加载器( Extension )、系统加载器( System )和用户自定义类加载器(java.lang.ClassLoader 的子类)。从 Java 2 ( JDK 1.2 )开始,类加载过程采取了父亲委托机制( PDM )。 PDM 更好的保证了 Java 平台的安全性,在该机制中, JVM 自带的 Bootstrap 是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。 JVM 不会向 Java 程序提供对 Bootstrap 的引用.
下面是关于几个类加载器的说明:
1.Bootstrap :一般用本地代码实现,负责加载 JVM 基础核心类库( rt.jar );
2.Extension :从java.ext.dirs 系统属性所指定的目录中加载类库,它的父加载是Bootstrap;
3.system class loader :又叫应用类加载器,其父类是 Extension 。它是应用最广泛的类加载器。它从环境变量 classpath 或者系统属性 java.class.path 所指定的目录中记载类,是用户自定义加载器的默认父加载器;
4.用户自定义类加载器: java.lang.ClassLoader 的子类
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
示例代码:
public class TestAutoPlan {
public int FindGreatestSumOfSubArray(int[] array) {
}
}
实现代码:
public class TestAutoPlan {
public int FindGreatestSumOfSubArray(int[] array) {
//最大和
int maxSum=array[0];
//临时和
int curSum=0;
for(int i=0;i<array.length;i++){
//判断临时和是否为负数,为负数时,应重新开始
if(curSum<0){
curSum=0;
}
//子序求和
curSum+=array[i];
//大于最大值,赋值
if(curSum>maxSum){
maxSum=curSum;
}
}
return maxSum;
}
public static void main(String[] args) {
int[] array=new int[]{6,-3,-2,7,-15,1,2,2};
TestAutoPlan test=new TestAutoPlan();
int index = test.FindGreatestSumOfSubArray(array);
System.out.println(index);
}
}
动态规划解析: https://www.jianshu.com/p/65f3077d8e50