框架综合总结
MyBatis 是一个优秀持久框架,实现了对JDBC的封装,请问具体了封装了什么
本质上是实现对JDBC操作规范(java.sql)的封装,例如:
- Connection对象创建?(PooledDataSource)
- JDBC事务处理:JdbcTransaction
- Statement对象的创建及应用
- SQL参数映射(为"?"问号赋值)
- ResultSet结果集的处理?
Mapper接口方法中@Param注解的作用
使用@Param("参数名")注解修饰的参数,可以将其参数名作为key,参数的实际值作为value存储到一个map对象,后续在SQL语句中可以使用#{参数名}获取map中的参数值.
添加lombok插件
- 安装的sts位置,必须是英文全路径
- 可以简化set,get方法的添加
- 可以自动添加hashcode(),equals(),toString()
使用map直接封装数据有什么缺陷
- 值的类型不可控
- 可读性较差
但是为什么要使用map对象
- 因为使用map的速度是很快的
AOP编程中有五种类型的通知
- @before
- @AfterReturning
- @AfterThrowing
- @After
- @Around
其中环绕通知的优先级最高,同时也是最重要的一个通知
不使用shiro框架如何完成认证操作
filter,interector
过滤器 ,拦截器
含有@Value注解的变量,从哪里进行取值
表面上是从配置文件中进行取值,实质上是从spring容器中进行取值
SpringMVC的运行原理
- 浏览器发送请求,并在过滤链过滤后,经由前端控制器.
- 前端控制器会找到注册中心,找到对应的controller(map的使用)
- 目标controller执行完业务后,将返回一个modelandview对象交给前端控制器
- 前端控制器通过视图解析器找到对应的视图对象
- 视图对象进行渲染,并返回到浏览器
DI和IOC的区别
提到区别,先说联系:DI注入依赖于IOC容器,DI是IOC的实现
区别:DI是根据IOC创建对象后,为对象进行注入属性值
IOC是站在容器角度,为所需要的资源进行创建和管理
反向代理和正向代理
- 反向代理的原理:(由代理服务器去访问真实的资源)
- 用户请求获取资源,给代理服务器
- 代理服务器去访问真实的资源
- 并将最终资源返回给用户
- 特点:用户无需知道资源的真是地址
- 正向代理的原理:(由用户自己访问真实的资源)
- 用户请求获取资源,给代理服务器
- 代理服务器返回给用户真实的地址
- 用户直接访问真实的地址访问资源
- 优点:可以提高网站性能,支持更高并发请求
- 区别:nginx反向代理代理的是服务器,正向代理代理的是客户端
- 主进程:提供方向代理服务
- 守护进程:防止主进程意外关闭
Nginx负载均衡的策略
以下为三种不同的选择方式
- 轮询策略
根据配置文件的顺序,以此访问tomcat服务器 - 权重方式(旧的公司)
需求:公司中服务器可能会更新迭代,导致物理设备处理能力不同.(好的服务器运行快,旧服务器运行慢),这时,采用轮训的机制,会影响用户的体验 - IP_HASH(了解)
- 好处:采用ip的哈希测量,利用用户的ip地址进行哈希运算,之后与服务器进行动态地绑定,变相地实现了session的共享.
- 坏处:
- 会导致严重的负载不均问题
- 如果其中一台服务器宕机,将直接影响被绑定的用户
mybatis-plus
mybatis-plus并不适用于海量数据库访问(因为其底层使用了太多的反射机制)
序列化cache的实现
(参考MyBatis中SerializedCache)
为什么写到缓存中的对象要序列化
原因:获取时能拿到对象的拷贝,以保证缓存中对象的线程安全
如果每个线程拿到的是相同的对象,那么会造成线程的不安全
jetty和tomcat的各自擅长处
- 相同点:
- jetty和tomcat都是一种servlet引擎,他们都支持标准的servlet规范和javaEE的规范
- 两者的性能方面差异不大
- 不同点:
- jetty的架构是基于Handler实现的,而tomcat的架构是基于容器来设计的.
- jetty更擅长于多连接,且要长时间保持连接的情况,适合于web聊天应用等等.
- tomcat更适用于少连接,且非常繁忙的情况.
- jetty默认采用NIO技术,在IO请求上更占优势,在处理静态资源的时候,性能较高
- tomcat默认采用BIO处理IO请求,在处理静态资源的时候,性能较差
java中代理模式的分类
代理模式分为三种:
- 静态代理
代理对象和被代理对象都要实现同一个接口,但是被代理对象和代理对象却是一一绑定的,这样的代理模式并不机动. - 动态代理
- jdk动态代理
jdk自带的代理模式,创建一个代理模式工厂,对想要进行代理的对象创建响应的代理对象,
但是想要被代理的对象仍然要实现一个接口,所以使得非接口对象无法创建其代理对象 - Cglib代理
第三方框架的代理模式,可以对非接口类型的对象创建其代理对象.
- jdk动态代理
- 三大框架中的:
- Mybaits的代理模式用的是jdk自带的框架
- Spring的代理模式用的是CGlib自带的框架
Redis中的持久化策略:
- RDB模式:redis中默认的持久化策略
- 特点:定期持久化
- 缺点:可能会丢失数据
- 优点:
- 效率高
- 数据恢复时间短
- 定期做内存数据的快照
- 持久化文件较小
- 持久化的命令:
- save :阻塞式的持久化操作(将数据存入到文件的时候,不能存入/删除redis数据)
- bgsave:非阻塞式的持久化操作,在后台单独执行持久化操作(不能准确的了解什么时候执行完成)
- AOF模式
- 特点:
- 默认条件下是关闭的状态
- AOF模式记录用户的操作过程,持久化文件大,恢复数据的时间长
- 记录操作过程是异步的
- 优点:可以实现实时持久化(不丢数据)
- 缺点:效率低
- 特点:
------------------两种策略方式是可以同时存在的,但是有优先级,AOF优先----------------------------------
- 前者记录内存的数据状态,后者记录用户的操作过程(更新操作)
- RDB是从dump.RDB文件中进行的持久化
- 一般当存在主从关系的时候,主机一般都会使用RDB模式进行数据的持久化,而对应的从机一般都会使用AOF来进行持久化
对象序列化
- Tomcat中session对象的序列化
- Mybatis中的二级缓存(Serializedcache)
- RPC(远程过程调用)
使用mybatis访问数据库什么时候建立的连接Connection
真正建立连接的时候是执行insert或者update方法的时候(执行具体操作的时候)
真正控制(提交,回滚)事务的是:Connnection
AnnotationConfigApplicationContext相比于ClassPathXmlApplicationContext的优缺点?
- xml配置的缺点:xml的配置文件的学习门槛越来越高,xml文件不能做类型检查
- 注解配置的优点:而注解相比与xml文件的可读性和可维护性远高,新手接手项目的门槛大大降低
MyBatis 核心API 应用分析?
- SqlSessionFactoryBuilder
建造者:负责创建会话工厂 - SqlSessionFactory对象?
- 会话工厂对象:应用全局唯一 (单数据源)
- 线程安全
- 可共享
- SqlSession对象?
- 会话对象:(负责与数据库进行会话)
- 线程不安全
- 不可共享(每个线程一份)
MyBatis
- 什么是Mybatis?
- Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程.
程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高.
将面向对象语言程序中的对象自动持久化到关系数据库中.本质上就是将数据从一种形式转换到另外一种形式.- 以面向对象的方式操作数据库,但是mybatis并没有实现
- 从结果集来实现对用户想要对象的封装.
- MyBatis以使用XML或注解来配置和映射原生信息,将POJO映射成数据库中的记录,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集.
- 通过xml文件或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回.(从执行sql到返回result的过程).
- Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程.
- Mybatis的优点
- 基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;
- 提供XML标签,支持编写动态SQL语句,并可重用.
- 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
- 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持).
- 能够与Spring很好的集成;
- 提供映射标签,支持对象与数据库的ORM字段关系映射;
- 提供对象关系映射标签,支持对象关系组件维护.
- Mybatis的缺点
- SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求.
- SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库
- MyBatis与Hibernate有哪些不同
- Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句.
- Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,
- 因为这类软件需求变化频繁,一但需求变化要求迅速输出成果.
- 但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大.
- Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率.
- #{}和${}的区别是什么?
- #{}是预编译处理,${}是字符串替换.
- Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
- Mybatis在处理时,就是把{}替换成变量的值.
- 使用#{}可以有效的防止SQL注入,提高系统安全性.
- 当实体类中的属性名和表中的字段名不一样,怎么办?
- 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致
- 通过来映射字段名和实体类属性名的一一对应关系
- 在dao层中的方法参数添加@param注解
- 通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
- Dao接口即Mapper接口.接口的全限名,就是映射文件中的namespace的值;
- 接口的方法名,就是映射文件中Mapper的Statement的id值;
- 接口方法内的参数,就是传递给sql的参数.
- Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MapperStatement.
- 在Mybatis中,每一个select、insert、update、delete标签,都会被解析为一个MapperStatement对象.
举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id为findStudentById的MapperStatement. - Mapper接口里的方法是不能重载的,因为是使用全限名+方法名的保存和寻找策略.
- Mapper接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Mapper接口生成代理对象proxy,代理对象会拦截接口方法,转而执行MapperStatement所代表的sql,然后将sql执行结果返回.
- Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
- 使用标签,逐一定义数据库列名和对象属性名之间的映射关系.
- 使用sql列的别名功能,将列的别名书写为对象属性名.有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的.
- 如何获取自动生成的(主)键值?
- insert方法总是返回一个int值,这个值代表的是插入的行数.
- 如果采用自增长策略,自动生成的键值在insert方法执行完后可以被设置到传入的参数对象中.
- 在mapper的insert标签中添加两个属性:
- usegeneratedkeys=“true”
- keyproperty=“id”
- Mybatis动态sql有什么用?执行原理?有哪些动态sql?
- Mybatis动态sql可以在Xml映射文件内,以标签的形式编写动态sql,执行原理是根据表达式的值完成逻辑判断并动态拼接sql的功能.
- Mybatis提供了9种动态sql标签:
- trim
- where
- set
- foreach
- if
- choose
- when
- otherwise
- bind.
- 为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
- Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的.
- 而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具
- 多对一association,一对多collection
- Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
- Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一(多)对一,collection指的就是一对多查询.
- 在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false.
- 它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法;
比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),
于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用.这就是延迟加载的基本原理.
- Mybatis的一级、二级缓存:
- 一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当Session flush或close之后,该Session中的所有Cache就将清空,默认打开一级缓存.
- 二级缓存与一级缓存其机制相同,默认也是采用PerpetualCache,HashMap存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如Ehcache.(可跨SqlSession是缓存数据共享的)
说明:二级缓存,可以跨多个SqlSession共享数据,假如需要线程安全,我们的缓存设计及配置需要在线程安全方面进行控制.
默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/ > - 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了C/U/D操作后,默认该作用域下所有select中的缓存将被clear.
Spring是一个资源整合框架
- spring框架中一切资源的整合都源于IOC模块
- IOC是一种设计思想,IOC要实现对象生命周期的管理,对象依赖关系的管理
- IOC:我们把对象的创建,管理的控制权都交给spring容器,这就是一种控制权的反转
- 我们可以说spring容器是IOC容器,而不能说IOC容器就是spring容器
- ApplicationContext是一维护Bean定义以及对象之间协作关第的高级接口.
- Spring IOC的核心组件
- ApplicationContext
- BeanFactory
- spring中有两大map:(IOC中的两大容器)
- 用于保存定义信息的map
- 谁是key,谁又是value
- Map<String,BeanDefinition>
- 用于实现对象的单例设计的bean池
- 而为什么设计这种单例设计呢:节省内存
- Map<String,Bean>
- spring容器中注解bean,所注解的方法,key为对应的bean注解对应的value值,若不设置值则为方法名(首字母小写),对应的value值为方法的返回值类型
- 传统Spring项目整合的诟病
- 配置相对复杂
- 依赖冲突严重
- 扩展相对复杂
- Spring中的两大功能:
- spring如何管理我们的对象?
- spring 通过超大的Map集合管理对象.
- K:xml中bean的id/bean注解的方法名
- V:实例化后的对象
- 对象的生命周期有多久?
- 单例对象:理论上与容器的周期一致,这是因为单例对象要被放在bean池(容器)中进行管理
要求:容器中对象的key,要求必须唯一 - 多例对象:当用户使用的时候进行创建
为了扩展业务,在切面中实现了解耦
- 单例对象:理论上与容器的周期一致,这是因为单例对象要被放在bean池(容器)中进行管理
- AOP:切面的构成要素:
- 切面:切入点+通知
- Aop是一种设计思想
- AOP就是要基于OCP(开闭原则)在不改变原有系统核心业务代码的基础上,动态地添加一些扩展 功能并可以’控制’对象的执行(例如权限控制)(解决的是一种非核心业务问题)
- OCP原则:允许扩展代码,但是不允许修改代码
- 非核心关注点如何切入到系统中?
- 硬编码(违背了开闭原则,也难以提高代码的可维护性),
- AOP面向切面编程
- spring如何管理我们的对象?
- ApplicationContext和BeanFactory的区别和联系
- 联系:BeanFactory和ApplicationContext是Spring的两大核心接口,ApplicationContext间接继承了BeanFactory
- 区别:
- BeanFactory是Spring容器中的顶层接口.
- ApplicationContext是它的子接口.
- 两者创建对象的时间点不同,BeanFactory什么时候使用什么时候创建对象
ApplicationContext是只要一读取配置文件,就会进行创建对象
也就是后者延迟加载,前者不延迟加载
- spring中提供了两种事务管理方式:
- 编程式事务
- 声明式事务:
- 在xml中做相关的事务规则声明
- (2)基于@Transactional注解的方式 也就是在配置文件中进行声明,通过AOP将事务切面切入程序,最大的好处是大大减少了代码量.
- spring的优点
- 低侵入式
- 提供了对其他开源框架的整合机制
- AOP,可以提供事务,日志,或权限的控制
- IOC,将对象之间的依赖关系交给了spring容器,方便解耦,简化了开发
- 单例对象什么时候被销毁?多例对象什么时候被销毁?
- 单例对象的生命周期是和spring容器同生共死的,当spring容器的生命周期结束,该单例对象的生命周期也就此完结 (故想要让spring容器管理bean的生命周期,则该bean对象必须为单例对象) (且延迟加载仅针对于单例作用域对象,这就造成了@Lazy和@prototype两个注解不能够同时存在)
- 多例对象的生命周期是和相应的线程相关的,当前线程结束,则该多例对象的生命周期就此结束. (当对象长时间不用,并没也没有其他对象引用时,将会被gc回收)
| -------------------------------------
|(1)单例对象(与容器共存亡):
| 出生:容器创建出生对象
| 活着:只要容器存在,对象就一直活着可用
| 死亡:容器销毁,对象消亡
|(2)多例对象:
| 出生:每次调用时,容器会为我们创建对象
| 活着:只要对象在使用过程中,就一直活着可用
| 死亡:当对象长时间不用,并且也没有其他对象引用时,由java的垃圾回收器回收(非常精明的,交给了JVM的GC)
| --------------------------------------
component的使用介绍:
在持久层、业务层和控制层分别采用@Repository、@Service和@Controller对分层中的类进行凝视,而用@Component对那些比较中立的类进行凝视
因为不好说这个类属于哪个层面.就用@Component
用户行为日志
- 用户行为日志的写入?
运用的AOP原则 - 遇到过什么问题?
同步还是异步进行.
异步可能会有什么问题?不断地创建线程对象可能会导致内存溢出.怎么解决?自己写一个线程池
同步可能会遇到什么问题?导致线程阻塞.
redis雪崩
- 定义:当被设定了过期时间的key,到达过期时间的时候,此时到来了高并发的访问key,那么这些key会直接去访问数据库
数据库在高并发的压力下,会直接被打死,那么这样的现象就称之为redis雪崩现象. - 如何解决:为了防止发生redis雪崩,我们可以对设置过期时间的key的时间进行随机设定,这样防止当过期的时候,大批的key
发生过期淘汰,进而防止大规模的key去访问数据库,防止数据库被打死(如果其中的key访问频繁,则可以每次访问加一点时间)
redis穿透
- 定义:当高并发的数据去访问原本数据库不存在的数据的时候(redis中也不会存在),那么,将直接访问数据库,数据库在高并发的情况下,会被直接打死.
- 如何解决:我们可以设置一个set集,里面包含了访问的数据的主键,放在redis中,当访问的时候,在redis查找,如果没有,则返回null.
redis集群
- 不同于其他集群,其他集群当超过半数的集群宕机,则整个集群崩溃
但redis集群,有其从机的迁移机制,可以远远超过宕机一般的台数,仍然保持redis集群的使用,但是此时redis集群处于高危的状态 - 集群可使用的前提条件:
当前存活服务器的数量>n(整个集群数量)/2
(最小集群规模3台)
3-1 = 2 >1.5 true 最小集群规模3台 可以宕机1台
4-1 = 3 >2 true 4台可以搭建集群 可以宕机1台
为什么是奇数台?
因为搭建奇数台与搭建偶数台,都是可以进行工作的,奇数台可以宕机1台,但是搭建偶数台还是可以宕机1台,所以想要提高资源的利用率,搭建集群都是使用的奇数台的服务器 - 为什么要搭建redis集群?
为了提高网页的响应速度,把热点数据保存在内存中,而不是直接从后端数据库中进行读取 - redis集群使用的CRC16算法
redis的过期策略
为什么要使用过期策略? 答:因为redis工作的位置是系统的内存,内存总是有大小限制的,当存入的数据即将达到系统的内存,那么已经存在的数据,和即将还要继续写入的数据之间,必须有一种算法来解决这样的问题.
有哪些过期策略?
- 定期删除
redis每隔一定时间就抽取一些设置了过期时间的key,检查其是否过期,过期就进行删除
缺点:仍然会有哪些过期了的key,但是扔没有被扫描到的key, - 惰性删除
在获取某个key的时候,redis会检查一下,如果该key设置了过期时间,并且已经过期了,那么直接删除,返回空;
若未过期,将执行原本的操作- 缺点:仍然会有过期了的,但是并没有进行调用的key,暂存在键空间内,占用着系统内存.
那么怎么办?
redis会有着内置的淘汰算法.LRU,LFU等等
LRU:最近最少使用(热点)
LFU:最不经常使用(次数)
过期策略和淘汰算法的结合,保证了redis实现缓存的高质量使用
- 缺点:仍然会有过期了的,但是并没有进行调用的key,暂存在键空间内,占用着系统内存.
redis分片:
redis的作用:实现内存的扩容(redis分片机制性能是最高的!因为里面的算法(哈希一致性算法)是根据tomcat服务器中进行的,而其他的哨兵机制,则是在redis缓存中进行的)
哨兵机制&心跳检测(前提是必须存在主从关系)
原理:
- 哨兵主要根据IP地址和端口号来监听主机,并且记录主机全部的从机信息,
- 哨兵利用ping-pang机制来判定当前主机是否存活,如果三次没有响应,则视主机为宕机,则由哨兵进行选择新的主机
- 哨兵修改从机的配置文件,修改该redis的其他机器的配置文件,实现新的主从关系(防止出现多主的现象)
目的:实现高可用(HA) - 首先有主从结构.
- 当主机发生了宕机的现象,则可以自动地实现故障的迁移.(找从属的服务器代替其维护)
脑裂现象
发生原因:选举主机的时候,连续出现相同的票数
那么怎么降低:增加主机的个数
(1/2)^n 出现脑裂现象的概率
SpringMVC 是前台框架与用户进行交交互
- MVC是一种分层架构设计思想,目的是基于对象职责上的不同,实现其各司其职,各尽所能,以提高代码的可扩展性,可维护性.
- 对应的requestmapping的url地址和文件路径,将被注册中心进行注册,并将其相应注册为key和value存入到map集合中
- 底层将servlet进行了封装,简化了程序员的操作过程;
- springMVC的五大核心组件:
- DispatcherServlet 控制器入口:负责分发请求
- HandlerMapping 负责根据请求,找到对应的控制器
- Controller 真正处理请求的控制器
- ModelAndView 封装数据信息和视图信息的
- ViewResolver 视图处理器:通过处理找到对应的界面
- MVC中controller层参数对象赋值的原理?
- 从该参数类型的get方法中,去掉get,并将首字母进行小写,得到多个参数名
- 先从前端页面request.getParameter(参数名),获取到对应参数的参数值
- 在运用,通过反射获得的该类型实例的set方法,将对应的参数值赋值给该对象的属性
- springMVC的优点和缺点?
- 优点:
- 与spring实现了无缝衔接
- 实现了各司其职,各尽所能,使得我们开发更加简洁
- 优点:
延迟加载的作用:
延迟加载的作用是:提高性能,不用将程序未使用到的功能加载到内存
springboot框架
- 特点:
- 几乎实现了零配置制
- 内部定义了jar包的版本依赖
- 内置了tomcat服务器
- springboot内部拥有自动化的配置
- 核心:
- 内部封装了spring的全部
- 自动配置
- 起步依赖
- 健康检查
- springboot的优点?缺点?
- 优点:
- 快速整合第三方框架,无需配置文件
- 避免了编写大量的样板代码,注释和xml配置
- 内嵌了http服务器,可以容易快速的测试,无需外部依赖servlet容器
- 提供了很多插件
- 提供了运行时的应用监控
- 快速构建项目
- 缺点:仅仅适用于全新的spring项目,对于传统的项目而言,是非常困难和耗时的
maven进行传输数据的时候是如何保证安全性的?
运用了Sha1算法(安全的哈希算法)
Sha1会产生一个160位的消息摘要.当接收到消息的时候,这个消息摘要可以用来验证数据的完整性.
为什么cglib方式可以对接口实现代理
因为cglib动态代理利用的是asm开源包,加载目标对象的class文件,并通过修改其字节码生成子类来进行处理.(故此目标对象一定不能由final修饰)
数据一致性问题如何解决?
但凡更新数据,同步更新缓存
(redis)你对哈希一致性算法有多少了解?
哈希值有多少位? 32位16进制的数(也就是2的128次方)
hash:无论计算的数据多大,都能获取一个32位的数据,且时间复杂度为o1
- 首先会将哈希值组成一个哈希环,下面将根据不同节点,不同请求来计算hash值
- 首先计算节点ip地址对应的hash值,并分布在不同的hash位置,并开始计算每次请求的对应的hash值
- 节点和相关的hash值形成了映射,每次请求和相关的hash值也会形成映射
- 按照顺时针的机制,下一个节点为执行该请求的节点
提出疑问:这样会不会存在负载以及分散问题?
- 会
怎么解决的?
- redis会根据负载不均的情况,来对应引入虚拟节点,来平衡,但不会存在完全的公平
- 均衡性(虚拟节点):为了让数据尽可能分配到各节点中
- 问题(1防止某个节点发生宕机,2存不下数据)
- 解决:哈希算法,会触发均衡性,引入虚拟节点进行平衡数据(但是没有绝对的公平)
- 单调性:当节点新增的时候,可以自动实现数据的迁移
- 问题(但是节点少了并不能进行数据迁移)节点缺失导致内存缺失,可能会导致分片不可用
- 分散性:由于分布式部署,某些服务器不能获取全部的内存空间,导致一个key出现在多个位置
- 负载:由于分布式部署,某些服务器不能获取全部的内存空间,导致多个数据保存同一个位置
(尽可能让全部的服务器使用同一块内存,可以有效降低分散性和复杂性)
过滤器和拦截器的区别
- 拦截器时基于java反射实现的,而过滤器是基于函数回调实现的
- 拦截器不依赖于servlet容器,而过滤器依赖于servlet容器
- 拦截器只对action起作用,过滤器可以对任何请求起作用
- 在action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化的时候调用一次
- 拦截器可以获取IOC容器中的各个bean,而过滤器不行
嵌套的ajax为什么不显示?
被外层的ajax所覆盖,内层的ajax没有进行刷新数据
只能让其与外层的ajax实现同步刷新
故解决ajax嵌套的问题,则将内层的ajax设置为同步请求(多次刷新合并为一次)
JSONP实现跨域请求的原理
利用的就是scrpit标签中的src属性没有同源限制的漏洞
nginx重启时,用户怎么办?
这样的需求不用处理,这是因为nginx启动/重启异常快速,实现秒起/秒停
(一般挑选访问量小的时间完成线上的部署)
同源策略
规定:如果请求协议名称://域名:端口号都相同,那么则表示满足同源策略,可以正常地访问
反之是:跨域访问,浏览器将不予解析返回值
跨域工具:
- CROS 配置繁琐,但可以实现跨域访问
- JSONP(json and Padding)违反同源策略
- 也可以使用Dubbo框架
httpClient与JSON总结
- httpClient
- 首先,httpclient是一个接口,是一个用来跨项目访问的中间件.
- 可以在java端访问任何的远程资源(不是跨域访问),可以访问任何的远程服务器资源
- 可以用来?
- 访问远程资源
- 调用第三方接口
- 且调用的时候可以保证数据的安全性(让用户只知道访问的是当前家的资源,而可以实际上访问其他位置的资源)
- JSONP
- 可以实现主流浏览器跨域(违反同源策略)访问问题
- JSONP只支持Get请求类型
- 安全性较低
- JSONP是游览器解析ajax发起的请求
- 一般适合查询一些简单数据
cookie跨域
cookie不能跨域名进行共享(在一般情况下),但是可以设置其访问范围
RPC和HTTP协议的区别
- RPC是是传输层协议(第四层),而http协议是应用层协议(第七层)
- RPC协议可以直接调用中立接口,HTTP协议不可以.
- RPC通信协议是长链接,http一般采用短连接,需要进行三次握手
- RPC协议传递数据是加密压缩传输.HTTP协议需要传递大量的请求头信息.
- RPC协议一般都有注册中心.有丰富的监控机制.
http请求的过程
在OSI网络模型的基础上.即
- 物理层
- 数据链路层
- 网络层
- 传输层
- 会话层
- 表示层
- 应用层
有七步来完成http的请求: - 建立连接
- 接收请求
- 处理请求
- 访问资源
- 构建响应报文
- 发送响应报文
- 记录日志
单点登录的原理?(使用redis)
- 用户发起请求,前台服务器将用户的账号密码与后台服务器进行校对
- 若账号密码正确,后台服务器将返回给前台服务器一个秘钥,并将该秘钥通过cookie保存到用户的浏览器中
- 与此同时后台服务器将用户的信息进行脱敏处理,并将其转化为json串,保存在redis缓存中
- 当用户第二次进入页面时,其浏览器内的cookie会与对应的redis缓存中的数据进行查询,如果存在,则会实现用户信息的确认,用户不再进行登录的操作
dubbo的负载均衡策略?(就是消费者寻求提供者的过程)
- 随机策略(默认)
基于权重的随机负载均衡机制 - 轮询策略(权重),此方式不推荐
基于权重的轮询负载均衡策略(根据不同的权重,可以计算出落在每台服务器上的概率) - hash方式
一致性hash,相同参数的请求总是发到同一个提供者
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动. - 最小连接
最少活跃调用数(活跃数指调用前后计数差)
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大
从机作为:故障迁移,高可用,数据备份
Zookeeper集群中,leader负责监控集群状态,
follower主要:
- 负责数据的同步,将来要保证数据的一致性(读从,写主)
- 同时参与投票.(ZooKeeper是强一致性的CP)(Eureka为AP)
客户端读follower,因为主机负责整个集群状态的维护,从机负责数据的同步,以保证数据的一致性
但是zooKeeper满足CP原则,在进行数据的同步时,不允许客户端读写,程序阻塞
ZooKeeper是怎么存储数据的
- 以树形结构存储,形式:
- 先是根目录,/
- 后是用户定义的节点名称
- 后是全部接口的路径
- 后是 每一个接口下面都会有对应的生产者和消费者
- 而每一个生产者或是消费者都有其各自的详情信息
如果zooKeeper宕机,dubbo框架能否正常运行
不会有太大影响,因为我们的消费者启动的时候,已经将ZooKeeper中的服务列表数据,保存到消费者本地中,所以即使zooKeeper宕机,也不会有太大的影响
ZooKeeper负责服务的协调调度(注册中心)(正向代理)
微服务注册中心,工作原理
调用步骤:
- 当服务提供者启动时,将服务名称:IP:端口 写入注册中心
- 当注册中心接收提供者的写入请求时,会动态维护服务列表数据
- 当消费者启动时会连接注册中心,获取注册中心的服务列表数据保存到本地
- 当用户进行业务请求时,会通过消费者获取对应服务端(提供者)的数据,
- 注册中心有心跳检测机制,当连续三次没有任何响应,则断定当前服务器宕机,首先更新注册中心本地的服务列表数据,之后进行全网广播,之后及时更新消费者端的数据(并且更新时注册中心是阻塞的)这样就重新形成了新的注册中心的结构
nginx和dubbo负载均衡的区别
dubbo的负载均衡相比nginx来说,是更高的
nginx是集中式的负载均衡,全部请求必须交给nginx之后再进行负载均衡
而dubbo,客户端发起请求后,消费者就已经完成了负载均衡的操作,之后直接访问后台的服务器,效率更高
同时提供者集群宕机一台有何影响
会有影响,但只会影响一次,当第一次访问故障机时,如果不能通信,则访问下一次服务器,同时标识本地的服务列表数据(down),下次不会再次进行访问
Mybatis设置事务属性
设置readOnly=true适合查询的场景,readOnly=false适合其他修改的场景
微服务和分布式的联系和区别
微服务:分散能力
分布式:分散压力
微服务和单服务的联系和区别
微服务:压力分摊,解耦合
单服务:压力集中,紧耦合
分布式锁
- 同步锁
- LOCK锁
- 数据库锁
- redis锁
eureka服务的注册与发现
过程:
- 其他微服务启动时,要向eureka注册自己的地址(如果注册失败,会一次次重新尝试注册,直到…)
- 心跳:每30s一次心跳数据,三次心跳数据都没有,则视为宕机(视为服务不可用)(主动向注册中心发起)
- 但是当一个服务不可用的时候,不会删除该服务的用户信息,而仍会保留改地址(其他服务仍然能得到其地址)(默认)
pointCut和joinPoint的区别
- 切入点<左> 在切面中
- 连接点<右> 在想要添加切面的方法前
真正实现与数据库进行会话的是:
DefaultSqlSession中的Executor中的实现类