Java牛客题(1)

对应的知识点 后面写都有对应的哪些题:
修饰范围:

1、下列关于Java中类的构造方法的描述,正确的是(B)
A.构造方法的返回类型为void
B.可以定义一个类而在代码中不写构造方法。
C.在同一个类中定义的重载构造方法不可以相互调用。
D.子类不允许调用父类的构造方法。
解析:
c.构造器可以重载,而且可以使用super()、this()相互调用
d.每个构造器的默认第一行都是super(),但是一旦父类中没有无参构造,必须在子类的第一行显式的声明调用哪一个构造。

2、在异常处理中,如释放资源,关闭数据库、关闭文件应由(C )语句来完成
A.try子句
B.catch子句
C.finally子句
D.throw子句
解析:
try:可能发生异常的语句
catch:捕获,并处理异常(printStackTrace()用来跟踪异常事件发生时执行堆栈的内容)
throw:方法内部抛异常
throws:声明方法异常
finaly:代码中无论是否有异常都会执行,清除资源

3、Thread. sleep()是否会抛出checked exception?
会;Thread.sleep() 和 Object.wait(),都可以抛出 InterruptedException。这个异常是不能忽略的,因为它是一个检查异常(checked exception)

checked exception:指的是编译时异常,该类异常需要本函数必须处理的,用try和catch处理,或者用throws抛出异常,然后交给调用者去处理异常。
runtime exception:指的是运行时异常,该类异常不必须本函数必须处理,当然也可以处理。
Thread.sleep()抛出的InterruptException属于checked exception;IllegalArgumentException属于Runtime exception;

4、下面代码运行结果是(C)

public class Test{	
	public int add(int a,int b){	
		try {	
	       return a+b;		
	    } 
	    catch (Exception e) {	
           System.out.println("catch语句块");	
        }	
        finally{
           System.out.println("finally语句块");	
        }	
	        return 0;	
	} 
	 public static void main(String argv[]){ 
	      Test test =new Test(); 
          System.out.println("和是:"+test.add(9, 34)); 
     }
}

A.catch语句块
 和是:43
B.编译异常
C.finally语句块
 和是:43
D.和是:43
 finally语句块
解析:
先来看一段代码:

public abstract class Test {
    public static void main(String[] args) {
        System.out.println(beforeFinally());
    }
    
    public static int beforeFinally(){
        int a = 0;
        try{
            a = 1;
            return a;
        }finally{
            a = 2;
        }
    }
}
/**output:
1
*/

从结果上看,貌似finally 里的语句是在return 之后执行的,其实不然,实际上finally 里的语句是在在return 之前执行的。那么问题来了,既然是在之前执行,那为什么a 的值没有被覆盖了?
实际过程是这样的:当程序执行到try{}语句中的return方法时,它会干这么一件事,将要返回的结果存储到一个临时栈中,然后程序不会立即返回,而是去执行finally{}中的程序, 在执行a = 2时,程序仅仅是覆盖了a的值,但不会去更新临时栈中的那个要返回的值 。执行完之后,就会通知主程序“finally的程序执行完毕,可以请求返回了”,这时,就会将临时栈中的值取出来返回。这下应该清楚了,要返回的值是保存至临时栈中的。
再来看一个例子,稍微改下上面的程序:

public abstract class Test {
    public static void main(String[] args) {
        System.out.println(beforeFinally());
    }
    
    public static int beforeFinally(){
        int a = 0;
        try{
            a = 1;
            return a;
        }finally{
            a = 2;
            return a;
        }
    }
}
/**output:
2
*/

在这里,finally{}里也有一个return,那么在执行这个return时,就会更新临时栈中的值。同样,在执行完finally之后,就会通知主程序请求返回了,即将临时栈中的值取出来返回。故返回值是2.

5、protected访问权限要小于包访问权限。(×)
Java类成员的访问控制权限:
public > protected > 默认(包访问权限) > private
在这里插入图片描述
6、以下哪个不是Collection的子接口? D
A.List
B.Set
C.SortedSet
D.Map
解析:
Collection主要的子接口:
List:可以存放重复内容
Set:不能存放重复内容,所有重复的内容靠hashCode()和equals()两个方法区分
Queue:队列接口
SortedSet:可以对集合中的数据进行排序

Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
7、以下说法错误的是(D)
A.虚拟机中没有泛型,只有普通类和普通方法
B.所有泛型类的类型参数在编译时都会被擦除
C.创建泛型对象时请指明类型,让编译器尽早的做参数检查
D.泛型的类型擦除机制意味着不能在运行时动态获取List中T的实际类型
解析:
1、创建泛型对象的时候,一定要指出类型变量T的具体类型。争取让编译器检查出错误,而不是留给JVM运行的时候抛出类不匹配的异常。
2、JVM如何理解泛型概念 —— 类型擦除。事实上,JVM并不知道泛型,所有的泛型在编译阶段就已经被处理成了普通类和方法。 处理方法很简单,我们叫做类型变量T的擦除(erased) 。
总结:泛型代码与JVM
① 虚拟机中没有泛型,只有普通类和方法。
② 在编译阶段,所有泛型类的类型参数都会被Object或者它们的限定边界来替换。(类型擦除)
③ 在继承泛型类型的时候,桥方法的合成是为了避免类型变量擦除所带来的多态灾难。 无论我们如何定义一个泛型类型,相应的都会有一个原始类型被自动提供。原始类型的名字就是擦除类型参数的泛型类型的名字。

8、以下关于final关键字说法错误的是(A、C)
A.final是java中的修饰符,可以修饰类、接口、抽象类、方法和属性
B.final修饰的类不能被继承
C.final修饰的方法不能被重载
D.final修饰的变量不允许被再次赋值
解析:
1.final修饰变量,则等同于常量
2.final修饰方法中的参数,称为最终参数。
3.final修饰类,则类不能被继承
4.final修饰方法,则方法不能被重写。

final 不能修饰抽象类
final修饰的方法可以被重载 但不能被重写

9、局部变量能否和成员变量重名? A
A.可以,局部变量可以与成员变量重名,这时可用“this”来指向成员变量
B.可以,这时可用“local”关键字来指向局部变量
C.不能,局部变量不能与成员变量重名
D.不能,在一个类中不能有重名变量,不管是成员变量还是函数中的局部变量
解析:
局部变量可以和成员变量重名,不加“this”修饰时,优先使用最近的变量。
在这里插入图片描述
10、下列哪些语句关于内存回收的说明是正确的? (B)
A.程序员必须创建一个线程来释放内存
B.内存回收程序负责释放无用内存
C.内存回收程序允许程序员直接释放内存
D.内存回收程序可以在指定的时间释放内存对象
解析:
a、JVM一旦启动,就会创建一个守护线程来监测是否需要有对象内存被释放。
c、无法直接释放。
d、不可以指定时间,System.gc(),只是提醒JVM可以进行一次Full GC,但是什么时候真正执行,还是不知道的。
在这里插入图片描述
11、下面有关Java final的基本规则,描述错误的是? B
A.final修饰的类不能被继承
B.final修饰的成员变量只允许赋值一次,且只能在类方法赋值
C.final修饰的局部变量即为常量,只能赋值一次。
D.final修饰的方法不允许被子类覆盖
解析:
final修饰的成员变量为基本数据类型是,在赋值之后无法改变。当final修饰的成员变量为引用数据类型时,在赋值后其指向地址无法改变,但是对象内容还是可以改变的。
final修饰的成员变量在赋值时可以有三种方式:
1、在声明时直接赋值。2、在构造器中赋值。3、在初始代码块中进行赋值。

12、以下代码的输出的正确结果是 D

public class Test {
	public static void main(String args[]) {
		String s = "祝你考出好成绩!";
		System.out.println(s.length());
	}
}

A.24
B.16
C.15
D.8
解析:
length得到的是字符,不是字节。
如果是s.getBytes(“GBK”).length就是求的字节数。如果是GBK,一个中文字符占2字节,如果是UTF-8则是3个字节

13、下列关于final、finally、finalize说法正确的是(ABD)
A.final可以用来修饰类、方法、变量
B.finally是java保证重点代码一定要被执行的一种机制
C.变量被final修饰后不能再指向其他对象,但可以重写
D.finalize设计的目的是保证对象在被垃圾收集前完成特定资源的回收
解析:
(1)final用于声明属性、方法和类:
final属性不可变,指的是引用不可变,而不关心指向对象内容的变化,被final修饰的变量必须初始化
final方法不可被子类重写,可以实现inline(内联)的机制
final类不可以被继承(如String、StringBuffer),所有的方法不可以被重写,但其内的非final变量可以被修改

(2)finaally作为异常处理的一部分,只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定被执行(特殊情况不会被执行,如try语句前出现异常或try语句块中出现的异常没有被捕获),经常被用在需要释放资源的情况下或是释放锁
(3)finalize是Object类的一个方法,在垃圾回收器执行时会调用被回收对象的finalize()方法,可以覆盖此方法来实现对其他资源的回收(一旦垃圾回收器准备好释放对象占用的空间,将首先调用该方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存),从功能上来说,finalize()方法与c++中的析构函数比较相似,但是Java采用的是基于垃圾回收器的自动内存管理机制,所以finalize()方法在本质上不同于C++中的析构函数

关于finalize的补充!

判定一个对象objA是否可回收,至少要经历两次标记过程:
如果对象objA到GC Roots没有引用链,则进行第一次标记。
进行筛选,判断此对象是否有必要执行finalize()方法
如果对象objA没有重写finalize()方法,或者finalize()方法已经被虚拟机调用过,则虚拟机视为“没有必要执行”,objA被判定为不可触及的。
如果对象objA重写了finalize()方法,且还未执行过,那么objA会被插入到F-Queue队列中,由一个虚拟机自动创建的、低优先级的Finalizer线程触发其finalize()方法执行。
finalize()方法是对象逃脱死亡的最后机会,稍后GC会对F-Queue队列中的对象进行第二次标记。如果objA在finalize()方法中与引用链上的任何一个对象建立了联系,那么在第二次标记时,objA会被移出“即将回收”集合。之后,对象会再次出现没有引用存在的情况。在这个情况下,finalize方法不会被再次调用,对象会直接变成不可触及的状态,也就是说,一个对象的finalize方法只会被调用一次。

14、true、false、null、sizeof、goto、synchronized 哪些是Java关键字?
   goto、synchronized
在这里插入图片描述
15、以下关于继承的叙述正确的是(A)
A、在Java中类只允许单一继承
B、在Java中一个类不能同时继承一个类和实现一个接口
C、在Java中接口只允许单一继承
D、在Java中一个类只能实现一个接口
解析:
一个类可以实现多个接口,用逗号分隔
若又继承又实现时,应先继承后实现(先亲爹后干爹)
继承: 超类是亲爹,只能有一个
    一个超类可以有多个派生类(子类),
   一个派生类只能有一个超类(父类)
接口: 接口是干爹,可以有多个

接口可以继承接口(可以继承多个接口)

16、若所用变量都已正确定义,以下选项中,非法的表达式是(C)
A、a!= 4||b==1
B、’a’ % 3
C、’a’ = 1/3
D、’A’ + 32
解析:
‘a’是char类型,1/3是int类型。将int赋值给char属于从高向低赋值,所以错误
整数直接量(int型)可以赋值给byte,short,char,但不能超出范围

17、在异常处理中,若try中的代码可能产生多种异常则可以对应多个catch语句,若catch中的参数类型有父类子类关系,此时应该将父类放在后面,子类放在前面。
      正确
解析:所有异常都是Exception的子类

18、如果要导入一个java.scut.computer的包,叙述正确的是? (A)
A、只需在代码中加入“package java.scut.computer;”一个语句,并且必须放在代码非注释的第一行
B、只需在代码中加入“package java.scut;”一个语句
C、必须在代码中加入“package java.scut;”和“package java.scut.computer;”两个语句
D、在代码中,不一定是第一句,只要是类定义前,加入package语句即可
解析:

19、以下哪个区域不属于新生代?(C)
A、eden区
B、from区
C、元数据区
D、to区
解析:
Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。
在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。
这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。
堆的内存模型大致为:
在这里插入图片描述
从图中可以看出: 堆大小 = 新生代 + 老年代。

20、以下是java concurrent包下的4个类,选出差别最大的一个(C)
A、Semaphore
B、ReentrantLock
C、Future
D、CountDownLatch
解析:
A、Semaphore:类,控制某个资源可被同时访问的个数;
B、ReentrantLock:类,具有与使用synchronized方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大;
C、 Future:接口,表示异步计算的结果;
D、 CountDownLatch: 类,可以用来在一个线程中等待多个线程完成任务的类

21、根据以下接口和类的定义,要使代码没有语法错误,则类Hero中应该定义方法(D)

interface Action{  
    void fly();  
}

class Hero implements Action{  //……  } 

A、private void fly(){}
B、void fly(){}
C、protected void fly(){}
D、public void fly(){}
解析:
接口方法默认是public abstract的,且实现该接口的类中对应的方法的可见性不能小于接口方法的可见性,因此也只能是public的

22、静态内部类不可以直接访问外围类的非静态数据,而非静态内部类可以直接访问外围类的数据,包括私有数据。
      正确
解析:
在这里插入图片描述
总的来说一下内部类:

  1. 静态内部类:
    1. 静态内部类本身可以访问外部的静态资源,包括静态私有资源。但是不能访问非静态资源,可以不依赖外部类实例而实例化。
  2. 成员内部类:
    1. 成员内部类本身可以访问外部的所有资源,但是自身不能定义静态资源,因为其实例化本身就还依赖着外部类。
  3. 局部内部类:
    1. 局部内部类就像一个局部方法,不能被访问修饰符修饰,也不能被static修饰。
    2. 局部内部类只能访问所在代码块或者方法中被定义为final的局部变量。
  4. 匿名内部类:
    1. 没有类名的内部类,不能使用class,extends和implements,没有构造方法。
    2. 多用于GUI中的事件处理。
    3. 不能定义静态资源
    4. 只能创建一个匿名内部类实例。
    5. 一个匿名内部类一定是在new后面的,这个匿名类必须继承一个父类或者实现一个接口。
    6. 匿名内部类是局部内部类的特殊形式,所以局部内部类的所有限制对匿名内部类也有效。

23、 现有如下代码段:

