以下问题可能会有重复
- 仅本人整理,不能保证全对和详细
什么是框架(框架的概念)
框架:我们特指软件框架,它是我们在实际开发中解决项目需求的技术集合。在别人写好、封装好的代码上进行二次开发,它不是系统架构
spring(包括springmvc、springBoot、SpringData等)和mybatis是企业开发中最基础的两个框架。
框架解决的问题
框架解决了技术整合的问题,在框架的基础上进行进一步的开发,提高了性能,扩展,易于维护
框架的作用
- 提高开发效率
- 增强代码的可重用性
- 节约维护成本 提供编写规范
- 解耦底层实现原理
使用框架
导入框架所需要的jar包,在配置文件xml中定义好框架的行为,在使用框架的方法等进行操作
MyBatis框架概述
- MyBatis是基于DAO层持久层的框架,是对JDBC的封装,使开发人员只需要关注sq语句的使用即可,而不需要再去实现,加载驱动、获取链接、创建Statrment等繁琐的操作
- statrment( Statement 是 Java 执行数据库操作的一个重要接口,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。Statement对象,用于执行不带参数的简单SQL语句 )
- MyBatis最大特点就是把SQL语句写在xml中,而且sql执行完成后,返回的都是以对象形式
ORM
ORM对象/关系映射,对象就是指的 java 中类的实例,关系指的是关系型数据库
- ORM思想:将数据库中关系数据表映射为 java 中的对象,把对数据表的操作转换为对对象的操作,实现面对对对象的编程,所以
- **ORM的目的:**以面向对象的思想来操作数据库
日志:
可以通过打印日志查看一个框架的执行流程,通过日志查看软件运行期间发生的问题,通过配置日志 组件,可以控制日志信息输出的级别
日志的级别:
A:off 最高等级,用于关闭所有日志记录
B:fatal 指出每个严重的错误事件将会导致应用程序的推出
C:error 指出虽然发生错误事件,但仍然不影响系统的继续运行
D:warn 表明会出现潜在的错误情况
E:info 一般输出的应用程序的运行期间的信息
F:debug 一般用于细粒度级别上,对于程序的调试非常有帮助
G:all 最低级别,用于打开所有的日志记录
日志信息输入的级别如果设置的是debug级别,日志信息会包含比debug级别高的日志信息,不会包含低级别 的日志信息。
${} 和 #{} 区别
- 模糊查询能用 #{} 不用 ${}
- 在项目使用在一般是使用的 #{}
- 使用 #{} 的原理是 ? 占位符,而使用 ${} 的原理是字符串拼接的方式
- 使用 #{} 可以有效的防止 SQL 注入,提高系统安全性。
- 使用 #{} 是数据类型,${} 是字符串
XML文件中,如果传递的参数不是简单类型(基本数据类型和包装类,String),而是一个具体的对象,那么 #{属性名}
实体类与数据库表中字段不一致时
- 在于数据库表对于的pojo.class中
- @Transient:不是数据库表字段的属性必须加此注解(import javax.persistence.Transient; )
- MyBatis-Plus 中 使用注解 @TableField(exit = true|false) 来声明该字段在数据库表中不存在
- @Column:用来标识实体类中属性与数据表中字段的对应关系
- @Transient:不是数据库表字段的属性必须加此注解(import javax.persistence.Transient; )
- 传入参数与数据库表字段不一致时
- @Param是MyBatis所提供的(org.apache.ibatis.annotations.Param),作为Dao层的注解,作用是用于传递参数,从而可以与SQL中的字段名相对应
- 起别名:通过来映射字段名和实体类属性名的一一对应的关系
mapper动态代理开发遵从的规范
- SQL映射文件中的namespace必须和mapper接口的全限定名保持一致
- mapper接口中方法名必须和sql映射文件中sql语句的id属性保持一致
- mapper接口中方法的参数类型、返回值类型 必须和SQL语句中paramterType的值保持一致
当数据表中的列名和POJO类中的属性名不同时,将会出现封装数据失败的情况,Mybatis无法将数据表中的数据准确的封装到POJO对象中,因此必须手动映射表中字段和属性的匹配关系。
MyBatis动态SQL
动态SQL简介
- 动态SQL是MyBatis强大的特征之一,极大地简化了SQL拼装的操作
- 动态SQL元素的使用JSTL或其它类似基于XML的标签类似
- MyBatis采用功能强大的基于OGNL的表达式来简化操作
- OGNL对象图导航语言,这是一种强大的表达式语言,通过他可以非常方便的操作对象属性,类似于EL表达式
- 访问对象属性 ${对象名.属性名}
- 调用方法 ${对象名.方法名}
- 运算符:算术运算符、逻辑运算符(and or not )、比较运算符
- 动态SQL就是通过一系列的标签来完成判断,进行SQL语句的组装
在MyBatis框架中,提供了where和if标签进行SQL的动态代理
- where标签:处理SQL语句,自动添加where关键字,并去掉紧跟在它后面的一个and或者or
- if标签:test属性,判断表达式真假
- foreach标签遍历集合、遍历数组、传入pojo
多表查询(inner、left、right)
- 内连接:inner join on
- 显示内连接: INNER JOIN … ON INNER可省略
- 隐式内连接:FROM 主表,从表 WHERE
- 左外连接:left join on 查询出全部的主表的内容,符合条件的从表内容
- 右外连接:right join on 查询出全部的从表内容,符合条件的主表内容
- SELECT st.name,sc.id FROM student st LEFT JOIN score sc ON sc.code=st.code
- SELECT st.name,sc.id FROM student st RIGHT JOIN score sc ON sc.code=st.code
- 交叉连接(笛卡尔积):select * from 表名1,表名2;
- 子查询
- 一个查询的结果作为另一个查询的条件
- 有查询的嵌套,内部的查询称为子查询
- 子查询要使用小括号
- 多表查询效率比子查询效率高,因为:多表查询是查询一条,子查询是两条sql语句
- 内连接(在sql语句中,使用 where 和 on 连接的,左右没有内连接 )
- 外连接 左外连接、右外连接(left…on…、right…on…)
一对一查询:association联合标签,实现手动映射
- property 属性:封装的pojo对象 javaType属性:封装的pojo对象的类型
一对多、多对多查询:collection标签
- property属性:封装对应的属性名 ofType属性:指定集合中的泛型类型
【如果在进行关联查询时,列名如果有相同的,有可能会出现映射时数据不匹配的问题,所以建议任何 表的主键都不要直接定义为id】
什么是延迟加载
- 都是针对在多表查询情况下,对关联对象的操作。
- resultMap可以实现高级映射,一对一延迟加载,一对多延迟加载(association,collection),association、collection具备延迟加载功能。
- 先从单表查询、需要时再关联查询,大大提高数据库性能
- 默认是不开启延迟加载的,需要在 SqlMapConfig.xml 文件中,在标签中开启延迟加载功能。
MyBatis缓存
- 几乎所有的ORM框架都提供了缓存机制。缓存可以极大地提升查询效率。
- 目前 mybatis 和 Hibernate 都采用了 ORM 思想,mybatis是半自动 ORM 框架,Hibernate是全自动的 ORM 框架
- MyBatis缓存:拥有一级缓存和二级缓存两个
- 默认情况下,只有一级缓存是开启的,(一级缓存是SqlSession级别的缓存,只要SqlSession没有flush或close,它就有效。当调用SqlSession的修改、添加、删除、commit、close方法时,就会清空一级缓存,这样是为了使缓存中的数据永远都是最新的,避免了脏读)
- 二级缓存需要手动开启和配置,它是基于namespace级别的缓存(二级缓存是mapper映射级别的缓存,多个sqlSession去操作同一个Mapper映射的SQL语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。)
- 开启二级缓存
- 在UserMapper.xml中开启针对当前mapper映射文件的二级缓存()
- 在statement上配置useCache属性 ( SQL语句 )
- 注意事项使用二级缓存
- 当我们使用MyBatis中的二级缓存时,所缓存的对象一定要实现序列化接口
- 开启二级缓存
- 为了提高扩展性,MyBaits定义了缓存接口,可以整合第三方的二级缓存插件。
Spring框架
Spring简介
Spring是分层的 JavaSE/EE 应用的轻量级开源框架,以 IOC(Inverse Of Control:反转控制) 和 AOP (Aspect Oriented Programming:面向切面编程)为内核,提供了展示层(web层)SpringMVC 和 持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用的开源框架
老的ssm:SpringMVC+Spring+MyBatis
新的ssm:Spring+SpringBoot+MyBatis
Spring容器(什么是Spring容器)
Spring 容器负责实例化,配置和装配 Spring beans
Spring的优势
- 方便解耦,简化开发
- AOP编程的支持
- 声明事务的支持
- 方便程序的测试
- 方便继承各种的优秀的框架
- 降低 JavaEE API 的使用难度
- Spring 源码是经典的示例范例
程序的耦合
耦合性:也叫耦合度,它是对模块之间关联程序的度量
耦合指的就是对象之间的依赖关系,对象之间的耦合越高,则表明模块的独立性和可重用性越差,且维护性成本越高,划分模块的一个标准就是高内聚低耦合
内聚和耦合
- 内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐藏和局部化概念的自然扩展。内聚 是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功 能联系。
- 耦合是软件结构中各个模块之间相互连接的一种度量,耦合强弱取决于模块之间接口的复杂程度、 进入或访问一个模块的点以及通过接口的数据的复杂程度。程序
- 讲究的是低耦合,高内聚。就是同 一个模块内的各个元素之间要高度紧密,但是各个模块之间的相互依赖度却不要那么紧密。
解耦(低耦合)
- 解耦,顾名思义,即解除耦合,消除依赖关系 ,但在程序开发中,零耦合是不存在的,解耦并非消除代码间的耦合,而是降低它们的依赖关系,让依赖关系处在一 个合理的范围。
- 低耦合会使我们开发的功能独立性提高,大大增加了 模块的复用性。同时,在后期对项目维护时,降低了维护成本、项目做后续升级时,减少了重构的风 险。
IOC
IOC 控制反转 是一种设计思想,DI 是实现IOC的一种方式
什么是IOC (Spring 控制反转 IOC–Inverse Of Control)
- 控制反转,不是一种技术而是一种思想
- 其作用是:消减代码之间的耦合,实现思想是利用了工厂的设计模式,把创建对象代码从具体的类中分离出来,交给工厂来完成,从而降低了代码之间的依赖关系。
IOC的作用
它是用于降低代码之间的依赖关系,消减代码之间的耦合,实现思想是利用了工厂的设计模式,把创建对象代码从具体的类中分离出来,交给工厂来完成,从而降低了代码之间的依赖关系。
在使用Spring IOC配置时,它支持纯XML配置或者纯注解配置以及XML和注解混合配置三种方式
如何实现IOC
- setter方法的注入
- 构造器注入
- 静态工厂的注入
- 自动注入
Spring中BeanFactory和ApplicationContext的区别
BeanFactory 是Spring中IOC容器的顶层接口,而 ApplicationContext 是它的一个子接口,ApplicationContext 具备了 BeanFactory 提供的全部功能,但是它比BeanFactory多了许多功能
区别
- 创建的时间点不一样
- BeanFactory:什么时候使用就进行创建对象
- ApplicationContext:配置文件一读取,默认情况下就会创建对象
- 如果使用ApplicationContext,如果配置的bean是singleton,那么不管你有没有或想不想用它,它都会被实例化。好处是可以预先加载,坏处是浪费内存。
- BeanFactory,当使用 BeanFactory 实例化对象时,配置的bean不会马上被实例化,而是等到你使用该bean的时候(getBean)才会被实例化。好处是节约内存,坏处是速度比较慢。多用于移动设备的开发。
- 没有特殊要求的情况下,应该使用ApplicationContext完成。因为BeanFactory能完成的事情,ApplicationContext都能完成,并且提供了更多接近现在开发的功能。
ApplicationContext接口的实现类
- ClassPathXmlApplicationContext: 它是从类的根路径下加载配置文件,推荐使用
- FileSystemXmlApplicationContext: 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置
- AnnotationConfigApplicationContext: 当我们使用注解配置容器对象时,需要使用此类来创建Spring容器,它用来读取注解。
IOC中Bean标签和管理对象细节
- 什么是 Spring Bean
- Spring beans 就是被 Spring 容器所管理的 Java 对象
- Bean 标签的对象获取:getBean方法
Bean标签(线程安全)的作用和属性
- 作用:
- 用于配置对象让Spring来创建
- 默认情况下它调用的是类中的无参数的构造方法
- 属性:
- id:给对象在容器中提供一个唯一标识,用于获取对象
- class:指定类的全限定名。用于反射创建对象
- scope:指定对象的作用范围
- singleton:默认值,单例模式
- prototype:多例
- request:WEB项目中,Spring创建一个Bean对象,将对象存入到request域中
- session:WEB项目中,Spring创建一个Bean对象,将对象存入到session域中
- init-method:指定类中的初始化方法名称
- destory-method:指定类中销毁方法名称
Bean标签的生命周期
- 单例对象: scope=“singletion”
- 一个应用只有一个对象的实例,它的作用范围就是整个应用
- 生命周期
- 对象创建:当应用加载创建容器时,对象就被创建了
- 对象活着:只要容器在,对象一直活着
- 对象死亡:当应用卸载,销毁容器时,对象就被销毁了
- 总结:单例模式下 bean 对象的生命周期与容器相同
- 多例对象: scope=“prototype ”
- 生命周期
- 对象创建:当使用对象时,创建新的对象实例
- 对象活着:只要对象在使用中,就一直活着
- 对象死亡:当对象长时间不用,被Java的垃圾回收器回收
- 总结:spring框架只负责创建,不负责销毁
- 生命周期
实例化bean的三种方式
- Spring使用默认无参数构造方法
- 默认情况下,使用默认无参数的构造方法进行创建
- Spring 管理静态工厂----- 使用静态工厂的方法创建对象
- 使用 StaticFactory 类中的静态方法创建对象,并存入spring容器
- Spring管理工厂 ----- 使用实例工厂的方法创建对象
- 使用此工厂创建对象,必须现有工厂类的对象,在调用方法。
Spring的依赖注入(DI)
IOC也叫依赖注入(DI) ----> 也可以这么说(另一种说法)
什么是依赖注入
- 依赖注入:就是让Spring框架给 Bean 对象的属性进行赋值,它是 Spring 框架 IOC 的具体体现
- 通过控制反转,把对象的创建交给了Spring,但是代码中不可能出现没有依 赖的情况。IOC解耦只是降低它们的依赖关系,但是不会消除。
- 简单的来说,依赖注入(DI)就是坐等框架把所需要的对象传过来,而不用我们自己去获取。
使用构造方法注入
- 就是使用类中的构造方法,给成员变量赋值
- 通过配置的方式,让Spring框架来注入
使用set方法注入
- 就是在类中提供需要注入成员的set方法
Spring依赖注入,构造器注入和setter依赖注入哪种方式好
- 都有优缺点,构造器注入保证所有的注入都被初始化,但是setter注入提供更好的灵活性来设置可选依赖,如果使用 XML 来描述依赖, setter注入的可读写会更强,
- 经验:强制依赖是使用构造器注入,可选依赖是使用setter注入
Spring 整合 MyBatis 开发
MyBatis框架是一个持久层ORM框架,而Spring则是一个综合性的框架。
所以,整合是Spring整合 MyBatis,也就是Spring把MyBatis的一些工作接管了,让Spring框架接管SqlSessionFactory工厂的创建,同时再通过读取mapper配置文件创建dao代理实现类,并把它存入IOC容器中。包括数据源或者连 接池也都交给spring来管理。
Spring和MyBatis它们都有独立的配置文件,我们在整合时,有两种选择。第一种是保留两个框架的配 置文件,第二种是只保留Spring的配置文件,把MyBatis相关的配置都写在Spring的配置文件中。
AOP
AOP:全称是Aspect Oriented Programming ,面向切面编程。
什么是AOP
- AOP就是把我们程序中重复代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源代码的基础上,对我们已有的方法进行增强
- AOP面向切面编程,是对传统的OOP补充
- OOP(Object Oriented Programming)是面向对象的编程啊,还有OOD(面向对象的设计),OOA(面向对象的分析)
- AOP编程操作的主要对象是切面(aspect),而切面用于模块化横切关注点(公共功能)
AOP的作用
- 作用: 在程序运行期间,不修改源代码的基础上,对已有的方法进行增强。
- 优势: 减少重复代码 提高开发效率 维护方便
如何实现AOP
AOP的实现方式就是使用动态代理技术实现的
- 基于接口实现的动态代理:JDK动态代理
- 基于继承实现的动态代理:Cglib、Javassist动态代理
什么是切面
- 在应用AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能应用在哪里,以什么方式应用,并且 不需要修改受影响类的代码,这样一来横切关注点就被模块化到特殊的类里,----我们通常称为切面。
Spring(Spring AOP )动态代理
当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁 ---- 代理对象。
代理模式的设计原理:使用一个代理将原本的对象包装起来,然后使用该代理对象“取代”原始对象。任何 对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
分为:静态代理和动态代理
静态代理
事先写好的代理对象类,在程序发布前就已经存在
动态代理
应用程序发布后,在通过动态创建代理对象
方式:
- 基于接口实现的动态代理:JDK动态代理
- 基于继承实现的动态代理:Cglib、Javassist动态代理
JDK动态代理:
- 使用 JDK 官方的 Proxy类(动态代理类) 来实现动态代理
Cglib动态代理:
- CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。
JDK 和 Cglib 代理的 原理区别
- JDK 动态代理通过利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理
- Cglib 动态代理 是利用 ASM 开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理
- 如果对象实现了接口(是个实现类),默认情况下采用 JDK 进行动态代理实现AOP(java默认使用 JDK 动态代理) ,但也可以强制使用 Cglib进行动态代理
- 如果对象没有实现接口(不是个实现类),则必须采用 Cglib ,Spring 会自动在 JDK 和 Cglib 之间进行转换
环绕通知
Spring提供了一个接口,ProceedingJoinPoint 他可以作为环绕通知方法的参数
在环绕通知执行时,可以通过该接口的实例获取目标类的对象,直接执行目标类中的方法
【使用环绕通知时,目标方法返回值类型只能是引用类型(基本数据类型要写包装类)】
Spring 中的事务控制
位置
- JavaEE体系进行分层开发,事务处理位于业务层,Spring提供了分层设计业务层事务处理的解决方 案
- Spring框架为我们提供了一组事务控制的接口 spring-tx.jar
- Spring的事务控制都是基于AOP的,它既可以使用编程的方式实现,也可以使用配置的方式实现。
SpringMVC
什么是 SpringMvc
一种轻量级的、基于MVC的Web层应用框架。偏前端而不是基于业务逻辑层,是Spring框架的一个后续产品。通过把模型-视图-控制器分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。
**spring MVC是一种分层设计思想,目标是将复杂的应用系统按照分层处理进行设计和规划,通过这种设计方式达到分而治之的效果,从而降低程序开发的难度,提高代码的可维护性.**Spring MVC核心类是 DispatcherServlet,它是一个 Servlet,顶层是实现的Servlet接口
SpringMVC执行流程
- 用户发送请求至前端控制器DispatcherServlet。
- DispatcherServlet收到请求调用HandlerMapping处理器映射器。
- 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器 (如果有则生成)一并返回给DispatcherServlet。
- DispatcherServlet调用HandlerAdapter处理器适配器。
- HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
- Controller执行完成返回ModelAndView。
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
- ViewReslover解析后返回具体View。
- DispatcherServlet根据View进行渲染视图(即将模型数据 填充至视图中)。DispatcherServlet响应用户。
三层架构
- java开发架构一般都基于两种形式
- 一种是 C/S 架构 也就是 客户端/服务器
- 一种是 B/S 架构 也就是 浏览器/服务器
- B/S 框架中,系统标准的三层架构包括
- 表现层、业务层、持久层
SpringMVC组件解析
- 前端控制器:DispatcherServlet
- 处理器映射器:HandlerMapping
- 处理器适配器:HandlerAdapter
- 处理器:Handler
- 视图解析器:View Resolver
- 视图:View
SpringMVC 注解解析
@RequsetMapping
-
作用:
- 用于建立请求 URL 和处理请求方法之间的对应关系
-
位置:
- 类上:请求 URL 的第一级访问目录,如果不写则就相当于应用的根目录
- 方法上:请求 URL 的第二级访问目录,与类上的使用 @ReqquestMapping标注的一级目录一起组成 访问虚拟路径
当请求的方式和方法处理请求的方式不匹配时,出现405
JSON 格式数据实现AJAX交互
是轻量级的,格式比较清晰
交互:前端和后端的互动
-
前端传递JSON字符串到后台,后台如何能够自动转换为pojo对象。
- @RequestBody注解,将JSON字符串转换为POJO对象
-
用于获取请求(消息)体的内容,不适用于GET请求方式
- 后台return对象,可以通过@ResponseBody注解,将后台的对象转换为JSON格式的字符串。
-
@RestController:相当于在类上标记了@Controller,和相当于在每个处理器方法上标记了@ResponseBody
-
@RestController和@Controller就是多了@ResponseBody
REST 和 RESTful
REST(Representational State Transfer):表现层状态转移,是一种软件架构风格。REST并没有一个明确的标准,而更像是一种设计的风格。它本身并没有什么实用性,其核心价值在于如何设计出符合REST风格的API。
基于REST构建的API就是Resetful风格
- 资源:网络上的一个实体,或者说是网络上一个具体信息,可以用一个具体的 URL 进行指定。
- 表现层:把资源具体呈现出来的形式,叫做它的表现层。 比如:文本可以用txt 格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式。
- 状态转化 :每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。
表现层状态转化
- HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”,而这种转化是建立在表现层之上的,所以就是“表现层状态转化”。具体说,就是HTTP协议里面,四个表示操作方式的动词,GET、POST、PUT、DELETE。他们分别对应四种基本操作,GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源。
【RESTful就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一种风格,基于这个风格设 计的软件可以更加简洁、更有层次】
SpringBoot
什么是SpringBoot
进一步简化 Spring 的应用开发,结合分布式微服务的设计思想,将 Spring 相关技术和第三方相关技术进行整合的框架
设计目的/初衷
- Spring开发者提供一种:更加快捷、体验更好的 Spring 应用开发方式
- 开箱即用,同时也可以快速扩展
- 嵌入式 tomcat
- 绝对没有 冗余代码,无序 xml 的配置
Spring Cloud
什么是Spring Cloud
SpringCloud是分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的几何体,俗称微服务全家桶
什么是微服务
微服务架构的系统是一个分布式的系统,按业务进行划分为独立的服务单元,解决单体系统的不足,同时也满足越来越复杂的业务需求。
单个轻量级服务一般为一个单独微服务,微服务讲究的是 专注某个功能的实现 ,讲究的是职责单一,开箱即用,可以独立运行
微服务之间如何独立通讯的?
同步通信:dobbo通过 RPC 远程过程调用、springcloud通过 REST 接口json调用 等。
异步:消息队列,如:RabbitMq、ActiveM、Kafka 等。
SpringCloud 和 Dubbo 有哪些区别?
首先,他们都是分布式管理框架。
dubbo 是二进制传输,占用带宽会少一点。SpringCloud是http 传输,带宽会多一点,同时使用http协议一般会使用JSON报文,消耗会更大。
dubbo 开发难度较大,所依赖的 jar 包有很多问题大型工程无法解决。SpringCloud 对第三方的继承可以一键式生成,天然集成。
SpringCloud 接口协议约定比较松散,需要强有力的行政措施来限制接口无序升级。
最大的区别:
Spring Cloud抛弃了Dubbo 的RPC通信,采用的是基于HTTP的REST方式。
Spring Boot 和 Spring Cloud 的区别
SpringBoot可以离开SpringCloud独立使用,但是SpringCloud不可以离开SpringBoot,属于依赖关系。
什么是微服务架构?
微服务架构 就是 对微服务进行管理整合应用的。微服务架构 依赖于 微服务,是在微服务基础之上的。
什么是熔断?什么是服务降级?
服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的情况时,为了防止整个系统出现雪崩,暂时停止对该服务的调用。
服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的情况,在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的fallback(退路)错误处理信息。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。
参考:【121期】面试官:什么是熔断?什么是服务降级?
微服务的优缺点是什么?说下你在项目中碰到的坑。
优点:松耦合,聚焦单一业务功能,无关开发语言,团队规模降低。在开发中,不需要了解多有业务,只专注于当前功能,便利集中,功能小而精。微服务一个功能受损,对其他功能影响并不是太大,可以快速定位问题。微服务只专注于当前业务逻辑代码,不会和 html、css 或其他界面进行混合。可以灵活搭配技术,独立性比较舒服。
缺点:随着服务数量增加,管理复杂,部署复杂,服务器需要增多,服务通信和调用压力增大,运维工程师压力增大,人力资源增多,系统依赖增强,数据一致性,性能监控。
SpringBoot常见面试题
什么是Spring
在 《框架问题整理.md》中
-
Spring 的核心是一个轻量级(Lightweight)的容器(Container)。
-
Spring 是实现 IOC(Inversion of Control)容器和 非入侵性(No intrusive)的框架。
-
Spring 提供 AOP(Aspect-oriented programming)概念的实现方式。
-
Spring 提供对持久层(Persistence)、事物(Transcation)的支持。
-
Spring 提供MVC Web框架的实现和绝大多数框架的整合方案,并对一些常用的企业服务API(Application Interface)提供一致的模型封装。总之,Spring 是一个全方位的应用程序框架。
(Spring 提供了对现存的各种框架(Structs、JSF、Hibernate、Ibatis、Webwork等)相整合的方案。 )
1、问:你觉得Spring Boot最大的优势是什么?
答:Spring Boot的最大的优势是“约定优于配置”。“约定优于配置”是一种软件设计规范,开发人员按照约定的方式来进行编程,可以减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。
2、问:Spring Boot中“约定优于配置”的具体产品体现在哪里?
答:Spring Boot Starter、Spring Boot redis、Spring Boot MyBatis等都是“约定优于配置”的一种体现。都是通过“约定优于配置”的设计思路来设计的,Spring Boot Starter在启动的过程中会根据约定的信息对资源进行初始化。
3、问:Spring Boot的自动配置是如何实现的?
答:Spring Boot项目的启动注解是:@SpringBootApplication,其实它就是由以下是三个注解组成的:
- @Configuration
- @ComponentScan
- @EnableAutoConfiguration
其中@EnableAutoConfiguration是实现自动配置的入口,该注解又通过@Import注解导入了AutoConfigurationImportSelector,在该类中加载META-INF/spring.factories的配置信息。然后筛选出以EnableAutoConfiguration为key的数据,加载到IOC容器中,实现自动配置功能。
4、问:Spring、Spring Boot和Spring Cloud的关系?
答:Spring的核心功能是Spring IOC 和 Spring AOP ,Spring在这两大基础上进行发展,才有了Spring事务、Spring MVC 等一系列产品,直到后来 企业可以用 Spring 系列来解决几乎所有的问题
Spring Boot是基于Spring的发展而产生的,不是对Spring的替换,而是使人们更好的使用Spring框架,Spring Boot是使用的约定大于配置的理念
Spring Cloud则是利用Spring Boot 的开发便利性巧妙地简化了分布式系统 基础设施的开发。
Spring Cloud是为了解决微服务架构中服务治理的问题而提供的开发框架,并且Spring Cloud 是完全基于 Spring Boot的开发,Spring Cloud 利用 Spring Boot 特性整合了开源行业中优秀的组件,整体对外提供了一套在微服务架构中服务治理的解决方案。
(
Spring Cloud 是完全基于 Spring Boot 的开发而‘产生的,是对Spring Boot的依赖关系,Spring Cloud 利用了 Spring Boot 简化了分布式系统基础设施的开发,Spring Cloud是为了解决微服务中服务治理问题而产生的,并且整合了一套解决微服务中服务治理的解决方案
)
正是由于 Spring IOC 和 Spring AOP 两个强大的功能才有了 Spring ,Spring 生态不断的发展才有了 Spring Boot ,使用 Spring Boot 让 Spring 更易用更有生命力,Spring Cloud 是基于 Spring Boot 开发的一套微服务架构下的服务治理方案。
5、问:Spring Boot Starter 是什么?场景启动器(starter)
starter
答:starter是Spring Boot 依赖关系的整合和封装,它是一套依赖坐标
6、问:Spring Boot Starter的工作原理是什么?场景启动器(starter)
答:
- Spring Boot 在启动时会去依赖的 Starter 包中寻找 resources/META-INF/spring.factories 文件,然后根据文件中配置的 Jar 包去扫描项目所依赖的 Jar 包
- 根据 spring.factories 配置加载的 AutoConfigure 类
- 根据 @Conditional 注解的条件,进行自动配置并将 Bean 注入 Spring Context
总结:
就是 , Spring Boot 在启动时,按照约定去读取 Spring Boot Starter 的配置信息,再根据配置信息进行资源初始化,并注入到 Spring 容器中,这样 Spring Boot 启动完成后,就已经准备好了所有的资源,在使用的时候直接注入、读取相应的Bean即可
7、问: Spring Boot 注入bean的方式
答:
-
@ComponentScan包扫描+组件标注注解@Component(@Controller@Service@Repository)
默认是加载和Application类所在同一个目录下的所有类,包括所有子目录下的类。
当启动类和@Component分开时,如果启动类在某个包下,需要在启动类中增加注解@ComponentScan,配置需要扫描的包名。
-
@Configuration+@Bean
-
@Import快速给容器中导入一个组件
- @Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
- ImportSelector:返回需要导入的组件的全类名数组;
- ImportBeanDefinitionRegistrar:手动注册bean到容器中
8、问:什么是嵌入式服务器
嵌入式服务器就是我们的可执行单元包含服务器的二进制文件
9、问:Spring Boot 和 Spring Cloud 的区别
Spring Boot专注于快速方便地开发单个个体微服务,Spring Cloud 关注于全局的微服务协调(整治)治理框架。
Spring Cloud将Spring Boot 开发的一个个单体微服务整合并管理起来,为各个微服务之间提供配置管理,服务发现,断路器,路由,微代理,事件总线,全局锁,精选决策,分布式会话等合成服务
Spring Boot 可以离开 Spring Cloud进行独立的开发项目,但是 Spring Cloud 离不开 Spring Boot,属于依赖关系,Spring Boot 专注于快速、方便地开发单个微服务个体,Spring Cloud专注于全局的微服务框架
10、@Controller和@RestController的区别?
@Controller类中的方法可以直接通过返回String跳转到jsp、ftl、html等模版页面。在方法上加@ResponseBody注解,也可以返回实体对象。
@RestController类中的所有方法只能返回String、Object、Json等实体对象,不能跳转到模版页面。
@RestController相当于@ResponseBody + @Controller。
11、在Spring中动态代理有几种实现方式?
JDK、Cglib
JDK:官方的proxy类来进行实现
Cglib:是针对类来实现代理的,主要是对指定的类来生成一个子类,并覆盖所有的方法,该类或者方法不能声明final
12、简述SpringMVC、SpringBoot、SpringCloud之间的关联关系?
Spring Cloud 是基于 Spring Boot 的开发而产生的,是对Spring Boot的依赖关系,Spring Cloud 利用了 Spring Boot 简化了分布式系统基础设施的开发,Spring Cloud是为了解决微服务中服务治理问题而产生的,并且整合了一套解决微服务中服务治理的解决方案
而SpringMVC是SpringMVC是基于Spring功能之上添加的Web框架,想用SpringMVC必须先依赖Spring。
SpringMVC是一个类似于struts的MVC模式的WEB开发框架;
13、JDBC 优点和缺点
JDBC作为 java 原生的 API
优点:
- 直接进行底层的操作,提供了简单的、便捷的访问数据库的方法
- 跨平台比较强
- 灵活性强、可以写很复杂的sql语句
缺点:
- 编码繁琐、效率低下
- 数据库连接的创建和释放比较重复,也造成了系统资源的浪费
- 大量的硬编码,缺乏灵活性,不利于后期的维护
- 参数的赋值和数据的封装全是手动进行
14、对 JDBC 的封装和优化,一般分为二大类
第一类:
- 着重对 JDBC 进行 API 层的抽取和封装,以及功能的增强,典型代表是 Apache 的 DbUtils
- 在使用 Dbutils 时仍需要编写sql语句,并且手动进行数据的封装,但是相比于 JDBC 的使用,方便了很多
第二类:
- 借鉴面对对象的思想,以操作对象的方式操作数据库,无需编写sql语句,典型代表是 ORM
- ORM 吸收了面向对象的的思想,把对sql对象的操作转换成了对象的操作,这种转换是通过对象和表之间的元数据映射实现的,这是实现ORM 的关键
15、ORM 思想
由于类和表之间以及属性和字段之间建立起映射关系,所以,通过sql对表的操作就可以转换成为对象的操作,程序员从此也无需编写sql语句,这是由框架根据映射自动生成,这就是 ORM 思想
目前 mybatis 和 Hibernate 都采用了 ORM 思想,mybatis是半自动 ORM 框架,Hibernate是全自动的 ORM 框架
ORM 也是 JPA(SUN 推出的持久层规范)的核心内容
Spring和Spring MVC 以及 Spring Boot的区别
Spring 是一个开源框架,其核心是 IOC 和 AOP ,为简化企业级应用开发而生。
**Spring 容器的主要核心是:**IOC、AOP
控制反转(IOC),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用 spring 提供的对象就可以了,这是控制反转的思想。
依赖注入(DI),spring 使用 javaBean 对象的 set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。
面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。
AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用CGLIB 方式实现动态代理。
SpringMVC
SpringMVC是基于Spring功能之上添加的Web框架,想用SpringMVC必须先依赖Spring。
SpringMVC是一个类似于struts的MVC模式的WEB开发框架;
Spring是一个通用解决方案, 最大的用处就是通过 IOC/AOP 解耦, 降低软件复杂性, 所以Spring可以结合SpringMVC等很多其他解决方案一起使用, 不仅仅只适用于WEB开发
SpringBoot 不是Spring官方的框架模式,而是一个团队在Spring4.0版本上二次开发并开源公布出来的。简而言之,SpringBoot就是一个轻量级,简化配置和开发流程的web整合框架,我们可以说是因为SpringBoot才有了Spring这么火。
那么SpringBoot和Spring有什么区别呢?
- Spring 是一个框架,其核心是Spring IOC 和 Spring AOP ,因为Spring的不断发展,某个研发团队在Spring4.0时二次开发并开源公布出来的 Spring Boot
- Spring Boot可以建立独立的Spring应用程序;
- Spring Boot 是一个轻量级的为服务器,相比于Spring 消除了xml的配置,配置了内嵌服务器,可以建立独立的Spring应用程序
- Spring Boot 只需要一个以来项目来启动和运行Web应用程序
- Spring Boot 应用入口使用的是 @SpringBootApplicatiopn 注解类,其通过 starter 注入依赖。
Spring Boot 和 Spring MVC 的区别
二者的本质:SpringMVC一个web应用框架,springboot一个自动配置化的工具
- Springboot内嵌的Servlet容器,只需执行项目主程序的main函数。而SpringMVC需要配置tomcat,配置端口文件,重启tomcat还要清理缓存
- SpringMVC的MVC部分和config部分有很多的.xml要配置,还有web.xml。springboot将这样的xml配置简化为java配置
- SpringMVC使用简单,学习成本低,很容易就可以写出性能优秀的程序.springboot入门容易,但是如果没有完整学习spring的体系,碰到问题就一脸懵逼。如果没有一定的经验,根本就不知道springboot自动做了什么。
- Spring Boot提供了一系列的starter用来简化我们的Maven依赖。
Spring MVC 和 Spring 的区别
首先SpringMVC必须先依赖Spring。
Spring是个轻量级的IOC(控制反转)和AOP(面向切面)的容器框架,IOC与AOP可以单独用于任何应用,包括与struts等mvc框架与hibernate等orm框架的集成
Spring MVC就是一个MVC框架。spring mvc类似于struts的一个MVC开框架,当然spring mvc的执行效率比struts高,是因为struts的值栈影响效率,其实都是属于spring,spring mvc需要有spring的架包作为支撑才能跑起来
Spring、Spring Boot、Spring Cloud 小结
Spring Cloud 深度融合了 Spring Boot ,定制了很多 Spirng Cloud Starter 组件,当我们需要使用 Spring Cloud 对应的组件时,只需要引入对应的 spring-cloud-starter-xxx 即可,极大地方便了 Spring Cloud 子项目的部署和使用。
Spring Cloud 深度使用了 Spirng Boot ,因此 Spring Boot 具备的特性,Spring Cloud 也几乎都具有,Spring Boot 的这些特性以及快速开发的模式,极大地促进了 Spring Cloud 的发展。
JavaEE
HashMap
HashMap数据结构(较为经典),进行一定的逻辑的处理
1、HashMap底层的数据结构
(Map、数组、集合)
在Java中最常用的两种数据结构是数组和模拟指针(引用)
- 底层核心的数据结构为:数组
- 每次创建一个新的 HashMap 时,都会初始化一个 table 数组,table 数组元素为 Entry 的节点,在Entry中包含了其 键(key)、值(value)、下一个节点(next)、以及 hash值,之后在根据其hash值对数组的长度进行取模既可以进行存取数据
- 基于数组进行实现,通过key取hash值,对数组长度进行取模就可以往数组中存取数据
2、HashMap解决 hash 碰撞问题
- 两个或者多个 key 通过算出来 hash 的值,与 n-1 进行与运算后,发现定位出来的数组还是一样,就产生了 hash 碰撞、hash 冲突,所以就会在挂一个链表,而这个链表则放入多个元素,而这多个 key-value则都会存放在这一个位置中,get时如果这个链表很长则会进行全部遍历,性能很差,所以当链表长度到达一定时就会转成红黑树结构。
JavaSE
IO流
1、输入输出流
站在程序的方向中
输入:外部的数据读取到程序中(Input)核心含义是:读
- 下载网络上某个文件
- 读取硬盘
输出:程序中的数据保存到外部 (OutPut)核心含义是:写
- 数据写入到硬盘保存
- 网站注册
InputStream 是所有字节输出流的父类
OutputStream 是所有字节输出流的父类
在java的I/O流中所有的对字节流处理的类都是继承自 InputStream 和 OutputStream
2、 Data Source(数据源)
作用:提供数据的原始媒介
常见的有:数据库、文件、内存、网络连接、IO设备
数据源分为:源设备、目标设备
- 源设备:为程序提供数据,一般对应输入流
- 目标设备:程序数据的目的地,一般对应输出流
3、什么是流
流:抽象、动态的概念,是一连串连续动态的数据集合
输入流:通过流将数据源中的数据输送到程序中
输出流:通过流将程序中的数据输送到目的数据源中
输入和输出1流的划分是相对程序而言,而不是相对数据源
4、Java中IO抽象类(四大)
字节
- InputStream/OutputStream 字节输入流(抽象类)/字节输出流(抽象类)
字符
- Reader/Writer 字符输入流(抽象类)/字符输出流(抽象类)
5、InputStream 字节输入流
InputStream:此抽象类 表示字节输入流所有类的父类,不可实例化因为是抽象类,继承自此抽象类的流都用于向程序中输入数据,且数据的单位是字节(8 bit)
常用方法
read() 方法 返回值 int 类型:读取一个字节的数据,并将字节的值作为 int 类型(0-255之间)返回,未读出则返回 -1(读取结束,完毕)
close() 方法 返回值void :关闭流对象,释放相关系统资源
6、OutputStream 字节输出流
OutputStream:此抽象类是所有表示字节输出流的父类。
常用方法
write(int n)方法,返回值 void :向目的地写入一个字节
close() 方法,返回值 void :关闭输出流,释放相关资源
7、 Reader 字符输入流
用于读取字符流的抽象类,单位为字符
常用方法
read() 方法 返回int类型:读取一个字符的数据,并将字符的值作为int类型(0-65535之间)返回一个值,即 Unicode值,未读出则 -1(读取结束,完毕)
close() 方法:关闭
8、 Writer 字符输出流
用于输出的字符流抽象类,数据单位 字符
常用方法
writer(int in)方法 :向输出流中写入一个字符
close() :关闭
8.5 File创建
File file = new File(“创建的位置”)
file.createNewFile -----> 创建文件
file.mkdir ------> 创建目录(file.mkdirs 创建多级目录)
9、Java中流的概念细分
-
根据流的方向来分
- 输入流:数据流从数据源到程序(InputStream、Reader结尾的流)
- 输出流:数据流从程序到目的地 (OutputStream、Writer结尾的流)
-
根据处理的数据单元分类
- 字节流:以字节为单位的,命名上一般以 Stream 结尾的,例如:FileInputStream、FileOutPutStream
- 一般:影音、图片
- 字符流:以字符为单位的,命名一般以 Reader/Writer 结尾的,例如:FilrReader、FileWriter
- 一般是:文本型
- 字节流:以字节为单位的,命名上一般以 Stream 结尾的,例如:FileInputStream、FileOutPutStream
-
根据处理对象不同分类
- 节点流:可以直接从数据源或目的地读写数据的 如:FileInputStream、FileReader、DataInputStream
- 处理流:不直接连接到数据源或目的地,是”处理流的流“,通过对其它流的处理提高程序的性能,如:BuffereInputStream、BuffereReader等,处理流也叫包装流
节点流处于 IO 操作的第一线,所有操作必须通过节点流操作,处理流可以对节点流进行包装,提高性能或者提高程序的灵活性
10、IO常用流对象
-
文件字节流
- FileInputStream 通过字节的方式读取文件,适合读取所有的文件(图象、文本、视频等),Java也提供了 FileRead 专门的读取文件
- FileOutputStream 通过字节的方式写数据到文件中,适合所有类型的文件,Java也提供了 FileWriter 专门写入文本文件
-
文件字节输入流
11、IO中的对象流
-
对象流
- 对象的本职是组织和存储数据的,对象本身也是数据。
-
序列化与反序列化
- 序列化:将java对象转换成字节序列的过程
- 反序列号:将字节序列转换成 java 对象的过程
-
对象序列化的作用
- 持久化:把对象的字节序列永久的保存到硬盘上,通常存放在一个文件中
- 网络通信:在网络上传送对象的字节序列,比如:服务器之间的数据通信、对象传递
-
类和接口
- ObjectOutputStream 对象输出流,进行序列化
- ObjectInputStream 对象输入流 反序列化
注:只有实现了 Serializable 接口的类才能被序列化,Serializable 接口是一个空接口,只起到标记作用
12、 Java中有几种类型的流
- 字符流和字节流
- 字节流继承于:InputStream 和 OutputStream
- 字符流继承于:Read 和 Writer
14、什么是比特(Bit) 什么是字节(Byte) 什么是字符(char) 以及之间的差别
比特(Bit):位,是计算机最小的二进制单位,取0或者1,主要用于计算机的操作
字节(Byte):是数据最小的单位,由8位 Bit 组成,取值 (-128-127) 主要用于计算机的操作运算
字符(cahr):用户读写的最小单位,由16位(Bit) 组成(2个字节) ,取值在 0-65535 之间,主要用于用户数据的操作
15、IO 流,什么是IO流
是指:数据从源头流到目的地,所以把这种数据流叫做IO流
常用来处理数据之间的传输、文件的上传、下载、拷贝等
流分为:输出流和输入流,输出流是:从进程中写写入到文件中 输入流是:将文件写入到磁盘中
16、流按照传输的单位怎么划分的?分哪两种流?父类叫什么?常用的流有哪些?
按照传输单位:字节流和字符流
字节流的抽象父类是:java.io.InputStream 、 java.io.OutputStream
字符流的抽象父类是:java.io.Reader 、 java.io.Writer
面向 字节 的操作都是以8位bit为单位对二进制数据进行操作,对数据不需要进行转换,对数据不需要进行转换,所有的类都是 InputStream 和 OutputStream 的子类(以 InputStream 和 OutputStream 结尾)
面向 字符 的操作都是以字符为单位对数据进行操作,在读取二进制数据转换成字符,再写的时候则是将字符转换成二进制数据,这些都是 Reader 和 Writer 的子类 (以 Reader 和 Writer 结尾)
常用 IO 流
- InputStream,OutputStream
- FileInputStream,FileOutputStream
- BufferedInputStream,BufferedOutputStream
- Reader,Writer
- BufferedReader,BufferedWriter
IO类设计时使用了装饰者设计模式。
17、流按照传输的方向怎么分类
相对于内存来说,流按照传输方向,可以分为:输入流InputStream 和 输出流 OutputStream
18、流按照实现功能分类
按照实现功能分为:节点流OutputStream 处理流:OutputStreamWriter
节点流:直接与数据源相连,用于输入或输出
处理流 (转换流):在节点流的基础上对之进行加工,进行一些功能的扩展
处理流的构造器必须要 传入节点流的子类
19、BuffereReader 属于哪种流?主要是干什么?有那些经典的方法
属于处理流中的缓冲流,可以将读取的内容存放在内存里面
有 readLine() 方法读取一行文本,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取
这种处理流的构造器需要传入字点流。
20、InputStreamReader 类
是字节流通向字符流的桥梁,封装了 InputStream 在里面,一次读取一个字符,以文本格式输入、输出,可以指定编码格式
21、如果要对字节流进行大量的从硬盘读取,要用那个流,为什么?
BufferedInputStream 使用缓冲流能够减少对硬盘的损伤
22、System.out.println()是什么?
println是PrintStream的一个方法。Out是一个静态PrintStream类型的成员变量,system是一个java.lang包中的类,用于和底层的操作系统进行交互。
23、如果我要打印出不同类型的数据到数据源,那么最适合的流是那个流,为什么?怎么样把我们控制台的输出改成输出到一个文件里面,这个技术叫什么?怎么样把输出字节流转换成输出字符流,说出它的步骤?把一个对象写入数据源或者从一个数据源读出来,用哪两个流?
1)Printwriter 可以打印各种数据类型
2)SetOut(printWriter,printStream)重定向
3)使用 转换处理流OutputStreamWriter 可以将字节流转为字符流
New OutputStreamWriter(new FileOutputStream(File file));
4) ObjectInputStream ObjectOutputStream
24、什么是序列化和反序列化,实现对象序列化需要做哪些工作?
对象序列化是将对象以二进制的形式保存在硬盘上或者传输到网络;而反序列化则是将二进制的文件转化为对象读取。
Jre本身就提供了序列化支持,我们可以调OutputStream的writeObject方法来做,如果要让java 帮我们做,要被传输的对象必须实现serializable接口,这样,javac编译时就会进行特殊处理,编译的类才可以被writeObject方法操作,这就是所谓的序列化。
serializable接口是一个mini接口,其中没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的。 如果不想让字段放在硬盘上就加transient。
25、在实现序列化接口是时候一般要生成一个serialVersionUID字段,它叫做什么,一般有什么用?请问你在什么情况下会在你得java代码中使用可序列化? 如何实现java序列化?
serialVersionUID:是版本号,要保持版本号的一致 来进行序列化,主要是为了防止序列化出错
把一个对象写入数据源或者从一个数据源读出来,使用可序列化,需要实现Serializable接口
26、流一般需要不需要关闭?怎么关闭?一般要在那个代码块里面关闭比较好,处理流是怎么关闭的,如果有多个流互相调用传入是怎么关闭的?
关闭,使用close() 进行关闭 一般放在finally语句块中关闭(finally语句块都会执行)
处理流一般情况是:先打开后关闭,后打开先关闭 另一种如果有依赖的话(a依赖于 b,则先关闭a 再关闭b)
多个流相互调用:只关闭最外层的即可
27、写一段代码读取一个序列化的对象一般使用哪种Stream?用什么把对象动态的写入磁盘中,写入要实现什么接口?
一般用于 ObjectStream(ObjectInputStream)
一般用 ObjectInputStream 把对象动态的写入磁盘中,需要实现 Serializable 接口
28、PrintStream、BufferedWriter、PrintWriter的比较?
PrintStream类的输出功能非常强大,通常如果需要输出文本内容,都应该将输出流包装成PrintStream后进行输出。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream BufferedWriter:将文本写入字符输出流,缓冲各个字符从而提供单个字符,数组和字符串的高效写入。通过write()方法可以将获取到的字符输出,然后通过newLine()进行换行操作。BufferedWriter中的字符流必须通过调用flush方法才能将其刷出去。并且BufferedWriter只能对字符流进行操作。如果要对字节流操作,则使用BufferedInputStream。 PrintWriter的println方法自动添加换行,不会抛异常,若关心异常,需要调用checkError方法看是否有异常发生,PrintWriter构造方法可指定参数,实现自动刷新缓存(autoflush);
29、管道流
有四种管道流,PipedInputStream,PipedOutputStream,PipedReader和PipedWriter。在多个线程或进程中传递数据的时候管道流非常有用
30、File类
它不属于IP流,也不是用于文件的操作,它主要用于指导一个文件的属性,读写权限,大小等信息。注意:Java7中文件IO发生了很大的变化,专门引入了很多新的类来取代原来的基于java.io.File的文件IO操作方式。
31.RandomAccessFile
它在java.io包中是一个特殊的类,既不是输入流也不是输出流,它两者都可以做到。他是Object的直接子类。通常来说,一个流只有一个功能,要么读,要么写。但是RandomAccessFile既可以读文件,也可以写文件。DataInputStream和DataOutStream有的方法,在RandomAccessFile都存在。
32、对各种基本数据类型和String类型的读写,采用什么流?打印出不同类型的数据到数据源,采用什么流?
DataInputStream 和 DataOutputStream
Printwriter 可以打印各种数据类型
33、File的一些操作
public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
list()获取某个目录下所有的文件或者文件夹:
34、 对文本文件操作用什么I/O流?
FileReader 和 FileWriter
https://blog.csdn/CSDN_Terence/article/details/89513420/
https://blog.csdn/t0404/article/details/51893168
1、Forward和redirect的区别
- forward:请求转发、请求分派,redirect:重定向
- Servlet通过重定向、请求分配进行Servlet之间和网页资源的跳转
重定向的实现:
- 浏览器进行重定向
- 设置重定向状态码:302
- 设置重定向资源的地址:
- 第一种方式:分解
- 设置状态码:302,告诉浏览器要进访问新的资源
- resp.setStatus(302)
- 设置新的资源路径
- resp.setHeader(“location”); Servlet类
- resp.setHeader(“info.html”)
- 第二种方式:合成方式
- resp.sendRedirect(“info.html”)
- 第一种方式:分解
重定向的特点:
- 重定向是发生在客户端的浏览器上的
- 重定向有两次请求两次响应
- 使用重定向,浏览器地址栏中会发生变化
请求分派(转发)
- request对象方法获取转发器
- RequestDispathcher request.getRequestDispatcher(“转发的地址”)
- 使用转发器对象的forward方法
- 示例:
- //请求转发来实现资源跳转
- //step1:获取请求转发器对象 RequestDispatcher dispatcher=req.getRequestDispatcher(“responseDemo3”);
- //step2:调用forward方法实现请求的转发 dispatcher.forward(req,resp);
- 示例:
请求分派(转发)的特点
- 请求转发:只有一次请求、一次响应
- 请求转发:地址栏中的地址不会发生变化
- 请求转发:是在服务端完成的
重定向和请求分派的区别
- 请求转发是一次请求一次响应,重定向是两次请求两次响应
- 请求转发地址不会发生变化,重定向地址栏会发生变化
- 请求转发不会丢失数据而重定向会丢失第一次请求的数据(也就是在新的资源中,无法获取第一次请求的数据)
- 在请求转发中的 ‘/’ 表示 http://localhost:8080项目名称,包含项目名称路径,在重定向中 ‘/’ 表示 http://localhost:8080 ,也就是没有项目名称路径
- 请求分派是在服务器端的 servlet 上完成的,重定向是在客户端浏览器上完成的
- 请求转发只能转发到同一个应用中的其它资源,但是重定向可以定向到任意的网站资源
2、jdbc事务默认是自动提交还是手动提交,如何转换
- jdbc程序中当一个连接对象被创建时,默认情况下是自动提交事务,
- 在 配置文件中设置
3、include 指令和动作
jsp页面是把include指令元素所指定的页面的实际内容(也就是代码段)加入到引入它的jsp页面中,合成一个文件后被jsp容器将它转化成servlet。可以看到这时会产生一个临时class文件和一个java文件。是在翻译阶段执行
include动作包含的是代码执行后的结果 在请求处理阶段执行. include行为元素引入页面时,实际只是引用了date.jsp这个文件被转化并被编译后产生的servlet类文件
4、为什么要使用数据库连接池 、好处是什么
https://wwwblogs/FengZeng666/p/11610806.html
5、concurent
6、redis 持久化的方式
- Redis持久化的两种方式:RDB、AOF
- RDB:持久化机制,是对redis中的数据执行周期性的持久化,默认的,通过时间间隔进行储存
- AOF:AOP机制对每条写入命令作为日志,以 append-only 的模式写入一个日志文件,在 redis 重启的时候,可以通过回放AOF 日志中的写入指令来重新构建整个数据库,每过来一次命令就会存储一次
7、Spring 依赖注入(Spring的自动注入和自动装配)
- setter注入和构造器注入
构造器注入和setter依赖注入哪种方式更好
- 都有优缺点,构造器注入保证所有的注入都被初始化,但是setter注入提供更好的灵活性来设置可选依赖,如果使用 XML 来描述依赖, setter注入的可读写会更强,
- 经验:强制依赖是使用构造器注入,可选依赖是使用setter注入
8、解耦思路总结
- 第一:使用反射创建对象
- 第二:创建对象用到全限定类名配置在配置文件中
9、Spring的核心技术是 IOC/AOP
- 什么是IOC(反转控制)
- 反转控制,并不是一个技术而是一个思想,作用是消减代码之间的耦合,实现思想是利用了工厂的设计模式,把创建对象的代码从具体的类中剥离出来,交给工厂来完成,从而降低了代码的耦合
- 什么是 AOP(面向切面编程)
- AOP就是把我们程序中重复代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源代码的基础上,对我们已有的方法进行增强
- AOP面向切面编程,是对传统的OOP补充
- AOP编程操作的主要对象是切面(aspect),而切面用于模块化横切关注点(公共功能)
- 实现方式:
- 使用动态代理技术实现的
- Bean标签(线程安全)的作用和属性
- 作用:
- 用于配置对象让Spring来创建
- 默认情况下调用的是类中无参数的构造方法
- 生命周期
- 单例对象:一个应用只有一个对象的实例,作用范围是整个应用
- 多例对象:每次访问都会重新创建对象
- 作用:
- 实例化Bean的方式
- Spring使用默认无参数的构造方法
- Spring管理静态工厂—使用静态方法创建对象
- Spring管理实例工程
- Spring的依赖注入(DI)
- 什么是依赖注入
- DI:就是让Spring框架给Bean对象的属性进行赋值,它是Spring框架核心IOC的具体体现
- 使用构造方法注入
- set方法注入
- 什么是依赖注入
- 动态代理
- 原理:使用一个代理将原本的对象包装起来,然后使用该代理对象“取代”原始对象。任何对原始对象的调用都要通过代理,代理对象决定是否可以及何时将方法调用转到原始对象上
- 方式:
- JDK动态代理(使用JDK官方的Proxy实现动态代理)
- Cglib、javassist 动态代理
- AOP的作用和优势
- 作用:
- 在程序运行期间,不修改源代码的基础上,进行对代码的增强
- 优势
- 减少代码的重复
- 提高代码的开发效率
- 维护方便
- 作用:
1.Set 集合Set集合是继承Collection的一个接口,它的数据是无序,不可重复的。它主要包含三种存放数据类型的变量,分别是HashSet,LinkedHashSet,TreeSet。它适合删除,插入数据,不适合检索数据。
2.List集合List集合也是继承Collection的一个子接口,不同的是它里面的数据是有序可重复的。它类似数组,所以它适合检索数据,不适合插入,删除数据。
3.Map集合不直接继承Collection集合,它是双链式集合接口,数据以key-value的形式存储。键不可重复,值可重复。当输入的键重复时,它的值会进行覆盖。它适合存储以键值对存在的数据。
更多推荐
框架(Spring)、MyBatis、IO等琐碎问题
发布评论