当前位置: 首页 > news >正文

Java 高频面试闯关秘籍

目录

  1. Java基础篇:涵盖OOP、多线程、集合等基础知识。
  2. Java高级篇:深入探讨HashMap、JVM、线程池等高级特性。
  3. Java框架篇:介绍Spring、SpringMVC、MyBatis等常用框架。
  4. Mysql数据库篇:包含SQL语句、事务、索引等数据库知识。
  5. 分布式技术篇:讲解Redis、消息队列、ElasticSearch等分布式技术。
  6. 项目管理工具Git篇:阐述Git的使用流程和常见命令。
  7. 综合问题篇:涉及项目经验、并发问题、设计模式等综合问题。
  8. 数据结构和算法篇:介绍数组、链表、排序算法等数据结构与算法。
  9. 设计模式篇:讲解单例模式、工厂模式、代理模式等设计模式。
  10. 面试技巧篇:提供面试过程中的关键要点和技巧。

Java基础篇

1. OOP面向对象

  • 继承:从已有类获取信息创建新类。
  • 封装:将数据和操作数据的方法绑定,控制数据访问。
  • 多态性:不同子类型对象对同一消息作出不同响应。
  • 重载与重写:重载发生在本类,方法名相同;重写发生在父子类之间,方法名和返回值类型相同,重写方法访问权限不能比父类更严格。
  • 抽象类与接口:抽象类需被子类继承,接口需被类实现。接口可多继承,类只能单继承。抽象类有构造器,接口没有。抽象类抽象方法修饰符多样,接口只能是public。抽象类有成员变量,接口只能声明常量。

2. 深拷贝与浅拷贝

  • 浅拷贝:拷贝基本数据类型值和对象引用地址,不复制引用指向的对象。
  • 深拷贝:拷贝基本数据类型值,也复制引用指向的对象。

3. Thread类中的方法

  • sleep(1000):线程睡眠1秒,释放CPU但不释放锁资源。
  • wait(1000):线程等待1秒,释放CPU和锁资源,需配合synchronized使用。
  • wait():一直等待,需通过notify或notifyAll唤醒,同样需配合synchronized使用。

4. int和Integer的区别

  • 数据类型:int是基本数据类型,Integer是包装类。
  • 装箱与拆箱:装箱将基本类型转换为包装类对象,拆箱则相反。自动装箱和拆箱是编译器语法糖,底层通过Integer.valueOf()和Integer.intValue()实现。
  • 使用方式:Integer变量需实例化后使用,int变量不需要。Integer是对象引用,int直接存储数据值。Integer默认值是null,int默认值是0。

5. ==和equals区别

  • ==:比较基本数据类型时比较值,比较引用数据类型时比较地址值。
  • equals:未重写时比较地址值,重写后通常比较对象属性内容。equals方法继承自Object类,默认实现使用==。

6. String类相关

  • 不可继承原因:String类被final修饰,禁止继承和重写,以提高效率和保证安全,其内部有native方法调用操作系统API。
  • StringBuffer和StringBuilder:方法和功能等价,StringBuffer方法多由synchronized修饰,线程安全但效率低;StringBuilder未修饰,线程不安全但效率高。

7. final、finally、finalize

  • final:修饰类、变量和方法。修饰类时不能被继承,修饰变量时为常量,修饰方法时不能在子类中重写。
  • finally:放在try…catch后,程序无论正常执行还是异常,只要JVM不关闭都能执行,用于释放外部资源。
  • finalize:Object类中的方法,垃圾收集器销毁对象时调用,可重写用于清理系统资源。

8. Object类中的方法

  • clone():创建并返回对象副本。
  • equals(Object obj):判断其他对象是否与此对象“相等”。
  • finalize():垃圾回收器确定对象无更多引用时调用。
  • getClass():返回对象的运行时类。
  • hashCode():返回对象的哈希码值。
  • notify():唤醒在此对象监视器上等待的单个线程。
  • notifyAll():唤醒在此对象监视器上等待的所有线程。
  • wait():导致当前线程等待,直到其他线程调用notify()或notifyAll()方法。
  • wait(long timeout):等待指定时间,若超时未被唤醒则继续执行。
  • wait(long timeout, int nanos):更精确控制等待时间。

9. 集合体系

集合框架包含Collection和Map接口。Collection接口下有List和Set子接口,List有序可重复,Set无序不重复。Map接口用于存储键值对。常见实现类有ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等。

