牛客网选择题错题集锦(三)
1.默认RMI采用的是什么通信协议?
A.HTTP
B.UDP/IP
C.TCP/IP
D.Multicast
选C
RMI采用的是TCP/IP协议
2.下面关于volatile的功能说法正确的是哪个
A.原子性
B.有序性
C.可见性
D.持久性
选BC
synchronized保证三大性,原子性,有序性,可见性,volatile保证有序性,可见性,不能保证原子性
volatile到底做了什么:
(1)禁止了指令重排
(2)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量值,这个新值对其他线程是立即可见的
(3)不保证原子性(线程不安全)
synchronized关键字和volatile关键字比较:
volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字修饰非静态方法是给非静态方法加锁,修饰静态方法时相当于给类加锁。synchronized关键字
多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞
volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。
volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。
3.关于 访问权限说法正确 的是 ? ( )
A.外部类定义前面可以修饰public,protected和private
B.局部内部类前面可以修饰public,protected和private
C.匿名内部类前面可以修饰public,protected和private
D.以上说法都不正确
选D
在Java中,可以将一个类定义在另一个类里面或者一个方法里边,这样的类称为内部类,广泛意义上的内部类一般包
括四种:成员内部类,局部内部类,匿名内部类,静态内部类 。
1.成员内部类
(1)该类像是外部类的一个成员,可以无条件的访问外部类的所有成员属性和成员方法(包括private成员和静态成
员);
(2)成员内部类拥有与外部类同名的成员变量时,会发生隐藏现象,即默认情况下访问的是成员内部类中的成员。如
果要访问外部类中的成员,需要以下形式访问:【外部类.this.成员变量 或 外部类.this.成员方法】;
(3)在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访
问;
(4)成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对
象;
(5)内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。如果成员内部类
用private修饰,则只能在外部类的内部访问;如果用public修饰,则任何地方都能访问;如果用protected修
饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。外部类只
能被public和包访问两种权限修饰。
2.局部内部类
(1)局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方
法内或者该作用域内;
(2)局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰
符的。
3.匿名内部类
(1)一般使用匿名内部类的方法来编写事件监听代码;
(2)匿名内部类是不能有访问修饰符和static修饰符的;
(3)匿名内部类是唯一一种没有构造器的类;
(4)匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
4.内部静态类
(1)静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似;
(2)不能使用外部类的非static成员变量或者方法。
总结:
对于外部类来说,只有两种修饰,public和默认(default),因为外部类放在包中,只有两种可能,包可见和包
不可见。
对于内部类来说,可以有所有的修饰,因为内部类放在外部类中,与成员变量的地位一致,所以有四种可能。
4.对于线程局部存储TLS(thread local storage),以下表述正确的是
A.解决多线程中的对同一变量的访问冲突的一种技术
B.TLS会为每一个线程维护一个和该线程绑定的变量的副本
C.每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了
D.Java平台的java.lang.ThreadLocal是TLS技术的一种实现
选ACD
5.以下代码结果是什么?
public class foo {
public static void main(String sgf[]) {
StringBuffer a=new StringBuffer(“A”);
StringBuffer b=new StringBuffer(“B”);
operate(a,b);
System.out.println(a+”.”+b);
}
static void operate(StringBuffer x,StringBuffer y) {
x.append(y);
y=x;
}
}
A.代码可以编译运行,输出“AB.AB”。
B.代码可以编译运行,输出“A.A”。
C.代码可以编译运行,输出“AB.B”。
D.代码可以编译运行,输出“A.B”。
选C
引用a指向对象A
引用b指向对象B
引用x指向对象A
引用y指向对象B
在operate方法中,引用x指向的对象A被连接了B,对象A也就被改变为AB
然后又把引用y指向了x所指向的对象地址,也就是此时引用a,x,y指向同一个对象AB
而引用b没有发生任何变化,依旧指向对象B。
6.关于运行时常量池,下列哪个说法是正确的
A.运行时常量池大小受栈区大小的影响
B.运行时常量池大小受方法区大小的影响
C.存放了编译时期生成的各种字面量
D.存放编译时期生成的符号引用
选BCD
在JDK1.8之前运行时常量池被放