Java Basic
javadoc的缺点,javadoc不能强制说明某个类(或方法)应用场景以及缺陷,项目暴露出的功能和性能问题很多其实就是由于javadoc的自阐述性不够造成的,这是javadoc最大的败笔.
JVM JRE JDK的关系
- JVM:Java Virtual Machine —— 负责执行符合觃范癿Class文件
- JRE:Java Runtime Environment —— 包含JVM不类库
- JDK:Java Development Kit —— 包含JRE不一些开发工具,如javac
堆栈:
- 堆很灵活,但是不安全。对于对象,我们要动态地创建、销毁,不能说后创建的对象没有销毁,先前创建的对象就不能销毁,那样的话我们的程序就寸步难行,所以Java中用堆来存储对象。而一旦堆中的对象被销毁,我们继续引用这个对象的话,就会出现著名的 NullPointerException,这就是堆的缺点——错误的引用逻辑只有在运行时才会被发现。基本数据类型不能看作对象(这点很特殊),存放在栈中。栈内操作速度快,创建销毁很容易。
- 栈不灵活,但是很严格,是安全的,易于管理。因为只要上面的引用没有销毁,下面引用就一定还在,所以,在栈中,上面引用永远可以通过下面引用来查找对象,同时如果确认某一区间的内容会一起存在、一起销毁,也可以上下互相引用。在大部分程序中,都是先定义的变量、引用先进栈,后定义的后进栈,同时,区块内部的变量、引用在进入区块时压栈,区块结束时出栈,理解了这种机制,我们就可以很方便地理解各种编程语言的作用域的概念了,同时这也是栈的优点——错误的引用逻辑在编译时就可以被发现。
请说出你所知道的线程同步的方法
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
heap和stack有什么区别
栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。
堆是栈的一个组成元素
Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
面向对象的特征
1.抽象:2.继承:3.封装:4. 多态性:
抽象类和接口的区别
第一点. 接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
第二点. 接口可以继承,抽象类不行
第三点. 接口定义方法,不能实现,而抽象类可以实现部分方法。
第四点. 接口中基本数据类型为static 而抽类象不是的。
当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
heap和stack有什么区别
栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。
堆是栈的一个组成元素
Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
面向对象的特征
1.抽象:2.继承:3.封装:4. 多态性:
抽象类和接口的区别
- 第一点. 接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
- 第二点. 接口可以继承,抽象类不行
- 第三点. 接口定义方法,不能实现,而抽象类可以实现部分方法。
- 第四点. 接口中基本数据类型为static 而抽类象不是的。
- 当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
对象具有状态,行为和标识。即每个对象在内存中都有唯一的地址。
组合:使用现有的类合成新的类。
聚合:组合是动态发生的。
final只能保证引用永远指向固定对象,不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改,一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final,意图使得它“永远不变”。其实那是徒劳的。
可以用this调用一个构造器,却不能调用两个,且必需将构造器调用置于最起始处,否则编译器会报错。
除构造器外,编译器禁止在其他任何方法中调用构造器。
即时编译器技术 — JIT
通常javac将程序源代码编译,转换成java字节码,JVM通过解释字节码将其翻译成对应的机器指令,逐条读入,逐条解释翻译。很显然,经过解释执行,其执行速度必然会比可执行的二进制字节码程序慢。为了提高执行速度,引入了JIT技术。
在运行时JIT会把翻译过的机器码保存起来,已备下次使用
Java虚拟机中有许多附加技术用以提升速度,尤其是与加载器操作相关的,被称为“即时”(Just-In-Time,JIT)编译器的技术。这种技术可以把程序全部或部分翻译成本地机器码(这本来是JVM的工作),程序运行速度因此得以提升。当需要装载某个类时,编译器会先找到其.class文件,然后将该类的字节码装入内存。此时,有两种方案可供选择:
(1)一种就是让即时编译器编译所有代码。但这种做法有两个缺陷:这种加载动作散落在整个程序生命周期内,累加起来要花更多时间;并且会增加可执行代码的长度(字节码要比即时编译器展开后的本地机器码小很多),这将导致页面调度,从而降低程序速度。
(2)另一种做法称为惰性评估(lazy evaluation),意思是即时编译器只在必要的时候才编译代码,这样,从不会被执行的代码也许就压根不会被JIT所编译。新版JDK中的Java HotSpot技术就采用了类似方法,代码每次被执行的时候都会做一些优化,所以执行的次数越多,它的速度就越快。
public static void main(String[] args){}
javac编辑 java Test Tom 启动时允许执行环境传入启动参数
Java类初始化顺序(无继承):
静态变量–>静态初始化块–>其他变量–>初始化块–>构造器
Java类初始化顺序(有继承):先静后动,先父后子
父类静态初始化—->子类静态初始化—->父类初始化块—->父类构造方法—->子类初始化块—->子类构造方法。

this的用法:


基础类型:局部变量必须初始化,成员变量存储在堆内存,局部变量存储在栈内存
热部署与热加载
热部署就是在服务器运行时重新部署项目,热加载即在在运行时重新加载class
热加载的实现原理主要依赖java的类加载机制,在实现方式可以概括为在容器启动的时候起一条后台线程,定时的检测类文件的时间戳变化,如果类的时间戳变掉了,则将类重新载入。
热部署原理类似,但它是直接重新加载整个应用,这种方式会释放内存,比热加载更加干净彻底
备注:jrebel插件可以进行更彻底的热加载,不仅包括类,甚至支持spring 等配置文件的热加载
异常处理模型
异常发生时,会发生如下几件事:
1. 终止当前执行路径;
2. 使用new在堆上创建异常对象;
3. 从当前环境中弹出对异常对象的引用;
4. 由异常处理程序接管程序,异常处理程序的任务是试着将程序从错误状态恢复,要么使程序换一种方式运行,要么继续运行。
异常处理模型理论上有两种基本模型:终止模型和恢复模型。
终止模型是指异常发生时,程序无法再返回到异常发生的地方继续执行。恢复模型中异常处理程序的工作是修正错误,重新尝试调用出错问题的方法,并认为第二次能成功。
由于恢复模型存在耦合的缺陷:恢复处理程序需要了异常抛出地点,所以存在依赖于抛出位置的非通用性代码,增加了实现和维护的难度。
对于存在恢复可能的异常调用,建议是终止模型+适当次数的重试。
异常对性能的影响原因在于Java每次方法的调用都会在栈生成一帧来存储方法的相关信息,包括局部变量,参数,返回值和代码信息等。当出现异常时,Java虚拟机会首先根据帧中的信息执行finally语句块,然后在当前方法中寻找匹配的catch,如果没有找到,则将当前方法的帧弹出栈,在其调用方法中进行匹配,如此反复地在栈中向下匹配,如果最终没有匹配的catch块则到达ThreadGroup.uncaughtException(),整个过程比正常的流程付出了更多的代价。
ClassCastException
- Fruit和Apple类不兼容。
- Fruit和Apple类兼容,但加载时使用了不同的ClassLoader。由不同ClassLoader加载的同一类文件也会被视为不同的类,即便每个字节都完全相同。
浙公网安备 33010602011771号