前言
下面列出了Java面试中一些常见的基础问题,这里采用了网上的观点和一些自己的理解。
采用了总结(复习看的)+ 资料来源(忘了再看)的方式。如果大家有更好的资源、理解或者有路过的大佬,希望能够不吝赐教(留言或私信);长路漫漫,让我们互勉互进吧!
1. 数组的扩容 ?
1)Java数组对象的大小是固定不变的,数组对象是不可扩容的。
2)利用数组复制方法可以变通的实现数组扩容。
3)System.arraycopy()可以复制数组。
4)Arrays.copyOf()可以简便的创建数组副本。
5)创建数组副本的同时将数组长度增加就变通的实现了数组的扩容。
https://www.cnblogs.com/gw811/archive/2012/10/07/2714252.html
2. static关键字?
主要用途:方便在没有创建对象的情况下调用(方法/对象)。
修饰方法:因为非静态方法、变量需要依赖对象才能引用,而静态方法是没有对象的,所以静态方法是不能访问类的非静态成员变量和非静态方法。 但是在非静态成员方法中是可以访问静态成员方法和静态成员变量。
特别说明:static方法是属于类的,非实例对象,在JVM加载类时,就已经存在内存中,不会被虚拟机GC回收掉,这样内存负荷会很大,但是非static方法会在运行完毕后被虚拟机GC掉,减轻内存压力
修饰变量:
静态变量和非静态变量的区别:
静态变量被所有对象共享,在内存中只有一个副本,在类初次加载的时候才会初始化
非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响
static成员变量初始化顺序按照定义的顺序来进行初始化
static块:
主要作用:提高程序的性能,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行,来减少在调用一些重复性方法时,创建和销毁带来的性能损耗(有点像池化思想)。
静态初始化块可以置于类中的任何地方,类中可以有多个静态初始化块。
在类初次被加载时,会按照静态初始化块的顺序来执行每个块,并且只会执行一次
https://blog.csdn.net/kuangay/article/details/81485324
3. final关键字的作用?
修饰类:表示这个类不能被继承
被final修饰的类,final类中的成员变量可以根据自己的实际需要设计为fianl
final类中的成员方法都会被隐式的指定为final方法
修饰方法:不能被重写
一个类的private方法会隐式的被指定为final方法
如果父类中有final修饰的方法,那么子类不能去重写
修饰成员变量: 必须要赋初始值,而且是只能初始化一次。
必须初始化值。
被fianl修饰的成员变量赋值,有两种方式:1、直接赋值 2、全部在构造方法中赋初值。
如果修饰的成员变量是基本类型,则表示这个变量的值不能改变。
如果修饰的成员变量是一个引用类型,则是说这个引用的地址的值不能修改,但是这个引用所指向的对象里面的内容还是可以改变的。
https://baijiahao.baidu.com/s?id=1601084106055683243&wfr=spider&for=pc
4. 抽象类和接口的区别?
1 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
2 类可以实现很多个接口,但是只能继承一个抽象类
3 类可以不实现抽象类和接口声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
4 抽象类可以在不提供接口方法实现的情况下实现接口。
5 Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
6 Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。
7 接口是绝对抽象的,不可以被实例化,抽象类也不可以被实例化。
8 一个类实现接口的话要实现接口的所有方法,而抽象类不一定也可以参考JDK8中抽象类和接口的区别
总结:
从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
https://blog.csdn.net/weixin_43761659/article/details/100050353
5. 重写和重载 ?
重写:发生在子类中,但具体的实现方法与父类不同,则需要重写父类的方法。
重载:发生在同一个类中,多个同名方法,但参数不同(类型、个数)。
https://www.runoob.com/java/java-override-overload.html
6. 面向对象 的封装 继承 多态
面向对象:一种 抽取行为共性、强调对象的设计思想。主要特点为 封装、继承、多态。
封装(Encapsulation)是面向对象方法的重要原则,就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。
忽略组成的细节,强调整体,将其对象化,以方便使用。方法,类,脚本,框架都是封装的体现。类似于创新,将旧事物重新排列组合形成新的高效事物。
作用:代码复用,增加可读性,易维护,增强了安全性。
继承:从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
特点:关键字—extends,具有父类的行为和属性,只能单继承。
多态:引用变量指向的对象不能确定,有很多可能。
即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
条件:继承、重写、向上造型(父类型的引用指向子类对象)。
https://blog.csdn.net/jianyuerensheng/article/details/51602015
7. String的值可以改变 ?
引用类型数据,无法改变。源码中包含了 private final char value[];
https://www.cnblogs.com/hitfire/p/8728037.html
8. 集合 相关?
Collection 接口的接口 对象的集合(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│—————-├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序
Map 接口 键值对的集合 (双列集合)
├———Hashtable 接口实现类, 同步, 线程安全
├———HashMap 接口实现类 ,没有同步, 线程不安全-
│—————–├ LinkedHashMap 双向链表和哈希表实现
│—————–└ WeakHashMap
├ ——–TreeMap 红黑树对所有的key进行排序
└———IdentifyHashMap
https://blog.csdn.net/feiyanaffection/article/details/81394745
9. 线程相关?
线程生命周期 ?
5个阶段:新建、就绪、运行、阻塞、销毁。
https://www.cnblogs.com/marsitman/p/11228684.html
实现线程的方式 ?
1.继承Thread类,重写run方法
2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
3.通过Callable和FutureTask创建线程
4.通过线程池创建线程
https://www.cnblogs.com/ericz2j/p/10281572.html
10. 对反射了解多少?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
https://www.zhihu.com/question/24304289?sort=created
https://blog.csdn.net/qq_36226453/article/details/82790375