java面试题

一.javaSE

基础算法

一.斐波那契数列
逻辑:前两个数的值分别为 0 、1 或者 1、1;从第 3 个数字开始,它的值是前两个数字的和;
java递归代码实现

//定义斐波那契数列递归方式
    // index 表示求数列中第 index 个位置上的数的值
    public static int fibonacci(int index) {
        // 设置结束递归的限制条件
        if (index == 1 || index == 2) {
            return 1;
        }
        // F(index) = F(index-1) + F(index-2)
        return fibonacci(index - 1) + fibonacci(index - 2);
    }
    //斐波那契数列递归的 Java 程序
    @Test
    public void test1(){
        // 输出前 10 个数
        for (int i = 1; i <= 10; i++) {
            System.out.print(fibonacci(i) + " ");
        }
    }

java数组代码实现

    //斐波那契数列数组的Java程序
    // index 表示求数列中第 index 个位置上的数的值
    public static int fibonacci1(int index){
        if(index < 0){
            return -1;
        }else if(index == 0){
            return 0;
        }else if(index == 1 || index == 2){
            return 1;
        }else{
            int[] fibAry = new int[index+1];
            fibAry[1] = 1;
            fibAry[2] = 1;
            for(int i = 3;i <= index;i++) {
                fibAry[i] = fibAry[i - 1] + fibAry[i - 2];
            }
            return fibAry[index];
        }
    }

    //斐波那契数列数组的Java程序调用
    @Test
    public void test2(){
        // 输出前 10 个数
        for (int i = 1; i <= 10; i++) {
            System.out.print(fibonacci1(i)+" ");
        }
    }

二.完数
概念:各个小于它的约数(真约数,列出某数的约数,去掉该数本身,剩下的就是它的真约数)的和等于它本身的自然数叫做完全数(Perfect number),又称完美数或完备数。
java代码实现:

    public static void main(String[] args) {
        System.out.println("10000以内的完数如下:");
        fun(10000);
    }
    //求完数:完数的定义:一个数恰好等于它的所有真因子之和
    public static void fun(int n){
        for (int i = 1; i <= n; i++) {
            int factor = 0;//定义因子变量和,初始值为0
            for (int j = 1; j < (i / 2) + 1; j++) {
                if (i%j==0){
                    factor+=j;
                }
            }
            if(factor == i){
                System.out.println(i);
            }
        }
    }

==和equals比较

==基本数据类型比较的是值的本身,引用类型比较的是堆中内存对象的地址值.
equals:object中默认为= = ,通常会重写
例子:

public class test {
    public static void main(String[] args) {
        String str1 = "hello"; //常量池地址
        String str2 = new String("hello"); //堆中内存地址
        String str3 = str2;
        System.out.println(str1 == str2); //false
        System.out.println(str1 == str3); //false
        System.out.println(str2 == str3); //true
        System.out.println(str1.equals(str2)); //true
        System.out.println(str1.equals(str3)); //true
        System.out.println(str2.equals(str3)); //true
    }
}

JDK,JRE,JVM关系

在这里插入图片描述
java跨平台性的原理
.java文件经过javac工具编译为.class文件,java在不同版本中提供对应的jvm,由于我们的.class可以在
任意版本jvm中运行,使得我们一份.class文件能够在各种平台中运行
在这里插入图片描述

面向对象

什么是面向对象?
对比面向过程,是两种不同的处理问题的角度
面向过程更注重事情的每一个步骤以及顺序,面向过程更注重有哪些参与者(对象),各自需要做什么
比如:洗衣机洗衣服
面向过程会将任务拆分为一系列的步骤:1.打开洗衣机→2.放衣服→3.放洗衣粉→4.清洗→5.烘干
面向对象会拆分出人和洗衣机两个对象
人:打开洗衣机,放衣服,放洗衣粉
洗衣机:清洗,烘干
总结:面向过程比较简单直接,面向对象更易于复用,扩展和维护
封装
在于明确标识出允许外部使用的所有成员函数及属性
提供set,get方法对外访问,有效防止外部对其胡乱修改,具体细节由自身控制
继承
继承父类的方法,并做出自己的改变/或扩展
子类共性的方法或者属性直接使用父类的,实现了代码的复用性,只需扩展自己个性化的方法及属性
多态
基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同
条件:继承,重写,父类引用子类对象,无法调用子类的独有方法
父类类型 变量名 = new 子类对象
变量名.方法名();

