1.Java的内存泄露:
内存泄露(Memory Leak)——是指一个不再被使用的对象或者变量还在内存中占有存储空间。在C/C++语言中,内存泄露出现在开发人员忘记释放已分配的内存就会造成内存泄露。在java语言中引入垃圾回收机制,有GC负责进行回收不再使用的对象,释放内存。但是还是会存在内存泄露的问题。内存溢出(OOM)是指程序在申请内存时没有足够的内存供使用,进而导致程序崩溃这是结果描述。内存泄露(Memory Leak)最终会导致内存溢出。
内存泄露主要有两种情况:
- 在堆中申请的空间没有释放。
- 对象已不再被使用(注意:这里的不在被使用是指对程序来说没有用处,如数据库连接使用后没有关。但是还是存在着引用),但是仍然在内存中保留着。
GC机制的引入只能解决第一种情况,对于第2种情况无法保证不再使用的对象会被释放。java语言中的内存泄露主要指第2种情况。
内存泄露的原因:
- 静态集合类。如HashMap和Vector。这些容器是静态的,生命周期和程序的生命周期一致,那么在容器中对象的生命周期也和其一样,对象在程序结束之前将不能被释放,从而会造成内存泄露。
- 各种连接,如数据库连接,网络连接,IO连接,不再使用时如果连接不释放容易造成内存泄露。
- 监听器,释放对象时往往没有相应的删除监听器,可能会导致内存泄露。
2.泛型与虚拟机:
- 创建泛型对象的时候,一定要指出类型变量T的具体类型。争取让编译器检查出错误,而不是留给JVM运行的时候抛出类不匹 配的异常。
- JVM如何理解泛型概念 —— 类型擦除。事实上,JVM并不知道泛型,所有的泛型在编译阶段就已经被处理成了普通类和方法。 处理方法很简单,我们叫做类型变量T的擦除(erased) 。
总结:泛型代码与JVM
① 虚拟机中没有泛型,只有普通类和方法。
② 在编译阶段,所有泛型类的类型参数都会被Object或者它们的限定边界来替换。(类型擦除)
③ 在继承泛型类型的时候,桥方法的合成是为了避免类型变量擦除所带来的多态灾难。 无论我们如何定义一个泛型类型,相应的都会有一个原始类型被自动提供。原始类型的名字就是擦除类型参数的泛型类型的名字。
3.类方法与对象方法
类方法是属于整个类的(也就是static方法,比如main()方法),而实例方法是属于类的某个对象的。
由于类方法是属于整个类的,并不属于类的哪个对象,所以类方法的方法体中不能有与类的对象有关的内容。即类方法体有如下限制:
(1) 类方法中不能引用对象变量;
(2) 类方法中不能调用类的对象方法;
(3) 在类方法中不能使用super、this关键字。
(4) 类方法不能被覆盖。
如果违反这些限制,就会导致程序编译错误。
与类方法相比,对象方法几乎没有什么限制:
(1) 对象方法中可以引用对象变量,也可以引用类变量;
(2) 对象方法中可以调用类方法;
(3) 对象方法中可以使用super、this关键字。
4.结构模式
在GoF设计模式中,结构型模式有:
外观模式为子系统中的一组接口提供了同意的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式中,客户对各个具体的子系统是不了解的,所以对这些子系统进行了封装,对外只提供了用户所明白的单一而简单的接口,用户直接使用这个接口就可以完成操作,而不用去理睬具体的过程,而且子系统的变化不会影响到用户,这样就做到了信息隐蔽。
享元模式为运用共享技术有效的支持大量细粒度的对象。因为它可以通过共享大幅度地减少单个实例的数目,避免了大量非常相似类的开销。.
享元模式是一个类别的多个对象共享这个类别的一个对象,而不是各自再实例化各自的对象。这样就达到了节省内存的目的。
5.优化Hibernate所鼓励的7大措施:
- 尽量使用many-to-one,避免使用单项one-to-many
- 灵活使用单向one-to-many
- 不用一对一,使用多对一代替一对一
- 配置对象缓存,不使用集合缓存
- 一对多使用Bag 多对一使用Set
- 继承使用显示多态 HQL:from object polymorphism="exlicit" 避免查处所有对象
- 消除大表,使用二级缓存
6.静态属性和静态方法的继承:
- 静态属性和非静态属性不能被重写,所以不能实现多态。
- 静态方法可以被继承但是不能实现多态,因为静态方法和静态属性没有实现动态绑定。
Java规范中对类的方法和属性采用了俩中完全不同的处理机制:
- 对于方法,使用重载机制实现多态性;
- 对于属性,使用的是同名属性隐藏机制;
所谓同名属性隐藏机制是指:在具有父子关系的俩个类中,子类中同名的属性会使得从父类中继承过来的同名属性变得不可见,不管类型是否一致,名称一致的俩个属性就是同名属性。在子类中,无法简单的通过属性名称来获取父类中的属性,而是必须通过父类名称加属性名称(super.属性名)的方法才可以访问父类中的该属性。