2021年09月15日 java2

考点1:catch先捕获子类异常再捕获父类异常

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

  • A 正确
  • B 错误
显示答案/隐藏答案正确答案: A

如果将父类放在前面的话,异常将被父类完全捕获,子类永远不能捕获异常

考点2:自动拆箱

有如下4条语句:()

1
2
3
4
Integer i01=59;
int i02=59;
Integer i03=Integer.valueOf(59);
Integer i04=new Integer(59);

以下输出结果为false的是:

  • A System.out.println(i01==i02);
  • B System.out.println(i01==i03);
  • C System.out.println(i03==i04);
  • D System.out.println(i02==i04);
显示答案/隐藏答案正确答案: C

int和Integer比较时 Integer会自动拆箱取出值来和int进行比较

A选项,i01==i02,i02是int类型的,i01是Integer类型的,int类型的i02和Integer类型i01比较时,会给i02自动拆箱,取出里面的值59和i01的值59进行比较,59==59为true
D选项,A选项一样,i02是int类型,i04是Integer类型的,比较值,59==59,得到true
Integer有默认缓存[-128,+127]

Integer i01=59;会自动装箱,实际上调用:

1
Integer i01=Integer.valueOf(59);

1
Integer i03=Integer.valueOf(59);

59在区间[-128,+127]内,所以是同一个对象。

B选项,i01==i03,i01是Integer的引用变量名,i02是Integer引用变量,两个引用变量使用==比较时比较的是地址。
因为i01和i03引用的都是区间[-128,+127]内事先创建好的59,所以是同一个对象。所以得到true

C选项,i03==i04,i03引用的是缓存内的59,i04引用的是新创建的59对象。这两个对象不是同一个对象,所以得到false。

考点3:JVM参数 不懂 待学

假如某个JAVA进程的JVM参数配置如下:
-Xms1G -Xmx2G -Xmn500M -XX:MaxPermSize=64M -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=3,
请问eden区最终分配的大小是多少?

  • A 64M
  • B 500M
  • C 300M
  • D 100M
显示答案/隐藏答案正确答案: C

这是网易2016年在线笔试题中的一道选择题。
先分析一下里面各个参数的含义:
-Xms:1G , 就是说初始堆大小为1G
-Xmx:2G , 就是说最大堆大小为2G
-Xmn:500M ,就是说年轻代大小是500M(包括一个Eden和两个Survivor)
-XX:MaxPermSize:64M , 就是说设置持久代最大值为64M
-XX:+UseConcMarkSweepGC , 就是说使用使用CMS内存收集算法
-XX:SurvivorRatio=3 , 就是说Eden区与Survivor区的大小比值为3:1:1
题目中所问的Eden区的大小是指年轻代的大小,直接根据-Xmn:500M和-XX:SurvivorRatio=3可以直接计算得出
500M*(3/(3+1+1))
=500M(3/5)
=500M
0.6
=300M
所以Eden区域的大小为300M。

参数解释:
-Xms1G :初始堆空间为1G
-Xmx2G :指定最大堆空间为2G
-Xmn500M :指定堆空间的年轻代大小为500M(年轻代=Eden+Survivor)
-XX:MaxPermSize=64M:指定最大永久代为64M
-XX:+UseConcMarkSweepGC 使用CMS垃圾收集器
-XX:SurvivorRatio=3 指定堆的年轻代中Eden和Survivor区的比例,也就是Eden:Survivor(from):Survivor(to)=3:1:1
由-Xmn500M可知:eden=3/5*500M=300M
答案为C,
堆内存示意图:

考点4:

下列关于Java并发的说法中正确的是()

  • A CopyOnWriteArrayList适用于写多读少的并发场景
  • B ReadWriteLock适用于读多写少的并发场景
  • C ConcurrentHashMap的写操作不需要加锁,读操作需要加锁
  • D 只要在定义int类型的成员变量i的时候加上volatile关键字,那么多线程并发执行i++这样的操作的时候就是线程安全的了
显示答案/隐藏答案正确答案: B

答案:B
A,CopyOnWriteArrayList适用于写少读多的并发场景
B,ReadWriteLock即为读写锁,他要求写与写之间互斥,读与写之间互斥,读与读之间可以并发执行。在读多写少的情况下可以提高效率
C,ConcurrentHashMap是同步的HashMap,读写都加锁
D,volatile只保证多线程操作的可见性,不保证原子性