集合(collection)

1.HashMap的底层数据结构是?
	jdk1.8之前:
	HashMap采用数组+链表结构结合在一起使用就是链表散列
	Hash通过key的hashCode经过扰动函数处理后得到hash值,然后通过(n-1
	) & hash 判断当前元素存放的位置(n指数据的长度),如果当前位置存在元素,
	就判断该元素的hash值以及key值是否相等,相等则覆盖,如果不相同通过拉链
	法解决冲突
	扰动函数:就是HashMap中的hash方法,使用hash方法也就是扰动函数,是为了防止
	一些实现比较差的hashcode方法,减少hash碰撞的次数.
	jdk1.8之后:
	当链表长度大于阀值(默认为8),会首先调用treefyBin()方法.这个方法会根据HashMap
	数据来决定是否需要转换为红黑树.只有当数组长度大于或者等于64的情况下,才会执
	行转换红黑树的操作,以减少搜索时间.否则,就是执行resize()方法对数组扩容.

java核心API

Web

Mybatis

什么是Mybatis

  • MyBatis 是一款优秀的***持久层***框架,
  • 它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO为数据库中的记录。

何如获取Mybatis

  • Maven仓库
  • Github

持久化

数据持久化

  • 持久化就是将程序的数据在持久状态和瞬时状态的过程
  • 内存:断电即失
  • 数据库(JDBC),IO文件持久化
    为什么要持久化
  • 有一些对象,不能让他丢掉
  • 内存太贵了

持久层

  • Dao层,service层,controller层
  • 完成持久化工作的代码块
  • 层级界限十分明显

为什么需要Mybatis?

  • 最重要一点:使用的人多
  • 方便
  • 帮助程序猿将数据存入数据库中
  • 传统的JDBC太复杂,简化.框架,自动化
  • 不用Mybatis也可以
  • 优点
    简单易学:
    灵活:
    sql和代码的分离,提高了可维护性。
    提供映射标签,支持对象与数据库的orm字段关系映射。
    提供对象关系映射标签,支持对象关系组建维护。
    提供xml标签,支持编写动态sql。

构建一个Mybatis项目

1.创建Maven工程
2.导入依赖mysql,mybatis,junit
3.编写mybatis核心配置文件
4.编写工具类utils,获取SqlSession对象

