- 博客(96)
- 收藏
- 关注
原创 SSO单点登录原理
目录一、cookie及session二、普通的登录认证机制三、什么是SSO?四、SSO的优点五、不同场景下的单点登录5.1 同域的 SSO5.2 跨域的 SSOSSO的具体流程(以下步骤与图中的步骤一致)一、cookie及session在了解SSO之前,我们先了解以下知识:「cookie及session」具体看这篇介绍---- 「cookie 及 session 介绍 」二、普通的登录认证机制普通登录认证机制的过程:用户访问一个系统,这个系统需要登录,于是向后台服务器发送登录请求;数据库中根
2022-02-11 22:13:00 10045 9
原创 Spring中的循环依赖
目录一、什么是循环依赖?二、Bean的生命周期2.1 Spring Bean 的生命周期2.2 Bean 的生成步骤三、三级缓存3.1三个缓存分别有什么作用四、思路分析4.1 为什么 Spring 中还需要 singletonFactories 呢?五、Spring解决了哪种情况下的循环依赖5.1 ObjectFactory六、getEarlyBeanReference方法七、总结一、什么是循环依赖?例如,就是A对象依赖了B对象,B对象依赖了A对象。 // A依赖了B class A{ pub
2022-02-09 17:17:41 37309 31
原创 如何利用Redis实现一个分布式锁?
目录1、何时需要分布式锁?2、如何实现分布式锁?2.1 SETNX 命令2.2 优化过程2.2.1 出现的问题2.2.2 原因2.2.3 解决方案3、锁过期时间不好评估怎么办?3.1 Redisson3.1.1 小结4、基于RedLock算法的分布式锁4.1 Redlock 具体使用方式4.1.1 Redlock 为什么这么做?1、何时需要分布式锁?在分布式的环境下,当多个server并发修改同一个资源时,为了避免竞争就需要使用分布式锁。那为什么不能使用Java自带的锁呢?因为Java中的锁是面向多线程
2022-01-08 11:27:01 983
原创 如何保证Redis缓存与数据库的一致性?
这里写目录标题1、四种同步策略:2、更新缓存还是删除缓存2.1 更新缓存2.2 删除缓存3、先操作数据库还是缓存3.1 先删除缓存再更新数据库3.2 先更新数据库再删除缓存4、延时双删4.1 采用读写分离的架构怎么办?5、利用消息队列进行删除的补偿1、四种同步策略:想要保证缓存与数据库的双写一致,一共有4种方式,即4种同步策略:先更新缓存,再更新数据库;先更新数据库,再更新缓存;先删除缓存,再更新数据库;先更新数据库,再删除缓存。从这4种同步策略中,我们需要作出比较的是:更新缓存与删除缓
2022-01-07 13:41:03 28936 38
原创 OSI 7层模型讲解(大白话 通俗易懂)
文章目录>应用层>表示层>会话层>传输层>网络层>数据链路层>物理层>总结>应用层应用层是OSI参考模型的最高层,它是计算机用户,以及各种应用程序和网络之间的接口,是网络应用程序使用的,即使用互联网的计算机应用,例如谷歌,火狐。这些应用不驻留于应用层,但是它们使用应用层的各种网络协议,例如:HTTP协议,HTTPS协议。有几十个应用层协议,于各种功能在这一层,这些协议组成了各种网络服务的基础,例如域名解析协议DNS协议,文件传输是借助FTP协议完..
2021-02-20 12:58:10 37742 9
原创 ThreadLocal 核心原理
上述代码也说明,通过 ThreadLocal 为每个线程保存的本地变量不是存储在 ThreadLocal 实例中,而是存储在调用线程的 threadLocals 变量中,它的类型为 ThreadLocal 中的一个内部类 ThreadLocalMap,ThreadLocal 是一个壳子,真正的存储结构是 ThreadLocal 里有 ThreadLocalMap 这么个内部类,实现的类似 map 的功能。同时,删除 Thread-B 线程中的本地变量后,不会影响 Thread-A 线程中保存的本地变量。
2023-04-05 14:33:03 747 2
原创 ReentrantLock 核心原理
FairSync 类中的 lock 方法会调用 AQS 的 acquire 方法,AQS 的 acquire 方法又会调用 tryAcquire 方法,而 AQS 中的 tryAcquire 方法实际上是基于子类实现的,因此,此时调用的还是 FairSync 类的方法。不可中断锁指线程在抢占锁的过程中不能被中断。非公平锁的核心就是对抢占锁的所有线程都是不公平的,在多线程并发环境中,每个线程在抢占锁的过程中都会先直接尝试抢占锁,如果抢占锁成功,就继续执行程序的业务逻辑,如果抢占失败,就会进入等待队列中排队。
2023-04-01 21:25:19 828
原创 AQS 核心原理
一、AQS 核心数据结构AQS 内部主要维护了一个 FIFO(先进先出)的双向链表。AQS 内部维护的双向链表中的各个节点分别指向直接前驱节点和直接的后继节点。所以,在 AQS 内部维护的双向链表可以从其中任意一个节点遍历前驱节点和后继节点。链表中的每个节点其实都是对线程的封装,在并发场景下,如果某个线程竞争锁失败,就会被封装成一个 Node 节点加入 AQS 队列的末尾。当获取到锁的线程释放锁后,会从 AQS 队列中唤醒一个被阻塞的线程。同时,在 AQS 中维护一个使用 volatile 修饰的变量
2023-03-30 20:03:57 1454 1
原创 synchronized 核心原理
同时为了满足 JVM 中对象的起始地址必须是 8 的整数倍的要求,对象在 JVM 堆区中的存储结构还会有一部分对齐填充位。一个类的类元信息会存储在 JVM 的方法区中,对象头的类型指针会指向存储方法区中的类元信息。类元信息:类元信息在类编译期间放入方法区,里面放置了类的基本信息,包括类的版本、字段、方法、接口以及常量池表(Constant Pool Table)。
2023-03-25 13:04:36 1312
原创 Happens-Before 原则
在 JMM 中,定义了一套 Happens-Before 原则,用于保证程序在执行过程中的可见性和有序性。Happens-Before 原则主要包括程序次序原则、volatile 变量原则、传递原则、锁定原则、线程启动原则、线程总结原则、线程中断原则和对象终结原则。在JMM中, 如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系。
2023-03-21 18:55:16 922
原创 Java 内存模型
Java 内存模型规定了所有的变量都存储在主内存中,也就是存储在计算机的物理内存中,每个线程都有自己的工作内存,用于存贮线程私有的数据,线程对变量的所有操作都需要在工作内存中完成。对于线程工作内存与主内存之间的数据交互,JMM 定义了一套交互协议,规定了一个变量从主内存中复制到工作内存中,以及从工作内存同步到主存中的实现细节。Java 内存模型简称 JMM,是 Java 中为了解决可见性和有序性问题而制定的一种编程规范和规则,与 JVM 实实在在的内存结构不同,JMM 只是一种编程规范和规则。
2023-03-20 19:44:47 512
原创 volatile 核心原理
当一个线程修改了 volatile 修饰的共享变量之后,修改后的共享变量的值会立刻刷新到主内存,其他线程每次都从主内存中读取 volatile 修饰的共享变量,这就保证了使用 volatile 修饰的共享变量对线程的可见性。volatile 虽然能够保证数据的可见性和有序性,但是无法保证数据的原子性。volatile 在内存语义上有两个作用,一个作用是保证被 volatile 修饰的共享变量对每个线程都是可见的,当一个线程修改了被 volatile 修饰的共享变量之后,另一个线程能够立刻看到修改后的数据。
2023-03-20 10:01:03 362
原创 并发编程中的锁
如果数据被其他线程修改过,则当前线程会尝试再次读取数据,检测数据是否被其他线程修改过,如果再次检测的结果仍然为数据已经被其他线程修改过,则会再次尝试读取数据,如此反复,直到检测到的数据没有被其他线程修改过。最后,线程 3 被唤醒并获取锁,执行完任务释放锁。例如,存在三个线程,分别为线程 1 、线程 2 和线程 3 ,在线程 1 和线程 2 抢占锁的过程中,线程 1 获取到锁,线程 2 阻塞等待。例如,线程 A 在执行任务的过程中获取锁,在后续执行任务的过程中,如果遇到抢占同一个锁的情况,则也会再次获取锁。
2023-03-19 10:18:42 423
原创 Java岗面试题--Java并发(volatile 专题)
线程 A 首先得到了 i 的初始值100,但是还没来得及修改,就阻塞了,这时线程 B 开始了,它也得到了 i 的值,由于 i 的值未被修改,即使是被 volatile 修饰,主存的变量还没变化,那么线程 B 得到的值也是100,之后对其进行加 1 操作,得到101后,将新值写入到缓存中,再刷入主存中。一个变量 i 被 volatile 修饰,两个线程想对这个变量修改,都对其进行自增操作也就是 i++,i++ 的过程可以分为三步,首先获取 i 的值,其次对 i 的值进行加1,最后将得到的新值写会到缓存中。
2023-02-27 16:00:46 1225
原创 Java 基础回顾之泛型
如果在写接口的时候都没有定义泛型,它默认的就是 Object 类,其实这样写是不规范的。在上述的泛型接口中已经规定传入其中的必须是 A,B 类的对象,那么当我们传入其他类的对象时就会报错。使用泛型方式给 HashMap 中放入三个学生对象,并输出对象信息;
2023-02-26 18:40:12 613
原创 Java-重排序,happens-before 和 as-if-serial 语义
由于常见的处理器内存模型比 JMM 要弱,Java 编译器在生成字节码时,会在执行指令序列的适当位置插入内存屏障来限制处理器的重排序。同时,由于各种处理器内存模型的强弱不同,为了在不同的处理器平台向程序员展示一个一致的内存模型,JMM 在不同的处理器中需要插入的内存屏障的数量和种类也不同。对于处理器重排序,JMM 的处理器重排序规则会要求编译器在生成指令序列时,插入特定类型的内存屏障(Memory Barries / Memory Fence)指令,通过内存屏障指令来禁止特定类型的处理器重排序。
2023-02-26 09:58:00 536
转载 PO、VO、DAO、BO、DTO、POJO 能分清吗?
但是我们界面上只要显示 10 个字段,客户端用 WEB Service 来获取数据,没有必要把整个 PO 对象传递到客户端,这时我们就可以用只有这 10 个属性的 DTO 来传递结果到客户端,这样也不会暴露服务端表结构。当然,如果你有一个简单的运算属性也是可以的,但不允许有业务方法,也不能携带有 connection 之类的方法。各层操作属于该层自己的数据对象,这样就可以降低各层之间的耦合,便于以后系统的维护和扩展。但应是抽象出的业务对象,可以和表对应,也可以不,这根据业务的需要。
2023-02-25 13:41:18 163
原创 Java岗面试题--Java并发(日积月累,每日三题)
线程安全在三个方面体现:补充:关于「JMM」的文章请看这位大佬的博文->>>【Java线程】Java内存模型总结总结:JMM通过控制主内存与每个线程的本地内存之间的交互,来为 Java 程序员提供内存可见性保证。为了提高性能,编译器和处理器常常会对指令做重排序。重排序有 3 种类型,其中后 2 种都是处理器重排序。这些重排序可能会导致多线程程序出现内存可见性问题。单线程环境里面确保程序最终执行结果和代码顺序执行的结果一致。处理器在进行重排序时必须要考虑指令之间的数据依赖性。多线程环境中线程交替执行,由于编
2023-02-24 20:24:27 3354 2
原创 Java岗面试题--Java并发(日积月累,每日三题)
使用多线程的目的是为了充分利用 CPU,但是我们知道,并发其实是一个 CPU 来处理多个线程。为了让用户感觉多个线程是在同时执行的, CPU 资源的分配采用了时间片轮转也就是给每个线程分配一个时间片,线程在时间片内占用 CPU 执行任务。当线程使用完时间片后,就会处于就绪状态并让出 CPU 让其他线程占用,这就是上下文切换。多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。互斥条件;请求与保持条件;不剥夺条件;循环等待条件。
2023-02-21 20:46:43 2239
原创 Java岗面试题--Java并发(日积月累,每日三题)
sleep(long millis) : Thread 类中的静态方法,当一个执行中的线程 A 调用了 Thread 的 sleep 方法后,线程 A 会暂时让出指定时间的执行权,但是线程 A 所拥有的监视器资源,比如锁还是持有不让出的。:这个方法相比 wait() 方法多了一个超时参数,它的不同之处在于,如果线程 A 调用共享对象的 wait(long timeout) 方法后,没有在指定的 timeout ms时间内被其它线程唤醒,那么这个方法还是会因为超时而返回。
2023-02-20 18:52:01 3400 8
原创 Java岗面试题--Java并发(日积月累,每日三题)
原理:在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给 Future 对象在后台完成,当主线程将来需要时,就可以通过 Future 对象获得后台作业的计算结果或者执行状态。守护线程(即 Daemon thread),是个服务线程,用来服务于用户线程,准确地来说就是服务其他的线程。需要注意的是,Java 本身并不能创造线程,因为线程其实是操作系统的一种资源,它由操作系统管理。线程:是进程的⼀个实体,是 cpu 调度和分派的基本单位,是比程序更小的能独立运行的基本单位。
2023-02-18 20:08:25 3651 2
原创 Java岗面试题--Java基础(日积月累,每日三题)
为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀。Hash 值的范围值 -2147483648 到 2147483647,前后加起来⼤概40亿的映射空间,只要哈希函数映射得比较均匀松散,⼀般应用是很难出现碰撞的。但问题是⼀个40亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是(n代表数组长度)。这也就解释了 HashMap 的长度为什么是2的幂次方。
2023-02-12 17:59:10 3652 1
原创 Java岗面试题--Java基础(日积月累,每日三题)
因为字符串是不可变的,所以在它创建的时候 hashcode 就被缓存了,不需要重新计算。假设一种情况,线程 A 进入后还未进行数据插入时挂起,而线程 B 正常执行,从而正常插入数据,然后线程 A 获取 CPU 时间片,此时线程 A 不用再进行 hash 判断了,问题出现:线程 A 会把线程 B 插入的数据给覆盖,发生线程不安全。HashMap 不是线程安全的,在多线程环境下,HashMap 有可能会有数据丢失和获取不了最新数据的问题,比如说:线程A put 进去了,线程B get 不出来。
2023-02-10 19:29:11 3301 2
原创 Java岗面试题--Java基础(日积月累,每日三题)
java.util 包下的集合类大部分都是线程不安全的,例如我们常用的「HashSet、TreeSet、ArrayList、LinkedList、ArrayDeque、HashMap、TreeMap」这些都是线程不安全的集合类,但是它们的优点是性能好。是可以的,但是不推荐。HashMap 的大小只能是「2次幂」的,假设你传一个 10 进去,实际上最终 HashMap 的大小是 16,你传一个 7 进去,HashMap 最终的大小是 8 ,具体的实现在「tableSizeFor」可以看到。
2023-02-09 20:40:39 1456 1
原创 Java岗面试题--Java基础(日积月累,每日三题)
补充: 深克隆的实现就是在引用类型所在的类实现 Cloneable 接口,并使用 public 访问修饰符重写 clone 方法。Java 中定义的 clone 没有深浅之分,都是统⼀的调用 Object 的 clone 方法。不⼀样,因为内存的分配方式不一样。直接看这位大佬的文章—>
2023-02-08 18:49:07 4407 3
原创 Java岗面试题--Java基础(日积月累,每日三题)
Throwable」是异常的顶层父类,代表所有的非正常情况。它有两个直接子类,分别是「Error」「Exception」。Error 是错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不应该试图使用 catch 块来捕获Error 对象。在定义方法时,也无须在其 throws 子句中声明该方法可能抛出 Error 及其任何子类。
2023-02-07 19:11:58 5929 5
原创 Java岗面试题--Java基础(日积月累,每日三题)
对象序列化是⼀个用于将对象状态转换为字节流的过程,可以将其保存到磁盘文件中或通过网络发送到任何其他程序。从字节流创建对象的相反的过程称为反序列化。而创建的字节流是与平台无关的,在⼀个平台上序列化的对象可以在不同的平台上反序列化。序列化是为了解决在对象流进行读写操作时所引发的问题。
2023-02-06 18:45:56 3142
原创 Java岗面试题--Java基础(日积月累,每日三题)
从上面的代码中可以看出:Java 对于 [-128, 127] 之间的数会进行缓存,比如:Integer i = 127,会将 127 进行缓存,下次再写 Integer j = 127 的时候,就会直接从缓存中取出,而对于这个区间之外的数就需要 new 了。比如,某个方法的参数类型为包装类型,调用时我们所持有的数据却是基本类型的值,则可以不做任何特殊的处理,直接将这个基本类型的值传入给方法即可。原始类型:boolean、char、byte、short、int、long、float、double。
2023-02-05 17:09:28 4347 1
原创 Java岗面试题--Java基础(日积月累,每日三题)
Java 程序在执行子类的构造方法之前,如果没有用 super() 来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super() 来调用父类中特定的构造方法,则编译时将发生错误,因为Java 程序在父类中找不到没有参数的构造方法可供执行。解决办法是:在父类里加上⼀个不做事且没有参数的构造方法。
2023-02-04 20:39:56 680
原创 Java岗面试题--Java基础(日积月累,每日三题)
面向对象是⼀种基于面向过程的编程思想,是向现实世界模型的自然延伸,这是⼀种“万物皆对象”的编程思想。由执行者变为指挥者,在现实生活中的任何物体都可以归为⼀类事物,而每⼀个个体都是⼀类事物的实例。面向对象的编程是以对象为中心,以消息为驱动。面向过程更注重事情的每一个步骤及顺序;面向对象更注重事情有哪些参与者(对象)、及各自需要什么;举个栗子 :比如洗衣机洗衣服。面向过程:会将任务拆解成一系列的步骤:打开洗衣机----->放衣服----->放洗衣粉----->清洗----->烘干;面向对象。
2023-02-04 09:10:40 721
原创 Java岗面试题--Java基础(日积月累,每日三题)
如果没有对 equals 方法进行重写,则比较的是引用类型的变量所指向的对象的地址(很多类重写了 equals ⽅法,比如 String、Integer 等把它变成了值比较,所以⼀般情况下 equals 比较的是值是否相等)。Java 中也不可以覆盖 private 的方法,因为 private 修饰的变量和方法只能在当前类中使用, 如果是其他的类继承当前类是不能访问到 private 变量或方法的,当然也不能覆盖。extends T>表示类型的上界为T,即参数化的类型可能是T也可能是T的子类。
2023-02-01 19:55:42 4442 2
原创 Java岗面试题--Java基础(日积月累,每日三题)
在 Java 的一些集合类的实现中,在比较两个对象是否相等时,会根据上面的原则,会先调用对象的 hashCode() 方法得到 hashCode 进行比较,如果 hashCode 不相同,就可以直接认为这两个对象不相同,如果 hashCode 相同,那么就会进一步调用 equals() 方法进行比较。所以我们就需要注意,如果我们重写了 equals() 方法,那么就要注意 hashCode() 方法,一定要保证能遵守上述规则。HashCode 介绍:hashCode() 的作用是获取哈希码,也称为散列码;
2023-01-31 20:02:15 2267
原创 Spring 事件监听机制
假设现在有这么一个业务场景:用户在某购物软件下单成功后,平台要发送短信通知用户下单成功。这样做没什么不妥,但是随着时间推移,上面的代码就会暴露出局限性:嗯,nice。又过了一段时间,老板被抓了,股价暴跌,于是老板决定卖掉自己的车队,所以下单后就不用通知车队了。又过了一段时间,老板荣耀归来,东山再起,又把车队重现组建了起来。车队回来了,你却受不了这大起大落异常刺激的生活,决定离职。就在这时候,组长拉住了你,语重心长地和你说:小伙子,知道什么叫 “以增量的方式应对变化的需求” 吗?
2022-10-03 14:35:01 1146
原创 超详细:Java 读取 Windows 共享文件夹中的文件,并下载到本地电脑中
JCIFS 是使用纯 Java 开发的一个开源框架,通过 smb 协议访问远程文件夹。该框架同时支持 Windows 共享文件夹和 Linux 共享文件夹,不过,Linux 共享文件夹需要安装 Samba 服务软件。(官网:http://www.samba.org/)。
2022-10-01 18:16:45 7646 8
原创 SpringBoot 整合 WebSocket 实现长连接,将数据库中的数据进行推送
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 通信协议于2011年被 IETF 定为标准 RFC 6455,并由 RFC7936 补充规范。WebSocket API 也被W3C定为标准。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。HTTP 协议采用的是客户端(浏览器)轮询的方式,即客户端
2022-10-01 11:09:36 4906
原创 Mybatis 框架下易产生 SQL 注入漏洞的三种情况
这种场景应当在 Java 层面做映射,设置一个字段/表名数组,仅允许用户传入索引值。这样保证传入的字段或者表名都在白名单里面。需要注意的是在 mybatis-generator 自动生成的 SQL 语句中,order by 使用的也是 $,而 like 和 in 没有问题。这样如果 Java 代码层面没有对用户输入的内容做处理势必会产生 SQL 注入漏洞。在这种情况下使用「#」 程序会报错,新手程序员就把「#」 号改成了「$」
2022-09-27 18:54:39 1315
原创 程序员要搞明白CDN,这篇应该够了
那么如果百度要在全国各地都部署服务器,如果说每个服务器上都有相同的动态资源,那么可能还需要配置相应的数据库,因为动态资源所记录的信息通常会存储在数据库中,那么这就涉及到了数据同步等等问题,这会导致成本很高,这种做法专业一点其实就是。对“cdn.ali.com”进行解析,然后依据服务器上记录的所有CDN服务器地址信息,选出一个离用户最近的一个CDN服务器地址,并返回给用户,用户即可访问离自己最近的一台CDN服务器了。好,那么现在的问题是,用户在访问静态资源时也是通过域名来访问的,域名会被解析成。
2022-08-24 11:23:58 1647
空空如也
sqlserver 当前数据的开始时间减上一条数据的结束时间
2022-10-12
TA创建的收藏夹 TA关注的收藏夹
TA关注的人