对于D选项,volatite只保证线程在“加载数据阶段”加载的数据是最新的,并不能保证线程安全。

volatite

对于D选项,volatite只保证线程在“加载数据阶段”加载的数据是最新的,并不能保证线程安全。
一个线程执行的过程有三个阶段:
加载(复制)主存数据到操作栈 –> 对操作栈数据进行修改 –> 将操作栈数据写回主存。

volatite关键字,让编译器不去优化代码使用缓存等,以保证线程在“加载数据阶段”加载的数据都是最新的
比如:
某一时刻i=6是最新的值,volatile保证线程A,B都同时加载了这个最新的值,
然后A执行i(A)+1=7,然后将7写回主存,
B也执行i(B)+1=7,然后也将7写回内存,
这样,执行两次加法,i却只增加了1。

对于volatile修饰的变量,jvm虚拟机只是保证从主内存加载到线程工作内存的值是最新的,同时线程工作内存中的操作并不是原子性的。所以在一个线程对该变量进行操作的同时,其他的线程有可能也在对该变量进行操作。

A:CopyOnWrite并发容器用于读多写少的并发场景,Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet。
C:在JDK1.7之前,ConcurrentHashMap是通过分段锁机制来实现的,所以其最大并发度受Segment的个数限制。因此,在JDK1.8中,ConcurrentHashMap的实现原理摒弃了这种设计,而是选择了与HashMap类似的数组+链表+红黑树的方式实现,而加锁则采用CAS和synchronized实现。读写都加锁
D:volatile保证内存可见性和有序性(内存屏障实现),不能保证原子性。

考点5:

如果希望监听TCP端口9000,服务器端应该怎样创建socket?

  • A new Socket(“localhost”,9000);
  • B new ServerSocket(9000);
  • C new Socket(9000);
  • D new ServerSocket(“localhost”,9000);
显示答案/隐藏答案正确答案: B

答案选B。
ServerSocket(int port)是服务端绑定port端口,调accept()监听等待客户端连接,它返回一个连接队列中的一个socket。
Socket(InetAddress address ,int port)是创建客户端连接主机的socket流,其中InetAddress是用来记录主机的类,port指定端口。
socket和servletSocket的交互如下图所示:

详细了解,大家可以看此博客:http://www.cnblogs.com/rond/p/3565113.html

  • 服务端:ServerSocket(port),因为服务器知道自己的IP,所以不需要输入IP
  • 客户端:Socket(host,port),因为客户端不知道连接那个服务端,所以需要输入服务器的IP

首先,服务器监听端口的必定用 ServerSocket;其次,根据对 Server 和 Client 的了解,
Server 只需要监听请求即可,
Client 则必须指明向谁请求和向服务器的哪个端口请求。

ServerSocket(int port)创建一个serversocket绑定在服务器的特定的端口
Socket(InetAddress address, int port)创建一个socket流,连接到指定服务器(address)的指定端口(port)

考点6:

下列描述正确的是( )?

  • A 类不可以多继承而接口可以多实现
  • B 抽象类自身可以定义成员而接口不可以
  • C 抽象类和接口都不能被实例化
  • D 一个类可以有多个基类和多个基接口
显示答案/隐藏答案正确答案: AC

1.java支持单继承,却可以实现多个接口。a对d错
2.接口没有构造方法,所以不能实例化,抽象类有构造方法,但是不是用来实例化的,是用来初始化的。c对
3.抽象类可以定义普通成员变量,静态成员变量。接口只能定义静态成员常量,也就是接口成员变量要使用 public static final来修饰。b错

接口只能定义静态成员常量

考点7:

下面的Java赋值语句哪些是有错误的 ()

  • A int i =1000;
  • B float f = 45.0;
  • C char s = '\u0639'
  • D Object o = 'f';
  • E String s = "hello,world\0";
  • F Double d = 100;
显示答案/隐藏答案正确答案: BCF

B选项45.0默认是double类型的。
C选项少了分号
F选项是自动装箱, 装箱过程中调用的是Double类的valueOf(double d)方法, 而这里是100为int型, 所以编译会“cannot convert from int to Double”。