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错误