   x = 2;
   while(x<n/2) 
          x = 2*x;

假设n>=0,则其时间复杂度为(A)
A、O(log(n))
B、O(nlog(n))
C、O(n)
D、O(n^2)
解析:
在这里插入图片描述24、下面哪种情况会导致持久区Jvm堆内存溢出(C)
A、循环上万次的字符串处理
B、在一段代码内申请上百M甚至上G的内存
C、使用CGLib技术直接操作字节码运行,生成大量的动态类
D、不断创建对象
解析:
简单的来说 java的堆内存分为两块:permantspace(持久带) 和 heap space。
持久带中主要存放用于存放静态类型数据,如 Java Class, Method 等, 与垃圾收集器要收集的Java对象关系不大。
而heapspace分为年轻带和年老带
年轻代的垃圾回收叫 Young GC, 年老代的垃圾回收叫 Full GC。
在年轻代中经历了N次(可配置)垃圾回收后仍然存活的对象,就会被复制到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象
年老代溢出原因有 循环上万次的字符串处理、创建上千万个对象、在一段代码内申请上百M甚至上G的内存,既A B D选项
持久代溢出原因 动态加载了大量Java类而导致溢出

25、下列不属于Java语言性特点的是(D)
A、Java致力于检查程序在编译和运行时的错误
B、Java能运行虚拟机实现跨平台
C、Java自己操纵内存减少了内存出错的可能性
D、Java还实现了真数组,避免了覆盖数据类型的可能
解析:
Java致力于检查程序在编译和运行时的错误。
Java虚拟机实现了跨平台接口
类型检查帮助检查出许多开发早期出现的错误。
Java自己操纵内存减少了内存出错的可能性。
Java还实现了真数组,避免了覆盖数据的可能。
注意,是避免数据覆盖的可能,而不是数据覆盖类型

25、若需要定义一个类,下列哪些修饰符是允许被使用的?(ACD)
A、static
B、package
C、private
D、public
解析:
普通类(外部类):只能用public、abstract、final、default(不写)修饰。
(成员)内部类:可理解为外部类的成员,所以修饰类成员的public、protected、private、static、default(不写)等关键字都能使用。
局部内部类:出现在方法里的类,不能用上述关键词来修饰。
匿名内部类:给的是直接实现,类名都没有,没有修饰符。

26、以下代码可以使用的修饰符是:(ABD)

public interface Status {
 /*INSERT CODE HERE*/  int MY_VALUE=10;
 }

A、final
B、static
C、abstract
D、public
解析:
接口中字段的修饰符:public static final default(默认不写)
接口中方法的修饰符:public abstract default(默认不写)

abstract只能修饰类和方法,不能修饰字段

27、关于Java中的ClassLoader下面的哪些描述是错误的:(BDF)
A、默认情况下,Java应用启动过程涉及三个ClassLoader: Boostrap, Extension, System
B、一般的情况不同ClassLoader装载的类是不相同的,但接口类例外,对于同一接口所有类装载器装载所获得的类是相同的
C、类装载器需要保证类装载过程的线程安全
D、ClassLoader的loadClass在装载一个类时,如果该类不存在它将返回null
E、ClassLoader的父子结构中,默认装载采用了父优先
F、所有ClassLoader装载的类都来自CLASSPATH环境指定的路径
解析:
A、Java系统提供3种类加载器:启动类加载器(Bootstrap ClassLoader) 扩展类加载器(Extension ClassLoader) 应用程序类加载器(Application ClassLoader). A正确
B、《深入理解Java虚拟机》P228:对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间。这句话可以表达得更通俗一些:比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个Class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那么这两个类必定不相等。接口类是一种特殊类,因此对于同一接口不同的类装载器装载所获得的类是不相同的。B错误
C、类只需加载一次就行,因此要保证类加载过程线程安全,防止类加载多次。C正确
D、Java程序的类加载器采用双亲委派模型,实现双亲委派的代码集中在java.lang.ClassLoader的loadClass()方法中,此方法实现的大致逻辑是:先检查是否已经被加载,若没有加载则调用父类加载器的loadClass()方法,若父类加载器为空则默认使用启动类加载器作为父类加载器。如果父类加载失败,抛出ClassNotFoundException异常。D错误
E、双亲委派模型的工作过程:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。E正确
F、应用程序类加载器(Application ClassLoader)负责加载用户类路径(ClassPath)上所指定的类库,不是所有的ClassLoader都加载此路径。F错误

28、关于Java的一些概念,下面哪些描述是正确的:(BF)
A、所有的Java异常和错误的基类都是java.lang.Exception, 包括java.lang.RuntimeException
B、通过try … catch … finally语句,finally中的语句部分无论发生什么异常都会得到执行
C、java中所有的数据都是对象
D、Java通过垃圾回收回收不再引用的变量,垃圾回收时对象的finallize方法一定会得到执行
E、Java是跨平台的语言,无论通过哪个版本的Java编写的程序都能在所有的Java运行平台中运行
F、Java通过synchronized进行访问的同步,synchronized作用非静态成员方法和静态成员方法上同步的目标是不同的
解析:
A、Error和Exception都是集成Throwable,其中Exception又被IOException和RuntimeException继承/n
B、finally语句是无论发生什么异常都会执行的,并且如果try、catch中有return语句,且finally中也有return语句,则finally会覆盖前面的return。值得注意的是,如果try catch中有System.exit(0)的话,就会提前退出
C、java中有基本数据类型,如int,boolean,他们的包装对象是Integer和Boolean,所以不是万物皆对象
D、首先,垃圾回收的优先级相当低。另外,即使垃圾回收器工作,finalize()也不一定得到执行,这是由于程序中的其他线程的优先级远远高于执行finalize()函数线程的优先级。或者说,如果是等待清理队列中如果又被调用,则不会执行finallize()。所以说:Java通过垃圾回收回收不再引用的变量,垃圾回收时对象的finallize()不一定会得到执行。
E、java是跨平台的语言,这个主要是由于有针对不同平台的JVM,而JVM可以无差别的执行字节码(.class文件).但是,平台无关并不意味着版本无关,对于高版本编译器编写的java程序可能无法在低版本的java平台中运行。
F、Synchroized修饰非静态方法,是对调用该方法的对象加锁,Synchroized修饰静态方法,是对类加锁(因为类会调用它,)

29、以下说法错误的是(BCD)
A、其他选项均不正确
B、java线程类优先级相同
C、Thread和Runnable接口没有区别
D、如果一个类继承了某个类,只能使用Runnable实现线程
解析:
B选项,在java中线程是有分优先等级的所以优先级不能相同,错误
C选项,Thread实现了Runnable接口是一个类不是接口,错误
D选项,实现多线程的三种方式,一种是继承Thread类使用此方式就不能继承其他的类了。还有两种是实现Runnable接口或者实现Callable接口
,所以D错误。
A选项,综上A说其余三项都是错误的,所以A选项所述为真,不是错误的。

30、在 main() 方法中给出数组buffer和下标i,如果将此下标中的元素显示到控制台上,需要使用(A)
A、System.out.print (buffer[i]);
B、FileOutputStream fout = new FileOutputStream(this.filename);
C、FileInputStream fin = new FileInputStream(this.filename);
D、System.in.read(buffer)
解析:
在main中已经给出字节数组,直接System.out.print();输出即可。BC都是文件输出输入流,D是标准输入流,所以不符合题意。

31、 下列程序段执行后t3的结果是()

int t1=2, t2=3, t3;
t3=t1<t2?t1:(t2+t1); 

A、2 B、4 C、5 D、6
解析:
if(t1<t2)
t3=t1;;
else
t3=t2+t1;
三元运算符吧,和优先级没关系; 先判断再真前假后。

32、下列哪个类的声明是正确的(D)
A、abstract final class HI{}
B、abstract private move(){}
C、protected private number;
D、public abstract class Car{}
解析:
A选项,final是最终类,不能被继承;abstrct类是抽象类,只能被继承,两者冲突。
B选项,private修饰符定义的属性及方法不能被子类实现,而抽象类的子类必须实现所有的抽象方法。两者冲突。
C选项,修饰符重复,而且没有定义数据类型。 D选项,正确。

33、已知如下类定义:

class Base {  
 public Base (){ 
 //... 
 }  
 public Base ( int m ){ 
 //... 
 }  
 public void fun( int n ){ 
 //... 
 } 
}  
public class Child extends Base{  
 // member methods  
}  

如下哪句可以正确地加入子类中? D

A、private void fun( int n ){ //…}
B、void fun ( int n ){ //… }
C、protected void fun ( int n ) { //… }
D、public void fun ( int n ) { //… }
解析:
方法的重写(override)两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。

34、下列代码的执行结果是:( B)

public class Test3{
 public static void main(String args[]){
    System.out.println(100%3);
    System.out.println(100%3.0);
 }
}

A、1和1
B、1和1.0
C、1.0和1
D、1.0和1.0
解析:
多种混合计算时,自动将所有数据类型转换为容量最大的一种数据类型。所以都转为float类型。

35、 以下类定义中的错误是什么?(C)

abstract class xy
{
    abstract sum (int x, int y) { }
}

A、没有错误
B、类标题未正确定义
C、方法没有正确定义
D、没有定义构造函数

解析:
1、抽象方法不能有方法体,这是规定
2、该方法缺少返回值,只有构造没有返回值

36、HashMap的数据结构是怎样的(C)
A、数组
B、链表
C、数组+链表
D、二叉树
解析:
HashMap 由数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
JDK8及其以后版本,HashMap的数据结构是数组+链表+红黑树

37、

public class Test1 {

	static int cnt = 6;

	static {
    	cnt += 9;
	}

	public static void main(String[] args) {
    	System.out.println("cnt =" + cnt);
 	}

	static {
    	cnt /= 3;
	}
}

A、cnt=5
B、cnt=2
C、cnt=3
D、cnt=6
解析:
(1)父类静态成员和静态初始化块,按在代码中出现的顺序依次执行。
(2)子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。
(3)父类实例成员和实例初始化块,按在代码中出现的顺序依次执行。
(4)执行父类构造方法。
(5)子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。
(6)执行子类构造方法。

看了前面的解答,我想更正一下其中几位同学的解答。
如楼上有的同学说的,静态初始化块,静态变量这两个是属于同一级别的,是按代码写得顺序执行的!
而不是先执行静态变量后执行静态初始化块!这是错的。我举个例子:

public class Test{  static{  cnt = 6;
    }  static int cnt = 100;  public static void main(String[] args){
        System.out.println("cnt = " + cnt);
        //最后输出是50,如果按照错误说法就应该是3
        //按顺序执行就是cnt=6--->cnt=100---->cnt = 100/2 = 50.
    }  static{ cnt /= 2;
    }
}

在JVM调用mian方法之前先用进行静态内容的初始化。顺序为:父类的静态变量, 父类的静态代码块 ,子类的静态变量,子类的静态代码块。

38、以下代码输出的是: A

public class SendValue{
	public String str="6";
	public static void main(String[] args) {
		SendValue sv=new SendValue();
		sv.change(sv.str);
		System.out.println(sv.str);
	}
	public void change(String str) {
		str="10";
	}
}

A、6
B、10
C、都不对
D、16
解析:

补充Java内存管理知识:

  1. 内存分配策略

按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的。

静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间。这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求。

栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的。和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存。和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。

静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例。堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放。

  1. JVM中的堆和栈

JVM是基于堆栈的虚拟机。JVM为每个新创建的线程都分配一个堆栈,也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

java把内存分两种:一种是栈内存,另一种是堆内存

栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

栈(stack):是一个先进后出的数据结构,通常用于保存方法(函数)中的参数,局部变量。

堆(heap):是一个可动态申请的内存空间(其记录空闲内存空间的链表由操作系统维护),是一个运行时数据区,C中的malloc语句所产生的内存空间就在堆中。

  1. 堆和栈优缺点比较

栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。

堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

  1. Java中的数据类型有两种

一种是基本类型

共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。

这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。

另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:

int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

特别注意的是,这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

另一种是包装类数据

如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。

String是一个特殊的包装类数据。即可以用String str = new String(“abc”);的形式来创建,也可以用String str = “abc”;的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i = 3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK 5.0中,这种表达式是可以的!因为编译器在后台进行Integer i = new Integer(3)的转换)。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在String str = “abc”;中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。

5.String在内存中的存放

String是一个特殊的包装类数据,可以用用以下两种方式创建:

String str = new String(“abc”);第一种创建方式是用new()来新建对象的,它会存放于堆中。每调用一次就会创建一个新的对象。

String str = “abc”; 第二种创建方式先在栈中创建一个对String类的对象引用变量str,然后在栈中查找有没有存放值为”abc”的地址,如果没有,则开辟一个存放字面值为”abc”的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为”abc”的地址,则查找对象o,并返回o的地址,最后将str指向对象o的地址。

值得注意的是,一般String类中字符串值都是直接存值的。但像String str = “abc”;这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!

6.数组在内存中的存放

int x[] 或者int []x 时,在内存栈空间中创建一个数组引用,通过该数组名来引用数组。

x = new int[5] 将在堆内存中分配5个保存int型数据的空间,堆内存的首地址放到栈内存中,每个数组元素被初始化为0。

7.static变量在内存中的存放

用 static的修饰的变量和方法,实际上是指定了这些变量和方法在内存中的“固定位置”-static storage。既然要有“固定位置”那么他们的 “大小”似乎就是固定的了,有了固定位置和固定大小的特征了,在栈中或堆中开辟空间那就是非常的方便了。如果静态的变量或方法在不出其作用域的情况下,其引用句柄是不会发生改变的。

  1. java中变量在内存中的分配

1、类变量(static修饰的变量)

在程序加载时系统就为它在堆中开辟了内存,堆中的内存地址存放于栈以便于高速访问。静态变量的生命周期一直持续到整个”系统”关闭

2、实例变量

当你使用java关键字new的时候,系统在堆中开辟并不一定是连续的空间分配给变量(比如说类实例),然后根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的”物理位置”。 实例变量的生命周期–当实例变量的引用丢失后,将被GC(垃圾回收器)列入可回收“名单”中,但并不是马上就释放堆中内存

3、局部变量

局部变量,由声明在某方法,或某代码段里(比如for循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域,内存立即释放

在这里插入图片描述
39、以下代码在编译和运行过程中会出现什么情况 A

public class TestDemo{
	private int count;
	public static void main(String[] args) {
		TestDemo test=new TestDemo(88);
		System.out.println(test.count);
	}
	 TestDemo(int a) {
		 count=a;
	}
}

A、编译运行通过,输出结果是88
B、编译时错误,count变量定义的是私有变量
C、编译时错误,System.out.println方法被调用时test没有被初始化
D、编译和执行时没有输出结果
解析:
private是私有变量,只能用于当前类中,题目中的main方法也位于当前类,所以可以正确输出

40、 关于 Socket 通信编程,以下描述错误的是:(D
A、服务器端通过new ServerSocket()创建TCP连接对象
B、服务器端通过TCP连接对象调用accept()方法创建通信的Socket对象
C、客户端通过new Socket()方法创建通信的Socket对象
D、客户端通过new ServerSocket()创建TCP连接对象
解析:
Socket套接字
就是源Ip地址,目标IP地址,源端口号和目标端口号的组合
服务器端:ServerSocket提供的实例
ServerSocket server= new ServerSocket(端口号)
客户端:Socket提供的实例
Socket soc=new Socket(ip地址,端口号)

41、 下面的程序 编译运行后,在屏幕上显示的结果是()

public class Test {

    public static void main(String args[]) {
        int x, y;
        x = 5 >> 2;
        y = x >>> 2;
        System.out.println(y);
    }
}

A、0
B、2
C、5
D、80
解析:
5 >> 2 相当于 5除于2的平方,等于1 ,>>> 表示无符号 右移,高位用0 填充,0001 右移两位
0000,所以答案选 A

Java中的位运算符:>>表示右移,如果该数为正,则高位补0,若为负数,则高位补1; >>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0。

42、检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。

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");
 }
}

A、
static A
I’m A class
static B
I’m B class
B、
I’m A class
I’m B class
static A
static B
C、
static A
static B
I’m A class
I’m B class
D、
I’m A class
static A
I’m B class
static B

解析:
1.静态代码块 2.构造代码块3.构造方法的执行顺序是1>2>3;明白他们是干嘛的就理解了。
1.静态代码块:是在类的加载过程的第三步初始化的时候进行的,主要目的是给类变量赋予初始值。
2.构造代码块:是独立的,必须依附载体才能运行,Java会把构造代码块放到每种构造方法的前面,用于实例化一些共有的实例变量,减少代码量。
3.构造方法:用于实例化变量。
1是类级别的,2、3是实例级别的,自然1要优先23.
在就明白一点:对子类得主动使用会导致对其父类得主动使用,所以尽管实例化的是子类,但也会导致父类的初始化和实例化,且优于子类执行。

只要记住,不论怎样,必定先执行静态代码,子由父生,所以父类必先执行,由此可以筛选出答案C

其中涉及:静态初始化代码块、构造代码块、构造方法
当涉及到继承时,按照如下顺序执行:
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
正确答案:C

43、下面的输出结果是什么 B

public class Demo {
  public static void main(String args[])
  {
    String str=new String("hello");
    if(str=="hello")
    {
      System.out.println("true");
    }      
    else     {
      System.out.println("false");
    }
  }
}

A、true           B、false
解析:
B:false

==判断的是对象引用地址是否相同,
style=“color: rgb(0,0,0);”> style=“color: rgb(102,0,102);”>String style=“color: rgb(0,0,0);”> str style=“color: rgb(102,102,0);”>= style=“color: rgb(0,0,136);”>new style=“color: rgb(0,0,0);”> style=“color: rgb(102,0,102);”>String style=“color: rgb(102,102,0);”>( style=“color: rgb(0,136,0);”>“hello” class=“pun”
style=“color: rgb(102,102,0);”>);
这句话new了一个新的String对象,所以地址与"hello"字符串常量的地址不同,答案为false

如果判断字符串是否相等应给用str.equals(“hello”)方法

public class Demo {
    public static void main(String args[]) {
        String str1 = new String("hello");
        String str2 = new String("hello");
        String str3 = "hello";
        String str4 = "hello";
        String str5 = "he"+"llo";
        String str6 = "he";
        String str7 = "llo";
        System.out.println(str1==str2);
        System.out.println(str1==str3);
        System.out.println(str3==str4);
        System.out.println(str3=="hello");
        System.out.println(str4==(str6+str7));
    }
}

上面代码的输出结果是:
false
false
true
true
false

String str1 = new String("hello"); 

这种方式创建的字符串,和正常创建对象一样,保存在堆区。

String str3 = "hello";

这种方式创建的字符串,保存在字符串常量区。

44、下面叙述那个是正确的?(B)
A、java中的集合类(如Vector)可以用来存储任何类型的对象,且大小可以自动调整。但需要事先知道所存储对象的类型,才能正常使用。
B、在java中,我们可以用违例(Exception)来抛出一些并非错误的消息,但这样比直接从函数返回一个结果要更大的系统开销。
C、java接口包含函数声明和变量声明。
D、java中,子类不可以访问父类的私有成员和受保护的成员。
解析:
接口中只有常量定义,没有变量声明。
我就说下B选项和C选项。
B选项说的情况就是我们自定义异常的情况,请仔细读:我们可以用违例(Exception)来抛出一些并非错误的消息,可以,并非错误的消息。比如我自定义一个异常,若一个变量大于10就抛出一个异常,这样就对应了B选项说的情况,我用抛出异常说明这个变量大于10,而不是用一个函数体(函数体内判断是否大于10,然后返回true或false)判断,因为函数调用是入栈出栈,栈是在寄存器之下的速度最快,且占的空间少,而自定义异常是存在堆中,肯定异常的内存开销大!所以B对。
C选项说的是接口包含方法声明和变量声明。因为接口中方法默认是 abstract public,所以在接口只写函数声明是符合语法规则。但是变量默认是用public final static 修饰的,意思它是静态常量,常量不管在接口中还是类中必须在声明时初始化!所以C的后半句是错的,必须在声明时并给出初始化!
A.vector是线程安全的ArrayList,在内存中占用连续的空间。初始时有一个初始大小,当数据条数大于这个初始大小后会重写分配一个更大的连续空间。如果Vector定义为保存Object则可以存放任意类型。

B.try{}catch{}会增加额外的开销

C.接口中声明的’变量’必须为public final static,所以为常量

D.子类可以访问父类受保护的成员

45、下列有关Servlet的生命周期,说法不正确的是 A
A、在创建自己的Servlet时候,应该在初始化方法init()方法中创建Servlet实例
B、在Servlet生命周期的服务阶段,执行service()方法,根据用户请求的方法,执行相应的doGet()或是doPost()方法
C、在销毁阶段,执行destroy()方法后会释放Servlet 占用的资源
D、destroy()方法仅执行一次,即在服务器停止且卸载Servlet时执行该方法
解析:
Servlet的生命周期分为5个阶段:加载、创建、初始化、处理客户请求、卸载。
(1)加载:容器通过类加载器使用servlet类对应的文件加载servlet
(2)创建:通过调用servlet构造函数创建一个servlet对象
(3)初始化:调用init方法初始化
(4)处理客户请求:每当有一个客户请求,容器会创建一个线程来处理客户请求
(5)卸载:调用destroy方法让servlet自己释放其占用的资源

46、关于Java中参数传递的说法,哪个是错误的 D
A、在方法中,修改一个基础类型的参数不会影响原始参数值
B、在方法中,改变一个对象参数的引用不会影响到原始引用
C、在方法中,修改一个对象的属性会影响原始对象参数
D、在方法中,修改集合和Maps的元素不会影响原始集合参数
解析:
注意!Java中方法的参数传递都是值传递
A. 在方法中,修改一个基础类型的参数不会影响原始参数值

public static void main(String []args){
int i = 5;
func(i);
System.out.println(i);
}
static void func(int j){
j = 10;
}

//输出结果
5

在主方法调用func(int j) 时 , 参数i是实际参数 , 值为5 , 参数j是形式参数 , 值是i给的 , 也是5 , i和j没有任何关系 , 是两个独立的参数 , 所以修改j的值时与i没有关系 , 仍然输出5。

B. 在方法中,改变一个对象参数的引用不会影响到原始引用

public static void main(String []args){
User rabbiter = new User();
rabbiter.setName(“rabbiter”);
func(rabbiter);
System.out.println(rabbiter.getName());
}
static void func(User user){
user = new User();
user.setName(“zhangsan”);
}

//输出结果
rabbiter

在主方法调用func(User user) 时 , 对象rabbiter保存的是一个地址值 , 本质上就是把rabbiter的地址值给了形参user , 所以此时实参rabbiter和形参user指向在堆中的同一个对象 , 他们的地址值相同 , 只是指向的对象一致 , 所以并不违反值传递的理论。
此时 , 如果修改形参user , new一个新的对象并让user指向它 , 修改的只是形参保存的地址 , 与实参rabbiter无关 , rabbiter指向的对象仍然是之前的那个对象。

C. 在方法中,修改一个对象的属性会影响原始对象参数

public static void main(String []args){
User rabbiter = new User();
rabbiter.setName(“rabbiter”);
func(rabbiter);
System.out.println(rabbiter.getName());
}
static void func(User user){
user.setName(“zhangsan”);
}

//输出结果
zhangsan

在主方法调用func(User user) 时 , 对象rabbiter保存的是一个地址值 , 本质上就是把rabbiter的地址值给了形参user , 所以此时实参rabbiter和形参user指向在堆中的同一个对象 , 他们的地址值相同 , 指向的对象一致 , 所以并不违反值传递的理论。
那么user对其指向的对象的属性name进行修改 , rabbiter指向的对象的name属性也就被修改了。

D. 在方法中,修改集合和Maps的元素不会影响原始集合参数
集合和Maps都是对象 , 所以此项跟C选项的解析一致。

47、检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。 A

package algorithms.com.guan.javajicu;  
public class Inc {  
    public static void main(String[] args) {  
       Inc inc = new Inc();  
       int i = 0;  
       inc.fermin(i);  
       i= i ++;  
       System.out.println(i); 
   
    }  
    void fermin(int i){  
       i++;  
    }  
}  

A、0
B、1
C、2
D、3
解析:
如果你理解JVM的内存模型,就不难理解为什么答案返回的是0,而不是1。

我们单独看问题中的这两句代码。

int i = 0; i = i++;

Java虚拟机栈(JVM Stack)描述的是Java方法执行的内存模型,而JVM内存模型是基于“栈帧”的,每个栈帧中都有
局部变量表

操作数栈
(还有动态链接、return
address等),那么JVM是如何执行这个语句的呢?通过javap大致可以将上面的两行代码翻译成如下的JVM指令执行代码。

0: iconst_0

1: istore_1

2: iload_1

3: iinc 1, 1

6: istore_1

7: iload_1

接下来分析一下JVM是如何执行的:

第0:将int类型的0入栈,就是放到操作数栈的栈顶

第1:将操作数栈栈顶的值0弹出,保存到局部变量表 index
(索引)值为1的位置。(局部变量表也是从0开始的,0位置一般保存当前实例的this引用,当然静态方法例外,因为静态方法是类方法而不是实例方法)

第2:将局部变量表index 1位置的值的副本入栈。(这时局部变量表index为1的值是0,操作数栈顶的值也是0)

第3:iinc是对int类型的值进行自增操作,后面第一个数值1表示,局部变量表的index值,说明要对此值执行iinc操作,第二个数值1表示要增加的数值。(这时局部变量表index为1的值因为执行了自增操作变为1了,但是操作数栈中栈顶的值仍然是0)

第6:将操作数栈顶的值弹出(值0),放到局部变量表index为1的位置(旧值:1,新值:0),覆盖了上一步局部变量表的计算结果。

第7:将局部变量表index 1位置的值的副本入栈。(这时局部变量表index为1的值是0,操作数栈顶的值也是0)

总结:从执行顺序可以看到,这里第1和第6执行了2次将0赋值给变量i的操作(=号赋值),i++操作是在这两次操作之间执行的,自增操作是对局部变量表中的值进行自增,而栈顶的值没有发生变化,这里需要注意的是保存这个初始值的地方是操作数栈而不是局部变量表,最后再将栈顶的值覆盖到局部变量表i所在的索引位置中去。

有兴趣的同学可以去了解一下JVM的栈帧(Stack Frame)

关于第二个陷阱(为什么
fermin方法没有影响到i的值
)的解答看下面。

inc.fermin(i);

  1. java方法之间的参数传递是
    值传递
    而不是
    引用传递

每个方法都会有一个栈帧,栈帧是方法运行时的数据结构。这就是说每个方法都有自己独享的局部变量表。(更严谨的说法其实是每个线程在执行每个方法时都有自己的栈帧,或者叫当前栈帧
current stack frame)

  1. 被调用方法fermin()的形式参数int i 实际上是调用方法main()的实际参数 i 的一个副本。

  2. 方法之间的参数传递是通过局部变量表实现的,main()方法调用fermin()方法时,传递了2个参数:

第0个隐式参数是当前实例(Inc inc = new Inc(); 就是inc引用的副本,引用/reference 是指向对象的一个地址,32位系统这个地址占用4个字节,也就是用一个Slot来保存对象reference,这里传递的实际上是reference的一个副本而不是
reference本身
);

第1个显示参数是 i 的一个副本。所以
fermin()方法对 i 执行的操作只限定在其方法独享或可见的局部变量表这个范围内,main()方法中局部变量表中的i不受它的影响;

如果main()方法和fermin()方法共享局部变量表的话,那答案的结果就会有所不同。
其实你自己思考一下,就会发现,
JVM虚拟机团队这么设计是有道理的。

48、下面哪一项不是加载驱动程序的方法 A
A、通过DriverManager.getConnection方法加载
B、调用方法 Class.forName
C、通过添加系统的jdbc.drivers属性
D、通过registerDriver方法注册
解析:
答案:A
DriverManager.getConnection方法返回一个Connection对象,这是加载驱动之后才能进行的

加载驱动方法
1.Class.forName(“com.microsoft.sqlserver.jdbc.SQLServerDriver”);
2. DriverManager.registerDriver(new com.mysql.jdbc.Driver());
3.System.setProperty(“jdbc.drivers”, “com.mysql.jdbc.Driver”);

创建一个以JDBC连接数据库的程序,包含7个步骤:  1、加载JDBC驱动程序: 

在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),
这通过java.lang.Class类的静态方法forName(String className)实现。
例如:

try{ //加载MySql的驱动类
Class.forName(“com.mysql.jdbc.Driver”);
}
catch(ClassNotFoundException e)
{
System.out.println(“找不到驱动程序类 ,加载驱动失败!”);
e.printStackTrace();
}

成功加载后,会将Driver类的实例注册到DriverManager类中。 

2、提供JDBC连接的URL

    			连接URL定义了连接数据库时的协议、子协议、数据源标识。
    		
    		

    			书写形式:协议:子协议:数据源标识
    		
    		

    			协议:在JDBC中总是以jdbc开始
    		
    		

    			子协议:是桥连接的驱动程序或是数据库管理系统名称。
    		
    		

    			数据源标识:标记找到数据库来源的地址与连接端口。

jdbc:mysql:
//localhost:3306/test?useUnicode=true&characterEncoding=gbk;

useUnicode=true:表示使用Unicode字符集。 

如果characterEncoding设置为gb2312或GBK,本参数必须设置为true &characterEncoding=gbk;字符编码方式。

3、创建数据库的连接

    			要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。
    		
    		

    			使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。
    		
    	




例如:

//连接MySql数据库,用户名和密码都是root
String url = “jdbc:mysql://localhost:3306/test” ;
String username = “root” ;
String password = “root” ;
try{
Connection con = DriverManager.getConnection(url , username , password ) ;
}catch(SQLException se){
System.out.println(“数据库连接失败!”);
se.printStackTrace() ;
}

4、创建一个Statement


	


    		

    			要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3 

    种类型: 

    			

        				

        					执行静态SQL语句。通常通过Statement实例实现。
        				
        				

        					执行动态SQL语句。通常通过PreparedStatement实例实现。
        				
        				

        					执行数据库存储过程。通常通过CallableStatement实例实现。
        				
        			

    		
    	




具体的实现方式:

Statement stmt = con.createStatement() ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;

5、执行SQL语句


	


    		

    			Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate和execute 

    			

        				

        					ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返回一个结果集(ResultSet)对象。
        				
        				

        					int executeUpdate(String sqlString):用于执行INSERT、UPDATE或 

        DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
        				
        				

        					execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的 

        语句。

ResultSet rs = stmt.executeQuery(“SELECT * FROM …”) ;
int rows = stmt.executeUpdate(“INSERT INTO …”) ;
boolean flag = stmt.execute(String sql) ;

		1
	

	

		2
	

	

		3
	




6、处理结果


	


    		

    			两种情况: 

    			

        				

        					执行更新返回的是本次操作影响到的记录数。
        				
        				

        					执行查询返回的结果是一个ResultSet对象。
        				
        			

    		
    	




	

		ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些 

行中数据的访问。
	
	

		使用结果集(ResultSet)对象的访问方法获取数据:

while(rs.next()){ String name = rs.getString(“name”) ; String pass = rs.getString(1) ; // 此方法比较高效 }

		1
	

	

		2
	

	

		3
	

	

		4
	




(列是从左到右编号的,并且从列1开始) 

7、关闭JDBC对象

操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声

明顺序相反:

1、关闭记录集

2、关闭声明

if(rs != null){ // 关闭记录集
try{
rs.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(stmt != null){ // 关闭声明
try{
stmt.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(conn != null){ // 关闭连接对象
try{
conn.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}

49、下列代码输出结果为(D)

class Animal{
    public void move(){
        System.out.println("动物可以移动");
    }
}
class Dog extends Animal{
    public void move(){
        System.out.println("狗可以跑和走");
    }
    public void bark(){
        System.out.println("狗可以吠叫");
    }
}
public class TestDog{
    public static void main(String args[]){
        Animal a = new Animal();
        Animal b = new Dog(); 
        a.move();
        b.move();
        b.bark();
    }
}

A、
动物可以移动
狗可以跑和走
狗可以吠叫
B、
动物可以移动
动物可以移动
狗可以吠叫
C、
运行错误
D、
编译错误
解析:
编译看左边,运行看右边。 父类型引用指向子类型对象,无法调用只在子类型里定义的方法
也就是是编译的时候会把它当成左边的类型,运行的时候看右边类型的方法体。这个题动物类没有另一个方法,而b调用了,所以编译器会认为b是一个动物类,所以报错。这就是多态的特性吧

编译错误:The method bark() is undefined for the type Animal。Animal中没有定义bark()方法。
Dog继承自Animal。
当用Dog对象初始化Animal类对象时,完成了对Animal对象中方法与变量的覆盖与隐藏,也就是b.move()调用的是Dog中move()方法。而Animal中本身并没有bark()方法,不存在被覆盖的情况,亦无法访问,也就是b.bark()会报错。

50、以下集合对象中哪几个是线程安全的(C D)
A、LinkedList
B、ArrayList
C、Vector
D、Hashtable
解析:
简单记忆线程安全的集合类:
喂!SHE! 喂是指 vector,S是指 stack, H是指 hashtable,E是指:Eenumeration

集合中线程安全的类有:vector,stack,hashtable,enumeration,除此之外均是非线程安全的类与接口

51、关于Java集合下列说法不正确的有哪些(ABD)
A、HashSet 它是线程安全的,不允许存储相同的对象
B、ConcurrentHashMap 它是线程安全的,其中存储的键对象可以重复,值对象不能重复
C、Collection接口是List接口和Set接口的父接口,通常情况下不被直接使用
D、ArrayList线程安全的,允许存放重复对象
解析:
A: HashSet 它不是线程安全的,属于Set接口下的实现类,Set下的实现类特征就是无序,不允许存储相同的对象
B: ConcurrentHashMap 它是线程安全的HashMap实现,特征也相似,其中存储的值对象可以重复,键对象不能重复
C: Collection接口是List接口和Set接口的父接口,通常情况下不被直接使用
D: ArrayList线程不安全的,底层是数组实现,允许存放重复对象

52、Java7特性中,abstract class和interface有什么区别 A B D
A、抽象类可以有构造方法,接口中不能有构造方法
B、抽象类中可以有普通成员变量,接口中没有普通成员变量
C、抽象类中不可以包含静态方法,接口中可以包含静态方法
D、一个类可以实现多个接口,但只能继承一个抽象类。
解析:
style=“font-family: Helvetica , Tahoma , Arial , sans-serif;line-height: 25.2px;background-color: rgb(255,255,255);”>含有abstract修饰符的class即为抽象类,abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract
class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。

style=“font-family: Helvetica , Tahoma , Arial , sans-serif;line-height: 25.2px;background-color: rgb(255,255,255);”>接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public
abstract类型,接口中的成员变量类型默认为public static final。

下面比较一下两者的语法区别:

1.抽象类可以有构造方法,接口中不能有构造方法。

2.抽象类中可以有普通成员变量,接口中没有普通成员变量

3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

style=“font-family: Helvetica , Tahoma , Arial , sans-serif;line-height: 25.2px;background-color: rgb(255,255,255);”>4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然

style=“font-family: Helvetica , Tahoma , Arial , sans-serif;line-height: 25.2px;background-color: rgb(255,255,255);”>eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

style=“font-family: Helvetica , Tahoma , Arial , sans-serif;line-height: 25.2px;background-color: rgb(255,255,255);”>5. 抽象类中可以包含静态方法,接口中不能包含静态方法

style=“font-family: Helvetica , Tahoma , Arial , sans-serif;line-height: 25.2px;background-color: rgb(255,255,255);”>6.
抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static
final类型,并且默认即为public static final类型。

style=“font-family: Helvetica , Tahoma , Arial , sans-serif;line-height: 25.2px;background-color: rgb(255,255,255);”>7. 一个类可以实现多个接口,但只能继承一个抽象类。

下面接着再说说两者在应用上的区别:

接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,

例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:

package com.lei;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class BaseServlet extends HttpServlet {

/**

  • serialVersionUID属性概述

*/
private static final long serialVersionUID = 1L;

public final void service(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
// 记录访问日志
// 进行权限判断
if (true)// if条件里写的是“具有权限”
{
try {
doService(request, response);
} catch (IOException e) {
// 记录异常信息
}
}

}

protected abstract void doService(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException;
}

实现类如下:

package com.lei;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends BaseServlet{

/**

  • serialVersionUID属性概述

*/
private static final long serialVersionUID = 1L;

@Override
protected void doService(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
// TODO Auto-generated method stub

}

}

父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。

备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,最后再说两者的应用区别。

比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。

53、以下哪些方法可以取到http请求中的cookie值(B D)
A、request.getAttribute
B、request.getHeader
C、request.getParameter
D、request.getCookies
解析:
下面的方法可用在 Servlet 程序中读取 HTTP 头。这些方法通过 HttpServletRequest 对象可用:

1)Cookie[] getCookies()
返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。

2)Object getAttribute(String name)
以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。

3)String getHeader(String name)
以字符串形式返回指定的请求头的值。Cookie也是头的一种;

4)String getParameter(String name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。

A. request.getAttribute:getAttribute是在服务器端的操作。
比如说 request.setAttribute(k,v),其行为动作在服务器端。
而在服务端放入cookies是通过response.addCookie(cookie)。因此,A错了

B. Accept 浏览器可接受的MIME类型
Accept-Charset 浏览器支持的字符编码
Accept-Encoding 浏览器知道如何解码的数据编码类型(如 gzip)。Servlets 可以预先检查浏览器是否支持gzip并可以对支持gzip的浏览器返回gzipped的HTML页面,并设置Content-Encoding回应头(response header)来指出发送的内容是已经gzipped的。在大多数情况下,这样做可以加快网页下载的速度。
Accept-Language 浏览器指定的语言,当Server支持多语种时起作用。
Authorization 认证信息,一般是对服务器发出的WWW-Authenticate头的回应。
Connection 是否使用持续连接。如果servlet发现这个字段的值是Keep-Alive,或者由发出请求的命令行发现浏览器支持 HTTP 1.1 (持续连接是它的默认选项),使用持续连接可以使保护很多小文件的页面的下载时间减少。
Content-Length (使用POST方法提交时,传递数据的字节数)
Cookie (很重要的一个Header,用来进行和Cookie有关的操作,详细的信息将在后面的教程中介绍)
Host (主机和端口)
If-Modified-Since (只返回比指定日期新的文档,如果没有,将会反回304 “Not Modified”)
Referer (URL)
User-Agent (客户端的类型,一般用来区分不同的浏览器)

C.request.getParameter()方法获取从客户端中通过get 或者post方式传送到服务器端的参数。行为操作在服务器端。所以cookies明显不是通过url或者form表单提交过来的。C错

D.看方法名字就行了。

54、 Hashtable 和 HashMap 的区别是: B C D E
A、Hashtable 是一个哈希表,该类继承了 AbstractMap,实现了 Map 接口

B、HashMap 是内部基于哈希表实现,该类继承AbstractMap,实现Map接口

C、Hashtable 线程安全的,而 HashMap 是线程不安全的

D、Properties 类 继承了 Hashtable 类,而 Hashtable 类则继承Dictionary 类

E、HashMap允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许
解析:
选B、C、D、E。
Hashtable:
(1)Hashtable 是一个散列表,它存储的内容是键值对(key-value)映射。
(2)Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。
(3)HashTable直接使用对象的hashCode。
HashMap:
(1)由数组+链表组成的,基于哈希表的Map实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。
(2)不是线程安全的,HashMap可以接受为null的键(key)和值(value)。
(3)HashMap重新计算hash值

Hashtable,HashMap,Properties继承关系如下:
public class Hashtable<K,V> extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable

public class HashMap<K,V>extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
java.lang.Objecct
java.util.Dictionary<K,V>
java.util.Hashtable<Object,Object>
java.util.Properties

55、以下哪几种方式可用来实现线程间通知和唤醒:(A C)
A、Object.wait/notify/notifyAll
B、ReentrantLock.wait/notify/notifyAll
C、Condition.await/signal/signalAll
D、Thread.wait/notify/notifyAll

wait()、notify()和notifyAll()是 Object类 中的方法

从这三个方法的文字描述可以知道以下几点信息:

1)wait()、notify()和notifyAll()方法是本地方法,并且为final方法,无法被重写。

2)调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(即锁)

3)调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程,如果有多个线程都在等待这个对象的monitor,则只能唤醒其中一个线程;

4)调用notifyAll()方法能够唤醒所有正在等待这个对象的monitor的线程;

有朋友可能会有疑问:为何这三个不是Thread类声明中的方法,而是Object类中声明的方法

(当然由于Thread类继承了Object类,所以Thread也可以调用者三个方法)?其实这个问

题很简单,由于每个对象都拥有monitor(即锁),所以让当前线程等待某个对象的锁,当然

应该通过这个对象来操作了。而不是用当前线程来操作,因为当前线程可能会等待多个线程

的锁,如果通过线程来操作,就非常复杂了。

上面已经提到,如果调用某个对象的wait()方法,当前线程必须拥有这个对象的monitor(即

锁),因此调用wait()方法必须在同步块或者同步方法中进行(synchronized块或者

synchronized方法)。

调用某个对象的wait()方法,相当于让当前线程交出此对象的monitor,然后进入等待状态,

等待后续再次获得此对象的锁(Thread类中的sleep方法使当前线程暂停执行一段时间,从

而让其他线程有机会继续执行,但它并不释放对象锁);

notify()方法能够唤醒一个正在等待该对象的monitor的线程,当有多个线程都在等待该对象

的monitor的话,则只能唤醒其中一个线程,具体唤醒哪个线程则不得而知。

同样地,调用某个对象的notify()方法,当前线程也必须拥有这个对象的monitor,因此调用

notify()方法必须在同步块或者同步方法中进行(synchronized块或者synchronized方法)。

nofityAll()方法能够唤醒所有正在等待该对象的monitor的线程,这一点与notify()方法是不同的。
Condition是在java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()这种方式实现线程间协作更加安全和高效。因此通常来说比较推荐使用Condition,在阻塞队列那一篇博文中就讲述到了,阻塞队列实际上是使用了Condition来模拟线程间协作。

Condition是个接口,基本的方法就是await()和signal()方法;
Condition依赖于Lock接口,生成一个Condition的基本代码是lock.newCondition()
调用Condition的await()和signal()方法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使用Conditon中的await()对应Object的wait(); Condition中的signal()对应Object的notify(); Condition中的signalAll()对应Object的notifyAll() 

56、下面哪个不是Java的关键字 ABC
A、null
B、true
C、sizeof
D、implements
E、instanceof

解析:
1、null、true、false 是 Java 中的显式常量值,并不是关键字 或 保留字

2、sizeof 是 C/C++ 中的方法,Java 中并没有这个方法,也没有该关键字 或 保留字

3、implements 和 instanceof 都是 Java 中的关键字

57、抽象类和接口的区别,以下说法错误的是 A C D
A、
接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的。
B、
abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface,实现多重继承。接口还有标识(里面没有任何方法,如Remote接口)和数据共享(里面的变量全是常量)的作用。
C、
在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是 static final的,不过在 interface中一般不定义数据成员),所有的成员方法默认都是 public abstract 类型的。
D、
abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"has-a"关系,interface表示的是"is-a"关系。
解析:

抽象类:在Java中被abstract关键字修饰的类称为抽象类,被abstract关键字修饰的方法称为抽象方法,抽象方法只有方法的声明,没有方法体。抽象类的特点:
a、抽象类不能被实例化只能被继承;
b、包含抽象方法的一定是抽象类,但是抽象类不一定含有抽象方法;
c、抽象类中的抽象方法的修饰符只能为public或者protected,默认为public;
d、一个子类继承一个抽象类,则子类必须实现父类抽象方法,否则子类也必须定义为抽象类;
e、抽象类可以包含属性、方法、构造方法,但是构造方法不能用于实例化,主要用途是被子类调用。
接口:Java中接口使用interface关键字修饰,特点为:
a、接口可以包含变量、方法;变量被隐士指定为public static final,方法被隐士指定为public abstract(JDK1.8之前);
b、接口支持多继承,即一个接口可以extends多个接口,间接的解决了Java中类的单继承问题;
c、一个类可以实现多个接口;
d、JDK1.8中对接口增加了新的特性:
(1)、默认方法(default method):JDK 1.8允许给接口添加非抽象的方法实现,但必须使用default关键字修饰;定义了default的方法可以不被实现子类所实现,但只能被实现子类的对象调用;如果子类实现了多个接口,并且这些接口包含一样的默认方法,则子类必须重写默认方法;
(2)、静态方法(static method):JDK 1.8中允许使用static关键字修饰一个方法,并提供实现,称为接口静态方法。接口静态方法只能通过接口调用(接口名.静态方法名)。
注意:jdk1.9是允许接口中出现private修饰的默认方法和静态方法。

解析:
A:jdk1.9是允许接口中出现private修饰的默认方法和静态方法,A错误;抽象类可以有私有的变量和方法。
B:正确
C:抽象类可以有抽象和非抽象的方法;jdk1.8接口中可以有默认方法和静态方法,C错误。
D:强调继承关系,is-a,如果A is-a B,那么B就是A的父类;
代表组合关系,like-a,接口,如果A like a B,那么B就是A的接口。 ;
强调从属关系,has-a,如果A has a B,那么B就是A的组成部分。
D项错误。

58、 java7后关键字 switch 支不支持字符串作为条件:(支持)
解析:
在Java7之前,switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型。在Java7中,呼吁很久的String支持也终于被加上了。

59、Java Application 中的主类需包含main方法,以下哪项是main方法的正确形参?(B)
A、String args
B、String[] args
C、Char arg
D、StringBuffer[] args
解析:
String[] args / String args[] / String… args都是正确的

60、关于finally,下面哪个描述正确? (B)
A、在catch块之前但在try块之后执行finally块
B、finally块会被执行无论是否抛出异常
C、只有在执行catch块之后才执行finally块
D、都不是
解析:

61、能用来修饰interface的有(B)
A、private
B、public
C、protected
D、static
解析:java中接口只能使用public修饰,接口内方法默认为public abstract

62、以下代码的循环次数是 D

public class Test {
    public static void main(String args[]) {
        int i = 7;
        do {
            System.out.println(--i);
            --i;
        } while (i != 0);
       System.out.println(i);
    }
}

A、0
B、1
C、7
D、无限次
解析:
执行1次,5
执行2次,3
执行3次,1
执行4次,-1
永远执行不到0

63、关于类的叙述正确的是(B)
A、在类中定义的变量称为类的成员变量,在别的类中可以直接使用
B、局部变量的作用范围仅仅在定义它的方法内,或者是在定义它的控制流块中
C、使用别的类的方法仅仅需要引用方法的名字即可
D、只要没有定义不带参数的构造函数,JVM都会为类生成一个默认构造函数
解析:
A在类中定义的变量称为类的成员变量,在别的类中不可以直接使用局部变量的
C使用别的类的方法需要通过该类的对象引用方法的名字
D只要没有定义任何构造函数,JVM都会为类生成一个默认构造函数

64、 C

public static void main(String[] args) {
    Thread t = new Thread() {

        public void run() {
           my360DW();
        }
    };

    t.run();
    System.out.print("DW");

}

static void my360DW() {

    System.out.print("360");

}

A、DW
B、360
C、360DW
D、都不输出
解析:
第一:方法名不能以数字开头,所以编译通不过 第二:改正确方法名后输出“360DW”,本题意在考察开启线程的方法t.start()和直接调用t.run()的区别。但在题目中没有提现 注:直接调用线程的run()方法不是开启线程,就是普通调用,会直接执行run()方法中的内容

65、下列语句哪一个是不正确的(D)
A、Log4j支持按分钟为间隔生成新的日志文件
B、Log4j是一个打印日志用的组件
C、Log4j支持按年为间隔生成新的日志文件
D、Log4j的日志打印级别可以在运行时重新设置
解析:
日志的级别之间的大小关系如右所示:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF Log4j建议只使用四个级别,优先级从高到低分别是 ERROR > WARN > INFO > DEBUG。 log4j在运行期间是不可以重新设置的

66、以下代码的输出的正确结果是 D

public class Test {
    public static void main(String args[]) {
        String s = "祝你考出好成绩!";
        System.out.println(s.length());
    }
}

A、24
B、16
C、15
D、8
解析:
java的String底层是char数组,它的length()返回数组大小,而unicode中一个汉字是可以用一个char表示的

67、 关于final说法正确的是? (B)
A、final类的方法肯定不能被同一个包的类访问
B、final类的方法能否被同一个包的类访问不是由final决定
C、final方法等同于private方法
D、final对象本身的引用和值都不能改变
解析:
final变量,如果是基本数据类型,则其数值一旦初始化后就不能被改变。如果是引用类型的变量,则对其初始化后,便不能再指向另一个对象,但是其里面的值是可以改变的。引用变量所指向的对象中的内容是可以改变的。

68、下列说法正确的是 B
A、在类方法中可用this来调用本类的类方法
B、在类方法中调用本类的类方法可直接调用
C、在类方法中只能调用本类的类方法
D、在类方法中绝对不能调用实例方法
解析:
在类方法中调用本类的类方法可直接调用。 实例方法也叫做对象方法。

类方法是属于整个类的,而实例方法是属于类的某个对象的。
由于类方法是属于整个类的,并不属于类的哪个对象,所以类方法的方法体中不能有与类的对象有关的内容。即类方法体有如下限制:
(1) 类方法中不能引用对象变量;
(2) 类方法中不能调用类的对象方法;
(3) 在类方法中不能使用super、this关键字。
(4)类方法不能被覆盖。
如果违反这些限制,就会导致程序编译错误。
与类方法相比,对象方法几乎没有什么限制:
(1) 对象方法中可以引用对象变量,也可以引用类变量;
(2) 对象方法中可以调用类方法;
(3) 对象方法中可以使用super、this关键字。

69、用户不能调用构造方法,只能通过new关键字自动调用。(错误)
解析:
1.在类内部可以用户可以使用关键字this.构造方法名()调用(参数决定调用的是本类对应的构造方法)
2.在子类中用户可以通过关键字super.父类构造方法名()调用(参数决定调用的是父类对应的构造方法。)
3.反射机制对于任意一个类,都能够知道这个类的所有属性和方法,包括类的构造方法。

70、关键字super的作用是? D
A、用来访问父类被隐藏的非私有成员变量
B、用来调用父类中被重写的方法
C、用来调用父类的构造函数
D、以上都是
解析:
super代表父类对应的对象,所以用super访问在子类中无法直接使用的父类成员和方法

71、下面程序运行完之后,t2与t3的关系为(D)

 Object obj=new Object();
    List aList=new ArrayList();
    List bList=new LinkedList();
    
    long t1=System.currentTimeMillis();
    for(int i=0;i<50000;i++){
        aList.add(0,obj);
    }
    long t2=System.currentTimeMillis()-t1;
    
    t1=System.currentTimeMillis();
    for(int i=0;i<50000;i++){
        bList.add(0,obj);
    }
    long t3=System.currentTimeMillis()-t1; 

A、t2
B、t2=t3
C、不确定
D、t2>t3
解析:
ArrayList内部是动态数组实现,在增加空间时会复制全部数据到新的容量大一些的数组中。而LinkedList内部为双向链表,可以按需分配空间,扩展容量简单,因此LinkedList用时少

72、JDK中提供的java、javac、jar等开发工具也是用Java编写的。 (正确)

73、关于 Socket 通信编程,以下描述正确的是:(C)
A、客户端通过new ServerSocket()创建TCP连接对象
B、客户端通过TCP连接对象调用accept()方法创建通信的Socket对象
C、客户端通过new Socket()方法创建通信的Socket对象
D、服务器端通过new ServerSocket()创建通信的Socket对象
解析:
客户端通过new Socket()方法创建通信的Socket对象
服务器端通过new ServerSocket()创建TCP连接对象 accept接纳客户端请求

74、在java7中,下列哪个说法是正确的: D
A、ConcurrentHashMap使用synchronized关键字保证线程安全
B、HashMap实现了Collection接口
C、Arrays.asList方法返回java.util.ArrayList对象
D、SimpleDateFormat对象是线程不安全的
解析:
Arrays.asList()
将一个数组转化为一个List对象,这个方***返回一个ArrayList类型的对象, 这个ArrayList类并非java.util.ArrayList类,而是Arrays类的静态内部类!用这个对象对列表进行添加删除更新操作,就会报UnsupportedOperationException异常。

hashMap在单线程中使用大大提高效率,在多线程的情况下使用hashTable来确保安全。hashTable中使用synchronized关键字来实现安全机制,但是synchronized是对整张hash表进行锁定即让线程独享整张hash表,在安全同时造成了浪费。concurrentHashMap采用分段加锁的机制来确保安全

ConcurrentHashMap使用segment来分段和管理锁,segment继承自ReentrantLock,因此ConcurrentHashMap使用ReentrantLock来保证线程安全。

75、JDK1.8版本之前,抽象类和接口的区别,以下说法错误的是 D
A、接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的。
B、abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface,实现多重继承。接口还有标识(里面没有任何方法,如Remote接口)和数据共享(里面的变量全是常量)的作用。
C、在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是 static final的,不过在 interface中一般不定义数据成员),所有的成员方法默认都是 public abstract 类型的。
D、abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"has-a"关系,interface表示的是"is-a"关系。
解析:
is-a:继承关系 has-a:从属关系 like-a:组合关系

76、下列哪一个方法你认为是新线程开始执行的点,也就是从该点开始线程n被执行 B
A、public void start()
B、public void run()
C、public void int()
D、public static void main(String args[])
E、public void runnable()
解析:
要写一个线程类,可以继承Thread方法,然后override他的run()方法
另一种方法是实现Runable接口,即为实现run()方法。
A,start()是启动一个线程的方法

题目的意思是,下列哪一个方法你认为是新线程开始执行的点,也就是从该点开始线程n被执行。
了解过线程的知识我们知道:
start()方法是启动一个线程,此时的线程处于就绪状态,但并不一定就会执行,还需要等待CPU的调度。
run()方法才是线程获得CPU时间,开始执行的点。

77、关于异常的编程,以下描述错误的是:(A)
A、在有除法存在的代码处,为了防止分母为零,必须抛出并捕获异常
B、int i=Integer.parseInt(”123a”);将产生NumberFormatException
C、int a[]=null; a[0]=1; 将产生NullPointerException
D、输入输出流编程中,读和写时都要抛出IOException
解析:
Java的异常分为两种,一种是运行时异常(RuntimeException),一种是非运行异常也叫检查式异常(CheckedException)。
1、运行时异常不需要程序员去处理,当异常出现时,JVM会帮助处理。常见的运行时异常有:
ClassCastException(类转换异常)
ClassNotFoundException
IndexOutOfBoundsException(数组越界异常)
NullPointerException(空指针异常)
ArrayStoreException(数组存储异常,即数组存储类型不一致)
还有IO操作的BufferOverflowException异常
2、非运行异常需要程序员手动去捕获或者抛出异常进行显示的处理,因为Java认为Checked异常都是可以被修复的异常。常见的异常有:
IOException
SqlException

异常分为运行时异常,非运行时异常和error,其中error是系统异常,只能重启系统解决。非运行时异常需要我们自己补获,而运行异常是程序运行时由虚拟机帮助我们补获,运行时异常包括数组的溢出,内存的溢出空指针,分母为0等!

78、下面关于Spring的说法中错误的是(D)
A、Spring是一个支持快速开发Java EE框架的框架
B、Spring中包含一个“依赖注入”模式的实现
C、使用Spring可以实现声明式事务
D、Spring提供了AOP方式的日志系统
解析:
D.Spring提供了AOP方式的日志系统
Spring并没有为我们提供日志系统,我们需要使用AOP(面向方面编程)的方式,借助Spring与日志系统log4j实现我们自己的日志系统。

解释一下答案A
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。

核心容器,Spring上下文,Spring AOP, Spring DAO, Spring ORM, Spring Web, Spring MVC。

79、在java中,下列对继承的说法,正确的是(A)
A、子类能继承父类的所有成员
B、子类继承父类的非私有方法和状态
C、子类只能继承父类的public方法和状态
D、子类只能继承父类的方法
解析:
使用反射可以看出子类是继承了父类的私有方法的(不管是否是final),只是直接调用父类的私有方法是不可以的,但是利用反射的方式可以调用。字段同理。

package work.litao;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
class Parent{
    Parent() {
        System.out.println("调用父类构造方法!");
    }
    private static void staticParent() {
        System.out.println("调用父类静态方法");
    }
    private final  void finalParent() {
        System.out.println("调用父类final方法");
    }
    private void printParent(){
        System.out.println("调用父类私有方法");
    }
}
class Child extends Parent {
    public void printChild(){
        System.out.println("调用子类公有方法");
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        //获取子类
        Class clazz = Class.forName("work.litao.Child");
        //得到父类
        Class superClass = clazz.getSuperclass();
        //得到父类非继承的所以方法
        Method[] methods = superClass.getDeclaredMethods();
        //设置私有方法可以被访问
        AccessibleObject.setAccessible(methods,true);
        for (Method m:methods) {
            System.out.println();
            System.out.println("子类调用方法"+m.getName()+"()的调用结果:" );
            m.invoke(new Child());
        }

    }
}

运行结果:
在这里插入图片描述
子类从其父类继承所有成员(字段,方法和嵌套类)。 构造函数不是成员,所以它们不被子类继承,但是可以从子类调用超类的构造函数。]
来自Oracle官方文档https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

