- 博客(157)
- 收藏
- 关注
原创 MyBatis学习总结
我们整理一下这个类切换数据源的运作方式,这个类在连接数据库之前会执行determineCurrentLookupKey()方法,这个方法返回的数据将作为key去targetDataSources中查找相应的值,如果查找到相对应的DataSource,那么就使用此DataSource获取数据库连接它是一个abstract类,所以我们使用的话,推荐的方式是创建一个类来继承它并且实现它的determineCurrentLookupKey() 方法,这个方法介绍上面也进行了说明,就是通过这个方法进行数据源的切换。
2024-02-20 21:56:43 947
原创 Java实现线程安全的几种方式:常量/数据私有/互斥同步/非阻塞同步
java提供锁机制控制多线程对共享资源的访问,只允许获取锁的线程执行。先进行操作,如果没有其它线程争用共享数据,那操作就成功。数据声明成常量,使数据无法被修改,则一定线程安全。将数据变成线程私有的数据。
2024-02-05 20:35:19 436
原创 redis的缓存击穿和缓存雪崩和缓存穿透问题解决方法
缓存的key大量集中同时过期了或者缓存服务器挂掉,所有的请求全部冲到持久层数据库上,导致持久层数据库挂掉,导致整个应用都不可用。热点的key,在不停的扛着大并发,当这个key失效时,一瞬间大量的请求冲到持久层的数据库中,就像在一堵墙上某个点凿开了一个洞!1.数据预热:数据加热的含义就是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。3.布隆过滤器:实现黑名单或者白名单,黑名单:数据库不存在的数据放到过滤器,白名单:数据库存在的数据放到过滤器。
2024-02-04 22:01:08 539
原创 HashMap学习和线程安全的HashMap
索引的计算方式(n - 1) & hash,当扩容后,容量是之前的两倍,新的n-1比老的n-1的最高位多了一个1,因此计算新的索引位置时,只取决于高位多出来的这一位,而这一位的值刚好等于oldCap( 两者相减,值是oldCap,2的N次方)。计算索引位置的公式为:(n - 1) & hash,当n的值是2的N次方,n - 1 为低位全是 1 ,此时任何值跟 n - 1 进行 & 运算的结果为该值的低 N 位,达到了和取模同样的效果,实现了均匀分布。防止节点数在8附近,导致频繁的转换,影响性能。
2024-01-17 21:49:08 476
原创 cookie和session的工作过程和作用:弥补http无状态的不足
cookie是客户端浏览器保存服务端数据的一种机制。当通过浏览器去访问服务端时,服务端可以把状态数据以key-value的形式写入到cookie中,存储到浏览器。session表示一个会话,是一个容器对象,是服务端的保存客户端数据的一种机制。因为http是无状态的通信协议,服务器端无法知道客户端发送过来的多次http请求是不是属于同一个用户,session用来弥补http无状态的一个不足。因此,基于客户端的cookie和服务端的session机制实现有状态的http协议。
2024-01-16 21:34:20 617
原创 用Guava做本地缓存示例
通过CacheBuilder类构建一个缓存对象,CacheBuilder类采用builder设计模式,它的每个方法都返回CacheBuilder本身,直到build方法被调用。本地缓存为了保证线程安全问题,一般使用ConcurrentMap的方式保存在内存之中,而常见的分布式缓存则有Redis,MongoDB等。本地缓存适用于数据量较小或变动较少的数据,因为变动多需要考虑到不同实例的缓存一致性问题,而数据量大则需要考虑缓存回收策略及GC相关的问题。softValues():使用软引用存储值。
2023-12-10 08:51:57 329
原创 SpringBoot面试题:(一)SpringBoot自动装配原理源码解析
这样,springboot框架就可以读入到所有的配置类信息,在执行run方法时,解析上面的注解,将AutoConfigurationImportSelector加载进方法区,通过反射创建对象,调用其某一个方法,从缓存读取前面存储的k-v,并经过一系列的过滤、去重等,最后将需要的配置类加载,生成BD对象,创建Bean对象,放入spring容器。自动装配:自动装配就是把别人(官方)写好的config配置类加载到spring容器,然后根据这个配置类生成一些项目需要的bean对象。可以看到主要是三个注解构成。
2023-12-05 20:51:22 116
原创 Spring面试题:(八)Spring事务
Spring事务基于数据库,基于数据库的事务封装了统一的接口。编程式事务和声明式事务。声明式事务分为Xml声明式或者注解声明式。
2023-11-18 15:32:51 78
原创 Spring面试题:(七)Spring AOP思想及实现
在spring框架提供的bean扩展点的bean后置处理器中的后置方法和aware接口,获取容器对象获取增强对象,对bean进行动态代理,在bean目标前后执行增强方法,返回代理对象。通过spring容器获取目标对象和增强对象,通过动态代理生产代理对象,在目标对象的目标方法执行增强方法,返回生成代理对象给spring容器,在获取bean时则获取代理对象。JDK相当于生成了一个兄弟类,实现相同的接口,Cglib则生产一个子类。注解的方式使用AOP。
2023-11-14 21:01:18 269
原创 Spring面试题:(六)Spring注解开发原理
调用BeanDefinitionRegistryPostProcessor,再调用ClassPathDefinitionScanner的doScan方法。注册bean的接口:BeanDefinitionRegistryPostProcessor。发现只要将bean注册到BeanDefinitionMap中就可以创建bean对象。如何将xml配置的bean注册到BeanDefinitionMap。通过注解注册的bean过程一样。
2023-11-12 19:50:06 117
原创 Spring面试题:(五)Spring注解开发@Component,@Autowired,@Bean,@Configuration
Autowired先根据类型匹配,如果匹配到多个,则按照名次二次匹配。spring提供注解的版本。@Profile设置环境。@Primary优先级。
2023-11-12 19:10:03 235
原创 Spring面试题:(四)Spring Bean生命周期
BeanPostProcessor接口是Spring框架中的一个扩展点,它允许开发人员在Spring容器完成Bean的实例化、配置和其他初始化后,对Bean进行额外的处理。当Spring容器完成Bean的实例化、配置和其他初始化后,会依次调用所有注册的BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法,对Bean进行自定义处理。一级缓存:单例池,完整的bean。
2023-11-09 20:42:29 197
原创 Spring面试题:(三)SpringBean实例化过程和Spring后置处理器BeanFactoryPostProcessor和BeanPostProcessor
实例化BeanPostProcessor前置方法init初始化方法BeanPostProcessor后置方法。
2023-11-06 21:32:59 70
原创 Spring面试题:(二)基于xml方式的Spring配置
ApplicationContext底层调用BeanFactory创建Bean,BeanFactory可以利用反射机制调用构造方法实例化Bean,也可采用工厂模式创建Bean。
2023-11-01 21:29:21 547
原创 Spring面试题:(一)IoC,DI,AOP和BeanFactory,ApplicationContext
AOP(面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。DI依赖注入,和控制反转是同一个概念的不同角度的描述,即 应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源。Spring AOP是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP就会使用JDK。而对于没有实现接口的对象,就无法使用JDK动态代理,转而使用CGlib。
2023-10-30 22:04:00 146
原创 Java并发面试题:(八)AQS原理和Semaphore、CountdownLatch、CyclicBarrier类
通过维护一个共享资源状态( Volatile Int State )和一个先进先出( FIFO )的线程等待队列来实现一个多线程访问共享资源的同步框架。AQS队列同步器(AbstractQueuedSynchronizer),是用来构建锁或者其他同步组件的基础框架。它使用了一个int的成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。
2023-10-23 21:25:26 164
原创 Java并发面试题:(七)ThreadLocal原理和内存泄漏
因为ThreadLocalMap的key对它的引用是弱引用,将会在下一次gc被回收,那就会出现key变成null,如果这时value外部也没有强引用指向它,那么value就永远也访问不到了,按理也应该被GC回收,但是由于ThreadLocalMap.Entry对象还在强引用value,导致value无法被回收,这时「内存泄漏」就发生了,value成了一个永远也无法被访问,但是又无法被回收的对象。ThreadLocalMap存储的键值对,key就是ThreadLocal实例,value就是要缓存的值。
2023-10-19 21:08:37 444
原创 Java并发面试题:(六)悲观锁和乐观锁和Java内存模型和CAS原理
当线程各自修改完AY1、BY1之后,同步主内存之前,会用AY2、BY2与主内存中的资源Y对比,如果对比一致,则立即更新主内存,如果不一致,则重复上面操作,重新从主内存获取资源、修改、同步。Java线程在操作资源时,会将其用到的资源复制一份到线程的私有工作内存中,线程在自己的工作内存中对资源完成操作后,再把资源同步回主内存当中。悲观锁认为所有的资源都是不安全的,随时会被其他线程操作、更改。乐观锁是一种特殊的锁,它认为所有的资源都是安全的,每个线程对资源的操作都是符合预期的,所以它不需要对资源加锁。
2023-10-18 21:02:58 133
原创 Java并发面试题:(五)volatile关键字
volatile的一个重要作用就是和CAS结合,保证了原子性,详细的可以参见java.util.concurrent.atomic 包下的类,比如 AtomicInteger。1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线。程来说是立即可见的,volatile关键字会强制将修改的值立即写入主存。Volatile 一般用于 状态标记量 和 单例模式的双检锁。2)禁止进行指令重排序。
2023-10-17 21:44:08 377 1
原创 Java并发面试题:(四)synchronized和lock区别
⾃旋锁:⾃旋锁就是线程在获取锁的过程中,不会去阻塞线程,也就⽆所谓唤醒线程,阻塞和唤醒这两个步骤都是需要操作系统去进⾏的,⽐较消耗时间,⾃旋锁是线程通过CAS获取预期的⼀个标记,如果没有获取到,则继续循环获取,如果获取到了则表示获取到了锁,这个过程线程⼀直在运⾏中,相对⽽⾔没有使⽤太多的操作系统资源,⽐较轻量。优化机制包括自适应锁、自旋锁、锁消除、锁粗化、轻量级锁和偏向锁。锁的状态从低到高依次为无锁->偏向锁->轻量级锁->重量级锁,升级的过程就是从低到高,降级在一定条件也是有可能发生的。
2023-10-17 20:06:24 205
原创 Java并发面试题:(三)sleep和wait方法区别,notify 和 notifyAll方法
由于Java采用抢占式的线程调度算法,因此可能会出现某条线程常常获取到CPU控制权的情况,为了让某些优先级比较低的线程也能获取到CPU控制权,可以使用Thread.sleep(0)手动触发一次操作系统分配时间片的操作,这也是平衡CPU控制权的一种操作。wait()方法和notify()/notifyAll()方法在放弃对象监视器的时候的区别在于:wait()方法立即释放对象监视。这是JDK强制的,wait()方法和notify()/notifyAll()方法在调用前都必须先获得对象的锁。
2023-10-15 15:58:55 80
原创 Java并发面试题:(二)线程池参数和使用
ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。的任务提交,则会创建新的线程处理任务。当我们提交任务,线程池会根据corePoolSize大小创建若干任务数量线程执行任务。池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。
2023-10-15 15:43:54 101
原创 Java并发面试题:(一)线程的5种状态及转换
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻。2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线。5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。入就绪状态,才有机会转到运行状态。
2023-10-15 15:27:44 71
原创 JVM面试题:(四)四种引用方式强弱软虚
可用场景: Java源码中的 java.util.WeakHashMap 中的 key 就是使用弱引用,我的理解就是,虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入 ReferenceQueue 中。被用于引用销毁前的处理工作。强引用是平常中使用最多的引用,强引用在程序内存不足(OOM)的时候也不会被回收,使用。// 注意:wrf这个引用也是强引用,它是指向SoftReference这个对象的,上诉所说的几类引用,都是指对象本身的引用,而不是指Reference的四个子类的引用。
2023-10-12 20:57:39 99
原创 JVM面试题:(三)GC和垃圾回收算法
新生代的收集器包括Serial、PraNew、Parallel Scavenge,回收老年代的收集器包括Serial Old、Parallel Old、CMS,还有用于回收整个Java堆的G1收集器。标记 -清除算法,“标记-清除”(Mark-Sweep)算法,如它的名字一样,算法分为“标记”和“清。复制算法,“复制”(Copying)的收集算法,它将可用内存按容量划分为大小相等的两块,每次。除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。长期存活的对象进入老年代。
2023-10-11 21:12:05 925 1
原创 JVM面试题:(二)内存结构和内存溢出、方法区的两种实现
JVM栈(JVM Stacks),与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stacks)也是。方法区(Method Area),方法区(Method Area)与Java堆一样,是各个线程共享的内存区。Java堆(Heap),是Java虚拟机所管理的内存中最大的一块。挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服。较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。永久代的方法区,和堆使用的物理内存是连续的。
2023-10-10 22:00:03 266
原创 JVM面试题:(一)类加载机制和双亲委派
直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。直接引用是和虚拟机实现的内存布局相关的,同一个符号引用在不同的虚拟机示例上翻译出来的直接引用一般不会相同。如果有了直接引用,那引用的目标必定已经存在在内存中了。类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。常量池符号引用解析为直接引用?
2023-10-09 20:50:52 116 1
原创 cookie和session区别
如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。Session:在计算机中,尤其是在网络应用中,称为“会话控制”。
2023-08-31 21:25:22 139
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人