Java高频面试题附带答案

题目都来自网上收集,如果对你有用请点个关注支持一下,刚开博客有什么不妥的可以留言讨论,我也在准备秋招;

后续还会整理一些面经分享出来,一起加油!。

微信公众号:Java成长录

老铁们可以关注下,书籍,知识点,视频链接都会陆续更新,也是自己梳理学习的一个过程。


一、面试整体流程
1.1 简单的自我介绍
我是 xxxx,工作 xxx 年.我先后在 xxxx 公司、yyyy 公司工作。先后做个 xxxx 项目、yyyy
项目。
1.2 你简单介绍一下 xxxx 项目
为了解决 xxxx 问题,开发了一套 xxxx 系统,该系统主要有那些部分组成。简单介绍项
目的整体架构。参与某个模块的开发。就要求你说一下这个模块的业务及设计。
1.3 会问一下 JAVA 的专业技能
后面详细讲解
1.4 你还有什么需要询问我的吗
公司要做的项目?项目中会使用一下什么技术?
注意:经历了多轮面试后,对于你的自我介绍和项目项目经验面试官就不太关心了。
你说一下你最擅长的什么?你简单说一下?
最终技术面试完成后,都会让你回家等消息,或者等 hr 来和你谈薪资和福利。
二、java 的专业技能
2.1 java 的基础部分
2.1.1 简单讲一下 java 的跨平台原理
由于各操作系统(windows,liunx 等)支持的指令集,不是完全一致的。就会让我们
的程序在不同的操作系统上要执行不同程序代码。Java 开发了适用于不同操作系统及位数
的 java 虚拟机来屏蔽个系统之间的差异,提供统一的接口。对于我们 java 开发者而言,你
只需要在不同的系统上安装对应的不同 java 虚拟机、这时你的 java 程序只要遵循 java 规范,
就可以在所有的操作系统上面运行 java 程序了。
Java 通过不同的系统、不同版本、不同位数的 java 虚拟机(jvm),来屏蔽不同的系统指令集差
异而对外体统统一的接口(java API),对于我们普通的 java 开发者而言,只需要按照接口开发
即可。如果我系统需要部署到不同的环境时,只需在系统上面按照对应版本的虚拟机即可。
2.2.2 搭建一个 java 开发环境的步骤
Java 开发环境需要些什么?
1、适用于我们开发环境的 jdk
2、对应开发环境 eclipse
3、还需要 web 服务器(tomcat)
一、下载对应组件
二、安装
Jdk,安装正常流程安装即可,配置我们的 JAVA_HOME,因为后面的 eclispe 和 tomcat 会依
赖于这个变量.
Eclispe 正常解压就 ok,设置 workspace 的默认编码
Tomcat 正常解压就 ok,把 tomcat 集成到 eclispe 中,安装插件就 OK。
.......
Svn/git


2.1.3 讲一下 java 中 int 数据占几个字节
Java 中有几种基本数据类型?8 种
Int 占 4 个字节,32 位
Boolean 1 位


2.1.4 面向对象的特征有哪些方面
有四大基本特征:封装、抽象、继承、多态
面向对象的封装性,即将对象封装成一个高度自治和相对封闭的个体,对象状态(属性)由
这个对象自己的行为(方法)来读取和改变。
张三这个人,他的姓名等属性,要有自己提供的获取或改变的方法来操作。private name setName
getName
抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些
事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目
标有关的方面。 就是把现实生活中的对象,抽象为类。
在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的
类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的
需要,这就是继承。遗产继承
多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时
并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变
量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
Object obj = new xxx();
UserDao userDao = new UserDaoJdbcImpl();
UserDao userDao = new UserDaoHibernateImpl();
靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法
在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个
对象的方法,而不是引用变量的类型中定义的方法。
原则:回答比较抽象问题的时候,要举例说明


2.1.5 有了基本数据类型,为什么还需要包装类型?
基本数据类型,java 中提供了 8 中基本的数据类型。boolean int float 等
包装类型:每一个基本的数据类型都会一一对应一个包装类型。
boolean ----->Boolean
Int -------->Integer
装箱和拆箱
装箱:把基本的数据类型转换成对应的包装类型.
Integer .valueOf(1)
Integer i = 1;自动装箱,实际上在编译时会调用 Integer .valueOf 方法来装箱
拆箱:就是把包装类型转换为基本数据类型.基本数据类型 名称 = 对应的包装类型。
Integer i = 1;
int j = i;//自动拆箱//int j = i=intValue();手动拆箱
自动拆箱:实际上会在编译调用 intValue
Java 是一个面向对象的语言,而基本的数据类型,不具备面向对象的特性。
null Integer--->null int---->0 用 Integer 和 int 分别表示 Person 这个类的 ID
Max 最大值
min 最小值
缓存值:对象缓存,Integer i=1; integer j= 1;i ==j


2.1.6、说一下"=="和 equals 方法究竟有什么区别?
非常经典的一个面试题?先说清楚一个,再来说另一个?
==用来判断两个变量之间的的值是否相等。变量就可以分为基本数据类型变量,引用类型。
如果是基本数据类型的变量直接比较值而引用类型要比较对应的引用的内存的首地址。
equals 用来比较两个对象长得是否一样。判断两个对象的某些特征是否一样。实际上就是
调用对象的 equals 方法进行比较。


2.1.7 讲 一 下 String 和 StringBuilder 的 区 别 (fnal) ?
StringBuffer 和 StringBuilder 的区别?
1.在 java 中提供三个类 String StringBuillder StringBuffer 来表示和操作字符串。字符串就是多
个字符的集合。
String 是内容不可变的字符串。String 底层使用了一个不可变的字符数组(fnal char[])
String str =new String(“bbbb”);
而 StringBuillder StringBuffer,是内容可以改变的字符串。StringBuillder StringBuffer 底层使用
的可变的字符数组(没有使用 fnal 来修饰)
2.最经典就是拼接字符串。
1、String 进行拼接.String c = “a”+”b”;
2、StringBuilder 或者 StringBuffer
StringBuilder sb = new StringBuilder(); sb.apend(“a”).apend(“b”)
拼接字符串不能使用 String 进行拼接,要使用 StringBuilder 或者 StringBuffer
3.StringBuilder 是线程不安全的,效率较高.而 StringBuffer 是线程安全的,效率较低。


2.1.8、讲一下 java 中的集合?
Java 中的集合分为 value,key--vale(Conllecton Map)两种。
存储值有分为 List 和 Set.
List 是有序的,可以重复的。
Set 是无序的,不可以重复的。根据 equals 和 hashcode 判断,也就是如果
一个对象要存储在 Set 中,必须重写 equals 和 hashCode 方法。
存储 key-value 的为 map.
8、ArrayList 和 LinkedList 的区别?
List 常用的 ArrayList 和 LinkedList。区别和使用场景?
ArrayList 底层使用时数组。LinkedList 使用的是链表。
数组查询具有所有查询特定元素比较快。而插入和删除和修改比较慢(数组在内存中是一
块连续的内存,如果插入或删除是需要移动内存)。
链表不要求内存是连续的,在当前元素中存放下一个或上一个元素的地址。查询时需要
从头部开始,一个一个的找。所以查询效率低。插入时不需要移动内存,只需改变引用指
向即可。所以插入或者删除的效率高。
ArrayList 使用在查询比较多,但是插入和删除比较少的情况,而 LinkedList 使用在查询比较
少而插入和删除比较多的情况。


2.1.9 讲 一 下 HashMap 哈 HashTable 的 区 别 ?HashTable 和
ConcurrentHashMap 的区别?
相同点:HashMap 和 HasheTalbe 都可以使用来存储 key--value 的数据。
区别:
1、HashMap 是可以把 null 作为 key 或者 value 的,而 HashTable 是不可以的。
2、HashMap 是线程不安全的,效率较高。而 HashTalbe 是线程安全的,效率较低。
?我想线程安全但是我又想效率高?
通过把整个 Map 分为 N 个 Segment(类似 HashTable),可以提供相同的线程安全,但是效
率提升 N 倍,默认提升 16 倍。


2.1.10、实现一个拷贝文件的工具类使用字节流还是字
符流?
我们拷贝的文件不确定是只包含字符流,有可以能有字节流(图片、声音、图像等),为考
虑到通用性,要使用字节流。


