《面试精选》主要分享各种技术栈相关的面试题,主要包括面试常见问题、原理解析、概念特点等。有需要的小伙伴可以关注收藏,干货不断!
一.静态对象
1.在main方法开始运行时需要注意static的先后顺序,静态标量和静态代码块>匿名块和成员变量>构造函数>静态方法
2.先执行父类的静态块,再执行子类的静态块,再执行父类的构造方法,再执行子类的构造方法
静态块>构造方法
父>子
二.final关键字
1.用在类上不能被继承,abstract(需要被继承)个final不能共存
2.用在方法上不能被重写
3.用在变量上表示变量不能被修改
对于final类的成员变量的初始化方式:
a.申明变量时直接赋值
b.在构造方法中完成赋值,如果有多个构造方法,则每个都要完成final类变量的赋值
C.如果一个变量为staic final则只能在申明时赋值
对于final类型的引用变量来说,所谓的不能改变指引用不能改变,值是可以改变的
为什么public类final成员变量申明时要加static?
static对象存放在静态空间,不会在运行时被释放,可以节省内存,类的多个对象同时引用只有一份,没有多份拷贝。
三.多态
1.多态条件:有继承、有重写、要有父类引用指向子类对象
2.父类或者接口引用指向子类或者实现该接口的类对象
3.多态是运行时的行为,不是编译时的行为
4.多态要有动态绑定,通过方法重写与方法重载来实现多态?这种说法错误,因为方法重载是编译期决定好的,没有后期也就是运行期的动态绑定
四.HashMap和HashTable的区别?
1.线程安全上,HashTable是同步的线程安全,HashMap是非同步的线程不安全,可以接受null的值和value,HashTable不允许。
2.对单线程来说,HashTable效率低。
3.线程安全的类:vector,stack、hashtable、enumeration
五.hash冲突
当关键字值域远大于哈希表的长度,而且事先并不知道关键字的具体值,冲突可能就会发生。(两个或者两个以上的hash值计算的结果相同)
解决办法
1.开放地址法,插入元素时如果发生冲突,算法会简单地从该位置循环遍历hash表,直到找到下一个空位,放入该元素。查找元素时,首先散列值所指向的位置如果没有找到匹配,则继续从该位置遍历hash表,直到找到相应的元素,如果找到空位置,表示元素不存在,整个hash表遍历完毕,表示元素不存在并且hash表已满。
2.链地址发,基本思想将所有哈希地址为i的元素构成一个同义词链的单链表,将单链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行,链地址发经常用于插入和删除的情况。
3.当发生hash冲突时,使用多个hash函数计算地址,直到没有冲突,缺点计算时间较长。
4.建立一个公共的溢出区,假设hash函数的值域为[0,m-1],则向量HashTable[0,m-1]为基本表,另外设立存储空间overtable[0,v]用来存储发生冲突的记录。
六.幂等性的处理方式
幂等性:接口可以重复调用,在多次调用情况下最终的结果一致。
1.查询操作是天然幂等性
2.唯一索引,防止新增脏数据
3.Token机制,防止页面重复提交
4.悲观锁
5.乐观锁,通过版本号、时间戳实现
6.分布式锁
七.wait和sleep的区别
1.sleep来自Thread类,wait来自Object类
2.最主要是sleep方法没有释放锁,wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3.wait,notify和notifyall只能在同步控制方法或者同步控制块中使用,而sleep可以在任何地方使用
4.sleep必须捕获异常,而wait,notify和notifyall不需要捕获异常
八.面向对象和面向过程的区别
面向对象:容易维护,复用,扩展,由于面向对象有封装、继承、多态的特性,可以设计出低耦合的系统,使系统更加灵活。
缺点,性能比面向过程低
面向过程:性能更高一些,因为类调用的时候需要实例化,开销比较大,比较消耗资源。比如嵌入式开发,Linux等一般都是采用面向过程开发。
缺点:没有面向对象好维护和扩展
九.重载和重写的区别
重载:发生在同一个类中,方法名必须相同,参数类型不同,个数不同,顺序不同,方法的返回值和访问修饰符可以不同,发生在编译时。
重写:发生在父子类中,方法名和参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类,如果父类方法访问修饰符为private则子类就不能重写该方法。
十.自动装箱与拆箱
装箱:将基本类型用它们对应的引用类型包装起来
拆箱:将包装类型转换为基本数据类型
十一.成员变量和局部变量的区别有哪些?
1.从语法形式上,看成员变量是属于类的,而局部变量是在方法中定义的变量或者是方法的参数,成员变量可以被public,private,static等修饰符所修饰,局部变量不能被访问修饰符以及static修饰,但是成员变量和局部变量都可以被final修饰。
2.从变量在内存中的存储方式来看,成员变量是内存的一部分,而对象存在堆内存中,局部变量存在栈内存。
3.从变量在内存中的生存时间上来看,成员变量是对象的一部分,它随着对象的创建而存在,随着对象的消失而消失。局部变量随着方法的调用而存在,方法调用完毕后消失。
4.成员变量如果没有被赋初值,则会自动以类型的默认值而赋值,而局部变量则不会被自动赋值。