Java基础知识
重载与重写的区别
重载指的是在同一个类中,函数的方法必须一样但是参数顺序不同,个数不同,类型不同,返回值和访问修饰符可以不一样,发生在编译时。
重写发生在父子类中,方法名必须一样,参数列表必须一致。返回值类型范围必须小于等于父类,抛出异常范围小于等于父类,访问修饰符的范围必须大于父类。private类型的方法不可以被重写。子类对父类中的方法功能不满意,对该方法进行功能修改。
问题:
- 为什么返回值的范围和抛出异常的范围必须小于等于父类?
- 为什么访问修饰符的范围必须大于父类?
String,StringBuffer,StringBuilder之间的区别,String为什么是不可变的?
多变性
String类中使用final关键字字符数组保存字符串 private final char value[],所以String是对象是不可变。
StringBuffer和StringBuilder都是继承于AbstractStringBuilder类,它们的源码定义是char []value;
线程安全性
String中的对象是不可变的,也就可以理解为常量,线程安全。在StringBuffer中这些操作是添加了线程锁,所以线程是安全的。StringBuilder的并没有对方法进行同步锁,所以使非线程安全。
性能
每次对String类型进行改变的时候,都会生成一个新的String对象,然后引用指向新的地址。
StringBuffer每次都对自身进行操作,相同情况下,StringBuilder和相比StringBuffer性能提升了15%~20%,但是要冒着线程不安全的风向。
三者使用的选择:
- 操作少量的数据使用String;
- 在单线程下操作大量数据则使用StringBuffer;
- 在多线程下操作大量数据则使用StringBuilder。
自动装箱与拆箱
装箱:将基本类型转换为引用类型。
拆箱:将引用类型转换为基本类型。
equals 与 == 的区别
==对于基本类型比较的是数据的值,对于引用类型比较的是存储地址。
equals有两种用法:
- 对于未被类覆盖的equals方法使用方式和==一样;
- 对于类覆盖了的方法(即重写)equals比较的是两个对象的内容是否相等。
请注意以下几种情况:
- String中的equals已经被重写了,所以比较的是内容。Object中的equals方法是比较的对象的内存地址。
- 创建一个String对象,JVM会现在常量池中寻找相同的内容,如果有则把引用指向该内容,反之则创建一个新的内容。
关于Final关键字的一些总结
Final一般用于变量、方法、类
Final修饰基本类型的变量以后该值无法改变。对于引用类型的常量来说,一旦被指定该应用无法指向其他内存地址。
Final修饰类,这该类无法被继承。对应的该类里面的方法则被隐式的变为Final方法。
Final修饰方法,1.这样做是为了锁定该方法,无法被任何继承类修改2.提升效率,早期的Java,会将Final方法转为内嵌调用。如果方法过于庞大,内嵌式函数对于效率的提升并没有多少(现在的Java已经做出了优化,不在使用Final优化方法),类中所有的Private方法都隐式的指定为Final。
Object中常见的方法总结
public final native Class<?> getClass()//用于返回当前运行时中Object中的所有对象。
public native int hashCode()//返回当前值的Hash值常用于hashMap中。
public bolean equals(Object obj)//用于比较2个对象的内存地址是否相等。String中对equals方法进行了重写,用于比较两个对象的内容是否相等。
protect native Object clone() throws CloneNotSupportException//用于创建并返回当前对象的拷贝。Obeject对象本身没有实现cloneable接口,如果不重写clone方法并直接调用会出现 CloneNotSupportException。
Public String toString() //返回类的名字。
notify//唤醒一个在此对象监视器上等待的一个线程(监视器相当于锁的概念),如果有很多线程只会任意唤醒一个。
notifyAll()//唤醒在此监视器上等待的所有的线程。
wait()//暂停线程的执行,并且根据参数实现不同的时间等待。
finalize()//实例被垃圾回收器回收触发的操作。
Java中的异常处理
Java中的异常类结构层次图
Java中java.lang中的Thorwabale拥有两个处理所有异常的子类Error与Exception‘
Error是程序无法处理的错误,它一般与程序的操作者无关,而是JVM出现问题或者JVM在程序的过程中出现错误。如StackOverflow和OutofMemory,当JVM出现这些问题时一般会关闭线程。这些错误是不可查的,因为他们出现在程序的处理与计算能力之外。而且绝大多数是程序不允许出现的状况,对于合理的程序设计来说,即使确实发生这样的错误,也应该有对应的处理机制。
Exception,是程序可以处理的异常。它有一个重要的子类runtimeException。
Throable类中常用的方法
- public String getMesssage()//返回异常发生时的详细信息。
- public String toString()//返回异常发生时的简要描述。
- public String getLocalizedMessage()//返回异常对象的本地化信息,如果没有对类的方法进行重载其作用等同于getMessage()。
- public void printStackTrace()//在控制台上打印Throwable封装的信息。
异常处理总结
try块:捕捉异常,其后可接任意个catch块,如果没有catch块则必须加上fianlly。
catch块:用于处理try块捕捉到的异常。
fianlly:无论是否捕捉到异常,finally语句块都会执行。如果在finally语句之前出现return语句,则在return语句执行之前执行finally语句。
以下四种情况finally不会执行:
- 所有的线程都被关闭;
- 关闭CPU;
- 在finally语句块中出现异常;
- 在前面的语句中遇到System.exit();
获取键盘常用的两种输入方法
方法1:通过Scanner对象获取:
Scanner input= new Scannner(System.in);
String s=input.nextline();
input.close();
方法2:通过BufferedReader()
BufferedReader input =new BufferedReader(new InputStreamReader(System.in));
String s =input.readline();
接口和抽象类的区别是什么?
- 接口的默认方法是public,所有方法在接口类中都不能实现(Java以后所有的方法默认可以在接口中实现)。非抽象类中可以有非抽象方法;
- 接口中实例化的变量都是final,而抽象类中并不一定;
- 一个类只能实现一个抽象类,但是可以实现多个接口;
- 接口可以声明但是不能使用new实例化,new必须是一个实现了接口的类。从设计层面来讲,抽象是对类的一种设计,是一种模板。接口是对行为的一种抽象是一种方法。
Java框架的集合
ArrayList与LinkedList的异同
线程安全
ArrayList与LinkedList都是不同步的所以他们是线程不安全的。
底层数据结构
ArrayList中的底层数据结构是Object中的数组,LinkedList底层数据机构是双向链表的结构(1.7以后取消双向循坏链表)
Q:双向循环链表和双向链表的区别。
插入和删除是否受元素位置的影响:
- 因为ArrayList底层数据结构是数组所以插入和删除的时间复杂度都受到元素位置的影响。
- LinkedList底层的数据结构采用的链表所以插入删除的时间复杂度不受影响。
是否支持快速随机访问
Linkedlist不支持快速高效的随机访问,而ArrayList支持。快速的随机访问就是根据序号进行访问。
内存空间占用
ArrayList的空间浪费体现在会队尾预留一定的空间。而inkedList的空间浪费体现在它每一个元素所占有的空间都比ArrayList大,它需要一定的空间存储前驱和后继的地址。
拓展:AcessRandom接口,该接口属于标识作用,如果类中实现了该接口说明该数据结构支持快速访问。
对于List的访问方式:
如果实现了AcessRandom接口的List,优先用for然后用foreach。
如果没有实现呢AcessRandom接口的List,优先用iterator遍历.(foreach底层也是通过iterator实现),大size数据千万不要用普通的for循环。
ArrayList与Vector的区别
Vecotor是线程安全的,可以由两个线程同时访问一个Vector变量。但是如果只有一个线程访问Vector将花费大量的时间在线程的同步上。
如果在不需要保证线程的同步的情况下,请使用ArrayList。
HashMap的底层实现与基本原理
HashMap继承于Map类,它可用put()和get()来存储和读取键值对。HashMap通过hashCode()将key转换成hashCode,然后将这些值分布到Bucket中。
- 它不含有关键字Synchronized,所以他不是线程安全的。但是访问的速度就很快。
- 它是无序的。
- 它的Iterator是fail-fast不允许外部操作改变Map的结构,会抛出错误,除非通过自身的remove方法去修改。
- 它可以存放Null键和Null值(一个HashMap里面只能存在一个键为Null)
JVM
1.JVM 概述
JVM 是一台假想的计算机,它运行在操作系统上不和硬件做直接接触。它包含字节码指令集,堆,栈,方法存储域,垃圾回收,寄存器。
2.代码的执行过程
Java代码先通过编译器转换为class文件,然后通过JVM转换为机器字节码。
3.JVM内存区域
线程共享 :堆,方法区
线程私有:虚拟机栈,本地方法栈,程序计数器。
直接内存
4.HotSpot 后台运行的几种线程
JVM线程:线程到达安全点以后执行的任务例如Stop the world
周期任务线程:周期暂停wait
编译线程:便衣任务
GC线程:
信号分发线程:传递给JVM并调用适当的JVM方法
5.虚拟机内存分配机制
堆上分配,栈上分配,TLAB分配
6.内存回收算法:
复制算法,标记清除算法,标记清楚整理算法
7.内存分析状况工具
Jconsole ,JMap,Jstat,viscialvm,MAT
8.线程同步和交互机制
线程资源同步(Synchronized,lock/unlock机制)
线程资源交互机制wait,notify,notifyall,并发包提供的机制(semaphore,CountDownLatch)
9.线程状态分析及方法Jstack
使用Jstack会生成一个JVM当前线程快照,保存系统状态
作用帮助开发分析程序运行问题,比如CPU状态,线程卡死。
10.JVM内存区域,哪些区域会发生OOM
堆,栈(虚拟机栈,本地方法栈),方法区
11.线程私有区的生命周期有多长:
随着线程的创建而创建,随着线程的销毁儿销毁
12.直接内存的作用
在SDK1.4中NIO中引入了channel,Buffer的IO方式。它可以直接使用Native函数库直接分配堆外内存,然后使用DirectByteBuffer对这块内存进行使用,而不用在Native堆和直接内存中两边移动。
13.谈一谈对程序计数器的理解;
它是当前线程所执字节码的行号指示器,不会发生OOM。
14.虚拟机栈
是描述JAVA方法的内存执行模型,JAVA方法在执行的过程中都会创造一个栈帧,它用来存储局部变量表,操作数栈,动态链接,方法出口。每一个方法从调用到执行完毕的过程也代表着一个栈帧入栈到出栈的过程。
15Java堆-运行时数据区
是一块被线程共享的区域,所有对象及数组的创建都是在这一块,也是垃圾收集器,进行垃圾收集最重要的一块。由于现代VM采用垃圾收集算法,因此Java堆从GC的角度还可以分为新生代(eden,survior from ,survivor to),老年代。
16.方法区-永久代
就是我们说的永久代用来存储类信息,方法常量,静态变量,即时编译器编译后的代码等数据。HotSpot JVM将分代扩展到方法区,这样就不用特地为方法设置特定的内存管理器。
17.运行时常量池是什么
运行时常量迟池是方法区的一部分,Class类文件除了用来存储class 版本信息,字段,方法,借口等描述信息,还有一项信息就是常量池。
它用来存储编译期生成的各种字面量和符号引用。
18.谈谈对堆内存理解
Java堆按照GC可以分为青年代(Eden, Survivor From,Survivor To),老年代(old)。
Eden,对象出生的地方(如果创建对象占用的地方很大,就直接分配到老年代),如果空间不够就触发Minor GC,对新生代进行一次垃圾回收。
Survivor From
上一次GC的幸存者,作为这一次GC被扫描者;
Survivor To
保留一次MinorGC中的生存者
老年代
主要存放应用程序中生命周期比较长的对象
老年代的对象不稳定,所以MajorGC不会频繁执行今天,在进行MajorGC之前会进行一次MinorGC,使得新生代的对象晋入老年时代,导致空间不足也会造成MajorGC。当无法找到足够大的连续空间分配给新创建的较大的对象提前触发一次MajorGC进行垃圾回收腾出空间。
MajorGC采用标记清楚算法:首先扫描一次所有的老年代,标记出存活的对象,然后回收没有标记的对象。
19.谈谈Minor GC的过程(复制->清空->互换)
1.首先将Eden ,Survivor From 发送到Survivor To区域,并且年龄+1
(如果Servivor To
2.亲空Survivir from 和Eden 里面的内容
3.最后将Survivor To里面的内容与清楚后的Survivor From 内容互换。
20.永久代
指内存的永久保存的区域运行时方法区
21.常用的垃圾收集器
Serial,ParNew,Parallel Scavenge,SerialOld,Parllel Old ,CMS,G1.
22.垃圾回收算法
复制算法,标记清除算法,标记整理算法,分代收集。
23。如何判断哪些对象已经失望
1.可达性分析法,根搜索算法。
这篇博客整理了Java基础知识,包括重载与重写、String相关特性、自动装箱与拆箱、异常处理和Final关键字等内容。还深入讨论了Java集合框架,如ArrayList与LinkedList的异同以及HashMap的基本原理。最后,涉及JVM内存区域和垃圾回收机制,对面试中的常见问题进行了总结。
1504

被折叠的 条评论
为什么被折叠?