80、 DBMS 中实现事务持久性的子系统是(D)
A、安全性管理子系统
B、完整性管理子系统
C、并发控制子系统
D、恢复管理子系统
解析:
原子性:事务是一组不可分割的操作单元,这组单元要么同时成功要么同时失败(由DBMS的事务管理子系统来实现);
一致性:事务前后的数据完整性要保持一致(由DBMS的完整性子系统执行测试任务);
隔离性:多个用户的事务之间不要相互影响,要相互隔离(由DBMS的并发控制子系统实现);
持久性:一个事务一旦提交,那么它对数据库产生的影响就是永久的不可逆的,如果后面再回滚或者出异常,都不会影响已提交的事务(由DBMS的恢复管理子系统实现的)

事务的四个特性以及对应的子系统:

(1)原子性(A):安全性管理子系统;

(2)一致性(C):完整性管理子系统;

(3)隔离性(I):并发控制子系统;

(4)持久性(D):恢复管理子系统;

81、servlet周期包含哪些:初始化、销毁、请求处理

解析:
init() --> 初始化
service() --> 处理请求
destory () --> 销毁(停止)

Servlet生命周期分成3个阶段:

1)初始化阶段:调用init方法

2)响应客户请求:调用service

3)终止:调用destory方法

初始化阶段:在下列时刻servlet容器装载servlet

