技能重点

熟悉使用java语言进行编程设计,有良好的编程习惯和注释。

1、每个程序的开始都加上注释,解释该程序的目的、作者以及程序最后一次被修改的日期和时间。
2、使用空行和空格来增强程序的可读性。
3、.代码低耦合
4、避免太多变量和函数的大型类.
5、拒绝长函数和深度嵌套。(一个长函数意味着包含了太多的功能实现。一般情况下长函数应该被分解成许多子函数,其中每个子函数被设计为处理单个任务或问题)
6、标识符命名有意义。

tomcat性能优化
1、tomcat运行模式是三种,bio、nio、apr ,默认的是bio。需要改成nio,利用Java的异步IO处理,因为可以通过少量的线程处理大量的请求,实现更好的并发。
在\conf\server.xml文件改protocol,而apr 是解决异步的IO问题,但安装复杂。
2、执行器线程池
默认的tomcat没有启用线程池,默认是150-200并发,超过则会等待。
启用连接池 在\conf\server.xml文件把Executor的name改为线程池,Connector 里面也设置线程池。
3、启动程序内存优化(启动行参数优化)
在启动程序运行脚本右键编辑打开调试最大内存,避免当大并发的时候内存不足而请求失败。

熟练Mysql、Oracle、SQLServer数据库使用和性能调优,熟练掌握Sql语句
1、mysql和Oracle的区别
本质区别:
oracle是一个对象关系数据库管理系统,是一个收费的数据库。
mysql是一个开源的关系数据库管理系统,是一个开源免费的数据库。

数据库的安全性:
MySQL使用三个参数来验证用户,即用户名,密码和位置;Oracle使用了许多安全功能,
如用户名,密码,配置文件,本地身份验证,外部身份验证,高级安全增强功能等

sql语法的区别
oracle和mysql语法上大致相同,但是Oracle的sql编程语言提供了更大的灵活性以及更多的命令,比如说生成报表输出和变量定义。

mysql的存储引擎分为MyISAM 和 InnoDB两种

  1. MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。
  2. InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。

2、mysql怎么优化
(1)查询时,能不用* 就不用,尽量写全字段名。
(2)索引不是越多越好,每个表控制在6个索引以内。范围where条件的情况下,索引不起作用,比如where value<100
(3)大部分情况连接效率远大于子查询,但是有例外。当你对连接查询的效率都感到不能接受的时候可以试试用子查询,虽然大部分情况下你会更失望,但总有碰到惊喜的时候不是么…
(4)多用explain 和 profile分析查询语句。
(5)有时候可以1条大的SQL可以分成几个小SQL顺序执行,分了吧,速度会快很多。
(6)每隔一段时间用alter table table_name engine=innodb;优化表
(7)连接时注意:小表 jion 大表的原则
(8)学会用explain 和 profile判断是什么原因使你的SQL慢*
(9)查看慢查询日志,找出执行时间长的SQL进行优化
(10)尽量避免使用order by
(11)因为where子句后面的条件是执行顺序是从右到左,所以尽量把能过滤掉大部分数据的条件放在最后

数据库的优化策略
1、优化sql语句(多表操作) where 左连接 右连接 内连接,尽可能根据主键查询
2.创建索引(对经常查询的数据创建索引)
3.添加缓存(Redis/MemCache)
4.定期进行数据转储(将一些查询较少的数据保存到历史表,让当前表维护可控的数据量)
5.分库分表(需要大量的数据库服务器)

3、熟悉Spring、Spring Boot、MyBatis等开源框架,理解IOC设计原则和AOP思想
3.1什么是Spring框架、
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,能够管理项目中的所有对象,目的为了简化java开发。

简化以下:
1.基于POJO的轻量级和最小侵入性编程。
2.通过依赖注入和面向接口实现松耦合。
3.基于切面和惯例进行声明式编程。
4.通过切面和模板减少样板式代码。

spring核心主要两部分

如何理解IOC设计原则
IOC (控制反转和依赖注入)控制反转是Spring中提供一种控制反转机制,目的是将我们
项目中对象的依赖管理交给Spring实现,这样可以更好
实现对象关系的解耦,提高程序的可扩展性.
依赖注入是由容器动态的将某种依赖关系注入到组件之中。
实现步骤:
第一步:需要添加相关pom.xml文件的依赖。
第二步:创建spring的XML文件,添加bean标签.
第三步:编辑api类
第四步:在spring当中定义和配置一个JavaBean。
使用无参构造方法+set方法创建一个JavaBean
1 id:在容器中查找Bean(对象)的id(唯一、且不能以/开头)
2 class:bean(对象)的完整类名
3 name:在容器中查找Bean(对象)的名字(唯一、允许以/开头、允许多个值,多个值之间用逗号或空格隔开)
4 scope:(singleton|prototype)默认是singleton

Spring DI 如何理解?
答:DI 是Spring中的依赖注入机制,IOC的实现需要借助
这种机制.我们通常会这样理解,Spring Bean容器中的
IOC思想一种目标,DI是实现这种思想的目标的手段.

AOP作用是什么,底层如何实现在哪些地方会用到,分别简述切面,切入点和通知。
AOP:面向切面编程:将一个系统中共同的业务逻辑提取出来,进行单独的封装成一个组件(切面),然后以配置的方式作用于系统中,实现程序的可插拔性,提高代码的复用性,
提升系统的灵活性和性能
底层实现:JDK动态代理,只支持接口注入CGLIB:可以支持普通类的注入
那些地方会用到:事物开启,日志记录,安全验证,权限验证
切面:系统中共通的业务提取出来,在某个时刻或者某个阶段共同调用
切入点:找到目标方法,给它追加共通的业务逻辑,在spring中提供了切入点表达式帮助我们找到目标方法execution
通知:什么时候调用这个共通的业务逻辑,用于指定切面方法作用到系统中的时机.前置通知,后置通知,环绕通知,异常通知,最终通知。

AOP应用于项目中的日志处理,事务处理,权限处理,缓存处理等等

代理实现:
假如目标对象(被代理对象)实现接口,则底层可以采用JDK动态代理机制为目标对象创建代理对象。
假如目标对象(被代理对象)没有实现接口,则底层可以采用CGLIB代理机制为目标对象创建代理对象。

在Spring AOP 中,关注点和横切关注的区别是什么?
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。
横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,
安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。

@Async方法进行异步声明(默认会基于线程池的对象获取工作线程,通过@Async注解描述的方法,让方法运行于一个工作线程,实现异步加载)
切面(@aspect): 横切面对象,一般为一个具体类对象(可以借助@Aspect声明)。
通知(@Advice):在切面的某个特定连接点上执行的动作(扩展功能),例如around,before,after等。
连接点(@joinpoint):程序执行过程中某个特定的点,一般指向被拦截到的目标方法。
切入点(@pointcut):对多个连接点(Joinpoint)一种定义,一般可以理解为多个连接点的集合。
@annotation 用于匹配指定注解修饰的方法
bean 用于匹配指定bean对象的所有方法
正常情况:around(statr)—>before(在…之前)—>目标方法—>around (end)—>after(在…之后)—>after returning
异常情况:around—>before(在…之前)—>目标方法—>around (end)—>after(在…之后)—>after throwing

