springboot访问本地资源
SpringBoot映射本地图片,外界可通过网络路径发送 HTTP 请求访问该图片。 在工作中,我们会把图片保存到服务器本地的某个目录下,然后前端 image 标签的 src 属性,填写网络路径即可访问到该图片,这该如何配置呢?有两种方法: 第一种方法,我们可以修改 application.yml 文件 12345678spring: web: resources: # 支持本地图片上传之后的链接,其中 file:///d的用于win系统,后面的file: 适用于mac/linux系统 static-locations: - classpath:/static/ - file:///d:/tmp/storage/ - file:/tmp/storage/ 这个方法有个弊端,在某些场景下,可能会无效,比如你的项目中写了某些过滤器等原因。另外,使用yml配置,也会使你静态访问路径失效 第二种方法,添加 webConfig 配置类...
线程池
线程池的核心思想就是实现线程的复用,避免线程反复创建和销毁带来的性能开销。这里主要介绍了基本的 ThreadPoolExecutor 以及用于定时循环任务的 ScheduledThreadPoolExecutor ,而且线程池是面试的重点。 ThreadPoolExecutor线程池的核心思想就是实现线程的复用,避免线程反复创建和销毁带来的性能开销。 Java 通过 ThreadPoolExecutor 来创建线程池,其核心参数如下: 线程池 execute 工作 1public void execute(Runnable command){} 线程在线程池内部被封装成内部类 Worker 创建的对象。 在线程池的 execute 方法中是通过 addWorker 方法来创建线程并执行任务的,Worker 会将线程和任务一同封装到 Worker 对象中,在通过 runWorker 方法来执行任务。 在 runWorker 方法内部,通过 while 循环保证执行完任务的线程不被销毁,而是复用不断地 getTask...
通知等待Condition
ConditonObject 是 Condition 接口的实现类,用来做线程同步的通知等待,最重要的是它维护了一个单向的等待队列,要明确它和 AQS 队列的关系。此外还介绍了 LockSupport 类,Condition 的 await 底层就是通过 LockSupport 实现的。 等待通知 ConditionCondition 的等待队列是一个不带头节点的链式队列,而 AQS 的同步队列是带头节点的。 多个 Condition 对象的多个等待队列有什么用? 同步队列和等待队列的关系: 调用 Condition 的 await 方法,会使当前持有锁的线程进入同步队列,并释放锁,线程进入等待状态。相当于将同步队列的头节点(占用线程)移动到等待队列的尾部。 调用 Condition 的 signal 方法,唤醒该线程,相当于将等待队列的头节点移动到同步队列的尾部。 Condition 是个接口,它的实现类是 ConditionObject,是 AQS 的子类。 Condition 的 await 方法当前线程调用 Condtion.await()...
可重入锁 ReentrantLock、ReentrantReadWriteLock
可重入锁支持重入性,表示能够对共享资源重复加锁,即当前线程获取该锁后再次获取不会被阻塞,主要介绍了 ReentrantLock、ReentrantReadWriteLock 两种。 ReentrantLock支持重入性,表示能够对共享资源重复加锁,即当前线程获取该锁后再次获取不会被阻塞。 ReentrantLock 是通过抽象队列同步器 AQS 在 API 程序级别实现的,其内部类 Sync 继承了 AQS 抽象类,是 Lock 接口的默认实现。 源码 在线程获取锁的时候,如果已经获取锁的线程是当前线程的话则直接再次获取成功; 12345678910111213141516171819202122// 以内部类 Sync 的 nonfairTryAcquire 方法为例final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); // 1....
volatile和synchronized关键字
之所以把 volatile 和 synchronized 放在一起是因为二者都是关键字,而 synchronized 相比 volatile 除了提供内存可见性外还提供了锁的作用,也就是在同一时刻只允许一个线程访问共享资源,保证了线程安全性。 volatile关键字当使用 volatile 关键字修饰一个变量,Java 内存模型会插入一个内存屏障,确保执行到 volatile 变量的时候前面的语句全都执行完,后面的语句全都没有执行, 且前面的语句对 volatile 变量及后面的语句是可见的。 volatile 可以保证可见性,但不保证原子性: 当写一个 volatile 变量时,JMM 会把该线程在本地内存中的变量强制刷新到主内存中去; 这个写操作会导致其他线程中的 volatile 变量缓存无效(修改对其他线程立即可见)。 保证可见性: 1234567891011121314class ReorderExample { int a = 0; boolean volatile flag = false; public void writer()...
Java内存模型(JMM)
Java 内存模型(Java Memory Model,JMM)是个抽象的概念,负责 Java 并发中每个线程工作内存和共享主存之间的交互。JMM 很重要,也是后端程序员面试的重点。 Java 内存模型(Java Memory Model,JMM)是个抽象的概念,负责 Java 并发中每个线程工作内存和共享主存之间的交互。 JMM 定义了线程与主存之间的抽象关系: 线程间通信必须经过主存:① 线程 A 将本地内存 A 中更新过的共享变量刷新到主存中;② 线程 B 到主存中去读取线程 A 之前更新过的共享变量。 说到 JMM 正好复习一下跟它很像的 Java 运行时内存区域 Java 运行时内存区域描述的是在 JVM 运行时,如何具体地将内存划分为不同的区域: JMM 意在解决 Java 多线程并发编程中主内存和工作内存之间如何安全执行操作的问题: JMM 的指令重排 计算机在执行程序时为了性能,编译器和处理器往往会对指令进行重排序: 12a = b + c;d = e - f ; 加载完 b 和 c,可以一起把 e 和 f 都加载了,这样再去执行两个 add...
MIT6.5830-Lab6
MIT6.5830 的数据库课程。Lab6 主要是完成数据库的 STEAL / NO FORCE 策略,也就是基于 undo log 的日志回滚和基于 redo log 的崩溃恢复。 Undo log是什么 每当InnoDB引擎要对一条记录进行修改、删除、新增时,要把回滚时需要的信息都记录到undo log里,比如: 在插入一条记录时,要把这条记录的主键记录下来,方便回滚时根据主键将对应的记录删除; 在删除一条记录时,要把这条记录的所有内容都记录下来,方便回滚时把这些内容组成的记录插入回去; 在更新一条记录时,要把更新列的旧值记录下来,方便回滚时把该记录的旧值复原回去。 Redo log是什么 为什么要有Redo...
MIT6.5830-Lab5
MIT6.5830 的数据库课程。Lab5 主要是完成 InnoDB 的索引,完成 B+ 树的查询、插入、删除操作。 索引InnoDB存储数据InnoDB是以数据页(默认16KB)为单位进行I/O读写的。 多个数据页之间是以双向链表结构连接(逻辑上的连续)的,数据页中的指针存在于File Header文件头。 数据页中的数据检索数据页的作用是存储数据,重点就是User Records用户记录部分:数据页中的记录按照主键顺序组成单向链表。单向链表的特点是插入和删除非常方便,但是检索效率低——因此数据页中需要有一个页目录,起到快捷索引的功能。 上图要注意的细节: 每个分组最后一条记录的头信息中会存储该组一共有多少条记录,作为 n_owned...
MIT6.5830-Lab4
MIT6.5830 的数据库课程。Lab4 主要是完成数据库事务以及锁机制,在 Lab 中只是考虑设计了 page 级别锁。 Exercise1 Exercise2 Exercise3 Exercise4 Exercise5 为了简化工作,Lab4采用了NO STEAL/FORCE缓冲区策略,不需要记录undo log和redo log日志(Lab6中完成): NO STEAL:不允许一个未提交的事务将修改更新到磁盘,即磁盘中不会存在uncommitted数据,因此无需回滚操作,不需记录undo log。 FORCE:事务在提交之后必须将所有更新立刻持久化到磁盘(产生很多随机写,效率低),但无需记录redo log。 背景知识事务事务:事务是一组以原子方式执行的数据库操作(读取、插入、删除),是不可分割的。 事务的四大特性(ACID) 原子性(Atomicity):事务是一个不可分割的单位。 一致性(Consistency):事务执行是从一个一致状态到另一个一致状态,一致指的是:①...
MIT6.5830-Lab3
MIT6.5830 的数据库课程。Lab3 主要是完成数据库查询优化的成本优化器。 Exercise1 Exercise2 Exercise3 ...