2.1.11、讲一下线程的几种实现方式?启动方式?区分方
式?
①实现方式
1、通过继承 Thread 类实现一个线程
2、通过实现 Runnable 接口实现一个线程
继承扩展性不强,java 总只支持单继承,如果一个类继承 Thread 就不能继承其他的类
了。
②怎么启动?
Thread thread = new Thread(继承了 Thread 的对象/实现了 Runnable 的对象)
thread.setName(“设置一个线程名称”);
thread.start();
启动线程使用 start 方法,而启动了以后执行的是 run 方法。
③怎么区分线程?在一个系统中有很多线程,每个线程都会打印日志,我想区分是哪个线
程打印的怎么办?
thread.setName(“设置一个线程名称”); 这是一种规范,在创建线程完成后,都需要设
置名称。


2.1.12 有没有使用过线程并发库?
简单了解过?
JDK5 中增加了 Doug Lea 的并发库,这一引进给 Java 线程的管理和使用提供了强大的便利性。
java.utl.current 包中提供了对线程优化、管理的各项操作,使得线程的使用变得的心应手。
该包提供了线程的运行,线程池的创建,线程生命周期的控制.
Java 通过 Executors 提供四个静态方法创建四种线程池,分别为:
newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活
回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在
队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执
行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行


2.1.13 线程池的作用?
1、限定线程的个数,不会导致由于线程过多导致系统运行缓慢或崩溃
2、线程池不需要每次都去创建或销毁,节约了资源、
3、线程池不需要每次都去创建,响应时间更快。
连接池也是一样?


2.1.14 讲一下什么是设计模式?常用的设计模式有哪些?
设计模式就是经过前人无数次的实践总结出的,设计过程中可以反复使用的、可以解决特
定问题的设计方法。
单例(饱汉模式、饥汉模式)
1、构造方法私有化,让出了自己类中能创建外其他地方都不能创建
2、在自己的类中创建一个单实例(饱汉模式是一出来就创建创建单实例,而饥汉模式需要
的时候才创建)
3、提供一个方法获取该实例对象(创建时需要进行方法同步)
工厂模式:Spring IOC 就是使用了工厂模式.
对象的创建交给一个工厂去创建。
代理模式:Spring AOP 就是使用的动态代理。

 


2.2 java web 部分


2.2.1 讲一下 htp get 和 post 请求的区别?
GET 和 POST 请求都是 http 的请求方式,用户通过不同的 http 的请求方式完成
对资源(url)的不同操作。GET,POST,PUT,DELETE 就对应着对这个资源的
查 ,改 ,增 ,删 4 个操作,具体点来讲 GET 一般用于获取/查询资源信息,而
POST 一般用于更新资源信息
1、Get 请求提交的数据会在地址栏显示出来,而 post 请求不会再地址栏显示出
来.
GET 提交,请求的数据会附在 URL 之后(就是把数据放置在 HTTP 协议头中),
以?分割 URL 和传输数据,多个参数用&连接;POST 提交:把提交的数据放置在
是 HTTP 包的包体中。 因此,GET 提交的数据会在地址栏中显示出来,而 POST
提交,地址栏不会改变
2、传输数据的大小
http Get 请求由于浏览器对地址长度的限制而导致传输的数据有限制。而 POST
请求不会因为地址长度限制而导致传输数据限制。
3、安全性,POST 的安全性要比 GET 的安全性高。由于数据是会在地址中呈现,
所以可以通过历史记录找到密码等关键信息。
2.2.2 说一下你对 servlet 的理解?或者 servlet 是什么?
Servlet(Server Applet),全称 Java Servlet, 是用 Java 编写的服务
器端程序。而这些 Sevlet 都要实现 Servlet 这个借口。其主要功能在于交互式
地浏览和修改数据,生成动态 Web 内容。Servlet 运行于支持 Java 的应用服务
器中。
HttpServlet 重写 doGet 和 doPost 方法或者你也可以重写 service 方法完成对
get 和 post 请求的响应


2.2.3 简单说一下 servlet 的生命周期?
servlet 有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这
个生存期由 javax.servlet.Servlet 接口的 init,service 和 destroy 方法表达。
加载 Servlet 的 class---->实例化 Servlet----->调用 Servlet 的 init 完成初始化 ---->响应请求
(Servlet 的 service 方法)----->Servlet 容器关闭时(Servlet 的 destory 方法)
Servlet 启动时,开始加载 servlet 生命周期开始。Servlet 被服务器实例化后,容器运行其
init 方法,请求到达时运行其 service 方法,service 方法自动派遣运行与请求对应的 doXXX
方法(doGet,doPost)等,当服务器决定将实例销毁的时候(服务器关闭)调用其 destroy 方
法。
2.2.4 Servlet API 中 forward() 与 redirect()的区别?
1、forward 是服务器端的转向而 redirect 是客户端的跳转。
2、使用 forward 浏览器的地址不会发生改变。而 redirect 会发生改变。
3、Forward 是一次请求中完成。而 redirect 是重新发起请求。
4、Forward 是在服务器端完成,而不用客户端重新发起请求,效率较高。


2.2.5 JSP 和 Servlet 有哪些相同点和不同点?
JSP 是 Servlet 技术的扩展,所有的 jsp 文件都会被翻译为一个继承 HtpServlet 的类。也就是
jsp 最终也是一个 Servlet.这个 Servlet 对外提供服务。
Servlet 和 JSP 最主要的不同点在于 JSP 侧重于视图,Servlet 主要用于控制逻辑。
Servlet 如果要实现 html 的功能,必须使用 Writer 输出对应的 html,比较麻烦。而 JSP 的情况
是 Java 和 HTML 可以组合成一个扩展名为.jsp 的文件,做界面展示比较方便而嵌入逻辑比较
复杂。


2.2.6 jsp 有哪些内置对象?作用分别是什么?
9 个内置的对象:
request 用户端请求,此请求会包含来自 GET/POST 请求的参数
response 网页传回用户端的回应
pageContext 网页的属性是在这里管理
session 与请求有关的会话期
applicaton servlet 正在执行的内容
out 用来传送回应的输出
confg servlet 的构架部件
page JSP 网页本身
excepton 针对错误网页,未捕捉的例外
四大作用域:pageContext request session applicaton 可以通过 jstl 从四大作用域中取值.
Jsp 传递值 request session applicaton cookie 也能传值


2.2.7 说一下 session 和 cookie 的区别?你在项目中都有
哪些地方使用了?
Session 和 cookie 都是会话(Seesion)跟踪技术。Cookie 通过在客户端记录信
息确定用户身份,Session 通过在服务器端记录信息确定用户身份。 但是
Session 的实现依赖于 Cookie,sessionId(session 的唯一标识需要存放在客户
端).
cookie 和 session 的区别:
1、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
2、cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗
考虑到安全应当使用 session。
3、session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务
器的性能,考虑到减轻服务器性能方面,应当使用 COOKIE。
4、单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存
20 个 cookie。
5、所以个人建议:
将登陆信息等重要信息存放为 SESSION
其他信息如果需要保留,可以放在 COOKIE 中,比如购物车
购物车最好使用 cookie,但是 cookie 是可以在客户端禁用的,这时候我们要使
用 cookie+数据库的方式实现,当从 cookie 中不能取出数据时,就从数据库获取。
2.2.8、MVC 的各个部分都有那些技术来实现?
M(Model) 模型 javabean
V(View) 视图 html jsp volicity freemaker
C(Control) 控制器 Servlet,Acton
Jsp+Servlet+javabean 最经典 mvc 模式,实际上就是 model2 的实现方式,就是把视图和逻辑
隔离开来
Model1 的方式 jsp+service+dao
MOdel2 的方式 jsp+servlet+service+dao
使用 struts2 和 springmvc 这样的 mvc 框架后,jsp+核心控制器+acton+javabean


2.3 数据库部分


