一.前言
好久没写博客了,因为疫情在家待了两三个月,回到工作的城市后按照之前的计划从上一家公司离职了。现在寻找新的工作,但是我深知自己的基础知识薄弱,上一家公司使用的技术已经落后了,现在主流的东西都只是处于了解阶段,没有实际经验很伤啊,所以现在查看下现在主流的技术、框架啥的,补充下基础知识,后续再挨个进行百度教程,自己上手弄个实际部署应用的经验。
以下是我个人收集的一些可能会问到的问题进行百度后的查询,整理出来结合自己的理解手打一遍,记忆深刻些。如果有什么理解上的问题或者有兴趣进行探讨的可以留言。
二.多线程和并发
2.1.多线程:指的是一个程序(即进程)运行时产生了不止一个线程
并行:多个CPU实例或多台机器同时执行一段同样的逻辑
并发:通过CPU的充分利用,让客户看上去同时执行,实际上并不是真正意义上的同时
线程安全 :通常指在并发的情况下,一段代码进行多线程使用,使用顺序不会影响结果
线程不安全:通常指在并发的情况下,一段代码进行多线程使用,使用顺序会影响结果
同步:指的是通过人为的控制和调度,保证多线程使用同一段代码,使用顺序不会影响结果
2.2.创建线程有三种方式:
2.2.1.继承Thread类,重写run方法。这个方式的好处就是不用创建一个线程,直接用this获取当前线程,弊端就是继承Thread后就不能继承其他类了
2.2.2.实现Runable接口,实现run方法。
2.2.3.实现Callable接口,实现call方法。
2.3.线程的6种状态:
1.new(刚刚创建,还未启动线程)2.runnable(正常运行中)3.blocked(多线程同步操作时,等待其他线程释放)4.waiting(线程调用了自己的wait方法)5.timed_waiting(有时间限制的waiting)6.terminated(执行完毕)
![在这里插入图片描述](https://img2020.cnblogs.com/blog/1880035/202004/1880035-20200414162212823-2033085009.png)
三.线程锁
3.1.同步锁(synchronized):实现多线程之间的同步,对同步的代码加锁,使这段代码同一时间只有允许一个线程访问,从而保证线程安全
3.2.重入锁(ReentrantLock):同步锁只有两个状态(拥有锁执行代码和等待拥有锁),重入锁可以在等待的时候调用unlock()方法进行中断,tryLock()方法可以设置等待时间并有返回值告知是否获取到锁
3.3.读写锁(ReadWriteLock):读写分离,读写锁允许多个线程同时读,但是不允许同时写或者同时读写
四.JVM
4.1.JVM的组成:类加载器子系统、运行时数据区、执行引擎、本地方法。其中运行时数据区分为方法区、堆、栈、本地方法栈、程序计数器
4.2.JVM的运行原理:JVM是Java的核心和基础,在Java编译器和硬件平台之间的虚拟处理器。虚拟机可以执行Java的字节码程序。Java编译器只需要面对Java,把Java源文件经过编译器,生成JVM能理解的字节码文件,然后通过JVM将文件程序翻译成指定的硬件平台机器码,这是Java能够跨平台的基本
4.3.![在这里插入图片描述](https://img-blog.csdnimg.cn/20200429181016728.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4NDk5NDg3,size_16,color_FFFFFF,t_70)
4.4.JVM的GC(垃圾回收机制)
4.4.1.如何判断内存中的对象是“死”是“活”:引用计数法(引用分4种,强引用、软引用、弱引用、虚引用)
4.4.2.垃圾回收算法:标记清除(不足:效率不高,会产生大量碎片)、复制算法(解决标记清除的不足,但是空间利用率低下)、标记整理算法、分代回收(把内存区分为新生代和老年代,新生代就是一些最新引用的部分,老年代就是一些大对象和长期存活的对象)
4.5.类加载类的生命周期(加载、连接、初始化、使用、卸载)。连接分为验证、准备、解析
4.6.内存泄漏:一般分为3种(堆内存泄漏、本地内存泄漏、加载类内存不足),大多数内存泄漏都是JVM堆内存泄漏。(鉴于本人经验不足,我没碰到过内存泄漏问题,百度的解决办法都是先分出JVM内存镜像,然后利用工具进行查看占用内存最多的对象,结合这个对象的使用地方分析内存泄漏原因)
五.NIO和IO
5.1.两者的区别:IO是面向流的阻塞IO,NIO是面向缓冲的非阻塞IO
5.2.IO面对流就意味着每次都是从流中读字节,直至读完,他在读完之前不能移动流中的数据。而NIO不同,NIO把字节读取到一个缓冲区,需要的时候可以在缓冲区中移动字节,但是这需要检查读取到缓冲区的数据是不是包含你需要处理的数据,而且还要确保更多的数据在读入缓冲区的时候不会覆盖之前的数据
5.3.IO是堵塞的,所以在一个线程读取读写完之前这个线程不能干其他事情,而NIO是把整个任务切换成许多小任务,由一个线程处理所有的IO事件,并负责分发。它是利用事件驱动机制而不是监听机制,事件到了再触发。NIO线程之前通过wait(等待)和notify(通知)等方式通讯
六.缓存
6.1.我之前用的都是几大作用域中的session。这种占用内存容易内存溢出,没有持久化(服务重启就没了),限于作用域,超出就没办法共享数据
6.2.Redis:Redis是我知道的用的比较多的缓存手段。Redis是一个开源免费的、最受BSD协议、高性能的key-value非关系型数据库
6.3.Redis的主从复制和哨兵机制
6.3.1.主从复制:Redis一般都是一主多从,主服务器可以用来写,从服务器可以用来读。一般流程大致分为:1、从服务器数据库启动时会向主服务器要一个快照文件(类似MySQL的那种可执行文件),主服务器是生成快照文件时把后续收到的命令缓存起来,快照文件生成后把文件和期间缓存的命令一起发给从服务器,从服务器收到后会执行文件并执行收到的缓存命令。
6.3.2.哨兵机制:哨兵用于管理多个Redis服务器,执行三个任务(监控:不断检查你的主从服务器是否运作正常、提醒:当监控的某个服务器出现问题是通知管理员、故障迁移:当一个主服务器不能工作时,哨兵会自动随机将一个从服务器升级为主服务器来替代之前不能工作的主服务器)
6.3.3.Redis的数据持久化:Redis支持AOF和RDB两种存储方式
6.3.3.1.RDB存储:在一个时间点,如果达到所配置的数据修改量,就写入一个临时文件,持久化结束后用临时文件替换上次持久化的文件。
6.3.3.2.AOF存储:以日志文件进行存储。其实就是把你的操作和数据追加到日志后面。这样日志文件包含所有的操作。但是这种方式的日志文件大,导致恢复数据的过程很长
6.4.Redis事务:事务是一个单独的隔离操作,所有的事务都会按顺序执行,并且在执行过程中不会被其他操作打断。事务是一个原子操作(要么全部执行成功,要么全部执行失败)
七.消息机制
7.1.我知道的消息中间件:RabbitMQ、ActiveMQ、阿里的MQ服务
7.2.消息两种模型:发布订阅主题(topic)、队列(queue)
7.3.消息都分为消费者和生产者。一般一条消息的过程包含:创建连接工厂,创建连接,创建会话,发布传输消息
八.数据结构
8.1.数据结构常用的有:数组、链表、二叉树、哈希表、红黑树
8.2.数组:数组是一种连续存储线性结构,元素类型相同,大小相等。数组存取数据快,插入删除很慢
8.3.链表:离散分配,彼此通过头尾指针相连。链表细分为3类(单向链表、双向链表、循环链表),链表插入删除数据快,存取数据慢
8.4.二叉树:一棵树至少会有一个节点(根节点),树由节点组成,每个节点的数据结构包括一个数据和两个分叉
8.5.哈希表:不在意元素顺序,能快速查找元素。哈希表为每个对象计算出一个整数,即为哈希码。这个整数保存在对应的位置上,就是索引
8.6.红黑树:红黑树就是一种平衡树,它保证二叉树基本符合均衡的金字塔结构。(1.节点是红色或黑色2.根节点必须是黑色3.每个叶节点(NULL节点、空节点)都是黑色4.每个红色节点的两个子节点都是黑色5.从任意节点到其每个叶子的所有路径包含相同数目的黑色节点)这个我是完全不懂
九.集合
9.1.List、Set、Map。其中List和Set都是继承至Collection接口,Map为独立接口
9.2.List(有序且元素可重复)分为ArrayList(底层是数组,查询快,增删慢,线程不安全,效率高)Vector(底层也是数组,查询快,增删慢,线程安全,效率低)、LinkedList(底层是链表,查询慢,增删快,线程不安全,效率高)
9.3.Set(无序且元素唯一)分为HashSet(底层是哈希表)、LinkedHashSet(底层是链表和哈希表)、TreeSet(底层是红黑树)
9.4.Map分为HashMap(无序,不同步)、HashTable(无序,同步)、TreeMap(有序)
十.分布式
10.1.分布式系统是由多个节点组成的系统,这些连通的节点上部署我们的节点,并且相互的操作会有协同。
10.2.使用分布式系统的特点:1.增大系统容量。2.加强系统可用。3.模块化,复用性更高。4.服务模块拆分,开发和发布速度可以并行而且变得更快。5.系统扩展性更高。6.有利于团队协作流程
10.3.分布式架构中存在的问题:通讯异常(网络异常)、网络分区(由于通信异常,出现两个主服务)、三态(由于网络异常在之前的服务器响应状态成功或失败上增加一种超时)、节点故障(某个节点出现宕机断电等)
10.4.分布式协调理论:CAP(C:一致性,保证数据一致性、A:可用性,系统收到请求后一定回复、P:分区容错性,多个服务某一个出现问题后的容错机制)。
10.5.BASE理论:上诉CAP中无法保证同时满足三个基本需求,诞生出的适当的方式:Basically Avaliable 基本可用(当分布式系统出现不可预见的故障时,允许损失部分可用性,保障系统的“基本可用”;体现在“时间上的损失”和“功能上的损失”)、Soft state 软状态(允许系统中的数据存在中间状态,既系统的不同节点的数据副本之间的数据同步过程存在延时,并认为这种延时不会影响系统可用性)、Eventually consistent 最终一致性(所有的数据在经过一段时间的数据同步后,最终能够达到一个一致的状态)
10.6.分布式的常用技术:加缓存(Redis)、负载均衡(nginx)、异步调用(消息中间件,异步事务)、数据分区(集群)
十一.mybatis框架原理
11.1.mybatis框架其本质就是映射,通过框架自带的映射方式将查询结果映射为Java对象
11.2.工作原理:mybatis通过配置文件来构建SQLSession工厂,然后工厂实例开启一个SQLsession,SQLsession的实例获取到对象并运行映射的SQL语句,最后关闭SQLsession
十二.spring框架原理
12.1.IOC容器(控制反转):IOC容器,依赖注入,自动生产对象而不是去new一个对象,实现了模块之间的解耦
12.2.AOP(面向切面编程):AOP的目的就是为了解耦,在很多不相干的模块中的某个切点之前之后进行相同的操作和代码。
十三.动态代理
13.1.这个代理一般就是为了给需要实现的方法前后添加一些操作,但是不干预正常业务,听起来跟上面AOP挺像的吧,实际AOP原理就是基于动态代理
13.2.基于JDK的动态代理。JDK代理是基于接口的动态代理,一般流程就是创建一个代理类,这个代理类实现了InvocationHandler接口,并重写invoke方法,重写方法中在具体业务方法前后增加自己需要的操作。最后利用Proxy类创建被代理后的类,调用类的方法,实现代理
13.3.基于CDLIB的动态代理。流程:创建一个类实现MethodInterceptor接口,拦截业务方法,并在业务方法前后加入操作。最后利用Enhancer来生产被代理类,调用业务方法。
十四.反射机制
14.1.反射机制是指在运行状态中,对于任意一个类,都能获取这个类的所有属性和方法;对于任意对象都能调用它的任意方法和属性,这种动态获取信息和动态调用方法的功能称之为Java的反射机制。
14.2.利用反射机制获取对象的私有属性和私有方法
十五.内省机制
15.1.Java内省机制就是Java对JavaBean类属性、事件的一种缺省处理方法
15.2.Java JDK中提供了一套API用来访问某个属性的getter/setter方法,这就是内省。