10. HashMap底层结构及原理

  • 结构:JDK1.7中由数组+链表实现,JDK1.8中由数组+链表+红黑树实现。
  • 原理:数组存储数据,链表解决哈希冲突,JDK1.8中链表长度大于阈值(默认为8)且数组长度大于64时,链表转换为红黑树以提升查询性能。
  • 与HashTable区别:HashMap线程不安全,HashTable线程安全;HashMap只有containsValue和containsKey方法,HashTable有contains、containsKey和containsValue三个方法;HashMap允许null作为键和值,HashTable不允许;HashMap默认容量为16,要求底层数组容量为2的整数次幂,扩容时容量变为原来的2倍;HashTable默认容量为11,不要求容量为2的整数次幂,扩容时容量变为原来的2倍加1。

11. 线程的创建方式

  • 继承Thread类:创建Thread类的子类并重写run方法。
  • 实现Runnable接口:实现Runnable接口的run方法,创建Thread对象时传入该实现类实例。
  • 使用Callable和Future:实现Callable接口的call方法,通过FutureTask获取返回值。
  • 使用线程池:通过线程池管理和复用线程,提高效率。

12. 线程的状态转换

线程状态包括新建、就绪、运行、阻塞和死亡。新建状态下线程对象被创建;就绪状态下线程等待CPU调度;运行状态下线程获取CPU执行;阻塞状态下线程因获取锁失败、调用sleep()或join()方法、发出I/O请求等原因暂停运行;死亡状态下线程执行结束或因异常退出run方法。

13. Java中的流

Java流分为字节流和字符流。字节流包括InputStream和OutputStream,用于处理原始字节数据;字符流包括Reader和Writer,用于处理字符数据。还有缓冲流、转换流等,提高流操作的性能和功能。

14. 常见的RuntimeException

  • NullPointerException:调用未经初始化或不存在的对象。
  • ClassNotFoundException:指定的类找不到。
  • NumberFormatException:字符串转换为数字异常。
  • IndexOutOfBoundsException:数组越界异常。
  • ClassCastException:数据类型转换异常。

15. 反射机制

Java反射机制允许在运行时获取类的信息并动态调用对象方法。借助class、Constructor、Field、Method四个类实现,可在运行时判断对象所属类、构造对象、获取类的成员变量和方法等。

16. 序列化

序列化用于解决对象流读写操作问题。实现Serializable接口,使用ObjectOutputStream将对象写出,使用ObjectInputStream恢复对象。

17. Http常见的状态码

  • 200 OK:客户端请求成功。
  • 301 Permanently Moved:请求的URL已永久移走,Response中应包含Location URL。
  • 302 Temporarily Moved:临时重定向。
  • 404 Not Found:服务器无法找到请求的资源。
  • 500 Internal Server Error:服务器发生不可预期的错误。

18. GET和POST的区别

  • 数据传输方式:GET请求数据附在URL后,POST请求数据在请求体中。
  • URL长度限制:GET请求受浏览器和服务器限制,POST请求理论上无长度限制。
  • 安全性:POST安全性高于GET,GET提交数据可能导致用户名和密码明文出现在URL上,存在安全风险。

19. cookie和session的区别

  • 存储位置:cookie存储在客户端浏览器,session存储在服务器端。
  • 工作机制:cookie随请求发送给服务器,session通过会话ID识别用户。
  • 存储数据类型和大小:cookie只能存储字符串类型数据,存储量有限;session可存储任意Java对象。

Java高级篇

1. JVM内存分区及作用

JVM内存分为方法区、虚拟机栈、本地方法栈、堆和程序计数器。

  • 方法区:存储已加载的类信息、常量、静态变量等,很少发生垃圾回收。
  • 虚拟机栈:为Java方法服务,每个方法执行时创建栈帧,存储局部变量表、操作数栈等,线程私有。
  • 本地方法栈:为Native方法服务,与虚拟机栈类似。
  • :所有线程共享,几乎所有对象实例在此创建,频繁发生垃圾回收。
  • 程序计数器:记录当前线程执行的字节码指令地址,是唯一不会出现OOM的区域。

2. Java中垃圾收集的方法

采用分区分代回收思想,年轻代使用复制算法,老年代一般由标记清除或标记清除与标记整理的混合实现。

  • 引用计数法:通过对象引用计数器判断对象是否存活,无法解决循环引用问题。
  • 可达性算法:以GC Roots对象为起点,通过引用链判断对象是否可达,不可达则可被回收。可作为GC Roots的对象有虚拟机栈中引用的对象、方法区类静态属性引用的对象等。

3. StackOverflowError和OutOfMemoryError

  • StackOverflowError常见原因:无限递归循环调用、执行大量方法导致线程栈空间耗尽、方法内声明海量局部变量等。
  • OutOfMemoryError常见原因:内存中数据过多、对象无法被回收等。
  • 排查方法:可通过jvisualvm进行内存快照分析。

