CPU调度算法
先进先出算法(FIFO):根据进程就绪的先后顺序来使用CPU;
短进程优先算法(SCBF):先给每个进程都设置一个优先级,根据比较优先级来确定下一个执行的进程;将一些相对较短的进程优先级适当提高。
时间片轮转调度算法(RR):给每个进程分配一个时间片,运行完毕后切换进程;
虚拟轮转法(Virtual RR):基于时间片轮转算法的改进,时间片走完的进程会进入辅助队列。
优先级算法(PSA):给每个进程一个优先级,优先级越高的事件越紧急,应该先执行。
线程和进程的区别
(1)进程是资源分配的最小单位,线程是程序执行的最小单位
(2)进程有自己的独立地址空间,每启动一个进程,系统就会自动为它分配地址空间,建立数据库表来维护代码段、堆栈段和数据段;线程是共享进程中的数据,使用相同的地址空间,因此CPU切换一个线程花费要更小,同时创建线程的花费也更小。
(3)线程之间通信更方便,同一进程下的线程共享全局变量、静态变量等数据;而进程之间的通信是以通信的方式进行。多线程要解决同步和互斥问题;
(4)多进程程序更加健壮,多线程程序只要一个线程死掉,整个进程就会死掉;而一个进程死掉并不会对另一个进程造成影响。
线程的几种状态
- 新建(new):创建新线程、
- 就绪(runnable):调用线程start方法、
- 运行(running):获取cpu时间片,执行程序代码、
- 阻塞(block):等待阻塞,同步阻塞(synchronized),其他阻塞(sleep(),join())、
- 死亡(dead):结束线程,或是异常退出,
- 其实通过thread类可以知道到其实还有一种状态是terminal(中止);
线程首先被new创建,进入初始状态,然后线程调用start方法,进入就绪状态。这里要注意,线程只要抢占了cpu时间片,可以不用获取全部的锁就可以运行,但是当运行到需要的锁没有获得时,会进入阻塞状态。
当一个线程被sleep后,线程会先进入超时等待状态,当时间结束后,会先进入等待阻塞状态,当有锁以后再进入就绪状态。
线程池的实现方式
1、newCachedThreadPool类,创建一个线程池,如果线程池中的线程数量过大,它可以有效的回收多余的线程,如果线程不足,那么它可以创建新的线程。
2、newFixedThreadPool,这种方式可以指定线程池中的线程数。数满之后需要排队等候。
3、newScheduledThreadPool,该线程池支持定时,以及周期性的任务执行,我们可以延迟任务的执行时间,也可以设置一个周期性的时间让任务重复执行。
4、newSingleThreadExecutor,这是一个单线程,至始至终都由一个线程来执行。
5、ThreadPoolTaskExecutor,这是spring包下的,是spring为我们提供的线程池类。
线程池的拒绝策略
1、ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
2、ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。
3、ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
4、ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
线程的创建方式
三种方式:①继承thread类,②实现Runnable()接口,都是重写Run方法;③通过Callable和Future创建线程,实现call方法。
一般使用继承Thread类的方式创建线程,重写Run()方法。
线程池的七大参数
corePollSize:核心线程数;
maximumPoolSize:最大线程数;
keepAliveTime:空闲线程存活时间;
TimeUnit: 时间单位;
BlockingQueue: 线程池任务队列;
ThreadFactory: 创建线程工厂;
RejectedExecutionHandler: 拒绝策略
线程池的工作流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RffD1BDj-1662292499415)(en-resource://database/1089:1)]
sleep和wait的区别
都是用来进行线程控制,他们最大本质的区别是:sleep不释放同步锁,使用时间自动唤醒,可以用interrupt()来强行打断;wait释放同步锁,可以直接用notify()直接唤醒;sleep是thread类的静态方法。1,这两个方法来自不同的类分别是Thread和Object 2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。3,wait,notify和notify All只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。
IOC和AOP的理解
IOC,即控制反转,把对象的创建、初始化、销毁交给Spring来管理
AOP,面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。通俗的说就是不用修改源代码,在主干功能里面添加新功能。
基于接口的实现,基于Aspectj实现
单例模式怎么保证线程安全,volatile是防止指令重排
①加锁;②静态对象在类加载中被初始化了,loadClass对象加了锁
spring和springboot的区别
(1)spring boot提供极其快速和简化的操作,让Spring开发者快速上手
(2)spring boot提供了spring运行的默认配置
(3)spring boot为通用spring项目提供了很多的非功能性特性
mybatis的取参方式,传参方式
有两种取参方式:KaTeX parse error: Expected 'EOF', got '#' at position 4: {}和#̲{};{}本质是字符串拼接,若为字符串或者日期类型的话需要使用单引号;#{}本质是占位符赋值,若为字符串类型或者日期类型时,可以自动添加单引号。
传参:①顺序传递,②@Param传递参数,③map集合传递参数,④JavaBean的实体类传递,⑤集合类型参数List传递。
bean的注入方式
1)Autowired注入方式、(2)构造方法注入、(3)@Bean方法形参注入、(4)直接在@Bean方法上使用@ConfigurationProperties(prefix=“jdbc”)
springMVC的执行流程
1)用户向服务器发送请求,请求被springmvc前端控制器dispatcherSevlet捕获
2)DispatcherServlet对请求URL进行解析,得到请求资源标识符,判断请求URL对应的映射。
3)根据该URL,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain执行链对象的形式返回。
4)DispatcherServlet根据获得的handler,选择一个的handlerAdapter。
5)如果成功获得HandlerAdapter,此时将开始执行拦截器的preHandler()方法
6)提取request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作。
7)Handler执行完成后,向DispatcherServlet返回一个ModelAndView对象
8)此时将开始执行拦截器的postHandler()方法
9)根据返回的ModelAndView选择合适的ViewResolver进行试图解析,根据Model和View,来渲染视图。
10)渲染视图完毕执行拦截器的afterCompletion()方法。
11)将渲染结果返回给客户端。
序列化和反射是什么,序列化接口实现
反射指的是程序运行时透过反射API可以取得任何一个类的内部信息,包括修饰符、变量类型,返回类型,字段、方法等,并可以在运行时改变字段和唤醒方法。
序列化就是用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。为了解决在对对象进行读写操作时所引发的问题。
序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需 要实现的方法,implements Serializable 只是为了标注该对象是可被序列化的, 然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对 象流)对象,接着,使用 ObjectOutputStream 对象的 writeObject(Object obj)方 法就可以将参数为 obj 的对象写出(即保存其状态),要恢复的话则用输入流。
三大特性封装、继承、多态
1)封装是指把一个对象的状态(属性)隐藏在对象内部,不允许外部对象直接访问对象的内部信息。但是可以提供一些可以被外部访问的方法来操作属性。
2)继承拓展已存在的代码模块,目的是为了代码复用。
3)多态:对象的编译时类型和运行时类型不一致,具体表现为父类的引用指向子类的实例。JAVA引用变量有两个类型(编译时类型和运行时类型)。其中,编译时类型由声明该变量时使用的类型(父类)决定,运行时类型由实际赋给该变量的对象决定(子类)。
list、set、map
线性表、集合(不能重复),map是k-v类型
接口和抽象类
(1)抽象类要被子类继承,接口类要被类实现
(2)接口只能做方法声明,抽象类可以做方法实现
(3)接口里定义的变量只能是公共的静态常量,抽象类中的变量是普通变量
(4)接口是设计的结果,抽象类是重构的结果
(5)抽象类和接口都是用来抽象具体对象,接口的抽象级别最高
(6)抽象类可以有具体的方法和属性,接口只能抽象方法和不可变常量
(7)抽象类主要用来抽象类别,接口主要用来抽象功能
jdk1.7和1.8的改变
Default关键字,接口中使用它定义方法体,实现类可以直接调用。
Lambda表达式,函数式编程,抽象程度很高的编程范式,纯粹的函数式编程语言编写函数没有变量。
函数式接口,局部变量限制。
数组和列表的区别
(1)类型不同,数组列表和数组非常类似,不过数组列表的容量可以动态的变化,所以数组列表也是集合类型中使用频率较高的类型。Array和ArrayList
(2)元素不同,Array数组可以包含基本类型和对象类型,而列表ArrayList只能包含对象类型。但是数据存储的元素都是同一个类型,而数组列表不一样,可以存储Object对象。