1 servlet容器启动时,自动装载某些servlet

2 在servlet容器启动后,客户首次向servlet发送请求

3 servlet类文件被更新之后,重新装载servlet

Servlet被装载之后,servlet容器创建一个servlet’对象并调用servlet的init方法,在servlet生命周期内,init方法只能被调用一次。servlet工作原理:客户端发起一个请求,servlet调用service方法时请求进行响应,service对请求的方式进行了匹配,选择调用dopost或者doget等这些方法,然后进入对应方法中调用逻辑层的方法,实现对客户的响应。

响应客户请求:对于用户到达servlet的请求,servlet容器会创建特定于该请求的servletrequest和servletresponse对象,然后调用servlet的service方法,service方法从servletrequest对象中获取客户请求的信息,处理该请求,并且通过servletresponse对象向客户端返回响应信息。

终止:当web应用终止或者servlet容器终止或servlet容器重新装载servlet新实例时,servlet容器会调用servlet对象的destory方法,在destory方法中可以释放servlet占用的资源

在这里插入图片描述82、以下说法错误的是(A、B)
A、final修饰的方法不能被重载
B、final可以修饰类、接口、抽象类、方法和属性
C、final修饰的方法也不能被重写
D、final修饰的属性是常量,不可以修改
解析:
final表示最终的意思,它修饰的类是不能被继承的;final修饰的方法能被继承(Math类里就有),但是不能够被重写。其实关系并不复杂,你只需要记住这样一句话:final可用于声明属性、方法和类,分别表示属性不可变,方法不可重写,类不可继承。当然final修饰的方法是可以被重载的。

