网站首页 > 知识剖析 正文
161 说出 5 个 JDK 1.8 引入的新特性?
Java 8 在 Java 历史上是一个开创新的版本,下面 JDK 8 中 5 个主要的特
性:Lambda 表达式,允许像对象一样传递匿名函数Stream API,充分利用现代多
核 CPU,可以写出很简洁的代码Date 与 Time API,最终,有一个稳定、简单
的日期和时间库可供你使用扩展方法,现在,接口中可以有静态、默认方法。重复
注解,现在你可以将相同的注解在同一类型上使用多次。
162 a==b”和”a.equals(b)”有什么区别?
如果 a 和 b 都是对象,则 a==b 是比较两个对象的引用,只有当 a 和 b 指向的
是堆中的同一个对象才会返回 true,而 a.equals(b) 是进行逻辑比较,所以通常需
要重写该方法来提供逻辑一致性的比较。例如,String 类重写 equals() 方法,所
以可以用于两个不同对象,但是包含的字母相同的比较。
163 a.hashCode() 有什么用?与 a.equals(b) 有什么关系?
hashCode() 方法是相应对象整型的 hash 值。它常用于基于 hash 的集合类,
如 Hashtable、HashMap、LinkedHashMap等等。它与 equals() 方法关系特别
紧密。根据 Java 规范,两个使用 equal() 方法来判断相等的对象,必须具有相
同的 hash code。
164 JVM为什么可以跨平台
JVM能跨计算机体系结构(操作系统)来执行Java字节码(JVM字节码指令集),屏
蔽可与各个计算机平台相关的软件或者硬件之间的差异,使得与平台相关的耦合统一
由JVM提供者来实现。
指令集:计算机所能识别的机器语言的命令集合。
每个运行中的Java程序都是一个JVM实例
165 描述JVM体系结构
(1)类加载器:JVM启动时或者类运行时将需要的class加载到JVM中。每个被装载的
类的类型对应一个Class实例,唯一表示该类,存于堆中。
(2)执行引擎:负责执行JVM的字节码指令(CPU)。执行引擎是JVM的核心部分,作
用是解析字节码指令,得到执行结果(实现方式:直接执行,JIT(just in time)
即时编译转成本地代码执行,寄存器芯片模式执行,基于栈执行)。本质上就是一个
个方法串起来的流程。每个Java线程就是一个执行引擎的实例,一个JVM实例中会有
多个执行引擎在工作,有的执行用户程序,有的执行JVM内部程序(GC).
(3)内存区:模拟物理机的存储、记录和调度等功能模块,如寄存器或者PC指针记录器
。存储执行引擎执行时所需要存储的数据。
(4)本地方法接口:调用操作系统本地方法返回结果。
166 描述JVM工作机制
机器如何执行代码:源代码-预处理器-编译器-汇编程序-目标代码-链接器-可执行程
序。
Java编译器将高级语言编译成虚拟机目标语言。
JVM执行字节码指令是基于栈的架构,所有的操作数必须先入栈,然后根据操作码选择
从栈顶弹出若干元素进行计算后将结果压入栈中。
通过Java编译器将源代码编译成虚拟机目标语言,然后通过JVM执行引擎执行。
167 为何JVM字节码指令选择基于栈的结构
JVM要设计成平台无关性,很难设计统一的基于寄存器的指令。
为了指令的紧凑性,让编译后的class文件更加紧凑,提高字节码在网络上的传输效率
168 描述执行引擎的架构设计
创建新线程时,JVM会为这个线程创建一个栈,同时分配一个PC寄存器(指向第一行可
执行的代码)。调用新方法时会在这个栈上创建新的栈帧数据结构。执行完成后方法对
应的栈帧将消失,PC寄存器被销毁,局部变量区所有值被释放,被JVM回收。
169 描述javac编译器的基本结构
Javac编译器的作用是将符合Java语言规范的的源代码转换成JVM规范的Java字节码。
(1)词法分析器组件:找出规范化的Token流
(2)语法分析器组件:生成符合Java语言规范的抽象语法树
(3)语义分析器组件:将复杂的语法转化成最简单的语法,注解语法树
(4)代码生成器组件:将语法树数据结构转化成字节码数据结构
170 ClassLoader(类加载器)有哪些
1)Bootstrap ClassLoader(启动类加载器):完全由JVM控制,加载JVM自身工作需要
的类(JAVA_HOME/lib)
(2)Extension ClassLoader(扩展类加载器):属于JVM自身一部分,不是JVM自身实
现的(JAVA_HOME/lib/ext)
(3)Appclication ClassLoader(应用程序类加载器):父类是Extension ClassLoader,
加载Classpath(用户类路径)上的类库
171 描述ClassLoader的作用(什么是类加载器)和加载过程
将Class文件加载到JVM中、审查每个类由谁加载(父优先的等级加载机制)、将Class字
节码重新解析成JVM统一要求的对象(Class对象)格式。
.class->findclass->Liking:Class规范验证、准备、解析->类属性初始化赋值
(static块的执行)->Class对象(这也就是为什么静态块只执行一次)
172 描述JVM类加载机制
ClassLoader首先不会自己尝试去加载类,而是把这个请求委托给父类加载器完成,
每一个层次都是。只有当父加载器反馈无法完成请求时(在搜索范围内没有找到所需
的类),子加载器才会尝试加载(等级加载机制、父优先、双亲委派)。
好处:类随着它的加载器一起具有一种带有优先级的层次关系;保证同一个类只能
被一个加载器加载。
173 JVM加载class文件到内存的两种方式
(1)隐式加载:继承或者引用的类不在内存中
(2)显式加载:代码中通过调用ClassLoader加载
174 加载类错误分析及其解决
1)ClassNotFoundException:没有找到对应的字节码(.class)文件;检查
classpath下有无对应文件
(2)NoClassDefFoundError:隐式加载时没有找到,ClassNotFoundException引
发NoClassDefFoundError;确保每个类引用的类都在classpath下
(3)UnsatisfiedLinkError:(未满足链接错误)删除了JVM的某个lib文件或者解
析native标识的方法时找不到对应的本地库文件
(4)ClassCastException:强制类型转换时出现这个错误;容器类型最好显示指明其
所包含对象类型、先instanceof检查是不是目标类型,再类型转换
(5)ExceptionInitializerError:给类的静态属性赋值时
175 Java应不应该动态加载类(JVM能不能动态加载类)
JVM中对象只有一份,不能被替换,对象的引用关系只有对象的创建者持有和使用,
JVM不可干预对象的引用关系,因为JVM不知道对象是怎么被使用的,JVM不知道对象
的运行时类型,只知道编译时类型。
但是可以不保存对象的状态,对象创建和使用后就被释放掉,下次修改后,对象就是
新的了(JSP)。
176 Java中哪些组件需要使用内存
(1)Java堆:存储Java对象
(2)线程:Java运行程序的实体
(3)类和类加载器:存储在堆中,这部分区域叫永久代(PermGen区)
(4)NIO:基于通道和缓冲区来执行I/O的新方式。
(5)JNI:本地代码可以调用Java方法,Java方法也可以调用本地代码
177 描述JVM内存结构及内存溢出
JVM是按照运行时数据的存储结构来划分内存结构的。
PC寄存器数据:严格来说是一个数据结构,保存当前正在执行的程序的内存地址。
为了线程切换后能恢复到正确的执行位置,线程私有。不会内存溢出。
(1)Java栈:方法执行的内存模型,存储线程执行所需要的数据。线程私有。
–OutOfMemoryError:JVM扩展栈时无法申请到足够的空间。一个不断调用自身而
不会终止的方法。
–StackOverflowError:请求的栈深度大于JVM所允许的栈深度。创建足够多的线程。
(2)堆:存储对象,每一个存在堆中Java对象都是这个对象的类的副本,复制包括
继承自他父类的所有非静态属性。线程共享。
–OutOfMemoryError:对象数量到达堆容量限制。可通过不断向ArrayList中添加
对象实现。
178 描述JVM内存结构及内存溢出
(3)方法区:存储类结构信息。包括常量池(编译期生产的各种字面量和符号引用)
和运行时常量池。线程共享。
–OutOfMemoryError:同运行时常量池。
(4)本地方法栈:与Java栈类似,为JVM运行Native方法准备的空间。线程私有。
(C栈)OutOfMemoryError和StackOverflowError同JVM栈。
(5)运行时常量池:代表运行时每个class文件中的常量表。运行期间产生的新的常
量放入运行时常量池。
–OutOfMemoryError:不断向List中添加字符串,然后String.inern(),
PermGen Space(运行时常量池属于方法区)。
(6)本地直接内存:即NIO。
–OutOfMemoryError:通过直接向操作系统申请分配内存。
179 描述JVM内存分配策略
(1)对象优先分配在Eden
(2)大对象直接进入老年代
(3)长期存活的对象将进入老年代
(4)幸存区相同年龄对象的占幸存区空间的多于其一半,将进入老年代
(5)空间担保分配(老年代剩余空间需多于幸存区的一半,否则要Full GC)
180 描述JVM如何检测垃圾
通过可达性分析算法,通过一些列称为GC Roots的对象作为起始点,从这些起始
点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引
用链相连(GC Roots到这个对象不可达),则证明这个对象是不可用的。
使用可达性分析算法而不是引用计数算法。因为引用计数算法很难解决对象之间相
互循环引用的问题。
181 哪些元素可作为GC Roots
(1)JVM栈(栈帧中的本地变量表)中的引用
(2)方法区中类静态属性引用
(3)方法区中常量引用
(4)本地方法栈中JNI(一般的Native方法)引用
182 描述分代垃圾收集算法的思路
把对象按照寿命长短来分组,分为年轻代和老年代,新创建的在老年代,经历几次
回收后仍然存活的对象进入老年代,老年代的垃圾频率不像年轻代那样频繁,减少
每次收集都去扫描所有对象的数量,提高垃圾回收效率。
183 描述基于分代的堆结构及其比例
(1)年轻代(Young区-1/4):Eden+Survior(1/8,这个比例保证只有10%的空间被
浪费,保证每次回收都只有不多于10%的对象存活)=From+To,存放新创建的对象.
(2)老年代(Old区 ):存放几次垃圾收集后存活的对象
(3)永久区(Perm区):存放类的Class对象
184 描述垃圾收集算法
1)标记-清除算法:首先标记处所要回收的对象,标记完成后统一清除。缺点:标记
效率低,清除效率低,回收结束后会产生大量不连续的内存碎片(没有足够连续空间
分配内存,提前触发另一次垃圾回收)。适用于对象存活率高的老年代。
(2)复制算法(Survivor的from和to区,from和to会互换角色):
将内存容量划分大小相等的两块,每次只使用其中一块。一块用完,就将存活的对象
复制到另一块,然后把使用过的一块一次清除。不用考虑内存碎片,每次只要移动顶
端指针,按顺序分配内存即可,实现简单运行高效。适用于新生代。
缺点:内存缩小为原来的一般,代价高。浪费50%的空间。
(3)标记-整理算法:
标记完成后,将存活的对象移动到一端,然后清除边界以外的内存。适用于对象存活
率高的老年代。
185 描述新生代和老年代的回收策略
Eden区满后触发minor GC,将所有存活对象复制到一个Survivor区,另一Survivor
区存活的对象也复制到这个Survivor区中,始终保证有一个Survivor是空的。
Toung区Survivor满后触发minor GC后仍然存活的对象存到Old区,如果Survivor
区放不下Eden区的对象或者Survivor区对象足够老了,直接放入Old区,如果Old
区放不下则触发Full GC。
Perm区满将触发Major GC。
186 描述CMS垃圾收集器
CMS 收集器:Concurrent Mark Sweep 并发标记-清除。重视响应速度,适用于互
联网和B/S系统的服务端上。初始标记还是需要Stop the world 但是速度很快。缺
点:CPU资源敏感,无法浮动处理垃圾,会有大量空间碎片产生。
187 MySQL的复制原理以及流程
基本原理流程,3个线程以及之间的关联;
主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中;
从:io线程——在使用start slave 之后,负责从master上拉取 binlog 内
容,放进 自己的relay log中;
从:sql执行线程——执行relay log中的语句;
188 MySQL中myisam与innodb的区别
1>.InnoDB支持事物,而MyISAM不支持事物
2>.InnoDB支持行级锁,而MyISAM支持表级锁
3>.InnoDB支持MVCC, 而MyISAM不支持
4>.InnoDB支持外键,而MyISAM不支持
5>.InnoDB不支持全文索引,而MyISAM支持。
189 innodb引擎的4大特性
插入缓冲(insert buffer),二次写(double write),自适应哈希索引(ahi),预读(read ahead)
190 MySQL中varchar与char的区别以及varchar(50)中的50代表的涵义
1)、varchar与char的区别char是一种固定长度的类型,varchar则是一种可变
长度的类型(2)、varchar(50)中50的涵义最多存放50个字符,varchar(50)和
(200)存储hello所占空间一样,但后者在排序时会消耗更多内存,因为order by col采
用fixed_length计算col长度(memory引擎也一样)(3)、int(20)中20的涵义是指显
示字符的长度但要加参数的,最大为255,比如它是记录行数的id,插入10笔资料,它
就显示00000000001 ~~~00000000010,当字符的位数超过11,它也只显示11位,如果
你没有加那个让它未满11位就前面加0的参数,它不会在前面加020表示最大显示宽度为
20,但仍占4字节存储,存储范围不变;(4)、mysql为什么这么设计对大多数应用没有
意义,只是规定一些工具用来显示字符的个数;int(1)和int(20)存储和计算均一样
191 innodb有多少种日志
错误日志:记录出错信息,也记录一些警告信息或者正确的信息。查询日志:记录所
有对数据库请求的信息,不论这些请求是否得到了正确的执行。慢查询日志:设置一个
阈值,将运行时间超过该值的所有SQL语句都记录到慢查询的日志文件中。二进制日志:记录
对数据库执行更改的所有操作。中继日志:事务日志
192 事物的4种隔离级别
隔离级别读未提交(RU)读已提交(RC)可重复读(RR)串行
193 如何设计一个高并发的系统
数据库的优化,包括合理的事务隔离级别、SQL语句优化、索引的优化
使用缓存,尽量减少数据库 IO
分布式数据库、分布式缓存
服务器的负载均衡
194 锁的优化策略
读写分离
分段加锁
减少锁持有的时间
多个线程尽量以相同的顺序去获取资源
195 索引的底层实现原理和优化
B+树,经过优化的B+树
主要是在所有的叶子结点中增加了指向下一个叶子节点的指针,因此InnoDB建议为大部
分表使用默认自增的主键作为主索引。
196 什么情况下设置了索引但无法使用
以“%”开头的LIKE语句,模糊匹配
OR语句前后没有同时使用索引
数据类型出现隐式转化(如varchar不加单引号的话可能会自动转换为int型)
197 实践中如何优化MySQL
SQL语句及索引的优化
数据库表结构的优化
系统配置的优化
硬件的优化
198 简单描述mysql中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着
对数据表里所有记录的引用指针。普通索引(由关键字KEY或INDEX定义的索引)的唯一任
务是加快对数据的访问速度。普通索引允许被索引的数据列包含重复的值。如果能确定
某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字
UNIQUE把它定义为一个唯一索引。也就是说,唯一索引可以保证数据记录的唯一性。主
键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条
记录,使用关键字PRIMARY KEY 来创建。索引可以覆盖多个数据列,如像
INDEX(columnA, columnB)索引,这就是联合索引。索引可以极大的提高数据的
查询速度,但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作
索引文件
199 数据库中的事务是什么?
事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都
成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果所有操作完成,事
务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该
事务所有操作的影响都将取消。ACID 四大特性,原子性、隔离性、一致性、持久性
200 了解XSS攻击吗?如何防止?
XSS是跨站脚本攻击,首先是利用跨站脚本漏洞以一个特权模式去执行攻击者构造的脚
本,然后利用不安全的Activex控件执行恶意的行为。使用htmlspecialchars()函数
对提交的内容进行过滤,使字符串里面的特殊符号实体化
201 SQL注入漏洞产生的原因?如何防止
SQL注入产生的原因:程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,
导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行。
防止SQL注入的方式:
开启配置文件中的magic_quotes_gpc 和 magic_quotes_runtime设置
执行sql语句时使用addslashes进行sql语句转换
Sql语句书写尽量不要省略双引号和单引号。
过滤掉sql语句中的一些关键词:update、insert、delete、select、 * 。
提高数据库表和字段的命名技巧,对一些重要的字段根据程序的特点命名,取不易被猜到的。
Php配置文件中设置register_globals为off,关闭全局变量注册
控制错误信息,不要在浏览器上输出错误信息,将错误信息写到日志文件中
202 解释MySQL外连接、内连接与自连接的区别
先说什么是交叉连接: 交叉连接又叫笛卡尔积,它是指不使用任何条件,直接将一个表的
所有记录和另一个表中的所有记录一一匹配。
内连接 则是只有条件的交叉连接,根据某个条件筛选出符合条件的记录,不符合条件的记
录不会出现在结果集中,即内连接只连接匹配的行。外连接 其结果集中不仅包含符合连
接条件的行,而且还会包括左表、右表或两个表中的所有数据行,这三种情况依次称之为左
外连接,右外连接,和全外连接。
左外连接,也称左连接,左表为主表,左表中的所有记录都会出现在结果集中,对于那些
在右表中并没有匹配的记录,仍然要显示,右边对应的那些字段值以NULL来填充。右外连
接,也称右连接,右表为主表,右表中的所有记录都会出现在结果集中。左连接和右连接可
以互换,MySQL目前还不支持全外连接
203 Myql中的事务回滚机制概述
事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工
作单位,事务回滚是指将该事务已经完成的对数据库的更新操作撤销。
要同时修改数据库中两个不同表时,如果它们不是一个事务的话,当第一个表修改完,可能
第二个表修改过程中出现了异常而没能修改,此时就只有第二个表依旧是未修改之前的状
态,而第一个表已经被修改完毕。而当你把它们设定为一个事务的时候,当第一个表修改
完,第二表修改出现异常而没能修改,第一个表和第二个表都要回到未修改的状态,这就
是所谓的事务回滚
204 什么是存储过程?用什么来调用?
存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后
在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语
句执行要快。可以用一个命令对象来调用存储过程
205 MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?
a. 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。
b. 选择合适的表字段数据类型和存储引擎,适当的添加索引。
c. mysql库主从读写分离。
d. 找规律分表,减少单表中的数据量提高查询速度。
e。添加缓存机制,比如memcached,apc等。
f. 不经常改动的页面,生成静态页面。
g. 书写高效率的SQL。比如 SELECT * FROM TABEL 改为 SELECT field_1,
field_2, field_3 FROM TABLE.
206 对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题
a. 确认服务器是否能支撑当前访问量。
b. 优化数据库访问。
c. 禁止外部访问链接(盗链), 比如图片盗链。
d. 控制文件下载。
e. 使用不同主机分流。
f. 使用浏览统计软件,了解访问量,有针对性的进行优化。
207 存储时期
Datatime:以 YYYY-MM-DD HH:MM:SS 格式存储时期时间,精确到秒,占用8个字节
得存储空间,datatime类型与时区无关
Timestamp:以时间戳格式存储,占用4个字节,范围小1970-1-1到2038-1-19,显示
依赖于所指定得时区,默认在第一个列行的数据修改时可以自动得修改timestamp列得值
Date:(生日)占用得字节数比使用字符串.datatime.int储存要少,使用date只需
要3个字节,存储日期月份,还可以利用日期时间函数进行日期间得计算
Time:存储时间部分得数据
注意:不要使用字符串类型来存储日期时间数据(通常比字符串占用得储存空间小,
在进行查找过滤可以利用日期得函数)
使用int存储日期时间不如使用timestamp类型
208 Hibernate工作原理
1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3.打开
Sesssion 4.创建事务Transation 5.持久化操作 6.提交事务 7.关闭Session
8.关闭SesstionFactory (finally进行执行)
209 Hibernate中get和load有什么不同之处
把get和load放到一起进行对比是Hibernate面试时最常问到的问题,这是因为只有
正确理解get()和load()这二者后才有可能高效地使用Hibernate。get和load的最
大区别是,如果在缓存中没有找到相应的对象,get将会直接访问数据库并返回一个
完全初始化好的对象,而这个过程有可能会涉及到多个数据库调用;而load方法在缓
存中没有发现对象的情况下,只会返回一个代理对象,只有在对象getId()之外的其它
方法被调用时才会真正去访问数据库,这样就能在某些情况下大幅度提高性能
210 Hibernate中save、persist和saveOrUpdate这三个方法的不同之处
除了get和load,这又是另外一个经常出现的Hibernate面试问题。 所有这三个方法,
也就是save()、saveOrUpdate()和persist()都是用于将对象保存到数据库中的方法,
但其中有些细微的差别。例如,save()只能INSERT记录,但是saveOrUpdate()可以
进行 记录的INSERT和UPDATE。还有,save()的返回值是一个Serializable对象,
而persist()方法返回值为void
211 Hibernate中的命名SQL查询指的是什么
Hibernate的这个面试问题同Hibernate提供的查询功能相关。命名查询指的是
用标签在影射文档中定义的SQL查询,可以通过使用Session.getNamedQuery()
方法对它进行调用。命名查询使你可以使用你所指定的一个名字拿到某个特定的查询。
Hibernate中的命名查询可以使用注解来定义,也可以使用我前面提到的xml影射问句
来定义。在Hibernate中,@NameQuery用来定义单个的命名查询,@NameQueries用来定义多个命名查询。
212 Hibernate中的SessionFactory有什么作用? SessionFactory是线程安全的吗
这也是Hibernate框架的常见面试问题。顾名思义,SessionFactory就是一个用于
创建Hibernate的Session对象的工厂。SessionFactory通常是在应用启动时创建
好的,应用程序中的代码用它来获得Session对象。作为一个单个的数据存储,它也
是 线程安全的,所以多个线程可同时使用同一个SessionFactory。Java JEE应用
一般只有一个SessionFactory,服务于客户请求的各线程都通过这个工厂来获得
Hibernate的Session实例,这也是为什么SessionFactory接口的实现必须是线
程安全的原因。还有,SessionFactory的内部状态包含着同对象关系影射有关的所
有元数据,它是 不可变的,一旦创建好后就不能对其进行修改了。
213 Hibernate中的Session指的是什么? 可否将单个的Session在多个线程间进行共享
前面的问题问完之后,通常就会接着再问这两个问题。问完SessionFactory的问题
后就该轮到Session了。Session代表着Hibernate所做的一小部分工作,它负责维
护者同数据库的链接而且 不是线程安全的,也就是说,Hibernage中的Session不能
在多个线程间进行共享。虽然Session会以主动滞后的方式获得数据库连接,但是
Session最好还是在用完之后立即将其关闭。
214 hibernate中sorted collection和ordered collection有什么不同
Hibernate中,对象具有三种状态:transient、persistent和detached。同
Hibernate的session有关联的对象是persistent对象。对这种对象进行的所有
修改都会按照事先设定的刷新策略,反映到数据库之中,也即,可以在对象的任何
一个属性发生改变时自动刷新,也可以通过调用Session.flush()方法显式地进行
刷新。如果一个对象原来同Session有关联关系,但当下却没有关联关系了,这样的
对象就是detached的对象。你可以通过调用任意一个session的update()或者
saveOrUpdate()方法,重新将该detached对象同相应的seesion建立关联关系。
Transient对象指的是新建的持久化类的实例,它还从未同Hibernate的任何
Session有过关联关系。同样的,你可以调用persist()或者save()方法,将
transient对象变成persistent对象
215 Hibernate中Session的lock()方法有什么作用
这是一个比较棘手的Hibernate面试问题,因为Session的lock()方法重建了关联
关系却并没有同数据库进行同步和更新。因此,你在使用lock()方法时一定要多加
小心。顺便说一下,在进行关联关系重建时,你可以随时使用Session的update()
方法同数据库进行同步。有时这个问题也可以这么来问:Session的lock()方法和
update()方法之间有什么区别?。这个小节中的关键点也可以拿来回答这个问题。
216 Hibernate中二级缓存指的是什么
这是同Hibernate的缓存机制相关的第一个面试问题,不出意外后面还会有更多这方
面的问题。二级缓存是在SessionFactory这个级别维护的缓存,它能够通过节省几
番数据库调用往返来提高性能。还有一点值得注意,二级缓存是针对整个应用而不是
某个特定的session的。
217 Hibernate中的查询缓存指的是什么
这个问题有时是作为上个Hibernate面试问题的后继问题提出的。查询缓存实际上保
存的是sql查询的结果,这样再进行相同的sql查询就可以之间从缓存中拿到结果了。
为了改善性能,查询缓存可以同二级缓存一起来使用。Hibernate支持用多种不同的
开源缓存方案,比如EhCache,来实现查询缓存
218 为什么在Hibernate的实体类中要提供一个无参数的构造器这一点非常重要
每个Hibernate实体类必须包含一个 无参数的构造器, 这是因为Hibernate框架要
使用Reflection API,通过调用Class.newInstance()来创建这些实体类的实例。
如果在实体类中找不到无参数的构造器,这个方法就会抛出一个InstantiationException异常
219 可不可以将Hibernate的实体类定义为final类
是的,你可以将Hibernate的实体类定义为final类,但这种做法并不好。因为
Hibernate会使用代理模式在延迟关联的情况下提高性能,如果你把实体类定义成
final类之后,因为 Java不允许对final类进行扩展,所以Hibernate就无法再使
用代理了,如此一来就限制了使用可以提升性能的手段。不过,如果你的持久化类实
现了一个接口而且在该接口中声明了所有定义于实体类中的所有public的方法轮到
话,你就能够避免出现前面所说的不利后果
220 hibernate的三种状态之间如何转换
当对象由瞬时状态(Transient)一save()时,就变成了持久化状态; 当我们在
Session里存储对象的时候,实际是在Session的Map里存了一份, 也就是它的缓
存里放了一份,然后,又到数据库里存了一份,在缓存里这一份叫持久对象
(Persistent)。 Session 一 Close()了,它的缓存也都关闭了,整个Session也
就失效了,这个时候,这个对象变成了游离状态(Detached),但数据库中还是存在
的。 当游离状态(Detached)update()时,又变为了持久状态(Persistent)。
当持久状态(Persistent)delete()时,又变为了瞬时状态(Transient), 此时,
数据库中没有与之对应的记录
221 Hibernate是如何延迟加载
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的
操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,
从而提高了服务器的性能
222 解Hibernate中怎样实现类之间的关系
类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操
作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的
many-to-one、one-to-many、many-to-many
223 如何优化Hibernate
1.使用双向一对多关联,不使用单向一对多 2.灵活使用单向一对多关联
3.不用一对一,用多对一取代 4.配置对象缓存,不使用集合缓存 5.一对多
集合使用Bag,多对多集合使用Set 6. 继承类使用显式多态 7. 表字段要少,
表关联不要怕多,有二级缓存撑腰
224 Hibernate的五个核心接口
Configuration 接口:配置Hibernate,根据其启动hibernate,创建
SessionFactory 对象; SessionFactory 接口:初始化Hibernate,充当
数据存储源的代理,创建 session 对象,sessionFactory 是线程安全的,
意味着它的同一个实例可以被应 用的多个线程共享,是重量级、二级缓存;
Session 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,
避免多个线程共享同一个session,是轻量级、一级缓存; Transaction 接口:
管理事务; Query 和Criteria 接口:执行数据库的查询
225 #{}和${}的区别是什么
是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如 {}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如{driver}会被静态替换为com.mysql.jdbc.Driver。#{}是sql
的参数占位符,Mybatis会将sql中的#{}替换为?号,在sql执行前会使用
PreparedStatement的参数设置方法,按序给sql的?号占位符设置参数值,
比如ps.setInt(0, parameterValue),#{item.name}的取值方式为使用反
射从参数对象中获取item对象的name属性值,相当于param.getItem().getName()。
226 Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签
还有很多其他的标签,、、、、
,加上动态sql的9个标签,trim|where|set|foreach|if|choose|when|otherwise|bind等,
其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签
227 最佳实践中,通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗
Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的
值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就
是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方
法名拼接字符串作为key值,可唯一定位一个MappedStatement,举例:
com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到
namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的
MappedStatement。在Mybatis中,每一个、、、
标签,都会被解析为一个MappedStatement对象。
Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。
Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生
成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代
表的sql,然后将sql执行结果返回
228 Mybatis是如何进行分页的?分页插件的原理是什么
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,
而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以
使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截
方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句
和物理分页参数。
举例:select * from student,拦截sql后重写为:select t.* from (select
from student)t limit 0,10
229 为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对
象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对
象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具
230 Mybatis比IBatis比较大的几个改进是什么
a.有接口绑定,包括注解绑定sql和xml绑定Sql ,
b.动态sql由原来的节点配置变成OGNL(对象图导航语言)表达式,
c. 在一对一,一对多的时候引进了association,在一对多的时候引入了collection节
点,不过都是在resultMap里面配置
231 接口绑定有几种实现方式,分别是怎么实现的
接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上
@Select@Update等注解里面包含Sql语句来绑定,另外一种就是通过xml里面写SQL来绑定,
在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名.
232 MyBatis实现一对一有几种方式?具体怎么操作的
有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,
通过在resultMap里面配置association节点配置一对一的类就可以完成;
嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查
询数据,也是通过association配置,但另外一个表的查询通过select属性配置
233 MyBatis的缓存
MyBatis的缓存分为一级缓存和二级缓存,
一级缓存放在session里面,默认就有,二级缓存放在它的命名空间里,默认是打开的
, 使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态)
,可在它的映射文件中配置<cache/
234 什么是spring?
Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用,但
是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应
用开发,并通过POJO为基础的编程模型促进良好的编程习惯。
235 使用Spring框架的好处是什么
轻量:Spring 是轻量的,基本的版本大约2MB
控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是
创建或查找依赖的对象们
面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统
服务分开
容器:Spring 包含并管理应用中对象的生命周期和配置
MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品
事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全
局事务(JTA)
异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate
or JDO抛出的)转化为一致的unchecked 异常
236 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
237 核心容器(应用上下文) 模块
这是基本的Spring模块,提供spring 框架的基础功能,BeanFactory 是 任何
以spring为基础的应用的核心。Spring 框架建立在此模块之上,它使Spring成为一个容器
238 BeanFactory – BeanFactory 实现举例
Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和
依赖从正真的应用代码中分离。
最常用的BeanFactory 实现是XmlBeanFactory 类
239 XMLBeanFactory
最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory ,
它根据XML文件中的定义加载beans。该容器从XML 文件读取配置元数据并用它去
创建一个完全配置的系统或应用
240 解释AOP模块
AOP模块用于发给我们的Spring应用做面向切面的开发, 很多支持由AOP联盟提供,
这样就确保了Spring和其他AOP框架的共通性。这个模块将元数据编程引入Spring
241 什么是Spring IOC 容器
Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,
并且管理这些对象的整个生命周期
242 IOC的优点是什么
IOC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例
和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载
服务时的饿汉式初始化和懒加载
243 ApplicationContext通常的实现是什么
FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,
XML Bean 配置文件的全路径名必须提供给它的构造函数。
ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,
这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用
的所有bean
244 Bean 工厂和 Application contexts 有什么区别?
Application contexts提供一种方法处理文本消息,一个通常的做法是加载文件资源
(比如镜像),它们可以向注册为监听器的bean发布事件。另外,在容器或容器内的对
象上执行的那些不得不由bean工厂以程序化方式处理的操作,可以在Application
contexts中以声明的方式处理。Application contexts实现了MessageSource接口,
该接口的实现以可插拔的方式提供获取本地化消息的方
245 什么是Spring的依赖注入
依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建
对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在
配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来
246 有哪些不同类型的IOC(依赖注入)方式
构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系
列参数,每个参数代表一个对其他类的依赖。
Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法
实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入
247 Spring 的优点
(1)spring属于低侵入式设计,代码的污染极低;
(2)spring的DI机制降低了业务对象替换的复杂性;
(3)容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能;
(4)降低了组件之间的耦合性 ,实现了软件各层之间的解耦;
(5)容器提供单例模式支持;
(6)可以使用容器提供的众多服务,如事务管理,消息服务等;
(7)容器提供了众多的辅助类,能加快应用的开发;
(8)spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等
(9)独立于各种应用服务器
(10)Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择
spring的部分或全部。
248 Spring的AOP理解
AOP,一般称为面向方面(切面)编程,作为面向对象的一种补充,用于解剖封装好的
对象内部,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,
这个模块被命名为“切面”(Aspect),切面将那些与业务无关,却被业务模块共同调用
的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了
系统的可维护性。可用于权限认证、日志、事务处理。
AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代
理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。
(1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP
代理类,因此也称为编译时增强,他会在编译阶段将AspectJ织入到Java字节码中,
运行的时候就是增强之后的AOP对象。
(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码
,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对
象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:
①JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。
JDK动态代理的核心是InvocationHandler接口和Proxy类。生成的代理对象的方法
调用都会委托到InvocationHandler.invoke()方法,当我们调用代理类对象的方
法时,这个“调用”会转送到invoke方法中,代理类对象作为proxy参数传入,参数
method标识了我们具体调用的是代理类的哪个方法,args为这个方法的参数。
②如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。
CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动
态的生成指定类的一个子类对象,并覆盖其中特定方法,覆盖方法时可以添加增强代
码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为
final,那么它是无法使用CGLIB做动态代理的。
(3)静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的
静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring
AOP则无需特定的编译器处理
249 Spring的IoC理解
(1)IOC就是控制反转。就是对象的创建权反转交给Spring,由容器控制程序之间
的依赖关系,作用是实现了程序的解耦合,而非传统实现中,由程序代码直接操控。
(依赖)控制权由应用代码本身转到了外部容器,由容器根据配置文件去创建实例并管
理各个实例之间的依赖关系,控制权的转移,是所谓反转,并且由容器动态的将某种
依赖关系注入到组件之中。BeanFactory 是Spring IoC容器的具体实现与核心接口,
提供了一个先进的配置机制,使得任何类型的对象的配置成为可能,用来包装和管理
各种bean。
(2)最直观的表达就是,IOC让对象的创建不用去new了,可以由spring自动生产,
这里用的就是java的反射机制,通过反射在运行时动态的去创建、调用对象。spring
就是根据配置文件在运行时动态的去创建对象,并调用对象的方法的。
(3)Spring的IOC有三种注入方式 :第一是根据属性注入,也叫set方法
注入;第二种是根据构造方法进行注入;第三种是根据注解进行注入。
详细的说:
(4)IoC,控制反转:将对象交给容器管理,你只需要在spring
配置文件总配置相应的bean,以及设置相关的属性,让spring容器
生成类的实例对象以及管理对象。在spring容器启动的时候,spring会
把你在配置文件中配置的bean都初始化以及装配好,然后在你需要调用的时候
,就把它已经初始化好的那些bean分配给你需要调用这些bean的类。就是将
对象的控制权反转给spring容器管理。
(5)DI机制(Dependency Injection,依赖注入):可以说是IoC的其中一
个内容,在容器实例化对象的时候主动的将被调用者(或者说它的依赖对象)注
入给调用对象。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码
来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要
一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在
系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注
射到A当中,这样就完成了对各个对象之间关系的控制。
IoC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功
能分离出来形成可重用的功能组件
250 BeanFactory和ApplicationContext有什么区别
BeanFactory和ApplicationContext是Spring的两大核心接口,而其中
ApplicationContext是BeanFactory的子接口。它们都可以当做Spring的
容器,生成Bean实例的,并管理容器中的Bean。
(1)BeanFactory:是Spring里面最底层的接口,提供了最简单的容器的功
能,负责读取bean配置文档,管理bean的加载与实例化,维护bean之间的依
赖关系,负责bean的生命周期,但是无法支持spring的aop功能和web应用。
(2)ApplicationContext接口作为BeanFactory的派生,因而具有BeanFactory
所有的功能。而且ApplicationContext还在功能上做了扩展,以一种更面向框架的
方式工作以及对上下文进行分层和实现继承,相较于BeanFactorty,
ApplicationContext还提供了以下的功能: ①默认初始化所有的Singleton,
也可以通过配置取消预初始化。
②继承MessageSource,因此支持国际化。
③资源访问,比如访问URL和文件。
④事件机制。
⑤同时加载多个配置文件。
⑥以声明式方式启动并创建Spring容器。
⑦载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层
次,比如应用的web层。
(3)①BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到
某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就
不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,
BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。
②而ApplicationContext则相反,它是在容器启动时,一次性创建了所有
的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,
这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入
所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用
等待,因为它们已经创建好了。
③相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存
空间。当应用程序配置Bean较多时,程序启动较慢。
(4)BeanFactory通常以编程的方式被创建,ApplicationContext还能以声
明的方式创建,如使用ContextLoader。
(5)BeanFactory和ApplicationContext都支持BeanPostProcessor、
BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory
需要手动注册,而ApplicationContext则是自动注册
251 解释Spring支持的几种bean的作用域。
Spring容器中的bean可以分为5个范围:
(1)singleton:这种bean范围是默认的,这种范围确保不管接受到多少个
请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护。
(2)prototype:原形范围与单例范围相反,为每一个bean请求提供一个实例。
(3)request:在请求bean范围内会每一个来自客户端的网络请求创建一个实例,
在请求完成以后,bean会失效并被垃圾回收器回收。
(4)Session:与请求范围类似,确保每个session中有一个bean的实例,
在session过期后,bean会随之失效。(5)global-session:global-session
和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。
如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储
在global-session中。全局作用域与Servlet中的session作用域效果相同
252 请解释Spring Bean的生命周期
首先说一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy;
Spring上下文中的Bean生命周期也类似,如下:
(1)实例化一个Bean--也就是我们常说的new;
(2)按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;
(3)如果这个Bean已经实现了BeanNameAware接口,会调用它实现的
setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值;
(4)如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的
setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自
身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);
(5)如果这个Bean已经实现了ApplicationContextAware接口,会调用
setApplicationContext(ApplicationContext)方法,传入Spring上下
文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext
是BeanFactory的子接口,有更多的实现方法);
(6)如果这个Bean关联了BeanPostProcessor接口,将会调用
postProcessBeforeInitialization(Object obj, String s)方法,
BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean
初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;
(7)如果Bean在Spring配置文件中配置了init-method属性会自动调用其配
置的初始化方法。
(8)如果这个Bean关联了BeanPostProcessor接口,将会调用
postProcessAfterInitialization(Object obj, String s)方法、;
253 Spring中bean的加载过程
(1)获取配置文件资源;
(2)对获取的xml资源进行一定的处理检验;
(3)处理包装资源;
(4)解析处理包装过后的资源;
(5)加载提取bean并注册(添加到beanDefinitionMap中)
254 Spring框架中的单例Beans是线程安全的么
Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安
全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变
的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安
全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线
程安全。最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”
255 Spring如何处理线程并发问题
Spring使用ThreadLocal解决线程安全问题。
我们知道在一般情况下,只有有状态的Bean才可以在多线程环境下共享,在Spring中,绝
大部分Bean都可以声明为singleton作用域。就是因为Spring对一些
Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)
中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,
因为有状态的Bean就可以在多线程中共享了。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
(1)在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。
这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变
量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,
程序设计和编写难度相对较大。
(2)而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为
每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为
每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal
提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
(3)概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,
而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,
而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响
256 请解释Spring自动装配模式的区别
在Spring框架中共有5种自动装配:
(1)no:这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行
在bean定义中用标签明确的设置依赖关系。
(2)byName:该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个
属性时,容器将根据bean的名称自动在配置文件中查询一个匹配的bean。如果找到的话,
就装配这个属性,如果没找到的话就报错。
(3)byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性
时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装
配这个属性,如果没找到的话就报错。
(4)constructor:构造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同
参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
(5)autodetect:该模式自动探测使用构造器自动装配或者byType自动装配。首先,首先
会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没
有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式
257 Spring 控制器的加载过程
(1)Web容器创建;
(2)上下文创建,但未初始化;
(3)监听器创建,并注册到Context上;
(4)上下文初始化;
(5)通知到监听者,Spring配置文件/@Configuration加载;
(6)Load-on-startup>0的ServletConfig创建,springMVC的DispatcherServlet此时创建
258 Spring 框架中都用到了哪些设计模式
(1)代理模式—在AOP和remoting中被用的比较多。(2)单例模式—在spring配置文件中
定义的bean默认为单例模式。(3)工厂模式—BeanFactory用来创建对象的实例。(4)模
板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
(5)前端控制器—Spring提供了DispatcherServlet来对请求进行分发。(6)视图帮
助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在
视图里。(7)依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念
259 Spring事务的种类和各自的区别
spring支持编程式事务管理和声明式事务管理两种方式:
(1)编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。
对于编程式事务管理,spring推荐使用TransactionTemplate。
(2)声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建
或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点
就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需
在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规
则应用到业务逻辑中。
(3)显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声
明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事
务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别
,无法做到像编程式事务那样可以作用到代码块级别
260 Spring事务的实现方式和实现原理
(1)划分处理单元——IOC:
由于spring解决的问题是对单个数据库进行局部事务处理的,具体的实现首相用spring中的
IOC划分了事务处理单元。并且将对事务的各种配置放到了ioc容器中(设置事务管理器,设
置事务的传播特性及隔离机制)。
(2)AOP拦截需要进行事务处理的类:
Spring事务处理模块是通过AOP功能来实现声明式事务处理的,具体操作(比如事务实行的
配置和读取,事务对象的抽象),用TransactionProxyFactoryBean接口来使用AOP功能,
生成proxy代理对象,通过TransactionInterceptor完成对代理方法的拦截,将事务处理的
功能编织到拦截的方法中。
读取ioc容器事务配置属性,转化为spring事务处理需要的内部数据结构
(TransactionAttributeSourceAdvisor),转化为TransactionAttribute表示的数据对象。
(3)对事物处理实现(事务的生成、提交、回滚、挂起):
spring委托给具体的事务处理器实现。实现了一个抽象和适配。适配的具
体事务处理器:DataSource数据源支持、hibernate数据源事务处理支持、
JDO数据源事务处理支持,JPA、JTA数据源事务处理支持。这些支持都是通过设
计PlatformTransactionManager、AbstractPlatforTransaction一系列事
务处理的支持。为常用数据源支持提供了一系列的TransactionManager。
(4)结合:
PlatformTransactionManager实现了TransactionInterception接口,让
其与TransactionProxyFactoryBean结合起来,形成一个Spring声明式事务
处理的设计体系
261 解释一下Spring AOP里面的几个名词
(1)切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。事
务管理是J2EE应用中一个关于横切关注点的很好的例子。 在Spring AOP中,切面可
以使用通用类(基于模式的风格) 或者在普通类中以 @Aspect 注解(@AspectJ风格)
来实现。
(2)连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调用的
时候或者处理异常的时候。 在Spring AOP中,一个连接点 总是 代表一个方法的
执行。 通过声明一个org.aspectj.lang.JoinPoint类型的参数可以使通知(Advice)
的主体部分获得连接点信息。
(3)通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作。通
知有各种类型,其中包括“around”、“before”和“after”等通知。 通知的类型将在后
面部分进行讨论。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个
以连接点为中心的拦截器链。
(4)切入点(Pointcut):匹配连接点(Joinpoint)的断言。通知和一个切入点表达
式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。
切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。
(5)引入(Introduction):(也被称为内部类型声明(inter-type declaration))。
声明额外的方法或者某个类型的字段。 Spring允许引入新的接口(以及一个对应的实现)
到任何被代理的对象。例如,你可以使用一个引入来使bean实现 IsModified 接口,以便
简化缓存机制。
(6)目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)
的对象。也有人把它叫做 被通知(advised) 对象。 既然Spring AOP是通过运行时代理
实现的,这个对象永远是一个 被代理(proxied) 对象
(7)织入(Weaving):把切面(aspect)连接到其它的应用程序类型或者对象上,并创
建一个被通知(advised)的对象。 这些可以在编译时(例如使用AspectJ编译器),类加
载时和运行时完成。 Spring和其他纯Java AOP框架一样,在运行时完成织入。
切入点(pointcut)和连接点(join point)匹配的概念是AOP的关键,这使得AOP不同于
其它仅仅提供拦截功能的旧技术。 切入点使得定位通知(advice)可独立于OO层次。
例如,一个提供声明式事务管理的around通知可以被应用到一组横跨多个对象中的方法上
————————————————
版权声明:本文为CSDN博主「xuzhiyonggithubpers」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_47572402/article/details/107096645
猜你喜欢
- 2024-11-11 详解如何防止SQL注入:应对方案与优缺点分析
- 2024-11-11 XSS注入我也不怕不怕啦--PHP从框架层面屏蔽XSS的思考和实践
- 2024-11-11 挖0day漏洞原来如此简单,我的黑客朋友手把手教你
- 2024-11-11 php用soap调用接口实例,返回值没有见到xml
- 2024-11-11 备战金九银十,2020最新大厂PHP面试题(附答案)
- 2024-11-11 dede后台发布文章的时候显示标题不能为空?
- 2024-11-11 PHP漏洞之-Session劫持 php session机制
- 2024-11-11 php特殊字符处理 php 特殊字符自动转义
- 2024-11-11 2020最新大厂PHP面试题(附答案) php面试官应该问些什么
- 2024-11-11 反射型 XSS 攻击实战 xss反射性攻击
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)