4. 线程池

  • 概念:事先将多个线程对象放入容器,使用时直接从池中获取线程,节省线程创建时间,提高效率。
  • 创建方式:通过Executors工具类创建,如newCachedThreadPool、newFixedThreadPool、newScheduledThreadPool、newSingleThreadExecutor等。
  • 底层工作原理:提交任务时,若核心线程池未满则创建线程执行任务;若满了则将任务放入等待队列;若等待队列已满且最大线程池未满,则创建新线程执行任务;若最大线程池已满,则执行拒绝策略。
  • ThreadPoolExecutor参数:corePoolSize(核心线程数)、maximumPoolSize(最大线程数)、keepAliveTime(存活时间)、unit(存活时间单位)、workQueue(任务队列)、threadFactory(线程工厂)、handler(拒绝策略)。
  • 线程池大小设置:需分析任务特性(CPU密集型或IO密集型),根据任务执行平均时长和CPU核心数等因素确定。
  • 拒绝策略:AbortPolicy(直接抛出异常)、CallerRunsPolicy(用调用者所在线程执行任务)、DiscardOldestPolicy(丢弃阻塞队列中最靠前的任务,执行当前任务)、DiscardPolicy(直接丢弃任务),也可自定义拒绝策略。

5. 常见线程安全的并发容器

常见线程安全的并发容器有ConcurrentHashMap、CopyOnWriteArrayList、CopyOnWriteArraySet等。

6. Atomic原子类

Java原子类位于java.util.concurrent.atomic包下,利用CAS(Compare and Swap)、volatile和native方法保证原子操作,避免synchronized的高开销,提升执行效率。

7. ConcurrentHashMap

  • 线程安全性:线程安全的Map容器。
  • JDK7原理:使用锁分段技术,每个数据段配置一把锁,提高性能,但Segment个数初始化后不能改变。
  • JDK8原理:使用Synchronized锁加CAS机制,结构上数组+链表+红黑树,优化了并发性能。

8. synchronized和volatile的区别

  • 本质:volatile保证变量从主存读取,synchronized锁定变量,只允许当前线程访问。
  • 使用范围:volatile仅用于变量,synchronized可用于变量、方法、类。
  • 功能:volatile仅实现变量修改可见性,不保证原子性;synchronized保证变量修改可见性和原子性。
  • 线程阻塞:volatile不会造成线程阻塞,synchronized可能会。
  • 编译器优化:volatile标记的变量不会被编译器优化,synchronized标记的变量可以被优化。

9. Java类加载过程

  • 加载:通过类的全限定名获取二进制流,转化为方法区运行时数据结构,生成Class对象。
  • 验证:验证字节流是否符合Class文件规范,包括文件格式验证、元数据验证、字节码验证等。
  • 准备:为类的静态变量分配内存并设置初始值。
  • 解析:将符号引用转换为直接引用。
  • 初始化:执行类中定义的Java程序代码。

10. 类加载器

  • 分类:引导类加载器(Bootstrap ClassLoader)加载Java核心类库,无法被继承;扩展类加载器(extension class loader)加载Java扩展库;系统类加载器(system class loader)根据Java应用的类路径加载Java类;用户自定义类加载器通过继承java.lang.ClassLoader类实现。
  • 加载机制:按需加载,初始化子类时父类先被加载,JVM启动时加载启动类。

11. Java内存分配与回收策略

  • 内存分配:栈区分为虚拟机栈和本地方法栈;堆区存放对象实例,分为新生代和老年代;方法区存储类信息等;程序计数器记录当前线程执行的字节码指令地址。
  • 回收策略:采用分代回收,新生代对象优先在Eden区分配,大对象直接进入老年代,长期存活的对象进入老年代。
  • Minor GC和Major GC:Minor GC发生在新生代,回收新生代垃圾;Major GC(full GC)发生在老年代,回收老年代和新生代垃圾,通常比Minor GC耗时更长。

12. 查看Java死锁及避免方法

  • 查看死锁:可使用jconsole、jstack等工具查看。
  • 避免死锁:注意加锁顺序,保证每个线程按同样顺序加锁;设置加锁时限,避免线程长时间等待;进行死锁检查,及时发现和解决死锁问题。

Java框架篇

1. SpringMVC工作流程

  • 用户发送请求至前端控制器DispatcherServlet。
  • DispatcherServlet调用HandlerMapping处理器映射器。
  • 处理器映射器找到对应的处理器,返回给DispatcherServlet。
  • DispatcherServlet调用HandlerAdapter处理器适配器。
  • 处理器适配器经过适配调用具体的处理器(Controller)。
  • Controller执行完成返回ModelAndView。
  • DispatcherServlet将ModelAndView返回给ViewReslover视图解析器。
  • 视图解析器解析后返回具体View。
  • 根据View进行渲染视图,响应用户。

