Java SE基础知识
1、面向对象的四大特征
1、抽象
将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象,只关注有什么,而不关心实现。
2、封装
将数据和对数据的操作包围,只能通过接口对内部数据进行访问,保证了数据的安全性。
3、继承
从已有类中获得属性和方法,创建新的类方法,使得不断更新的软件系统得以延续。
4、多态
允许相同的或者不同子类对象对同一个消息做出不同的响应。必须有继承、重写和父类对象引用子类对象(向上转型)。
2、==、equals和hashcode的联系
1、==
基本类型:比较的是值。
引用类型:比较的是对象的地址。
2、equals
object类:比较的是类的地址,即是否是同一个对象。
String类:重写了equals方法,比较的是对象的值。(其他所有需要比较内容的类都需要重写equals方法)。
3、hashcode
object类:对堆上面的对象产生一个独特的hash值。
String类:重写hashcode方法,比较对象的值。
如果类不重写equals和hashcode的话会导致比较的是地址,不同对象的地址不同比较的结果一直是false。
3、java IO(字符流和字节流)
reader
1、节点流:FileReader 、PiprReader、CharArrayReader。
2、处理流:BufferReader、InputStreamReader。
writer
1、节点流:FileWriter、PipeWriter、CharArrayWriter。
2、处理流:BufferWriter、OutputStreamWriter、printWriter
InputStream
1、节点流:FileInputStream 、PipeInputStream、ByteArrayInputStream。
2、处理流:BufferInputStream、DataInputStream。
OutputSteam
1、节点流:FileOutputStream 、PipeOutputStream、ByteArrayOutputStream。
2、处理流:BufferOutputStream、DataOutputStream。
4、BIO、NIO、AIO
1、BIO(block):同步阻塞IO,传统IO,简单方便,处理并发能力低。
2、NIO(non):非同步阻塞,传统IO升级,客户端和服务端通过channel通讯,实现了多路复用。
3、AIO(Asynchronous):异步非阻塞,基于事件和回调机制。
5、反射机制
在运行状态中,对于任何一个类(对象),都能够知道它的所有属性和方法。
1、反射的应用场景
模块化开发,通过反射调用字节码;动态代理设计模式;框架。
例子:1、jdbc中通过反射加载驱动。
2、spring框架,通过xml配置方式装载Bean:
1)将xml文件和properties文件加载到内存中
2)得到文件中对应实体类的字节码字符串以及相关的属性信息
3)反射机制通过字符串获得类实例
4)动态配置类的属性
2、获取反射的方式
1、对象实现-----------------------对象.getClass();
2、路径实现-----------------------Class.forName(“路径”);
3、类名实现-----------------------类.class;
注意:静态代理:需要代理对象和目标对象实现一样的接口。
动态代理:动态代理是在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中
6、String类
1、字符串常量池
位于堆内存中,存储字符串常量,避免开辟多个空间存储同一个字符串。
2、String特性
1、不变性:对它的任何操作都是新建一个字符串对象,再将引用指向新对象。
2、常量池优化:相同的字符串不必重新建,只需将对象引用指向池中已有的字符串。
3、final修饰:不能继承,提高安全性。
问题
—new String(“dfds”);创建了几个对象?
1)常量池中有dfds,创建了一个。
2)常量池中没有dfds,两个。
—字符串翻转?
利用StringBuffer或者StringBuilder的reverse方法
—String的数据结构是char型数组,但是数组有length属性没有length方法,String有length方法。
—StringBuffer和StringBuffer的区别?
StringBuffer较StringBuider慢一点,但是线程却是安全的。
—String、StringBuffer、StringBuilder的使用场景?
如果要操作少量的数据用 = String
单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
7、int和Integer的区别
int是基本数据类型 ,Integer是int的对应的包装类,是对象类
初始值:int是0,Integer是null
java 异常
throwable:error和exception的超类,用于指示异常发生的情况。
Error(非受检)
程序无法解决的错误。有虚拟机运行错误、内存不足错误、栈溢出错误、类定义错误等
Exception
程序可以捕获和处理的异常。
1、运行时异常(非受检):jvm运行期间出现的异常。java虚拟机会对其自动捕获和抛出(即使我们没有写异常捕获语句),绝大部分都是代码异常,要从逻辑上改进代码。
2、编译时异常(受检):java编译器检查出的异常。必须手动写代码捕获并且处理异常。
异常处理
抛出异常
throw:方法内部对捕获的异常进行抛出。只能抛出一种异常。
捕获异常
try、、、catch、、finally:对要执行的事务try检查,用catch捕获处理,在finally处定义事务即使异常也要执行的处理。
声明异常
throws:在方法签名处直接声明可能出现的异常,可以是多种异常。
多线程
基础知识
线程安全问题
1、线程切换带来的原子性问题
2、缓存导致的可见性问题
3、编译优化带来的有序性问题
线程和进程
进程:在内存中运行的应用程序,有自己的独立的内存空间。
线程:进程中的一个执行任务。
区别:进程是计算机资源的分配单元,线程处理器调度和执行的基本单元。同一个进程的线程共享进程的资源和空间,进程之间的空间和资源都是独立的。进程不会对其他的进程产生影响,但是一个进程里面的线程崩溃了会导致整个进程的崩溃。
死锁
两个或者两个以上的线程由于竞争资源或彼此通信造成的阻塞现象。
条件:互斥、请求和保持(一次申请全部资源可以避免)、不剥夺(申请不了,主动释放)、循环等待(按照一定的顺序获取资源)。(括号里面试解决办法)
创建线程
1、继承Thread类,重写run方法。
2、实现Runnable接口,重写run方法。
3、实现Callable接口
4、线程池
线程同步
1、同步代码方法
2、同步代码快
3、特殊变量域volatile
4、重入锁reentrantLock
保证线程安全方法
1、使用原子类
2、自动锁synchronize
1)作用于实例方法,当前实例加锁,进入同步代码前要获得当前实例的锁;
2)作用于静态方法,当前类加锁,进去同步代码前要获得当前类对象的锁;
3)作用于代码块,这需要指定加锁的对象,对所给的指定对象加锁,进入同步代码前要获得指定对象的锁。
3、手动锁Lock
volatile相关
当一个共享变量被 volatile 修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。
线程池
使用Executors提供的工厂方法创建下面四种线程池的一种,他们都实现了ExecutorService接口。
newSingleThreadExecutor:创建一个单线程的线程池。(堆积的任务可能会导致内存不足)
newFixedThreadPool:创建固定大小的线程池。(堆积的任务可能会导致内存不足)
newCachedThreadPool:创建一个可缓存的线程池。创建的线程多于任务时,将空闲的回收,智能创建,大小不限制,取决于jvm。(导致过多的线程,导致oom)
newScheduledThreadPool:创建一个大小无限的线程池。(导致过多的线程,导致oom)
阿里线程池
ThreadPoolExecutor,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。解决上面四种线程池导致的问题,采用有界队列存储任务。
七大参数
(1)corePoolSize:线程池中常驻核心线程数
(2)maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值必须大于等于1
(3)keepAliveTime:多余的空闲线程存活时间。当前线程池数量超过corePoolSize时,当空闲时间到达keepAliveTime值时,多余空闲线程会被销毁直到只剩下corePoolSize个线程为止。
(4)unit:keepAliveTime的时间单位
(5)workQueue:任务队列,被提交但尚未执行的任务
(6)threadFactory:表示生成线程池中的工作线程的线程工厂,用于创建线程,一般为默认线程工厂即可
(7)handler:拒绝策略,表示当队列满了并且工作线程大于等于线程池的最大线程数(maximumPoolSize)时如何来拒绝来请求的Runnable的策略
拒绝策略
(1)AbortPolicy(默认) 直接抛出RejectedExecutionException异常阻止系统正常运行。
(2)CallerRunsPolicy “调用者运行”一种调节机制,该策略既不会丢弃任务,也不会抛出异常,而是将某些任务回退给调用者,从而降低新任务的流量。
(3)DiscardOldestPolicy 抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务。
(4)DiscardPolicy 直接丢弃任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种方案。
java内存
栈区:变量、方法的参数引用、对象引用
堆区:对象、成员变量
方法区:方法、常量池(存放常量)
jvm垃圾回收算法
1、标记-清除算法:标记无用的对象,进行回收。缺点:效率不高,无法清除垃圾碎片。
2、复制算法:分A、B内存,A内存中的对象用完复制到B内存上,将A清理。缺点:内存使用率低,只有一半。
3、标记-整理:标记无用对象,将存活的对象向一端移动,清除掉边界以外的内存。
4、分代算法:根据存活周期将内存划分,新生代和老年代,新生代采用复制算法,老年代采用整理算法。