0
点赞
收藏
分享

微信扫一扫

一周面试错题整理(二)

M4Y 2022-04-21 阅读 54
java

1、下面哪些具体实现类可以用于存储键,值对,并且方法调用提供了基本的多线程安全支持:(AE)

A、java.util.cocurrent.ConcurrentHashMap

B、java.util.Map

C、java.util.TreeMap

D、java.util.SortMap

E、java.util.Hashtable

F、java.util.HashMap

分析:

  • Hashtable是线程安全的哈希表,它是通过synchronized来保证线程安全的;即,多线程通过同一个“对象的同步锁”来实现并发控制。Hashtable在线程竞争激烈时,效率比较低(此时建议使用ConcurrentHashMap)。当一个线程访问Hashtable的同步方法时,其它线程如果也在访问Hashtable的同步方法时,可能会进入阻塞状态。
  • Collections.synchronizedMap()使用了synchronized同步关键字来保证对Map的操作是线程安全的。
  • ConcurrentHashMap是线程安全的哈希表。在JDK1.7中它是通过“锁分段”来保证线程安全的,本质上也是一个“可重入的互斥锁”(ReentrantLock)。多线程对同一个片段的访问,是互斥的;但是,对于不同片段的访问,却是可以同步进行的。在JDK1.8中是通过使用CAS原子更新、volatile关键字、synchronized可重入锁实现的。

2、mysql数据库,game_order表表结构如下,下面哪些sql能使用到索引(BCDE)

A、select * from game_order where plat_game_id=5 and plat_id=134

B、select * from game_order where plat_id=134 and plat_game_id=5 and plat_order_id=’100’

C、select * from game_order where plat_order_id=’100’

D、select * from game_order where plat_game_id=5 and plat_order_id=’100’ and plat_id=134

E、select * from game_order where plat_game_id=5 and plat_order_id=’100’

分析:

  • 这道题目想考察的知识点是MySQL组合索引(复合索引)的最左优先原则。最左优先就是说组合索引的第一个字段必须出现在查询组句中,这个索引才会被用到。只要组合索引最左边第一个字段出现在Where中,那么不管后面的字段出现与否或者出现顺序如何,MySQL引擎都会自动调用索引来优化查询效率。
  • 根据最左匹配原则可以知道B-Tree建立索引的过程,比如假设有一个3列索引(col1,col2,col3),那么MySQL只会会建立三个索引(col1),(col1,col2),(col1,col2,col3)。
  • 所以题目会创建三个索引(plat_order_id)、(plat_order_id与plat_game_id的组合索引)、(plat_order_id、plat_game_id与plat_id的组合索引)。根据最左匹配原则,where语句必须要有plat_order_id才能调用索引(如果没有plat_order_id字段那么一个索引也调用不到),如果同时出现plat_order_id与plat_game_id则会调用两者的组合索引,如果同时出现三者则调用三者的组合索引。
  • 题目问有哪些sql能使用到索引,Where后出现了plat_order_id字段的SQL语句都会调用到索引,只不过是所调用的索引不同而已,所以选BCDE。如果题目说清楚是调用到三个字段的复合索引,那答案才是BD。

3、下面有关jdbc statement的说法错误的是?(C)

A、JDBC提供了Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程

B、对于PreparedStatement来说,数据库可以使用已经编译过及定义好的执行计划,由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象”

C、PreparedStatement中,“?” 叫做占位符,一个占位符可以有一个或者多个值

D、PreparedStatement可以阻止常见的SQL注入式攻击

分析:

一个占位符有一个值

Statement、PreparedStatement和CallableStatement的区别

  • Statement、PreparedStatement和CallableStatement都是接口(interface)。 
  • Statement继承自Wrapper、PreparedStatement继承自Statement、CallableStatement继承自PreparedStatement。 
  • Statement接口提供了执行语句和获取结果的基本方法; 
  • Statement: 普通的不带参的查询SQL;支持批量更新,批量删除; 
  • PreparedStatement: 可变参数的SQL,编译一次,执行多次,效率高; 安全性好,有效防止Sql注入等问题; 支持批量更新,批量删除; 
  • CallableStatement: 继承自PreparedStatement,支持带参数的SQL操作; 支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持; 
  • Statement每次执行sql语句,数据库都要执行sql语句的编译 ,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement。

