问题1:JPBM的常用接口有哪些?
ProcessEngine工作流的流程引擎对象
1、RepositoryService 流程资源服务的接口。
作用: 提供对流程定义的部署、查询、删除等操作。
2、ExecutionService 流程执行服务的接口。
作用: 提供启动流程实例、“执行”推进,设置流程实例变量等操作。
3、ManagementService 流程管理控制服务接口。
作用: 提供异步工作相关的执行和查询操作。
4、TaskService 人工任务服务接口。
作用: 提供对任务(Task)的创建、提交、查询、保存、删除等操作。
5、HistoryService 流程历史服务的接口。
作用: 提供对任务的管理操作,提供对流程历史库中历史流程实例、历史活动实例等记录的查询操作。还提供诸如某个流程定义中所有活动的平均持续时间、某个流程定义中某转移的结果次数等数据分析服务。
6、IdentityService 身份认证服务的接口。
作用: 提供对流程用户、用户组以及组成员关系的相关服务。
问题2:Hibernate的核心接口有哪些?
Hibernate的核心接口一共有5个,分别为:Session、SessionFactory、Transaction、Query和Configuration。
这5个核心接口在任何开发中都会用到。通过这些接口,不仅可以对持久化对象进行存取,还能够进行事务控制。
问题3:Hibernate的缓存有哪些?
Session是一级缓存,SessionFactry是二级缓存。
SessionFactory是Hibernate的概念,对应一个数据存储源(如MySql,SQLServer,Oracle)
看你项目中用的哪个数据库,可以有多个,在XML文件中配置,由Configuration创建
SessionFactory可以创建Session,Session用来控制事务以及增删改查操作
SessionFactory是线程安全的,多线程可以同时访问它,创建一次就行
Session是线程不安全的,代表对数据库一次操作。一般每一次对数据库的操作都要创建一个Session,用之后关闭
1、内部缓存存在Hibernate中又叫一级缓存,属于应用事务级缓存
2、二级缓存:
a) 应用级缓存
b) 分布式缓存,比如使用Memcached可作为Hibernate二级分布式缓存
条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非关键数据
c) 第三方缓存的实现
问题4:Hibernate中get和load有什么区别?
不存在对应记录时表现不一样
load返回的是代理对象(javassist.jar生成二进制码),等到真正用到对象的内容才会发出SQL语句
get直接从数据库加载,不会延迟
get不支持懒加载 ,load支持
get查询数据库不存在的记录时返回null ,load就报异常了
问题5:什么是Session?
Session 是客户端与服务器之间的会话,用来保存用户的信息。
在编程里是会话的意思
Session 对象存储特定用户会话所需的信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去
当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话
问题6:Session和Cookie区别?
Session是服务器端缓存,Cookie是客户端缓存。
Cookie机制采用的是在客户端保持状态的方案,而Session机制采用的是在服务器端保持状态的方案
2013年8月7日:天懋数码、图创科技
问题1:书籍表,借书表,查询借书表每一本书的最新借书时间
书籍表 Book 表结构:主键ID、书名Name
借书表 Lend 表结构:主键ID、外键BookID、借书时间Time
要求精确到秒
/* 查询lend表,通过bookId分组,查出每组中时间最大的,时间最大的代表最新的*/
SELECT max(l.time)
FROM lend as l
GROUP BY l.bookId;
/* 查询book表和lend表 */
SELECT b.name as "书名", l.time as "最新借出时间"
FROM book as b , lend as l
WHERE l.bookId = b.id
AND
l.time IN
(
SELECT max(l.time)
FROM lend as l
GROUP BY l.bookId
);
问题2:WebService相关
概念:
Web Service 是一项新技术,能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件,就可相互交换数据或集成。依据Web Service 规范实施的应用之间,无论它们所使用的语言、平台或内部协议是什么,都可以相互交换数据。
通俗的讲,Web Service 就是一个部署在Web 服务器上的一个应用程序,它向外界暴露出一个能够通过Web 进行调用的API。
这就是说,你能够用编程的方法通过Web 来调用这个应用程序。我们把调用这个Web Service 的应用程序叫做客户端,发布这个web 服务的机器称为Web Service 服务器。
优势:
异构平台的互通性
更广泛的软件复用
成本低、可读性强、应用范围广
迅捷的软件发行方式
WSDL:WebService服务描述语言
获取WEB的发布信息是通过wsimport来解析wsdl文件得到Java类来实现的。无论是获取发布的服务,还是调用发布的服务,都需要参考wsdl文件
CXF框架概念介绍
Apache CXF 是一个开源的Services框架,CXF 帮助您来构建和开发 Services。
这些 Services 可以支持多种协议,比如:SOAP1.1/1.2、POST/HTTP、RESTful、HTTP,CXF大大简化了Service,可以天然地和 Spring 进行无缝集成。
问题3:Lucene相关
对索引库的操作可以分为两种:管理与查询
管理索引库使用IndexWriter,从索引库中查询使用IndexSearcher。
Lucene的数据结构为Document文档与Field字段
Document代表一条数据,Field代表数据中的一个属性。
一个Document中有多个Field,Field的值为String型,因为Lucene只处理文本
我们只需要把在我们的程序中的对象转成Document,就可以交给Lucene管理了,搜索的结果中的数据列表也是Document的集合
中文分词器之一:IKAnalyzer
格式器对象Formatter
索引库数据查看器(lukeall-1.0.0.jar)
IndexSearcher:是用来在建立好的索引上进行搜索
QueryParser:QueryParser 是查询操作的解析类, 要告诉QueryParser对哪个字段进行查询, 用什么样的分词器,进行分词,最后返回的是一个Query对象, 交给IndexSearcher做查询操作
Term:是搜索的基本单元, Term对象有两个String类型的域组成:字段的名称和字段的值, 被分词建立索引的Field就是Term
TopDocs:
int totalHits Expert: The total number of hits for the query.
ScoreDoc[] scoreDocs Expert: The top hits for the query
创建索引API分析
Directory: 类代表一个Lucene索引的位置,FSDirectory:它表示一个存储在文件系统中的索引的位置
Analyzer类是一个抽象类, 它有多个实现,在一个文档被入索引库之前,首先需要对文档内容进行分词处理,针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引
IndexWriter:是创建索引和维护索引的中心组件, 这个类创建一个新的索引并且添加文档到一个已有的索引中。IndexWriter只负责索引库的更新(删、更新、插入),不负责查询
Document:由多个字段(Field)组成,一个Field代表与这个文档相关的元数据。如作者、标题、主题等等,分别做为文档的字段索引和存储。add(Fieldable field)添加一个字段(Field)到Document
Jar包至少有:
lucene-core-3.0.1.jar(核心包)
contrib\analyzers\common\lucene-analyzers-3.0.1.jar(分词器)
contrib\highlighter\lucene-highlighter-3.0.1.jar(高亮)
contrib\memory\lucene-memory-3.0.1.jar(高亮)
全文检索与数据查询的区别
相关度排序: 查出的结果没有相关度排序,不知道我想要的结果在哪一页。我们在使用百度搜索时,一般不需要翻页,为什么?因为百度做了相关度排序:为每一条结果打一个分数,这条结果越符合搜索条件,得分就越高,叫做相关度得分,结果列表会按照这个分数由高到低排列,所以第1页的结果就是我们最想要的结果
查询的方式: 全文检索的速度大大快于SQL的like搜索的速度。这是因为查询方式不同造成的,以查字典举例:数据库的like就是一页一页的翻,一行一行的找,而全文检索是先查目录,得到结果所在的页码,再直接翻到这一页
定位不一样:一个更侧重高效、安全的存储、一个是侧重准确、方便的搜索
问题4:要求在不允许引入第三个变量的情况下交换 var a=1; var b=2;
方法一:
a=a+b; b=a-b; a=a-b;
输出a,b可以发现两值已经交换
方法二:
a=a^b; b=a^b; a=a^b;
问题5:使用正则表达式验证邮箱
正则表达式(regular expression, 常常缩写为RegExp) 是一种用特殊符号编写的模式,描述一个或多个文本字符串。使用正则表达式匹配文本的模式,这样脚本就可以轻松的识别和操作文本。
其实,正则表达式是值得大家花时间学习的。正则表达式不仅在JavaScript 中有用,在其他许多地方也可以使用正则表达式,例如其他编程语言(比如Perl,Java,C#,Python 和PHP ),Apache 配置文件以及BBEdit 和TextMate 等文本编辑器。甚至Adobe Dreamweaver 和Microsoft Word( 在一定程度上) 使用正则表达式也可以实现更强大的搜索和替换。
下面是一个验证电子邮件的正则表达式 :
var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ ;
下面我们开始剖析这个正则表达式:
re 是一个变量, 用来存储右边的正则表达式,在JavaScript中,声明变量使用Var 关键字。
正则表达式的阅读顺序是从左向右的
正则表达式总是以( / ) 开头和结尾,斜杠之间的所有内容都是正则表达式的组成部分
脱字符( ^ ) 表示我们要使用这个表达式来检查以特定字符串开头的字符串。如果去掉脱字符,那么即使字符串开头有一堆垃圾字符,电子邮件地址也可能被认为是有效的。
表达式\w 表示任意单一字符,包括a~z 、A~Z 、0~9 或下划线。电子邮件必须这些字符之一开头
加号+ 表示我们要寻找前面条目的一次或多次出现
圆括号( ) 表示一个组,这意味着后面要引用圆括号中的所有内容,所以现在将它们放在一个组中
方括号[ ] 用来表示可以出现其中的任意一个字符。在这个示例中,方括号内包含字符\.- 。我们希望允许用户输入点号或连字符,但是点号对于正则表达式有特殊的意义,所以需要在它前面加上反斜杠\, 在特殊字符前加反斜杠表示“对字符转义”,经转义后的字符表示其本身意义。因为有方括号,输入字符串在这个位置可以有一个点号或一个连字符,但是两种不能同时存在
问号?表示前面的条目可以出现一次或不出现。所以电子邮件地址的第一部分中可以有一个点号或一个连字符,也可以没有
在?后面,再次使用\w+ ,表示点号或连字符后面必须有其他字符
在()后面出现的* 号,表示前面的条目可以出现零次或多次。所以圆括号中的内容可以出现零次或多次
@ 字符代表其本身,没有任何其他意义,这个字符位于电子邮件地址和域名之间
@ 字符后再次出现\w+ ,表示@ 后必须出现字符。在此之后,再次出现([\.-]?\w+)*, 表示电子邮件地址的后缀中允许出现点号或连字符
然后,在一对圆括号中建立另一个组(\.\w{2,3}), 表示我们希望找到一个点号,后面跟一些字符。在这个示例中,花括号中的数字表示前面的条目可以出现2 到3 次。在这个组的后面是一个+ 号,表示前面的条目(这个组)必须出现一次或多次。这会匹配.com 或.edu 之类的,也与ox.ac.uk 匹配
最后,正则表达式的末尾是一个美元符号$ ,表示匹配的字符串必须在这里结束。斜杠结束正则表达式
问题6:不使用正则表达式验证邮箱
< script type="text/javascript">
document.getElementById('email').onblur = function() {
var value = this.value;
if (typeof value == 'undefined') { //未定义
alert('Email不能为空');
return false;
} else if (value.trim() == '') { //空值
alert('Email不能为空');
return false;
} else if (value.indexOf('@') == -1) { //不包含@
alert('Email必须包含@,如
[email protected] ');
return false;
} else if (value.indexOf('.') == -1) { //不包含.
alert('Email必须包含.,如
[email protected] ');
return false;
} else { //包含@与.
//以@或.开头@qq.com 和
[email protected] 非法
if (value.indexOf('@') == 0 || value.indexOf('.') == 0) {
alert('Email只能以字母开头');
return false;
} else if (value.lastIndexOf('@') == value.length - 1
|| value.lastIndexOf('.') == value.length - 1) {
//以@或.结束
[email protected] @ 和
[email protected] .非法
alert('Email只能以字母结束');
return false;
} else { //包含@与.且不以它们结束
var count_at = 0;
//多个@ a@
[email protected] 非法
if (value.indexOf('@') != value.lastIndexOf('@')) {
alert('Email只能包含一个@,如
[email protected] ');
return false;
}
var beforeAt = value.substr(0, value.indexOf('@'));
if (beforeAt.indexOf('.') != -1) { //
[email protected] 非法
alert('Email的@前必须全部为字母');
return false;
}
//删除@,.替换@,反正替换后按.分隔时a@.拼接,导致@.之间无法判定为空
value = value.replace('@', '.');
var splits = value.split('.'); //按.分隔
var a_z = 'abcdefghijklmnopqrstuvwxyz'; //仅字母
for ( var i in splits) {
//对点分隔后的字符进行单字切割并匹配a-z
if (splits[i] == '') {
alert('Email的@.或..不能连接');
return false;
}
var words = splits[i].split(""); //单字切割
for ( var w in words) { //对每个单字进行验证
if (a_z.indexOf(words[w].toLowerCase()) == -1) {
alert('Email只能包含字母!');
return false;
}}}}}
return true; }
< /script>
2013年8月8日:图创科技、进易通信技术
问题1:使用A、B、C三个线程,有序的输出ABCABCABC循环十次
class A implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
try {
synchronized (a) {
synchronized (b) {
System.out.print("A");
b.notify();
}
if (i < 9) {
a.wait();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class B implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
try {
synchronized (b) {
synchronized (c) {
System.out.print("B");
c.notify();
}
if (i < 9) {
b.wait();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class C implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
try {
synchronized (c) {
synchronized (a) {
System.out.print("C");
a.notify();
}
if (i < 9) {
c.wait();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static Object a = new Object();
public static Object b = new Object();
public static Object c = new Object();
public static void main(String[] args) throws Exception {
TestThread t = new TestThread();
Thread a = new Thread(t.new A());
Thread b = new Thread(t.new B());
Thread c = new Thread(t.new C());
a.start();
Thread.sleep(1);
b.start();
Thread.sleep(1);
c.start();
}
问题2:读取文本信息,读取指定信息,比如“姓名:陈小影”里的陈小影,以及统计数据
用缓冲流的readline(),一次读一行,然后截取冒号后面的,再加上字符串截取就行了subString(),最后再拼起来。
代码:
InputStreamReader read = new InputStreamReader(new FileInputStream(file), "UTF-8");
BufferedReader reader = new BufferedReader(read);
代码:
public static void main(String[] args) throws IOException
{
FileReader is = new FileReader("D:/input.txt.txt");
BufferedReader br = new BufferedReader(is);
StringBuffer buffer = new StringBuffer();
String test = "";
while((test = br.readLine()) != null){
int num = numString(test,"java");
PrintWriter os = new PrintWriter ("D:/result.txt.txt");
buffer.append("input.txt文件中,包含");
buffer.append(num);
buffer.append("个java字符串");
os.write(buffer.toString());
os.close();
}
}
public static int numString(String s , String str) {
int i = 0 ; //指定的开始搜索的索引
int index = 0 ; //查找到的第一个索引
int num = 0 ; //字符串出现的次数
while(index != -1) {
//indexOf(String str, int fromIndex)
//返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
index = s.indexOf(str,i) ;
if(index != -1)
num ++ ;
i = index + str.length() ;
}
return num ;
}
}
问题3:JSP的九大内置对象和四个作用域
九大内置对象:
request 请求对象 用户端请求,此请求会包含来自GET/POST请求的参数 作用域 Request
response 响应对象 网页传回用户端的回应 作用域 Page
pageContext 页面上下文对象 网页的属性在这里管理 作用域 Page
session 会话对象 与请求有关的会话期 作用域 Session
application 应用程序对象 servlet正在执行的内容 作用域 Application
out 输出对象 用来传送回应的输出 作用域 Page
config 配置对象 servlet的构架部件 作用域 Page
page 页面对象 JSP网页本身 作用域 Page
exception 例外对象 针对错误网页,未捕捉的例外 作用域 page
四个作用域:page、request、session、application
Page 范围是当前页面
Request 范围是当前请求周期(从请求发起到服务器处理结束,返回响应的整个过程)
Session 范围是当前会话(用户打开浏览器开始,到用户关闭浏览器并且会话失效的整个过程)
Application 范围是整个应用,从应用启动到应用结束
问题4:FileWriter和PrintWriter有什么区别?
在写文件时我认为:
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(filename)));
比较好点
PrintWriter 提供print系方法
BufferedWriter 提供缓冲,用以加速
FileWriter 用于写文件
FileWriter类/FileReader类:
用于对字符文件的读写的便捷的结点流类
使用时最好用BufferedReader/BufferedWriter对其进行包装。
PrintStream类(如System.out):
格式化打印输出字节数据的流,该类提供的print[ln]()方法可格式化打印输出各种类型的数据(包括类对象)
它使用平台的默认字符编码将所有字符都转换为字节打印输出(写入)
在需要写入字符而不是写入字节的情况下,应该使用PrintWriter类
问题5:简述JSP和Servlet的关系?
JSP---Java Server Pages
拥有Servlet的特性与优点(本身就是一个Servlet)
直接在HTML中内嵌JSP代码
只有当客户端第一次请求JSP时,才需要将其转换、编译Servlet代码
优点:
优良的性能 优于CGI,PHP,ASP
平台无关性 操作系统无关,Web服务器无关
可扩展性 标签库Tag的扩展机制,简化页面开发——Taglib uri
Servlet是在Web服务器上的Java程序,它提供服务,由它来传递给你html的格式
Servlet是服务器小小的Java应用程序
用来完成B/S架构下,客户端请求的响应处理
平台独立,性能优良,能以线程方式运行
Servlet API为Servlet提供了统一的编程接口
Servlet一般在容器中运行(必须部署在Servlet容器,才能响应客户端的请求,对外提供服务,要对外统一接口,由容器来调用)
JSP在被第1次访问的时候 会被转义编译成类Servlet也可以说JSP就是一个Servlet
2者的区别:JSP是Html中内嵌Java代码;Servlet把Html代码和Java代码分离开
JSP侧重与显示;Servlet侧重与控制逻辑
问题6:简述JAVA设计模式的概念?
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。
问题7:常用的数据库优化方法有哪些?
建立索引
导出历史数据
定期整理索引(sp_msforeachtable 'dbcc dbreindex("?")' )
少用like,查询前检查条件是不是完整,如果完整就用 = 替代like查询,不要不检查条件完整不完整全部用like来
问题8:什么是动态游标?什么是静态游标?
静态游标是以游标打开时刻的当时状态显示结果集的游标。静态游标在游标打开时不反映对基础数据进行的更新、删除或插入。有时称它们为快照游标。
动态游标是可以在游标打开时反映对基础数据进行的修改的游标。用户所做的更新、删除和插入在动态游标中加以反映。
问题9:为什么要用Struts2框架?
它是建立在MVC这种公认的好的模式上的,Struts在M、V和C上都有涉及,但它主要是提供一个好的控制器和一套定制的标签库上,也就是说它的着力点在C和V上。因此,它天生就有MVC所带来的一系列优点,如:结构层次分明,高可重用性,增加了程序的健壮性和可伸缩性,便于开发与设计分工,提供集中统一的权限控制、校验、国际化、日志等等
其次,它是个开源项目得到了包括它的发明者Craig R.McClanahan在内的一些程序大师和高手持续而细心的呵护,并且经受了实战的检验,使其功能越来越强大,体系也日臻完善
是它对其他技术和框架显示出很好的融合性
问题10:Struts2的工作原理?
Struts2框架由3个部分组成:
核心控制器FilterDispatcher、业务控制器和用户实现的业务逻辑组件。
在这3个部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用户需要实现业务控制器和业务逻辑组件。
1、核心控制器:FilterDispatcher
FilterDispatcher是Struts2框架的核心控制器,该控制器作为一个Filter运行在Web应用中,它负责拦截所有的用户请求,当用户请求到达时,该Filter会过滤用户请求。如果用户请求以action结尾,该请求将被转入Struts2框架处理。
Struts2框架获得了*.action请求后,将根据*.action请求的前面部分决定调用哪个业务逻辑组件。例如,对于login.action请求,Struts2调用名为login的Action来处理该请求。
Struts2应用中的Action都被定义在struts.xml文件中,在该文件中定义Action时,定义了该Action的name属性和class属性,其中name属性决定了该Action处理哪个用户请求,而class属性决定了该Action的实现类。
Struts2用于处理用户请求的Action实例,并不是用户实现的业务控制器,而是Action代理。因为用户实现的业务控制器并没有与Servlet API耦合,显然无法处理用户请求。而Struts2框架提供了系列拦截器,该系列拦截器负责将HttpServletRequest请求中的请求参数解析出来,传入到Action中,并回调Action 的execute方法来处理用户请求。
2、一个请求在Struts2框架中的处理大概分为以下几个步骤:
客户端初始化一个指向Servlet容器(例如Tomcat)的请求 ,即HttpServletRequest请求
这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
ActionProxy创建一个ActionInvocation的实例
ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用
一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
在上述过程中所有的对象(Action,Results,Interceptors,等)都是通过ObjectFactory来创建的。
问题11:Hibernate的工作原理?
读取并解析hibernate.cfg.xml配置文件
读取并解析映射信息,创建SessionFactory
打开Sesssion
创建事务Transaction
持久化操作
提交事务
关闭Session
关闭SesstionFactory
问题12:为什么要用Hibernate?
对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作
Hibernate使用Java反射机制,而不是字节码增强程序来实现透明性
Hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系
问题13:Hibernate如何实现延迟加载?
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。
问题14:Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many
问题15:Spring的工作原理?
IoC(Inversion of control): 控制反转
概念:控制权由对象本身转向容器,由容器根据配置文件去创建实例并创建各个实例之间的依赖关系
核心:bean工厂,在Spring中,bean工厂创建的各个实例称作bean
AOP(Aspect-Oriented Programming): 面向切面编程
1、代理的两种方式:
静态代理:
针对每个具体类分别编写代理类
针对一个接口编写一个代理类
动态代理:
针对一个切面编写一个InvocationHandler,然后借用JDK反射包中的Proxy类为各种接口动态生成相应的代理类
2、AOP的主要原理:动态代理
Spring的工作原理
Spring 已经用过一段时间了,感觉Spring是个很不错的框架。内部最核心的就是IOC了, 动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用Java里的反射
反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟XMLSpring的配置文件来动态的创建对象,以及调用对象里的方法
Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能,这些都是通过配置类达到的
Spring的目的:
就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置内部通过反射去动态的组装对象),要记住:Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能
Spring里用的最经典的一个设计模式就是:模板方法模式。(这里我都不介绍了,是一个很常用的设计模式)Spring里的配置是很多的,很难都记住,但是Spring里的精华也无非就是以上的两点,把以上两点跟理解了也就基本上掌握Spring。
问题16:SpringMVC的工作原理?
Spring的MVC框架主要由DispatcherServlet、处理器映射、处理器、视图解析器、视图组成
整个处理过程从一个HTTP请求开始:
DispatcherServlet接收到请求后,根据对应配置文件中配置的处理器映射,找到对应的处理器映射项(HandlerMapping),根据配置的映射规则,找到对应的处理器(Handler)
调用相应处理器中的处理方法,处理该请求,处理器处理结束后会将一个ModelAndView类型的数据传给DispatcherServlet,这其中包含了处理结果的视图和视图中要使用的数据
DispatcherServlet根据得到的ModelAndView中的视图对象,找到一个合适的ViewResolver(视图解析器),根据视图解析器的配置,DispatcherServlet将视图要显示的数据传给对应的视图,最后给浏览器构造一个HTTP响应
DispatcherServlet是整个Spring MVC的核心,它负责接收HTTP请求组织协调Spring MVC的各个组成部分
其主要工作有以下三项:
截获符合特定格式的URL请求
初始化DispatcherServlet上下文对应的WebApplicationContext,并将其与业务层、持久化层的WebApplicationContext建立关联
初始化Spring MVC的各个组成组件,并装配到DispatcherServlet中
问题17:SendRedirect 和Foward区别
1、请求次数不同,这是最本质的区别
在Foward方式下,在执行当前JSP对象或者Servlet对象的过程中去调用目标文件对应的对象,相当于方法调用,把request和response对象作为参数传递到目标文件对应的对象,当前文件和目标文件的执行是在用户发送的一次请求中完成的。
在redirect方式下,用于首先请求了当前文件,当前文件把目标文件的地址返回给了客户端,客户端再次发送请求,请求目标文件,实际上是发送了两次请求。
2、传值方式不同
在Foward方式下,当前文件和目标文件属于同一次请求,共享request对象,所以可以使用request对象传值。
在redirect方式下,当前文件和目标文件属于不同的请求,每次请求会单独创建request和response对象,这样就不能使用request对象来传值。
在MVC模式下,通常在控制器中调用模型得到数据,然后保存到request中,然后Foward到目标文件,目标文件从request中获取需要的信息。如果使用sendRedirect方式在控制器和视图之间传递信息,需要使用在目标文件之后加上“?名字=值”的方式传递。
3、客户端在地址栏中看到的地址不一样
对于Foward,在地址栏中看到的是第1个文件的名字。
对于sendRedirect,在地址栏中看到的是第2个文件的地址。
有时候会影响目标文件中的相对路径,例如当前文件是aa文件夹中的a.jsp,目标文件是bb文件夹中的b.jsp,在b.jsp中要访问一个图片,使用相对路径,直接写face.jpg,这个文件与b.jsp放在一起。如果采用forward方式,地址栏中是a.jsp,这样系统会在aa文件夹中找face.jpg,这时候就会出错。
问题18:addBatch批量处理数据库数据时用execute对吗?
错,要使用executeBatch执行批量SQL语句
问题19:简述JavaWeb中Model2及软件分层架构的好处
Model2(JSP+Servlet+JavaBean)具有组件化的优点从而更易于实现对大规模系统的开发和管理,职责划分清晰。
优点:
分层式结构究竟其优势何在?Martin Fowler在《Patterns of Enterprise Application Architecture》一书中给出了答案:
1、开发人员可以只关注整个结构中的其中某一层
2、可以很容易的用新的实现来替换原有层次的实现
3、可以降低层与层之间的依赖
4、有利于标准化
5、利于各层逻辑的复用
概括来说,分层式设计可以达至如下目的:分散关注、松散耦合、逻辑复用、标准定义
缺点:
“金无足赤,人无完人”,分层式结构也不可避免具有一些缺陷
1、降低了系统的性能,这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成
2、有时会导致级联的修改,这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
关于第一个缺点,完全可以通过系统的缓存机制来减小对性能的影响。第二个缺点,我想只能通过采用一些设计模式来得到改善吧。
问题20:说说Session分话的原理,Session与Cookie的关系及区别
服务器上通过Session来分别不同的用户Session ID
任何连接到服务器上的用户,服务器都会位之分配唯一的一个不会重复的Session ID
Session ID是由服务器统一管理的,人为不能控制
Session在服务器上2个基本操作:
Session.setAttribute(String key,Object obj)以键值对的方式存储数据
Session.getAttribute(String key)根据键获取数据
Session是服务器端缓存,Cookie是客户端缓存
Cookie机制采用的是在客户端保持状态的方案,而Session机制采用的是在服务器端保持状态的方案
问题21:Cookie中的值能否包含各种特殊字符及中文字符?如果不能,那应该如何处理?
当Cookie中包含有等号、空格、分号等特殊字符时,可能会导致数据丢失、或者不能解析的错误,一个较好的解决办法就是:在将Cookie值写入客户端浏览器之前,首先进行URLEncode编码,读取Cookie时,进行URLDecode即可。
问题22:JDBC和Hibernate的比较?
JDBC与Hibernate在性能上相比,JDBC灵活性有优势。而Hibernate在易学性,易用性上有些优势。当用到很多复杂的多表联查和复杂的数据库操作时,JDBC有优势。
相同点:
两者都是JAVA的数据库操作中间件
两者对于数据库进行直接操作的对象都不是线程安全的,都需要及时关闭
两者都可以对数据库的更新操作进行显式的事务处理
不同点:
使用的SQL语言不同:JDBC使用的是基于关系型数据库的标准SQL语言,Hibernate使用的是HQL(Hibernate query language)语言
操作的对象不同:JDBC操作的是数据,将数据通过SQL语句直接传送到数据库中执行,Hibernate操作的是持久化对象,由底层持久化对象的数据更新到数据库中。
数据状态不同:JDBC操作的数据是“瞬时”的,变量的值无法与数据库中的值保持一致,而Hibernate操作的数据是可持久的,即持久化对象的数据属性的值是可以跟数据库中的值保持一致的。
Hibernate与JDBC哪个好?各自的优点和缺点:
1、内存消耗:采用JDBC的无疑是最省内存的,Hibernate的次之
2、运行效率:如果JDBC的代码写的非常优化,那么JDBC架构运行效率最高,但是实际项目中,这一点几乎做不到,这需要程序员非常精通JDBC,运用Batch语句,调整PreapredStatement的Batch Size和Fetch Size等参数,以及在必要的情况下采用结果集cache等等。而一般情况下程序员是做不到这一点的。因此Hibernate架构表现出最快的运行效率
3、开发效率:在大的项目,特别是持久层关系映射很复杂的情况下,Hibernate效率高的惊人,JDBC次之
延迟加载是罪魁祸首,所谓“成也萧何,败也萧何”
有时发现查询速度很慢,检查才发现是我没有启用延迟加载,造成递归的数据都被加载进来了
如果加上了延迟加载,那么许多页面将无法使用,必须在程序里进行代码级别的递归的延迟加载数据的读取
1 用HQL来写查询语句,这是最高效的办法(推荐)
2 用JDBC,脱离了Hibernate范畴,缓存方面和乐观所方面会出现不一致,而且语句变得繁琐了(不推荐)
3 将前台要用到的实体,独立设计成单独的类,没有任何关联,都是单表,用到的只是Hibernate的封装以及简单的OR映射
4 在大数据量系统中都会遇到类似的问题,我的解决方法是少用一对多关联映射或者不用一对多关联,设置关联少的数据表,用SQL语句做关联的查询,Hibernate中映射的配置 Lazy都为False
2013年8月9日:微游科技、三六五世界科技
问题1:有一个1001个元素的数组a[n],每个元素都在1到1000这些整数中取值,其中只有一个数得复,并且数组中每个元素只能被访问一次,设计一个算法找出这个数字.说明:每个元素只能被访问一次,就像执行int v=a[1],v变量和a[1]元素不能再访问.求高手指教
一共有1001个数,其中1000个数是从1到1000取值的(而且取完一遍),另外一个数是重复数,那就用这1001个数的和,与前头那个1000数的等差数列相减,便得出那个重复数了.
for (int num=0,i=0;i<1001;i++){num+=a【i】-i;} i从0开始,所以减的是1到1000的和。
int[] arr = new int[1001];// 定义一个能够存储1001个元素的数组。
int sum = 0;// 定义一个变量用于存储arr数组元素里面的所有总和。
int sum1 = 0;// 定义一个变量用于存储1-1000的总和。
for (int i = 0; i < arr.length; i++) {
sum += arr[i];// 用for循环,遍历求出集合中所有元素的总和。
}
for (int i = 0; i < 1001; i++) {
sum1 += arr[i];// 用for循环,遍历求出1-1000中所有元素的总和。
}
int a = sum - sum1;// 假设a为,arr数组里面重复的元素!
System.out.println("数组里面重复的数字为:" + a);
问题2:瀑布式开发模型和螺旋式开发模型?
瀑布式模型:可行性研究与计划、需求分析、设计、开发、测试、维护
螺旋式模型:可行性研究报告、需求说明书、设计文档、程序、测试报告
瀑布式模型要做完上一步才可以进行下一步,现已淘汰
螺旋模型(Spiral Model)采用一种周期性的方法来进行系统开发,这会导致开发出众多的中间版本
使用它,项目经理在早期就能够为客户实证某些概念。该模型是快速原型法,以进化的开发方式为中心,在每个项目阶段使用瀑布模型法。
这种模型的每一个周期都包括需求定义、风险分析、工程实现和评审4个阶段,由这4个阶段进行迭代。软件开发过程每迭代一次,软件开发又前进一个层次。
问题3:Spring底层动态代理失效,怎么实现切面?
Spring默认使用JDK动态代理(Proxy),但JDK动态代理是针对接口做代理的。如果类不是实现的接口的时候,就会使用cglib代理。当然,你也可以在配置文件里指定使用cglib
JDK代理:只能代理实现了接口的类
cglib代理:不仅可以对实现接口的类进行代理,同时也可以对类本身生成代理(主要是通过继承这个类来生成的,所以不要将要代理的类设成final)
问题4:什么是动态代理?
动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实
代理一般会实现它所表示的实际对象的接口
代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功能,代理对象对客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道
问题5:Struts2中的Action为什么是多例的?
Struts2的Action是多实例的并非单例,也就是每次请求产生一个Action的对象
原因是:
Struts2的Action中包含数据
例如你在页面填写的数据就会包含在Action的成员变量里面,如果Action是单实例的话,这些数据在多线程的环境下就会相互影响,例如造成别人填写的数据被你看到了
而Struts1的Action是单实例的
因为它的数据保存在Form类中,多线程环境下,Action只负责处理一些逻辑,并没有数据,也就是大家把它当做一个工具使用
同样Servlet也是单实例的
问题6:Struts1和Struts2的区别?
Struts1的前端控制器是一个Servlet,名称为ActionServlet,Struts2的前端控制器是一个filter,在Struts2.0中叫FilterDispatcher,在Struts2.1中叫StrutsPrepareAndExecuteFilter
Struts1的action需要继承Action类,Struts2的action可以不继承任何类;Struts1对同一个路径的所有请求共享一个Action实例,Struts2对同一个路径的每个请求分别使用一个独立Action实例对象,所有对于Struts2的Action不用考虑线程安全问题
在Struts1中使用formbean封装请求参数,在Struts2中直接使用action的属性来封装请求参数
Struts1 整合了JSTL,因此使用JSTL/EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--Object Graph Notation Language (OGNL)对象导航语言
Struts 1使用标准JSP机制把对象绑定到页面中来访问
Struts 2 使用ValueStack值栈技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来
Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换
Struts2 使用OGNL进行类型转换,提供基本和常用对象的转换器
Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。
Struts2支持通过validate方法和XWork校验框架来进行校验。
执行流程
Struts1
JSP发起HTTPRequest请求Servlet捕获struts.xmlnamespace+ActionNameAction填充表单setXxx()action.execute()“success”Result设置Request属性跳转目标页
Struts2
Action(JSP发起HTTPRequest请求,被过滤器捕获)FilterDispatcherstruts.xmlnamespace+ActionNamenew Action填充表单setXxx()action.execute()“success”Result设置Request属性跳转目标页
问题7:MySQL和Oracle的分页查询语句?
MySQL:
第一个参数指定返回的第一行在所有数据中的位置,从0开始(注意不是1),第二个参数指定最多返回行数
SELECT * FROM table LIMIT 5,10; #返回第6-15行数据
SELECT * FROM table LIMIT 5; #返回前5行
SELECT * FROM table LIMIT 0,5; #返回前5行
Oracle:
第1种:
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40
)
WHERE RN >= 21
第2种:
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
)
WHERE RN BETWEEN 21 AND 40
对比这两种写法,绝大多数的情况下,第一个查询的效率比第二个高得多。
这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件WHERE ROWNUM <= 40就可以被Oracle推入到内层查询中,这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了
而第二个查询语句,由于查询条件BETWEEN 21 AND 40是存在于查询的第三层,而Oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道RN代表什么)
因此,对于第二个查询语句,Oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多
问题8:部署在不同Tomcat的两个项目间如何通信?
使用WebService技术实现
使用Socket技术实现
使用Http请求技术实现
问题9:请你谈谈SSH整合?
Struts(表示层)+Spring(业务层)+Hibernate(持久层)
Struts:
Struts是一个表示层框架,主要作用是界面展示,接收请求,分发请求
在MVC框架中,Struts属于VC层次,负责界面表现,负责MVC关系的分发
View:沿用 JSP,HTTP,Form,Tag,Resourse
Controller:ActionServlet,struts-config.xml,Action
Hibernate:
Hibernate是一个持久层框架,它只负责与关系数据库的操作
Spring:
Spring是一个业务层框架,是一个整合的框架,能够很好地黏合表示层与持久层
问题10:Struts2的数据都在ValueStack中,怎么保证数据的安全性?ValueStack生命周期多长?
因为ValueStack在ActionContext中,而ActionContext在ThreadLocal中,所以能保证数据的安全性
ValueStack的生命周期是一次请求,因为ActionContext把ValueStack放在Request域里面
问题11:OGNL有什么优点?
可以访问ValueStack和AcionContext
可以操作集合对象,很方便的构建各种集合
可以在 struts.xml访问action定义的属性
可以调用对象的方法
JSTL/EL只能在JSP中使用,而OGNL可以在更多的View使用
问题12:为什么使用Spring?有什么优点?
降低了组件之间的耦合性 ,实现了软件各层之间的解耦
可以使用容器提供的众多服务,如事务管理,消息服务等
容器提供单例模式支持
容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能
容器提供了众多的辅助类,能加快应用的开发
Spring对于主流的应用框架提供了集成支持,如Hibernate,JPA,Struts等
Spring属于低侵入式设计,代码的污染极低
独立于各种应用服务器
Spring的DI机制降低了业务对象替换的复杂性(依赖注入)
10、Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择Spring的部分或全部
2013年8月13日:信诺网利
问题1:Spring的AOP是用什么来实现的?
Spring AOP就是用AspectJ来实现的,是依赖关系
AspectJ是动态代理的一种实现,而Spring默认使用的就是AspectJ来实现的动态代理,Spring自己的AOP就是使用AspectJ来实现的
AOP:Aspect Oriented Programming(面向切面编程)
利用动态代理实现面向切面编程
Spring实现动态代理配置是有两种配置文件:
XML文件方式
Annotation方式,使用AspectJ类库实现的
AspectJ类库,AspectJ是一个专门用来实现动态代理(AOP编程)的类库,AspectJ是面向切面编程的框架,Spring使用就是这个类库实现动态代理的
AspectJ的专业术语:
JoinPoint连接点(切入点)
PointCut切入点,当需要定义一个切入点时,则需要使用这个
Aspect切面
Advice切入点的逻辑
Target被代理对象
Weave织入
问题2:单例模式
单例模式是设计模式中最简单的形式之一
这一模式的目的是使得类的一个对象成为系统中的唯一实例,要实现这一点,可以从客户端对其进行实例化开始
因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。
使用工厂方法来限制实例化过程,这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义
// 第一种形式: 也是常用的形式。
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// do something
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
// 第二种形式:
public class Singleton {
// 在自己内部定义自己的一个实例,只供内部调用
private static Singleton instance = new Singleton();
private Singleton() {
// do something
}
// 这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}
// 第三种形式: 双重锁的形式。
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// do something
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (null == instance) {
instance = new Singleton();
}
}
}
return instance;
}
}// 这个模式将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。
问题3:PrepareStatement和Statement的区别?
Statement用于执行静态SQL语句,在执行时,必须指定一个事先准备好的SQL语句,也就是说SQL语句是静态的
PrepareStatement是预编译的SQL语句对象,SQL语句被预编译并保存在对象中。被封装的SQL语句代表某一类操作,语句中可以包含动态参数“?”,在执行时可以为“?”动态设置参数值
使用PrepareStatement对象执行SQL时,SQL被数据库进行解析和编译,然后被放到命令缓冲区,每当执行同一个PrepareStatement对象时,它就会被解析一次,但不会被再次编译。在缓冲区可以发现预编译的命令,并且可以重用。所以PrepareStatement可以减少编译次数提高数据库性能
1、创建时的区别:
Statement stm=con.createStatement();
PreparedStatement pstm=con.prepareStatement(SQL);
执行的时候:
stm.execute(SQL);
pstm.execute();
2、pstm一旦绑定了SQL,此pstm就不能执行其他的SQL,即只能执行一条SQL命令
stm可以执行多条SQL命令
3、 对于执行同构的SQL(只有值不同,其他结构都相同),用pstm的执行效率比较高,对于异构的SQL语句,Statement的执行效率要高
4、当需要外部变量的时候,pstm的执行效率更高
问题4:团队项目开发中,功能模块完成后如何和组员集成(整合)测试?
先进行单元测试,单元测试无误后再进行集成测试
例子:Junit+Ant
这个是属于软件测试的范畴,由测试人员做的,分为功能测试与性能测试
2013年8月14日:21CN世纪龙信息、凯通软件
问题1:解释一下什么是哈希表?
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构
也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度
这个映射函数叫做散列函数,存放记录的数组叫做散列表
问题2:线程的生命周期
新建就绪(阻塞)运行死亡
新建:其中当用new创建完一个线程对象后,该线程处于新建状态
就绪:当线程对象调用start()后,该线程处于就绪状态
运行:如果处于就绪状态的线程获得CPU时间片,开始执行run方法的线程执行体,该线程处于运行状态
阻塞:如果线程调用了sleep()或者调用了一个阻塞式IO方法等,该线程处于阻塞状态
死亡:如果线程的run()执行完成或者抛出一个未捕获的异常等原因,该线程处于死亡状态
问题3:JSP页面如何实现自定义标签?
首先新建继承了SimpleTagSupport类的自定标签类,重写doTag方法
然后新建tld文件,定义标签的属性及格式
JSP页面引入标签
注意要放置在WEB-INF目录下才可以解析
自定义标签采用
格式
问题4:JSP页面如何实现自定义函数?
首先新建自定函数类,定义public static boolean方法
然后新建tld文件,定义标签的属性及格式
JSP页面引入标签
注意要放置在WEB-INF目录下才可以解析
自定义函数采用${myfn:contains(字符串,字符串)}格式
问题5:你所了解的Apache的commons项目所包含的工具?
BeanUtils:提供了对于JavaBean进行各种操作,克隆对象、属性等等
Betwixt:XML与Java对象之间相互转换
Codec:处理常用的编码方法的工具类包 例如DES、SHA1、MD5、Base64等
Collections:Java集合框架操作
Compress:Java提供文件打包 压缩类库
Configuration:一个Java应用程序的配置管理类库
DBCP:提供数据库连接池服务
DbUtils:提供对JDBC的操作封装来简化数据查询和记录读取操作
Email:Java发送邮件对JavaMail的封装
FileUpload:提供文件上传功能
HttpClient:提供HTTP客户端与服务器的各种通讯操作. 现在已改成HttpComponents
IO:IO工具的封装
Lang:Java基本对象方法的工具类包,如:StringUtils,ArrayUtils等等
Logging:提供的是一个Java 的日志接口
Validator:提供了客户端和服务器端的数据验证框架
问题6、如何对SQL语句进行优化?
尽可能合理运用索引
少用“*”,比如select * from tableName,只查询自己需要的数据
使用LIKE ‘%关键字%’模糊查询时,由于关键字前面用了“%”符号,因此该查询必定会进行全表查询,尽量不要在关键字前加“%”符号
尽可能减少子查询的层数
尽可能在子查询中进行数据筛选
尽量使用数字型字段,一部分开发人员和数据库管理人员喜欢把包含数值信息的字段设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
2013年8月15日:
问题1、你所了解的测试技术,并说一下你觉得测试与开发之间的关系
1、按是否查看程序内部结构分为:
黑盒测试:只关心输入和输出的结果
白盒测试:去研究里面的源代码和程序结构
2、按是否运行程序分为:
静态测试:是指不实际运行被测软件,而只是静态地检查程序代码、界面或文档可能
动态测试:是指实际运行被测程序,输入相应的测试数据,检查输出结果和预期结果是否相符的过程
3、按阶段划分:
单元测试:是指对软件中的最小可测试单元进行检查和验证
集成测试:是单元测试的下一阶段,是指将通过测试的单元模块组装成系统或子系统,再进行测试,重点测试不同模块的接口部门。集成测试就是用来检查各个单元模块结合到一起能否协同配合,正常运行
系统测试:指的是将整个软件系统看做一个整体进行测试,包括对功能、性能,以及软件所运行的软硬件环境进行测试。系统测试的主要依据是《系统需求规格说明书》文档
验收测试:指的是在系统测试的后期,以用户测试为主,或有测试人员等质量保障人员共同参与的测试,它也是软件正式交给用户使用的最后一道工序。验收测试又分为a测试和beta测试,其中a测试指的是由用户、 测试人员、开发人员等共同参与的内部测试,而beta测试指的是内测后的公测,即完全交给最终用户测试
软件开发是生产制造软件;软件测试是验证开发出来软件的质量
类比传统加工制造企业,软件开发人员就是生产加工的工人,软件测试人员就是质检人员
开发与测试的关系应该是:
没有软件开发就没有测试,软件开发提供软件测试的对象
软件开发和软件测试都是软件生命周期中的重要组成部分
软件开发和软件测试都是软件过程中的重要活动
软件测试是保证软件开发产物质量的重要手段
问题2、Oracle里varchar2的最大长度?
字段类型:Oracle SQL varchar2的最大支持长度为4000个字节(bytes)
变量类型:Oracle PLSQL varchar2最大支持长度为32767个字节(缓冲区)
问题3、如何判断Session过期?
request.getSession(boolean)这个方法里面传了一个boolean值,这个值如果是true,那么如果当前的Request的Session不可用,那么就创建新的会话,如果存在就返回当前的会话。如果参数是false,那么在Request的当前会话不存在的时候就返回null
if(request.getSession(false)==null){
System.out.println("Session has been invalidated!");
}
else{
System.out.println("Session is active!");
}
问题4、Oracle的行列转换?
姓名 科目 分数
--- --- ----
太上 语文 80
太上 数学 70
太上 英语 60
唤魔 语文 90
唤魔 数学 80
唤魔 英语 100
转换为:
姓名 语文 数学 英语
太上 80 70 60
唤魔 90 80 100
使用Oracle的Decode函数,如果“科目”是“语文”,返回对应科目的分数的综合,0是缺省值
语句如下:
select 姓名,
sum(decode(科目,'语文', 分数,0)) "语文",
sum(decode(科目,'数学', 分数,0)) "数学",
sum(decode(科目,'英语', 分数,0)) "英语"
from table
group by 姓名;
2013年8月16日:
问题1:Hibernate框架下如何实现分页?
Hibernate有自带分页功能
Query.setFirstResult() //从哪一条条记录开始
Query.setMaxResults() //希望获得的记录数
问题2:AJAX的优缺点?
优点:
局部刷新页面,减少用户心理和实际的等待时间,带来更好的用户体验
使用异步方式与服务器通信,不需要打断用户的操作,具有更加迅速的响应能力
减轻服务器的负担,按需取数据,最大程度的减少冗余请求
基于XML标准化,并被广泛支持,不需安装插件等
缺点:
AJAX大量的使用了JavaScript和AJAX引擎,这些取决于浏览器的支持。在编写的时候考虑对浏览器的兼容性IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持,Mozilla虽然也支持AJAX,但是提供XMLHttpRequest的方式不一样
AJAX更新页面内容的时候并没有刷新整个页面,因此,网页的后退功能是失效的;有的用户还经常搞不清楚现在的数据是旧的还是已经更新过的这个就需要在明显位置提醒用户“数据已更新”
对流媒体还有移动设备的支持不太好等,比如手机还有平板电脑
问题3、Hibernate里配置生成主键的方式有哪些?
Increment:
由Hibernate从数据库中取出主键的最大值(每个Session只取1次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库
特点:跨数据库,不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于集群环境
Hilo:
hilo(高低位方式high low)是Hibernate中最常用的一种生成方式,需要一张额外的表保存hi的值。保存hi值的表至少有一条记录(只与第一条记录有关),否则会出现错误。可以跨数据库
特点:跨数据库,hilo算法生成的标志只能在一个数据库中保证唯一
Sehilo:
与hilo类似,通过hi/lo算法实现的主键生成机制,只是将hilo中的数据表换成了序列Sequence,需要数据库中先创建Sequence,适用于支持Sequence的数据库,如Oracle
特点:与hilo类似,只能在支持序列的数据库中使用
Identity:
identity由底层数据库生成标识符。identity是由数据库自己生成的,但这个主键必须设置为自增长,使用identity的前提条件是底层数据库支持自动增长字段类型,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,Oracle这类没有自增字段的则不支持
特点:只能用在支持自动增长的字段数据库中使用,如MySQL
Sequence:
采用数据库提供的Sequence机制生成主键,需要数据库支持Sequence。如ORACLE、DB、SAP DB、PostgerSQL、McKoi中的SequenceMySQL这种不支持Sequence的数据库则不行(可以使用identity)
特点:只能在支持序列的数据库中使用,如Oracle
Native:
native由Hibernate根据使用的数据库自行判断采用identity、hilo、Sequence其中一种作为主键生成方式,灵活性很强如果能支持identity则使用identity,如果支持Sequence则使用Sequence
特点:根据数据库自动选择,项目中如果用到多个数据库时,可以使用这种方式,使用时需要设置表的自增字段或建立序列,建立表等
Uuid:
UUID:Universally Unique Identifier,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字
特点:uuid长度大,占用空间大,跨数据库,不用访问数据库就生成主键值,所以效率高且能保证唯一性,移植非常方便,推荐使用
Assigned:
主键由外部程序负责生成,在 save() 之前必须指定一个Hibernate不负责维护主键生成,与Hibernate和底层数据库都无关,可以跨数据库。在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免
特点:可以跨数据库,人为控制主键生成,应尽量避免
Composite-id:复合主键,联合主键
2013年8月17日:
问题1、Oracle是否支持Auto_Increment?如不支持如何实现类似功能?
建立一个Sequence序列:
CREATE SEQUENCE Sequence_Name
INCREMENT BY 1 每次加1个
START WITH 1 从1开始计数
NOMAXVALUE 不设置最大值
NOCYCLE ; 一直累加,不循环
建立一个TRIGGER触发器:
CREATE OR REPLACE TRIGGER Trigger_Name
BEFORE
INSERT
ON Table_Name referencing NEW as NEW FOR EACH ROW 行级触发,即每行都触发
DECLARE
begin
select Sequence_Name.nextval into:New.increment_column from dual;
end;
/
问题2、建模使用什么工具?
Rational Rose、Power Designer、StarUML、Enterprise Architect [ˈɑ:kitekt]
问题3、Svn主要作用?Svn的服务如何配置?
主要作用:版本控制管理和代码服务器,主要用于团队开发时对项目代码的管理
服务配置:
创建版本库svnadmin create 版本库路径
建议注册到services.msc服务中
命令:sc create/delete svn binPath= “盘符:\subversion\bin\svnserve.exe –service –r 仓库目录” DisplayName= “逻辑名”
binPath的值之前一定要加空格
2013年8月19日:凯通软件
问题1、Java基础数据类型有哪些?最大长度分别是多少位?多少字节?
整数类型:
Byte 8位 1字节 范围:-128 ~ 127范围:-27 ~ 27-1
Short 16位 2字节 范围:-32768 ~ 32767 范围:-215 ~ 215-1
Int 32位4字节 范围:-2,147,483,648 ~ 2,147,483,647 范围:-231 ~ 231-1
Long 64位8字节 范围:-9,223,372,036,854,775,808~+9,223,372,036,854,775,807 范围:-263 ~ 263 -1
浮点数型:
Float 32位4字节 范围:-3,40292347E+38 ~ +3,40292347E+38范围:
Double 64位8字节 范围:-1.79769313486231576E+308 ~ 1.79769313486231576E+308范围:
其他类型:
Char 16位2字节(默认Unicode编码) 范围:‘\u0000′ ~ ‘\uFFFF’ 范围:
Boolean 1位0.125字节(8分之1字节) 范围:true/false
注意:
Int最常用(20亿左右),long可以用在统计世界人口,byte,short用在特殊场合(如果知道存储在变量中的整数在一个字节范围内,就应该将变量声明为byte)
Double和Float,一般都使用double,double类型,因为double类型比float更精确。需要存储大量数据才考虑单精度一般使用(float可以节约内存)
问题2、String有哪些方法?
trim() 去掉起始和结尾的空格
charAt (int index) 返回index所指定的字符
concat(String str) 将两字符串连接
equals() 比较两个字符串
length() 返回字符串的长度
replace(char old ,char new) 将old用new替代
valueOf() 转换为字符串
substring(int1,int2) 取出字符串内第int1位置到int2的字符串
indexOf() 查找字符或者子串第一次出现的地方,lastIndexOf() 查找字符或者子串是后一次出现的地方
startsWith(String str) 测试字符串是否以str开始,endsWith(String str) 测试字符串是否以str结尾
getBytes 将字符串转换成字节数组返回,toCharArray 将字符串转换成字符数组
toLowerCase() 将字符串内的字符改写成小写,toUpperCase() 将字符串内的字符改写成大写
问题3、冒泡排序的代码?
基本思想:
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
实例:
冒泡排序(bubble sort):冒泡排序,每次两个相邻的值进行比较,内层循环结束,最后出现最大值。
/*
冒泡排序,每次两个相邻的值进行比较,内层循环结束,最后出现最大值。
内层循环 arr.length-1 避免角标越界
arr.length-x 减少参与比较的数,因为这些数,已经是最大值,排在最后,没有必要参与比较。
*/
public static void bubbleSort(int[] arr){
for(int x=0;x
for(int y=0;y if(arr[y]>arr[y+1]){
int temp =arr[y+1];
arr[y+1]=arr[y];
arr[y]=temp;
}}}}
问题4、选择排序的代码?
基本思想:
在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
实例:
/*
选择排序。内循环结束 0角标位出现最小值。只要外层循环的值比内层循环值大,就互换位置。
0角标位的元素,和0角标位以后的每个元素进行比较,只要比他们大就互换,位置,这样可以保证0角标位置值最小。
然后,再进行1角标位置和1角标后的每个元素进行比较。
依次类推,
*/
public static void selectSort(int[] arr){
for(int x=0;x for(int y=x+1;y if(arr[x]>arr[y]){
int temp=arr[y];
arr[y]=arr[x];
arr[x]=temp;
}}}}
问题5、inner join、left join、right join、full out join有什么区别?
left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的.。
换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID),B表记录不足的地方均为NULL。
范例代码:
SELECT C.First_Name, C.Last_Name, O.Order_Id FORM Customer AS C LEFT JOIN Order AS O ON C.Customer_ID = O.Customer_ID
right join和left join的结果刚好相反,这次是以右表(B)为基础的,A表不足的地方用NULL填充。
inner join只显示出了 A.aID = B.bID的记录,这说明inner join并不以谁为基础,它只显示符合条件的记录。
Oracle中的使用:
连接分为两种:内连接与外连接。
A.内连接,即最常见的等值连接,例:
SELECT *
FROM TESTA,TESTB
WHERE TESTA.A=TESTB.A
等价于
select * from testa inner join testb on testa.a=testb.a
B.外连接分为左外连接,右外连接和全外连接。
1.左外连接 left outer join 或者 left join
左外连接就是在等值连接的基础上加上主表中的未匹配数据,例:
SELECT *
FROM TESTA
LEFT OUTER JOIN TESTB
ON TESTA.A=TESTB.A
---------------------其中主表是TESTA。
Oracle 中等价于: (+)是outer join 的意思,能将匹配备件中有空值的记录也显示出来,如果没有这个符号,则不会显示条件中包含空值的结果。
SELECT *
FROM TESTA,TESTB
WHERE TESTA.A=TESTB.A(+)
三个表做左外连接:
SELECT *
FROM TESTA
LEFT OUTER JOIN TESTB
ON TESTA.A=TESTB.A
LEFT OUTER JOIN TESTC
ON TESTA.A=TESTC.A
Oracle 中等价于:
SELECT *
FROM TESTA,TESTB,TESTC
WHERE TESTA.A=TESTB.A(+)
AND TESTA.A=TESTC.A(+)
2. 右外连接 right outer join 或者 right join,是在等值连接的基础上加上被连接表的不匹配数据。
SELECT *
FROM TESTA
RIGHT OUTER JOIN TESTB
ON TESTA.A=TESTB.A
----------------------其中被连接表是TESTB
Oracle支持的另一种写法:
SELECT *
FROM TESTA,TESTB
WHERE TESTA.A(+)=TESTB.A
3.全外连接 full outer join 或者 full join,是在等值连接的基础上将左表和右表的未匹配数据都加上。
SELECT *
FROM TESTA
FULL OUTER JOIN TESTB
ON TESTA.A=TESTB.A
全外连接的等价写法,对同一表先做左连接,然后右连接:
SELECT TESTA.*,TESTB.*
FROM TESTA
LEFT OUTER JOIN TESTB
ON TESTA.A=TESTB.A
UNION
SELECT TESTA.*,TESTB.*
FROM TESTB
LEFT OUTER JOIN TESTA
ON TESTA.A=TESTB.A
2013年8月20日:
问题1、JS中有哪些数据类型?
Undefined、Null、Boolean、Number、String、Object、Array、Function。
JavaScript有三种基本数据类型(字符串、数值、布尔 ),两种引用数据类型(对象、数组)和两种特殊数据类型(Null 、Undefined )。
问题2、String 和StringBuffer的区别?
JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。
String类表示内容不可改变的字符串。而StringBuffer类表示内容可以被修改的字符串。当你知道字符数据要改变的时候你就可以使用StringBuffer。
典型地,你可以使用StringBuffers来动态构造字符数据。
另外,String实现了equals方法,new String(“abc”).equals(new String(“abc”)的结果为true,而StringBuffer没有实现equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的结果为false。
接着要举一个具体的例子来说明,我们要把1到100的所有数字拼起来,组成一个串。
StringBuffer sbf = new StringBuffer();
for(int i=0;i<100;i++)
{
sbf.append(i);
}
上面的代码效率很高,因为只创建了一个StringBuffer对象,而下面的代码效率很低,因为创建了101个对象。
String str = new String();
for(int i=0;i<100;i++)
{
str = str + i;
}
在讲两者区别时,应把循环的次数搞成10000,然后用endTime-beginTime来比较两者执行的时间差异,最后还要讲讲StringBuilder与StringBuffer的区别。
String覆盖了equals方法和hashCode方法,而StringBuffer没有覆盖equals方法和hashCode方法,所以,将StringBuffer对象存储进Java集合类中时会出现问题。
问题3、StringBuffer与StringBuilder的区别?
StringBuffer和StringBuilder类都表示内容可以被修改的字符串,StringBuilder是线程不安全的,运行效率高,如果一个字符串变量是在方法里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素了,则用StringBuilder。如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环境下使用,那么最好用StringBuffer。
String 不可变 每次对其操作都会在数据池产生一个新的对象,不适合使用在对字符串进行频繁修改的场景
StringBuffer和StringBuilder可变,对其修改不会产生新的对象 其两者区别在于StringBuffer线程安全而StringBuilder线程不安全,StringBuilder是线程非安全的效率比StringBuffer高
比喻:
String是一个商品
StringBuffer/StringBuilder是生产这个商品的流水线,
StringBuffer速度慢,但(线程)安全性高
StringBuilder速度快,但(线程)安全性差
问题4、Threadlocal类的作用?
ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另一个线程中则共享另一份数据,线程的数据是独享的。
ThreadLocal的实现原理:每个线程调用全局ThreadLocal的set方法,就相当于往其内部的Map中增加一条记录,key是各自的线程,value是各自的线程调用set放进的值。在线程结束时可以调用ThreadLocal.clear()方法,可以立即释放内存。也可以不调用,线程运行完成之后内存也会被回收。
顾名思义它是local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。
它主要由四个方法组成initialValue(),get(),set(T),remove(),其中值得注意的是initialValue(),该方法是一个protected的方法,显然是为了子类重写而特意实现的。该方法返回当前线程在该线程局部变量的初始值,这个方法是一个延迟调用方法,在一个线程第1次调用get()或者set(Object)时才执行,并且仅执行1次。ThreadLocal中的确实实现直接返回一个null。也是解决线程安全的问题的一种方法。
问题5、Statement、Preparedstatement、Callablestatement的区别?
Statement
|
PreparedStatement
|
CallableStatement
Statement用于执行一条普通的动态SQL语句,PreparedStatement用于执行预编译好的SQL语句,CallableStatement用于调用数据库的存储过程。他们的继承关系如上。
Statement 每次执行sql语句,数据库都要执行sql语句的编译 ,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement.
PreparedStatement是预编译的,使用PreparedStatement有几个好处
在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。
安全性好,有效防止Sql注入等问题。
对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;
代码的可读性和可维护性。
CallableStatement接口扩展 PreparedStatement,用来调用存储过程,它提供了对输出和输入/输出参数的支持。CallableStatement 接口还具有对 PreparedStatement 接口提供的输入参数的支持。
问题6、把一个字符串类型的日期 转换成Date类型?
字符串转换为日期:
String brithday = new String("1991-02-02");
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf1.parse(brithday);
System.out.println("将字符串转化为时间是" + date);
日期转换为字符串:
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMDDHHMMSSmmm ");
System.out.println(sdf2.format(new Date()));
将输入的字符串转换为需要的日期格式:
String myBirthday = new String("19881113");
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMdd");
Date date = sdf3.parse(myBirthday);
String newBirthday = sdf2.format(date);
System.out.println("将输入的字符串转换为需要的日期格式" + newBirthday);
问题7、Spring中加载XML配置文件的方法?
Spring中的几种容器都支持使用xml装配bean,包括:
XmlBeanFactory引用资源、ClassPathXmlApplicationContext编译路径
FileSystemXmlApplicationContext用文件系统的路径、XmlWebApplicationContext专为Web工程定制
加载这些容器的配置文件的XML有以下几种常见的方法:
1、引用资源用XmlBeanFactory(不能实现多个文件相互引用)
Resource resource = new ClassPathResource("appcontext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
从factory中获取相应资源文件中的bean,但是这种bean读不到引用了其他文件中的bean!
2、引用应用上下文用ClassPathXmlApplicationContext
ApplicationContext factory = new ClassPathXmlApplicationContext(
"classpath:applicationContext.xml");
ApplicationContext factory = new ClassPathXmlApplicationContext(
"conf/userConfig.xml"); // src/conf 目录下的
ApplicationContext factory = new ClassPathXmlApplicationContext(
"file:G:/Test/src/appcontext.xml");
3、用文件系统的路径引用应用上下文用FileSystemXmlApplicationContext
ApplicationContext factory = new FileSystemXmlApplicationContext(
"src/applicationContext.xml");
ApplicationContext factory = new FileSystemXmlApplicationContext(
"classpath:appcontext.xml");
ApplicationContext factory = new FileSystemXmlApplicationContext(
"file:G:/Test/src/appcontext.xml");
ApplicationContext factory = new FileSystemXmlApplicationContext(
"G:/Test/src/appcontext.xml");
注意:在2、3的加载方式中可以加载多个配置文件,获取到ApplicationContext 对象中
String[] configs = { "applicationContext.xml", "user_spring.xml" };
ApplicationContext ctx = new ClassPathXmlApplicationContext(configs);
// ApplicationContext ctx=new FileSystemXmlApplicationContext(configs);
AbstractDao myUserDAO = (AbstractDao) ctx.getBean("userDao");
4、Web工程定制的加载方法 XmlWebApplicationContext
ServletContext servletContext = request.getSession()
.getServletContext();
ApplicationContext ctx = WebApplicationContextUtils
.getWebApplicationContext(servletContext);
注:web.xml里面可以定义两种参数:
application范围内的参数,存放在servletcontext中。中的参数(可以指定多个文件)
servlet范围内的参数,只能在servlet的init()方法中取得, 中的参数,在init方法中用this.getInitParameter("param1")获取
要在spring配置多个xml,并且这些文件相互应用的加载方式:
1、在web.xml配置,应用服务去加载
app
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation /WEB-INF/applicationContext*.xml,/WEB-INF/user_spring*.xml
1
2、在/WEB-INF/applicationContext.xml配置应用服务去加载
可以在applicationContext.xml中用import引入其他的配置文件
问题8、查询分组后,每个分组前几条记录?
建表语句:
/* 创建表并初始化数据 */
drop table if exists Orders;
create table Orders(
id int primary key auto_increment,
Company varchar(255),
OrderNumber varchar(255),
);
插入数据:
insert into Orders(Company,OrderNumber, pid) values('IBM','3532',1);
insert into Orders(Company,OrderNumber, pid) values('IBM','4211',1);
insert into Orders(Company,OrderNumber, pid) values('IBM','2342',2);
insert into Orders(Company,OrderNumber, pid) values('IBM','12345',3);
insert into Orders(Company,OrderNumber, pid) values('W3School','45323',1);
insert into Orders(Company,OrderNumber, pid) values('W3School','2356',2);
insert into Orders(Company,OrderNumber, pid) values('Apple','4538',1);
insert into Orders(Company,OrderNumber, pid) values('Apple','4698',2);
insert into Orders(Company,OrderNumber, pid) values('Apple','3234',2);
insert into Orders(Company,OrderNumber, pid) values('Apple','3232',3);
insert into Orders(Company,OrderNumber, pid) values('W3School','6953',3);
insert into Orders(Company,OrderNumber) values('W3School','6953');
查询语句:/* 查询Orders表,以Company分组,查出每组中的前两个记录 */
SELECT * FROM Orders o WHERE 2 >(SELECT count(*) FROM Orders WHERE Company = o.Company and OrderNumber > o.OrderNumber);
问题9、外部js中如何使用EL表达式?
外部js中的el表达式默认无效,有以下解决方案:
1、把数据保存在隐藏域中,然后由js去调
例如jsp中
js中,用getElementById方法
2、如果js非要放入单独文件中,可以把js文件命名为.jsp文件就可以了,这样里面el就能运行,也就是服务器可以执行这个文件了。无非页面引用的时候引用jsp就可以了。
< script src="myjs.jsp" type="text/javascript>
EL表达式是在服务端执行的,服务端执行完成后再传给客户端的,js是在客户端执行的,el在js前就被执行了。
把引入的外部js改为jsp文件,然后在jsp页面中引入
在完全是js的jsp文件中,在执行的时候会出现乱码
在顶部加入
< %@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>可解决乱码
然后在jsp页面中引入myjs.jsp,
< script src="myjs.jsp" type="text/javascript">
但是如果js文件有创建html,就会出现错误,比如document.createElement('' );即使转义后
document.createElement(' ' ); 也没有效果 ,在解析的时候,会创建
document.createElement(' ' );使用时候不识别的标识符
可以直接使用document.createElement('option')
火狐不支持select.options.appendChild(option),IE支持
select.appendChild(option) IE和Firefox都支持
火狐不支持option.innerText="test",
为兼容 改写为option.innerHTML="test"
问题10、给你一张表查询同一IP的登录次数,以及登录次数大于10次的IP?
给的参数是 id datetime url session_id ip
select 记录, count(记录) from 表 where 记录=表.记录 group by 记录 having count(记录)>10
select count(ip),ip from table group by ip having count(ip)>10;
问题11、和<%@include file=""%>有什么区别?
动态:--动作,运行时包含,先处理后包含
父页面和包含进来的页面单独编译,单独翻译成servlet后,在前台拼成一个HTML页面。
a.能自动区分被包含文件是静态还是动态;
b.如果被包含文件是静态文件,处理方式跟第1种方式一样,
如果是动态文件,则各自处理完之后把结果包含进来发给客户端。
静态:<%@include file=""%>--指令,编译时包含,先包含后处理
父页面和包含进来的页面,代码合并后,才一起翻译成servlet,反馈到前台,形成一个HTML页面。
a.不管被包含文件是静态还是动态,直接将页面中的全部内容包含进来;
b.执行时先将包含进来的内容一起处理完之后再将所有的内容发给客户端。
2013年8月22日:嘉瑶软件
问题1、使用JavaScript动态添加删除表格行?
< script type="text/javascript">
//动态增加和删除表格行的内容
document.getElementById("addID").onclick = function(){
var tbodyElement = document.getElementById("tbodyID");
//创建tr元素
var trElement = document.createElement("tr");
//创建td元素
var td1Element = document.createElement("td");
var td2Element = document.createElement("td");
var td3Element = document.createElement("td");
//创建删除按钮
var delInputElement = document.createElement("input");
delInputElement.type = "button";
delInputElement.value = "删除";
td3Element.appendChild(delInputElement);
//为删除按钮添加单击事件
delInputElement.onclick = function(){
//this表示删除按钮
//父.removeChild(子);
//this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
tbodyElement.removeChild(trElement);
}
//将td元素添加到tr元素中
trElement.appendChild(td1Element);
trElement.appendChild(td2Element);
trElement.appendChild(td3Element);
//将tr元素添加到tbody元素中
tbodyElement.appendChild(trElement);
}
function trim(message){ //去空格,正则表达式
return message.replace(/^\s*$/,"");
}
问题2、什么叫面向接口编程?有什么好处?
在系统分析和架构中,分清层次和依赖关系,每个层次不是直接向其上层提供服务(即不是直接实例化在上层中),而是通过定义一组接口,仅向上层暴露其接口功能,上层对于下层仅仅是接口依赖,而不依赖具体类。
这样做的好处是显而易见的,首先对系统灵活性大有好处。当下层需要改变时,只要接口及接口功能不变,则上层不用做任何修改。甚至可以在不改动上层代码时将下层整个替换掉,就像我们将一个WD的60G硬盘换成一个希捷的160G的硬盘,计算机其他地方不用做任何改动,而是把原硬盘拔下来、新硬盘插上就行了,因为计算机其他部分不依赖具体硬盘,而只依赖一个IDE接口,只要硬盘实现了这个接口,就可以替换上去。从这里看,程序中的接口和现实中的接口极为相似,所以我一直认为,接口(interface)这个词用的真是神似!
使用接口的另一个好处就是不同部件或层次的开发人员可以并行开工,就像造硬盘的不用等造CPU的,也不用等造显示器的,只要接口一致,设计合理,完全可以并行进行开发,从而提高效率。
问题3、事务的概念?开发中如何使用事务?
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。
MySQL数据库开启事务命令:
start transaction 开启事务
rollback 回滚事务
commit 提交事务
savepoint 设置回滚点
rollback to savepoint 回滚到指定的回滚点
问题4、递归算法题:一个整数,大于0,不用循环和本地变量,按照n,2n,4n,8n的顺序递增,当值大于10000时,把值按照指定顺序输出来。先顺序后逆序
public static void main(String[] args) throws Exception {
doubleNum(512);
}
public static void doubleNum(int n) {
System.out.println(n);
if (n <= 10000)
doubleNum(n * 2);
System.out.println(n);
}
问题5、两个div 并排放到同一个div上面?
第一步:
中间两个div 设置的宽度 加起来等于1000px,
第二步:
中间两个div 分别加样式 style="float:left;"
例如:
< div style="width:1000px;height:500px;background: black;">
< div style="background: blue;width: 500px;height:500px;float:left;">