以前整理的几个面试题,主要是Java的基本语法,如下
String、StringBuidler、StringBuffer区别
String是只读类型,所以每一次的改变都会新建一个对象
StringBuilder多线程非安全的,所以他的效率比StringBuffer高
StringBuffer是通过锁来保证线程安全的
重载(Overload)和重写(Overwrite)的区别
重载是在一个类里面,重写是在两个类里面(例如子类重写父类)
重载是通过参数不同来表现的不同形式是在编译阶段就确定了,而重写则是在运行阶段表现出来的不同行为
类的加载需要了解以下知识点
-
类的加载器有 bootstrap加载器,ext记载器,application加载器和用户自定义加载器
-
双亲委派模型是指,当application加载器加载一个类的时候,会先委派他的父类ext是否已经加载过了,ext会委派看他的父类bootstrap有没有加载过。如果bootstrap没有加载过,会尝试用ext加载,如果没有再使用application加载
-
类的生命周期
-
-
加载,将.class的二进制文件,加载进来,生成java.lang.Class对象到堆的方法区
-
验证,验证这个对jvm是否有伤害
-
准备,生成静态变量的对象,注意全部是默认初始值
-
初始化,再进行类的初始化,先初始化父类
-
销毁,当java虚拟机退出或程序结束的时候
-
Java的内存模型
方法区
存储的是类的元信息,静态变量,常量等,抛出的是outofmemory
堆栈
线程自有的,存储的是局部变量等,抛出的是Stack Overflow
堆
存储是对象实例,是gc垃圾回收的主要工作区域。可以设置最大值和最小值,outofmemory
新生代:又分为伊甸区和幸存区
老年代
垃圾回收的算法
标记,清除法。最简单,但是碎片比较多
标记,复制法。消除了碎片问题,但是太占空间
标记,整理法。向一端移动
分代收集算法,新生代用复制算法,老年代用标记清除法
垃圾回收的实现
-
单线程,新生代和老年代串行收集,效率低下
-
多线程,新生代和老年代并行运行
-
Parallel,可以根据系统负载来调节垃圾回收的线程数量
-
CMS, 标记很快中断用户线程,清除则不需要中断用户线G1,目前性能最好的垃圾收集器
Java容器
List:有序的,按照存入的先后顺序
-
ArrayList : 数组实现的list,方便index读取,但是写入比较慢
-
LinkedList : 链表实现的list,比如容易写入,但是随机访问查
Set: 不可重复的,只有一个null
-
HashSet: 无序的
-
TreeSet:有序的
-
LiknedHashSet: 按照存入的先后顺序
Map:是一种key value结构
-
HashMap:非线程安全的,key和value都可以是null
-
HashTable: 同步的
-
TreeMap : 有序的
-
LinkedHashMap: 按照存入的先后顺序
-
ConcurrentHashMap:线程安全的
HashMap多线程死循环
i. 存储结构是数组 + 链表的方式
ii. 初始值是16,负载因子是0.85,需要扩容,rehash
iii. rehash的时候,多线程下会导致,循环链表,在下次读取的时候就死循环了
iv. concurrentHashMap使用分段锁的技术保证性能
v. java8里面,少的时候还是用链表,多的时候用红黑树
向对象的"六原则一法则
-
单一职责原则:一个类只做它该做的事情
-
开闭原则:软件实体应当对扩展开放,对修改关闭。
-
依赖倒转原则:面向接口编程。
-
里氏替换原则:任何时候都可以用子类型替换掉父类型。
-
接口隔离原则:接口要小而专,绝不能大而全。
-
合成聚合复用原则:优先使用聚合或合成关系复用代码
-
迪米特法则:迪米特法则又叫最少知识原则,一个对象应当对其他对象有尽可能少的了解