public class SpringUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static{
        try{
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

注意代码实现时:
当执行的是增删改的操作时,需要提交事务

    <insert id="insert" parameterType="com.atguigu.pojo.User">
        insert into mybatis.user values(#{id},#{name},#{pwd})
    </insert>

提交事务代码实现:commit

    public void insert(){
        SqlSession sqlSession = SpringUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.insert(new User(3,"小花","123456"));
        sqlSession.commit();
        sqlSession.close();
    }

错误分析

1.resource里面使用的是/连接

    <mappers>
        <mapper resource="com/atguigu/mapper/UserMapper.xml"/>
    </mappers>

2.需要配置pom.xml
加载java中的properties,xml文件,默认不加载

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

万能Map

假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map
代码实现

    //添加一个用户
    int insert2(Map<String,Object> map);
    
    <!--添加一个用户-->
    <insert id="insert2" parameterType="map">
        insert into mybatis.user(id,pwd) values(#{userid},#{userpwd})
    </insert>
    
    public void insert2(){
       SqlSession sqlSession = SpringUtils.getSqlSession();
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       Map<String,Object> map = new HashMap<String, Object>();
       map.put("userid",4);
       map.put("userpwd","123456");
       mapper.insert2(map);
       sqlSession.commit();
       sqlSession.close();
    }

Map传递参数,直接sql中取出key即可!【parameterType=“map”】
对象传递参数,直接sql中去对象的属性即可!【parameterType=“Object”】
只有一个基本类型的情况下,直接在sql中取到!
多个参数用Map,或者注解!

配置解析

1.核心配置文件

  • mybatis-config.xml
  • MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
    configuration(配置)
    properties(属性)
    settings(设置)
    typeAliases(类型别名)
    typeHandlers(类型处理器)
    objectFactory(对象工厂)
    plugins(插件)
    environments(环境配置)
    environment(环境变量)
    transactionManager(事务管理器)
    dataSource(数据源)
    databaseIdProvider(数据库厂商标识)
    mappers(映射器)
    2.环境配置(environments)
  • MyBatis 可以配置成适应多种环境
  • 尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
  • 学会配置多套运行环境
  • Mybatis默认的事务管理器就是JDBC,连接池:POOLED
    3.属性(properties)
  • 我们使用通过properties属性来实现引用配置文件
  • 这些属性可以在外部进行配置,并可以进行动态替换
  • 编写一个配置文件
  • db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mysql?characterEncoding=UTF-8
username=root
password=root
  • 在核心配置文件中引入
    <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </properties>

可以直接引入外部文件
可以在其中增加一些属性配置
如果两个文件有同一个字段,优先使用外部配置文件的!
4.类型别名(typeAliases)
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写
方式一:

    <!--可以给实体类起别名-->
    <typeAliases>
        <typeAlias type="com.atguigu.pojo.User" alias="User"/>
    </typeAliases>

方式二: 每一个在包中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名

    <typeAliases>
        <package name="com.atguigu.pojo"/>
    </typeAliases>

第一种可以DIY自定义别名,第二种不可以,如果非要改,在类上加注解@Alias(“user”)
5.设置(settings)
这是Mybatis中极为重要的调整设置,他们会改变Mybatis的运行是行为
在这里插入图片描述
在这里插入图片描述
7.映射器(mappers)
方式一:

    <!--让每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->
    <mappers>
        <mapper resource="com/atguigu/mapper/UserMapper.xml"/>
    </mappers>

方式二:

    <!--让每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->
    <mappers>
        <mapper class="com.atguigu.mapper.UserMapper"/>
    </mappers>

注意:

  • 接口和它的映射文件必须同名
  • 接口和他的映射文件必须在同一个包
    方式三
    <!--让每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->
    <mappers>
        <package name="com.atguigu.mapper"/>
    </mappers>

注意:

  • 接口和它的映射文件必须同名
  • 接口和他的映射文件必须在同一个包

6.作用域(Scope)和生命周期
生命周期和作用域是非常重要的,错误的使用会导致非常严重的***并发问题***
在这里插入图片描述
SqlSessionFactoryBuild

  • 一旦创建了SqlSessionFactory,就不在需要它了
  • 局部变量
    SqlSessionFactory
  • 可以想象为数据库连接池
  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例
  • SqlSessionFactory 的最佳作用域是应用作用域
  • 最简单的就是使用单例模式或者静态单例模式
    SqlSession
  • 连接到连接池的一个请求
  • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域
  • 打开一个 SqlSession,返回一个响应后,就关闭它
  • 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中
  • 这里的每一个Mapper就是一个具体的业务在这里插入图片描述

解决属性名与字段名不一致问题

解决方法一:

  • 起别名
    <select id="selectAll" resultType="User">
        select id,name,pwd as pwaaword from mybatis.user
    </select>

解决方式二:resultMap
结果集映射
resultMap 元素是 MyBatis 中最重要最强大的元素。
ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
ResultMap 的优秀之处——你完全可以不用显式地配置它们。
原因:
数据库:id,name,pwd
实体类:id,name,password

    <!--结果集映射-->
    <resultMap id="UserMap" type="User">
        <!--column数据库中的列,property实体类的属性-->
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>
    <select id="selectAll" resultMap="UserMap">
        select * from mybatis.user
    </select>

日志

  • 日志工厂
    如果一个数据库操作,出现了异常,我们需要排错,日志就是最好的帮手
    在这里插入图片描述
  • SLF4J
  • LOG4J【掌握】
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING【掌握】
  • NO_LOGGING
    在Mybatis中具体使用那个日志,在设置中设定
    STDOUT_LOGGING的日志实现
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

具体的体现

Opening JDBC Connection
Created connection 937773018.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@37e547da]
==>  Preparing: select * from mybatis.user 
==> Parameters: 
<==    Columns: id, name, pwd
<==        Row: 1, 小唐, 123456
<==        Row: 2, 小王, 123456
<==        Row: 3, 小花, 123456
<==        Row: 4, null, 123456
<==        Row: 5, null, 123456
<==      Total: 5
User{id=1, name='小唐', password='123456'}
User{id=2, name='小王', password='123456'}
User{id=3, name='小花', password='123456'}
User{id=4, name='null', password='123456'}
User{id=5, name='null', password='123456'}
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@37e547da]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@37e547da]

LOG4J的日志实现
1.什么是log4j:
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件
我们也可以控制每一条日志的输出格式
通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程
可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
2.导入log4jMaven包

多对一处理

按照查询嵌套处理