Spring Bean加载首先是解析XML 或扫描注解,将其属性封装到BeanDefinition 对象中,
并对它beanName(key) 、BeanDefinition(v) 保存到一个Map 中,为后面spring加载依赖注入提供了对应的元数据(bean 定义)。

何为Spring Bean容器?Spring Bean容器与Spring IOC 容器有什么不同吗?
答:用于创建bean对象,管理bean对象的那个容器
Spring IOC 容器本质上指的的就是Spring Bean容器,
Spring Bean容器中最核心一个机制是IOC机制(
控制反转),所以有时候又将springbean容器称之为
Spring IOC 容器.

Spring Bean是如何管理的
spring的IOC容器能够帮我们创建对象,通过容器中的
BeanFactory工厂去读取bean配置文档,管理bean的加载,进行实例化,同时BeanFactory在解析配置文件时并不会初始化对象,只有在使用对象getBean()才会对该对象进行初始化。
且维护bean之间的依赖关系,负责bean的声明周期。

Spring Bean的生命周期
2、bean的生命销毁的周期(什么时候销毁)

销毁的时候并不取决于Spring容器,取决于客户端,当客户端访问的时候由Spring创建对象,客户端访问完成后,Bean对象处于未引用的状态下,就会被JVM自动回收。

3、bean什么时候创建
一般是在项目启动的时候创建的.以前用原生态的三大框架的时候是需要我们手动去指定 它要去扫描哪些包的,指定包路径.这些包路径指定好了之后,
将来在启动的同时,就会去扫描 这些包下的注解作为一种标识向@Service,@Controller,@Component 等.当它识别到这些注解 的同时,就会生成对象交给 spring 容器来管理.
现在我们用的是 springboot,在@SpringBootApplication 下面有个 AutoPackage 这个注解自动扫 描包路径的,我们在使用 springboot 的时候有个主启动包,在它的下面都是子包,
它要去扫描的 是所有的子包里面是否有那些注解,如果有就会给他初始化好,放在容器里面进行管理.

3.2、什么是Spring Boot框架
Spring Boot是一种快速启动框架(整合了所有的框架),其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,
从而使开发人员不再需要定义样板化的配置。

3.3、什么是MyBatis框架
MyBatis是与数据交互的一个持久层框架,底层是封装了jdbc,在与数据连接的同时就用到了jdbc.
怎么实现原理:
1.读取配置文件,配置文件包含数据库连接信息和Mapper映射文件或者Mapper包路径。
2.有了这些信息就能创建SqlSessionFactory(会话工厂),SqlSessionFactory的生命周期是程序运行的时候建立起来,程序结束的时候消亡
3.SqlSessionFactory建立SqlSession,目的执行sql语句,SqlSession是过程级,一个方法中建立,方法结束应该关闭。
4.当用户使用mapper.xml文件中配置的的方法时,mybatis首先会解析sql动态标签为对应数据库sql语句的形式,并将其封装进MapperStatement对象,然后通过executor将sql注入数据库执行,
并返回结果。
5.将返回的结果通过映射,包装成java对象。

连接需要用到数据源,mybatis是存在核心配置当中,xml文件,springboot是放在yml配置文件中,依靠这个数据源将来我们集合mybatis封装jdbc我们给它赋值,就可以正常连接,连接后进行
交互,交互基于sql语句,sql语句可以写到mapper.xml文件当中,也可以在写dao层已注解的形式。用户发起一个请求,我们基于两个配置文件:1个是mapper.xml文件,1个是核心application配置文件.
去创建一个工厂,工厂创建的同时需要用到jdbc,然后工厂创建一个session对象,有了这个对象后可以进行对数据进行各种增删改查,事务提交,关闭资源。
mybatis怎么使用:1、导包,2、yml配置(数据源),3、定义接口。(接口对应的是mapper.xml里面的namespean接口名,id是方法名)4、在启动类上家上mapperscan注解,让他去扫描
dao层的接口,通过接口生成动态代理类,定义一些接口,定义的接口名与mapper文件里面的namespean是一一对应的,方法名要与id对应,一个接口对应一个xml文件,将来我们在调用这个
方法的同时就能定位到他的sql,执行sql,查询出响应的数据给我们返回。

jdbc步骤
1、注册数据库驱动 2、获取数据库连接、3、获取传输器 4、通过传输器把sql发送到数据库服务器 5、execute执行返回多个结果集 6、遍历结果集 7、关闭连接资源

jdbc不足:数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题
解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接.

缓存:
一级缓存是基于SqlSession,同一个用户在执行同一条sql操作的同时,优先从SqlSession去查找,二级缓存基于mapper,底层是通过map的键值对存储,key 为mapper.xml里面的namespean和id.
value为sql语句查询出来的结果。只要key的存在,就可以通过id和namespean查找就可以获取value.

sql语句中#和 符 号 的 区 别 : 符号的区别: 用的比较少,KaTeX parse error: Expected 'EOF', got '#' at position 23: …导致sql注入。我们一般用的是#̲号,两者主要的区别在于安全,因…和#来区分,#则生成安全的PreparedStatement,$则生成不安全的Statement。

PreparedStatement为什么是安全的,因为它会自动转义特殊字符。

一级缓存
      默认开启
      SqlSession级别的缓存,实现在同一个会话中数据的共享
      一级缓存的生命周期和SqlSession一致
      当有多个SqlSession或者分布式环境下,数据库写操作会引起脏数据。

一级缓存:是默认开启的.一般是基于 session 来实现.我们在用 MyBatis 的时候有个 sqlsession 其实就是一个与数据库连接开启的会话.
当同一个用户去操作数据库的时候,首先 要去调 sql 语句.在调用的同时首先要定位到这个 sql,sql 一般有个标识,然后紧接着去查询,
查 询完之后,他会先把数据保存到 session 域里面.当用户第二次去查询的时候,他不会去查询数 据库,而是先从域里面看一下是否有这条数据,
如果有的话就直接从域里面取,而不会直接操 作数据库.

二级缓存
      默认不开启,需手动开启
      SqlSessionFactory级别的缓存,实现不同会话中数据的共享,是一个全局变量
      可自定义存储源,如Ehcache
      当开启缓存后,数据查询的执行的流程是:二级缓存>一级缓存>数据库
      不同于一级缓存,二级缓存可设置是否允许刷新和刷新频率实现
实体类实现序列化,在mapper文件中开启
在配置文件中设置cacheEnabled为true

二级缓存:要去开启,一般是在 mapper.xml 文件里面有一个标签 Cache,我们要给他一个标识. 它是基于不同的用户来实现的,当用户 A 去做查询的时候首先要定位一条 sql,
这里面会有 nameSpace 加上 sql 的 id,nameSpace 是接口的全类名,sql 的 id 对应的方法名.假如用户 A 调 用了这个方法,他先把数据查询出来,然后这条数据的 key
是 nameSpace+sql 的 id,作为 key,value 就是查询出来的数据. 当用户 B 去做查询的时候,不会直接去查询数据库,只要他们 调同一个方法的同时,
他会先去查缓存里面有没有这样一个 key,如果有,就从里面取出来,而不 会去查数据库.

