目录
题目:
1.下面哪些类可以被继承?
2、下面有关servlet中init,service,destroy方法描述错误的是?
3.下面哪一项不是加载驱动程序的方法?
4. 下面叙述那个是正确的?()
5.说明输出结果。
6.下面代码输出是?
7.下面几个关于Java里queue的说法哪些是正确的()?
8.关于ThreadLocal类 以下说法正确的是
9.编辑
10. 在为传统面向对象语言的程序做单元测试的时候,经常用到mock对象。Mock对象通过反射数。请问反射最大程度破坏了面向对象的以下哪个特性?
11.运用下列哪个命令能够获取JVM的内存映像
12.以下代码的输出结果是?
13.如果希望监听TCP端口9000,服务器端应该怎样创建socket?
14.在java语言中,如果你编写一个多线程序,可以使用的方法是()
15.下面有关servlet和cgi的描述,说法错误的是?
收获知识点总结
1.全选,Object 类中方法及说明如下:
2.线程的生命周期中包含五种状态:初始态、就绪态、运行态、阻塞态、死亡状态。
3.使用泛型的好处
4.CopyOnWriteArrayList的实现原理
5.、线程的创建方式
6.Servlet和CGI(Common Gateway Interface)都是用于处理Web请求的技术,但它们有一些不同之处。
每日一记:
1、你是怎样理解OOP面向对象的
2、你是怎样理解多态的?什么地方用过?
3、sleep和wait在线程里有什么区别?(上海)
Java.lang.Thread、java.lang.Number、java.lang.Double、java.lang.Math、 java.lang.ClassLoader
Thread
Number
Double
Math
ClassLoader
正确答案: A B E 你的答案:A B E (正确)
题解:
A:Thread可以被继承,用于创建新的线程
B:Number类可以被继承,Integer,Float,Double等都继承自Number类
C:Double类的声明为 public final class Doubleextends Numberimplements Comparable
D:Math类的声明为 public final class Mathextends Object 不能被继承
E:ClassLoader可以被继承,用户可以自定义类加载器
A.init()方法是servlet生命的起点。一旦加载了某个servlet,服务器将立即调用它的init()方法
service()方法处理客户机发出的所有请求
destroy()方法标志servlet生命周期的结束
servlet在多线程下使用了同步机制,因此,在并发编程下servlet是线程安全的
正确答案: D
题解:
servlet在多线程下其本身并不是线程安全的。
如果在类中定义成员变量,而在service中根据不同的线程对该成员变量进行更改,那么在并发的时候就会引起错误。最好是在方法中,定义局部变量,而不是类变量或者对象的成员变量。由于方法中的局部变量是在栈中,彼此各自都拥有独立的运行空间而不会互相干扰,因此才做到线程安全。
A 通过DriverManager.getConnection方法加载
B 调用方法 Class.forName
C 通过添加系统的jdbc.drivers属性
D 通过registerDriver方法注册
正确答案:A
你的答案:B
参考答案:答案:A DriverManager.getConnection方法返回一个Connection对象,这是加载驱动之后才能进行的
加载驱动方法
1.Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
2. DriverManager.registerDriver(new com.mysql.jdbc.Driver());
3.System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
A java中的集合类(如Vector)可以用来存储任何类型的对象,且大小可以自动调整。但需要事先知道所存储对象的类型,才能正常使用。
B 在java中,我们可以用违例(Exception)来抛出一些并非错误的消息,但这样比直接从函数返回一个结果要更大的系统开销。
C java接口包含函数声明和变量声明。
D java中,子类不可以访问父类的私有成员和受保护的成员。
A.vector是线程安全的ArrayList,在内存中占用连续的空间。初始时有一个初始大小,当数据条数大于这个初始大小后会重写分配一个更大的连续空间。如果Vector定义为保存Object则可以存放任意类型。
B.try{}catch{}会增加额外的开销
C.接口中声明的'变量'必须为public final static,所以为常量
D.子类可以访问父类受保护的成员
B选项说的情况就是我们自定义异常的情况,请仔细读:我们可以用违例(Exception)来抛出一些并非错误的消息,可以,并非错误的消息。比如我自定义一个异常,若一个变量大于10就抛出一个异常,这样就对应了B选项说的情况,我用抛出异常说明这个变量大于10,而不是用一个函数体(函数体内判断是否大于10,然后返回true或false)判断,因为函数调用是入栈出栈,栈是在寄存器之下的速度最快,且占的空间少,而自定义异常是存在堆中,肯定异常的内存开销大
1 2 3 4 5 6 7 8 9 10 11 |
|
A SuperTest B SuperTest.class
C test.SuperTest D test.SuperTest.class
参考答案:C. TestSuper和Date的getClass都没有重写,他们都是调用Object的getClass,而Object的getClass作用是返回的是运行时的类的名字。这个运行时的类就是当前类,所以 super.getClass().getName() 返回的是test.SuperTest,与Date类无关 要返回Date类的名字需要写super.getClass().getSuperclass()
1 2 3 |
|
答案 Ceil d1=-0.0 floor d1=-1.0
ceil 方法上有这么一段注释:If the argument value is less than zero but greater than -1.0, then the result is negative zero
如果参数小于0且大于-1.0,结果为 -0.0
A LinkedBlockingQueue是一个可选有界队列,不允许null值
B PriorityQueue,LinkedBlockingQueue都是线程不安全的
C PriorityQueue是一个无界队列,不允许null值,入队和出队的时间复杂度是O(log(n))
D PriorityQueue,ConcurrentLinkedQueue都遵循FIFO原则
A、LinkedBlockingQueue是一个基于节点链接的可选是否有界的阻塞队列,不允许null值。
B、LinkedBlockingQueue是一个线程安全的阻塞队列,实现了先进先出等特性。
C、PriorityQueue是一个***队列,不允许null值,入队和出队的时间复杂度是O(log(n))。
D、PriorityQueue是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。ConcurrentLinkedQueue是一个基于链接节点的***线程安全队列,该队列的元素遵循FIFO原则 AC
A ThreadLocal继承自Thread
B ThreadLocal实现了Runnable接口
C ThreadLocal重要作用在于多线程间的数据共享
D ThreadLocal是采用哈希表的方式来为每个线程都提供一个变量的副本
E ThreadLocal保证各个线程间数据安全,每个线程的数据不会被另外线程访问和破坏
参考答案:选DE.
1、ThreadLocal的类声明: public class ThreadLocal
2、ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有了自己独立的一个变量。 所以ThreadLocal重要作用并不在于多线程间的数据共享,而是数据的独立,C选项错。 由于每个线程在访问该变量时,读取和修改的,都是自己独有的那一份变量拷贝,不会被其他线程访问, 变量被彻底封闭在每个访问的线程中。所以E对。
3、ThreadLocal中定义了一个哈希表用于为每个线程都提供一个变量的副本: static class ThreadLocalMap { static class Entry extends WeakReference
ThreadLocal主要作用是数据的独立,保证了并发时线程的安全性,因为每个线程都会创建一个独立的副本,它并不继承Thread类也不实现Runnable接口。DE
A 封装
B 多态
C 继承
D 抽象
正确答案:A 你的答案:C
参考答案:A.封装 反射破坏代码的封装性,破坏原有的访问修饰符访问限制 因为反射可以绕过访问权限,访问类的私有属性和方法
mock对象:也成为伪对象,在测试中的利用mock对象来代替真实对象,方便测试的进行。
java的封装性:指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,通过该类提供的方法实现对内部信息的操作访问。
反射机制:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性
A jinfo
B jmap
C jhat
D jstat
正确答案:B
1、jps:查看本机java进程信息。
2、jstack:打印线程的栈信息,制作线程dump文件。
3、jmap:打印内存映射,制作堆dump文件
4、jstat:性能监控工具
5、jhat:内存分析工具
6、jconsole:简易的可视化控制台
7、jvisualvm:功能强大的控制台
public class B
{
public static B t1 = new B();
public static B t2 = new B();
{
System.out.println("构造块");
}
static
{
System.out.println("静态块");
}
public static void main(String[] args)
{
B t = new B();
}
}
A 静态块 构造块 构造块 构造块
B 构造块 静态块 构造块 构造块
C 构造块 构造块 静态块 构造块
D 构造块 构造块 构造块 静态块
总结一下: 1.程序入口main方法要执行首先要加载类B 2.静态域:分为静态变量,静态方法,静态块。这里面涉及到的是静态变量和静态块,当执行到静态域时,按照静态域的顺序加载。并且静态域只在类的第一次加载时执行 3.每次new对象时,会执行一次构造块和构造方法,构造块总是在构造方法前执行(当然,第一次new时,会先执行静态域,静态域〉构造块〉构造方法) 注意:加载类时并不会调用构造块和构造方法,只有静态域会执行 4.根据前三点,首先加载类B,执行静态域的第一个静态变量,static b1=new B,输出构造块和构造方法(空)。ps:这里为什么不加载静态方法呢?因为执行了静态变量的初始化,意味着已经加载了B的静态域的一部分,这时候不能再加载另一个静态域了,否则属于重复加载 了(静态域必须当成一个整体来看待。否则加载会错乱) 于是,依次static b2 =new B,输出构造块,再执行静态块,完成对整个静态域的加载,再执行main方法,new b,输出构造块。
A new Socket("localhost",9000);
B new ServerSocket(9000);
C new Socket(9000);
D new ServerSocket("localhost",9000);
正确答案: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
A 扩展类Thread
B 实现Runnable接口
C 扩展类 Runnable
D 实现接口Thread
正确答案:AB
Java多线程实现方式主要有四种:继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用ExecutorService、Callable、Future实现有返回结果的多线程。
A servlet处于服务器进程中,它通过多线程方式运行其service方法
B CGI对每个请求都产生新的进程,服务完成后就销毁
C servlet在易用性上强于cgi,它提供了大量的实用工具例程,例如自动地解析和解码HTML表单数据、读取和设置HTTP头、处理Cookie、跟踪会话状态等
D cgi在移植性上高于servlet,几乎所有的主流服务器都直接或通过插件支持cgi
Servlet在移植性方面更高于CGI。Servlet是基于Java的标准,可以在支持Java Servlet规范的任何Web容器中运行,如Tomcat、Jetty等。而CGI是一种通用的Web服务器接口,虽然大多数主流服务器都支持CGI,但并不是所有服务器都直接支持CGI,有些服务器可能需要通过插件或配置来支持CGI。因此,从移植性的角度来看,Servlet更具优势。
registerNatives() //私有方法
getClass() //返回此 Object 的运行类。 hashCode() //用于获取对象的哈希值。 equals(Object obj) //用于确认两个对象是否“相同”。 clone() //创建并返回此对象的一个副本。 toString() //返回该对象的字符串表示。 notify() //唤醒在此对象监视器上等待的单个线程。 notifyAll() //唤醒在此对象监视器上等待的所有线程。 wait(long timeout) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或 者超过指定的时间量前,导致当前线程等待。 wait(long timeout, int nanos) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。 wait() //用于让当前线程失去操作权限,当前线程进入等待序列 finalize() //当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
其状态转换如下图所示:
1,类型安全。 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。
2,消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。
3,潜在的性能收益。 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。
所以泛型只是提高了数据传输安全性,并没有改变程序运行的性能
CopyOnWriteArrayList的实现原理
在使用CopyOnWriteArrayList之前,我们先阅读其源码了解下它是如何实现的。以下
代码是向ArrayList里添加元素,可以发现在添加的时候是需要加锁的,否则多线程写的
时候会Copy出N个副本出来。
public boolean add(T e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
// 复制出新数组
Object[] newElements = Arrays.copyOf(elements, len + 1);
// 把新元素添加到新数组里
newElements[len] = e;
// 把原数组引用指向新数组
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
final void setArray(Object[] a) {
array = a;
}
读的时候不需要加锁,如果读的时候有多个线程正在向ArrayList添加数据,读还是
会读到旧的数据,因为写的时候不会锁住旧的ArrayList。
public E get(int index) {
return get(getArray(), index);
} CopyOnWriteArrayList适用于读多写少的并发场景
1)继承Thread类创建线程
2)实现Runnable接口创建线程
3)使用Callable和Future创建线程
4)使用线程池创建线程
Servlet是Java编写的服务器端组件,它运行在支持Java Servlet规范的Web容器中(如Tomcat)。Servlet通过继承javax.servlet.Servlet接口来实现,它可以接收HTTP请求并生成HTTP响应。Servlet可以处理动态内容、会话管理、数据库访问等功能。Servlet具有更好的性能和可扩展性,并且可以与Java EE平台的其他组件(如JSP、EJB等)进行集成。
CGI是一种通用的Web服务器接口,它允许外部程序(通常是脚本)与Web服务器进行通信。CGI程序可以用任何编程语言编写,如Perl、Python、C++等。当Web服务器接收到CGI请求时,它会将请求的数据传递给CGI程序,并将CGI程序的输出作为HTTP响应返回给客户端。CGI程序可以处理动态内容,但每个请求都需要启动一个新的进程,这可能会导致性能问题。
总结来说,Servlet是Java编写的服务器端组件,运行在Java Servlet容器中,具有更好的性能和可扩展性;而CGI是一种通用的Web服务器接口,可以用任何编程语言编写,但每个请求都需要启动一个新的进程,性能较差。
面向对象是利于语言对现实事物进行抽象。面向对象具有以下特征:
(1)继承:继承是从已有类得到继承信息创建新类的过程
(2)封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。
(3)多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。
同一个行为具有多个不同表现形式或形态的能力。(重写和重载正是多态)
父类引用指向子类对象,例如 List
sleep方法:
属于Thread类中的方法;会导致程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持着,当指定时间到了之后,又会自动恢复运行状态;在调用sleep方法的过程中,线程不会释放对象锁。(只会让出CPU,不会导致锁行为的改变)
wait方法:
属于Object类中的方法;在调用wait方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify方法后本线程才进入对象锁定池准备。获取对象锁进入运行状态。(不仅让出CPU,还释放已经占有的同步资源锁