牛客练习笔记-JAVA 五

目录

题目:

1.java7后关键字 switch 支不支持字符串作为条件:()

2.一个容器类数据结构,读写平均,使用锁机制保证线程安全。如果要综合提高该数据结构的访问性能,最好的办法是______。

3.java语言的下面几种数组复制方法中,哪个效率最高?

4.下列不属于Java语言性特点的是

5.jre 判断程序是否执行结束的标准是()

6.以下JAVA程序的运行结果是什么(  )

7.关于volatile关键字,下列描述不正确的是?

8.JDK提供的用于并发编程的同步器有哪些?

9.JDK1.8版本之前,抽象类和接口的区别,以下说法错误的是

10.下面哪个流类不属于面向字符的流()

11.以下哪种方式实现的单例是线程安全的

12.下列类定义中哪些是合法的抽象类的定义?()

13.哪个关键字可以对对象加互斥锁?()

14.从以下四个选项选出不同的一个。

知识点总结:

1.java中复制数组的四种方法

1.Arrays类的copyOf()方法

2.Arrays类的copyOfRange()方法

3.System类的arraycopy()方法

4.Object类的clone()方法

2.同步器

3、了解volatile关键字不?

4.synchronized和volatile有什么区别?


题目:

1.java7后关键字 switch 支不支持字符串作为条件:()

A 支持

B 不支持

正确答案:A

参考答案:

在Java7之前,switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型。

在Java7中,呼吁很久的String支持也终于被加上了。 在switch语句中,表达式的值不能是null,否则会在运行时抛出NullPointerException。在case子句中也不能使用null,否则会出现编译错误。 同时,case字句的值是不能重复的。对于字符串类型的也一样,但是字符串中可以包含Unicode转义字符。重复值的检查是在Java编译器对Java源代码进行相关的词法转换之后才进行的。也就是说,有些case字句的值虽然在源代码中看起来是不同的,但是经词法转换之后是一样的,就会在成编译错误。

比如:“男”和“\u7537”就是一个意思。 然后看一个源代码及反编译后的代码: public class StringForSwitch { public void test_string_switch() { String result=""; switch ("doctor") { case "doctor": result = "doctor"; break; default: break; } } } 反编译后的,还原成大致的Java的代码如下: public class StringForSwitch { public StringForSwitch() { } public void test_string_switch() { String result = ""; String var2 = "doctor"; switch("doctor".hashCode()) { case -1326477025: if(var2.equals("doctor")) { result = "doctor"; } default: break; } } } 可以看出,字符串类型在switch语句中利用hashcode的值与字符串内容的比较来实现的;但是在case字句中对应的语句块中仍然需要使用String的equals方法来进一步比较字符串的内容,这是因为哈希函数在映射的时候可能存在冲突。

2.一个容器类数据结构,读写平均,使用锁机制保证线程安全。如果要综合提高该数据结构的访问性能,最好的办法是______。

A 只对写操作加锁,不对读操作加锁

B 读操作不加锁,采用copyOnWrite的方式实现写操作

C 分区段加锁

D 无法做到

正确答案:C

参考答案:答案:C A,只对写操作加锁,不对读操作加锁,会造成读到脏数据 B,CopyOnWrite的核心思想是利用高并发往往是读多写少的特性,对读操作不加锁,对写操作,先复制一份新的集合,在新的集合上面修改,然后将新集合赋值给旧的引用。这里读写平均,不适用 C,分段加锁,只在影响读写的地方加锁,锁可以用读写锁,可以提高效率

3.java语言的下面几种数组复制方法中,哪个效率最高?

A for 循环逐一复制

B System.arraycopy

C Array.copyOf

D 使用clone方法

正确答案:B

复制的效率System.arraycopy>clone>Arrays.copyOf>for循环,这个有兴趣自己测试一下就知道了。这里面在System类源码中给出了arraycopy的方法,是native方法,也就是本地方法,肯定是最快的。而Arrays.copyOf(注意是Arrays类,不是Array)的实现,在源码中是调用System.copyOf的,多了一个步骤,肯定就不是最快的。

4.下列不属于Java语言性特点的是

A Java致力于检查程序在编译和运行时的错误

B Java能运行虚拟机实现跨平台