PreparedStatement是预编译的,使用PreparedStatement有几个好处 :

  • 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。 
  • 安全性好,有效防止Sql注入等问题。 
  • 对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;
  • 代码的可读性和可维护性。

4、下列说法正确的是(C)

A、WebLogic中开发消息Bean的non-persistent 方式可以保证消息的可靠

B、EJB容器发生错误,non-persistent方式下JMS容器仍然会将消息发送

C、EJB容器发生错误,persistent方式下JMS容器仍然会将消息发送

D、EJB容器发生错误,两种方式下JMS容器仍会在MDB可用的时候将消息发送

分析:

weblogic中开发消息Bean时的persistent与non-persisten的差别:

  • persistent方式的MDB可以保证消息传递的可靠性,也就是如果EJB容器出现问题而JMS服务器依然会将消息在此MDB可用的时候发送过来。
  • non-persistent方式的消息将被丢弃

J2EE中容器充当中间件的角色,主要的容器包括:

  • WEB容器:给处于其中的应用程序组件(jsp,servlet)提供一个环境,使jsp,servlet直接与容器中的环境变量接***互,不必关注其它系统问题。主要由WEB服务器来实现。 例如:tomcat,weblogic,websphere等
  • EJB容器:Enterprise java bean容器。供给运行在其中的组件EJB各种管理功能,满足J2EE规范的EJB放入该容器,马上就会被容器进行高效率的管理,并且可以通过现成的接口来获得系统级别的服务。例如邮件服务、事务管理。
  • WEB容器更多的是跟基于HTTP的请求打交道。而EJB容器更多的和数据库、其它服务打交道。但他们都是把与外界的交互实现从而减轻应用程序的负担。例如SERVLET不用关心HTTP的细节,直接引用环境变量session,request,response就行、EJB不用关心数据库连接速度、各种事务控制,直接由容器来完成。

5、在一个基于分布式的游戏服务器系统中,不同的服务器之间,哪种通信方式是不可行的(A)?

A、管道

B、消息队列

C、高速缓存数据库

D、套接字

分析:

管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。不适于不同服务器之间的通信

消息队列

什么是消息队列? 我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。 摘自 https://www.jianshu.com/p/36a7775b04ec 举例: 小红是小明的姐姐。 小红希望小明多读书,常寻找好书给小明看,之前的方式是这样:小红问小明什么时候有空,把书给小明送去,并亲眼监督小明读完书才走。久而久之,两人都觉得麻烦。 后来的方式改成了:小红对小明说「我放到书架上的书你都要看」,然后小红每次发现不错的书都放到书架上,小明则看到书架上有书就拿下来看。 书架就是一个消息队列,小红是生产者,小明是消费者。 这带来的好处有: 1.小红想给小明书的时候,不必问小明什么时候有空,亲手把书交给他了,小红只把书放到书架上就行了。这样小红小明的时间都更自由。 2.小红相信小明的读书自觉和读书能力,不必亲眼观察小明的读书过程,小红只要做一个放书的动作,很节省时间。 3.当明天有另一个爱读书的小伙伴小强加入,小红仍旧只需要把书放到书架上,小明和小强从书架上取书即可(唔,姑且设定成多个人取一本书可以每人取走一本吧,可能是拷贝电子书或复印,暂不考虑版权问题)。 4.书架上的书放在那里,小明阅读速度快就早点看完,阅读速度慢就晚点看完,没关系,比起小红把书递给小明并监督小明读完的方式,小明的压力会小一些。 这就是消息队列的四大好处: 1.解耦 每个成员不必受其他成员影响,可以更独立自主,只通过一个简单的容器来联系。 小红甚至可以不知道从书架上取书的是谁,小明也可以不知道往书架上放书的人是谁,在他们眼里,都只有书架,没有对方。 毫无疑问,与一个简单的容器打交道,比与复杂的人打交道容易一万倍,小红小明可以自由自在地追求各自的人生。 2.提速 小红选择相信「把书放到书架上,别的我不问」,为自己节省了大量时间。 小红很忙,只能抽出五分钟时间,但这时间足够把书放到书架上了。 3.广播 小红只需要劳动一次,就可以让多个小伙伴有书可读,这大大地节省了她的时间,也让新的小伙伴的加入成本很低。 4.削峰 假设小明读书很慢,如果采用小红每给一本书都监督小明读完的方式,小明有压力,小红也不耐烦。 反正小红给书的频率也不稳定,如果今明两天连给了五本,之后隔三个月才又给一本,那小明只要在三个月内从书架上陆续取走五本书读完就行了,压力就不那么大了。 摘自 https://www.zhihu.com/question/34243607