5.Springmvc 的运行流程
答:用户在浏览器发起一个请求,我们基于点对点的通信方式被我们的 dispatcherServlet 给拦
截了(dispatcherServlet 为什么能拦截,因为它底层是实现了一个 HttpServlet,HttpServlet又实现
了一个 HttpSocket 接口,最终的底层就是在点对点.由 dispatcherServlet 拦截到之后)紧接着把
这个请求交给 HandlerMapping,HandlerMapping 是映射处理器,映射找相对应的资源 Handler
处理方法,处理请求.然后去查找标注了@Controller 类控制层里面的@RequestMapping注解
括号里面的路径.只要完全匹配上,就证明找到了相对应的请求,然后要去处理调用他的
方法,调用方法的同时,一般是控制层调用业务层,业务层将来查询出来的数据我们用 model
进行封装和返回,然后进行视图解析,并把数据在页面上进行渲染的一个过程.

集合分为map和Collection
List和Set继承了Collection接口,而map不是,map与Collection是一种并行的关系,是同级。
List中存放元素有顺序并且可以重复;
set中存放的元素是无序并且是不可重复的;
Map中存放是键值对。

list下面有两个实现类,一个是ArrayList和LinkedList。
ArrayList底层封装的是一个数组,每个对象都有下标,可以根据下标获取到元素,内部数组默认初始容量是10。如果不够会以1.5倍容量增长。
ArrayList遍历快,因为存储空间连续,另外new的一个数组的时候,只要是满足同一种类型的数组都可以存储成功,所以不要求是否重复的。
LinkedList底层封装了一个双向链表,存储空间不连续,查找的话要通过指针一步一步的定位下一个元素,而插入元素和删除元素只需要改变相邻两个元素的指针即可。
业务一次赋值,不会改变,顺序遍历,就采用数组;业务频繁变化,有新增,有删除,则链表更加适合。

ArrayList和LinkedList的区别?
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
2.对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。 
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。(除了最后一位,全部要重新排序)

set集合是无序且唯一的,下面有三个实现类HashSet和TreeSet、LinkedHashSet;
HashSet底层是哈希表,包装了hashmap,k,v结构,当向HashSet中存入数据时,会把数据作为K,存入内部的HashMap中,
满足键值位就可以往set集合里面放,但未排序,如果key相同value不同则会覆盖,这就是唯一且无序的。(允许null值)
TreeSet:底层就是TreeMap,也是红黑树的形式,不能写入空的数据和重复的数据,且写入的数据是有序的。
LinkedHashSet底层是哈希表和链表结合,不重复同时具有可预测的迭代顺序,我们一般用的比较少,因为线程不安全的问题。

map底层封装了数组,链表,hash算法,用于存储键值对结构的数据。其中的键不能重复,值可以重复,可以根据键获取对应的值。
如果键重复则值会被覆盖,存放的都是无序数据,初始容量是16,如果超过16会按照加载因子0.75倍进行容量扩容。(允许null值,但key只能允许一个null,因为是key是唯一的)
map下面有三个实现类hashMap、hashtable 、TreeMap
hashmap底层是一个Entry数组,当存放数据时会根据hash算法计算数据的存放位置(hash值除于长度16取余),得出一个结果再绑定到数据的每一个位置,
当计算的位置没有数据时,就直接存放。如果存储的下标值重复了,则进行双向链表挂载,当达到长度为8 的同时,转为红黑树。

TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。

hashtable 是散列表,是根据键值对直接访问的数据结构,通过把关键码映射到表中一个位置来访问记录,优点是加快查找速度。

hashMap、和hashtable 区别:
Hashtable 线程是安全的,因为它每个方法中都加入了Synchronize。
hashMap是不安全的,因为
当多个线程同时操作同一个数组位置的时候,也都会先取得现在状态下该位置存储的头结点,然后各自去进行计算操作,之后再把结果写会到该数组位置去,
其实写回的时候可能其他的线程已经就把这个位置给修改过了,就会覆盖其他线程的修改。

set方法
add(E e):添加元素 isEmpty()没有返回true size() :返回此 collection 中的元素数
contains() 如果此 collection 包含指定的元素,则返回 true toArray():返回对象数组
list方法
add() get(int index)返回列表中指定位置的元素 size()长度

map方法
put()方法 赋值 Next()下一个 ; getKey() , getValue() sort()排序

当两个对象的hashcode相同会发生什么?
hashcode相同,说明两个对象HashMap数组的同一位置上,接着HashMap会遍历链表中的每个元素
,通过key的equals方法来判断是否为同一个key,如果是同一个key,则新的value会覆盖旧的
value。如果不是同一个key,则存储在该位置上的链表链头

如果两个键的hashcode相同,你如何获取值对象?
遍历HashMap链表中的每个元素,并对每个key进行hash计算,最后通过get方法获取其对应的值
对象

HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,
然后通过 (n - 1) & hash值 判断当前元素存放的位置(这里的 n 指的是数组的长度)。
如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,
如果相同的话,直接覆盖;不相同就通过拉链法解决冲突,对象将会存储在链表的下一个节点中。

什么是String

string的作用是创建和操作字符串。
string类是不可变的,一旦创建了String对象就不能改变,返回的都是一个新的String类对象。
底层是封装char[]数组的对象,是一个有序的集合,用来表示字符串。char的数组长度是可变的,内部字符数组默认初始容量是16,超过16
新数组大小原来的变成2倍+2进行扩容。经常使用的方法比如字符串的反转reverse,字符串的分割split,字符串的拼接concat、追加append。
以及subString方法是返回字符串的子字符串等。(tostring:返回对象本身 trim()去掉前尾)

第一次使用字符串,会在字符串常量池创建一个对象,再次使用相同内容,会去常量池中找到已经存在的对象,不会新建

当需要对字符串进行大量修改是,使用StringBuffer和StringBuilder类。
String、StringBuffer和StringBuilder的区别?

1.首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
2. 再来说线程安全
在线程安全上,StringBuilder是线程不安全的需要添加同步锁,而StringBuffer是线程安全的,只是运行速度慢
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

什么是线程

讲一下线程的几种实现方式?
线程实现方式有三种
1/继承Thread;
2/implements Runnable
3/implements Callable

Callable规定的方法是call(),Runnable规定的方法是run()。Thread的方法是start();

Thread;编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,
直接使用this即可获得当前线程。

Runnable和Callable的区别是
Callable的任务执行后可返回值,而Runnable的任务是不能返回值得 
call方法可以抛出异常,run方法不可以

线程的几种启动方式?
.第一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法,然后在run方法里填写相应的逻辑代码。
第二种方法是实现Runnable接口,并编写run方法,相比继承Thread类创建线程的好处是以实现接口的方式创建线程可以对类
进行更好的扩展,该类可以继承其他类来扩展自身需求,相比第一种方式更加灵活,扩展性强。
实现Callable接口创建线程与Runnable接口的不同之处在于:如果你想要在线程执行完毕之后得到带有返回值的线程则实
现Callable接口

