目录
认证(Authentication)和授权(Authorization)
Cookie和Session有什么区别? 如何用session进行身份验证?
什么是Token? 什么是JWT? 如何基于Token进行身份验证?
Java面向对象的特征
面向对象的三大特征: 封装, 继承, 多态.
封装保护了类的内部结构, 方便对方法的调用, 增强了代码的可读性和可维护性.
继承的作用是避免了重复开发, 增加了代码的复用性, 类与类之间的关系也更加清晰.
多态是在继承和重写的基础上增加了类的多样性和灵活性, 丰富了类的功能.
Arraylist和LinkedList
ArrayList 是基于索引的数据结构, 他的底层是数组.
LinkedList是基于链表的数据结构.
Array使用索引搜索和读取数据是很快的, 而删除和插入数据开销较大
Linked搜索和访问数据不如Array快, 而插入和删除数据优于Array.
应用场景:
Array适合访问和查询数据的场景.Linked更适合经常插入和删除元素的场景.
JDK1.8的新特性
1. 接口可以有默认方法
解决了实现类中必须要实现接口的每个方法的问题.
Java8支持声明方法的同时提供方法默认实现, 方法声明为default
2. Lambda表达式
操作符是->, 根据上下文可以推断出参数的类型, 若只有一条语句, 则可以省略return和大括号. 简化了代码.
3. Optional可选容器类
用于判断对象是否存在, 如果存在则获取该对象, 如果不存在则抛出异常或返回其他对象.
接口和抽象类
- 用interface 定义接口, 用abstract声明一个类是抽象类,
- 接口需要实现接口中的方法, 抽象类是继承, 重写抽象类中的方法(抽象方法也不允许有方法体).
- 抽象类中可以定义各种类型的成员变量, 接口中成员变量只能 public static final类型(通常作为常量使用)
- 接口中不能定义静态代码块和静态方法(static修饰的方法), 抽象类可
- 一个类只能继承一个抽象类, 但是可以实现多个接口
应用场景:
描述某一类事物用抽象类
描述具有某些功能用接口
mybatis的优缺点
优点:
- 较Hibernate容易上手, 基于sql编程.
- JDBC相比, 不需要手动开关连接, 减少代码冗余
- 很好的与各种数据库想兼容
- 提供很多有用插件, 分页插件/逆向工程(代码生成)
- 开发灵活, 解除与JAVA代码的耦合, 便于统一管理和维护
- 支持动态sql, 支持对象关系映射
缺点:
- SQL语句开发量大
- 移植性差, 不能随意更换数据库
mybatis中#{}和${}的区别
#{}是预编译, 类似?占位符, 可以防止sql注入, 调用PreparedStatement的set方法赋值
${}是字符串替换, 直接拼接再sql中
mysql的隔离级别
隔离级别是用于限定事务内外哪些改变可见, 哪些改变不可见.
低级别的隔离, 支持更高的并发处理, 开销更低. 但是安全性低.
- 读未提交
- 读已提交(oracle默认)
- 可重复读(mysql默认)
- 串行化
Spring, SpringMvc, Springboot
- Spring是一个一站式的轻量级java开发框架. 核心是控制反转(IOC)和面向切面(AOP). 针对开发的WEB层(Springmvc), 业务层(IOC), 持久层(jdbcTemplate)等提供了多种配置解决方案.
- Springmvc是Spring基础上的一个MVC框架. 主要处理web开发的路径映射和视图渲染. 属于spring框架中的WEB层开发部分.
- springboot是相较于springmvc更专注于微服务后台接口的开发. 遵循约定大于配置的原则, 简化了配置流程, 大大提高了开发效率.
总结:
- Spring是基础框架, 延伸出很多产品如boot, security, jps等. 他们都是基于ioc和aop. ioc提供了依赖注入容器, aop解决了面向切面的编程.
- springmvc主要解决web开发问题. 是基于Servlet的MVC框架, 通过xml配置, 统一开发前端视图和后端逻辑
- springboot更专注于微服务接口开发, 遵循了约定大于配置的原则, 简化了配置流程.
Spring事务传播机制
required: 默认传播机制, 如果当前没有事务, 则新建一个事务, 如果当前存在事务, 则加入这个事务
supports: 如果当前存在事务, 则加入当前事务, 如果当前没有事务, 则以非事务方式执行
mandatory: 如果当前存在事务, 则加入当前事务, 如果当前没有事务, 则抛出异常
required_new: 创建一个新事务, 如果当前有事务, 则挂起当前事务
not_supported: 以非事务方式执行, 如果当前存在事务, 则挂起当前事务
never: 不使用事务, 如果当前存在事务, 则抛出异常
nested: 如果当前存在事务, 则嵌套事务执行, 否则跟required操作一样
Spring框架中的单例Bean是否线程安全?
Spring中的Bean默认是单例的, 框架没有对bean进行多线程的封装处理.
因此不推荐再bean中声明实例变量或者是类变量. 如果一定要如此, 就要使用ThreadLocal把变量变成线程私有, 或者使用synchronized, lock加同步锁确保线程安全.
Spring用到了哪些设计模式?
- 工厂模式, 各种BeanFactory, ApplicationContext的创建都用到了
- 模板模式, 各种BeanFactory, ApplicationContext的实现中都用到了
- 代理模式, Spring AOP底层就是动态代理实现的
- 单例模式, 创建bean的时候
- 观察者模式, Spring中的各种事件, 各种监听器, ApplicationEvent, ApplicationListener
Spring事务的实现原理
Spring框架中, 实现事务有两种方式: 一种是编程式事务, 一种是声明式事务, 通过@Transactional注解来实现.
开发中更多使用第二种声明式事务.
他的底层原理是Spring的AOP实现的. 如果执行时没有出现异常, 那么会提交事务. 如果出现异常, 且没有指定哪些异常需要回滚操作, 那么进行事务的回滚操作.
mysql 索引有哪些?
普通索引: 允许重复
唯一索引: 具有唯一性
主键索引: 只能有一个主键索引, 用于唯一标识一条记录, 关键字是primary key
联合索引: 一个索引可以覆盖多个列
索引可以极大提升查询效率, 但是会占用存储空间. 所以要合理创建索引.
怎么处理mysql慢查询?
- 开启慢查询日志, 准确定位到哪条sql出了问题
- 分析sql, 是否查询了多余的列,
- 索引是否合理,
- 尽量避免子查询
如何实现一个IOC容器?
IOC(Inversion of Control)控制反转. 是一种设计思想. IOC将你设计好的对象交给容器控制, 而不是传统的通过new的方式创建.
在对象中主动创建依赖对象是正转, IOC容器帮忙创建注入依赖对象, 这个过程是反转.
实现:
- 先准备一个容器, 包含一些map结构的集合, 方便后续存储具体对象.
- 进行配置文件的读取工作或注解的解析工作, 将要创建的bean对象封装成BeanDefinition对象存储在容器中.
- 容器将封装好的BeanDefinition对象通过反射的方式实例化, 完成对象的实例化工作.
- 进行对象的初始化工作, 也就是依赖注入, 完成一个完整的对象
- 通过容器获取对象, 进行处理工作.
- 提供销毁方法, 当对象不用或关闭时, 销毁对象
说说对AOP的理解
一个系统是由多个业务逻辑组件组成. 每个业务组件功能各不相同, 但是某些功能与业务无关且重复例如: 日志, 事务, 权限控制等. 如果给每一个业务组件添加同样的代码, 代码就会很冗余, 且不好维护. 因此需要把公共代码抽象出一个切面, 然后织入到具体的业务方法或者类中. 这样公共业务逻辑被分离出来, 不影响其他业务逻辑的开发.
mysql索引设计的原则
- 应该保证索引字段占用空间越小越好, 这是一个大方向
- 合适做索引的列是经常会出现在where, join, order等中的列
- 表中数据量不大, 没必要创建索引
- 索引列越短越好
- 频繁更新的列不适合当索引
- 大文本大对象不适合当索引
认证(Authentication)和授权(Authorization)
Authentication 认证 是身份的验证, 也就是是否允许登录, 例如用户名密码的校验.
Authorization 授权 是发生在认证之后. 用于区分不同用户的权限.
这两者通常是结合在一起使用, 目的是保护系统的安全.
Cookie和Session有什么区别? 如何用session进行身份验证?
Cookie保存在客户端(浏览器端), Session保存在服务器端. Session的安全性更高.
如何使用session进行身份验证?
- 客户端发送登录请求, 如果服务端验证通过, 会生成一个session保存用户信息, 通常这个session有过期时间, 同时生成一个sessionid返回给客户端, 客户端使用cookie保存sessionid
- 当用户保持登录状态时, Cookie将与后续的每一个请求一起发送到服务端. 服务端将取出Cookie上的Sessionid找出相应的session信息以获取该用户身份. 后续业务操作应当符合该用户身份权限.
什么是Token? 什么是JWT? 如何基于Token进行身份验证?
Session需要保存一份信息在服务端. 而Token身份验证不需要保存session, 只需让客户端保存服务端返回的Token就可以.
Token是JWT方式实现的, 是带有签名的加密JSON数据.
JWT由3部分组成:
Header: 定义了生成签名的算法和Token类型,
Payload: 负载, 存放用户基本信息(如账号, 手机号等)
Signature: 签名, 服务器通过Header, Payload, 秘钥通过指定算法生成签名
如何基于Token进行身份验证:
- 客户端发送登录请求, 服务端验证通过后, 通过JWT生成token, 负载中包含了用户的基本信息(如手机号, 账号), 将token返回给客户端
- 客户端后续的每次请求将token放在HttpHeader的Authorization字段中: Authorization:Bearer Token
- 服务端JWT反向解密, 获取用户信息.