<经典> 关于ArrayList扩容 的讲解:
ArrayList的构造器总共有三个:ArrayList()无参构造器构造一个初始容量为10的空列表,每次扩容大小为1.5倍;
ArrayList(Collection
ArrayList(int initialCapacity)构造一个具有指定初始容量的空容量;这种方式是指定了创建的容量大小,没有扩充;
<经典> 关于HashMap和HashTable扩容 的讲解:
HashTable 中hash数组默认初始容量为11,每次扩容的大小为old*2+1;
HashMap 中hash数组默认初始容量为16,每次扩容大小为2*old;
<经典> 线程安全的map在jdk1.5开始有哪几种方法可以实现?
A.Map map = new HashMap()
B.Map map = new TreeMap()
C.Map map = new ConcurrentHashMap();
D.Map map = Collections.synchronizedMap(new HashMap());
正确答案为CD ;首先可以排除AB,因为HashMap和TreeMap都是线程不安全的,而HashTable和ConcurrentHashMap 都是线程安全的,区别在于他们加锁范围不同,HashTable对整张Hash表进行加锁,ConcurrentHashMap将Hash表分为16桶,每次只对需要的桶进行加锁;而Collections 类提供了synchronizedXxx(),可以将指定的集合类包装成一个线程安全的集合对象,比如List、Map、Set
两个数值进行二元操作时,会有如下的转换操作:
如果两个操作数其中有一个是double类型,另一个操作就会转换为double类型。
否则,如果其中一个操作数是float类型,另一个将会转换为float类型。
否则,如果其中一个操作数是long类型,另一个会转换为long类型。
否则,两个操作数都转换为int类型。
<经典> 有关自动拆箱的一些理解:
包装类在与自己对应的基本数据类型进行==、算术运算时都会进行自动拆箱;
包装类在与其他类型的数据进行==比较时不会进行自动拆箱,只有进行算数运算时才会进行自动拆箱;
包装类在进行equals方法不会处理不同数据之间的转型;
如下代码运行结果:
public class StringDemo{
private static final String MESSAGE="taobao" ;
public static void main (String [] args) {
String a ="tao" +"bao" ;
String b="tao" ;
String c="bao" ;
System.out .println(a==MESSAGE);
System.out .println((b+c)==MESSAGE);
}
}
最终运行结果为true/false;首先需要知道:字符串在java中存储在字符串常量区中 ;a和message是同一个字符串常量 ,在内存中只有一份,因此指向的是同一个地址,第一个return true;第二个b+c创建了一个新的对象,地址不一样,返回false;
Java 程序中使用赋值运算符进行对象赋值时,可以得到两个完全相同的对象 这句话是错的,因为在进行A=B赋值后,只是声明了一个新的引用指向同一个对象,并没有创建一个新的对象,此时对象仍然只有一个;
<正则经典> Java中用正则表达式截取字符串中第一个出现的英文左括号之前的字符串。比如:北京市(海淀区)(朝阳区)(西城区),截取结果为:北京市。正则表达式为():
A.".*?(?=\\()"
B.".*?(?=\()"
C .".*(?=\\()"
D .".*(?=\()"
正确答案为A。首先前面.*查找出/n以外的任意0-n个字符,然后使用了?进行了懒惰匹配 ,然后使用(?=Expression)进行顺序环视Expression对应的匹配字符 ,最后找到结果
懒惰匹配 :在正则中,有两种匹配模式,分别是贪婪模式和懒惰模式 ,其中贪婪模式表示匹配的字符越多越好,而懒惰模式表示匹配的结果字符越少越好;正则默认采用的是贪婪模式,如果想使用懒惰模式可以在匹配的正则表达式后面添加?如下:
String str = "abcaxc" ;
Pattern pat = "ab.*c" ;
String str = "abcaxc" ;
Pattetn pat = "ab.*?c" ;
环视 一共分为四种:
(?<=Expression )
逆序肯定环视,表示所在位置左侧能够匹配Expression
(?<!Expression )
逆序否定环视,表示所在位置左侧不能匹配Expression
(?=Expression )
顺序肯定环视,表示所在位置右侧能够匹配Expression
(?!Expression )
顺序否定环视,表示所在位置右侧不能匹配Expression
线程局部存储TLS技术 用于解决多线程中对同一变量的访问冲突,它会为每一个线程设置和维护一个和该线程独立绑定的变量副本,想java中的ThreadLocal类就用的是TLS技术;
就算TLS为每个线程单独设置了一个变量副本,对于一些特殊的变量仍然需要使用线程同步进行访问操作 ,比如静态变量和全局变量,对这些变量即使使用了独立的副本,操作的仍然是同一个变量;
如下代码的运行结果为:
public class Tester{
public static void main (String[] args){
Integer var1=new Integer(1 );
Integer var2=var1;
doSomething(var2);
System.out .print(var1.intValue());
System.out .print(var1==var2);
}
public static void doSomething (Integer integer){
integer=new Integer(2 );
}
}
运行结果为1true;参数的传递可以看图:
java中的引用类型变量的传递传递的只是一个引用,可以说是地址,而不是传递对象本身,接受传递的参数只是创建了一个新的对象,也指向传递过来的引用的地址;
如下代码的输出结果:
public class B
{
public static B t1 = new B();
public static B t2 = new B();
{
System.out .println("构造块" );
}
static
{
System.out .println("静态块" );
}
public static void main (String[] args)
{
B t = new B();
}
}
输出结果为 构造块 构造块 静态块 构造块 ;类的初始化执行顺序:静态块<-main<-构造块<-构造方法 ;而对于静态代码块和静态成员变量来说,他们的执行级别是一样的 ,谁先定义就先执行谁,在这里静态成员变量先声明,因此先执行静态成员变量;而此时不执行静态代码块,所以为此输出结果
JS闭包 如下程序的输出结果:
function Foo () {
var i=0 ;
return function () {
document.write(i++);
}
}
var f1=Foo(),
f2=Foo();
f1();
f1();
f2();
最终的输出结果为:010;这里的局部变量i对于f1和f2来说都是全局变量,f1和f2中的i之间又是相互独立不可见的,各自进行相关操作,又不相互影响,就类似于TLS为保证线程安全而为每一个线程设置和维护一个单独的变量副本一样
JVM经典 对于JVM的内存配置参数如下:
-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio = 3
求其最小内存值和Survivor区总的大小
Xmx表示最大堆,也就是最大内存值;Xms表示最小堆,也就是最小内存之;Xmn表示新生代;而新生代分为一个Eden和两个Survivor;最后一个参数表示Survivor与Eden的大小比值;因为Survivor有两个区,所以Survivor最终大小为5120/5=1024m,而索要求的最小内存值即Xms