2.3.1 数据库的分类及常用的数据库
数据库分为:关系型数据库和非关系型数据库
关系型:mysql oracle sqlserver 等
非关系型:redis,memcache,mogodb,hadoop 等
2.3.2 简单介绍一下关系数据库三范式?
范式就是规范,就是关系型数据库在设计表时,要遵循的三个规范。
要想满足第二范式必须先满足第一范式,要满足第三范式必须先满足第二范式。
第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一
列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。
列数据的不可分割
二范式(2NF)要求数据库表中的每个行必须可以被唯一地区分。为实现区
分通常需要为表加上一个列,以存储各个实例的唯一标识。(主键)
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式
(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
(外键)
反三范式,有的时候为了效率,可以设置重复或者可以推导出的字段.
订单(总价)和订单项(单价)
2.3.3 事务四个基本特征或 ACID 特性。
事务是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,
要么都不做,是一个不可分割的工作单位。
一个转账必须 A 账号扣钱成功,B 账号加钱成功,才算正真的转账成功。
事务必须满足四大特征:原子性,一致性,隔离性持久性/持续性
原子性:表示事务内操作不可分割。要么都成功、要么都是失败.
一致性:要么都成功、要么都是失败.后面的失败了要对前面的操作进行回滚。
隔离性:一个事务开始后,不能后其他事务干扰。
持久性/持续性:表示事务开始了,就不能终止。


2.3.4 mysql 数据库的默认的最大连接数?
100
为什么需要最大连接数?特定服务器上面的数据库只能支持一定数目同时连接,这时候我
们一般都会设置最大连接数(最多同时服务多少连接)。在数据库安装时都会有一个默认
的最大连接数为 100
2.3.5 说一下 msyql 的分页?Oracle 的分页?
为什么需要分页?在很多数据是,不可能完全显示数据。进行分段显示.
Mysql 是使用关键字 limit 来进行分页的 limit offset,size 表示从多少索引去多少位.
Oracle 的分页,大部分情况下,我们是记不住了。说思路,要使用三层嵌套查询。
Oracle 的分页有点儿记不住了,只记得一些大概。是使用了三层嵌套查询。如果在工作
中使用了,可以到原来的项目中拷贝或上网查询。
mysql:
String sql =
"select * from students order by id limit " + pageSize*(pageNumber-1) + "," + pageSize;
oracle:
String sql =
"select * from " +
(select *,rownum rid from (select * from students order by postme desc) where rid<=" +
pagesize*pagenumber + ") as t" +
"where t>" + pageSize*(pageNumber-1);


2.3.6 简单讲一下数据库的触发器的使用场景?
触发器,需要有触发条件,当条件满足以后做什么操作。
触发器用处还是很多的,比如校内网、开心网、Facebook,你发一个日志,自动通知好友,
其实就是在增加日志时做一个后触发,再向通知表中写入条目。因为触发器效率高。而
UCH 没有用触发器,效率和数据处理能力都很低。
每插入一个帖子,都希望将版面表中的最后发帖时间,帖子总数字段进行同步更新,用触
发器做效率就很高。
create table board1(id int primary key auto_increment,name varchar(50),ar
tcleCount int);
create table artcle1(id int primary key auto_increment,ttle varchar(50)
,bid int references board1(id));
delimiter |#把分割符;改成|
create trigger insertArtcle_Trigger afer insert on artcle1 for each ro
w begin
-> update board1 set artcleCount=artcleCount+1 where id= NEW.bid;
-> end;
-> |
delimiter ;
insert into board1 value (null,'test',0);
insert into artcle1 value(null,'test',1);


2.3.7 简单讲一下数据库的存储过程的使用场景?
数据库存储过程具有如下优点:
1、存储过程只在创建时进行编译,以后每次执行存储过程都不需再重新编译,而一般
SQL 语句每执行一次就编译一次,因此使用存储过程可以大大提高数据库执行速度。
2、通常,复杂的业务逻辑需要多条 SQL 语句。这些语句要分别地从客户机发送到服务器,
当客户机和服务器之间的操作很多时,将产生大量的网络传输。如果将这些操作放在一个
存储过程中,那么客户机和服务器之间的网络传输就会大大减少,降低了网络负载。
3、存储过程创建一次便可以重复使用,从而可以减少数据库开发人员的工作量。
4、安全性高,存储过程可以屏蔽对底层数据库对象的直接访问,使用 EXECUTE 权限调用
存储过程,无需拥有访问底层数据库对象的显式权限。
正是由于存储过程的上述优点,目前常用的数据库都支持存储过程,例如 IBM
DB2,Microsoft SQL Server,Oracle,Access 等,开源数据库系统 MySQL 也在
5.0 的时候实现了对存储过程的支持。

定义存储过程 :
create procedure insert_Student (_name varchar(50),_age int ,out _id int)
begin
insert into student value(null,_name,_age);
select max(stuId) into _id from student;
end;
call insert_Student('wfz',23,@id);
select @id;

2.3.8 用 jdbc 怎么调用存储过程?
贾琏欲执事
加载驱动
获取连接
设置参数
执行
释放连接
package com.huawei.interview.lym;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
public class JdbcTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Connection cn = null;
CallableStatement cstmt = null;
try {
//这里最好不要这么干,因为驱动名写死在程序中了
Class.forName("com.mysql.jdbc.Driver");
//实际项目中,这里应用 DataSource 数据,如果用框架,
//这个数据源不需要我们编码创建,我们只需 Datasource ds =
context.lookup()
//cn = ds.getConnection();
cn =
DriverManager.getConnection("jdbc:mysql:///test","root","root");
cstmt = cn.prepareCall("{call insert_Student(?,?,?)}");
cstmt.registerOutParameter(3,Types.INTEGER);
cstmt.setString(1, "wangwu");
cstmt.setInt(2, 25);
cstmt.execute();
//get 第几个,不同的数据库不一样,建议不写
System.out.println(cstmt.getString(3));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
/*try{cstmt.close();}catch(Exception e){}
try{cn.close();}catch(Exception e){}*/
try {
if(cstmt != null)
cstmt.close();
if(cn != null)
cn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.3.9 常用 SQL

2.3.10 简单说一下你对 jdbc 的理解?
Java database connecton java 数据库连接.数据库管理系统(mysql oracle 等)是很多,每个数据
库管理系统支持的命令是不一样的。
Java 只定义接口,让数据库厂商自己实现接口,对于我们者而言。只需要导入对应厂商开
发的实现即可。然后以接口方式进行调用.(mysql + mysql 驱动(实现)+jdbc)
2.3.11 写一个简单的 jdbc 的程序。写一个访问 oracle 数
据的 jdbc 程序?
贾琏欲执事
加载驱动(com.mysql.jdbc.Driver,oracle.jdbc.driver.OracleDriver)
获取连接(DriverManager.getConnecton(url,usernam,passord))
设置参数 Statement PreparedStatement
cstmt.setXXX(index, value);
执行 executeQuery executeUpdate
释放连接(是否连接要从小到大,必须放到 fnnaly)
2.3.12 JDBC 中的 PreparedStatement 相比 Statement 的好处
大多数我们都使用 PreparedStatement 代替 Statement
1:PreparedStatement 是预编译的,比 Statement 速度快
2:代码的可读性和可维护性
虽然用 PreparedStatement 来代替 Statement 会使代码多出几行,但这样的代码无论从
可读性还是可维护性上来说.都比直接用 Statement 的代码高很多档次:
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values
('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");
perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4)
values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
不用我多说,对于第一种方法,别说其他人去读你的代码,就是你自己过一段时间再去读,
都会觉得伤心。
3:安全性
PreparedStatement 可以防止 SQL 注入攻击,而 Statement 却不能。比如说:
String sql = "select * from tb_name where name= '"+varname+"' and
passwd='"+varpasswd+"'";
如果我们把[' or '1' = '1]作为 varpasswd 传入进来.用户名随意,看看会成为什么?
select * from tb_name = '随意' and passwd = '' or '1' = '1';
因为'1'='1'肯定成立,所以可以任何通过验证,更有甚者:
把[';drop table tb_name;]作为 varpasswd 传入进来,则:
select * from tb_name = '随意' and passwd = '';drop table tb_name;有些数据
库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行。
而如果你使用预编译语句你传入的任何内容就不会和原来的语句发生任何匹配的关系,只
要全使用预编译语句你就用不着对传入的数据做任何过虑。而如果使用普通的
statement,有可能要对 drop 等做费尽心机的判断和过虑。
2.3.13 数据库连接池作用
1、限定数据库的个数,不会导致由于数据库连接过多导致系统运行缓慢或崩溃
2、数据库连接不需要每次都去创建或销毁,节约了资源
3、数据库连接不需要每次都去创建,响应时间更快。


2.4 前端部分


2.4.1 简单说一下 html,css,javascript 在网页开发中的定位?
HTML 超文本标记语言 定义网页的结构
CSS 层叠样式表,用来美化页面
JavaScript 主要用来验证表单,做动态交互(其中 ajax)
2.4.2 简单介绍一下 Ajax?
什么是 Ajax? 异步的 javascript 和 xml
作用是什么?通过 AJAX 与服务器进行数据交换,AJAX 可以使网页实现布局更新。
这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
怎么来实现 Ajax XmlHtpRequest 对象,使用这个对象可以异步向服务器发送请求,获取
获取响应,完成局部更新。Open send responseText/responseXML 局部响应.
使用场景 登陆失败时不跳转页面,注册时提示用户名是否存在,二级联动等等使用场景
2.4.3 js 和 jQuery 的关系?
jQuery 是一个 js 框架,封装了 js 的属性和方法。让用户使用起来更加便利。
,并且增强了 js 的功能.
使用原生 js 是要处理很多兼容性的问题(注册事件等),由 jQuery 封装了底层,就不用处理
兼容性问题。
原生的 js 的 dom 和事件绑定和 Ajax 等操作非常麻烦,jQuery 封装以后操作非常方便。
2.4.4 jQuery 的常用选择器?
ID 选择器 通过 ID 获取一个元素
Class 选择器 通过类(css)获取元素
标签选择器 通过标签获取元素
通用选择器(*) 获取所以的元素
div.myCls 获取有 myCls 这个类的 div
层次选择器
儿子选择器 > 获取下面的子元素
后代选择器 空格 获取下面后代,包括儿子、孙子等后代
属性选择器
Tag[atrName=’test’] 获取有属性名为 xxxx 并且属性的值为 test 的所有 xxx 标签
<input type=”checkbox” name=”hobby”/> 吃饭<br/>
<input type=”checkbox” name=”hobby”/> 睡觉<br/>
Input[name=’hobby’],表示获取属性名为 name 并且 name 属性值为 hobby 的的所有
input 标签元素
2.4.5 jQuery 的页面加载完毕事件?
很多时候我们需要获取元素,但是必须等到该元素被加载完成后才能获取。我们可以
把 js 代码放到该元素的后面,但是这样就会造成 js 在我们的 body 中存在不好管理。所有页
面加载完毕后所有的元素当然已经加载完毕。一般获取元素做操作都要在页面加载完毕后
操作。

第一种:
$(document).ready(functon(){
});
$(document)把原生的 document 这个 dom 对
象转换为 jQuery 对象,转换完成后才能调用
ready 方法
ready(fn),表示的是页面结构被加载完毕后执
行传入函数 fn
第二种:
$(functon(){
});
当页面加载完毕后执行里面的函数,这一种
相对简单,用得最多。
window.onload 的区别
1、jQuery 中的页面加载完毕事件,表示的是页面结构被加载完毕。
2、window.onload 表示的是页面被加载完毕。
<img src=”http://baidu.com/1.jpg”/> onload 必须等等页面中的图片、声音、图像等远程
资源被加载完毕后才调用而 jQuery 中只需要页面结构被加载完毕。

2.4.6 Jquery 的 Ajax 和原生 Js 实现 Ajax 有什么关系?
jQuery 中的 Ajax 也是通过原生的 js 封装的。封装完成后让我们使用起来更加便利,不用考
虑底层实现或兼容性等处理。
如果采用原生 js 实现 Ajax 是非常麻烦的,并且每次都是一样的。如果我们不使用 jQuery 我
们也要封装 Ajax 对象的方法和属性。有像 jQuery 这些已经封装完成,并经过很多企业实际
的框架,比较可靠并且开源。我们就不需要封装,直接使用成熟的框架(jQuery)即可.
2.4.7 简单说一下 html5?你对现在的那些新技术有了解?
Html5 是最新版本的 html,是在原来 html4 的基础上增强了一些标签。
Html 增加一些像画板、声音、视频、web 存储等高级功能。但是 html5 有一个不好的地方,
那就是 html5 太强调语义了,导致开发中都不知道要选择那个标签。
在做页面布局是,无论头部、主题、导航等模块都使用 div 来表示,但是 html5 的规范,
需要使用不同的标签来表示。(header footer 等)
你对现在的那些新技术有了解
Html5 css3 等
2.4.8 简单说一下 css3?
Css3 是最新版本的 css,是对原理 css2 的功能增强。
Css3 中提供一些原来 css2 中实现起来比较困难或者不能实现的功能。
1、盒子圆角边框
2、盒子和文字的阴影
3、渐变
4、转换 移动、缩放、旋转等
5、过渡、动画都可以使用动画。
6、可以使用媒体查询实现响应式网站。
Css3 最大缺点就是要根据不同的浏览器处理兼容性。对应有一些处理兼容性的工具。不
用担心.
2.4.9 bootstrap 是什么?
BootStrap 是一个移动设备优先的 UI 框架。我们可以不用谢任何 css,js 代码就能实现比较漂
亮的有交互性的页面。我们程序员对页面的编写是有硬伤的,所有要自己写页面的话就要
使用类似于 bootstrap 这样的 UI 框架。
平时用得很多的:
1、模态框
2、表单,表单项
3、布局
4、删格系统


2.5 框架部分


2.5.1 什么是框架?
框架(Framework)是一个框子——指其约束性,也是一个架子——指其支撑性。
IT 语境中的框架,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构。在
此结构上可以根据具体问题扩展、安插更多的组成部分,从而更迅速和方便地构建完整的
解决问题的方案。
1)框架本身一般不完整到可以解决特定问题,但是可以帮助您快速解决特定问题;
没有框架所有的工作都从零开始做,有了框架,为我们提供了一定的功能,我们就可以在框
架的基础上开发,极大的解放了生产力。
不同的框架,是为了解决不同领域的问题。一定要为了解决问题才去学习框架。
2)框架天生就是为扩展而设计的;
3)框架里面可以为后续扩展的组件提供很多辅助性、支撑性的方便易用的实用工具
(utlites),也就是说框架时常配套了一些帮助解决某类问题的库(libraries)或工具
(tools)。
java 中就是一系列的 jar 包,其本质就是对 jdk 功能的扩展.
2.5.2 MVC 模式
MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)
的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将
业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新
编写业务逻辑。
最简单的、最经典就是 Jsp(view) +Servlet(controller) + JavaBean(model)
1、当控制器收到来自用户的请求
2、控制器调用 JavaBean 完成业务
3、完成业务后通过控制器跳转 JSP 页面的方式给用户反馈信息
4、Jsp 个 用户做出响应。
控制器都是核心
2.5.3 MVC 框架
什么是 MVC 框架?
是为了解决传统 MVC 模式(Jsp + Servlet + JavaBean)的一些问题而出现的框架。
传统 MVC 模式问题
1、所有的 Servlet 和 Servlet 映射都要配置在 web.xml 中,如果项目太大,web.xml 就太
庞大,并且不能实现模块化管理。
2、Servlet 的主要功能就是接受参数、调用逻辑、跳转页面,比如像其他字符编码、文
件上传等功能也要写在 Servlet 中,不能让 Servlet 主要功能而需要做处理一下特例。
3 、 接 受 参 数 比 较 麻 烦 (String name = request.getParameter(“name”),User user=new User
user.setName(name)),不能通过 model 接收,只能单个接收,接收完成后转换封装 model.
4、跳转页面方式比较单一(forword,redirect),并且当我的页面名称发生改变时需要修改
Servlet 源代码.
现在比较常用的 MVC 框架有:
struts
webwork
Struts2
Spring MVC
2.5.4 简单讲一下 struts2 的执行流程?
Struts2 的原理?
一个请求在 Struts2 框架中的处理大概分为以下几个步骤:
1、客户端浏览器发送请求
2 、 这 个 请 求 经 过 一 系 列 的 过 滤 器 ( Filter ) ( 这 些 过 滤 器 中 有 一 个 叫 做
ActonContextCleanUp 的可选过滤器,这个过滤器对于 Struts2 和其他框架的集成很有帮助,
例如:SiteMesh Plugin);
3、接着 FilterDispatcher(StrutsPrepareAndExecuteFilter)被调用,FilterDispatcher
(StrutsPrepareAndExecuteFilter) 询 问 ActonMapper 来 决 定 这 个 请 求 是 否 需 要 调 用 某 个
Acton;
4、如果 ActonMapper 决定需要调用某个 Acton,FilterDispatcher
(StrutsPrepareAndExecuteFilter)把请求的处理交给 ActonProxy;
5、ActonProxy 通过 Confguraton Manager 询问框架的配置文件,找到需要调用的 Acton 类;
6、ActonProxy 创建一个 ActonInvocaton 的实例。
7、ActonInvocaton 实例使用命名模式来调用,在调用 Acton 的过程前后,涉及到相关拦截
器(Intercepter)的调用。
8、一旦 Acton 执行完毕,ActonInvocaton 负责根据 struts.xml 中的配置找到对应的返回结
果。返回结果通常是(但不总是,也可能是另外的一个 Acton 链)一个需要被表示的 JSP
或者 FreeMarker 的模版。在表示的过程中可以使用 Struts2 框架中继承的标签。在这个过程
中需要涉及到 ActonMapper。
面试:
1、浏 览 器 发 送 请 求 , 经 过 一 系 列 的 过 滤 器 后 , 到 达 核 心 过 滤 器
(StrutsPrepareAndExecuteFilter).
2、StrutsPrepareAndExecuteFilter 通过 ActonMapper 判断当前的请求是否需要某个
Acton 处理,如果不需要,则走原来的流程。如果需要则把请求交给 ActonProxy 来
处理
3、ActonProxy 通过 Confguraton Manager 询问框架的配置文件(Struts.xml),找到需要
调用的 Acton 类;
4、创建一个 ActonInvocaton 实例,来调用 Acton 的对应方法来获取结果集的 name,在
调用前后会执行相关拦截器。
5、通过结果集的 Name 知道对应的结果集来对浏览器进行响应。
拦截、判断、寻找、执行、响应
2.5.5 Struts2 中的拦截器,你都用它干什么?
java 里的拦截器是动态拦截 Acton 调用的对象。它提供了一种机制可以使开发者可以
定义在一个 acton 执行的前后执行的代码,也可以在一个 acton 执行前阻止其执行,同时
也提供了一种可以提取 acton 中可重用部分的方式。
在 AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,
进行拦截然后在之前或之后加入某些操作。
面试:
struts2 中的的功能(参数处理、文件上传、字符编码等)都是通过系统拦截器实现的。
如果业务需要,当然我们也可以自定义拦截器,进行可插拔配置,在执行 Acton 的方法
前后、加入相关逻辑完成业务。
使用场景:
1、用户登录判断,在执行 Acton 的前面判断是否已经登录,如果没有登录的跳转到登
录页面。
2、用户权限判断,在执行 Acton 的前面判断是否具有,如果没有权限就给出提示信息。
3、操作日志......
4、......
2.5.6 简单讲一下 SpringMVC 的执行流程?
1. 用户向服务器发送请求,请求被 Spring 前端控制 Servelt DispatcherServlet 捕获;
2. DispatcherServlet 对请求 URL 进行解析,得到请求资源标识符(URI)。然后根据该
URI,调用 HandlerMapping 获得该 Handler 配置的所有相关的对象(包括 Handler 对
象以及 Handler 对象对应的拦截器),最后以 HandlerExecutionChain 对象的形式返回;
3. DispatcherServlet 根据获得的 Handler,选择一个合适的 HandlerAdapter。(附注:
如果成功获得 HandlerAdapter 后,此时将开始执行拦截器的 preHandler(...)方法)
4. 提取 Request 中的模型数据,填充 Handler 入参,开始执行
Handler(Controller)。 在填充 Handler 的入参过程中,根据你的配置,Spring 将帮你
做一些额外的工作:
HttpMessageConveter: 将请求消息(如 Json、xml 等数据)转换成一个对象,将
对象转换为指定的响应信息
数据转换:对请求消息进行数据转换。如 String 转换成 Integer、Double 等
数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日
期等
数据验证: 验证数据的有效性(长度、格式等),验证结果存储到 BindingResult 或
Error 中
5. Handler 执行完成后,向 DispatcherServlet 返回一个 ModelAndView 对象;
6. 根据返回的 ModelAndView,选择一个适合的 ViewResolver(必须是已经注册到
Spring 容器中的 ViewResolver)返回给 DispatcherServlet ;
7. ViewResolver 结合 Model 和 View,来渲染视图
8. 将渲染结果返回给客户端。
面试:
1、 用户向服务器发送请求,请求被 Spring 前端控制 Servelt DispatcherServlet 捕获(捕
获)
2、 DispatcherServlet 对请求 URL 进行解析,得到请求资源标识符(URI)。然后根据该
URI,调用 HandlerMapping 获得该 Handler 配置的所有相关的对象(包括 Handler 对象以及
Handler 对象对应的拦截器),最后以 HandlerExecutonChain 对象的形式返回;(查找
handler)
3、 DispatcherServlet 根据获得的 Handler,选择一个合适的 HandlerAdapter。 提取
Request 中的模型数据,填充 Handler 入参,开始执行 Handler(Controller), Handler
执行完成后,向 DispatcherServlet 返回一个 ModelAndView 对象(执行 handler)
4、DispatcherServlet 根据返回的 ModelAndView,选择一个适合的 ViewResolver(必
须是已经注册到 Spring 容器中的 ViewResolver) (选择 ViewResolver)
5、通过 ViewResolver 结合 Model 和 View,来渲染视图,DispatcherServlet 将渲染结果
返回给客户端。(渲染返回)
快速记忆技巧:
核心控制器捕获请求、查找 Handler、执行 Handler、选择 ViewResolver,通过
ViewResolver 渲染视图并返回
2.5.7 说一下 struts2 和 springMVC 有什么不同?
目前企业中使用 SpringMvc 的比例已经远远超过 Struts2,那么两者到底有什么区别,是很多
初学者比较关注的问题,下面我们就来对 SpringMvc 和 Struts2 进行各方面的比较:
1. 核 心控制器(前端控制器、预处理控制器):对于使用过 mvc 框架的人来说这个词应该
不会陌生,核心控制器的主要用途是处理所有的请求,然后对那些特殊的请求 (控制器)
统一的进行处理(字符编码、文件上传、参数接受、异常处理等等),spring mvc 核心控制器是
Servlet,而 Struts2 是 Filter。
2.控制器实例:Spring Mvc 会比 Struts 快一些(理论上)。Spring Mvc 是基于方法设计,而
Sturts 是基于对象,每次发一次请求都会实例一个 acton,每个 acton 都会被注入 属性,
而 Spring 更像 Servlet 一样,只有一个实例,每次请求执行对应的方法即可(注意:由于是单
例实例,所以应当避免全局变量的修改,这样会产生线程安全问题)。
3. 管理方式:大部分的公司的核心架构中,就会使用到 spring,而 spring mvc 又是 spring 中
的一个模块,所以 spring 对于 spring mvc 的控制器管理更加简单方便,而且提供了全 注解
方式进行管理,各种功能的注解都比较全面,使用简单,而 struts2 需要采用 XML 很多的配
置参数来管理(虽然也可以采用注解,但是几乎没有公司那 样使用)。
4.参数传递:Struts2 中自身提供多种参数接受,其实都是通过(ValueStack)进行传递和赋
值,而 SpringMvc 是通过方法的参数进行接收。
5.学习难度:Struts 更加很多新的技术点,比如拦截器、值栈及 OGNL 表达式,学习成本较
高,springmvc 比较简单,很较少的时间都能上手。
6.intercepter 的实现机制:struts 有以自己的 interceptor 机制,spring mvc 用的是独立的 AOP
方式。这样导致 struts 的配置文件量还是比 spring mvc 大,虽然 struts 的配置能继承,所以
我觉得论使用上来讲,spring mvc 使用更加简洁,开发效率 Spring MVC 确实比 struts2 高。
spring mvc 是方法级别的拦截,一个方法对应一个 request 上下文,而方法同时又跟一个 url
对应,所以说从架构本身上 spring3 mvc 就容易实现 restul url。struts2 是类级别的拦截,一
个类对应一个 request 上下文;实现 restul url 要费劲,因为 struts2 acton 的一个方法可以
对应一个 url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方
法了。spring3 mvc 的方法之间基本上独立的,独享 request response 数据,请求数据通过参
数获取,处理结果通过 ModelMap 交回给框架方法之间不共享变量,而 struts2 搞的就比较
乱,虽然方法之间 也是独立的,但其所有 Acton 变量是共享的,这不会影响程序运行,却
给我们编码,读程序时带来麻烦。
7.spring mvc 处 理 ajax 请 求 , 直 接 通 过 返 回 数 据 , 方 法 中 使 用 注 解
@ResponseBody,spring mvc 自动帮我们对象转换为 JSON 数据。而 struts2 是通过插
件的方式进行处理
在 SpringMVC 流行起来之前,Struts2 在 MVC 框架中占核心地位,随着 SpringMVC 的出现,
SpringMVC 慢慢的取代 struts2,但是很多企业都是原来搭建的框架,使用 Struts2 较多。
2.5.8 说一下 Spring 中的两大核心?
Spring 是什么?
spring 是 J2EE 应用程序框架,是轻量级的 IoC 和 AOP 的容器框架(相对于重量级的
EJB),主要是针对 javaBean 的生命周期进行管理的轻量级容器,可以单独使用,也可以和
Struts 框架,ibats 框架等组合使用。
1、IOC(Inversion of Control )或 DI(Dependency Injecton)
IOC 控制权反转
原来:我的 Service 需要调用 DAO,Service 就需要创建 DAO
Spring:Spring 发现你 Service 依赖于 dao,就给你注入.
核心原理:就是配置文件+反射(工厂也可以)+容器(map)
2、AOP:面向切面编程
核心原理:使用动态代理的设计模式在执行方法前后或出现异常做加入相关逻辑。
我们主要使用 AOP 来做:
1、事务处理
2、权限判断
3、日志
4、....
2.5.9 AOP 是什么?你都拿它做什么?
3、AOP:面向切面编程
核心原理:使用动态代理的设计模式在执行方法前后或出现异常做加入相关逻辑。
我们主要使用 AOP 来做:
1、事务处理 执行方法前,开启事务、执行完成后关闭事务、出现异常后回滚事务
2、权限判断 在执行方法前,判断是否具有权限
3、日志 在执行前进行日志处理
4、....
2.5.10 讲一下 Spring 的事务传播特性
多个事务存在是怎么处理的策略
1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则
开启
2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,
则非事务的执行
3. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没
有一个活动的事务,则抛出异常。
4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经
存在,则将这个存在的事务挂起。
5. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。
6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异

7. PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务
中. 如果没有活动事务, 则按 TransactionDefinition.PROPAGATION_REQUIRED 属
性执行
Propagaton
Required 需要 如果存在一个事务,则支持当前事务。如果没有事务则开启
Supports 支持 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
Mandatory 必要的 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则
抛出异常。
required_new 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
Not_support 总是非事务地执行,并挂起任何存在的事务。
Never 绝不 总是非事务地执行,如果存在一个活动事务,则抛出异常
Nested 嵌套的 如果有就嵌套、没有就开启事务
2.5.11 Spring 事务的隔离级别
1. ISOLATION_DEFAULT: 这是一个 PlatfromTransactionManager 默认的隔离级别,使用
数据库默认的事务隔离级别.
另外四个与 JDBC 的隔离级别相对应
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务
可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事
务读取。另外一个事务不能读取该事务未提交的数据
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但
是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况
产生(不可重复读)。
5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理
为顺序执行。
除了防止脏读,不可重复读外,还避免了幻像读。
其中的一些概念的说明:
脏读: 指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交
到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据
是还没有提交的数据, 那么另外一 个事务读到的这个数据是脏数据,依据脏数据所做的
操作可能是不正确的。
不可重复读: 指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一
个事务也访问该同一数据。 那么,在第一个事务中的两次读数据之间,由于第二个事务的
修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次
读到的数据是不一样的,因此称为是不可重复读。
幻觉读: 指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数
据进行了修改,这种修改涉及 到表中的全部数据行。同时,第二个事务也修改这个表中的
数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发
现表中还有没有修改的数据行,就好象发生了幻觉一样。
2.5.12 什么是 ORM?
对象关系映射(Object Relatonal Mapping,简称 ORM)模式是一种为了解决面向对象与
关系数据库存在的互不匹配的现象的技术。简单的说,ORM 是通过使用描述对象和数据库
之间映射的元数据,将程序中的对象自动持久化到关系数据库中。那么,到底如何实现持
久化呢?一种简单的方案是采用硬编码方式(jdbc 操作 sql 方式),为每一种可能的数据库访
问操作提供单独的方法。
这种方案存在以下不足:
1.持久化层缺乏弹性。一旦出现业务需求的变更,就必须修改持久化层的接口
2.持久化层同时与域模型与关系数据库模型绑定,不管域模型还是关系数据库模型发
生变化,都要修改持久化曾的相关程序代码,增加了软件的维护难度。
ORM 提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,
使得 ORM 中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。Java 典型的
ORM 框架有:Hibernate,ibats(mybats),speedframework。
ORM 的方法论基于三个核心原则:
简单:以最基本的形式建模数据。
传达性:数据库结构被任何人都能理解的语言文档化。
精确性:基于数据模型创建正确标准化了的结构。
对象关系映射(Object Relatonal Mapping,简称 ORM)模式是一种为了解决面向对象
与关系数据库存在的互不匹配的现象的技术。可以简单的方案是采用硬编码方式(jdbc 操作
sql 方式),为每一种可能的数据库访问操作提供单独的方法。这种方法存在很多缺陷,使

使用 ORM 框架(为了解决解决面向对象与关系数据库存在的互不匹配的现象的框架)来解决.
Hibernate,ibats(mybats),
2.5.13 iBats(mybats)与 Hibernate 有什么不同?
相同点:
都是 java 中 orm 框架、屏蔽 jdbc api 的底层访问细节,使用我们不用与 jdbc api 打
交道,就可以完成对数据库的持久化操作。jdbc api 编程流程固定,还将 sql 语句与 java 代
码混杂在了一起,经常需要拼凑 sql 语句,细节很繁琐。
ibats 的好处:屏蔽 jdbc api 的底层访问细节;将 sql 语句与 java 代码进行分离;提供了将
结果集自动封装称为实体对象和对象的集合的功能 .queryForList 返回对象集合,用
queryForObject 返回单个对象;提供了自动将实体对象的属性传递给 sql 语句的参数。
Hibername 的好处:Hibernate 是一个全自动的 orm 映射工具,它可以自动生成 sql 语句,
并执行并返回 java 结果。
不同点:
1、hibernate 要比 ibats 功能强大很多。因为 hibernate 自动生成 sql 语句。
2、ibats 需要我们自己在 xml 配置文件中写 sql 语句,hibernate 我们无法直接控制该语
句,我们就无法去写特定的高效率的 sql。对于一些不太复杂的 sql 查询,hibernate 可以很
好帮我们完成,但是,对于特别复杂的查询,hibernate 就很难适应了,这时候用 ibats 就
是不错的选择,因为 ibats 还是由我们自己写 sql 语句。
ibats 可以出来复杂语句,而 hibernate 不能。
3、ibats 要比 hibernate 简单的多。ibats 是面向 sql 的,不同考虑对象间一些复杂的映
射关系。
2.5.14 Hibernate 映射对象的状态
临时状态/瞬时状态(transient):刚刚用 new 语句创建,没有被持久化
不处于 session 中(没有使用 session 的方法去操作临时对象)。该对象成为临时对象
持久化状态/托管状态(persistent):已经被持久化,加入到 session 的缓存中。session 是没有
关闭该状态的对象为持久化对象。
游离状态/脱管状态(detached):已经被持久化,但不处于 session 中。
该状态的对象为游离对象。
删除状态(removed):对象有关联的 ID,并且在 Session 管理下,但是已经被计划(事务提交
的时候,commit())删除。如果没有事务就不能删除
相互转换
2.5.15 介绍一下 Hibernate 的缓存?
一、why(为什么要用 Hibernate 缓存?)
Hibernate 是一个持久层框架,经常访问物理数据库。
为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。
缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特
定的时刻或事件会同步缓存和物理数据源的数据。
为了提供访问速度,把磁盘或数据库访问变成内存访问。
二、what(Hibernate 缓存原理是怎样的?)Hibernate 缓存包括两大类:Hibernate 一级缓
存和 Hibernate 二级缓存。
1.Hibernate 一级缓存又称为“Session 的缓存”。
Session 缓存内置不能被卸载,Session 的缓存是事务范围的缓存(Session 对象的生命周期
通常对应一个数据库事务或者一个应用事务)。
一级缓存中,持久化类的每个实例都具有唯一的 OID。
2.Hibernate 二级缓存又称为“SessionFactory 的缓存”。
由于 SessionFactory 对象的生命周期和应用程序的整个过程对应,因此 Hibernate 二级缓存
是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策
略,该策略为被缓存的数据提供了事务隔离级别。
第二级缓存是可选的,是一个可配置的插件,默认下 SessionFactory 不会启用这个插件。
Hibernate 提供了 org.hibernate.cache.CacheProvider 接口,它充当缓存插件与 Hibernate 之间
的适配器。
面试:
Hibernate 中的缓存分一级缓存和二级缓存。
一级缓存就是 Session 级别的缓存,在事务范围内有效是,内置的不能被卸载。二级缓存
是 SesionFactory 级别的缓存,从应用启动到应用结束有效。是可选的,默认没有二级缓存,
需要手动开启。
保存数据库后,在内存中保存一份,如果更新了数据库就要同步更新。
什么样的数据适合存放到第二级缓存中?
1) 很少被修改的数据 帖子的最后回复时间
2) 经常被查询的数据 电商的地点
2) 不是很重要的数据,允许出现偶尔并发的数据
3) 不会被并发访问的数据
4) 常量数据
扩展:hibernate 的二级缓存默认是不支持分布式缓存的。使用 memcahe,redis 等中央
缓存来代替二级缓存。
2.5.16 简单讲一下 webservice 使用的场景?
webservice 是一个 SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平
台,可以实现不同的语言间的相互调用,通过 Internet 进行基于 Http 协议的网络应用间的
交互。
1、异构系统(不同语言)的整合
2、不同客户端的整合 浏览器、手机端(android,ios.塞班)、微信单、PC 端等终端来访