线程执行有优先级,优先级越高先执行机会越大(并不是一定先执行!!)。优先级用int的priority参数表示。
线程优先级最高为10,最低为1。默认为5

(检测一个线程是否存活:isAlice())

线程生命周期,总共有五种状态:

  1. 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

  2. 就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,
    随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

  3. 运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

  4. 阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,
    才有机会再次被CPU调用以进入到运行状态;

根据阻塞产生的原因不同,阻塞状态又可以分为三种:

a) 等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

b) 同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

c) 其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、
或者I/O处理完毕时,线程重新转入就绪状态。

  1. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

进程与线程关系
一个进程中可以有多个线程,每个进程有自己独立的内存,每个线程共享一个进程中的内存,每个线程又有自己独立的内存

sleep()和wait()有什么区别?
Thread类的方法:sleep(),yield()等
Object的方法:wait()和notify()等
sleep方法没有释放锁,wait方法释放了锁
notify唤醒,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

同步锁
当多个对象操作共享数据时,可以使用sychronized关键字同步锁解决线程安全问题,一次只让一个线程执行。缺点:降低程序的执行效率

单例模式 :一个类只有一个对象的实例

GC垃圾回收,可以有效的防止内存泄露,有效的使用可以使用的内存

Shiro框架权限管理时的认证和授权流程描述.
答:Shiro权限控制流程的原理:
应用代码 —- 调用Subject (shiro的Subject 就代表当前登陆用户) 控制权限 —- Subject 在shiro框架内部 调用 Shiro SecurityManager 安全管理器
—– 安全管理器调用 Realm (程序和安全数据连接器 )。
Subject要进行任何操作,都必须要调用安全管理器(对我们来说是自动的)。 
而安全管理器会调用指定的Realms对象,来连接安全数据。
Realms用来编写安全代码逻辑和访问安全数据,是连接程序和安全数据的桥梁。

系统调用subject(项目)相关方法将用户信息(例如isPermitted(是否允许))递交给SecurityManager。(安全管理器)
SecurityManager将权限检测操作委托给Authorizer(授权)对象。
Authorizer将用户信息委托给realm。(范围)
Realm访问数据库获取用户权限信息并封装。
Authorizer对用户授权信息进行判定。

@EnableCaching 注解表示启动缓存配置
@Configuration 注解描述的类为一个配置对象,此对象也会交给spring管理

分布式项目的设计思想
为了实现架构之间的松耦合,将项目根据分布式的思想进行拆分.
1.项目的垂直拆分
根据功能模块的不同将项目进行拆分.
2.项目的水平拆分
在大型项目中,由于开发的人数众多,项目复杂度高.为了保证项目开发的耦合性低.实现项目的水平拆分.
将一个大型项目根据层级模块进行拆分.Controller项目/Service项目Mapper项目
项目创建时采用聚合项目的方式进行管理。

分布式:分布式服务顾名思义服务是分散部署在不同的机器上的,一个服务可能负责几个功能,是一种面向SOA架构的,
服务之间也是通过rpc来交互或者是webservice来交互的

缓存:最简单的距离,去dao请求数据,先去缓存暂定redis,如果发现有,返回数据,不去数据库查询。
也可以把一些常用的数据放置到redis里,再用其服务专门去更新,比如京东的价格服务,全部是redis前置,非常快速。

消息:MQ,Java ee标准,阿里的RocketMQ,很多实现。应用于服务解耦,距离,下订单系统,不需要知道订单发给谁了,
只用发送给MQ就行,MQ根据订阅发给消费者,这时候,生产者和消费者就解耦了,处理订单的逻辑可以随时更换,
而不依赖生成订单的逻辑,中间MQ也可以做持久化,万一服务挂了,消息都存在MQ里, 有保障。也只是一方面

Nginx是什么,有什么作用。
nginx是web服务器的集群管理。
Nginx (engine x) 是一个轻量级的是一个高性能的HTTP和反向代理服务器,其特点是占有内存少,并发能力强
主要是用来反向代理和实现负载均衡.

谈一下反向代理和负载均衡
1.Nginx首先需要监听特定的域名.
2.当用户根据域名进行资源访问时.首先会访问nginx
3.之后nginx代替请求者根据内部的配置文件,实现反向代理.将请求转化为特定的请求路径进行资源访问.
4.当Nginx获取资源后将数据返回给用户.完成请求的正确的响应.

负载均衡:访问量高时,可以让服务器尽量分摊压力,实现策略:轮询,权重,IP_HASH(一般不用)。
nginx的策略
1、轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,且加上一个心跳机制,如果后端服务器down掉,在1到3内没有给响应,
则默认为down机且发送警报,会自动剔除将请求给另一台服务器进行处理。

2、weight (权重)
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。(比较常用)

3、ip_hash 根据访问用户的访问,会随带着ip地址来通过hash算法绑定到第一个访问的服务器,第二次
访问时,依然是第一次处理的那个服务器来处理。如果这台服务器宕机。用户将访问不上。(用户体验不好,所以我们比较少用)

正向代理,
英文是forward proxy,一个介于用户客户端与目标主机服务器端的服务器,客户端向代理服务器发送一个目标性的请求
,代理服务器转发客户端的请求给目标主机服务器,然后将目标主机服务器的结果返回给客户端,
我们一般说的代理都是正向代理,这就是我对正向代理的理解。

反向代理,
英文是 reverse proxy,之所以叫反向代理,是因为正向代理是有目的性的去访问目标主机服务器的代
理服务器,而反向代理是用户不知道代理服务器的存在下,直接访问目标主机服务器的站点,而目标主机中间多了
一个代理服务器,同正向代理一样,转发客户端请求给目标主机服务器,然后返回结果给用户端,用户看起来没有
什么差异,以为自己访问了目标主机,实际上不是。

客户发起一个请求到nginx,nginx在模拟出另外一个请求,指向具体的某一台服务器为其服务。反向代理。

Nginx怎么使用:配置redis.conf文件添加一个server,设置监听端口。监听服务名、反正代理proxy_pass映射服务 。
nginx不是我们配的,是公司专门的人配的,我们也可以配,只是在自己本地的
虚拟机上测试。

ajax
是一种Web应用技术,可以借助客户端脚本(javascript)与服务端应用进行异步通讯,获取服务端数据以后,
可以进行局部刷新。进而提高数据的响应和渲染速度。
为什么用ajax; 因为按需异步加载,局部更新,改善用户体验。

怎么实现:
第一步:基于dom事件创建XHR对象(XMLHttpRequest对象)
第二步:注册XHR对象状态监听,通过回调函数(callback)处理状态信息。
第三步:创建与服务端的连接
第四步:发送异步请求实现与服务端的通讯

SpringMvc怎么和AJAX相互调用的?
通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象。具体步骤如下 :
(1)加入Jackson.jar
(2)在配置文件中配置json的映射
(3)在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上

redis
什么是Redis,运行在哪里?
答:开源的内存中的数据结构存储系统,可以用做数据库,缓存和消息中间件
基于C语言开发,运行时在内存中,运行速度很快。

redis服务器运行效率

  1. tomcat服务器 150-250 之间 JVM调优 1000/秒
  2. NGINX 3-5万/秒
  3. REDIS 读 11.2万/秒 写 8.6万/秒 平均 10万/秒

