目录
假定Base b = new Derived(); 调用执行b.methodOne()后,输出结果是什么?
若采用命令行“java Test one two three”调用,则程序输出的结果为:
String s = new String(“xyz”);创建了几个StringObject?
将此对象序列化为文件,并在另外一个JVM中读取文件,进行反序列化,请问此时读出的Data0bject对象中的word和i的值分别为:
以下哪个事件会导致线程销毁?()
正确答案: D 你的答案: C (错误)
调用方法sleep()
调用方法wait()
start()方法的执行结束
run()方法的执行结束
来源:https://www.nowcoder.com/questionTerminal/e108aea70e334abc84f9001734fe3c4c
下面有关java基本类型的默认值和取值范围,说法错误的是?
正确答案: C 你的答案: C (正确)
字节型的类型默认值是0,取值范围是-2^7—2^7-1
boolean类型默认值是false,取值范围是true\false
字符型类型默认是0,取值范围是-2^15 —2^15-1
long类型默认是0,取值范围是-2^63—2^63-1
来源:https://www.nowcoder.com/questionTerminal/18f100abfe294eceb6c421d2f6501c1d
默认值 取值范围 示例
字节型 : 0 -2^7—-2^7-1 byte b=10;
字符型 : ‘ \u0000′ 0—-2^16-1 char c=’c’ ;
short : 0 -2^15—-2^15-1 short s=10;
int : 0 -2^31—-2^31-1 int i=10;
long : 0 -2^63—-2^63-1 long o=10L;
float : 0.0f -2^31—-2^31-1 float f=10.0F
double : 0.0d -2^63—-2^63-1 double d=10.0;
boolean: false true\false boolean flag=true
下列关于异常处理的描述中,错误的是()。
正确答案: D 你的答案: D (正确)
程序运行时异常由Java虚拟机自动进行处理
使用try-catch-finally语句捕获异常
可使用throw语句抛出异常
捕获到的异常只能在当前方法中处理,不能在其他方法中处理
来源:https://www.nowcoder.com/questionTerminal/aa997d8ad0c54da0ae8e0f22c00f1e0d
编译时异常必须显示处理,运行时异常交给虚拟机。
运行时异常可以不处理。当出现这样的异常时,总是由虚拟机接管。
比如我们从来没有人去处理过Null Pointer Exception异常,它就是运行时异常,并且这种异常还是最常见的异常之一。
出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。
如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。
抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,整个程序也就退出了。
运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。
只不过往往不对它处理罢了。也就是说,如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
Java的体系结构包含( )。
正确答案: A B C D 你的答案: B C D (错误)
Java编程语言
Java类文件格式
Java API
JVM
来源:https://www.nowcoder.com/questionTerminal/00f7f8eb019945e4876b724338f84f18
Java体系结构包括四个独立但相关的技术:
- Java程序设计语言
- Java.class文件格式
- Java应用编程接口(API)
- Java虚拟机
我们再在看一下它们四者的关系:
当我们编写并运行一个Java程序时,就同时运用了这四种技术,用Java程序设计语言编写源代码,把它编译成Java.class文件格式,然后再在Java虚拟机中运行class文件。当程序运行的时候,它通过调用class文件实现了Java API的方法来满足程序的Java API调用
下面有关 java 类加载器,说法正确的是?()
正确答案: A B C D 你的答案: A B C (错误)
引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的
扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。
系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类
tomcat 为每个 App 创建一个 Loader,里面保存着此 WebApp 的 ClassLoader。需要加载 WebApp 下的类时,就取出 ClassLoader 来使用
来源:https://www.nowcoder.com/questionTerminal/99bfa10e4c1e429e98856bca6d80586e
类的加载是由类加载器完成的,类加载器包括:根加载器( BootStrap )、扩展加载器( Extension )、系统加载器( System )和用户自定义类加载器( java.lang.ClassLoader 的子类)。
从 Java 2 ( JDK 1.2 )开始,类加载过程采取了父亲委托机制( PDM )。 PDM 更好的保证了 Java 平台的安全性,在该机制中, JVM 自带的 Bootstrap 是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。 JVM 不会向 Java 程序提供对 Bootstrap 的引用。下面是关于几个类加载器的说明:
- Bootstrap :一般用本地代码实现,负责加载 JVM 基础核心类库( rt.jar );
- Extension :从 java.ext.dirs 系统属性所指定的目录中加载类库,它的父加载器是 Bootstrap ;
- system class loader :又叫应用类加载器,其父类是 Extension 。它是应用最广泛的类加载器。它从环境变量 classpath 或者系统属性 java.class.path 所指定的目录中记载类,是用户自定义加载器的默认父加载器。
- 用户自定义类加载器: java.lang.ClassLoader 的子类
父类委托机制是可以修改的,有些服务器就是自定义类加载器优先的。
下列哪些操作会使线程释放锁资源?
正确答案: B C 你的答案: A C (错误)
sleep()
wait()
join()
yield()
来源:https://www.nowcoder.com/questionTerminal/3a3f308d61d0453e91ccc23bd6aff468
1.sleep会使当前线程睡眠指定时间,不释放锁
2.yield会使当前线程重回到可执行状态,等待cpu的调度,不释放锁
3.wait会使当前线程回到线程池中等待,释放锁,当被其他线程使用notify,notifyAll唤醒时进入可执行状态
4.当前线程调用 某线程.join()时会使当前线程等待某线程执行完毕再结束,底层调用了wait,释放锁
下面有关JVM内存,说法错误的是?
正确答案: C 你的答案: B (错误)
程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,是线程隔离的
虚拟机栈描述的是Java方法执行的内存模型,用于存储局部变量,操作数栈,动态链接,方法出口等信息,是线程隔离的
方法区用于存储JVM加载的类信息、常量、静态变量、以及编译器编译后的代码等数据,是线程隔离的
原则上讲,所有的对象都在堆区上分配内存,是线程之间共享的
来源:https://www.nowcoder.com/questionTerminal/2a1cdf3e61d14947bf00dfe10e25a2c0
大多数 JVM 将内存区域划分为 Method Area(Non-Heap)(方法区) ,Heap(堆) , Program Counter Register(程序计数器) , VM Stack(虚拟机栈,也有翻译成JAVA 方法栈的),Native Method Stack ( 本地方法栈 ),其中Method Area 和 Heap 是线程共享的 ,VM Stack,Native Method Stack 和Program Counter Register 是非线程共享的。为什么分为 线程共享和非线程共享的呢?请继续往下看。
首先我们熟悉一下一个一般性的 Java 程序的工作过程。一个 Java 源程序文件,会被编译为字节码文件(以 class 为扩展名),每个java程序都需要运行在自己的JVM上,然后告知 JVM 程序的运行入口,再被 JVM 通过字节码解释器加载运行。那么程序开始运行后,都是如何涉及到各内存区域的呢?
概括地说来,JVM初始运行的时候都会分配好 Method Area(方法区) 和Heap(堆) ,而JVM 每遇到一个线程,就为其分配一个 Program Counter Register(程序计数器) , VM Stack(虚拟机栈)和Native Method Stack (本地方法栈), 当线程终止时,三者(虚拟机栈,本地方法栈和程序计数器)所占用的内存空间也会被释放掉。这也是为什么我把内存区域分为线程共享和非线程共享的原因,非线程共享的那三个区域的生命周期与所属线程相同,而线程共享的区域与JAVA程序运行的生命周期相同,所以这也是系统垃圾回收的场所只发生在线程共享的区域(实际上对大部分虚拟机来说知发生在Heap上)的原因。
以下代码将打印出
1 2 3 4 |
|
正确答案: C 你的答案: B (错误)
com. jd
com/jd/MyClass.class
///MyClass.class
com.jd.MyClass
来源:https://www.nowcoder.com/questionTerminal/53ea61fdee47423fb63a71d9dd0309f4
由于replaceAll方法的第一个参数是一个正则表达式,而”.”在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成”/”。
如果想替换的只是”.”,那么就要写成”\\.”.
如果想替换的只是“.”的话,正则表达式那里就要写成“\\.”或者是“[.]”。前者将“.”转义为“.”这个具体字符,后者则匹配“[]”中的任意字符,“.”就代表具体字符“.”。
代码片段:
1 2 3 4 5 |
|
关于上面代码片段叙述正确的是()
正确答案: C 你的答案: A (错误)
输出结果:13
语句:b6=b4+b5编译出错
语句:b3=b1+b2编译出错
运行期抛出异常
来源:https://www.nowcoder.com/questionTerminal/344945bc01fd49b5beca0cf5f6edea78
被final修饰的变量是常量,这里的b6=b4+b5可以看成是b6=10;在编译时就已经变为b6=10了
而b1和b2是byte类型,java中进行计算时候将他们提升为int类型,再进行计算,b1+b2计算后已经是int类型,赋值给b3,b3是byte类型,类型不匹配,编译不会通过,需要进行强制转换。
Java中的byte,short,char进行计算时都会提升为int类型。
假定Base b = new Derived(); 调用执行b.methodOne()后,输出结果是什么?
public class Base
{
public void methodOne()
{
System.out.print("A");
methodTwo();
}
public void methodTwo()
{
System.out.print("B");
}
}
public class Derived extends Base
{
public void methodOne()
{
super.methodOne();
System.out.print("C");
}
public void methodTwo()
{
super.methodTwo();
System.out.print("D");
}
}
正确答案: A 你的答案: D (错误)
ABDC
AB
ABCD
ABC
来源:https://www.nowcoder.com/questionTerminal/b2d79f37c4f444d989d47a392147d65e
只要是被子类重写的方法,不被super调用都是调用子类方法
关于多线程和多进程,下面描述正确的是():
正确答案: A C 你的答案: B C (错误)
多进程里,子进程可获得父进程的所有堆和栈的数据;而线程会与同进程的其他线程共享数据,拥有自己的栈空间。
线程因为有自己的独立栈空间且共享数据,所有执行的开销相对较大,同时不利于资源管理和保护。
线程的通信速度更快,切换更快,因为他们在同一地址空间内。
一个线程可以属于多个进程。
来源:https://www.nowcoder.com/questionTerminal/fbe0cb97dcff4df5bf849d15cbe29e64
A.子进程得到的是除了代码段是与父进程共享以外,其他所有的都是得到父进程的一个副本,子进程的所有资源都继承父进程,得到父进程资源的副本,子进程可获得父进程的所有堆和栈的数据,但二者并不共享地址空间。两个是单独的进程,继承了以后二者就没有什么关联了,子进程单独运行;进程的线程之间共享由进程获得的资源,但线程拥有属于自己的一小部分资源,就是栈空间,保存其运行状态和局部自动变量的。
B.线程之间共享进程获得的数据资源,所以开销小,但不利于资源的管理和保护;而进程执行开销大,但是能够很好的进行资源管理和保护。
C.线程的通信速度更快,切换更快,因为他们共享同一进程的地址空间。
D.一个进程可以有多个线程,线程是进程的一个实体,是CPU调度的基本单位。
以下JAVA程序的运行结果是什么( )
public static void main(String[] args) {
Object o1 = true ? new Integer(1) : new Double(2.0);
Object o2;
if (true) {
o2 = new Integer(1);
} else {
o2 = new Double(2.0);
}
System.out.print(o1);
System.out.print(" ");
System.out.print(o2);
}
正确答案: D 你的答案: A (错误)
1 1
1.0 1.0
1 1.0
1.0 1
来源:https://www.nowcoder.com/questionTerminal/701d348fec8f4c1893740e253217a65f
三元操作符类型的转换规则:三元运算符会对两个结果的数据类型,进行自动的类型提升。
1.若两个操作数不可转换,则不做转换,返回值为Object类型
2.若两个操作数是明确类型的表达式(比如变量),则按照正常的二进制数字来转换,int类型转换为long类型,long类型转换为float类型等。
3.若两个操作数中有一个是数字S,另外一个是表达式,且其类型标示为T,那么,若数字S在T的范围内,则转换为T类型;若S超出了T类型的范围,则T转换为S类型。4.若两个操作数都是直接量数字,则返回值类型为范围较大者
符合4,所以选D.
以下哪个不能用来处理线程安全
正确答案: D 你的答案: D (正确)
synchronized关键字
volatile关键字
Lock类
transient关键字
来源:https://www.nowcoder.com/questionTerminal/dd1854a663654400ad8c54a49c664011
synchrozied关键字 称作同步,主要用来给方法、代码块加锁,被加锁的代码段,同一时间内多线程同时访问同一对象的加锁方法/代码块时,只能有一个线程执行能执行方法/代码块中的代码,其余线程必须等待当前线程执行完以后才执行该方法/代码块。
volatile关键字 1.保证了不同线程对该变量操作的内存可见性.(当一个线程修改了变量,其他使用次变量的线程可以立即知道这一修改)。2.禁止了指令重排序.
Lock接口 提供了与synchronized关键字类似的同步功能,但需要在使用时手动获取锁和释放锁。
transient关键字 简单地说,就是让某些被修饰的成员属性变量不被序列化。
如下的Java程序
public class Test {
public static void main(String[] args) {
System.out.println(args[0]);
}
}
若采用命令行“java Test one two three”调用,则程序输出的结果为:
正确答案: B 你的答案: D (错误)
Test
one
two
java
来源:https://www.nowcoder.com/questionTerminal/fb0b258bc80b4da0bdfea52818389c23
采用命令行“ java Test one two three ”调用
其中Test为调用的方法,而one two three则为Test方法里面main函数的参数;
System.out.println(args[0]);表示输出第一个元素,故为one;
This调用语句必须是构造函数中的第一个可执行语句。
正确答案: B 你的答案: A (错误)
正确
错误
来源:https://www.nowcoder.com/questionTerminal/c051336317bd4a2f99eccb0913d0c965
this()和super()为构造方法,作用是在JVM堆中构建出一个对象。
因此避免多次创建对象,同一个方法内只能调用一次this()或super()。
同时为了避免操作对象时对象还未构建成功,需要this()和super()的调用在第一行实现【以此来创建对象】,防止异常。
String s = new String(“xyz”);创建了几个StringObject?
正确答案: A 你的答案: C (错误)
两个或一个都有可能
两个
一个
三个
来源:https://www.nowcoder.com/questionTerminal/644933ebcb814fc3a99c8533b8ac6301
String str2 = new String(“aaa”) ; 一共会创建两个字符串对象 一个在堆中,一个在常量池中(前提是常量池中还没有 “aaa” 字符串对象)。
public class DataObject implements Serializable{
private static int i=0;
private String word=" ";
public void setWord(String word){
this.word=word;
}
public void setI(int i){
Data0bject. i=I;
}
}
创建一个如下方式的DataObject:
DataObject object=new Data0bject ( );
object. setWord("123");
object. setI(2);
将此对象序列化为文件,并在另外一个JVM中读取文件,进行反序列化,请问此时读出的Data0bject对象中的word和i的值分别为:
正确答案: D 你的答案: C (错误)
"", 0
"", 2
"123", 2
"123", 0
来源:https://www.nowcoder.com/questionTerminal/cbec6a41dc75420eb4f909a5fd4652bf
序列化的是对象,不是类,类变量不会被序列化