83、对于构造方法,下列叙述正确的是( A C D)
A、构造方法的优先级一般比代码块低。
B、构造方法的返回类型只能是void型。
C、构造方法的主要作用是完成对类的对象的初始化工作。
D、一般在创建新对象时,系统会自动调用构造方法。
解析:
A:静态成员变量或静态代码块>main方法>非静态成员变量或非静态代码块>构造方法
B:think in java中提到构造器本身并没有任何返回值。
C: 构造方法的主要作用是完成对类的对象的初始化工作。
D: 一般在创建(new)新对象时,系统会自动调用构造方法。

84、Java1.8版本之前的前提,Java特性中,abstract class和interface有什么区别(A B D)
A、抽象类可以有构造方法,接口中不能有构造方法
B、抽象类中可以有普通成员变量,接口中没有普通成员变量
C、抽象类中不可以包含静态方法,接口中可以包含静态方法
D、一个类可以实现多个接口,但只能继承一个抽象类。
解析;
A B D显然都是对的。主要说C选项:
在JDK1.8之前的版本(不包括JDK1.8),接口中不能有静态方法,抽象类中因为有普通方法,故也可以有静态方法。
在JDK1.8后(包括JDK1.8),在抽象类中依旧可以有静态方法,同时在接口中也可以定义静态方法了。
以下代码在JDK1.8之后是没有问题的(可以通过接口名来调用静态方法 :Main.prinf(); ):

