第一题:
”static”关键字是什么意思ava中是否可以覆盖(override)一个private或者是static的方法/strong>
A:static表示“静态”的意思,可用于修饰成员变量和成员方法,静态成员是随着类的加载而加载的,因此可以直接使用类访问。但是要注意,在静态成员方法中,不可以调用非静态成员变量或者非静态成员方法。
B:不可以重写,也没办法重写,因为private修饰的方法只能在本类被访问,连子类也无法访问,因此重写是无法实现的,但是可以继承,绝不可以调用。
C:对于静态方法,是编译时静态绑定,而重写是为了实现多态,是动态时绑定的,并不需要重写。
静态变量被分配内存中仅仅被加载一次,是指着个静态变量在此jvm进程中仅仅加载一次,也就是为什么无论创建多少个对象都只有一个相同的静态变量。
见下列例题:
public class A {
static{
System.out.print(“1”);
}
public A(){
System.out.print(“2”);
}
}
public class B extends A {
static{
System.out.print(“a”);
}
public B(){
System.out.print(“b”);
}
}
public class Hello {
public static void main(String[] args) {
A a = new B(); // 第一步
a = new B(); // 第二步
}
}
请问
第一步单独输出结果为多少 1a2b
第二步单独输出结果为多少 2b
整个输出结果为多少 1a2b2b
第一步静态变量被加载一次,初始化一次,得出结果
第二步静态变量不被加载(jvm进程仅仅执行一次静态变量),初始化一次,仅仅有个2b,
所以加上第一步的,整个输出结果为:1a2b2b
什么是Java虚拟机什么Java被称作是“平台无关的编程语言”/strong>
因为首先 .java文件是要在jvm上面运行的,这是一个可以执行字节码文件的虚拟机进程,而Java虚拟机对应着各种平台有着不同的版本,因此可以被运行在任意平台,而字节码文件只需要运行在jvm上面,便可以执行程序。
Java虚拟机英文名是:Java Virtual Machine,简称JVM。是可以执行字节码文件的虚拟机进程。
Java源文件(.java)—-编译成(javac命令)—- Java字节码文件(.class),运行在jvm上(java命令)
JDK和JRE的区别是什么/strong>
JRE的全名为:Java Runtime Environment; 是Java运行环境,它包含了jvm和Java基础类库,是使用Java语言编写的程序运行所需要的软件环境。
JDK的全名为:Java Development kit; 是Java开发工具包,它包含了JRE,以及下列等工具
Java.exe是java虚拟机
javadoc.exe用来制作java文档
jdb.exe是java的调试器
javaprof,exe是剖析工具
是否可以在static环境中访问非static变量/strong>
(类加载机制)
不可以,因为静态成员是属于类的,它随着类的加载而加载到静态方法区内存,当类加载时,此时不一定有实例创建,没有实例就不可以访问非静态成员。
补充一点,静态成员变量只可以在类主体中定义,不能在方法中定义,即使是静态方法也不行。我是这样理解的,因为方法中定义的变量,生命周期便是方法执行完便销毁内存,但是静态变量很明显是属于类的,因此生命周期一定比局部变量的生命周期长,因此两者是相矛盾的,也就说明了,方法中不允许定义静态变量。
Java支持的数据类型有哪些么是自动拆装箱/strong>
A:Java的数据类型分为两种,
第一种是基本数据类型(又名原生态或内置类型),分类为,四类八种
整数类型 byte 1,short 2,int 4,long 8
浮点型 float 4,double 8
逻辑型 boolean 1(允许分配的最小内存是8位)
字符型 char 2 (‘u0000’)
String是属于引用类型。
第二种便是引用数据类型,包括类,接口和数组,引用数据类型就是指对一个对象的引用,也可以理解成,引用类型声明的变量,在内存中存储的实际上是地址,而实体在堆中。对象包括实例和数组两种。
B:自动装箱和拆箱是基本类型和引用类型之间的转换,可以new出对象,更好的操作数据,例如可以集合中想存放基本类型,泛型的限定类型只能是对应的包装类型。
Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思/strong>
A:覆盖是发生在父类和子类之间的状况,是子类重新定义了父类的方法。
要遵循“两同两小一大的规则”,即:
1,两同:方法名相同,形参列表相同
2,两小:子类方法返回值类型如果是引用,应是父类方法返回值类型的子类或者原类型,如果是基本类型,必须一样,子类方法声明抛出的异常应比父类方法声明跑出的异常更小或相等。
3,一大:子类方法的访问权限应比父类方法的访问权限更大或相等。
4,重写是发生在运行时期的,因为编译期编译器不知道并且没办法确定该去调用哪个方法,JVM会在代码运行的时候作出决定。
B:重载是发生一个类当中的状况
1,方法名必须相同
2,参数列表必须不同(个数不同,类型不同,排列顺序不同等)
3,和返回值类型无关
4,重载是发生在编译时期的,因为编译器是根据参数的类型来选择使用哪种方法。
以上都是为了实现多态。
Java中,什么是构造函数么是构造函数重载么是复制构造函数/strong>
A:构造函数是创建实例时将会被调用的一种特殊函数。(特殊在那一方面有返回值,不会被实例调用,而是创建实例)
B:构造函数重载和方法重载很相似,每个重载的构造函数都有着不同的形参列表,这也是在创建实例传入不同的参数来选择不同的构造器。
C:Java不支持像C++那样复制构造函数。
Java支持多继承吗/strong>
Java不支持多继承,只支持单继承,即一个子类只能有一个直接父类。但是Java中的接口支持多继承,一个子接口可以有多个父接口,一个子接口继承了多个父接口,也就扩展了多个功能,当类实现接口时,类也就相应的扩展了多个功能,这也弥补了单继承的缺点。
为什么不支持多继承的理解是,可能是怕引起混淆,如果有多个直接父类,这多个直接父类中有相同的变量或方法名,但是行为不一样(都是吃饭,用勺子和用筷子),那么在运行时,JVM也无法判断使用哪个变量或方法了,因为相同的方法可能有不同的行为,但是接口不一样,即使这多个接口含有相同的方法名, 但是因为没有方法体(也就避免了相同的方法有不同的行为),子接口继承那个父类都不是问题,这个子接口只能有这么一个方法,实现时,根据需求,在方法中填入不同的行为,也就扩展了相应的功能。
接口和抽象类的区别是什么/strong>
接口可以说是抽象类中的一种特例。
1,抽象类可以有构造方法,接口不能有构造方法。
2,抽象类可以有普通成员变量和静态成员变量,并且静态变量的访问类型可以任意,但是接口不能有普通成员变量,且成员变量默认只能为 public static final。
3,抽象类中的成员方法默认为public abstract,但是访问修饰符可以是public,protected,或者默认(不能是private,因为抽象类可以被继承),以及可以包含普通成员方法,但是接口中的抽象方法只能是public abstract。
4,抽象类中可以包含静态方法,接口类中不能包含静态方法,1.8之后可以有静态方法,不必加abstract(abstract和static不能放在一起)。
5,一个类可以实现多个接口,但只能继承一个抽象类。
6,如果子类可以没有实现抽象父类中的所有抽象方法,但是子类也必须定义为abstract类型,而接口是必须实现所有抽象方法的,否则定义为抽象类(我们平时所实现的接口其实已经实现了所有抽象方法,只是没写出来罢了)。
但是平时中,应该多用接口,少用抽象,因为软件设计讲究的是低耦合性,接口可以实现多个,但是抽象只能单继承。
什么是值传递和引用传递/strong>
值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量.
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对 象本身 。 所以对该副本进行操作时,会同时改变原对象。
final和abstract,private和abstract,static和abstract,这些是不能放在一起的修饰符
因为abstract修饰的方法是必须在其子类中实现(覆盖),才能以多态方式调用,以上修饰符在修饰方法时期子类都覆盖不了这个方法,final是不可以覆盖,private是不能够继承到子类,所以也就不能覆盖,static是可以覆盖的,但是在调用时会调用编译时类型的方法,因为调用的是父类的方法,而父类的方法又是抽象的方法,抽象方法不具备调用的意义,又不能够调用,所以上的修饰符不能放在一起。
下面这条语句一共创建了多少个对象:
String s=”a”+”b”+”c”+”d”;
(直接形成abcd,而不是先生成四个字符)
一个对象,因为像这种在编译时期就可以被编译器识别的,可以直接拼接成 String s = “abcd”; ,他和变量不同,变量相加,编译器识别不出来,只有在运行时期才知道。是相当于 StringBuffer调用append(),在堆上产生新的对象。
Error和Exception的区别是什么/strong>
Error类和Exception类的父类都是throwable类,他们的区别是:
Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误所导致的应用程序中断,仅靠程序本身无法恢复和预防。
而Exception类又分为运行时异常(Runtime Exception)和受检查的异常(Checked Exception )
运行时异常;编译能通过,但是一运行就终止了,程序不会处理运行时异常,出现这类异常,程序会直接终止。
而受检查的异常,都是可以被处理修复的异常,要么用try…catch…捕获并处理,要么抛出。
常见的异常;
– ArithmeticException(算术异常)
– ClassCastException (类转换异常)
– IllegalArgumentException (非法参数异常)
– IndexOutOfBoundsException (下标越界异常)
– NullPointerException (空指针异常)
– SecurityException (安全异常)
第异常问答题
异常处理完成以后,Exception对象会发生什么变化/strong>
Exception对象会在下一个垃圾回收过程中被回收掉。
final,finally以及finalize有什么区别/strong>
Final用于修饰属性,方法以及类,各表示属性不可改变,方法不可重写,
子类不可覆盖。
Finally是异常处理结构中的一部分,表示总是处理。
Finalize是Object类的一个方法。当垃圾回收器(garbage colector)决定回收某对象时,就会运行该对象的finalize()方法 但是在Java中,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说filalize()可能永远不被执行。
Java中实现多态的机制是什么/strong>
静态多态:重载
动态多态:重写
JAVA 语言如何进行异常处理,关键字: throws,throw,try,catch,finally 分别代表什么意义 try 块中可以抛出异常吗/strong>
Throws代表捕获并向外抛出异常。
Throw代表抛出异常,往往是throw new 自定义异常
此为有参构造
Class sextends Exception{
public 方法名(String msg)
Super(msg);
}
try…catch 内部捕获异常并作自定义处理
Finally 表示总是被执行,除非前面有System.exit(1);表示非正常退出程序。
两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对ashCode()和equals()方法的重要性体现在什么地方/strong>
答:不对,Java对于eqauls方法和hashCode方法是这样规定的:
(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
(2)如果两个对象的hashCode相同,它们并不一定相同。
其重要性体现在,hashCode用来确定位置,而equals用来比较对象是否相等,但是如果重写equals而没有重写hashCode则可能导致同一个对象没有机会equals,因为可能同一个对象有着不同的hashCode。所以hashCode和equals对hashMap的精确性比较重要。
是否可以继承String类/strong>
String 类是final类,不可以被继承。
char 型变量中能不能存贮一个中文汉字,为什么/strong>
char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode,每个Unicode码占用2个字节,而一个char类型也是占2个字节(16比特),所以放一个中文是没问题的。
String和StringBuilder、StringBuffer的区别/strong>
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
String 类代表字符串,它是位于字符串常量区;因为它的底层是用final修饰的,所以它们的值在是不可改变的。任何试图改变它的行为都会产生新的对象。
而StringBuilder和StringBuffer类似,都是字符串缓冲区,初始容量一般是16 ,长度也可以改变,但StringBuffer是线程安全的,StringBuilder不是线程安全的,如果只是在单线程中使用字符串缓冲区,那么StringBuilder的效率会更高些。
值得注意的是StringBuilder是在JDK1.5版本中增加的。以前版本的JDK不能使用该类。
JVM加载class文件的原理机制
当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。
加载class文件需要三个阶段,分别是加载、连接(验证、准备和解析)和初始化。
类的加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件。
类的加载是由类加载器完成的,类加载过程采取了委托模型机制(PDM)。PDM更好的保证了Java平台的安全性。PDM是指类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。
线程类问答
比喻来说,当你开了一个QQ,就开了一个进程,开了一个迅雷,也开了一个进程。
在QQ的这个进程里,传输文字开一个线程、传输语音开了一个线程、弹出对话框又开了一个线程
一个进程管着多个线程。
创建线程有哪几种方式喜欢哪一种什呢/strong>
就我目前所学来看,一共有两种
A:继承Thread类
B:实现Runnable接口
我比较喜欢实现Runnable接口,虽然他必须再次使用Thread类包装后才能调用start()方法,因为它是符合低耦合的要求的(但是如果一个类已经在继承其它父类的时候,因为Java不支持多继承,这时可以使用接口来完成线程的创建。)
概括的解释下线程的几种可用状态/strong>
线程的生命周期:
1:(new) 新创建一个线程对象
2: (可运行runnable)线程对象创建之后,其他线程,例如main线程调取了该对象的start()方法。该状态的线程位于可运行的线程池中,等待被分配给cpu的时间片。
3: (正在运行running)运行状态,获取cpu的时间片,执行该程序代码。
4: (其他阻塞状态)阻塞状态是指线程因为某种原因而让出了CPU的时间片,进入到可运行状态。
阻塞的三种情况:
1:等待阻塞:运行(running)的线程执行O.wait()方法,jvm会把该线程放入到等待队列中。
2:同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则jvm会把该线程放入锁池中。
3:其他阻塞:运行(running)的线程执行Thread.sleep或者Thread.join()方法,或者发出I/O请求时,jvm会把该线程置为阻塞状态。
当sleep方法超时,或者join等待线程终止或者超时,或者I/O处理完毕 后,线程重新转入可运行的状态,等待分配CPU资源。
4: 死亡(dead):线程run(),main(),方法执行结束,或者因异常退出run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
同步方法和同步代码块的区别是什么/strong>
同步方法即有synchronized关键字修饰的方法。
同步方法默认用this或者当前类class对象作为锁。
同步代码块:
synchronized(object){代码内容}
主要是修饰需要进行同步的代码块,比同步方法更颗粒度。
我们应该用同步代码块,因为要知道同步是一种高开销的操作,因此应该尽量减少同步的内容。
在监视器(Monitor)内部,是如何做到线程同步的/strong>
监视器和锁在Java虚拟机中是一块使用的,一旦方法或者代码块被synchronized修饰,那么这个部分就放入了监视器的监视区域,确保一次只能有一个线程执行该部分的代码。线程在获取锁之前不允许执行该部分代码。
线程的sleep()方法和yield()方法有什么区别/strong>
①
sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
②
线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
阻塞状态–>就绪状态–>运行状态
③
sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
④
sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。
第四十题
Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别/strong>
sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复。
wait()是Object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。
第四十一题
举例说明同步和异步。
同步:发送一个请求,等待返回,然后再发送下一个请求。(可以单线程和多线程)是属于阻塞式操作。
异步:发送一个请求,不需要等待返回,随时可以再发送下一个请求,是属于非阻塞式操作。在很多情况下采用异步途径往往更有效率。
例如正在写的数据以后可能被另一个线程读到,这是异步。
数据写完之后,另一个线程才可以读,这是同步操作。
启动一个线程是调用run()还是start()方法/strong>
启动一个新线程是调用start()方法,start内部调用run()方法,让此线程处于就绪状态。
run()方法只是Runnable接口中定义的一个普通方法。
什么是死锁/strong>
是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的状况。
产生死锁的四个条件
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
如何避免
一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。
14.Java接口的修饰符可以为()
A private B protected C final D abstract
答案:CD
关于String类的一些方法
Str.CharAt(index); –返回索引处的字符
Str.codePointAt(index); –返回索引处字符的unicode值
s1.compareTo(s2); –按字典顺序比较两个字符串,小返负,大返正,往往是以括 内的作为参考点,来返回具体数字
s1.concat(s2) –链接两个字符串
Str.endWith(“.java”); –判断是否以指定的后缀结束,返回布尔值
s1.equalsIgnoreCase(s2); –忽略大小写来比较两个字符串的内容,返回布尔值
Str.indexOf(“java”); –返回指定字符串第一次出现的索引(索引都是依旧从0开始的),如果没有,返回-1
Str.isEmpty(); –判断字符串是否为空,只有length()方法为0时才会返回true,如果是含有空格,返回false
Str.replaceAll(“共产党”,”*”); –替换String为某些内容
Str.split(“;”) –把一个有规则的String按照特定标记切分为一个String[];里面的元素便是一个字符串
Str.substring(2,10); –截取字符串,从索引2开始,到索引(10-1)结束
Str.substring(2); –截取字符串,从索引2开始,一直到末端
Str.toUpperCase(); –将字符串转换为大
Str.toLowerCase(); –将字符串转换为小
Str.trim(); –去掉前边和后边的空格,但是中间的不行
Str.replaceAll(“ ”;“”); –这样可以去掉所有的空格
Str.toCharArray(“”); –将字符串转换为字符数组
Math.round(11.5);为多少
Math.round(-11.5);为多少/p>
Math.round(x)相当于Math.floor(x+0.5);加上0.5再向下(最小数)取整就行了.
Math.floor();往最小数靠近
Math.ceil();往最大数靠近
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91438 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!