2. Spring或SpringMVC中常用的注解

  • @Component:标识一个受Spring管理的组件。
  • @Controller:标识为一个表示层的组件。
  • @Service:标识为一个业务层的组件。
  • @Repository:标识为一个持久层的组件。
  • @Autowired:自动装配。
  • @Qualifier(“”):指定要装配的组件的id值。
  • @RequestMapping():完成请求映射。
  • @PathVariable:映射请求URL中占位符到请求处理方法的形参。

3. SpringMVC中返回JSON数据的方法

在项目中加入json转换的依赖(如jackson、fastjson、gson等),在请求处理方法上使用@ResponseBody注解。

4. Spring的理解

Spring是一个开源框架,为简化企业级应用开发而生,提供了IOC(控制反转)和AOP(面向切面编程)功能。IOC通过容器管理对象的创建和依赖注入,AOP用于实现横切关注点的功能,如日志记录、事务管理等。

5. Spring中常用的设计模式

  • 代理模式:若目标对象实现接口,Spring使用JDK的Proxy类代理;若未实现接口,使用CGLIB库生成目标类的子类代理。
  • 单例模式:在Spring配置文件中设置bean默认为单例模式。
  • 工厂模式:通过BeanFactory创建对象,解耦对象的创建和使用。

6. Spring循环依赖问题

Spring通过三级缓存解决循环依赖问题。在创建bean时,先将创建中的bean放入三级缓存,其他bean需要时可从缓存中获取,避免循环创建。但构造器注入属性无法解决循环依赖问题,因为实例化时属性未填充,无法提前暴露对象。

由于内容较多,以下将继续为你提炼补充该文档的部分内容,如果你需要更详细的章节提炼,请随时告诉我。

Java框架篇(续)

7. Spring bean的生命周期、注入方式和作用域(续)

  • 作用域(续):除了Singleton(单例)、Prototype(原型),还有Request(每次HTTP请求创建一个新的Bean实例)、Session(同一个HTTP Session共享一个Bean实例) 。

8. Spring的事务管理

  • 声明式事务管理:通过配置文件或注解来管理事务,如<tx:annotation-driven>配合@Transactional注解 ,声明式事务管理将事务管理与业务逻辑分离,方便维护。可以指定事务管理器,并通过Properties类型的transactionAttributes属性配置事务相关操作。
  • 编程式事务管理:在代码中显式调用beginTransaction()commit()等事务管理方法,这种方式对代码侵入性较大,实际应用中不如声明式事务管理常用。

9. MyBatis中#{}和${}的区别

  • #{}:MyBatis在处理#{}时,会将SQL中的#{}替换为?号,调用PreparedStatementset方法来赋值,能有效防止SQL注入,提高系统安全性。
  • ** ∗ ∗ : M y B a t i s 在处理 ‘ {}**:MyBatis在处理` MyBatis在处理{}时,会直接把${}`替换成变量的值,存在SQL注入风险,一般用于传入表名、字段名等,但使用时需谨慎。

10. MyBatis中一级缓存与二级缓存

  • 一级缓存:是SqlSession级别的缓存,默认开启。在同一个SqlSession中,执行相同的查询语句时,会直接从缓存中获取数据,而不再查询数据库。
  • 二级缓存:是NameSpace级别(Mapper)的缓存,多个SqlSession可以共享,使用时需要进行配置开启。开启二级缓存后,查询数据时会先从二级缓存中查找,若未找到再查询数据库。

11. MyBatis如何获取自动生成的(主)键值

