概述
1、线程
线程创建方式继承Thread类和实现Runable接口,重写run方法
使用callable和future创建线程,使用线程池
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rVathKHe-1583845715739)(https://media.geeksforgeeks.org/wp-content/uploads/threadLifeCycle.jpg)]
2、线程池
**线程池可重复使用先前创建的线程来执行当前任务,并为线程周期开销和资源颠簸问题提供了解决方案。**由于在请求到达时线程已经存在,因此消除了线程创建带来的延迟,从而使应用程序具有更高的响应速度。
-
Java提供了Executor框架,该框架以Executor接口,其子接口ExecutorService和ThreadPoolExecutor类为中心,后者实现了这两个接口。通过使用执行程序,仅需实现Runnable对象并将其发送给执行程序即可执行。
-
它们使您可以利用线程的优势,而专注于希望线程执行的任务,而不是线程机制。
-
要使用线程池,我们首先创建一个ExecutorService对象,并将一组任务传递给它。ThreadPoolExecutor类允许设置核心和最大池大小。由特定线程运行的可运行对象按顺序执行。
-
使用线程池的风险
-
-
- **死锁:**尽管死锁可以在任何多线程程序中发生,但是线程池会引入另一种死锁情况,在这种情况下,由于线程无法执行,所有正在执行的线程都在等待队列中被阻塞线程的结果。
- **线程泄漏:**如果从线程池中删除线程以执行任务,但任务完成后没有返回线程,则会发生线程泄漏。例如,如果线程引发异常,并且池类没有捕获此异常,则线程将直接退出,从而将线程池的大小减小一个。如果重复多次,则该池最终将变为空,并且没有线程可用于执行其他请求。
- **资源释放:**如果线程池很大,那么浪费时间在线程之间进行上下文切换。如所解释的,具有比最佳数量更多的线程可能会导致饥饿问题,从而导致资源崩溃。
-
-
重要事项
-
-
- 不要将同时等待其他任务结果的任务排队。如上所述,这可能导致死锁的情况。
- 使用线程进行长寿命操作时要小心。它可能导致线程永远等待,并最终导致资源泄漏。
- 线程池必须在末尾显式结束。如果未完成,则程序将继续执行,并且永远不会结束。在池上调用shutdown()以结束执行程序。如果您尝试在关闭后将另一个任务发送给执行器,它将抛出RejectedExecutionException。
- 需要了解任务以有效地调整线程池。如果任务之间有很大差异,则有必要对不同类型的任务使用不同的线程池,以便对其进行适当的调整。
-
-
调优线程池
-
- 线程池的最佳大小取决于可用处理器的数量和任务的性质。在仅处理计算类型的队列的N处理器系统上,最大线程池大小为N或N + 1将实现最大效率,但是任务可能会等待I / O,因此在这种情况下,我们要考虑比率请求的等待时间(W)和服务时间(S);导致最大池大小为N *(1+ W / S),以实现最大效率。
-
线程池是用于组织服务器应用程序的有用工具。它在概念上非常简单明了,但是在实现和使用它时要注意几个问题,例如死锁,资源崩溃。使用执行程序服务使其更易于实现。
-
3、反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
与Java反射相关的类如下:
类名 | 用途 |
---|---|
Class类 | 代表类的实体,在运行的Java应用程序中表示类和接口 |
Field类 | 代表类的成员变量(成员变量也称为类的属性) |
Method类 | 代表类的方法 |
Constructor类 | 代表类的构造方法 |
Class类
Class代表类的实体,在运行的Java应用程序中表示类和接口。在这个类中提供了很多有用的方法,这里对他们简单的分类介绍。
- 获得类相关的方法
方法 | 用途 |
---|---|
asSubclass(Class clazz) | 把传递的类的对象转换成代表其子类的对象 |
Cast | 把对象转换成代表类或是接口的对象 |
getClassLoader() | 获得类的加载器 |
getClasses() | 返回一个数组,数组中包含该类中所有公共类和接口类的对象 |
getDeclaredClasses() | 返回一个数组,数组中包含该类中所有类和接口类的对象 |
forName(String className) | 根据类名返回类的对象 |
getName() | 获得类的完整路径名字 |
newInstance() | 创建类的实例 |
getPackage() | 获得类的包 |
getSimpleName() | 获得类的名字 |
getSuperclass() | 获得当前类继承的父类的名字 |
getInterfaces() | 获得当前类实现的类或是接口 |
- 获得类中属性相关的方法
方法 | 用途 |
---|---|
getField(String name) | 获得某个公有的属性对象 |
getFields() | 获得所有公有的属性对象 |
getDeclaredField(String name) | 获得某个属性对象 |
getDeclaredFields() | 获得所有属性对象 |
- 获得类中注解相关的方法
方法 | 用途 |
---|---|
getAnnotation(Class annotationClass) | 返回该类中与参数类型匹配的公有注解对象 |
getAnnotations() | 返回该类所有的公有注解对象 |
getDeclaredAnnotation(Class annotationClass) | 返回该类中与参数类型匹配的所有注解对象 |
getDeclaredAnnotations() | 返回该类所有的注解对象 |
- 获得类中构造器相关的方法
方法 | 用途 |
---|---|
getConstructor(Class…<?> parameterTypes) | 获得该类中与参数类型匹配的公有构造方法 |
getConstructors() | 获得该类的所有公有构造方法 |
getDeclaredConstructor(Class…<?> parameterTypes) | 获得该类中与参数类型匹配的构造方法 |
getDeclaredConstructors() | 获得该类所有构造方法 |
- 获得类中方法相关的方法获取私有方法添加setAccessible(true);
方法 | 用途 |
---|---|
getMethod(String name, Class…<?> parameterTypes) | 获得该类某个公有的方法 |
getMethods() | 获得该类所有公有的方法 |
getDeclaredMethod(String name, Class…<?> parameterTypes) | 获得该类某个方法 |
getDeclaredMethods() | 获得该类所有方法 |
- 类中其他重要的方法
方法 | 用途 |
---|---|
isAnnotation() | 如果是注解类型则返回true |
isAnnotationPresent(Class<? extends Annotation> annotationClass) | 如果是指定类型注解类型则返回true |
isAnonymousClass() | 如果是匿名类则返回true |
isArray() | 如果是一个数组类则返回true |
isEnum() | 如果是枚举类则返回true |
isInstance(Object obj) | 如果obj是该类的实例则返回true |
isInterface() | 如果是接口类则返回true |
isLocalClass() | 如果是局部类则返回true |
isMemberClass() | 如果是内部类则返回true |
Field类
Field代表类的成员变量(成员变量也称为类的属性)。
方法 | 用途 |
---|---|
equals(Object obj) | 属性与obj相等则返回true |
get(Object obj) | 获得obj中对应的属性值 |
set(Object obj, Object value) | 设置obj中对应属性值 |
Method类
Method代表类的方法。
方法 | 用途 |
---|---|
invoke(Object obj, Object… args) | 传递object对象及参数调用该对象对应的方法 |
Constructor类
Constructor代表类的构造方法。
方法 | 用途 |
---|---|
new Instance(Object… initargs) | 根据传递的参数创建类的对象实例 |
4、反射创建对象的方式
//1.1.对象.getClass();获取对象
//1.2.类.class
//1.3.Class.forName(“包名.类名”);
//1.源头:获取Class对象,用三种方式
phone iPhone=new phone();
//1.1.对象.getClass();获取对象
Class<?> clazz1 = iPhone.getClass();
//1.2.类.class
clazz1=phone.class;
//1.3.Class.forName("包名.类名");
clazz1 = Class.forName("test.phone");
//2.创建对象
//2.1通过newInstence()
phone instance1 = (phone) clazz1.newInstance();
//2.2先调用构造器,再通过newInstence()创建
Object instance2 = clazz1.getConstructor().newInstance();
5、反射怎么调用方法对象?
obj.getClass().getMethod(“方法名!!!”)
6、设计模式用到哪些?单例模式是怎么实现的?
-
/** * 饿汉-单例模式 */ public class Singleton1 { //1.定义私有静态变量,类型为类类型 //直接创建好对象,不论到底会用到用不到,故称为饿汉式 private static Singleton1 instance = new Singleton1(); //2.定义私有构造函数 private Singleton1(){ } //3.定义公共静态方法,返回私有静态变量 public static Singleton1 getInstance(){ return instance; } } /** * 懒汉-单例模式 */ public class Singleton2 { //1.定义私有静态变量,类型为类类型, // 先不创建,等用到时再创建(正是由于等用到时才创建,故而才称为懒汉式) private static Singleton2 instance = null; //2.定义私有构造函数 private Singleton2(){ } //3.定义公共静态方法,返回私有静态变量 // public static Singleton2 getInstance(){//线程不安全的 public static synchronized Singleton2 getInstance(){// 线程安全,通过synchronize保证线程安全 if(instance == null){ instance = new Singleton2(); } return instance; } } /** * 内部类创建方式-单例模式 * 这种方式是线程安全的 */ public class Singleton3 { //1.定义静态内部类,类里面有静态内部属性,为类类型 private static class SingletonInnerClass{ private static final Singleton3 instance = new Singleton3(); } //2.定义私有构造函数 private Singleton3(){ } //3.定义公共静态方法,返回内部类的静态常量 public static Singleton3 getInstance(){ return SingletonInnerClass.instance; } }
spring中常用的设计模式达到九种,我们举例说明:
第一种:简单工厂
又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。
spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。如下配置,就是在 HelloItxxz 类中创建一个 itxxzBean。
<beans> <bean id="singletonBean" class="com.itxxz.HelloItxxz"> <constructor-arg> <value>Hello! 这是singletonBean!value> </constructor-arg> </ bean> <bean id="itxxzBean" class="com.itxxz.HelloItxxz" singleton="false"> <constructor-arg> <value>Hello! 这是itxxzBean! value> </constructor-arg> </bean> </beans>
第二种:工厂方法(Factory Method)
通常由应用程序直接使用new创建新的对象,为了将对象的创建和使用相分离,采用工厂模式,即应用程序将对象的创建及初始化职责交给工厂对象。
一般情况下,应用程序有自己的工厂对象来创建bean.如果将应用程序自己的工厂对象交给Spring管理,那么Spring管理的就不是普通的bean,而是工厂Bean。
螃蟹就以工厂方法中的静态方法为例讲解一下:
import java.util.Random; public class StaticFactoryBean { public static Integer createRandom() { return new Integer(new Random().nextInt()); } }
建一个config.xm配置文件,将其纳入Spring容器来管理,需要通过factory-method指定静态方法名称
<bean id=“random”
class=“example.chapter3.StaticFactoryBean” factory-method=“createRandom” //createRandom方法必须是static的,才能找到 scope=“prototype”
/>
测试:
public static void main(String[] args) {
//调用getBean()时,返回随机数.如果没有指定factory-method,会返回StaticFactoryBean的实例,即返回工厂Bean的实例 XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource(“config.xml”)); System.out.println(“我是IT学习者创建的实例:”+factory.getBean(“random”).toString());
}
第三种:单例模式(Singleton)
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。但没有从构造器级别去控制单例,这是因为spring管理的是是任意的java对象。
核心提示点:Spring下默认的bean均为singleton,可以通过singleton=“true|false” 或者 scope=“?”来指定
第四种:适配器(Adapter)
在Spring的Aop中,使用的Advice(通知)来增强被代理类的功能。Spring实现这一AOP功能的原理就使用代理模式(1、JDK动态代理。2、CGLib字节码生成技术代理。)对类进行方法级别的切面增强,即,生成被代理类的代理类, 并在代理类的方法前,设置拦截器,通过执行拦截器重的内容增强了代理方法的功能,实现的面向切面编程。
Adapter类接口:Target
public interface AdvisorAdapter { boolean supportsAdvice(Advice advice); MethodInterceptor getInterceptor(Advisor advisor); } MethodBeforeAdviceAdapter类,Adapter class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable { public boolean supportsAdvice(Advice advice) { return (advice instanceof MethodBeforeAdvice); } public MethodInterceptor getInterceptor(Advisor advisor) { MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); return new MethodBeforeAdviceInterceptor(advice); } }
第五种:包装器(Decorator)
在我们的项目中遇到这样一个问题:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。我们以往在spring和hibernate框架中总是配置一个数据源,因而sessionFactory的dataSource属性总是指向这个数据源并且恒定不变,所有DAO在使用sessionFactory的时候都是通过这个数据源访问数据库。但是现在,由于项目的需要,我们的DAO在访问sessionFactory的时候都不得不在多个数据源中不断切换,问题就出现了:如何让sessionFactory在执行数据持久化的时候,根据客户的需求能够动态切换不同的数据源?我们能不能在spring的框架下通过少量修改得到解决?是否有什么设计模式可以利用呢?
首先想到在spring的applicationContext中配置所有的dataSource。这些dataSource可能是各种不同类型的,比如不同的数据库:Oracle、SQL Server、MySQL等,也可能是不同的数据源:比如apache 提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。然后sessionFactory根据客户的每次请求,将dataSource属性设置成不同的数据源,以到达切换数据源的目的。
spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。
第六种:代理(Proxy)
为其他对象提供一种代理以控制对这个对象的访问。 从结构上来看和Decorator模式类似,但Proxy是控制,更像是一种对功能的限制,而Decorator是增加职责。
spring的Proxy模式在aop中有体现,比如JdkDynamicAopProxy和Cglib2AopProxy。
第七种:观察者(Observer)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
spring中Observer模式常用的地方是listener的实现。如ApplicationListener。
第八种:策略(Strategy)
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
spring中在实例化对象的时候用到Strategy模式
在SimpleInstantiationStrategy中有如下代码说明了策略模式的使用情况:
第九种:模板方法(Template Method)
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
Template Method模式一般是需要继承的。这里想要探讨另一种对Template Method的理解。spring中的JdbcTemplate,在用这个类时并不想去继承这个类,因为这个类的方法太多,但是我们还是想用到JdbcTemplate已有的稳定的、公用的数据库连接,那么我们怎么办呢?我们可以把变化的东西抽出来作为一个参数传入JdbcTemplate的方法中。但是变化的东西是一段代码,而且这段代码会用到JdbcTemplate中的变量。怎么办?那我们就用回调对象吧。在这个回调对象中定义一个操纵JdbcTemplate中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入这个回调对象到JdbcTemplate,从而完成了调用。这可能是Template Method不需要继承的另一种实现方式吧。
7、工厂模式有哪些?
简单工厂模式是由一个具体的类去创建其他类的实例,父类是相同的,父类是具体的。
工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成。
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。
8、常用的设计模式
单例模式
代理模式:动态代理和静态代理
观察者模式
装饰模式
简单工厂模式
9、面向对象的四大特征
抽象
定义:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面,抽象只关注对象的哪些属性和行为,并不关注这此行为的细节是什么
封装
定义:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口.面向对象的本质就是将现实世界描绘成一系列完全自治,封闭的对象,可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口。封装给对象提供了隐藏内部特性和行为的能力,对象提供一些能这被其它对象访问的方法来改变它内部的数据。
2.1.提供构造方法(有了构造方法才能通过new去构建一个对象 1.构造方法必须和类名称一样2.构造方法不能有返回值)
继承(关键字:extends)
目的:对父类和方法的复用
继承是从已有类得到继承信息创建新类的过程,继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段.子类继承父类属性(静态特征)和方法(动态特征),继承必须遵循封装当中的控制访问
多态
多态性是指允许相同或不同子类型的对象对同一消息作出不同响应
重载:同一个动作作用在同一个对象上拥有不同的解释 overload
重载又称静态多态,编译时多态
重写:同一个动作作用在不同的对象上拥有不同的解释 override
重写又称动态多态,运行时多态
狭义的多态指重写
五大设计原则
单一职责原则
里氏替换原则
依赖原则
接口分离原则
开放封闭原则
10、重写与重载的区别
重写必须存在于字符类继承关系的类中,子类重写父类方法,方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private) 重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常
重载存在于类中,区别于同样的方法名,不同的参数类型和参数返回值同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。
一. Java基础部分
1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?
可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致。
一个文件中可以只有非public类,如果只有一个非public类,此类可以跟文件名不同
2、说说&和&&的区别。
&和&&都可以用作逻辑与的运算符,&&为短路与,&不是短路与。
另外&可以做为整数的位运算符
例1:对于if(str != null&& !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。
例2:If(x33 &++y>0) y会增长,If(x33 && ++y>0)不会增长
3、在JAVA中如何跳出当前的多重嵌套循环?
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;
}
}
另外,我个人通常并不使用标号这种方式,而是让外层的循环条件表达式的结果可以受到里层循环体代码的控制,例如,要在二维数组中查找到某个数字。
int arr[][] ={{1,2,3},{4,5,6,7},{9}};
boolean found = false;
for(int i=0;i<arr.length&& !found;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
private static int 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;
}
4、switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
作用在byte, short, char, int, enum
封装类对象,其它基本数据类型及引用数据类型都不能做为case的条件
6、用最有效率的方法算出2乘以8等於几?
2 << 3
因为将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,而位运算cpu直接支持的,效率最高,所以,2乘以8等於几的最效率的方法是2 << 3。
7、请设计一个一百亿的计算器
如果只是大整数运算,使用BigInteger就可以
如果有浮点数据参与去处,需要使用BigDecimal进行运算
Java中基本类型的浮点数运算是不精确的,需要使用BigDecimal运算,尤其是金融、会计方向的软件
8、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
引用变量不能重新赋值,但是引用指向的对象的内容可以变化
例1:final StringBuffer a=new StringBuffer(“immutable”);
a=new StringBuffer("");
有编译错
例2:
final StringBuffer a=new StringBuffer(“immutable”);
a.append(“123”);
正确
9、"=="和equals方法究竟有什么区别?
他们的区别主要存在在引用数据类型上
==为比较两侧的对象是否同一对象,是用内存地址来比较的
equals是方法,默认是用内存地址比较,重写后,主要是用来比较两侧的对象的值是否相同,和equals方法中的实现有关
==可以两侧都为null,但equals左侧的引用指向的对象不能空,不然有NullPointerException
除非需要比较两个引用指向的对象是同一对象,一般都使用equals方法进行比较。尤其是String之类的值对象,另外,常量尽量放在比较的左侧
10、静态变量和实例变量的区别?
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。
总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
11、是否可以从一个static方法内部发出对非static方法的调用?
不可以。因为非static方法(实例方法)是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用。也就是说,当一个static方法被调用时,可能还没有创建任何实例对象,如果从一个static方法中发出对非static方法的调用,那个非static方法是关联到哪个对象上的呢?这个逻辑无法成立,所以,一个static方法内部发出对非static方法的调用。
12、Integer与int的区别
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中还定义了表示整数的最大值和最小值的常量。
13、Math.round(11.5)等于多少? Math.round(-11.5)等于多少?
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。
14、请说出作用域public,private,protected,以及不写时的区别
这四个作用域的可见范围如下表所示。
说明:如果在修饰的元素上面没有写任何访问修饰符,则表示friendly/default。
作用域 | 当前类 | 同package | 子孙类 | 其他package |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
friendly | √ | √ | × | × |
private | √ | × | × | × |
备注:只要记住了有4种访问权限,4个访问范围,然后将全选和范围在水平和垂直方向上分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。
15、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
Overload是重载的意思,Override是覆盖的意思,也就是重写。
Overload和Override有共同之处,两个方法的方法名都必须相同,如果不同,既不构成Overload,也不构成Override。
- Override必须发生在父子类之间,Overload可以不在父子类之间
- Override的特点:
a) 参数列表完全相同:个数相同、类型相同、顺序相同
b) 子类的返回值不能比父类的返回值范围大
c) 子类方法抛出的异常不能比父类方法抛出的异常范围大
d) 修饰符只能为public、protected、friendly,不能为private
e) 父子类方法不能使用static修饰
- 重载发生在同一个类或父子类之间,重写中参数列表至少满足个数不同、类型不同、顺序不同中的一个条件,不包含父子类之间的static方法
17、写clone()方法时,通常都有一行代码(不是必须有),是什么?
clone 有缺省行为,**super.clone();**因为首先要把父类中的成员复制到位,然后才是复制自己的成员。
18、面向对象的特征有哪些方面
1. 封装,隐藏内部实现,只暴露公共行为
2. 继承,提高代码的重用性
3. 多态,体现现实生活中相似对象的差异性
4. 抽象,抽取现实世界中相似对象的共同点
19、java中实现多态的机制是什么?
通过继承父类或实现接口。不同子类或实现类对同一父类方法有不同的实现。根据对象调用相应的实现方法。另外对于相似的方法,可以使用重载。
20、abstract class和interface有什么区别?
含有abstract修饰符的class即为抽象类,abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。
下面接着再说说两者在应用上的区别:
接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约;
而抽象类在代码实现方面发挥作用,可以实现代码的重用。
21、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
abstract的method不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系!
native方法表示该方法要用另外一种依赖平台的编程语言实现的,不存在着被子类实现的问题,所以,它也不能是抽象的,不能与abstract混用。
synchronized和abstract合用的问题不能共用,abstract方法只能存在于抽象类或接口中,它不能直接产生对象,而默认synchronized方法对当前对象加锁,没有对象是不能加锁。
另外synchronized不能被继承,子类继承时,需要另加修改符。
22、什么是内部类?Static Nested Class和Inner Class的不同。
内部类就是在一个类的内部定义的类。内部可以定义在除参数位置上的任意位置。印象中有四种方式。
1. 静态内部类需要使用static修饰,而普通内部类不能使用static修饰
2. 静态内部类只能定义在和属性同级,普通内部类可以定义在除参数位置以外的任意位置
3. 静态内部类必需有名称,而普通内部类可以是匿名的
4. 静态内部类没有this引用,只此只能访问外部类的静态成员,而普通内部类可以访问外部类的全部成员
5. 静态内部类访问外部类的同名函数时,使用“外部类名.方法名”即可,而普通内部类需要使用“外部类名.this.外部方法”
6. 静态内部类可以定义静态方法,而普通内部类不能定义静态方法
23、内部类可以引用它的包含类的成员吗?有没有什么限制?
1. 如果内部类为静态内部类,只能调用外部类的静态成员;如果有重名成员,需要用“外部类名.成员名”访问;不能调用外部类的对象成员。
2. 如果内部类为非静态内部类,则可以调用外部类的所有成员;如果有重名成员,需要使用“外部类名.this.外部方法”
24、String是最基本的数据类型吗?
基本数据类型包括byte、int、char、long、float、double、boolean和short。
String是引用数据类型。
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer/StringBuilder类
27、String和StringBuffer的区别
这两个类都实现了CharSequence接口。
1. 类型不同,因为不是一个类,也没有继承关系,做参数时不能共用
2. String对象是不可变对象,不能修改值。而StringBuffer是可变对象,能修改值。
3. 拼接字符串时,String会产生新对象,而StringBuffer只是增加新字符,不产生新对象,因此效率高。
4. String覆盖了equals方法和hashCode方法,而StringBuffer没有覆盖equals方法和hashCode方法,所以,将StringBuffer对象存储进Java集合类中时会出现问题。
28、如何把一段逗号分割的字符串转换成一个数组?
如果不查jdk api,我很难写出来!我可以说说我的思路:
- 用正则表达式,代码大概为:String [] result = orgStr.split(“,”, -1);
- 用 StingTokenizer ,代码为:
StringTokenizer tokener = new StringTokenizer(s, “,”);
String[] result = new String[tokener.countTokens()];
Integer i = 0;
while (tokener.hasMoreTokens()) {
result[i++] = tokener.nextToken();
}
- 最笨的办法,用String.indexOf()
int index = -1;
int oldIndex = 0;
List ss = new ArrayList();
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));
30、final, finally, finalize的区别。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成final类型
final int[] number = { 20 };
new Thread() {
@Override
public void run() {
for (int k = 0; k < 20; k++) {
number[0]++;
}
}
}.start();
Thread.sleep(10);
System.out.println(number[0]);
finally是异常处理语句结构的一部分,表示总是执行,用来释放资源。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用
31、运行时异常(Runtime)与检查异常(Checked)有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
32、error和exception有什么区别?
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出,不可能指望程序能处理这样的情况。exception表示一种设计或实现问题,也就是说,它表示如果程序运行正常,从不会发生的情况。
33、Java中的异常处理机制的简单原理和应用。
异常是指java程序运行时(非编译)所发生的非正常情况或错误。
Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象中,该对象中包含有异常的信息。
Java可以自定义异常类,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception。
- Error表示应用程序本身无法克服和恢复的一种严重问题,程序只有退的份了,例如说内存溢出和线程死锁等系统问题。
- Exception表示程序还能够克服和恢复的问题,其中又分为运行时异常和检查异常,运行时异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉。例如,数组越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);检查异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。
Java为运行时异常和检查异常提供了不同的解决方案,编译器强制检查异常必须try…catch处理或用throws声明继续抛给上层调用方法处理,所以检查异常也称为checked异常,而运行异常可以处理也可以不处理,所以编译器不强制用try…catch处理或用throws声明,所以运行异常也称为Runtime异常。
提示答题者:就按照三个级别去思考:虚拟机必须宕机的错误,程序可以死掉也可以不死掉的错误,程序不应该死掉的错误
34、请写出你最常见到的5个RuntimeException。
NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、IllegelArgumentException、SecurityException。
35、Java语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
- Java语言如何进行异常处理见43题
- throws为向上抛异常
throw程序出错时,手工抛出异常
try尝试执行,里面的语句可能出现异常,如出现异常需要处理
catch处理try中出现的异常
finally在try后执行清理操作,用于释放资源
- 在try中可以抛出异常
36,Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
java5以前,有如下两种:
第一种:
new Thread(){}.start();这表示调用Thread子类对象的run方法,new Thread(){}表示一个Thread的匿名子类的实例对象,子类加上run方法后的代码如下:
new Thread() {
public void run() {
}
}.start();
第二种:
new Thread(new Runnable(){}).start();这表示调用Thread对象接受的Runnable对象的run方法,new Runnable(){}表示一个Runnable的匿名子类的实例对象,runnable的子类加上run方法后的代码如下:
new Thread(new Runnable() {
public void run() {
}
}).start();
从Java5开始,还有如下一些线程池创建多线程的方式:
ExecutorService pool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
pool.execute(new Runable() {
public void run() {
}
});
}
Executors.newCachedThreadPool().execute(new Runable() {
public void run() {
}
});
Executors.newSingleThreadExecutor().execute(new Runable() {
public void run() {
}
});
有两种实现方法,分别使用new Thread()和new Thread(runnable)形式,第一种直接调用thread的run方法,所以,我们往往使用Thread子类,即new SubThread()。第二种调用runnable的run方法。
- 有两种实现方法,分别是继承Thread类与实现Runnable接口。可以的话使用线程池
- 用synchronized关键字修饰同步方法
- 反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
38、同步和异步有何异同,在什么情况下分别使用他们?举例说明。
同步是指所有操作串行化执行,顺序不能改变,前一操作未完成,后个操作不执行。
异步是指所有操作可以并行执行,顺序无关。
例如寄信
同步:如果没有寄完,不能吃饭,邮递员10天后送到,发送人被饿死
异步:寄出后可以立即吃饭,邮递员送完后,通知发送人送信结果。
如果强调执行顺序的话,用同步。如果顺序无关,则可以用异步。
异步执行效率比同步高。
39. 下面两个方法同步吗?(自己发明)
class Test {
synchronized static void sayHello3() {
}
synchronized void getX() {
}
}
40、多线程有几种实现方法?同步有几种实现方法?
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有五种,分别是synchronized、wait与notify、sleep、suspend、join
synchronized: 一直持有锁,直至执行结束
wait():使一个线程处于等待状态,并且释放所持有的对象的lock,需捕获异常。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,需捕获异常,不释放锁。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
41、启动一个线程是用run()还是start()?
启动一个线程是调用start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。
42、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
如果其它方法中使用当前对象作为锁对象,则不能;
如果其它方法中没有使用当前对象作为锁对象,则能。
43、线程的基本概念、线程的基本状态以及状态之间的关系
在多任务操作系统中,为了提高CPU的利用率,可以使用多进程编程。但对进程通信比较困难,进程间数据不能共享,因此可以使用多线程编程。一个进程至少包含一个主入口线程。
单个CPU,在同一时间只能处理一个线程的数据,但是操作系统的任务调度非常快,人眼无法识别,感觉上是多个线程同时执行。有的线程可以已经用完CPU,正在作磁盘操作,此时并不使用CPU,可以让出CPU资源给其它线程使用,提高效率。
线程有生命周期及相关关系和对应方法如下图:
45、介绍Collection框架的结构
Iterable
->Collection
->List
->ArrayList
->LinkedList
->Vector
->Stack
->Set
->HashSet
->TreeSet
Map
->Hashtable
->HashMap
->LinkedHashMap
Collections,不属于集合,是集合类的工具类
Arrays,不属于集合类,是数据对象的工具类
46、ArrayList和Vector的区别
1. 线程同步,Vector线程安全,ArrayList线程不安全
2. 效率问题,Vector效率低,ArrayList效率高
3. 增长数量,Vector以1.5倍增长,ArrayList以2倍增长
47、HashMap和Hashtable的区别
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接口
48、List和 Map区别?
一个是存储单列数据的集合,另一个是存储键和值的双列数据的集合,List中存储的数据是有顺序,并且允许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。
- List有重复值,Map没有重复key,但可以有重复值
- List有序,Map不一定有序
- List只能存单列值,Map可以存双列值
49、List, Set, Map是否继承自Collection接口?
List,Set是,Map不是
50、List、Map、Set三个接口,存取元素时,各有什么特点?
List使用get(index)取值,也可以使用Iterator、toArray取值
Set只能通过Iterator、toArray取值
Map取值使用get(key)取值,也可以使用keySet取键值集合,也可使用values取值集合,entrySet取全部映射。
51、说出ArrayList,Vector, LinkedList的存储性能和特性
1. ArrayList和Vector使用数组存储元素;LinkedList使用链表存储元素
2. ArrayList和Vector插入删除数据时,需要搬运数据,效率较差;LinkedList使用链表,不需要搬运数据,效率高
3. ArrayList和Vectory查询时,按数组下标查询,不需要遍历,效率高;LinkedList需要遍历,查询效率底
4. ArrayList和Vector的区别见59条
51、去掉一个Vector集合中重复的元素
1. 自行遍历,用另外一个Vector来判断是否有重复
2. 用Set(TreeSet或HashSet)来去重
3. 用Apache的CollectionUtil工具类去重
Vector newVector = new Vector();
for (int i = 0; i < vector.size(); i++) {
Object obj = vector.get(i);
if (!newVector.contains(obj))
newVector.add(obj);
}
还有一种简单的方式,HashSet set = new HashSet(vector);
53、Collection和 Collections的区别。
Collection是集合类的上级接口,继承与他的接口主要有Set和List.
Collections是针对集合类的一个工具类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
54、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?
Set里的元素是不能重复的,元素重复与否视具体情况而定:
1. HashSet使用equals比较
2. TreeSet使用compareTo进行比较
55、你所知道的集合类都有哪些?主要方法?
最常用的集合类接口是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
56、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
1. equals等,hashCode同,因此重写equals方法必须重写hashCode
2. hashCode等,equals不一定同,但hashCode最好散列化
3. 任何对象equals null都得false
4. 没有继承关系的两个类,equals都得false
5. 重写equals方法的类最好是值类,即不可变
68、说出一些常用的类,包,接口,请各举5个
要让人家感觉你对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
59、Java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
字节流,字符流。字节流继承于InputStream、OutputStream,字符流继承于Reader、Writer。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便。
FileInputStream、FileReader、BufferedInputStream、BufferedReader、ZipInputStream、PrintStream、StringReader、ObjectInputStream、RandomAccessFile(不属于流,但像流)
60、字节流与字符流的区别
字节流是按字节读取或写入设备,但字符流是以字符为单位读取或写入设备。
如果是二进制文件,需要用字节流读取。一般来说,字符流只处理文本文件。在设备中,大多数情况是以字节形式存储数据的,因此字符流通过需要传入字节流当参数。
61、什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。
序列化是把内存Java对象保存到存储介质中,反序列化就是把存储介质中的数据转化为Java对象。Java通过ObjectInputStream和ObjectOutputStream实现序列化和反序列化。需要进行序列化的对象的类必须实现Serializable接口,通常情况下需要满足以下条件:
1. 强烈建议手动生成serialVersionUID常量
2. 如果需要加解密的话,需要实现两个方法readObject和writeObject方法
3. 如果使用Hibernate二级缓存或其它缓存服务器的话,对象必须是可序列化的
4. 如果需要远程调用对象或传值的话,则对像需要序列化
5. 序列化类的可序列化成员必须也是可序列化的,不需要序列化的属性用transient修饰
62、描述一下JVM加载class文件的原理机制?
1. 查找当前ClassLoader中是否有此class的类对象,有则返回
2. 若没有的话,向上递归所有的父ClassLoader中有无此class类对象,有则返回
3. 若还没有,查找BootstrapClassLoader中有无此class类对象,有则返回
4. 若还没有的话,使用findClass或resolveClass加载类对象
a. 读取class二进制文件
b. 根据字节数组生成Class对象
c. 缓存到当前ClassLoader中
JVM加载class对象是懒加载,按需加载
63、heap和stack有什么区别。
Java的内存分为两类,一类是栈内存,一类是堆内存。
栈中存储的是当前线程的方法调用、基本数据类型和对象的引用,栈是有序的。
堆中存储的是对象的值,堆是无序的。
方法中的局部变量使用final修饰后,放在堆中,而不是栈中。
64、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。
65、什么时候用assert。
assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,assert将给出警告或退出。一般来说,**assertion用于保证程序最基本、关键的正确性。**assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。
66、能不能自己写个类,也叫java.lang.String?
可以,如果非要实现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;
public class String {
public static void main(String[] args) {
System.out.println(“string”);
}
}
报告的错误如下:
java.lang.NoSuchMethodError:main
Exception inthread “main”
这是因为加载了jre自带的java.lang.String,而该类中没有main方法。
67、SSH集成方式
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中管理
二.算法与编程
1、编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替合并到c.txt文件中,a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格进行分隔。
答:
package com.bwie.interview;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.StringTokenizer;
public class AnswerB01 {
public static void main(String[] args) throws IOException {
StringTokenizer tokenizer1 = getTokenzer("/a.txt");
StringTokenizer tokenizer2 = getTokenzer("/b.txt");
PrintStream out = new PrintStream(“C:/c.txt”);
while (tokenizer1.hasMoreTokens() && tokenizer2.hasMoreTokens()) {
out.println(tokenizer1.nextToken());
out.println(tokenizer2.nextToken());
}
out.close();
}
private static StringTokenizer getTokenzer(String fileName) throws IOException {
InputStreamReader reader = new InputStreamReader(AnswerB01.class.getResourceAsStream(fileName));
StringBuilder builder = new StringBuilder(1000);
int length = -1;
char[] cs = new char[1024];
while ((length = reader.read(cs)) != -1) {
builder.append(cs, 0, length);
}
reader.close();
return new StringTokenizer(builder.toString());
}
}
2、编写一个程序,将d:java目录下的所有.java文件复制到d:jad目录下,并将原来文件的扩展名从.java改为.jad。
(大家正在做上面这道题,网上迟到的朋友也请做做这道题,找工作必须能编写这些简单问题的代码!)
答:listFiles方法接受一个FileFilter对象,这个FileFilter对象就是过虑的策略对象,不同的人提供不同的FileFilter实现,即提供了不同的过滤策略。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
public class AnswerB02 {
public static void 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));
}
}
private static void copy(File source, File target) throws IOException {
FileInputStream input = new FileInputStream(source);
FileOutputStream out = new FileOutputStream(target);
int length = -1;
byte[] bs = new byte[1024];
while ((length = input.read(bs)) != -1) {
out.write(bs, 0, length);
}
input.close();
out.close();
}
private static final class JavaFileFilter implements FilenameFilter {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
}
}
3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉的半个”。
import java.io.IOException;
public class AnswerB03 {
public static void main(String[] args) throws IOException {
String s = “我ABC汉DEF”;
System.out.println(substring(s, 6));
}
public static String substring(String s, int length) {
char[] cs = s.toCharArray();
StringBuilder builder = new StringBuilder();
int count = 0;
for (char c : cs) {
if (isAsc©) {
count++;
} else {
count += 2;
}
if (count > length) {
break;
}
builder.append©;
}
return builder.toString();
}
public static boolean isAsc(char c) {
return c < 128;
}
}
4、有一个字符串,其中包含中文字符、英文字符和数字字符,请统计和打印出各个字符的个数。
答:哈哈,其实包含中文字符、英文字符、数字字符原来是出题者放的烟雾弹。
String content = “中国aadf的111萨bbb菲的zz萨菲”;
HashMap map = new HashMap();
for (int i = 0; i < content.length; i++) {
char c = content.charAt(i);
Integer num = map.get©;
if (num == null)
num = 1;
else
num = num + 1;
map.put(c, num);
}
for (Map.EntrySet entry : map) {
system.out.println(entry.getkey() + “:” + entry.getValue());
}
估计是当初面试的那个学员表述不清楚,问题很可能是:
如果一串字符如"aaaabbc中国1512"要分别统计英文字符的数量,中文字符的数量,和数字字符的数量,假设字符中没有中文字符、英文字符、数字字符之外的其他特殊字符。
int engishCount;
int chineseCount;
int digitCount;
for (int i = 0; i < str.length; i++) {
char ch = str.charAt(i);
if (ch >= ‘0’ && ch <= ‘9’) {
digitCount++;
} else if ((ch >= ‘a’ && ch <= ‘z’) || (ch >= ‘A’ && ch <= ‘Z’)) {
engishCount++;
} else {
chineseCount++;
}
}
5、说明生活中遇到的二叉树,用java实现二叉树
这是组合设计模式。
我有很多个(假设10万个)数据要保存起来,以后还需要从保存的这些数据中检索是否存在某个数据,(我想说出二叉树的好处,该怎么说呢?那就是说别人的缺点),假如存在数组中,那么,碰巧要找的数字位于99999那个地方,那查找的速度将很慢,因为要从第1个依次往后取,取出来后进行比较。平衡二叉树(构建平衡二叉树需要先排序,我们这里就不作考虑了)可以很好地解决这个问题,但二叉树的遍历(前序,中序,后序)效率要比数组低很多,原理如下图:
代码如下:
public class AnswerB04 {
public static void main(String[] args) {
Node root = makeupTree();
traverse(root);
}
private static void traverse(Node node) {
if (node == null) {
return;
}
traverse(node.left);
System.out.println(node.value);
traverse(node.right);
}
private static 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;
}
public static class Node {
public Node left;
public Node right;
public int value;
public Node(int value) {
this.value = value;
}
}
}
8、递归算法题1
一个整数,大于0,不用循环和本地变量,按照n,2n,4n,8n的顺序递增,当值大于5000时,把值按照指定顺序输出来。
例:n=1237
则输出为:
1237,
2474,
4948,
9896,
9896,
4948,
2474,
1237,
提示:写程序时,先致谢按递增方式的代码,写好递增的以后,再增加考虑递减部分。
public static void doubleNum(int n) {
System.out.println(n);
if (n <= 5000)
doubleNum(n * 2);
System.out.println(n);
}
Gaibaota(N) = Gaibaota(N-1) + n
9、递归算法题2
第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?
package cn.itcast;
import java.util.Date;
public class A1 {
public static void main(String[] args) {
System.out.println(computeAge(8));
}
public static int computeAge(int n) {
if (n == 1)
return 10;
return computeAge(n - 1) + 2;
}
}
public static void toBinary(int n, StringBuffer result) {
if (n / 2 != 0)
toBinary(n / 2, result);
result.append(n % 2);
}
10、排序都有哪几种方法?请列举。用JAVA实现一个快速排序。
本人只研究过冒泡排序、选择排序和快速排序,下面是快速排序的代码:
冒泡排序:
private static void bubbleSort(int[] array) {
for (int i = 1; i < array.length; i++) {
for (int j = 0; j < i; j++) {
if (array[i] < array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
快速排序:
public class QuickSort {
public void 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);
}
}
public static void 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 < strVoid.length; i++) {
System.out.println(strVoid[i] + " ");
}
}
}
11、有数组a[n],用java代码将数组元素顺序颠倒
public class AnswerB11 {
public static void main(String[] args) {
int[] array = { 2, 25, 21, 63, 234, 83 };
reverse(array);
System.out.println(Arrays.toString(array));
}
private static void reverse(int[] array) {
for (int i = 0; i < array.length / 2; i++) {
int temp = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = temp;
}
}
}
12 不使用递归遍历二叉树
import java.util.Stack;
public class AnswerB13 {
public static void main(String[] args) {
Node tree = makeupTree();
Stack stack = new 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;
}
}
}
}
private static 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;
}
public static class Node {
public Node left;
public Node right;
public int value;
public Node(int value) {
this.value = value;
}
}
}
三.前端页面部分
3.当service有一个实例变量,doGet和doPost去调用这个变量,会出现什么问题,你是如何解决的。
会出现线程不安全问题。无论是doGet还是doPost去调用,服务器端处理的过程都是一样的,那么我们可以把处理过程单独写在另外一个方法handle里,让两个方法都去调用handle,根据不同请求去调用不同的方法。
4.有三台服务器,如果在一台服务器上登陆了这个用户,其他两台就不能再登陆这个用户,使用session共享,你是怎么做的。
把所有的session的数据保存到Mysql服务器上,所有Web服务器都来这台Mysql服务器来获取Session数据。
5.写一个自定义标签要继承什么类
SimpleTagSupport,一般调用doTag方法或者实现SimpleTag接口
6.Jsp如何处理json
在 jsp 中处理 JSON,通常需要配套使用 JQuery 控件,并且导入一些 Common jar 包。使用 JQuery 控件是因为它能有效的解析并且展示 JSON 数据,导入Common 则是因为 Java 中的对象并不是纯粹的数据,需要通过这些 Jar 包的处理使之转化成真实数据。
7.Jsp的重定向和转发的流程有什么区别
重定向是客户端行为,转发是服务器端行为
重定向时服务器产生两次请求,转发产生一次请求,重定向时可以转发到项目以外的任何网址,转发只能在当前项目里转发
重定向会导致request对象信息丢失。转发则不会
转发的url不会变,request.getRequestDispatch()。forward()
重定向的url会改变,response.getRedirect();
8.Jsp和servlet的区别
jsp的可读性强,容易维护,并且jsp在最后会编译成servlet,servlet容易调试。
9.jsp可以操作窗口吗?
Jsp不能够直接调用窗口,只能先 生成打开窗口的js,再由js调用
10.session的主要几个方法的区别
Session不能通过new创建,需要通过调用getSession()或者getSession(true)方法创建,getSession()是自动创建session,getSession(true)是强制创建session,setAttribute()方法可以用于传值,getAttribute()可以用于取值
(第一次创建session的时候,就是访问第一次一个jsp页面<这个页面的page指令 没有设置session=false>)
销毁session调用invalidate方法
通过setMaxInactiveInterval()可以设定session的生存时间(web.xml可以设置session的生存时间)
11.jsp的三大指令,七大动作的具体功能
三大指令:
Page :指令是针对当前页面的指令 Include :用于指定如何包含另一个页面 Taglib :用于定义和指定自定义标签
七大动作:
Forward,执行页面跳转,将请求的处理转发到另一个页面 Param :用于传递参数 Include :用于动态引入一个jsp页面 Plugin :用于下载javaBean或applet到客户端执行 useBean :使用javaBean setProperty :修改javaBean实例的属性值 getProperty :获取javaBean实例的属性值
12.获取页面的元素和值有几种方式,分别说一下
request.getParameter() 返回客户端的请求参数与值
request.getParameterNames() 返回所有可用属性名的枚举
request.getParameterValues() 返回包含参数的所有值的数组
13.servlet和javaScript的区别,他们分别是什么作用
一个是服务端,一个是客户端
Servlet是独立于平台和协议的服务器端的java应用程序,可以动态生成web页面,并采用响应--请求的模式提供web服务
javaScript是一种解释性语言,用于向html页面提供交互行为,通常被直接嵌入在html页面中
servlet是java语言编写的web应用
js是基于html上的一种解释语言
14.jsp的执行原理
客户端发出请求(request),jsp引擎将jsp页面翻译成servlet的java源文件,在Tomcat中将源文件编译成class文件,并加载到内存中执行,把结果返回(response)给客户端。
16.HTML和Servlet的异同
不同: Html是静态,servlet是动态 html页面由服务器直接返回, servlet是用来处理客户请求,并返回html页面 //servlet需要服务器调用servlet方法生成动态html页面,且需要在web.xml中配置url路径
17.会话跟踪有哪些,他们的区别是什么
Cookie,session和application, Cookie是http对象,客户端与服务端都可以操纵
cookie是在客户端保持状态,session是在服务器端保持状态,由于cookie是保存在客户端本地的,所以数据很容易被窃取,当访问量很多时,使用session则会降低服务器的性能,application的作用域是整个工程里只有一个,可以在不同浏览器之间共享数据,所有人都可以共享,因此application也是不安全的
18.session和application的作用
Session用于客户端与服务器之间保持状态的解决方案,数据保存在服务器内存中,底层是有cookie实现的
Application的作用域是整个工程里只有一个,可以在不同浏览器之间共享数据,所有人都可以共享,因此application是不安全的。
19.request ,response,session 和 application是怎么用的
Request是客户端向服务端发送请求
Response是服务端对客户端请求做出响应
Session在servlet中不能直接使用,需要通过getSession()创建,如果没有设定它的生命周期,或者通过invildate()方法销毁,关闭浏览器session就会消失
Application不能直接创建,存在于服务器的内存中,由服务器创建和销毁
20.有几种方式将页面的值传到后台
可通过form表单的get或post将值传递到后台,也可通过setAttribute()方法将值传递到后台
21.一个form表单的值如何获取
在servlet中通过request.getParameter()方法可以获取表单的值 或者是request.getParameterValuse();
22.传递参数到后台有几种方式
表单传参,url传参,jquery.ajax传参
23.Jsp中父页面中怎么拿到子页面的表单元素,不是拿值怎么拿
通过设置属性setAttribute(),通过getAttribute()拿值,getParameter()方法可以做到
24.定义一个String类型的字符串,如果重定向之后还能不能获得这个数据
不能
25.404和500是什么意思
404 :找不到url请求的路径,一般是工程名不对或者拼写错误
500 :服务器内部错误,一般是服务器内部代码编写错误,也有可能是抛异常导致
26.写出5种JSTL常用标签
<c:if>,<c:item>,<c:foreach>,<c:out>,<c:set>
28.Jsp页面把一个元素隐藏的方法
通过使用属性hidden可以将元素隐藏
29.Session,application,cookie的区别
Session不能通过new创建,要通过调用getSession()方法创建,数据保存在服务器端,单个客户端session是共享的,底层是由cookie实现的,大小没有限制
Application的作用域是整个工程只有共享一个,生命周期比session大
Cookie需要通过new创建,数据保存在客户端中,cookie保存的数据不能超过4k,不安全
30.我们在web应用开发过程中经常遇到输出某种编码的字符,如ISO-8859-1,如何输出一个某种编码的字符串
如将ISO-8859-1输出为GBK格式的字符, 通过new String(byte[] bytes,String charset) 构造器设置编码构造一个新的String(new String("ISO-8859-1","GBK"));
32.怎么判断用户请求时是第一次,如果客户端和服务端断开怎么连到上一次操作
通过session中的isNew()可以判断是否是新用户
33.如果创建servlet实例不用构造方法,怎么创建一个servlet实例
Web容器会自动为servlet写一个无参的构造器,它使用class.forName("").newInstance()反射来创建servlet实例的
34.Servlet是安全的吗?当service有一个实例变量,doGet和doPost去调用这个变量,会出现什么问题,你是如何解决的
是线程不安全的,因为servlet是单例模式,当多个客户端共同访问的时候线程不安全。
尽量用局部变量,同步块,如果当前字段是不会改变的,用final修饰
36.说明一下jsp中<jsp: include page…>和<%@ include file%>的区别
<jsp:include page=""/> 动态导入
是行为元素、是在请求处理阶段引入的,引入执行页面或servlet所生成的应答文本
先编译,后包含,就是将每个jsp页面都单独转化成html页面,最后再将所有的html页面相加,如果有相同变量不会冲突
<%@ include file="" %> 静态导入
是指令元素
是编译时包含,引入静态文本(html,jsp),在JSP页面被转化成servlet之前和它融和到一起。先包含,后编译
就是将多个jsp一起解析,最后再一起生成html页面,如果有相同变量会冲突
37. pageContext有什么作用
可以使用pageContext对象来设定属性,并指定属性的作用范围,提供了对JSP页面内所有的对象及名字空间的访问
39.Filter与拦截器怎么执行的
首先初始化过滤器,然后服务器组织过滤器链,所有的请求都必须需要先通过过滤器链,
过滤器链是一个栈,遵循先进后出的原则 ,所有的请求需要经过一个一个的过滤器,执行顺序要根据web.xml里配置的<filter-mapping>的位置前后执行,每个过滤器之间通过chain.doFilter连接, 最后抵达真正请求的资源,执行完后再从过滤器链退出
40.Jsp中如何进行分页,项目中如何进行分页?
需要上一页和下一页的超链接(至少需要这两个),通过计算当前页的页码获取下一页数据
的起始位置,然后在 MySql 中查询,如果使用 Oracle 则需要另外计算下一页数据的结
束位置。
使用hibernate框架,它可以针对不同的数据库自动产生为你分页的代码。
41,关于Ajax的技术组成与核心原理
1、Ajax特点: 局部刷新、提高用户的体验度,数据从服务器商加载。 2、AJax的技术组成:不是新技术,而是之前技术的整合 Ajax: Asynchronous Javascript And Xml;(异步的JavaScript和XML) 包括的技术:JavaScript、XML、CSS、XMLHttpRequest 异步:发送请求以后,不等结果,由回调函数处理。 JavaScript:向服务器发送请求,获得返回结果,更新页面 XML: 用来封装数据
3、Ajax核心原理 XMLHttpRequst对象:通过该对象向服务器发送请求。 它是异步请求的技术,所有现代浏览器都支持(Chrome、IE5+) 1)创建XMLHttpReuest对象 非IE浏览器(Mozilla/Safari): var xhr=new XMLHttpRequest(); IE: xhr=new ActiveXObject(“Msxml2.XMLHTTP”); 低版本IE: xhr=new ActiveXObject(“Microsfot.XMLHTTP”); 2)XMLHttpRequest对象的属性与方法 a)方法: open(“GET/POST”,URL,true/false):用来向服务器建立连接 有三个参数: 参数1:提交方式,post或get 参数2:请求的URL 参数3:表示同步或异步请求,true:表示异步请求 false: 表示同步请求
send(data):发送请求 参数:提交的内容。
POST方式:data就是提交的参数,send(username=root&password=abc123);
GET方式:send(null)
b)属性: onreadystatechange:设置状态改变时的回调函数,回调函数用来获取服务器数据。
onreadystatechange=function(){
}
readyState:服务器状态响应 状态码: 0:未初始化 1:正在加载 2:加载完成 3:请求进行中 4:请求完成 responseText:服务器返回的数据(文本格式)
responseXML:服务器返回的数据(XML格式)
43.Xhtml和html有什么区别。
Html(超文本标记语言)是标准通用标记语言下的一个应用,也是一种规范,一种标准。
Xhtml(可扩展超文本标记语言)是一种置标语言,表现方式与html类似,不过语法上更加严格,主要不同:
1,所有元素必须被正确嵌套,
2,所有标记必须闭合,
3,标签名,属性名必须小写字母,
4,所有的属性必须用“”括起来,
5,所有非标签一部分的><&都必须以编码形式,
6,所有属性必须要有值,
7,注释中不要有–
8,图片必须要有说明文字
44.css的引入方式有哪些?link和@import的区别是?
四种:内联,内嵌,外链,导入
区别:
1,link属于xhtml标签,@import完全是css提供的一种方式,link除了加载css还可以定义rss,定义rel属性等,@import只能加载css。
2,加载顺序差别:link引用的css是同时被加载的,@import引用的css会等到页面全部被下载完才会再被加载。
3,兼容性差别,@import是css2.1提出,ie5以上才支持,link没有兼容问题。
4,使用dom控制样式的差别,当用javascript去控制样式的时候,只能使用link,@import不是dom能控制的。
5,@import可以在css中再次引入其他样式表。
45.css选择符有哪些?哪些属性可以继承?优先级如何计算?内联和important哪个优先级高?
标签选择符,类选择符,id选择符,继承的不如指定的,id>class>Tagname
Important优先级高
46.前端页面由哪三层构成,分别是什么?作用是什么?
结构层:html由html或者xhtml负责创建,运用标签对网页内容的含义作出描述。
表示层:css由css负责创建,对如何显示有关内容做出回答。
行为层:javascript由javascript负责创建,负责回答应该如何对事件作出反应。
47.你曾经在哪些浏览器测试过兼容?这些浏览器的内核分别是什么?
Ie(ie内核),火狐(Gecko),谷歌(webkit),opera(presto)
48.标签上title与alt属性的区别是什么?
Alt是在你的图片因为某种原因不能加载的时候在页面显示的提示信息,它会直接输出在原本加载图片的地方,title是在鼠标悬停在图片上的显示的小提示,鼠标离开就没了,绝大数html标签都支持title。
50.描述css reset的作用和用途。
Css reset重置浏览器的默认css样式,浏览器种类不同,默认样式不一样,通过使用css reset重置,让他们统一,方便开发。
51.你如何对网站的文件和资源进行优化?期待的解决方案包括:
1,尽可能减少http请求数(文件合并)
2,使用CDN(内容分发网络)
3,添加Expire/Cache-Control头
4,启用Gzip压缩
5,css放在页面最上面
6,scrip放在页面最下面
7,避免在css中使用Expressions
8,把js和css放在外部文件中
9,减少dns查询
10,压缩javascript和css
11,避免重定向
12,移除重复脚本
13,配置实体标签
14,使用ajax缓存
52.什么是语义化的html?
根据内容的结构化(内容语义化),选择合式的标签(代码语义化),便于开发者的阅读和写出更加优雅的代码的同时让浏览器的爬虫和机器更好地解析。
53.清除浮动有几种方式?各自的优缺点是?
1,父级定义height(优点:代码少,简单易掌握;缺点:只适合固定高度元素,无法高度自适应)
2,结尾处使用空标签清除浮动:Clear:both(优点:理论上能清除所有标签的浮动,简代码少浏览器支持好;缺点:增加了无意义的标签)
3,父级定义伪类after和zoom(优点:浏览器支持好;缺点:代码多,两句代码结合使用才能让主流浏览器都支持)
4,父级定义overflow:hidden(优点:代码少,简单,浏览器支持好;缺点:必须定义width或者zoom,同时不能定义height,不能和position配合使用)
5,父级定义overflow:auto(优点:代码少,简单,浏览器支持好;缺点:必须定义width或者zoom,同时不能定义height,内部元素高度超过父级会出现滚动条
还有,父级一起浮动,父级定义display:table,结尾加br的clear:both等
54.解释下 CSS sprites,以及你要如何在页面或网站中使用它?
是一种网页图片应用处理方式。它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去,这样一来,当访问该页面时,载入的图片就不会像以前那样一幅一幅地慢慢显示出来了。页面icon很多的情况下使用合适。
55,html5有哪些新特性、移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和HTML5??
HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。
绘画 canvas用于媒介回放的 video 和 audio 元素本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;sessionStorage 的数据在浏览器关闭后自动删除
语意化更好的内容元素,比如 article、footer、header、nav、section
表单控件,calendar、date、time、email、url、search
新的技术webworker, websockt, Geolocation
移除的元素
纯表现的元素:basefont,big,center,font, s,strike,tt,u;
对可用性产生负面影响的元素:frame,frameset,noframes;
支持HTML5新标签:
IE8/IE7/IE6支持通过document.createElement方法产生的标签,
可以利用这一特性让这些浏览器支持HTML5新标签,
浏览器支持新标签后,还需要添加标签默认的样式:
当然最好的方式是直接使用成熟的框架、使用最多的是html5shim框架
如何区分: DOCTYPE声明新增的结构元素功能元素
56.javascript的同源策略。
一段脚本只能读取来自于同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合
57、HTML的 form提交之前如何验证数值文本框的内容全部为数字?否则的话提示用户并终止提交?
<input type=“text” name=“d1” />
<input type=“submit” />
60. jsp有哪些动作?作用分别是什么?
(这个问题似乎不重要,不明白为何有此题)
答:JSP共有以下6种基本动作
jsp:include:在页面被请求的时候引入一个文件。
jsp:useBean:寻找或者实例化一个JavaBean。
jsp:setProperty:设置JavaBean的属性。
jsp:getProperty:输出某个JavaBean的属性。
jsp:forward:把请求转到一个新的页面。
jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记
61、JSP的常用指令
isErrorPage(是否能使用Exception对象),isELIgnored(是否忽略表达式)
62. JSP中动态INCLUDE与静态INCLUDE的区别?
<jsp:include page=included.jsp flush=true />它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数 静态INCLUDE用include伪码实现,不会检查所含文件的变化,适用于包含静态页面 <[%@include file=included.htm %](https://www.cnblogs.commailto:%@include file%3Dincluded.htm %/)>
标签不同
执行的时机不同,动态include是在运行时把两个JSP合并,静态include是在编译期合并动态include在页面发生改变时,能及时更新,而静态页面,不会再次重新编译
63、页面间对象传递的方法
1. request
2. session
3. application
4. cookie
5. URL地址
三. Java web部分
1、Tomcat的优化经验
1. 内存优化-Xms
2. 增加线程数maxThreads=“150”
3. 修正server.xml中的中文编码
4. BIO改NIO
2、HTTP请求的GET与POST方式的区别
答:
1. URL地址长度不同, GET支持的字符少
2. GET的密码是明文,安全问题,容易受到黑客攻击
3. GET只传输文本,不支持文件传输
4. GET方式通常用来查询,不用来修改数据,是幂等操作,修改数据用POST
3、解释一下什么是servlet;
答: 通常Servlet特指HttpServlet,用来接受浏览器的访问请求,浏览器最常用的请求为GET和POST方式,还有其它五种,而HttpServlet分别有七个方法(PUT、DELETE、HEADER、TRACE、OPTION)处理这些类型的请求,另有一个是J2EE不支持的,是CONNECT。Servlet是J2EE规范中的重要成员,是构成WEB的重要组件
4、说一说Servlet的生命周期?
1. 加载Servlet类
2. 实例化
3. 初始化init
4. 处理请求 service à 进一步调用doGet/doPost方法
5. 销毁 destory
5、Servlet的基本架构
1. 定义一个Servlet类,继承HttpServlet抽象类
2. 在web.xml中定义一个servlet标签,配置类名和servlet名
3. 配置servlet处理的URL请求连接,可以用模糊匹配
4. 在J2EE生命周期中,一个Servlet只有一个实例
5. 一个Servlet可以为多个请求服务,每个请求在独立的线程中执行
6、Servlet API中forward()与redirect()的区别?
Forward: 服务器端内部跳转,URL地址不变,属于单次请求
Redirect: 服务器通知浏览器中转,URL地址发生改变,是两次跳转
Forward不能跨域跳转
Redirect可以跨域跳转
Forward在两个页面传值可以通过parameter,也可以通过attribute,能传递Java对象
Redirect在两个页面传值只能通过parameter,在URL中传参
7、Request对象的主要方法:
setAttribute(String name,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(String name):获得有name指定的参数的所有值
getProtocol():获取客户端向服务器端传送数据所依据的协议名称
getQueryString():获得查询字符串
getRequestURI():获取发出请求字符串的客户端地址
getRemoteAddr():获取客户端的IP地址
getRemoteHost():获取客户端的名字
getSession([Boolean create]):返回和请求相关Session
getServerName():获取服务器的名字
getServletPath():获取客户端所请求的脚本文件的路径
getServerPort():获取服务器的端口号
removeAttribute(String name):删除请求中的一个属性
8、request.getAttribute()和 request.getParameter()有何区别?
1. getParameter是表单数据或URL参数,不能在server端修改
getAttribute是两个页面或servlet之间内部跳转传递对象参数,可以修改
2. getParameter的类型只能是String
getAttribute的类型可以是任意Java对象
3. forward跳转时才有attribute,redirect时,attribute全部为null
9、MVC的各个部分都有那些技术来实现?如何实现?
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展示框架,作者江南白衣
10、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso-8859-1等,如何输出一个某种编码的字符串?
public String translate(String str) {
try {
return new String(str.getBytes(“ISO-8859-1”), “GBK”).trim();
} catch (Exception e) {
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
}
四.数据库部分
1、用两种方式根据部门号从高到低,工资从低到高列出每个员工的信息。
employee: eid, ename, salary, dept_id
select * from employee order by dept_id desc, salary;
2、ORACLE和MySQL的区别。
1. Oracle是大型数据库而Mysql是中小型数据库,Oracle市场占有率达40%,Mysql只有20%左右,同时Mysql是开源的而Oracle价格非常高Oracle。
2. Oracle支持大并发,大访问量,是OLTP最好的工具。(OLTP[联机事务处理])(OLAP[数据仓库处理 有了基础大数据后 根据数据分析 市场定位])。
3. 安装所用的空间差别也是很大的,Mysql安装完后才几百M而Oracle有几G左右,且使用的时候Oracle占用特别大的内存空间和其他机器性能。
4.Oracle和Mysql操作上的一些区别【开发人员接触的】
①主键Mysql一般使用自动增长类型,在创建表时只要指定表的主键为auto_increment,插入记录时,不需要再指定该记录的主键值,Mysql将自动增长;Oracle没有自动增长类型,主键一般使用的序列,插入记录时将序列号的下一个值付给该字段即可;只是ORM框架是只要是native主键生成策略即可。
②单引号的处理MYSQL里可以用双引号包起字符串,ORACLE里只可以用单引号包起字符串。在插入和修改字符串前必须做单引号的替换:把所有出现的一个单引号替换成两个单引号。
③翻页的SQL语句的处理MYSQL处理翻页的SQL语句比较简单,用LIMIT开始位置,记录个数;ORACLE处理翻页的SQL语句就比较繁琐了。每个结果集只有一个ROWNUM字段标明它的位置,并且只能用ROWNUM<100,不能用ROWNUM>80
④ 长字符串的处理长字符串的处理ORACLE也有它特殊的地方。INSERT和UPDATE时最大可操作的字符串长度小于等于4000个单字节,如果要插入更长的字符串,请考虑字段用CLOB类型,方法借用ORACLE里自带的DBMS_LOB程序包。插入修改记录前一定要做进行非空和长度判断,不能为空的字段值和超出长度字段值都应该提出警告,返回上次操作。
⑤空字符的处理MYSQL的非空字段也有空的内容,ORACLE里定义了非空字段就不容许有空的内容。按MYSQL的NOT NULL来定义ORACLE表结构,导数据的时候会产生错误。因此导数据时要对空字符进行判断,如果为NULL或空字符,需要把它改成一个空格的字符串。
⑥字符串的模糊比较MYSQL里用 字段名 like ‘%字符串%’,ORACLE里也可以用 字段名like '%字符串%'但这种方法不能使用索引,速度不快。【like ‘%’开头 无法使用索引 不使用开头 可以使用索引】
⑦Oracle实现了ANSII SQL中大部分功能,如,事务的隔离级别、传播特性等而Mysql在这方面还是比较的弱
3、存储过程和函数的区别。
1). 可以理解函数是存储过程的一种 ,都是预编译的 【块语句每次运行都会编译 存储过程块 一次编译多次运行 效率更高】 Plsql块语句 Begin End 存储过程块 Create procedure prg_add() As Begin End; 2). 函数可以没有参数,但是一定需要一个返回值,存储过程可以没有参数,不需要返回值 3). 函数return返回值没有返回参数模式,存储过程通过out参数返回值,如果需要返回多个参数则建议使用存储过程 【函数oracle 在函数可以使用in和out mysql不能使用out】 4). 在sql数据操纵(DML)语句中只能调用函数而不能调用存储过程
4、Oracle导入和导出方式
使用oracle工具exp/imp
使用plsql相关工具 1. 导入/导出的是二进制的数据,
2.plsql导入/导出的是sql语句的文本文件
5、Oracle分页方法
Oracle中使用rownum来进行分页,这个是效率最好的分页方法,hibernate也是使用rownum来进行oralce分页的select * from ( select rownum r,a from tabName where rownum <= 20 )where r > 10
6、mysql的分页方法
select * from content order by id desc limit 0, 10
在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的问题就是确保使用了索引。随着数据量的增加,页数会越来越多,查看后几页的SQL就可能类似:
select * from content order by id desc limit 10000, 10
一言以蔽之,就是越往后分页,LIMIT语句的偏移量就会越大,速度也会明显变慢。
此时,我们可以通过2种方式:
一,子查询的分页方式来提高分页效率,飘易用的SQL语句如下:
SELECT * FROM content
WHERE id (SELECT id FROM content
ORDER BY id desc LIMIT “.(
p
a
g
e
−
1
)
∗
page-1)*
page−1)∗pagesize.”, 1) ORDER BY id desc LIMIT $pagesize
为什么会这样呢?因为子查询是在索引上完成的,而普通的查询时在数据文件上完成的,通常来说,索引文件要比数据文件小得多,所以操作起来也会更有效率。(via)通过explain SQL语句发现:子查询使用了索引!
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY content range PRIMARY PRIMARY 4 NULL 6264 Using where
2 SUBQUERY content index NULL PRIMARY 4 NULL 27085 Using index
7、解释什么是死锁,如何解决Oracle中的死锁?
简言之就是存在加了锁而没有解锁,可能是使用锁没有提交或者回滚事务,如果是表级锁则不能操作表,客户端处于等在状态,如果是行级锁则不能操作锁定行
解决办法:
1). 查找出被锁的表
select b.owner,b.object_name,a.session_id,a.locked_mode
from v$locked_object a,dba_objects b
where b.object_id = a.object_id;
select b.username,b.sid,b.serial#,logon_time
from v l o c k e d o b j e c t a , v locked_object a,v lockedobjecta,vsession b
where a.session_id = b.sid order by b.logon_time;
2). 杀进程中的会话
alter system kill session “sid,serial#”;
8、列出各个部门中工资高于本部门的平均工资的员工数和部门号,并按部门号排序
employee: eid, ename, salary, dept_id
select count(*), a.dept_id
from employee a
where
a.salary > (select avg(b.salary) from employee b where b.dept_id = ‘本部门’)
group by a.dept_id
order by a.dept_id
9、存储过程与触发器必须讲,经常被面试到?
create or replace procedure insert_Student (_name varchar, _age int , out_id int)
declear
a varchar
begin
insert into studentvalue(null,_name,_age);
select max(stuId)into _id from student;
end;
call insert_Student(‘wfz’,23,@id);
select @id;
mysql> create trigger update_Student BEFORE update on student FOR EACH ROW
-> select * from student;
触发器不允许返回结果
create trigger update_StudentBEFORE update on student FOR EACH ROW
insert into student value(null,‘zxx’,28);
mysql的触发器目前不能对当前表进行操作
create trigger update_StudentBEFORE update on student FOR EACH ROW
delete from articles where id=8;
这个例子不是很好,最好是用删除一个用户时,顺带删除该用户的所有帖子
这里要注意使用OLD.id
触发器用处还是很多的,比如校内网、开心网、Facebook,你发一个日志,自动通知好友,其实就是在增加日志时做一个后触发,再向通知表中写入条目。因为触发器效率高。而UCH没有用触发器,效率和数据处理能力都很低。
存储过程的实验步骤:
mysql> delimiter |
mysql> create procedure insertArticle_Procedure (pTitle varchar(50),pBid int,out
pId int)
-> begin
-> insert into article1value(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(id intprimary key auto_increment,name varchar(50),ar
ticleCount int);
create table article1(id intprimary key auto_increment,title varchar(50)
,bid int referencesboard1(id));
delimiter |
create triggerinsertArticle_Trigger after insert on article1 for each ro
w begin
-> update board1 setarticleCount=articleCount+1 where id= NEW.bid;
-> end;
-> |
delimiter ;
insert into board1 value(null,‘test’,0);
insert into article1value(null,‘test’,1);
还有,每插入一个帖子,都希望将版面表中的最后发帖时间,帖子总数字段进行同步更新,用触发器做效率就很高。下次课设计这样一个案例,写触发器时,对于最后发帖时间可能需要用declare方式声明一个变量,或者是用NEW.posttime来生成。
10、数据库三范式是什么?
第一范式(1NF):字段具有原子性,不可再分。所有关系型数据库系统都满足第一范式。
数据库表中的字段都是单一属性的,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。
第二范式(2NF):在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
要求数据库表中的每个实例或行必须可以被唯一地区分。通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。
第三范式的要求如下:
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
所以第三范式具有如下特征:
1,每一列只有一个值
2,每一行都能区分。
3,每一个表都不包含其他表已经包含的非主关键字信息。
例如,帖子表中只能出现发帖人的id,而不能出现发帖人的id,还同时出现发帖人姓名,否则,只要出现同一发帖人id的所有记录,它们中的姓名部分都必须严格保持一致,这就是数据冗余。
11、说出一些数据库优化方面的经验?
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.使用数据库连接池
12、union和union all有什么不同?
union和union all都是合并结果集
区别是:
1. union去除两个结果集的重复记录,union all不去除重复记录,是两个结果集的加和
2. union效率低,union all效率高
13.用一条SQL语句查询出每门课都大于80分的学生姓名
name kecheng fenshu
张三 语文 81
张三 数学 75
李四 语文 76
李四 数学 90
王五 语文 81
王五 数学 100
王五 英语 90
答案:
A:select distinct name from score where name not in (select distinct name from score where fenshu <=80)
B:select distinct name t1 from score where 80< all (select fenshu from score where name=t1);
14.所有部门之间的比赛组合
一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合.
select a.name, b.name
from team a, team b
where a.name > b.name
15.显示文章标题,发帖人、最后回复时间
文章表: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
)
16.删除除了id号不同,其他都相同的学生冗余信息
学生表(student)如下:
id号 学号 姓名 课程编号 课程名称 分数
id sid name cno cname score
1 2005001 张三 0001 数学 69
2 2005002 李四 0001 数学 89
3 2005001 张三 0001 数学 69
A: delete from student where id not in(select min(id) from student group by sid, name, cno, cname, score)
18.求出发帖最多的人:
select max(post_count), b.post_user_id, u.name
from
(
select count(*) as post_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。
19、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决?
方案一:update user set score=0;
方案二:假设上面的代码要执行好长时间,超出我们的容忍范围,使用alter table:
drop columnscore;alter table user add column score int。
在Oracle中,动了表结构,索引失效
方案三:使用Java程序,for循环,效率最差
方案四:使用存储过程loop循环,效率其次差
21、注册Jdbc驱动程序的三种方式
1. Class.forName(driver)
2. ClassLoader.loadClass(driver)
3. new XXXDriver();
22、用JDBC如何调用存储过程
Class.forName(“com.mysql.jdbc.Driver”);
String url = “jdbc:mysql:///test”;
Connection cn = DriverManager.getConnection(url, “root”, “root”);
String sql = “{call insert_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));
23、JDBC中的PreparedStatement相比Statement的好处
一个sql命令在数据库执行的步骤为:语法检查,语义分析,编译成内部指令,缓存指令,执行指令等过程。
1. PrepareStatement第一次执行某SQL时可以把最终结果缓存到数据中,以后再执行同一格式的SQL时,不再进行优化,直接使用缓存中的优化结果,效率比较高。
2.参数传值,可以防止SQL注入
24、Class.forName的作用?为什么要用?
答:按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。
有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名通常也是通过配置文件来配置的,以便在产品交付使用后不用修改源程序就可以更换驱动类名。
25、大数据量下的分页解决方法。
查询结果集如果记录数比较多时,服务器内存和浏览器内存都可能溢出,另外,数据量太大客户端的性能会降低,滚动条较小,操作也不方便,需要数据库分页查询。
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 students order 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
where t.rid>#pageSize#*(#pageNumber#-1)
27、说出数据连接池的工作机制是什么?
J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接标记为空闲,其他调用就可以使用这个连接。
实现方式,返回的Connection是原始Connection的代理,代理Connection的close方法不是真正关连接,而是把它代理的Connection对象还回到连接池中。
28、为什么要用 ORM? 和 JDBC有何不一样?
ORM是对象和关系型数据库映射,是把Java中的JavaBean对象和数据库表进行映射,使数据库表中的记录和JavaBean对象一一对应,从而大大简化原来直接使用JDBC时,手工拼写SQL带来的不便。
ORM通过配置文件,使数据库表和JavaBean类对应起来,提供简便的操作方法,增、删、改、查记录,不再拼写字符串生成SQL,编程效率大大提高,同时减少程序出错机率,增强数据库的移植性,方便测试。但是原生的JDBC具有更强的灵活性,适合复杂多变的SQL应用。
常用的ORM框架有:Hibernate、MyBatis、TopLink、OJB
29. 数据库大数据处理
1. 大数据可以采用分布式数据库和建立分区表(PARTITION)
2. 建立有效索引:主键索引、联合索引、倒序索引、函数索引(INDEX)
3. 使用物化视图(MATERIALIZED VIEW)
4. 使用存储过程(PROCDUDER)
5. 读写分离(golden gate软件实现)
6. 归档旧数据(新旧数据查询,保证新数据的效率提高),程序做调整,旧数据和新数据查询页面分离
31. 什么是事务?什么是锁?
答:事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。
锁:在所以的DBMS中,锁是实现事务的关键,锁可以保证事务的完整性和并发性。与现实生活中锁一样,它可以使某些数据的拥有者,在某段时间内不能使用某些数据或数据结构。当然锁还分级别的。
32. 维护数据库的完整性和一致性,你喜欢用触发器还是自写业务逻辑?为什么?
我是这样做的,尽可能使用约束,如check,主键,外键,非空字段等来约束,这样做效率最高,也最方便。其次是使用触发器,这种方法可以保证,无论什么业务系统访问数据库都可以保证数据的完整新和一致性。最后考虑的是自写业务逻辑,但这样做麻烦,编程复杂,效率低下。
33. 什么是内存泄漏?
答:一般我们所说的内存泄漏指的是堆内存的泄漏。堆内存是程序从堆中为其分配的,大小任意的,使用完后要显示释放内存。当应用程序用关键字new等创建对象时,就从堆中为它分配一块内存,使用完后程序调用free或者delete释放该内存,否则就说该内存就不能被使用,我们就说该内存被泄漏了。
34.触发器的作用?
触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的。它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级运算。如,某表上的触发器上包含对另一个表的数据操作,而该操作又会导致该表触发器被触发。
35. 常用的oracle操作的命令
操作的命令:
Sqlplus 登陆用户
Conn 连接数据库
Disconn 断开数据库连接
Exit或quit退出sql*plus
Pass 修改用户口令
Show user 查看当前用户
List 列出sql缓冲区的内容
Run或/ 执行缓冲区中的所有内容
Save 文件名 把缓冲区的内容保存到sql脚本文件
Get 文件名 将sql脚本文件中的内容加载到缓冲区
Start或@文件名 将指定sql脚本文件加载到缓冲区并执行
Edit 编辑缓冲区或sql脚本文件的内容
Spool 文件名 把sql*plus中的输入结果复制到指定文件中
Spool off 停止sql*plus中的输出结果复制,并关闭文件
Help 命令名 查看某个命令的详细帮助信息。
36, 索引的优缺点 优点: 1 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性 2 可以大大加快数据的检索速度,这也是创建索引的最主要的原因 3 可以加速表和表之间的连接, 4 在使用分组和排序子句进行数据检索时,同样可以减少查询中分组和排序的时间。 缺点: 1 降低了dml操作的速度 2 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加 3 索引需要占据物理空间,创建索引会加大储存空间
37.使用oracle伪列删除表中重复记录:? Delete table t where t.rowid!=(select max(t1.rowid) from table t1 where t1.name=t.name)
五. XML部分
1、xml有哪些解析技术?区别是什么?
答:有DOM,SAX,STAX等
DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问
STAX:Streaming API for XML (StAX)
讲解这些区别是不需要特别去比较,就像说传智播客与其他培训机构的区别时,我们只需说清楚传智播客有什么特点和优点就行了,这就已经间接回答了彼此的区别。
2、你在项目中用到了xml技术的哪些方面?如何实现的?
答:用到了数据存贮,信息配置两方面。在做数据交换平台时,将不能数据源的数据组装成XML文件,然后将XML文件压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再同XML文件中还原相关信息进行处理。在做软件配置时,利用XML可以很方便的进行,软件的各种配置参数都存贮在XML文件中。
4、XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?
a: 两种形式 dtd schema,b:本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的),c:有DOM,SAX,STAX等
DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问
SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问
STAX:Streaming API forXML (StAX)
六.流行的框架与新技术
1、 谈谈你对Struts的理解。
1. struts是一个按MVC模式设计的Web层框架,实质是一个强大的Servlet。负责处理请求转发和路由。
2. struts的基本配置文件为struts-config.xml,里面配置了很多Action、ActionForm及中转规则,这个文件通过web.xml中的ActionServlet进行加载和初始化。
3. 当用户请求发送到服务器端时,ActionServlet会接收到此请求,然后根据struts.xml中的配置找到相应的Action,同时根据ActionForm的配置,创建ActionForm的实例并进行赋值,当做参数交给Action进行业务处理,返回ActionMapping对象。
4. ActionServlet根据struts.xml中action的配置,forward到指定的页面,把结果以JSP处理过的HTML返回给客户的浏览器。
5.可以继续谈一谈struts1和struts2的区别
2、Struts优缺点
优点:
1. 实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现.
2.有丰富的tag可以用 ,Struts的标记库(Taglib),如能灵活动用,则能大大提高开发效率
3. 页面导航
使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
4. 提供Exception处理机制 .
5. 数据库链接池管理
6. 支持I18N
缺点
一、转到展示层时,需要配置forward,如果有十个展示层的jsp,需要配置十次struts,而且还不包括有时候目录、文件变更,需要重新修改forward,注意,每次修改配置之后,要求重新部署整个项目,而tomcate这样的服务器,还必须重新启动服务器
二、Struts的Action必需是thread-safe方式,它仅仅允许一个实例去处理所有的请求。所以action用到的所有的资源都必需统一同步,这个就引起了线程安全的问题。
三、测试不方便. Struts的每个Action都同Web层耦合在一起,这样它的测试依赖于Web容器,单元测试也很难实现。不过有一个Junit的扩展工具Struts TestCase可以实现它的单元测试。
四、类型的转换. Struts的FormBean把所有的数据都作为String类型,它可以使用工具Commons-Beanutils进行类型转化。但它的转化都是在Class级别,而且转化的类型是不可配置的。类型转化时的错误信息返回给用户也是非常困难的。
五、对Servlet的依赖性过强. Struts处理Action时必需要依赖ServletRequest和ServletResponse,所有它摆脱不了Servlet容器。
六、前端表达式语言方面.Struts集成了JSTL,所以它主要使用JSTL的表达式语言来获取数据。可是JSTL的表达式语言在Collection和索引属性方面处理显得很弱。
七、对Action执行的控制困难. Struts创建一个Action,如果想控制它的执行顺序将会非常困难。甚至你要重新去写Servlet来实现你的这个功能需求。
八、对Action执行前和后的处理. Struts处理Action的时候是基于class的hierarchies,很难在action处理前和后进行操作。
九、对事件支持不够.在struts中,实际是一个表单Form对应一个Action类(或DispatchAction),换一句话说:在Struts中实际是一个表单只能对应一个事件,struts这种事件方式称为application event,application event和component event相比是一种粗粒度的事件。
3、STRUTS的应用(如STRUTS架构)
Struts是采用Java Servlet/JavaServer Pages技术,开发Web应用程序的开放源码的framework。采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架。 Struts有如下的主要功能:一.包含一个controller servlet,能将用户的请求发送到相应的Action对象。二.JSP自由tag库,并且在controller servlet中提供关联支持,帮助开发员创建交互式表单应用。三.提供了一系列实用对象:XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息
4、谈谈你对Hibernate的理解。
它是ORM思想的一个实现,对JDBC进行了很好的封装,它通过配置使JavaBean对象和数据库表之间进行映射,并提供对增、删、改、查便利的操作方法,同时支持事务处理,它对数据库记录还提供了缓存机制,提高效率,它可以使程序员不用书写SQL,也不用关心数据库SQL之间的差异,它通过方言对数据库进行了很好的适配。
1. Hiberante的主配置文件为hibernate.cfg.xml,其中定义了数据源、连接池、缓存、事务、表生成策略等配置
2. 通过*.hbm.xml映射配置文件,定义了JavaBean对象和数据库表之间的映射关系,还定了对象和对象之间的映射关系,包括:一对一、多对一、一对多、多对多
3. 对于复杂查询和修改,Hiberante提供了Query对象进行支持,它可以使用HQL语句处理查询、修改、删除和分页。如果需要处理针对数据库相关的SQL,可以SQLQuery对象处理。
4. Hibernate可以集成到Spring中,通过Spring进行事务处理,事务的配置通常分两类,一种是AOP方式,一种是注释方式的声明式事务。
5. Hiberante从3版本后,支持JPA规范,可以不使用映射文件配置,而全部采用JPA注解方式进行对象和数据库表的映射,Hibernate还扩容了JPA规范。
6. Hibernate对常用的缓存技术做了封装,可以轻松的调用各种缓存框架
5、你对Spring的理解。
Spring实质上讲就是一个Bean工厂,主要用来管理Bean的生命周期和框架集成。
Spring分为两个部分:
1. IOC控制反转(也叫DI依赖注入,此名由Mardin Fowler给出)。Spring的顶层容器为BeanFactory,常用的ApplicationContext为它的子接口,实现了工厂模式。Spring需要加载它的配置文件,通常配置文件名为applicationContext.xml或spring-config.xml,其中Bean的定义为
2. Spring容器负责根据配置文件创建Bean对象并进行对其的装载。Bean有懒加载,属性配置,自动装载,parent Bean,abstract Bean,FactoryBean(通常用于框架集成,需要了解BeanFactory和FactoryBean的区别),scope(singleton单例,prototype多例)。
3. Spring 2.5后提供了对注释的支持,更加方便,在重构时作用巨大。
4. Spring的IOC解除了模块间的耦合,可以使项目多模块并行开发。
5. Spring还提供了AOP的支持,方便在切面级开发,例如事务控制、日志、性能、安全等。Spring的AOP有两种配置方式,都是通过动态代理技术实现的,一种是JDK自带的Proxy类的实现,一种是CGLIB动态代理实现,通过<aop:aspect target-class-proxy=”true” />开关进行设置。
6. Spring的重要做用是集成其它框架。Spring官方提供了许多类库对其它框架进行了封装,例如通过的事务模块、JMS框架的调用模块、Email支持、调试器Scheduler、JNDI等,同时其它框架也提供了针对Spring的集成包,例如Hibernate、MyBatis、Struts等
。
6.Spring由哪些模块组成?
以下是Spring 框架的基本模块:
- Core module
- Bean module
- Context module
- Expression Language module
- JDBC module
- ORM module
- OXM module
- Java Messaging Service(JMS) module
- Transaction module
- Web module
- Web-Servlet module
- Web-Struts module
- Web-Portlet module
7. 核心容器模块。
这是基本的Spring模块,提供spring 框架的基础功能,BeanFactory 是任何以spring为基础的应用的核心。Spring 框架建立在此模块之上,它使Spring成为一个容器。
9、写Hibernate的一对多和多对一双向关联的orm配置?
hibernate的inverse属性的作用?
解决方案一,按照Object[]数据取出数据,然后自己组bean
解决方案二,对每个表的bean写构造函数,比如表一要查出field1,field2两个字段,那么有一个构造函数就是Bean(type1filed1,type2
field2) ,然后在hql里面就可以直接生成这个bean了。
10、在DAO中如何体现DAO设计模式?
解决方案一,按照Object[]数据取出数据,然后自己组bean
解决方案二,对每个表的bean写构造函数,比如表一要查出field1,field2两个字段,那么有一个构造函数就是Bean(type1filed1,type2
field2) ,然后在hql里面就可以直接生成这个bean了。
11、spring+Hibernate中委托方案怎么配置?
解决方案一,按照Object[]数据取出数据,然后自己组bean
解决方案二,对每个表的bean写构造函数,比如表一要查出field1,field2两个字段,那么有一个构造函数就是Bean(type1filed1,type2
field2) ,然后在hql里面就可以直接生成这个bean了。
12. hibernate进行多表查询每个表中各取几个字段,也就是说查询出来的结果集没有一个实体类与之对应如何解决;
解决方案一,按照Object[]数据取出数据,然后自己组bean
解决方案二,对每个表的bean写构造函数,比如表一要查出field1,field2两个字段,那么有一个构造函数就是Bean(type1filed1,type2
field2) ,然后在hql里面就可以直接生成这个bean了。
13.介绍一下Hibernate的二级缓存
按照以下思路来回答:(1)首先说清楚什么是缓存,(2)再说有了hibernate的Session就是一级缓存,即有了一级缓存,为什么还要有二级缓存,(3)最后再说如何配置Hibernate的二级缓存。
(1)缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。下面是缓存的伪代码:
引出hibernate的第二级缓存,用下面的伪代码分析了Cache的实现原理
Dao
{
hashmap map = newmap();
User getUser(integerid)
{
User user =map.get(id)
if(user ==null)
{
user =session.get(id);
map.put(id,user);
}
return user;
}
}
Dao
{
Cache cache = null
setCache(Cachecache)
{
this.cache =cache
}
User getUser(int id)
{
if(cache!=null)
{
Useruser = cache.get(id);
if(user==null)
{
user= session.get(id);
cache.put(id,user);
}
returnuser;
}
returnsession.get(id);
}
}
(2)Hibernate的Session就是一种缓存,我们通常将之称为Hibernate的一级缓存,当想使用session从数据库中查询出一个对象时,Session也是先从自己内部查看是否存在这个对象,存在则直接返回,不存在才去访问数据库,并将查询的结果保存在自己内部。由于Session代表一次会话过程,一个Session与一个数据库连接相关连,所以Session最好不要长时间保持打开,通常仅用于一个事务当中,在事务结束时就应关闭。并且Session是线程不安全的,被多个线程共享时容易出现问题。通常只有那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值,因此,Hibernate的Session这一级缓存的缓存作用并不明显,应用价值不大。Hibernate的二级缓存就是要为Hibernate配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存。我们希望的是一个人使用过,其他人也可以使用,session没有这种效果。
(3)二级缓存是独立于Hibernate的软件部件,属于第三方的产品,多个厂商和组织都提供有缓存产品,例如,EHCache和OSCache等等。在Hibernate中使用二级缓存,首先就要在hibernate.cfg.xml配置文件中配置使用哪个厂家的缓存产品,接着需要配置该缓存产品自己的配置文件,最后要配置Hibernate中的哪些实体对象要纳入到二级缓存的管理中。明白了二级缓存原理和有了这个思路后,很容易配置起Hibernate的二级缓存。扩展知识:一个SessionFactory可以关联一个二级缓存,也即一个二级缓存只能负责缓存一个数据库中的数据,当使用Hibernate的二级缓存后,注意不要有其他的应用或SessionFactory来更改当前数据库中的数据,这样缓存的数据就会与数据库中的实际数据不一致。
14、Jdo是什么?
JDO是Java对象持久化的新的规范,为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化API。JDO提供了透明的对象存储,因此对开发人员来说,存储数据对象完全不需要额外的代码(如JDBC API的使用)。这些繁琐的例行工作已经转移到JDO产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,JDO很灵活,因为它可以在任何数据底层上运行。JDBC只是面向关系数据库(RDBMS)JDO更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库(ODBMS)等等,使得应用可移植性更强。
16. IOC的优点是什么?
IOC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。
18. 什么是Spring的依赖注入?
依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。
19. 有哪些不同类型的IOC(依赖注入)方式?
- **构造器依赖注入:**构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
- **Setter方法注入:**Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。
20. 哪种依赖注入方式你建议使用,构造器注入,还是 Setter方法注入?
你两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖。
21. Spring对DAO的支持
Spring对数据访问对象(DAO)的支持旨在简化它和数据访问技术如JDBC,Hibernate or JDO 结合使用。这使我们可以方便切换持久层。编码时也不用担心会捕获每种技术特有的异常。
22. 解释AOP
面向切面的编程,或AOP, 是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。
23. Aspect 切面
AOP核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。比如,一个日志模块可以被称作日志的AOP切面。根据需求的不同,一个应用程序可以有若干切面。在Spring AOP中,切面通过带有@Aspect注解的类实现。
24. 在Spring AOP 中,关注点和横切关注的区别是什么?
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。 横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。
25. 连接点
连接点代表一个应用程序的某个位置,在这个位置我们可以插入一个AOP切面,它实际上是个应用程序执行Spring AOP的位置。
26. 通知
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。
Spring切面可以应用五种类型的通知:
- before:前置通知,在一个方法执行前被调用。
- after: 在方法执行之后调用的通知,无论方法执行是否成功。
- after-returning: 仅当方法成功完成后执行的通知。
- after-throwing: 在方法抛出异常退出时执行的通知。
- around: 在方法执行之前和之后调用的通知。
29 SpringMvc怎么和AJAX相互调用的
通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象
具体步骤如下
1.加入Jackson.jar
2.在配置文件中配置json的映射
3.在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上@ResponseBody注解
30当一个方法向AJAX返回特殊对象,譬如Object,List等,需要做什么处理
要加上@ResponseBody注解
31 SpringMvc里面拦截器是怎么写的
有两种写法,一种是实现接口,另外一种是继承适配器类,然后在SpringMvc的配置文件中配置拦截器即可:
<!-- 配置SpringMvc的拦截器 -->
<mvc:interceptors>
<!-- 配置一个拦截器的Bean就可以了 默认是对所有请求都拦截 -->
<bean id="myInterceptor" class="com.et.action.MyHandlerInterceptor"></bean>
<!-- 只针对部分请求拦截 -->
<mvc:interceptor>
<mvc:mapping path="/modelMap.do" />
<bean class="com.et.action.MyHandlerInterceptorAdapter" />
</mvc:interceptor>
</mvc:interceptors>
32讲下SpringMvc的执行流程
系统启动的时候根据配置文件创建spring的容器, 首先是发送http请求到核心控制器disPatherServlet,spring容器通过映射器去寻找业务控制器,
使用适配器找到相应的业务类,在进业务类时进行数据封装,在封装前可能会涉及到类型转换,执行完业务类后使用ModelAndView进行视图转发,数据放在model中,用map传递数据进行页面显示。
33解释Spring支持的几种bean的作用域。
Spring框架支持以下五种bean的作用域:
- singleton : bean在每个Spring ioc 容器中只有一个实例。
- prototype:一个bean的定义可以有多个实例。
- request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
- session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
- global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
缺省的Spring bean 的作用域是Singleton.
34,Spring框架中的单例bean是线程安全的吗?
不,Spring框架中的单例bean不是线程安全的。
35. 解释Spring框架中bean的生命周期。
- Spring容器 从XML 文件中读取bean的定义,并实例化bean。
- Spring根据bean的定义填充所有的属性。
- 如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。
- 如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。
- 如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。
- 如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。
- 如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。
- 如果bean实现了 DisposableBean,它将调用destroy()方法。
36.哪些是重要的bean生命周期方法? 你能重载它们吗?
有两个重要的bean 生命周期方法,第一个是setup , 它是在容器加载bean的时候被调用。第二个方法是 teardown 它是在容器卸载类的时候被调用。
The bean 标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)。
38. 什么是基于Java的Spring注解配置? 给一些注解的例子.
基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。
以@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
39. 什么是基于注解的容器配置?
相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。
开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。
40. 怎样开启注解装配?
注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置 context:annotation-config/元素。
41. 使用Spring通过什么方式访问Hibernate?
在Spring中有两种方式访问Hibernate:
- 控制反转 Hibernate Template和 Callback。
- 继承 HibernateDAOSupport提供一个AOP 拦截器。
42. Spring支持的ORM
Spring支持以下ORM:
- Hibernate
- iBatis
- JPA (Java Persistence API)
- TopLink
- JDO (Java Data Objects)
- OJB
43.如何通过HibernateDaoSupport将Spring和Hibernate结合起来?
用Spring的 SessionFactory 调用 LocalSessionFactory。集成过程分三步:
- 配置the Hibernate SessionFactory。
- 继承HibernateDaoSupport实现一个DAO。
- 在AOP支持的事务中装配。
44. Spring支持的事务管理类型
Spring支持两种类型的事务管理:
- 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
- **声明式事务管理:**这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。
- 它为不同的事务API 如 JTA,JDBC,Hibernate,JPA 和JDO,提供一个不变的编程模式。
- 它为编程式事务管理提供了一套简单的API而不是一些复杂的事务API如
- 它支持声明式事务管理。
- 它和Spring各种数据访问抽象层很好得集成。
45. Spring框架的事务管理有哪些优点?
49. 什么是Spring MVC框架的控制器?
控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现。控制器解析用户输入并将其转换为一个由视图呈现给用户的模型。Spring用一个非常抽象的方式实现了一个控制层,允许用户创建多种用途的控制器。
50. 讲下SpringMvc的核心入口类是什么,Struts1,Struts2的分别是什么
SpringMvc的是DispatchServlet,Struts1的是ActionServlet,Struts2的是StrutsPrepareAndExecuteFilter
51. SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决
是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写字段
52. SpingMvc中的控制器的注解一般用那个,有没有别的注解可以替代
一般用@Conntroller注解,表示是表现层,不能用别的注解代替.
53. 如果在拦截请求中,我想拦截get方式提交的方法,怎么配置
可以在@RequestMapping注解里面加上method=RequestMethod.GET
54. 如果在拦截请求中,我想拦截提交参数中包含"type=test"字符串,怎么配置
可以在@RequestMapping注解里面加上params="type=test"
55. SpringMvc中函数的返回值是什么.
返回值可以有很多类型,有String, ModelAndView,当一般用String比较好
56. SpringMVC怎么样设定重定向和转发的
在返回值前面加"forward:"就可以让结果转发,譬如"forward:user.do?name=method4" 在返回值前面加"redirect:"就可以让返回值重定向,譬如"redirect:http://www.baidu.com"
57. SpringMvc用什么对象从后台向前台传递数据的
通过ModelMap对象,可以在这个对象里面用put方法,把对象加到里面,前台就可以通过el表达式拿到
58. SpringMvc中有个类把视图和数据都合并的一起的,叫什么
叫ModelAndView
59. 怎么样把ModelMap里面的数据放入Session里面
可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key
61. 当一个方法向AJAX返回特殊对象,譬如Object,List等,需要做什么处理
要加上@ResponseBody注解
63. 讲下SpringMvc的执行流程
系统启动的时候根据配置文件创建spring的容器, 首先是发送http请求到核心控制器disPatherServlet,spring容器通过映射器去寻找业务控制器,
使用适配器找到相应的业务类,在进业务类时进行数据封装,在封装前可能会涉及到类型转换,执行完业务类后使用ModelAndView进行视图转发,数据放在model中,用map传递数据进行页面显示。
64,Hibernate是如何延迟加载?
* Hibernate2延迟加载实现:a)实体对象 b)集合(Collection) * Hibernate3 提供了属性的延迟加载功能
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。 Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系) 类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、
说下Hibernate的缓存机制
* 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存 * 二级缓存:
a)应用及缓存
b)分布式缓存
条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非 关键数据
c) 第三方缓存的实现 Hibernate的查询方式 Sql、Criteria,object comptosition Hql:
* 属性查询 * 参数查询、命名参数查询 * 关联查询 * 分页查询 * 统计函数
66,如何优化Hibernate?
* 使用双向一对多关联,不使用单向一对多 * 灵活使用单向一对多关联 * 不用一对一,用多对一取代 * 配置对象缓存,不使用集合缓存 * 一对多集合使用Bag,多对多集合使用Set * 继承类使用显式多态 * 表字段要少,表关联不要怕多,有二级缓存撑腰
67,在数据库中条件查询速度很慢的时候,如何优化?
1.建索引 2.减少表之间的关联 3.优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据量大的表排在前面 4.简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据
69,Hibernate的主键生成机制
- assigned 主键由外部程序负责生成,无需Hibernate参与。 2) hilo 通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。 3) seqhilo 与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle。 4) increment 主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。因此,如果同一数据库有多个实例访问,此方式必须避免使用。 5) identity 采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL中的主键生成机制。 6) sequence 采用数据库提供的sequence 机制生成主键。如Oralce 中的Sequence。 7) native 由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。 8) uuid.hex 由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。 9) uuid.string 与uuid.hex 类似,只是生成的主键未进行编码(长度16)。在某些数据库中可能出现问题(如PostgreSQL)。 10) foreign 使用外部表的字段作为主键。一般而言,利用uuid.hex方式生成主键将提供最好的性能和数据库平台适应性。
69,Mybatis比IBatis比较大的几个改进是什么?
a.有接口绑定,包括注解绑定sql和xml绑定Sql ,b.动态sql由原来的节点配置变成OGNL表达式,c. 在一对一,一对多的时候引进了association,在一对多的时候引入了collection节点,不过都是在resultMap里面配置
70,什么是MyBatis的接口绑定,有什么好处
接口映射就是在IBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们直接调用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置.
71,接口绑定有几种实现方式,分别是怎么实现的?
接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上@Select @Update等注解里面包含Sql语句来绑定,另外一种就是通过xml里面写SQL来绑定,在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名.
72,什么情况下用注解绑定,什么情况下用xml绑定
当Sql语句比较简单时候,用注解绑定,当SQL语句比较复杂时候,用xml绑定,一般用xml绑定的比较多
73,MyBatis实现一对一有几种方式?具体怎么操作的
有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,通过在resultMap里面配置association节点配置一对一的类就可以完成;嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置
74,MyBatis实现一对多有几种方式,怎么操作的
有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,通过在resultMap里面配置collection节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置
75,MyBatis里面的动态Sql是怎么设定的?用什么语法?
MyBatis里面的动态Sql一般是通过if节点来实现,通过OGNL语法来实现,但是如果要写的完整,必须配合where,trim节点,where节点是判断包含节点有内容就插入where,否则不插入,trim节点是用来判断如果动态语句是以and 或or开始,那么会自动把这个and或者or取掉
78,讲下MyBatis的缓存
MyBatis的缓存分为一级缓存和二级缓存,一级缓存放在session里面,默认就有,二级缓存放在它的命名空间里,默认是打开的,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/>
七.软件工程与设计模式
1、j2ee常用的设计模式?说明工厂模式。
总共23种,分为三大类:创建型,结构型,行为型
我只记得其中常用的6、7种,分别是:
创建型(工厂、工厂方法、抽象工厂、单例)
结构型(包装、适配器,组合,代理)
行为(观察者,模版,策略)
然后再针对你熟悉的模式谈谈你的理解即可。
Java中的23种设计模式:
Factory(工厂模式), Builder(建造模式), Factory Method(工厂方法模式),
Prototype(原始模型模式),Singleton(单例模式), Facade(门面模式),
Adapter(适配器模式), Bridge(桥梁模式), Composite(合成模式),
Decorator(装饰模式), Flyweight(享元模式), Proxy(代理模式),
Command(命令模式), Interpreter(解释器模式), Visitor(访问者模式),
Iterator(迭代子模式), Mediator(调停者模式), Memento(备忘录模式),
Observer(观察者模式), State(状态模式), Strategy(策略模式),
Template Method(模板方法模式), Chain Of Responsibleity(责任链模式)
2、开发中都用到了那些设计模式?用在什么场合?
每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作。主要用到了MVC的设计模式。用来开发JSP/Servlet或者J2EE的相关应用。简单工厂模式等。
3,Session:与请求有关的会话期
setAttribute("name",Object obj):设置名字为name的request参数的值,该值是由Object类型的obj指定
getAttribute("name"):返回name属性值
getAttributeNames():返回所有可用属性名的枚举
invalidate():使当前会话失效
setMaxInactiveInterval():指定在Servlet容器使此会话失效之前客户端请求之间的时间间隔,以秒为单位。负数时间指示会话永远不会超时
getMaxInactivelnterval():返回servlet 容器在客户端访问之间将使此会话保持打开状态的最大时间间隔,以秒为单位。在此间隔之后,servlet 容器将使会话无效
4,Out:用来传送回应的输出
print():打印信息
println():换行打印信息
Config:Servlet的构架部件
getInitParameter(String paramNarne):从web.xml中获取指定名称的值 getInitParameterNames():从web.xml中获取所有的名称
Page:JSP页面本身
Exception:针对错误网页,未捕捉的例外 getMessage():返回异常的详细信息 getClass():返回异常的名称
八. j2ee部分
2、应用服务器与WEB SERVER的区别?
应用服务器:Weblogic、Tomcat、Jboss
WEB SERVER:IIS、 Apache
3、应用服务器有那些?
BEA WebLogic Server,IBM WebSphere Application Server,Oracle9i ApplicationServer,jBoss,Tomcat
4、J2EE是什么?
答:Je22是Sun公司提出的多层(multi-diered),分布式(distributed),基于组件(component-base)的企业级应用模型(enterpriese applicationmodel).在这样的一个应用系统中,可按照功能划分为不同的组件,这些组件又可在不同计算机上,并且处于相应的层次(tier)中。所属层次包括客户层(clietn tier)组件,web层和组件,Business层和组件,企业信息系统(EIS)层。
一个另类的回答:j2ee就是增删改查。
6、如何给weblogic指定大小的内存?
(这个问题不作具体回答,列出来只是告诉读者可能会遇到什么问题,你不需要面面俱到,什么都精通。)
在启动Weblogic的脚本中(位于所在Domian对应服务器目录下的startServerName),增加set MEM_ARGS=-Xms32m-Xmx200m,可以调整最小内存为32M,最大200M
7、如何设定的weblogic的热启动模式(开发模式)与产品发布模式?
可以在管理控制台中修改对应服务器的启动模式为开发或产品模式之一。或者修改服务的启动文件或者commenv文件,增加setPRODUCTION_MODE=true。
8、如何启动时不需输入用户名与密码?
修改服务启动文件,增加 WLS_USER和WLS_PW项。也可以在boot.properties文件中增加加密过的用户名和密码.
9、在weblogic管理制台中对一个应用域(或者说是一个网站,Domain)进行jms及ejb或连接池等相关信息进行配置后,实际保存在什么文件中?
保存在此Domain的config.xml文件中,它是服务器的核心配置文件。
10、在weblogic中发布ejb需涉及到哪些配置文件
不同类型的EJB涉及的配置文件不同,都涉及到的配置文件包括ejb-jar.xml,weblogic-ejb-jar.xmlCMP实体Bean一般还需要weblogic-cmp-rdbms-jar.xml
11、如何在weblogic中进行ssl配置与客户端的认证配置或说说j2ee(标准)进行ssl的配置?
缺省安装中使用DemoIdentity.jks和DemoTrust.jks KeyStore实现SSL,需要配置服务器使用Enable SSL,配置其端口,在产品模式下需要从CA获取私有密钥和数字证书,创建identity和trust keystore,装载获得的密钥和数字证书。可以配置此SSL连接是单向还是双向的。
九,项目功能实现技术问题(附带源码)
1,java实现excel模板导出:http://www.cnblogs.com/Mr-kevin/p/5793276.html
2,java中生成验证码:http://www.cnblogs.com/syscn/p/5794391.html
3,Java–>实现群聊功能(C/S模式–TCP协议):http://www.cnblogs.com/xmcx1995/p/5793879.html
4,Activiti工作流学习-----基于5.19.0版本(4):http://www.cnblogs.com/liujie037/p/5790698.html
5,Java关于IO流的介绍:http://www.cnblogs.com/crshuai/p/5789648.html
6,MVC权限管理的实现流程:http://www.cnblogs.com/xinxiaoai/p/5801995.html
7,批量数据上传的sql.xml:http://www.cnblogs.com/Asions/p/5801200.html
8, struts—文件的上传和下载: http://www.cnblogs.com/xiangkejin/p/5801032.html
9, Shiro系统权限管理、及原理剖析:http://blog.csdn.net/helloworldwt/article/details/51759224
10, Shiro学习–与SpringMVC整合(数据库,Shiro注解和Shiro标签): http://blog.csdn.net/frankcheng5143/article/details/50836619
11, Redis 缓存 + Spring 的集成示例
http://blog.csdn.net/defonds/article/details/48716161
十. 其他问题
1,svn的使用和搭建?
软件下载
服务器和客户端安装
建立版本库(Repository)
配置用户和权限
运行独立服务器
初始化导入
基本客户端操作
1,软件下载
下载Subversion服务器程序。
到官方网站的下载二进制安装文件,来到二进制包下载部分,找到 Windows NT, 2000, XP and 2003部分,然后选择" this directory ",这样我们可以看到许多下载的内容,目前可以下载 svn-1.4.0-setup.exe 。
下载Subversion的Windows客户端TortoiseSVN。
TortoiseSVN是扩展Windows Shell的一套工具,可以看作Windows资源管理器的插件,安装之后Windows就可以识别Subversion的工作目录。
官方网站是TortoiseSVN ,下载方式和前面的svn服务器类似,在Download页面的我们可以选择下载的版本,目前的最高稳定版本的安装文件为TortoiseSVN-1.4.0.7501-win32-svn-1.4.0.msi。
2,服务器和客户端安装
服务器安装,直接运行svn-1.4.0-setup.exe ,根据提示安装即可,这样我们就有了一套服务器可以运行的环境。
安装TortoiseSVN,同样直接运行TortoiseSVN-1.4.0.7501-win32-svn-1.4.0.msi按照提示安装即可,不过最后完成后会提示是否重启,其实重启只是使svn工作拷贝在windows中的特殊样式生效,与所有的实际功能无关,这里为了立刻看到好的效果,还是重新启动机器。
3,建立版本库(Repository)
运行Subversion服务器需要首先要建立一个版本库(Repository),可以看作服务器上存放数据的数据库,在安装了Subversion服务器之后,可以直接运行,如:
svnadmin create E:/svndemo/repository
就会在目录E:/svndemo/repository下创建一个版本库。
我们也可以使用TortoiseSVN图形化的完成这一步:
在目录E:/svndemo/repository下"右键->TortoiseSVN->Create Repository here…“, 然后可以选择版本库模式, 这里使用默认即可, 然后就创建了一系列目录和文件。
4,配置用户和权限
来到E:/svndemo/repository/conf目录,修改svnserve.conf:
# [general]
# password-db = passwd
改为:
[general]
password-db = passwd 然后修改同目录的passwd文件,去掉下面三行的注释:
# [users]
# harry = harryssecret
# sally = sallyssecret
最后变成:
[users]
harry = harryssecret
sally = sallyssecret
在这里,因为一般来说,项目的svn的用户名和密码是统一认证的,而为了不每次都输入密码,所以在使用TortoiseSVN的时候,直接都记住了密码,这里的用户名和密码最好和项目的一致,以免出现意外情况。
5,运行独立服务器
在任意目录下运行:
svnserve -d -r E:/svndemo/repository 我们的服务器程序就已经启动了。注意不要关闭命令行窗口,关闭窗口也会把svnserve停止。
在使用中发现,即使关闭了此窗口,svn一样好使~~不知道为啥~
6,初始化导入
来到我们想要导入的项目根目录,在这个例子里是E:/svndemo/initproject,目录下有一个readme.txt文件:
右键->TortoiseSVN->Import…
URL of repository输入“svn://localhost/”
ok
完成之后目录没有任何变化,如果没有报错,数据就已经全部导入到了我们刚才定义的版本库中。
需要注意的是,这一步操作可以完全在另一台安装了TortoiseSVN的主机上进行。例如运行svnserve的主机的IP是133.96.121.22,则URL部分输入的内容就是“svn://133.96.121.22/”。
在这里,不知道为什么,使用svn://localhost/ 一直都搞不定,最后灵机一动使用了file:///E:/svndemo/repository/ 反而搞定了~~
7,基本客户端操作
取出版本库到一个工作拷贝:
来到任意空目录下,在本例中是E:/svndemo/wc1,运行右键->Checkout,在URL of repository中输入svn://localhost/,这样我们就得到了一份工作拷贝。
在工作拷贝中作出修改并提交:
打开readme.txt,作出修改,然后右键->Commit…,这样我们就把修改提交到了版本库,我们可以运行。
察看所作的修改:
readme.txt上右键->TortoiseSVN->Show Log,这样我们就可以看到我们对这个文件所有的提交。在版本1上右键->Compare with working copy,我们可以比较工作拷贝的文件和版本1的区别。
2,git 命令总结?
pwd命令:显示当前的目录
git init:把当前目录变成git可以管理的仓库
git diff 文件名:查看修改了什么内容
git log:查看commit历史,包括时间、作者、版本号、commit备注
git log --pretty=oneline:查看commit历史,只显示时间和commit备注
git reset --hard 版本号:指定往前或往后穿越到任意一个版本,版本号通过git reflog查看
git reflog:查看版本操作历史,显示缩略版本号、commit备注
git checkout ./-- 不带引号的文件名:撤销工作区修改。如果存在add但没有commit的内容,则回到add后的状态,删除没有add的修改;如果没有add的内容,则回到最近一次commit完的状态
git checkout – 文件名:在commit之前执行,可恢复删除的文件
cat 文件名:查看文件内容
git branch:查看当前所有分支,当前所在的分支前面加*
git branch 分支名:创建新分支,但不切换过去,如果当前已存在该分支则报错
git checkout 分支名:切换到指定分支,如果该分支不存在则报错
git checkout -b 分支名:创建新分支并切换到该分支,相当于上面两条命令先后执行,如果分支已存在则报错,并不会切换过去
git branch -d 分支名:删除指定分支,必须在本分支上删除当前所在的分支,必须在其他分支上删除
git merge 分支名:使当前所在分支内容和merge后面指定的分支内容一致,也就是修改当前所在的分支,接着删除merge后指定的分支也可以
git remote (-v):查看远程库信息,加上-v查看详细信息
命令退不出来,按ctrl+C
输入前面输过的命令,按PgUp/PgDn
http://www.cnblogs.com/tugenhua0707/p/4050072.html git使用教程详解
3.tomcat给你你怎样去调优?
1. JVM参数调优:-Xms 表示JVM初始化堆的大小,-Xmx表示JVM堆的最大值。这两个值的大小一般根据需要进行设置。当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃。因此一般建议堆的最大值设置为可用内存的最大值的80%。在catalina.bat中,设置JAVA_OPTS=’-Xms256m -Xmx512m’,表示初始化内存为256MB,可以使用的最大内存为512MB。 2. 禁用DNS查询 当web应用程序向要记录客户端的信息时,它也会记录客户端的IP地址或者通过域名服务器查找机器名转换为IP地址。DNS查询需要占用网络,并且包括可能从很多很远的服务器或者不起作用的服务器上去获取对应的IP的过程,这样会消耗一定的时间。为了消除DNS查询对性能的影响我们可以关闭DNS查询,方式是修改server.xml文件中的enableLookups参数值: Tomcat4 Tomcat5 3. 调整线程数 通过应用程序的连接器(Connector)进行性能控制的的参数是创建的处理请求的线程数。Tomcat使用线程池加速响应速度来处理请求。在Java中线程是程序运行时的路径,是在一个程序中与其它控制线程无关的、能够独立运行的代码段。它们共享相同的地址空间。多线程帮助程序员写出CPU最大利用率的高效程序,使空闲时间保持最低,从而接受更多的请求。 Tomcat4中可以通过修改minProcessors和maxProcessors的值来控制线程数。这些值在安装后就已经设定为默认值并且是足够使用的,但是随着站点的扩容而改大这些值。minProcessors服务器启动时创建的处理请求的线程数应该足够处理一个小量的负载。也就是说,如果一天内每秒仅发生5次单击事件,并且每个请求任务处理需要1秒钟,那么预先设置线程数为5就足够了。但在你的站点访问量较大时就需要设置更大的线程数,指定为参数maxProcessors的值。maxProcessors的值也是有上限的,应防止流量不可控制(或者恶意的服务攻击),从而导致超出了虚拟机使用内存的大小。如果要加大并发连接数,应同时加大这两个参数。web server允许的最大连接数还受制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右。 在Tomcat5对这些参数进行了调整,请看下面属性: maxThreads Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数。 acceptCount 指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。 connnectionTimeout 网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。 minSpareThreads Tomcat初始化时创建的线程数。 maxSpareThreads 一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。 最好的方式是多设置几次并且进行测试,观察响应时间和内存使用情况。在不同的机器、操作系统或虚拟机组合的情况下可能会不同,而且并不是所有人的web站点的流量都是一样的,因此没有一刀切的方案来确定线程数的值。
4,Tomcat有几种部署方式
第一种方法:
在tomcat中的conf目录中,在server.xml中的,节点中添加: 至于Context 节点属性,可详细见相关文档。
第二种方法:
将web项目文件件拷贝到webapps 目录中。
第三种方法:
很灵活,在conf目录中,新建 Catalina(注意大小写)\localhost目录,在该目录中新建一个xml文件,名字可以随意取,只要和当前文件中的文件名不重复就行了,该xml文件的内容为:
第3个方法有个优点,可以定义别名。服务器端运行的项目名称为path,外部访问的URL则使用XML的文件名。这个方法很方便的隐藏了项目的名称,对一些项目名称被固定不能更换,但外部访问时又想换个路径,非常有效。
第2、3还有优点,可以定义一些个性配置,如数据源的配置等。
第四种办法,:
可以用tomcat在线后台管理器,一般tomcat都打开了,直接上传war就可以。
5,eclipse中server location灰色,如何修改?
Eclipse中tomcat service设置 选择window ----show view---services可以看到服务的面板 双击tomcat进入配置界面Service Locations(Specify the server path (i.e. catalina.base) and deploy path. Server must be published with no modules present to make changes.)选项变灰色无法更改配置。 若要更改,则先把tomcat下的所有項目移除。并右击,clean…之后方可设置。。。启动后将又变为黑色。
默认选项为: Use workspace metadata(dose not modify Tomcat installation) 修改选项为: Use Tomcat installation(takes control of Tomcat installation) 这样在Eclipse启动了tomcat服务器,我們也能夠访问到tomcat本地管理首页。 否则只能在DOS下使用Tomcat的启动命令才能访问Tomcat本地管理首页。
注意:Deploy path由:wtpwebapps改为webapps
7,如何加大tomcat可以使用的内存?
tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大。
Unix下,在文件{tomcat_home}/bin/catalina.sh的前面,增加如下设置:
JAVA_OPTS=’-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】’
需要把这个两个参数值调大。例如:
JAVA_OPTS=’-Xms256m -Xmx512m’
表示初始化内存为256MB,可以使用的最大内存为512MB。
8,如何加大tomcat连接数? 在tomcat配置文件server.xml中的配置中,和连接数相关的参数有: minProcessors:最小空闲连接线程数,用于提高系统处理性能,默认值为10 maxProcessors:最大连接线程数,即:并发处理的最大请求数,默认值为75 acceptCount:允许的最大连接数,应大于等于maxProcessors,默认值为100 enableLookups:是否反查域名,取值为:true或false。为了提高处理能力,应设置为false connectionTimeout:网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。 其中和最大连接数相关的参数为maxProcessors和acceptCount。如果要加大并发连接数,应同时加大这两个参数。 web server允许的最大连接数还受制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右。tomcat5中的配置示例: 对于其他端口的侦听配置,以此类推。
最后
以上就是奋斗西牛为你收集整理的java面试题一. Java基础部分二.算法与编程三.前端页面部分三. Java web部分四.数据库部分五. XML部分六.流行的框架与新技术七.软件工程与设计模式八. j2ee部分九,项目功能实现技术问题(附带源码)2,java中生成验证码:http://www.cnblogs.com/syscn/p/5794391.html3,Java–>实现群聊功能(C/S模式–TCP协议):http://www.cnblogs.com/xmcx1995/p/5793879.html十. 其他问题的全部内容,希望文章能够帮你解决java面试题一. Java基础部分二.算法与编程三.前端页面部分三. Java web部分四.数据库部分五. XML部分六.流行的框架与新技术七.软件工程与设计模式八. j2ee部分九,项目功能实现技术问题(附带源码)2,java中生成验证码:http://www.cnblogs.com/syscn/p/5794391.html3,Java–>实现群聊功能(C/S模式–TCP协议):http://www.cnblogs.com/xmcx1995/p/5793879.html十. 其他问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复