Java 笔试拾遗(1)
1.Java读取文件
(1)"“这个符号在中英文环境下是不一样的显示,所以需要转义——“c:\my\1.txt” ;
(2)而”/"在中英文环境下是相同的显示——“c:/my/1.txt” 。
2. JAVA的垃圾回收机制
java提供了一个系统级的线程:垃圾回收线程。用来对每一个分配出去的内存空间进行跟踪。当JVM空闲时,自动回收每块可能被回收的内存,GC是完全自动的,不能被强制执行。程序员最多只能用System.gc()来建议执行垃圾回收器回收内存,具体的回收时间不可知。当对象的引用变量被赋值为null,可能被当成垃圾。
3.两个最基本的java回收算法:复制算法和标记清理算法
(1)复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法
(2)标记清理:一块区域,标记可达对象(可达性分析),然后回收不可达对象,会出现碎片,那么引出标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象
新生代:初始对象,生命周期短的
永久代:长时间存在的对象
整个java的垃圾回收是新生代和年老代的协作,这种叫做分代回收。
新生代基本采用复制算法,老年代采用标记整理算法。
4.java的线程转换
5.类和接口
(1)类可以实现多个接口,接口可以继承(或扩展)多个接口;
(2)类与类之间的关系为继承,只能单继承,但可以多层继承。 类与接口之间的关系为实现,既可以单实现,也可以多实现;
(3)接口与接口之间的关系为继承,既可以单继承,也可以多继承。
6.如果int x=20, y=5,则语句System.out.println(x+y +""+(x+y)+y); 的输出结果是?
答案为25 255
解析:
1)不论有什么运算,小括号的优先级都是最高的,先计算小括号中的运算,得到x+y +""+25+y
2)任何字符与字符串相加都是字符串,但是是有顺序的,字符串前面的按原来的格式相加,字符串后面的都按字符串相加,得到25+“”+25+5
3)上面的结果按字符串相加得到25 255
7.Object 是引用数据类型,只申明而不创建实例,只会在栈内存中开辟空间,默认为空;成员变量有初始值,而局部变量没有初始值得。变量若没有初始值就使用的话,编译通不过。
8.初始化顺序:
(1).先父类,后子类
(2).先属性,后构造函数
(3).先静态,后非静态
(4).先静态属性,后静态代码块
(5).同一类型(非数据类型),按代码先后顺序
下面是例1
public class Test{
static int cnt = 6;
static{
cnt += 9;
}
public static void main(String[] args){
System.out.println(“cnt =” + cnt);
}
static{
cnt /=3;
};
}
输出
Cnt=5
例2
class A {
public A() {
System.out.println("class A");
}
{ System.out.println("I'm A class"); }
static { System.out.println("class A static"); }
}
public class B extends A {
public B() {
System.out.println("class B");
}
{ System.out.println("I'm B class"); }
static { System.out.println("class B static"); }
public static void main(String[] args) {
new B();
}
}
输出
class A static //先父类
class B static //后子类
I'm A class //先属性
class A // 后构造函数
I'm B class
class B
一个更好记得优先级规则:
父类静态代码块>子类静态代码块>父类非静态代码块>父类构造函数>子类非静态代码块>子类构造函数
9.一个关于存储和变量的题目
class Value{
public int i=15;
}
public class Test{
public static void main(String argv[]){
Test t=new Test( );
t.first( );
}
public void first( ){
int i=5;
Value v=new Value( );
v.i=25;
second(v,i);
System.out.println(v.i);
}
public void second(Value v,int i){
i = 0;
v.i = 20;
Value val = new Value( );
v = val;
System.out.println(v.i+" "+i);
}
}
输出
15 0 20
解析:
现在我们把second()换一下
public void second(Value tmp,inti){
i = 0;
tmp.i = 20;
Value val = new Value( );
tmp = val;
System.out.println(tmp.i+" "+i);
}
这个tmp其实相当于是一个指向原来first中的V这个对象的指针,也就是对v对象的引用而已。但是引用是会改变所指的地址的值的。
所以在second中当tmp.i= 20的时候,就把原来first中的v的i值改为20了。接下来,又把tmp指向了新建的一个对象,所以在second中的tmp
现在指的是新的对象val,i值为15.
当执行完毕second后,在first中在此输出v.i的时候,应为前面second中已经把该位置的i的值改为了20,所以输出的是20.
至于v指向了val,其实只是名字的问题(很像考研数学中的积分变量很相似),在second中的v也是另外的一个变量,名字相同了而已,这个估计也是纠结的重点。