1.下列InputStream类中哪个方法可以用于关闭流?
-
close方法用来关闭流
-
skip()用来跳过一些字节
-
mark()用来标记流
-
reset()复位流
2.Java Application 源程序的主类是指包含有( )方法的类。
-
public static void main方法
-
java程序种类:
1.内嵌于web文件中,有浏览器观看的applet
2.可独立运行的application
3.服务器端的servlets
3.不考虑反射,关于私有访问控制符 private 修饰的成员变量,以下说法正确的是()
-
只能被该类自身所访问和修改
4.下面关于依赖注入(DI)的说法不正确的是()
-
只有通过Spring才能实现依赖注入(DI)(不正确)
- 原因:依赖注入是一种思想,或者说是一种设计模式,在java中是通过反射机制实现,与具体框架无关。
-
Spring依赖注入(DI)的三种方式,分别为:
1. 接口注入
2. Setter 方法注入
3. 构造方法注入
5.请问以下程序执行的结果是()
public class Test{
public String name="abc";
public static void main(String[] args){
Test test=new Test();
Test testB=new Test();
System.out.println(test.equals(testB)+","+test.name.equals(testB.name));
}
}
- false,true
- equals没重写时候和 == 一样,比较的是对象的地址,题中 new 了两个对象,所以各自地址不一样,使用equals比较为false;但是string类型中的equals方法Java默认重写了,可以比较对象里的值;两个对象指向的同一个string成员变量里的值相同,所以eqauals比较也相同。
6.下列关于java 中的 wait()方法和 sleep()方法的区别描述错误的是?
-
sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线程(错误)
-
sleep和wait的区别有: 1. 这两个方法来自不同的类,wait()方法属于Object类,sleep()属于Thread类 2. 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得敏感词线程可以使用同步控制块或者方法。 调用wait()方法的时候,线程会放弃对象锁;调用wait()方法的时候,线程会放弃对象锁。 3. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在 任何地方使用 synchronized(x){ x.notify() //或者wait() } 4. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
7.关于修饰符混用的说法
-
abstract不能与final并列修饰同一个类
-
abstract类中不应该有private的成员
-
abstract方法必须在abstract类或接口中;一个类若有抽象方法,其本身也必须声明为抽象类;接口中的方法默认就是public abstract;综上所诉:abstract方法必须在abstract类或接口中。
- static方法中能处理非static的属性 错误 :在JVM中static方法在静态区,静态区无法调用非静态区属性
8.执行完以下代码 int [ ] x = new int[10] ;后,
-
x[9]为0
- 数组引用类型的变量的默认值为 null。当数组变量的实例后,如果没有没有显式的为每个元素赋值,Java 就会把该数组的所有元素初始化为其相应类型的默认值。int型的默认值为0。
9.一个Java源程序文件中定义几个类和接口,则编译该文件后生成几个以.class为后缀的字节码文件。
在java中一个unicode占2个字节(byte)。
10.对于JVM内存配置参数:-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3,其最小内存值和Survivor区总大小分别是()
-
-Xmx:最大堆大小
-Xms:初始堆大小
-Xmn:年轻代大小
-XXSurvivorRatio:年轻代中Eden区与Survivor区的大小比值
年轻代5120m, Eden:Survivor=3,Survivor区大小=1024m(Survivor区有两个,即将年轻代分为5份,每个Survivor区占一份),总大小为2048m。
-Xms初始堆大小即最小内存值为10240m
11.true、false、null都不是关键字;goto、const、native、this是保留的关键字。true和false看起来像关键字,但严格来说,它们是boolean常量;null看起来也像关键字,但严格来说,它是null常量。
12.对于构造方法,下列叙述正确的是( )
-
构造方法的优先级一般比代码块低。
-
构造方法的主要作用是完成对类的对象的初始化工作。
-
一般在创建新对象时,系统会自动调用构造方法。
- 构造方法没有返回值类型,也不写void
13.以下哪些类是线程安全的()
-
A,Vector相当于一个线程安全的List
B,HashMap是非线程安全的,其对应的线程安全类是HashTable
C,Arraylist是非线程安全的,其对应的线程安全类是Vector
D,StringBuffer是线程安全的,相当于一个线程安全的StringBuilder
E,Properties实现了Map接口,是线程安全的
14.Java语言中,如果"xyz"没有被创建过,String s =new String(“xyz”);创建了几个string object?
- 2
-
对于这句代码,可分为两个过程:jvm 首先在字符串常量池内里面看看找不找到字符串"xyz";找到,进入第二步;否则,创建新的 String 对象,并“放到”字符串常量池里面;然后由于遇到了 new,还会在堆创建 String 对象,其实是拷贝的常量池的那个,拷贝比创建快。最后将其返回给 s1。
-
将
new String("xyz")
拆分为new String()
和"xyz"
如果写在类方法里,请参考前面的类加载,就是相比之下提前驻留了吧。
15.以下代码执行的结果显示是多少()?
public class Test {
public static void main(String[] args){
System.out.print(getNumber(0));
System.out.print(getNumber(1));
System.out.print(getNumber(2));
System.out.print(getNumber(4));
}
public static int getNumber(int num){
try{
int result = 2 / num;
return result;
}catch (Exception exception){
return 0;
}finally{
if(num == 0){
return -1;
}
if(num == 1){
return 1;
}
}
}
}
- -110
-
try,catch,finally中:
num=0,捕获异常,执行catch语句,catch中返回0,执行finally语句,finally语句中返回-1,于是返回finally中的-1;
num=1,try中返回2,执行finally语句,finally语句中返回1,于是返回finally中的1;
num=2,try中返回1,执行finally语句,finally语句中没有返回,于是返回try中的1;
num=4,try中返回0,执行finally语句,finally语句中没有返回,于是返回try中的0。
-
finally中return语句会覆盖try-catch中的return语句
16.下面函数将返回?
public static int func (){
try{
return 1;
}catch (Exception e){
return 2;
}finally{
return 3;
}
}
- 3
-
finally一定会执行的,有两种情况:
1.finally中有return语句,当try执行到return时会执行finally中的代码,其中有return 就直接返回了,如题,返回值为3;
2.finally中不含return语句,那么当执行到return时,它会被保存等待finally执行完毕后返回,这个时候无论finally内部如何改变这个值,都不会影响返回结果!如:
int i = 0 ;
int test(){
try {
return i;
} catch (Exception e) {
return -1;
}finally{
i++;
}
}
//output: 0
17.有以下类定义:
abstract class Animal{
abstract void say();
}
public class Cat extends Animal{
public Cat(){
System.out.printf("I am a cat");
}
public static void main(String[] args) {
Cat cat=new Cat();
}
}
运行后:
-
Animal能编译,Cat不能编译
-
包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可以拥有成员变量和普通的成员方法。注意,抽象类和普通类的主要有三点区别:
1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
2)抽象类不能用来创建对象;
3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
-
基类是抽象类,子类继承父类,但是没有实现基类的抽象方法,那么子类也是抽象类。抽象类不能创建对象,所以在主函数中创建对象编译不会通过。
18.指出以下程序运行的结果是:
public class Example{
String str=new String("good");
char[]ch={'a','b','c'};
public static void main(String args[]){
Example ex=new Example();
ex.change(ex.str,ex.ch);
System.out.print(ex.str+" and ");
System.out.print(ex.ch);
}
public void change(String str,char ch[]){
//引用类型变量,传递的是地址,属于引用传递。
str="test ok";
ch[0]='g';
}
}
-
good and gbc
-
1、java语言参数之间只有值传递,包括按值调用和按引用调用。 一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。
按值调用:包括八大基本数据类型都是按值调用。传值的时候,也就是说方法得到的是所有参数值的一个拷贝。
按引用调用:数组、对象。传值时候,传递的是引用地址的拷贝,但是都是指向同一个对象。
2、String是不可变类(final and Immutable),这里只是把副本的指向修改成指向“test ok”,原地址str的指向的值没有发生改变。
19.检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。
public class HelloB extends HelloA
{
public HelloB() {
}
{
System.out.println("I’m B class");
}
static {
System.out.println("static B");
}
public static void main(String[] args) {
new HelloB();
}
}
class HelloA {
public HelloA() {
}
{
System.out.println("I’m A class");
}
static {
System.out.println("static A");
}
}
-
static A static B I’m A class I’m B class
- 其中涉及:静态初始化代码块、构造代码块、构造方法
当涉及到继承时,按照如下顺序执行:
1、执行父类的静态代码块
static {
System.out.println("static A");
}
输出:static A
2、执行子类的静态代码块
static {
System.out.println("static B");
}
输出:static B
3、执行父类的构造代码块
{
System.out.println("I’m A class");
}
输出:I'm A class
4、执行父类的构造函数
public HelloA() {
}
输出:无
5、执行子类的构造代码块
{
System.out.println("I’m B class");
}
输出:I'm B class
6、执行子类的构造函数
public HelloB() {
}
输出:无
那么,最后的输出为:
static A
static B
I'm A class
I'm B class
20.this()和super()为构造方法,作用是在JVM堆中构建出一个对象。因此避免多次创建对象,同一个方法内只能调用一次this()或super()。同时为了避免操作对象时对象还未构建成功,需要this()和super()的调用在第一行实现【以此来创建对象】,防止异常。
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存。
在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。
引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候(比如先前的引用变量x=null时),才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因。
总结起来就是对象存储在堆内存,引用变量存储在栈内存。栈内存指向堆内存。
21.下面赋值语句中正确的是()
-
java中整型默认的是int,浮点默认的是double. float f=11.1;//double类型的11.1 转成 float,是需要强制转换的 int i=0.0;//double类型的0.0 转成 int,也是需要强制转换的 Double oD=3;//int 转为封装类型Double,是无法编译的;Double oD = 3.0, 会把double类型的3.0自动装箱为Double,没有问题
22.以下代码执行的结果是多少()?
public class Demo {
public static void main(String[] args) {
Collection<?>[] collections =
{new HashSet<String>(), new ArrayList<String>(), new HashMap<String, String>().values()};
Super subToSuper = new Sub();
for(Collection<?> collection: collections) {
System.out.println(subToSuper.getType(collection));
}
}
abstract static class Super {
public static String getType(Collection<?> collection) {
return "Super:collection";
}
public static String getType(List<?> list) {
return "Super:list";
}
public String getType(ArrayList<?> list) {
return "Super:arrayList";
}
public static String getType(Set<?> set) {
return "Super:set";
}
public String getType(HashSet<?> set) {
return "Super:hashSet";
}
}
static class Sub extends Super {
public static String getType(Collection<?> collection) {
return "Sub"; }
}
}
-
Super:collection Super:collection Super:collection
-
考察点1:重载静态多分派——根据传入重载方法的参数类型,选择更加合适的一个重载方法
-
考察点2:static方法不能被子类覆写,在子类中定义了和父类完全相同的static方法,则父类的static方法被隐藏,Son.staticmethod()或new Son().staticmethod()都是调用的子类的static方法,如果是Father.staticmethod()或者Father f = new Son(); f.staticmethod()调用的都是父类的static方法。
考察点3:此题如果都不是static方法,则最终的结果是A. 调用子类的getType,输出collection
23.假设如下代码中,若t1线程在t2线程启动之前已经完成启动。代码的输出是()
public static void main(String[]args)throws Exception {
final Object obj = new Object();
Thread t1 = new Thread() {
public void run() {
synchronized (obj) {
try {
obj.wait();
System.out.println("Thread 1 wake up.");
} catch (InterruptedException e) {
}
}
}
};
t1.start();
Thread.sleep(1000);//We assume thread 1 must start up within 1 sec.
Thread t2 = new Thread() {
public void run() {
synchronized (obj) {
obj.notifyAll();
System.out.println("Thread 2 sent notify.");
}
}
};
t2.start();
}
-
Thread 2 sent notify. Thread 1 wake up
- 执行obj.wait();时已释放了锁,所以t2可以再次获得锁,然后发消息通知t1执行,但这时t2还没有释放锁,所以肯定是执行t2,然后释放锁,之后t1才有机会执行。