日常 笔记

MD文档如何编写:
https://www.jianshu.com/p/f378e3f2e7e1

1.Spring和Springmvc的区别

Spring有两大核心AOP (面向切面) 与IOC (控制反转),可以单独用于任何应用
spring的本质是管理软件中的对象,即创建对象维护对象之间的关系
SpringMVC是基于Spring功能之上添加的Web框架
Spring MVC需要有Spring 的架包作为支撑才能跑起来,也就是想用SpringMVC必须先依赖Spring。 可以将SpringMVC类比于Struts。

Spring可以说是一个管理bean的容器,也可以说是包括很多开源项目的总称,spring mvc是其中一个开源项目

2.MVC设计模式

MVC设计模式是一种通用的软件编程思想

在MVC设计模式中认为, 任何软件都可以分为三部分组成:

(1)控制程序流转的控制器(Controller

(2)封装数据处理数据的模型(Model

(3)负责展示数据的视图(view

并且在MVC设计思想中要求一个符合MVC设计思想的软件应该保证上面这三部分相互独立,互不干扰,每一个部分只负责自己擅长的部分。

如果某一个模块发生变化,应该尽量做到不影响其他两个模块。这样做的好处是,软件的结构会变得更加的清晰,可读性强。有利于后期的扩展和维护,并且代码可以实现复用。

3.springmvc执行原理

(1).用户发送请求 至 前端控制器(DispatcherServlet);

提示:DispatcherServlet的作用:接收请求,调用其它组件处理请求,响应结果,相当于转发器、中央处理器,是整个流程控制的中心

(2).前端控制器(DispatcherServlet)收到请求后调用处理器映射器(HandlerMapping)

处理器映射器(HandlerMapping)找到具体的Controller(可以根据xml配置、注解进行查找),并将Controller返回给DispatcherServlet;

(3).前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)。处理器适配器经过适配调用具体的Controller;(Controller–> service --> Dao --> 数据库)

Controller执行完成后返回ModelAndView,

提示:Model(模型数据,即Controller处理的结果,Map) View(逻辑视图名,即负责展示结果的JSP页面的名字)

处理器适配器(HandlerAdapter)将controller执行的结果(ModelAndView)返回给前端控制器(DispatcherServlet);

(4).前端控制器(DispatcherServlet)将执行的结果(ModelAndView)传给视图解析器(ViewReslover)

视图解析器(ViewReslover)根据View(逻辑视图名)解析后返回具体JSP页面

(5).前端控制器(DispatcherServlet)根据Model对View进行渲染(即将模型数据填充至视图中);

前端控制器(DispatcherServlet)将填充了数据的网页响应给用户。

其中整个过程中需要开发人员编写的部分有ControllerServiceDaoView;

4.@Autowired和@Resource注解的区别是什么?

区别:1、@Autowired注解由Spring提供,只按照byType注入;@resource注解由J2EE提供,默认按照byName自动注入。2、@Autowired默认按类型进行装配,@Resource默认按照名称进行装配
1、@Autowired

由Spring提供,只按照byType注入

2、@Resource

由J2EE提供,默认按照byName自动注入

@Resource有两个重要的属性:name和type

Spring将@Resource注解的name属性解析为bean的名字,type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

@Resource装配顺序:

(1)如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常

(2)如果指定了name,则从Spring上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常

(3)如果指定了type,则从Spring上下文中找到类型匹配的唯一bean进行装配,找不到或找到多个,都抛出异常

(4)如果既没指定name,也没指定type,则自动按照byName方式进行装配。如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入。

5.Spring bean装配 byName跟byType的区别

1、byName会搜索整个配置文件中的bean,如果有相同名称的bean则自动装配,否则显示异常。

2、byType会搜索整个配置文件中的bean,如果有相同类型的bean则自动装配,否则显示异常。

6.什么是类型擦除

类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法。 类型擦除可以简单的理解为将泛型java代码转换为普通java代码,只不过编译器更直接点,将泛型java代码直接转换成普通java字节码。 类型擦除的主要过程如下: 1.将所有的泛型参数用其最左边界(最顶级的父类型)类型替换。(这部分内容可以看:Java泛型中extends和super的理解) 2.移除所有的类型参数。

重写与重载的区别(Overload和Override的区别)

1、重载:是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不能完全相同

2、重写:是存在子父类之间的,子类定义的方法与父类中的方法具有相同的方法名字,相同的参数表和相同的返回类型

3、重写是父类与子类之间多态性的一种表现

4、重载是一类中多态性的一种表现

7.代码块加载顺序

静态代码块 - 构造代码块 - 构造方法 - 局部代码块
1、 静态代码块:在类加载时就加载,并且只被加载一次,一般用于项目的初始化
2、 构造代码块:在调用构造方法前会自动调用,每次创建对象都会被调用 在类的内部,方法外部,的代码块。 通常用于抽取构造方法中的共性代码。
每次调用构造方法前都会调用构造代码块
4、 优先于构造方法加载
3、 局部代码块:方法里的代码块,方法被调用时才会执行
4、 静态代码块:static{ },位置:在类里方法外

8.抽象类和接口的区别

1、 通过java关键字abstract实现

2、 可以修饰方法或者类

3、 抽象类中可以没有抽象方法(由子类去实现)

4、 如果类中有抽象方法,那该类必须定义为一个抽象类

5、 子类继承了抽象类以后,要么还是一个抽象类,要么就把所有抽象方法都重写

6、 多用于多态中

7、 抽象类不可以被实例化(抽象类也有构造方法,但是不能本身实例化)
既可以有变量,也可以有常量。
抽象类里,既可以有普通方法,有可以有抽象方法。

9.接口特点
1、 接口中都是抽象方法

2、 通过interface关键字创建接口

3、 通过implements让子类来实现

4、 可以理解成,接口是一个特殊的抽象类

5、 接口突破了java的单继承的局限性

6、 接口和类之间可以多实现,接口和接口之间可以多继承

7、 接口是对外暴露的规则,是一套开发规范

8、 接口提高了程序的功能扩展,降低了耦合性
接口里是没有构造方法的。

在创建实现类的对象时默认的super(),是调用的默认Object的无参构造。
接口里没有成员变量,都是常量。所以,你定义一个变量没有写修饰符时,默认会加上:
接口里的方法,默认就都是抽象的,如果你不写明是abstract的,那会自动补齐。
4、接口和抽象类的区别!!!

-- 相同点:都是抽象层,都不能实例化                      

-- 不同点:

   -- 1、抽象类用abstract关键字描述,接口用interface

   -- 2、子类和抽象类之间是extends关系,实现类和接口之间是implements关系

   -- 3、抽象类中 可以  有构造方法 ,接口里 不能 出现 构造方法

   -- 4、抽象类里可以有 变量,接口里没有变量全都是静态的常量

   -- 5、接口里定义常量的语法:public static final String NAME="jack",会为变量自动拼接public static final

   -- 6、抽象类里 可以有普通方法  也可以有 抽象方法,接口都是抽象方法

   -- 7、抽象类和子类之间是继承关系,而且java中,只支持单继承

   -- 8、接口突破了java单继承的局限性,因为接口可以多继承也可以多实现,甚至可以继承的同时多实现

   -- 9、接口的复杂用法

       -- 多继承: interface A  extends  B,C  其中A是子接口,同时拥有自己的和BC的功能

       -- 多实现: class AImpl implements M,N,O,P 其中AImpl是实现类,需要同时重写MNOP的所有抽象方法,否则就是一个抽象类

       -- 继承的同时多实现: class AImpl extends Object implements M,N 一定是先继承后实现

10. break、continue、return 的区别:

break默认是跳出最里层的循环,也就是break所在的最近的那层循环

continue是终止本次循环,继续下次循环

return 结束当前方法

11.序列化/反序列化 目的是什么?

序列化是将对象的状态信息转换为可以存储或传输的形式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

序列化的目的

1、以某种存储形式使自定义对象持久化
2、将对象从一个地方传递到另一个地方。(方便网络传输)  
3、使程序更具维护性

假设左边的是你的电脑,也就是客户端,右边的是服务器。之前你的客户端和服务器可能都在同一个电脑上,都是 Windows 下,那么右边的服务器也可以放到 Linux 中,这就涉及到左右两个不同的服务器了。中间用一条竖线分隔一下。
客户端可以调用服务器,所以肯定要传递参数。假设你传递的是字符串,没有问题,所有的机器都可以识别正常的字符串。
那么现在假设你传递的参数是一个 Java 对象,比如叫 cat。服务器并没有那么智能,它并不会知道你传递的是一个 Java 对象,而不是其他类型的数据,它识别不了 Java 对象。

12.HashMap的实现原理:

在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树(最多是64,超多64 就会重新拆分),这样大大减少了查找时间。
  当红黑树下挂的节点小于等于6的时候,系统会把红黑树转成链表。 Node 在jdk1.8之前是插入l链表头部的,在jdk1.8中是插入链表的尾部的。
  原理:
当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,他们在数组的同一位置,但是形成了链表(同一链表上的Hash值是相同的),所以说数组存放的是链表。而当链表长度超过阈值(8)时,链表就转换为红黑树(最多是64,超多64 就会重新拆分),这样大大提高了查找的效率。

当链表数组的容量超过初始容量的0.75时,再散列将链表数组扩大2倍,把原链表数组的搬移到新的数组中

13.数据的锁定分为两种,第一种叫做悲观锁,第二种叫做乐观锁。

1、悲观锁,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以再数据开始读取的时候就把数据锁定住。(数据锁定:数据将暂时不会得到修改)

2、乐观锁,认为数据一般情况下,不会造成冲突,所以再数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误信息。让用户决定如何去做。
实现方式:
悲观锁:select status from table where id=1 for update;(select语句末尾加for update)
乐观锁:利用版本号version

14.如何查看Mysql执行计划

执行计划:就是解释select语句如何在数据库执行的、相关表是怎么连接、连接的次序、有哪些索引和索引使用情况、每个表的扫描数据量等等。 简单来说,就是通过数据来分析select语句的执行情况;

怎么查看执行计划:查看执行需要用到关键字EXPLAIN,将EXPLAIN放在SQL语句的前面(explain select * from table)

15.union all和union的区别?

union all:两个以上表连接查询不去重不排序。
union:两个以上表连接查询去重,排序。

16.Truncate和Delete的区别是?

区别1:delete逐条删除,truncate整个表截断即删除表中所有记录。(当确定一张表的数据不再使用,应该使用truncate)
区别2:最根本的区别是:delete是DML(数据操纵语言,可以回滚)truncate是DDL(数据定义语言,不可以回滚)
区别3:Delete需要事务删除大量数据的时候速度慢,Truncate不需要事务,删除大量数据快
区别4:Delete不会释放空间,truncate会
区别5:delete会产生碎片,truncate不会。

17.SQL去重distinct方法

用法注意

1.distinct 【查询字段】,必须放在要查询字段的开头,即放在第一个参数;
2.只能在SELECT 语句中使用,不能在 INSERT, DELETE, UPDATE 中使用;
3.DISTINCT 表示对后面的所有参数的拼接取 不重复的记录,即查出的参数拼接每行记录都是唯一的
4.不能与all同时使用,默认情况下,查询时返回的就是所有的结果。

1.1只对一个字段去重
对一个字段查重,表示选取该字段一列不重复的数据。
1.2多个字段去重
对多个字段去重,表示选取多个字段拼接的一条记录,不重复的所有记录

18.如何创建.调用一个存储过程

在这里插入图片描述
DELIMITER $
CREATE PROCEDURE GetAllProducts()
BEGIN
SELECT * FROM products;
END $
DELIMITER ;
用关键词 create ,procedure begin end
2,存储过程调用方法
CALL GetAllProducts();

19.oracle死锁怎么解决

查看哪个用户哪个进程造成死锁

select b.owner, b.object_name, l.session_id, l.locked_mode
from v$locked_object l, dba_objects b
where l.OBJECT_ID = b.OBJECT_ID

查看哪个session引起的

select b.username,b.sid,b.serial#,logon_time
from v l o c k e d o b j e c t a , v locked_object a,v lockedobjecta,vsession b
where a.session_id = b.sid order by b.logon_time;
在这里插入图片描述

杀掉锁表的进程

alter system kill session ‘1260,40264’;

20.Final、Finally、Finalize的区别?

final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally:作为异常处理的一部分,它只能用在try/catch语句中 只有与finally对应的try语句块得到执行的情况下,finally语句块才会执行
finalize:Object 类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。这是一个被动的方法(其实就是回调方法),不需要我们调用。

21.反射获取class对象的方式

1:对象.getClass()
如果拿到了对对象,不知道是什么类型,用于获得对象的类型,
Object obj = new Person();
Class clazz1 = obj.getClass();
弊端:必须要创建该类对象,才可以调用getClass方法。

2:类名.class
如果是明确地获得某个类的Class对象 主要用于传参
弊端:必须要先明确该类。

前两种方式不利于程序的扩展,因为都需要在程序使用具体的类来完成。

3:Class.forName(“全路径”);
根据给定的类名来获得 用于类加载使用的Class类中的方法,静态的forName()方法。
指定什么类名,就获取什么类字节码文件对象,这种方式的扩展性最强,只要将类名的字符串传入即可。

22.Redis持久化 RDB和AOF

(1).RDB模式

特点:
1.RDB模式是redis默认的持久化规则

2.RDB模式记录的是Redis内存数据快照(只保留最新数据)

3.RDB模式定期持久化(时间可调)可能会导致数据丢失

4.RDB模式备份效率是最高的

5.RDB模式备份阻塞式的 在备份时不允许其他用户进行操作,保证数据安全性

命令:

  1.主动备份  save  会阻塞用户操作

  2.后台备份 bgsave  异步的方式进行持久化操作  不会阻塞

(2).AOF特点

1.AOF模式默认条件下是关闭状态,需要手动开启

2.AOF模式记录的是用户的操作过程,可实现实时持久化,保证数据不丢失

3.AOF模式维护的持久化文件占用的空间较大,所以持久化效率不高,并且需要定期的维护持久化文件

4.AOF模式一旦开启,则redis以AOF模式为主,读取的是AOF文件

appendonly yes   #打开AOF
appendfilename "appendonly.aof" # 持久化文件的名字
# appendfsync always	# 每次修改都会同步,消耗性能
appendfsync everysec	# 每秒都同步一次 sync,可能会丢失这1s数据
# appendfsync no		# 不执行同步,这时候操作系统自己同步数据,速度最快

23.spring如何控制事务

利用@Transactional注解和@EnableTransactionManagement注解

@Transactional注解要生效的话,需配置@EnableTransactionManagement,不过如果是使用SpringBoot的话,就可以不需要了
@Transactional注解应该只被应用到public方法上,这是由Spring AOP的本质决定的
@Transactional 注解控制事务有哪些不生效的场景:
数据库引擎不支持实物
数据源没有配置事务
方法本身不是public的
被异常吃了:被异常catch住了,又没有扔出来

24.int和Integer的区别

1、Integer是int的包装类,int则是java的一种基本数据类型
2、Integer变量必须实例化后才能使用,而int变量不需要
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
4、Integer的默认值是null,int的默认值是0

25.线程池的七个参数

一、corePoolSize 线程池核心线程大小
二、maximumPoolSize 线程池最大线程数量
三、keepAliveTime 空闲线程存活时间
四、unit 空闲线程存活时间单位
五、workQueue 工作队列
六、threadFactory 线程工厂
七、handler 拒绝策略

26.数据库三大范式

1.所有字段值都是不可分解的原子值
2.一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中
3.每一列数据都和主键直接相关,而不能间接相关。

27.为什么推荐使用整型自增序列作为主键

对InnoDB来说为了保持B+树的平衡,用整型,而且是递增的整型。这样在存储/查询上都是非常高效的。

nginx

  1. 启动nginx 服务器 start nginx 没有报错提示
  2. 重启nginx 服务器 nginx -s reload
  3. 关闭nginx 服务器 nginx -s stop

分布式事务

分布式事务顾名思义就是要在分布式系统中实现事务,它其实是由多个本地事务组合而成。

对于分布式事务而言几乎满足不了 ACID,其实对于单机事务而言大部分情况下也没有满足 ACID,不然怎么会有四种隔离级别呢?所以更别说分布在不同数据库或者不同应用上的分布式事务了
2PC
2PC(Two-phase commit protocol),中文叫二阶段提交。 二阶段提交是一种强一致性设计,2PC 引入一个事务协调者的角色来协调管理各参与者(也可称之为各本地资源)的提交和回滚,二阶段分别指的是准备(投票)和提交两个阶段。

让我们来看下两个阶段的具体流程。

准备阶段协调者会给各参与者发送准备命令,你可以把准备命令理解成除了提交事务之外啥事都做完了。

同步等待所有资源的响应之后就进入第二阶段即提交阶段(注意提交阶段不一定是提交事务,也可能是回滚事务)。

假如在第一阶段所有参与者都返回准备成功,那么协调者则向所有参与者发送提交事务命令,然后等待所有事务都提交成功之后,返回事务执行成功。

让我们来看一下流程图。

假如在第一阶段有一个参与者返回失败,那么协调者就会向所有参与者发送回滚事务的请求,即分布式事务执行失败。

那可能就有人问了,那第二阶段提交失败的话呢?

这里有两种情况。

第一种是第二阶段执行的是回滚事务操作,那么答案是不断重试,直到所有参与者都回滚了,不然那些在第一阶段准备成功的参与者会一直阻塞着。

第二种是第二阶段执行的是提交事务操作,那么答案也是不断重试,因为有可能一些参与者的事务已经提交成功了,这个时候只有一条路,就是头铁往前冲,不断的重试,直到提交成功,到最后真的不行只能人工介入处理。

怎么保证redis和数据库的数据一致性

最初级的缓存不一致问题及解决方案:

采用 cache aside pattern 并发更新操作的时候可以先删除缓存,然后更新数据库。
此方案下的更新操作情况:
删除缓存失败,那么不会去执行update操作。
删除缓存成功,update失败,读请求还是会将旧值写回到redis中。
删除缓存成功,update成功,读请求会将新值写回到redis中。
缓存和数据库一致性解决方案
1.第一种方案:采用延时双删策略
在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。
伪代码如下

public void write( String key, Object data )
{
    redis.delKey( key );
    db.updateData( data );
    Thread.sleep( 500 );
    redis.delKey( key );
}

2.具体的步骤就是:
先删除缓存
再写数据库
休眠500毫秒(根据业务设置时间)
再次删除缓存
参考:https://www.cnblogs.com/Zhengxue/p/13336421.html

mysql 索引失效的7种情况

1.条件有or
2.复合索引未用左列字段;
3.like以%开头;
4.需要类型转换;
5.where中索引列有运算;
6.where中索引列使用了函数;
7.如果mysql觉得全表扫描更快时(数据少)

myisam和innodb的区别

1.InnoDB 支持事务,支持外键 而 MyISAM 不支持
2.InnoDB 是聚集索引,MyISAM 是非聚集索引
3.InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁
MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值