我是靠谱客的博主 开放薯片,最近开发中收集的这篇文章主要介绍面试题综合JVM 知识开源框架知识操作系统多线程TCP 与 HTTP架构设计与分布式算法数据库知识消息队列Redis,Memcached搜索MQ分布式系统事务一致性解决方案redis分布式缓存多线程的40个面试题总结Servlet面试题归纳Redis面试题及分布式集群高可用分布式集群spring常见的面试题springmvc和mybatis面试题(含答案)Hibernate常见面试题对于Dubbo一些面试题自己的答案rmi://memcached://redis://1)Multicast 注册,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

优化数据库

1.数据库查询使用索引

外链接面试题大全

  • Oralce数据库的优化(面试必问题)

  • 数据库常见面试题

SSh三大框架常考面试题简述

hibernate工作原理及为什么要用?

原理:
1. 读取并解析配置文件
2. 读取并解析映射信息,创建SessionFactory
3. 打开Sesssion
4. 创建事务Transation
5. 持久化操作
6. 提交事务
7. 关闭Session
8. 关闭SesstionFactory
为什么要用:
● 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
● Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作
● hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
● hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
2. Hibernate是如何延迟加载?
1. Hibernate 延迟加载实现:a)实体对象 b)集合(Collection)
2. Hibernate 提供了属性的延迟加载功能
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。
3.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、
4. 说下Hibernate的缓存机制
1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存
2. 二级缓存:
a) 应用级缓存
b) 分布式缓存
条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非关键数据
c) 第三方缓存的实现
5. Hibernate的查询方式
Sql、Criteria,object comptosition
Hql:
1. 属性查询
2. 参数查询、命名参数查询
3. 关联查询
4. 分页查询
5. 统计函数
6. 如何优化Hibernate?
● 使用双向一对多关联,不使用单向一对多
● 灵活使用单向一对多关联
● 不用一对一,用多对一取代
● 配置对象缓存,不使用集合缓存
● 继承类使用显式多态
● 表字段要少,表关联不要怕多,有二级缓存撑腰
spring
为什么用:
{AOP 让开发人员可以创建非行为性的关注点,称为横切关注点,并将它们插入到应用程序代码中。使用 AOP 后,公共服务 (比如日志、持久性、事务等)就可以分解成方面并应用到域对象上,同时不会增加域对象的对象模型的复杂性。
IOC 允许创建一个可以构造对象的应用环境,然后向这些对象传递它们的协作对象。正如单词 倒置 所表明的,IOC 就像反 过来的 JNDI。没有使用一堆抽象工厂、服务定位器、单元素(singleton)和直接构造(straight construction),每一个对象都是用其协作对象构造的。因此是由容器管理协作对象(collaborator)。
Spring即使一个AOP框架,也是一IOC容器。 Spring 最好的地方是它有助于您替换对象。有了 Spring,只要用 JavaBean 属性和配置文件加入依赖性(协作对象)。然后可以很容易地在需要时替换具有类似接口的协作对象。}
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,如图 1 所示。
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
☆ 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
☆ Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
☆ Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
☆ Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
☆ Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
☆ Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
☆ Spring MVC 框架:MVC 框架是一个全功能的构建Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。
IOC 和 AOP
控制反转模式(也称作依赖性介入)的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器(在 Spring 框架中是 IOC 容器) 负责将这些联系在一起。
在典型的 IOC 场景中,容器创建了所有对象,并设置必要的属性将它们连接在一起,决定什么时间调用方法。下表列出了 IOC 的一个实现模式。
Spring 框架的 IOC 容器采用类型 2 和类型3 实现。
面向方面的编程
面向方面的编程,即 AOP,是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。
AOP 和 IOC 是补充性的技术,它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类不需要知道日志服务的存在,也不需要考虑相关的代码。所以,用 Spring AOP 编写的应用程序代码是松散耦合的。
AOP 的功能完全集成到了 Spring 事务管理、日志和其他各种特性的上下文中。
IOC 容器
Spring 设计的核心是 org.springframework.beans 包,它的设计目标是与 JavaBean 组件一起使用。这个包通常不是由用户直接使用,而是由服务器将其用作其他多数功能的底层中介。下一个最高级抽象是 BeanFactory 接口,它是工厂设计模式的实现,允许通过名称创建和检索对象。BeanFactory 也可以管理对象之间的关系。
BeanFactory 支持两个对象模型。
□ 单态 模型提供了具有特定名称的对象的共享实例,可以在查询时对其进行检索。Singleton 是默认的也是最常用的对象模型。对于无状态服务对象很理想。
□ 原型 模型确保每次检索都会创建单独的对象。在每个用户都需要自己的对象时,原型模型最适合。
bean 工厂的概念是 Spring 作为 IOC 容器的基础。IOC 将处理事情的责任从应用程序代码转移到框架。正如我将在下一个示例中演示的那样,Spring 框架使用 JavaBean 属性和配置数据来指出必须设置的依赖关系。
BeanFactory 接口
因为 org.springframework.beans.factory.BeanFactory 是一个简单接口,所以可以针对各种底层存储方法实现。最常用的 BeanFactory 定义是 XmlBeanFactory,它根据 XML 文件中的定义装入 bean,如清单 1 所示。
清单 1. XmlBeanFactory
BeanFactory factory = new XMLBeanFactory(new FileInputSteam("mybean.xml"));
在 XML 文件中定义的 Bean 是被消极加载的,这意味在需要 bean 之前,bean 本身不会被初始化。要从 BeanFactory 检索 bean,只需调用 getBean() 方法,传入将要检索的 bean 的名称即可,如清单 2 所示。
清单 2. getBean()
MyBean mybean = (MyBean) factory.getBean("mybean");
每个 bean 的定义都可以是 POJO (用类名和 JavaBean 初始化属性定义) 或 FactoryBean。FactoryBean 接口为使用 Spring 框架构建的应用程序添加了一个间接的级别。
Struts工作机制?为什么要使用Struts?
工作机制:
Struts的工作流程:
在web应用启动时就会加载初始化ActionServlet,ActionServlet从struts-config.xml文件中读取配置信息,把它们存放到各种配置对象..
当ActionServlet接收到一个客户请求时,将执行如下流程.
(1)检索和用户请求匹配的ActionMapping实例,如果不存在,就返回请求路径无效信息;
(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中;
(3)根据配置信息决定是否需要表单验证.如果需要验证,就调用ActionForm的validate()方法;
(4)如果ActionForm的validate()方法返回null或返回一个不包含ActionMessage的ActionErrors对象, 就表示表单验证成功;
(5)ActionServlet根据ActionMapping所包含的映射信息决定将请求转发给哪个Action,如果相应的Action实例不存在,就先创建这个实例,然后调用Action的execute()方法;
(6)Action的execute()方法返回一个ActionForward对象,ActionServlet在把客户请求转发给ActionForward对象指向的JSP组件;
(7)ActionForward对象指向JSP组件生成动态网页,返回给客户;
为什么要用:
JSP、Servlet、JavaBean技术的出现给我们构建强大的企业应用系统提供了可能。但用这些技术构建的系统非常的繁乱,所以在此之上,我们需要一个规则、一个把这些技术组织起来的规则,这就是框架,Struts便应运而生。
基于Struts开发的应用由3类组件构成:控制器组件、模型组件、视图组件
Struts的validate框架是如何验证的?
在struts配置文件中配置具体的错误提示,再在FormBean中的validate()方法具体调用。
说下Struts的设计模式
MVC模式: web应用程序启动时就会加载并初始化ActionServler。用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数据,ActionServler根据Struts-config.xml 文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的Validate()验证后选择将请求发送到哪个Action,如果 Action不存在,ActionServlet会先创建这个对象,然后调用Action的execute()方法。Execute()从 ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对象,ActionServlet再把客户请求转发给 ActionForward对象指定的jsp组件,ActionForward对象指定的jsp生成动态的网页,返回给客户。
单例模式
Factory(工厂模式):
定义一个基类===》实现基类方法(子类通过不同的方法)===》定义一个工厂类(生成子类实例)
===》开发人员调用基类方法
Proxy(代理模式)
spring工作机制及为什么要用?
1.spring mvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。
2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller.
3.DispatcherServlet请请求提交到目标Controller
4.Controller进行业务逻辑处理后,会返回一个ModelAndView
5.Dispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象
6.视图对象负责渲染返回给客户端。
为什么用:
AOP 让开发人员可以创建非行为性的关注点,称为横切关注点,并将它们插入到应用程序代码中。使用 AOP 后,公共服务 (比 如日志、持久性、事务等)就可以分解成方面并应用到域对象上,同时不会增加域对象的对象模型的复杂性。
IOC 允许创建一个可以构造对象的应用环境,然后向这些对象传递它们的协作对象。正如单词 倒置 所表明的,IOC 就像反 过来的 JNDI。没有使用一堆抽象工厂、服务定位器、单元素(singleton)和直接构造(straight construction),每一个对象都是用 其协作对象构造的。因此是由容器管理协作对象(collaborator)。
Spring即使一个AOP框架,也是一IOC容器。 Spring 最好的地方是它有助于您替换对象。有了 Spring,只要用 JavaBean 属性和配置文件加入依赖性(协作对象)。然后可以很容易地在需要时替换具有类似接口的协作对象。
网友自出的几道面试题
1、 简述你对IoC(Inversion of Control)的理解,描述一下Spring中实现DI(Dependency Injection)的几种方式。
2、 Spring的Bean有多种作用域,包括:
singleton、prototype、request、session、global session、application、自定义
3、 简单描述Spring Framework与Struts的不同之处,整合Spring与Struts有哪些方法,哪种最好,为什么?
4、 Hibernate中的update()和saveOrUpdate()的区别
5、 Spring对多种ORM框架提供了很好的支持,简单描述在Spring中使用Hibernate的方法,并结合事务管理。
Hibernate
1.在数据库中条件查询速度很慢的时候,如何优化?
1.建索引
2.减少表之间的关联
3.优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据量大的表排在前面
4.简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据
[2.在hibernate中进行多表查询,每个表中各取几个字段,也就是说查询出来的结果集并没有一个实体类与之对应,如何解决这个问题?
解决方案一,按照Object[]数据取出数据,然后自己组bean
解决方案二,对每个表的bean写构造函数,比如表一要查出field1,field2两个字段,那么有一个构造函数就是Bean(type1 filed1,type2 field2) ,然后在hql里面就可以直接生成这个bean了。具体怎么用请看相关文档,我说的不是很清楚。
session.load()和session.get()的区别
Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于:
如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException。
Load方法可返回实体的代理类实例,而get方法永远直接返回实体类。
load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。
Session在加载实体对象时,将经过的过程:
首先,Hibernate中维持了两级缓存。第一级缓存由Session实例维护,其中保持了Session当前所有关联实体的数据,也称为内部缓存。而第二级缓存则存在于SessionFactory层次,由当前所有由本 SessionFactory构造的Session实例共享。出于性能考虑,避免无谓的数据库访问,Session在调用数据库查询功能之前,会先在缓存中进行查询。首先在第一级缓存中,通过实体类型和id进行查找,如果第一级缓存查找命中,且数据状态合法,则直接返回。
之后,Session会在当前“NonExists”记录中进行查找,如果“NonExists”记录中存在同样的查询条件,则返回null。 “NonExists”记录了当前Session实例在之前所有查询操作中,未能查询到有效数据的查询条件(相当于一个查询黑名单列表)。如此一来,如果 Session中一个无效的查询条件重复出现,即可迅速作出判断,从而获得最佳的性能表现。
对于load方法而言,如果内部缓存中未发现有效数据,则查询第二级缓存,如果第二级缓存命中,则返回。
如在缓存中未发现有效数据,则发起数据库查询操作(Select SQL),如经过查询未发现对应记录,则将此次查询的信息在“NonExists”中加以记录,并返回null。
根据映射配置和Select SQL得到的ResultSet,创建对应的数据对象。
将其数据对象纳入当前Session实体管理容器(一级缓存)。
执行Interceptor.onLoad方法(如果有对应的Interceptor)。
将数据对象纳入二级缓存。
如果数据对象实现了LifeCycle接口,则调用数据对象的onLoad方法。
返回数据对象。
Hibernate的主键生成机制
1) assigned
主键由外部程序负责生成,无需Hibernate参与。
2) hilo
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
3) seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle。
4) increment
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。因此,如果同一数据库有多个实例访问,此方式必须避免使用。
5) identity
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL中的主键生成机制。
6) sequence
采用数据库提供的sequence 机制生成主键。如Oralce 中的Sequence。
7) native
由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。
8) uuid.hex
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
9) uuid.string
与uuid.hex 类似,只是生成的主键未进行编码(长度16)。在某些数据库中可能出现问题(如PostgreSQL)。
10) foreign
使用外部表的字段作为主键。一般而言,利用uuid.hex方式生成主键将提供最好的性能和数据库平台适应性。
这10中生成OID标识符的方法,increment 比较常用,把标识符生成的权力交给Hibernate处理.但是当同时多个Hibernate应用操作同一个数据库,甚至同一张表的时候.就推荐使用identity 依赖底层数据库实现,但是数据库必须支持自动增长,当然针对不同的数据库选择不同的方法.如果你不能确定你使用的数据库具体支持什么的情况下.可以选择用native 让Hibernate来帮选择identity,sequence,或hilo.
另外由于常用的数据库,如Oracle、DB2、SQLServer、MySql 等,都提供了易用的主键生成机制(Auto-Increase 字段或者Sequence)。我们可以在数据库提供的主键生成机制上,采用generator-class=native的主键生成方式。
不过值得注意的是,一些数据库提供的主键生成机制在效率上未必最佳,大量并发insert数据时可能会引起表之间的互锁。数据库提供的主键生成机制,往往是通过在一个内部表中保存当前主键状态(如对于自增型主键而言,此内部表中就维护着当前的最大值和递增量),之后每次插入数据会读取这个最大值,然后加上递增量作为新记录的主键,之后再把这个新的最大值更新回内部表中,这样,一次Insert操作可能导致数据库内部多次表读写操作,同时伴随的还有数据的加锁解锁操作,这对性能产生了较大影响。因此,对于并发Insert要求较高的系统,推荐采用uuid.hex 作为主键生成机制
myeclipse 加入Hibernate的全过程
1.Db-browers加入配置连接
2.新建工程
3.加入hibernate环境,指定*.hbm.xml及HibernateSessionFactory文件所在的位置
hibernate的核心类是什么,它们的相互关系是什么?重要的方法是什么?
Configuration
SessionFactory
Session如下方法
Save
load
Update
Delete
Query q=CreateQuery(“from Customer where customerName=:customerName”)
beginTransaction
close
Transaction
Commit()
Hibernate中数据表映射关系主要有什么类型
one-to-many
inverse:主控方,外键的关系有谁控制
inverse=false 是主控方,外键是由它控制的
inverse=true 是被控方,外键与它没关系
要想实现主控方的控制必须将被控方作为主控方的属性
cascade:级联
主表增从表增
主表修从表修
主表删从表删
lazy:延迟
lazy=false:一下将所有的内容取出,不延时(常用)
lazy=true:取出部分内容,其余内容动态去取
通过get可以取出对方的所有内容
Hibernate中Criteria和DetachedCriteria的作用是什么
Criteria c=session.createCriteria(Customer.class);
//设置条件
c.add(Expression.ge(“字段名”,”值对象”))
ge:>=
gt:>
le:<=
lt:<
eq:=
//排序
c.addOrder(Order.asc(“字段名”))
//分页
c.setFirstResult(1)//从第2行开始提取
c.setMaxResults(5)//返回5行
DetachedCriteria产生时不需要session
DetachedCriteria dc= DetachedCriteria.forClass(Customer.class)
Criteria c=Dc.getExecutableCriteria(session)
Hibernate中Query对象的使用
1 个或多个属性查询:
Query query=session.createQuery(”select customername,customerid from Customer”)
List l=query.list();
For(int i=0;i {
Obejct[] object=(Object[])l.get(i);
Object[0] object[1]
}
}
分组: “select count(*),productname from Product group by productname order by productname”
取值与属性一样
配置的查询,在*.hbm.xml中
from Product where productid=:productid
]]>
Query query=session.getNamedQuery(sql);
联接1
”from Customer as customer join fetch customer.buySet”:将多的放到buySet属性中,得出的结是Customer有一个,Buy有多个
联接2
“from Customer as customer join customer.buySet”:得出的对象,customer与buy是1对1
子查询:
”from Customer as customer where (select count(*) from customer.buySet)>1″
Hibernate如何实现数据表映射的继承关系
1、两个表,子类重复父类的属性。
2、一个表,子类父类共用一个表
3、两个表,子类引用父类的主键,享用公共的字段或属性。
批量删除
Query query=session.createQuery(“update”或”delete”);
query.executeUpdate();
jdbc、Hibernate、ibatis的区别
jdbc:手动
手动写sql
delete、insert、update要将对象的值一个一个取出传到sql中,不能直接传入一个对象。
select:返回的是一个resultset,要从ResultSet中一行一行、一个字段一个字段的取出,然后封装到一个对象中,不直接返回一个对象。
ibatis的特点:半自动化
sql要手动写
delete、insert、update:直接传入一个对象
select:直接返回一个对象
hibernate:全自动
不写sql,自动封装
delete、insert、update:直接传入一个对象
select:直接返回一个对象
Detached Object(游离对象)可以传递到任何层直到表现层而不是用任何DTO(Data Transfer Objects). 然后你还可以重新把游离对象赋给另外一个Session.
Hibernate的三种状态
瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。处于持久态的对象也称为PO(Persistence Object),瞬时对象和脱管对象也称为VO(Value Object)。
瞬时态
由new命令开辟内存空间的java对象,
eg. Person person = new Person(“amigo”, “女”);
如果没有变量对该对象进行引用,它将被java虚拟机回收。
瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系,在Hibernate中,可通过session的save()或 saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。
持久态
处于该状态的对象在数据库中具有对应的记录,并拥有一个持久化标识。如果是用hibernate的delete()方法,对应的持久对象就变成瞬时对象,因数据库中的对应数据已被删除,该对象不再与数据库的记录关联。
当一个session执行close()或clear()、evict()之后,持久对象变成脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具有数据库识别值,但它已不在HIbernate持久层的管理之下。
持久对象具有如下特点:
1. 和session实例关联;
2. 在数据库中有与之关联的记录。
脱管态
当与某持久对象关联的session被关闭后,该持久对象转变为脱管对象。当脱管对象被重新关联到session上时,并再次转变成持久对象。
脱管对象拥有数据库的识别值,可通过update()、saveOrUpdate()等方法,转变成持久对象。
脱管对象具有如下特点:
1. 本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收;
2. 比瞬时对象多了一个数据库记录标识值。
1. Hibernate有哪几种查询数据的方式
3种:hql、QBC——Query By Criteria API、原生sql (通过createSQLQuery建立)
2. 谈谈Hibernate中inverse的作用
inverse属性默认是false,就是说关系的两端都来维护关系。
比如Student和Teacher是多对多关系,用一个中间表TeacherStudent维护。Gp)i
如果Student这边inverse=”true”, 那么关系由另一端Teacher维护,就是说当插入Student时,不会操作TeacherStudent表(中间表)。只有Teacher插入或删除时才会触发对中间表的操作。所以两边都inverse=”true”是不对的,会导致任何操作都不触发对中间表的影响;当两边都inverse=”false” 或默认时,会导致在中间表中插入两次关系。
3. 说说Hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。
saveOrUpdate()方法可以实现update()的功能,但会多些步骤,具体如下:
如果对象在该session中已经被持久化,不进行操作;对象的标识符属性(identifier property)在数据库中不存在或者是个暂时的值,调用save()方法保存它;如果session中的另一个对象有相同的标识符抛出一个异常;以上皆不符合则调用update()更新之。
Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于:
如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException;load方法可返回实体的代理类实例,而get方法永远直接返回实体类;load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。
=====================Hibernate笔试题==========================
(1)一般情况下,关系数据模型与对象模型之间有哪些匹配关系(多选)
A)表对应类
B)记录对应对象
C)表的字段对应类的属性
D)表之间的参考关系对应类之间的依赖关系
(2)以下关于SessionFactory的说法哪些正确?(多选)
A)对于每个数据库事务,应该创建一个SessionFactory对象
B)一个SessionFactory对象对应一个数据库存储源。
C)SessionFactory是重量级的对象,不应该随意创建。如果系统中只有一个数据库存储源,只需要创建一个。
D)SessionFactory的load()方法用于加载持久化对象
(3)Customer类中有一个Set类型的orders属性,用来存放Order订单对象,在Customer.hbm.xml文件中,用哪个元素映射orders属性?
A) B) C) D)
(4)元素有一个cascade属性,如果希望Hibernate级联保存集合中的对象,casecade属性应该取什么值?(单选)
A)none
B)save
C)delete
D)save-update
(5)以下哪些属于Session的方法?
A)load()
B)save()
C)delete()
D)update()
E)open()
F)close()
(6)以下程序的打印结果是什么?(单选)
tx = session.beginTransaction();
Customer c1=(Customer)session.load(Customer.class,new Long(1));
Customer c2=(Customer)session.load(Customer.class,new Long(1));
System.out.println(c1==c2);
tx.commit();
session.close();
A)运行出错,抛出异常
B)打印false
C)打印true
(7)以下程序代码对Customer的name属性修改了两次:
tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,
new Long(1));
customer.setName(”Jack”);
customer.setName(”Mike”);
tx.commit();
执行以上程序,Hibernate需要向数据库提交几条update语句?(单选)
A)0 B)1 C)2 D)3
(8)在持久化层,对象分为哪些状态?(多选)
A)临时状态
B)独立状态
C)游离状态
D)持久化状态
(9)对于以下程序,Customer对象在第几行变为持久化状态?(单选)
Customer customer=new Customer(); //line1
customer.setName(”Tom”); //line2
Session session1=sessionFactory.openSession(); //line3
Transaction tx1 = session1.beginTransaction(); //line4
session1.save(customer); //line4
tx1.commit(); //line5
session1.close(); //line6
A) line1 B)line2 C)line3 D)line4 E)line5 F)line6
(10)对于以下程序,Customer对象在第几行变为游离状态?(单选)
Customer customer=new Customer(); //line1
customer.setName(”Tom”); //line2
Session session1=sessionFactory.openSession(); //line3
Transaction tx1 = session1.beginTransaction(); //line4
session1.save(customer); //line4
tx1.commit(); //line5
session1.close(); //line6
A) line1 B)line2 C)line3 D)line4 E)line5 F)line6
(11)以下哪一种检索策略利用了外连结查询?(单选)
A)立即检索 B)延迟检索 C)迫切左外连结检索
(12)假设对Customer类的orders集合采用延迟检索策略,编译或运行以下程序,会出现什么情况(单选)
Session session=sessionFactory.openSession();
tx = session.beginTransaction();
Customer customer=(Customer)session.get(Customer.class,new Long(1));
tx.commit();
session.close();
Iterator orderIterator=customer.getOrders().iterator();
A)编译出错 B)编译通过,并正常运行 C)编译通过,但运行时抛出异常
(13)关于HQL与SQL,以下哪些说法正确?(多选)
A)HQL与SQL没什么差别
B)HQL面向对象,而SQL操纵关系数据库
C)在HQL与SQL中,都包含select,insert,update,delete语句
D)HQL仅用于查询数据,不支持insert,update和delete语句
(14)事务隔离级别是由谁实现的?(单选)
A)Java应用程序 B)Hibernate C)数据库系统 D)JDBC驱动程序
(15)悲观锁与乐观锁,哪个具有较好的并发性能?(单选)
A)悲观锁 B)乐观锁
答案:
(1)A,B,C (2)B,C (3)A (4)D (5)A,B,C,D,F (6)C (7)B (8)A,C,D (9)D (10)F (11)C (12)C (13)B,D (14)C (15)B
1.strust的。
Action是不是线程安全的?如果不是
有什么方式可以保证Action的线程安全?如果是,说明原因
2.MVC,分析一下struts是如何实现MVC的
3.struts中的几个关键对象的作用(说说几个关键对象的作用)
4.spring
说说AOP和IOC的概念以及在spring中是如何应用的
5.Hibernate有哪几种查询数据的方式
6.load()和get()的区别
1. Struts的工作原理
在Struts中,用户的请求一般以*.do作为请求服务名,所有的*.do请求均被指向ActionSevlet, ActionSevlet根据Struts-config.xml中的配置信息,将用户请求封装成一个指定名称的FormBean,并将此 FormBean传至指定名称的ActionBean,由ActionBean完成相应的业务操作,如文件操作,数据库操作等。每一个*.do均有对应的 FormBean名称和ActionBean名称,这些在Struts-config.xml中配置。
2. Struts优点与缺点
Struts是开源软件,使开发者能更深入的了解其内部实现机制。
Struts 优点:业界”标准”(很多成功案例),学习资源丰富。
Struts的优点主要集中体现在两个方面:Taglib和页面导航。
a、利用Struts提供的taglib可以大大节约开发时间。
b、维护扩展比较方便。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。
c、表现与逻辑分离
d、表单验证解决了请求数据的验证问题,增强了系统健壮性。
e、便于团队开发
Struts缺点:a、大量的使用标签,对于初学者难度较大。
b、ActionForms使用不便、无法进行单元测试(StrutsTestCase只能用于集成)
3. Struts提供了几个标签库?都是什么标签库?
Struts提供了五个标签库,即:HTML、Bean、Logic、Template和Nested。
HTML 标签 用来创建能够和Struts 框架和其他相应的HTML 标签交互的HTML 输入表单
Bean 标签 在访问JavaBeans 及其属性,以及定义一个新的bean 时使用
Logic 标签 管理条件产生的输出和对象集产生的循环
Template 标签 随着Tiles框架包的出现,此标记已开始减少使用
Nested 标签 增强对其他的Struts 标签的嵌套使用的能力
4. Tiles框架是什么?
Tiles框架为创建Web页面提供了一种模板机制,它能将网页的布局和内容分离。
1、MVC的各个部分都有那些技术来实现?如何实现?
答:MVC是Model-View-Controller的简写。“Model”代表的是应用的业务逻辑(通过JavaBean,EJB组件实现),“View”是应用的表示面(由JSP页面产生),“Controller”是提供应用的处理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。
2、说说Struts的应用。
答:Struts 是采用Java Servlet/JavaServer Pages技术,开发Web应用程序的开放源码的framework。采用Struts能开发出基于MVC设计模式的应用构架。 Struts的主要功能包括:一包含一个controller servlet,能将用户的请求发送到相应的Action对象。二JSP自由tag库,并且在controller servlet中提供关联支持,帮助开发员创建交互式表单应用。三提供了一系列实用对象:XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息。
3、strust的Action是不是线程安全的?如果不是有什么方式可以保证Action的线程安全?如果是请说明原因。
答:不是线程安全的,只要不申明类变量就可以保证线程安全。因为只存在一个Action类实例,所有线程会共享类变量。
4、应用服务器具体包括那些?
答:应用服务器具体包括:BEA WebLogic Server、IBM WebSphere Application Server、Oracle9i Application Server、JBoss和Tomcat等。 

ArrayList和Vector的主要区别是什么?

1、Vector是多线程安全的,而ArrayList不是,这个可以从源码中看出,Vector类中的方法很多有synchronized进行修饰,这样就导致了Vector在效率上无法与ArrayList相比;

2、两个都是采用的线性连续空间存储元素,但是当空间不足的时候,两个类的增加方式是不同的,很多网友说Vector增加原来空间的一倍,ArrayList增加原来空间的50%,其实也差不多是这个意思,不过还有一点点问题可以从源码中看出,一会儿从源码中分析。

3、Vector可以设置增长因子,而ArrayList不可以,最开始看这个的时候,我没理解什么是增量因子,不过通过对比一下两个源码理解了这个,先看看两个类的构造方法:

同步机制的实现

Java同步机制有4种实现方式:(部分引用网上资源)

① ThreadLocal ② synchronized( ) ③ wait() 与 notify() ④ volatile

目的:都是为了解决多线程中的对同一变量的访问冲突 

volatile 

而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。 

且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。这样当多个线程同时与某

个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。而 volatile 关键字就

是提示 VM :对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。 

synchronized 代码块中,或者为常量时,不必使用。 

是B。只在某些动作时才进行A和B的同步,因此存在A和B不一致的情况。volatile就是用来避免这种

情况的。 volatile告诉jvm,它所修饰的变量不保留拷贝,直接访问主内存中的(读操作多时使用

较好;线程间需要通信,本条做不到)

Volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性。这就是说线程能够自

动发现 volatile 变量的最新值。Volatile 变量可用于提供线程安全,但是只能应用于非常有限的

一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。

您只能在有限的一些情形下使用 volatile 变量替代锁。要使 volatile 变量提供理

想的线程安全,必须同时满足下面两个条件:

对变量的写操作不依赖于当前值;该变量没有包含在具有其他变量的不变式中。

sleep() vs wait() 

控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 

定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁

进入运行状态。

(如果变量被声明为volatile,在每次访问时都会和主存一致;如果变量在同步方法或者同步块中

被访问,当在方法或者块的入口处获得锁以及方法或者块退出时释放锁时变量被同步。)

JAVA中的几种基本类型,各占用多少字节?

 

String能被继承吗?为什么?

不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。平常我们定义的String str=”a”;其实和String str=new String(“a”)还是有差异的。

前者默认调用的是String.valueOf来返回String实例对象,至于调用哪个则取决于你的赋值,比如String num=1,调用的是 

后者则是调用如下部分: 

String, Stringbuffer, StringBuilder 的区别。

String 字符串常量(final修饰,不可被继承),String是常量,当创建之后即不能更改。(可以通过StringBuffer和StringBuilder创建String对象(常用的两个字符串操作类)。) 

StringBuilder 字符串变量(非线程安全)其自jdk1.5起开始出现。与StringBuffer一样都继承和实现了同样的接口和类,方法除了没使用synch修饰以外基本一致,不同之处在于最后toString的时候,会直接返回一个新对象。 

ArrayList 和 LinkedList 有什么区别。

ArrayList和LinkedList都实现了List接口,有以下的不同点: 

讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当 new 的时候, 他们的执行顺序。

此题考察的是类加载器实例化时进行的操作步骤(加载–>连接->初始化)。 

用过哪些 Map 类,都有什么区别,HashMap 是线程安全的吗,并发下使用的 Map 是什么,他们内部原理分别是什么,比如存储方式, hashcode,扩容, 默认容量等。

hashMap是线程不安全的,HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,采用哈希表来存储的, 

有没有有顺序的 Map 实现类, 如果有, 他们是怎么保证有序的。

TreeMap和LinkedHashMap是有序的(TreeMap默认升序,LinkedHashMap则记录了插入顺序)。 

抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么。

1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。 

继承和聚合的区别在哪。

继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系;在Java中此类关系通过关键字extends明确标识,在设计时一般没有争议性; 

参考:http://www.cnblogs.com/jiqing9006/p/5915023.html

讲讲你理解的 nio和 bio 的区别是啥,谈谈 reactor 模型。

IO是面向流的,NIO是面向缓冲区的 

反射的原理,反射创建类实例的三种方式是什么

参照:http://www.jianshu.com/p/3ea4a6b57f87?amp

http://blog.csdn.net/yongjian1092/article/details/7364451

反射中,Class.forName 和 ClassLoader 区别。

https://my.oschina.net/gpzhang/blog/486743

描述动态代理的几种实现方式,分别说出相应的优缺点。

Jdk cglib jdk底层是利用反射机制,需要基于接口方式,这是由于 

动态代理与 cglib 实现的区别

同上(基于invocationHandler和methodInterceptor)

为什么 CGlib 方式可以对接口实现代理。

同上

final 的用途

类、变量、方法 

写出三种单例模式实现。

懒汉式单例,饿汉式单例,双重检查等 

如何在父类中为子类自动完成所有的 hashcode 和 equals 实现?这么做有何优劣。

同时复写hashcode和equals方法,优势可以添加自定义逻辑,且不必调用超类的实现。 

请结合 OO 设计理念,谈谈访问修饰符 public、private、protected、default 在应用设计中的作用。

访问修饰符,主要标示修饰块的作用域,方便隔离防护

同一个类
同一个包
不同包的子类
不同包的非子类
  • 1
  • 2

Private √ 

深拷贝和浅拷贝区别。

http://www.oschina.net/translate/java-copy-shallow-vs-deep-in-which-you-will-swim

数组和链表数据结构描述,各自的时间复杂度

http://blog.csdn.net/snow_wu/article/details/53172721

error 和 exception 的区别,CheckedException,RuntimeException 的区别

http://blog.csdn.net/woshixuye/article/details/8230407

请列出 5 个运行时异常。

同上

在自己的代码中,如果创建一个 java.lang.String 对象,这个对象是否可以被类加载器加载?为什么

类加载无须等到“首次使用该类”时加载,jvm允许预加载某些类。。。。 

说一说你对 java.lang.Object 对象中 hashCode 和 equals 方法的理解。在什么场景下需要重新实现这两个方法。

参考上边试题

在 jdk1.5 中,引入了泛型,泛型的存在是用来解决什么问题。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率 

这样的 a.hashcode() 有什么用,与 a.equals(b)有什么关系。

hashcode 

通常这个值是对象头部的一部分二进制位组成的数字,具有一定的标识对象的意义存在,但绝不定于地址。

作用是:用一个数字来标识对象。比如在HashMap、HashSet等类似的集合类中,如果用某个对象本身作为Key,即要基于这个对象实现Hash的写入和查找,那么对象本身如何实现这个呢?就是基于hashcode这样一个数字来完成的,只有数字才能完成计算和对比操作。

hashcode是否唯一 

equals与hashcode的关系 

有没有可能 2 个不相等的对象有相同的 hashcode。

Java 中的 HashSet 内部是如何工作的。

底层是基于hashmap实现的 

JVM 知识

什么情况下会发生栈内存溢出。

如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。 

JVM 的内存结构,Eden 和 Survivor 比例。

 

jvm 中一次完整的 GC 流程是怎样的,对象如何晋升到老年代,说说你知道的几种主要的jvm 参数。

对象诞生即新生代->eden,在进行minor gc过程中,如果依旧存活,移动到from,变成Survivor,进行标记代数,如此检查一定次数后,晋升为老年代, 

你知道哪几种垃圾收集器,各自的优缺点,重点讲下 cms,包括原理,流程,优缺点

Serial、parNew、ParallelScavenge、SerialOld、ParallelOld、CMS、G1 

垃圾回收算法的实现原理。

http://www.importnew.com/13493.html

当出现了内存溢出,你怎么排错。

首先分析是什么类型的内存溢出,对应的调整参数或者优化代码。 

JVM 内存模型的相关知识了解多少,比如重排序,内存屏障,happen-before,主内存,工作内存等。

内存屏障:为了保障执行顺序和可见性的一条cpu指令 

简单说说你了解的类加载器。

类加载器的分类(bootstrap,ext,app,curstom),类加载的流程(load-link-init) 

讲讲 JAVA 的反射机制。

Java程序在运行状态可以动态的获取类的所有属性和方法,并实例化该类,调用方法的功能 

你们线上应用的 JVM 参数有哪些。

-server 

g1 和 cms 区别,吞吐量优先和响应优先的垃圾收集器选择。

Cms是以获取最短回收停顿时间为目标的收集器。基于标记-清除算法实现。比较占用cpu资源,切易造成碎片。 

Server模式启动 

开源框架知识

简单讲讲 tomcat 结构,以及其类加载器流程。

Server- –多个service 

tomcat 如何调优,涉及哪些参数。

硬件上选择,操作系统选择,版本选择,jdk选择,配置jvm参数,配置connector的线程数量,开启gzip压缩,trimSpaces,集群等 

讲讲 Spring 加载流程。

通过listener入口,核心是在AbstractApplicationContext的refresh方法,在此处进行装载bean工厂,bean,创建bean实例,拦截器,后置处理器等。 

讲讲 Spring 事务的传播属性。

七种传播属性。 

Spring 如何管理事务的。

编程式和声明式 

Spring 怎么配置事务(具体说出一些关键的 xml 元素)。

说说你对 Spring 的理解,非单例注入的原理?它的生命周期?循环注入的原理, aop 的实现原理,说说 aop 中的几个术语,它们是怎么相互工作的。

核心组件:bean,context,core,单例注入是通过单例beanFactory进行创建,生命周期是在创建的时候通过接口实现开启,循环注入是通过后置处理器,aop其实就是通过反射进行动态代理,pointcut,advice等。 

Springmvc 中 DispatcherServlet 初始化过程。

入口是web.xml中配置的ds,ds继承了HttpServletBean,FrameworkServlet,通过其中的init方法进行初始化装载bean和实例,initServletBean是实际完成上下文工作和bean初始化的方法。 

操作系统

Linux 系统下你关注过哪些内核参数,说说你知道的。

 

http://www.haiyun.me/category/system/

Linux 下 IO 模型有几种,各自的含义是什么。

阻塞式io,非阻塞io,io复用模型,信号驱动io模型,异步io模型。 

epoll 和 poll 有什么区别。

select的本质是采用32个整数的32位,即32*32= 1024来标识,fd值为1-1024。当fd的值超过1024限制时,就必须修改FD_SETSIZE的大小。这个时候就可以标识32*max值范围的fd。 

平时用到哪些 Linux 命令。

Ls,find,tar,tail,cp,rm,vi,grep,ps,pkill等等 

用一行命令查看文件的最后五行。

Tail -n 5 filename

用一行命令输出正在运行的 java 进程。

ps -ef|grep Java

介绍下你理解的操作系统中线程切换过程。

控制权的转换,根据优先级切换上下文(用户,寄存器,系统) 

进程和线程的区别。

Linux 实现并没有区分这两个概念(进程和线程) 

http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

多线程

多线程的几种实现方式,什么是线程安全。

实现runable接口,继承thread类。 

volatile 的原理,作用,能代替锁么。

Volatile利用内存栅栏机制来保持变量的一致性。不能代替锁,其只具备数据可见性一致性,不具备原子性。 

画一个线程的生命周期状态图。

新建,可运行,运行中, 睡眠,阻塞,等待,死亡。 

sleep 和 wait 的区别。

Sleep是休眠线程,wait是等待,sleep是thread的静态方法,wait则是object的方法。 

Lock 与 Synchronized 的区别。

首先两者都保持了并发场景下的原子性和可见性,区别则是synchronized的释放锁机制是交由其自身控制,且互斥性在某些场景下不符合逻辑,无法进行干预,不可人为中断等。 

synchronized 的原理是什么,解释以下名词:重排序,自旋锁,偏向锁,轻量级锁,可重入锁,公平锁,非公平锁,乐观锁,悲观锁。

Synchronized底层是通过监视器的enter和exit实现 

用过哪些原子类,他们的原理是什么。

AtomicInteger; AtomicLong; AtomicReference; AtomicBoolean;基于CAS原语实现 ,比较并交换、加载链接/条件存储,最坏的情况下是旋转锁 

用过线程池吗,newCache 和 newFixed 有什么区别,他们的原理简单概括下,构造函数的各个参数的含义是什么,比如 coreSize,maxsize 等。

newSingleThreadExecutor返回以个包含单线程的Executor,将多个任务交给此Exector时,这个线程处理完一个任务后接着处理下一个任务,若该线程出现异常,将会有一个新的线程来替代。

  newFixedThreadPool返回一个包含指定数目线程的线程池,如果任务数量多于线程数目,那么没有没有执行的任务必须等待,直到有任务完成为止。

newCachedThreadPool根据用户的任务数创建相应的线程来处理,该线程池不会对线程数目加以限制,完全依赖于JVM能创建线程的数量,可能引起内存不足。 

线程池的关闭方式有几种,各自的区别是什么。

Shutdown shutdownNow tryTerminate 清空工作队列,终止线程池中各个线程,销毁线程池 

假如有一个第三方接口,有很多个线程去调用获取数据,现在规定每秒钟最多有 10 个线程同时调用它,如何做到。

ScheduledThreadPoolExecutor 设置定时,进行调度。 

http://ifeve.com/java-scheduledthreadpoolexecutor/

spring 的 controller 是单例还是多例,怎么保证并发的安全。

单例 

用三个线程按顺序循环打印 abc 三个字母,比如 abcabcabc。

public static void main(String[] args) { 

ThreadLocal 用过么,用途是什么,原理是什么,用的时候要注意什么。

Threadlocal底层是通过threadlocalMap进行存储键值 每个ThreadLocal类创建一个Map,然后用线程的ID作为Map的key,实例对象作为Map的value,这样就能达到各个线程的值隔离的效果。 

如果让你实现一个并发安全的链表,你会怎么做。

Collections.synchronizedList() ConcurrentLinkedQueue 

有哪些无锁数据结构,他们实现的原理是什么。

LockFree,CAS 

讲讲 java 同步机制的 wait 和 notify。

首先这两个方法只能在同步代码块中调用,wait会释放掉对象锁,等待notify唤醒。 

多线程如果线程挂住了怎么办。

根据具体情况(sleep,wait,join等),酌情选择notifyAll,notify进行线程唤醒。 

countdowlatch 和 cyclicbarrier 的内部原理和用法,以及相互之间的差别。

CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它运行一个或者多个线程一直处于等待状态。 

使用 synchronized 修饰静态方法和非静态方法有什么区别。

对象锁和类锁 

简述 ConcurrentLinkedQueue LinkedBlockingQueue 的用处和不同之处。

LinkedBlockingQueue 是一个基于单向链表的、范围任意的(其实是有界的)、FIFO 阻塞队列。 

导致线程死锁的原因?怎么解除线程死锁。

死锁问题是多线程特有的问题,它可以被认为是线程间切换消耗系统性能的一种极端情况。在死锁时,线程间相互等待资源,而又不释放自身的资源,导致无穷无尽的等待,其结果是系统任务永远无法执行完成。死锁问题是在多线程开发中应该坚决避免和杜绝的问题。 

非常多个线程(可能是不同机器),相互之间需要等待协调,才能完成某种工作,问怎么设计这种协调方案。

此问题的本质是保持顺序执行。可以使用executors

TCP 与 HTTP

http1.0 和 http1.1 有什么区别。

HTTP 1.0主要有以下几点变化: 

HTTP 1.1加入了很多重要的性能优化:持久连接、分块编码传输、字节范围请求、增强的缓存机制、传输编码及请求管道。 

TCP 三次握手和四次挥手的流程,为什么断开连接要 4 次,如果握手只有两次,会出现什么。

  • 第一次握手(SYN=1, seq=x):

    客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。

    发送完毕后,客户端进入 SYN_SEND 状态。

  • 第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):

    服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 SYN_RCVD 状态。

  • 第三次握手(ACK=1,ACKnum=y+1)

    客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1

发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED状态,TCP 握手结束。

第一次挥手(FIN=1,seq=x)

假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。

发送完毕后,客户端进入 FIN_WAIT_1 状态。

第二次挥手(ACK=1,ACKnum=x+1)

服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。

发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接。

第三次挥手(FIN=1,seq=y)

服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。

发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK。

第四次挥手(ACK=1,ACKnum=y+1)

客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的 ACK 包。

服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。

客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。 

TIME_WAIT 和 CLOSE_WAIT 的区别。

TIME_WAIT状态就是用来重发可能丢失的ACK报文。 

说说你知道的几种 HTTP 响应码,比如 200, 302, 404。

1xx:信息,请求收到,继续处理 

当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤。

Dns解析–>端口分析–>tcp请求–>服务器处理请求–>服务器响应–>浏览器解析—>链接关闭

TCP/IP 如何保证可靠性,说说 TCP 头的结构。

使用序号,对收到的TCP报文段进行排序以及检测重复的数据;使用校验和来检测报文段的错误;使用确认和计时器来检测和纠正丢包或延时。//TCP头部,总长度20字节 

https://zh.bywiki.com/zh-hans/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE

如何避免浏览器缓存。

无法被浏览器缓存的请求: 

简述 Http 请求 get 和 post 的区别以及数据包格式。

 

简述 HTTP 请求的报文格式。

参考上面

HTTPS 的加密方式是什么,讲讲整个加密解密流程。

加密方式是tls/ssl,底层是通过对称算法,非对称,hash算法实现 

架构设计与分布式

常见的缓存策略有哪些,你们项目中用到了什么缓存系统,如何设计的。

Cdn缓存,redis缓存,ehcache缓存等 

用 java 自己实现一个 LRU。

final int cacheSize = 100; 

分布式集群下如何做到唯一序列号。

Redis生成,mongodb的objectId,zk生成 

设计一个秒杀系统,30 分钟没付款就自动关闭交易。

分流 – 限流–异步–公平性(只能参加一次)–用户体验(第几位,多少分钟,一抢完) 

30分钟关闭 可以借助redis的发布订阅机制 在失效时进行后续操作,其他mq也可以 

如何使用 redis 和 zookeeper 实现分布式锁?有什么区别优缺点,分别适用什么场景。

首先分布式锁实现常见的有数据库锁(表记录),缓存锁,基于zk(临时有序节点可以实现的)的三种

Redis适用于对性能要求特别高的场景。redis可以每秒执行10w次,内网延迟不超过1ms 

锁无法释放?使用Zookeeper可以有效的解决锁无法释放的问题,因为在创建锁的时候,客户端会在ZK中创建一个临时节点,一旦客户端获取到锁之后突然挂掉(Session连接断开),那么这个临时节点就会自动删除掉。其他客户端就可以再次获得锁。

非阻塞锁?使用Zookeeper可以实现阻塞的锁,客户端可以通过在ZK中创建顺序节点,并且在节点上绑定监听器,一旦节点有变化,Zookeeper会通知客户端,客户端可以检查自己创建的节点是不是当前所有节点中序号最小的,如果是,那么自己就获取到锁,便可以执行业务逻辑了。

不可重入?使用Zookeeper也可以有效的解决不可重入的问题,客户端在创建节点的时候,把当前客户端的主机信息和线程信息直接写入到节点中,下次想要获取锁的时候和当前最小的节点中的数据比对一下就可以了。如果和自己的信息一样,那么自己直接获取到锁,如果不一样就再创建一个临时的顺序节点,参与排队。

单点问题?使用Zookeeper可以有效的解决单点问题,ZK是集群部署的,只要集群中有半数以上的机器存活,就可以对外提供服务。

http://www.hollischuang.com/archives/1716

如果有人恶意创建非法连接,怎么解决。

可以使用filter过滤处理

分布式事务的原理,优缺点,如何使用分布式事务。

Two Phase commit协议 

什么是一致性 hash。

一致性hash是一种分布式hash实现算法。满足平衡性 单调性 分散性 和负载。 

什么是 restful,讲讲你理解的 restful。

REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。 

如何设计建立和保持 100w 的长连接。

服务器内核调优(tcp,文件数),客户端调优,框架选择(netty)

如何防止缓存雪崩。

缓存雪崩可能是因为数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。 

http://www.cnblogs.com/jinjiangongzuoshi/archive/2016/03/03/5240280.html

解释什么是 MESI 协议(缓存一致性)。

MESI是四种缓存段状态的首字母缩写,任何多核系统中的缓存段都处于这四种状态之一。我将以相反的顺序逐个讲解,因为这个顺序更合理:

失效(Invalid)缓存段,要么已经不在缓存中,要么它的内容已经过时。为了达到缓存的目的,这种状态的段将会被忽略。一旦缓存段被标记为失效,那效果就等同于它从来没被加载到缓存中。 

说说你知道的几种 HASH 算法,简单的也可以。

哈希(Hash)算法,即散列函数。 它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程。 同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的输出 

什么是 paxos 算法。

Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的”La”,此人现在在微软研究院)于1990年提出的一种基于消息传递的一致性算法。

http://baike.baidu.com/item/Paxos%20%E7%AE%97%E6%B3%95

什么是 zab 协议。

ZAB 是 Zookeeper 原子广播协议的简称

整个ZAB协议主要包括消息广播和崩溃恢复两个过程,进一步可以分为三个阶段,分别是:

发现 Discovery 

一个在线文档系统,文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新。

点击编辑的时候,利用redis进行加锁setNX完了之后 expire 一下 

线上系统突然变得异常缓慢,你如何查找问题。

逐级排查(网络,磁盘,内存,cpu),数据库,日志,中间件等也可通过监控工具排查。

说说你平时用到的设计模式。

单例, 代理,模板,策略,命令 

Dubbo 的原理,数据怎么流转的,怎么实现集群,负载均衡,服务注册和发现。重试转发,快速失败的策略是怎样的。

Dubbo[]是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

Cluster 实现集群

在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。 

https://my.oschina.net/u/1378920/blog/693374

一次 RPC 请求的流程是什么。

1)服务消费方(client)调用以本地调用方式调用服务; 

异步模式的用途和意义。

异步模式使用与服务器多核,并发严重的场景 

编程中自己都怎么考虑一些设计原则的,比如开闭原则,以及在工作中的应用。

开闭原则(Open Close Principle) 

设计一个社交网站中的“私信”功能,要求高并发、可扩展等等。 画一下架构图。

MVC 模式,即常见的 MVC 框架。 

聊了下曾经参与设计的服务器架构。

应用服务器怎么监控性能,各种方式的区别。

如何设计一套高并发支付方案,架构如何设计。

如何实现负载均衡,有哪些算法可以实现。

Zookeeper 的用途,选举的原理是什么。

Mybatis 的底层实现原理。

请思考一个方案,设计一个可以控制缓存总体大小的自动适应的本地缓存。

请思考一个方案,实现分布式环境下的 countDownLatch。

后台系统怎么防止请求重复提交。

可以通过token值进行防止重复提交,存放到redis中,在表单初始化的时候隐藏在表单中,添加的时候在移除。判断这个状态即可防止重复提交。 

描述一个服务从发布到被消费的详细过程。

讲讲你理解的服务治理。

如何做到接口的幂等性。

算法

10 亿个数字里里面找最小的 10 个。

有 1 亿个数字,其中有 2 个是重复的,快速找到它,时间和空间要最优。

2 亿个随机生成的无序整数,找出中间大小的值。

给一个不知道长度的(可能很大)输入字符串,设计一种方案,将重复的字符排重。

遍历二叉树。

有 3n+1 个数字,其中 3n 个中是重复的,只有 1 个是不重复的,怎么找出来。

写一个字符串反转函数。

常用的排序算法,快排,归并、冒泡。 快排的最优时间复杂度,最差复杂度。冒泡排序的优化方案。

二分查找的时间复杂度,优势。

一个已经构建好的 TreeSet,怎么完成倒排序。

什么是 B+树,B-树,列出实际的使用场景。

数据库知识

数据库隔离级别有哪些,各自的含义是什么,MYSQL 默认的隔离级别是是什么。

·未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

·提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

·可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

·串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

MYSQL默认是RepeatedRead级别

MYSQL 有哪些存储引擎,各自优缺点。

MyISAM: 拥有较高的插入,查询速度,但不支持事务 

高并发下,如何做到安全的修改同一行数据。

使用悲观锁 悲观锁本质是当前只有一个线程执行操作,结束了唤醒其他线程进行处理。 

乐观锁和悲观锁是什么,INNODB 的行级锁有哪 2 种,解释其含义。

乐观锁是设定每次修改都不会冲突,只在提交的时候去检查,悲观锁设定每次修改都会冲突,持有排他锁。 

SQL 优化的一般步骤是什么,怎么看执行计划,如何理解其中各个字段的含义。

查看慢日志(show [session|gobal] status ),定位慢查询,查看慢查询执行计划 根据执行计划确认优化方案 

数据库会死锁吗,举一个死锁的例子,mysql 怎么解决死锁。

产生死锁的原因主要是:

(1)系统资源不足。 

如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。 

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。 

1)重启数据库(谁用谁知道) 

MYsql 的索引原理,索引的类型有哪些,如何创建合理的索引,索引如何优化。

索引是通过复杂的算法,提高数据查询性能的手段。从磁盘io到内存io的转变 

http://tech.meituan.com/mysql-index.html 

聚集索引和非聚集索引的区别。

“聚簇”就是索引和记录紧密在一起。 

数据库中 BTREE 和 B+tree 区别。

B+是btree的变种,本质都是btree,btree+与B-Tree相比,B+Tree有以下不同点: 

http://lcbk.net/9602.html 

ACID 是什么。

A,atomic,原子性,要么都提交,要么都失败,不能一部分成功,一部分失败。 

Mysql 怎么优化 table scan 的。

避免在where子句中对字段进行is null判断 

如何写 sql 能够有效的使用到复合索引。

由于复合索引的组合索引,类似多个木板拼接在一起,如果中间断了就无法用了,所以要能用到复合索引,首先开头(第一列)要用上,比如index(a,b) 这种,我们可以select table tname where a=XX 用到第一列索引 如果想用第二列 可以 and b=XX 或者and b like‘TTT%’

mysql 中 in 和 exists 区别。

mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询。一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的。这个是要区分环境的。

如果查询的两个表大小相当,那么用in和exists差别不大。 

2.IN当遇到包含NULL的情况,那么就会返回UNKNOWN。

数据库自增主键可能的问题。

在分库分表时可能会生成重复主键 利用自增比例达到唯一 自增1 2,3 等 

消息队列

用过哪些 MQ,和其他 mq 比较有什么优缺点,MQ 的连接是线程安全的吗,你们公司的MQ 服务架构怎样的。

根据实际情况说明 

MQ 系统的数据如何保证不丢失。

基本都是对数据进行持久化,多盘存储

rabbitmq 如何实现集群高可用。

集群是保证服务可靠性的一种方式,同时可以通过水平扩展以提升消息吞吐能力。RabbitMQ是用分布式程序设计语言erlang开发的,所以天生就支持集群。接下来,将介绍RabbitMQ分布式消息处理方式、集群模式、节点类型,并动手搭建一个高可用集群环境,最后通过java程序来验证集群的高可用性。

  1. 三种分布式消息处理方式

  RabbitMQ分布式的消息处理方式有以下三种:

  1、Clustering:不支持跨网段,各节点需运行同版本的Erlang和RabbitMQ, 应用于同网段局域网。

  2、Federation:允许单台服务器上的Exchange或Queue接收发布到另一台服务器上Exchange或Queue的消息, 应用于广域网,。

  3、Shovel:与Federation类似,但工作在更低层次。

  RabbitMQ对网络延迟很敏感,在LAN环境建议使用clustering方式;在WAN环境中,则使用Federation或Shovel。我们平时说的RabbitMQ集群,说的就是clustering方式,它是RabbitMQ内嵌的一种消息处理方式,而Federation或Shovel则是以plugin形式存在。 

Redis,Memcached

redis 的 list 结构相关的操作。

LPUSH LPUSHX RPUSH RPUSHX LPOP RPOP BLPOP BRPOP LLEN LRANGE 

Redis 的数据结构都有哪些。

字符串(strings):存储整数(比如计数器)和字符串(废话。。),有些公司也用来存储json/pb等序列化数据,并不推荐,浪费内存 

Redis 的使用要注意什么,讲讲持久化方式,内存设置,集群的应用和优劣势,淘汰策略等。

持久化方式:RDB时间点快照 AOF记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 

LRU(近期最少使用算法)TTL(超时算法) 去除ttl最大的键值 

redis2 和 redis3 的区别,redis3 内部通讯机制。

集群方式的区别,3采用Cluster,2采用客户端分区方案和代理方案 

当前 redis 集群有哪些玩法,各自优缺点,场景。

当缓存使用 持久化使用

Memcache 的原理,哪些数据适合放在缓存中。

基于libevent的事件处理 

变化频繁,具有不稳定性的数据,不需要实时入库, (比如用户在线 

redis 和 memcached 的内存管理的区别。

Memcached默认使用Slab Allocation机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。 

Redis 的并发竞争问题如何解决,了解 Redis 事务的 CAS 操作吗。

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法:

1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。

2.服务器角度,利用setnx实现锁。

MULTI,EXEC,DISCARD,WATCH 四个命令是 Redis 事务的四个基础命令。其中:

MULTI,告诉 Redis 服务器开启一个事务。注意,只是开启,而不是执行 

Redis 的选举算法和流程是怎样的

Raft采用心跳机制触发Leader选举。系统启动后,全部节点初始化为Follower,term为0.节点如果收到了RequestVote或者AppendEntries,就会保持自己的Follower身份。如果一段时间内没收到AppendEntries消息直到选举超时,说明在该节点的超时时间内还没发现Leader,Follower就会转换成Candidate,自己开始竞选Leader。一旦转化为Candidate,该节点立即开始下面几件事情:

1、增加自己的term。 

如果在计时器超时前,节点收到多数节点的同意投票,就转换成Leader。同时向所有其他节点发送AppendEntries,告知自己成为了Leader。

每个节点在一个term内只能投一票,采取先到先得的策略,Candidate前面说到已经投给了自己,Follower会投给第一个收到RequestVote的节点。每个Follower有一个计时器,在计时器超时时仍然没有接受到来自Leader的心跳RPC, 则自己转换为Candidate, 开始请求投票,就是上面的的竞选Leader步骤。

如果多个Candidate发起投票,每个Candidate都没拿到多数的投票(Split Vote),那么就会等到计时器超时后重新成为Candidate,重复前面竞选Leader步骤。

Raft协议的定时器采取随机超时时间,这是选举Leader的关键。每个节点定时器的超时时间随机设置,随机选取配置时间的1倍到2倍之间。由于随机配置,所以各个Follower同时转成Candidate的时间一般不一样,在同一个term内,先转为Candidate的节点会先发起投票,从而获得多数票。多个节点同时转换为Candidate的可能性很小。即使几个Candidate同时发起投票,在该term内有几个节点获得一样高的票数,只是这个term无法选出Leader。由于各个节点定时器的超时时间随机生成,那么最先进入下一个term的节点,将更有机会成为Leader。连续多次发生在一个term内节点获得一样高票数在理论上几率很小,实际上可以认为完全不可能发生。一般1-2个term类,Leader就会被选出来。

Sentinel的选举流程

Sentinel集群正常运行的时候每个节点epoch相同,当需要故障转移的时候会在集群中选出Leader执行故障转移操作。Sentinel采用了Raft协议实现了Sentinel间选举Leader的算法,不过也不完全跟论文描述的步骤一致。Sentinel集群运行过程中故障转移完成,所有Sentinel又会恢复平等。Leader仅仅是故障转移操作出现的角色。

选举流程

1、某个Sentinel认定master客观下线的节点后,该Sentinel会先看看自己有没有投过票,如果自己已经投过票给其他Sentinel了,在2倍故障转移的超时时间自己就不会成为Leader。相当于它是一个Follower。 

redis 的持久化的机制,aof 和 rdb 的区别。

RDB 定时快照方式(snapshot): 定时备份,可能会丢失数据 

redis 的集群怎么同步的数据的。

redis replication redis-migrate-tool等方式

搜索

elasticsearch 了解多少,说说你们公司 es 的集群架构,索引数据大小,分片有多少,以及一些调优手段。elasticsearch 的倒排索引是什么。

ElasticSearch(简称ES)是一个分布式、Restful的搜索及分析服务器,设计用于分布式计算;能够达到实时搜索,稳定,可靠,快速。和Apache Solr一样,它也是基于Lucence的索引服务器,而ElasticSearch对比Solr的优点在于:

轻量级:安装启动方便,下载文件之后一条命令就可以启动。
Schema free:可以向服务器提交任意结构的JSON对象,Solr中使用schema.xml指定了索引结构。
多索引文件支持:使用不同的index参数就能创建另一个索引文件,Solr中需要另行配置。
分布式:Solr Cloud的配置比较复杂。

倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。倒排索引主要由两个部分组成:“单词词典”和“倒排文件”。

elasticsearch 索引数据多了怎么办,如何调优,部署。

使用bulk API 

lucence 内部结构是什么

索引(Index): 


JAVA 基础

1. JAVA 中的几种基本数据类型是什么,各自占用多少字节。

 

数据类型

关键字

内置类

内存占用字节数

布尔型

boolean

Boolean

1字节

字符型

char

Character

2字节

字节型

byte

Byte

1字节

短整型

short

Short

2字节

整形

int

Integer

4字节

长整型

long

Long

8字节

单精度型

float

Float

4字节

双精度型

double

Double

8

 

2. String 类能被继承吗,为什么。

 

3. StringStringbufferStringBuilder的区别。

 

4. ArrayList  LinkedList 有什么区别。

 

5. 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当 new 的时候,他们的执行顺序。

 

6. 用过哪些 Map 类,都有什么区别,HashMap 是线程安全的吗,并发下使用的 Map 是什么,他们内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。

[plain]  view plain  copy
  1. 当 HashMap 中的元素个数超过数组大小 loadFactor时,就会进行数组扩容,loadFactor的默认值为 0.75,这是一个折中的取值。也就是说,默认情况下,数组大小为 16,那么当 HashMap 中元素个数超过 16*0.75=12 的时候,就把数组的大小扩展为 2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知 HashMap 中元素的个数,那么预设元素的个数能够有效的提高 HashMap 的性能。  
  2.    
  3. HashMap 的性能参数  
  4. HashMap 包含如下几个构造器:  
  5.    
  6. HashMap():构建一个初始容量为 16,负载因子为 0.75 的 HashMap。  
  7. HashMap(int initialCapacity):构建一个初始容量为 initialCapacity,负载因子为 0.75 的 HashMap  
  8.    
  9. ConcurrentHashMap适用于读者数量超过写者时,当写者数量大于等于读者时,CHM的性能是低于Hashtable和synchronized Map的。这是因为当锁住了整个Map时,读操作要等待对同一部分执行写操作的线程结束。CHM适用于做cache,在程序启动时初始化,之后可以被多个请求线程访问。正如Javadoc说明的那样,CHM是HashTable一个很好的替代,但要记住,CHM的比HashTable的同步性稍弱  
  10.    
  11. ArrayList:默认长度是10  一次扩容50%  
  12. 默认长度是10  一次扩容50%  

7. JAVA8  ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。

[plain]  view plain  copy
  1. 从Java 8开始,HashMap,ConcurrentHashMap和LinkedHashMap在处理频繁冲突时将使用平衡树来代替链表,  
  2. 当同一hash桶中的元素数量超过特定的值便会由链表切换到平衡树,这会将get()方法的性能从O(n)提高到O(logn)。  

8.  有没有有顺序的 Map  实现类,如果有,他们是怎么保证有序的。

 

9. 抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么。

10. 继承和聚合的区别在哪。

[plain]  view plain  copy
  1. 一、聚合  
  2. 为了能够使用一条命令就能构建 account-email和 account-persist两个模块,我们需要建立一个额外的名为 account-aggregator的模块,然后通过该模块构建整个项目的所有模块。 account-aggregator本身也是个 Maven项目,它的 POM如下  
  3. Xml代码  收藏代码  
  4.    
  5.     <project>    
  6.         <modelVersion>4.0.0</modelVersion>    
  7.         <groupId>com.juvenxu.mvnbook.account</groupId>    
  8.         <artifactId>account-aggregator</artifactId>    
  9.         <version>1.0.0-SNAPSHOT</version>    
  10.         <packaging> pom </packaging>    
  11.         <name>Account Aggregator</name>    
  12.          <modules>    
  13.             <module>account-email</module>    
  14.             <module>account-persist</module>    
  15.          </modules>    
  16.     </project>    
  17.    
  18.  注意:packaging的类型为pom ,module的值是一个以当前POM为主目录的相对路径。  
  19.    
  20. 二、继承  
  21.    
  22. 可声明父POM供子 POM继承  
  23.    
  24. 父模块POM如下:  
  25.    
  26.    
  27. Xml代码     
  28.     <project>    
  29.         <modelVersion>4.0.0</modelVersion>    
  30.         <groupId>com.juvenxu.mvnbook.account</groupId>    
  31.         <artifactId> account-parent </artifactId>    
  32.         <version>1.0.0-SNAPSHOT</version>    
  33.         <packaging>pom</packaging>    
  34.         <name>Account Parent</name>    
  35.     </project>    
  36.    
  37.  子模块声明继承如下:  
  38.    
  39.    
  40. Xml代码     
  41.     <project>    
  42.         <modelVersion>4.0.0</modelVersion>    
  43.             
  44.         < parent >    
  45.             <groupId>com.juvenxu.mvnbook.account</groupId>    
  46.             <artifactId> account-parent </artifactId>    
  47.             <version>1.0.0-SNAPSHOT</version>    
  48.             < relativePath >../account-parent/pom.xml</ relativePath>    
  49.         </ parent >    
  50.             
  51.         <artifactId> account-email </artifactId>    
  52.         <name>Account Email</name>    
  53.       ...    
  54.     </project>    
  55.    
  56.  最后,同样还需要把 account-parent加入到聚合模块account-aggregator中。聚合的 POM如下:  
  57.    
  58.    
  59. Xml代码     
  60.    
  61.     <project>    
  62.         <modelVersion>4.0.0</modelVersion>    
  63.         <groupId>com.juvenxu.mvnbook.account</groupId>    
  64.         <artifactId>account-aggregator</artifactId>    
  65.         <version>1.0.0-SNAPSHOT</version>    
  66.         <packaging> pom </packaging>    
  67.         <name>Account Aggregator</name>    
  68.         <modules>    
  69.             <module>account-email</module>    
  70.             <module>account-persist</module>    
  71.             <module> account-parent</module>    
  72.         </modules>    
  73.     </project>    

11. 讲讲你理解的 nio。他和 bio 的区别是啥,谈谈 reactor 模型。 

[plain]  view plain  copy
  1. Reactor模式首先是事件驱动的,有一个或多个并发输入源,有一个Service Handler,有多个Request Handlers;这个Service Handler会同步的将  
  2. 输入的请求(Event)多路复用的分发给相应的Request Handle  
  3. http://www.blogjava.net/DLevin/archive/2015/09/02/427045.html  

12. 反射的原理,反射创建类实例的三种方式是什么。

[java]  view plain  copy
  1. //第一种表示方式--》实际在告诉我们任何一个类都有一个隐含的静态成员变量class  
  2. Class class1 = Foo.class;  
  3.   
  4. //第二种表示方式  已经知道该类的对象通过getClass方法  
  5. Class class2 = foo1.getClass();  
  6.   
  7. //第三种表达方式  
  8. class3 = Class.forName("com.imooc.reflect.Foo");  
  9.    

13. 反射中,Class.forName  ClassLoader 区别

 

14. 描述动态代理的几种实现方式,分别说出相应的优缺点。

 

15. 动态代理与cglib 实现的区别。

[java]  view plain  copy
  1.       JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,  
  2. cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,  
  3. 并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。   
  4. 采用非常底层的字节码生成技术  

16. 为什么CGlib 方式可以对接口实现代理。

 

17. final的用途。

[plain]  view plain  copy
  1. final类不能被继承,没有子类,final类中的方法默认是final的。  
  2. final方法不能被子类的方法覆盖,但可以被继承。  
  3. final成员变量表示常量,只能被赋值一次,赋值后值不再改变。  
  4. final不能用于修饰构造方法  

18. 出三种单例模式实现

19. 如何在父类中为子类自动完成所有的 hashcode  equals 实现?这么做有何优劣。

 

20. 请结合 OO 设计理念,谈谈访问修饰符 publicprivateprotecteddefault 在应用设计中的作用。

21. 深拷贝和浅拷贝区别。

 

22. 数组和链表数据结构描述,各自的时间复杂度。

 

23. error  exception 的区别,CheckedExceptionRuntimeException 的区别。

 

24. 请列出 5 个运行时异常。


25. 在自己的代码中,如果创建一个 java.lang.String 对象,这个对象是否可以被类加载器加载?为什么。

[plain]  view plain  copy
  1. http://blog.csdn.net/bbirdsky/article/details/8283143  
  2. 字符串类(Java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生。在很多面试题中经常用String大做文章,只要掌握了String特性,对付它们就不再是困难了。  
  3. 1、从根本上认识java.lang.String类和String池  
  4. 首先,我建议先看看String类的源码实现,这是从本质上认识String类的根本出发点。  
  5. 从源码中可以看到:  
  6. String类是final的,不可被继承。public final class String。  
  7. String类是的本质是字符数组char[], 并且其值不可改变。private final char value[];  
  8.    
  9. 然后打开String类的API文档,从API中可以发现:  
  10. String类对象有个特殊的创建的方式,就是直接指定比如String x = "abc","abc"就表示一个字符串对象。而x是"abc"对象的地址,也叫做"abc"对象的引用。  
  11. String对象可以通过“+”串联。串联后会生成新的字符串。也可以通过concat()来串联,这个后面会讲述。  
  12. Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。  
  13.    
  14. 2、创建字符串的方式  
  15. 创建字符串的方式很多,归纳起来有三类:  
  16. 使用new关键字创建字符串,比如String s1 = new String("abc");  
  17. 直接指定。比如String s2 = "abc";  
  18. 使用串联生成新的字符串。比如String s3 = "ab" + "c"。  
  19.    
  20. 3、String对象的创建的特性  
  21. String对象的创建也很讲究,关键是要明白其原理。  
  22.    
  23. 特性1:  
  24. 当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个字符串的内容在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。  
  25.    
  26. 特性2:  
  27. Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。  
  28.    
  29. 特性3:  
  30. 使用直接指定、使用纯字符串串联或者在编译期间可以确定结果的变量表达式来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象;  
  31. 1、 直接指定,例如:下面代码运行结果为true;  
  32. String str1 = "abc";  
  33. String str2 = "abc";  
  34. System.out.println(str1 == str2);  
  35. 2、 使用纯字符串串联,例如:下面代码运行结果为true;  
  36. String str1 = "abc";  
  37. String str2 = "ab" + "c";  
  38. System.out.println(str1 == str2);  
  39. 3、 在编译期间可以确定结果的变量表达式,例如:下面代码运行结果为true。  
  40. final String str1 = "c"; //final类型的变量在编译时当常量处理  
  41. String str2 = "ab" + "c";  
  42. String str3 = "ab" + str1;  
  43. System.out.println(str2==str3);  
  44.    
  45. 否则使用包含编译期间无法确定结果的变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String(由StringBuilder.toString()生成)对象。  
  46. 1、普通变量表达式进行创建字符串,例如:下面代码运行结果为false;  
  47. String str1 = "c";  
  48. String str2 = "ab" + "c";  
  49. String str3 = "ab" + str1;  
  50. System.out.println(str2==str3);  

26. 说一说你对 java.lang.Object 对象中 hashCode  equals 方法的理解。在什么场景下需要重新实现这两个方法。

 

27.  jdk1.5 中,引入了泛型,泛型的存在是用来解决什么问题。

 

28. 这样的 a.hashcode() 有什么用,与 a.equals(b)有什么关系。

[plain]  view plain  copy
  1. 1、equals方法用于比较对象的内容是否相等(覆盖以后)  
  2. 2、hashcode方法只有在集合中用到  
  3. 3、当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较(判断对象的内容是否相等)。  
  4. 4、将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。  
  5. 如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。  

 
29. 有没有可能 2 个不相等的对象有相同的 hashcode

[plain]  view plain  copy
  1. equals()相等的两个对象,hashcode()一定相等;  
  2. equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。  

 
30. Java 中的 HashSet 内部是如何工作的。

 

31. 什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决。

 

JVM 知识

1. 什么情况下会发生栈内存溢出。

[plain]  view plain  copy
  1. 至于是堆内存溢出还是方法区内存溢出还是栈内存溢出,其实可以用一些工具比如  
  2. JConsole来监视  

2. JVM 的内存结构,Eden  Survivor 比例。

 

3. jvm 中一次完整的 GC 流程是怎样的,对象如何晋升到老年代,说说你知道的几种主要的 jvm 参数。

 

4. 你知道哪几种垃圾收集器,各自的优缺点,重点讲下 cms,包括原理,流程,优缺点

 

5. 垃圾回收算法的实现原理。

 

6. 当出现了内存溢出,你怎么排错。

 

7. JVM 内存模型的相关知识了解多少,比如重排序,内存屏障,happen-before,主内存,工作内存等。

8. 简单说说你了解的类加载器。

 

9. 讲讲 JAVA 的反射机制。

 

10. 你们线上应用的 JVM 参数有哪些。

 

11. g1  cms 区别,吞吐量优先和响应优先的垃圾收集器选择。

 

12. 请解释如下 jvm 参数的含义:

[plain]  view plain  copy
  1. -server -Xms512m -Xmx512m -Xss1024K  
  2.    
  3. -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxTenuringThreshold=20 XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly。  
  4.    
  5. http://blog.csdn.net/a503921892/article/details/39048889  
  6. Xmx3550m:设置JVM最大可用内存为3550M。  
  7. -Xms3550m:设置JVM初始内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。  
  8. -Xss128k: 设置每个线程的堆栈大小。在相同物理内 存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,  
  9. 经验值在3000~5000左右  
  10. -XX:MaxPermSize=16m:设置持久代大小为16m  
  11.  -XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。  
  12. 如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。  

 系统学习JVM知识这篇文章讲的比较清楚

https://yq.aliyun.com/articles/434362

开源框架知识

1. 简单讲讲 tomcat 结构,以及其类加载器流程。

 

2. tomcat 如何调优,涉及哪些参数

 

3. 讲讲 Spring 加载流程。

 

4. 讲讲 Spring 事务的传播属性。

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

5. Spring 如何管理事务的。

 

6. Spring 怎么配置事务(具体说出一些关键的 xml元素)。

[plain]  view plain  copy
  1. tx:advice,aop:config  

7. 说说你对 Spring 的理解,非单例注入的原理?它的生命周期?循环注入的原理,aop 的实现原理,说说 aop 中的几个术语,它们是怎么相互工作的。

 

8. Springmvc  DispatcherServlet初始化过程。

[java]  view plain  copy
  1. 1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;  
  2. 2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;  
  3. 3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)  
  4. 4.  提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:  
  5.       HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息  
  6.       数据转换:对请求消息进行数据转换。如String转换成Integer、Double等  
  7.       数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等  
  8.       数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中  
  9. 5.  Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;  
  10. 6.  根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;  
  11. 7. ViewResolver 结合Model和View,来渲染视图  

操作系统

1. Linux 系统下你关注过哪些内核参数,说说你知道的。

 

2. Linux  IO 模型有几种,各自的含义是什么。

 

3. epoll  poll 有什么区别。

 

4. 平时用到哪些 Linux 命令。

 

5. 用一行命令查看文件的最后五行。

[plain]  view plain  copy
  1. 输出test文件的后五行:  
  2.    
  3. liyi@liyi:~/Desktop > tail -n 5 test  
  4.    
  5. 输出test文件的前五行:  
  6.    
  7. liyi@liyi:~/Desktop > head -n 5 test  

6. 用一行命令输出正在运行的 java 进程。

 

7. 介绍下你理解的操作系统中线程切换过程。

 

8. 进程和线程的区别。

 

多线程

1. 多线程的几种实现方式,什么是线程安全。

 

2. volatile 的原理,作用,能代替锁么。

 

3. 画一个线程的生命周期状态图。

 

4. sleep  wait 的区别。

 

5. Lock  Synchronized 的区别

 

6. synchronized 的原理是什么,解释以下名词:重排序,自旋锁,偏向锁,轻量级锁,可重入锁,公平锁,非公平锁,乐观锁,悲观锁。

 

7. 用过哪些原子类,他们的原理是什么。

 

8. 用过线程池吗,newCache  newFixed 有什么区别,他们的原理简单概括下,构造函数的各个参数的含义是什么,比如 coreSizemaxsize 等。

9. 线程池的关闭方式有几种,各自的区别是什么。

 

10. 假如有一个第三方接口,有很多个线程去调用获取数据,现在规定每秒钟最多有 10 个线程同时调用它,如何做到。

 

11. spring  controller 是单例还是多例,怎么保证并发的安全。


[java]  view plain  copy
  1. singleton : bean在每个Spring ioc 容器中只有一个实例。  
  2. prototype:一个bean的定义可以有多个实例。  
  3. request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。  

 

12. 用三个线程按顺序循环打印 abc 三个字母,比如 abcabcabc

[plain]  view plain  copy
  1. 思路:解题思路大概是这样的,开启三个线程,每个线程一次打印一个字母,并且按照一定的顺序打印,当打印A的时候,其他线程处于阻塞状态,打印完A以后,  
  2. 将线程解锁,让打印B的那个线程开启,其他线程处于阻塞状态,同理打印C的时候,阻塞其他线程,这三个线程顺序循环,就达到顺序多次打印ABC的目的了。  
  3.    
  4. 这道题看似思路简单,其实主要需要用到wait()方法和notify()方法,还有关键字synchronized,只有充分理解了这些,才能解出这道题。下面我有必要讲解一下这两个方法,  
  5. 还有关键字synchronized。  

13. ThreadLocal 用过么,用途是什么,原理是什么,用的时候要注意什么。

 

14. 如果让你实现一个并发安全的链表,你会怎么做。

[java]  view plain  copy
  1. http://blog.csdn.net/iter_zc/article/details/41115021  

15. 有哪些无锁数据结构,他们实现的原理是什么。

[java]  view plain  copy
  1. ConcurrentLinkedQueue  
  2. 从源代码角度来看整个入队过程主要做二件事情。第一是定位出尾节点,第二是使用CAS算法能将入队节点设置成尾节点的next节点,如不成功则重试。  
  3. http://blog.csdn.net/iter_zc/article/details/4111502  

16. 讲讲 java 同步机制的 wait  notify

 

17. 多线程如果线程挂住了怎么办。

 

18. countdowlatch  cyclicbarrier的内部原理和用法,以及相互之间的差别。

 

19. 使用 synchronized 修饰静态方法和非静态方法有什么区别。

[java]  view plain  copy
  1. 所有的非静态同步方法用的都是同一把锁——实例对象本身,也就是说如果一个实例对象的非静态同步方法获取锁后,  
  2.  该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁,  
  3.  可是别的实例对象的非静态同步方法因为跟该实例对象的非静态同步方法用的是不同的锁,  
  4.  所以毋须等待该实例对象已获取锁的非静态同步方法释放锁就可以获取他们自己的锁。  
  5.   
  6.  而所有的静态同步方法用的也是同一把锁——类对象本身,这两把锁是两个不同的对象,  
  7.  所以静态同步方法与非静态同步方法之间是不会有竞态条件的。但是一旦一个静态同步方法获取锁后,  
  8.  其他的静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是同一个实例对象的静态同步方法之间,  
  9.  还是不同的实例对象的静态同步方法之间,只要它们同一个类的实例对象!  


20. 简述 ConcurrentLinkedQueue  LinkedBlockingQueue 的用处和不同之处。

 

21. 导致线程死锁的原因?怎么解除线程死锁。

 

22. 非常多个线程(可能是不同机器),相互之间需要等待协调,才能完成某种工作,问怎么设计这种协调方案。

[java]  view plain  copy
  1. CountDownLatch,CyclicBarrier  

23. 正确使用 Volatile 变量

[plain]  view plain  copy
  1. 正确使用 volatile 变量的条件  
  2.    
  3. 您只能在有限的一些情形下使用 volatile 变量替代锁。要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:  
  4.    
  5. 1对变量的写操作不依赖于当前值。  
  6. 2该变量没有包含在具有其他变量的不变式中。  
  7. http://www.ibm.com/developerworks/cn/java/j-jtp06197.html  

TCP  HTTP

1. http1.0  http1.1 有什么区别。

[java]  view plain  copy
  1. 在http1.0中,当建立连接后,客户端发送一个请求,服务器端返回一个信息后就关闭连接,  
  2. 当浏览器下次请求的时候又要建立连接,显然这种不断建立连接的方式,会造成很多问题。  
  3.      
  4. 在http1.1中,引入了持续连接的概念,通过这种连接,浏览器可以建立一个连接之后,  
  5. 发送请求并得到返回信息,然后继续发送请求再次等到返回信息,也就是说客户端可以连续发送多个请求,而不用等待每一个响应的到来。  


2. TCP 三次握手和四次挥手的流程,为什么断开连接要 4,如果握手只有两次,会出现什么。

 

3. TIME_WAIT  CLOSE_WAIT 的区别。

 

4. 说说你知道的几种 HTTP 响应码,比如 200, 302, 404

 

5. 当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤。

 

6. TCP/IP 如何保证可靠性,说说 TCP 头的结构。

 

7. 如何避免浏览器缓存。

 

8. 简述 Http 请求 get  post 的区别以及数据包格式。

[java]  view plain  copy
  1. GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头<request-line>中  
  2. POST提交:把提交的数据放置在是HTTP包的包体<request-body>中  

9. 简述 HTTP 请求的报文格式。

[java]  view plain  copy
  1. 一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成  
  2. http://blog.csdn.net/zhangliang_571/article/details/23508953  

10. HTTPS 的加密方式是什么,讲讲整个加密解密流程。

 

架构设计与分布式

 

1. 常见的缓存策略有哪些,你们项目中用到了什么缓存系统,如何设计的。

 

2.  java 自己实现一个 LRU

 

3. 分布式集群下如何做到唯一序列号。

 

4. 设计一个秒杀系统,30 分钟没付款就自动关闭交易。

 

5. 如何使用 redis  zookeeper 实现分布式锁?有什么区别优缺点,分别适用什么场景。

 

6. 如果有人恶意创建非法连接,怎么解决。

 

7. 分布式事务的原理,优缺点,如何使用分布式事务。

 

8. 什么是一致性 hash

 

9. 什么是 restful,讲讲你理解的 restful

 

10. 如何设计建立和保持 100w 的长连接。

 

11. 如何防止缓存雪崩。

 

12. 解释什么是 MESI 协议(缓存一致性)

 

13. 说说你知道的几种 HASH 算法,简单的也可以。

 

14. 什么是 paxos 算法。

 

15. 什么是 zab 协议。

 

16. 一个在线文档系统,文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新。

 

17. 线上系统突然变得异常缓慢,你如何查找问题。

18. 说说你平时用到的设计模式。 

19. Dubbo 的原理,数据怎么流转的,怎么实现集群,负载均衡,服务注册和发现。重试转发,快速失败的策略是怎样的

 

20. 一次 RPC 请求的流程是什么。

 

21. 异步模式的用途和意义。

 

22. 缓存数据过期后的更新如何设计。

 

23. 编程中自己都怎么考虑一些设计原则的,比如开闭原则,以及在工作中的应用。

 

24. 设计一个社交网站中的私信功能,要求高并发、可扩展等等。画一下架构图。

 

25. MVC 模式,即常见的 MVC 框架。

 

26. 聊了下曾经参与设计的服务器架构。

 

27. 应用服务器怎么监控性能,各种方式的区别。

 

28. 如何设计一套高并发支付方案,架构如何设计。

 

29. 如何实现负载均衡,有哪些算法可以实现。

 

30. Zookeeper 的用途,选举的原理是什么。

 

31. Mybatis 的底层实现原理。

[plain]  view plain  copy
  1. MyBatis底层就是JDBC   所以他的核心就是配置文件  :  
  2.    
  3.       1:全局配置文件 (配置数据源 事务运行时信息)  
  4.       2:映射文件(执行statement的相关信息,包括SQL语句,输入参数,输出结果)  
  5.       MyBatis把全局配置文件加载到内容中 构建出SqlSessionFactory    ,这个工厂的作用相当于生产对象生产SqlSession。  
  6.      SqlSession   :它是一个面向程序员的接口,可以操作数据库。 接口有一个默认实现DefaultSqlSession。  
  7. 在SqlSession   中有一个executor 执行器。  SqlSession   本身不能操作数据库 需要通过这个执行器去操作。有2个实现 一个叫做基本执行器,还有一个缓存执行器  
  8. (默认)。 MappedStatement:封装了执行Statement信息,包括SQL语句 输入参数,输出结果。由它去操作数据库。  
  9.    
  10. 输入输出参数类型:  
  11.             1:基本类型  
  12.             2:自定义类型  
  13.             3:hashmap  
  14.    
  15. 根据源码:看到Sqlsession内部并不能直接操作数据库。而是利用内部的一个执行器去操作数据库。执行器执行的时候会去执行MappedStatement   
  16. 到最后才去真正执行数据库。  

32. 请思考一个方案,设计一个可以控制缓存总体大小的自动适应的本地缓存。

 

33. 请思考一个方案,实现分布式环境下的 countDownLatch

 

34. 后台系统怎么防止请求重复提交。

[java]  view plain  copy
  1. <a href="http://blog.csdn.net/wws199304/article/details/44279589" target="_blank">http://blog.csdn.net/wws199304/article/details/44279589</a>  

35. 如何看待缓存的使用(本地缓存,集中式缓存),简述本地缓存和集中式缓存和优缺点。本地缓存在并发使用时的注意事项。

 

36. 描述一个服务从发布到被消费的详细过程。

 

37. 讲讲你理解的服务治理。

 

38. 如何做到接口的幂等性。

 

[java]  view plain  copy
  1. 接口幂等性,只要保证接口内的逻辑不涉及接口外的对象状态累积或变迁即可。  
  2.   
  3. 譬如说需求是:  
  4. 当用户点击赞同时,将答案的赞同数量+1。  
  5. 改为:  
  6. 当用户点击赞同时,确保答案赞同表中存在一条记录,用户、答案。  
  7. 赞同数量由答案赞同表统计出来  

39.redis和memcached的区别

[java]  view plain  copy
  1. 1、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等;  
  2. 2、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储;  
  3. 3、虚拟内存--Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;  
  4. 4、过期策略--memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10;  
  5. 5、分布式--设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从;  
  6. 6、存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);  
  7. 7、灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;  
  8. 8、Redis支持数据的备份,即master-slave模式的数据备份;  
  9. 9、应用场景不一样:Redis出来作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等。  

算法

 

 

1. 10 亿个数字里里面找最小的 10 个。

 

2.  1 亿个数字,其中有 2 个是重复的,快速找到它,时间和空间要最优。

 

3. 2 亿个随机生成的无序整数,找出中间大小的值。

 

4. 给一个不知道长度的(可能很大)输入字符串,设计一种方案,将重复的字符排重。

 

5. 遍历二叉树。

 

6.  3n+1 个数字,其中 3n 个中是重复的,只有 1 个是不重复的,怎么找出来。

 

7. 写一个字符串反转函数。

 

8. 常用的排序算法,快排,归并、冒泡。 快排的最优时间复杂度,最差复杂度。冒泡排序的优化方案。

 

9. 二分查找的时间复杂度,优势。

 

10. 一个已经构建好的 TreeSet,怎么完成倒排序。

 

11. 什么是 B+树,B-树,列出实际的使用场景。

SQL

1. 行转列

姓名       课程       分数

---------- ---------- -----------

张三       语文        74

张三       数学        83

张三       物理        93

李四       语文        74

李四       数学        84

李四       物理        94

[plain]  view plain  copy
  1. SELECT 姓名,  
  2.  max(CASE 课程 WHEN'语文' THEN 分数 ELSE 0 END) 语文,  
  3.  max(CASE 课程 WHEN'数学' THEN 分数 ELSE 0 END) 数学,  
  4.  max(CASE 课程 WHEN'物理' THEN 分数 ELSE 0 END) 物理  
  5. FROM tb  
  6. GROUP BY 姓名  
  7.    
  8. 姓名       语文        数学        物理  
  9. ---------- ----------- ----------- -----------  
  10. 李四        74          84          94  
  11. 张三        74          83          93  


2. MySQL存储引擎- MyISAM与InnoDB区别

[plain]  view plain  copy
  1. InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定。基本的差别为:MyISAM类型不支持事务处理等高级处理,  
  2. 而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能。  
  3.    
  4. 两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁。而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用  

中间件

Dubbo提供了多种均衡策略,缺省为random随机调用。

Random LoadBalance

随机,按权重设置随机概率。

在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

   RoundRobin LoadBalance

轮循,按公约后的权重设置轮循比率。

存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

   LeastActive LoadBalance

最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。

使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

  ConsistentHash LoadBalance

一致性Hash,相同参数的请求总是发到同一提供者。

当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

集群容错模式:

   Failover Cluster

失败自动切换,当出现失败,重试其它服务器。(缺省)

通常用于读操作,但重试会带来更长延迟。

可通过retries="2"来设置重试次数(不含第一次)。正是文章刚开始说的那种情况.

  Failfast Cluster

快速失败,只发起一次调用,失败立即报错。

通常用于非幂等性的写操作,比如新增记录。

  Failsafe Cluster

失败安全,出现异常时,直接忽略。

通常用于写入审计日志等操作。

  Failback Cluster

失败自动恢复,后台记录失败请求,定时重发。

通常用于消息通知操作。

  Forking Cluster

并行调用多个服务器,只要一个成功即返回。

通常用于实时性要求较高的读操作,但需要浪费更多服务资源。

可通过forks="2"来设置最大并行数。

  Broadcast Cluster

广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)

通常用于通知所有提供者更新缓存或日志等本地资源信息。

重试次数配置如:(failover集群模式生效)

MQ分布式系统事务一致性解决方案

http://www.infoq.com/cn/articles/solution-of-distributed-system-transaction-consistency

redis分布式缓存

http://blog.csdn.net/javaloveiphone/article/details/52327240
http://blog.csdn.net/javaloveiphone/article/details/52352894

java基础

Arrays.sort实现原理和Collection实现原理 foreach和while的区别(编译之后) 线程池的种类,区别和使用场景 分析线程池的实现原理和线程的调度过程 线程池如何调优 线程池的最大线程数目根据什么确定 动态代理的几种方式 HashMap的并发问题 了解LinkedHashMap的应用吗 反射的原理,反射创建类实例的三种方式是什么? cloneable接口实现原理,浅拷贝or深拷贝 Java NIO使用 hashtable和hashmap的区别及实现原理,hashmap会问到数组索引,hash碰撞怎么解决 arraylist和linkedlist区别及实现原理 反射中,Class.forName和ClassLoader区别 String,Stringbuffer,StringBuilder的区别? 有没有可能2个不相等的对象有相同的hashcode 简述NIO的最佳实践,比如netty,mina TreeMap的实现原理

JVM相关

类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,他们的执行顺序 JVM内存分代 Java 8的内存分代改进 JVM垃圾回收机制,何时触发MinorGC等操作 jvm中一次完整的GC流程(从ygc到fgc)是怎样的,重点讲讲对象如何晋升到老年代,几种主要的jvm参数等 你知道哪几种垃圾收集器,各自的优缺点,重点讲下cms,g1 新生代和老生代的内存回收策略 Eden和Survivor的比例分配等 深入分析了Classloader,双亲委派机制 JVM的编译优化 对Java内存模型的理解,以及其在并发中的应用 指令重排序,内存栅栏等 OOM错误,stackoverflow错误,permgen space错误 JVM常用参数 tomcat结构,类加载器流程 volatile的语义,它修饰的变量一定线程安全吗 g1和cms区别,吞吐量优先和响应优先的垃圾收集器选择 说一说你对环境变量classpath的理解?如果一个类不在classpath下,为什么会抛出ClassNotFoundException异常,如果在不改变这个类路径的前期下,怎样才能正确加载这个类? 说一下强引用、软引用、弱引用、虚引用以及他们之间和gc的关系

JUC/并发相关

ThreadLocal用过么,原理是什么,用的时候要注意什么 Synchronized和Lock的区别 synchronized 的原理,什么是自旋锁,偏向锁,轻量级锁,什么叫可重入锁,什么叫公平锁和非公平锁 concurrenthashmap具体实现及其原理,jdk8下的改版 用过哪些原子类,他们的参数以及原理是什么 cas是什么,他会产生什么问题(ABA问题的解决,如加入修改次数、版本号) 如果让你实现一个并发安全的链表,你会怎么做 简述ConcurrentLinkedQueue和LinkedBlockingQueue的用处和不同之处 简述AQS的实现原理 countdowlatch和cyclicbarrier的用法,以及相互之间的差别? concurrent包中使用过哪些类?分别说说使用在什么场景?为什么要使用? LockSupport工具 Condition接口及其实现原理 Fork/Join框架的理解 jdk8的parallelStream的理解 分段锁的原理,锁力度减小的思考

Spring

Spring AOP与IOC的实现原理 Spring的beanFactory和factoryBean的区别 为什么CGlib方式可以对接口实现代理? RMI与代理模式 Spring的事务隔离级别,实现原理 对Spring的理解,非单例注入的原理?它的生命周期?循环注入的原理,aop的实现原理,说说aop中的几个术语,它们是怎么相互工作的? Mybatis的底层实现原理 MVC框架原理,他们都是怎么做url路由的 spring boot特性,优势,适用场景等 quartz和timer对比 spring的controller是单例还是多例,怎么保证并发的安全

分布式相关

Dubbo的底层实现原理和机制 描述一个服务从发布到被消费的详细过程 分布式系统怎么做服务治理 接口的幂等性的概念 消息中间件如何解决消息丢失问题 Dubbo的服务请求失败怎么处理 重连机制会不会造成错误 对分布式事务的理解 如何实现负载均衡,有哪些算法可以实现? Zookeeper的用途,选举的原理是什么? 数据的垂直拆分水平拆分。 zookeeper原理和适用场景 zookeeper watch机制 redis/zk节点宕机如何处理 分布式集群下如何做到唯一序列号 如何做一个分布式锁 用过哪些MQ,怎么用的,和其他mq比较有什么优缺点,MQ的连接是线程安全的吗 MQ系统的数据如何保证不丢失 列举出你能想到的数据库分库分表策略;分库分表后,如何解决全表查询的问题。

算法&数据结构&设计模式

海量url去重类问题(布隆过滤器) 数组和链表数据结构描述,各自的时间复杂度 二叉树遍历 快速排序 BTree相关的操作 在工作中遇到过哪些设计模式,是如何应用的 hash算法的有哪几种,优缺点,使用场景 什么是一致性hash paxos算法 在装饰器模式和代理模式之间,你如何抉择,请结合自身实际情况聊聊 代码重构的步骤和原因,如果理解重构到模式?

数据库

MySQL InnoDB存储的文件结构 索引树是如何维护的? 数据库自增主键可能的问题 MySQL的几种优化 mysql索引为什么使用B+树 数据库锁表的相关处理 索引失效场景 高并发下如何做到安全的修改同一行数据,乐观锁和悲观锁是什么,INNODB的行级锁有哪2种,解释其含义 数据库会死锁吗,举一个死锁的例子,mysql怎么解决死锁

Redis&缓存相关

Redis的并发竞争问题如何解决了解Redis事务的CAS操作吗 缓存机器增删如何对系统影响最小,一致性哈希的实现 Redis持久化的几种方式,优缺点是什么,怎么实现的 Redis的缓存失效策略 缓存穿透的解决办法 redis集群,高可用,原理 mySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据 用Redis和任意语言实现一段恶意登录保护的代码,限制1小时内每用户Id最多只能登录5次 redis的数据淘汰策略

网络相关

http1.0和http1.1有什么区别 TCP/IP协议 TCP三次握手和四次挥手的流程,为什么断开连接要4次,如果握手只有两次,会出现什么 TIME_WAIT和CLOSE_WAIT的区别 说说你知道的几种HTTP响应码 当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤 TCP/IP如何保证可靠性,数据包有哪些数据组成 长连接与短连接 Http请求get和post的区别以及数据包格式 简述tcp建立连接3次握手,和断开连接4次握手的过程;关闭连接时,出现TIMEWAIT过多是由什么原因引起,是出现在主动断开方还是被动断开方。

其他

maven解决依赖冲突,快照版和发行版的区别 Linux下IO模型有几种,各自的含义是什么 实际场景问题,海量登录日志如何排序和处理SQL操作,主要是索引和聚合函数的应用 实际场景问题解决,典型的TOP K问题 线上bug处理流程 如何从线上日志发现问题 linux利用哪些命令,查找哪里出了问题(例如io密集任务,cpu过度) 场景问题,有一个第三方接口,有很多个线程去调用获取数据,现在规定每秒钟最多有10个线程同时调用它,如何做到。 用三个线程按顺序循环打印abc三个字母,比如abcabcabc。 常见的缓存策略有哪些,你们项目中用到了什么缓存系统,如何设计的 设计一个秒杀系统,30分钟没付款就自动关闭交易(并发会很高) 请列出你所了解的性能测试工具 

后台系统怎么防止请求重复提交?

一、Java基础
1.String类为什么是final的。
2.HashMap的源码,实现原理,底层结构。
3.反射中,Class.forName和classloader的区别
4.session和cookie的区别和联系,session的生命周期,多个服务部署时session管理。
5.Java中的队列都有哪些,有什么区别。
6.Java的内存模型以及GC算法
7.Java7、Java8的新特性(baidu问的,好BT)
8.Java数组和链表两种结构的操作效率,在哪些情况下(从开头开始,从结尾开始,从中间开始),哪些操作(插入,查找,删除)的效率高
9.Java内存泄露的问题调查定位:jmap,jstack的使用等等
二、框架
1.struts1和struts2的区别
2.struts2和springMVC的区别
3.spring框架中需要引用哪些jar包,以及这些jar包的用途
4.srpingMVC的原理
5.springMVC注解的意思
6.spring中beanFactory和ApplicationContext的联系和区别
7.spring注入的几种方式
8.spring如何实现事物管理的
9.springIOC和AOP的原理
10.hibernate中的1级和2级缓存的使用方式以及区别原理
11.spring中循环注入的方式
三、多线程
1.Java创建线程之后,直接调用start()方法和run()的区别
2.常用的线程池模式以及不同线程池的使用场景
3.newFixedThreadPool此种线程池如果线程数达到最大值后会怎么办,底层原理。
4.多线程之间通信的同步问题,synchronized锁的是对象,衍伸出和synchronized相关很多的具体问题,例如同一个类不同方法都有synchronized锁,一个对象是否可以同时访问。或者一个类的static构造方法加上synchronized之后的锁的影响。
5.了解可重入锁的含义,以及ReentrantLock 和synchronized的区别
6.同步的数据结构,例如concurrentHashMap的源码理解以及内部实现原理,为什么他是同步的且效率高
7.atomicinteger和volatile等线程安全操作的关键字的理解和使用
8.线程间通信,wait和notify
9.定时线程的使用
10.场景:在一个主线程中,要求有大量(很多很多)子线程执行完之后,主线程才执行完成。多种方式,考虑效率。
四、网络通信
1.http是无状态通信,http的请求方式有哪些,可以自己定义新的请求方式么。
2.socket通信,以及长连接,分包,连接异常断开的处理。
3.socket通信模型的使用,AIO和NIO。
4.socket框架netty的使用,以及NIO的实现原理,为什么是异步非阻塞。
5.同步和异步,阻塞和非阻塞。
五、Linux
1.常用的linux下的命令
2.大的log文件中,统计异常出现的次数、排序,或者指定输出多少行多少列的内容。(主要考察awk)
3.linux下的调查问题思路:内存、CPU、句柄数、过滤、查找、模拟POST和GET请求等等场景
4.shell脚本中#!的作用
六、数据库MySql
1.MySql的存储引擎的不同
2.单个索引、联合索引、主键索引
3.Mysql怎么分表,以及分表后如果想按条件分页查询怎么办(如果不是按分表字段来查询的话,几乎效率低下,无解)
4.分表之后想让一个id多个表是自增的,效率实现
5.MySql的主从实时备份同步的配置,以及原理(从库读主库的binlog),读写分离
6.写SQL语句。。。
7.索引的数据结构,B+树
8.事物的四个特性,以及各自的特点(原子、隔离)等等,项目怎么解决这些问题
七、设计模式(写代码)
1.单例模式:饱汉、饿汉。以及饿汉中的延迟加载
2.工厂模式、装饰者模式、观察者模式。
八、算法
1.使用随机算法产生一个数,要求把1-1000W之间这些数全部生成。(考察高效率,解决产生冲突的问题)
2.两个有序数组的合并排序
3.一个数组的倒序
4.计算一个正整数的正平方根
5.说白了就是常见的那些查找排序算法(排序转载:http://mp.weixin.qq.com/s?__biz=MjM5MTAzMTE4Nw==&mid=204838393&idx=2&sn=e9b50c8ef689e2cb6436110a8dc148a3&scene=5#rd)
九、缓存
1.为什么用缓存,用过哪些缓存,redis和memcache的区别
2.redis的数据结构
3.redis的持久化方式,以及项目中用的哪种,为什么
4.redis集群的理解,怎么动态增加或者删除一个节点,而保证数据不丢失。(一致性哈希问题)
Arrays.sort实现原理和Collection实现原理 
foreach和while的区别(编译之后) 
线程池的种类,区别和使用场景 
分析线程池的实现原理和线程的调度过程 
线程池如何调优 
线程池的最大线程数目根据什么确定 
动态代理的几种方式 
HashMap的并发问题 
了解LinkedHashMap的应用吗 
反射的原理,反射创建类实例的三种方式是什么? 
cloneable接口实现原理,浅拷贝or深拷贝 
Java NIO使用 
hashtable和hashmap的区别及实现原理,hashmap会问到数组索引,hash碰撞怎么解决 
arraylist和linkedlist区别及实现原理 
反射中,Class.forName和ClassLoader区别 
String,Stringbuffer,StringBuilder的区别? 
有没有可能2个不相等的对象有相同的hashcode 
简述NIO的最佳实践,比如netty,mina 
TreeMap的实现原理
JVM相关
类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,他们的执行顺序 
JVM内存分代 
Java 8的内存分代改进 
JVM垃圾回收机制,何时触发MinorGC等操作 
jvm中一次完整的GC流程(从ygc到fgc)是怎样的,重点讲讲对象如何晋升到老年代,几种主要的jvm参数等 
你知道哪几种垃圾收集器,各自的优缺点,重点讲下cms,g1 
新生代和老生代的内存回收策略 
Eden和Survivor的比例分配等 
深入分析了Classloader,双亲委派机制 
JVM的编译优化 
对Java内存模型的理解,以及其在并发中的应用 
指令重排序,内存栅栏等 
OOM错误,stackoverflow错误,permgen space错误 
JVM常用参数 
tomcat结构,类加载器流程 
volatile的语义,它修饰的变量一定线程安全吗 
g1和cms区别,吞吐量优先和响应优先的垃圾收集器选择 
说一说你对环境变量classpath的理解?如果一个类不在classpath下,为什么会抛出ClassNotFoundException异常,如果在不改变这个类路径的前期下,怎样才能正确加载这个类? 
说一下强引用、软引用、弱引用、虚引用以及他们之间和gc的关系
JUC/并发相关
ThreadLocal用过么,原理是什么,用的时候要注意什么 
Synchronized和Lock的区别 
synchronized 的原理,什么是自旋锁,偏向锁,轻量级锁,什么叫可重入锁,什么叫公平锁和非公平锁 
concurrenthashmap具体实现及其原理,jdk8下的改版 
用过哪些原子类,他们的参数以及原理是什么 
cas是什么,他会产生什么问题(ABA问题的解决,如加入修改次数、版本号) 
如果让你实现一个并发安全的链表,你会怎么做 
简述ConcurrentLinkedQueue和LinkedBlockingQueue的用处和不同之处 
简述AQS的实现原理 
countdowlatch和cyclicbarrier的用法,以及相互之间的差别? 
concurrent包中使用过哪些类?分别说说使用在什么场景?为什么要使用? 
LockSupport工具 
Condition接口及其实现原理 
Fork/Join框架的理解 
jdk8的parallelStream的理解 
分段锁的原理,锁力度减小的思考
Spring
Spring AOP与IOC的实现原理 
Spring的beanFactory和factoryBean的区别 
为什么CGlib方式可以对接口实现代理? 
RMI与代理模式 
Spring的事务隔离级别,实现原理 
对Spring的理解,非单例注入的原理?它的生命周期?循环注入的原理,aop的实现原理,说说aop中的几个术语,它们是怎么相互工作的? 
Mybatis的底层实现原理 
MVC框架原理,他们都是怎么做url路由的 
spring boot特性,优势,适用场景等 
quartz和timer对比 
spring的controller是单例还是多例,怎么保证并发的安全
分布式相关
Dubbo的底层实现原理和机制 
描述一个服务从发布到被消费的详细过程 
分布式系统怎么做服务治理 
接口的幂等性的概念 
消息中间件如何解决消息丢失问题 
Dubbo的服务请求失败怎么处理 
重连机制会不会造成错误 
对分布式事务的理解 
如何实现负载均衡,有哪些算法可以实现? 
Zookeeper的用途,选举的原理是什么? 
数据的垂直拆分水平拆分。 
zookeeper原理和适用场景 
zookeeper watch机制 
redis/zk节点宕机如何处理 
分布式集群下如何做到唯一序列号 
如何做一个分布式锁 
用过哪些MQ,怎么用的,和其他mq比较有什么优缺点,MQ的连接是线程安全的吗 
MQ系统的数据如何保证不丢失 
列举出你能想到的数据库分库分表策略;分库分表后,如何解决全表查询的问题。
算法&数据结构&设计模式
海量url去重类问题(布隆过滤器) 
数组和链表数据结构描述,各自的时间复杂度 
二叉树遍历 
快速排序 
BTree相关的操作 
在工作中遇到过哪些设计模式,是如何应用的 
hash算法的有哪几种,优缺点,使用场景 
什么是一致性hash 
paxos算法 
在装饰器模式和代理模式之间,你如何抉择,请结合自身实际情况聊聊 
代码重构的步骤和原因,如果理解重构到模式?
数据库
MySQL InnoDB存储的文件结构 
索引树是如何维护的? 
数据库自增主键可能的问题 
MySQL的几种优化 
mysql索引为什么使用B+树 
数据库锁表的相关处理 
索引失效场景 
高并发下如何做到安全的修改同一行数据,乐观锁和悲观锁是什么,INNODB的行级锁有哪2种,解释其含义 
数据库会死锁吗,举一个死锁的例子,mysql怎么解决死锁
Redis&缓存相关
Redis的并发竞争问题如何解决了解Redis事务的CAS操作吗 
缓存机器增删如何对系统影响最小,一致性哈希的实现 
Redis持久化的几种方式,优缺点是什么,怎么实现的 
Redis的缓存失效策略 
缓存穿透的解决办法 
redis集群,高可用,原理 
mySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据 
用Redis和任意语言实现一段恶意登录保护的代码,限制1小时内每用户Id最多只能登录5次 
redis的数据淘汰策略
网络相关
http1.0和http1.1有什么区别 
TCP/IP协议 
TCP三次握手和四次挥手的流程,为什么断开连接要4次,如果握手只有两次,会出现什么 
TIME_WAIT和CLOSE_WAIT的区别 
说说你知道的几种HTTP响应码 
当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤 
TCP/IP如何保证可靠性,数据包有哪些数据组成 
长连接与短连接 
Http请求get和post的区别以及数据包格式 
简述tcp建立连接3次握手,和断开连接4次握手的过程;关闭连接时,出现TIMEWAIT过多是由什么原因引起,是出现在主动断开方还是被动断开方。
其他
maven解决依赖冲突,快照版和发行版的区别 
Linux下IO模型有几种,各自的含义是什么 
实际场景问题,海量登录日志如何排序和处理SQL操作,主要是索引和聚合函数的应用 
实际场景问题解决,典型的TOP K问题 
线上bug处理流程 
如何从线上日志发现问题 
linux利用哪些命令,查找哪里出了问题(例如io密集任务,cpu过度) 
场景问题,有一个第三方接口,有很多个线程去调用获取数据,现在规定每秒钟最多有10个线程同时调用它,如何做到。 
用三个线程按顺序循环打印abc三个字母,比如abcabcabc。 
常见的缓存策略有哪些,你们项目中用到了什么缓存系统,如何设计的 
设计一个秒杀系统,30分钟没付款就自动关闭交易(并发会很高) 
请列出你所了解的性能测试工具 

后台系统怎么防止请求重复提交?

多线程的40个面试题总结

周末在微信公共号看到一篇关于《线程的40个道题》的文章,由于今年工作之前参加过几次面试,所以觉得这篇文章总结的很好

只要读者朋友们耐心看完,并且在阅读过程中遇到自己疑惑的地方时自己能动手查一查做一做,我相信以后遇到很多关于线程上的问题都会迎刃而解。

打算用两个部分来写,第一便于读者阅读,第二谁也不能一口吃个胖子,相信我有的知识是需要时间的积累才能获得的,没有时间的积累谁也不能成为专家,只有时间才能将你打磨的更加完美。

原文出自“去哪技术沙龙”公众号 40个多线程问题总结,没有地址实在无法标注原文地址

这些多线程的问题,有些来源于各大网站、有些来源于自己的思考。可能有些问题网上有、可能有些问题对应的答案也有、也可能有些各位网友也都看过,但是本文写作的重心就是所有的问题都会按照自己的理解回答一遍,不会去看网上的答案

40个问题汇总

1、多线程有什么用?

一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了,还管它有什么用?在我看来,这个回答更扯淡。所谓”知其然知其所以然”,”会用”只是”知其然”,”为什么用”才是”知其所以然”,只有达到”知其然知其所以然”的程度才可以说是把一个知识点运用自如。OK,下面说说我对这个问题的看法:

(1)发挥多核CPU的优势

随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4核、8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。单核CPU上所谓的”多线程”那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程”同时”运行罢了。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。

(2)防止阻塞

从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题,多条线程同时运行,哪怕一条线程的代码执行读取数据阻塞,也不会影响其它任务的执行。

(3)便于建模

这是另外一个没有这么明显的优点了。假设有一个大的任务A,单线程编程,那么就要考虑很多,建立整个程序模型比较麻烦。但是如果把这个大的任务A分解成几个小任务,任务B、任务C、任务D,分别建立程序模型,并通过多线程分别运行这几个任务,那就简单很多了。

2、创建线程的方式

比较常见的一个问题了,一般就是两种:

(1)继承Thread类

(2)实现Runnable接口

至于哪个好,不用说肯定是后者好,因为实现接口的方式比继承类的方式更灵活,也能减少程序之间的耦合度,面向接口编程也是设计模式6大原则的核心。

3、start()方法和run()方法的区别

只有调用了start()方法,才会表现出多线程的特性,不同线程的run()方法里面的代码交替执行。如果只是调用run()方法,那么代码还是同步执行的,必须等待一个线程的run()方法里面的代码全部执行完毕之后,另外一个线程才可以执行其run()方法里面的代码。

4、Runnable接口和Callable接口的区别

有点深的问题了,也看出一个Java程序员学习知识的广度。

Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。

这其实是很有用的一个特性,因为多线程相比单线程更难、更复杂的一个重要原因就是因为多线程充满着未知性,某条线程是否执行了?某条线程执行了多久?某条线程执行的时候我们期望的数据是否已经赋值完毕?无法得知,我们能做的只是等待这条多线程的任务执行完毕而已。而Callable+Future/FutureTask却可以获取多线程运行的结果,可以在等待时间太长没获取到需要的数据的情况下取消该线程的任务,真的是非常有用。

5、CyclicBarrier和CountDownLatch的区别

两个看上去有点像的类,都在java.util.concurrent下,都可以用来表示代码运行到某个点上,二者的区别在于:

(1)CyclicBarrier的某个线程运行到某个点上之后,该线程即停止运行,直到所有的线程都到达了这个点,所有线程才重新运行;CountDownLatch则不是,某线程运行到某个点上之后,只是给某个数值-1而已,该线程继续运行

(2)CyclicBarrier只能唤起一个任务,CountDownLatch可以唤起多个任务

(3)CyclicBarrier可重用,CountDownLatch不可重用,计数值为0该CountDownLatch就不可再用了

6、volatile关键字的作用

一个非常重要的问题,是每个学习、应用多线程的Java程序员都必须掌握的。理解volatile关键字的作用的前提是要理解Java内存模型,这里就不讲Java内存模型了,可以参见第31点,volatile关键字的作用主要有两个:

(1)多线程主要围绕可见性和原子性两个特性而展开,使用volatile关键字修饰的变量,保证了其在多线程之间的可见性,即每次读取到volatile变量,一定是最新的数据

(2)代码底层执行不像我们看到的高级语言—-Java程序这么简单,它的执行是Java代码–>字节码–>根据字节码执行对应的C/C++代码–>C/C++代码被编译成汇编语言–>和硬件电路交互,现实中,为了获取更好的性能JVM可能会对指令进行重排序,多线程下可能会出现一些意想不到的问题。使用volatile则会对禁止语义重排序,当然这也一定程度上降低了代码执行效率

从实践角度而言,volatile的一个重要作用就是和CAS结合,保证了原子性,详细的可以参见java.util.concurrent.atomic包下的类,比如AtomicInteger。

7、什么是线程安全

又是一个理论的问题,各式各样的答案有很多,我给出一个个人认为解释地最好的:如果你的代码在多线程下执行和在单线程下执行永远都能获得一样的结果,那么你的代码就是线程安全的

这个问题有值得一提的地方,就是线程安全也是有几个级别的:

(1)不可变

像String、Integer、Long这些,都是final类型的类,任何一个线程都改变不了它们的值,要改变除非新创建一个,因此这些不可变对象不需要任何同步手段就可以直接在多线程环境下使用

(2)绝对线程安全

不管运行时环境如何,调用者都不需要额外的同步措施。要做到这一点通常需要付出许多额外的代价,Java中标注自己是线程安全的类,实际上绝大多数都不是线程安全的,不过绝对线程安全的类,Java中也有,比方说CopyOnWriteArrayList、CopyOnWriteArraySet

(3)相对线程安全

相对线程安全也就是我们通常意义上所说的线程安全,像Vector这种,add、remove方法都是原子操作,不会被打断,但也仅限于此,如果有个线程在遍历某个Vector、有个线程同时在add这个Vector,99%的情况下都会出现ConcurrentModificationException,也就是fail-fast机制

(4)线程非安全

这个就没什么好说的了,ArrayList、LinkedList、HashMap等都是线程非安全的类

8、Java中如何获取到线程dump文件

死循环、死锁、阻塞、页面打开慢等问题,打线程dump是最好的解决问题的途径。所谓线程dump也就是线程堆栈,获取到线程堆栈有两步:

(1)获取到线程的pid,可以通过使用jps命令,在Linux环境下还可以使用ps -ef | grep java

(2)打印线程堆栈,可以通过使用jstack pid命令,在Linux环境下还可以使用kill -3 pid

另外提一点,Thread类提供了一个getStackTrace()方法也可以用于获取线程堆栈。这是一个实例方法,因此此方法是和具体线程实例绑定的,每次获取获取到的是具体某个线程当前运行的堆栈,

9、一个线程如果出现了运行时异常会怎么样

如果这个异常没有被捕获的话,这个线程就停止执行了。另外重要的一点是:如果这个线程持有某个某个对象的监视器,那么这个对象监视器会被立即释放

10、如何在两个线程之间共享数据

通过在线程之间共享对象就可以了,然后通过wait/notify/notifyAll、await/signal/signalAll进行唤起和等待,比方说阻塞队列BlockingQueue就是为线程之间共享数据而设计的

11、sleep方法和wait方法有什么区别

这个问题常问,sleep方法和wait方法都可以用来放弃CPU一定的时间,不同点在于如果线程持有某个对象的监视器,sleep方法不会放弃这个对象的监视器,wait方法会放弃这个对象的监视器

12、生产者消费者模型的作用是什么

这个问题很理论,但是很重要:

(1)通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率,这是生产者消费者模型最重要的作用

(2)解耦,这是生产者消费者模型附带的作用,解耦意味着生产者和消费者之间的联系少,联系越少越可以独自发展而不需要收到相互的制约

13、ThreadLocal有什么用

简单说ThreadLocal就是一种以空间换时间的做法,在每个Thread里面维护了一个以开地址法实现的ThreadLocal.ThreadLocalMap,把数据进行隔离,数据不共享,自然就没有线程安全方面的问题了

14、为什么wait()方法和notify()/notifyAll()方法要在同步块中被调用

这是JDK强制的,wait()方法和notify()/notifyAll()方法在调用前都必须先获得对象的锁

15、wait()方法和notify()/notifyAll()方法在放弃对象监视器时有什么区别

wait()方法和notify()/notifyAll()方法在放弃对象监视器的时候的区别在于:wait()方法立即释放对象监视器,notify()/notifyAll()方法则会等待线程剩余代码执行完毕才会放弃对象监视器

16、为什么要使用线程池

避免频繁地创建和销毁线程,达到线程对象的重用。另外,使用线程池还可以根据项目灵活地控制并发的数目。

17、怎么检测一个线程是否持有对象监视器

我也是在网上看到一道多线程面试题才知道有方法可以判断某个线程是否持有对象监视器:Thread类提供了一个holdsLock(Object obj)方法,当且仅当对象obj的监视器被某条线程持有的时候才会返回true,注意这是一个static方法,这意味着“某条线程”指的是当前线程

18、synchronized和ReentrantLock的区别

synchronized是和if、else、for、while一样的关键字,ReentrantLock是类,这是二者的本质区别。既然ReentrantLock是类,那么它就提供了比synchronized更多更灵活的特性,可以被继承、可以有方法、可以有各种各样的类变量,ReentrantLock比synchronized的扩展性体现在几点上:

(1)ReentrantLock可以对获取锁的等待时间进行设置,这样就避免了死锁

(2)ReentrantLock可以获取各种锁的信息

(3)ReentrantLock可以灵活地实现多路通知

另外,二者的锁机制其实也是不一样的。ReentrantLock底层调用的是Unsafe的park方法加锁,synchronized操作的应该是对象头中mark word,这点我不能确定。

19、ConcurrentHashMap的并发度是什么

ConcurrentHashMap的并发度就是segment的大小,默认为16,这意味着最多同时可以有16条线程操作ConcurrentHashMap,这也是ConcurrentHashMap对Hashtable的最大优势,任何情况下,Hashtable能同时有两条线程获取Hashtable中的数据吗?

20、ReadWriteLock是什么

首先明确一下,不是说ReentrantLock不好,只是ReentrantLock某些时候有局限。如果使用ReentrantLock,可能本身是为了防止线程A在写数据、线程B在读数据造成的数据不一致,但这样,如果线程C在读数据、线程D也在读数据,读数据是不会改变数据的,没有必要加锁,但是还是加锁了,降低了程序的性能。

因为这个,才诞生了读写锁ReadWriteLock。ReadWriteLock是一个读写锁接口,ReentrantReadWriteLock是ReadWriteLock接口的一个具体实现,实现了读写的分离,读锁是共享的,写锁是独占的,读和读之间不会互斥,读和写、写和读、写和写之间才会互斥,提升了读写的性能。

Servlet面试题归纳

   

1、说一说Servlet生命周期

Servlet生命周期包括三部分:

初始化:Web容器加载servlet,调用init()方法

处理请求:当请求到达时,运行其service()方法。service()自动派遣运行与请求相对应的doXXX(doGet或者doPost)方法。

销毁:服务结束,web容器会调用servlet的distroy()方法销毁servlet。

2、get提交和post提交有何区别

(1)get一般用于从服务器上获取数据,post一般用于向服务器传送数据

(2)请求的时候参数的位置有区别,get的参数是拼接在url后面,用户在浏览器地址栏可以看到。post是放在http包的包体中。

比如说用户注册,你不能把用户提交的注册信息用get的方式吧,那不是说把用户的注册信息都显示在Url上了吗,是不安全的。

(3)能提交的数据有区别,get方式能提交的数据只能是文本,且大小不超过1024个字节,而post不仅可以提交文本还有二进制文件。

所以说想上传文件的话,那我们就需要使用post请求方式

(4)servlet在处理请求的时候分别对应使用doGet和doPost方式进行处理请求

3、JSP与Servlet有什么区别

Servlet是服务器端的程序,动态生成html页面发送到客户端,但是这样程序里会有很多out.println(),java与html语言混在一起

很乱,所以后来sun公司推出了JSP.其实JSP就是Servlet,每次运行的时候JSP都首先被编译成servlet文件,然后再被编译成

.class文件运行。有了jsp,在MVC项目中servlet不再负责动态生成页面,转而去负责控制程序逻辑的作用,控制jsp与javabean

之间的流转。

4、doGet与doPost方法的两个参数是什么

HttpServletRequest:封装了与请求相关的信息

HttpServletResponse:封装了与响应相关的信息

5、request.getAttribute()和request.getParameter

(1)有setAttribute,没有setParameter方法

(2)getParameter获取到的值只能是字符串,不可以是对象,而getAttribute获取到的值是Object类型的。

(3)通过form表单或者url来向另一个页面或者servlet传递参数的时候需要用getParameter获取值;getAttribute只能获取setAttribute的值

(4)setAttribute是应用服务器把这个对象放到该页面所对应的一块内存当中,当你的页面服务器重定向到另一个页面的时候,应用服务器

会把这块内存拷贝到另一个页面对应的内存当中。通过getAttribute可以取得你存下的值,当然这种方法可以用来传对象。

用session也是一样的道理,这是说request和session的生命周期不一样而已。

6、JSP有哪些内置对象,作用是什么?

JSP内置对象
名称作用
request包含用户端请求的信息
response包含服务器传回客户端的响应信息
session与请求有关的会话期
pageContext管理网页属性
application服务器启动时创建,服务器关闭时停止,为多个应用程序保存信息
out向客户端输出数据
configservlet的架构部件
page指网页本身
exception针对错误页面才可使用

7、四种会话跟踪技术作用域

(1)page:一个页面

(2)request::一次请求

(3)session:一次会话

(4)application:服务器从启动到停止。

7、JSP中动态INCLUDE和静态INCLUDE有什么区别

include指令用于把另一个页面包含到当前页面中,在什么时候包含的?再转换成servlet的时候包含进去的。

动态INCLUDE用jsp:include动作实现 <jsp:include page="included.jsp" flush="true" />它总是会检查所含文件中的变化,适合用于包含动态页面,

并且可以带参数.

静态INCLUDE用include伪码实现,定不会检查所含文件的变化,适用于包含静态页面<%@ include file="included.htm" %>

8、forward和redirect的区别

转发与重定向

(1)从地址栏显示来说 

forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送

的内容从哪里来的,所以它的地址栏还是原来的地址.redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是

新的URL.

(2)从数据共享来说 

forward:转发页面和转发到的页面可以共享request里面的数据.

redirect:不能共享数据.

(3)从运用地方来说 

forward:一般用于用户登陆的时候,根据角色转发到相应的模块.

redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.

(4)从效率来说 

forward:高.

redirect:低.

版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/hai_cheng001/article/details/38116481

Redis面试题及分布式集群

1. 使用Redis有哪些好处?

(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,list,set,sorted set,hash (3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行 (4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

2. redis相比memcached有哪些优势?

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 (2) redis的速度比memcached快很多 (3) redis可以持久化其数据

3. redis常见性能问题和解决方案:

(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件 (2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次 (3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内 (4) 尽量避免在压力很大的主库上增加从库 (5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3… 这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。

4. MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:

voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-enviction(驱逐):禁止驱逐数据

5. Memcache与Redis的区别都有哪些?

1)、存储方式

Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。

Redis有部份存在硬盘上,这样能保证数据的持久性。

2)、数据支持类型

Memcache对数据类型支持相对简单。

Redis有复杂的数据类型。

3)、使用底层模型不同

它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。

Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

4),value大小

redis最大可以达到1GB,而memcache只有1MB

6. Redis 常见的性能问题都有哪些?如何解决?

1).Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。

2).Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

3).Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。

4). Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内

7, redis 最适合的场景

Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢? 如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点: 1 、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 2 、Redis支持数据的备份,即master-slave模式的数据备份。 3 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。 (1)、会话缓存(Session Cache)

最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?

幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。

(2)、全页缓存(FPC)

除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。

此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

(3)、队列

Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。

如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。

(4),排行榜/计数器

Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:

当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。

(5)、发布/订阅

最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。

Redis提供的所有特性中,我感觉这个是喜欢的人最少的一个,虽然它为用户提供如果此多功能。

高可用分布式集群

一,高可用

高可用(High Availability),是当一台服务器停止服务后,对于业务及用户毫无影响。 停止服务的原因可能由于网卡、路由器、机房、CPU负载过高、内存溢出、自然灾害等不可预期的原因导致,在很多时候也称单点问题。

(1)解决单点问题主要有2种方式:

主备方式 这种通常是一台主机、一台或多台备机,在正常情况下主机对外提供服务,并把数据同步到备机,当主机宕机后,备机立刻开始服务。 Redis HA中使用比较多的是keepalived,它使主机备机对外提供同一个虚拟IP,客户端通过虚拟IP进行数据操作,正常期间主机一直对外提供服务,宕机后VIP自动漂移到备机上。

优点是对客户端毫无影响,仍然通过VIP操作。 缺点也很明显,在绝大多数时间内备机是一直没使用,被浪费着的。

主从方式 这种采取一主多从的办法,主从之间进行数据同步。 当Master宕机后,通过选举算法(Paxos、Raft)从slave中选举出新Master继续对外提供服务,主机恢复后以slave的身份重新加入。 主从另一个目的是进行读写分离,这是当单机读写压力过高的一种通用型解决方案。 其主机的角色只提供写操作或少量的读,把多余读请求通过负载均衡算法分流到单个或多个slave服务器上。

缺点是主机宕机后,Slave虽然被选举成新Master了,但对外提供的IP服务地址却发生变化了,意味着会影响到客户端。 解决这种情况需要一些额外的工作,在当主机地址发生变化后及时通知到客户端,客户端收到新地址后,使用新地址继续发送新请求。

(2)数据同步 无论是主备还是主从都牵扯到数据同步的问题,这也分2种情况:

同步方式:当主机收到客户端写操作后,以同步方式把数据同步到从机上,当从机也成功写入后,主机才返回给客户端成功,也称数据强一致性。 很显然这种方式性能会降低不少,当从机很多时,可以不用每台都同步,主机同步某一台从机后,从机再把数据分发同步到其他从机上,这样提高主机性能分担同步压力。 在redis中是支持这杨配置的,一台master,一台slave,同时这台salve又作为其他slave的master。

异步方式:主机接收到写操作后,直接返回成功,然后在后台用异步方式把数据同步到从机上。 这种同步性能比较好,但无法保证数据的完整性,比如在异步同步过程中主机突然宕机了,也称这种方式为数据弱一致性。

Redis主从同步采用的是异步方式,因此会有少量丢数据的危险。还有种弱一致性的特例叫最终一致性,这块详细内容可参见CAP原理及一致性模型。

(3)方案选择 keepalived方案配置简单、人力成本小,在数据量少、压力小的情况下推荐使用。 如果数据量比较大,不希望过多浪费机器,还希望在宕机后,做一些自定义的措施,比如报警、记日志、数据迁移等操作,推荐使用主从方式,因为和主从搭配的一般还有个管理监控中心。

宕机通知这块,可以集成到客户端组件上,也可单独抽离出来。 Redis官方Sentinel支持故障自动转移、通知等,详情见低成本高可用方案设计(四)。

逻辑图: 

二,分布式

分布式(distributed), 是当业务量、数据量增加时,可以通过任意增加减少服务器数量来解决问题。

集群时代 至少部署两台Redis服务器构成一个小的集群,主要有2个目的:

高可用性:在主机挂掉后,自动故障转移,使前端服务对用户无影响。 读写分离:将主机读压力分流到从机上。 可在客户端组件上实现负载均衡,根据不同服务器的运行情况,分担不同比例的读请求压力。

逻辑图: 

三,分布式集群时代

当缓存数据量不断增加时,单机内存不够使用,需要把数据切分不同部分,分布到多台服务器上。 可在客户端对数据进行分片,数据分片算法详见C#一致性Hash详解、C#之虚拟桶分片。

逻辑图: 

大规模分布式集群时代 当数据量持续增加时,应用可根据不同场景下的业务申请对应的分布式集群。 这块最关键的是缓存治理这块,其中最重要的部分是加入了代理服务。 应用通过代理访问真实的Redis服务器进行读写,这样做的好处是:

避免越来越多的客户端直接访问Redis服务器难以管理,而造成风险。 在代理这一层可以做对应的安全措施,比如限流、授权、分片。 避免客户端越来越多的逻辑代码,不但臃肿升级还比较麻烦。 代理这层无状态的,可任意扩展节点,对于客户端来说,访问代理跟访问单机Redis一样。 目前楼主公司使用的是客户端组件和代理两种方案并存,因为通过代理会影响一定的性能。 代理这块对应的方案实现有Twitter的Twemproxy和豌豆荚的codis。

逻辑图: 

四,总结

分布式缓存再向后是云服务缓存,对使用端完全屏蔽细节,各应用自行申请大小、流量方案即可,如淘宝OCS云服务缓存。 分布式缓存对应需要的实现组件有:

一个缓存监控、迁移、管理中心。 一个自定义的客户端组件,上图中的SmartClient。 一个无状态的代理服务。 N台服务器。

spring常见的面试题

1使用Spring框架的好处是什么?    轻量:Spring 是轻量的,基本的版本大约2MB。    控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。    面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。    容器:Spring 包含并管理应用中对象的生命周期和配置。    MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。    事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。    异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。2.说说AOP和IOC/DI的概念以及在spring中是如何应用的?AOP,Aspect Oriented Program,面向(方面)切面的编程;IOC,Invert Of Control,控制反转。对象的实例由容器自动生成,即用接口编程,在程序中不出现new关键字,而是用接口来命名引用,然后通过某种方式把接口的某个实现类的实例注入到引用里,从而实现接口与具体实现类的松耦合。由容器控制程序之间的关系(通过XML配置),而非传统实现中的由程序代码直接操控,依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。简单说一下,IOC就是其实就是依赖注入,(在一个Class对象中引用另一个Class对象时,我们通常都是直接通过new contructor)。控制权由应用代码中转到了外部容器,控制权的转移,是所谓的反转。 AOP方式很类似filter,就是在程序正常的业务流中间像切面一样插入很多其他需要执行的代码,比如登录时候,在进入登录页面前写入日志,很常用的,尤其是跟数据库有关的,或者跟支付有关的程序肯定会在每一步前面插入日志。面向方面的编程,即 AOP,是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。AOP Advice(AOP通知)分为:前置通知   后置通知   异常通知   环绕通知 3:Spring的事物有几种方式?Spring框架的事务管理有哪些优点? 你更倾向用那种事务管理类型?谈谈spring事物的隔离级别和传播行为?编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。它为不同的事务API  如 JTA,JDBC,Hibernate,JPA 和JDO,提供一个不变的编程模式。 它为编程式事务管理提供了一套简单的API而不是一些复杂的事务API如 它支持声明式事务管理。 它和Spring各种数据访问抽象层很好得集成。大多数Spring框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式允许你通过代码控制事务)少了一点灵活性。事务的隔离级别:数据库系统提供了4种事务隔离级别,在这4种隔离级别中,Serializable的隔离级别最高,Read Uncommitted的隔离级别最低;· Read Uncommitted   读未提交数据;(会出现脏读)· Read Committed      读已提交数据;· Repeatable Read       可重复读;事务的传播属性包括:· Required业务方法需要在一个事务中运行,如果一个方法运行时已经处在一个事务中,那么加入到该事务,否则为自己创建一个新事务,  80%的方法用到该传播属性;· Not-Supported· Requiresnew· Mandatoky· Supports· Never· Nested4: 解释Spring框架中bean的生命周期及Spring支持的几种作用域。    Spring容器 从XML 文件中读取bean的定义,并实例化bean。    Spring根据bean的定义填充所有的属性。    如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。    如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。    如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。    如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。    如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。    如果bean实现了 DisposableBean,它将调用destroy()方法。Spring框架支持以下五种bean的作用域:    singleton : bean在每个Spring ioc 容器中只有一个实例。    prototype:一个bean的定义可以有多个实例。    request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。    session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。    global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

5:面向切面的原理

Spring提供了对AOP技术的良好封装,AOP称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多的方法中要加入某种系统功能代码,例如:加入日志、权限判断、异常处理等,这种应用成为AOP。
实现AOP功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,而是作为目标的子类在JDK中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某类个生成子类,则可以用CGLIB。(动态代理这方面的可以参考我的另一篇文章)

在生成的代理类的方法中加入系统功能和调用目标类的相应方法,系统功能的代理以Advice对象进行提供,显然要创建出代理对象,至少需要目标类和Advice类。

集合面试题

1.请讲下Java里面的容器 

 分两大类,Map和Collection。而Collection又有子接口List(数据存储顺序和插入顺序是一样的)、Set(里面的元素具有唯一性) 

 Map是存储键值对的,里面的健不可以重复,但值可以重复a. 对于List主要有ArrayList和LinkedList两种实现。实现的数据结构不同,所以主要的区别也都是和数据结构相关的。 ArrayList基于数组,随机访问快,而对于中间元素的插入删除效率比较低,而且需要考虑扩容问题。LinkedList,则 基于链表,和ArrayList提到的正相反,随机访问慢,但对于中间元素的插入和删除更有效率。Set也是一种Collection,和List比起来主要体现在元素唯一性。

2.请说下Iterator的作用

 迭代器可以实现Collection接口的方法,可以一个一个地获取集合中的元素在遍历集合时 可判断是否有下一个元素

3.说下ArrayList和LinkedList的区别和联系,并说明什么情况下用它们

 区别:ArrayList用于对象的随机访问速度快,没有顺序LinkedList实现机制是链表式的,和顺序有关,速度比ArrayList慢联系:ArrayList和LinkedList都是List接口的实现类当要快速获取一个值时,用ArrayList,用于顺序插入操作时,用LinkedList.

4.说下List,Set,Map三种集合各有什么特征

 List集合中的元素可以重复,Set集合中的元素不可以重复Map集合用键-值映射存放对象,Map容器中的键对象不能重复,值对象可以重复

5.HashSet和TreeSet有什么区别,什么时候用它们

 区别:HashSet中的元素不能重复,没有顺序TreeSet中的元素不能重复,但有顺序当集合中的元素需要排序时,用TreeSet一般情况下用HashSet,因为不需要排序,速度比TreeSet快

6.什么是泛型,怎么使用的,有什么好处?

答案

 定义一个集合时,可以知道里面定义的是什么类型使用:在集合类型后面加< 数据类型 >使用泛型后,从集合中取得元素后就不用再用强转 

7.什么是for each循环,它可以循环那些数据类型

答案

 也可以叫增强型循环通过对象拿到集合里的值,因为扩展性比较强,建议多使用可以用来循环集合和数组

8.写一个for each循环看看

for(Object object : list){System.out.println(object);}

9. 什么是强转怎么写的,有什么优缺点,一般要多用还是少用,为什么?

 一般在继承的基础上用.一般是范围小的转换成范围大的,譬如byte可以转换成int,还可以子类转换成父类,反之则不行。

Person person=new Student();

Student student=(Student)person;

把运行期的强转为编译期的.

编译期不会出错.运行期容易出错.所以一般少用

10.HashMap和Hashtable有什么区别,一 般情况下常用那个?

 HashMap的键-值都可以为空(null)Hashtable的键-值都不可以为空(null),线程安全 ,一般情况下用HashMap

 11.Hashtable名字为什么没有驼峰命名

 Hashtable的由来比较古老,当时还没有命名规范

12.Collections和Collection有什么区别

Collections是一个工具类,可以直接调用List和Set的方法Collection是一个接口,是List和Set集合的父接口

13.写出Collections的6个方法,并详细解释

 sort():对集合进行排序shuffle():打乱集合中的元素顺序addAll():将一个集合添加到另一个集合中max():判断集合中的最大值min():判断集合中的最小值copy():将一个集合中的元素复制到另一个集合中去fill():将一个集合中的元素全部替换成指定的元素

14.Arrays类是做什么的,写出它的常用6个方法

 Arrays是数组的一个工具类sort():对数组进行排序binarySearch():搜索数组指定元素的下标copyOf():复制数组中指定长度的元素deepEquals():比较两个数组的深度fill():把数组中的所有元素替换成指定元素equals():比较指定两个数组的元素是否相等

15.比较下集合和数组的优缺点

 集合是多个对象的容器,可以将不同数据类型的多个对象组织在一起数组类型是有相同数据类型的数据集合,数组是很多语言都支持的底层数据结构,性能上是最高的

16.如何对一个对象排序,有几种方法

 把对象放入List集合中,用Collections工具类调用sort()方法进行排序,但是这个类必须实现Compable接口才行把对象放在Set集合中,用TreeSet()实现类对集合直接排序

17.在集合里面怎么判断两个对象相等,要实现什么方法

 equals方法

18.怎么样把集合转化成数组,或把数组转化为集合

把集合转为数组,可以用toArray()方法 
把数组转为集合时, for each循坏,先把数组中的元素转为String型,再放到集合里

19.分别写出List,Set,Map里面的5个常用方法

 List:add()新增 clear()清除 contains()判断是否包含某个元素 indexOf()一个元素在集合中首次出现的位置set()把指定下标的元素替换成自定义元素Set:add()新增 clear()清除 contains()判断是否包含某个元素remove():把集合中指定下标的元素删掉size():返回集合长度Map: containsKey()是否包含指定key containsValue()是否包含指定value keySet()返回所有key put()添加元素 Remove()移除

20.HashMap与LinkedHashMap,和TreeMap的区别。

共同点:HashMap,LinkedHashMap,TreeMap都属于Map的实现类. 不同点: 1.HashMap里面存入的键值对在取出的时候是随机的, 2.TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。 3. LinkedHashMap 是HashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现.

21.HashMap怎么实现有序  可以转化放入TreeMap里面。 

22.在List里面怎么去掉重复的数?

通过把List里面的数据放入HashSet可以去除重复

23.在List里面有几种排序?

答:两种:实现Comparable<Article>接口,实现里面的CompareTo方法进行排序。还有调用Collections.sort()方法排序!

24.说一下链表跟数组的区别

链表:用一组任意储存单元存放线性表的数据元素,并且通过指针链相接结点的序列称为链表。是一种常见的数据组织形式,它采用了动态分配内存的形式实现。需要时可以用new分配内存空间,不需要时用delete将已分配的空间释放,不会造成内存空间的浪费。不靠数组实现,没有下标。数组必须事先定义固定的长度,不能适应数据动态增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成数据浪费。在使用的时候还要数组初始化,注意数组的下标越界。

25.HashSet的理解

HashSet实现了Set接口,HashSet不保证集合的迭代顺序,允许使用Null元素。HashSet的底层使用了HashMap,使用HashMap实列进行对集合的元素进行操作,然后再封装成HashSet的操作。

26.什么类可以实现有序存储(除ArrayList以外)?一种按照插入的顺序排序,譬如LinkedList,LiskedHashMap,另外一种是插入后重新排序TreeSet,TreeMap 

27.HashMap和ArrayList是不是都是线程不安全的? 

ArrayList是线程不安全的;HashMap是线程不安全的;还有我们常见的一些JAVA集合都是线程不安全,这样做是为了提高性能

在JDK5以后提供了线程安全的并发包java.util.concurrent并发包,譬如里面的类CopyOnWriteArrayList,CopyOnWriteArraySet,ConcurrentHashMap等

28.ArrayList集合加入1万条数据,应该怎么提高效率

因为ArrayList的底层是数组实现,并且数组的默认值是10,如果插入10000条要不断的扩容,耗费时间,所以我们调用ArrayList的指定容量的构造器方法ArrayList(int size) 就可以实现不扩容,就提高了性能

29.你知道HashMap底层是怎么实现的吗?

  简单的说是一个数组,因为数组的性能比较好,数组里面放的是Entry类,HashMap类有一个叫做Entry的内部类。这个Entry类包含了key-value作为实例变量。当存储或者获取对象的时候,就根据哈希算法,对象的hashCode调用得到这个下标,以便实现快速访问.

30.怎样遍历List Set,Map

 List 和Set可以通过一般for循环,迭代器循环,或者增强型循环来遍历, 其中一般for循环性能最快,迭代器循环可以判断和得到下一个值,for each增强型循环扩展性强,但性能稍低.

Map循环可以通过keySet得到Key的Set集合,然后遍历这个集合就可以得到所有的Value

31.Set为什么是不允许重复的。

set的实现机制不允许重复的

32.ArrayList为什么要用for循环,为什么要用迭代器,又有什么好处。

for循环通过对象拿到集合里的值迭代器可以实现Collection接口的方法,可以一个一个地获取集合中的元素在遍历集合时 可判断是否有下一个元素

33.你对栈与队列了解多少你是怎么用的。

答:队列是一种数据结构,FIFO 先进先出有点类似与栈,只是在队列中第一个插入的数据项也会被最先删除,队列的两个基本操作:一个是插入一个数据项,即把一个数据项放入队尾另一个是移除一个数据项,即移除队头的数据项.

34.如果我要存取很多的数据,但是又不需要重复的,要选择什么容器,说一下为什么使用它,它是哪个的子类?

答:Set容器,它是不允许重复的,它是collection的子类

35.哪种方法可以得到Map的Key?

keySet()方法

springmvc和mybatis面试题(含答案)

Spring MVC Framework有这样一些特点:

1。它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是java组件.并且和Spring提供的其他基础结构紧密集成.
2。不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的)
3。可以任意使用各种视图技术,而不仅仅局限于JSP
4。支持各种请求资源的映射策略
5。它应是易于扩展的
  • 1
  • 2
  • 3
  • 4
  • 5

2) SpringMVC的工作流程?

1. 用户发送请求至前端控制器DispatcherServlet
2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
5. 执行处理器(Controller,也叫后端控制器)。
6. Controller执行完成返回ModelAndView
7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9. ViewReslover解析后返回具体View
10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
11. DispatcherServlet响应用户
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3) 如果你也用过struts2.简单介绍下springMVC和struts2的区别有哪些?

1. springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
2. springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
3. Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。
  • 1
  • 2
  • 3

4) SpringMvc原理图 

5) SSM优缺点、使用场景?

1. Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
2. Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。
3. Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
4. 总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Mybatis 

1. mybatis配置
2. SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
3. mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
4. 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
5. 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
6. mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
7. Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
8. Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
9. Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
版权声明:博客的原创文章,大家可以转载,但是一定要声明文章来源。谢谢。 http://blog.csdn.net/xinghuo0007/article/details/53463897

Socket(网络编程)面试题

Java网络面试

     http是一种无状态的协议

     get提交的有大小限制,post没有

     LinkedList增加和删除效率优于ArrayList

     Redis 可是数据持久化的,但是Memcache不可以

1、什么是TCP协议?UDP协议?区别?

TCP:传输控制协议,面向连接,可靠。保证数据传输成功。

UDP:不可靠。传输速度快。占系统资源少。

2TCP三次握手?

A——》B  通信请求以及序列号作为起始数据段。

B——》A  收到请求,序列号作为起始数据段。

A——》B  收到请求

Java网络编程

服务端套接字:ServerSocketaccept() bind() close()

客户端套接字:Socket

 

网络编程时的同步、异步、阻塞、非阻塞?

同步:函数调用在没得到结果之前,没有调用结果,不返回任何结果。

异步:函数调用在没得到结果之前,没有调用结果,返回状态信息。

阻塞:函数调用在没得到结果之前,当前线程挂起。得到结果后才返回。

非阻塞:函数调用在没得到结果之前,当前线程不会挂起,立即返回结果。

 

Java如何实现无阻塞方式的Socket编程?

NIO有效解决了多线程服务器存在的线程开销问题。在NIO中使用多线程主要目的不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分利用多个CPU的处理能力和处理中的等待时间,达到提高服务能力的目的。chanelBufferselector

 

HTTPHTTPS

HTTPS=HTTP+SSL443端口。

http是明文传输,https是密文传输。

https需要到ca申请证书,缴费。


Hibernate常见面试题

1、什么是Hibernate的并发机制?怎么去处理并发问题?

Hibernate并发机制:

a、Hibernate的Session对象是非线程安全的,对于单个请求,单个会话,单个的工作单元(即单个事务,单个线程),它通常只使用一次, 然后就丢弃。


如果一个Session 实例允许共享的话,那些支持并发运行的,例如Http request,session beans将会导致出现资源争用。
如果在Http Session中有hibernate的Session的话,就可能会出现同步访问Http Session。只要用户足够快的点击浏览器的“刷新”,
就会导致两个并发运行的线程使用同一个Session。
  • 1
  • 2
  • 3
  • 4

b、多个事务并发访问同一块资源,可能会引发第一类丢失更新,脏读,幻读,不可重复读,第二类丢失更新一系列的问题。

解决方案:设置事务隔离级别。 

2、update和saveOrUpdate的区别?

update()和saveOrUpdate()是用来对跨Session的PO进行状态管理的。 

3、hibernate的三种状态之间如何转换

当对象由瞬时状态(Transient)一save()时,就变成了持久化状态; 

4、比较hibernate的三种检索策略优缺点

1立即检索; 优点: 对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便的从一个对象导航到与它关联的对象; 缺点: 1.select语句太多;2.可能会加载应用程序不需要访问的对象白白浪费许多内存空间; 优点: 由应用程序决定需要加载哪些对象,可以避免可执行多余的select语句,以及避免加载应用程序不需要访问的对象。因此能提高检索性能,并且能节省内存空间; 缺点: 应用程序如果希望访问游离状态代理类实例,必须保证他在持久化状态时已经被初始化; 优点: 1对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便地冲一个对象导航到与它关联的对象。2使用了外连接,select语句数目少; 缺点: 1 可能会加载应用程序不需要访问的对象,白白浪费许多内存空间;2复杂的数据库表连接也会影响检索性能;

5、如何在控制台看到hibernate生成并执行的sql

在定义数据库和数据库属性的文件applicationConfig.xml里面,把hibernate.show_sql 设置为true 

6、hibernate都支持哪些缓存策略

Read-only: 这种策略适用于那些频繁读取却不会更新的数据,这是目前为止最简单和最有效的缓存策略 

7、hibernate里面的sorted collection 和ordered collection有什么区别

sorted collection是在内存中通过Java比较器进行排序的 

8、Hibernate工作原理及为什么要用?

1.读取并解析配置文件 

为什么要用: 

  1. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作

  2. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。

  3. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。

10、Hibernate是如何延迟加载?

当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。

11、Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)

类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、

12、说下Hibernate的缓存机制

  1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存

  2. 二级缓存: 

13、Hibernate的查询方式

Sql、Criteria,objectcomposition 

14、如何优化Hibernate?

1.使用双向一对多关联,不使用单向一对多 

15、Hibernate有哪几种查询数据的方式

3种:hql、条件查询QBC(QueryBy Criteria)、原生sql (通过createSQLQuery建立)

16、谈谈Hibernate中inverse的作用

inverse属性默认是false,就是说关系的两端都来维护关系。 

17、Detached Object(游离对象)有什么好处

Detached Object(游离对象)可以传递到任何层直到表现层而不是用任何DTO(DataTransfer Objects). 然后你还可以重新把游离对象赋给另外一个Session.

18、JDBC hibernate 和 ibatis 的区别

jdbc:手动 

19、在数据库中条件查询速度很慢的时候,如何优化?

1.建索引 

20、什么是SessionFactory,她是线程安全么?

SessionFactory 是Hibrenate单例数据存储和线程安全的,以至于可以多线程同时访问。一个SessionFactory 在启动的时候只能建立一次。SessionFactory应该包装各种单例以至于它能很简单的在一个应用代码中储存.

21、Hibernate的五个核心接口

Configuration 接口:配置Hibernate,根据其启动hibernate,创建 

版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/qq1137623160/article/details/71194677

 

对于Dubbo一些面试题自己的答案

Dubbo

      头几天瞧到《Java顶尖口试必问-Dubbo口试题汇总》,对于内里得难点本人试着答复少许,有错误得请民众指正。

      Dubbo固然大概不革新了,可是背靠阿里得措施能力,中文报告得多样,非常合适很多几中小型分散式类型得开辟。

一、Dubbo通讯协议

      第一、dubbo

 

Dubbo 缺省协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。

反之,Dubbo 缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。

特性

缺省协议,使用基于 mina 1.1.7 和 hessian 3.2.1 的 tbremoting 交互。

   第二、RMI

      

rmi://

RMI 协议采用 JDK 标准的 java.rmi.* 实现,采用阻塞式短连接和 JDK 标准序列化方式。

注意:如果正在使用 RMI 提供服务给外部访问 1,同时应用里依赖了老的 common-collections 包 2的情况下,存在反序列化安全风险 3

特性

      第三、hessian

      

Hessian 1 协议用于集成 Hessian 的服务,Hessian 底层采用 Http 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。

Dubbo 的 Hessian 协议可以和原生 Hessian 服务互操作,即:

特性


      第四、Http

      

基于 HTTP 表单的远程调用协议,采用 Spring 的 HttpInvoker 实现 1

特性

      第五、WebService

      

基于 WebService 的远程调用协议,基于 Apache CXF 1 的 frontend-simple 和 transports-http实现 2

可以和原生 WebService 服务互操作,即:

      第六、thrift

      

当前 dubbo 支持 1的 thrift 协议是对 thrift 原生协议 2 的扩展,在原生协议的基础上添加了一些额外的头信息,比如 service name,magic number 等。

使用 dubbo thrift 协议同样需要使用 thrift 的 idl compiler 编译生成相应的 java 代码,后续版本中会在这方面做一些增强。

      第七、缓存

memcached://

基于 memcached 1 实现的 RPC 协议 2

redis://

基于 Redis 1 实现的 RPC 协议 2

二、注册中心

     

1)Multicast 注册中心

Multicast 注册中心不需要启动任何中心节点,只要广播地址一样,就可以互相发现。

  1. 提供方启动时广播自己的地址
  2. 消费方启动时广播订阅请求
  3. 提供方收到订阅请求时,单播自己的地址给订阅者,如果设置了 unicast=false,则广播给订阅者
  4. 消费方收到提供方地址时,连接该地址进行 RPC 调用。

组播受网络结构限制,只适合小规模应用或开发阶段使用。组播地址段: 224.0.0.0 - 239.255.255.255

2)zookeeper 注册中心

Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用 1

流程说明:

  • 服务提供者启动时: 向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址
  • 服务消费者启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址
  • 监控中心启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址。

支持以下功能:

  • 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息
  • 当注册中心重启时,能自动恢复注册数据,以及订阅请求
  • 当会话过期时,能自动恢复注册数据,以及订阅请求
  • 当设置 <dubbo:registry check="false" /> 时,记录失败注册和订阅请求,后台定时重试
  • 可通过 <dubbo:registry username="admin" password="1234" /> 设置 zookeeper 登录信息
  • 可通过 <dubbo:registry group="dubbo" /> 设置 zookeeper 的根节点,不设置将使用无根树
  • 支持 * 号通配符 <dubbo:reference group="*" version="*" />,可订阅服务的所有分组和所有版本的提供者

3)Redis 注册中心

基于 Redis 1 实现的注册中心 2

使用 Redis 的 Key/Map 结构存储数据结构:

  • 主 Key 为服务名和类型
  • Map 中的 Key 为 URL 地址
  • Map 中的 Value 为过期时间,用于判断脏数据,脏数据由监控中心删除 3

使用 Redis 的 Publish/Subscribe 事件通知数据变更:

  • 通过事件的值区分事件类型:registerunregistersubscribeunsubscribe
  • 普通消费者直接订阅指定服务提供者的 Key,只会收到指定服务的 registerunregister 事件
  • 监控中心通过 psubscribe 功能订阅 /dubbo/*,会收到所有服务的所有变更事件

调用过程:

  1. 服务提供方启动时,向 Key:/dubbo/com.foo.BarService/providers 下,添加当前提供者的地址
  2. 并向 Channel:/dubbo/com.foo.BarService/providers 发送 register 事件
  3. 服务消费方启动时,从 Channel:/dubbo/com.foo.BarService/providers 订阅 register 和 unregister 事件
  4. 并向 Key:/dubbo/com.foo.BarService/providers 下,添加当前消费者的地址
  5. 服务消费方收到 register 和 unregister 事件后,从 Key:/dubbo/com.foo.BarService/providers 下获取提供者地址列表
  6. 服务监控中心启动时,从 Channel:/dubbo/* 订阅 register 和 unregister,以及 subscribe 和unsubsribe事件
  7. 服务监控中心收到 register 和 unregister 事件后,从 Key:/dubbo/com.foo.BarService/providers 下获取提供者地址列表
  8. 服务监控中心收到 subscribe 和 unsubsribe 事件后,从 Key:/dubbo/com.foo.BarService/consumers 下获取消费者地址列表

4)Simple 注册中心

Simple 注册中心本身就是一个普通的 Dubbo 服务,可以减少第三方依赖,使整体通讯方式一致。


三、集群容错

Failover Cluster

失败自动切换,当出现失败,重试其它服务器 1。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。

重试次数配置如下:

<dubbo:service retries="2" />

<dubbo:reference retries="2" />

<dubbo:reference>
<dubbo:method name="findFoo" retries="2" />
</dubbo:reference>

Failfast Cluster

快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

Failsafe Cluster

失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

Failback Cluster

失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

Forking Cluster

并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。

Broadcast Cluster

广播调用所有提供者,逐个调用,任意一台报错则报错 2。通常用于通知所有提供者更新缓存或日志等本地资源信息。

http://www.njszjw.gov.cn/jrjd/02017082114135.html

Java面试题之精选最常见的面试真题

异常处理

1.Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?

Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并可以对其进行处理。 

2.列出一些你常见的运行时异常? 

3.Java中的两种异常类型是什么?他们有什么区别?

Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常。不受检查的异常不需要在方法或者是构造函数上声明,就算方法或者是构造函数的执行可能会抛出这样的异常,并且不受检查的异常可以传播到方法或者是构造函数的外面。相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。这里有Java异常处理的一些小建议。

4.Java中Exception和Error有什么区别?

Exception和Error都是Throwable的子类。 

5.异常处理的时候,finally代码块的重要性是什么?

无论是否抛出异常,finally代码块总是会被执行。就算是没有catch语句同时又抛出异常的情况下,finally代码块仍然会被执行。最后要说的是,finally代码块主要用来释放资源,比如:I/O缓冲区,数据库连接。

6.异常处理完成以后,Exception对象会发生什么变化?

Exception对象会在下一个垃圾回收过程中被回收掉。

7.finally代码块和finalize()方法有什么区别?

无论是否抛出异常,finally代码块都会执行,它主要是用来释放应用占用的资源。finalize()方法是Object类的一个protected方法,它是在对象被垃圾回收之前由Java虚拟机来调用的。

Java小应用程序

1.什么是Applet?

java applet是能够被包含在HTML页面中并且能被启用了java的客户端浏览器执行的程序。Applet主要用来创建动态交互的web应用程序。

2.简述Applet的生命周期?

applet可以经历下面的状态:

Init:每次被载入的时候都会被初始化。 

3.当applet被载入的时候会发生什么?

首先,创建applet控制类的实例,然后初始化applet,最后开始运行。

4.Applet和普通的Java应用程序有什么区别?

applet是运行在启用了java的浏览器中,Java应用程序是可以在浏览器之外运行的独立的Java程序。但是,它们都需要有Java虚拟机。

进一步来说,Java应用程序需要一个有特定方法签名的main函数来开始执行。Java applet不需要这样的函数来开始执行。

最后,Java applet一般会使用很严格的安全策略,Java应用一般使用比较宽松的安全策略。

5.Java applet有哪些限制条件?

主要是由于安全的原因,给applet施加了以下的限制:

applet不能够载入类库或者定义本地方法。 

6.从网络上加载的applet和从本地文件系统加载的applet有什么区别?

当applet是从网络上加载的时候,applet是由applet类加载器载入的,它受applet安全管理器的限制。

当applet是从客户端的本地磁盘载入的时候,applet是由文件系统加载器载入的。

从文件系统载入的applet允许在客户端读文件,写文件,加载类库,并且也允许执行其他程序,但是,却通不过字节码校验。

7.applet类加载器是什么?它会做哪些工作?

当applet是从网络上加载的时候,它是由applet类加载器载入的。类加载器有自己的java名称空间等级结构。类加载器会保证来自文件系统的类有唯一的名称空间,来自网络资源的类有唯一的名称空间。

当浏览器通过网络载入applet的时候,applet的类被放置于和applet的源相关联的私有的名称空间中。然后,那些被类加载器载入进来的类都是通过了验证器验证的。验证器会检查类文件格式是否遵守Java语言规范,确保不会出现堆栈溢出(stack overflow)或者下溢(underflow),传递给字节码指令的参数是正确的。

8.applet安全管理器是什么?它会做哪些工作?

applet安全管理器是给applet施加限制条件的一种机制。浏览器可以只有一个安全管理器。安全管理器在启动的时候被创建,之后不能被替换覆盖或者是扩展。

9.什么是不受信任的applet?

不受信任的applet是不能访问或是执行本地系统文件的Java applet,默认情况下,所有下载的applet都是不受信任的。

Swing

1.说出三种支持重绘(painting)的组件。

Canvas, Frame, Panel,和Applet支持重绘。

2.什么是裁剪(clipping)?

限制在一个给定的区域或者形状的绘图操作就做裁剪。

3.MenuItem和CheckboxMenuItem的区别是什么?

CheckboxMenuItem类继承自MenuItem类,支持菜单选项可以选中或者不选中。

4.边缘布局(BorderLayout)里面的元素是如何布局的?

BorderLayout里面的元素是按照容器的东西南北中进行布局的。

5.网格包布局(GridBagLayout)里面的元素是如何布局的?

GridBagLayout里面的元素是按照网格进行布局的。不同大小的元素可能会占据网格的多于1行或一列。因此,行数和列数可以有不同的大小。

6.Window和Frame有什么区别?

Frame类继承了Window类,它定义了一个可以有菜单栏的主应用窗口。

7.裁剪(clipping)和重绘(repainting)有什么联系?

当窗口被AWT重绘线程进行重绘的时候,它会把裁剪区域设置成需要重绘的窗口的区域。

8.事件监听器接口(event-listener interface)和事件适配器(event-adapter)有什么关系?

事件监听器接口定义了对特定的事件,事件处理器必须要实现的方法。事件适配器给事件监听器接口提供了默认的实现。

9.GUI组件如何来处理它自己的事件?

GUI组件可以处理它自己的事件,只要它实现相对应的事件监听器接口,并且把自己作为事件监听器。

10.Java的布局管理器比传统的窗口系统有哪些优势?

Java使用布局管理器以一种一致的方式在所有的窗口平台上摆放组件。因为布局管理器不会和组件的绝对大小和位置相绑定,所以他们能够适应跨窗口系统的特定平台的不同。

11.Java的Swing组件使用了哪种设计模式? 

12.弹出式选择菜单(Choice)和列表(List)有什么区别?

Choice是以一种紧凑的形式展示的,需要下拉才能看到所有的选项。Choice中一次只能选中一个选项。List同时可以有多个元素可见,支持选中一个或者多个元素。

13.什么是布局管理器?

布局管理器用来在容器中组织组件。

14.滚动条(Scrollbar)和滚动面板(JScrollPane)有什么区别?

Scrollbar是一个组件,不是容器。而ScrollPane是容器。ScrollPane自己处理滚动事件。

15.哪些Swing的方法是线程安全的?

只有3个线程安全的方法: repaint(), revalidate(), and invalidate()。

JDBC

1.什么是JDBC?

JDBC是允许用户在不同数据库之间做选择的一个抽象层。JDBC允许开发者用JAVA写数据库应用程序,而不需要关心底层特定数据库的细节。

2.解释下驱动(Driver)在JDBC中的角色。

JDBC驱动提供了特定厂商对JDBC API接口类的实现,驱动必须要提供java.sql包下面这些类的实现:Connection, Statement, PreparedStatement,CallableStatement, ResultSet和Driver。

3.Class.forName()方法有什么作用?

这个方法用来载入跟数据库建立连接的驱动。

4.PreparedStatement比Statement有什么优势?

PreparedStatements是预编译的,因此,性能会更好。同时,不同的查询参数值,PreparedStatement可以重用。

5.什么时候使用CallableStatement?用来准备CallableStatement的方法是什么?

CallableStatement用来执行存储过程。存储过程是由数据库存储和提供的。存储过程可以接受输入参数,也可以有返回结果。非常鼓励使用存储过程,因为它提供了安全性和模块化。准备一个CallableStatement的方法是:CallableStament.prepareCall();

6.数据库连接池是什么意思?

像打开关闭数据库连接这种和数据库的交互可能是很费时的,尤其是当客户端数量增加的时候,会消耗大量的资源,成本是非常高的。可以在应用服务器启动的时候建立很多个数据库连接并维护在一个池中。连接请求由池中的连接提供。在连接使用完毕以后,把连接归还到池中,以用于满足将来更多的请求。

远程方法调用(RMI)

1.RMI中的远程接口(Remote Interface)扮演了什么样的角色?

远程接口用来标识哪些方法是可以被非本地虚拟机调用的接口。远程对象必须要直接或者是间接实现远程接口。实现了远程接口的类应该声明被实现的远程接口,给每一个远程对象定义构造函数,给所有远程接口的方法提供实现。

2.java.rmi.Naming类扮演了什么样的角色?

java.rmi.Naming类用来存储和获取在远程对象注册表里面的远程对象的引用。Naming类的每一个方法接收一个URL格式的String对象作为它的参数。

3.RMI的绑定(Binding)是什么意思?

绑定是为了查询找远程对象而给远程对象关联或者是注册以后会用到的名称的过程。远程对象可以使用Naming类的bind()或者rebind()方法跟名称相关联。

4.Naming类的bind()和rebind()方法有什么区别?

bind()方法负责把指定名称绑定给远程对象,rebind()方法负责把指定名称重新绑定到一个新的远程对象。如果那个名称已经绑定过了,先前的绑定会被替换掉。

5.让RMI程序能正确运行有哪些步骤?

为了让RMI程序能正确运行必须要包含以下几个步骤:

编译所有的源文件。 6.RMI的stub扮演了什么样的角色?

远程对象的stub扮演了远程对象的代表或者代理的角色。调用者在本地stub上调用方法,它负责在远程对象上执行方法。当stub的方法被调用的时候,会经历以下几个步骤:

初始化到包含了远程对象的JVM的连接。 

7.什么是分布式垃圾回收(DGC)?它是如何工作的?

DGC叫做分布式垃圾回收。RMI使用DGC来做自动垃圾回收。因为RMI包含了跨虚拟机的远程对象的引用,垃圾回收是很困难的。DGC使用引用计数算法来给远程对象提供自动内存管理。

8.RMI中使用RMI安全管理器(RMISecurityManager)的目的是什么?

RMISecurityManager使用下载好的代码提供可被RMI应用程序使用的安全管理器。如果没有设置安全管理器,RMI的类加载器就不会从远程下载任何的类。

9.解释下Marshalling和demarshalling。

当应用程序希望把内存对象跨网络传递到另一台主机或者是持久化到存储的时候,就必须要把对象在内存里面的表示转化成合适的格式。这个过程就叫做Marshalling,反之就是demarshalling。

10.解释下Serialization和Deserialization。

Java提供了一种叫做对象序列化的机制,他把对象表示成一连串的字节,里面包含了对象的数据,对象的类型信息,对象内部的数据的类型信息等等。因此,序列化可以看成是为了把对象存储在磁盘上或者是从磁盘上读出来并重建对象而把对象扁平化的一种方式。反序列化是把对象从扁平状态转化成活动对象的相反的步骤。

11.什么是RMI?

Java远程方法调用(Java RMI)是Java API对远程过程调用(RPC)提供的面向对象的等价形式,支持直接传输序列化的Java对象和分布式垃圾回收。远程方法调用可以看做是激活远程正在运行的对象上的方法的步骤。RMI对调用者是位置透明的,因为调用者感觉方法是执行在本地运行的对象上的。看下RMI的一些注意事项。

12.RMI体系结构的基本原则是什么?

RMI体系结构是基于一个非常重要的行为定义和行为实现相分离的原则。RMI允许定义行为的代码和实现行为的代码相分离,并且运行在不同的JVM上。

13.RMI体系结构分哪几层?

RMI体系结构分以下几层:

存根和骨架层(Stub and Skeleton layer):这一层对程序员是透明的,它主要负责拦截客户端发出的方法调用请求,然后把请求重定向给远程的RMI服务。

远程引用层(Remote Reference Layer):RMI体系结构的第二层用来解析客户端对服务端远程对象的引用。这一层解析并管理客户端对服务端远程对象的引用。连接是点到点的。

传输层(Transport layer):这一层负责连接参与服务的两个JVM。这一层是建立在网络上机器间的TCP/IP连接之上的。它提供了基本的连接服务,还有一些防火墙穿透策略。

Servlet

1.什么是Servlet?

Servlet是用来处理客户端请求并产生动态网页内容的Java类。Servlet主要是用来处理或者是存储HTML表单提交的数据,产生动态内容,在无状态的HTTP协议下管理状态信息。

2.说一下Servlet的体系结构。

所有的Servlet都必须要实现的核心的接口是javax.servlet.Servlet。每一个Servlet都必须要直接或者是间接实现这个接口,或者是继承javax.servlet.GenericServlet或者javax.servlet.http.HTTPServlet。最后,Servlet使用多线程可以并行的为多个请求服务。

3.Applet和Servlet有什么区别?

Applet是运行在客户端主机的浏览器上的客户端Java程序。而Servlet是运行在web服务器上的服务端的组件。applet可以使用用户界面类,而Servlet没有用户界面,相反,Servlet是等待客户端的HTTP请求,然后为请求产生响应。

4.GenericServlet和HttpServlet有什么区别?

GenericServlet是一个通用的协议无关的Servlet,它实现了Servlet和ServletConfig接口。继承自GenericServlet的Servlet应该要覆盖service()方法。最后,为了开发一个能用在网页上服务于使用HTTP协议请求的Servlet,你的Servlet必须要继承自HttpServlet。这里有Servlet的例子。

5.解释下Servlet的生命周期。

对每一个客户端的请求,Servlet引擎载入Servlet,调用它的init()方法,完成Servlet的初始化。然后,Servlet对象通过为每一个请求单独调用service()方法来处理所有随后来自客户端的请求,最后,调用Servlet(译者注:这里应该是Servlet而不是server)的destroy()方法把Servlet删除掉。

6.doGet()方法和doPost()方法有什么区别?

doGet:GET方法会把名值对追加在请求的URL后面。因为URL对字符数目有限制,进而限制了用在客户端请求的参数值的数目。并且请求中的参数值是可见的,因此,敏感信息不能用这种方式传递。

doPOST:POST方法通过把请求参数值放在请求体中来克服GET方法的限制,因此,可以发送的参数的数目是没有限制的。最后,通过POST请求传递的敏感信息对外部客户端是不可见的。

7.什么是Web应用程序?

Web应用程序是对Web或者是应用服务器的动态扩展。有两种类型的Web应用:面向表现的和面向服务的。面向表现的Web应用程序会产生包含了很多种标记语言和动态内容的交互的web页面作为对请求的响应。而面向服务的Web应用实现了Web服务的端点(endpoint)。一般来说,一个Web应用可以看成是一组安装在服务器URL名称空间的特定子集下面的Servlet的集合。

8.什么是服务端包含(Server Side Include)?

服务端包含(SSI)是一种简单的解释型服务端脚本语言,大多数时候仅用在Web上,用servlet标签嵌入进来。SSI最常用的场景把一个或多个文件包含到Web服务器的一个Web页面中。当浏览器访问Web页面的时候,Web服务器会用对应的servlet产生的文本来替换Web页面中的servlet标签。

9.什么是Servlet链(Servlet Chaining)?

Servlet链是把一个Servlet的输出发送给另一个Servlet的方法。第二个Servlet的输出可以发送给第三个Servlet,依次类推。链条上最后一个Servlet负责把响应发送给客户端。

10.如何知道是哪一个客户端的机器正在请求你的Servlet?

ServletRequest类可以找出客户端机器的IP地址或者是主机名。getRemoteAddr()方法获取客户端主机的IP地址,getRemoteHost()可以获取主机名。看下这里的例子。

11.HTTP响应的结构是怎么样的?

HTTP响应由三个部分组成:

状态码(Status Code):描述了响应的状态。可以用来检查是否成功的完成了请求。请求失败的情况下,状态码可用来找出失败的原因。如果Servlet没有返回状态码,默认会返回成功的状态码HttpServletResponse.SC_OK。

HTTP头部(HTTP Header):它们包含了更多关于响应的信息。比如:头部可以指定认为响应过期的过期日期,或者是指定用来给用户安全的传输实体内容的编码格式。如何在Serlet中检索HTTP的头部看这里。

主体(Body):它包含了响应的内容。它可以包含HTML代码,图片,等等。主体是由传输在HTTP消息中紧跟在头部后面的数据字节组成的。

12.什么是cookie?session和cookie有什么区别?

cookie是Web服务器发送给浏览器的一块信息。浏览器会在本地文件中给每一个Web服务器存储cookie。以后浏览器在给特定的Web服务器发请求的时候,同时会发送所有为该服务器存储的cookie。下面列出了session和cookie的区别:

无论客户端浏览器做怎么样的设置,session都应该能正常工作。客户端可以选择禁用cookie,但是,session仍然是能够工作的,因为客户端无法禁用服务端的session。

在存储的数据量方面session和cookies也是不一样的。session能够存储任意的Java对象,cookie只能存储String类型的对象。

13.浏览器和Servlet通信使用的是什么协议?

浏览器和Servlet通信使用的是HTTP协议。

14.什么是HTTP隧道?

HTTP隧道是一种利用HTTP或者是HTTPS把多种网络协议封装起来进行通信的技术。因此,HTTP协议扮演了一个打通用于通信的网络协议的管道的包装器的角色。把其他协议的请求掩盖成HTTP的请求就是HTTP隧道。

15.sendRedirect()和forward()方法有什么区别?

sendRedirect()方法会创建一个新的请求,而forward()方法只是把请求转发到一个新的目标上。重定向(redirect)以后,之前请求作用域范围以内的对象就失效了,因为会产生一个新的请求,而转发(forwarding)以后,之前请求作用域范围以内的对象还是能访问的。一般认为sendRedirect()比forward()要慢。

16.什么是URL编码和URL解码?

URL编码是负责把URL里面的空格和其他的特殊字符替换成对应的十六进制表示,反之就是解码。

JSP

1.什么是JSP页面?

JSP页面是一种包含了静态数据和JSP元素两种类型的文本的文本文档。静态数据可以用任何基于文本的格式来表示,比如:HTML或者XML。JSP是一种混合了静态内容和动态产生的内容的技术。这里看下JSP的例子。

2.JSP请求是如何被处理的?

浏览器首先要请求一个以.jsp扩展名结尾的页面,发起JSP请求,然后,Web服务器读取这个请求,使用JSP编译器把JSP页面转化成一个Servlet类。需要注意的是,只有当第一次请求页面或者是JSP文件发生改变的时候JSP文件才会被编译,然后服务器调用servlet类,处理浏览器的请求。一旦请求执行结束,servlet会把响应发送给客户端。这里看下如何在JSP中获取请求参数。

3.JSP有什么优点?

下面列出了使用JSP的优点:

JSP页面是被动态编译成Servlet的,因此,开发者可以很容易的更新展现代码。 

4.什么是JSP指令(Directive)?JSP中有哪些不同类型的指令?

Directive是当JSP页面被编译成Servlet的时候,JSP引擎要处理的指令。Directive用来设置页面级别的指令,从外部文件插入数据,指定自定义的标签库。Directive是定义在<%@ 和 %>之间的。下面列出了不同类型的Directive:

包含指令(Include directive):用来包含文件和合并文件内容到当前的页面。 

5.什么是JSP动作(JSP action)?

JSP动作以XML语法的结构来控制Servlet引擎的行为。当JSP页面被请求的时候,JSP动作会被执行。它们可以被动态的插入到文件中,重用JavaBean组件,转发用户到其他的页面,或者是给Java插件产生HTML代码。下面列出了可用的动作:

jsp:include-当JSP页面被请求的时候包含一个文件。 

6.什么是Scriptlets?

JSP技术中,scriptlet是嵌入在JSP页面中的一段Java代码。scriptlet是位于标签内部的所有的东西,在标签与标签之间,用户可以添加任意有效的scriplet。

7.声明(Decalaration)在哪里?

声明跟Java中的变量声明很相似,它用来声明随后要被表达式或者scriptlet使用的变量。添加的声明必须要用开始和结束标签包起来。

8.什么是表达式(Expression)?

JSP表达式是Web服务器把脚本语言表达式的值转化成一个String对象,插入到返回给客户端的数据流中。表达式是在<%=和%>这两个标签之间定义的。

9.隐含对象是什么意思?有哪些隐含对象?

JSP隐含对象是页面中的一些Java对象,JSP容器让这些Java对象可以为开发者所使用。开发者不用明确的声明就可以直接使用他们。JSP隐含对象也叫做预定义变量。下面列出了JSP页面中的隐含对象:

application 

如若有错,欢迎留言指正,我会及时更正,不会错误性的误导他人,方便大家学习,谢谢!!!

版权声明:本文为博主原创文章,未经博主允许不得转载。转载请注明出处:http://blog.csdn.net/wenteryan http://blog.csdn.net/wenteryan/article/details/51203107


zookeeper常见面试题

zookeeper是如何保证事务的顺序一致性的
zookeeper采用了递增的事务Id来标识,所有的proposal都在被提出的时候加上了zxid,zxid实际上是一个64位的数字,高32位是epoch用来标识leader是否发生改变,如果有新的leader产生出来,epoch会自增,低32位用来递增计数。当新产生proposal的时候,会依据数据库的两阶段过程,首先会向其他的server发出事务执行请求,如果超过半数的机器都能执行并且能够成功,那么就会开始执行
zookeeper是如何选取主leader的?
当leader崩溃或者leader失去大多数的follower,这时zk进入恢复模式,
zk中znode类型有四种,持久化目录节点 持久化顺序编号目录节点(有顺序 能够在注册机器等许多场景用到) 临时目录节点 临时顺序编号节点 
zk的通知机制
client端会对某个znode建立一个watcher事件,当该znode发生变化时,这些client会收到zk的通知,然后client可以根据znode变化来做出业务上的改变等。
zk的配置管理
程序分布式的部署在不同的机器上,将程序的配置信息放在zk的znode下,当有配置发生改变时,也就是znode发生变化时,可以通过改变zk中某个目录节点的内容,利用water通知给各个客户端 从而更改配置。
zk的命名服务
命名服务是指通过指定的名字来获取资源或者服务的地址,利用zk创建一个全局的路径,这个路径就可以作为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。
分布式通知和协调
对于系统调度来说:操作人员发送通知实际是通过控制台改变某个节点的状态,然后zk将这些变化发送给注册了这个节点的watcher的所有客户端。
对于执行情况汇报:每个工作进程都在某个目录下创建一个临时节点。并携带工作的进度数据,这样汇总的进程可以监控目录子节点的变化获得工作进度的实时的全局情况。
机器中为什么会有master;

在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果,这样可以大大减少重复计算,提高性能,于是就需要进行master选举。

JAVA多线程和并发基础面试题

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:非常赞同这个观点

Java多线程面试问题

1. 进程和线程之间有什么不同?

一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序的单一进程。线程可以被称为轻量级进程。线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源。

2. 多线程编程的好处是什么?

在多线程程序中,多个线程被并发的执行以提高程序的效率,CPU不会因为某个线程需要等待资源而进入空闲状态。多个线程共享堆内存(heap memory),因此创建多个线程去执行一些任务会比创建多个进程更好。举个例子,Servlets比CGI更好,是因为Servlets支持多线程而CGI不支持。

3. 用户线程和守护线程有什么区别?

当我们在Java程序中创建一个线程,它就被称为用户线程。一个守护线程是在后台执行并且不会阻止JVM终止的线程。当没有用户线程在运行的时候,JVM关闭程序并且退出。一个守护线程创建的子线程依然是守护线程。

4. 我们如何创建一个线程?

有两种创建线程的方法:一是实现Runnable接口,然后将它传递给Thread的构造函数,创建一个Thread对象;二是直接继承Thread类。若想了解更多可以阅读这篇关于如何在Java中创建线程的文章。

5. 有哪些不同的线程生命周期?

当我们在Java程序中新建一个线程时,它的状态是New。当我们调用线程的start()方法时,状态被改变为Runnable。线程调度器会为Runnable线程池中的线程分配CPU时间并且讲它们的状态改变为Running。其他的线程状态还有Waiting,Blocked 和Dead。读这篇文章可以了解更多关于线程生命周期的知识。

6. 可以直接调用Thread类的run()方法么?

当然可以,但是如果我们调用了Thread的run()方法,它的行为就会和普通的方法一样,为了在新的线程中执行我们的代码,必须使用Thread.start()方法。

7. 如何让正在运行的线程暂停一段时间?

我们可以使用Thread类的Sleep()方法让线程暂停一段时间。需要注意的是,这并不会让线程终止,一旦从休眠中唤醒线程,线程的状态将会被改变为Runnable,并且根据线程调度,它将得到执行。

8. 你对线程优先级的理解是什么?

每一个线程都是有优先级的,一般来说,高优先级的线程在运行时会具有优先权,但这依赖于线程调度的实现,这个实现是和操作系统相关的(OS dependent)。我们可以定义线程的优先级,但是这并不能保证高优先级的线程会在低优先级的线程前执行。线程优先级是一个int变量(从1-10),1代表最低优先级,10代表最高优先级。

9. 什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?

线程调度器是一个操作系统服务,它负责为Runnable状态的线程分配CPU时间。一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现。时间分片是指将可用的CPU时间分配给可用的Runnable线程的过程。分配CPU时间可以基于线程优先级或者线程等待的时间。线程调度并不受到Java虚拟机控制,所以由应用程序来控制它是更好的选择(也就是说不要让你的程序依赖于线程的优先级)。

10. 在多线程中,什么是上下文切换(context-switching)?

上下文切换是存储和恢复CPU状态的过程,它使得线程执行能够从中断点恢复执行。上下文切换是多任务操作系统和多线程环境的基本特征。

11. 你如何确保main()方法所在的线程是Java程序最后结束的线程?

我们可以使用Thread类的joint()方法来确保所有程序创建的线程在main()方法退出前结束。这里有一篇文章关于Thread类的joint()方法。

12.线程之间是如何通信的?

当线程间是可以共享资源时,线程间通信是协调它们的重要的手段。Object类中wait()notify()notifyAll()方法可以用于线程间通信关于资源的锁的状态。点击这里有更多关于线程wait, notify和notifyAll.

13.为什么线程通信的方法wait(), notify()和notifyAll()被定义在Object类里?

Java的每个对象中都有一个锁(monitor,也可以成为监视器) 并且wait(),notify()等方法用于等待对象的锁或者通知其他线程对象的监视器可用。在Java的线程中并没有可供任何对象使用的锁和同步器。这就是为什么这些方法是Object类的一部分,这样Java的每一个类都有用于线程间通信的基本方法

14. 为什么wait(), notify()和notifyAll()必须在同步方法或者同步块中被调用?

当一个线程需要调用对象的wait()方法的时候,这个线程必须拥有该对象的锁,接着它就会释放这个对象锁并进入等待状态直到其他线程调用这个对象上的notify()方法。同样的,当一个线程需要调用对象的notify()方法时,它会释放这个对象的锁,以便其他在等待的线程就可以得到这个对象锁。由于所有的这些方法都需要线程持有对象的锁,这样就只能通过同步来实现,所以他们只能在同步方法或者同步块中被调用。

15. 为什么Thread类的sleep()和yield()方法是静态的?

Thread类的sleep()和yield()方法将在当前正在执行的线程上运行。所以在其他处于等待状态的线程上调用这些方法是没有意义的。这就是为什么这些方法是静态的。它们可以在当前正在执行的线程中工作,并避免程序员错误的认为可以在其他非运行线程调用这些方法。

16.如何确保线程安全?

在Java中可以有很多方法来保证线程安全——同步,使用原子类(atomic concurrent classes),实现并发锁,使用volatile关键字,使用不变类和线程安全类。在线程安全教程中,你可以学到更多。

17. volatile关键字在Java中有什么作用?

当我们使用volatile关键字去修饰变量的时候,所以线程都会直接读取该变量并且不缓存它。这就确保了线程读取到的变量是同内存中是一致的。

18. 同步方法和同步块,哪个是更好的选择?

同步块是更好的选择,因为它不会锁住整个对象(当然你也可以让它锁住整个对象)。同步方法会锁住整个对象,哪怕这个类中有多个不相关联的同步块,这通常会导致他们停止执行并需要等待获得这个对象上的锁。

19.如何创建守护线程?

使用Thread类的setDaemon(true)方法可以将线程设置为守护线程,需要注意的是,需要在调用start()方法前调用这个方法,否则会抛出IllegalThreadStateException异常。

20. 什么是ThreadLocal?

ThreadLocal用于创建线程的本地变量,我们知道一个对象的所有线程会共享它的全局变量,所以这些变量不是线程安全的,我们可以使用同步技术。但是当我们不想使用同步的时候,我们可以选择ThreadLocal变量。

每个线程都会拥有他们自己的Thread变量,它们可以使用get()set()方法去获取他们的默认值或者在线程内部改变他们的值。ThreadLocal实例通常是希望它们同线程状态关联起来是private static属性。在ThreadLocal例子这篇文章中你可以看到一个关于ThreadLocal的小程序。

21. 什么是Thread Group?为什么建议使用它?

ThreadGroup是一个类,它的目的是提供关于线程组的信息。

ThreadGroup API比较薄弱,它并没有比Thread提供了更多的功能。它有两个主要的功能:一是获取线程组中处于活跃状态线程的列表;二是设置为线程设置未捕获异常处理器(ncaught exception handler)。但在Java 1.5中Thread类也添加了setUncaughtExceptionHandler(UncaughtExceptionHandler eh) 方法,所以ThreadGroup是已经过时的,不建议继续使用。

 

22. 什么是Java线程转储(Thread Dump),如何得到它?

线程转储是一个JVM活动线程的列表,它对于分析系统瓶颈和死锁非常有用。有很多方法可以获取线程转储——使用Profiler,Kill -3命令,jstack工具等等。我更喜欢jstack工具,因为它容易使用并且是JDK自带的。由于它是一个基于终端的工具,所以我们可以编写一些脚本去定时的产生线程转储以待分析。读这篇文档可以了解更多关于产生线程转储的知识。

23. 什么是死锁(Deadlock)?如何分析和避免死锁?

死锁是指两个以上的线程永远阻塞的情况,这种情况产生至少需要两个以上的线程和两个以上的资源。

分析死锁,我们需要查看Java应用程序的线程转储。我们需要找出那些状态为BLOCKED的线程和他们等待的资源。每个资源都有一个唯一的id,用这个id我们可以找出哪些线程已经拥有了它的对象锁。

避免嵌套锁,只在需要的地方使用锁和避免无限期等待是避免死锁的通常办法,阅读这篇文章去学习如何分析死锁。

24. 什么是Java Timer类?如何创建一个有特定时间间隔的任务?

java.util.Timer是一个工具类,可以用于安排一个线程在未来的某个特定时间执行。Timer类可以用安排一次性任务或者周期任务。

java.util.TimerTask是一个实现了Runnable接口的抽象类,我们需要去继承这个类来创建我们自己的定时任务并使用Timer去安排它的执行。

这里有关于java Timer的例子。

25. 什么是线程池?如何创建一个Java线程池?

一个线程池管理了一组工作线程,同时它还包括了一个用于放置等待执行的任务的队列。

java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池。线程池例子展现了如何创建和使用线程池,或者阅读ScheduledThreadPoolExecutor例子,了解如何创建一个周期任务。

Java并发面试问题

1. 什么是原子操作?在Java Concurrency API中有哪些原子类(atomic classes)?

原子操作是指一个不受其他操作影响的操作任务单元。原子操作是在多线程环境下避免数据不一致必须的手段。

int++并不是一个原子操作,所以当一个线程读取它的值并加1时,另外一个线程有可能会读到之前的值,这就会引发错误。

为了解决这个问题,必须保证增加操作是原子的,在JDK1.5之前我们可以使用同步技术来做到这一点。到JDK1.5,java.util.concurrent.atomic包提供了int和long类型的装类,它们可以自动的保证对于他们的操作是原子的并且不需要使用同步。可以阅读这篇文章来了解Java的atomic类。

2. Java Concurrency API中的Lock接口(Lock interface)是什么?对比同步它有什么优势?

Lock接口比同步方法和同步块提供了更具扩展性的锁操作。他们允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的条件对象。

它的优势有:

  • 可以使锁更公平
  • 可以使线程在等待锁的时候响应中断
  • 可以让线程尝试获取锁,并在无法获取锁的时候立即返回或者等待一段时间
  • 可以在不同的范围,以不同的顺序获取和释放锁

阅读更多关于锁的例子

3. 什么是Executors框架?

Executor框架同java.util.concurrent.Executor 接口在Java 5中被引入。Executor框架是一个根据一组执行策略调用,调度,执行和控制的异步任务的框架。

无限制的创建线程会引起应用程序内存溢出。所以创建一个线程池是个更好的的解决方案,因为可以限制线程的数量并且可以回收再利用这些线程。利用Executors框架可以非常方便的创建一个线程池,阅读这篇文章可以了解如何使用Executor框架创建一个线程池。

4. 什么是阻塞队列?如何使用阻塞队列来实现生产者-消费者模型?

java.util.concurrent.BlockingQueue的特性是:当队列是空的时,从队列中获取或删除元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。

阻塞队列不接受空值,当你尝试向队列中添加空值的时候,它会抛出NullPointerException。

阻塞队列的实现都是线程安全的,所有的查询方法都是原子的并且使用了内部锁或者其他形式的并发控制。

BlockingQueue 接口是java collections框架的一部分,它主要用于实现生产者-消费者问题。

阅读这篇文章了解如何使用阻塞队列实现生产者-消费者问题。

5. 什么是Callable和Future?

Java 5在concurrency包中引入了java.util.concurrent.Callable 接口,它和Runnable接口很相似,但它可以返回一个对象或者抛出一个异常。

Callable接口使用泛型去定义它的返回类型。Executors类提供了一些有用的方法去在线程池中执行Callable内的任务。由于Callable任务是并行的,我们必须等待它返回的结果。java.util.concurrent.Future对象为我们解决了这个问题。在线程池提交Callable任务后返回了一个Future对象,使用它我们可以知道Callable任务的状态和得到Callable返回的执行结果。Future提供了get()方法让我们可以等待Callable结束并获取它的执行结果。

阅读这篇文章了解更多关于Callable,Future的例子。

6. 什么是FutureTask?

FutureTask是Future的一个基础实现,我们可以将它同Executors使用处理异步任务。通常我们不需要使用FutureTask类,单当我们打算重写Future接口的一些方法并保持原来基础的实现是,它就变得非常有用。我们可以仅仅继承于它并重写我们需要的方法。阅读Java FutureTask例子,学习如何使用它。

7.什么是并发容器的实现?

Java集合类都是快速失败的,这就意味着当集合被改变且一个线程在使用迭代器遍历集合的时候,迭代器的next()方法将抛出ConcurrentModificationException异常。

并发容器支持并发的遍历和并发的更新。

主要的类有ConcurrentHashMap, CopyOnWriteArrayList 和CopyOnWriteArraySet,阅读这篇文章了解如何避免ConcurrentModificationException。

8. Executors类是什么?

Executors为Executor,ExecutorService,ScheduledExecutorService,ThreadFactory和Callable类提供了一些工具方法。

Executors可以用于方便的创建线程池。

很多核心Java面试题来源于多线程(Multi-Threading)和集合框架(Collections Framework),理解核心线程概念时,娴熟的实际经验是必需的。这篇文章收集了 Java 线程方面一些典型的问题,这些问题经常被高级工程师所问到。

0.Java 中多线程同步是什么?

在多线程程序下,同步能控制对共享资源的访问。如果没有同步,当一个 Java 线程在修改一个共享变量时,另外一个线程正在使用或者更新同一个变量,这样容易导致程序出现错误的结果。

1.解释实现多线程的几种方法?

一 Java 线程可以实现 Runnable 接口或者继承 Thread 类来实现,当你打算多重继承时,优先选择实现 Runnable。

2.Thread.start ()与 Thread.run ()有什么区别?

Thread.start ()方法(native)启动线程,使之进入就绪状态,当 cpu 分配时间该线程时,由 JVM 调度执行 run ()方法。

3.为什么需要 run ()和 start ()方法,我们可以只用 run ()方法来完成任务吗?

我们需要 run ()&start ()这两个方法是因为 JVM 创建一个单独的线程不同于普通方法的调用,所以这项工作由线程的 start 方法来完成,start 由本地方法实现,需要显示地被调用,使用这俩个方法的另外一个好处是任何一个对象都可以作为线程运行,只要实现了 Runnable 接口,这就避免因继承了 Thread 类而造成的 Java 的多继承问题。

4.什么是 ThreadLocal 类,怎么使用它?

ThreadLocal 是一个线程级别的局部变量,并非“本地线程”。ThreadLocal 为每个使用该变量的线程提供了一个独立的变量副本,每个线程修改副本时不影响其它线程对象的副本(译者注)。

下面是线程局部变量(ThreadLocal variables)的关键点:

一个线程局部变量(ThreadLocal variables)为每个线程方便地提供了一个单独的变量。

ThreadLocal 实例通常作为静态的私有的(private static)字段出现在一个类中,这个类用来关联一个线程。

当多个线程访问 ThreadLocal 实例时,每个线程维护 ThreadLocal 提供的独立的变量副本。

常用的使用可在 DAO 模式中见到,当 DAO 类作为一个单例类时,数据库链接(connection)被每一个线程独立的维护,互不影响。(基于线程的单例)

ThreadLocal 难于理解,下面这些引用连接有助于你更好的理解它。

《Good article on ThreadLocal on IBM DeveloperWorks 》、《理解 ThreadLocal》、《Managing data : Good example》、《Refer Java API Docs》

5.什么时候抛出 InvalidMonitorStateException 异常,为什么?

调用 wait ()/notify ()/notifyAll ()中的任何一个方法时,如果当前线程没有获得该对象的锁,那么就会抛出 IllegalMonitorStateException 的异常(也就是说程序在没有执行对象的任何同步块或者同步方法时,仍然尝试调用 wait ()/notify ()/notifyAll ()时)。由于该异常是 RuntimeExcpetion 的子类,所以该异常不一定要捕获(尽管你可以捕获只要你愿意).作为 RuntimeException,此类异常不会在 wait (),notify (),notifyAll ()的方法签名提及。

6.Sleep ()、suspend ()和 wait ()之间有什么区别?

Thread.sleep ()使当前线程在指定的时间处于“非运行”(Not Runnable)状态。线程一直持有对象的监视器。比如一个线程当前在一个同步块或同步方法中,其它线程不能进入该块或方法中。如果另一线程调用了 interrupt ()方法,它将唤醒那个“睡眠的”线程。

注意:sleep ()是一个静态方法。这意味着只对当前线程有效,一个常见的错误是调用t.sleep (),(这里的t是一个不同于当前线程的线程)。即便是执行t.sleep (),也是当前线程进入睡眠,而不是t线程。t.suspend ()是过时的方法,使用 suspend ()导致线程进入停滞状态,该线程会一直持有对象的监视器,suspend ()容易引起死锁问题。

object.wait ()使当前线程出于“不可运行”状态,和 sleep ()不同的是 wait 是 object 的方法而不是 thread。调用 object.wait ()时,线程先要获取这个对象的对象锁,当前线程必须在锁对象保持同步,把当前线程添加到等待队列中,随后另一线程可以同步同一个对象锁来调用 object.notify (),这样将唤醒原来等待中的线程,然后释放该锁。基本上 wait ()/notify ()与 sleep ()/interrupt ()类似,只是前者需要获取对象锁。

7.在静态方法上使用同步时会发生什么事?

同步静态方法时会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。

8.当一个同步方法已经执行,线程能够调用对象上的非同步实例方法吗?

可以,一个非同步方法总是可以被调用而不会有任何问题。实际上,Java 没有为非同步方法做任何检查,锁对象仅仅在同步方法或者同步代码块中检查。如果一个方法没有声明为同步,即使你在使用共享数据 Java 照样会调用,而不会做检查是否安全,所以在这种情况下要特别小心。一个方法是否声明为同步取决于临界区访问(critial section access),如果方法不访问临界区(共享资源或者数据结构)就没必要声明为同步的。

下面有一个示例说明:Common 类有两个方法 synchronizedMethod1()和 method1(),MyThread 类在独立的线程中调用这两个方法。


  1. public class Common {  
  2.    
  3. public synchronized void synchronizedMethod1() {  
  4. System.out.println ("synchronizedMethod1 called");  
  5. try {  
  6. Thread.sleep (1000);  
  7. } catch (InterruptedException e) {  
  8. e.printStackTrace ();  
  9. }  
  10. System.out.println ("synchronizedMethod1 done");  
  11. }  
  12. public void method1() {  
  13. System.out.println ("Method 1 called");  
  14. try {  
  15. Thread.sleep (1000);  
  16. } catch (InterruptedException e) {  
  17. e.printStackTrace ();  
  18. }  
  19. System.out.println ("Method 1 done");  
  20. }  

  1. public class MyThread extends Thread {  
  2. private int id = 0;  
  3. private Common common;  
  4.    
  5. public MyThread (String name, int no, Common object) {  
  6. super(name);  
  7. common = object;  
  8. id = no;  
  9. }  
  10.    
  11. public void run () {  
  12. System.out.println ("Running Thread" + this.getName ());  
  13. try {  
  14. if (id == 0) {  
  15. common.synchronizedMethod1();  
  16. } else {  
  17. common.method1();  
  18. }  
  19. } catch (Exception e) {  
  20. e.printStackTrace ();  
  21. }  
  22. }  
  23.    
  24. public static void main (String[] args) {  
  25. Common c = new Common ();  
  26. MyThread t1 = new MyThread ("MyThread-1", 0, c);  
  27. MyThread t2 = new MyThread ("MyThread-2", 1, c);  
  28. t1.start ();  
  29. t2.start ();  
  30. }  
  31. }  

这里是程序的输出:


  1. Running ThreadMyThread-1  
  2. synchronizedMethod1 called  
  3. Running ThreadMyThread-2  
  4. Method 1 called  
  5. synchronizedMethod1 done  
  6. Method 1 done 

 

结果表明即使 synchronizedMethod1()方法执行了,method1()也会被调用。

9.在一个对象上两个线程可以调用两个不同的同步实例方法吗?

不能,因为一个对象已经同步了实例方法,线程获取了对象的对象锁。所以只有执行完该方法释放对象锁后才能执行其它同步方法。看下面代码示例非常清晰:Common 类有 synchronizedMethod1()和 synchronizedMethod2()方法,MyThread 调用这两个方法。


  1. public class Common {  
  2. public synchronized void synchronizedMethod1() {  
  3. System.out.println ("synchronizedMethod1 called");  
  4. try {  
  5. Thread.sleep (1000);  
  6. } catch (InterruptedException e) {  
  7. e.printStackTrace ();  
  8. }  
  9. System.out.println ("synchronizedMethod1 done");  
  10. }  
  11.    
  12. public synchronized void synchronizedMethod2() {  
  13. System.out.println ("synchronizedMethod2 called");  
  14. try {  
  15. Thread.sleep (1000);  
  16. } catch (InterruptedException e) {  
  17. e.printStackTrace ();  
  18. }  
  19. System.out.println ("synchronizedMethod2 done");  
  20. }  

  1. public class MyThread extends Thread {  
  2. private int id = 0;  
  3. private Common common;  
  4.    
  5. public MyThread (String name, int no, Common object) {  
  6. super(name);  
  7. common = object;  
  8. id = no;  
  9. }  
  10.    
  11. public void run () {  
  12. System.out.println ("Running Thread" + this.getName ());  
  13. try {  
  14. if (id == 0) {  
  15. common.synchronizedMethod1();  
  16. } else {  
  17. common.synchronizedMethod2();  
  18. }  
  19. } catch (Exception e) {  
  20. e.printStackTrace ();  
  21. }  
  22. }  
  23.    
  24. public static void main (String[] args) {  
  25. Common c = new Common ();  
  26. MyThread t1 = new MyThread ("MyThread-1", 0, c);  
  27. MyThread t2 = new MyThread ("MyThread-2", 1, c);  
  28. t1.start ();  
  29. t2.start ();  
  30. }  

10.什么是死锁

死锁就是两个或两个以上的线程被无限的阻塞,线程之间相互等待所需资源。这种情况可能发生在当两个线程尝试获取其它资源的锁,而每个线程又陷入无限等待其它资源锁的释放,除非一个用户进程被终止。就 JavaAPI 而言,线程死锁可能发生在一下情况。

  • 当两个线程相互调用 Thread.join ()
  • 当两个线程使用嵌套的同步块,一个线程占用了另外一个线程必需的锁,互相等待时被阻塞就有可能出现死锁。

11.什么是线程饿死,什么是活锁?

线程饿死和活锁虽然不想是死锁一样的常见问题,但是对于并发编程的设计者来说就像一次邂逅一样。

当所有线程阻塞,或者由于需要的资源无效而不能处理,不存在非阻塞线程使资源可用。JavaAPI 中线程活锁可能发生在以下情形:

  • 当所有线程在程序中执行 Object.wait (0),参数为 0 的 wait 方法。程序将发生活锁直到在相应的对象上有线程调用 Object.notify ()或者 Object.notifyAll ()。
  • 当所有线程卡在无限循环中。
2017 最新java面试题(技术面试)

以下面试题为个人在面试过程中所遇到的,仅供参考!如有错误,望指出。

1、servlet执行流程

客户端发出http请求,web服务器将请求转发到servlet容器,servlet容器解析url并根据web.xml找到相对应的servlet,并将requestresponse对象传递给找到的servletservlet根据request就可以知道是谁发出的请求,请求信息及其他信息,当servlet处理完业务逻辑后会将信息放入到response并响应到客户端。

2、springMVC的执行流程

springMVC是由dispatchservlet为核心的分层控制框架。首先客户端发出一个请求web服务器解析请求url并去匹配dispatchservlet的映射url,如果匹配上就将这个请求放入到dispatchservletdispatchservlet根据mapping映射配置去寻找相对应的handel,然后把处理权交给找到的handelhandel封装了处理业务逻辑的代码,当handel处理完后会返回一个逻辑视图modelandviewdispatchservlet,此时的modelandview是一个逻辑视图不是一个正式视图,所以dispatchservlet会通过viewresource视图资源去解析modelandview,然后将解析后的参数放到view中返回到客户端并展现。

3、给定一个txt文件,如何得到某字符串出现的次数

File file = new File("E://test.txt");

InputStream is = new FileInputStream(file);

byte b[] = new byte[1024];

int a = is.read(b);

String str[] = new String(b,0,a).split("");

int count = 0;

for(int i = 0;i<str.length;i++){

if("a".equals(str[i]))count++;

}

System.out.println(count);

4、Java设计模式思想(单列模式,工厂模式,策略模式,共23种设计模式)

a) 单例模式:单例模式核心只需要new一个实例对象的模式,比如数据库连接,在线人数等,一些网站上看到的在线人数统计就是通过单例模式实现的,把一个计时器存放在数据库或者内存中,当有人登陆的时候取出来加一再放回去,有人退出登陆的时候取出来减一再放回去,但是当有两个人同时登陆的时候,会同时取出计数器,同时加一,同时放回去,这样的话数据就会错误,所以需要一个全局变量的对象给全部人使用,只需要new出一个实例对象,这就是单例模式的应用,并且单例模式节省资源,因为它控制了实例对象的个数,并有利于gc回收。

b) 策略模式:就是将几个类中公共的方法提取到一个新的类中,从而使扩展更容易,保证代码的可移植性,可维护性强。比如有个需求是写鸭子对象,鸭子有叫,飞,外形这三种方法,如果每个鸭子类都写这三个方法会出现代码的冗余,这时候我们可以把鸭子中的叫,飞,外形这三个方法提取出来,放到鸭父类中,让每个鸭子都继承这个鸭父类,重写这三个方法,这样封装的代码可移植性强,当用户提出新的需求比如鸭子会游泳,那么对于我们oo程序员来讲就非常简单了我们只需要在鸭父类中加一个游泳的方法,让会游泳的鸭子重写游泳方法就可以了。

c) 工厂模式:简单的工厂模式主要是统一提供实例对象的引用,通过工厂模式接口获取实例对象的引用。比如一个登陆功能,后端有三个类,controller类,interface类,实现接口的实现类。当客户端发出一个请求,当请求传到controller类中时,controller获取接口的引用对象,而实现接口的实现类中封装好了登陆的业务逻辑代码。当你需要加一个注册需求的时候只需要在接口类中加一个注册方法,实现类中实现方法,controller获取接口的引用对象即可,不需要改动原来的代码,这种做法是的可拓展性强。

5、冒泡排序、二分查找

a) 冒泡

  public static void mp(int a[]) {

 

int swap = 0;

for (int i = 0; i < a.lengthi++) {

 

for (int j = ij < a.lengthj++) {

if (a[j] > a[i]) {

swap = a[i];

a[i] = a[j];

a[j] = swap;

}

}

}

 

System.out.println(Arrays.toString(a));

}

 

b)二分查找public static int ef(int a[], int tag) {

 

int first = 0;

int end = a.length;

for (int i = 0; i < a.lengthi++) {

int middle = (first + end) / 2;

 

if (tag == a[middle]) {

return middle;

}

if (tag > a[middle]) {

first = middle + 1;

}

if (tag < a[middle]) {

end = middle - 1;

}

 

}

return 0;

}

6、ajax的理解

a) Ajax为异步请求,即局部刷新技术,在传统的页面中,用户需要点击按钮或者事件触发请求,到刷新页面,而异步技术为不需要点击即可触发事件,这样使得用户体验感增强,比如商城购物车的异步加载,当你点击商品时无需请求后台而直接动态修改参数。

9、父类与子类之间的调用顺序(打印结果)

a) 父类静态代码块

b) 子类静态代码块

c) 父类构造方法

d) 子类构造方法

e) 子类普通方法

f) 重写父类的方法,则打印重写后的方法

10、内部类与外部类的调用

a) 内部类可以直接调用外部类包括private的成员变量,使用外部类引用的this.关键字调用即可

b) 而外部类调用内部类需要建立内部类对象

11、多线程

a)一个进程是一个独立的运行环境,可以看做是一个程序,而线程可以看做是进程的一个任务,比如QQ是一个进程,而一个QQ窗口是一个线程。

b)在多线程程序中,多线程并发可以提高程序的效率,cpu不会因为某个线程等待资源而进入空闲状态,它会把资源让给其他的线程。

c)用户线程就是我们开发程序是创建的线程,而守护线程为系统线程,如JVM虚拟中的GC

d)线程的优先级别:每一个线程都有优先级别,有限级别高的可以先获取CPU资源使该线程从就绪状态转为运行状态。也可以自定义线程的有限级别

e)死锁:至少两个以上线程争取两个以上cpu资源,避免死锁就避免使用嵌套锁,只需要在他们需要同步的地方加锁和避免无限等待

12、AOPIOC的概念(即spring的核心)

a) IOCSpring是开源框架,使用框架可以使我们减少工作量,提高工作效率并且它是分层结构,即相对应的层处理对应的业务逻辑,减少代码的耦合度。而spring的核心是IOC控制反转和AOP面向切面编程。IOC控制反转主要强调的是程序之间的关系是由容器控制的,容器控制对象,控制了对外部资源的获取。而反转即为,在传统的编程中都是由我们创建对象获取依赖对象,而在IOC中是容器帮我们创建对象并注入依赖对象,正是容器帮我们查找和注入对象,对象是被获取,所以叫反转。

b) AOP:面向切面编程,主要是管理系统层的业务,比如日志,权限,事物等。AOP是将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为切面(aspect),切面将那些与业务逻辑无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

13、hibernate的核心思想

a) Hibernate的核心思想是ROM对象关系映射机制。它是将表与表之间的操作映射成对象与对象之间的操作。也就是从数据库中提取的信息会自动按照你设置的映射要求封装成特定的对象。所以hibernate就是通过将数据表实体类的映射,使得对对象的修改对应数据行的修改。

14、Struts1Struts2的区别

15、最优删除谋字符串的某个字符

16、Arraylistlinkedlist的区别

a) 都是实现list接口的列表,arraylist是基于数组的数据结构,linkedlist是基于链表的数据结构,当获取特定元素时,ArrayList效率比较快,它通过数组下标即可获取,而linkedlist则需要移动指针。当存储元素与删除元素时linkedlist效率较快,只需要将指针移动指定位置增加或者删除即可,而arraylist需要移动数据。

17、mybatiesibatise的区别

18、数据库优化

a) 选择合适的字段,比如邮箱字段可以设为char6),尽量把字段设置为notnull,这样查询的时候数据库就不需要比较null

b) 使用关联查询( left join on)查询代替子查询

c) 使用union联合查询手动创建临时表

d) 开启事物,当数据库执行多条语句出现错误时,事物会回滚,可以维护数据库的完整性

e) 使用外键,事物可以维护数据的完整性但是它却不能保证数据的关联性,使用外键可以保证数据的关联性

f) 使用索引,索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快的多的速度检索特定的行,特别是对于maxminorder by查询时,效果更明显

g) 优化的查询语句,绝大多数情况下,使用索引可以提高查询的速度,但如果sql语句使用不恰当的话,索引无法发挥它的特性。

19、Tomcat服务器优化(内存,并发连接数,缓存)

a) 内存优化:主要是对Tomcat启动参数进行优化,我们可以在Tomcat启动脚本中修改它的最大内存数等等。

b) 线程数优化:Tomcat的并发连接参数,主要在Tomcat配置文件中server.xml中配置,比如修改最小空闲连接线程数,用于提高系统处理性能等等。

c) 优化缓存:打开压缩功能,修改参数,比如压缩的输出内容大小默认为2KB,可以适当的修改。

20、HTTP协议

a) 常用的请求方法有getpost

b) Getpost的区别:传送数据,get携带参数与访问地址传送,用户可以看见,这的话信息会不安全,导致信息泄露。而post则将字段与对应值封装在实体中传送,这个过程用户是不可见的。Get传递参数有限制,而post无限制。

21、TCP/UDP协议

22、Java集合类框架的基本接口有哪些

a) Collection集合接口,Listset实现Collection接口,arraylistlinkedlistvector实现list接口,stack继承vectorMap接口,hashtablehashmap实现map接口

23、类加载的过程

a) 遇到一个新的类时,首先会到方法区去找class文件,如果没有找到就会去硬盘中找class文件,找到后会返回,将class文件加载到方法区中,在类加载的时候,静态成员变量会被分配到方法区的静态区域,非静态成员变量分配到非静态区域,然后开始给静态成员变量初始化,赋默认值,赋完默认值后,会根据静态成员变量书写的位置赋显示值,然后执行静态代码。当所有的静态代码执行完,类加载才算完成。

24、对象的创建

a) 遇到一个新类时,会进行类的加载,定位到class文件

b) 对所有静态成员变量初始化,静态代码块也会执行,而且只在类加载的时候执行一次

c) New 对象时,jvm会在堆中分配一个足够大的存储空间

d) 存储空间清空,为所有的变量赋默认值,所有的对象引用赋值为null

e) 根据书写的位置给字段一些初始化操作

f) 调用构造器方法(没有继承)

25、jvm的优化

a) 设置参数,设置jvm的最大内存数

b) 垃圾回收器的选择

26、高并发处理

a) 了解一点高并发性问题,比如一W人抢一张票时,如何保证票在没买走的情况下所有人都能看见这张票,显然是不能用同步机制,因为synchronize是锁同步一次只能一个人进行。这时候可以用到锁机制,采用乐观锁可以解决这个问题。乐观锁的简单意思是在不锁定表的情况下,利用业务的控制来解决并发问题,这样即保证数据的可读性,又保证保存数据的排他性,保证性能的同时解决了并发带来的脏读数据问题。

27、事物的理解

a) 事物具有原子性,一致性,持久性,隔离性

b) 原子性:是指在一个事物中,要么全部执行成功,要么全部失败回滚。

c) 一致性:事物执行之前和执行之后都处于一致性状态

d) 持久性:事物多数据的操作是永久性

e) 隔离性:当一个事物正在对数据进行操作时,另一个事物不可以对数据进行操作,也就是多个并发事物之间相互隔离。

28、Struts工作流程

a) 客户端发出一个请求到servlet容器

b) 请求经过一些列过滤被filterdispatcher调用,filterdispatch通过actionMapper去找相对应的action

c) Actionmapper找到对应的action返回给filterdispatchdispatch把处理权交给actionproxy

d) Actionproxy通过配置文件找到对应的action

e) Actionproxy创建一个actionIinvocation的实例处理业务逻辑

f) 一旦action处理完毕,actioninvocation负责根据stuts.xml的配置找到对应的返回结果。返回结果通常是jsp页面。

数据库面试题(开发者必看)

数据库常见面试题(开发者篇)

什么是存储过程?有哪些优缺点?

什么是存储过程?有哪些优缺点?

存储过程就像我们编程语言中的函数一样,封装了我们的代码(PLSQL、T-SQL)

存储过程的优点:

  • 能够将代码封装起来
  • 保存在数据库之中
  • 让编程语言进行调用
  • 存储过程是一个预编译的代码块,执行效率比较高
  • 一个存储过程替代大量T_SQL语句 ,可以降低网络通信量,提高通信速率

存储过程的缺点:

  • 每个数据库的存储过程语法几乎都不一样,十分难以维护(不通用)
  • 业务逻辑放在数据库上,难以迭代

三个范式是什么

三个范式是什么

第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。 第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。 第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在”A → B → C”的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系: 关键字段 → 非关键字段x → 非关键字段y

上面的文字我们肯定是看不懂的,也不愿意看下去的。接下来我就总结一下:

  • 首先要明确的是:满足着第三范式,那么就一定满足第二范式、满足着第二范式就一定满足第一范式
  • 第一范式:字段是最小的的单元不可再分 
    • 学生信息组成学生信息表,有年龄、性别、学号等信息组成。这些字段都不可再分,所以它是满足第一范式的
  • 第二范式:满足第一范式,表中的字段必须完全依赖于全部主键而非部分主键。 
    • 其他字段组成的这行记录和主键表示的是同一个东西,而主键是唯一的,它们只需要依赖于主键,也就成了唯一的
    • 学号为1024的同学,姓名为Java3y,年龄是22岁。姓名和年龄字段都依赖着学号主键。
  • 第三范式:满足第二范式,非主键外的所有字段必须互不依赖 
    • 就是数据只在一个地方存储,不重复出现在多张表中,可以认为就是消除传递依赖
    • 比如,我们大学分了很多系(中文系、英语系、计算机系……),这个系别管理表信息有以下字段组成:系编号,系主任,系简介,系架构。那我们能不能在学生信息表添加系编号,系主任,系简介,系架构字段呢?不行的,因为这样就冗余了,非主键外的字段形成了依赖关系(依赖到学生信息表了)!正确的做法是:学生表就只能增加一个系编号字段。

参考链接:

  • https://www.zhihu.com/question/24696366
  • http://www.cnblogs.com/CareySon/archive/2010/02/16/1668803.html

什么是视图?以及视图的使用场景有哪些?

什么是视图?以及视图的使用场景有哪些?

视图是一种基于数据表的一种虚表

  • (1)视图是一种虚表
  • (2)视图建立在已有表的基础上, 视图赖以建立的这些表称为基表
  • (3)向视图提供数据内容的语句为 SELECT 语句,可以将视图理解为存储起来的 SELECT 语句
  • (4)视图向用户提供基表数据的另一种表现形式
  • (5)视图没有存储真正的数据,真正的数据还是存储在基表中
  • (6)程序员虽然操作的是视图,但最终视图还会转成操作基表
  • (7)一个基表可以有0个或多个视图

有的时候,我们可能只关系一张数据表中的某些字段,而另外的一些人只关系同一张数据表的某些字段…

那么把全部的字段都都显示给他们看,这是不合理的。

我们应该做到:他们想看到什么样的数据,我们就给他们什么样的数据…一方面就能够让他们只关注自己的数据,另一方面,我们也保证数据表一些保密的数据不会泄露出来…

我们在查询数据的时候,常常需要编写非常长的SQL语句,几乎每次都要写很长很长….上面已经说了,视图就是基于查询的一种虚表,也就是说,视图可以将查询出来的数据进行封装。。。那么我们在使用的时候就会变得非常方便

值得注意的是:使用视图可以让我们专注与逻辑,但不提高查询效率

drop、delete与truncate分别在什么场景之下使用?

drop、delete与truncate分别在什么场景之下使用?

我们来对比一下他们的区别:

drop table

  • 1)属于DDL
  • 2)不可回滚
  • 3)不可带where
  • 4)表内容和结构删除
  • 5)删除速度快

truncate table

  • 1)属于DDL
  • 2)不可回滚
  • 3)不可带where
  • 4)表内容删除
  • 5)删除速度快

delete from

  • 1)属于DML
  • 2)可回滚
  • 3)可带where
  • 4)表结构在,表内容要看where执行的情况
  • 5)删除速度慢,需要逐行删除

  • 不再需要一张表的时候,用drop

  • 想删除部分数据行时候,用delete,并且带上where子句
  • 保留表而删除所有数据的时候用truncate

索引是什么?有什么作用以及优缺点?

索引是什么?有什么作用以及优缺点?

什么是索引【Index】

  • (1)是一种快速查询表中内容的机制,类似于新华字典的目录
  • (2)运用在表中某个些字段上,但存储时,独立于表之外

索引表把数据变成是有序的…. 

快速定位到硬盘中的数据文件…


rowid特点

rowid的特点

  • (1)位于每个表中,但表面上看不见,例如:desc emp是看不见的
  • (2)只有在select中,显示写出rowid,方可看见
  • (3)它与每个表绑定在一起,表亡,该表的rowid亡,二张表rownum可以相同,但rowid必须是唯一的
  • (4)rowid是18位大小写加数字混杂体,唯一表代该条记录在DBF文件中的位置
  • (5)rowid可以参与=/like比较时,用”单引号将rowid的值包起来,且区分大小写
  • (6)rowid是联系表与DBF文件的桥梁

索引特点

索引的特点

  • (1)索引一旦建立,* Oracle管理系统会对其进行自动维护*, 而且由Oracle管理系统决定何时使用索引
  • (2)用户不用在查询语句中指定使用哪个索引
  • (3)在定义primary key或unique约束后系统自动在相应的列上创建索引
  • (4)用户也能按自己的需求,对指定单个字段或多个字段,添加索引

需要注意的是:Oracle是自动帮我们管理索引的,并且如果我们指定了primary key或者unique约束,系统会自动在对应的列上创建索引..

什么时候【要】创建索引

  • (1)表经常进行 SELECT 操作
  • (2)表很大(记录超多),记录内容分布范围很广
  • (3)列名经常在 WHERE 子句或连接条件中出现

什么时候【不要】创建索引

  • (1)表经常进行 INSERT/UPDATE/DELETE 操作
  • (2)表很小(记录超少)
  • (3)列名不经常作为连接条件或出现在 WHERE 子句中

索引优缺点:

  • 索引加快数据库的检索速度
  • 索引降低了插入、删除、修改等维护任务的速度(虽然索引可以提高查询速度,但是它们也会导致数据库系统更新数据的性能下降,因为大部分数据更新需要同时更新索引)
  • 唯一索引可以确保每一行数据的唯一性,通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能
  • 索引需要占物理和数据空间

索引分类:

  • 唯一索引:唯一索引不允许两行具有相同的索引值
  • 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的,并且不能为空
  • 聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个
  • 非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个

深入理解索引可参考:

  • https://kb.cnblogs.com/page/45712/
  • https://www.cnblogs.com/drizzlewithwind/p/5707058.html

什么是事务?

什么是事务?

事务简单来说:一个Session中所进行所有的操作,要么同时成功,要么同时失败

ACID — 数据库事务正确执行的四个基本要素

  • 包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

一个支持事务(Transaction)中的数据库系统,必需要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易。

举个例子:A向B转账,转账这个流程中如果出现问题,事务可以让数据恢复成原来一样【A账户的钱没变,B账户的钱也没变】。

事例说明:


/*
* 我们来模拟A向B账号转账的场景
*
A和B账户都有1000块,现在我让A账户向B账号转500块钱
*
* */
//JDBC默认的情况下是关闭事务的,下面我们看看关闭事务去操作转账操作有什么问题
//A账户减去500块
String sql = "UPDATE a SET money=money-500 ";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
//B账户多了500块
String sql2 = "UPDATE b SET money=money+500";
preparedStatement = connection.prepareStatement(sql2);
preparedStatement.executeUpdate();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

从上面看,我们的确可以发现A向B转账,成功了。可是如果A向B转账的过程中出现了问题呢?下面模拟一下


//A账户减去500块
String sql = "UPDATE a SET money=money-500 ";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
//这里模拟出现问题
int a = 3 / 0;
String sql2 = "UPDATE b SET money=money+500";
preparedStatement = connection.prepareStatement(sql2);
preparedStatement.executeUpdate();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

显然,上面代码是会抛出异常的,我们再来查询一下数据。A账户少了500块钱,B账户的钱没有增加这明显是不合理的


我们可以通过事务来解决上面出现的问题


//开启事务,对数据的操作就不会立即生效。
connection.setAutoCommit(false);
//A账户减去500块
String sql = "UPDATE a SET money=money-500 ";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
//在转账过程中出现问题
int a = 3 / 0;
//B账户多500块
String sql2 = "UPDATE b SET money=money+500";
preparedStatement = connection.prepareStatement(sql2);
preparedStatement.executeUpdate();
//如果程序能执行到这里,没有抛出异常,我们就提交数据
connection.commit();
//关闭事务【自动提交】
connection.setAutoCommit(true);
} catch (SQLException e) {
try {
//如果出现了异常,就会进到这里来,我们就把事务回滚【将数据变成原来那样】
connection.rollback();
//关闭事务【自动提交】
connection.setAutoCommit(true);
} catch (SQLException e1) {
e1.printStackTrace();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

上面的程序也一样抛出了异常,A账户钱没有减少,B账户的钱也没有增加。

注意:当Connection遇到一个未处理的SQLException时,系统会非正常退出,事务也会自动回滚,但如果程序捕获到了异常,是需要在catch中显式回滚事务的。

事务隔离级别

数据库定义了4个隔离级别:

  1. Serializable【可避免脏读,不可重复读,虚读】
  2. Repeatable read【可避免脏读,不可重复读】
  3. Read committed【可避免脏读】
  4. Read uncommitted【级别最低,什么都避免不了】

分别对应Connection类中的4个常量

  1. TRANSACTION_READ_UNCOMMITTED
  2. TRANSACTION_READ_COMMITTED
  3. TRANSACTION_REPEATABLE_READ
  4. TRANSACTION_SERIALIZABLE

脏读:一个事务读取到另外一个事务未提交的数据

例子:A向B转账,A执行了转账语句,但A还没有提交事务,B读取数据,发现自己账户钱变多了!B跟A说,我已经收到钱了。A回滚事务【rollback】,等B再查看账户的钱时,发现钱并没有多。


不可重复读:一个事务读取到另外一个事务已经提交的数据,也就是说一个事务可以看到其他事务所做的修改

注:A查询数据库得到数据,B去修改数据库的数据,导致A多次查询数据库的结果都不一样【危害:A每次查询的结果都是受B的影响的,那么A查询出来的信息就没有意思了】


虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

注:和不可重复读类似,但虚读(幻读)会读到其他事务的插入的数据,导致前后读取不一致


简单总结:脏读是不可容忍的,不可重复读和虚读在一定的情况下是可以的【做统计的肯定就不行】

数据库的乐观锁和悲观锁是什么?

数据库的乐观锁和悲观锁是什么?

确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性,乐观锁和悲观锁是并发控制主要采用的技术手段。

  • 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作 
  • 在查询完数据的时候就把事务锁起来,直到提交事务
  • 实现方式:使用数据库中的锁机制
  • 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 
  • 在修改数据的时候把事务锁起来,通过version的方式来进行锁定
  • 实现方式:使用version版本或者时间戳
  • 悲观锁:

    乐观锁:

    参考资料:

    • http://www.open-open.com/lib/view/open1452046967245.html

    超键、候选键、主键、外键分别是什么?

    超键、候选键、主键、外键分别是什么?

    • 超键:在关系中能唯一标识元组的属性集称为关系模式的超键。一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键。超键包含候选键和主键
    • 候选键(候选码):是最小超键,即没有冗余元素的超键
    • 主键(主码):数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null)。
    • 外键:在一个表中存在的另一个表的主键称此表的外键

    候选码和主码:

    例子:邮寄地址(城市名,街道名,邮政编码,单位名,收件人)

    • 它有两个候选键:{城市名,街道名} 和 {街道名,邮政编码}
    • 如果我选取{城市名,街道名}作为唯一标识实体的属性,那么{城市名,街道名} 就是主码(主键)

    SQL 约束有哪几种?

    SQL 约束有哪几种?

    • NOT NULL: 用于控制字段的内容一定不能为空(NULL)。
    • UNIQUE: 控件字段内容不能重复,一个表允许有多个 Unique 约束。
    • PRIMARY KEY: 也是用于控件字段内容不能重复,但它在一个表只允许出现一个。
    • FOREIGN KEY: 用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
    • CHECK: 用于控制字段的值范围。

    数据库运行于哪种状态下可以防止数据的丢失?

    数据库运行于哪种状态下可以防止数据的丢失?

    在archivelog mode(归档模式)只要其归档日志文件不丢失,就可以有效地防止数据丢失。

    Mysql存储引擎

    Mysql的存储引擎有以下几种:

    我的是5.7.15版本,默认使用的是Innodb版本!

    常用的存储引擎有以下:

    • Innodb引擎,Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。
    • MyIASM引擎(原本Mysql的默认引擎),不提供事务的支持,也不支持行级锁和外键。
    • MEMORY引擎:所有的数据都在内存中,数据的处理速度快,但是安全性不高。

    同一个数据库也可以使用多种存储引擎的表。如果一个表修改要求比较高的事务处理,可以选择InnoDB。这个数据库中可以将查询要求比较高的表选择MyISAM存储。如果该数据库需要一个用于查询的临时表,可以选择MEMORY存储引擎

    参考资料:

    • https://www.cnblogs.com/xiaohaillong/p/6079551.html
    • http://blog.csdn.net/ls5718/article/details/52248040
    • http://blog.csdn.net/t146lla128xx0x/article/details/78737290

    MyIASM和Innodb两种引擎所使用的索引的数据结构是什么?

    MyIASM和Innodb两种引擎所使用的索引的数据结构是什么?

    答案:都是B+树!

    MyIASM引擎,B+树的数据结构中存储的内容实际上是实际数据的地址值。也就是说它的索引和实际数据是分开的,只不过使用索引指向了实际数据。这种索引的模式被称为非聚集索引。

    Innodb引擎的索引的数据结构也是B+树,只不过数据结构中存储的都是实际的数据,这种索引有被称为聚集索引

    varchar和char的区别

    varchar和char的区别

    Char是一种固定长度的类型,varchar是一种可变长度的类型

    mysql有关权限的表都有哪几个

    mysql有关权限的表都有哪几个

    MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host。下面分别介绍一下这些表的结构和内容:

    • user权限表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的。
    • db权限表:记录各个帐号在各个数据库上的操作权限。
    • table_priv权限表:记录数据表级的操作权限。
    • columns_priv权限表:记录数据列级的操作权限。
    • host权限表:配合db权限表对给定主机上数据库级操作权限作更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。

    数据表损坏的修复方式有哪些?

    数据表损坏的修复方式有哪些?

    使用 myisamchk 来修复,具体步骤:

    • 1)修复前将mysql服务停止。
    • 2)打开命令行方式,然后进入到mysql的/bin目录。
    • 3)执行myisamchk –recover 数据库所在路径/*.MYI

    使用repair table 或者 OPTIMIZE table命令来修复,REPAIR TABLE table_name 修复表 OPTIMIZE TABLE table_name 优化表 REPAIR TABLE 用于修复被破坏的表。 

    MySQL中InnoDB引擎的行锁是通过加在什么上完成

    MySQL中InnoDB引擎的行锁是通过加在什么上完成

    InnoDB是基于索引来完成行锁

    例: select * from tab_with_index where id = 1 for update;

    for update 可以根据条件来完成行锁锁定,并且 id 是有索引键的列,

    如果 id 不是索引键那么InnoDB将完成表锁,,并发将无从谈起

    数据库优化的思路

    SQL优化

    在我们书写SQL语句的时候,其实书写的顺序、策略会影响到SQL的性能,虽然实现的功能是一样的,但是它们的性能会有些许差别。

    因此,下面就讲解在书写SQL的时候,怎么写比较好。

    ①选择最有效率的表名顺序

    数据库的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表将被最先处理

    在FROM子句中包含多个表的情况下:

    • 如果三个表是完全无关系的话,将记录和列名最少的表,写在最后,然后依次类推
    • 也就是说:选择记录条数最少的表放在最后

    如果有3个以上的表连接查询:

    • 如果三个表是有关系的话,将引用最多的表,放在最后,然后依次类推
    • 也就是说:被其他表所引用的表放在最后

    例如:查询员工的编号,姓名,工资,工资等级,部门名

    emp表被引用得最多,记录数也是最多,因此放在form字句的最后面

    
    select emp.empno,emp.ename,emp.sal,salgrade.grade,dept.dname
    from salgrade,dept,emp
    where (emp.deptno = dept.deptno) and (emp.sal between salgrade.losal and salgrade.hisal)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ②WHERE子句中的连接顺序

    数据库采用自右而左的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之左,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的之右

    emp.sal可以过滤多条记录,写在WHERE字句的最右边

    
    select emp.empno,emp.ename,emp.sal,dept.dname
    from dept,emp
    where (emp.deptno = dept.deptno) and (emp.sal > 1500) 
    • 1
    • 2
    • 3
    • 4

    ③SELECT子句中避免使用*号

    我们当时学习的时候,“*”号是可以获取表中全部的字段数据的。

    • 但是它要通过查询数据字典完成的,这意味着将耗费更多的时间
    • 使用*号写出来的SQL语句也不够直观。

    ④用TRUNCATE替代DELETE

    这里仅仅是:删除表的全部记录,除了表结构才这样做

    DELETE是一条一条记录的删除,而Truncate是将整个表删除,保留表结构,这样比DELETE快

    ⑤多使用内部函数提高SQL效率

    例如使用mysql的concat()函数会比使用||来进行拼接快,因为concat()函数已经被mysql优化过了。

    ⑥使用表或列的别名

    如果表或列的名称太长了,使用一些简短的别名也能稍微提高一些SQL的性能。毕竟要扫描的字符长度就变少了。。。

    ⑦多使用commit

    comiit会释放回滚点…

    ⑧善用索引

    索引就是为了提高我们的查询数据的,当表的记录量非常大的时候,我们就可以使用索引了。

    ⑨SQL写大写

    我们在编写SQL 的时候,官方推荐的是使用大写来写关键字,因为Oracle服务器总是先将小写字母转成大写后,才执行

    ⑩避免在索引列上使用NOT

    因为Oracle服务器遇到NOT后,他就会停止目前的工作,转而执行全表扫描

    ①①避免在索引列上使用计算

    WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描,这样会变得变慢

    ①②用 >= 替代 >

    
    低效:
    SELECT * FROM EMP WHERE DEPTNO > 3
    首先定位到DEPTNO=3的记录并且扫描到第一个DEPT大于3的记录
    高效:
    SELECT * FROM EMP WHERE DEPTNO >= 4
    直接跳到第一个DEPT等于4的记录
    

    ①③用IN替代OR

    
    select * from emp where sal = 1500 or sal = 3000 or sal = 800;
    select * from emp where sal in (1500,3000,800);
    

    ①④总是使用索引的第一个列

    如果索引是建立在多个列上,只有在它的第一个列被WHERE子句引用时,优化器才会选择使用该索引。 当只引用索引的第二个列时,不引用索引的第一个列时,优化器使用了全表扫描而忽略了索引

    
    create index emp_sal_job_idex
    on emp(sal,job);
    ----------------------------------
    select *
    from emp
    where job != 'SALES';
    上边就不使用索引了。

    数据库结构优化

    服务器硬件优化

    这个么多花钱咯!

    SQL练习题

    下列练习题参考自公众号Java知音:

    基本表结构:

    student(sno,sname,sage,ssex)学生表
    course(cno,cname,tno) 课程表
    sc(sno,cno,score) 成绩表
    teacher(tno,tname) 教师表
    

    题目:

    
    101,查询课程1的成绩比课程2的成绩高的所有学生的学号
    select a.sno from
    (select sno,score from sc where cno=1) a,
    (select sno,score from sc where cno=2) b
    where a.score>b.score and a.sno=b.sno
    102,查询平均成绩大于60分的同学的学号和平均成绩
    select a.sno as "学号", avg(a.score) as "平均成绩"
    from
    (select sno,score from sc) a
    group by sno having avg(a.score)>60
    103,查询所有同学的学号、姓名、选课数、总成绩
    select a.sno as 学号, b.sname as 姓名,
    count(a.cno) as 选课数, sum(a.score) as 总成绩
    from sc a, student b
    where a.sno = b.sno
    group by a.sno, b.sname
    或者:
    selectstudent.sno as 学号, student.sname as 姓名,
    count(sc.cno) as 选课数, sum(score) as 总成绩
    from student left Outer join sc on student.sno = sc.sno
    group by student.sno, sname
    104,查询姓“张”的老师的个数
    selectcount(distinct(tname)) from teacher where tname like '张%‘
    或者:
    select tname as "姓名", count(distinct(tname)) as "人数"
    from teacher
    where tname like'张%'
    group by tname
    105,查询没学过“张三”老师课的同学的学号、姓名
    select student.sno,student.sname from student
    where sno not in (select distinct(sc.sno) from sc,course,teacher
    where sc.cno=course.cno and teacher.tno=course.tno and teacher.tname='张三')
    106,查询同时学过课程1和课程2的同学的学号、姓名
    select sno, sname from student
    where sno in (select sno from sc where sc.cno = 1)
    and sno in (select sno from sc where sc.cno = 2)
    或者:
    selectc.sno, c.sname from
    (select sno from sc where sc.cno = 1) a,
    (select sno from sc where sc.cno = 2) b,
    student c
    where a.sno = b.sno and a.sno = c.sno
    或者:
    select student.sno,student.sname from student,sc where student.sno=sc.sno and sc.cno=1
    and exists( select * from sc as sc_2 where sc_2.sno=sc.sno and sc_2.cno=2)
    107,查询学过“李四”老师所教所有课程的所有同学的学号、姓名
    select a.sno, a.sname from student a, sc b
    where a.sno = b.sno and b.cno in
    (select c.cno from course c, teacher d where c.tno = d.tno and d.tname = '李四')
    或者:
    select a.sno, a.sname from student a, sc b,
    (select c.cno from course c, teacher d where c.tno = d.tno and d.tname = '李四') e
    where a.sno = b.sno and b.cno = e.cno
    108,查询课程编号1的成绩比课程编号2的成绩高的所有同学的学号、姓名
    select a.sno, a.sname from student a,
    (select sno, score from sc where cno = 1) b,
    (select sno, score from sc where cno = 2) c
    where b.score > c.score and b.sno = c.sno and a.sno = b.sno
    109,查询所有课程成绩小于60分的同学的学号、姓名
    select sno,sname from student
    where sno not in (select distinct sno from sc where score > 60)
    110,查询至少有一门课程与学号为1的同学所学课程相同的同学的学号和姓名
    select distinct a.sno, a.sname
    from student a, sc b
    where a.sno <> 1 and a.sno=b.sno and
    b.cno in (select cno from sc where sno = 1)
    或者:
    select s.sno,s.sname
    from student s,
    (select sc.sno
    from sc
    where sc.cno in (select sc1.cno from sc sc1 where sc1.sno=1)and sc.sno<>1
    group by sc.sno)r1
    where r1.sno=s.sno
    111、把“sc”表中“王五”所教课的成绩都更改为此课程的平均成绩
    update sc set score = (select avg(sc_2.score) from sc sc_2 wheresc_2.cno=sc.cno)
    from course,teacher where course.cno=sc.cno and course.tno=teacher.tno andteacher.tname='王五'
    112、查询和编号为2的同学学习的课程完全相同的其他同学学号和姓名
    这一题分两步查:
    1,
    select sno
    from sc
    where sno <> 2
    group by sno
    having sum(cno) = (select sum(cno) from sc where sno = 2)
    2,
    select b.sno, b.sname
    from sc a, student b
    where b.sno <> 2 and a.sno = b.sno
    group by b.sno, b.sname
    having sum(cno) = (select sum(cno) from sc where sno = 2)
    113、删除学习“王五”老师课的sc表记录
    delete sc from course, teacher
    where course.cno = sc.cno and course.tno = teacher.tno and tname = '王五'
    114、向sc表中插入一些记录,这些记录要求符合以下条件:
    将没有课程3成绩同学的该成绩补齐, 其成绩取所有学生的课程2的平均成绩
    insert sc select sno, 3, (select avg(score) from sc where cno = 2)
    from student
    where sno not in (select sno from sc where cno = 3)
    115、按平平均分从高到低显示所有学生的如下统计报表:
    -- 学号,企业管理,马克思,UML,数据库,物理,课程数,平均分
    select sno as 学号
    ,max(case when cno = 1 then score end) AS 企业管理
    ,max(case when cno = 2 then score end) AS 马克思
    ,max(case when cno = 3 then score end) AS UML
    ,max(case when cno = 4 then score end) AS 数据库
    ,max(case when cno = 5 then score end) AS 物理
    ,count(cno) AS 课程数
    ,avg(score) AS 平均分
    FROM sc
    GROUP by sno
    ORDER by avg(score) DESC
    116、查询各科成绩最高分和最低分:
    以如下形式显示:课程号,最高分,最低分
    select cno as 课程号, max(score) as 最高分, min(score) 最低分
    from sc group by cno
    select
    course.cno as '课程号'
    ,MAX(score) as '最高分'
    ,MIN(score) as '最低分'
    from sc,course
    where sc.cno=course.cno
    group by course.cno
    117、按各科平均成绩从低到高和及格率的百分数从高到低顺序
    SELECT t.cno AS 课程号,
    max(course.cname)AS 课程名,
    isnull(AVG(score),0) AS 平均成绩,
    100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/count(1) AS 及格率
    FROM sc t, course
    where t.cno = course.cno
    GROUP BY t.cno
    ORDER BY 及格率 desc
    118、查询如下课程平均成绩和及格率的百分数(用"1行"显示):
    企业管理(001),马克思(002),UML (003),数据库(004)
    select
    avg(case when cno = 1 then score end) as 平均分1,
    avg(case when cno = 2 then score end) as 平均分2,
    avg(case when cno = 3 then score end) as 平均分3,
    avg(case when cno = 4 then score end) as 平均分4,
    100 * sum(case when cno = 1 and score > 60 then 1 else 0 end) / sum(casewhen cno = 1 then 1 else 0 end) as 及格率1,
    100 * sum(case when cno = 2 and score > 60 then 1 else 0 end) / sum(casewhen cno = 2 then 1 else 0 end) as 及格率2,
    100 * sum(case when cno = 3 and score > 60 then 1 else 0 end) / sum(casewhen cno = 3 then 1 else 0 end) as 及格率3,
    100 * sum(case when cno = 4 and score > 60 then 1 else 0 end) / sum(casewhen cno = 4 then 1 else 0 end) as 及格率4
    from sc
    119、查询不同老师所教不同课程平均分, 从高到低显示
    select max(c.tname) as 教师, max(b.cname) 课程, avg(a.score) 平均分
    from sc a, course b, teacher c
    where a.cno = b.cno and b.tno = c.tno
    group by a.cno
    order by 平均分 desc
    或者:
    select r.tname as '教师',r.rname as '课程' , AVG(score) as '平均分'
    from sc,
    (select
    t.tname,c.cno as rcso,c.cname as rname
    from teacher t ,course c
    where t.tno=c.tno)r
    where sc.cno=r.rcso
    group by sc.cno,r.tname,r.rname
    order by AVG(score) desc
    120、查询如下课程成绩均在第3名到第6名之间的学生的成绩:
    -- [学生ID],[学生姓名],企业管理,马克思,UML,数据库,平均成绩
    select top 6 max(a.sno) 学号, max(b.sname) 姓名,
    max(case when cno = 1 then score end) as 企业管理,
    max(case when cno = 2 then score end) as 马克思,
    max(case when cno = 3 then score end) as UML,
    max(case when cno = 4 then score end) as 数据库,
    avg(score) as 平均分
    from sc a, student b
    where a.sno not in
    (select top 2 sno from sc where cno = 1 order by score desc)
    and a.sno not in (select top 2 sno from sc where cno = 2 order by scoredesc)
    and a.sno not in (select top 2 sno from sc where cno = 3 order by scoredesc)
    and a.sno not in (select top 2 sno from sc where cno = 4 order by scoredesc)
    and a.sno = b.sno
    group by a.sno
    

    Oracle和Mysql的区别

    在Mysql中,一个用户下可以创建多个库

    而在Oracle中,Oracle服务器是由两部分组成

    一个数据库实例可拥有多个用户,一个用户默认拥有一个表空间。

    表空间是存储我们数据库表的地方,表空间内可以有多个文件。

    当我们使用Oracle作为我们数据库时,我们需要指定用户、表空间来存储我们所需要的数据

    最后

    参考资料:

    面试题精华-框架

    原文地址:http://blog.csdn.net/jackfrued/article/details/44931161

    SpringMVC运行原理

    1. 客户端请求提交到DispatcherServlet
    2. 由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller
    3. DispatcherServlet将请求提交到Controller
    4. Controller调用业务逻辑处理后,返回ModelAndView
    5. DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
    6. 视图负责将结果显示到客户端
    Hibernate中Session的load和get方法的区别是什么? 
    答:主要有以下三项区别: 
    ① 如果没有找到符合条件的记录,get方法返回null,load方法抛出异常。 
    ② get方法直接返回实体类对象,load方法返回实体类对象的代理。 
    ③ 在Hibernate 3之前,get方法只在一级缓存中进行数据查找,如果没有找到对应的数据则越过二级缓存,直接发出SQL语句完成数据读取;load方法则可以从二级缓存中获取数据;从Hibernate 3开始,get方法不再是对二级缓存只写不读,它也是可以访问二级缓存的。
    说明:对于load()方法Hibernate认为该数据在数据库中一定存在可以放心的使用代理来实现延迟加载,如果没有数据就抛出异常,而通过get()方法获取的数据可以不存在。
    谈一谈Hibernate的一级缓存、二级缓存和查询缓存。 
    答:Hibernate的Session提供了一级缓存的功能,默认总是有效的,当应用程序保存持久化实体、修改持久化实体时,Session并不会立即把这种改变提交到数据库,而是缓存在当前的Session中,除非显示调用了Session的flush()方法或通过close()方法关闭Session。通过一级缓存,可以减少程序与数据库的交互,从而提高数据库访问性能。 

    SessionFactory级别的二级缓存是全局性的,所有的Session可以共享这个二级缓存。不过二级缓存默认是关闭的,需要显示开启并指定需要使用哪种二级缓存实现类(可以使用第三方提供的实现)。一旦开启了二级缓存并设置了需要使用二级缓存的实体类,SessionFactory就会缓存访问过的该实体类的每个对象,除非缓存的数据超出了指定的缓存空间。 

    一级缓存和二级缓存都是对整个实体进行缓存,不会缓存普通属性,如果希望对普通属性进行缓存,可以使用查询缓存。查询缓存是将HQL或SQL语句以及它们的查询结果作为键值对进行缓存,对于同样的查询可以直接从缓存中获取数据。查询缓存默认也是关闭的,需要显示开启。
    @OneToMany注解的mappedBy属性有什么作用? 
    答:@OneToMany用来配置一对多关联映射,但通常情况下,一对多关联映射都由多的一方来维护关联关系,例如学生和班级,应该在学生类中添加班级属性来维持学生和班级的关联关系(在数据库中是由学生表中的外键班级编号来维护学生表和班级表的多对一关系),如果要使用双向关联,在班级类中添加一个容器属性来存放学生,并使用@OneToMany注解进行映射,此时mappedBy属性就非常重要。如果使用XML进行配置,可以用<set>标签的inverse="true"设置来达到同样的效果。
    MyBatis中使用#$书写占位符有什么区别? 
    答:
    #将传入的数据都当成一个字符串,会对传入的数据自动加上引号;$将传入的数据直接显示生成在SQL中。注意:使用$占位符可能会导致SQL注射攻击,能用#的地方就不要使用$,写order by子句的时候应该用$而不是#。($:where admin=admin 永远为true,而#:where admin='admin',自动加上引号,不会被sql注入攻击)
    解释一下MyBatis中命名空间(namespace)的作用。 
    答:在大型项目中,可能存在大量的SQL语句,这时候为每个SQL语句起一个唯一的标识(ID)就变得并不容易了。为了解决这个问题,在MyBatis中,可以为每个映射文件起一个唯一的命名空间,这样定义在这个映射文件中的每个SQL语句就成了定义在这个命名空间中的一个ID。只要我们能够保证每个命名空间中这个ID是唯一的,即使在不同映射文件中的语句ID相同,也不会再产生冲突了。
    MyBatis中的动态SQL是什么意思? 
    答:对于一些复杂的查询,我们可能会指定多个查询条件,但是这些条件可能存在也可能不存在,例如在58同城上面找房子,我们可能会指定面积、楼层和所在位置来查找房源,也可能会指定面积、价格、户型和所在位置来查找房源,此时就需要根据用户指定的条件动态生成SQL语句。如果不使用持久层框架我们可能需要自己拼装SQL语句,还好MyBatis提供了动态SQL的功能来解决这个问题。MyBatis中用于实现动态SQL的元素主要有: 

    - if 
    - choose / when / otherwise 
    - trim 
    - where 
    - set 
    - foreach

    什么是IoC和DI?DI是如何实现的? 

    举个例子:一个类A需要用到接口B中的方法,那么就需要为类A和接口B建立关联或依赖关系,最原始的方法是在类A中创建一个接口B的实现类C的实例,但这种方法需要开发人员自行维护二者的依赖关系,也就是说当依赖关系发生变动的时候需要修改代码并重新构建整个系统。如果通过一个容器来管理这些对象以及对象的依赖关系,则只需要在类A中定义好用于关联接口B的方法(构造器或setter方法),将类A和接口B的实现类C放入容器中,通过对容器的配置来实现二者的关联。

    依赖注入可以通过setter方法注入(设值注入)、构造器注入和接口注入三种方式来实现,Spring支持setter注入和构造器注入,通常使用构造器注入来注入必须的依赖关系,对于可选的依赖关系,则setter注入是更好的选择,setter注入需要类提供无参构造器或者无参的静态工厂方法来创建对象。

    Spring中Bean的作用域有哪些? 

    补充:设计模式中的创建型模式中也有一个原型模式,原型模式也是一个常用的模式,例如做一个室内设计软件,所有的素材都在工具箱中,而每次从工具箱中取出的都是素材对象的一个原型,可以通过对象克隆来实现原型模式。

    Spring 2.x中针对WebApplicationContext新增了3个作用域,分别是:request(每次HTTP请求都会创建一个新的Bean)、session(同一个HttpSession共享同一个Bean,不同的HttpSession使用不同的Bean)和globalSession(同一个全局Session共享一个Bean)。

    说明:单例模式和原型模式都是重要的设计模式。一般情况下,无状态或状态不可变的类适合使用单例模式。在传统开发中,由于DAO持有Connection这个非线程安全对象因而没有使用单例模式;但在Spring环境下,所有DAO类对可以采用单例模式,因为Spring利用AOP和Java API中的ThreadLocal对非线程安全的对象进行了特殊处理。

    ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。ThreadLocal,顾名思义是线程的一个本地化对象,当工作于多线程中的对象使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程分配一个独立的变量副本,所以每一个线程都可以独立的改变自己的副本,而不影响其他线程所对应的副本。从线程的角度看,这个变量就像是线程的本地变量。

    ThreadLocal类非常简单好用,只有四个方法,能用上的也就是下面三个方法: 

    ThreadLocal是如何做到为每一个线程维护一份独立的变量副本的呢?在ThreadLocal类中有一个Map,键为线程对象,值是其线程对应的变量的副本,自己要模拟实现一个ThreadLocal类其实并不困难,代码如下所示:

    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Map;
    public class MyThreadLocal<T> {
    private Map<Thread, T> map = Collections.synchronizedMap(new HashMap<Thread, T>());
    public void set(T newValue) {
    map.put(Thread.currentThread(), newValue);
    }
    public T get() {
    return map.get(Thread.currentThread());
    }
    public void remove() {
    map.remove(Thread.currentThread());
    }
    }
    Java动态代理

    说明:从JDK 1.3开始,Java提供了动态代理技术,允许开发者在运行时创建接口的代理实例,主要包括Proxy类和InvocationHandler接口。下面的例子使用动态代理为ArrayList编写一个代理,在添加和删除元素时,在控制台打印添加或删除的元素以及ArrayList的大小:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.util.List;
    public class ListProxy<T> implements InvocationHandler {
    private List<T> target;
    public ListProxy(List<T> target) {
    this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    Object retVal = null;
    System.out.println("[" + method.getName() + ": " + args[0] + "]");
    retVal = method.invoke(target, args);
    System.out.println("[size=" + target.size() + "]");
    return retVal;
    }
    }
    import java.lang.reflect.Proxy;
    import java.util.ArrayList;
    import java.util.List;
    public class ProxyTest2 {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    Class<?> clazz = list.getClass();
    ListProxy<String> myProxy = new ListProxy<String>(list);
    List<String> newList = (List<String>)
    Proxy.newProxyInstance(clazz.getClassLoader(),
    clazz.getInterfaces(), myProxy);
    newList.add("apple");
    newList.add("banana");
    newList.add("orange");
    newList.remove("banana");
    }
    }

    说明:使用Java的动态代理有一个局限性就是代理的类必须要实现接口,虽然面向接口编程是每个优秀的Java程序都知道的规则,但现实往往不尽如人意,对于没有实现接口的类如何为其生成代理呢?继承!继承是最经典的扩展已有代码能力的手段,虽然继承常常被初学者滥用,但继承也常常被进阶的程序员忽视。CGLib采用非常底层的字节码生成技术,通过为一个类创建子类来生成代理,它弥补了Java动态代理的不足,因此Spring中动态代理和CGLib都是创建代理的重要手段,对于实现了接口的类就用动态代理为其生成代理类,而没有实现接口的类就用CGLib通过继承的方式为其创建代理。

    Spring中自动装配的方式有哪些? 

    说明:自动装配没有自定义装配方式那么精确,而且不能自动装配简单属性(基本类型、字符串等),在使用时应注意。

    Spring中如何使用注解来配置Bean?有哪些相关的注解? 

    <context:component-scan base-package="org.example"/>

    然后可以用@Component、@Controller、@Service、@Repository注解来标注需要由Spring IoC容器进行对象托管的类。这几个注解没有本质区别,只不过@Controller通常用于控制器,@Service通常用于业务逻辑类,@Repository通常用于仓储类(例如我们的DAO实现类),普通的类用@Component来标注。

    选择使用Spring框架的原因(Spring框架为企业级开发带来的好处有哪些)? 
    答:可以从以下几个方面作答: 
    - 非侵入式:支持基于POJO的编程模式,不强制性的要求实现Spring框架中的接口或继承Spring框架中的类。 
    - IoC容器:IoC容器帮助应用程序管理对象以及对象之间的依赖关系,对象之间的依赖关系如果发生了改变只需要修改配置文件而不是修改代码,因为代码的修改可能意味着项目的重新构建和完整的回归 测试 。有了IoC容器,程序员再也不需要自己编写工厂、单例,这一点特别符合Spring的精神"不要重复的发明轮子"。 
    - AOP(面向切面编程):将所有的横切关注功能封装到切面(aspect)中,通过配置的方式将横切关注功能动态添加到目标代码上,进一步实现了业务逻辑和系统服务之间的分离。另一方面,有了AOP程序员可以省去很多自己写代理类的工作。 
    - MVC:Spring的MVC框架是非常优秀的,从各个方面都可以甩Struts 2几条街,为Web表示层提供了更好的解决方案。 
    - 事务管理:Spring以宽广的胸怀接纳多种持久层技术,并且为其提供了声明式的事务管理,在不需要任何一行代码的情况下就能够完成事务管理。 
    - 其他:选择Spring框架的原因还远不止于此,Spring为Java企业级开发提供了一站式选择,你可以在需要的时候使用它的部分和全部,更重要的是,你甚至可以在感觉不到Spring存在的情况下,在你的项目中使用Spring提供的各种优秀的功能。

    Spring IoC容器配置Bean的方式? 

    package com.jackfrued.bean;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    @Component
    public class Person {
    private String name;
    private int age;
    @Autowired
    private Car car;
    public Person(String name, int age) {
    this.name = name;
    this.age = age;
    }
    public void setCar(Car car) {
    this.car = car;
    }
    @Override
    public String toString() {
    return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
    }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    package com.jackfrued.bean;
    import org.springframework.stereotype.Component;
    @Component
    public class Car {
    private String brand;
    private int maxSpeed;
    public Car(String brand, int maxSpeed) {
    this.brand = brand;
    this.maxSpeed = maxSpeed;
    }
    @Override
    public String toString() {
    return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]";
    }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    package com.jackfrued.config;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import com.jackfrued.bean.Car;
    import com.jackfrued.bean.Person;
    @Configuration
    public class AppConfig {
    @Bean
    public Car car() {
    return new Car("Benz", 320);
    }
    @Bean
    public Person person() {
    return new Person("骆昊", 34);
    }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    package com.jackfrued.test;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import com.jackfrued.bean.Person;
    import com.jackfrued.config.AppConfig;
    class Test {
    public static void main(String[] args) {
    // TWR (Java 7+)
    try(ConfigurableApplicationContext factory = new AnnotationConfigApplicationContext(AppConfig.class)) {
    Person person = factory.getBean(Person.class);
    System.out.println(person);
    }
    }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    依赖注入时如何注入集合属性? 
    答:可以在定义Bean属性时,通过<list> / <set> / <map> / <props>分别为其注入列表、集合、映射和键值都是字符串的映射属性。

    在Web项目中如何获得Spring的IoC容器? 

    WebApplicationContext ctx =
    WebApplicationContextUtils.getWebApplicationContext(servletContext);
    • 1
    • 2
    • 1
    • 2
    大型网站在架构上应当考虑哪些问题?  
    答: 
    - 分层:分层是处理任何复杂系统最常见的手段之一,将系统横向切分成若干个层面,每个层面只承担单一的职责,然后通过下层为上层提供的基础设施和服务以及上层对下层的调用来形成一个完整的复杂的系统。 计算机网络 的开放系统互联参考模型(OSI/RM)和Internet的TCP/IP模型都是分层结构,大型网站的软件系统也可以使用分层的理念将其分为持久层(提供数据存储和访问服务)、业务层(处理业务逻辑,系统中最核心的部分)和表示层(系统交互、视图展示)。需要指出的是:(1)分层是逻辑上的划分,在物理上可以位于同一设备上也可以在不同的设备上部署不同的功能模块,这样可以使用更多的计算资源来应对用户的并发访问;(2)层与层之间应当有清晰的边界,这样分层才有意义,才更利于软件的开发和维护。 
    - 分割:分割是对软件的纵向切分。我们可以将大型网站的不同功能和服务分割开,形成高内聚低耦合的功能模块(单元)。在设计初期可以做一个粗粒度的分割,将网站分割为若干个功能模块,后期还可以进一步对每个模块进行细粒度的分割,这样一方面有助于软件的开发和维护,另一方面有助于分布式的部署,提供网站的并发处理能力和功能的扩展。 
    - 分布式:除了上面提到的内容,网站的静态资源( JavaScript 、CSS、图片等)也可以采用独立分布式部署并采用独立的域名,这样可以减轻应用服务器的负载压力,也使得浏览器对资源的加载更快。数据的存取也应该是分布式的,传统的商业级关系型数据库产品基本上都支持分布式部署,而新生的NoSQL产品几乎都是分布式的。当然,网站后台的业务处理也要使用分布式技术,例如查询索引的构建、数据分析等,这些业务计算规模庞大,可以使用 Hadoop 以及MapReduce分布式计算框架来处理。 
    - 集群:集群使得有更多的服务器提供相同的服务,可以更好的提供对并发的支持。 
    - 缓存:所谓缓存就是用空间换取时间的技术,将数据尽可能放在距离计算最近的位置。使用缓存是网站优化的第一定律。我们通常说的CDN、反向代理、热点数据都是对缓存技术的使用。 
    - 异步:异步是实现软件实体之间解耦合的又一重要手段。异步架构是典型的生产者消费者模式,二者之间没有直接的调用关系,只要保持 数据结构 不变,彼此功能实现可以随意变化而不互相影响,这对网站的扩展非常有利。使用异步处理还可以提高系统可用性,加快网站的响应速度(用Ajax加载数据就是一种异步技术),同时还可以起到削峰作用(应对瞬时高并发)。&quot;能推迟处理的都要推迟处理"是网站优化的第二定律,而异步是践行网站优化第二定律的重要手段。 
    - 冗余:各种服务器都要提供相应的冗余服务器以便在某台或某些服务器宕机时还能保证网站可以正常工作,同时也提供了灾难恢复的可能性。冗余是网站高可用性的重要保证。

    你使用过的应用服务器优化技术有哪些? 
    答: 
    ① 分布式缓存:缓存的本质就是内存中的哈希表,如果设计一个优质的哈希函数,那么理论上哈希表读写的渐近时间复杂度为O(1)。缓存主要用来存放那些读写比很高、变化很少的数据,这样应用程序读取数据时先到缓存中读取,如果没有或者数据已经失效再去访问数据库或文件系统,并根据拟定的规则将数据写入缓存。对网站数据的访问也符合二八定律(Pareto分布,幂律分布),即80%的访问都集中在20%的数据上,如果能够将这20%的数据缓存起来,那么系统的性能将得到显著的改善。当然,使用缓存需要解决以下几个问题: 
    - 频繁修改的数据; 
    - 数据不一致与脏读; 
    - 缓存雪崩(可以采用分布式缓存服务器集群加以解决, memcached 是广泛采用的解决方案); 
    - 缓存预热; 
    - 缓存穿透(恶意持续请求不存在的数据)。 
    ② 异步操作:可以使用消息队列将调用异步化,通过异步处理将短时间高并发产生的事件消息存储在消息队列中,从而起到削峰作用。电商网站在进行促销活动时,可以将用户的订单请求存入消息队列,这样可以抵御大量的并发订单请求对系统和数据库的冲击。目前,绝大多数的电商网站即便不进行促销活动,订单系统都采用了消息队列来处理。 
    ③ 使用集群。 
    ④ 代码优化: 
    - 多线程:基于Java的Web开发基本上都通过多线程的方式响应用户的并发请求,使用多线程技术在编程上要解决线程安全问题,主要可以考虑以下几个方面:A. 将对象设计为无状态对象(这和面向对象的编程观点是矛盾的,在面向对象的世界中被视为不良设计),这样就不会存在并发访问时对象状态不一致的问题。B. 在方法内部创建对象,这样对象由进入方法的线程创建,不会出现多个线程访问同一对象的问题。使用ThreadLocal将对象与线程绑定也是很好的做法,这一点在前面已经探讨过了。C. 对资源进行并发访问时应当使用合理的锁机制。 
    - 非阻塞I/O: 使用单线程和非阻塞I/O是目前公认的比多线程的方式更能充分发挥服务器性能的应用模式,基于 Node.js 构建的服务器就采用了这样的方式。Java在JDK 1.4中就引入了NIO(Non-blocking I/O),在Servlet 3规范中又引入了异步Servlet的概念,这些都为在服务器端采用非阻塞I/O提供了必要的基础。 
    - 资源复用:资源复用主要有两种方式,一是单例,二是对象池,我们使用的数据库连接池、线程池都是对象池化技术,这是典型的用空间换取时间的策略,另一方面也实现对资源的复用,从而避免了不必要的创建和释放资源所带来的开销。

    各大公司Java后端开发面试题总结

    ThreadLocal(线程变量副本)

    Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量。

    采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程提供一个副本,每个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突。

    ThreadLocal类中维护一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值为对应线程的变量副本。

    ThreadLocal在Spring中发挥着巨大的作用,在管理Request作用域中的Bean、事务管理、任务调度、AOP等模块都出现了它的身影。

    Spring中绝大部分Bean都可以声明成Singleton作用域,采用ThreadLocal进行封装,因此有状态的Bean就能够以singleton的方式在多线程中正常工作了。

    友情链接:深入研究java.lang.ThreadLocal类


    Java内存模型:

    Java虚拟机规范中将Java运行时数据分为六种。

    1.程序计数器:是一个数据结构,用于保存当前正常执行的程序的内存地址。Java虚拟机的多线程就是通过线程轮流切换并分配处理器时间来实现的,为了线程切换后能恢复到正确的位置,每条线程都需要一个独立的程序计数器,互不影响,该区域为“线程私有”。

    2.Java虚拟机栈:线程私有的,与线程生命周期相同,用于存储局部变量表,操作栈,方法返回值。局部变量表放着基本数据类型,还有对象的引用。

    3.本地方法栈:跟虚拟机栈很像,不过它是为虚拟机使用到的Native方法服务。

    4.Java堆:所有线程共享的一块内存区域,对象实例几乎都在这分配内存。

    5.方法区:各个线程共享的区域,储存虚拟机加载的类信息,常量,静态变量,编译后的代码。

    6.运行时常量池:代表运行时每个class文件中的常量表。包括几种常量:编译时的数字常量、方法或者域的引用。

    友情链接: Java中JVM虚拟机详解


    “你能不能谈谈,java GC是在什么时候,对什么东西,做了什么事情?”

    在什么时候:

    1.新生代有一个Eden区和两个survivor区,首先将对象放入Eden区,如果空间不足就向其中的一个survivor区上放,如果仍然放不下就会引发一次发生在新生代的minor GC,将存活的对象放入另一个survivor区中,然后清空Eden和之前的那个survivor区的内存。在某次GC过程中,如果发现仍然又放不下的对象,就将这些对象放入老年代内存里去。

    2.大对象以及长期存活的对象直接进入老年区。

    3.当每次执行minor GC的时候应该对要晋升到老年代的对象进行分析,如果这些马上要到老年区的老年对象的大小超过了老年区的剩余大小,那么执行一次Full GC以尽可能地获得老年区的空间。

    对什么东西:从GC Roots搜索不到,而且经过一次标记清理之后仍没有复活的对象。

    做什么: 

    GC Roots都有哪些: 

    友情链接:Java GC的那些事(上)

    友情链接:Java GC的那些事(下)

    友情链接:CMS垃圾收集器介绍


    Synchronized 与Lock都是可重入锁,同一个线程再次进入同步代码的时候.可以使用自己已经获取到的锁。

    Synchronized是悲观锁机制,独占锁。而Locks.ReentrantLock是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。 

    1. 某个线程在等待一个锁的控制权的这段时间需要中断
    2. 需要分开处理一些wait-notify,ReentrantLock里面的Condition应用,能够控制notify哪个线程,锁可以绑定多个条件。
    3. 具有公平锁功能,每个到来的线程都将排队等候。

    友情链接: Synchronized关键字、Lock,并解释它们之间的区别


    StringBuffer是线程安全的,每次操作字符串,String会生成一个新的对象,而StringBuffer不会;StringBuilder是非线程安全的

    友情链接:String、StringBuffer与StringBuilder之间区别


    fail-fast:机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。 
    happens-before:如果两个操作之间具有happens-before 关系,那么前一个操作的结果就会对后面一个操作可见。 
    Volatile和Synchronized四个不同点: 

    同步:就是一个任务的完成需要依赖另外一个任务,只有等待被依赖的任务完成后,依赖任务才能完成。 

    友情链接:Java并发编程之volatile关键字解析


    CAS(Compare And Swap) 无锁算法: 

    友情链接:非阻塞同步算法与CAS(Compare and Swap)无锁算法


    线程池的作用: 

    友情链接:线程池原理

    友情链接:线程池原理解析


    类加载器工作机制: 

    双亲委派模型:类加载器收到类加载请求,首先将请求委派给父类加载器完成 

    友情链接:深入理解Java虚拟机笔记—双亲委派模型 

    友情链接:JVM类加载的那些事

    友情链接:JVM(1):Java 类的加载机制


    一致性哈希:

    Memcahed缓存: 

    友情链接:hashcode(),equal()方法深入解析


    Redis数据结构: String—字符串(key-value 类型) 

    友情链接: Spring + Redis 实现数据的缓存


    java自动装箱拆箱深入剖析

    谈谈Java反射机制

    如何写一个不可变类?


    索引:B+,B-,全文索引 

    友情链接:MySQL:InnoDB存储引擎的B+树索引算法

    友情链接:MySQL索引背后的数据结构及算法原理


    Spring IOC (控制反转,依赖注入)

    Spring支持三种依赖注入方式,分别是属性(Setter方法)注入,构造注入和接口注入。

    在Spring中,那些组成应用的主体及由Spring IOC容器所管理的对象被称之为Bean。

    Spring的IOC容器通过反射的机制实例化Bean并建立Bean之间的依赖关系。 

    友情链接: Spring框架IOC容器和AOP解析

    友情链接:浅谈Spring框架注解的用法分析

    友情链接:关于Spring的69个面试问答——终极列表 


    代理的共有优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性。 

    JDK和CGLIB生成动态代理类的区别: 


    SpringMVC运行原理 

    友情链接:Spring:基于注解的Spring MVC(上)

    友情链接: Spring:基于注解的Spring MVC(下) 

    友情链接:SpringMVC与Struts2区别与比较总结

    友情链接:SpringMVC与Struts2的对比 


    一个Http请求 

    设计存储海量数据的存储系统:设计一个叫“中间层”的一个逻辑层,在这个层,将数据库的海量数据抓出来,做成缓存,运行在服务器的内存中,同理,当有新的数据到来,也先做成缓存,再想办法,持久化到数据库中,这是一个简单的思路。主要的步骤是负载均衡,将不同用户的请求分发到不同的处理节点上,然后先存入缓存,定时向主数据库更新数据。读写的过程采用类似乐观锁的机制,可以一直读(在写数据的时候也可以),但是每次读的时候会有个版本的标记,如果本次读的版本低于缓存的版本,会重新读数据,这样的情况并不多,可以忍受。

    友情链接: HTTP与HTTPS的区别

    友情链接: HTTPS 为什么更安全,先看这些 

    友情链接: HTTP请求报文和HTTP响应报文

    友情链接: HTTP 请求方式: GET和POST的比较


    Session与Cookie:Cookie可以让服务端跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果Cookie很多,则无形的增加了客户端与服务端的数据传输量, 
    分布式Session框架 
    适配器模式:将一个接口适配到另一个接口,Java I/O中InputStreamReader将Reader类适配到InputStream,从而实现了字节流到字符流的准换。 
    Spring事务配置方法: 
    Mybatis 
    Servlet和Filter的区别: 

    Filter有如下几个用处: 

    实际上Filter和Servlet极其相似,区别只是Filter不能直接对用户生成响应。实际上Filter里doFilter()方法里的代码就是从多个Servlet的service()方法里抽取的通用代码,通过使用Filter可以实现更好的复用。

    Filter和Servlet的生命周期: 


    HashMap与HashTable的区别。 

    HashMap的实现机制: 

    HashMap和TreeMap区别

    友情链接: Java中HashMap和TreeMap的区别深入理解

    HashMap冲突

    友情链接: HashMap冲突的解决方法以及原理分析

    友情链接: HashMap的工作原理

    友情链接: HashMap和Hashtable的区别

    友情链接: 2种办法让HashMap线程安全


    HashMap,ConcurrentHashMap与LinkedHashMap的区别

    1. ConcurrentHashMap是使用了锁分段技术技术来保证线程安全的,锁分段技术:首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问
    2. ConcurrentHashMap 是在每个段(segment)中线程安全的
    3. LinkedHashMap维护一个双链表,可以将里面的数据按写入的顺序读出

    ConcurrentHashMap应用场景

    1:ConcurrentHashMap的应用场景是高并发,但是并不能保证线程安全,而同步的HashMap和HashMap的是锁住整个容器,而加锁之后ConcurrentHashMap不需要锁住整个容器,只需要锁住对应的Segment就好了,所以可以保证高并发同步访问,提升了效率。

    2:可以多线程写。 

    ConcurrentHashMap的应用场景是高并发,但是并不能保证线程安全,而同步的HashMap和HashTable的是锁住整个容器,而加锁之后ConcurrentHashMap不需要锁住整个容器,只需要锁住对应的segment就好了,所以可以保证高并发同步访问,提升了效率。

    ConcurrentHashMap能够保证每一次调用都是原子操作,但是并不保证多次调用之间也是原子操作。

    友情链接:Java集合—ConcurrentHashMap原理分析


    Vector和ArrayList的区别

    友情链接:Java中Vector和ArrayList的区别


    ExecutorService service = Executors…. 

    ThreadPoolExecutor源码分析

    线程池本身的状态:

    等待任务队列和工作集:

    线程池的主要状态锁:

    线程池的存活时间和大小:

    1.2 ThreadPoolExecutor 的内部工作原理 

    Executor包结构

    CopyOnWriteArrayList : 写时加锁,当添加一个元素的时候,将原来的容器进行copy,复制出一个新的容器,然后在新的容器里面写,写完之后再将原容器的引用指向新的容器,而读的时候是读旧容器的数据,所以可以进行并发的读,但这是一种弱一致性的策略。 


    Linux常用命令:cd,cp,mv,rm,ps(进程),tar,cat(查看内容),chmod,vim,find,ls


    死锁的必要条件 
    进程间的通信方式

    1. 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
    2. 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
    3. 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
    4. 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
    5. 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
    6. 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
    7. 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

    进程与线程的区别和联系

    操作系统的进程调度算法

    计算机系统的层次存储结构详解


    数据库事务是指作为单个逻辑工作单元执行的一系列操作。

    友情链接:数据库事务的四大特性以及事务的隔离级别


    MySQL数据库优化总结

    MYSQL 优化常用方法

    MySQL存储引擎--MyISAM与InnoDB区别

    关于SQL数据库中的范式


    Hibernate的一级缓存是由Session提供的,因此它只存在于Session的生命周期中,当程序调用save(),update(),saveOrUpdate()等方法 及调用查询接口list,filter,iterate时,如Session缓存中还不存在相应的对象,Hibernate会把该对象加入到一级缓存中,当Session关闭的时候缓存也会消失。 
    更新于2017/3/9

    Java I/O 总结

    JVM(8):JVM知识点总览-高级Java工程师面试必备

    细数JDK里的设计模式

    Java中创建对象的5种不同方法

    关于Java Collections的几个常见问题

    类在什么时候加载和初始化

    两个栈实现队列 两个队列实现栈


    更新于2017/3/12

    java collection.sort()根据时间排序list

    单点登录原理与简单实现


    更新于2017/3/13

    AQS详解

    Java的concurrent包

    Java 并发工具包 java.util.concurrent 用户指南


    更新于2017/6/12

    进程和线程的区别:

      进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。

      线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。

      线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。

      多进程是指操作系统能同时运行多个任务(程序)。

      多线程是指在同一程序中有多个顺序流在执行。

    在java中要想实现多线程,有三种手段,一种是继续Thread类,另外一种是实现Runable接口,还有就是实现Callable接口。


    Switch能否用string做参数?

    a.在 Java 7 之前, switch 只能支持byte,short,char,int 或者其对应的封装类以及 Enum 类型。在Java 7中,String 支持被加上了。


    Object有哪些公用方法?

    a.方法equals测试的是两个对象是否相等

    b.方法clone进行对象拷贝

    c.方法getClass返回和当前对象相关的Class对象

    d.方法notify,notifyall,wait都是用来对给定对象进行线程同步的


    Java的四种引用,强弱软虚,以及用到的场景

    a.利用软引用和弱引用解决OOM问题:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题。

    b.通过软可及对象重获方法实现Java对象的高速缓存:比如我们创建了一Employee的类,如果每次需要查询一个雇员的信息。哪怕是几秒中之前刚刚查询过的,都要重新构建一个实例,这是需要消耗很多时间的。我们可以通过软引用和 HashMap 的结合,先是保存引用方面:以软引用的方式对一个Employee对象的实例进行引用并保存该引用到HashMap 上,key 为此雇员的 id,value为这个对象的软引用,另一方面是取出引用,缓存中是否有该Employee实例的软引用,如果有,从软引用中取得。如果没有软引用,或者从软引用中得到的实例是null,重新构建一个实例,并保存对这个新建实例的软引用。

    c.强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。

    d.软引用:在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。

    e.弱引用:具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象。

    f.虚引用:顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。


    Hashcode的作用,与 equal 有什么区别?

    a.同样用于鉴定2个对象是否相等的,java集合中有 list 和 set 两类,其中 set不允许元素重复实现,那个这个不允许重复实现的方法,如果用 equal 去比较的话,如果存在1000个元素,你 new 一个新的元素出来,需要去调用1000次 equal 去逐个和他们比较是否是同一个对象,这样会大大降低效率。hashcode实际上是返回对象的存储地址,如果这个位置上没有元素,就把元素直接存储在上面,如果这个位置上已经存在元素,这个时候才去调用equal方法与新元素进行比较,相同的话就不存了,散列到其他地址上。


    Override和Overload的含义以及区别

    a.Overload顾名思义是重新加载,它可以表现类的多态性,可以是函数里面可以有相同的函数名但是参数名、返回值、类型不能相同;或者说可以改变参数、类型、返回值但是函数名字依然不变。

    b.就是ride(重写)的意思,在子类继承父类的时候子类中可以定义某方法与其父类有相同的名称和参数,当子类在调用这一函数时自动调用子类的方法,而父类相当于被覆盖(重写)了。

    具体可前往C++中重载、重写(覆盖)的区别实例分析查看


    抽象类和接口的区别

    a.一个类只能继承单个类,但是可以实现多个接口

    b.抽象类中可以有构造方法,接口中不能有构造方法

    c.抽象类中的所有方法并不一定要是抽象的,你可以选择在抽象类中实现一些基本的方法。而接口要求所有的方法都必须是抽象的

    d.抽象类中可以包含静态方法,接口中不可以

    e.抽象类中可以有普通成员变量,接口中不可以


    解析XML的几种方式的原理与特点:DOM、SAX、PULL

    a.DOM:消耗内存:先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据。这个写起来很简单,但是很消耗内存。要是数据过大,手机不够牛逼,可能手机直接死机

    b.SAX:解析效率高,占用内存少,基于事件驱动的:更加简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。

    c.PULL:与 SAX 类似,也是基于事件驱动,我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。


    wait()和sleep()的区别

    sleep来自Thread类,和wait来自Object类

    调用sleep()方法的过程中,线程不会释放对象锁。而 调用 wait 方法线程会释放对象锁

    sleep睡眠后不出让系统资源,wait让出系统资源其他线程可以占用CPU

    sleep(milliseconds)需要指定一个睡眠时间,时间一到会自动唤醒


    JAVA 中堆和栈的区别,说下java 的内存机制

    a.基本数据类型比变量和对象的引用都是在栈分配的

    b.堆内存用来存放由new创建的对象和数组

    c.类变量(static修饰的变量),程序在一加载的时候就在堆中为类变量分配内存,堆中的内存地址存放在栈中

    d.实例变量:当你使用java关键字new的时候,系统在堆中开辟并不一定是连续的空间分配给变量,是根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的”物理位置”,实例变量的生命周期–当实例变量的引用丢失后,将被GC(垃圾回收器)列入可回收“名单”中,但并不是马上就释放堆中内存

    e.局部变量: 由声明在某方法,或某代码段里(比如for循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域,内存立即释放


    JAVA多态的实现原理

    a.抽象的来讲,多态的意思就是同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)

    b.实现的原理是动态绑定,程序调用的方法在运行期才动态绑定,追溯源码可以发现,JVM 通过参数的自动转型来找到合适的办法。


    具体更多资源可前往Java后端面试总结
    各种Java面经资源

    面试的角度诠释Java工程师(一)

    面试的角度诠释Java工程师(二)

    Java面试参考指南(一)

    Java面试参考指南(二)

    阿里面试回来,想和Java程序员谈一谈

    面试心得与总结—BAT、网易、蘑菇街

    2017年小米春招内推面试面经

    历年阿里面试题汇总(2017年不断更新中)

    最近5年133个Java面试问题列表

    Java的常见误区与细节

    Java9都快发布了,Java8的十大新特性你了解多少呢?


    更多内容欢迎关注我的个人公众号

    QQ学习交流群(内有干货):

    版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/sinat_35512245/article/details/59056120
    • 本文已收录于以下专栏:
    • Java面试题总结

    java技术面试之面试题大全

    本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺(阅读本文需要有一定的Java基础)。本文的问题列表来自于www.nowcoder.com/discuss/304…在此感谢原作者的无私分享:)

    1. Java中的原始数据类型都有哪些,它们的大小及对应的封装类是什么?

    • booleanboolean类型单独使用是4个字节,在数组中又是1个字节。那虚拟机为什么要用int来代替boolean呢?为什么不用byte或short,这样不是更节省内存空间吗?实际上,使用int的原因是,对于当下32位的CPU来说,一次进行32位的数据交换更加高效。
    • byte——1 byte——Byte
    • short——2 bytes——Short
    • int——4 bytes——Integer
    • long——8 bytes——Long
    • float——4 bytes——Float
    • double——8 bytes——Double
    • char——2 bytes——Character

    2. 谈一谈”==“与”equals()"的区别。

    3. Java中的四种引用及其应用场景是什么?

    • 强引用: 通常我们使用new操作符创建一个对象时所返回的引用即为强引用

    • 软引用: 若一个对象只能通过软引用到达,那么这个对象在内存不足时会被回收,可用于图片缓存中,内存不足时系统会自动回收不再使用的Bitmap

    • 弱引用: 若一个对象只能通过弱引用到达,那么它就会被回收(即使内存充足),同样可用于图片缓存中,这时候只要Bitmap不再使用就会被回收

    • 虚引用: 虚引用是Java中最“弱”的引用,通过它甚至无法获取被引用的对象,它存在的唯一作用就是当它指向的对象回收时,它本身会被加入到引用队列中,这样我们可以知道它指向的对象何时被销毁。

    4. object中定义了哪些方法?

    5. hashCode的作用是什么?

    6. ArrayList, LinkedList, Vector的区别是什么?

    • ArrayList: 内部采用数组存储元素,支持高效随机访问,支持动态调整大小

    • LinkedList: 内部采用链表来存储元素,支持快速插入/删除元素,但不支持高效地随机访问

    • Vector: 可以看作线程安全版的ArrayList

    7. String, StringBuilder, StringBuffer的区别是什么?

    • String: 不可变的字符序列,若要向其中添加新字符需要创建一个新的String对象

    • StringBuilder: 可变字符序列,支持向其中添加新字符(无需创建新对象)

    • StringBuffer: 可以看作线程安全版的StringBuilder

    8. Map, Set, List, Queue、Stack的特点及用法。

    • Map: Java中存储键值对的数据类型都实现了这个接口,表示“映射表”。支持的两个核心操作是get(Object key)以及put(K key, V value),分别用来获取键对应的值以及向映射表中插入键值对。

    • Set: 实现了这个接口的集合类型中不允许存在重复的元素,代表数学意义上的“集合”。它所支持的核心操作有add(E e), remove(Object o)contains(Object o),分别用于添加元素,删除元素以及判断给定元素是否存在于集中。

    • List: Java中集合框架中的列表类型都实现了这个接口,表示一种有序序列。支持get(int index)add(E e)等操作。

    • Queue: Java集合框架中的队列接口,代表了“先进先出”队列。支持add(E element),remove()等操作。

    • Stack: Java集合框架中表示堆栈的数据类型,堆栈是一种“后进先出”的数据结构。支持push(E item)pop()等操作。

    更详细的说明请参考官方文档,对相关数据结构不太熟悉的同学可以参考《算法导论》或其他相关书籍。

    9. HashMap和HashTable的区别

    • HashTable是线程安全的,而HashMap不是

    • HashMap中允许存在null键和null值,而HashTable中不允许

    10. HashMap的实现原理

    11. ConcurrentHashMap的实现原理

    12. TreeMap, LinkedHashMap, HashMap的区别是什么?

    • HashMap的底层实现是散列表,因此它内部存储的元素是无序的;

    • TreeMap的底层实现是红黑树,所以它内部的元素的有序的。排序的依据是自然序或者是创建TreeMap时所提供的比较器(Comparator)对象。

    • LinkedHashMap可以看作能够记住插入元素的顺序的HashMap。

    13. Collection与Collections的区别是什么?

    • Collection是Java集合框架中的基本接口;
    • Collections是Java集合框架提供的一个工具类,其中包含了大量用于操作或返回集合的静态方法。

    14. 对于“try-catch-finally”,若try语句块中包含“return”语句,finally语句块会执行吗?**

    • 调用了System.exit()方法;

    • JVM“崩溃”了。

    15. Java中的异常层次结构

    我们可以看到Throwable类是异常层级中的基类。Error类表示内部错误,这类错误使我们无法控制的;Exception表示异常,RuntimeException及其子类属于未检查异常,这类异常包括ArrayIndexOutOfBoundsException、NullPointerException等,我们应该通过条件判断等方式语句避免未检查异常的发生。IOException及其子类属于已检查异常,编译器会检查我们是否为所有可能抛出的已检查异常提供了异常处理器,若没有则会报错。对于未检查异常,我们无需捕获(当然Java也允许我们捕获,但我们应该做的事避免未检查异常的发生)。

    16. Java面向对象的三个特征与含义三大特征:封装、继承、多态。详细介绍请戳Java面向对象三大特性

    17. Override, Overload的含义与区别

    • Override表示“重写”,是子类对父类中同一方法的重新定义

    • Overload表示“重载”,也就是定义一个与已定义方法名称相同但签名不同的新方法**

    18. 接口与抽象类的区别

    • 接口是一种约定,实现接口的类要遵循这个约定;
    • 抽象类本质上是一个类,使用抽象类的代价要比接口大。

    • 接口与抽象类的对比如下:

      • 抽象类中可以包含属性,方法(包含抽象方法与有着具体实现的方法),常量;接口只能包含常量和方法声明。

      • 抽象类中的方法和成员变量可以定义可见性(比如public、private等);而接口中的方法只能为public(缺省为public)。

      • 一个子类只能有一个父类(具体类或抽象类);而一个接口可以继承一个多个接口,一个类也可以实现多个接口。

      • 子类中实现父类中的抽象方法时,可见性可以大于等于父类中的;而接口实现类中的接口 方法的可见性只能与接口中相同(public)。

    19. 静态内部类与非静态内部类的区别

    20. Java中多态的实现原理

    21. 简述Java中创建新线程的两种方法

    • 继承Thread类(假设子类为MyThread),并重写run()方法,然后new一个MyThread对象并对其调用start()即可启动新线程。

    • 实现Runnable接口(假设实现类为MyRunnable),而后将MyRunnable对象作为参数传入Thread构造器,在得到的Thread对象上调用start()方法即可。

    22. 简述Java中进行线程同步的方法

    • volatile: Java Memory Model保证了对同一个volatile变量的写happens before对它的读;

    • synchronized: 可以来对一个代码块或是对一个方法上锁,被“锁住”的地方称为临界区,进入临界区的线程会获取对象的monitor,这样其他尝试进入临界区的线程会因无法获取monitor而被阻塞。由于等待另一个线程释放monitor而被阻塞的线程无法被中断。

    • ReentrantLock: 尝试获取锁的线程可以被中断并可以设置超时参数。

    23. 简述Java中具有哪几种粒度的锁

    24. 给出“生产者-消费者”问题的一种解决方案

    public class BlockingQueueTest {
    private int size = 20;
    private ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(size);
    public static void main(String[] args) {
    BlockingQueueTest test = new BlockingQueueTest();
    Producer producer = test.new Producer();
    Consumer consumer = test.new Consumer();
    producer.start(); consumer.start();
    }
    class Consumer extends Thread{
    @Override
    public void run() {
    while(true){
    try {
    //从阻塞队列中取出一个元素 
    queue.take();
    System.out.println("队列剩余" + queue.size() + "个元素");
    } catch (InterruptedException e) {
    }
    }
    }
    }
    class Producer extends Thread{
    @Override
    public void run() {
    while (true) {
    try {
    //向阻塞队列中插入一个元素 
    queue.put(1);
    System.out.println("队列剩余空间:" + (size - queue.size()));
    } catch (InterruptedException e) {
    }
    }
    }
    }
    }

    25. ThreadLocal的设计理念与作用

    26. concurrent包的整体架构


    27. ArrayBlockingQueue, CountDownLatch类的作用

    • CountDownLatch: 允许线程集等待直到计数器为0。适用场景: 当一个或多个线程需要等待指定数目的事件发生后再继续执行。

    • ArrayBlockingQueue: 一个基于数组实现的阻塞队列,它在构造时需要指定容量。当试图向满队列中添加元素或者从空队列中移除元素时,当前线程会被阻塞。通过阻塞队列,我们可以按以下模式来工作:工作者线程可以周期性的将中间结果放入阻塞队列中,其它线程可以取出中间结果并进行进一步操作。若工作者线程的执行比较慢(还没来得及向队列中插入元素),其他从队列中取元素的线程会等待它(试图从空队列中取元素从而阻塞);若工作者线程执行较快(试图向满队列中插入元素),则它会等待其它线程取出元素再继续执行。

    28. wait(),sleep() 的区别

    • wait(): Object类中定义的实例方法。在指定对象上调用wait方法会让当前线程进入等待状态(前提是当前线程持有该对象的monitor),此时当前线程会释放相应对象的monitor,这样一来其它线程便有机会获取这个对象的monitor了。当其它线程获取了这个对象的monitor并进行了所需操作时,便可以调用notify方法唤醒之前进入等待状态的线程。

    • sleep(): Thread类中的静态方法,作用是让当前线程进入休眠状态,以便让其他线程有机会执行。进入休眠状态的线程不会释放它所持有的锁。

    29. 线程池的用法与优势

    • 优势: 实现对线程的复用,避免了反复创建及销毁线程的开销;使用线程池统一管理线程可以减少并发线程的数目,而线程数过多往往会在线程上下文切换上以及线程同步上浪费过多时间。

    • 用法: 我们可以调用ThreadPoolExecutor的某个构造方法来自己创建一个线程池。但通常情况下我们可以使用Executors类提供给我们的静态工厂方法来更方便的创建一个线程池对象。创建了线程池对象后,我们就可以调用submit方法提交任务到线程池中去执行了;线程池使用完毕后我们要记得调用shutdown方法来关闭它。

    30. for-each与常规for循环的效率对比

    for-each能够让代码更加清晰,并且减少了出错的机会。

    for (Element e : elements) {
    doSomething(e);
    }

    使用for-each循环与常规的for循环相比,并不存在性能损失,即使对数组进行迭代也是如此。实际上,在有些场合下它还能带来微小的性能提升,因为它只计算一次数组索引的上限。

    31. 简述Java IO与NIO的区别

    • Java IO是面向流的,这意味着我们需要每次从流中读取一个或多个字节,直到读取完所有字节;NIO是面向缓冲的,也就是说会把数据读取到一个缓冲区中,然后对缓冲区中的数据进行相应处理。

    • Java IO是阻塞IO,而NIO是非阻塞IO。

    • Java NIO中存在一个称为选择器(selector)的东西,它允许你把多个通道(channel)注册到一个选择器上,然后使用一个线程来监视这些通道:若这些通道里有某个准备好可以开始进行读或写操作了,则开始对相应的通道进行读写。而在等待某通道变为可读/写期间,请求对通道进行读写操作的线程可以去干别的事情。

    32. 反射的作用与原理

    33. Java中的泛型机制

    34. Java 7与Java 8的新特性

    35. 常见设计模式

    常用的设计模式可以分为以下三大类:

    • 创建型模式: 包括工厂模式(又可进一步分为简单工厂模式、工厂方法模式、抽象工厂模式)、建造者模式、单例模式。

    • 结构型模式: 包括适配器模式、桥接模式、装饰模式、外观模式、享元模式、代理模式。

    • 行为型模式: 包括命令模式、中介者模式、观察者模式、状态模式、策略模式。

      关于每个模式具体的介绍请参考图说设计模式

    36. JNI的基本用法

    37. 动态代理的定义、应用场景及原理

    38. 注解的基本概念与使用/虚拟机传递信息,我们也可以使用注解来生成一些“模板化”的代码。

    Java 方向如何准备 BAT 技术面试答案 (汇总版)

    1.面向对象和面向过程的区别

    面向过程面向对象

    2.Java的四个基本特性(抽象、封装、继承,多态)

    抽象:就是把现实生活中的某一类东西提取出来,用程序代码表示,我们通常叫做类或者接口。抽象包括两个方面:一个是数据抽象,一个是过程抽象。数据抽象也就是对象的属性。过程抽象是对象的行为特征。

    3.重载和重写的区别

    重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。

    4.构造器Constructor是否可被override

    构造器不能被重写,不能用static修饰构造器,只能用public

    5.访问控制符public,protected,private,以及默认的区别

    private只有在本类中才能访问;

    7.String和StringBuffer、StringBuilder的区别

    可变性线程安全性性能

    8.hashCode和equals方法的关系

    equals相等,hashcode必相等;hashcode相等,equals可能不相等。

    9.抽象类和接口的区别

    语法层次设计层次跨域不同

    10.自动装箱与拆箱

    装箱:将基本类型用它们对应的引用类型包装起来;

    11.什么是泛型、为什么要使用以及泛型擦除

    泛型,即“参数化类型”。

    12.Java中的集合类及关系图

    List和Set继承自Collection接口。

    13.HashMap实现原理

    具体原理参考文章:

    14.HashTable实现原理

    具体原理参考文章:

    15.HashMap和HashTable区别

    1).HashTable的方法前面都有synchronized来同步,是线程安全的;HashMap未经同步,是非线程安全的。

    16.ArrayList和vector区别

    ArrayList和Vector都实现了List接口,都是通过数组实现的。

    17.ArrayList和LinkedList区别及使用场景

    区别使用场景

    18.Collection和Collections的区别

    java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

    19.Concurrenthashmap实现原理

    具体原理参考文章:

    20.Error、Exception区别

    Error类和Exception类的父类都是throwable类,他们的区别是:

    21.Unchecked

    Exception和Checked Exception,各列举几个#Unchecked Exception:

    Checked Exception:

    22.Java中如何实现代理机制(JDK、CGLIB)

    JDK动态代理:代理类和目标类实现了共同的接口,用到InvocationHandler接口。

    23.多线程的实现方式

    继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。

    24.线程的状态转换


    20140828202610671.jpg

    25.如何停止一个线程

    参考文章:

    26.什么是线程安全

    线程安全就是多线程访问同一代码,不会产生不确定的结果。

    27.如何保证线程安全

    对非安全的代码进行加锁控制;

    28.synchronized如何使用

    synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:

    29.synchronized和Lock的区别

    主要相同点:Lock能完成synchronized所实现的所有功能

    30.多线程如何进行信息交互

    void notify() 唤醒在此对象监视器上等待的单个线程。

    31.sleep和wait的区别(考察的方向是是否会释放锁)

    sleep()方法是Thread类中方法,而wait()方法是Object类中的方法。

    32.多线程与死锁

    死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。

    33.如何才能产生死锁

    产生死锁的四个必要条件:

    34.死锁的预防

    打破产生死锁的四个必要条件中的一个或几个,保证系统不会进入死锁状态。

    35.什么叫守护线程,用什么方法实现守护线程

    守护线程是为其他线程的运行提供服务的线程。

    36.Java线程池技术及原理

    参考文章:

    37.java并发包concurrent及常用的类

    这个内容有点多,参考文章:

    38.volatile关键字

    用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。


    39.Java中的NIO,BIO,AIO分别是什么

    BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

    40.IO和NIO区别

    一.IO是面向流的,NIO是面向缓冲区的。

    41.序列化与反序列化

    把对象转换为字节序列的过程称为对象的序列化。

    42.常见的序列化协议有哪些

    Protobuf, Thrift, Hessian, Kryo

    43.内存溢出和内存泄漏的区别

    内存溢出是指程序在申请内存时,没有足够的内存空间供其使用,出现out of

    44.Java内存模型及各个区域的OOM,如何重现OOM

    这部分内容很重要,详细阅读《深入理解Java虚拟机》,也可以详细阅读这篇文章hllvm.group.iteye.com/group/wiki/…

    45.出现OOM如何解决

    一. 可通过命令定期抓取heap dump或者启动参数OOM时自动抓取heap dump文件。

    46.用什么工具可以查出内存泄漏

    一. Memory

    47.Java内存管理及回收算法

    阅读这篇文章:www.cnblogs.com/hnrainll/ar…

    48.Java类加载器及如何加载类(双亲委派)

    阅读文章:

    49.xml解析方式

    一.DOM(JAXP区别:

    50.Statement和PreparedStatement之间的区别

    一.PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程代码片段1:代码片段2:

    51.servlet生命周期及各个方法

    参考文章www.cnblogs.com/xuekyo/arch…

    52.servlet中如何自定义filter

    参考文章www.cnblogs.com/javawebsoa/…

    53.JSP原理

    参考文章blog.csdn.net/hanxuemin12…

    54.JSP和Servlet的区别

    (1)JSP经编译后就变成了“类servlet”。

    55.JSP的动态include和静态include

    (1)动态include用jsp:include动作实现,如<jsp:include page="abc.jsp" flush="true" />,它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。会先解析所要包含的页面,解析后和主页面合并一起显示,即先编译后包含。

    56.Struts中请求处理过程

    参考文章www.cnblogs.com/liuling/p/2…

    57.MVC概念

    参考文章www.cnblogs.com/scwyh/artic…

    58.Springmvc与Struts区别

    参考文章:

    59.Hibernate/Ibatis两者的区别

    参考文章blog.csdn.net/firejuly/ar…

    60.Hibernate一级和二级缓存

    参考文章blog.csdn.net/windrui/art…

    61.简述Hibernate常见优化策略

    参考文章blog.csdn.net/shimiso/art…

    62.Springbean的加载过程(推荐看Spring的源码)

    参考文章geeekr.com/read-spring…

    63.Springbean的实例化(推荐看Spring的源码)

    参考文章geeekr.com/read-spring…

    64.Spring如何实现AOP和IOC(推荐看Spring的源码)

    参考文章www.360doc.com/content/15/…

    65.Springbean注入方式

    参考文章blessht.iteye.com/blog/116213…

    66.Spring的事务管理

    这个主题的参考文章没找到特别好的,blog.csdn.net/trigl/artic…

    67.Spring事务的传播特性

    参考文章blog.csdn.net/lfsf802/art…

    68.springmvc原理

    参考文章blog.sina.com.cn/s/blog_7ef0…

    69.springmvc用过哪些注解

    参考文章aijuans.iteye.com/blog/216014…

    70.Restful有几种请求

    参考文章,www.infoq.com/cn/articles…

    71.Restful好处

    (1)客户-服务器:客户-服务器约束背后的原则是分离关注点。通过分离用户接口和数据存储这两个关注点,改善了用户接口跨多个平台的可移植性;同时通过简化服务器组件,改善了系统的可伸缩性。

    72.Tomcat,Apache,JBoss的区别

    Apache:HTTP服务器(WEB服务器),类似IIS,可以用于建立虚拟站点,编译处理静态页面,可以支持SSL技术,支持多个虚拟主机等功能。

    73.memcached和redis的区别

    (1)性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。

    74.如何理解分布式锁

    参考文章:

    75.你知道的开源协议有哪些

    常见的开源协议有GPL、LGPL、BSD、Apache Licence

    76.json和xml区别

    XML:

    77.设计模式

    参考文章:www.cnblogs.com/beijiguangy…

    78.设计模式的六大原则

    参考文章www.uml.org.cn/sjms/201211…

    79.用一个设计模式写一段代码或画出一个设计模式的UML

    参考文章www.cnblogs.com/beijiguangy…

    80.高内聚,低耦合方面的理解

    参考文章my.oschina.net/heweipo/blo…

    81.深度优先和广度优先算法

    推荐看书籍复习!可参考文章:

    82.排序算法及对应的时间复杂度和空间复杂度

    推荐看书籍复习!可参考文章:

    83.排序算法编码实现

    参考www.cnblogs.com/liuling/p/2…

    84.查找算法

    参考sanwen8.cn/p/142Wbu5.h…

    85.B+树

    参考www.cnblogs.com/syxchina/ar…

    86.KMP算法

    推荐阅读数据复习!参考www.cnblogs.com/c-cloud/p/3…

    87.hash算法及常用的hash算法

    参考www.360doc.com/content/13/…

    88.如何判断一个单链表是否有环

    参考文章:

    89.队列、栈、链表、树、堆、图

    推荐阅读数据复习!

    90.linux常用命令

    参考www.jianshu.com/p/03cfc1a72…

    91.如何查看内存使用情况

    参考blog.csdn.net/windrui/art…

    92.Linux下如何进行进程调度

    推荐阅读书籍复习,参考文章:

    93.产生死锁的必要条件

    参考blog.sina.com.cn/s/blog_5e36…

    94.死锁预防

    参考blog.sina.com.cn/s/blog_5e36…

    95.数据库范式

    参考www.360doc.com/content/12/…

    96.数据库事务隔离级别

    参考blog.csdn.net/fg2006/arti…

    97.数据库连接池的原理

    参考blog.csdn.net/shuaihj/art…

    98.乐观锁和悲观锁

    参考www.open-open.com/lib/view/op…

    99.如何实现不同数据库的数据查询分页

    参考blog.csdn.net/yztezhl/art…

    100.SQL注入的原理,如何预防

    参考www.aliyun.com/zixun/conte…

    101.数据库索引的实现(B+树介绍、和B树、R树区别)

    参考文章:

    102.SQL性能优化

    参考文章:

    103.数据库索引的优缺点以及什么时候数据库索引失效

    参考文章:

    104.Redis的数据类型

    参考blog.csdn.net/hechurui/ar…

    105.OSI七层模型以及TCP/IP四层模型

    参考文章:

    106.HTTP和HTTPS区别

    参考:

    107.HTTP报文内容

    参考文章:

    108.get提交和post提交的区别

    参考文章:

    109.get提交是否有字节限制,如果有是在哪限制的

    参考www.jellythink.com/archives/80…

    110.TCP的三次握手和四次挥手

    阅读www.jianshu.com/p/f7d1010fa…

    111.session和cookie的区别

    参考www.cnblogs.com/shiyangxt/a…

    112.HTTP请求中Session实现原理

    参考blog.csdn.net/zhq426/arti…

    113.redirect与forward区别

    参考www.cnblogs.com/wxgblogs/p/…

    114.TCP和UDP区别

    参考www.cnblogs.com/bizhu/archi…

    115.DDos攻击及预防

    参考文章:

    最近 5 年 133 个 Java 面试问题列表

    ava 面试随着时间的改变而改变。在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来越高级,面试官问的问题也更深入。 在我初入职场的时候,类似于 Vector 与 Array 的区别、HashMap 与 Hashtable 的区别是最流行的问题,只需要记住它们,就能在面试中获得更好的机会,但这种情形已经不复存在。如今,你将会被问到许多 Java 程序员都没有看过的领域,如 NIO,设计模式,成熟的单元测试,或者那些很难掌握的知识,如并发、算法、数据结构及编码。

    由于我喜欢研究面试题,因此我已经收集了许多的面试问题,包括许多许多不同的主题。我已经为这众多的问题准备一段时间了,现在我将它们分享给你们。这里面不但包含经典的面试问题,如线程、集合、equals 和 hashcode、socket,而且还包含了 NIO、数组、字符串、Java 8 等主题。

    该列表包含了入门级 Java 程序员和多年经验的高级开发者的问题。无论你是 1、2、3、4、5、6、7、8、9 还是 10 年经验的开发者,你都能在其中找到一些有趣的问题。这里包含了一些超级容易回答的问题,同时包含经验丰富的 Java 程序员也会棘手的问题。

    当然你们也是非常幸运的,当今有许多好的书来帮助你准备 Java 面试,其中有一本我觉得特别有用和有趣的是 Markham 的 Java 程序面试揭秘(Java Programming Interview Exposed)。 这本书会告诉你一些 Java 和 JEE 面试中最重要的主题,即使你不是准备 Java 面试,也值得一读。

    该问题列表特别长,我们有各个地方的问题,所以,答案必须要短小、简洁、干脆,不拖泥带水。因此,除了这一个段落,你只会听到问题与答案,再无其他内容,没有反馈,也没有评价。为此,我已经写好了一些博文,在这些文章中你可以找到我对某些问题的观点,如我为什么喜欢这个问题,这个问题的挑战是什么?期望从面试者那获取到什么样的答案?

    这个列表有一点不同,我鼓励你采用类似的方式去分享问题和答案,这样容易温习。我希望这个列表对面试官和候选人都有很好的用处,面试官可以对这些问题上做一些改变以获取新奇和令人惊奇的元素,这对一次好的面试来说非常重要。而候选者,可以扩展和测试 Java 程序语言和平台关键领域的知识。2015 年,会更多的关注并发概念,JVM 内部,32 位 JVM 和 64 JVM的区别,单元测试及整洁的代码。我确信,如果你读过这个庞大的 Java 面试问题列表,无论是电话面试还是面对面的面试,你都能有很好的表现。

    Java 面试中的重要话题

    除了你看到的惊人的问题数量,我也尽量保证质量。我不止一次分享各个重要主题中的问题,也确保包含所谓的高级话题,这些话题很多程序员不喜欢准备或者直接放弃,因为他们的工作不会涉及到这些。Java NIO 和 JVM 底层就是最好的例子。你也可以将设计模式划分到这一类中,但是越来越多有经验的程序员了解 GOF 设计模式并应用这些模式。我也尽量在这个列表中包含 2015 年最新的面试问题,这些问题可能是来年关注的核心。为了给你一个大致的了解,下面列出这份 Java 面试问题列表包含的主题:

    多线程,并发及线程基础单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)设计原则

    120 大 Java 面试题及答案

    现在是时候给你展示我近 5 年从各种面试中收集来的 120 个问题了。我确定你在自己的面试中见过很多这些问题,很多问题你也能正确回答。

    多线程、并发及线程的基础问题

    1)Java 中能创建 volatile 数组吗?

    2)volatile 能使得一个非原子操作变成原子操作吗?

    3)volatile 修饰符的有过什么实践?

    4)volatile 类型变量提供什么保证?(答案)

    5) 10 个线程和 2 个线程的同步代码,哪个更容易写?

    6)你是如何调用 wait()方法的?使用 if 块还是循环?为什么?(答案)

    // The standard idiom for using the wait method
    synchronized (obj) {
    while (condition does not hold)
    obj.wait(); // (Releases lock, and reacquires on wakeup)
    ... // Perform action appropriate to condition
    }

    参见 Effective Java 第 69 条,获取更多关于为什么应该在循环中来调用 wait 方法的内容。

    7)什么是多线程环境下的伪共享(false sharing)?

    有经验程序员的 Java 面试题

    伪共享问题很难被发现,因为线程可能访问完全不同的全局变量,内存中却碰巧在很相近的位置上。如其他诸多的并发问题,避免伪共享的最基本方式是仔细审查代码,根据缓存行来调整你的数据结构。

    8)什么是 Busy spin?我们为什么要使用它?

    9)Java 中怎么获取一份线程 dump 文件?

    10)Swing 是线程安全的?(答案)

    11)什么是线程局部变量?(答案)

    12)用 wait-notify 写一段代码来解决生产者-消费者问题?(答案)

    13) 用 Java 写一个线程安全的单例模式(Singleton)?(答案)

    14)Java 中 sleep 方法和 wait 方法的区别?(答案)

    15)什么是不可变对象(immutable object)?Java 中怎么创建一个不可变对象?(答案)

    16)我们能创建一个包含可变对象的不可变对象吗?

    数据类型和 Java 基础面试问题

    17)Java 中应该使用什么数据类型来代表价格?(答案)

    18)怎么将 byte 转换为 String?(答案)

    19)Java 中怎样将 bytes 转换为 long 类型?

    20)我们能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?

    21)存在两个类,B 继承 A,C 继承 B,我们能将 B 转换为 C 么?如 C = (C) B;(answer答案)

    22)哪个类包含 clone 方法?是 Cloneable 还是 Object?(答案)

    23)Java 中 ++ 操作符是线程安全的吗?(答案)

    24)a = a + b 与 a += b 的区别(答案)

    25)我能在不进行强制转换的情况下将一个 double 值赋值给 long 类型的变量吗?(答案)

    26)3*0.1 == 0.3 将会返回什么?true 还是 false?(答案)

    27)int 和 Integer 哪个会占用更多的内存?(答案)

    28)为什么 Java 中的 String 是不可变的(Immutable)?(answer答案)

    29)我们能在 Switch 中使用 String 吗?(answer答案)

    30)Java 中的构造器链是什么?(answer答案)

    JVM 底层 与 GC(Garbage Collection) 的面试问题

    31)64 位 JVM 中,int 的长度是多数?

    32)Serial 与 Parallel GC之间的不同之处?(答案)

    33)32 位和 64 位的 JVM,int 类型变量的长度是多数?(答案)

    34)Java 中 WeakReference 与 SoftReference的区别?(答案)

    35)WeakHashMap 是怎么工作的?(答案)

    36)JVM 选项 -XX:+UseCompressedOops 有什么作用?为什么要使用?(答案)

    37)怎样通过 Java 程序来判断 JVM 是 32 位 还是 64 位?(答案)

    38)32 位 JVM 和 64 位 JVM 的最大堆内存分别是多数?(答案)

    39)JRE、JDK、JVM 及 JIT 之间有什么不同?(答案)

    3 年工作经验的 Java 面试题

    40)解释 Java 堆空间及 GC?(答案)

    JVM 底层面试题及答案

    41)你能保证 GC 执行吗?(答案)

    42)怎么获取 Java 程序使用的内存?堆使用的百分比?

    43)Java 中堆和栈有什么区别?(答案)

    关于内存的的面试问题和答案

    Java 基本概念面试题

    44)“a==b”和”a.equals(b)”有什么区别?(答案)

    45)a.hashCode() 有什么用?与 a.equals(b) 有什么关系?(答案)

    46)final、finalize 和 finally 的不同之处?(答案)

    47)Java 中的编译期常量是什么?使用它又什么风险?

    Java 集合框架的面试题

    这部分也包含数据结构、算法及数组的面试问题

    48) List、Set、Map 和 Queue 之间的区别(答案)

    49)poll() 方法和 remove() 方法的区别?

    50)Java 中 LinkedHashMap 和 PriorityQueue 的区别是什么?(答案)

    51)ArrayList 与 LinkedList 的不区别?(答案)

    52)用哪两种方式来实现集合的排序?(答案)

    53)Java 中怎么打印数组?(answer答案)

    54)Java 中的 LinkedList 是单向链表还是双向链表?(答案)

    55)Java 中的 TreeMap 是采用什么树实现的?(答案)

    56) Hashtable 与 HashMap 有什么不同之处?(答案)

    57)Java 中的 HashSet,内部是如何工作的?(answer答案)

    58)写一段代码在遍历 ArrayList 时移除一个元素?(答案)

    59)我们能自己写一个容器类,然后使用 for-each 循环码?

    60)ArrayList 和 HashMap 的默认大小是多数?(答案)

    在 Java 7 中,ArrayList 的默认大小是 10 个元素,HashMap 的默认大小是16个元素(必须是2的幂)。这就是 Java 7 中 ArrayList 和 HashMap 类的代码片段:

    // from ArrayList.java JDK 1.7
    private static final int DEFAULT_CAPACITY = 10;
    //from HashMap.java JDK 7
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

    61)有没有可能两个不相等的对象有有相同的 hashcode?

    62)两个相同的对象会有不同的的 hash code 吗?

    63)我们可以在 hashcode() 中使用随机数字吗?(答案)

    64)Java 中,Comparator 与 Comparable 有什么不同?(答案)

    65)为什么在重写 equals 方法的时候需要重写 hashCode 方法?(答案)

    Java IO 和 NIO 的面试题

    IO 是 Java 面试中一个非常重要的点。你应该很好掌握 Java IO,NIO,NIO2 以及与操作系统,磁盘 IO 相关的基础知识。下面是 Java IO 中经常问的问题。

    66)在我 Java 程序中,我有三个 socket,我需要多少个线程来处理?

    67)Java 中怎么创建 ByteBuffer?

    68)Java 中,怎么读写 ByteBuffer ?

    69)Java 采用的是大端还是小端?

    70)ByteBuffer 中的字节序是什么?

    71)Java 中,直接缓冲区与非直接缓冲器有什么区别?(答案)

    72)Java 中的内存映射缓存区是什么?(answer答案)

    73)socket 选项 TCP NO DELAY 是指什么?

    74)TCP 协议与 UDP 协议有什么区别?(answer答案)

    75)Java 中,ByteBuffer 与 StringBuffer有什么区别?(答案)

    Java 最佳实践的面试问题

    包含 Java 中各个部分的最佳实践,如集合,字符串,IO,多线程,错误和异常处理,设计模式等等。

    76)Java 中,编写多线程程序的时候你会遵循哪些最佳实践?(答案)

    77)说出几点 Java 中使用 Collections 的最佳实践(答案)

    78)说出至少 5 点在 Java 中使用线程的最佳实践。(答案)

    79)说出 5 条 IO 的最佳实践(答案)

    80)列出 5 个应该遵循的 JDBC 最佳实践(答案)

    81)说出几条 Java 中方法重载的最佳实践?(答案)

    Date、Time 及 Calendar 的面试题

    82)在多线程环境下,SimpleDateFormat 是线程安全的吗?(答案)

    83)Java 中如何格式化一个日期?如格式化为 ddMMyyyy 的形式?(答案)

    84)Java 中,怎么在格式化的日期中显示时区?(答案)

    85)Java 中 java.util.Date 与 java.sql.Date 有什么区别?(答案)

    86)Java 中,如何计算两个日期之间的差距?(程序)

    87)Java 中,如何将字符串 YYYYMMDD 转换为日期?(答案)

    单元测试 JUnit 面试题

    89)如何测试静态方法?(答案)

    90)怎么利用 JUnit 来测试一个方法的异常?(答案)

    91)你使用过哪个单元测试库来测试你的 Java 程序?(答案)

    92)@Before 和 @BeforeClass 有什么区别?(答案)

    编程和代码相关的面试题

    93)怎么检查一个字符串只包含数字?(解决方案)

    94)Java 中如何利用泛型写一个 LRU 缓存?(答案<)< p="">

    95)写一段 Java 程序将 byte 转换为 long?(答案)

    95)在不使用 StringBuffer 的前提下,怎么反转一个字符串?(解决方案)

    97)Java 中,怎么获取一个文件中单词出现的最高频率?(解决方案)

    98)如何检查出两个给定的字符串是反序的?(解决方案)

    99)Java 中,怎么打印出一个字符串的所有排列?(解决方案)

    100)Java 中,怎样才能打印出数组中的重复元素?(解决方案)

    101)Java 中如何将字符串转换为整数?(解决方案)

    102)在没有使用临时变量的情况如何交换两个整数变量的值?(解决方案)

    关于 OOP 和设计模式的面试题

    这部分包含 Java 面试过程中关于 SOLID 的设计原则,OOP 基础,如类,对象,接口,继承,多态,封装,抽象以及更高级的一些概念,如组合、聚合及关联。也包含了 GOF 设计模式的问题。

    103)接口是什么?为什么要使用接口而不是直接使用具体类?

    104)Java 中,抽象类与接口之间有什么不同?(答案)

    105)除了单例模式,你在生产环境中还用过什么设计模式?

    106)你能解释一下里氏替换原则吗?(答案)

    107) 什么情况下会违反迪米特法则?为什么会有这个问题?(答案)

    108)适配器模式是什么?什么时候使用?

    109)什么是“依赖注入”和“控制反转”?为什么有人使用?(答案)

    110)抽象类是什么?它与接口有什么区别?你为什么要使用过抽象类?(答案)

    111)构造器注入和 setter 依赖注入,那种方式更好?(答案)

    112)依赖注入和工程模式之间有什么不同?(答案)

    113)适配器模式和装饰器模式有什么区别?(答案)

    114)适配器模式和代理模式之前有什么不同?(答案)

    115)什么是模板方法模式?(答案)

    116)什么时候使用访问者模式?(答案)

    117)什么时候使用组合模式?(答案)

    118)继承和组合之间有什么不同?(答案)

    119)描述 Java 中的重载和重写?(答案)

    120)Java 中,嵌套公共静态类与顶级类有什么不同?(答案)

    121) OOP 中的 组合、聚合和关联有什么区别?(答案)

    122)给我一个符合开闭原则的设计模式的例子?(答案)

    123)抽象工厂模式和原型模式之间的区别?(答案)

    124)什么时候使用享元模式?(答案)

    Java 面试中其他各式各样的问题

    这部分包含 Java 中关于 XML 的面试题,JDBC 面试题,正则表达式面试题,Java 错误和异常及序列化面试题

    125)嵌套静态类与顶级类有什么区别?(答案)

    126)你能写出一个正则表达式来判断一个字符串是否是一个数字吗?(解决方案)

    127)Java 中,受检查异常 和 不受检查异常的区别?(答案)

    128)Java 中,throw 和 throws 有什么区别?(答案)

    throw 用于抛出 java.lang.Throwable 类的一个实例化对象,意思是说你可以通过关键字 throw 抛出一个 Error 或者 一个Exception,如:

    而throws 的作用是作为方法声明和签名的一部分,方法被抛出相应的异常以便调用者能处理。Java 中,任何未处理的受检查异常强制在 throws 子句中声明。

    129)Java 中,Serializable 与 Externalizable 的区别?(答案)

    130)Java 中,DOM 和 SAX 解析器有什么不同?(答案)

    131)说出 JDK 1.7 中的三个新特性?(答案)

    132)说出 5 个 JDK 1.8 引入的新特性?(答案)

    133)Java 中,Maven 和 ANT 有什么区别?(答案)

    这就是所有的面试题,如此之多,是不是?我可以保证,如果你能回答列表中的所有问题,你就可以很轻松的应付任何核心 Java 或者高级 Java 面试。虽然,这里没有涵盖 Servlet、JSP、JSF、JPA,JMS,EJB 及其它 Java EE 技术,也没有包含主流的框架如 Spring MVC,Struts 2.0,Hibernate,也没有包含 SOAP 和 RESTful web service,但是这份列表对做 Java 开发的、准备应聘 Java web 开发职位的人还是同样有用的,因为所有的 Java 面试,开始的问题都是 Java 基础和 JDK API 相关的。如果你认为我这里有任何应该在这份列表中而被我遗漏了的 Java 流行的问题,你可以自由的给我建议。我的目的是从最近的面试中创建一份最新的、最优的 Java 面试问题列表。


    版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/lijizhi19950123/article/details/77679489

    69 个经典 Spring 面试题和答案

    Spring 概述

    1. 什么是spring?

    Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯。

    2. 使用Spring框架的好处是什么?

    • 轻量:Spring 是轻量的,基本的版本大约2MB。

    • 控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。

    • 面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。

    • 容器:Spring 包含并管理应用中对象的生命周期和配置。

    • MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。

    • 事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。

    • 异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。

    3. Spring由哪些模块组成?

    以下是Spring 框架的基本模块:

    • Core module

    • Bean module

    • Context module

    • Expression Language module

    • JDBC module

    • ORM module

    • OXM module

    • Java Messaging Service(JMS) module

    • Transaction module

    • Web module

    • Web-Servlet module

    • Web-Struts module

    • Web-Portlet module

    4. 核心容器(应用上下文) 模块。

    这是基本的Spring模块,提供spring 框架的基础功能,BeanFactory 是 任何以spring为基础的应用的核心。Spring 框架建立在此模块之上,它使Spring成为一个容器。

    5. BeanFactory – BeanFactory 实现举例。

    Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从正真的应用代码中分离。

    最常用的BeanFactory 实现是XmlBeanFactory 类。

    6. XMLBeanFactory

    最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory ,它根据XML文件中的定义加载beans。该容器从XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用。

    7. 解释AOP模块

    AOP模块用于发给我们的Spring应用做面向切面的开发, 很多支持由AOP联盟提供,这样就确保了Spring和其他AOP框架的共通性。这个模块将元数据编程引入Spring。

    8. 解释JDBC抽象和DAO模块。

    通过使用JDBC抽象和DAO模块,保证数据库代码的简洁,并能避免数据库资源错误关闭导致的问题,它在各种不同的数据库的错误信息之上,提供了一个统一的异常访问层。它还利用Spring的AOP 模块给Spring应用中的对象提供事务管理服务。

    9. 解释对象/关系映射集成模块。

    Spring 通过提供ORM模块,支持我们在直接JDBC之上使用一个对象/关系映射映射(ORM)工具,Spring 支持集成主流的ORM框架,如Hiberate,JDO和 iBATIS SQL Maps。Spring的事务管理同样支持以上所有ORM框架及JDBC。

    10. 解释WEB 模块。

    Spring的WEB模块是构建在application context 模块基础之上,提供一个适合web应用的上下文。这个模块也包括支持多种面向web的任务,如透明地处理多个文件上传请求和程序级请求参数的绑定到你的业务对象。它也有对Jakarta Struts的支持。

    12. Spring配置文件

    Spring配置文件是个XML 文件,这个文件包含了类信息,描述了如何配置它们,以及如何相互调用。

    13. 什么是Spring IOC 容器?

    Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。

    14. IOC的优点是什么?

    IOC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。

    15. ApplicationContext通常的实现是什么?

    • FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。

    • ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。

    • WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。

    16. Bean 工厂和 Application contexts 有什么区别?

    Application contexts提供一种方法处理文本消息,一个通常的做法是加载文件资源(比如镜像),它们可以向注册为监听器的bean发布事件。另外,在容器或容器内的对象上执行的那些不得不由bean工厂以程序化方式处理的操作,可以在Application contexts中以声明的方式处理。Application contexts实现了MessageSource接口,该接口的实现以可插拔的方式提供获取本地化消息的方法。

    17. 一个Spring的应用看起来象什么?

    • 一个定义了一些功能的接口。

    • 这实现包括属性,它的Setter , getter 方法和函数等。

    • Spring AOP。

    • Spring 的XML 配置文件。

    • 使用以上功能的客户端程序。

    依赖注入

    18. 什么是Spring的依赖注入?

    依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。

    19. 有哪些不同类型的IOC(依赖注入)方式?

    • 构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。

    • Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。

    20. 哪种依赖注入方式你建议使用,构造器注入,还是 Setter方法注入?

    你两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖。

    Spring Beans

    21.什么是Spring beans?

    Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中<bean/> 的形式定义。

    Spring 框架定义的beans都是单件beans。在bean tag中有个属性”singleton”,如果它被赋为TRUE,bean 就是单件,否则就是一个 prototype bean。默认是TRUE,所以所有在Spring框架中的beans 缺省都是单件。

    22. 一个 Spring Bean 定义 包含什么?

    一个Spring Bean 的定义包含容器必知的所有配置元数据,包括如何创建一个bean,它的生命周期详情及它的依赖。

    23. 如何给Spring 容器提供配置元数据?

    这里有三种重要的方法给Spring 容器提供配置元数据。

    XML配置文件。

    基于注解的配置。

    基于java的配置。

    24. 你怎样定义类的作用域?

    当定义一个<bean> 在Spring里,我们还能给这个bean声明一个作用域。它可以通过bean 定义中的scope属性来定义。如,当Spring要在需要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype。另一方面,一个bean每次使用的时候必须返回同一个实例,这个bean的scope 属性 必须设为 singleton。

    25. 解释Spring支持的几种bean的作用域。

    Spring框架支持以下五种bean的作用域:

    • singleton : bean在每个Spring ioc 容器中只有一个实例。

    • prototype:一个bean的定义可以有多个实例。

    • request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。

    • session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

    • global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

    缺省的Spring bean 的作用域是Singleton.

    26. Spring框架中的单例bean是线程安全的吗?

    不,Spring框架中的单例bean不是线程安全的。

    27. 解释Spring框架中bean的生命周期。

    • Spring容器 从XML 文件中读取bean的定义,并实例化bean。

    • Spring根据bean的定义填充所有的属性。

    • 如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。

    • 如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。

    • 如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。

    • 如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。

    • 如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。

    • 如果bean实现了 DisposableBean,它将调用destroy()方法。

    28. 哪些是重要的bean生命周期方法? 你能重载它们吗?

    有两个重要的bean 生命周期方法,第一个是setup , 它是在容器加载bean的时候被调用。第二个方法是 teardown 它是在容器卸载类的时候被调用。

    The bean 标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)。

    29. 什么是Spring的内部bean?

    当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean,为了定义inner bean,在Spring 的 基于XML的 配置元数据中,可以在 <property/>或 <constructor-arg/> 元素内使用<bean/> 元素,内部bean通常是匿名的,它们的Scope一般是prototype。

    30. 在 Spring中如何注入一个java集合?

    Spring提供以下几种集合的配置元素:

    • <list>类型用于注入一列值,允许有相同的值。

    • <set> 类型用于注入一组值,不允许有相同的值。

    • <map> 类型用于注入一组键值对,键和值都可以为任意类型。

    • <props>类型用于注入一组键值对,键和值都只能为String类型。

    31. 什么是bean装配?

    装配,或bean 装配是指在Spring 容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起。

    32. 什么是bean的自动装配?

    Spring 容器能够自动装配相互合作的bean,这意味着容器不需要<constructor-arg>和<property>配置,能通过Bean工厂自动处理bean之间的协作。

    33. 解释不同方式的自动装配 。

    有五种自动装配的方式,可以用来指导Spring容器用自动装配方式来进行依赖注入。

    • no:默认的方式是不进行自动装配,通过显式设置ref 属性来进行装配。

    • byName:通过参数名 自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该bean的属性具有相同名字的bean。

    • byType::通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。

    • constructor:这个方式类似于byType, 但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。

    • autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。

    34.自动装配有哪些局限性 ?

    自动装配的局限性是:

    • 重写: 你仍需用 <constructor-arg>和 <property> 配置来定义依赖,意味着总要重写自动装配。

    • 基本数据类型:你不能自动装配简单的属性,如基本数据类型,String字符串,和类。

    • 模糊特性:自动装配不如显式装配精确,如果有可能,建议使用显式装配。

    35. 你可以在Spring中注入一个null 和一个空字符串吗?

    可以。

    Spring注解

    36. 什么是基于Java的Spring注解配置? 给一些注解的例子.

    基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。

    以@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。

    37. 什么是基于注解的容器配置?

    相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。

    开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。

    38. 怎样开启注解装配?

    注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置 <context:annotation-config/>元素。

    39. @Required 注解

    这个注解表明bean的属性必须在配置的时候设置,通过一个bean定义的显式的属性值或通过自动装配,若@Required注解的bean属性未被设置,容器将抛出BeanInitializationException。

    40. @Autowired 注解

    @Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和@Required一样,修饰setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法。

    41. @Qualifier 注解

    当有多个相同类型的bean却只有一个需要自动装配时,将@Qualifier 注解和@Autowire 注解结合使用以消除这种混淆,指定需要装配的确切的bean。

    Spring数据访问

    42.在Spring框架中如何更有效地使用JDBC?

    使用SpringJDBC 框架,资源管理和错误处理的代价都会被减轻。所以开发者只需写statements 和 queries从数据存取数据,JDBC也可以在Spring框架提供的模板类的帮助下更有效地被使用,这个模板叫JdbcTemplate (例子见这里here)

    43. JdbcTemplate

    JdbcTemplate 类提供了很多便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理。

    44. Spring对DAO的支持

    Spring对数据访问对象(DAO)的支持旨在简化它和数据访问技术如JDBC,Hibernate or JDO 结合使用。这使我们可以方便切换持久层。编码时也不用担心会捕获每种技术特有的异常。

    45. 使用Spring通过什么方式访问Hibernate?

    在Spring中有两种方式访问Hibernate:

    • 控制反转 Hibernate Template和 Callback。

    • 继承 HibernateDAOSupport提供一个AOP 拦截器。

    46. Spring支持的ORM

    Spring支持以下ORM:

    • Hibernate

    • iBatis

    • JPA (Java Persistence API)

    • TopLink

    • JDO (Java Data Objects)

    • OJB

    47.如何通过HibernateDaoSupport将Spring和Hibernate结合起来?

    用Spring的 SessionFactory 调用 LocalSessionFactory。集成过程分三步:

    • 配置the Hibernate SessionFactory。

    • 继承HibernateDaoSupport实现一个DAO。

    • 在AOP支持的事务中装配。

    48. Spring支持的事务管理类型

    Spring支持两种类型的事务管理:

    • 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。

    • 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。

    49. Spring框架的事务管理有哪些优点?

    • 它为不同的事务API 如 JTA,JDBC,Hibernate,JPA 和JDO,提供一个不变的编程模式。

    • 它为编程式事务管理提供了一套简单的API而不是一些复杂的事务API如

    • 它支持声明式事务管理。

    • 它和Spring各种数据访问抽象层很好得集成。

    50. 你更倾向用那种事务管理类型?

    大多数Spring框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式允许你通过代码控制事务)少了一点灵活性。

    Spring面向切面编程(AOP)

    51. 解释AOP

    面向切面的编程,或AOP, 是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。

    52. Aspect 切面

    AOP核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。比如,一个日志模块可以被称作日志的AOP切面。根据需求的不同,一个应用程序可以有若干切面。在Spring AOP中,切面通过带有@Aspect注解的类实现。

    52. 在Spring AOP 中,关注点和横切关注的区别是什么?

    关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。

    横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。

    54. 连接点

    连接点代表一个应用程序的某个位置,在这个位置我们可以插入一个AOP切面,它实际上是个应用程序执行Spring AOP的位置。

    55. 通知

    通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。

    Spring切面可以应用五种类型的通知:

    • before:前置通知,在一个方法执行前被调用。

    • after: 在方法执行之后调用的通知,无论方法执行是否成功。

    • after-returning: 仅当方法成功完成后执行的通知。

    • after-throwing: 在方法抛出异常退出时执行的通知。

    • around: 在方法执行之前和之后调用的通知。

    56. 切点

    切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。

    57. 什么是引入?

    引入允许我们在已存在的类中增加新的方法和属性。

    58. 什么是目标对象?

    被一个或者多个切面所通知的对象。它通常是一个代理对象。也指被通知(advised)对象。

    59. 什么是代理?

    代理是通知目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。

    60. 有几种不同类型的自动代理?

    BeanNameAutoProxyCreator

    DefaultAdvisorAutoProxyCreator

    Metadata autoproxying

    61. 什么是织入。什么是织入应用的不同点?

    织入是将切面和到其他应用类型或对象连接或创建一个被通知对象的过程。

    织入可以在编译时,加载时,或运行时完成。

    62. 解释基于XML Schema方式的切面实现。

    在这种情况下,切面由常规类以及基于XML的配置实现。

    63. 解释基于注解的切面实现

    在这种情况下(基于@AspectJ的实现),涉及到的切面声明的风格与带有java5标注的普通java类一致。

    Spring 的MVC

    64. 什么是Spring的MVC框架?

    Spring 配备构建Web 应用的全功能MVC框架。Spring可以很便捷地和其他MVC框架集成,如Struts,Spring 的MVC框架用控制反转把业务对象和控制逻辑清晰地隔离。它也允许以声明的方式把请求参数和业务对象绑定。

    65. DispatcherServlet

    Spring的MVC框架是围绕DispatcherServlet来设计的,它用来处理所有的HTTP请求和响应。

    66. WebApplicationContext

    WebApplicationContext 继承了ApplicationContext 并增加了一些WEB应用必备的特有功能,它不同于一般的ApplicationContext ,因为它能处理主题,并找到被关联的servlet。

    67. 什么是Spring MVC框架的控制器?

    控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现。控制器解析用户输入并将其转换为一个由视图呈现给用户的模型。Spring用一个非常抽象的方式实现了一个控制层,允许用户创建多种用途的控制器。

    68. @Controller 注解

    该注解表明该类扮演控制器的角色,Spring不需要你继承任何其他控制器基类或引用Servlet API。

    69. @RequestMapping 注解

    该注解是用来映射一个URL到一个类或一个特定的方处理法上。

     

    java常见面试题

    多线程、并发及线程的基础问题

    1)Java 中能创建 Volatile 数组吗?

    2)volatile 能使得一个非原子操作变成原子操作吗?

    3)volatile 修饰符的有过什么实践?

    4)volatile 类型变量提供什么保证?(答案)

    5) 10 个线程和 2 个线程的同步代码,哪个更容易写?

    6)你是如何调用 wait()方法的?使用 if 块还是循环?为什么?(答案)

    // The standard idiom for using the wait method
    synchronized (obj) {
    while (condition does not hold)
    obj.wait(); // (Releases lock, and reacquires on wakeup)
    ... // Perform action appropriate to condition
    }

    参见 Effective Java 第 69 条,获取更多关于为什么应该在循环中来调用 wait 方法的内容。

    7)什么是多线程环境下的伪共享(false sharing)?

    有经验程序员的 Java 面试题

    伪共享问题很难被发现,因为线程可能访问完全不同的全局变量,内存中却碰巧在很相近的位置上。如其他诸多的并发问题,避免伪共享的最基本方式是仔细审查代码,根据缓存行来调整你的数据结构。

    8)什么是 Busy spin?我们为什么要使用它?

    9)Java 中怎么获取一份线程 dump 文件?

    10)Swing 是线程安全的?(答案)

    11)什么是线程局部变量?(答案)ThreadLocal 类来支持线程局部变量,是一种实现线程安全的方式。但是在管理环境下(如 web 服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期都要长。任何线程局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险。

    12)用 wait-notify 写一段代码来解决生产者-消费者问题?(答案)

    13) 用 Java 写一个线程安全的单例模式(Singleton)?(答案)

    14)Java 中 sleep 方法和 wait 方法的区别?(答案)

    15)什么是不可变对象(immutable object)?Java 中怎么创建一个不可变对象?(答案)

    16)我们能创建一个包含可变对象的不可变对象吗?

    数据类型和 Java 基础面试问题

    17)Java 中应该使用什么数据类型来代表价格?(答案)

    18)怎么将 byte 转换为 String?(答案)

    19)Java 中怎样将 bytes 转换为 long 类型?

    20)我们能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?

    21)存在两个类,B 继承 A,C 继承 B,我们能将 B 转换为 C 么?如 C = (C) B;(answer答案)

    22)哪个类包含 clone 方法?是 Cloneable 还是 Object?(答案)

    23)Java 中 ++ 操作符是线程安全的吗?(答案)

    24)a = a + b 与 a += b 的区别(答案)

    25)我能在不进行强制转换的情况下将一个 double 值赋值给 long 类型的变量吗?(答案)

    26)3*0.1 == 0.3 将会返回什么?true 还是 false?(答案)浮点数不能完全精确的表示出来。

    27)int 和 Integer 哪个会占用更多的内存?(答案)

    28)为什么 Java 中的 String 是不可变的(Immutable)?(answer答案)

    29)我们能在 Switch 中使用 String 吗?(answer答案)

    30)Java 中的构造器链是什么?(answer答案)

    JVM 底层 与 GC(Garbage Collection) 的面试问题

    31)64 位 JVM 中,int 的长度是多数?

    32)Serial 与 Parallel GC之间的不同之处?(答案)

    33)32 位和 64 位的 JVM,int 类型变量的长度是多数?(答案)

    34)Java 中 WeakReference 与 SoftReference的区别?(答案)

    35)WeakHashMap 是怎么工作的?(答案)

    36)JVM 选项 -XX:+UseCompressedOops 有什么作用?为什么要使用?(答案)

    37)怎样通过 Java 程序来判断 JVM 是 32 位 还是 64 位?(答案)

    38)32 位 JVM 和 64 位 JVM 的最大堆内存分别是多数?(答案)

    39)JRE、JDK、JVM 及 JIT 之间有什么不同?(答案)

    3 年工作经验的 Java 面试题

    40)解释 Java 堆空间及 GC?(答案)

    JVM 底层面试题及答案

    41)你能保证 GC 执行吗?(答案)

    42)怎么获取 Java 程序使用的内存?堆使用的百分比?

    43)Java 中堆和栈有什么区别?(答案)

    关于内存的的面试问题和答案

    Java 基本概念面试题

    44)“a==b”和”a.equals(b)”有什么区别?(答案)

    45)a.hashCode() 有什么用?与 a.equals(b) 有什么关系?(答案)

    46)final、finalize 和 finally 的不同之处?(答案)

    47)Java 中的编译期常量是什么?使用它又什么风险?

    Java 集合框架的面试题

    这部分也包含数据结构、算法及数组的面试问题

    48) List、Set、Map 和 Queue 之间的区别(答案)

    49)poll() 方法和 remove() 方法的区别?

    50)Java 中 LinkedHashMap 和 PriorityQueue 的区别是什么?(答案)

    51)ArrayList 与 LinkedList 的不区别?(答案)

    52)用哪两种方式来实现集合的排序?(答案)

    53)Java 中怎么打印数组?(answer答案)

    54)Java 中的 LinkedList 是单向链表还是双向链表?(答案)

    55)Java 中的 TreeMap 是采用什么树实现的?(答案)

    56) Hashtable 与 HashMap 有什么不同之处?(答案)

    57)Java 中的 HashSet,内部是如何工作的?(answer答案)

    58)写一段代码在遍历 ArrayList 时移除一个元素?(答案)

    59)我们能自己写一个容器类,然后使用 for-each 循环码?

    60)ArrayList 和 HashMap 的默认大小是多数?(答案)

    在 Java 7 中,ArrayList 的默认大小是 10 个元素,HashMap 的默认大小是16个元素(必须是2的幂)。这就是 Java 7 中 ArrayList 和 HashMap 类的代码片段:

    // from ArrayList.java JDK 1.7
    private static final int DEFAULT_CAPACITY = 10;
    //from HashMap.java JDK 7
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

    61)有没有可能两个不相等的对象有有相同的 hashcode?

    62)两个相同的对象会有不同的的 hash code 吗?

    63)我们可以在 hashcode() 中使用随机数字吗?(答案)

    64)Java 中,Comparator 与 Comparable 有什么不同?(答案)

    65)为什么在重写 equals 方法的时候需要重写 hashCode 方法?(答案)

    Java IO 和 NIO 的面试题

    IO 是 Java 面试中一个非常重要的点。你应该很好掌握 Java IO,NIO,NIO2 以及与操作系统,磁盘 IO 相关的基础知识。下面是 Java IO 中经常问的问题。

    66)在我 Java 程序中,我有三个 socket,我需要多少个线程来处理?

    67)Java 中怎么创建 ByteBuffer?

    68)Java 中,怎么读写 ByteBuffer ?

    69)Java 采用的是大端还是小端?

    70)ByteBuffer 中的字节序是什么?

    71)Java 中,直接缓冲区与非直接缓冲器有什么区别?(答案)

    72)Java 中的内存映射缓存区是什么?(answer答案)

    73)socket 选项 TCP NO DELAY 是指什么?

    74)TCP 协议与 UDP 协议有什么区别?(answer答案)

    75)Java 中,ByteBuffer 与 StringBuffer有什么区别?(答案)

    Java 最佳实践的面试问题

    包含 Java 中各个部分的最佳实践,如集合,字符串,IO,多线程,错误和异常处理,设计模式等等。

    76)Java 中,编写多线程程序的时候你会遵循哪些最佳实践?(答案)

    77)说出几点 Java 中使用 Collections 的最佳实践(答案)

    78)说出至少 5 点在 Java 中使用线程的最佳实践。(答案)

    79)说出 5 条 IO 的最佳实践(答案)

    80)列出 5 个应该遵循的 JDBC 最佳实践(答案)

    81)说出几条 Java 中方法重载的最佳实践?(答案)

    Date、Time 及 Calendar 的面试题

    82)在多线程环境下,SimpleDateFormat 是线程安全的吗?(答案)

    83)Java 中如何格式化一个日期?如格式化为 ddMMyyyy 的形式?(答案)

    84)Java 中,怎么在格式化的日期中显示时区?(答案)

    85)Java 中 java.util.Date 与 java.sql.Date 有什么区别?(答案)

    86)Java 中,如何计算两个日期之间的差距?(程序)

    87)Java 中,如何将字符串 YYYYMMDD 转换为日期?(答案)

    单元测试 JUnit 面试题

    89)如何测试静态方法?(答案)

    90)怎么利用 JUnit 来测试一个方法的异常?(答案)

    91)你使用过哪个单元测试库来测试你的 Java 程序?(答案)

    92)@Before 和 @BeforeClass 有什么区别?(答案)

    编程和代码相关的面试题

    93)怎么检查一个字符串只包含数字?(解决方案)

    94)Java 中如何利用泛型写一个 LRU 缓存?(答案<)

    95)写一段 Java 程序将 byte 转换为 long?(答案)

    95)在不使用 StringBuffer 的前提下,怎么反转一个字符串?(解决方案)

    97)Java 中,怎么获取一个文件中单词出现的最高频率?(解决方案)

    98)如何检查出两个给定的字符串是反序的?(解决方案)

    99)Java 中,怎么打印出一个字符串的所有排列?(解决方案)

    100)Java 中,怎样才能打印出数组中的重复元素?(解决方案)

    101)Java 中如何将字符串转换为整数?(解决方案)

    102)在没有使用临时变量的情况如何交换两个整数变量的值?(解决方案)

    关于 OOP 和设计模式的面试题

    这部分包含 Java 面试过程中关于 SOLID 的设计原则,OOP 基础,如类,对象,接口,继承,多态,封装,抽象以及更高级的一些概念,如组合、聚合及关联。也包含了 GOF 设计模式的问题。

    103)接口是什么?为什么要使用接口而不是直接使用具体类?

    104)Java 中,抽象类与接口之间有什么不同?(答案)

    105)除了单例模式,你在生产环境中还用过什么设计模式?

    106)你能解释一下里氏替换原则吗?(答案)

    107) 什么情况下会违反迪米特法则?为什么会有这个问题?(答案)

    108)适配器模式是什么?什么时候使用?

    109)什么是“依赖注入”和“控制反转”?为什么有人使用?(答案)

    110)抽象类是什么?它与接口有什么区别?你为什么要使用过抽象类?(答案)

    111)构造器注入和 setter 依赖注入,那种方式更好?(答案)

    112)依赖注入和工程模式之间有什么不同?(答案)

    113)适配器模式和装饰器模式有什么区别?(答案)

    114)适配器模式和代理模式之前有什么不同?(答案)

    115)什么是模板方法模式?(答案)

    116)什么时候使用访问者模式?(答案)

    117)什么时候使用组合模式?(答案)

    118)继承和组合之间有什么不同?(答案)

    119)描述 Java 中的重载和重写?(答案)

    120)Java 中,嵌套公共静态类与顶级类有什么不同?(答案)

    121) OOP 中的 组合、聚合和关联有什么区别?(答案)

    122)给我一个符合开闭原则的设计模式的例子?(答案)

    123)抽象工厂模式和原型模式之间的区别?(答案)

    124)什么时候使用享元模式?(答案)

    Java 面试中其他各式各样的问题

    这部分包含 Java 中关于 XML 的面试题,JDBC 面试题,正则表达式面试题,Java 错误和异常及序列化面试题

    125)嵌套静态类与顶级类有什么区别?(答案)

    126)你能写出一个正则表达式来判断一个字符串是否是一个数字吗?(解决方案)

    127)Java 中,受检查异常 和 不受检查异常的区别?(答案)

    128)Java 中,throw 和 throws 有什么区别?(答案)

    throw 用于抛出 java.lang.Throwable 类的一个实例化对象,意思是说你可以通过关键字 throw 抛出一个 Error 或者 一个Exception,如:

    而throws 的作用是作为方法声明和签名的一部分,方法被抛出相应的异常以便调用者能处理。Java 中,任何未处理的受检查异常强制在 throws 子句中声明。

    129)Java 中,Serializable 与 Externalizable 的区别?(答案)

    130)Java 中,DOM 和 SAX 解析器有什么不同?(答案)

    131)说出 JDK 1.7 中的三个新特性?(答案)

    132)说出 5 个 JDK 1.8 引入的新特性?(答案)

    133)Java 中,Maven 和 ANT 有什么区别?(答案)

    这就是所有的面试题,如此之多,是不是?我可以保证,如果你能回答列表中的所有问题,你就可以很轻松的应付任何核心 Java 或者高级 Java 面试。虽然,这里没有涵盖 Servlet、JSP、JSF、JPA,JMS,EJB 及其它 Java EE 技术,也没有包含主流的框架如 Spring MVC,Struts 2.0,Hibernate,也没有包含 SOAP 和 RESTful web service,但是这份列表对做 Java 开发的、准备应聘 Java web 开发职位的人还是同样有用的,因为所有的 Java 面试,开始的问题都是 Java 基础和 JDK API 相关的。如果你认为我这里有任何应该在这份列表中而被我遗漏了的 Java 流行的问题,你可以自由的给我建议。我的目的是从最近的面试中创建一份最新的、最优的 Java 面试问题列表。

    最后

    以上就是开放薯片为你收集整理的面试题综合JVM 知识开源框架知识操作系统多线程TCP 与 HTTP架构设计与分布式算法数据库知识消息队列Redis,Memcached搜索MQ分布式系统事务一致性解决方案redis分布式缓存多线程的40个面试题总结Servlet面试题归纳Redis面试题及分布式集群高可用分布式集群spring常见的面试题springmvc和mybatis面试题(含答案)Hibernate常见面试题对于Dubbo一些面试题自己的答案rmi://memcached://redis://1)Multicast 注册的全部内容,希望文章能够帮你解决面试题综合JVM 知识开源框架知识操作系统多线程TCP 与 HTTP架构设计与分布式算法数据库知识消息队列Redis,Memcached搜索MQ分布式系统事务一致性解决方案redis分布式缓存多线程的40个面试题总结Servlet面试题归纳Redis面试题及分布式集群高可用分布式集群spring常见的面试题springmvc和mybatis面试题(含答案)Hibernate常见面试题对于Dubbo一些面试题自己的答案rmi://memcached://redis://1)Multicast 注册所遇到的程序开发问题。

    如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

    本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
    点赞(206)

    评论列表共有 0 条评论

    立即
    投稿
    返回
    顶部