6、以下代码结果是什么?(C)

A、代码可以编译运行,输出“AB.AB”。

B、代码可以编译运行,输出“A.A”。

C、代码可以编译运行,输出“AB.B”。

D、代码可以编译运行,输出“A.B”。

解析:

引用a指向对象A

引用b指向对象B

引用x指向对象A

引用y指向对象B

在operate方法中,引用x指向的对象A被连接了B,对象A也就被改变为AB

然后又把引用y指向了x所指向的对象地址,也就是此时引用a,x,y指向同一个对象AB

而引用b没有发生任何变化,依旧指向对象B。

7、DBMS 中实现事务持久性的子系统是(D)

A、安全性管理子系统

B、完整性管理子系统

C、并发控制子系统

D、恢复管理子系统

分析:

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

8、下面的类哪些可以处理Unicode字符?(ABC)

A、InputStreamReader

B、BufferedReader

C、Writer

D、PipedInputStream

解析:

字符流是字节流根据字节流所要求的编码集解析获得的

可以理解为字符流=字节流+编码集

和字符流有关的类都拥有操作编码集(unicode)的能力。

9、有程序片段如下,以下表达式结果为 true 的是( B)

Float  s=new  Float(0.1f);

Float  t=new  Float(0.1f);

Double  u=new  Double(0.1);

A、s==t

B、s.equals(t)

C、u.equals(s)

D、t.equals(u)

解析:

jdk1.5之后,==与equals方法:

  • 基本型和基本型封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较。
  • 两个Integer类型进行“==”比较,如果其值在-128至127,那么返回true,否则返回false。
  • 两个基本型的封装型进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true
  • 基本型封装类型调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,再进行3中的比较。

Float类和Double类都重写对于的equals方法,在比较之前都会判断是否同属于Float对象或Double对象,如果不是直接返回false,如果是再继续比较对应的数值大小。

A比较的是两个对象的地址,显然不同的对象地址不同,A是false。

B同属于Float对象且值相等,true。

C和D比较的对象不同,false。

10、以下哪个区域不属于新生代?(C)

A、eden区

B、from区

C、元数据区

D、to区

分析:

Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。

在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。
这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。

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

A、64M

B、500M

C、300M

D、100M

分析:

先分析一下里面各个参数的含义: 
-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。

12、下面有关值类型和引用类型描述正确的是(ABC)?

A、值类型的变量赋值只是进行数据复制,创建一个同值的新对象,而引用类型变量赋值,仅仅是把对象的引用的指针赋值给变量,使它们共用一个内存地址。

B、值类型数据是在栈上分配内存空间,它的变量直接包含变量的实例,使用效率相对较高。而引用类型数据是分配在堆上,引用类型的变量通常包含一个指向实例的指针,变量通过指针来引用实例。

C、引用类型一般都具有继承性,但是值类型一般都是封装的,因此值类型不能作为其他任何类型的基类。

D、值类型变量的作用域主要是在栈上分配内存空间内,而引用类型变量作用域主要在分配的堆上。

分析:

引用类型的变量也在栈区,只是其引用的对象在堆区

13、下面代码运行结果是?(A)

A、15 0 20

B、15 0 15

C、20 0 20

D、0 15 20

分析:

  • new一个Test对象t,调t.first()方法
  • first方法

new一个Value对象v,将v的i改为25,调second(v,i)

  • second()方法

把second()换一下

publicvoidsecond(Value tmp,inti){

    i = 0;

    tmp.i = 20;

    Value val = newValue( );

    tmp = val;

    System.out.println(tmp.i+" "+i);

   }

这个tmp其实相当于是一个指向原来first中的V这个对象的指针,也就是对v对象的引用而已。但是引用是会改变所指的地址的值的。所以在second中当tmp.i= 20的时候,就把原来first中的v的i值改为20了。