1、缓存穿透
问题描述: 由于用户高并发环境下访问 数据库中不存在的数据时 ,容易导致缓存穿透.
如何解决: 1、设定IP限流的操作,由于请求的参数是不合法的(每次都请求不存在的参数),
于是我们可以用压缩filter提前拦截,不合法就不让这个请求到数据库层!
2、当我们从数据库找不到的时候,我们也将这个空对象设置到缓存里边去,将空对象设置一个较短的过期时间。(设定超时时间)

2、缓存击穿
问题描述: 由于用户高并发环境下, 由于某个数据之前存在于内存中,但是由于特殊原因(数据超时/数据意外删除)导致redis缓存失效. 而使大量的用户的请求直接访问数据库.
俗语: 趁他病 要他命
如何解决:
1.设定超时时间时 不要设定相同的时间.
2.设定多级缓存

3 缓存雪崩
说明: 由于高并发条件下 有大量的数据失效.导致redis的命中率太低.而使得用户直接访问数据库(服务器)导致奔溃,称之为缓存雪崩.
解决方案:
1.不要设定相同的超时时间 随机数
2.设定多级缓存.
3.提高redis缓存的命中率 调整redis内存优化策略 采用LRU等算法.

LRU等算法是什么?
用一个数组存储,最近很少用的数据放在后面,热点数据放在最前面,如果数组空间满时,则会根据时间戳最久不使用的数据进行淘汰

Redis数据类型
5种

Redis中的数据持久化策略
如果使用时允许丢失部分数据(少量的)则使用RDB模式,它的效率高,也是redis默认的策略,如果不允许丢失数据则采用AOF模式,它的安全性高,但是效率较低
问题:如果数据都存储到redis中,如果内存占满了,redis如何维护?
1.为数据设定超时时间
2.动态的将不用的数据删除.(LRU算法)

分片是内存的一块分区,就是多部署几台redis,把大的数据分成几个小的部分,分布放置存储。实现内存的动态扩容。
数据的存储是redis的节点会根据Id、端口加上一致性hash算法,经过计算按照顺时针的方向查找节点,哈希槽一共为16384个,根据算法存储到平均分配到
每个节点对应的槽位范围(也就是平衡性)。新增或者删除节点的时候对应的数据可以动态的迁移(也就是单调性)。数据应该分散地存放在分布式集群中
的各个节点。没必要存储所有的数据(也就是分散性)

redis为什么运行效率高
redis分片几种的hash运算发生在业务服务器中,redis只负责存取,不负责计算,使用效率高。

为什么觉得分片不好
如果redis分片中有一个节点出现了问题.,则整个redis分片机制用户访问必然有问题 直接影响用户的使用.

哨兵是监控redis系统运行的状态,功能是实现redis高可用。

哨兵模式是通过配置哨兵来管理redis集群,解决redis分片后不能实现高可用缺点
多个哨兵启动时,首先会根据配置文件检测谁是主机,之后利用心跳检测机制,检查主机是否正常运行,当发现主机宕机现象时,
有哨兵通过主机的配置获取链接主机主从的情况,之后哨兵通过内部的选票机制推选出新的主机继续为用户提供服务,之后将另外的丛机动态的修改配置文件,
将其挂载在新的主机上面实现数据的主从同步,如果旧的主机修复完成后,也会动态的挂载到新的主机上实现主从同步

哨兵怎么使用
1.配置redis主从的结构.
2.哨兵服务启动时,会监控当前的主机. 同时获取主机的详情信息(主从的结构)
3.当哨兵利用心跳检测机制(PING-PONG) 连续3次都没有收到主机的反馈信息则断定主机宕机.
4.当哨兵发现主机宕机之后,则开启选举机制,在当前的从机中挑选一台Redis当做主机.
5.将其他的redis节点设置为新主机的从

优点:
1.分片可以使redis动态内存扩容.
2.分片可以将数据均匀的分配到不同的节点中,使数据分散保存.
3.哨兵可以实现redis高可用.
缺点:
1.分片如果有一个节点出现宕机则整个分片都不能正常使用.
2.哨兵如果发生宕机现象,则影响整个redis服务.

伪静态技术
动态页面不能被搜索引擎收录.为了保证搜索引擎的友好性.则以.html的静态页面形式展现动态页面数据

同源策略
请求协议/域名/端口号是否相同,如果三者都一致,那么是同域访问.(即同源策略)浏览器可以正常执行.除此之外的全部的请求都是跨域请求.

利用javascript中src属性实现跨域.
客户端定义回调函数 callback=hello
服务端程序封装特定的JSON格式 callback(JSON) 执行回调函数

什么是Dubbo框架
dubbo是⼀个分布式服务框架,提供⾼性能和透明化的RPC远程服务调⽤⽅案,以及SOA服务治理方案
。说白了其实dubbo就是一个远程调用的分布式框架。

Dubbo特点
智能负载均衡、服务自动注册和发现、RPC调用等等

Dubbo三大核心
1.远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。

2.集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。

3.自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。

Dubbo
1、如果其中一个服务器宕机 用户访问是否受限?
答:由于zk的帮助,使得程序永远可以访问正确的服务器.并且当服务重启时,duboo有服务的自动发现功能,消费者不需要重启即可以访问新的服务.

2、如果ZK集群短时间宕机,用户访问是否受限?
答: 用户的访问不受影响,由于消费者在本地存储服务列表信息,当访问故障机时,自动的将标识信息改为down属性.

3、Dubbo 和 Spring Cloud 有什么区别?
两个没关联,如果硬要说区别,有以下几点。
1)通信方式不同
Dubbo 使用的是 RPC 通信,而 Spring Cloud 使用的是 HTTP RESTFul 方式。
2)组成部分不同

配置:
dubbo:
scan:
basePackages: com.jt #指定dubbo的包路径 扫描dubbo注解
application: #应用名称
name: provider-user #一个接口对应一个服务名称 一个接口可以有多个实现
registry: #注册中心 用户获取数据从机中获取 主机只负责监控整个集群 实现数据同步
address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
protocol: #指定协议
name: dubbo #使用dubbo协议(tcp-ip) web-controller直接调用sso-Service
port: 20880 #每一个服务都有自己特定的端口 不能重复.

dubbo整合springboot
1、新建空项目,下面建三个maven项目:公共api,用来存放公用的接口和pojo类。服务提供者、服务消费者。
2、导包
3、部署zookeeper注册中心到服务器上,修改配置文件,正常启动。
4、配置服务提供者、服务消费者项目的yml文件。消费者和服务器配置的是不一样的。(区别在于提供者有指定协议、和对外提供指定端口)
5、配置启动类里要加 @EnableDubbo 注解 ,开启基于注解的dubbo功能开启包扫描。同时实现类中需要添加dubbo的service注解,
将类声明为提供方。作用是暴露服务。
6、浏览器通过ajax请求到服务消费者controller进行拦截,controller层添加Reference注解可以远程调用提供者的业务层进行注入。