C Java自己操纵内存减少了内存出错的可能性

D Java还实现了真数组,避免了覆盖数据的可能

正确答案:D

你的答案:C

参考答案:答案:D Java致力于检查程序在编译和运行时的错误。 Java虚拟机实现了跨平台接口 类型检查帮助检查出许多开发早期出现的错误。 Java自己操纵内存减少了内存出错的可能性。 Java还实现了真数组,避免了覆盖数据的可能。 注意,是避免数据覆盖的可能,而不是数据覆盖类型

5.jre 判断程序是否执行结束的标准是()

A 所有的前台线程执行完毕

B 所有的后台线程执行完毕

C 所有的线程执行完毕

D 和以上都无关

正确答案:A

JRE(Java Runtime Environment)判断程序是否执行结束的标准是所有的前台线程执行完毕。当所有的前台线程都执行完毕时,JRE会认为程序执行结束。后台线程不会影响程序的执行结束判断。

后台线程:指为其他线程提供服务的线程,也称为守护线程。JVM的垃圾回收线程就是一个后台线程。 前台线程:是指接受后台线程服务的线程,其实前台后台线程是联系在一起,就像傀儡和幕后操纵者一样的关系。傀儡是前台线程、幕后操纵者是后台线程。由前台线程创建的线程默认也是前台线程。可以通过isDaemon()和setDaemon()方法来判断和设置一个线程是否为后台线程。

6.以下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);
}

A 1 1

B 1.0 1.0

C 1 1.0

D 1.0 1

正确答案:D

 三元操作符类型的转换规则:

1.若两个操作数不可转换,则不做转换,返回值为Object类型

2.若两个操作数是明确类型的表达式(比如变量),则按照正常的二进制数字来转换,int类型转换为long类型,long类型转换为float类型等。

3.若两个操作数中有一个是数字S,另外一个是表达式,且其类型标示为T,那么,若数字S在T的范围内,则转换为T类型;若S超出了T类型的范围,则T转换为S类型。

4.若两个操作数都是直接量数字,则返回值类型为范围较大者

符合4,所以选D.

7.关于volatile关键字,下列描述不正确的是?

A 用volatile修饰的变量,每次更新对其他线程都是立即可见的。

B 对volatile变量的操作是原子性的。

C 对volatile变量的操作不会造成阻塞。

D 不依赖其他锁机制,多线程环境下的计数器可用volatile实现。

正确答案:BD

参考答案:一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。 2)禁止进行指令重排序。 volatile只提供了保证访问该变量时,每次都是从内存中读取最新值,并不会使用寄存器缓存该值——每次都会从内存中读取。 而对该变量的修改,volatile并不提供原子性的保证。 由于及时更新,很可能导致另一线程访问最新变量值,无法跳出循环的情况 多线程下计数器必须使用锁保护。

volatile的措施,就是

1. 每次从内存中取值,不从缓存中什么的拿值。这就保证了用 volatile修饰的共享变量,每次的更新对于其他线程都是可见的。

2. volatile保证了其他线程的立即可见性,就没有保证原子性。

3.由于有些时候对 volatile的操作,不会被保存,说明不会造成阻塞。不可用与多线程环境下的计数器。

8.JDK提供的用于并发编程的同步器有哪些?

A Semaphore

B CyclicBarrier

C CountDownLatch

D Counter

正确答案:ABC

A.  semaphore:信号量。用于表示共享资源数量。用acquire()获取资源,用release()释放资源。

B.  CyclicBarrier  线程到达屏障后等待,当一组线程都到达屏障后才一起恢复执行

C. CountDownLatch  初始时给定一个值,每次调用countDown值减1,当值为0时阻塞的线程恢复执行

参考答案:答案:ABC

A,Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。 B,CyclicBarrier 主要的方法就是一个:await()。await() 方法没被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。 C,直译过来就是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程。 D,Counter不是并发编程的同步器

9.JDK1.8版本之前,抽象类和接口的区别,以下说法错误的是

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"关系。

答案:D

  • 抽象类表示的是 is-a 关系;
  • 接口表示的是 like-a 关系;

10.下面哪个流类不属于面向字符的流()

A BufferedWriter

B FileInputStream

C ObjectInputStream

D InputStreamReader

