整理一些Java基础的概念和知识点,以便加深印象。
1.基础数据类型:btye(8位)、short(16位)、int(32位)、long(64位)、float(32位)、double(64位)、boolean、char(16位)。
1.2.关键字:
·final:修饰符,被final修饰的类不能被继承,被final修饰的对象不能被修改,初始化时必须赋值;finally:try/catch异常处理块的一部分,不管有没有抛异常,都会执行finally块中的代码;finalize:这是对象被垃圾回收器回收前被调用的方法。
1.3.自动装箱和自动拆箱
·概念:java将基础类型自动转换成对应的类,或反向转换的一种操作。
·经典场景:往List添加基础类型的值时。
·弊端:自动装箱和拆箱会创建多余的对象,避免在循环中使用装拆箱。
2.接口和抽象类:
·接口中所有方法都是抽象的,而抽象类可以包含抽象方法和非抽象方法;
·类可以实现多个接口,但只能继承一个类;
·实现接口必须实现所有抽象方法,但如果将类声明为抽象类,可以不用实现其继承的抽象类父类的抽象方法,抽象类也可以不提供方法实现的情况下实现接口;
·接口声明的变量默认是final的,而抽象类可以非final;
·接口的方法都是public,而抽象类可以是private、public、protected;
3.值传递:基本数据类型、基本数据类型对应的类(Integer等)、String
引用传递:类、接口、数组
4.集合
·List、Set继承了Collection接口;
·Iterator和ListIterator、fail-fast和fail-safe
·HashMap的容量、负载因子、扩容极限
·增删频繁用无序数组,查找频繁用有序数组;
·Collection是List、Set等集合类的顶级接口,提供了对集合对象的基本操作的方法;Collections是服务于Collection框架的工具类,其提供了许多静态的方法,例如排序、搜索等。
5.垃圾回收
·条件:当对象对当前程序变得不可达的时候,可被回收;引用计数为0的对象;
·回收算法:标记-清除算法(效率不高,且会产生内存碎片)、复制算法(每次只用可用内存的一半,满了就复制清理,不会产生内存碎片,但是可用空间只有一半)、标记-整理算法(让存活对象向同一端移动,然后清理掉边界意外的内存);新生代用复制算法,老年代用标记整理或标记清除算法;
6.线程和进程
·线程是包含在进程中的实际运作单位;同一进程中的多个线程可共享进程所拥有的资源。
·线程和进程是不同的操作系统资源管理方式,系统中多个进程之间先对独立,而进程中多个线程可共享资源。
·不同进程使用不同的内存空间,而一个进程内多个线程共享相同的内存空间,但每个线程都有独立的栈内存。
7.使用线程
·继承Thread、实现Runnable、Callable接口;JAVA是单继承,实现接口的方式更符合JAVA的编程规范。
·Thread.interrupte()是将停止状态标识设为true,当线程下一次判断状态的时候会结束线程;对于wait、sleep、join状态的线程,会抛出异常;
对于整在获取同步锁的线程,不会去判断该状态;
·使用继承Thread方式实现线程时,最好设置Thread.name和Group,方便管理。
·线程中的异常无法通过trycatch来捕获,应使用Thread.setUncaughtExceptionHandler来获取异常。
·只有调用了Thread.start()方法,才有新建线程,仅仅调用run方法只是在原本的线程执行。
8.内存模型
·线程私有:虚拟机栈、本地方法栈、PC寄存器;线程公有:堆、方法区。
·虚拟机栈伴随线程的生命周期,虚拟机栈包含多个栈帧,一个栈帧对应一个方法;本地方法栈是与本地方法相关的地方;PC寄存器保存了当前指令的地址。
·堆是程序运行时所使用的内存空间,所有线程都可以访问堆内存;堆内存通过GC回收,如果内存不足会抛出OOM异常;方法区本质上是包含在堆内存中,通常会将其与堆区分开来;方法区用于存放类的信息、常量池、方法的数据和代码等。
·方法区的实现:永久代(jdk1.7以前)和元空间(jdk1.8开始);元空间没有了永久代容量上限的限制,减少大量新建类时导致的频繁FULL GC;
9.volatile
·volatile保证了被修饰对象的可见性。
·可见性指的是对所有线程而言,该对象读取到的永远是最新的值(每次都是从内存中重新获取,写入时也是写入到内存)。
·volatile不能保证对象的原子性。
10.synchronized
·被synchronized修饰的方法或代码块,将具备原子性和可见性。
·属于悲观锁,获取锁和释放锁的开销极大。(乐观锁:CAS算法,AtomicInteger是基于CAS实现的乐观锁同步int类)
·sy是java语音内置特性,java1.6之后性能有了较大提高。
10.1.Lock
·Lock是类,通过代码层面实现同步。
·Lock需要手动释放锁,lock.unlock();
·Lock可以使获取不到锁的线程不必要一直等待;Lock可以知道线程是否已经获取到锁;Lock可以使多个读操作之间不会互斥;
11.线程安全相关
·wait、notify、notifyall等方法,之所以在Object类里面,是因为JAVA的锁是针对对象,而不是针对线程;这三个方法只能在同步块中调用,是要避免产生竞态条件。
·同步集合和并发集合:同为线程安全的集合,但并发集合更具扩展性,jdk1.5之后提供的Concurrent***集合类属于并发集合。
·堆和栈,栈是每个线程独有,堆是所有线程共享,对象在堆里创建,没有使用volatile修饰的对象,线程使用时会将该对象缓存到自己的栈空间,导致线程不安全。
12.线程池
·线程池减少了线程创建和销毁的开销。
·通过new ThreadPoolExcutor(corePoolSize,maximumPoolSize,keepAliveTime,timeUnit,runnableTaskQueue,threadFactory,handler)新建线程池,几个参数分别为:线程池的基本大小、线程池线程的最大数量、线程空闲后的存活时间、keepAliveTime的单位、用于保存等待执行的任务队列、创建线程的工厂、拒绝处理任务时的策略。
·几种常用的线程池:FixedThreadPool(固定线程数量,全部为核心线程,减少新建和销毁线程的开销,但是空闲线程也不会回收)、CachedThreadPool(没有核心线程,无穷大的线程数量,任务进来如果没有空闲线程就会创新新线程,优点是不会有任务排队的情况)、SingleThreadPool(有且只有一个线程的线程池,多个任务只能一个个排队,可以确保按顺序执行)、ScheduledThreadPool(可设置任务加入后延时执行,可设置任务定时循环执行)
13.序列化
·为了持久化对象,或者远程方法调用。
·实现java.io.Serializable接口。
·transient关键字,序列化时会忽略该属性。
14.反射
·在运行状态中,获取某个类的属性和方法,调用对象的属性或方法。
·获取类的Class对象,Class对象是由JVM自动创建的,包含了类的属性和方法的信息。
15.类加载流程
·加载-验证-准备-解析-初始化-使用-卸载
·ClassLoader根据类名查找到对应的class文件,读取二进制字节流,转换为一个Class对象。
·双亲委托模式:每个ClassLoader都会优先请求父类去加载,在父类返回无法完成加载时才尝试自己去加载,保证了Class类的唯一性。
·验证:格式、语义、操作。
·准备:为静态变量分配空间,设置初始值。
·解析:静态绑定的解析,如final方法、static方法,构造方法。
·初始化:执行static关键字修饰的代码块和变量,给变量覆盖设定的值。