在MyBatis的insert标签中,使用useGeneratedKeys="true"keyProperty="id"属性来获取自动生成的主键值。例如:<insert id="insertname" useGeneratedKeys="true" keyProperty="id"> insert into names (name) values (#{name}) </insert>,执行插入操作后,生成的主键值会自动赋值给对应的Java对象的id属性。

12. 简述MyBatis的动态SQL,列出常用的6个标签及作用

  • 动态SQL:MyBatis的动态SQL基于功能强大的OGNL表达式,主要用于解决查询条件不确定的情况,在程序运行期间,根据提交的条件动态完成查询。
  • 常用标签
    • <if>:进行条件判断,根据条件是否成立决定SQL片段是否包含在最终的SQL语句中。
    • <where>:在<if>判断后的SQL语句前面添加WHERE关键字,并处理SQL语句开始位置的AND或者OR的问题,避免出现多余的关键字。
    • <trim>:可以在SQL语句前后添加指定字符或者去掉指定字符,灵活调整SQL语句的格式。
    • <set>:主要用于修改操作时处理逗号问题,在更新语句中,会自动去掉多余的逗号。
    • <choose><when><otherwise>:类似于Java中的switch语句,在多个条件中选择其一,根据条件的优先级依次判断,满足条件则执行对应的SQL片段。
    • <foreach>:用于遍历集合,在插入或更新操作中,实现批量操作,例如批量插入数据时,循环遍历集合生成多条插入语句。

13. MyBatis如何完成MySQL的批量操作

通过<foreach>标签实现MySQL的批量操作。在<insert>标签中,使用<foreach>遍历集合,将集合中的元素按照指定的格式插入到数据库中。例如:

<insert id="insertBatch">insert into tbl_employee(last_name,email,gender,d_id) values<foreach collection="emps" item="curr_emp" separator=",">(#{curr_emp.lastName},#{curr_emp.email},#{curr_emp.gender},#{curr_emp.dept.id})</foreach>
</insert>

14. Spring Boot框架

  • 框架概述:Spring Boot是Spring开源组织下的子项目,是Spring组件一站式解决方案,主要简化了使用Spring的难度,减少了繁重的配置,提供了各种启动器,开发者能快速上手。
  • 优点:独立运行,可直接打包成可执行的JAR文件;启动器自动依赖其他组件,减少了Maven的配置;能根据当前类路径下的类、JAR包来自动配置Bean;无需XML配置文件,借助条件注解完成所有配置工作。
  • 核心注解@SpringBootApplication是Spring Boot的核心注解,组合包含了@SpringBootConfiguration(实现配置文件的功能)、@EnableAutoConfiguration(打开自动配置的功能,也可关闭某个自动配置选项)、@ComponentScan(扫描指定包及其子包下的组件)。
  • 自动配置原理:基于@EnableAutoConfiguration@Configuration@ConditionalOnClass等注解实现。根据类路径下是否存在某个类来自动配置Bean,例如添加一个启动器就能拥有相应的功能,无需额外配置。
  • 配置文件:包括application.propertiesbootstrap.propertiesbootstrap由父ApplicationContext加载,比application优先加载,且里面的属性不能被覆盖,常用于连接配置中心、设置固定属性或加密/解密场景。可通过不同的配置文件实现多环境配置,运行时指定具体的配置文件。

15. Spring Boot和Spring Cloud的关系

Spring Boot是一个快速开发框架,提供了快速配置和开发单个微服务的能力;Spring Cloud是一个基于Spring Boot实现的开发工具,关注全局的服务治理框架,很多集成方案基于Spring Boot实现,必须基于Spring Boot开发项目。Spring Cloud依赖Spring Boot提供的基础能力,如自动配置、内嵌服务器等,来构建分布式系统。

16. Spring Cloud常用组件及作用

  • Eureka:服务注册与发现组件,服务提供者将自己注册到Eureka Server,服务消费者从Eureka Server获取服务列表,实现服务的自动注册和发现。
  • Gateway:作为网关,是分布式系统统一的出入口,进行服务路由、统一鉴权、请求过滤、负载均衡等操作。
  • OpenFeign:作为远程调用的客户端,实现服务之间的远程调用,通过注解方式定义接口来调用其他服务的API。
  • Sentinel:实现系统的熔断限流,保护系统在高并发情况下的稳定性,防止因流量过大导致系统崩溃。
  • Sleuth:实现服务的链路追踪,通过生成唯一的Trace ID和Span ID来追踪请求在各个服务之间的调用路径和耗时,便于排查问题和优化系统性能。

17. Nacos作用以及注册中心的原理

  • Nacos作用:Nacos(Dynamic Naming and Configuration Service)是一个集服务注册中心和配置中心于一体的平台,为服务提供注册、发现、配置管理等功能,支持多种框架和语言。
  • 注册中心原理:Nacos注册中心分为server与client。server采用Java编写,为client提供注册服务、保存并提供Client配置信息、向Client提供服务列表等功能;client负责注册自身服务、获取服务列表、获取配置信息、维持心跳信息等。Nacos通过心跳机制检查服务实例的健康状态,若实例不健康则剔除。服务变更时,通过长轮询订阅服务,client拉取服务信息。

18. Feign工作原理

  • 首先通过@EnableFeignClients注解开启对FeignClient的扫描加载处理。
  • 根据Feign的开发规范,定义接口并加@FeignClient注解。
  • 当程序启动时,会进行包扫描,扫描到带有@FeignClient注解的类,并将这些信息注入Spring IOC容器。
  • 接口中的方法被调用时,通过JDK的代理方式生成具体的代理对象。Feign会为每个接口方法创建一个RequestTemplate,确定请求需要的全部信息,如请求参数名、请求方法等。
  • 最后根据RequestTemplate生成Request,基于负载均衡、重试器以及不同的HTTP请求框架,发送HTTP请求。

Mysql数据库篇

1. Select语句完整的执行顺序

  • from子句:组装来自不同数据源的数据,确定数据的来源表或视图。
  • where子句:基于指定的条件对记录行进行筛选,过滤掉不符合条件的数据行。
  • group by子句:对数据进行分组,将满足相同条件的数据分为一组。
  • having子句:筛选分组,对分组后的结果进行进一步筛选,只有满足having条件的分组才会被保留。
  • select子句:选择要查询的列,可以是具体的列名,也可以使用通配符*表示选择所有列。
  • order by子句:对结果集进行排序,可以按照升序(ASC)或降序(DESC)排列。

2. MySQL事务

  • 事务概念:事务是一组操作的集合,这些操作要么全部完成,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,保证数据的一致性和完整性。
  • 事务的基本要素(ACID)
    • 原子性(Atomicity):事务中的所有操作要么全部成功,要么全部失败,不可分割。
    • 一致性(Consistency):事务执行前后,数据库的完整性约束没有被破坏,数据从一个一致性状态转换到另一个一致性状态。
    • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不能被其他事务干扰,各个事务之间相互隔离。
    • 持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
  • MySQL事务隔离级别
    • 读未提交(read - uncommitted):允许读取未提交的数据,可能会出现脏读、不可重复读和幻读问题。
    • 读提交(read - committed):只能读取已提交的数据,可避免脏读,但仍可能出现不可重复读和幻读。
    • 可重复读(repeatable - read):保证在同一个事务中多次读取同一数据时,结果一致,可避免脏读和不可重复读,但仍可能出现幻读。
    • 串行化(serializable):最高的隔离级别,事务串行执行,可避免所有并发问题,但性能较低。

3. MyISAM和InnoDB的区别

  • 事务支持:MyISAM不支持事务;InnoDB支持事务,提供了更好的数据一致性和完整性保障,适合处理需要事务支持的业务场景,如银行转账、电商订单处理等。
  • 锁机制:MyISAM使用表锁,对表进行操作时会锁定整个表;InnoDB支持表锁和行锁,行锁可以提高并发性能,减少锁冲突,适合高并发的应用场景。
  • 文件存储:MyISAM存储为3个文件;InnoDB存储为1个文件,InnoDB的文件存储方式在数据管理和维护上相对更方便。
  • 外键支持:MyISAM不支持外键;InnoDB支持外键约束,用于维护表与表之间的数据一致性和完整性,确保相关数据的准确性和一致性。

4. 悲观锁和乐观锁的实现

  • 悲观锁:悲观锁认为数据在并发操作时很可能会发生冲突,所以在操作数据前先获取锁,锁定数据,防止其他线程修改。在MySQL中,使用select...for update语句实现悲观锁,例如:select price from item where id = 100 for update,该语句会锁定查询到的行,确保在当前事务处理期间,其他事务无法修改这些行的数据。使用悲观锁时必须确定走了索引,避免全表扫描,否则会锁住整个数据表。
  • 乐观锁:乐观锁认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测。如果发现冲突了,则返回错误信息,让用户决定如何去做。利用数据版本号(version)机制是乐观锁最常用的一种实现方式,一般通过为数据库表增加一个数字类型的“version”字段,当读取数据时,将version取出,数据每更新一次,对此version值 + 1。当提交更新时,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果相等,则予以更新,否则认为是过期数据,返回更新失败。

5. 聚簇索引与非聚簇索引区别

  • 数据结构:聚簇索引和非聚簇索引都是B + 树的数据结构。
  • 数据存储方式:聚簇索引将数据存储与索引放到了一块,并且是按照一定的顺序组织的,找到索引也就找到了数据,数据的物理存放顺序与索引顺序一致;非聚簇索引的数据和索引是分开存储的,通过索引需要二次查询才能获取数据。
  • 查询效率:查询通过聚簇索引可以直接获取数据,相比非聚簇索引需要第二次查询,效率要高;聚簇索引对于范围查询的效率很高,因为其数据是按照大小排列的;非聚簇索引适合用在查询条件不固定,需要频繁进行随机查询的场景。
  • 维护成本:聚簇索引维护索引很昂贵,特别是插入新行或者主键被更新导致要分页(pagesplit)时,会移动大量数据,可能造成碎片;非聚簇索引的维护成本相对较低。

6. 什么情况下mysql会索引失效

  • where后面使用函数:例如explain SELECT * from test_slow_query where age = 20explain SELECT * from test_slow_query where age + 10 = 30,后者在where条件中使用了函数,会导致索引失效。
  • 使用or条件:当or条件中的字段没有全部建立索引时,可能导致索引失效,如explain SELECT * from test_slow_query where NAME = '吕布' or name = "aaa"
  • 模糊查询%放在前边explain SELECT * from test_slow_query where NAME like '%吕布',这种情况下索引无法有效利用,会导致全表扫描。
  • 类型转换:如果查询条件中的字段类型与索引定义的类型不一致,会发生隐式类型转换,导致索引失效,如explain SELECT * from test_slow_query where NAME = 11(假设NAME字段为字符串类型)。
  • 组合索引(最佳左前缀匹配原则):组合索引使用时需遵循最佳左前缀匹配原则,否则会导致部分索引失效,如建立了(a,b,c)组合索引,查询时where b = 1 and c = 1无法利用该组合索引的全部字段。

7. B + tree与B - tree区别

  • 结构区别:B - tree的节点既存储数据又存储索引,数据指针指向实际的数据块;B + tree的非叶子节点只存储索引,不存储数据,数据全部存储在叶子节点中,叶子节点之间通过双向链表连接。
  • 查询效率:B + tree的查询效率更高,因为其所有数据都在叶子节点,且叶子节点有序排列,适合范围查询和全表扫描;B - tree在范围查询时效率相对较低,因为需要遍历更多的节点。
  • 节点存储内容:B - tree的一个节点可以存储多个元素,并且这些元素也排序了;B + tree的叶子节点存储了所有的数据,非叶子节点用于索引查找,节点中的元素也排序了,这种结构使得B + tree在查找数据时可以更快地定位到目标数据。

相关文章:

Java 高频面试闯关秘籍

目录 Java基础篇&#xff1a;涵盖OOP、多线程、集合等基础知识。Java高级篇&#xff1a;深入探讨HashMap、JVM、线程池等高级特性。Java框架篇&#xff1a;介绍Spring、SpringMVC、MyBatis等常用框架。Mysql数据库篇&#xff1a;包含SQL语句、事务、索引等数据库知识。分布式技…...

边缘计算网关驱动智慧煤矿智能升级——实时预警、低延时决策与数字孪生护航矿山安全高效运营

迈向智能化煤矿管理新时代 工业物联网和边缘计算技术的迅猛发展&#xff0c;煤矿安全生产与高效运营正迎来全新变革。传统煤矿监控模式由于现场环境复杂、数据采集和传输延时较高&#xff0c;已难以满足当下高标准的安全管理要求。为此&#xff0c;借助边缘计算网关的实时数据…...

Oracle认证大师(OCM)学习计划书

Oracle认证大师&#xff08;OCM&#xff09;学习计划书 一、学习目标 Oracle Certified Master&#xff08;OCM&#xff09;是Oracle官方认证体系中的最高级别认证&#xff0c;要求考生具备扎实的数据库管理技能、丰富的实战经验以及解决复杂问题的能力。本计划旨在通过系统化的…...

力扣 单词拆分

动态规划&#xff0c;字符串截取&#xff0c;可重复用&#xff0c;集合类。 题目 单词可以重复使用&#xff0c;一个单词可用多次&#xff0c;应该是比较灵活的组合形式了&#xff0c;可以想到用dp&#xff0c;遍历完单词后的状态的返回值。而这里的wordDict给出的是list&…...

如何在Linux中设置定时任务(cron)

在Linux系统中&#xff0c;定时任务是自动执行任务的一种非常方便的方式&#xff0c;常常用于定期备份数据、更新系统或清理日志文件等操作。cron是Linux下最常用的定时任务管理工具&#xff0c;它允许用户根据设定的时间间隔自动执行脚本和命令。在本文中&#xff0c;我们将详…...

C# ASP.NET核心特性介绍

.NET学习资料 .NET学习资料 .NET学习资料 在当今的软件开发领域中&#xff0c;C# ASP.NET凭借其强大的功能和丰富的特性&#xff0c;成为构建 Web 应用程序的重要技术之一。以下将详细介绍 C# ASP.NET的核心特性。 多语言支持 ASP.NET 支持多种语言进行开发&#xff0c;这使…...

Response 和 Request 介绍

怀旧网个人博客网站地址&#xff1a;怀旧网&#xff0c;博客详情&#xff1a;Response 和 Request 介绍 1、HttpServletResponse 1、简单分类 2、文件下载 通过Response下载文件数据 放一个文件到resources目录 编写下载文件Servlet文件 public class FileDownServlet exten…...

Spring常用注解和组件

引言 了解Spring常用注解的使用方式可以帮助我们更快速理解这个框架和其中的深度 注解 Configuration&#xff1a;表示该类是一个配置类&#xff0c;用于定义 Spring Bean。 EnableAutoConfiguration&#xff1a;启用 Spring Boot 的自动配置功能&#xff0c;让 Spring Boo…...

Spring中都应用了哪些设计模式?

好的&#xff01;以下是您提到的八种设计模式在 Spring 中的简单示例&#xff1a; 1. 简单工厂模式 简单工厂模式通过传入参数来决定实例化哪个类。Spring 中的 BeanFactory 就是简单工厂模式的应用。 示例代码&#xff1a; // 1. 创建接口和具体实现类 public interface A…...

VSCode的安裝以及使用

c配置: 【MinGw-w64编译器套件】 https://blog.csdn.net/weixin_60915103/article/details/131617196?fromshareblogdetail&sharetypeblogdetail&sharerId131617196&sharereferPC&sharesourcem0_51662391&sharefromfrom_link Python配置: 【簡單&#xff…...

Datawhale 组队学习 Ollama教程 task1

一、Ollama 简介 比喻&#xff1a;Ollama 就像是一个“魔法箱子”&#xff0c;里面装满了各种大型语言模型&#xff08;LLM&#xff09;。你不需要懂复杂的魔法咒语&#xff08;配置&#xff09;&#xff0c;只需要轻轻一按&#xff08;一条命令&#xff09;&#xff0c;就能让…...

前端技术学习——ES6核心基础

1、ES6与JavaScript之间的关系 ES6是JavaScript的一个版本&#xff1a;JavaScript是基于ECMAScript规范实现的编程语言&#xff0c;而ES6&#xff08;ECMAScript 2015&#xff09;是该规范的一个具体版本。 2、ES6的基础功能 &#xff08;1&#xff09;let和const let用于声明…...

《DeepSeek技术应用与赋能运营商办公提效案例实操落地课程》

大模型算法实战专家—周红伟老师 法国科学院数据算法博士/曾任阿里巴巴人工智能专家/曾任马上消费企业风控负责人 课程背景 随着大模型技术的迅猛发展&#xff0c;企业面临着提升工作效率、降低运营成本和优化资源配置的巨大压力。DeepSeek做出十三项革命性的大模型技术突破…...

STM32-知识

一、Cortex-M系列双指针 Cortex-M系列的MSP与PSP有一些重要的区别&#xff0c;双指针是为了保证OS的安全性和稳健性。本质上&#xff0c;区别于用户程序使用PSP&#xff0c;操作系统和异常事件单独使用一个MSP指针的目的&#xff0c;是为了保证栈数据不会被用户程序意外访问或…...

线程同步(互斥锁与条件变量)

文章目录 1、为什么要用互斥锁2、互斥锁怎么用3、为什么要用条件变量4、互斥锁和条件变量如何配合使用5、互斥锁和条件变量的常见用法 参考资料&#xff1a;https://blog.csdn.net/m0_53539646/article/details/115509348 1、为什么要用互斥锁 为了使各线程能够有序地访问公共…...

Ubuntu指令学习(个人记录、偶尔更新)

Ubuntu指令学习 0、一点常用指令列表一、Ubuntu下复制与移动&#xff0c;cp/mv二、Ubuntu下echo 与 重定向>,>>三、Ubuntu下chmod,用户权限四、Ubuntu下的tar打包&#xff0c;gzip压缩五、Ubuntu(22.04)下系统语言为中文&#xff0c;切换主目录文件名为英文。六、Ubun…...

Visual Studio 进行单元测试【入门】

摘要&#xff1a;在软件开发中&#xff0c;单元测试是一种重要的实践&#xff0c;通过验证代码的正确性&#xff0c;帮助开发者提高代码质量。本文将介绍如何在VisualStudio中进行单元测试&#xff0c;包括创建测试项目、编写测试代码、运行测试以及查看结果。 1. 什么是单元测…...

【经验分享】Linux 系统安装后内核参数优化

在 Linux 系统安装后&#xff0c;进行内核优化有助于提升系统的性能、稳定性和安全性。以下是一些常见的内核优化操作&#xff1a; 修改/etc/sysctl.conf 文件 执行sysctl -p使配置生效。 kernel.shmmax 135185569792 kernel.shmall 4294967296 fs.aio-max-nr 3145728 fs.fi…...

linux统计文件夹下有多少个.rst文件行数小于4行

您可以使用 find 命令结合 wc 命令来统计文件夹下 .rst 文件行数小于 4 行的文件数量。以下是一个具体的命令示例&#xff1a; find /path/to/directory -name "*.rst" -type f -exec wc -l {} | awk $1 < 4 | wc -l解释&#xff1a; find /path/to/directory …...

使用开源项目xxl-cache构建多级缓存

xxl-cache简介 官网地址&#xff1a;https://www.xuxueli.com/xxl-cache/ 概述 XXL-CACHE 是一个 多级缓存框架&#xff0c;高效组合本地缓存和分布式缓存(RedisCaffeine)&#xff0c;支持“多级缓存、一致性保障、TTL、Category隔离、防穿透”等能力&#xff1b;拥有“高性…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...