zookeeper
调用步骤:
1.将服务信息写入到注册中心(1.服务名称 2.服务IP地址 3.端口)
2.注册中心接收到服务器信息,会动态的维护服务列表数据.
3.消费者启动时会链接注册中心.目的获取服务列表数据.
4.注册中心会将服务列表数据同步给消费者,并且保存到消费者本地.以后方便调用.
5.当消费者开始业务调用时,会根据已知的服务信息进行负载均衡操作,访问服务提供者.
6.当服务提供者宕机时,由与注册中心有心跳检测机制.所以会动态的维护服务列表.
7.当注册中心的服务列表变化时, 则会全网广播 通知所有的消费者 更新本地服务列表

ZooKeeper
Zookeeper是基于CP来设计的,即任何时刻对Zookeeper的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性,但是它不能保证每次服务请求的可用性。
从实际情况来分析,在使用Zookeeper获取服务列表时,如果zookeeper正在选主,或者Zookeeper集群中半数以上机器不可用,那么将无法获得数据。所以说,
Zookeeper不能保证服务可用性。
诚然,在大多数分布式环境中,尤其是涉及到数据存储的场景,数据一致性应该是首先被保证的,这也是zookeeper设计成CP的原因。但是对于服务发现场景来说,
情况就不太一样了:针对同一个服务,即使注册中心的不同节点保存的服务提供者信息不尽相同,也并不会造成灾难性的后果。因为对于服务消费者来说,
能消费才是最重要的——拿到可能不正确的服务实例信息后尝试消费一下,也好过因为无法获取实例信息而不去消费。
(尝试一下可以快速失败,之后可以更新配置并重试)所以,对于服务发现而言,可用性比数据一致性更加重要——AP胜过CP。

最小的集群单位几台
公式: 存活节点的数量 > N/2 集群可以创建
1台: 1-1 > 1/2 假的
2台: 2-1> 2/2 假的
3台: 3-1> 3/2 正确
4台: 4-1> 4/2 正确

为什么集群一般都是奇数
3台集群最多宕机几台 集群可以正常工作 最多宕机1台
4台集群最多宕机几台集群可以正常工作 最多宕机1台
如果实现相同的功能 奇数台更优.

zk集群选举规则:
myid最大值优先 myid值越大的越容易当主机. 超半数同意即当选主机

SpringCloud
SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,(关注于宏观)
为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务。
依赖于springboot

Eureka
微服务治理,服务注册和发现。
而Spring Cloud Netflix在设计Eureka时遵守的就是AP原则。Eureka Server也可以运行多个实例来构建集群,解决单点问题,但不同于ZooKeeper的选举leader的过程,
种去中心化的架构,无master/slave区分,每一个Peer都是对等的。在这种架构中,节点通过彼此互相注册来提高可用性,
每个节点需要添加一个或多个有效的serviceUrl指向其他节点。每个节点都可被视为其他节点的副本。
如果某台Eureka Server宕机,Eureka Client的请求会自动切换到新的Eureka Server节点,当宕机的服务器重新恢复后,
Eureka会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会进行replicateToPeer(节点间复制)操作,
将请求复制到其他Eureka Server当前所知的所有节点中。
一个新的Eureka Server节点启动后,会首先尝试从邻近节点获取所有实例注册表信息,完成初始化。
Eureka Server通过getEurekaServiceUrls()方法获取所有的节点,
并且会通过心跳续约的方式定期更新。默认配置下,如果Eureka Server在一定时间内没有接收到某个服务实例的心跳,
Eureka Server将会注销该实例(默认为90秒,通过eureka.instance.lease-expiration-duration-in-seconds配置)。
当Eureka Server节点在短时间内丢失过多的心跳时(比如发生了网络分区故障),那么这个节点就会进入自我保护模式。

Feigh概念
Feigh是一个声明式web服务客户端。它能让开发web服务变得容易。使用Feign需要创建一个接口并注解它。它拥有包括Feign注解和JAX-RS注解的可插拔支持。它还支持可插拔的编码器和解码器。Spring Cloud拥有Spring MVC支持,并使用Spring Web中默认同样的HttpMessageConverters。在使用Feign时,Spring Cloud集成了Ribbon和Eureka来提供负载均衡的HTTP客户端。
总结:Feign简化HttpClient开发,封装了JAX-RS和SprinMVC的注解,学习成本很低。

ribbon
负载均衡、请求重试

hystrix
断路器,服务降级、熔断

feign
ribbon + hystrix 集成,并提供声明式客户端

zuul
API 网关,提供微服务的统一入口,并提供统一的权限验证

config
配置中心

spring clound和dubbo区别
spring clound框架集,集成多种工具解决微服务中的多种问题。基于http协议,rest调用,开源易用,成本低。
dobbo:只解决远程调用问题,基于长链接,实现序列化调用。
两者最大的区别是
dobbo:要解决微服务系统中其他的问题,需要注解集成其他的工具,而spring clound就本身就有这个集成的工具来处理。

什么是Mycat
是一个数据库中间件,实现读写分离,分库分表和数据库故障迁移(双机热备)

什么是单点登录
在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统。

单点登录实现
实现步骤:
1.当用户输入用户名和密码点击登录时,将请求发送给前端服务器.
2.前端服务器将用户信息传递给单点登录系统完成数据校验.
3.如果登录成功,则动态生成密钥信息,将user数据转化为json.保存到redis中. 注意超时时间的设定.
4.单点登录系统将登录的凭证 传给前端服务器.
5.前端服务器将用户密钥TICKET信息保存到用户的cookie中 注意超时时间设定.
6.如果登录不成功,则直接返回错误信息即可.

跨越单点登录
用户访问app系统,app系统是需要登录的,但用户现在没有登录。
跳转到CAS server,即SSO登录系统,以后图中的CAS Server我们统一叫做SSO系统。 SSO系统也没有登录,弹出用户登录页。
用户填写用户名、密码,SSO系统进行认证后,将登录状态写入SSO的session,浏览器(Browser)中写入SSO域下的Cookie。
SSO系统登录完成后会生成一个ST(Service Ticket),然后跳转到app系统,同时将ST作为参数传递给app系统。
app系统拿到ST后,从后台向SSO发送请求,验证ST是否有效。
验证通过后,app系统将登录状态写入session并设置app域下的Cookie。
至此,跨域单点登录就完成了。

单点登录的缺点:
安全隐患
因为只需要登录一次,所有的授权的应用系统都可以访问,可能导致一些很重要的信息泄露。(设置cookie的超时时间,获取cookie从内存中获取,浏览器已关闭,cookie会
自动删除,客户端使用https协议。)
资源消耗
在并发量比较高的情况下,如果许多线程调用会给cpu带来很大的压力,而且涉及的的系统很多,不利于重构(耗时)

单点登录的优点:
提高用户的体验,无需重复的登录。
简化管理。

