掉进水里你不会淹死,待在水里你才会淹死,只有不断学习才不会被前沿淘汰,如下面试题但愿对大家有帮助!java
答:在程序设计中有面向过程和面向对象,C语言是面向过程的,就是一步一步的很是清楚,比较直接高效,而java是面向对象的,更易于重复使用、扩展和维护。程序员
面向过程只会思考这个事情(问题)自己面试
面向对象要将一个事情解拆成一个一个的模块sql
封装、继承、多态 数据库
内部细节对外部调用透明,外部调用无需修改或者关心内部实现编程
好比:ORM框架 操做数据库,咱们不须要关心连接是如何创建的、sql是如何执行的,只需要引入mybatis,调方法便可数组
继承基类的方法,并作出本身的改变和扩展安全
将共性的方法或属性写在父类,而不须要本身再定义,只须要扩展本身的个性化 就有点像AOP面向切面编程同样 在不改变源码的基础上添加一些新的功能, 继承也是在继承了父类的全部方法和属性上 子类能够优化父类的方法和扩展本身的方法数据结构
多态和继承实际上是一脉相承的 多态有一个条件:要有继承 要重写父类的方法 父类引用指向子类对象 mybatis
多态的用法 : 父类类型 变量名 = new 子类对象; 变量名.方法名() ; 调用的方法是子类对象的方法 这就是多态 可是多态有一个弊端 没法调用子类本身特有的功能 就是子类对象的方法必须是在父类中有
也就是重写了父类的方法才能被调用 (方法重写)
JAVA语言有一个很是牛B的特性 就是跨平台 代码一次编写处处运行
跨平台特性实现:使用JVM(虚拟机)实现 字节码文件都会放到jvm里面去运行 针对不一样的平台 会生成不一样的代码 java虚拟机帮咱们作到的
java虚拟机是JDK的一个组成部分
java虚拟机由那些部分组成:
1:类装载子系统
2:运行时数据区(内存模型(重点)) 包含堆 栈(线程) 本地方法栈 方法区(元空间) 程序技术器
3:字节码执行引xin
栈(线程): 官网叫(虚拟机栈) 而我本身想叫它线程栈,为何呢?只要一个线程开始运行 java虚拟机就会给这个线程分配它一块本身的专属内存空间 这个内存空间就叫作线程栈 !为何分配这个空间?由于在这个线程运行过程当中须要内存空间去存放一些变量 那么就是放到这个线程栈的
栈帧内存空间:就是线程栈内部为每一个方法分配的一个内存空间 这个内存空间用来存放这个方法内的局部变量 这就叫(栈帧)!
数据结构里面有个叫栈的数据结构 有个很是重要的特性FILO 先进后出
线程栈内部放栈帧的数据结构就是FILO结构 先进后出
先调用的方法后结束 后调用的方法先结束 也就是先调用的方法后释放内存资源 后调用的方法先释放内存资源
将JAVA文件编译后的class文件转换为方便阅读的源码:
栈帧内的操做数栈操做步骤:
当前在内存中执行的代码行 字节代码行号从0开始
用处: 多线程 当前线程正在运行时 一个比当前线程优先级高的线程开始执行了 那么当前线程就会被挂起 后面开始执行的时候就经过这个程序计数器的行号开始执行
程序计数器的值由字节码执行引擎来进行修改 由于字节码执行引擎指向着Math.class和程序计数器 当Math.class每行代码执行完毕时都会修改程序计数器的值
就是一个局部变量表 放当前局部的变量
放操做数的 +-*/操做运算的 临时存放的一块内容空间
源码 牵扯到C语言和C++ 把一些符号引用转换为直接引用
符号引用:方法名称 括号啊 在JVM里面都有一个名称 叫符号 当程序真正运行到一行代码的时候 就将这些符号引用转换为直接引用
经过动态连接在方法区(元空间)找到那些要执行的代码
就是compute方法执行完毕后知道返回到main主函数的第几行代码去继续执行
对象是放在堆区域的
栈和堆的关系就是栈里面的内存地址经过指针指向堆里相对应的对象
方法区放:常量+静态变量+类信息
不论是栈里面的对象仍是方法区里的静态对象 都是经过内存地址指针指向堆里对应的对象 堆里就是存放对象的 不论是静态仍是非静态的 只要是对象都会存放在堆里 让其它地方经过内存地址指针到对应的对象
方法区类信息 字节码的一些信息会加载到方法区内部
本地方法栈:本地方法分配内存空间 native (nei ti wu) 修饰的方法叫本地方法 本地方法:底层是C和C++实现的 这个本地方法确定有要运行的东西嘛 因此就须要分配一个内存空间
堆:由年轻代和老年代构成 老年代占3分之2 年轻代占3分之1
若是一个对象被minor gc(ma lr GC)干了15次尚未被干掉 那么这个对象会被移到老年代
完整对象包含:对象头、实例数据
调优工具 阿里开源工具: Arthas(啊 sr 死) JDK自带的:Visual GC
JDK:java开发工具 提供给开发人员来使用的
JRE:java运行时环境 提供给运行java程序的用户来使用的 谁须要运行java程序就须要安装JRE
JVM:虚拟机 解析class文件 解析成机器码(二进制)让操做系统能够执行
是class文件是能够处处运行的 并非JVM能够处处运行 JVM是将当前class文件解析成当前操做系统能识别的机器码
在java中有两块很重要的内存 栈和堆 堆是存对象 栈是存值
String s = new String() String ss = new String() s=“123” ss = “123”
boolean b = s == s?true:false; b的值为false 由于s和ss在堆里开辟了不一样的内存空间
boolean b = s.equals(ss) b的值为true 由于equals重写了方法 只是比较了两个字符串的内容 没有进行对象比较 只是比较了值 因此能够理解equals就是比较的值
int a = 1 int b = 1
boolean b = a==b ?true:false; b的值为true 由于a和b都是在栈中 而且值都是1 因此结果为true
来一道题:
解析:
str1==str2 false 由于str1和str2 使用== 比较的是栈中的值 栈中str1 str2 都存放的是不一样的内存地址 是存放在堆中的对象 因此它们的内存对象值不一样 因此返回为false
str2==str3 同理
str2==str3 true 由于str3 直接经过赋值运算符取得了str2在栈中的内存地址值 因此str3和str2的内存地址值是一摸同样的 都指向的是堆里的那个对象
str1.equals(str2) true equals 对比的是内容 内容都是Hello 确定都是true
本身的理解:final声明的变量只是为了局部生成的匿名类或者内部类调用时这个值是一致的 就是面向对象的思想
重载:发生在同一个类中,方法名必须相同,参数类型不一样,个数不一样、顺序不一样,方法返回值和访问修饰符能够不一样,发生在编译时。
重写:发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;若是父类方法访问修饰符为private则子类就不能重写该方法
抽象类只能继承一个,接口能够实现多个
抽象类能够存在普通成员函数,而接口中只能存在public abstract方法 接口里面只能是抽象的方法
抽象类中的成员变量能够是各类类型的,而接口中的成员变量只能是public static final类型的
初级程序员答:
抽象类除了有抽象方法还有实现了的方法也就是普通成员函数 而接口不能够 接口里面的方法必须所有是抽象的
在咱们的抽象类中成员变量是能够有多种类型的 而接口中的成员变量只能是public static final类型的 接口中的成员变量默认都是常量
抽象类是单继承 而接口是能够多实现的
接口的设计目的:它只对类可以提供那些方法 至于这个方法怎么实现的 它无论
抽象类的设计目的:代码服用 不一样的类具备相同的行为 有共性的东西 这个时候就能够把这些共同的东西抽取出来写入道抽象类中 能够有抽象方法 也能够有已经实现了的方法
抽象类包含并实现子类的通用特性
抽象类是对类本质的抽象 表达的是is a的关系 好比 BMW is a Car 若是用BMW继承Car类 就表明BMW是Car
而接口是对行为的抽象 表达的是like a的关系 是相似 不是直接就是 Bird like a Aircraft Aircraft 接口有一个飞的方法 Bird就能够去实现Aircraft接口里的飞的方法
可是Bird(小鸟)不是一个Aircraft(飞行器) 由于Aircraft(飞行器)接口里面有飞的方法 因此Bird小鸟能够去实现Aircraft接口飞的方法
使用场景:
当你关注一个事务的本质的时候,用抽象类
当你关注一个操做的时候,用接口
抽象类的功能要远超过接口 抽象类能够有实现的方法 也能够有未实现的方法 可是定义抽象类的代价比较高 抽象类只能实现一个 接口会下降难度:接口能够实现多个
List和Set:List是有序的 可重复的 可使用迭代器和下表读取存入的值 set是无需的 不可重复的 只能使用迭代器读取存入的值
hashcode和equals:
若是两个对象相等,那么hashcode必定也是相同的
两个对象相等,对两个对象分别调用equals方法都返回true
ArrayList是基于动态数组的 亮点在于扩容机制 老数组和新数组 当使用ArrayList开辟了一个能容纳10个值的数组时想插入第11个值的话 那么扩容机制就来了
扩容机制原理:就是新数组和老数组 开辟一个比老数组要长的新数组 将老数组的值CP到新数组中并将新插入的值插入到新数组中 这就是扩容机制也就是动态数组的机制
它更利于插入不利于查询 可是 若是将ArrayList使用的恰当是能够比LinkedList性能要好的 它能够经过下标和迭代器访问存入的值
LinkedList是基于链表的 它利于插入不利于查询 只能使用迭代器访问存入的值 不能经过下标 并且不推荐使用for循环来遍历 由于LinkedList是基于链表的 若是使用for循环去访问存入的值 那么每读取一个值都会从链表链一次 效率可想而知有多低
HashMap是线程不安全的 HashTable是线程安全的 由于HashTable为里面的每一个方法都添加了锁 而HashMap没有 它们两的方法都差很少 可是HashTable效率低 HashMap效率高 能够根据不一样的业务来选择使用
HashMap基于动态数组实现
HashTable基于链表实现
实现Runable 或者继承Thread si wei dr Thread实现了Runable Thread和Runable的实质是继承关系 ,没有可比性,Thread是单继承可是Runable是多实现
在文章的最后做者为你们整理了不少资料!包括java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书等等!
所有免费分享给你们,有须要的朋友欢迎关注公众号:前程有光,领取!