标签:
1、面向对象的特点 抽象、封装、继承、多态 2、Collection 和 Collections的区别。 Collection是集合类的上级接口(主要有Set无序 和List有序) Collections是针对集合类的一个帮助类,提供一系列静态方法实现对各种集合的搜索、排序等操作。 3、final、finally、finalize的区别 final修饰符(关键字)final修饰的变量的值不能够再改变,final修饰的方法不能被覆盖,final修饰的类不能被继承。 finally是异常处理try-catch语句的一部分,表示总是执行。 finalize是object类的一个子方法,在垃圾收集器删除对象之前对这个对象调用的。 4、 stack(栈)和heap(堆)的区别 栈是一种线性结构,其添加和删除元素应在同一段完成,栈按照先进后出的方式进行处理。 堆是栈的一个组成元素。 5、 基本的数据类型 byte,int,long,double,char,boolean,float,short String不是基本数据类型,java.util.String是final类,因此不能修改这个类,不能继承这个类。 6、 assert什么时候使用? assertion检查通常在开发和测试时启动,为了提高效率,在软件发布后,assertion检查通常是关闭的。 7、 jsp中的内置对象 request:用户端请求,此请求会包含来自GET/Post请求的参数; response:网页传回用户端的回应。 pageContext:页面的属性是在这里管理 session:与请求有关的回话期 application :Servlet正在执行的内容 out :用来传递回应的输出 config :servlet的构架部件 page jsp网页本身 exception :针对错误的网页。未捕捉的例外。 8、 HashMap和HashTable的区别 HashMap是HashTable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空键值(key),效率上高于HashTable。 9、 sleep()和wait()的区别? sleep到时候后自动恢复,调用sleep不会释放对象锁。 wait是object类的方法,放弃对象锁,只有针对此对象发出notify方法(或者notifyAll)后,才准备获得对象锁进入运行状态。 10、 数组有没有length()这个方法?String有没有length()这个方法? 数组有length这个属性。String有length()方法。 11、 Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? 方法的重写OVerriding和重载Overloading是Java多态的不同表现, 重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现, 如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Voerriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被屏蔽了,如果在一个类中定义了多个同名的方法,他们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overriding),Overriding的方法是可以改变返回值的类型。 12、 Set里的元素是不是能够重复的,那么用什么方法来区分重复与否呢?使用==还是用equals()?他们有什么区别? Set里的元素是不能重复的,用equals()方法来区分重复与否。 ==是用来判断两者是否是同一对象,而equals是用来判断是否引用同一个对象。根据java的存储机制可知,set里面存放的是对象的引用,所以当两个元素只要满足了equals()时就已经指向同一个对象,也就出现了重复元素。所以应该用equals()来判断。 13、 error和exception的区别 error表示系统级的错误,比如说内存溢出。 exception表示需要捕捉或者需要程序进行处理的异常,一般是程序设计上面的问题。 14、 abstract class和interface有什么区别?(抽象类与接口的区别) 声明方法不去实现他的类被叫做抽象类(abstrct class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在类终中实现该类的情况,不能创建abstract类的实例。然而可以创建一个变量,其类型就是一个抽象类,并让他指向具体的子类的一个实例。不能有抽象构造函数或抽象静态方法,abstract类的子类为他们的父类中的所有抽象方法提供实现,否则他们也是抽象类为,取而代之,在子类中是实现该方法。知道其行为的其他类可以在类中实现这些方法。 接口(interface)是抽象类的变体,在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体,接口只可以定义static final成员变量,接口的实现与子类相似,除了个实现类不能从从接口定义中继承行为,当类实现特殊的接口时,他定义(即将程序给予)多有这种接口的犯法,然后,它可以在实现了该接口的类的任何对象上调用接口的方法,由于抽象类,它允许使用接口名作为应用变量的类型。通常的动态联编将生效,引用可以转换到接口类型或从接口类型转换,instanceof运算符可以用来决定某对象的类是实现了接口。 15、 jsp页面中的跳转方式分别是什么?有什么区别? 跳转页面有两种方式:1.forward跳转:<jsp:forward page="跳转页面地址" />2.response跳转:response.sendRedirect("跳转页面地址");两种跳转的区别如下:1.forward跳转: a.服务器端跳转,地址栏不改变; b.执行到跳转语句后马上无条件跳转,之后的代码不再执行(跳转之前一定要释放全部资源); c.request设置的属性在跳转后的页面仍可以使用; d.使用<jsp:param name="参数名" value="参数值" />传递参数。2.response跳转: a.客户端跳转,地址栏改变; b.所有代码执行完毕后跳转; c.跳转后的页面不能使用上一个页面的request属性; d.使用地址重写传递参数(response.sendRedirect("URL?参数名=参数值")) 16、 java servlet API中的forward()和redirect()的区别? 前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向的地址,ee后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接,这样,从浏览器的地址栏中就可以看到跳转以后的链接地址,多亿,牵制更为高效。在前者可以满足需要的同时,尽量使用forward()方法,并且这样有助于隐藏实际的链接,在有些情况下,比如需要跳转到其他浏览器的资源,则必须用sendRedeirct()方法。 forward转向 地址栏不变 redirect 重定向 地址栏改变 17、xml有哪些解析技术?区别是什么? 有DOM,SAX,STAX等 DOM:处理大型文件是其性能下降的非常厉害,这个问题是由DOM的树结构造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对xml的随机访问,sax:不现于,DOM,SAX是事件驱动型的xml解析方式,他顺序的读取xml文件,不需要自已全部装载正文件,当遇到文档开头,文档结束,或者标签开都与标签结束时,他会触发一个事件,用于通过在其回调事件中写入处理代码来处理xml文件,适合对xml的顺序访问。 Stax:Streaming API for xml(Stax)。 18、java类初始化优先级 父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数 19、Java里的传引用和传值的区别是什么? 传引用是指传递的是地址而不是值本身,传值则是传递值的一份拷贝。 20、union和union all的区别 union会自动压缩多个结果集合中的重复结果,而union all则将所有的结果全部显示出来,不管是不是重复。 21、Thread和runnable的区别 Thread类也是Runnable接口的子类。 runnable适合于资源的共享 Runnable适合于多个相同程序代码线程去处理统一资源的情况,把虚拟的cpu(线程)同程序的代码,数据有效分离,较好体现面向对象的编程的思想 Runnable可以避免由于java的单继承机制带来的局限。可以再继承其他类的同时,还能实现多线程的功能。 22、拦截器interceptor和过滤器Filter的区别 a、拦截器是基于java的反射机制的,而过滤器是基于函数回调 b、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 c、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用 d、拦截器可以访问action上下文、值栈里的对象,而过滤器不能 e、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次 f、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。 23、spring下的bean单例模式与设计模式(GOF)中的单例模式区别 一般的单例是指JVM中只有一个实例,Spring的单例是spirng 容器中只有一个实例。 当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例,这里要注意的是singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean。 而设计模式中,我们是对构造方法私有化,进行单例模式,用户从而不能new多个实例。 24、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select * from people where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1) 25、防止重复提交 重复提交问题: 1、ie缓存问题重复提交 --url加时间戳,让每次请求都不一样 2、请求没处理完重复提交: 解决方法: step1,使用一个监听器,当容器在创建一个 session对象之后,绑订一个随机数flag = 1。 step2,在表单里面,添加一个隐藏域,(或者其他事件url中)值 也是flag的值,即1。 step3,用户点击提交,后台比较提交的值与 session当中绑订的值,如果相等,说明是第 一次提交,此时,需要将session中的随机数 重置。当用户不等系统回应,又点击提交,此 时,提交的flag与session中的flag是不相等的, 不允许再次提交。 26、hibernate中一级缓存和二级缓存的区别 Hibernate中提供了两级Cache,第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存由hibernate管理的,一般情况下无需进行干预;第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或群集范围的缓存。这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。 Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存。 27、hibernate与表的自增长 a. sequence :序列,只使用于oracle demo: <id name="id" column="pk_id" type="int"> <generator class="sequence"> <param name="sequence">seq_PETINFO</param> </generator> </id> b. identity :自增长,适用于mysql,sqlserver demo: <id name="id" column="pk_id" type="int"> <generator class="identity"/> </id> c. native :本地,(可移值性好,只需要把方言改变就行) demo: <id name="id" column="pk_id" > <generator class="native"/> </id> ========================= 问题:如果main方法被声明为private会怎样? 答案:能正常编译,但运行的时候会提示”main方法不是public的”。 问题:Java里的传引用和传值的区别是什么? 答案:传引用是指传递的是地址而不是值本身,传值则是传递值的一份拷贝。 问题:如果要重写一个对象的equals方法,还要考虑什么? 答案:hashCode。 问题:Java的”一次编写,处处运行”是如何实现的? 答案:Java程序会被编译成字节码组成的class文件,这些字节码可以运行在任何平台,因此Java是平台独立的。 问题:说明一下public static void main(String args[])这段声明里每个关键字的作用 答案:public: main方法是Java程序运行时调用的第一个方法,因此它必须对Java环境可见。所以可见性设置为pulic. static: Java平台调用这个方法时不会创建这个类的一个实例,因此这个方法必须声明为static。 void: main方法没有返回值。 String是命令行传进参数的类型,args是指命令行传进的字符串数组。 问题:==与equals的区别 答案:==比较两个对象在内存里是不是同一个对象,就是说在内存里的存储位置一致。两个String对象存储的值是一样的,但有可能在内存里存储在不同的地方 . ==比较的是引用而equals方法比较的是内容。public boolean equals(Object obj) 这个方法是由Object对象提供的,可以由子类进行重写。默认的实现只有当对象和自身进行比较时才会返回true,这个时候和==是等价的。String, BitSet, Date, 和File都对equals方法进行了重写,对两个String对象 而言,值相等意味着它们包含同样的字符序列。对于基本类型的包装类来说,值相等意味着对应的基本类型的值一样。 public class EqualsTest { public static void main(String[] args) { String s1 = “abc”; String s2 = s1; String s5 = “abc”; String s3 = new String(”abc”); String s4 = new String(”abc”); System.out.println(”== comparison : ” + (s1 == s5)); System.out.println(”== comparison : ” + (s1 == s2)); System.out.println(”Using equals method : ” + s1.equals(s2)); System.out.println(”== comparison : ” + s3 == s4); System.out.println(”Using equals method : ” + s3.equals(s4)); } } 结果: == comparison : true == comparison : true Using equals method : true false Using equals method :true 问题:如果去掉了main方法的static修饰符会怎样? 答案:程序能正常编译。运行时会抛NoSuchMethodError异常。 问题:为什么oracle type4驱动被称作瘦驱动? 答案:oracle提供了一个type 4 JDBC驱动,被称为瘦驱动。这个驱动包含了一个oracle自己完全用Java实现的一个TCP/IP的Net8的实现,因此它是平台独立的,可以在运行时由浏览器下载,不依赖任何客户端 的oracle实现。客户端连接字符串用的是TCP/IP的地址端口,而不是数据库名的tnsname。 问题:介绍一下finalize方法 答案: final: 常量声明。 finally: 处理异常。 finalize: 帮助进行垃圾回收。 接口里声明的变量默认是final的。final类无法继承,也就是没有子类。这么做是出于基础类型的安全考虑,比如String和Integer。这样也使得编译器进行一些优化,更容易保证线程的安全性。final方法无法重写。final变量的值不能改变。finalize()方法在一个对象被销毁和回收前会被调用。finally,通常用于异常处理,不管有没有异常被抛出都会执行到。比如,关闭连接通常放到finally块中完成。 问题:什么是Java API? 答案:Java API是大量软件组件的集合,它们提供了大量有用的功能,比如GUI组件。 问题:GregorianCalendar类是什么东西? 答案:GregorianCalendar提供了西方传统日历的支持。 问题:ResourceBundle类是什么? 答案:ResourceBundle用来存储指定语言环境的资源,应用程序可以根据运行时的语言环境来加载这些资源,从而提供不同语言的展示。 问题:为什么Java里没有全局变量? 答案:全局变量是全局可见的,Java不支持全局可见的变量,因为:全局变量破坏了引用透明性原则。全局变量导致了命名空间的冲突。 问题:如何将String类型转化成Number类型? 答案:Integer类的valueOf方法可以将String转成Number。下面是代码示例: String numString = “1000″; int id=Integer.valueOf(numString).intValue(); 问题:SimpleTimeZone类是什么? 答案:SimpleTimeZone提供公历日期支持。 问题:while循环和do循环有什么不同? 答案:while结构在循环的开始判断下一个迭代是否应该继续。do/while结构在循环的结尾来判断是否将继续下一轮迭代。do结构至少会执行一次循环体。 问题:Locale类是什么? 答案:Locale类用来根据语言环境来动态调整程序的输出。 问题:面向对象编程的原则是什么? 答案:主要有三点,多态,继承和封装。 问题:介绍下继承的原则 答案:继承使得一个对象可以获取另一个对象的属性。使用继承可以让已经测试完备的功能得以复用,并且可以一次修改,所有继承的地方都同时生效。 问题:什么是隐式的类型转化? 答案:隐式的类型转化就是简单的一个类型赋值给另一个类型,没有显式的告诉编译器发生了转化。并不是所有的类型都支持隐式的类型转化。 代码示例: int i = 1000; long j = i; //Implicit casting 问题:sizeof是Java的关键字吗? 答案:不是。 问题:native方法是什么? 答案:native方法是非Java代码实现的方法。 问题:在System.out.println()里面,System, out, println分别是什么? 答案:System是系统提供的预定义的final类,out是一个PrintStream对象,println是out对象里面一个重载的方法。 问题:封装,继承和多态是什么? 答案:简单来说,多态是指一个名字多种实现。多态使得一个实体通过一个通用的方式来实现不同的操作。具体的操作是由实际的实现来决定的。 多态在Java里有三种表现方式:方法重载通过继承实现方法重写通过Java接口进行方法重写。 问题:显式的类型转化是什么? 答案:显式的类型转化是明确告诉了编译器来进行对象的转化。 代码示例: long i = 700.20; int j = (int) i; //Explicit casting 问题:什么是Java虚拟机? 答案:Java虚拟机是能移植到不同硬件平台上的软件系统。 问题:类型向下转换是什么? 答案:向下转换是指由一个通用类型转换成一个具体的类型,在继承结构上向下进行。 问题:Java的访问修饰符是什么? 答案:访问权限修饰符是表明类成员的访问权限类型的关键字。使用这些关键字来限定程序的方法或者变量的访问权限。它们包含: public: 所有类都可以访问 protected: 同一个包内以及所有子类都可以访问 private: 只有归属的类才能访问默认: 归属类及相同包下的子类可以访问 问题:所有类的父类是什么? 答案:Object. 问题:Java的基本类型有哪些? 答案:byte,char, short, int, long, float, double, boolean。 问题:静态类型有什么特点? 答案:静态变量是和类绑定到一起的,而不是类的实例对象。每一个实例对象都共享同样一份静态变量。也就是说,一个类的静态变量只有一份,不管它有多少个对象。类变量或者说静态变量是通过static这个关键字来声明的。类变量通常被用作常量。静态变量通常通过类名字来进行访问。当程序运行的时候这个变量就会创建直到程序结束后才会被销毁。类变量的作用域和实例变量是一样的。它的初始值和成员变量也是一样的,当变量没被初始化的时候根据它的数据类型,会有一个默认值。类似的,静态方法是属于类的方法,而不是类对象,它的调用并不作用于类对象,也不需要创建任何的类实例。静态方法本身就是final的,因为重写只会发生在类实例上,静态方法是和类绑定在一起的,不是对象。父类的静态方法会被子类的静态方法屏蔽,只要原来方法没有声明为final。非静态方法不能重写静态方法,也就是说,你不能在子类中把一个静态方法改成实例方法。 非静态变量在每一个对象实例上都有单独的一份值。 问题:&操作符和&&操作符有什么区别? 答案:当一个&表达式在求值的时候,两个操作数都会被求值,&&更像是一个操作符的快捷方式。当一个&&表达式求值的时候,先计算第一个操作数,如果它返回true才会计算第二个操作数。如果第一个操作数取值为fale,第二个操作数就不会被求值。 问题:Java是如何处理整型的溢出和下溢的? 答案:Java根据类型的大小,将计算结果中的对应低阶字节存储到对应的值里面。 问题:public static void写成static public void会怎样? 答案:程序正常编译及运行。 问题,声明变量和定义变量有什么不同? 答案:声明变量我们只提供变量的类型和名字,并没有进行初始化。定义包括声明和初始化两个阶段String s;只是变量声明,String s = new String(“bob”); 或者String s = “bob”;是变量定义。 问题:Java支持哪种参数传递类型? 答案:Java参数都是进行传值。对于对象而言,传递的值是对象的引用,也就是说原始引用和参数引用的那个拷贝,都是指向同一个对象。 问题:对象封装的原则是什么? 答案:封装是将数据及操作数据的代码绑定到一个独立的单元。这样保障了数据的安全,防止外部代码的错误使用。对象允许程序和数据进行封装,以减少潜在的干涉。对封装的另一个理解是作为数据及代码的保护层,防止保护层外代码的随意访问。 问题:你怎么理解变量? 答案:变量是一块命名的内存区域,以便程序进行访问。变量用来存储数据,随着程序的执行,存储的数据也可能跟着改变。 问题:数值提升是什么? 答案:数值提升是指数据从一个较小的数据类型转换成为一个更大的数据类型,以便进行整型或者浮点型运算。在数值提升的过程中,byte,char,short值会被转化成int类型。需要的时候int类型也可能被提升成long。long和float则有可能会被转换成double类型。 问题:Java的类型转化是什么? 答案:从一个数据类型转换成另一个数据类型叫做类型转换。Java有两种类型转换的方式,一个是显式的类型转换,一个是隐式的。 问题:main方法的参数里面,字符串数组的第一个参数是什么? 答案:数组是空的,没有任何元素。不像C或者C++,第一个元素默认是程序名。如果命令行没有提供任何参数的话,main方法中的String数组为空,但不是null。 问题:怎么判断数组是null还是为空? 答案:输出array.length的值,如果是0,说明数组为空。如果是null的话,会抛出空指针异常。 问题:程序中可以允许多个类同时拥有都有main方法吗? 答案:可以。当程序运行的时候,我们会指定运行的类名。JVM只会在你指定的类中查找main方法。因此多个类拥有main方法并不存在命名冲突的问题。 问题:静态变量在什么时候加载?编译期还是运行期?静态代码块加载的时机呢? 答案:当类加载器将类加载到JVM中的时候就会创建静态变量,这跟对象是否创建无关。静态变量加载的时候就会分配内存空间。静态代码块的代码只会在类第一次初始化的时候执行一次。一个类可以有多个静态代码块,它并不是类的成员,也没有返回值,并且不能直接调用。静态代码块不能包含this或者super,它们通常被用初始化静态变量。 问题:一个类能拥有多个main方法吗? 答案:可以,但只能有一个main方法拥有以下签名: public static void main(String[] args) {} 否则程序将无法通过编译。编译器会警告你main方法已经存在。 问题:简单的介绍下JVM是如何工作的? 答案:JVM是一台抽象的计算机,就像真实的计算机那样,它们会先将.java文件编译成.class文件(.class文件就是字节码文件),然后用它的解释器来加载字节码。 问题:如果原地交换两个变量的值? 答案:先把两个值相加赋值给第一个变量,然后用得到的结果减去第二个变量,赋值给第二个变量。再用第一个变量减去第二个变量,同时赋值给第一个变量。代码如下: int a=5,b=10;a=a+b; b=a-b; a=a-b; 使用异或操作也可以交换。第一个方法还可能会引起溢出。异或的方法如下: int a=5,b=10;a=a+b; b=a-b; a=a-b; int a = 5; int b = 10; a = a ^ b; b = a ^ b; a = a ^ b; 问题:什么是数据的封装? 答案:数据封装的一种方式是在类中创建set和get方法来访问对象的数据变量。一般来说变量是private的,而get和set方法是public的。封装还可以用来在存储数据时进行数据验证,或者对数据进行计算,或者用作自省(比如在struts中使用javabean)。把数据和功能封装到一个独立的结构中称为数据封装。封装其实就是把数据和关联的操作方法封装到一个独立的单元中,这样使用关联的这些方法才能对数据进行访问操作。封装提供的是数据安全性,它其实就是一种隐藏数据的方式。 问题:什么是反射API?它是如何实现的? 答案:反射是指在运行时能查看一个类的状态及特征,并能进行动态管理的功能。这些功能是通过一些内建类的反射API提供的,比如Class,Method,Field, Constructors等。使用的例子:使用Java反射API的getName方法可以获取到类名。 Java 反射机制主要提供了以下功能: 在运?时判断任意?个对象所属的类; 在运?时构造任意?个类的对象; 在运?时判断任意?个类所具有的成员变量和? 法; 在运?时调?任意?个对象的?法; ?成动态代理。 问题:JVM自身会维护缓存吗,是不是在堆中进行对象分配,操作系统的堆还是JVM自己管理的堆?为什么? 答案:是的,JVM自身会管理缓存,它在堆中创建对象,然后在栈中引用这些对象。 问题:虚拟内存是什么? 答案:虚拟内存又叫延伸内存,实际上并不存在真实的物理内存。 问题:方法可以同时即是static又是synchronized的吗? 答案:可以。如果这样做的话,JVM会获取和这个对象关联的java.lang.Class实例上的锁。这样做等于: synchronized(XYZ.class) { } 问题:String和StringTokenizer的区别是什么? 答案:StringTokenizer是一个用来分割字符串的工具类。 StringTokenizer st = new StringTokenizer(”Hello World”); while (st.hasMoreTokens()) { System.out.println(st.nextToken()); } 输出: Hello World 问题:transient变量有什么特点? 答案:transient变量不会进行序列化。例如一个实现Serializable接口的类在序列化到ObjectStream的时候,transient类型的变量不会被写入流中,同时,反序列化回来的时候,对应变量的值为null。 问题:哪些容器使用Border布局作为它们的默认布局? 答案:Window, Frame, Dialog。 问题:怎么理解什么是同步? 答案:同步用来控制共享资源在多个线程间的访问,以保证同一时间内只有一个线程能访问到这个资源。在非同步保护的多线程程序里面,一个线程正在修改一个共享变量的时候,可能有另一个线程也在使用或者更新它的值。同步避免了脏数据的产生。 对方法进行同步: public synchronized void Method1 () { // Appropriate method-related code. } 在方法内部对代码块进行同步: public myFunction (){ synchronized (this) { // Synchronized code here. } } 处理并发: 1、将对象设计为无状态对象 2、使用局部对象:在方法内部创建对象,这些对象会被每个进入该方法的线程创建 3、并发访问资源时使用锁 事务隔离机制: 在SQL92标准中,事务隔离级别分为四种,分别为:Read Uncommitted、Read Committed、Read Repeatable、Serializable 其中Read Uncommitted与Read Committed为语句级别的,而Read Repeatable与Serializable是针对事务级别的。 在Oracle和SQL Server中设置事务隔离级别的语句是相同的,都使用SQL92标准语法,即: Set Transaction Isolation Level Read Committed 1.SQL Server中的隔离级别及实现机制 在SQL Server中提供了所有这四种隔离级别。 Read Uncommitted 一个会话可以读取其他事务未提交的更新结果,如果这个事务最后以回滚结束,这时的读取结果就可能是错误的,所以多数的数据库应用都不会使用这种隔离级别。 Read Committed 这是SQL Server的缺省隔离级别,设置为这种隔离级别的事务只能读取其他事务已经提交的更新结果,否则,发生等待,但是其他会话可以修改这个事务中被读取的记录,而不必等待事务结束,显然,在这种隔离级别下,一个事务中的两个相同的读取操作,其结果可能不同。 Read Repeatable 在一个事务中,如果在两次相同条件的读取操作之间没有添加记录的操作,也没有其他更新操作导致在这个查询条件下记录数增多,则两次读取结果相同。换句话说,就是在一个事务中第一次读取的记录保证不会在这个事务期间发生改变。SQL Server是通过在整个事务期间给读取的记录加锁实现这种隔离级别的,这样,在这个事务结束前,其他会话不能修改事务中读取的记录,而只能等待事务结束,但是SQL Server不会阻碍其他会话向表中添加记录,也不阻碍其他会话修改其他记录。(其他会话:不能修改当前会话读的数据,但是可以添加数据---》可以幻想读) Serializable 在一个事务中,读取操作的结果是在这个事务开始之前其他事务就已经提交的记录,SQL Server通过在整个事务期间给表加锁实现这种隔离级别。在这种隔离级别下,对这个表的所有DML操作都是不允许的,即要等待事务结束,这样就保证了在一个事务中的两次读取操作的结果肯定是相同的。 2.Oracle中的隔离级别及实现机制 在Oracle中,没有Read Uncommitted及Repeatable Read隔离级别,这样在Oracle中不允许一个会话读取其他事务未提交的数据修改结果,从而避免了由于事务回滚发生的读取错误。Oracle中的Read Committed和Serializable级别,其含义与SQL Server类似,但是实现方式却大不一样。 在Oracle中,存在所谓的回滚段(Oracle9i之前版本)或撤销段(Oracle9i版本),Oracle在修改数据记录时,会把这些记录被修改之前的结果存入回滚段或撤销段中,就是因为这种机制,Oracle对于事务隔离级别的实现与SQL Server截然不同。在Oracle中,读取操作不会阻碍更新操作,更新操作也不会阻碍读取操作,这样在Oracle中的各种隔离级别下,读取操作都不会等待更新事务结束,更新操作也不会因为另一个事务中的读取操作而发生等待,这也是Oracle事务处理的一个优势所在。 Read Committed Oracle缺省的设置是Read Committed隔离级别(也称为语句级别的隔离),在这种隔离级别下,如果一个事务正在对某个表进行DML操作,而这时另外一个会话对这个表的记录进行读取操作,则Oracle会去读取回滚段或撤销段中存放的更新之前的记录,而不会象SQL Server一样等待更新事务的结束。 Serializable 在Serializable隔离级别(也称为事务级别的隔离),事务中的读取操作只能读取这个事务开始之前已经提交的数据结果。如果在读取时,其他事务正在对记录进行修改,则Oracle就会在回滚段或撤销段中去寻找对应的原来未经更改的记录(而且是在读取操作所在的事务开始之前存放于回滚段或撤销段的记录),这时读取操作也不会因为相应记录被更新而等待。 乐观锁和悲观锁: 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。 乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。 两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。 compareTo和compare区别: compareTo是Compareable接口的一个方法,主要用于规定创建对象的大小关系,该对象要实现compareable接口, 当a.compareTo(b)>0时,则a>b, 当a.compareTo(b)<0时, a<b. compare方法是java.util中的Comparator接口的一个方法,compare方法内主要靠定义compareTo规定的对象大小关系来确定对象的大小。 super&this: 1)调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。 2)super()和this()类似,区别是,super从子类中调用父类的构造方法,this()在同一类内调用其它方法。 3)super()和this()均需放在构造方法内第一行。 4)尽管可以用this调用一个构造器,但却不能调用两个。 5)this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。 6)this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。 7)从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。 Redis和Memcache的区别分析: Redis中,并不是所有的数据都一直存储在内存中的,这是和Memcached相比一个最大的区别。 Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等。 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。 Redis在很多方面具备数据库的特征,或者说就是一个数据库系统,而Memcached只是简单的K/V缓存 Redis支持数据的备份,即master-slave模式的数据备份。 虚拟内存--Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘 过期策略--memcache在set时就指定,例如set key1 008,即永不过期。Redis可以通过例如expire 设定,例如expire name 10 分布式--设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从 存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化) 灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复 struts1标签库: Struts提供了五个标签库,即:HTML、Bean、Logic、Template和Nested。 HTML标签 : 用来创建能够和Struts 框架和其他相应的HTML 标签交互的HTML 输入表单 Bean标签: 在访问JavaBeans 及其属性,以及定义一个新的bean 时使用 Logic标签: 管理条件产生的输出和对象集产生的循环 Template标签:随着Tiles框架包的出现,此标记已开始减少使用 Nested标签: 增强对其他的Struts 标签的嵌套使用的能力 详解Oracle DELETE和TRUNCATE 的区别: 语法 delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以。 2.delete from记录是一条条删的,所删除的每行记录都会进日志,而truncate一次性删掉整个页,因此日至里面只记录页释放,简言之,delete from更新日志,truncate基本不,所用的事务日志空间较少。 3.delete from删空表后,会保留一个空的页,truncate在表中不会留有任何页。 4.当使用行锁执行 DELETE 语句时,将锁定表中各行以便删除。truncate始终锁定表和页,而不是锁定各行。 5.如果有identity产生的自增id列,delete from后仍然从上次的数开始增加,即种子不变,而truncate后,种子会恢复初始。 6.truncate不会触发delete的触发器,因为truncate操作不记录各个行删除。 总结 1.truncate和 delete只删除数据不删除表的结构(定义) drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger),索引(index); 依赖于该表的存储过程/函数将保留,但是变为invalid状态。 2.delete语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;如果有相应的trigger,执行的时候将被触发 truncate,drop是ddl, 操作立即生效,原数据不放到rollback segment中,不能回滚. 操作不触发trigger。 3.delete语句不影响表所占用的extent, 高水线(high watermark)保持原位置不动 显然drop语句将表所占用的空间全部释放 truncate 语句缺省情况下见空间释放到 minextents个 extent,除非使用reuse storage; truncate会将高水线复位(回到最开始)。 4.速度,一般来说: drop> truncate > delete。 5.安全性:小心使用drop 和truncate,尤其没有备份的时候.否则哭都来不及。 6.使用上,想删除部分数据行用delete,注意带上where子句. 回滚段要足够大. 想删除表,当然用drop 想保留表而将所有数据删除. 如果和事务无关,用truncate即可. 如果和事务有关,或者想触发trigger,还是用delete 如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据。 Spring中接口注入的三种方式: Type1 接口注入 我们常常借助接口来将调用者与实现者分离。如: publicclass ClassA { private InterfaceB clzB; public init() { Ojbect obj = Class.forName(Config.BImplementation).newInstance(); clzB = (InterfaceB)obj; } …… } 上面的代码中,ClassA依赖于InterfaceB的实现,如何获得InterfaceB实现类的实例?传统的方法是在代码中创建InterfaceB实现类的实例,并将起赋予clzB。 而这样一来,ClassA在编译期即依赖于InterfaceB的实现。为了将调用者与实现者在编译期分离,于是有了上面的代码,我们根据预先在配置文件中设定的实现类的类名,动态加载实现类,并通过InterfaceB强制转型后为ClassA所用。 这就是接口注入的一个最原始的雏形。 而对于一个Type1型IOC容器而言,加载接口实现并创建其实例的工作由容器完成,如J2EE开发中常用的Context.lookup(ServletContext.getXXX),都是Type1型IOC的表现形式。 Apache Avalon是一个典型的Type1型IOC容器。 Type2构造子注入 构造子注入,即通过构造函数完成依赖关系的设定,如: publicclass DIByConstructor { private final DataSource dataSource; private final String message; public DIByConstructor(DataSource ds, String msg) { this.dataSource = ds; this.message = msg; } …… } 可以看到,在Type2类型的依赖注入机制中,依赖关系是通过类构造函数建立,容器通过调用类的构造方法,将其所需的依赖关系注入其中。 PicoContainer(另一种实现了依赖注入模式的轻量级容器)首先实现了Type2类型的依赖注入模式。 Type3设值注入 在各种类型的依赖注入模式中,设值注入模式在实际开发中得到了最广泛的应用(其中很大一部分得力于Spring框架的影响)。 在笔者看来,基于设置模式的依赖注入机制更加直观、也更加自然。Quick Start中的示例,就是典型的设置注入,即通过类的setter方法完成依赖关系的设置。 几种依赖注入模式的对比总结 接口注入模式因为具备侵入性,它要求组件必须与特定的接口相关联,因此并不被看好,实际使用有限。 Type2 构造子注入的优势: 1、“在构造期即创建一个完整、合法的对象”,对于这条Java设计原则,Type2无疑是最好的响应者。 2、避免了繁琐的setter方法的编写,所有依赖关系均在构造函数中设定,依赖关系集中呈现,更加易读。 3、由于没有setter方法,依赖关系在构造时由容器一次性设定,因此组件在被创建之后即处相对“不变”的稳定状态,无需担心上层代码在调用过程中执行setter方法对组件依赖关系产生破坏,特别是对于Singleton模式的组件而言,这可能对整个系统产生重大的影响。 4、同样,由于关联关系仅在构造函数中表达,只有组件创建者需要关心组件内部的依赖关系。对调用者而言,组件中的依赖关系处于黑盒之中。对上层屏蔽不必要的信息,也为系统的层次清晰性提供了保证。 5、通过构造子注入,意味着我们可以在构造函数中决定依赖关系的注入顺序,对于一个大量依赖外部服务的组件而言,依赖关系的获得顺序可能非常重要,比如某个依赖关系注入的先决条件是组件的DataSource及相关资源已经被设定。 Type3设值注入的优势 1、对于习惯了传统JavaBean开发的程序员而言,通过setter方法设定依赖关系显得更加直观,更加自然。 2、如果依赖关系(或继承关系)较为复杂,那么Type2模式的构造函数也会相当庞大(我们需要在构造函数中设定所有依赖关系),此时Type3模式往往更为简洁。 3、对于某些第三方类库而言,可能要求我们的组件必须提供一个默认的构造函数(如Struts中的Action),此时Type2类型的依赖注入机制就体现出其局限性,难以完成我们期望的功能。 可见,Type2和Type3模式各有千秋,而Spring、PicoContainer都对Type2和Type3类型的依赖注入机制提供了良好支持。这也就为我们提供了更多的选择余地。理论上,以Type2类型为主,辅之以Type3类型机制作为补充,可以达到最好的依赖注入效果,不过对于基于Spring Framework开发的应用而言,Type3使用更加广泛。 get和post区别: 1、get请求的url带参数,post请求的url不带参数. 2、post请求是不会被缓存的. 3、长度限制: a.Get方法长度限制 Http Get方法提交的数据大小长度并没有限制,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。 如:IE对URL长度的限制是2083字节(2K+35)。 下面就是对各种浏览器和服务器的最大处理能力做一些说明. Microsoft Internet Explorer (Browser) IE浏览器对URL的最大限制为2083个字符,如果超过这个数字,提交按钮没有任何反应。 Firefox (Browser) 对于Firefox浏览器URL的长度限制为65,536个字符。 Safari (Browser) URL最大长度限制为 80,000个字符。 Opera (Browser) URL最大长度限制为190,000个字符。 Google (chrome) URL最大长度限制为8182个字符。 Apache (Server) 能接受最大url长度为8,192个字符。 Microsoft Internet Information Server(IIS) 能接受最大url的长度为16,384个字符。 通过上面的数据可知,为了让所有的用户都正常浏览, URL最好不要超过IE的最大长度限制(2083个字符),当然,如果URL不直接提供给用户,而是提供给程序调用,这时的长度就只受Web服务器影响了。 注:对于中文的传递,最终会为urlencode后的编码形式进行传递,如果浏览器的编码为UTF8的话,一个汉字最终编码后的字符长度为9个字符。 因此如果使用的 GET 方法,最大长度等于URL最大长度减去实际路径中的字符数。 b.POST方法长度限制 理论上讲,POST是没有大小限制的。HTTP协议规范也没有进行大小限制,起限制作用的是服务器的处理程序的处理能力。 如:在Tomcat下取消POST大小的限制(Tomcat默认2M); 打开tomcat目录下的conf目录,打开server.xml 文件,修改 <Connector debug="0" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" port="8080" redirectPort="8443" enableLookups="false" minSpareThreads="25" maxSpareThreads="75" maxThreads="150" maxPostSize="0" URIEncoding="GBK" > </Connector> 增加红色字体部分 maxPostSize="0" (设为0是取消POST的大小限制) 单例: Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 一般Singleton模式通常有以下两种种形式: 第一种形式:定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。 publicclass Singleton { //第一步,定义一个私有的构造函数private Singleton(){} //第二步,定义一个私有、静态的该类的实例变量,并调用构造函数初始化privatestatic Singleton instance = new Singleton(); //第三步,定义一个公有、静态的方法,用于供外部取得定义的实例变量publicstatic Singleton getInstance() { //第四步,返回(return)实例变量return instance; } } 第二种形式 publicclass Singleton { //第一步,定义一个私有、静态的该类的实例变量,并初始化为nullprivatestatic Singleton instance = null; //第二步,定义一个公有、静态、线程安全的方法,用于供外部取得定义的实例变量publicstaticsynchronized Singleton getInstance() { //第三步,判断是否是第一次调用(实例变量为空),第一次时需要创建对象if (instance == null) { instance = new Singleton(); } //第四步,返回(return)实例变量return instance; }
标签:
原文地址:http://www.cnblogs.com/sprinng/p/5476583.html