    <!--思路:
        1.查询所有学生的信息
        2.根据查询出来的学生的tid,寻找对应的老师!子查询
    -->
    <select id="getAllStudent" resultMap="StudentMap">
        select * from student
    </select>

    <resultMap id="StudentMap" type="Student">
        <!--复杂的属性我们需要单独处理 association 对象 collection 集合-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacherById"/>
    </resultMap>

    <select id="getTeacherById" resultType="Teacher">
        select * from teacher where id = #{id}
    </select>

按照结果嵌套查询处理

    <select id="getAllStudent2" resultMap="StudentMap2">
        SELECT s.id as tid,s.name as sname,t.name as tname
        FROM teacher AS t,student AS s WHERE t.id=s.tid
    </select>

    <resultMap id="StudentMap2" type="Student">
        <result property="id" column="tid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>

一对多处理

按照结果嵌套处理

    <select id="getTeacherById" resultMap="TeacherStudent">
        SELECT t.id AS tid,t.name AS tname,s.id AS sid,s.name AS sname
        FROM teacher AS t,student AS s WHERE t.id=s.tid
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"></result>
        </collection>
    </resultMap>

按照查询嵌套处理

    <select id="getTeacherById2" resultMap="TeacherStudent2">
        select * from teacher where id=#{id}
    </select>
    
    <resultMap id="TeacherStudent2" type="Teacher">
        <collection property="students" column="id" ofType="Student" select="getStudentByTeacherId" javaType="ArrayList"/>
    </resultMap>
    
    <select id="getStudentByTeacherId" resultType="Student">
        select * from student where tid=#{id}
    </select>

小结:

  • association 属性为对象时使用
  • collection 属性为集合时使用
  • javaType & ofType
  • javaType 用来指定实体类中属性的类型
  • ofType 用来指定映射到List或者集合中的pojo类型,泛型的约束类型

注意点:

  • 保证sql的可读性,尽量保证通俗易懂
  • 注意一对多和多对一中,属性名和字段的问题
  • 如果问题不好排查,可以使用日志,建议使用log4j

动态SQL

什么是动态SQL:
动态SQL就是指根据不同的条件生成不同的SQL语句
所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面,添加一些逻辑代码

在这里插入图片描述
if实例代码

<select id="findActiveBlogWithTitleLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
</select>

choose、when、otherwise实例代码

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

缓存

查询数据库比较浪费资源,我们采用把数据存储在内存中,方便下次使用
缓存:

  • 存在内存中的临时数据
  • 解决高并发系统的性能问题
    好处
  • 减少和数据库的交互次数,减少系统开销,提高系统效率
    使用情况
  • 经常查询且不常改变的数据

一级缓存

一级缓存也叫本地缓存: sqlsession