public interface Demo{
    public static void print() {         
      System.out.println("Hello World!");      }
}

PS:
在JDK1.7,接口中只包含抽象方法,使用public abstract 修饰。

public interface Demo{
    public abstract void method();
}

在JDK1.8,接口中新加了默认方法和静态方法:
默认方法:使用default修饰,在接口的实现类中,可以直接调用该方法,也可以重写该方法。
静态方法:使用static修饰,通过接口直接调用。

public interface Demo{
    //默认方法
    public default void method(){
        System.out.println("default method...");
    }

    //静态方法
    public static void print(){
        System.out.println("static method...");
    }
}

在JDK1.9,接口中新加了私有方法,使用private修饰,私有方法供接口内的默认方法调用

public interface Demo{
    private void method() {
        System.out.println("Hello World!");
    }
} 

85、Gadget has-a Sprocket and Gadget has-a Spring and Gadget is-a Widget and Widget has-a Sprocket 以下哪两段代码可以表示这个关系? (选择两项) (AC)
A、
class Widget { Sprocket s; }
class Gadget extends Widget { Spring s; }
B、
class Widget { }
class Gadget extends Widget { Spring s1; Sprocket s2; }
C、
class Widget { Sprocket s1; Spring s2; }
class Gadget extends Widget { }
D、
class Gadget { Spring s; }
class Widget extends Gadget{ Sprocket s; }
解析:
is-a 表示继承:Gadget is-a Widget就表示Gadget 继承 Widget;
has-a表示从属:Gadget has-a Sprocket就表示Gadget中有Sprocket的引用,Sprocket是Gadget的组成部分;
like-a表示组合:如果A like-a B,那么B就是A的接口

