简单了解单例模式
什么是单例模式对于一个类,只有一个实例化的对象,我们构建单例模式一般有两种:饿汉式和懒汉式
饿汉式
优点是无线程安全问题,类加载就创建对象
缺点是占内存
1234567class Singleton01{ private static Singleton01 instance = new Singleton01();//声明对象同时私有化 public static Singleton01 getInstance(){//向外声明访问该类对象的方法 return instance; }}
懒汉式
优点是延迟加载,创建后才占用内存
缺点是有线程安全问题,需要双重检查锁保证
1234567891011121314151617181920212223242526272829303132333435363738394041// 1.线程不安全 class Singleton02 { private static volatile Singleton02 instance = null;/ ...
AOP简单使用的时候的问题
问题主要出在测试类
目标类1234public interface Target { void fun();}
12345678@Componentpublic class TargetImpl implements Target{ @Override public void fun(){ System.out.println("执行方法"); }}
切面类12345678910111213141516171819@Component("DoAOP")@Aspect // 告知Spring容器当前DoAOP类是一个切面类public class DoAOP { @Pointcut("execution(* com.example.leetcode.aop..*(..))") public void pointcut(){ } @Before("pointcut ...
简单了解TCP
TCP是什么?由于应用层IP协议的不可靠传输,主要是无法保证数据报到达目的地以及包乱序的问题,在运输层实现了TCP协议,提供可靠的传输,对于TCP来说,在发送数据之前需要先建立连接,同时每个报文段的大小不能超过MSS,对于IP协议来说,MSS + IP头和TCP头的大小不能超过MTU(一般是1500字节)。
TCP和UDP的区别TCP和UDP都是运输层的协议,提供进程到进程的一个逻辑连接,两者的主要区别体现在:
连接:TCP是面向连接的,用一个四元组标记一个TCP连接,UDP则不用握手就可以传输,只需要一个二元组(目标IP,目标端口)标记一个UDP
字节流:TCP是基于字节流的,有粘包问题(所以要记录数据长度),而UDP是基于报文的
可靠:TCP是可靠传输(重传、网络控制、拥塞控制),而UDP的数据报可能丢失
头部长度:TCP的头部长度一般是20字节,而UDP的头部长度只有8字节
使用场景:TCP一般用于文件传输或者浏览器HTTP请求等,UDP主要用于视频通话或者DNS等
TCP的面向连接是什么如果传输层协议选择了TCP,那么在首次发送报文段之前需要通过三次握手先建立TCP连接。
...
简单了解volatile
什么是volatilevolatile是Java的一个关键字,用于修饰变量,保证变量的可见性以及有序性。
volatile的使用场景线程通信(可见性)1234567891011121314151617181920212223242526public class volatileTest { volatile boolean flag = true; @Test public void fun() throws InterruptedException { // 3s 后修改 flag = false interruptFun(); while (flag) { System.out.println("正在循环"); Thread.sleep(1000); } } private void interruptFun() { new Thread(() -> ...
LeetCode的LRU缓存实现
LRU是什么意思LRU是操作系统底层的一个页面置换算法,当空间不够需要换出最长时间没有使用的页面,在本题中的意思就是当到达容量上限的时候要换出最长时间没有被访问过的节点。
如何实现LRU的实现可以使用链表的方式,参照MySQL的实现,将热数据每次都放到链表头,删除链表尾的冷数据。
题目需要get()和put()方法都是O(1)的事件复杂度,但是链表遍历需要O(n)的时间复杂度,无法满足题目要求,可以想到数组下标索引或者HashMap辅助我们访问,本题如果用数组还需要多写一步hash()来确认key存放的位置,所以我们使用HashMap。
通过HashMap我们可以快速找到节点,也就满足了get()的O(1),但是对于put()的O(1),考虑到我们需要删除节点,单链表显然无法满足,因为单链表需要O(n)找到前驱节点,所以我们修改为双链表。
最终的结构就是HashMap + 双链表。
简单了解JMM
什么是JMM?对于不同的硬件和操作系统,有着自己的底层内存模型,可能导致Java程序在一些的平台可以正确并发,而在另一些平台出现并发错误,JMM是Java内存模型,是语言级别的内存模型,用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM主要考虑的就是各种变量的访问规则,正确实现线程间的通信以及线程间的同步,对于JMM,把各种硬件抽象为本地内存和主存来存放变量。
总的来说JMM把硬件和操作系统的差异屏蔽了,让Java在不同机器上都可以正确的访问数据从而实现并发。
为了提升速度,给线程加了本地内存,JMM用来处理线程本地内存和主存的一致性问题
内存间交互操作关于变量如何从主存拷贝到本地线程以及变量如何从本地线程同步到主存的细节,JMM定义了8中操作来完成,对于每个线程来说,只能操作本地内存的变量,规定read、load要顺序执行,store、write要顺序执行。
操作系统的三大问题在谈论JMM之前,首先我们需要了解操作系统的几个问题,JMM正是解决了操作系统这些问题。
随着时代的发展,计算机逐步更新换代,人们对于计算机的要求越来 ...
简单了解ReentrantReadWriteLock
什么是ReentrantReadWriteLock?ReentrantLock是Java的一个锁,用于协作多线程,对于读锁来说是一个共享锁,而写锁呢是一个独占锁,支持锁降级(占用写锁同时再获取读锁,但是占用读锁同时不能再获取写锁)
ReentrantReadWriteLock的使用场景读多于写的场景下保证并发安全同时提高效率
读写缓存123456789101112131415161718192021222324252627282930313233343536// 缓存对象,这里用jvm缓存Map<String, String> cache = new HashMap<>();// 读写锁ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); // 读取操作public String getData(String key) { // 加读锁,防止其他线程修改缓存 readWriteLock.readLock().lock(); try { Strin ...
简单了解ReentrantLock
什么是ReentrantLock?ReentrantLock是Java的一个锁,用于协作多线程,同时也是一个独占锁
ReentrantLock应用场景保证并发安全代替synchronized实现同步
线程通信如线程交替打印1~100
123456789101112131415161718192021222324252627282930313233343536public class JUCTest { private static volatile int count = 0; private static final int MAX = 100; private static final ReentrantLock lock = new ReentrantLock(); private static final Condition condition = lock.newCondition(); public static void main(String[] args) { Thread t1 = new Th ...
简单了解跨域问题如何解决
跨域问题是怎么产生的?跨域就是违反了浏览器规定的一个同源策略,同源策略是为了保证不同页面之间不能用到对方的一下信息(如cookie,DOM对象)保证安全,同源策略主要是三个方面相同,用一个URL来举例的话,http://www.baidu.com,就是当前页面和请求地址的协议相同、端口相同、域名相同,后面的路径无所谓。
那么浏览器如何知道这个请求跨域了,首先请求会到服务器,然后服务器会响应一个响应头Access-Control-Allow-Origin,浏览器就知道是否违反了同源策略,那么只需要浏览器收到的响应的响应头Access-Control-Allow-Origin没有跨域问题就行了。
那么只需要
浏览器发送一个不受同源策略限制的请求
不用浏览器发送请求,使用模拟代理服务器,每次浏览器都先请求本地的模拟代理服务器,就没有同源策略了
或者服务器返回响应头Access-Control-Allow-Origin是OK的(*)
使用反向代理的Nginx设置响应头
如何解决跨域问题前端Jsonp:可以把请求路径放在标签里面,src、link这些属性是不受同源策略限制的
后端通过CORS ...
简单了解CyclicBarrier
什么是CyclicBarrier?CyclicBarrier是Java的一个同步类,用于协作多线程,同时也是一个共享锁
CyclicBarrier的使用场景多线程一起开始异步线程之间互相等待
1234567891011121314151617181920212223242526272829public static void main(String[] args) throws IOException { CyclicBarrier cyclicBarrier = new CyclicBarrier(3); for (int i = 0; i < 6; i++) { new MyThread(cyclicBarrier).start(); } System.in.read();}static class MyThread extends Thread { CyclicBarrier cyclicBarrier; public MyThread(CyclicBarrier cycli ...