3、实实在在的列子:
天气预报:可以通过实现 webservice 客户端调用远程天气服务实现的。
单点登录:一个服务是所有系统的登录
2.5.17 简单介绍一下 actvit?
Activiti 是一个业务流程管理(BPM)和工作流系统,适用于开发人员和系统管理员。其核心是超快速,
稳定的 BPMN2 流程引擎。它易于与 Spring 集成使用。
主要要在 OA 中,把线下流程放到线上。 把现实生活中一些流程固话定义到系统中,然后通过输入表单
数据完成业务。
他可用在 OA 系统的流程管理中:
请假流程 小于三天,一级主管审批,大于三天二级才能审批。
报销流程 1000 2000 3000>....
如果你想找专门这方面的工作,要下去复习。


2.6 高级部分


2.6.1 有没有用过 linux?你都用它来做什么?
Linux 是一个长时间运行比较稳定的操作系统,所有我们一般会拿它作为服务器(web,db,app
等)。
Linux 本身具有 C 的编译环境、我们的一些软件是没有软件包(redis、nginx 等)的,需要在
Linux 的 C 编译环境编译得到软件包.
2.6.2 说一下 linux 下面的一下常用命令?
常用:
Pwd 获取当前路径
Cd 跳转到目录
Su -u 切换到管理员
Ls ls 列举目录
文件操作命令:
文件
tail 查看
rm -rf
vi
文件夹
mkdir
rm -r
2.6.3 你是使用什么来连接远程的 Linux 服务器的?
需要依赖于 Linux 服务器安装 ssh 服务端,一般这个 ssh 服务的端口 22.
需要依赖于 Linux 服务器安装 sfp 服务端,一般这个 sfp 服务的端口 25.
使用 ssh 客户端连接 linux 服务器,就有点儿像 windows 下面的远程连接。但是 linux 通过
ssh 连接上以后是没有图形界面,全是命令行。
Puty
Xshell
使用 sfp 客户端来连接 sfp 服务端,来上传和下载文件.(上传安装包,修改了配置文件上
传。)
Winscp
xfp
企业中常用的两种组合:
puty+winscp
Xshell+xfp=xmanager
面试:使用 xshell、puty 等 ssh 客户端来连接服务器,使用 xfp、winscp 等 sfp 客户端
来上传和现在文件。连接和上传、下载必须依赖于服务器的 ssh、sfp 服务,也就是 linux
服务器需要启动这两个服务。
2.6.4 有没有使用过云主机?
使用过,在原来的公司,我们没有使用自己的服务器,而是租用阿里的云主机。
没有使用过,但是有所了解。
云主机就是一些云服务运营商(阿里、华为、西部数码、新浪等),提供的远程的服务器功
能,我们开发者或者企业只需按需付费就可以租用对应的服务器。
使用 ssh 和 sfp 来进行操作。
2.6.5 有没有做过数据库优化方面的事情?
做过 mysql 数据库的优化、其他数据库类似
定位:查找、定位慢查询
优化手段:
a) 创建索引:创建合适的索引,我们就可以现在索引中查询,查询到以后直接找对应
的记录。
b) 分表 :当一张表的数据比较多或者一张表的某些字段的值比较多并且很少使用
时,采用水平分表和垂直分表来优化
c) 读写分离:当一台服务器不能满足需求时,采用读写分离的方式进行集群。
d) 缓存:使用 redis 来进行缓存
e) 一些常用优化技巧
2.6.6 查找慢查询并定位慢查询?
在项目自验项目转测试之前,在启动 mysql 数据库时开启慢查询,并且把执行慢的语句
写到日志中,在运行一定时间后。通过查看日志找到慢查询语句。
要找出项目中的慢 Sql 时
1、关闭数据库服务器(关闭服务)
2、把慢查询记录到日志中
3、设置慢查询时间
4、找出日志中的慢查询 SQL
使用 explain 慢查询语句,来详细分析语句的问题.
2.6.6 数据库优化之遵循范式?
数据库表设计时需要遵循方式
表的范式,是首先符合 1NF, 才能满足 2NF , 进一步满足 3NF
1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解.只要数据库是关系
型数据库(mysql/oracle/db2/sysbase/sql server),就自动的满足 1NF.关系型数据库中是不允许
分割列的。
2NF:表中的记录是唯一的.通常我们设计一个主键来实现
3NF:即表中不要有冗余数据, 就是说,表的信息,如果能够被推导出来,就不应该单独
的设计一个字段来存放.(外键)
反 3NF :没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低
范式标准,适当保留冗余数据。具体做法是: 在概念数据模型设计时遵守第三范式,降低
范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。 订
单和订单项、相册浏览次数和照片的浏览次数
2.6.7 选择合适的存储引擎
在开发中,我们经常使用的存储引擎 myisam / innodb/ memory
MyISAM 存储引擎
如果表对事务要求不高,同时是以查询和添加为主的,我们考虑使用 myisam 存储
引擎. 比如 bbs 中的 发帖表,回复表.
INNODB 存储引擎:
对事务要求高,保存的数据都是重要数据,我们建议使用 INNODB,比如订单表,
账号表.
Memory 存储
我们数据变化频繁,不需要入库,同时又频繁的查询和修改,我们考虑使用
memory, 速度极快.
问 MyISAM 和 INNODB 的区别(主要)
1. 事务安全 myisam 不支持事务而 innodb 支持
2. 查询和添加速度 myisam 不用支持事务就不用考虑同步锁,查找和添加和添加的速
度快
3. 支持全文索引 myisam 支持 innodb 不支持
4. 锁机制 myisam 支持表锁而 innodb 支持行锁(事务)
5. 外键 MyISAM 不支持外键, INNODB 支持外键. (通常不设置外键,通常是在程序中
保证数据的一致)
2.6.8 数据库优化之创建合适的索引?
索引(Index)是帮助 DBMS 高效获取数据的数据结构。
分类:普通索引/唯一索引/主键索引/全文索引
普通索引:允许重复的值出现
唯一索引:除了不能有重复的记录外,其它和普通索引一样(用户名、用户身份证、
email,tel)
主键索引:是随着设定主键而创建的,也就是把某个列设为主键的时候,数据库就会
给改列创建索引。这就是主键索引.唯一且没有 null 值
全文索引:用来对表中的文本域(char,varchar,text)进行索引, 全文索引针对 MyIsam
explain select * from artcles where match(ttle,body) against(‘database’);【会使用全
文索引】
2.6.9 索引使用小技巧?*****
索引弊端
1.占用磁盘空间。
2.对 dml(插入、修改、删除)操作有影响,变慢。
使用场景:
a: 肯定在 where 条件经常使用,如果不做查询就没有意义
b: 该字段的内容不是唯一的几个值(sex)
c: 字段内容不是频繁变化.
具体技巧:
1. 对于创建的多列索引(复合索引),不是使用的第一部分就不会使用索引。
alter table dept add index my_ind (dname,loc); // dname 左边的列,loc 就是右边的列
explain select * from dept where dname='aaa'\G 会使用到索引
explain select * from dept where loc='aaa'\G 就不会使用到索引
2. 对于使用 like 的查询,查询如果是’%aaa’不会使用到索引而‘aaa%’会使用到索引。
explain select * from dept where dname like '%aaa'\G 不能使用索引
explain select * from dept where dname like 'aaa%'\G 使用索引.
所以在 like 查询时,‘关键字’的最前面不能使用 % 或者 _这样的字符.,如果一定要前面
有变化的值,则考虑使用 全文索引->sphinx.
3. 如果条件中有 or,有条件没有使用索引,即使其中有条件带索引也不会使用。换言之,
就是要求使用的所有字段,都必须单独使用时能使用索引.
4. 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索
引。
expain select * from dept where dname=’111’;
expain select * from dept where dname=111;(数值自动转字符串)
expain select * from dept where dname=qqq;报错
也就是,如果列是字符串类型,无论是不是字符串数字就一定要用 ‘’ 把它包括起
来.
5. 如果 mysql 估计使用全表扫描要比使用索引快,则不使用索引。
表里面只有一条记录
2.6.10 数据库优化之分表?
分表分为水平(按行)分表和垂直(按列)分表
根据经验,Mysql 表数据一般达到百万级别,查询效率会很低,容易造成表锁,甚至堆积
很多连接,直接挂掉;水平分表能够很大程度较少这些压力。
按行数据进行分表。
如果一张表中某个字段值非常多(长文本、二进制等),而且只有在很少的情况下会查询。
这时候就可以把字段多个单独放到一个表,通过外键关联起来。
考试详情,一般我们只关注分数,不关注详情。
水平分表策略:
1.按时间分表
这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信
消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表。
2.按区间范围分表
一般在有严格的自增 id 需求上,如按照 user_id 水平分表:
table_1 user_id 从 1~100w
table_2 user_id 从 101~200w
table_3 user_id 从 201~300w
3.hash 分表*****
通过一个原始目标的 ID 或者名称通过一定的 hash 算法计算出数据存储表的表名,
然后访问相应的表。
2.6.11 数据库优化之读写分离
一台数据库支持的最大并发连接数是有限的,如果用户并发访问太多。一台服务器满足不
要要求是就可以集群处理。Mysql 的集群处理技术最常用的就是读写分离。
主从同步
数据库最终会把数据持久化到磁盘,如果集群必须确保每个数据库服务器的数据
是一直的。能改变数据库数据的操作都往主数据库去写,而其他的数据库从主数
据库上同步数据。
读写分离
使用负载均衡来实现写的操作都往主数据去,而读的操作往从服务器去。
2.6.12 数据库优化之缓存
在持久层(dao)和数据库(db)之间添加一个缓存层,如果用户访问的数据已经缓存起来
时,在用户访问时直接从缓存中获取,不用访问数据库。而缓存是在操作内存级,访问速
度快。
作用:减少数据库服务器压力,减少访问时间。
Java 中常用的缓存有,
1、hibernate 的二级缓存。该缓存不能完成分布式缓存。
2、可以使用 redis(memcahe 等)来作为中央缓存。
对缓存的数据进行集中处理
2.6.13 语句优化小技巧
DDL 优化:
1 、通过禁用索引来提供导入数据性能 。 这个操作主要针对有数据库的表,追加数