86、关于下面一段代码,以下说法正确的是: (AC)

public class Test {
    private synchronized void a() {
    }
    private void b() {
        synchronized (this) {
        }
    }
    private synchronized static void c() {
    }
    private void d() {
        synchronized (Test.class) {
        }
    }
}

A、同一个对象,分别调用方法a和b,锁住的是同一个对象
B、同一个对象,分别调用方法a和c,锁住的是同一个对象
C、同一个对象,分别调用方法b和c,锁住的不是同一个对象
D、同一个对象,分别调用方法a、b、c,锁住的不是同一个对象
解析:
修饰非静态方法 锁的是this 对象
修饰静态方法 锁的是class对象

方法a为同步方法,方法b里面的是同步块,同步方法使用的锁是固有对象this,同步块使用的锁可以是任意对象,但是方法b里面的同步块使用的锁是对象this,所以方法a和方法b锁住的是同一个对象。方法 c为静态同步方法,使用的锁是该类的字节码文件,也就是Test.class。方法d里面的也是同步块,只不过使用的锁是Test.class,所以方法c和方法d锁住的是同一个对象。

87、以下哪项不属于java类加载过程 B
A、生成java.lang.Class对象
B、int类型对象成员变量赋予默认值
C、执行static块代码
D、类方法解析
解析:
不应该选D,而应该选B
类的加载包括:加载,验证,准备,解析,初始化。
选项A:生成java.lang.Class对象是在加载时进行的。生成Class对象作为方法区这个类的各种数据的访问入口。
选项B:既然是对象成员,那么肯定在实例化对象后才有。在类加载的时候会赋予初值的是类变量,而非对象成员。
选项C:这个会调用。可以用反射试验。
选项D:类方法解析发生在解析过程。

类加载过程
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中准备、验证、解析3个部分统称为连接(Linking)。如图所示。
在这里插入图片描述
加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)。以下陈述的内容都已HotSpot为基准。
加载
在加载阶段(可以参考java.lang.ClassLoader的loadClass()方法),虚拟机需要完成以下3件事情:
1.通过一个类的全限定名来获取定义此类的二进制字节流(并没有指明要从一个Class文件中获取,可以从其他渠道,譬如:网络、动态生成、数据库等);
2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
3.在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;
加载阶段和连接阶段(Linking)的部分内容(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未完成,连接阶段可能已经开始,但这些夹在加载阶段之中进行的动作,仍然属于连接阶段的内容,这两个阶段的开始时间仍然保持着固定的先后顺序。
验证
验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

验证阶段大致会完成4个阶段的检验动作:
1.文件格式验证:验证字节流是否符合Class文件格式的规范;例如:是否以魔术0xCAFEBABE开头、主次版本号是否在当前虚拟机的处理范围之内、常量池中的常量是否有不被支持的类型。
2.元数据验证:对字节码描述的信息进行语义分析(注意:对比javac编译阶段的语义分析),以保证其描述的信息符合Java语言规范的要求;例如:这个类是否有父类,除了java.lang.Object之外。
3.字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。
4.符号引用验证:确保解析动作能正确执行。

验证阶段是非常重要的,但不是必须的,它对程序运行期没有影响,如果所引用的类经过反复验证,那么可以考虑采用-Xverifynone参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间。
准备
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。这时候进行内存分配的仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在堆中。其次,这里所说的初始值“通常情况”下是数据类型的零值,假设一个类变量的定义为:

            publicstaticintvalue=123;        

那变量value在准备阶段过后的初始值为0而不是123.因为这时候尚未开始执行任何java方法,而把value赋值为123的putstatic指令是程序被编译后,存放于类构造器()方法之中,所以把value赋值为123的动作将在初始化阶段才会执行。
至于“特殊情况”是指:public static final int value=123,即当类字段的字段属性是ConstantValue时,会在准备阶段初始化为指定的值,所以标注为final之后,value的值在准备阶段初始化为123而非0.
解析
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。
初始化
类初始化阶段是类加载过程的最后一步,到了初始化阶段,才真正开始执行类中定义的java程序代码。在准备极端,变量已经付过一次系统要求的初始值,而在初始化阶段,则根据程序猿通过程序制定的主管计划去初始化类变量和其他资源,或者说:初始化阶段是执行类构造器()方法的过程.
()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块static{}中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的,静态语句块只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访问
原文链接 http://www.importnew.com/18548.html

88、对于如下代码段,可以放入到横线位置,使程序正确编译运行,而且不产生错误的选项是(C)

class A{
    public A foo() {
        return this;
    }
}
class B extends A {
    public A foo(){
        return this;
    }
}
class C extends B {
    _______

}

A、public void foo(){}
B、public int foo(){return 1;}
C、public A foo(B b){return b;}
D、public A foo(){return A;}
解析:
重写 要求两同两小一大原则, 方法名相同,参数类型相同,子类返回类型小于等于父类方法返回类型, 子类抛出异常小于等于父类方法抛出异常, 子类访问权限大于等于父类方法访问权限。[注意:这里的返回类型必须要在有继承关系的前提下比较]

重载 方法名必须相同,参数类型必须不同,包括但不限于一项,参数数目,参数类型,参数顺序
再来说说这道题 A B 都是方法名和参数相同,是重写,但是返回类型没与父类返回类型有继承关系,错误 D 返回一个类错误 c的参数类型与父类不同,所以不是重写,可以理解为广义上的重载访问权限小于父类,都会显示错误
虽然题目没点明一定要重载或者重写,但是当你的方法名与参数类型与父类相同时,已经是重写了,这时候如果返回类型或者异常类型比父类大,或者访问权限比父类小都会编译错误

public void foo(){} 方法名相同,返回值不同–>不是重写;而参数列表与父类相同,那么也不是重载。

public int foo(){return 1;} 方法名相同,返回值不同–>不是重写;而参数列表与父类相同,那么也不是重载。

public A foo(B b){return b;} 方法名相同,返回值(无所谓),而参数列表与父类不相同,那么是重载。另:B是A的子类,根据里氏替换原则/自动向上转型,可以这个选项正确。

public A foo(){return A;} 方法名相同,返回值相同,而参数列表也与父类相同,那么也不是重载。

89、下列哪个是合法的 Java 标识符?(BC)
A、Tree&Glasses
B、FirstJavaApplet
C、First_Applet
D、273.5
解析:
记住标识符只有英文,数字,下划线和$,而且数字不能做开头~

90、

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值