有C背景的程序员特别喜欢问这种问题。 2 << 3
39,两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对? 不对,有相同的hash code。
40,当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。 41,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。 42,编程题: 写一个Singleton出来。
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 一般Singleton模式通常有几种种形式:
第一种形式:定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。 public class Singleton { private Singleton(){}
//在自己内部定义自己一个实例,是不是很奇怪? //注意这是private 只供内部调用
private static Singleton instance = new Singleton();
//这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance() { return instance; }
达内java学习笔记
9
}
第二种形式: public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次 //使用时生成实例,提高了效率! if (instance==null)
instance=new Singleton(); return instance; } }
其他形式:
定义一个类,它的构造函数为private的,所有方法为static的。 一般认为第一种形式要更加安全些 Hashtable和HashMap
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现 HashMap允许将null作为一个entry的key或者value,而Hashtable不允许
还有就是,HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在 多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。 43.描述一下JVM加载class文件的原理机制?
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备、解析 装载:查找和导入类或接口的二进制数据; 达内java学习笔记
10
链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的; 校验:检查导入类或接口的二进制数据的正确性; 准备:给类的静态变量分配并初始化存储空间; 解析:将符号引用转成直接引用;
初始化:激活类的静态变量,初始化Java代码和静态Java代码块 44.试举例说明一个典型的垃圾回收算法?
45.请用java写二*树算法,实现添加数据形成二*树功能,并以先序的方式打印出来. 46.请写一个java程序实现线程连接池功能?
import java.util.LinkedList;
//抽象类,命名为Manager(管理者)
public abstract class Manager {
private String mThreadPoolName = null; //线程池名称
private int mThreadPoolMaxSize = 1; //线程池最大线程数
private LinkedList workers = new LinkedList(); //工作线程的集合
public Manager() {
}
public Manager(String name, int poolMaxSize) { //设置线程池的名称和最大线程数 mThreadPoolName = name;
createWorker(name, poolMaxSize); //创建最大数据的线程 mThreadPoolMaxSize = poolMaxSize; }
private void createWorker(int poolMaxSize) {
for (int i = 0; i < poolMaxSize; i++) {
Worker worker = new ...Worker(this); //这是什么构建对象的方式?自己也是第一次看到。 workers.addLast(worker); } }
public synchronized Worker getIdleWorker() {
return (Worker)workers.removeFirst(); //返回一个移除第一个线程对象的线程集合 }
public synchronized void notifyFree(Worker worker) {
if (workers.size() < mThreadPoolMaxSize) {
workers.addLast(worker); //如果线程集合中的线程对象数小于线程池最大线程数,则添加一个新到线程互线程集合中去 } else {
worker = null; 否则,设置线程集合为null } } 达内java学习笔记
11
public int getThreadPoolMaxSize() { //取得线程池中最大的线程数 return mThreadPoolMaxSize; }
public void setThreadPoolMaxSize(int threadPoolMaxSize) { //设置线程池中最大线程数 this.mThreadPoolMaxSize = threadPoolMaxSize; }
}
线程抽象类
public abstract class Worker implements Runnable {
private Manager mManager = null;
private Thread mThread = null;
public Worker() { }
public Worker(String threadName, Manager manager) {
mManager = manager;
mThread = new Thread(this, threadName); //每次都产生一个新的线程对象 init();
mThread.start(); //启动线程 }
public abstract void init();
public void run() {
while (true) {
waitForStart(); //设置线程为等待状态 Worker worker = mManager.getIdleWorker(); process();
isRunning = false;
mManager.notifyFree(worker); } }
public abstract void process();
public void start() { isRunning = true;
mManager.getIdleWorker(); notifyToStart(); }
public synchronized void waitForStart() {
达内java学习笔记
12
相关推荐: