1.关于spring说法错误的是()
A. spring是一个轻量级JAVA EE的框架集合
B. spring是“依赖注入”模式的实现
C. 使用spring可以实现声明事务
D. spring提供了AOP方式的日志系统
解:D,spring没有自己的日志系统,只能与日志系统log4j实现我们自己的日志系统。
拓展:
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。
Spring通过对AOP的支持,借助log4j等Apache开源组件实现了日志系统。
2.以下代码将打印出
public static void main (String[] args) {
String classFile = "com. jd. ". replaceA11(".", "/") + "MyClass.class";
System.out.println(classFile);
}
A. com. jd
B. com/jd/MyClass.class
C. ///////MyClass.class
D. com.jd.MyClass
解:C,由于replaceAll方法的第一个参数是一个正则表达式,而”.”在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成”/”。如果想替换的只是”.”,那么要写成”\.”.
3.Given the following code:
public class Enclosingone
{
public class InsideOne {}
}
public class inertest
{
public static void main(string[]args)
{
EnclosingOne eo = new EnclosingOne();
//insert code here
}
}
Which statement at line 7 constructs an instance of the inner class?
A. InsideOne ei=eo.new InsideOne();
B. eo.InsideOne ei=eo.new InsideOne();
C. InsideOne ei=EnclosingOne.new InsideOne();
D. EnclosingOne.InsideOne ei=eo.new InsideOne();
解:D,
public class Enclosingone {
//非静态内部类
public class InsideOne {}
//静态内部类
public static class InsideTwo{}
}
class Mytest{
public static void main(String args []){
Enclosingone.InsideOne obj1 = new Enclosingone().new InsideOne();//非静态内部类对象,非静态,先有Enclosingone对象才能有属性
Enclosingone.InsideTwo obj2 = new Enclosingone.InsideTwo();//静态内部类对象
}
}
4.下面有关java内存模型的描述,说法错误的是?
A. JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证
B. “synchronized” — 保证在块开始时都同步主内存的值到工作内存,而块结束时将变量同步回主内存
C. “volatile” — 保证修饰后在对变量读写前都会与主内存更新。
D. 如果在一个线程构造了一个不可变对象之后(对象仅包含final字段),就可以保证了这个对象被其他线程正确的查看
解:D,
Java线程之间的通信由Java内存模型(简称为JMM)控制,JMM决定一个线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化
volatile变量的写-读可以实现线程之间的通信。
从内存语义的角度来说,volatile与监视器锁有相同的效果:volatile写和监视器的释放有相同的内存语义;volatile读与监视器的获取有相同的内存语义。
5.假设如下代码中,若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();
}
A. Thread 1 wake up
Thread 2 sent notify.
B. Thread 2 sent notify.
Thread 1 wake up
C. A、B皆有可能
D. 程序无输出卡死
解:B,执行obj.wait();时已释放了锁,所以t2可以再次获得锁,然后发消息通知t1执行,但这时t2还没有释放锁,所以肯定是执行t2,然后释放锁,之后t1才有机会执行。
拓展:
notify()就是对对象锁的唤醒操作。但有一点需要注意的是notify()调用后,并不是马上就释放对象锁的,而是在相应的synchronized(){}语句块执行结束,自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。这样就提供了在线程间同步、唤醒的操作。
6.
public class Test
{
static boolean foo(char c)
{
System.out.print(c);
return true;
}
public static void main( String[] argv )
{
int i = 0;
for ( foo('A'); foo('B') && (i < 2); foo('C'))
{
i++ ;
foo('D');
}
}
}
what is the result?
A. ABDCBDCB
B. ABCDABCD
C. Compilation fails.
D. An exception is thrown at runtime.
解:A,
for(条件1;条件2;条件3) {
//语句
}
执行顺序是条件1->条件2->语句->条件3->条件2->语句->条件3->条件2……..
如果条件2为true,则一直执行。如果条件2位false,则for循环结束
7.考虑下面这个简单的例子,让我们看看reflection是如何工作的。
import java.lang.reflect.*;
public class DumpMethods{
public static void main(String[] args) {
try {
Class c=Class.forName(args[0]);
Method m[]=c.getDeclaredMethods();
for (int i = 0; i < m.length; i++) {
System.out.println(m[i].toString());
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
其中”c.getDeclaredMethods”的作用是:
A. 取得类的公有方法对象
B. 取得类的所有公有方法名称
C. 取得类的所有方法对象
D. 以上选项都不正确
解:C,
public Method[] getDeclaredMethods()返回类或接口声明的所有方法,包括public, protected, default (package) 访问和private方法的Method对象,但不包括继承的方法。当然也包括它所实现接口的方法。
public Method[] getMethods()返回某个类的所有public方法,包括其继承类的公用方法,当然也包括它所实现接口的方法。
8.以下哪几种方式可用来实现线程间通知和唤醒:( )
A. Object.wait/notify/notifyAll
B. ReentrantLock.wait/notify/notifyAll
C. Condition.await/signal/signalAll
D. Thread.wait/notify/notifyAll
解:AC,
wait()、notify()和notifyAll()是 Object类 中的方法 ;
Condition是在java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、 notify(),使用Condition的await()、signal()这种方式实现线程间协作更加安全和高效。
拓展:
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()。
9.java中 String str = “hello world”下列语句错误的是?
A. str+=’ a’
B. int strlen = str.length
C. str=100
D. str=str+100
解:ABC
A. ‘a’是字符,’ a’这个是空格和a,必须要用” a”才可以;
B.String有length()方法
C.int 无法直接转成String类型
D.尾部添加字符串”100“
10.已知如下类定义:
class Base {
public Base (){
//...
}
public Base ( int m ){
//...
}
public void fun( int n ){
//...
}
}
public class Child extends Base{
// member methods
}
如下哪句可以正确地加入子类中?
A. private void fun( int n ){ //…}
B. void fun ( int n ){ //… }
C. protected void fun ( int n ) { //… }
D. public void fun ( int n ) { //… }
解:D
方法的重写(override)两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。
本文是Java面试系列第四天的内容,涉及Spring框架、AOP概念、Java内存模型以及多线程相关问题,包括wait/notify、线程间通信、反射、线程同步和唤醒等知识点。
2万+

被折叠的 条评论
为什么被折叠?



