List, Set, Map的区别
1、List中的元素,有序、可重复、可为空;
2、Set中的元素,无序、不重复、只有一个空元素;
3、Map中的元素,无序、键不重,值可重、可一个空键、多个空值;
ArrayList和LinkedList的区别
ArrayList:底层实现就是数组,且ArrayList实现了(/ˈrændəm/)RandomAccess( /ˈækses/ ),表示它能快速随机访问存储的元素,通过下标 index 访问,只是我们需要用 get() 方法的形式, 数组支持随机访问, 查询速度快, 增删元素慢。
LinkedList:底层实现是链表, (/lɪŋkt/)LinkedList 没有实现 RandomAccess 接口,链表支持顺序访问, 查询速度慢, 增删元素快。
HashMap和Hashtable的区别是什么
HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。
HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的( /kənˈkɜːrənt/ )concurrentHashMap。
HashMap 实现了Serializable( /ˈsɪŋkrənaɪz)接口,因此它支持序列化,实现了Cloneable接口,能被克隆。
Hashtable 中的方法是Synchronize的,在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步,但使用HashMap时就必须要自己增加同步处理。
HashMap由数组和链表来实现对数据的存储
HashMap采用Entry数组来存储key-value对,每一个键值对组成了一个Entry实体,Entry类实际上是一个单向的链表结构,它具有Next指针,可以连接下一个Entry实体,以此来解决Hash冲突的问题。
数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;
链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易。
HashMap结构及原理
HashMap是基于哈希表的Map接口的非同步实现。实现HashMap对数据的操作,允许有一个null键,多个null值。
HashMap底层就是一个数组结构,数组中的每一项又是一个链表。数组+链表结构,新建一个HashMap的时候,就会初始化一个数组。Entry就是数组中的元素,每个Entry(/ˈentri/ )其实就是一个key-value的键值对,它持有一个指向下一个元素的引用,这就构成了链表,HashMap底层将key-value当成一个整体来处理,这个整体就是一个Entry对象。HashMap底层采用一个Entry【】数组来保存所有的key-value键值对,当需要存储一个Entry对象时,会根据hash算法来决定在其数组中的位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry对象时,也会根据hash算法找到其在数组中的存储位置, 在根据equals方法从该位置上的链表中取出Entry。
TreeSet 和 HashSet 区别
HashSet 是采用 hash 表来实现的。其中的元素没有按顺序排列,add()、remove()以及contains()等方法都是复杂度为 O(1)的方法。
TreeSet 是采用树结构实现(红黑树算法)。元素是按顺序进行排列,但是 add()、
remove()以及 contains()等方法都是复杂度为 O(log (n))的方法。它还提供了一些方法来处理排序的 set,如 first(),last(),headSet(),tailSet()等等。
final的用法:
修饰数据:final修饰的数据的值是不可改变的
修饰方法参数:可以在参数前面添加final关键字,它表示在整个方法中,我们不会(实际上是不能)改变参数的值:
修饰方法:该方法不能被覆盖
修饰类:那就是用final修饰的类是无法被继承的。
static的用法:
被static所修饰的变量或者方法会储存在数据共享区;
被static修饰后的成员变量只有一份!
当成员被static修饰之后,就多了一种访问方式,除了可以被对象调用之外,还可以直接被类名调用,(类名.静态成员);
1、优点:
随着类的加载而被加载;
优先于对象存在;
被所有对象共享;
被static修饰的变量成为静态变量(类变量)或者实例变量;
2、存放位置:
类变量随着类的加载而存在于date内存区;
实例变量随着对象的建立而存在于堆内存;
3、方法注意事项:
静态的方法只能访问静态的成员;
非静态得方法即能访问静态得成员(成员变量,成员方法)又能访问非静态得成员;
局部变量不能被static修饰;
静态得方法中是不可以定义this、super关键字的,因为静态优先于对象存在,所以静态方法不可以出this;
4、什么时候使用static修成员:
当属于同一个类的所有对象出现共享数据时,就需要将存储这个共享数据的成员用static修饰;
多线程(并发线程)
进程和线程的区别:线程是进程的子集一个进程可以有多个线程,每条线程并行执行多个任务
start和run启动线程的区别:start是启动一个新的线程run方法是内部启动的但是run只是在原有的线程上启动不会启动新的线程
thread和runnable的区别:如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口好了。、
编写多线程程序的几种实现方式(换个问法:创建多线程的方式)?
(1)通过继承Thread类
(2)通过实现Runnable接口(推荐使用,因为Java中是单继承,一个类只有一个父类,若继承了Thread类,就无法在继承其它类,显然实现Runnable接口更为灵活)
(3)通过实现Callable接口(Java 5之后)。
sleep()和wait()的区别?
1.sleep()方法,属于Thread类的。;wait()方法,则是属于Object类的;
2.sleep方法不会释放锁,而wait方法会释放锁
3.wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
4.sleep需要接收时间参数,wait不需要接收时间参数;
5.sleep可以自然醒,wait必须等待别人唤醒;
Spring+SpringMVC:
Spring是一个容器,因为它包含并且管理应用对象的生命周期。
string和stringbuff和stringbuild区别
String类是不可变类,任何对String的改变都会引发新的String对象的生成;
StringBuffer是可变类,任何对它所指代的字符串的改变都不会产生新的对象,线程安全的。
StringBuilder是可变类,线性不安全的,不支持并发操作,不适合多线程中使用,但其在单线程中的性能比StringBuffer高。
谈谈你理解的spring的工作流程的理解?
创建配置文件applicationContext.xml
编写配置文件(加入一些对象的配置信息)
Spring内部采用工厂模式,配合xml解析+反射技术,根据用户的配置,生成相应的对象
工厂提供一个getBean方法,从工厂中获取对象
操作对象的方法,属性。
说说spring对象创建的三种方式。
1.无参构造2.实例工厂 3.静态工厂
SpringMVC的执行流程是什么?
第一步:发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求HandlerMapping查找 Handler
可以根据xml配置、注解进行查找
第三步:处理器映射器HandlerMapping向前端控制器返回Handler
第四步:前端控制器调用处理器适配器去执行Handler
第五步:处理器适配器去执行Handler
第六步:Handler执行完成给适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView
ModelAndView是springmvc框架的一个底层对象,包括Model和view
第八步:前端控制器请求视图解析器去进行视图解析
根据逻辑视图名解析成真正的视图(jsp)
第九步:视图解析器向前端控制器返回View
第十步:前端控制器进行视图渲染
视图渲染将模型数据(在ModelAndView对象中)填充到request域
第十一步:前端控制器向用户响应结果。
使用springMVC框架的时候,如何解决post和get的乱码问题?
解决post请求乱码:我们可以在web.xml里边配置一个CharacterEncodingFilter过滤器。设置为utf-8.
解决get请求的乱码:有两种方法。对于get请求中文参数出现乱码解决方法有两个:
1.修改tomcat配置文件添加编码与工程编码一致。
2.另外一种方法对参数进行重新编码 String userName = New String(Request.getParameter(“userName”).getBytes(“ISO8859-1”), “utf-8”);
IOC(DI)和AOP容器框架:
IOC控制反转,我们不再手动创建对象 而是将对象的创建权交给IOC容器,需要获取对象时直接从IOC容器中获取,IOC开发中实现的两种方式xml和注解通过配置Spring.xml文件或者注解 ClassPathXmlApplicationContext。
IOC创建多个实例:在bean标签中加入属性scope(“prototype”)
AOP面向切面编程:利用AOP编程实现日志记录功能
TCP和UDP的区别
1、TCP(面向连接如打电话要先拨号建立连接),建立TCP连接需经过三次握手,释放TCP连接需经过四次挥手;UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。
3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP对系统资源要求较多,UDP对系统资源要求较少。
乐观锁和悲观锁
悲观锁:总是假设最坏的情况。
每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁。
传统的关系型数据库里边就用到了很多这种锁机制,比如读锁,写锁等,都是在做操作之前先上锁。
乐观锁
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。
乐观锁适用于写比较少的情况,即冲突真的很少发生,这样可以省去锁的开销,从而提高系统的吞吐量。
悲观锁使用于写比较频繁的情况,即经常产生冲突,上层引用会不断的进行重试,这样反倒降低了性能,所以使用锁比较合适。
SSM:
SpringBoot整合Mybatis+SpringMVC
SpringBoot极大的简化的SSM整合过程,只需要加入相关依赖和少量配置即可。
Spring Boot 是 Spring 开源组织下的一个子项目,也是 Spring 组件一站式解决方案,主要是为了简化使用 Spring 框架的难度,简省繁重的配置。
Spring Boot提供了各种组件的启动器(starters),开发者只要能配置好对应组件参数,Spring Boot 就会自动配置,让开发者能快速搭建依赖于 Spring 组件的 Java 项目。
分布式开发经验:
架构
分布式的系统架构,主要从以下几个方面来考虑:分层、面向服务以及分布式数据库。
分层模型
一般地,我们将应用程序功能分为三个方面,对应3层架构模式。它们是数据层、中间层(业务逻辑层)和表示层,如下图所示。
数据层:存储数据以及从数据库中获得较为原始的数据。
业务逻辑层:介于数据层和表示层之间,负责处理来自数据存储或发送给数据存储的数据,把数据转换成符合商务规则的有意义的信息。
表示层:从业务逻辑层获得信息并显示给用户,负责与用户的交互。
针对大型的网站应用,分布式部署策略可以从以下几个方面考虑:
代理服务器实现请求的分离 。
缓存的分布式部署,提高系统性能。
拆分网站的对外功能,例如不同域名前、后缀,URL 重写。
面向服务,每个服务分布到一台服务器上 。
数据库的分布式集群部署。
SQL优化经验:
要提高SQL语句的执行效率,最常见的方法就是建立索引,以及尽量避免全表扫描。在本章MySQL教程中,UncleToo给大家整理一些常见的SQL优化技巧,避免全表扫描。一个简单的优化,也许能让你的SQL执行效率提高几倍,甚至几十倍。
1、避免在where子句中使用 is null 或 is not null 对字段进行判断。
如:select id from table where name is null
在这个查询中,就算我们为 name 字段设置了索引,查询分析器也不会使用,因此查询效率底下。为了避免这样的查询,在数据库设计的时候,尽量将可能会出现 null 值的字段设置默认值,这里如果我们将 name 字段的默认值设置为0,那么我们就可以这样查询:
select id from table where name = 0
2、避免在 where 子句中使用 != 或 <> 操作符。
如:select name from table where id <> 0
数据库在查询时,对 != 或 <> 操作符不会使用索引,而对于 < 、 <= 、 = 、 > 、 >= 、 BETWEEN AND,数据库才会使用索引。因此对于上面的查询,正确写法应该是:
select name from table where id < 0
union all
select name from table where id > 0
这里我们为什么没有使用 or 来链接 where 后的两个条件呢?这就是我们下面要说的第3个优化技巧。
3、避免在 where 子句中使用 or来链接条件。
如:select id from tabel where name = ‘UncleToo’ or name = ‘PHP’
这种情况,我们可以这样写:
select id from tabel where name = ‘UncleToo’
union all
select id from tabel where name = ‘PHP’
4、少用 in 或 not in。
虽然对于 in 的条件会使用索引,不会全表扫描,但是在某些特定的情况,使用其他方法也许效果更好。如:select name from tabel where id in(1,2,3,4,5)
像这种连续的数值,我们可以使用 BETWEEN AND,如:
select name from tabel where id between 1 and 5
5、注意 like 中通配符的使用。
下面的语句会导致全表扫描,尽量少用。如:select id from tabel where name like’%UncleToo%’
或者select id from tabel where name like’%UncleToo’
而下面的语句执行效率要快的多,因为它使用了索引:
select id from tabel where name like’UncleToo%’
6、避免在 where 子句中对字段进行表达式操作。
如:select name from table where id/2 = 100
正确的写法应该是:select name from table where id = 100*2
7、避免在 where 子句中对字段进行函数操作。
如:select id from table where substring(name,1,8) = ‘UncleToo’
或select id from table where datediff(day,datefield,‘2014-07-17’) >= 0
这两条语句中都对字段进行了函数处理,这样就是的查询分析器放弃了索引的使用。正确的写法是这样的:select id from table where name like’UncleToo%’
或select id from table where datefield <= ‘2014-07-17’
也就是说,不要在 where 子句中的 = 左边进行函数、算术运算或其他表达式运算。
8、在子查询中,用 exists 代替 in 是一个好的选择。
如:select name from a where id in(select id from b)
如果我们将这条语句换成下面的写法:
select name from a where exists(select 1 from b where id = a.id)
这样,查询出来的结果一样,但是下面这条语句查询的速度要快的多。
Spring MVC(视图框架)
Spring MVC 是一个 MVC 开源框架,用来代替 Struts。它是 Spring 项目里面的一个重要组成部分,能与 Spring IOC 容器紧密结合,以及拥有松耦合、方便配置、代码分离等特点,让 JAVA 程序员开发 WEB 项目变得更加容易。
SpringMVC 的工作原理
a. 用户向服务器发送请求,请求被 springMVC 前端控制器 DispatchServlet 捕获;
b. DispatcherServle 对请求 URL 进行解析,得到请求资源标识符(URL),然后根据该 URL 调用 HandlerMapping
将请求映射到处理器 HandlerExcutionChain;
c. DispatchServlet 根据获得 Handler 选择一个合适的 HandlerAdapter 适配器处理;
d. Handler 对数据处理完成以后将返回一个 ModelAndView()对象给 DisPatchServlet;
e. Handler 返回的 ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet 通过
ViewResolver 试图解析器将逻辑视图转化为真正的视图 View;
h. DispatcherServle 通过 model 解析出 ModelAndView()中的参数进行解析最终展现出完整的 view 并返回给客户端;
SpringMVC 常用注解都有哪些?
@requestMapping 用于请求 url 映射。
@RequestBody 注解实现接收 http 请求的 json 数据,将 json 数据转换为 java 对象。
@ResponseBody 注解实现将 controller 方法返回对象转化为 json 响应给客户。
Spring Boot(是一个简化Spring开发的框架)
SpringBoot整合Mybatis+SpringMVC
SpringBoot极大的简化的SSM整合过程,只需要加入相关依赖和少量配置即可。
Spring Boot 是 Spring 开源组织下的一个子项目,也是 Spring 组件一站式解决方案,主要是为了简化使用 Spring 框架的难度,简省繁重的配置。
Spring Boot提供了各种组件的启动器(starters),开发者只要能配置好对应组件参数,Spring Boot 就会自动配置,让开发者能快速搭建依赖于 Spring 组件的 Java 项目。
Spring boot执行流程
1、 用户发送请求至前端控制器DispatcherServlet。
2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、 DispatcherServlet调用HandlerAdapter处理器适配器。
5、 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、 Controller执行完成返回ModelAndView。
7、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、 ViewReslover解析后返回具体View。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、 DispatcherServlet响应用户。
SpringBoot核心原理
基于SpringMVC无配置文件(纯Java)完全注解化+内置tomcat-embed-core实现SpringBoot框架,Main函数启动。
SpringBoot核心快速整合第三方框架原理:Maven继承依赖关系。
Mybatis/ iBatis(持久层框架)
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
1.Mybatis 的编程步骤是什么样的?
1、创建 SqlSessionFactory
2、通过 SqlSessionFactory 创建 SqlSession
3、通过 sqlsession 执行数据库操作
4、调用 session.commit()提交事务
5、调用 session.close()关闭会话
Mybatis #{}和KaTeX parse error: Expected 'EOF', got '#' at position 11: {}的区别是什么? #̲{}是预编译处理,{}是字符串替换。
Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
Mybatis在处理 时 , 就 是 把 {}时,就是把 时,就是把{}替换成变量的值。
使用#{}可以有效的防止SQL注入,提高系统安全性。
MySQL:
MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
MySQL索引类型:
Mysql目前主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RTREE。
Spring 框架现在是 Java 后端框架家族里面最强大的一个,其拥有 IOC 和 AOP 两大利器,大大简化了软件开发复杂性。并且,Spring 现在能与所有主流开发框架集成,可谓是一个万能框架,Spring 让 JAVA 开发变得更多简单。
Spring 容器的主要核心是:
控制反转(IOC),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接
或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用 spring 提供的对象就可以了,这是控制反转的思想。
依赖注入(DI),spring 使用 javaBean 对象的 set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。
面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等。公用操作处理的过程就是面向切面编程的思想。AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用CGLIB 方式实现动态代理。
Spring 的常用注解
@Required:该注解应用于设值方法
@Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变量。
@Qualifier:该注解和@Autowired 搭配使用,用于消除特定 bean 自动装配的歧义。
简单介绍一下 Spring bean 的生命周期
bean 定义:在配置文件里面用来进行定义。
bean 初始化:有两种方式初始化:
1.在配置文件中通过指定 init-method 属性来完成
2.实现 org.springframwork.beans.factory.InitializingBean 接口
bean 调用:有三种方式可以得到 bean 实例,并进行调用
bean 销毁:销毁有两种方式
1.使用配置文件指定的 destroy-method 属性
2.实现 org.springframwork.bean.factory.DisposeableBean 接口
有哪些不同类型的 IOC(依赖注入)方式?
Spring 提供了多种依赖注入的方式:
1.Set 注入
2.构造器注入
3.静态工厂的方法注入
4.实例工厂的方法注入
Spring Cloud(微服务框架)
Spring Cloud 是一系列框架的有序集合,是目前最火热的微服务框架首选,它利用Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。
Spring Cloud常用组件
服务发现——Netflix Eureka
客服端负载均衡——Netflix Ribbon
断路器——Netflix Hystrix
服务网关——Netflix Zuul
分布式配置——Spring Cloud Config。
Hibernate(服务端验证)
Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,它将 POJO 与数据库表建立映射关系,是一个全自动的 orm 框架。Hibernate 可以自动生成 SQL 语句,自动执行,使得 Java 程序员可以随心所欲的使用对象编程思维来操作数据库。
简述一下 hibernate 的开发流程
第一步:加载 hibernate 的配置文件,读取配置文件的参数(jdbc 连接参数,数据 库方言,hbm 表与对象关系映射文件)
第二步:创建 SessionFactory 会话工厂(内部有连接池)
第三步:打开 session 获取连接,构造 session 对象(一次会话维持一个数据连接, 也是一级缓存)
第四步:开启事务
第五步:进行操作
第六步:提交事务
第七步:关闭 session(会话)将连接释放
第八步:关闭连接池
hibernate 中对象的三种状态
瞬时态(临时态、自由态):不存在持久化标识 OID,尚未与 Hibernate Session 关联对象, 被认为处于瞬时态,失去引用将被 JVM 回收
持久态:存在持久化标识 OID,与当前 session 有关联,并且相关联的 session 没有关闭 , 并且事务未提交
脱管态(离线态、游离态):存在持久化标识 OID,但没有与当前 session 关联,脱管状态 改变 hibernate 不能检测到。
Hibernate 的查询方式有哪些
Hibernate 的查询方式常见的主要分为三种: HQL, QBC(命名查询), 以及使用原生 SQL 查询(SqlQuery) 。
Hibernate 和 Mybatis 的区别?
两者相同点:
1)Hibernate 与 MyBatis 都可以是通过 SessionFactoryBuider 由 XML 配置文件生成 SessionFactory,然后由SessionFactory 生成 Session,最后由 Session 来开启执行事务和 SQL 语句。其中 SessionFactoryBuider,SessionFactory,Session 的生命周期都是差不多的。
2)Hibernate 和 MyBatis 都支持 JDBC 和 JTA 事务处理。
Mybatis 优势:
1)MyBatis 可以进行更为细致的 SQL 优化,可以减少查询字段。
2)MyBatis 容易掌握,而 Hibernate 门槛较高。
Hibernate 优势:
1)Hibernate 的 DAO 层开发比 MyBatis 简单,Mybatis 需要维护 SQL 和结果映射。
2)Hibernate 对对象的维护和缓存要比 MyBatis 好,对增删改查的对象的维护要方便。
3)Hibernate 数据库移植性很好,MyBatis 的数据库移植性不好,不同的数据库需要写不同 SQL。
4)Hibernate 有更好的二级缓存机制,可以使用第三方缓存。MyBatis 本身提供的缓存机制不佳。
关于 Hibernate 的 orm 思想你了解多少?
ORM 指的是对象关系型映射(Object RelationShip Mapping ),指的就是我们通过创建实体类对象和数据库中的表关系进行一一对应,来实现通过操作实体类对象来更改数据库里边的数据信息。这里边起到关键作用的是通过Hibernate 的映射文件+Hibernate 的核心配置文件。
如何进行 Hibernate 的优化?
(1)数据库设计调整。
(2)HQL 优化。
(3)API 的正确使用(如根据不同的业务类型选用不同的集合及查询 API)。
(4)主配置参数(日志,查询缓存,fetch_size, batch_size 等)。
(5)映射文件优化(ID 生成策略,二级缓存,延迟加载,关联优化)。
(6)一级缓存的管理。
(7)针对二级缓存,还有许多特有的策略。
(8)事务控制策略。
Dubbo(高性能Java RPC框架)
Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已成为 Apache 基金会孵化项目。使用 Dubbo 可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用灵活扩展,使前端应用能更快速的响应多变的市场需求。
Dubbo 的容错机制有哪些。
Dubbo 官网提出总共有六种容错策略:
1)Failover Cluster 模式
失败自动切换,当出现失败,重试其它服务器。(默认)
2)Failfast Cluster
快速失败,只发起一次调用,失败立即报错。 通常用于非幂等性的写操作,比如新增记录。
3)Failsafe Cluster
失败安全,出现异常时,直接忽略。 通常用于写入审计日志等操作。
4)Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。 通常用于消息通知操作。
5)Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=”2”来设置最大并行数。
6)Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0 开始支持) 通常用于通知所有提供者更新缓存或日志等本地资源信息。
总结: 在实际应用中查询语句容错策略建议使用默认 Failover Cluster ,而增删改建议使用 Failfast Cluster 或 者 使用 Failover Cluster(retries=”0”) 策略 防止出现数据 重复添加等等其它问题!建议在设计接口时候把查询接口方法单独做一个接口提供查询。
Dubbo 的连接方式有哪些?
Dubbo 的客户端和服务端有三种连接方式,分别是:广播,直连和使用 zookeeper 注册中心。
Netty(Netty是由JBOSS提供的一个java开源框架)
Netty 是由 JBOSS 提供的一个开源的、异步的、基于事件驱动的网络通信框架,用 Netty 可以快速开发高性能、高可靠性的网络服务器和客户端程序,Netty 简化了网络应用的编程开发过程,使开发网络编程变得异常简单。
Shiro(安全框架)
Apache Shiro是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密。
三个核心组件:Subject, SecurityManager 和 Realms。
Subject:即“当前操作用户”。但是,在 Shiro 中,Subject 这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是 Shiro 的“用户”概念。
Subject 代表了当前用户的安全操作,SecurityManager 则管理所有用户的安全操作。
SecurityManager:它是 Shiro 框架的核心,典型的 Facade 模式,Shiro 通过 SecurityManager 来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm: Realm 充当了 Shiro 与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro 会从应用配置的 Realm 中查找用户及其权限信息。
Shiro 主要的四个组件
1)SecurityManager
典型的 Facade,Shiro 通过它对外提供安全管理的各种服务。
2)Authenticator
对“Who are you ?”进行核实。通常涉及用户名和密码。 这个组件负责收集 principals 和 credentials,并将它们提交给应用系统。如果提交的 credentials 跟应用系统中提供的 credentials 吻合,就能够继续访问,否则需要重新提交 principals 和 credentials, 或者直接终止访问。
3)Authorizer
身份份验证通过后,由这个组件对登录人员进行访问控制的筛查,比如“who can do what”, 或者“who can do which actions”。 Shiro 采用“基于 Realm”的方法,即用户(又称 Subject)、 用户组、角 色和permission 的聚合体。 感恩于心,回报于行。 面试宝典系列-Java
4)Session Manager
这个组件保证了异构客户端的访问,配置简单。它是基于 POJO/J2SE 的,不跟任何的客户 端或者协议绑定。
Shiro 运行原理
1、Application Code:应用程序代码,就是我们自己的编码,如果在程序中需要进 行权限控制,需要调用Subject 的 API。
2、Subject:主体,代表的了当前用户。所有的 Subject 都绑定到 SecurityManager, 与 Subject 的所有交互都会委托给 SecurityManager,可以将 Subject 当成一个 门面,而真正执行者是 SecurityManager 。
3、SecurityManage:安全管理器,所有与安全有关的操作都会与 SecurityManager 交互,并且它管理所有的 Subject 。
4、Realm:域 shiro 是从 Realm 来获取安全数据(用户,角色,权限)。就是说 SecurityManager 要验证用户身份, 那么它需要从 Realm 获取相应的用户进行比较以确定用户 身份是否合法;也需要从Realm 得到用户相应的角色/权限进行验证用户是否 能进行操作; 可以把 Realm 看成 DataSource,即安全数据源 。
Ehcache(缓存框架)
EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的CacheProvider。它使用的是 JVM 的堆内存,超过内存可以设置缓存到磁盘,企业版的可以使用 JVM 堆外的物理内存。
Shiro 的四种权限控制方式
1)url 级别权限控制
2)方法注解权限控制
3)代码级别权限控制
4)页面标签权限控制
Quartz(定时任务调度框架)
Quartz 是一个基于 Java 的广泛使用的开源的任务调度框架,做过定时任务的没有没用过这个框架的吧。
配置文件 applicationContext_job.xml 各个属性作用
(1)、Job:表示一个任务(工作),要执行的具体内容。
(2)、JobDetail:表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外
JobDetail 还包含了这个任务调度的方案和策略。
(3)、Trigger:代表一个调度参数的配置,什么时候去调。
(4)、Scheduler:代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与JobDetail 组合,就可以被 Scheduler 容器调度了。
.如何监控 Quartz 的 job 执行状态:运行中,暂停中,等待中?
通过往表(新建一个操作日志表)里插入日志的形式:
1)运行中:通过 JobListener 监听器来实现运行时更改表信息。
2)暂停中:调用 scheduler.pauseTrigger()方法时,更改表中 job 信息。
3)等待中:新添加的 job 默认给其等待中的状态,也是更改表中的 job 信息 但是上面这种形式的麻烦之处是得频繁的往表里插入数据。
Velocity( Velocity是一个基于Java的模板引擎)
Velocity 是一个基于 Java 的模板引擎,简单而强大的模板语言为各种 Web 框架提供模板服务,来适配 MVC 模型。
jQuery(jQuery是一个快速、简洁的JavaScript框架)
jQuery是一个快速、简洁的 JavaScript 框架,它封装 JavaScript 常用的功能代码,提供一种简便的 JavaScript 设计模式,极大地简化了 JavaScript 编程。
JUnit(是一个Java语言的单元测试框架)
JUnit 是一个 Java 语言的单元测试框架,绝大多数 Java 的开发环境都已经集成了 JUnit 作为其单元测试的工具。
Log4j(日志)
Log4j 是 Apache 的一个开源日志框架,通过 Log4j 我们可以将程序中的日志信息输出到控制台、文件等来记录日志。作为一个最老牌的日志框架,它现在的主流版本是 Log4j2。Log4j2是重新架构的一款日志框架,抛弃了之前 Log4j 的不足,以及吸取了优秀日志框架 Logback 的设计。
什么是中间件:非底层操作系统软件,非业务应用软件,不是直接给最终用户使用的,不能直接给客户带来价值的软件统称为中间件。
什么是消息中间件:关注于数据的发送和接受,利用高效可靠的异步消息传递机制集成分布式系统
为什么使用消息中间件
消息中间件作用:解耦服务调用。松耦合。 使用中间件,不用等调用的服务处理完才返回结果。提高效率。
kafka 是一个高吞吐量的分布式发布订阅消息系统,是一个分布式的,分区的,可靠的分布式日志存储服务。(不是一个严格消息中间件 )
1)高吞吐量:即使非常普通的硬件kafka也可以支持每秒数百万的消息
消息中间件带来的好处
解耦
异步
横向扩展
安全可靠
顺序保证
等等。。。
什么是JMS:Java消息服务(Java Message Service)即JMS,是一个Java平台中关于面向消息中间件的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
什么是AMQP:AMQP(advanced message queuing protocol)是一个提供统一消息服务的应用层标准协议,基于此协议的客户端与消息中间件可传递消息,并不接受客户端/中间件不同产品,不同开发语言等条件的限制。
Redis 的特点?
Redis 是由意大利人 Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库。Redis 全称为:Remote Dictionary Server(远程数据服务),该软件使用 C 语言编写,典型的 NoSQL 数据库服务器,Redis 是一 个 key-value 存储系统,它支持丰富的数据类型,如:string、list、set、zset(sorted set)、hash。 Redis 本质上是一个 Key-Value 类型的内存数据库,很像 memcached,整个 数据库统统加载在内存当中进 行操作,定期通过异步操作把数据库数据 flush 到硬盘 上进行保存。因为是纯内存操作,Redis 的性能非常出色,每秒 可以处理超过 10 万次读写操作,是已知性能最快的 Key-Value DB。
Redis 的出色之处不仅仅是性能,Redis 最大的魅力是支持保存多种数据结构,此外单 个 value 的最大限制是 1GB,不像 memcached 只能保存 1MB 的数据,另外 Redis 也可以对存入的 Key-Value 设置 expire 时间。
Redis 的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此 Redis 适合的场景主要 局限在较小数据量的高性能操作和运算上。
为什么 redis 需要把所有数据放到内存中?
Redis 为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以 redis 具有快速和 数据持久化的特征。如果不将数据放在内存中,磁盘 I/O 速度为严重影响 redis 的性能。在内存越来越便宜的今天, redis 将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
Redis 最适合的场景有哪些?
(1)、会话缓存(Session Cache)
(2)、全页缓存(FPC)
(3)、队列
(4)、排行榜/计数器
(5)、发布/订阅
Redis 有哪几种数据结构?
Redis 的数据结构有五种,分别是:
String——字符串
String 数据结构是简单的 key-value 类型,value 不仅可以是 String,也可以是数字(当数字类型用 Long 可
以表示的时候 encoding 就是整型,其他都存储在 sdshdr 当做字符串)。
Hash——字典
在 Memcached 中,我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值
(一般是 JSON 格式),比如用户的昵称、年龄、性别、积分等。
List——列表
List 说白了就是链表(redis 使用双端链表实现的 List),相信学过数据结构知识的人都应该能理解其结构。
Set——集合
Set 就是一个集合,集合的概念就是一堆不重复值的组合。利用 Redis 提供的 Set 数据结构,可以存储一些集
合性的数据。
Sorted Set——有序集合
和 Sets 相比,Sorted Sets 是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进
行有序排列,
ZooKeeper 的基本运转流程:
1、选举 Leader。2、同步数据。3、选举 Leader 过程中算法有很多,但要达到的选举标准是一致的。 4、Leader 要具有最高的执行 ID,类似 root 权限。 5、集群中大多数的机器得到响应并 follow 。
选出的 Leader。
简单介绍一下 solr
Solr 是一个独立的企业级搜索应用服务器,它对外提供类似于 Web-service 的 API 接口。 用户可以通过 http 请求,向搜索引擎服务器提交一定格式的 XML 文件,生成索引;也可以 通过 Http Get 操作提出查找请求,并得到XML 格式的返回结果。
solr 特点:
Solr 是一个高性能,采用 Java5 开发,基于 Lucene 的全文搜索服务器。同时对其进行 了扩展,提供了比Lucene 更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能 进行了优化,并且提供了一个完善的功能管
理界面,是一款非常优秀的全文搜索引擎。
solr 工作方式:
文档通过 Http 利用 XML 加到一个搜索集合中。查询该集合也是通过 http 收到一个 XML/JSON 响应来实现。它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮 显示搜索结果,通过索引复制来提高可用性,提供一套强大 Data Schema 来定义字段,类 型和设置文本分析,提供基于 Web 的管理界面等。
solr 怎么设置搜索结果排名靠前?
可以设置文档中域的 boost 值,boost 值越高,计算出来的相关度得分就越高,排名也就越靠前。此方法可以把热点商品或者推广商品的排名提高。
solr 中 IK 分词器原理是什么?
Ik 分词器的分词原理本质上是词典分词。先在内存中初始化一个词典,然后在分词过程中挨个读取字符,和字典中的字符相匹配,把文档中的所有的词语拆分出来的过程。
Activity 工作流
Activity 什么是工作流?
现在大多数公司的请假流程是这样的:员工打电话(或网聊)向上级提出请假申请——上级口头同 意——上级将请假记录下来——月底将请假记录上交公司——公司将请假录入电脑。采用工作流技术的公司的请假流 程是这样的:员工使用账户登录系统——点击请假——上级登录系统点击允许。就这样,一个请假流程就结束了。有
人会问,那上级不用向公司提交请假记录?公司不用将记录录入电脑?答案是,用的。但是这一切的工作都会在上级 点击允许后自动运行!这就是工作流技术。
Georgakopoulos 给出的工作流定义是: 工作流是将一组任务组织起来以完成某个经营过程:定义了任务的触 发顺序和触发条件,每个任务可以由一个或多个软件系统完成,也可以由一个或一组人完成,还可以由一个或多个人 与软件系统协作完。
Activity 工作流技术的优点
从上面的例子,很容易看出,工作流系统实现了工作流程的自动化,提高了企业运营效率、改善企业资源利
用、提高企业运作的灵活性和适应性、提高量化考核业务处理的效率、减少浪费(时间就是金钱)。而手工处理工
作流程,一方面无法对整个流程状况进行有效跟踪、了解,另一方面难免会出现人为的失误和时间上的延时导致
效率低下,特别是无法进行量化统计,不利于查询、报表及绩效评估。
Activity 工作流生命周期
除了我们自行启动(start)或者结束(finish)一个 Activity,我们并不能直接控制一个 Activity 的生 命状态,我们只能通过实现 Activity 生命状态的表现——即回调方法来达到管理 Activity 生命周期的变化。
Git
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
Git 与 SVN 区别
GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。
如果你是一个具有使用SVN背景的人,你需要做一定的思想转换,来适应GIT提供的一些概念和特征。
Git 与 SVN 区别点:
1、GIT是分布式的,SVN不是:这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。
2、GIT把内容按元数据方式存储,而SVN是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。
3、GIT分支和SVN的分支不同:分支在SVN中一点不特别,就是版本库中的另外的一个目录。
4、GIT没有一个全局的版本号,而SVN有:目前为止这是跟SVN相比GIT缺少的最大的一个特征。
5、GIT的内容完整性要优于SVN:GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。