-【 面试宝典 + 我的问题。】
面试题:当用户很多时,怎样对服务器进行优化?
一般面试官问个这个问题的目的就是考监听器钝化与活化的概念与操作。
对存入session中的对象设置绑定监听器并且序列化,如果用户长时间不操作(这个时间可以通过配置文件修改),那么服务器就会做以下操作:
1,对存入session中的对象在服务器内存中钝化,存入系统硬盘中。
2,如果用户回来了,就将之前存入硬盘中的数据活化回来(这就是要序列化的原因,因为他是以流的方式读入的),但是硬盘中也不会被删除。
问题:一个页面里有有三张img图片,浏览器会向服务器发送几次请求。?
四次:页面一次,每张图片一次,因为不同的资源会浏览器都会请求一次。
拓展:如果三张图片一样,浏览器也会有四次请求,但是只会看到两次,因为浏览器会缓存。
因此,为了加快浏览器的速度,一般会将一些图片整合到一张图中,然后使用CSS定位。这样的话就实现”多张图”一次请求!
wait()与sleep()方法的区别?
1,wait()方法使当前线程进入等待状态让出CPU时间片,并且释放对象的同步锁!等待其他线程调用notify()方法唤醒。
【wait方法只能在同步块或同步方法中被调用】
而且wait()方法是object内的方法。
2,sleep(long t)方法使线程进入睡眠状态让出CPU时间片,但不释放同步锁。但是都会使当前线程让出cpu的时间片。
而sleep()方法是线程的静态方法。
-单例模式。
//【饿汉式单例模式】:
//线程安全,对于贡献数据的操作带码不会产生不同步问题(只有一行);
class Single{
private static Single s = new Single();
private Single(){
}
//通过此方法获取对象,有点就是可控!。你可以根据条件是否返回该实例
public static Single getInstance(){
return s;
}
}
//【懒汉式】
//线程不安全的,因为操作贡献数据的代码存在多行,会产生不同步!
//为了解决单例模式的线程不安全问题,因此需要同步代码【当然你可以直接用安全的恶汉式】
//以下就是,既安全又不会因为cpu的调度导致效率低下的懒汉式单例模式
class Single {
private static Single s = null;
private Single(){}
// Thread2
private static Single getInstanceSingle(){
if(s==null){
synchronized(Single.class) {
//Thread1
if(s == null) {
return s = new Single();
}
}
//Thread0
}
return s;
}
-String、StringBuffer、StringBuilder的联系与区别?
1,最大区别。String 是不可变的(这里的不可变指的是引用变量所指的对象只能赋值一次,但是可以再指向别的对象),打开源码看,String的char数组加了final修饰符!还有private权限,而且还没有实现公开的访问方式。所以修改该数组肯定是不可能的。后两者都继承自抽象类 AbstractStringBuilder,当中的char数组并没有加final修饰。
2,另外就是StringBuffer,和StringBuilder的区别。也从源码来看。如下:
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
StringBuffer的很多方法加了synchronized修饰,线程时安全的,支持多线程。但是效率就会降低了。所以单线程时一般都使用StringBuilder。
-final,finally,finalize的区别?
1,final修饰符:修饰的类不能被继承,修饰的方法不能被重写,修饰的变量不能被重新赋值。且不能修饰局部变量。
2,finally:try -catch-finally捕捉异常语句。不管前面是是否捕捉到异常都会执行的代码块。
3,finalize:这个方法在基类Object当中。查资料是说这个是和个C++里面的析构函数类似。用来释放消亡的对象。
代码举例:
public class FinalizeDemo {
public static void main(String[] args) {
Girl g1 = new Girl();
Girl g2 = new Girl();
g1=null;
System.gc();//JVM会尽力回收没有被引用的的对象
}
}
class Girl extends Object{
public Girl() {
System.out.println("A Girl was created.");
}
@Override
protected void finalize() throws Throwable {
System.out.println("A Girl just broke with you .");
super.finalize();
}
}
就是说finalize()函数是当对象没有被引用时,垃圾收集器被调用后,gc会调用finalize()用来清除没有用的对象。
我的问题:抽象类如何做到不能被实例化的?
如题:即使把抽象列的构造器的权限改为public也不行!请问是如何做到的。?
抽象类和接口的区别?
他们都是通过抽取子类代码形成的。
-类是用来被单重继承的,接口时用来被单或多重实现的
-抽象类中可以存在非抽象内容供子类直接是用。
接口中则都是抽象内容,需要子类实现接口后才能用。
-类之间的继承关系为 is a..
接口与类之间的关系为 like a…
异常体系:
Throwable
|-Error
|-Exception
异常的父类是Exception。但是Exception 和Error都是Throwable的子类。
所有的Exception都可以被抛出和捕获。
但是Error只能抛出。不能捕获。
继承和内部类的关系。
他们虽然都实现了代码的共享。但是他们两个的概念区别还是挺大的。
继承的关系像is a,即父子关系。他们的生命周期也没有关系。而内部类像是寄生关系。内部类存在的外部类的生命周期结束,内部类也会消失。
HashSet,HashMap和Hashtable之间的联系和区别?
1.HashSet底层是通过HashMap实现的,但是他并不存储映射关系。
HashMap存储映射关系,HashSet不允许存储重复的元素。
2.Hashtable的父类是Dictionary,HashMap的父类是AbstractMap
但是它们都实现了同样了接口Map Cloneable, Serializable
3.Hashtable当中公开的方法都被synchronized修饰符修饰,Hashtable是线程安全的。
HashMap的方法不同步,说明是线程不安全的。
4.HashMap的key和value当中可以存放null值,但是要求key值不能够重复,
所以HashMap的key至多只能存放一个null值,但是value可以存储多个null值。
而Hashtable则不同,key和value都不允许存放null值。
5.内存初始化的大小不同,Hashtable创建对象内存初始化为11,而HashMap的内存初始化为16.
6.内存扩充采用的公式也不同。
HashMap :2*old
Hashtable :2*old+1
7.hashcode值计算的方式不同,hashtable直接使用了存放的对象的hashcode值。
而HashMap在对象的hashcode值基础之上做了一些加工。