接下来,又把tmp指向了新建的一个对象,所以在second中的tmp,现在指的是新的对象val,新对象的i值为15。所以输出v.i=15,i=0。

当执行完毕second后,在first中在此输出v.i的时候,应为前面second中已经把该位置的i的值改为了20,所以输出的是20

14、存根(Stub)与以下哪种技术有关(B)

A、交换

B、动态链接

C、动态加载

D、磁盘调度

分析:

  • 存根类是一个类,它实现了一个接口,它的作用是:如果一个接口有很多方法,如果要实现这个接口,就要实现所有的方法。但是一个类从业务来说,可能只需要其中一两个方法。如果直接去实现这个接口,除了实现所需的方法,还要实现其他所有的无关方法。而如果通过继承存根类就实现接口,就免去了这种麻烦。
  • RMI 采用stubs 和 skeletons 来进行远程对象(remote object)的通讯。stub 充当远程对象的客户端代理,有着和远程对象相同的远程接口,远程对象的调用实际是通过调用该对象的客户端代理对象stub来完成的。
  • 每个远程对象都包含一个代理对象stub,当运行在本地Java虚拟机上的程序调用运行在远程Java虚拟机上的对象方法时,它首先在本地创建该对象的代理对象stub, 然后调用代理对象上匹配的方法。每一个远程对象同时也包含一个skeleton对象,skeleton运行在远程对象所在的虚拟机上,接受来自stub对象的调用。这种方式符合等到程序要运行时将目标文件动态链接的思想。

15、下面有关servlet和cgi的描述,说法错误的是?(D)

A、servlet处于服务器进程中,它通过多线程方式运行其service方法

B、CGI对每个请求都产生新的进程,服务完成后就销毁

C、servlet在易用性上强于cgi,它提供了大量的实用工具例程,例如自动地解析和解码HTML表单数据、读取和设置HTTP头、处理Cookie、跟踪会话状态等

D、cgi在移植性上高于servlet,几乎所有的主流服务器都直接或通过插件支持cgi

分析:

Servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁。 
而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于Servlet 。


CGI(Common Gateway Interface),通用网关接口

通用网关接口,简称CGI,是一种根据请求信息动态产生回应内容的技术。通过CGI,Web 服务器可以将根据请求不同启动不同的外部程序,并将请求内容转发给该程序,在程序执行结束后,将执行结果作为回应返回给客户端。也就是说,对于每个请求,都要产生一个新的进程进行处理。因为每个进程都会占有很多服务器的资源和时间,这就导致服务器无法同时处理很多的并发请求。另外CGI程序都是与操作系统平台相关的,虽然在互联网爆发的初期,CGI为开发互联网应用做出了很大的贡献,但是随着技术的发展,开始逐渐衰落。

Servlet

Servlet最初是在1995年由James Gosling 提出的,因为使用该技术需要复杂的Web服务器支持,所以当时并没有得到重视,也就放弃了。后来随着Web应用复杂度的提升,并要求提供更高的并发处理能力,Servlet被重新捡起,并在Java平台上得到实现,现在提起Servlet,指的都是Java Servlet。Java Servlet要求必须运行在Web服务器当中,与Web服务器之间属于分工和互补关系。确切的说,在实际运行的时候Java Servlet与Web服务器会融为一体,如同一个程序一样运行在同一个Java虚拟机(JVM)当中。与CGI不同的是,Servlet对每个请求都是单独启动一个线程,而不是进程。这种处理方式大幅度地降低了系统里的进程数量,提高了系统的并发处理能力。另外因为Java Servlet是运行在虚拟机之上的,也就解决了跨平台问题。如果没有Servlet的出现,也就没有互联网的今天。
在Servlet出现之后,随着使用范围的扩大,人们发现了它的一个很大的一个弊端。那就是 为了能够输出HTML格式内容,需要编写大量重复代码,造成不必要的重复劳动。为了解决这个问题,基于Servlet技术产生了JavaServet Pages技术,也就是JSP。Servlet和JSP两者分工协作,Servlet侧重于解决运算和业务逻辑问题,JSP则侧重于解决展示问题。 Servlet与JSP一起为Web应用开发带来了巨大的贡献,后来出现的众多Java Web应用开发框架都是基于这两种技术的,更确切的说,都是基于Servlet技术的。

16、在Java线程状态转换时,下列转换不可能发生的有(AC)?

A、初始态->运行态

B、就绪态->运行态

C、阻塞态->运行态

D、运行态->就绪态

分析:

17、 socket编程中,以下哪个socket的操作是不属于服务端操作的(C)?

A、accept

B、recieve

C、getInputStream

D、close

分析:

TCP客户端: 

  • 建立连接套接字,设置Ip和端口监听,socket()
  • 建立连接 connect
  • write() 获取网络流对象 发送数据
  • read()获取网络流对象 接收数据
  • 关闭套接字

TCP服务器端

  • 建立端口监听 socket()
  • 绑定指定端口 bind()
  • listen 进行端口监听
  • accept() 阻塞式 直到有客户端访问
  • read()获取客户端发送数据
  • write()发送返回数据
  • close关闭端口监听

18、ArrayLists和LinkedList的区别,下述说法正确的有?(ABCD)

A、ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

B、对于随机访问get和set,ArrayList绝对优于LinkedList,因为LinkedList要迭代器。

C、对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。

D、ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间。

解析:

A、这里的所谓动态数组并不是那个“ 有多少元素就申请多少空间 ”的意思,通过查看源码,可以发现,这个动态数组是这样实现的,如果没指定数组大小,则申请默认大小为10的数组,当元素个数增加,数组无法存储时,系统会另个申请一个长度为当前长度1.5倍的数组,然后,把之前的数据拷贝到新建的数组。

B、ArrayList是数组,所以,直接定位到相应位置取元素,LinkedLIst是链表,所以需要从前往后遍历。

C、ArrayList的新增和删除就是数组的新增和删除,LinkedList与链表一致。

D、因为ArrayList空间的增长率为1.5倍,所以,最后很可能留下一部分空间是没有用到的,因此,会造成浪费的情况。对于LInkedList的话,由于每个节点都需要额外的指针

19、关于下列程序段的输出结果,说法正确的是:(D)

A、有错误,变量i没有初始化。

B、null

C、1

D、0

分析:

静态变量会默认赋初值,局部变量和final声明的变量必须手动赋初值

20、下列哪个选项是Java调试器?如果编译器返回程序代码的错误,可以用它对程序进行调试。(C)

A、java

B、javadoc

C、jdb

D、javaprof

分析:

java.exe是java虚拟机

javadoc.exe用来制作java文档

jdb.exe是java的调试器

javaprof,exe是剖析工具

21、以下代码执行后输出结果为( A)

A 、blockAblockBblockA

B、blockAblockAblockB

C、blockBblockBblockA

D、blockBblockAblockB

分析:

静态域:用staitc声明,jvm加载类时执行,仅执行一次
构造代码块:类中直接用{}定义,每一次创建对象时执行。

执行顺序优先级:静态域,main(),构造代码块,构造方法。
1 静态域 :首先执行,第一个静态域是一个静态变量 public static Test t1 = new Test(); 创建了Test 对象,会执行构造块代码,所以输出blockA。然后执行第二个静态域(即静态代码块)输出blockB。
2 main():Test t2 = new Test()执行,创建Test类对象,只会执行构造代码块(创建对象时执行),输出blockA。
3 构造代码块只会在创建对象时执行,没创建任何对象了,所以没输出
4 构造函数:使用默认构造函数,没任何输出

22、当我们需要所有线程都执行到某一处,才进行后面的的代码执行我们可以使用?(B)

A、CountDownLatch

B、CyclicBarrier

C、Semaphore

D、Future

分析:

CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行; CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。 对于CountDownLatch来说,重点是“一个线程(多个线程)等待”,而其他的N个线程在完成“某件事情”之后,可以终止,也可以等待。 而对于CyclicBarrier,重点是多个线程,在任意一个线程没有完成,所有的线程都必须互相等待,然后继续一起执行。 CountDownLatch是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而CyclicBarrier更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行。 按照这个题目的描述等所有线程都到达了这一个阀门处,再一起执行,此题强调的是,一起继续执行, 选B 比较合理!