集合分为map和Collection
map与Collection是一种并行的关系,是同级。map的存储结构k,v结构,list下面有两个实现类,一个是ArrayList和LinkedList。
为什么说存储的数据是有序且重复的,因为底层封装
的是一个数组,可以根据数据的下标来排序,另外new的一个数组的时候,只要是满足同一种类型的数组都可以存储成功,不要求是否重复的。
set集合是无序且唯一的,因为底层封装的是一个hashmap,k,v结构,满足键值位就可以往set集合里面放,但未排序,
如果key相同则value不同则会覆盖,这就是达到了唯一无序的。map下面有三个实现类hashMap、hashtable 、TreeMap
hashmap底层封装了三个东西,hash算法,数组、双向链表、存数据的同时,先经过hash算法算出hash值,除于16,然后取余
得出一个结果再绑定到数据的每一个位置,如果存储的下标值重复了,双向链表挂载,当达到长度为8 的同时,转为红黑树。
map可以存null值,但只能存一个,因为key是唯一的。

hashMap、和hashtable 区别:
Hashtable 线程是安全的,因为它每个方法中都加入了Synchronize。
hashMap是不安全的,因为
当多个线程同时操作同一个数组位置的时候,也都会先取得现在状态下该位置存储的头结点,然后各自去进行计算操作,之后再把结果写会到该数组位置去,
其实写回的时候可能其他的线程已经就把这个位置给修改过了,就会覆盖其他线程的修改。

对象的三大特性。(类的三个基本特性)
封装性,把相关的数据封装成一个“类”组件。(封装是使类中的字段保持私密并通过公共方法提供对字段访问的技术)
继承性,是子类自动共享父类属性和方法,这是类之间的一种关系。(一个对象获取另一个对象的属性过程)
多态,增强软件的灵活性和重用性。(同一个对象,在不同时刻,代表的对象不一样,就是对象的多种形态)
前提是继承,父类的引用指向子类的对象,编译看左边,执行看右边。

构造代码块
1、 在类的内部,方法外部,的代码块。
2、 通常用于抽取构造方法中的共性代码。
3、 每次调用构造方法前都会调用构造代码块
4、 优先于构造方法加载

局部代码块
1、 在方法里面的代码块
2、 通常用于控制变量的作用范围,出了括号就失效
3、 变量的范围越小越好,成员变量会有线程安全问题
4、 总结:执行顺序:
构造代码块是最优先的,局部代码块顺序执行

this
this代表本类对象的一个引用对象。
构造函数中,this()必须放在第一行

super
通过super关键字可以使用父类的内容
super代表父类的一个引用对象
如果用,必须出现在调用位置的第一行

this和super的区别
1、 this代表本类对象的引用,super代表父类对象的引用。
2、 this用于区分局部变量和成员变量
3、 super用于区分本类变量和父类变量
4、 this.成员变量 this.成员方法() this(【参数】)代表调用本类内容
5、 super.成员变量 super.成员方法() super(【参数】),代表调用父类内容
6、 this和super不可以同时出现在同一个构造方法里,他们两个只要出现都得放在第一行,同时出现的话,到底第一行放谁呢。。

重写与重载的区别(Overload和Override的区别)
1、重载:是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不能完全相同
2、重写:是存在子父类之间的,子类定义的方法与父类中的方法具有相同的方法名字,相同的参数表和相同的返回类型
3、重写是父类与子类之间多态性的一种表现
4、重载是一类中多态性的一种表现

mybatis-plus
首先是把mybatis和mybatis-spring依赖换成mybatis-plus的依赖,然后把sqlsessionfactory换成mybatis-plus的,然后实体类中添加@TableName、@TableId等注解,最后mapper继承BaseMapper即可.

HttpClient作用:当某些操作时,可能会对数据进行业务加工,之后由服务器与服务器之间形同通讯
什么是HttpClient —HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包
项目怎么整合HttpClient:
1、引入jar包
2、编辑API
3、HttpClient
HttpClient怎么使用:

  1. 创建HttpClient对象。
  2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
  3. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
  4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
  5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
  6. 释放连接。无论执行方法是否成功,都必须释放连接

抽象类和接口
抽象类:没有方法体的方法我们称之为抽象方法,含有抽象方法的类我们称之为抽象类。(一个只有方法声明没有方法体的特殊类)。
特点:
1、 通过java关键字abstract实现
2、 可以修饰方法或者类
3、 抽象类中可以没有抽象方法(由子类去实现)
4、 如果类中有抽象方法,那该类必须定义为一个抽象类
5、 子类继承了抽象类以后,要么还是一个抽象类,要么就把所有抽象方法都重写
6、 多用于多态中
7、 抽象类不可以被实例化

接口:接口是一个特殊的抽象类,突破了java的单继承的局限性。如果要实现多个类的功能,则可以通过实现多个接口来实现。
特点
1、 接口中都是抽象方法
2、 通过interface关键字创建接口
3、 通过implements让子类来实现
4、 可以理解成,接口是一个特殊的抽象类
5、 接口突破了java的单继承的局限性
6、 接口和类之间可以多实现,接口和接口之间可以多继承
7、 接口是对外暴露的规则,是一套开发规范
8、 接口提高了程序的功能扩展,降低了耦合性

抽象类和接口的区别:
相同点
A. 两者都是抽象类,都不能实例化。
B. interface实现类及abstrct class的子类都必须要实现已经声明的抽象方法。

  1. 不同点
    A. interface需要实现,要用implements,而abstract class需要继承,要用extends。
    B. 一个类可以实现多个interface,但一个类只能继承一个abstract class。
    C. interface强调特定功能的实现,而abstract class强调所属关系。
    D. 尽管interface实现类及abstrct class的子类都必须要实现相应的抽象方法,但实现的形式不同。
    interface中的每一个方法都是抽象方法,都只是声明的 (declaration, 没有方法体),实现类必须要实现。
    而abstract class的子类可以有选择地实现。

反射的三种方式
Class.forName(“类的全路径”);
类名.class
对象.getClass();

全文搜索引擎
elasticsearch与solr区别
1、当单纯的对已有数据进行搜索时,Solr更快。
2、当实时建立索引时, Solr会产生io阻塞,查询性能较差, Elasticsearch具有明显的优势。
3、随着数据量的增加,Solr的搜索效率会变得更低,而Elasticsearch却没有明显的变化。
4、Solr的架构不适合实时搜索的应用。
5、Solr 支持更多格式的数据,而 Elasticsearch 仅支持json文件格式
6、Solr 在传统的搜索应用中表现好于 Elasticsearch,但在处理实时搜索应用时效率明显低于 Elasticsearch
7、Solr 是传统搜索应用的有力解决方案,但 Elasticsearch 更适用于新兴的实时搜索应用

Quartz是做什么用的?Quartz框架主要核心组件包括那几部分,分别作用是什么?
1)Quartz是一个由java编写的开源作业调度框架,简单来说,Quartz就是启动定时任务的框架,像linux系统中的corntab,可以定时启动任务。
2)Quartz框架主要核心组件包括调度器、触发器、作业。调度器作为作业的总指挥,触发器作为作业的操作者,作业为应用的功能模块。
( Job为作业的接口,为任务调度的对象;JobDetail用来描述Job的实现类及其它相关的静态信息;Trigger做为作业的定时管理工具,一个Trigger只能对应一个作业实例,而一个作业实例可对应多个触发器;Scheduler做为定时任务容器,是quartz最上层的东西,它提携了所有触发器和作业,使它们协调工作,每个Scheduler都存有JobDetail和Trigger的注册,一个Scheduler中可以注册多个JobDetail和多个Trigger。)