  • 与数据库同一次会话间查询到的数据会放在本地缓存中
  • 以后如果需要获取相同的数据,直接从缓存中拿,没有必要去查数据库
    测试步骤:

SpringMVC框架

spring框架

概述:spring是轻量级的管理Bean生命周期的框架,可以解决企业开发的负责性
特点:
(1)方便解耦,简化开发
(2)Aop编程
(3)方便与其他框架整合
(4)方便进行事务
(5)降低API开发

IOC

概念:控制反转,把对象的创建和对象之间的调用过程交给spring管理,
目的:为了耦合度降低
IOC底层原理:xml解析,工厂模式,反射
解析xml文件获取类的全路径,通过工厂模式,反射,class.newInstance()创建对象,并返回
IOC(接口):
1.IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
2.Spring提供IOC容器实现两种方式:
(1)BeanFactory:IOC容器基本实现,是Spring内部的接口,不提供开发人员进行使用
*加载配置文件不会创建对象,在获取对象的时候才去创建对象
(2)ApplicationContext:Beanfactory的子接口,提供更强大的功能,一般由开发人员使用
*加载配置文件时就会把配置文件对象进行创建
3.ApplicationContext实现类:
ClassPathXmlApplicationContext:相对路径src
FileSystemXmlAplicationComtext:绝对路径
4.bean管理基于xml方式创建对象

<bean id="唯一标识" class="类的全路径" ></bean>

4.1.bean管理基于xml方式创建对象并注入属性(set注入)

<bean id="唯一标识" class="类的全路径" >
        <property name="属性名" value="属性值"></property>
    </bean>

4.2.bean管理基于xml方式创建对象并注入属性(有参构造注入)

    <bean id="唯一标识" class="类的全路径" >
        <constructor-arg name="属性名" value="属性值"></constructor-arg>
    </bean>

4.3.bean管理基于xml方式创建对象并注入其他类型属性属性(set注入)
属性注入空值

        <property name="属性名">
            <null></null>
        </property>

属性注入特殊符号

        <property name="属性名">
            <value><![CDATA[<<南京>>]]></value>
        </property>

4.4.bean管理基于xml方式创建对象并注入对象属性(set注入)