23、关于OutOfMemoryError,下面说法正确的是(ABCD)

A、java.lang.OutOfMemoryError: PermGen space 增加-XX:MaxPermSize这个参数的值的话,这个问题通常会得到解决。

B、java.lang.OutOfMemoryError: Requested array size exceeds VM limit当你正准备创建一个超过虚拟机允许的大小的数组时,这条错误将会出现

C、java.lang.OutOfMemoryError: Java heap space 一般情况下解决这个问题最快的方法就是通过-Xmx参数来增加堆的大小

D、java.lang.OutOfMemoryError: nativeGetNewTLA这个异常只有在jRockit虚拟机时才会碰到

分析:

A:属于运行时常量池导致的溢出,设置-XX:MaxPermSize可以解决这个问题,

B:属于堆空间不足导致的错误,问题比较少见,解决方式和C相同,

C:属于java堆内存问题,一般的手段是通过内存映像分析工具,对Dump出来的堆转储存快照进行分析,重点是确认内存中的对象是否是有必要的,也就是要判断是出现了内存泄漏,还是出现了内存溢出,如果是内存列楼,通过工具检查泄露对象打GC Roots的引用链信息,可以准确的确定出泄露代码的位置,不存在泄露,就应该检查虚拟机的堆参数,如果可以继续调大,可以设置-Xmx解决问题

D:java.lang.OutOfMemoryError: nativeGetNewTLA指当虚拟机不能分配新的线程本地空间(Thread Local Area)的时候错误信息,此错误是线程申请一个新的TLA时产生的,这个异常一般只会发生在jRockit虚拟机,只有过于绝对。

24、假设 a 是一个由线程 1 和线程 2 共享的初始值为 0 的全局变量,则线程 1 和线程 2 同时执行下面的代码,最终 a 的结果不可能是(D)

A、-1

B、-2

C、0

D、1

分析:

易知:每个线程对a 均做了两次读写操作,分别是 “ +1 ” 和 “ -2 ”

而题目问了是最终a 的结果,所以 a 的结果取决于各自线程对 a 的先后读写的顺序

结论:a的可能取值为-1、0、-2

25、进行Java基本的GUI设计需要用到的包是(C)

A、java.io

B、java.sql

C、java.awt

D、 java.rmi

分析:

java.io提供了全面的IO接口。包括:文件读写、标准设备输出等。

java.sql 提供使用 Java 编程语言访问并处理存储在数据源中的数据的 API。此 API 包括一个框架,凭借此框架可以动态地安装不同驱动程序来访问不同数据源。

java.awt是一个软件包,包含用于创建用户界面和绘制图形图像的所有分类。功能:包含用于创建用户界面和绘制图形图像的所有类。

java.rmi 提供 RMI 包。RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。

26、下列说法正确的有(A)

A、能被java.exe成功运行的java class文件必须有main()方法

B、J2SDK就是Java API

C、Appletviewer.exe可利用jar选项运行.jar文件

D、能被Appletviewer成功运行的java class文件必须有main()方法

分析:

java程序的种类

1.Application:Java应用程序,是可以由Java解释器直接运行的程序。

2.Applet:即Java小应用程序,是可随网页下载到客户端由浏览器解释执行的Java程序。
3.Servlet:Java服务器端小程序,由Web服务器(容器)中配置运行的Java程序。

A:正确main方法是入口 

B:J2SDK当然不仅仅包含java API 

C:jar选项是java.exe 的选项 

D:Appletviewer是运行applet的, applet 不用main方法,继承applet类即可。

27、off-heap是指那种内存(B)

A、JVM GC能管理的内存

B、JVM进程管理的内存

C、在JVM老年代内存区

D、在JVM新生代内存

分析:

off-heap叫做堆外内存,将你的对象从堆中脱离出来序列化,然后存储在一大块内存中,这就像它存储到磁盘上一样,但它仍然在RAM中。对象在这种状态下不能直接使用,它们必须首先反序列化,也不受垃圾收集。序列化和反序列化将会影响部分性能(所以可以考虑使用FST-serialization)使用堆外内存能够降低GC导致的暂停。堆外内存不受垃圾收集器管理,也不属于老年代,新生代。

28、关于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错误

举报

相关推荐

0 条评论