正确答案:BC

11.以下哪种方式实现的单例是线程安全的

A 枚举

B 静态内部类

C 双检锁模式

D 饿汉式

正确答案:ABCD

单例 线程安全

饿汉式 懒汉式 枚举

静态内部类 双检锁模式

12.下列类定义中哪些是合法的抽象类的定义?()

A abstract Animal{abstract void growl();}

B class abstract Animal{abstract void growl();}

C abstract class Animal{abstract void growl();}

D abstract class Animal{abstract void growl(){System.out.println( “growl”);};}

正确答案:C

1. 首先,类的修饰符,都应该在class关键字之前,AB错;

2. 抽象方法不能有方法体,D错

13.哪个关键字可以对对象加互斥锁?()

A synchronized

B volatile

C serialize

D static

正确答案:A

synchronized 关键字 : 用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。

volatile:用来确保将变量的跟新操作通知到其他线程,当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。然而,在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比 synchronized关键字更轻量级的同步机制。

serialize:Java 对象序列化为二进制文件。

static关键字: static关键字可以修饰变量,方法,静态代码块。

14.从以下四个选项选出不同的一个。

A LVS

B Nginx

C Lighttpd

D Apache

正确答案:A  你的答案:B

官方解析:

LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。
Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。
Lighttpd 是一个德国人领导的开源Web服务器软件,其根本的目的是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的web server环境。具有非常低的内存开销、cpu占用率低、效能好以及丰富的模块等特点。
Apache是世界使用排名第一的Web服务器软件。它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一。

15.

知识点总结:

1.java中复制数组的四种方法

1.Arrays类的copyOf()方法

语法格式:

Arrays.copyOf(dataType[] srcArray,int length);

其中,srcArray表示要进行复制的数组,length表示复制后新数组的长度。
使用此方法复制数组时,默认从原数组的第一个元素,即下标为0的元素开始复制,目标数组的长度为length。如果length大于原数组的长度,则新数组中多余的元素以相应的默认值代替填充;如果length小于原数组的长度,则在新数组中只复制length个元素。
用法:

int []newList = (int[])Arrays.copyOf(list,5);
2.Arrays类的copyOfRange()方法

语法格式:

Arrays.copyOfRange(dataType[] srcArray,int startIndex,int endIndex);

其中,srcArray表示原数组,startIndex表示复制的起始索引,endIndex表示复制的终止索引,复制所得的数组是一个左闭右开的数组。且endIndex可以大于原数组的长度,此时目标数组中多余的元素以相应的默认值代替填充。
用法:

int []newList = (int[])Arrays.copyOfRange(list,0,5);
3.System类的arraycopy()方法

arraycopy()位于java.lang.System类中,其语法格式为:

System.arraycopy(dataType[] array1,int index1,dataType[] array2,int index2,int length)

其中,array1表示原数组,index1表示原数组中复制的起始索引,array2表示目标数组,index2表示目标数组中复制的起始索引,length表示复制的长度。而且length+index1必须小于原数组长度,length+index2必须小于目标数组长度。
用法:

System.arraycopy(list,0,newList,0,5);
4.Object类的clone()方法

clone()方法的返回值类型为Object类型,所以需要进行类型强制转换。其语法格式为:

array_name.clone()

其中,array_name为原数组名,用原数组直接调用clone()即可。
用法:

int []newList = (int[])list.clone();


效率:System.arraycopy > clone > Arrays.copyOf > for循环

2.同步器

3、了解volatile关键字不?

volatile是Java提供的最轻量级的同步机制,保证了共享变量的可见性,被volatile关键字修饰的变量,如果值发生了变化,其他线程立刻可见,避免出现脏读现象。同时volatile禁止了指令重排,可以保证程序执行的有序性,但是由于禁止了指令重排,所以JVM相关的优化没了,效率会偏弱

4.synchronized和volatile有什么区别?

从内存语义方面进行阐述

1. volatile本质是告诉JVM当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。

2. volatile仅能用在变量级别,而synchronized可以使用在变量、方法、类级别。

3. volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性。

4. volatile不会造成线程阻塞,synchronized可能会造成线程阻塞。

5. volatile标记的变量不会被编译器优化,synchronized标记的变量可以被编译器优化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值