//去除键
alter table test3 DISABLE keys;
//批量插入数据
insert into test3 select * from test;
//恢复键
alter table test3 ENABLE keys;
2、 关闭唯一校验
set unique_checks=0 关闭
set unique_checks=1 开启
3、修改事务提交方式(导入)(变多次提交为一次)
set autocommit=0 关闭
//批量插入
set autocommit=1 开启
DML 优化(变多次提交为一次)
insert into test values(1,2);
insert into test values(1,3);
insert into test values(1,4);
//合并多条为一条
insert into test values(1,2),(1,3),(1,4)
DQL 优化
Order by 优化
1、多用索引排序
2
、普通结果排序(非索引排序)Filesort
group by 优化
是使用 order by null,取消默认排序
子查询优化
在客户列表找到不在支付列表的客户
#在客户列表找到不在“支付列表”的客户 , 查询没买过东西的客户
explain
select * from customer where customer_id not in (select DISTINCT customer_id from
payment); #子查询 -- 这种是基于 func 外链
explain
select * from customer c lef join payment p on(c.customer_id=p.customer_id) where
p.customer_id is null -- 这种是基于“索引”外链
Or 优化
在两个独立索引上使用 or 的性能优于
1
、 or 两边都是用索引字段做判断,性能好!!
2
、 or 两边,有一边不用,性能差
3、 如果 employee 表的 name 和 email 这两列是一个复合索引,但是如果是 :
name='A' OR email='B' 这种方式,不会用到索引!
limit 优化
select flm_id,descripton from flm order by ttle limit 50,5;
select a.flm_id,a.descripton from flm a inner join (select flm_id from flm order by ttle
limit 50,5)b on a.flm_id=b.flm_id
2.6.14 jdbc 批量插入几百万数据怎么实现?*****
1、变多次提交为一次
3、使用批量操作
省出的时间可观。
像这样的批量插入操作能不使用代码操作就不使用,可以使用存储过程来实现。
2.6.15 有没有使用过 redis? Redis 是什么
Redis 是一个 key-value 的 nosql 数据库.先存到内存中,会根据一定的策略持久化到磁盘,即
使断电也不会丢失数据。支持的数据类型比较多。
主要用来做缓存数据库的数据和 web 集群时当做中央缓存存放 seesion
2.4.15 Redis 和 memche 的比较?
1、 Redis 和 Memcache 都是将数据存放在内存中,都是内存数据库。不过 memcache 还可
用于缓存其他东西,例如图片、视频等等。
2、Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,hash 等数据结构的存储。
3、虚拟内存--Redis 当物理内存用完时,可以将一些很久没用到的 value 交换到磁盘
2.6.16 简单说一下 redis 的使用场景?
缓存:
把经常需要查询的、很少修改数据,放到读速度很快的空间(内存),以便下次访问减
少时间。减轻压力,减少访问时间.
计数器:
redis 中的计数器是原子性的内存操作。
可以解决库存溢出问题.进销存系统库存溢出。
session 缓存服务器:
web 集群时作为 session 缓存服务器
缓存队列等
2.6.17 redis 对象保存方式?
Json 字符串:
需要把对象转换为 json 字符串,当做字符串处理。直接使用 set get 来设置或者或。
优点:设置和获取比较简单
缺点:没有提供专门的方法,需要把把对象转换为 json。(jsonlib)
字节:
需要做序列号,就是把对象序列化为字节保存。
如果是担心 JSON 转对象会消耗资源的情况,这个问题需要考量几个地方,
第一点:就是使用的 JSON 转换 lib 是否就会存在性能问题。
第二点:就是数据的数据量级别,如果是存储百万级的大数据对象,建议采用存储序列化
对象方式。如果是少量的数据级对象,或者是数据对象字段不多,还是建议采用 JSON 转换
成 String 方式。
毕竟 redis 对存储字符类型这部分优化的非常好。具体采用的方式与方法,还要看你所使用
的场景。
2.6.18 Redis 数据淘汰机制
在 redis 中,允许用户设置最大使用内存大小 server.maxmemory,在内存限定的情况下是
很有用的。譬如,在一台 8G 机子上部署了 4 个 redis 服务点,每一个服务点分配 1.5G 的
内存大小,减少内存紧张的情况,由此获取更为稳健的服务。
内存大小有限,需要保存有效的数据?
redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。
redis 提供 6 种数据淘汰策略:
volatle-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的
数据淘汰
volatle-tl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据
淘汰
volatle-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-envicton(驱逐):禁止驱逐数据
2.6.19 Java 访问 Redis
1、使用 jedis java 客户端来访问 redis 服务器,有点类似通过 jdbc 访问 mysql 一样。
2、当然如果是 spring 进行集成时,可以使用 spring data 来访问 redis,spring data 只是对 jedis
的二次封装。jdbcTemplate jdbc 关系一样
2.6.20 Redis 集群
当一台数据无法满足要求,可以使用 reids 集群来处理,类似于 mysql 的读写分离。
2.6.21 简单介绍一下微信公共号的分类?
公众号:个人和企业都能申请
服务号:企业才能申请
企业号:企业才能申请
2.6.22 微信开发原理
微信公众平台开发者,通过接入认证的方式,让我们的服务器能处理来自微信服务器转发
的微信用户的请求,处理完成后返回给微信服务器,有微信服务器对用户响应。
2.6.23 怎么把微信和业务平台绑定?
微信用户和注册用户绑定?
让微信用户也能完成注册用户的功能。
用户注册实体中包含一个微信号的字段,当我进行绑定时就是修改用户的微信号字段。
当然我们在进行菜单跳转到页面后,我们是无法直接获取微信号的。要通过微信网页授权
来获取微信号。
第一步:用户同意授权,获取 code
https://open.weixin.qq.com/connect/oauth2/authorize?
appid=APPID&redirect_uri=REDIRECT_URI&response_type=c
ode&scope=SCOPE&state=STATE#wechat_redirect 若提示“该
链接无法访问”,请检查参数是否填写错误,是否拥有 scope 参数对应
的授权作用域权限。
第二步:通过 code 换取网页授权 openId 也就是我们微信号
获 取 code 后 , 请 求 以 下 链 接 获 取 access_token :
https://api.weixin.qq.com/sns/oauth2/access_token?
appid=APPID&secret=SECRET&code=CODE&grant_type=aut
horization_code
{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE" }
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章