聚合函数有哪些
sum min count avg max
事务的概念
事务就是sql的执行要么同时成功 要么同时失败 那么就需要统一管理 这就是事务管理
事务的4大特性
1原子性 要么同时成功 要么同时失败
2.持久性 一旦操作成功 数据就永久的存在数据库
3隔离性 事务之间本不应该相互影响 应该相互独立
4.一致性 事务执行后数据总量不发现变化
jdbc的概念和本质
jdbc就是java操作数据库 本质就是一套sun提供操作数据库的接口 各大厂商继承这些接口 将接口的实现类打包成了jar包 我们要使用哪个数据库 就把哪个数据库对应的jar包导入就可以了
html是一个超文本标记语言 用于网页设计
css主要用于美化页面
arraylist和linklist的区别
arraylist是数组结构 优点查询快 缺点增删慢
linklist是链表结构 优点增删快 查询慢
悲观锁就是总是假设最坏的情况 每次拿数据的时候都认为别人也会修改 就在操作之前就上锁 这样别人想拿到数据就会阻塞 直到拿到锁, 传统的关系型数据库就用到了这种锁机制 比如行锁 表锁
乐观锁 就是每次拿数据 认为别人不会修改, 所以不上锁 但是在更新的时候会判断期间有没有人更新,可以使用版本号机制, 乐观锁多用于读机制,这样可以提高吞吐量
线程池 可以根据系统环境的情况 自动或手动设置线程数量 达到运行的最佳效果
为什么要使用线程池 减少创建和销毁的次数, 每个工作线程都可以重复利用 可执行多个任务
servlet的生命周期 简单分为4步 1.类加载 2.实例化 3.服务 4.销毁
其中三个方法代表了servlet的生命周期
1.init 负责初始化servlet对象
2.service 负责响应客户的请求
3.destroy 当servlet退出生命周期时 负责释放占用的资源
jsp和servlet的区别
1.jsp编译后就变成了servlet
2.jsp的本质就是servlet, jvm只能识别java的类
3. servlet中没有内置对象 jsp是servlet的简化
jdbc操作数据库的步骤 贾琏预执释
1.先导依赖jar包
2.获取链接对象
3.预编译sql
4.执行sql
5.释放资源
cookie和session的区别
1.cookie的数据存放在浏览器上,session存放在服务器上
2.cookie不是很安全,别人可以分析本地的cookie并进行cookie欺骗, 考虑安全可以用session
3.session 会有一定时间保存在服务器上,当访问增多, 会比较占用服务器的性能,考虑性能 可以使用cookie
4.单个cookie不能超过4K, 很多浏览器限制一个站点只能保存20个cookie
5.所以建议登录等重要信息可以存放到session, 其他的可以放cookie
MVC是由
model 代表的是应用的业务逻辑
view 是应用的表示面 由jsp页面产生
contorller 是提供应用的处理过程控制 (一般是一个servlet)
什么是存储过程?
存储过程是一组预编译的sql语句
它的优点有,1允许模块化程序设计,只要创建一次过程,以后在程序中就可以调用任意次,
2.允许更快执行 它比sql执行的更快
3.减少网络流量,更好的安全机制
mysql性能优化
数据结构,sql,索引成本最低而且效果最好
性能优化是无止境的 当性能满足需求即可 没必要过度优化
优化方向
1.sql以及索引的优化,索引不是越多越好,多了反而影响效率
2.合理的数据库设计,三大范式 三大范式只是一个基础 不要生搬硬套
3.系统配置的优化
4.硬件优化
mysql和oracle分页有什么不同?
mysql是limit关键字,oracle是rownum
jdk1.8的新特性
1.接口的默认方法 2.lambda表达式 3.函数式接口 4.新日期时间api
设计模式: 就是前人经过无数次的测试,是解决特定问题的一系列套路,他不是语法规定 而是一套提高代码复用性 稳定性 安全性 维护性 可读性的解决方案
常用的设计模式 1.工厂模式 factory 可以帮助我们创建对象
2.单例模式 在一个类的运行期间有且只有一个运行的实例 两种实现方式: 懒汉式和饿汉式
3. 建造者模式 : builder
4.适配器模式 adapter 通常在springmvc的源码中使用
5. 代理模式 proxy通常在aop中具体使用
6. 桥接模式 jdbc桥driverManager, jdbc连接数据库时就是桥接模式
7.享元模式 flyweight 享元模式的主要目的是实现对象的共享 即共享池, 当系统中对象多的时候可以减少内存的开销
8.模板方法模式 template
冒泡排序: 冒泡排序的原理就是小的数字慢慢往上浮,从数组最后面开始循环,如果一个数比它前面的小,则交换两者位置
mybatis中#{}和KaTeX parse error: Expected 'EOF', got '#' at position 8: {}的区别? #̲{}是预编译处理,{}是字符串替换,使用#{}可以有效的防止sql注入,提高系统的安全性
springmvc和springboot的区别?
springboot只是简化spring框架的使用 和springmvc没有关系
为什么要使用消息队列?
1.可以解耦 解决维护代码的成本
2. 异步 提升流畅性 用户体验
3.削逢 减轻高峰期数据库的压力 mysql的并发也就2000左右
4个MQ的优点
activeMq社会不活跃 版本更新慢 会丢消息 ,rabbitMq性能好 延迟低 版本更新快 适合中小型公司, tockteMQ阿里开源的,十万级吞吐量,适合大公司,kafka适合大数据相关的数据, 日志收集
面试官问mq挂了怎么办?
mq的高可用,rabbitMQ有三种模式,
1.单机模式,生产模式不会用单机模式,单机模式就是自己玩,
2.集群模式,缺点是可能会在集群内部大量消息传输,可用性也没什么保障,一旦queue所在的节点宕机了 就都挂了
3.镜像集群模式才是高可用模式,每个节点都有这个queue的消息数据,任何一个节点宕机了,没事,消费者可以到其他节点消费消息,缺点就是对性能的损耗太大了
kafka是分布式实现高可用的
websocket是html5新增的一种全双工通信协议
==和equals的区别?
是判断基本数据类型的值是否相等
equals没有重写是判断的地址值,对于引用数据类型 也是判断的地址值,string类重写了equals方法, 比较的是两个对象的内容
MVC模式是什么?
M是model 用来封装数据的 V是View 视图页面 C是controller用来接收用户请求的
谈谈你对springmvc的理解?
springmvc本质就是对servlet的封装,常用在表现层 接收用户的请求 调用业务逻辑层 对用户的请求做出响应
说一下springmvc的执行流程?
1.用户发送请求 会被web.xxml所拦截
2.找到核心控制器 dispachchersevlet 专门用来处理请求的核心控制器
3.在通过处理器映射器找到具体交给谁来处理这个请求
4.找到具体的处理器适配器,指定给具体的那个controllrt来处理这个业务
5.控制层调用业务逻辑层,返回一个modelandview
6.通过视图解析器对返回的modelandview进行解析
7.浏览器解析返回的视图和数据 对页面进行渲染
8.返回给用户
springmvc的常用注解
@component 当一些组件不属于三层架构 但又需要交给spring来进行管理 就用这个注解
@repository 对dao实现类进行注解(特殊的component)
@service 用于对业务逻辑层进行注解(特殊的component)
@controller 用于控制层注解 (特殊的component)
@bean 当一个普通类需要交给spring来管理的时候 就用这个
@autowred 注入(可以用来从ioc容器中获取需要的对象,在指定的地方进行注入)
谈谈你对spring框架的理解
spring的作用: 帮我们创建对象 偏于解耦合
1.ioc 控制反转
以前我们需要一个对象, 是我们主动去创建一个对象 [new对象]
弊端:代码的耦合度过高, 不便于代码的复用
我们将创建对象的主动权交给spring
好处: 可以便于解耦合
ioc组件 为何可以帮助我们创建对象呢
基本的原理: ioc的底层是基于java的反射技术,可以帮我们实例化对象
ioc容器: 可以用来装创建好的对象
aop[面向切面编程]
作用: 可以对方法和切面类 进行增强 (做更多的事情)
本质: 在不修改原有代码的情况下 对现在的方法进行增强;
连接点: 一个类中的所有方法都是连接点
切入点: 一个类中 需要进行增强的连接点 称为切入点
切面: 在一个类中 所有的连接点都进行增强 我们就称为切面
底层的原理 : 都是基于动态代理来实现的
基于接口和子类的实现方式
aop的适用场景:
事务,日志功能的添加 性能统计
DI 依赖注入
依赖注入的方式有哪些?
1.构造方法注入
2.set方法注入
3.使用autowred注解进行注入
谈谈你对mybatis的理解?
1.mybatis是一个半自动的持久层框架,是对jdbc的封装
用来简化开发,让开发人员更方便的实现,对数据库的增删改查
2.mybatis框架的动态sql,实现分页,通用mapper
3.mybatis框架的一级和二级缓存
一级缓存 sqlsession级别的缓存 也称本地缓存 默认是开启的;
二级缓存 需要手动的进行设置 设置cache=true
使用mybatis框架的好处
是一个实现对jdbc的封装 需要程序员自己编写需要的sql [这样比较灵活]
hibernate框架
ORM思想: 对象关系映射 对数据进行持久化操作
hibernate的一个开源的对象关系映射框架,它对jdbc进行了非常轻量级的封装
它将pojo实体类与数据库建立映射关系,是一个全自动的orm框架,hibernate开源框架,可以自动生成sql语句,自动执行
hibernate的优点:
1.简化了jdbc的操作,可以减少开发人员的工作量
2.可以实现对表的各种操作 [一对一,一对多];
3.支持各种关系型数据库 [mysql,oracle]
使用框架的基本步骤
1.添加框架对应的pom文件 [jar包, jar包是别人写好的代码 工具类 框架]
2.添加框架对应的核心配置文件
注意:
hibernate框架不支持直接编写sql语句,但是支持HQL语句
HQL语句的语法:
form 实体类名称[实体类的全路径]
form con.dao.domain.user
mybatis和hibernate的比较:
1.mybatis是半自动 sql需要手动编写,比较繁琐 但是较为灵活 可以避免不需要的查询 提高性能
mybatis是主流的开发框架 使用于数据量比较大 后期可能需要对sql优化的业务项目
2.hibernate是全自动 自动生成的sql,封装的很好,有些语句较为繁琐,会多消耗一些性能 不能对sql进行优化 一般是传统的项目在用
比如酒店管理 超市管理 和物流管理系统
oracle存储过程:
定义: 一般都是提前根据业务编写好的一段sql脚本 预先编译好 存储在数据库中的一段sql语句的集合
存储过程的适用场景
一般适合比较固定的业务,阶梯电价,公交扣费系统 保险的收费
注意:在实际的开发中 一般不推荐使用存储过程 [现在使用存储过程的项目, 一般都比较老]
mysql相关
你觉得你的sql技术怎么样?
还可以 满足日常的开发
关于外键约束的使用
1.第一种实现方式 foreign key 不推荐使用
因为有时候对数据进行操作的时候 不方便
2.可以使用编码的方式 来维护两个表之间的主建关系
设计数据库表的三大范式 三大范式是一个规范而已 不是规定
1.第一范式 当一个表的属性都是不可分割的最小单位时 就满足的第一范式
2.第二范式 每一行的数据只能与其中一列相关,即一行数据只做一件事,只要数据列中出现数据重复,就要把表拆分开来
3.第三范式 数据不能存在传递关系,即每个属性都跟主键有直接关系而不是间接关系
数据库常见的数据库连接池
1.c3p0
2.druid
css常用的选择器
id选择器 类选择器 元素选择器
mysql的数据库优化
1.对于数据库相关的硬件,网络进行优化升级
2.对数据库结构进行优化,分表分库,进行读写分离
3.对sql语句进行调优 建立索引
从优化的成本来考虑 硬件>系统配置>数据库表结构>sql及索引
从优化的效果进行考虑 硬件<系统配置<数据库表结构<sql及索引
进行数据库优化的常用工具
explain 获取查询语句的执行计划
索引的使用
建立索引是为了查询的更快 [适用于实际业务中, 对于查询的需求比较多的情况]
索引的分类
1.主键索引 [创建表主键的时候,一般也就创建了主键的索引]
2.普通索引 [推荐使用,用的比较多的索引]
一般需要根据那个字段搜索比较多的列, 我们就创建对应的索引
一般来说,需要进行模糊搜索的就不适合建立索引
3.组合索引
若在实际中 需要将多个列设置索引时, 就可以采用多列索引
key num(number,name) using btree
注意,组合索引前面索引必须要先使用,后面的索引才能使用[最左原则]
4.全文索引 [使用es或者solr进行专业的搜索]
一般使用在网站的前台
创建索引的原则
1.对于查询频率高的字段需要创建索引
2.对排序 分组 联合查询频率高的字段创建索引 索引建多了反而影响性能
3.尽量使用字段长度少的字段来建立索引 因为索引的长度太长 查询的速度也会受到影响
4.删除不再使用或者很少使用的索引 因为建立的索引需要占用内存空间,并且在添加修改,删除的时候 需要进行维护
mysql我们用的是innoDB的存储引擎
1.支持事务,但是执行的效率没有mylsam存储引擎高
2.innoDB会在内存中建立缓冲池,用于缓冲数据和索引
3.innoDB统计表中的行记录的时候,需要进行全表扫描
4.innoDB引擎是行锁,粒度更小,所以写操作不好锁定全表
在并发较高的时候,使用innoDB在提高效率
即存在大量update/insert操作时, 效率更高
5.innoDB的管理的颗粒度更细,innoDB清空数据量大的表时,是非常缓慢的
mylsam存储引擎
1.不支持事务,不支持外键
2.mysql5.6版本前,只有mylsam支持full-text全文索引
3.适用于查询和添加比较多的场景
4.需要统计表中行记录的时候,有很多统计的方法可以直接使用
两种引擎的比较
1.mylsam不支持事务,innoDB支持事务
2.mysql强调的是性能,其执行速度比innoDB更快,适用于数量比较小,并发量不大的清空
而innoDB提供事务支持和外部键等高级数据库功能
3.innoDB是行锁,mylsam是表锁
存储优化
执行数据插入时,将一些影响性能的[索引,唯一性检查,外键检查]操作先禁用,插入完数据,在打开
多使用批量插入,提高插入的性能
优化表结构
1.数值型字段的比较比字符串的比较效率高的多,字段类型尽量使用最小,最简单的数据类型
设计数据库表字段的类型,都是需要结合具体实际的需求,方便开发和满足日常使用的规则
2.尽量使用timestamp而非datetime,可以节约存储空间
3.单表不要有太多的字段,建议20以内
可以根据具体的业务 将表描述的业务进行拆分 [订单主表和订单的明细表]
4.合理的加入冗余字段可以提高查询速度
表拆分
有垂直拆分和水平拆分
缓存优化
1.查询缓存
2.全局缓存
3.局部缓存
ajax的使用
ajax是一个异步的操作 [使用的目的是 不加载整个页面的情况 对局部的数据进行刷新]
使用ajax的原因
1.可以减轻服务器端的访问压力, 因为只是查询部分数据
2.加载的是局部的数据,可以提高用户体验
关于redis的使用
常用来做临时存储, 不能存放大量的数据, 一般存储的都是key-value这种格式
是一个非关系型数据库
在项目中哪些地方使用到了redis 作为缓存 [畅购项目]
1.购物车功能
2.网站前台的秒杀功能
3.广告轮播的功能
juc多线程
线程和进程的关系
一个进程包含一个或者多个线程
进程与线程的区别
进程: 有独立的内存空间,进程中的数据存放空间 (堆空间和栈空间) 是独立的, 至少有一个线程
线程: 堆空间是共享的, 栈空间是独立的, 线程消耗的资源比进程小的多
创建线程的方式
1.继承thread类
2.实现runnable 接口 推荐使用
3.匿名内部类的方式
java中有两种线程,一种是用户线程,一种是守护线程
1.用户线程: 当主线程停止,我们的用户线程可以继续执行
2.守护线程: 当主线程停止了, 我们的用户线程也就停止了
线程安全
同一个资源被处理了多次,我们就认为不安全,存在线程的问题
线程的同步问题 怎么解决?
1.使用同步代码块
2.同步方法
3.使用lock锁
死锁是什么?
多线程死锁: 同步中嵌套同步, 导致锁无法释放
死锁解决办法, 不要在同步中嵌套同步
多线程的6种状态
1.new: 初始状态, 线程被创建 没有调用start() 就绪状态
2.runnable: 运行状态 调用run()方法
3.blocked, 线程进入等待状态 线程因为某种原因, 放弃了cpu的使用权
A: 等待阻塞: 运行的线程执行了wait(), JVM会把当前的线程放入等待队列, 需要使用notify()方法唤醒
B:同步阻塞: 线程被同步锁了, 导致线程不能继续运行
C: 其他阻塞: 运行的线程执行了sleep().join(), JVM会把当前线程设置为阻塞状态, 当sleep()执行完
join()线程终止后再恢复
4.waiting:等待状态
5.timed_waiting:超时等待状态,超时以后自动返回
6.terminated: 终止状态,当前线程执行完毕
wait与sleep的区别?
wait方法,当对象进入锁定池处于等待状态,需要调用notify方法进行唤醒
sleep方法,暂停执行指定的时间,当指定的时间到了,会自动执行线程,而不需要唤醒
在调用sleep方法的过程中,线程不会释放对象锁,而当调用wait方法的时候,线程会放弃对象锁
线程停止的方式
1.设置退出标志,使线程正常退出 [可以理解为人正常的死亡]
2.使用interrupt()方法中断线程 [人的成长中出意外]
3.使用stop方法强行终止线程 [不推荐使用, 可以理解为枪毙]
线程的优先级
1.join方法的作用是让其他线程变为等待,thread.join把指定的线程加入到当前的线程中
2.thread.yield()方法的作用: 展厅当前正在执行的线程, 并执行其他线程 (可能没有效果)
3.通过一个int priority() 方法来控制优先级, 范围为1-10, 其中10最高,默认值为5
并发多线程的三个特性
原子性,可见性,有序性
原子性: 多个线程之间彼此是独立的,互相不影响,没有干扰
可见性: 当多个线程访问同一个变量时, 一个线程修改了这个变量的值,其他线程能够立即看得到修改的值
[可以得到最新的数据]
有序性: 程序执行的顺序按照代码的先后循序执行 (可以保证忙而不乱)
重排序不会影响单个线程的执行,但是会影响到线程并发执行的正确性
[因为数据之间有依赖性,所有有序性是可以保证的]
GC: 即垃圾回收机制,主要是用来回收,释放垃圾占用计算机的内存空间
juc多线程的第二部分
volatile关键字
1.synchronized这个是一个重量级的锁;
2.volatile是一个轻量级的锁,可以实现内存的可见性
它比使用synchronized的成本更加地,因为它不会引起线程上下文的切换和调度
volatile解决内存的可见性
解决的方式: pricate volatile boolean flag=true;
内存的可见性, 可以保证读取到的都是最新的值
volatile实现内存可见性原理:
1.写操作时,通过在写操作指令后加入一条store屏障指令,让本地内存中变量的值能够刷新到朱内存中
2.读操作时,通过在读操作前加入一条load屏障指令,及时读取到变量在主内存中的值
volatile实现原子性的问题:
volatile不具备原子性
如何解决volatile的原子性?
1.使用synchronized [效率比较低,但是可以解决原子性问题]
2.使用Reentranlock [可重入锁]
3.使用Atomiclnteger (原子操作) [推荐使用的方式,效率比较高,比较简单]
public volatile AtomicInteger count = new AtomicInteger(0);
synchronized和volatile比较
1.volatile不需要加锁,比synchronized更轻便,不会阻塞线程,执行的效率更高
2.synchronized既能保证可见性,又能保证原子性,volatile只能保证可见性,无法保证原子性
在某些情况下[变量真正独立于其他变量和自己以前的值] 可以使用volatile代替synchronized来优化代码提高性能
为什么要学习springboot?
spring框架是一个轻量级的容器框架,但是它的配置文件是重量级的,
以前使用spring框架的时候,配置文件比较多,比较复杂(配置文件是重量级的)
spring框架的弊端
a配置文件是重量级的,比较复杂;
会增加程序员的工作量,容易写错
b使用的时候需要添加很多的依赖
springboot和spring框架的关系
springboot不是对spring的封装,只是提供了一个更加简单使用sp[ring框架的方式
spring框架的特点
1.自动配置[约定大于配置]
将很多程序员都需要编写的配置文件 [文件的命名,解析,端口号] 设置为默认
[自动加载以xml,properties,yml结尾的配置文件都加载]
不需要程序员来手动的解析
2.起步依赖
使用spring框架的时候的问题
手动的添加这些jar包,容易出现一些jar包版本的问题,jar包的冲突
手动添加jar包,引入会增加开发人员的工作量
使用springboot可以简化开发:
添加一个起步依赖 [将需要依赖的jar包进行打包]
springboot框架的常用注解
@enableautoconfiguration 将需要的配置文件 和bean自动的进行配置
@componentscan 将需要使用的包和组件, 进行扫描
@springbootapplication 表明当前类是一个引导类, 是程序执行的入口
@springbootconfiguration 是来声明当前类是springboot应用的配置类
thymeleaf
1.为何要学习thymelea页面静态化技术?
为了提高用户的体验,减轻数据库的访问的压力
2.thymeleaf页面静态化技术的适用场景
因为在实际的开发中,对于[商品的详情页面,新闻网站,旅游产品的详情介绍]
这些布局和样式比较固定的页面,我们就可以适用thymeleaf页面静态化技术
3.如何适用thymeleaf页面静态化技术
- 定义模板 [适用thymeleaf的一些标签]
2.构造一个条件查询, 将页面需要的数据都查询处理
3.需要将模板中的插值, 使用查询出来的数据进行替换
4.使用io流写入到一个指定的磁盘的路径下面 [静态的html页面]
堆和栈的比较 [本质上就是一个内存的分配]
堆: 只要是new出来的对象 都是存储在堆中, 并且有默认值
堆中的对象都有一个地址值
对于内存的回收,是使用gc垃圾回收机制,随机回收
栈: 定义的变量都是存储在栈内存中
定义的变量使用完毕后,立即回收
面对对象的几大特征
封装,继承,多态
成员变量和局部变量的区别
成员变量 定义在类中,作用范围是类中都有效,系统会给定默认值
局部变量 定义在方法内部,作用范围就是方法内部,系统不会给定默认值,如果没有赋值,将不能使用
构造方法是用来干什么的?
1.可以用来创建对象
2.可以用来使用构造方法赋值
方法的重载和方法的重写是什么?
方法的重载 : 构造方法的重载
在同一个类中,如果两个方法的方法名称相同, 但是方法的参数个数, 参数的类型,或者顺序不一样,
返回值可以一样也可以不一样,我们就将满足这些特效的方法, 称为方法重载了
方法的重写:
在子类和父类之间, 如果子类将父类的方法进行了一个复写
值传递和引用传递
值传递: 就是将需要传递的值, 复制一份, 之间以形式参数的方式进行传递;
在传递大量数据时, 运行效率会特别低下
引用传递;就是将对象的地址值传递过去,函数接收的是原始值的地址值[通常对于对象的传递使用引用传递]
string类
1.比较的方法 2.截取的方法 3以…开头
string的长度一旦确定就不能随意改变
stringbuidler 可变的字符串
java中的string,stringbuilder,stringbuffer的区别
1.在这方面运行速度从快到慢的顺序为: stringbuilder>stringbuffer>string
string为字符串常量,而stringbuiler和stringbuffer均为字符串变量,即string对象一旦创建之后该对象是不可更改的,但后两者的对象是变量, 是可以更改的
线程安全方面来看
stringbuffer中很多方法带有synchronized关键字, 所以线程是安全的
stringbuilder的方法没有该关键字, 所以不能线程安全
string:适用于少量的字符串操作的情况
stringbuilder: 适用于单线程下在字符缓冲区进行大量操作的情况
stringbuffer: 适用多线程下在字符缓冲区进行大量操作的情况
arraylist集合
特点:底层就是一个数组,长度是可变的,可以存储一些重复的值
可以根据脚标来查询数据
final,finally,finalized的区别
final: 这是一个关键字,表示最终的,常用来修饰变量 类
final修饰的变量是一个常量, 不能被修改和继承
final修饰的类是一个最终类,不能被继承
finally是异常处理语句结构的一部分,表示总是执行
常用在关闭资源的时候 [关闭数据库的连接]
finalized是object中的方法,当垃圾回收器将要回收对象所占内存之前被调用
设计模式: 就是前人经过无数次的测试,适用,被很多人知晓的此程序,经过分类编目的,代码设计经验的总结
常用的设计模式:
1.工厂模式 factory 可以帮助我们创建对象
2.单例模式: 在一个类的运行期间有且只有一个运行的实列
两种实现方式: 懒汉式和饿汉式
饿汉式: 就是类一旦加载,就把单例初始化完成 线程是安全的
懒汉式: 只有使用到的时候才实例化,性能比饿汉式要好 但是线程不安全
3.建造者模式: builder
4.适配器模式 adapter 通常在springmvc的源码中使用
5.代理模式 proxy通常在aop具体使用
6.桥接模式 jdbc桥drivermanager一样,jdbc进行连接数据库的时候使用的就是桥接模式
7.享元模式
享元模式主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销
举例:数据连接池的使用
8.模板方法模式 template
抽象类和接口的区别?
1.抽象类中即可以有抽象的方法,也可以有具体的方法,而接口中都是抽象的方法, 不能有具体的方法
2.两者的关键字不一样 [abstract和interface]
3.抽象类中的方法可以被继续,而接口需要实现 [接口还可以多实现]
spring实现定时任务的方式
1.quartz
2.springtask
都要根据具体的业务编写 cron表达式
@scheduled(cron=“0 0 3 * * ?”)
应用的场景:
1.定时盘点库存 [可以定时扫描库存数量,可以设置一个警戒值]
2.房贷的扣减
3.短信的提醒,生日祝福,保险公司推送的短信
4.订单的后台,进行统计的时候
5.秒杀功能 [定时查询商品是否到了截至日期,如果有就移除商品]
java结合体系结构
list(有序,可重复)
arraylist (底层是数组,查找快,增删慢) ->最常用
linkedlist (底层是链表,查询慢,增删快)-> 常用
set(无序,不可重复) 很少用set系列
hashset linkedhashset
treeset
map(双列集合)
hashmap
hashmap->最常用 (无序)
linkedhashmap 常用 有序
treemap
请列举使用过springcloud哪些组件?
1.eureka: 服务治理组件,包含服务注册中心,服务注册与发现机制的实现
2.zuul: 网关组件 提供智能路由,访问过滤功能
3.ribbon: 客户端负载均衡的服务调用组件
4.feign: 服务的远程调用
5.hystrix: 容错管理组件,实现断路器模式,帮助服务依赖中出现的延迟和为故障提供强大的容错能力
oauth(开放授权) 是一个开放标准, 允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,
而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容
spring security是一个强大的和高度可定制的身份验证和访问控制框架,
spring security框架集成了oauth2协议
jwt令牌的优点:
1.jwt基于json,非常方便解析
2.可以在令牌中自定义内容,容易扩展
3.通过非对称加密算法及数字签名技术 ,jwt防止篡改,安全性高
4.资源服务使用jwt可不依赖认证服务器即可完成授权
缺点:
jwt令牌过长,占存储空间大
jwt包含三部分 头部 负载 签名
springcloud是什么?
简单来说springcloud是一个微服务框架的规范
微服务是一种架构模式,叫微服务架构更合理,就是把一个系统中的各个功能点都拆开为一个小的
应用单独部署,同时因为这些小应用多,所以需要一些办法来管理这些小应用
dubbo是什么?
dubbo是阿里巴巴开源的一个分布式服务框架,致力于提供高性能和透明化
的RPC远程调用方案,以及SOA服务治理方案,简单来说dubbo就是个服务框架,如果没有分布式的需求,
其实是不需要的,说白了就是个远程服务调用的分布式框架
其核心部分包含
1.远程通讯
2.集群容错
3.自动发现
如何保证消息的可靠传输性? 如何保证消息不丢失?
设置queue的时候为持久化
消费端 关闭rabbitMq的自动ack机制
大量消息在mq里积压了几个小时还没解决怎么办?
这个时候只能紧急扩容了,具体思路如下:
1.先解决消费端的问题,先将消费者停掉
2.新建一个topic(话题)原来的10倍大小,临时建好10倍的队列
3.然后写一个临时分发数据的consumer,这个程序部署上消费积压的数据,
消费之后不做耗时处理,分均给临时建好的队列
4.接着临时征用10倍的机器来部署消费端,每一批消费者消费临时的队列
5.等快速消费积压数据之后,得恢复原先部署的架构,重新用原先的消费机器来消费消息
mq中的消息过期失效了
mq可以设置过期时间的 也就是TTL,但是过期的消息会被mq清理掉,数据就没了,只能批量重导,
写个临时程序一点点的查出来,然后重新灌入到mq里去.
mq都快写满了
这是积压太久没解决,只能写个临时程序,接下数据消费,消费一个丢一个,都不要了,然后再批量重导,
查出来重新灌到mq里去
ES的分布式构架原理?
es设计的理念就是分布式搜索引擎,底层还是基于lucene,核心思想就是再多台机器
上启动多个es进程实列,组成一个es集群
es中存储数据的基本单位是索引,索引差不多相当于mysql的一张表
底层lucene
简单来说lucene就是一个jar包,里面包含了封装好的各种建立倒排索引的算法代码,
我们用java开发的时候,引入lucene jar
用过lucene,我们可以将已有的数据建立索引,lucene会在本地磁盘上面,给我们组织索引的数据结构
倒排索引
倒排索引就是关键词到文档id的映射,每个关键词都对应着一系列的文件,这些文件中都出现了关键词
倒排索引的两个重要细节:
1.倒排索引中的所有此对应一个或多个文档
2.倒排索引中的词项根据字典顺序升序排列
ES 在数据量很大的情况下(数十亿级别)如何提高查询效率啊?
1.es的搜索引擎严重依赖底层的文件缓存,如果给文件缓存更多的内存,尽量让内存
可以容纳所有的索引数据文件,那么搜索基本都是走内存的,性能非常高
2.数据预热:
可以搞个系统,把平常看的人多的数据,刷到文件缓存,后面用户实际上来看这个热数据的时候,他们搜索就是直接
从内存搜索,很快
3.冷热分离:
将访问很少的数据写一个索引,访问频繁的单独写一个索引,这样可以确保热数据在被
预热之后,尽量让他们留在文件缓存里,别让冷数据给冲刷掉
4.document模型设计:
es里面的复杂的关联查询尽量别用,document模型设计非常重要,不要再搜索
的时候才想去执行各种乱七八糟的操作
5.分页性能优化:
不允许深度分页,默认翻的越深,性能越差,做成类似于app里的推荐商品
不断下拉出来一页一页的
ES 生产集群的部署架构是什么?每个索引的数据量大概有多少?每个索引大概有多少个分片?
1.es生产集群我们部署了5台机器,每台机器6核64G的,集群总内存320G
2.我们es集群日增数据大概2000多万条,每天日增数据大概500MB,每月增量数据大概是6亿,
15G
3.目前线上有5个索引,每个索引的数据量大概是20G,所以这个数据量之内,我们每个索引分配的8个
碎片,比默认的5个碎片多了3个
项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果?
用缓存主要有两个用途: 高性能,高并发
mysql是很重的数据库不适合高并发,并发量也很低,2000左右,一旦请求太多就挂了,
用缓存的话,并发轻松一秒几万,十几万,缓存是走内存的,内存天然支持高并发
用了缓存的不良后果?
常见的缓存问题有
1.缓存与数据库双写不一致
读的时候,先读缓存,缓存没有的话就读数据库,然后取出数据后放入缓存,同时返回响应
更新的时候,先更新数据库,然后再删除缓存
2.缓存雪崩,缓存雪崩的事前,事中,事后的解决方案
事前: redis高可用,主从+哨兵,避免全盘崩溃
事中: 本地ehcache 缓存+hystrix限流和降级,避免mysql被打死
事后:redis持久化,一旦重启,自动从磁盘加载数据,快递恢复缓存数据
缓存穿透
如果查询的那个数据不存在的话,缓存就不会有,直接查询数据库,这种恶意攻击
场景的缓存穿透会把数据库打死
解决方案就是如果没有查到,就写一个空值到缓存里去,然后设定一个过期时间,这样
下去有相同的key来访问的时候,再缓存失效之前,都可以直接从缓存中获取数据
缓存击穿
缓存击穿,就是说某个key非常热点,访问频繁,当这个key失效的瞬间,大量的请求就
击穿了缓存,直接请求数据库
若缓存的数据基本不会发生改变,可尝试将该热点数据设置为永不过期
若缓存的数据更新频繁,可以利用定时线程再缓存过期前主动重新构建缓存
或者延后缓存的过期时间,以保证所有的请求能一直访问到对应的缓存
3.缓存并发竞争
sql的优化
1.在表中建立索引
2.尽量避免使用select * 返回无用的时段会降低查询效率
3.尽量避免使用in,会导致数据库引擎放弃索引进行全表扫描
4.尽量避免使用or,会导致数据库引擎放弃索引进行全表扫描
5.尽量避免在字段开头使用模糊查询,会导致数据库引擎放弃索引进行全表扫描
6.尽量避免子查询
redis支持的数据类型有哪些?
redis支持5种数据类型
string,哈希,list,set,有序集合
springmvc有哪些注解>注解的作用? 哪些场景使用到?
常用注解有:@restcontrollrt 声明控制层并响应json数据
@requstmapping 路径映射
@requestBody 请求json数据, 比如封装map
@responBody 响应json数据
@pathValiable 基本restfu风格接收参数,路径拼接
@requestparam 接收普通字符串
string的常用方法?
1.indexof() 返回指定字符的索引
2.charAt() 返回指定索引处的字符
3.repalce () 字符串替换
trim() 去除字串串两端的空白
split() 分割字符串 返回分割后的字符串数组
getBytes 返回字符串byte类型的数组
length 返回字符串的长度
tolowerCase 字符串转小写
touppercase 字符串转大写
substring 截取字符串
equals 字符串比较
redis支持哪几种数据类型?
string list(列表) 哈希 set 有序集合
redis主要消耗什么物理资源?
内存
redis官方为什么不提供windows本版?
目前linux版本相当稳定,而且用户量很大,无需开发windows版本,反而会带来兼容性等问题
为什么 Redis 需要把所有数据放到内存中?
因为放内存更快更能发挥redis的性能,在内存越来越便宜的今天,redis会越来越受欢迎
rabbitmq的交换机和工作模式有哪些?
交换机有三种,广播,定向,通配符
工作模式有6种
简单模式.工作工作,订阅模式,路由模式,通配符模式,rpc模式
类的修饰词有哪几个?
public default abstract final static pricate protected
hashmap实际是一个链表散列的数据结构 即数组和链表的结合体 这是jdk8之前的实现方式,但是在
jdk8之后优化改为了数组+链表+红黑树,主要的目的是提高查找效率
hashmap你经常用在哪个地方?
hashmap性能比较好,电子商务也使用到hashmap作为缓存,controller层向前台返回
数据可以用map封装数据,还有mybatis种的map可以作为参数或者封装结果集
HashMap和Hashtable的区别?
hashmap去掉hashtable的contains方法,但是加上了containsValue和containsKey方法
hashTable同步的,而hashmap是非同步的,效率上比hashtable要高
hashmap允许空键值,而hashtable不允许
一般用hashmap代替hashtable
(8)List、Map、Set三个接口,存取元素时,各有什么特点?
list以特定次序来持有元素,可有重复元素
set无法有重复元素 无序
map保存key-value值,value可多值
hashmap可以重复键,重复值吗? 不能存重复键
(9)HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成
(10)TreeSet怎么对集合中的元素进行排序?
TreeSet底层数据结构是二叉树,保证元素唯一性的依据:compareTofangfa
(11)map集合的两种取出方式?
第一种:通过map.keySet()遍历key和value
第二种:推荐,尤其容量大时,通过map.entrySet遍历key和value
注意map集合不能直接使用增强for循环,因为增强for循环底层是使用的迭代器,而map没有实现
迭代器接口,所以不能用迭代器遍历或者增强for循环遍历
Collection 和 Collections的区别?
Collection是集合类的上级接口,继承与他的接口主要有set和list
Collections是工具类,有很多对集合操作的方法
IO
字节流
inputStream字节输入流 outputStream 字节输出流
字符流
reader 字符输入流 writer字符输出流
前台需要一个时间格式怎么做?
可以用@jsonFormat 注解
前后端怎么对接的?
根据文档连条,接口需要什么,前端就传什么