redis 高级篇
Redis高级篇Redis单线程 VS 多线程 入门面试题1、redis到底是单线程还是多线程
2、IO多路复用
3、redis为什么快?
Redis为什么选择单线程?redis3以及之前是单线程的。
redis4之后才慢慢支持多线程 支持异步删除,部分多线程,直到redis6/7之后才稳定,完全支持多线程。
那以前我们说redis是单线程是什么意义
主要是指Redis的网络IO和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时包括获取(socket读),解析,执行,内容返回(socket写)等都由一个顺序串行的主线程处理,这就是所谓的单线程,这也是redis对外提供剪枝存储服务的主要流程。
但是Redis的其他功能,比如持久化RDB、AOF、异步删除、集群数据同步等等,其实是由额外的线程执行的。Redis命令工作线程是单线程的,但是,整个Redis来说,是多线程的。
也就是说一个命令set但是这时候需要RDB,AOF,这时候就会新开一个线程,处理这些。
但是操作十大类型的原子性操作都是单线程的。
Redis3单线程时代但性能依旧很快的原因
从硬件的角度,Redis是基 ...
Spring面试
Spring相关面试什么是循环依赖循环依赖就是A依赖B,然后B又依赖A了,无法确定加载模块顺序
Spring如何解决循环依赖Spring主要用三级缓存来解决循环依赖
一级缓存:用于存储完全初始化完成的单例Bean
二级缓存:用于存储尚未完全初始化,但已经实例化的Bean
三级缓存:用于存储对象工厂,比如AOP代理对象创建的时候就需要工厂了。
解决步骤就是:
步骤 1:开始创建 Bean A
Spring 调用 A 的构造方法,实例化 A 对象(此时 A 的属性还未注入)
将 A 的 ObjectFactory放入三级缓存(singletonFactories)
singletonFactories.put("a", () -> getEarlyBeanReference("a", a));
步骤 2:为 A 填充属性(发现依赖 B)
Spring 发现 A 需要注入 B
于是转去创建 B
步骤 3:开始创建 Bean B
实例化 B 对象
将 B 的 ObjectFactory 放入三级缓存
为 B 填充属性 → 发现依赖 A
步骤 ...
SpringMVC
SpringMVCSpringMVC是spring为展现层提供的基于MVC设计理念的优秀WEB框架
SpringMVC通过一套注解,可以让普通的JAVA类成为contrllor控制器,无需继承Servlet
实现了控制层和Servlet之间的解耦。SpringMVC支持Rest风格的URL写法SpringMVC采用了松耦合,可热插的主键结构,比其他的框架更具扩展性和灵活性。
框架执行流程
1DispatcherServlet:前端控制器用户请求到达前端控制器,它就相当于 mvc 模式中的 c,dispatcherServlet 是整个流程控制的中心,由 它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。
2 HandlerMapping:处理器映射器HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的 映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3 Handler:处理器 (自己定义的Controller处理单元)它就是我们开发中要编写的具体业务控制器。 ...
动态代理和反射
动态代理和反射由于这两个东西很重要经常用,所以我专门用一个文章来讲解,忘了就看着一个就够了
反射反射机制就是在 运行的时候 获取类的结构信息,比如方法,字段,构造函数并操作对象的一种机制。
反射操作相对于静态调用有比较高的性能开销,因为他涉及到动态解析和方法调用。所以在性能敏感的场景中,尽量避免使用反射。可以通过 缓存反射结果 避免反射性能问题。
反射主要有个Class类,通过Class类的实例可以获取类的各种信息。
反射的主要主要功能:
创建对象:通过Class.newInstance 或者Constructor.newInstance()创建对象实例
访问字段:通过Field类访问和修改对象的字段。
调用方法:使用Method类调用对象的方法
获取类对象:获取类的名称、父类、接口等信息。
类的元数据存在方法区 / 元空间,Class 实例存在堆中,反射通过堆中的 Class 实例,访问方法区的元数据,进而操作对象。
动态代理首先了解静态代理
一个租房子问题,中介就是这个原理。
缺点代理需要手动创建,简单来说就是房主和中介都要实现租房接口,这个租房接口规定了租房的规范,然后消 ...
算法理解(口语化)
算法理解(口语化)前导要学算法首先要熟悉 IO 模板这里先提前学 IO模板
提前告诉数据量的类型
1234567891011121314151617181920import java.io.*;import java.util.*;public class Main{ //这里注意要抛出异常 public static void main(String[] args) throws IOException{ //注意输入和输出流 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StreamTokenizer in = new StreamTokenizer(br); PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); while(in.nextToken() != S ...
Spring扩展点案例
Spring扩展点案例首先Spring扩展点有三个
1、BeanPostProcessor这个可以在Bean实例前后进行增强
2、BeanFactoryPostProcessor这个是用来修改Bean的元数据的
3、FactoryBean是通过java来进行初始化而不是xml
创建一个Bean的流程
我们模拟一个 “订单服务(OrderService)” 的开发场景,流程如下:
FactoryBean:封装 OrderService 的复杂初始化(比如加载订单模板配置、初始化缓存)。
BeanFactoryPostProcessor:在 OrderService 实例化前,动态修改其元数据(比如根据环境切换订单超时时间)。
BeanPostProcessor:在 OrderService 初始化后,增强其方法(比如添加订单操作的日志记录)。
整个项目是标准 Spring Boot 结构,靠 @SpringBootApplication 自动启动容器,无需手动创建 ApplicationContext。
实际案例1、首先有一个核心业务类
123456789101112131415 ...
JavaEE
JavaEE首先JavaEE就是在之前JavaSE本地运行的基础上,增加了企业级Web应用中的技术标准,也就是说现在JavaEE可以开发WEB应用了。
JavaEE平台包含了13个技术规范
JAVEE阶段需要学习的核心技能
Servlet、JSP、JSTL/EL、JavaBean、MVC模式、过滤器Filter、监听器listener、Ajax 分页
然后既然是JavaEE开发那么就需要有个服务器,然后再利用JavaEE的库来开发web项目,然后常用的Web容器有Tomcat和Jetty
WEB应用运行流程:
用户访问 http://localhost:8080/hello
请求到达 Tomcat(Web 容器)
Tomcat 根据 web.xml 或注解,找到对应的 Servlet
Servlet 处理请求,可能调用 Service → DAO → 数据库
处理完成后,跳转到 JSP 页面(View)
JSP 被编译成 Servlet,结合 JSTL/EL 渲染 HTML
返回 HTML 响应给浏览器
Filter 可能在请求前后做日志、编码、权限检查
Listener 可 ...
Spring
Spring核心技术Spring框架的控制反转IoC 容器。
Spring面相切面编程 AOP 技术。
此外还有Spring和AspectJ
IOC容器Spring IoC容器和Bean简介原本是 “对象自己找依赖”(比如 A 类要用到 B 类,A 自己 new B、自己找 B 的实例),现在是 “容器给对象送依赖”(A 不用管 B 怎么来,容器提前准备好 B,在创建 A 时主动 “塞” 给 A)—— 这种 “找依赖的权力从对象手里转到容器手里” 的反转,就是 IoC;而容器 “塞依赖” 的具体动作,就是 DI(依赖注入)
IoC 是 “设计原则”(核心思想是 “反转依赖控制权”),DI 是 “实现方式”(具体怎么把依赖给对象)—— 二者本质是同一概念的不同角度描述,Spring 用 DI 的方式实现了 IoC 原则。
一个对象(比如 A 类)要和其他对象(比如 B 类、C 类,也就是 A 的 “依赖”)合作,不用自己去创建或查找这些依赖,只需要 “明确告诉容器自己需要什么”—— 告诉的方式有 3 种:
构造参数:A 的构造方法里写public A(B b) { ... & ...
Netty
NettyBIO、NIO、AIO 的区别BIO、AIO和NIO是Java中不同的I/O模型,它们在处理输入输出操作时有不同的特点。
BIO: 阻塞式的I/O模型。当一个线程执行I/O操作时,如果数据还没准备好,这个线程会被阻塞,直到数据到达。适合连接数较少且固定的场景,但扩展性较差。在Java中用ServerSocket和Socket的accpet方法,用来阻塞,等待客户端连接。
NIO: 非阻塞的I/O模型。NIO使用缓冲区和通道来处理数据,提高了I/O操作的效率。支持面向缓冲区的读写操作,可以处理大量并发的连接。在java.nio包中提供了Selector、Channel等类实现高效的非阻塞IO
AIO: 异步I/O模型,从Java 7开始引入。在AIO中,I/O操作被发起后,线程可以继续执行其他任务,一旦I/O操作完成,操作系统会通知线程。适合需要处理大量并发I/O操作,且希望避免I/O操作阻塞线程的场景。在Java中通过AsynchronousSocketChannel类来实现异步IO
使用场景:
BIO适合低并发、连接数较少的应用。
NIO适合高并发、需要处理大量连接的应用 ...