面试总结:

文思海辉
1.乐观锁和悲观锁
悲观锁
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,
这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。

乐观锁
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,
但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。
乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。
在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

2、用了哪几种数据结构
数据结构分为8类有:数组、栈、队列、链表、红黑树、散列表、堆、图

3、了解几种设计模式
三大模式:
1、创建型模式:工厂方法模式、抽象工厂模式、单例模式
2、结构型模式:适配器模式、桥接模式、组合模式
3、行为型模式:策略模式、命令模式、状态模式

工厂模式:工厂类可以根据条件生成不同的子类实例,这些子类有一个公共的抽象父类并且实现了相同的方法,
但是这些方法针对不同的数据进行了不同的操作(多态方法)。当得到子类的实例后,
开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。

代理模式:给一个对象提供一个代理对象,并由代理对象控制原对象的引用。实际开发中,
按照使用目的的不同,代理可以分为:远程代理、虚拟代理、保护代理、Cache代理、防火墙代理、
同步化代理、智能引用代理等。

适配器模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起使用的类能够一起工作。

模板方法模式:提供一个抽象类,将部分逻辑以具体方法或构造器的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。
不同的子类可以以不同的方式实现这些抽象方法(多态实现),从而实现不同的业务逻辑。

4、同步于异步的区别
同步就是所有的任务都处在同一队列中,不可以插队,一个任务执行完接着开始执行下一个,相对于浏览器而言,
同步的效率过低,一些耗费时间比较长的任务应该用异步来执行。
异步就是将一个任务放入到异步队列中,当这个任务执行完成之后,再从异步队列中提取出来,
插队到同步队列中,拿到异步任务的结果,可以提升代码执行的效率,不需要因为一个耗费时长的代码而一直等待。

5、事物的隔离级别
MySQL的事务隔离级别一共有四个,分别是读未提交、读已提交、可重复读以及可串行化。
MySQL的隔离级别的作用就是让事务之间互相隔离,互不影响,这样可以保证事务的一致性。
隔离级别比较:可串行化>可重复读>读已提交>读未提交
隔离级别对性能的影响比较:可串行化>可重复读>读已提交>读未提交
由此看出,隔离级别越高,所需要消耗的MySQL性能越大(如事务并发严重性),
为了平衡二者,一般建议设置的隔离级别为可重复读,MySQL默认的隔离级别也是可重复读。

6、项目中哪些用到了微服务
业务复杂度和性能要求。

软通
1、常用的集合(hashmap底层实现红黑树的特性)
JDK1.8版本后,hashmap就是当链表中的元素达到8并且元素数量大于64时,
会将链表替换成红黑树才会树化时,会将链表替换成红黑树,红黑树是一种特殊的二叉查找树
,二叉查找树所有节点的左子树都小于该节点,
所有节点的右子树都大于该节点,就可以通过大小比较关系来进行快速的检索。

2、jvm的了解
Java虚拟机,我们编写的 Java 源码,编译后会生成一种 .class 文件,称为字节码文件。
Java 虚拟机(JVM)就是负责将字节码文件翻译成特定平台下的机器码然后运行,也就是说,只要在不同平台上安装对应的 JVM,就可以运行字节码文件,运行我们编写的 Java 程序。
3、多线程死锁,如何避免死锁
多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放,而该资源又被其他线程锁定,
从而导致每一个线程都得等其它线程释放其锁定的资源,造成了所有线程都无法正常结束。

如何避免死锁
1、加锁顺序:当多个线程需要相同的一些锁,但是按照相同的顺序加锁,死锁就不会发生。
2、加锁时限:加一个超时时间,若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁。
3、死锁检测:(从线程B所请求的锁开始,线程A找到了线程C,然后又找到了线程D,发现线程D请求的锁被线程A自己持有着。这是它就知道发生了死锁)
当检测出死锁时,释放所有锁,回退,并且等待一段随机的时间后重试

4、syn和lock的区别
1、lock是一个接口,而synchronized是java的一个关键字,synchronized是内置的语言实现
2、synchronized在发生异常时候会自动释放占有的锁,因此不会出现死锁;而lock发生异常时候,
不会主动释放占有的锁,必须手动unlock来释放锁,可能引起死锁的发生
3、lock等待锁过程中可以用interrupt来中断等待,而synchronized只能等待锁的释放,不能响应中断
4、Lock可以提高多个线程进行读操作的效率
5、在性能上,Lock的性能要远远优于synchronized。

东莞小天才

1、内存如何管理
垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法:System.gc()或Runtime.getRuntime().gc()

2、介绍一下你的项目,你负责的模块,开发文档如何编写

3、谈谈你的在工作过程中遇到最棘手的问题,做的总结,以及解决方法。

vue使用步骤
1、引用vue.js 2、新建Vue实例
3、数据绑定 4、事件绑定
5、表单控件绑定

存储过程性能优化
1.使用 SET NOCOUNT(设置之后“消息”少了受影响行数,减少网络流量)
SET NOCOUNT ON
go
sql语句
SET NOCOUNT OFF
go

2.使用确定的架构
如:select * from dbo.table 比select * from table 性能上要好
如果一张表是my.table,那么直接查询色select * from table 是会报错的
3.存储过程不要以"sp_"开头,因为这个是系统默认存储过程的开头,系统会多一道筛选
4.使用sp_executesql替代exec
sp_executesql可以使用参数,exec是直接拼sql字符串
5.少使用游标(sql是面向集合的,游标查询是面向行的)
6.事务尽量不要过长(过长会导致并发操作阻塞,最终使查询极慢,cpu占用率极低)
7.使用try-catch来处理异常

有了 Google Web Toolkit工具包 (GWT),
可以使用 Java 编程语言编写 AJAX 前端,然后 GWT 会交叉编译到优化的JavaScript 中,
而 JavaScript 可以自动在所有主要浏览器上运行。

Mule
以Java为核心的轻量级的消息框架和整合平台,基于EIP,
包括了服务终端和Javascript客户端允许事件被直接发布到浏览器,并且事件可以从浏览器进行发布

人事管理:
1、来公司面试的优势:

1、擅长 MySQL 性能优化、nginx集群。
2、沟通和自学能力强,项目中遇到不会的或者其他的困难,我都会尝试的自己去解决,百度呀、或者向身边的同事请教,等我了解梳理好后,会用idea写一个demo亲自测试下,然后在应用到项目中

2、简单说下你做过的项目:
管理门户系统,业务支撑系统、医疗电子病历系统、龙岗健康在线系统。这些系统主要是给医院或者患者使用,所有的系统都已上线,
每个项目的周期平均是9个月左右,用到最多的是oracle数据库,我主要是负责一些功能编码的实现。

3、哪个项目是你觉的做的最好

4、快到年底了为什么离职

1、晋升空间比较小。向换一个环境。
2、十月初的时候家里有事,离职后回家照顾家人,后续因为家人情况好转所以又返回来继承找工作。

5、是否接受加班
只要项目需要义不容辞,但是我也会在指定的工作计划时间内完成今天交付的任务。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值