目录
1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?............ 8
2、Java有没有goto?................................................................................................. 8
3、说说&和&&的区别。........................................................................................... 8
4、在JAVA中如何跳出当前的多重嵌套循环?.......................................................... 8
5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上?.......... 9
6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?......................... 9
7、char型变量中能不能存贮一个中文汉字?为什么?................................................... 9
8、用最有效率的方法算出2乘以8等於几?............................................................... 9
9、请设计一个一百亿的计算器................................................................................. 9
10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?..... 9
11、"=="和equals方法究竟有什么区别?................................................................ 10
12、静态变量和实例变量的区别?.......................................................................... 10
13、是否可以从一个static方法内部发出对非static方法的调用?............................. 10
14、Integer与int的区别.......................................................................................... 10
15、Math.round(11.5)等于多少? Math.round(-11.5)等于多少?..................................... 11
16、下面的代码有什么不妥之处?............................................................................. 11
17、请说出作用域public,private,protected,以及不写时的区别............................ 11
18、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?.... 11
19、构造器Constructor是否可被override?................................................................ 11
20、接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?抽象类中是否可以有静态的main方法?抽象类是否可有以内部类?接口是否可以有内部类?....... 11
21、写clone()方法时,通常都有一行代码(不是必须有),是什么?.......................... 12
22、面向对象的特征有哪些方面.............................................................................. 12
23、java中实现多态的机制是什么?....................................................................... 12
24、abstract class和interface有什么区别?................................................................. 12
25、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?12
26、什么是内部类?Static Nested Class和Inner Class的不同。................................. 13
27、内部类可以引用它的包含类的成员吗?有没有什么限制?................................ 13
28、Anonymous Inner Class (匿名内部类)是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?13
29、super.getClass()方法和this.getClass()方法返回对象是否相同?............................ 13
30、String是最基本的数据类型吗?.......................................................................... 13
31、String s = "Hello";s= s + " world!";这两行代码执行后,原始的String对象中的内容到底变了没有? 13
32、是否可以继承String类?.................................................................................... 13
33、String s = newString("xyz");创建了几个String Object?二者之间有什么区别?.... 13
34、String和StringBuffer的区别............................................................................. 14
35、如何把一段逗号分割的字符串转换成一个数组?................................................ 14
36、数组有没有length()这个方法? String有没有length()这个方法?JS的字符串有没有length()方法? 14
37、下面这条语句一共创建了多少个对象:Strings="a"+"b"+"c"+"d";...................... 14
38、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?............................................................................................................... 15
39、下面的程序代码输出的结果是多少?................................................................ 15
40、final, finally, finalize的区别。........................................................................... 16
41、运行时异常(Runtime)与检查异常(Checked)有何异同?...................................... 17
42、error和exception有什么区别?........................................................................... 17
43、Java中的异常处理机制的简单原理和应用。..................................................... 17
44、请写出你最常见到的5个RuntimeException。................................................... 18
45、Java语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?............................................................................................................................... 18
46、 Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用?18
47、sleep()和wait()有什么区别?.............................................................................. 19
48、同步和异步有何异同,在什么情况下分别使用他们?举例说明。...................... 21
49. 下面两个方法同步吗?(自己发明)................................................................. 21
50、多线程有几种实现方法?同步有几种实现方法?.................................................. 22
51、启动一个线程是用run()还是start()?.................................................................. 22
52、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 22
53、线程的基本概念、线程的基本状态以及状态之间的关系.................................... 22
54、简述synchronized和java.util.concurrent.locks.Lock的异同?.............................. 22
55、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。 24
56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。............................................................................................... 26
57、介绍Collection框架的结构............................................................................... 29
58、Collection框架中实现比较要实现什么接口........................................................ 30
59、ArrayList和Vector的区别................................................................................. 30
60、HashMap和Hashtable的区别............................................................................. 30
61、List和Map区别?............................................................................................. 30
62、List, Set, Map是否继承自Collection接口?......................................................... 30
63、List、Map、Set三个接口,存取元素时,各有什么特点?................................. 30
64、说出ArrayList,Vector, LinkedList的存储性能和特性........................................... 31
65、去掉一个Vector集合中重复的元素................................................................... 31
66、Collection和 Collections的区别。..................................................................... 31
67、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别? 31
68、你所知道的集合类都有哪些?主要方法?......................................................... 31
69、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?32
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常!............................................................. 32
71、说出一些常用的类,包,接口,请各举5个...................................................... 33
72、Java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 33
73、字节流与字符流的区别..................................................................................... 33
74、什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。33
75、描述一下JVM加载class文件的原理机制?........................................................ 33
76、heap和stack有什么区别。................................................................................ 34
77、GC是什么?为什么要有GC?.............................................................................. 34
78、垃圾回收的优点和原理。并考虑2种回收机制。............................................... 34
79、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?............................................................................................................................... 34
80、什么时候用assert。.......................................................................................... 34
81、java中会存在内存泄漏吗,请简单描述。......................................................... 35
82、能不能自己写个类,也叫java.lang.String?....................................................... 35
83. Java代码查错.................................................................................................... 35
84、SSH集成方式................................................................................................... 39
二.算法与编程................................................................................................................ 40
1、编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替合并到c.txt文件中,a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格进行分隔。................................................................ 40
2、编写一个程序,将d:\java目录下的所有.java文件复制到d:\jad目录下,并将原来文件的扩展名从.java改为.jad。............................................................................................................................... 40
3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉的半个”。............................................................................................................................... 42
4、有一个字符串,其中包含中文字符、英文字符和数字字符,请统计和打印出各个字符的个数。 42
5、说明生活中遇到的二叉树,用java实现二叉树................................................... 43
6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 44
7、写一个Singleton出来。...................................................................................... 46
8、递归算法题1...................................................................................................... 48
9、递归算法题2...................................................................................................... 48
10、排序都有哪几种方法?请列举。用JAVA实现一个快速排序。.......................... 49
11、有数组a[n],用java代码将数组元素顺序颠倒.................................................. 50
12.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。 51
13 不使用递归遍历二叉树....................................................................................... 51
三. html&JavaScript&ajax部分........................................................................................ 53
1. 判断第二个日期比第一个日期大......................................................................... 53
2. 用table显示n条记录,每3行换一次颜色,即1,2,3用红色字体,4,5,6用绿色字体,7,8,9用红颜色字体。............................................................................................................................... 54
3、HTML的form提交之前如何验证数值文本框的内容全部为数字?否则的话提示用户并终止提交? 54
4、请写出用于校验HTML文本框中输入的内容全部为数字的javascript代码............ 55
5、说说你用过那些ajax技术和框架,说说它们的区别............................................ 55
四. Java web部分............................................................................................................ 55
1、Tomcat的优化经验............................................................................................. 55
2、HTTP请求的GET与POST方式的区别............................................................... 55
3、解释一下什么是servlet;...................................................................................... 56
4、说一说Servlet的生命周期?................................................................................. 56
5、Servlet的基本架构............................................................................................. 56
6、Servlet API中forward()与redirect()的区别?....................................................... 56
7、什么情况下调用doGet()和doPost()?.................................................................. 56
8、Request对象的主要方法:.................................................................................. 56
9、request.getAttribute()和 request.getParameter()有何区别?...................................... 57
10. jsp有哪些内置对象?作用分别是什么?分别有什么方法?..................................... 57
12. jsp生命周期?..................................................................................................... 58
12. jsp有哪些动作?作用分别是什么?........................................................................ 58
13、JSP的常用指令................................................................................................ 58
14. JSP中动态INCLUDE与静态INCLUDE的区别?............................................... 58
15、两种跳转方式分别是什么?有什么区别?............................................................. 58
16、页面间对象传递的方法..................................................................................... 58
17、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么?...................... 58
18、MVC的各个部分都有那些技术来实现?如何实现?............................................. 59
19、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso-8859-1等,如何输出一个某种编码的字符串?............................................................................................................................... 59
20、现在输入n个数字,以逗号分开;然后可选择升或者降序排序;按提交键就在另一页面显示按什么排序,结果为,提供reset................................................................................................................. 59
五.数据库部分................................................................................................................ 59
1、用两种方式根据部门号从高到低,工资从低到高列出每个员工的信息。............. 59
2、列出各个部门中工资高于本部门的平均工资的员工数和部门号,并按部门号排序59
3、存储过程与触发器必须讲,经常被面试到?......................................................... 60
4、数据库三范式是什么?......................................................................................... 61
5、说出一些数据库优化方面的经验?....................................................................... 62
6、union和unionall有什么不同?............................................................................ 63
7.分页语句.............................................................................................................. 63
8.用一条SQL语句查询出每门课都大于80分的学生姓名......................................... 63
9.所有部门之间的比赛组合...................................................................................... 63
10.每个月份的发生额都比101科目多的科目............................................................ 63
11.统计每年每月的信息........................................................................................... 65
12.显示文章标题,发帖人、最后回复时间............................................................... 66
13.删除除了id号不同,其他都相同的学生冗余信息................................................... 66
14.航空网的几个航班查询题:................................................................................ 67
15.查出比经理薪水还高的员工信息:...................................................................... 67
16、求出小于45岁的各个老师所带的大于12岁的学生人数.................................... 67
17.求出发帖最多的人:........................................................................................... 68
18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决?................................................................................... 68
19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他用户。(跟第42条SQL语句同) 68
20. xxx公司的sql面试............................................................................................ 69
21、注册Jdbc驱动程序的三种方式......................................................................... 70
22、用JDBC如何调用存储过程.............................................................................. 70
23、JDBC中的PreparedStatement相比Statement的好处........................................... 71
24、Class.forName的作用?为什么要用?................................................................... 71
25、大数据量下的分页解决方法。.......................................................................... 71
26、用 JDBC查询学生成绩单,把主要代码写出来(考试概率极大)........................ 71
27、这段代码有什么不足之处?................................................................................ 72
28、说出数据连接池的工作机制是什么?.................................................................. 72
29、为什么要用 ORM? 和 JDBC有何不一样?........................................................ 72
30. 数据库大数据处理............................................................................................. 73
31. 存储过程和函数具体的区别:........................................................................... 73
六. XML部分................................................................................................................. 73
1、xml有哪些解析技术?区别是什么?...................................................................... 73
2、你在项目中用到了xml技术的哪些方面?如何实现的?.......................................... 73
3、用jdom解析xml文件时如何解决中文问题?如何解析?........................................ 73
4、编程用JAVA解析XML的方式........................................................................... 74
5、XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式? 76
七.流行的框架与新技术.................................................................................................. 77
1、 谈谈你对Struts的理解。........................................................................... 77
2、谈谈你对Hibernate的理解。.............................................................................. 77
3、AOP的作用。.................................................................................................... 77
4、你对Spring的理解。.......................................................................................... 77
5、谈谈Struts中的ActionServlet。.......................................................................... 78
6、Struts优缺点...................................................................................................... 78
7、STRUTS的应用(如STRUTS架构)...................................................................... 79
8、说说struts1与struts2的区别。............................................................................ 79
9、hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。80
10、简述 Hibernate和 JDBC的优缺点?如何书写一个 one to many配置文件............ 80
11、iBatis与Hibernate有什么不同?.......................................................................... 80
12、写Hibernate的一对多和多对一双向关联的orm配置?........................................ 80
13、在DAO中如何体现DAO设计模式?................................................................. 80
14、spring+Hibernate中委托方案怎么配置?.............................................................. 80
15、spring+Hibernate中委托方案怎么配置?.............................................................. 80
16. hibernate进行多表查询每个表中各取几个字段,也就是说查询出来的结果集没有一个实体类与之对应如何解决;............................................................................................................................... 80
17.介绍一下Hibernate的二级缓存............................................................................ 81
18、Spring的依赖注入是什么意思?给一个 Bean 的 message属性,字符串类型,注入值为"Hello"的XML配置文件该怎么写?...................................................................................................................... 82
19、Jdo是什么?...................................................................................................... 82
20、什么是spring的IOC AOP................................................................................. 82
21、STRUTS的工作流程!..................................................................................... 82
22、spring与EJB的区别!!.................................................................................. 82
八.软件工程与设计模式.................................................................................................. 82
1、UML方面.......................................................................................................... 82
2、j2ee常用的设计模式?说明工厂模式。............................................................... 82
3、开发中都用到了那些设计模式?用在什么场合?.................................................... 83
九. j2ee部分................................................................................................................... 83
1、BS与CS的联系与区别。................................................................................... 83
2、应用服务器与WEB SERVER的区别?............................................................... 84
3、应用服务器有那些?.......................................................................................... 84
4、J2EE是什么?................................................................................................... 84
5、J2EE是技术还是平台还是框架?什么是J2EE.................................................... 84
6、请对以下在J2EE中常用的名词进行解释(或简单描述)........................................ 85
7、如何给weblogic指定大小的内存?....................................................................... 85
8、如何设定的weblogic的热启动模式(开发模式)与产品发布模式?.......................... 85
9、如何启动时不需输入用户名与密码?.................................................................... 85
10、在weblogic管理制台中对一个应用域(或者说是一个网站,Domain)进行jms及ejb或连接池等相关信息进行配置后,实际保存在什么文件中?.......................................................................................... 85
11、说说weblogic中一个Domain的缺省目录结构?比如要将一个简单的helloWorld.jsp放入何目录下,然的在浏览器上就可打入http://主机:端口号//helloword.jsp就可以看到运行结果了?又比如这其中用到了一个自己写的javaBean该如何办?............................................................................................................................... 85
12、在weblogic中发布ejb需涉及到哪些配置文件................................................... 86
13、如何在weblogic中进行ssl配置与客户端的认证配置或说说j2ee(标准)进行ssl的配置? 86
14、如何查看在weblogic中已经发布的EJB?........................................................... 86
十. EJB部分................................................................................................................... 86
1、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别。 86
2、简要讲一下 EJB的 7个 TransactionLevel?........................................................ 86
3、EJB与JAVABEAN的区别?.............................................................................. 86
4、EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的?87
5、EJB容器提供的服务.......................................................................................... 87
6、EJB的激活机制................................................................................................. 87
7、EJB的几种类型................................................................................................. 87
8、客服端调用EJB对象的几个基本步骤................................................................. 87
十一. Web Service部分................................................................................................... 87
1、Web Service名词解释。JWSDL开发包的介绍。JAXP、JAXM的解释。SOAP、UDDI、 WSDL解释。 87
十二. 智力题.................................................................................................................. 88
十三. 其他..................................................................................................................... 92
1、请用英文简单介绍一下自己................................................................................ 92
2、请把http://tomcat.apache.org/ 首页的这一段话用中文翻译一下?.......................... 92
3、美资软件公司JAVA工程师电话面试题目............................................................ 92
思维拓展........................................................................................................................ 93
拓展题1.................................................................................................................. 93
1. Java基础部分
基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io的语法,虚拟机方面的语法。
可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致。
一个文件中可以只有非public类,如果只有一个非public类,此类可以跟文件名不同
java中的保留字,现在没有在java中使用。
&和&&都可以用作逻辑与的运算符,&&为短路与,&不是短路与。
另外&可以做为整数的位运算符
例1:对于if(str!= null&& !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。
例2:If(x==33&++y>0) y会增长,If(x==33&& ++y>0)不会增长
备注:这道题先说两者的共同点,再说出&&和&的特殊之处,并列举一些经典的例子来表明自己理解透彻深入、实际经验丰富。
1. Break+ 标签
2. 使用多个条件判断
3. 使用方法的return
在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break语句,即可跳出外层循环。例如,
ok: for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10;j++) {
System.out.println("i=" + i + ",j=" + j);
if (j == 5)
break ok;
}
}
另外,我个人通常并不使用标号这种方式,而是让外层的循环条件表达式的结果可以受到里层循环体代码的控制,例如,要在二维数组中查找到某个数字。
intarr[][]={{1,2,3},{4,5,6,7},{9}};
boolean found = false;
for(inti=0;i
for(int j=0;j<arr[i].length;j++){
System.out.println("i=" + i + ",j=" + j);
if(arr[i][j] ==5) {
found = true;
break;
}
}
}
第三种,使用方法的return
privatestaticint test() {
int count = 0;
for (int i = 0; i < 10;i++) {
for (int j = 0; j < 10;j++) {
count++;
System.out.println("i=" + i + ",j=" + j);
if (j == 5) {
return count;
}
}
}
return 0;
}
作用在byte, short, char, int, enum
封装类对象,其它基本数据类型及引用数据类型都不能做为case的条件
对于short s1 = 1; s1 = s1 + 1;由于s1+1运算时会自动提升表达式的类型,所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误。
对于short s1 = 1; s1 += 1;由于 +=是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译。
char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字
补充说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。
2<< 3
因为将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,而位运算cpu直接支持的,效率最高,所以,2乘以8等於几的最效率的方法是2<< 3。
如果只是大整数运算,使用BigInteger就可以
如果有浮点数据参与去处,需要使用BigDecimal进行运算
Java中基本类型的浮点数运算是不精确的,需要使用BigDecimal运算,尤其是金融、会计方向的软件
引用变量不能重新赋值,但是引用指向的对象的内容可以变化
例1:finalStringBuffer a=new StringBuffer("immutable");
a=newStringBuffer("");
有编译错
例2:
final StringBuffer a=newStringBuffer("immutable");
a.append(“123”);
正确
他们的区别主要存在在引用数据类型上
==为比较两侧的对象是否同一对象,是用内存地址来比较的
equals是方法,默认是用内存地址比较,重写后,主要是用来比较两侧的对象的值是否相同,和equals方法中的实现有关
==可以两侧都为null,但equals左侧的引用指向的对象不能空,不然有NullPointerException
除非需要比较两个引用指向的对象是同一对象,一般都使用equals方法进行比较。尤其是String之类的值对象,另外,常量尽量放在比较的左侧
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。
总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
不可以。因为非static方法(实例方法)是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用。也就是说,当一个static方法被调用时,可能还没有创建任何实例对象,如果从一个static方法中发出对非static方法的调用,那个非static方法是关联到哪个对象上的呢?这个逻辑无法成立,所以,一个static方法内部发出对非static方法的调用。
int是java提供的8种原始数据类型之一,意思整型,占用4字节。
Integer是java为int提供的封装类,是引用数据类型。
int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况。
例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer
在JSP开发中,Integer的默认为null,所以用el表达式在文本框中显示时,值为空白字符串,而int默认的默认值为0,所以用el表达式在文本框中显示时,结果为0,所以,int不适合作为web层的表单数据的类型。
在Hibernate中,如果将OID定义为Integer类型,那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。
另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。
Math类中提供了三个与取整有关的方法:ceil、floor、round,这些方法的作用与它们的英文名称的含义相对应,例如,ceil的英文意义是天花板,该方法就表示向上取整,Math.ceil(11.3)的结果为12,Math.ceil(-11.3)的结果是-11;floor的英文意义是地板,该方法就表示向下取整,Math.ceil(11.6)的结果为11,Math.ceil(-11.6)的结果是-12;最难掌握的是round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。
1. if(username.equals(“zxx”){}
username可能为NULL,会报空指针错误;改为"zxx".equals(username)
2. int x = 1;
returnx==1?true:false; 这个改成returnx==1;就可以!
这四个作用域的可见范围如下表所示。
说明:如果在修饰的元素上面没有写任何访问修饰符,则表示friendly/default。
作用域 |
当前类 |
同package |
子孙类 |
其他package |
public |
√ |
√ |
√ |
√ |
protected |
√ |
√ |
√ |
× |
friendly |
√ |
√ |
× |
× |
private |
√ |
× |
× |
× |
备注:只要记住了有4种访问权限,4个访问范围,然后将全选和范围在水平和垂直方向上分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。
Overload是重载的意思,Override是覆盖的意思,也就是重写。
Overload和Override有共同之处,两个方法的方法名都必须相同,如果不同,既不构成Overload,也不构成Override。
1. Override必须发生在父子类之间,Overload可以不在父子类之间
2. Override的特点:
a) 参数列表完全相同:个数相同、类型相同、顺序相同
b) 子类的返回值不能比父类的返回值范围大
c) 子类方法抛出的异常不能比父类方法抛出的异常范围大
d) 修饰符只能为public、protected、friendly,不能为private
e) 父子类方法不能使用static修饰
3. 重载发生在同一个类或父子类之间,重写中参数列表至少满足个数不同、类型不同、顺序不同中的一个条件,不包含父子类之间的static方法
构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。
接口可以继承接口;抽象类可以实现(implements)接口;抽象类可以继承具体类;抽象类中可以有静态的main方法;抽象类可有以内部类;接口可以有内部类,但必须是static内部类,但不一定是final的。
只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。
clone 有缺省行为,super.clone();因为首先要把父类中的成员复制到位,然后才是复制自己的成员。
1. 封装,隐藏内部实现,只暴露公共行为
2. 继承,提高代码的重用性
3. 多态,体现现实生活中相似对象的差异性
4. 抽象,抽取现实世界中相似对象的共同点
通过继承父类或实现接口。不同子类或实现类对同一父类方法有不同的实现。根据对象调用相应的实现方法。另外对于相似的方法,可以使用重载。
含有abstract修饰符的class即为抽象类,abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstractclass类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为publicabstract类型,接口中的成员变量类型默认为publicstatic final。
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是publicstatic final类型,并且默认即为publicstatic final类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。
下面接着再说说两者在应用上的区别:
接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约;
而抽象类在代码实现方面发挥作用,可以实现代码的重用。
abstract的method不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系!
native方法表示该方法要用另外一种依赖平台的编程语言实现的,不存在着被子类实现的问题,所以,它也不能是抽象的,不能与abstract混用。
synchronized和abstract合用的问题不能共用,abstract方法只能存在于抽象类或接口中,它不能直接产生对象,而默认synchronized方法对当前对象加锁,没有对象是不能加锁。
另外synchronized不能被继承,子类继承时,需要另加修改符。
内部类就是在一个类的内部定义的类。内部可以定义在除参数位置上的任意位置。印象中有四种方式。
1. 静态内部类需要使用static修饰,而普通内部类不能使用static修饰
2. 静态内部类只能定义在和属性同级,普通内部类可以定义在除参数位置以外的任意位置
3. 静态内部类必需有名称,而普通内部类可以是匿名的
4. 静态内部类没有this引用,只此只能访问外部类的静态成员,而普通内部类可以访问外部类的全部成员
5. 静态内部类访问外部类的同名函数时,使用“外部类名.方法名”即可,而普通内部类需要使用“外部类名.this.外部方法”
6. 静态内部类可以定义静态方法,而普通内部类不能定义静态方法
1. 如果内部类为静态内部类,只能调用外部类的静态成员;如果有重名成员,需要用“外部类名.成员名”访问;不能调用外部类的对象成员。
2. 如果内部类为非静态内部类,则可以调用外部类的所有成员;如果有重名成员,需要使用“外部类名.this.外部方法”
可以继承其他类或实现其他接口。不仅是可以,而是必须!
默认返回的Class对象是同一对象,都是子类的对象。除非子类重写getClass()方法
基本数据类型包括byte、int、char、long、float、double、boolean和short。
String是引用数据类型。
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer/StringBuilder类
没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。
s = s + "world!";相当于: (JDK1.5以上版本)
s = newStringBuilder(String.valueOf(s)).append(" world!").toString();
String类是final类故不可以继承。
两个对象。一个是"xyz",为缓冲区对象。另一个是new出来的String对象。
这两个对象的值相同,但不是同一个对象。
补充,新建对象有几种方式?
1. 使用new关键字
2. 使用反射,调用newInstance
3. 使用clone方法
4. 使用序列化与反序列化
5. 动态代理(Proxy类和CGLIB)
这两个类都实现了CharSequence接口。
1. 类型不同,因为不是一个类,也没有继承关系,做参数时不能共用
2. String对象是不可变对象,不能修改值。而StringBuffer是可变对象,能修改值。
3. 拼接字符串时,String会产生新对象,而StringBuffer只是增加新字符,不产生新对象,因此效率高。
4. String覆盖了equals方法和hashCode方法,而StringBuffer没有覆盖equals方法和hashCode方法,所以,将StringBuffer对象存储进Java集合类中时会出现问题。
如果不查jdk api,我很难写出来!我可以说说我的思路:
1. 用正则表达式,代码大概为:String[] result = orgStr.split(“,”, -1);
2. 用StingTokenizer ,代码为:
StringTokenizer tokener = new StringTokenizer(s, ",");
String[] result = new String[tokener.countTokens()];
Integer i = 0;
while(tokener.hasMoreTokens()) {
result[i++] =tokener.nextToken();
}
3. 最笨的办法,用String.indexOf()
int index = -1;
int oldIndex = 0;
List
while ((index =s.indexOf(',', index + 1)) != -1) {
ss.add(s.substring(oldIndex,index));
oldIndex = index+ 1;
}
if (s.charAt(s.length()- 1) == ',') {
ss.add("");
}
String[] array = ss.toArray(new String[ss.size()]);
System.out.println(Arrays.toString(array));
数组没有length()这个方法,有length的属性。String有有length()这个方法。JS中只有length属性,没有length方法。
答:对于如下代码:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab"); // false
System.out.println(s3 == "ab"); // true
String s = "a" + "b" + "c" + "d";
System.out.println(s == "abcd"); // true s被优化为”abcd”
也许你的答案是在return之前,但往更细地说,我的答案是在return中间执行,请看下面程序代码的运行结果:
publicclass Test {
publicstatic void main(String[]args) {
System.out.println(new Test().test());
}
staticint test() {
int x = 1;
try {
return x;
}
finally {
++x;
}
}
}
---------执行结果 ---------
1
运行结果是1,为什么呢?主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。
publicclass smallT {
publicstaticvoid main(Stringargs[]) {
smallT t = new smallT();
int b = t.get();
System.out.println(b);
}
publicint get() {
try {
return 1;
}
finally {
return 2;
}
}
}
返回的结果是2。
我可以通过下面一个例子程序来帮助我解释这个答案,从下面例子的运行结果中可以发现,try中的return语句调用的函数先于finally中调用的函数执行,也就是说return语句先执行,finally语句后执行,所以,返回的结果是2。Return并不是让函数马上返回,而是return语句执行后,将把返回结果放置进函数栈中,此时函数并不是马上返回,它要执行finally语句后才真正开始返回。
在讲解答案时可以用下面的程序来帮助分析:
publicclass Test {
publicstaticvoid main(String[]args) {
System.out.println(newTest().test());
}
int test() {
try {
return func1();
} finally {
return func2();
}
}
int func1() {
System.out.println("func1");
return 1;
}
int func2() {
System.out.println("func2");
return 2;
}
}
-----------执行结果-----------------
func1
func2
2
结论:finally中的代码比return和break语句后执行
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成final类型
finalint[] number = { 20 };
new Thread() {
@Override
publicvoid run() {
for (int k = 0; k < 20;k++) {
number[0]++;
}
}
}.start();
Thread.sleep(10);
System.out.println(number[0]);
finally是异常处理语句结构的一部分,表示总是执行,用来释放资源。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出,不可能指望程序能处理这样的情况。exception表示一种设计或实现问题,也就是说,它表示如果程序运行正常,从不会发生的情况。
异常是指java程序运行时(非编译)所发生的非正常情况或错误。
Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象中,该对象中包含有异常的信息。
Java可以自定义异常类,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception。
1. Error表示应用程序本身无法克服和恢复的一种严重问题,程序只有退的份了,例如说内存溢出和线程死锁等系统问题。
2. Exception表示程序还能够克服和恢复的问题,其中又分为运行时异常和检查异常,运行时异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉。例如,数组越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);检查异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。
Java为运行时异常和检查异常提供了不同的解决方案,编译器强制检查异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,所以检查异常也称为checked异常,而运行异常可以处理也可以不处理,所以编译器不强制用try..catch处理或用throws声明,所以运行异常也称为Runtime异常。
提示答题者:就按照三个级别去思考:虚拟机必须宕机的错误,程序可以死掉也可以不死掉的错误,程序不应该死掉的错误
NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、IllegelArgumentException、SecurityException。
1. Java语言如何进行异常处理见43题
2. throws为向上抛异常
throw程序出错时,手工抛出异常
try尝试执行,里面的语句可能出现异常,如出现异常需要处理
catch处理try中出现的异常
finally在try后执行清理操作,用于释放资源
3. 在try中可以抛出异常
java5以前,有如下两种:
第一种:
newThread(){}.start();这表示调用Thread子类对象的run方法,new Thread(){}表示一个Thread的匿名子类的实例对象,子类加上run方法后的代码如下:
new Thread() {
publicvoid run() {
}
}.start();
第二种:
newThread(new Runnable(){}).start();这表示调用Thread对象接受的Runnable对象的run方法,new Runnable(){}表示一个Runnable的匿名子类的实例对象,runnable的子类加上run方法后的代码如下:
new Thread(new Runnable() {
publicvoid run() {
}
}).start();
从Java5开始,还有如下一些线程池创建多线程的方式:
ExecutorService pool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10;i++) {
pool.execute(new Runable() {
publicvoid run() {
}
});
}
Executors.newCachedThreadPool().execute(new Runable() {
publicvoid run() {
}
});
Executors.newSingleThreadExecutor().execute(new Runable() {
publicvoid run() {
}
});
有两种实现方法,分别使用new Thread()和new Thread(runnable)形式,第一种直接调用thread的run方法,所以,我们往往使用Thread子类,即new SubThread()。第二种调用runnable的run方法。
1. 有两种实现方法,分别是继承Thread类与实现Runnable接口。可以的话使用线程池
2. 用synchronized关键字修饰同步方法
3. 反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
(网上的答案:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。)
sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。对于wait的讲解一定要配合例子代码来说明,才显得自己真明白。
packagecom.huawei.interview;
publicclass MultiThread {
publicstaticvoid main(String[]args) {
newThread(newThread1()).start();
try {
Thread.sleep(10);
} catch(InterruptedException e) {
e.printStackTrace();
}
newThread(newThread2()).start();
}
privatestaticclass Thread1 implements Runnable {
@Override
publicvoid run() {
// 由于这里的Thread1和下面的Thread2内部run方法要用同一对象作为监视器,我们这里不能用this,因为在Thread2里面的this和这个Thread1的this不是同一个对象。我们用MultiThread.class这个字节码对象,当前虚拟机里引用这个变量时,指向的都是同一个对象。
synchronized(MultiThread.class) {
System.out.println("enterthread1...");
System.out.println("thread1is waiting");
try {
// 释放锁有两种方式,第一种方式是程序自然离开监视器的范围,也就是离开了synchronized关键字管辖的代码范围,另一种方式就是在synchronized关键字管辖的代码内部调用监视器对象的wait方法。这里,使用wait方法释放锁。
MultiThread.class.wait();
} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
System.out.println("thread1is going on...");
System.out.println("thread1is being over!");
}
}
}
privatestaticclass Thread2 implements Runnable {
@Override
publicvoid run() {
synchronized(MultiThread.class) {
System.out.println("enterthread2...");
System.out.println("thread2notify other thread can release waitstatus..");
// 由于notify方法并不释放锁,即使thread2调用下面的sleep方法休息了10毫秒,但thread1仍然不会执行,因为thread2没有释放锁,所以Thread1无法得不到锁。
MultiThread.class.notify();
System.out.println("thread2is sleeping ten millisecond...");
try {
Thread.sleep(10);
} catch (InterruptedExceptione) {
e.printStackTrace();
}
System.out.println("thread2is going on...");
System.out.println("thread2is being over!");
}
}
}
}
同步是指所有操作串行化执行,顺序不能改变,前一操作未完成,后个操作不执行。
异步是指所有操作可以并行执行,顺序无关。
例如寄信
同步:如果没有寄完,不能吃饭,邮递员10天后送到,发送人被饿死
异步:寄出后可以立即吃饭,邮递员送完后,通知发送人送信结果。
如果强调执行顺序的话,用同步。如果顺序无关,则可以用异步。
异步执行效率比同步高。
class Test {
synchronizedstaticvoid sayHello3() {
}
synchronizedvoid getX() {
}
}
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有五种,分别是synchronized、wait与notify、sleep、suspend、join
synchronized:一直持有锁,直至执行结束
wait():使一个线程处于等待状态,并且释放所持有的对象的lock,需捕获异常。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,需捕获异常,不释放锁。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
启动一个线程是调用start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。
如果其它方法中使用当前对象作为锁对象,则不能;
如果其它方法中没有使用当前对象作为锁对象,则能。
在多任务操作系统中,为了提高CPU的利用率,可以使用多进程编程。但对进程通信比较困难,进程间数据不能共享,因此可以使用多线程编程。一个进程至少包含一个主入口线程。
单个CPU,在同一时间只能处理一个线程的数据,但是操作系统的任务调度非常快,人眼无法识别,感觉上是多个线程同时执行。有的线程可以已经用完CPU,正在作磁盘操作,此时并不使用CPU,可以让出CPU资源给其它线程使用,提高效率。
线程有生命周期及相关关系和对应方法如下图:
主要相同点:Lock能完成synchronized所实现的所有功能
主要不同点:
1. 更好的语义
2. 更高性能
3. Synchronized自动释放锁,Lock手动释放
4. 功能强大,可以用tryLock方法可以非阻塞方式去拿锁
线Lock有比synchronized更精确的程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。
举例说明(对下面的题用lock进行了改写):
package com.huawei.interview;
importjava.util.concurrent.locks.Lock;
importjava.util.concurrent.locks.ReentrantLock;
publicclass ThreadTest {
privateintj;
private Lock lock = newReentrantLock();
publicstaticvoid main(String[]args) {
ThreadTest tt = new ThreadTest();
for (int i = 0; i < 2;i++) {
new Thread(tt.new Adder()).start();
new Thread(tt.newSubtractor()).start();
}
}
privateclass Subtractor implements Runnable {
@Override
publicvoid run() {
while (true) {
lock.lock();
try {
System.out.println("j--=" + j--);
} finally {
lock.unlock();
}
}
}
}
privateclass Adder implements Runnable {
@Override
publicvoid run() {
while (true) {
lock.lock();
try {
System.out.println("j++=" + j++);
} finally {
lock.unlock();
}
}
}
}
}
以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。
publicclass ThreadTest1 {
privateintj;
publicstaticvoid main(Stringargs[]) {
ThreadTest1tt = new ThreadTest1();
Inc inc = tt.new Inc();
Dec dec = tt.new Dec();
for (inti = 0; i <2; i++) {
Thread t= new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
}
}
privatesynchronizedvoid inc() {
j++;
System.out.println(Thread.currentThread().getName()+ "-inc:" + j);
}
privatesynchronizedvoid dec() {
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
class Inc implements Runnable {
publicvoid run() {
for (inti = 0; i <100; i++) {
inc();
}
}
}
class Dec implements Runnable {
publicvoid run() {
for (inti = 0; i <100; i++) {
dec();
}
}
}
}
----------随手再写的一个-------------
class A {
JManger j = new JManager();
publicstaticvoid main(String[]args) {
new A().call();
}
void call() {
for (int i = 0; i < 2;i++) {
new Thread(new Runnable() {
publicvoid run() {
while (true) {
j.accumulate();
}
}
}).start();
new Thread(new Runnable() {
publicvoid run() {
while (true) {
j.sub();
}
}
}).start();
}
}
}
class JManager {
privateintj = 0;
publicsynchronizedvoid subtract()
{
j--
}
publicsynchronizedvoid accumulate() {
j++;
}
}
最终的程序代码如下:
publicclass ThreadTest {
publicstaticvoid main(String[]args) {
newThreadTest().init();
}
publicvoid init() {
final Business business= new Business();
new Thread(new Runnable() {
publicvoid run() {
for (int i = 0; i < 50;i++) {
business.SubThread(i);
}
}
}).start();
for (int i = 0; i < 50;i++) {
business.MainThread(i);
}
}
privateclass Business {
booleanbShouldSub = true;// 这里相当于定义了控制该谁执行的一个信号灯
publicsynchronizedvoid MainThread(int i) {
if (bShouldSub)
try {
this.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
for (int j = 0; j < 5;j++) {
System.out.println(Thread.currentThread().getName()+ ":i=" + i + ",j=" + j);
}
bShouldSub = true;
this.notify();
}
publicsynchronizedvoid SubThread(int i) {
if (!bShouldSub)
try {
this.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
for (int j = 0; j < 10;j++) {
System.out.println(Thread.currentThread().getName()+ ":i=" + i + ",j=" + j);
}
bShouldSub = false;
this.notify();
}
}
}
备注:不可能一上来就写出上面的完整代码,最初写出来的代码如下,问题在于两个线程的代码要参照同一个变量,即这两个线程的代码要共享数据,所以,把这两个线程的执行代码搬到同一个类中去:
packagecom.huawei.interview.lym;
publicclass ThreadTest {
privatestaticbooleanbShouldMain = false;
publicstaticvoid main(String[]args) {
new Thread(new Runnable() {
publicvoid run() {
for (int i = 0; i < 50;i++) {
synchronized(ThreadTest.class) {
if (bShouldMain) {
try {
ThreadTest.class.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 10;j++) {
System.out.println(Thread.currentThread().getName()+ "i=" + i + ",j=" + j);
}
bShouldMain = true;
ThreadTest.class.notify();
}
}
}
}).start();
for (int i = 0; i < 50;i++) {
synchronized(ThreadTest.class) {
if (!bShouldMain) {
try {
ThreadTest.class.wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 5; j++) {
System.out.println(Thread.currentThread().getName()+ "i=" + i + ",j=" + j);
}
bShouldMain = false;
ThreadTest.class.notify();
}
}
}
}
下面使用jdk5中的并发库来实现的:
import java.util.concurrent.Executors;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.locks.Lock;
importjava.util.concurrent.locks.ReentrantLock;
importjava.util.concurrent.locks.Condition;
publicclass ThreadTest {
privatestatic Lock lock = new ReentrantLock();
privatestatic Condition subThreadCondition = lock.newCondition();
privatestaticbooleanbBhouldSubThread = false;
publicstaticvoid main(String[]args) {
ExecutorService threadPool = Executors.newFixedThreadPool(3);
threadPool.execute(new Runnable() {
publicvoid run() {
for (int i = 0; i < 50;i++) {
lock.lock();
try {
if (!bBhouldSubThread)
subThreadCondition.await();
for (int j = 0; j < 10;j++) {
System.out.println(Thread.currentThread().getName()+ ",j=" + j);
}
bBhouldSubThread = false;
subThreadCondition.signal();
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}
});
threadPool.shutdown();
for (int i = 0; i < 50;i++) {
lock.lock();
try {
if (bBhouldSubThread)
subThreadCondition.await();
for (int j = 0; j < 10;j++) {
System.out.println(Thread.currentThread().getName()+ ",j=" + j);
}
bBhouldSubThread = true;
subThreadCondition.signal();
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}
}
Iterable
->Collection
->List
->ArrayList
->LinkedList
->Vector
->Stack
->Set
->HashSet
->TreeSet
Map
->Hashtable
->HashMap
->LinkedHashMap
Collections,不属于集合,是集合类的工具类
Arrays,不属于集合类,是数据对象的工具类
Comparable/Comparator
1. 线程同步,Vector线程安全,ArrayList线程不安全
2. 效率问题,Vector效率低,ArrayList效率高
3. 增长数量,Vector以1.5倍增长,ArrayList以2倍增长
1. 线程同步,Hashtable线程安全,HashMap线程不安全
2. 效率问题,Hashtable效率低,HashMap效率高
3. HashMap可以使用null作为key,Hashtable不可以使用null为key
4. HashMap使用的是新实现,继承AbstractMap,而Hashtable是继承Dictionary类,实现比较老
5. Hash算不同,HashMap的hash算法比Hashtable的hash算法效率高
6. HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey。因为contains方法容易让人引起误解。
7. 取值不同,HashMap用的是Iterator接口,而Hashtable中还有使用Enumeration接口
一个是存储单列数据的集合,另一个是存储键和值的双列数据的集合,List中存储的数据是有顺序,并且允许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。
1. List有重复值,Map没有重复key,但可以有重复值
2. List有序,Map不一定有序
3. List只能存单列值,Map可以存双列值
List,Set是,Map不是
List使用get(index)取值,也可以使用Iterator、toArray取值
Set只能通过Iterator、toArray取值
Map取值使用get(key)取值,也可以使用keySet取键值集合,也可使用values取值集合,entrySet取全部映射。
1. ArrayList和Vector使用数组存储元素;LinkedList使用链表存储元素
2. ArrayList和Vector插入删除数据时,需要搬运数据,效率较差;LinkedList使用链表,不需要搬运数据,效率高
3. ArrayList和Vectory查询时,按数组下标查询,不需要遍历,效率高;LinkedList需要遍历,查询效率底
4. ArrayList和Vector的区别见59条
1. 自行遍历,用另外一个Vector来判断是否有重复
2. 用Set(TreeSet或HashSet)来去重
3. 用Apache的CollectionUtil工具类去重
Vector newVector = new Vector();
for (int i = 0; i
Object obj =vector.get(i);
if(!newVector.contains(obj))
newVector.add(obj);
}
还有一种简单的方式,HashSet set = new HashSet(vector);
Collection是集合类的上级接口,继承与他的接口主要有Set和List.
Collections是针对集合类的一个工具类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
Set里的元素是不能重复的,元素重复与否视具体情况而定:
1.HashSet使用equals比较
2. TreeSet使用compareTo进行比较
最常用的集合类接口是List 和 Map。
List的具体实现包括ArrayList、Vector、LinkedList,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。List适用于按数值索引访问元素的情形。
Set的具体实现包括HashSet和TreeSet,它们也是可变大小集合,但不适合用索引取值。
Map 提供了一个更通用的元素存储方法。Map集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。
ArrayList/Vector、LinkedList
HashSet/TreeSetàSet
Properties/HashTable/TreeMap/HashMap
List的主要方法有:
add、get、remove、set、iterator、contains、addAll、removeAll、indexOf、toArray、clear、isEmpty
Set的主要方法有:
add、remove、iterator、contains、addAll、removeAll、toArray、clear、isEmpty
Map的主要方法有:
put、get、keySet、values、entrySet、clear、remove、isEmpty
1. equals等,hashCode同,因此重写equals方法必须重写hashCode
2. hashCode等,equals不一定同,但hashCode最好散列化
3. 任何对象equals null都得false
4. 没有继承关系的两个类,equals都得false
5. 重写equals方法的类最好是值类,即不可变
(应该是没有针对问题的确切的答案,当前的add方法放入的是哪个对象,就调用哪个对象的compareTo方法,至于这个compareTo方法怎么做,就看当前这个对象的类中是如何编写这个方法的)
实验代码:
publicclass Parent implements Comparable {
privateintage = 0;
public Parent(int age) {
this.age = age;
}
publicint compareTo(Objecto) {
System.out.println("methodofparent");
Parent o1 = (Parent) o;
returnage > o1.age ? 1 : age < o1.age ? -1 : 0;
}
}
publicclass Child extends Parent {
public Child() {
super(3);
}
publicint compareTo(Objecto) {
System.out.println("methodofchild");
// Child o1 = (Child)o;
return 1;
}
}
publicclass TreeSetTest {
publicstatic void main(String[]args) {
TreeSet set = new TreeSet();
set.add(newParent(3));
set.add(new Child());
set.add(newParent(4));
System.out.println(set.size());
}
}
要让人家感觉你对java ee开发很熟,所以,不能仅仅只列core java中的那些东西,要多列你在做ssh项目中涉及的那些东西。就写你最近写的那些程序中涉及的那些类。
常用的类:BufferedReader,BufferedWriter,FileReader,FileWirter,String,Integer,
java.util.Date,System,Class,List,HashMap
常用的包:java.lang,java.io,java.util,java.sql,javax.servlet,org.apache.strtuts.action,org.hibernate
常用的接口: List,Map,Document,NodeList,Servlet,HttpServletRequest,HttpServletResponse,Transaction(Hibernate) ,Session(Hibernate),HttpSession
字节流,字符流。字节流继承于InputStream、OutputStream,字符流继承于Reader、Writer。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便。
FileInputStream、FileReader、BufferedInputStream、BufferedReader、ZipInputStream、PrintStream、StringReader、ObjectInputStream、RandomAccessFile(不属于流,但像流)
字节流是按字节读取或写入设备,但字符流是以字符为单位读取或写入设备。
如果是二进制文件,需要用字节流读取。一般来说,字符流只处理文本文件。在设备中,大多数情况是以字节形式存储数据的,因此字符流通过需要传入字节流当参数。
序列化是把内存Java对象保存到存储介质中,反序列化就是把存储介质中的数据转化为Java对象。Java通过ObjectInputStream和ObjectOutputStream实现序列化和反序列化。需要进行序列化的对象的类必须实现Serializable接口,通常情况下需要满足以下条件:
1. 强烈建议手动生成serialVersionUID常量
2. 如果需要加解密的话,需要实现两个方法readObject和writeObject方法
3. 如果使用Hibernate二级缓存或其它缓存服务器的话,对象必须是可序列化的
4. 如果需要远程调用对象或传值的话,则对像需要序列化
5. 序列化类的可序列化成员必须也是可序列化的,不需要序列化的属性用transient修饰
1. 查找当前ClassLoader中是否有此class的类对象,有则返回
2. 若没有的话,向上递归所有的父ClassLoader中有无此class类对象,有则返回
3. 若还没有,查找BootstrapClassLoader中有无此class类对象,有则返回
4. 若还没有的话,使用findClass或resolveClass加载类对象
a. 读取class二进制文件
b. 根据字节数组生成Class对象
c. 缓存到当前ClassLoader中
JVM加载class对象是懒加载,按需加载
Java的内存分为两类,一类是栈内存,一类是堆内存。
栈中存储的是当前线程的方法调用、基本数据类型和对象的引用,栈是有序的。
堆中存储的是对象的值,堆是无序的。
方法中的局部变量使用final修饰后,放在堆中,而不是栈中。
GC是垃圾回收的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。线程对象在没有终止前,即使没有任何引用,也不会被垃圾回收。
只能建议JVM回收内存,不能强制,可以使用System.gc()建议执行。
GC有三种方式,串行回收、并行回收、混合回收。
Java语言中一个显著的特点就是引入了垃圾回收机制,使C++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,更有效的使用内存。垃圾回收器通常是作为一个单独的低级别的线程运行,对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
1. 按时间轮询,把没有引用的对象进行回收
2. 按内存的使用量超不超过报警值进行回收
3. 按CPU空闲时间进行回收
4. 程序建议JVM进行垃圾回收
GC有三种方式,串行回收、并行回收、混合回收。
对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。
assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,assert将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。
会,原因:
如果对象被集合类引用时,如果只是添加,而不删除,会引起内存泄漏,严重时会发出内存溢出。
Java中的内存泄露的情况:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露
内存泄露的另外一种情况:当一个对象被存储进HashSet或HashMap中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露。
可以,如果非要实现java.lang.String,需要自已写ClassLoader,不然JVM优先加载默认rt.jar中的java.lang.String。
可以,但在应用的时候,需要用自己的类加载器去加载,否则,系统的类加载器永远只是去加载rt.jar包中的那个java.lang.String。由于在tomcat的web应用程序中,都是由webapp自己的类加载器先自己加载WEB-INF/classess目录中的类,然后才委托上级的类加载器加载,如果我们在tomcat的web应用程序中写一个java.lang.String,这时候Servlet程序加载的就是我们自己写的java.lang.String,但是这么干就会出很多潜在的问题,原来所有用了java.lang.String类的都将出现问题。
虽然java提供了endorsed技术,可以覆盖jdk中的某些类,但是,能够被覆盖的类是有限制范围,反正不包括java.lang这样的包中的类。
(下面的例如主要是便于大家学习理解只用,不要作为答案的一部分,否则,人家怀疑是题目泄露了)例如,运行下面的程序:
package java.lang;
publicclass String {
publicstaticvoid main(String[]args) {
System.out.println("string");
}
}
报告的错误如下:
java.lang.NoSuchMethodError:main
Exception inthread"main"
这是因为加载了jre自带的java.lang.String,而该类中没有main方法。
1.
abstractclass Name {
private String name;
publicabstractbooleanisStupidName(String name) {}
}
大侠们,这有何错误?
答案: 错。abstract method必须以分号结尾,且不带花括号。
2.
publicclass Something {
void doSomething() {
private String s = "";
int l = s.length();
}
}
有错吗?
答案: 错。局部变量前不能放置任何访问修饰符 (private,public,和protected)。final可以用来修饰局部变量
(final如同abstract和strictfp,都是非访问修饰符,strictfp只能修饰class和method而非variable)。
3.
abstractclass Something {
privateabstract StringdoSomething();
}
这好像没什么错吧?
答案: 错。abstract的methods不能以private修饰。abstract的methods就是让子类implement(实现)具体细节的,怎么可以用private把abstract
method封锁起来呢? (同理,abstract method前不能加final)。
4.
publicclass Something {
publicint addOne(finalint x) {
return ++x;
}
}
这个比较明显。
答案: 错。int x被修饰成final,意味着x不能在addOne method中被修改。
5.
publicclass Something {
publicstaticvoid main(String[]args) {
Other o = new Other();
newSomething().addOne(o);
}
publicvoid addOne(final Other o) {
o.i++;
}
}
class Other {
publicinti;
}
和上面的很相似,都是关于final的问题,这有错吗?
答案: 正确。在addOne method中,参数o被修饰成final。如果在addOne method里我们修改了o的reference
(比如: o = new Other();),那么如同上例这题也是错的。但这里修改的是o的member vairable
(成员变量),而o的reference并没有改变。
6.
class Something {
inti;
publicvoid doSomething() {
System.out.println("i = " + i);
}
}
有什么错呢? 看不出来啊。
答案: 正确。输出的是"i = 0"。int i属於instant variable (实例变量,或叫成员变量)。instant variable有default value。int的default value是0。
7.
class Something {
finalinti;
publicvoid doSomething() {
System.out.println("i = " + i);
}
}
和上面一题只有一个地方不同,就是多了一个final。这难道就错了吗?
答案: 错。final int i是个final的instant variable (实例变量,或叫成员变量)。final的instant variable没有default value,必须在constructor (构造器)结束之前被赋予一个明确的值。可以修改为"final int i =0;"。
8.
publicclass Something {
publicstaticvoid main(String[]args) {
Something s =new Something();
System.out.println("s.doSomething() returns " + doSomething());
}
public StringdoSomething() {
return"Do something ...";
}
}
看上去很完美。
答案: 错。看上去在main里call doSomething没有什么问题,毕竟两个methods都在同一个class里。但仔细看,main是static的。static method不能直接call non-staticmethods。可改成"System.out.println("s.doSomething()returns" + s.doSomething());"。同理,static method不能访问non-static instant variable。
9.
此处,Something类的文件名叫OtherThing.java
class Something {
privatestaticvoid main(String[]something_to_do) {
System.out.println("Dosomething ...");
}
}
这个好像很明显。
答案: 正确。从来没有人说过Java的Class名字必须和其文件名相同。但public class的名字必须和文件名相同。
10.
interface A {
intx = 0;
}
class B {
intx = 1;
}
class C extends B implements A {
publicvoid pX() {
System.out.println(x);
}
publicstaticvoid main(String[]args) {
new C().pX();
}
}
答案:错误。在编译时会发生错误(错误描述不同的JVM有不同的信息,意思就是未明确的x调用,两个x都匹配(就象在同时import java.util和java.sql两个包时直接声明Date一样)。对于父类的变量,可以用super.x来明确,而接口的属性默认隐含为 public staticfinal.所以可以通过A.x来明确。
11.
interface Playable {
void play();
}
interface Bounceable{
void play();
}
interface Rollable extends Playable,Bounceable {
Ball ball = new Ball("PingPang");
}
class Ball implements Rollable {
private String name;
public String getName() {
returnname;
}
public Ball(String name){
this.name = name;
}
publicvoid play() {
ball = new Ball("Football");
System.out.println(ball.getName());
}
}
这个错误不容易发现。
答案: 错。"interfaceRollableextends Playable, Bounceable"没有问题。interface可继承多个interfaces,所以这里没错。问题出在interface Rollable里的"Ball ball =new Ball("PingPang");"。任何在interface里声明的interface variable (接口变量,也可称成员变量),默认为public static final。也就是说"Ball ball = new Ball("PingPang");"实际上是"public staticfinal Ball ball = newBall("PingPang");"。在Ball类的Play()方法中,"ball =newBall("Football");"改变了ball的reference,而这里的ball来自Rollable interface,Rollable interface里的ball是public static final的,final的object是不能被改变reference的。因此编译器将在"ball =newBall("Football");"这里显示有错。
1. 在web.xml中配置struts的servlet或filter入口类,同时在web.xml中配置spring的listener和配置文件路径
2. 引用SSH所需的jar包放在WEB-INF/lib下,需要有struts-spring-plugin.jar
3. 在struts.xml配置中,把Struts的Action类交由Spring托管
4. 把Hibernate所需的DataSource,SessionFactory, Transcation, HibernateTemplate配置在Spring的配置文件中
5. Dao层的类有时需要继承HiberateDaoSupport类,如果有HibernateTemplate时,可以不继承
6. 把Action、Service、Dao等类注册到Spring中管理
答:
packagecom.bwie.interview;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintStream;
importjava.util.StringTokenizer;
publicclass AnswerB01 {
publicstaticvoid main(String[]args) throws IOException {
StringTokenizertokenizer1 = getTokenzer("/a.txt");
StringTokenizertokenizer2 = getTokenzer("/b.txt");
PrintStreamout = new PrintStream("C:/c.txt");
while(tokenizer1.hasMoreTokens() && tokenizer2.hasMoreTokens()) {
out.println(tokenizer1.nextToken());
out.println(tokenizer2.nextToken());
}
out.close();
}
privatestatic StringTokenizergetTokenzer(String fileName) throws IOException {
InputStreamReaderreader = new InputStreamReader(AnswerB01.class.getResourceAsStream(fileName));
StringBuilderbuilder = new StringBuilder(1000);
int length = -1;
char[] cs = newchar[1024];
while ((length =reader.read(cs)) != -1) {
builder.append(cs,0, length);
}
reader.close();
returnnewStringTokenizer(builder.toString());
}
}
(大家正在做上面这道题,网上迟到的朋友也请做做这道题,找工作必须能编写这些简单问题的代码!)
答:listFiles方法接受一个FileFilter对象,这个FileFilter对象就是过虑的策略对象,不同的人提供不同的FileFilter实现,即提供了不同的过滤策略。
import java.io.File;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.FilenameFilter;
importjava.io.IOException;
publicclass AnswerB02 {
publicstaticvoid main(String[]args) throws IOException {
File sourceFolder = new File("D:/java");
File[] files = sourceFolder.listFiles(new JavaFileFilter());
for (File file :files) {
String absolutePath = file.getName();
String targetFile = "D:/jad/" +absolutePath.substring(0, absolutePath.length() - 5) + ".jad";
copy(file, new File(targetFile));
}
}
privatestaticvoid copy(File source,File target) throws IOException {
FileInputStream input = newFileInputStream(source);
FileOutputStream out = newFileOutputStream(target);
int length = -1;
byte[] bs = newbyte[1024];
while ((length =input.read(bs)) != -1) {
out.write(bs, 0, length);
}
input.close();
out.close();
}
privatestaticfinalclass JavaFileFilter implements FilenameFilter {
@Override
publicboolean accept(File dir,String name) {
return name.endsWith(".java");
}
}
}
importjava.io.IOException;
publicclass AnswerB03 {
publicstaticvoid main(String[]args) throws IOException {
String s = "我ABC汉DEF";
System.out.println(substring(s,6));
}
publicstatic Stringsubstring(String s, int length) {
char[] cs =s.toCharArray();
StringBuilder builder = new StringBuilder();
int count = 0;
for (char c : cs) {
if (isAsc(c)) {
count++;
} else {
count += 2;
}
if (count > length) {
break;
}
builder.append(c);
}
returnbuilder.toString();
}
publicstaticboolean isAsc(char c) {
return c < 128;
}
}
答:哈哈,其实包含中文字符、英文字符、数字字符原来是出题者放的烟雾弹。
String content = "中国aadf的111萨bbb菲的zz萨菲";
HashMap map = new HashMap();
for (int i = 0; i
char c =content.charAt(i);
Integer num =map.get(c);
if (num == null)
num = 1;
else
num = num +1;
map.put(c, num);
}
for (Map.EntrySetentry : map) {
system.out.println(entry.getkey()+ ":" + entry.getValue());
}
估计是当初面试的那个学员表述不清楚,问题很可能是:
如果一串字符如"aaaabbc中国1512"要分别统计英文字符的数量,中文字符的数量,和数字字符的数量,假设字符中没有中文字符、英文字符、数字字符之外的其他特殊字符。
int engishCount;
int chineseCount;
int digitCount;
for (int i = 0; i
char ch =str.charAt(i);
if (ch >= '0' && ch<= '9') {
digitCount++;
} elseif ((ch >= 'a' && ch<= 'z') || (ch >= 'A' && ch <= 'Z')) {
engishCount++;
} else {
chineseCount++;
}
}
这是组合设计模式。
我有很多个(假设10万个)数据要保存起来,以后还需要从保存的这些数据中检索是否存在某个数据,(我想说出二叉树的好处,该怎么说呢?那就是说别人的缺点),假如存在数组中,那么,碰巧要找的数字位于99999那个地方,那查找的速度将很慢,因为要从第1个依次往后取,取出来后进行比较。平衡二叉树(构建平衡二叉树需要先排序,我们这里就不作考虑了)可以很好地解决这个问题,但二叉树的遍历(前序,中序,后序)效率要比数组低很多,原理如下图:
代码如下:
publicclass AnswerB04 {
publicstaticvoid main(String[]args) {
Node root = makeupTree();
traverse(root);
}
privatestaticvoid traverse(Nodenode) {
if (node == null) {
return;
}
traverse(node.left);
System.out.println(node.value);
traverse(node.right);
}
privatestatic Node makeupTree(){
Node root = new Node(0);
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node11 = new Node(11);
Node node12 = new Node(12);
Node node21 = new Node(21);
Node node22 = new Node(22);
root.left = node1;
root.right = node2;
node1.left = node11;
node1.right = node12;
node2.left = node21;
node2.right = node22;
return root;
}
publicstaticclass Node {
public Node left;
public Node right;
publicintvalue;
public Node(int value) {
this.value = value;
}
}
}
1,张三,28
2,李四,35
3,张三,28
4,王五,35
5,张三,28
6,李四,35
7,赵六,28
8,田七,35
importjava.io.BufferedReader;
import java.io.IOException;
importjava.io.InputStreamReader;
importjava.util.ArrayList;
importjava.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
publicclass AnswerB06 {
publicstaticvoid main(String[]args) throws IOException {
Map
BufferedReader reader = new BufferedReader(newInputStreamReader(AnswerB06.class.getResourceAsStream("/person.txt")));
String line = null;
while ((line =reader.readLine()) != null) {
String[] segments = line.split(",", -1);
String name = segments[1];
Integer count = nameMap.get(name);
if (count == null) {
count = 0;
}
count++;
nameMap.put(name, count);
}
reader.close();
List
Set
for (String name :names) {
PersonCount personCount = new PersonCount();
personCount.name = name;
personCount.count =nameMap.get(name);
personCounts.add(personCount);
}
Collections.sort(personCounts);
for (PersonCountpersonCount : personCounts) {
System.out.println(personCount.name + "=" + personCount.count);
}
}
staticclass PersonCount implementsComparable
public String name;
publicintcount;
@Override
publicintcompareTo(PersonCount o) {
returncount - o.count;
}
}
}
第一种:饱汉模式
publicclass SingleTon {
private SingleTon() {
}
// 实例化放在静态代码块里可提高程序的执行效率,但也可能更占用空间
privatefinalstatic SingleTon instance = new SingleTon();
publicstatic SingleTongetInstance() {
returninstance;
}
}
第二种:饥汉模式
publicclass SingleTon {
private SingleTon() {
}
privatestatic SingleTon instance = null;
publicstaticsynchronized SingleTongetInstance() {
if (instance == null)
instance = new SingleTon();
returninstance;
}
}
第三种:用枚举
publicenum SingleTon {
ONE;
}
第三:更实际的应用(在什么情况用单例)
publicclass SequenceGenerator{
// 下面是该类自身的业务功能代码
privateintcount = 0;
publicsynchronizedint getSequence() {
++count;
}
// 下面是把该类变成单例的代码
privateSequenceGenerator() {
}
privatefinalstatic SingleTon instance = newSequenceGenerator();
publicstatic SingleTongetInstance() {
returninstance;
}
}
第四:
publicclass MemoryDao {
private HashMap map = new HashMap();
publicvoidadd(Student stu1) {
map.put(SequenceGenerator.getInstance().getSequence(),stu1);
}
// 把MemoryDao变成单例
}
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
一般Singleton模式通常有几种种形式:
第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。
publicclass Singleton {
private Singleton() {
}
// 在自己内部定义自己一个实例,是不是很奇怪?
// 注意这是private只供内部调用
privatestatic Singleton instance = new Singleton();
// 这里提供了一个供外部访问本class的静态方法,可以直接访问
publicstatic SingletongetInstance() {
returninstance;
}
}
第二种形式:
publicclass Singleton {
privatestatic Singleton instance = null;
publicstaticsynchronized SingletongetInstance() {
// 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
// 使用时生成实例,提高了效率!
if (instance == null)
instance = new Singleton();
returninstance;
}
}
其他形式:
定义一个类,它的构造函数为private的,所有方法为static的。
一般认为第一种形式要更加安全些
一个整数,大于0,不用循环和本地变量,按照n,2n,4n,8n的顺序递增,当值大于5000时,把值按照指定顺序输出来。
例:n=1237
则输出为:
1237,
2474,
4948,
9896,
9896,
4948,
2474,
1237,
提示:写程序时,先致谢按递增方式的代码,写好递增的以后,再增加考虑递减部分。
publicstaticvoid doubleNum(int n) {
System.out.println(n);
if (n <= 5000)
doubleNum(n* 2);
System.out.println(n);
}
Gaibaota(N) = Gaibaota(N-1) + n
第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?
package cn.itcast;
import java.util.Date;
publicclass A1 {
publicstaticvoid main(String[]args) {
System.out.println(computeAge(8));
}
publicstaticint computeAge(int n) {
if (n == 1)
return 10;
return computeAge(n- 1) + 2;
}
}
publicstaticvoid toBinary(int n, StringBufferresult) {
if (n / 2 != 0)
toBinary(n / 2, result);
result.append(n % 2);
}
本人只研究过冒泡排序、选择排序和快速排序,下面是快速排序的代码:
冒泡排序:
privatestaticvoid bubbleSort(int[] array) {
for (int i = 1; i
for (int j = 0; j < i;j++) {
if (array[i]
int temp = array[i];
array[i]= array[j];
array[j]= temp;
}
}
}
}
快速排序:
publicclass QuickSort {
publicvoid quickSort(String[]strDate, int left, int right) {
String middle, tempDate;
int i, j;
i = left;
j = right;
middle = strDate[(i + j) / 2];
do {
while(strDate[i].compareTo(middle) < 0 && i < right)
i++; // 找出左边比中间值大的数
while(strDate[j].compareTo(middle) > 0 && j > left)
j--; // 找出右边比中间值小的数
if (i <= j) { // 将左边大的数和右边小的数进行替换
tempDate = strDate[i];
strDate[i] = strDate[j];
strDate[j] = tempDate;
i++;
j--;
}
} while (i <= j); // 当两者交错时停止
if (i < right) {
quickSort(strDate, i, right);
}
if (j > left) {
quickSort(strDate, left, j);
}
}
publicstaticvoid main(String[]args) {
String[] strVoid = new String[] { "11", "66", "22", "0", "55", "22", "0", "32" };
QuickSort sort = new QuickSort();
sort.quickSort(strVoid, 0, strVoid.length - 1);
for (int i = 0; i
System.out.println(strVoid[i]+ " ");
}
}
}
publicclass AnswerB11 {
publicstaticvoid main(String[]args) {
int[] array = { 2, 25,21, 63, 234, 83 };
reverse(array);
System.out.println(Arrays.toString(array));
}
privatestaticvoid reverse(int[] array) {
for (int i = 0; i
int temp = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = temp;
}
}
}
publicclass AnswerB12 {
privatestaticfinalchar[] data = newchar[] { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' };
privatestaticfinalchar[] units = newchar[] { '元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿' };
publicstaticvoid main(String[]args) {
System.out.println(toUpcaseMoney(convert(100215)));
}
privatestatic StringtoUpcaseMoney(String money) {
returnnewStringBuilder(money).toString().replaceAll("零[拾佰仟]", "零").replaceAll("零+万", "万").replaceAll("零+元", "元").replaceAll("零+", "零");
}
publicstatic String convert(int money) {
StringBuffer sbf = new StringBuffer();
int unit = 0;
while (money != 0) {
sbf.insert(0, units[unit++]);
int number = money %10;
sbf.insert(0, data[number]);
money /= 10;
}
return sbf.toString();
}
}
import java.util.Stack;
publicclass AnswerB13 {
publicstaticvoid main(String[]args) {
Node tree = makeupTree();
Stack
Node currentNode = tree;
while (currentNode != null) {
System.out.println(currentNode.value);
stack.push(currentNode);
currentNode = currentNode.left;
if (currentNode == null) {
Node parent = stack.pop();
currentNode = parent.right;
if (currentNode == null) {
if (stack.isEmpty()){
break;
}
Node parentParent = stack.pop();
currentNode = parentParent.right;
}
}
}
}
privatestatic Node makeupTree(){
Node root = new Node(0);
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node11 = new Node(11);
Node node12 = new Node(12);
Node node21 = new Node(21);
Node node22 = new Node(22);
root.left = node1;
root.right = node2;
node1.left = node11;
node1.right = node12;
node2.left = node21;
node2.right = node22;
return root;
}
publicstaticclass Node {
public Node left;
public Node right;
publicintvalue;
public Node(int value) {
this.value = value;
}
}
}
如何用脚本判断用户输入的字符串是下面的时间格式2004-11-21必须要保证用户的输入是此格式,并且是时间,比如说月份不大于12等等,另外我需要用户输入两个,并且后一个要比前一个晚,只允许用JAVASCRIPT,请详细帮助作答,,
//这里可用正则表达式判断提前判断一下格式,然后按下提取各时间字段内容
<script type="text/javascript">
window.onload = function() {
//这么写是为了实现js代码与html代码的分离,当我修改js时,不能影响html代码。
document.getElementById("frm1").onsubmit = function() {
vard1 = this.d1.value;
vard2 = this.d2.value;
if(!verifyDate(d1)) {
alert("第一个日期格式不对");
returnfalse;
}
if(!verifyDate(d2)) {
alert("第二个日期格式不对");
returnfalse;
}
if(!compareDate(d1, d2)) {
alert("第二个日期比第一日期小");
returnfalse;
}
};
}
functioncompareDate(d1, d2){
var arrayD1 =d1.split("-");
var date1 = new Date(arrayD1[0],arrayD1[1], arrayD1[2]);
var arrayD2 =d2.split("-");
var date2 = new Date(arrayD2[0],arrayD2[1], arrayD2[2]);
return date1 > date2;
}
functionverifyDate(d){
vardatePattern=/^\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\d|3[0-1])$/;
returndatePattern.test(d);
}
<body>
<form id="frm1" action="xxx.html">
<input type="text" name="d1" />
<input type="text" name="d2" />
<input type="submit" />
form>
<table id="tbl"> <tr><td>1td>tr> <tr><td>2td>tr> <tr><td>3td>tr> <tr><td>4td>tr> <tr><td>5td>tr> <tr><td>6td>tr> <tr><td>7td>tr> <tr><td>8td>tr> <tr><td>9td>tr> <tr><td>10td>tr> table>
<form onsubmit='chkForm(this)'>
<input type="text"name="d1"/>
<input type="submit"/>
form>
<script type="text/javascript">
function chkForm(this){
var value1 = this.d1.value;
var len =value1.length;
for(var i=0;i
if(value1.charAt(i)>"9"|| value1.charAt(i)<"0"){
alert("含有非数字字符");
returnfalse;
}
}
returntrue;
}
script>
<input type="text" id="d1" onblur=" chkNumber(this)"/>
<script type="text/javascript">
function chkNumber(eleText){
var value =eleText.value;
var len =value.length;
for(var i=0;i
if(value.charAt(i)>"9"|| value.charAt(i)<"0"){
alert("含有非数字字符");
eleText.focus();
break;
}
}
}
script>
除了写完代码,还应该在网页上写出实验步骤和在代码中加入实现思路,让面试官一看就明白你的意图和检查你的结果。
jQuery、ExtJs、Dojo、DWR、Pushlet
1. 内存优化-Xms
2. 增加线程数maxThreads="150"
3. 修正server.xml中的中文编码
4. BIO改NIO
5.
6.
答:
1. URL地址长度不同, GET支持的字符少
2. GET的密码是明文,安全问题,容易受到黑客攻击
3. GET只传输文本,不支持文件传输
4. GET方式通常用来查询,不用来修改数据,是幂等操作,修改数据用POST
答: 通常Servlet特指HttpServlet,用来接受浏览器的访问请求,浏览器最常用的请求为GET和POST方式,还有其它五种,而HttpServlet分别有七个方法(PUT、DELETE、HEADER、TRACE、OPTION)处理这些类型的请求,另有一个是J2EE不支持的,是CONNECT。Servlet是J2EE规范中的重要成员,是构成WEB的重要组件
1. 加载Servlet类
2. 实例化
3. 初始化init
4. 处理请求 service à进一步调用doGet/doPost方法
5. 销毁 destory
1. 定义一个Servlet类,继承HttpServlet抽象类
2. 在web.xml中定义一个servlet标签,配置类名和servlet名
3. 配置servlet处理的URL请求连接,可以用模糊匹配
4. 在J2EE生命周期中,一个Servlet只有一个实例
5. 一个Servlet可以为多个请求服务,每个请求在独立的线程中执行
Forward: 服务器端内部跳转,URL地址不变,属于单次请求
Redirect: 服务器通知浏览器中转,URL地址发生改变,是两次跳转
Forward不能跨域跳转
Redirect可以跨域跳转
Forward在两个页面传值可以通过parameter,也可以通过attribute,能传递Java对象
Redirect在两个页面传值只能通过parameter,在URL中传参
Jsp页面中的FORM标签里的method属性为get时调用doGet(),为post时调用doPost()。
在地址栏进接输入URL回车,会调用doGet()方法
setAttribute(Stringname,Object):设置名字为name的request的参数值
getAttribute(String name):返回由name指定的属性值
getAttributeNames():返回request对象所有属性的名字集合,结果是一个枚举的实例
getCookies():返回客户端的所有Cookie对象,结果是一个Cookie数组
getCharacterEncoding():返回请求中的字符编码方式
getContentLength():返回请求的Body的长度
getHeader(String name):获得HTTP协议定义的文件头信息
getHeaders(String name):返回指定名字的request Header的所有值,结果是一个枚举的实例
getHeaderNames():返回所以request Header的名字,结果是一个枚举的实例
getInputStream():返回请求的输入流,用于获得请求中的数据
getMethod():获得客户端向服务器端传送数据的方法
getParameter(String name):获得客户端传送给服务器端的有name指定的参数值
getParameterNames():获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例
getParametervalues(Stringname):获得有name指定的参数的所有值
getProtocol():获取客户端向服务器端传送数据所依据的协议名称
getQueryString():获得查询字符串
getRequestURI():获取发出请求字符串的客户端地址
getRemoteAddr():获取客户端的IP地址
getRemoteHost():获取客户端的名字
getSession([Booleancreate]):返回和请求相关Session
getServerName():获取服务器的名字
getServletPath():获取客户端所请求的脚本文件的路径
getServerPort():获取服务器的端口号
removeAttribute(Stringname):删除请求中的一个属性
1. getParameter是表单数据或URL参数,不能在server端修改
getAttribute是两个页面或servlet之间内部跳转传递对象参数,可以修改
2. getParameter的类型只能是String
getAttribute的类型可以是任意Java对象
3. forward跳转时才有attribute,redirect时,attribute全部为null
JSP共有以下9个内置的对象:
request 用户端请求,此请求会包含来自GET/POST请求的参数
response 网页传回用户端的回应
pageContext 网页的属性是在这里管理
session 与请求有关的会话期
application servlet 正在执行的内容
out 用来传送回应的输出
config servlet的构架部件
page JSP网页本身
exception 针对错误网页,未捕捉的例外
request表示HttpServletRequest对象。它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header,和session数据的有用的方法。
response表示HttpServletResponse对象,并提供了几个用于设置送回浏览器的响应的方法(如cookies,头信息等)
out对象是javax.jsp.JspWriter的一个实例,并提供了几个方法使你能用于向浏览器回送输出结果。
pageContext表示一个javax.servlet.jsp.PageContext对象。它是用于方便存取各种范围的名字空间、servlet相关的对象的API,并且包装了通用的servlet相关功能的方法。
session表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信息
applicaton 表示一个javax.servle.ServletContext对象。这有助于查找有关servlet引擎和servlet环境的信息
config表示一个javax.servlet.ServletConfig对象。该对象用于存取servlet实例的初始化参数。
page表示从该页面产生的一个servlet实例
1. JSP生成.java文件
2. 编译成.class文件
3. 加载jsp.class类
4. 实例化
5. 初始化_jspInit
6. 处理请求 _jspService
7. 销毁 _jspDestory
(这个问题似乎不重要,不明白为何有此题)
答:JSP共有以下6种基本动作
jsp:include:在页面被请求的时候引入一个文件。
jsp:useBean:寻找或者实例化一个JavaBean。
jsp:setProperty:设置JavaBean的属性。
jsp:getProperty:输出某个JavaBean的属性。
jsp:forward:把请求转到一个新的页面。
jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记
isErrorPage(是否能使用Exception对象),isELIgnored(是否忽略表达式)
标签不同
执行的时机不同,动态include是在运行时把两个JSP合并,静态include是在编译期合并动态include在页面发生改变时,能及时更新,而静态页面,不会再次重新编译
跟6题同
1. request
2. session
3. application
4. cookie
5. URL地址
1. JSP编译后就是Servlet,因此本质上讲,JSP就是Servlet
2. JSP常用来做展示层,Servlet常用来做控制层
3. JSP容易编写,美工也可以参与修改,但Servlet专业技术要求较高
JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。JSP编译后是"类servlet"。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑。
MVC是Model-View-Controller的简写。
Model代表的是应用的业务逻辑(通过JavaBean,EJB组件实现),通常是数据访问层。
View是应用的表示层(由JSP页面产生)或模板框架,如freemarker、velocity
Controller是提供应用的处理过程控制(一般是一个Servlet),负责页面间跳转
通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。
Model:JDBC、Hibernate、MyBatis
View:JSP、FreeMarker、Struts
Controller:Spring MVC、Struts、Servlet
SpringSide集成Spring、Struts、Hibernate、WebService、View展示框架,作者江南白衣
public String translate(String str) {
try {
returnnew String(str.getBytes("ISO-8859-1"), "GBK").trim();
} catch (Exception e) {
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
}
employee: eid, ename,salary, dept_id
select * from employeeorder by dept_id desc, salary;
employee: eid, ename,salary, dept_id
select count(*),a.dept_id
from employee a
where
a.salary > (select avg(b.salary) from employee b whereb.dept_id = '本部门')
group by a.dept_id
order by a.dept_id
create or replace procedureinsert_Student (_name varchar, _age int , out_id int)
declear
a varchar
begin
insert intostudentvalue(null,_name,_age);
select max(stuId)into _idfrom student;
end;
callinsert_Student('wfz',23,@id);
select @id;
mysql> create triggerupdate_Student BEFORE update on student FOR EACH ROW
-> select * fromstudent;
触发器不允许返回结果
create triggerupdate_StudentBEFORE update on student FOR EACH ROW
insert into student value(null,'zxx',28);
mysql的触发器目前不能对当前表进行操作
create triggerupdate_StudentBEFORE update on student FOR EACH ROW
delete from articles where id=8;
这个例子不是很好,最好是用删除一个用户时,顺带删除该用户的所有帖子
这里要注意使用OLD.id
触发器用处还是很多的,比如校内网、开心网、Facebook,你发一个日志,自动通知好友,其实就是在增加日志时做一个后触发,再向通知表中写入条目。因为触发器效率高。而UCH没有用触发器,效率和数据处理能力都很低。
存储过程的实验步骤:
mysql> delimiter |
mysql> createprocedure insertArticle_Procedure (pTitle varchar(50),pBid int,out
pId int)
-> begin
-> insert intoarticle1value(null,pTitle,pBid);
-> select max(id) into pId fromarticle1;
-> end;
-> |
Query OK, 0 rows affected(0.05sec)
mysql>callinsertArticle_Procedure('传智播客',1,@pid);
-> |
Query OK, 0 rows affected(0.00sec)
mysql> delimiter ;
mysql> select @pid;
@pid |
3 |
1 row in set (0.00 sec)
mysql> select *fromarticle1;
id |
title |
bid |
1 |
test |
1 |
2 |
chuanzhiboke |
1 |
3 |
传智播客 |
1 |
3 rows in set (0.00 sec)
触发器的实验步骤:
create table board1(idintprimary key auto_increment,name varchar(50),ar
ticleCount int);
create table article1(idintprimary key auto_increment,title varchar(50)
,bid intreferencesboard1(id));
delimiter |
createtriggerinsertArticle_Trigger after insert on article1 for each ro
w begin
-> update board1setarticleCount=articleCount+1 where id= NEW.bid;
-> end;
-> |
delimiter ;
insert into board1value(null,'test',0);
insert intoarticle1value(null,'test',1);
还有,每插入一个帖子,都希望将版面表中的最后发帖时间,帖子总数字段进行同步更新,用触发器做效率就很高。下次课设计这样一个案例,写触发器时,对于最后发帖时间可能需要用declare方式声明一个变量,或者是用NEW.posttime来生成。
第一范式(1NF):字段具有原子性,不可再分。所有关系型数据库系统都满足第一范式。
数据库表中的字段都是单一属性的,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。
第二范式(2NF):在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
要求数据库表中的每个实例或行必须可以被唯一地区分。通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。
第三范式的要求如下:
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
所以第三范式具有如下特征:
1,每一列只有一个值
2,每一行都能区分。
3,每一个表都不包含其他表已经包含的非主关键字信息。
例如,帖子表中只能出现发帖人的id,而不能出现发帖人的id,还同时出现发帖人姓名,否则,只要出现同一发帖人id的所有记录,它们中的姓名部分都必须严格保持一致,这就是数据冗余。
1. 程序优化,用PrepareedStatement进行增删改查
2. 程序优化,尽量批量处理,避免逐条处理,减小IO数
3. 查询结果不要用*来查询所有字段,要明确指明结果字段
4. 减少多表连接数,尽量少的表进行连接
5. 表连接时,尽量用主键进行连接或用唯一索引
6. 表的查询多时,一定建立索引
7. 根据查询条件,建立索引,如果查询条件不止一个时,使用组合索引
8. 在查询条件表达式的左侧尽量不要使用函数,否则索引失效
9. 如果不得不用函数,则建立函数索引
10. 使用合适的索引,例如时间索引、哈希索引、聚簇索引
11. 如果有like话,尽量避免%xxx%两侧都有%的条件,单侧%可以使用索引,多侧不可以
12. 尽量不用数据库,使用缓存
13. 可以考虑用nosql数据库提高效率
14. SQL的条件表达式,在Oracle中,是按倒序使用索引的
15. 如果用DDL改动了数据库表字段,需要重建索引,不然索引失效
16. SQL尽量不要有多余的空格和换行
17.使用分布式数据库
18. 合理创建表分区表空间
19.建立索引时字段不能有null值
20.使用数据库连接池
21.条件中与null比较索引无效
22.表结构改动时索引全部失效
union和union all都是合并结果集
区别是:
1. union去除两个结果集的重复记录,union all不去除重复记录,是两个结果集的加和
2. union效率低,union all效率高
取出sql表中第31到40的记录(以自动增长ID为主键)
sql server方案1:
select top 10 * from t where id not in(select top 30 id from t order by id ) orde by id
sql server方案2:
select top 10 * from t where id in (selecttop 40 id from t order by id) order by id desc
mysql方案:select * from t order by idlimit 30,10
oracle方案:select * from (select rownum r,* from t where r<=40) where r>30
name kecheng fenshu
张三 语文 81
张三 数学 75
李四 语文 76
李四 数学 90
王五 语文 81
王五 数学 100
王五 英语 90
答案:
A:select distinct name from score where name not in (select distinctname from score where fenshu <=80)
B:select distinct name t1 from score where 80< all (select fenshu fromscore where name=t1);
一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合.
select a.name, b.name
from team a, team b
where a.name > b.name
请用SQL语句实现:从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。请注意:TestDB中有很多科目,都有1-12月份的发生额。
AccID:科目代码,Occmonth:发生额月份,DebitOccur:发生额。
数据库名:JcyAudit,数据集:Select * from TestDB
准备数据的sql代码:
drop table if existsTestDB;
create table TestDB(idint primary key auto_increment,AccIDvarchar(20), Occmonth date, DebitOccurbigint);
insert into TestDB values
(null,'101','1988-1-1',100),
(null,'101','1988-2-1',110),
(null,'101','1988-3-1',120),
(null,'101','1988-4-1',100),
(null,'101','1988-5-1',100),
(null,'101','1988-6-1',100),
(null,'101','1988-7-1',100),
(null,'101','1988-8-1',100);
--复制上面的数据,故意把第一个月份的发生额数字改小一点
insert into TestDB values
(null,'102','1988-1-1',90),
(null,'102','1988-2-1',110),
(null,'102','1988-3-1',120),
(null,'102','1988-4-1',100),
(null,'102','1988-5-1',100),
(null,'102','1988-6-1',100),
(null,'102','1988-7-1',100),
(null,'102','1988-8-1',100);
--复制最上面的数据,故意把所有发生额数字改大一点
insert into TestDB values
(null,'103','1988-1-1',150),
(null,'103','1988-2-1',160),
(null,'103','1988-3-1',180),
(null,'103','1988-4-1',120),
(null,'103','1988-5-1',120),
(null,'103','1988-6-1',120),
(null,'103','1988-7-1',120),
(null,'103','1988-8-1',120);
--复制最上面的数据,故意把所有发生额数字改大一点
insert into TestDB values
(null,'104','1988-1-1',130),
(null,'104','1988-2-1',130),
(null,'104','1988-3-1',140),
(null,'104','1988-4-1',150),
(null,'104','1988-5-1',160),
(null,'104','1988-6-1',170),
(null,'104','1988-7-1',180),
(null,'104','1988-8-1',140);
--复制最上面的数据,故意把第二个月份的发生额数字改小一点
insert into TestDB values
(null,'105','1988-1-1',100),
(null,'105','1988-2-1',80),
(null,'105','1988-3-1',120),
(null,'105','1988-4-1',100),
(null,'105','1988-5-1',100),
(null,'105','1988-6-1',100),
(null,'105','1988-7-1',100),
(null,'105','1988-8-1',100);
答案:
select distinct AccIDfrom TestDB
where AccID not in
(
select
TestDB.AccID
from
TestDB,
(select * from TestDB whereAccID='101') asdb101
where
TestDB.Occmonth=db101.Occmonth
andTestDB.DebitOccur<=db101.DebitOccur
);
year month amount
1991 1 1.1
1991 2 1.2
1991 3 1.3
1991 4 1.4
1992 1 2.1
1992 2 2.2
1992 3 2.3
1992 4 2.4
查成这样一个结果
year m1 m2 m3 m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4
准备sql语句:
drop table if exists sales;
create table sales(id intauto_increment primary key,year varchar(10), month varchar(10), amount float(2,1));
insert into sales values
(null,'1991','1',1.1),
(null,'1991','2',1.2),
(null,'1991','3',1.3),
(null,'1991','4',1.4),
(null,'1992','1',2.1),
(null,'1992','2',2.2),
(null,'1992','3',2.3),
(null,'1992','4',2.4);
答案一:
select s.year ,
(select t.amount from salest where t.month='1' and t.year= s.year) m1,
(select t.amount from salest where t.month='2' and t.year= s.year) m2,
(select t.amount from salest where t.month='3' and t.year= s.year) m3,
(select t.amount from salest where t.month='4' and t.year= s.year) m4
from sales s
group by s.year;
答案二:
select
y.year,
(select t.amount fromsales t where t.month='1' and t.year= y.year) m1,
(select t.amount fromsales t where t.month='2' and t.year= y.year) m2,
(select t.amount fromsales t where t.month='3' and t.year= y.year) m3,
(select t.amount fromsales t where t.month='4' and t.year= y.year) m4
from
(select distinct yearfrom sales s order by year) y
文章表:article_id, title, post_user, post_date
回复表:reply_id, article_id, reply_time, content
select
a.title, a.post_user, r.reply_time
from reply r
left join article a on a.article_id = r.article_id
where
r.reply_id =
(
select max(re.reply_id)
from reply re
where
re.article_id =r.article_id
)
学生表(student)如下:
id号 学号 姓名 课程编号课程名称 分数
id sid name cno cname score
1 2005001 张三 0001 数学 69
2 2005002 李四 0001 数学 89
3 2005001 张三 0001 数学 69
A: delete from studentwhere id not in(select min(id) from student group by sid, name, cno, cname,score)
表结构如下:
航班(flight){ID(flight_id),起飞城市ID(start_city_id) ,降落城市ID(end_city_id),起飞时间(start_time)}
城市(city){城市ID(city_id),城市名称(city_name)}
1、查询起飞城市是北京的所有航班,按到达城市的名字排序
select *
from flight f
left join city sc onsc.city_id = f.start_city_id
left join city ec onec.city_id = f.end_city_id
where
sc.city_name = '北京'
order by ec.city_name
2、查询北京到上海的所有航班纪录(起飞城市,到达城市,起飞时间,航班号)
select sc.city_name,ec.city_name, f.start_time, flight_id
from flight f
left join city sc onsc.city_id = f.start_city_id
left join city ec onec.city_id = f.end_city_id
where
sc.city_name = '北京'
and ec.city_name = '上海'
3、查询具体某一天(2005-5-8)的北京到上海的的航班次数
select count(*)
from flight f
left join city sc on sc.city_id = f.start_city_id
left join city ec on ec.city_id = f.end_city_id
where
sc.city_name = '北京'
and ec.city_name = '上海'
and f.start_time >= to_date('2005-05-08','yyyy-mm-dd')
and f.start_time < to_date('2005-05-08','yyyy-mm-dd') + 1
employee: id, name,salary, manager_id;
答案:
select *
from employee e
left join employee m onm.id = e.manager_id
where
e.salary > m.salary
数据库中有3个表 teacher表,student表,teacher_student关系表。
teacher表:teacher_id,name,age
student表:student_id,name,age
teacher_student表:teacher_id,student_id
答案一:
select count(*),ts.teacher_id
from teacher_student ts
left join teacher t ont.teacher_id = ts.teacher_id
left join student s ons.student_id = ts.student_id
where
t.age < 45
and s.age > 12
group by ts.teacher_id
答案二:
select count(*),ts.teacher_id
from teacher_student ts,teacher t, student s
where
t.teacher_id =ts.teacher_id
and s.student_id =ts.student_id
and t.age < 45
and s.age > 12
group by ts.teacher_id
select max(post_count), b.post_user_id, u.name
from
(
select count(*) aspost_count, a.post_user_id
from article a
group by a.post_user_id
) b
left join user u on u.user_id = b.post_user_id。
方案一:update user set score=0;
方案二:假设上面的代码要执行好长时间,超出我们的容忍范围,使用alter table:
drop columnscore;altertable user add column score int。
在Oracle中,动了表结构,索引失效
方案三:使用Java程序,for循环,效率最差
方案四:使用存储过程loop循环,效率其次差
select distinct user_id
from user_role scx
where
not exists
(
select *
from user_role scy
where
scy.user_id = '张三'
and not exits
(
select *
from user_role scz
where
scz.user_id =scx.user_id
and scz.role_id =scy.role_id
)
)
EMPLOYEES(employee_id NUMBER, first_name VARCHAR2(25), last_name VARCHAR2(25), salary number(8,2),hired_date DATE,department_id number(2))
Departments(Departmentid number(2),DepartmentName VARCHAR2(25))
(1)基于上述EMPLOYEES表写出查询:写出雇用日期在今年的,或者工资在[1000,2000]之间的,或者员工姓名(last_name)以’Obama’打头的所有员工,列出这些员工的全部个人信息。
答案一、
select * from employees
where
Year(hired_date) =Year(date())
or (salary between 1000and 200)
or left(last_name,5)=' Obama’';
答案二、
select * from employees
where
(
hired_date >= to_date(Year(date())|| ‘-01-01’, ‘yyyy-mm-dd’
and hired_date
)
or (salary between 1000and 200)
or last_name like ‘ Obama%’
(2) 查出部门平均工资大于1800元的部门的所有员工,列出这些员工的全部个人信息。
答案一、
select * from employee em
where
em.department_id in
(
select department_id
from employee e
group by department_id
having avg(salary) > 1800
)
答案二、
select * from employee em
where
(
select avg(e.salary) from employee e where e.department_id= em. department_id
) > 1800
(3)查出个人工资高于其所在部门平均工资的员工,列出这些员工的全部个人信息及该员工工资高出部门平均工资百分比。
答案一、
select e.*, ((e.salary -as.avg_salary) / as.avg_salary) as salary_percent
from employee e
left join
(
select em.department_id, avg(em.salary) as avg_salary
from employee em
group by em.department_id
) as on e.department_id =as.department_id
where
e.salary >as.avg_salary
答案二、
select employee e.*,(e.salary-t.avg_salary)/ as.avg_salary
from employee e,
(
select t.department_id,avg(salary)avg_salary
from employee em
group by t.department_id
) as t
where
e. department_id = t. department_id and e.salary>t.avg_salary
1. Class.forName(driver)
2.ClassLoader.loadClass(driver)
3. new XXXDriver();
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql:///test";
Connection cn =DriverManager.getConnection(url, "root","root");
String sql = "{callinsert_student(?,?,?)}";
CallableStatement cstmt =cn.prepareCall(sql);
cstmt.registerOutParameter(3,Types.INTEGER);
cstmt.setString(1, "wangwu");
cstmt.setInt(2, 25);
cstmt.execute();
// get第几个,不同的数据库不一样,建议不写
System.out.println(cstmt.getString(3));
一个sql命令在数据库执行的步骤为:语法检查,语义分析,编译成内部指令,缓存指令,执行指令等过程。
1. PrepareStatement第一次执行某SQL时可以把最终结果缓存到数据中,以后再执行同一格式的SQL时,不再进行优化,直接使用缓存中的优化结果,效率比较高。
2.参数传值,可以防止SQL注入
答:按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。
有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名通常也是通过配置文件来配置的,以便在产品交付使用后不用修改源程序就可以更换驱动类名。
查询结果集如果记录数比较多时,服务器内存和浏览器内存都可能溢出,另外,数据量太大客户端的性能会降低,滚动条较小,操作也不方便,需要数据库分页查询。
SQL Server分页:
select top #pageSize# *from students where id not in
(select top #pageSize# *(#pageNumber#-1) id from students order by id) order by id
My SQL分页:
select * from studentsorder by id limit #pageSize#*(#pageNumber#-1),#pageSize#
Oracle分页:
select * from
(
select *, rownum rid
from
(
select * from students order by postime desc
)
where
rid<=#pagesize#*#pagenumber#
) as t
wheret.rid>#pageSize#*(#pageNumber#-1)
Connection cn = null;
PreparedStatement pstmt=null;
Resultset rs = null;
try {
Class.forname(driveClassName);
cn = DriverManager.getConnection(url,username,password);
pstmt=cn.prepareStatement(“select score.* fromscore,student “ +
“wherescore.stuId =student.id and student.name = ?”);
pstmt.setString(1,studentName);
Resultset rs=pstmt.executeQuery();
while(rs.next()) {
system.out.println(rs.getInt(“subject”) + “\t”+ rs.getFloat(“score”) );
}
}catch(Exceptione){e.printStackTrace();}
finally{
if(rs != null)try{rs.close(); }catch(exception e){}
if(pstmt !=null)try{pstmt.close();}catch(exception e){}
if(cn != null)try{cn.close(); }catch(exception e){}
}
try {
Connection conn = ...;
Statement stmt = ...;
ResultSet rs=stmt.executeQuery("select * from table1");
while(rs.next()) {
}
} catch(Exception ex) {
}
答:没有finally语句来关闭各个对象,另外,使用finally之后,要把变量的定义放在try语句块的外面,以便在try语句块之外的finally块中仍可以访问这些变量。
J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接标记为空闲,其他调用就可以使用这个连接。
实现方式,返回的Connection是原始Connection的代理,代理Connection的close方法不是真正关连接,而是把它代理的Connection对象还回到连接池中。
ORM是对象和关系型数据库映射,是把Java中的JavaBean对象和数据库表进行映射,使数据库表中的记录和JavaBean对象一一对应,从而大大简化原来直接使用JDBC时,手工拼写SQL带来的不便。
ORM通过配置文件,使数据库表和JavaBean类对应起来,提供简便的操作方法,增、删、改、查记录,不再拼写字符串生成SQL,编程效率大大提高,同时减少程序出错机率,增强数据库的移植性,方便测试。但是原生的JDBC具有更强的灵活性,适合复杂多变的SQL应用。
常用的ORM框架有:Hibernate、MyBatis、TopLink、OJB
1. 大数据可以采用分布式数据库和建立分区表(PARTITION)
2. 建立有效索引:主键索引、联合索引、倒序索引、函数索引(INDEX)
3. 使用物化视图(MATERIALIZED VIEW)
4. 使用存储过程(PROCDUDER)
5. 读写分离(golden gate软件实现)
6. 归档旧数据(新旧数据查询,保证新数据的效率提高),程序做调整,旧数据和新数据查询页面分离
存储过程:可以使得对的管理、以及显示关于及其用户信息的工作容易得多。存储过程是 SQL 语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单元处理。存储过程存储在数据库内,可由应用程序通过一个调用执行,而且允许用户声明变量、有条件执行以及其它强大的编程功能。存储过程可包含程序流、逻辑以及对数据库的查询。它们可以接受参数、输出参数、返回单个或多个结果集以及返回值。
可以出于任何使用 SQL 语句的目的来使用存储过程,它具有以下优点:
(1)功能强大,限制少。
(2)可以在单个存储过程中执行一系列 SQL 语句。
(3)可以从自己的存储过程内引用其它存储过程,这可以简化一系列复杂语句。
(4)存储过程在创建时即在上进行编译,所以执行起来比单个 SQL 语句快。
(5)可以有多个返回值,即多个输出参数,并且可以使用SELECT返回结果集。
函数:是由一个或多个 SQL 语句组成的子程序,可用于封装代码以便重新使用。自定义函数诸多限制,有许多语句不能使用,许多功能不能实现。函数可以直接引用返回值,用表变量返回记录集。但是,用户定义函数不能用于执行一组修改全局数据库状态的操作。
答:有DOM,SAX,STAX等
DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问
STAX:Streaming API forXML (StAX)
讲解这些区别是不需要特别去比较,就像说传智播客与其他培训机构的区别时,我们只需说清楚传智播客有什么特点和优点就行了,这就已经间接回答了彼此的区别。
答:用到了数据存贮,信息配置两方面。在做数据交换平台时,将不能数据源的数据组装成XML文件,然后将XML文件压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再同XML文件中还原相关信息进行处理。在做软件配置时,利用XML可以很方便的进行,软件的各种配置参数都存贮在XML文件中。
答:看如下代码,用编码方式加以解决
package test;
import java.io.*;
public class DOMTest
{
private String inFile ="c:\\people.xml"
private String outFile ="c:\\people.xml"
public static voidmain(String args[])
{
new DOMTest();
}
public DOMTest()
{
try
{
javax.xml.parsers.DocumentBuilderbuilder =
javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder();
org.w3c.dom.Document doc= builder.newDocument();
org.w3c.dom.Element root= doc.createElement("老师");
org.w3c.dom.Element wang= doc.createElement("王");
org.w3c.dom.Element liu =doc.createElement("刘");
wang.appendChild(doc.createTextNode("我是王老师"));
root.appendChild(wang);
doc.appendChild(root);
javax.xml.transform.Transformertransformer =
javax.xml.transform.TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING,"gb2312");
transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT,"yes");
transformer.transform(newjavax.xml.transform.dom.DOMSource(doc),
new
javax.xml.transform.stream.StreamResult(outFile));
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
答:用SAX方式解析XML,XML文件如下:
事件回调类SAXHandler.java
import java.io.*;
importjava.util.Hashtable;
import org.xml.sax.*;
public class SAXHandlerextends HandlerBase
{
private Hashtable table =new Hashtable();
private StringcurrentElement = null;
private StringcurrentValue = null;
public voidsetTable(Hashtable table)
{
this.table = table;
}
public HashtablegetTable()
{
return table;
}
public voidstartElement(String tag, AttributeList attrs)
throws SAXException
{
currentElement = tag;
}
public voidcharacters(char[] ch, int start, int length)
throws SAXException
{
currentValue = newString(ch, start, length);
}
public voidendElement(String name) throws SAXException
{
if(currentElement.equals(name))
table.put(currentElement,currentValue);
}
}
JSP内容显示源码,SaxXml.jsp:
<%@ pageerrorPage=ErrPage.jsp contentType=text/html;charset=GB2312%> <%@ pageimport=java.io.* %> <%@ pageimport=java.util.Hashtable %> <%@ page import=org.w3c.dom.*%> <%@ pageimport=org.xml.sax.* %> <%@ pageimport=javax.xml.parsers.SAXParserFactory %> <%@ pageimport=javax.xml.parsers.SAXParser %> <%@ pageimport=SAXHandler %> <% File file = newFile(c:\people.xml); FileReader reader = newFileReader(file); Parser parser; SAXParserFactory spf =SAXParserFactory.newInstance(); SAXParser sp =spf.newSAXParser(); SAXHandler handler = newSAXHandler(); sp.parse(newInputSource(reader), handler); Hashtable hashTable =handler.getTable(); out.println( out.println( (String)hashTable.get(newString(name)) + out.println( (String)hashTable.get(newString(college))+ out.println( (String)hashTable.get(newString(telephone)) + out.println( (String)hashTable.get(newString(notes)) + out.println(); %>
);姓名 + +
);学院 + +
);电话 + +
);备注 + +