    <!--service和dao对象的创建-->
    <!--给service中的属性注入对象-->
    <bean id="对象的唯一标识1" class="类的全路径" >
        <property name="属性值" ref="对象的唯一标识2"></property>
    </bean>
    <bean name="对象的唯一标识2" class="类的全路径"></bean>

5.bean管理基于注解方式
5.1注解
(1)注解是代码特殊标记,格式@注解名(属性名=属性值,属性名=属性值…)
(2)注解的目的:简化开发
(3)注解的作用域:类,方法,属性
5.2.基于注解方式实现对象创建
(1)@Component
(2)@Service 常用在Service层
(3)@Controller 常用在Controller层
(4)@Repository 常用在Dao,Mapper层
作用一致,注解方式实现对象的创建.
5.3.基于注解方式实现属性对象的注入
(1)@Autowired 根据类型进行注入
(2)@Qualifier 根据名称进行注入,配合@Autowired一起使用
5.3.基于注解方式实现属性中基本属性的注入
@Value
5.4完全注解开发
创建配置类config,添加注解@Configuration,@ComponentScan(basePackages = {“包路径”})
加载配置类 AnnotationConfigApplicationContext(配置类.class)

Aop

概述:面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑
部分之间的***耦合度降低,提高程序的可重用性,提高了代码的开发效率.
通俗描述:不通过修改源代码方式,在主干工功能里面添加新功能
AOP底层原理:
1.动态代理
(1)有接口的情况→JDK动态代理
创建接口实现类的代理对象,增强类的方法
在这里插入图片描述
(2)没有接口的情况→CGLIB动态代理
在这里插入图片描述
AOP操作(AspectJ注解)
1.创建类,在类中定义方法
2.创建增强类(编写增强逻辑)
3.进行通知的配置
(1)在spring配置文件中,开启注解扫描
(2)使用注解创建类和增强类
(3)在增强类上面添加注解@Aspect
(4)在spring配置文件中开始生成代理对象
表示:所有的访问修饰符,包名下面的所有类,所有方法,任意参数
切入点表达式:execution(
包名.
.
(…))
4.5种通知
前置,后置,异常,最终,环绕通知
环绕通知

@Around(@value = "切入点表达式")
public void around(ProceedingJoinPoint point){
		执行被增强的方法
		point.proceed();
}

5.公共切入点抽取

@Pointcut(@value = "切入点表达式")
public void pointdemo(){

}

(1)使用公共切入点

@Around(@value = "pointdemo()")
public void around(ProceedingJoinPoint point){
		执行被增强的方法
		point.proceed();
}

6.对同一个类的方法增强,使用注解@Order(数字)进行优先级判定,数字越小优先级越高

事务

事务是数据库中最小的单元,逻辑上一组操作,要么都成功,要么都失败
四大特性(ACID):
原子性:操作的最小单位,逻辑上一组操作,要么都成功,要么都失败
一致性:操作之前和操作之后,总量保持一直
隔离性:多事务操作时,不会产生影响
持久性:数据的修改是持久的
Spring事务管理
两种方式:编程式事务管理和声明式事务管理(建议使用)
声明式事务管理(底层使用AOP):
(1)基于注解方式(推荐使用)
(2)基于xml方式
Spring事务管理API
(1)提供一个接口,代表事务管理,这个接口针对不同的框架提供了不同的实现类
PlatformTransactionManager
(2)在类或者方法上添加注解@Transactional()
(3)@Transactional()中的相关参数
propagation:事务的传播行为
多事务方法之间的调用,这个过程中事务是如何管理的
事务方法:对数据库表数据进行变化的操作
Spring框架事务传播行为7种:
REQUIRED:如果方法本身有事务,调用其他方法之后,其他方法使用当前方法的里面的事务
如果方法本身没有事务,调用其他方法之后,创建新事务
REQUIRED_NEW:无论方法本身是否有事务,调用其他方法之后,创建新的事务
isolation:事务隔离级别
隔离性:多事务之间操作时不会产生影响,不考虑隔离性会出现很多问题
有3个问题:脏读,不可重复读,虚(幻)读
脏读:一个未提交的事务读取到另一个未提交事务的数据
不可重复读:一个未提交事务读取到另一个提交事务修改的数据
虚读:一个未提交的事务读取到另一个提交事务修改数据
解决问题的方式:
通过隔离级别,mysql默认使用repeatable read
在这里插入图片描述
timeout:超时时间
事务在一定时间内进行提交,如果不提交进行回滚
默认值是-1,不会超时,设置时间以秒为单位进行计算
readOnly:是否只读
默认值为false,修改为true时,只能进行查询操作
rollbackFor:回滚
设置出现哪些异常回滚
noRollbackFor:不回滚
设置出现哪些异常不回滚

SpringBoot

1.什么是springBoot

微服务

1.什么是微服务?
是一种架构风格
把一个项目拆分为多个服务,多个服务是独立运行,每个服务占用独立进程

Springcloud

1.什么是SpringCloud
springcloud并不是一种技术,是很多技术总称,很多框架的集合
springcloud里面有很多框架(技术),使用springcloud里面这些框架实现微服务的操作
springcloud,需要依赖springboot
2.springcloud版本依赖
参考网址:
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
3.什么是注册中心(nacos,Eureka,Zookeeper)
实现不同的微服务模块之间调用,把这些模块在注册中心进行注册,注册之后,实现互相调用
nacos:
comsumer(消费者)(调用方法) provider(生产者)(提供方法)
4.Feign
要求:必须在注册中心都注册,才能调用
5.Spring Cloud 在接口调用上,大致会经过哪些组件?
接口化请求调用→Fegin→Hystrix→Ribbon→http client
过程说明:在调用端创建接口,使用接口化请求调用(只是定义),Feign(服务发现)根据服务名字
找到对应的服务地址进行调用;Hystrix(熔断器),当服务端不能调用时,进行熔断;Ribbon(负载均衡)
,服务集群时负载均衡,http client(最终调用)
在这里插入图片描述

nginx

Redis

1.怎么解决事务冲突问题
悲观锁:采用锁机制,使数据只能一个线程操作,其他的必须排队,效率低
悲观锁:采用添加状态字段,多线程同时操作时,比较执行码是否一致,一致操作成功并
修改执行码(+1).
redis中采用watch监视一个或者多个key值,如果事务在执行之前这个(这些)key被其他
命令所改动,那么事务被打断.
2.事务的特点
操作指令:开启事务:multi 执行事务:exec 终止事务:discard
单独的隔离操作:事务中所有的命令序列化,按顺序执行.事务在执行过程中,不会被其他
客户端发来的命令所打断
没有隔离级别:队列中的命令没有提交之前,都不会实际执行,因为事务提交前任何指令都
不会被实际执行
不保证原子性:事务中如果有一条命令执行失败,其后的命令会被执行,没有回滚

docker

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值