Java

基础部分part1
【1】Java基本类型
解:基本数据类型:byte short int long float double char boolean
Java基本数据类型在内存中的存储
1)基本数据类型的存储原理:所有简单的数据类型不存在"引用"的概念,基本数据类型都是直接存储在内存中的内存栈上的,数据本身的值就是存储在栈空间里面的。
2)引用数据类型的存储原理:引用类型继承于Object类(也是引用型)都是按照Java里面存储对象的内存模型来进行数据存储的,使用Java内存堆和内存栈这种类型的数据存储。“引用”是存储在有序的内存栈上的,而对象本身的值存储在内存堆上的;
区别:基本数据类型和引用数据类型的区别主要在于基本数据类型是分配在栈上的,而引用类型是分配在堆上的;
//== equals() 操作符 方法
public class Test
{
    public static void main(String[] args)
    {
        //基本数据类型 比较用 == 比较的是值
        String a ="abc";
        String b = "abc";
        System.out.println(a == b);
        String s1 = "a";
        String s2 = new String("a");
        String s3 = new String("a");
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));
        System.out.println(s2.equals(s3));
    }
}
/*
---------- java ----------
true
false
true
true
a==b
 
输出完成 (耗时 0 秒) - 正常终止
*/
 
【3】Java反射
解答:Java反射 传递class,可以动态生成该类,取得这个类的所有信息,包括里面的属性、方法以及构造函数,甚至可以取得其父类或父接口里面的内容
obj.getClass().getDeclaredMethods();//取得obj类中自己定义的方法,包括私有的方法
obj.getClass().getMethods();//取得obj类中自己定义的方法及继承过来的方法,但私有方法得不到
同样,对于field也是一样。
Java的反射机制:在运行状态,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能。
 
class:
1)一个描述类的类,封装了描述方法method、描述字段filed、描述构造器constructor
2)反射可以得到的信息:某个类的数据成员名、方法、构造器、实现了哪些接口
3)每个类,jre都为其保留一个不变的class类型的对象。一个class对象包含了特定某个类的有关信息。
4)class对象只能由系统建立对象
5)一个类在JVM中只会有一个class实例
 
【3】this、super
【4】Java中创建对象的方法
1、通过new关键字创建对象
2、利用Java的反射机制,通过java.lang.Class或者java.lang.reflect.Constructor创建对象
3、实现Cloneable接口,重写Object.clone()方法创建对象
4、实现序列化serialiable接口,通过反序列化,ObjectInputStream的readObject()方法创建对象
5、String str="abc"直接由jvm创建 或者 使用字符串操作符“+” String str1 = "a" + "bc"由jvm创建
 
【5】java为什么能够跨平台运行
java程序编译之后的代码不能被硬件系统直接运行的代码,而是一种“中间码”--字节码。不同的硬件平台上安装有不同的java虚拟机(JVM),由JVM来把字节码再“翻译”成所对应的硬件平台能够执行的代码。因此对于Java编程者来说,不考虑硬件平台是什么。
【6】整型数据转化为字符串的方式
1、直接在数字后面加 空格
2、使用String.valueOf(int i )
3、Integer.toString(i);
 
int转String
int i;
1)String s = String.valueOf(i);  //valueOf(Type patameter): 返回类型参数的字符串表示形式
2)String s = Interger.toString(i);   //toString() 返回表示此整数值的字符串对象
3)String s = "" + i;
 
String转int
1)int i = Integer.parseInt([String]);  //parseInt(String)方法是类Integer的静态方法,作用讲形参s转化为整数
2)int i = Integer.valueOf(my_str).intValue()  //valueOf将形参s转化为Integer对象,再调用intValue方法,将对象表示形式转化为基本数据
 
String数组转字符串
利用StringBuffer / StringBuilder的append()方法
package com.wyp.string;

public class StringTest {

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
           String[] arr = {"0","1","2"};
        StringBuffer stringbuffer = new StringBuffer();
        StringBuilder stringbuilder = new StringBuilder();
        for(int i=0; i<arr.length; i++) {
            stringbuffer.append(arr[i]);
        }
        for(int i=0; i<arr.length; i++) {
            stringbuilder.append(arr[i]);
        }
        
        String s1 = stringbuffer.toString();
        String s2 = stringbuilder.toString();
        System.out.println(s1);
        System.out.println(s2);
    }

}

 char数组转字符串

String st = string.copyValueof(char arr[]);

String st = new String(char arr[]);

字符串转数组

String st = "abc",st可以调用一下函数

split():如果用".""|"作为分隔符,需要如下写法String.split(".") 空格无需

toCharArray() : 将此字符串转换为新的字符数组

getByte():将字符串转化为一个序列使用平台的默认字符集字节,结果存放到一个新的数组。

replace():

charAt(int index) 返回指定索引处的char值

【7】String是基本数据类型吗?能不能写个类继承String?
String是引用数据类型;String是final的类,是不可以被继承的。
 
【8】&   &&的区别
 都可以用作逻辑与的运算符。
&&短路运算符,如果第一个表达式为false,则不再计算第二个表达式
&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作。
 
【9】switch语句中的条件
用于switch判断的类型:byte、short、int、char(JDK 1.6),还有枚举类型,在JDK1.7后添加了对String类型的判断。case语句中少些了break,编译不会报错,但是会一直执行之后所有的case条件下的语句而不再判断,知道default语句。没有符合条件的case语句,就会执行default下的代码块,default并不是必须的,也可以不写。
 
【10】short s1=1;s1=s1+1; 错误?short s1=1;s1+=1; 错误?
s1+1运算时会自动提升表达式的类型,所以结果是int型。
+=是java语言规定的运算符,java编译器会对他进行特殊处理,可以编译通过。
【11】char为什么能存储一个汉字
char型变量是用来存储Unicode编码的字符的,Unicode编码字符集中包含了全世界所有的字体。
【12】用最有效率的办法算出2乘以8等于几?
2<<3 位移运算是最底层的运算,它直接操作的是二进制,故效率很快
【13】final修饰变量时,该变量是对象时,对象的值可不可以改变?
final修饰的变量指的是引用不可变,对象的值是可以改变的。
final关键字修饰一个变量时,是引用对象的地址值不能变,引用对象所指向的对象内容时可以改变的。final变量永远指向这个对象,是一个常量指针,而不是指向常量的指针。
 
final可以用来修饰变量(类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类
1、final修饰类
final修饰类不能被继承,即不能拥有自己的子类。
2、final修饰的方法不能被重写(可以重载多个final修饰的方法)。因为重写的前提是子类可以从父类中继承此方法,如果父类中final修饰的方法同时访问控制权限为private,将会导致子类中不能直接继承到此方法,因此可以在子类中定义相同的方法名和参数,此事不再产生重写与final的矛盾,而是在子类中重新定义了新的方法。
3、final修饰的变量值不可被改变。
final修饰的变量,无论是类属性、对象属性、形参还是局部变量,这些变量都是需要进行显示初始化(即为其显示指定初始值)。
4、final修饰变量后导致的"宏替换/宏变量"
指的是java代码中在编译期某些变量能够直接被其本身的值所替换,编译到.class文件中。final修饰符修饰的变量在由于其本身的特性,在编译期就能直接确定其值 ,且此值不可变。在编译过程中,可以直接将其变量直接转换成其值本身去表示。
 
【14】静态变量和实例变量的区别?
静态变量也称为类变量,归全类所有,它不依赖某个对象,可通过类名直接访问;而实例对象必须依存于某一实例,只能通过对象才能访问它
【15】面对对象的基本特征?
1、继承:子类拥有父类一切非私有的属性和方法。
2、封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
3、多态性:同一事物的不同种表现形式。
4、抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,一遍更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面:过程抽象和数据抽象。
 
【16】作用域public private protected 以及不写时的区别(当前类 同包 子孙类 其他)
默认为default 
 
【17】overload 和 override的区别
overload(重载):发生在同一个类中,方法名相同,参数列表不同,与返回值无关,与final无关,与修饰符无关、与异常无关
override(重写):发生在子类和父类之间,方法名相同、参数列表相同、返回值相同、不能是final的方法、重写的方法不能有比父类方法更为严格的修饰符权限、重写的方法所抛出的异常不能比父类的更大
如果父类私有的方法,子类拥有方法签名相同的方法,子类不属于重写父类的方法,该方法属于子类的新方法
 
【18】构造器(构造方法)可不不可以被重载或者重写
构造器不能被继承,故不能被重写、但可以被重载
1)构造器和方法的区别
1、功能不同:构造器是为了创建一个类的实例,命名与类名相同,可以有任何访问的修饰,无返回值。
this:
方法引用this指向的正在执行方法的类的实例。静态方法不能使用this关键字,构造器的this指向同一个类中,不同参数列表的另一个构造器。
在构造器中,如果要使用关键字this,必须放在第一行。
super:
构造器和方法,都用关键字super指向超类,但是用法不一样,方法用这个关键字去执行被重载的超类中的方法。
使用super调用超类中的构造器,这行代码必须放在第一行。
 
【19】Java有没有多继承
java中没有多继承,但是可以多实现,即一个类实现多个接口。
虽然没有多继承,但是java中接口可以近似的实现多继承,那就是接口;
接口和接口之间可以进行多继承
 
【20】抽象类和接口的区别
1、抽象类继承与object接口不继承object
2、抽象类有构造器,接口中没有构造器
3、抽象类中可以有普通成员变量和常量,接口中只能有常量,而且只能是public static final不写默认
4、抽象类中可以有抽象方法,也可以有普通方法,接口中只能有抽象的方法,而且修饰符只能是public abstract 不写默认
5、抽象类中可以有final的方法,接口中不能有final的方法
6、抽象类只能是单继承、多实现;接口是可以多继承其他接口,但是不能实现接口和不能继承其他类
7、抽象类中可以有静态的方法,接口中不可以
 
【21】java中实现多态的机制是什么
重写、重载、父类的声明指向子类的对象
 
【22】int  integer的区别
int是java的基本数据类型
integer是基本类型包装类。
初始化值:int:0      integer : null
其中integer提供了一些对整数操作的方法,定义了integer型数值的最值,其他基本类型也有对应的包装类,基本类型包装类的出现,是的java完全面对对象
 
【23】String和StringBuffer的区别?StringBuffer和StringBuilder区别?
String是不可变的,对String类的任何改变都会返回一个新的String的对象。
StringBuffer是可变的,对StringBuffer中的内容修改都是当前这个对象。
String重写了equals方法和hashCode方法,StringBuffer没有重写equals方法
String是final的类。StringBuffer不是。
 
String创建的字符串是在常量池中,创建的变量初始化一次,如果再对该字符串改变会产生新的字符串地址值,StringBuffer是在堆中创建对象,当对字符串改变时不会产生新的字符串地址值,如果对字符串进行频繁修改的话建议使用StringBuffer,以节省内存。
StringBuffer和StringBuilder,StringBuffer是线程安全的,StringBuilder是线程不安全的。当不考虑并发问题时候,用StringBuilder。
 
【24】String s = new String("xyz"); 创建了几个String Object?
两个对象,一个是“xyz” 一个是指向“xyz”的引用对象s
 
【25】数组中有没有length()方法,String中有没有length方法?
数组中没有length()方法,但是有length属性,String中有length()方法
 
【26】try{}里面有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候执行,在return前还是后?
a、finally中没有return时候:先会执行try里面的,return会执行但是没有真正的return此时去执行了finally里面的,然后再返回来执行return。
b、finally中有return时候(会有黄线警告):会先执行try里面的,return会执行但没有真正的return此时去执行了finally里面的,然后执行finally里面的return,直接返回。 
 
【27】final finally finalize
final 用于声明属性、方法和类;分别表示属性不可变,方法不可覆盖,类不可继承。
finally 是异常处理语句结构的一部分,表示总是执行
finalize 是object类的一个方法,在垃圾收集器执行的时候回调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。jvm不保证此方法总被调用
 
【28】==   和 equals()区别
== 比较的是两个变量的内容和在内存中的地址值是否相同;如果比较两个基本数据类型必须用“==”
equals()如果没有重写,和==意义一样,但是如果重写了,则会按照重写的内容进行比较,javaBean规定当重写equals时候必须重写hashcode,如果不重写会出现对象相同但是hashCode不同,这样会出现问题。
hashSet存储元素时候按照hashCode,如果重写equals不重写hashCode会导致同一个对象,存储了两次。
 
【29】error 和 exception的区别
error表示恢复不是不可能但是很困难的情况下的一种严重问题,例如程序书写错误、虚拟机错误等。
exception是一种设计和实现问题,如果程序运行正常,从不会发生的问题
error是可以避免的,但是exception是不可以避免的
 
【30】java的checked和unchecked异常
1、unchecked异常即运行时异常。即runtimeexception,不需要try catch throws机制去处理的异常
2、除了runtimeexception,其他继承自java.lang.exception的异常统称为checked exception。
【31】java中有几种方法可以实现线程?用什么关键字修饰同步方法?stop 和 suspend 方法为何不推荐使用?
1、实现线程的两种方法:
继承Thread类,重写run方法,再调用start方法。
实现Runnable接口,重写run方法。再传给Thread构造器,调用时调用Thread的start方法
2、用synchronized关键字修饰同步方法
3、不使用stop方法,是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种并不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。
suspend方法容易发生死锁。调用suspend的时候,目标线程会听下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源。除非被“挂起的”线程恢复运行,对任何线程来说,如果他们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend,而应在自己的thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,使用wait命其进入等待状态。若标志指出线程应当恢复,则用一个notify重新启动线程。
 
【32】sleep 和 wait区别?
sleep是线程类Thread的方法,导致此线程暂停执行指定时间,给执行机会到其他线程,但是监控状态依然保持,到时后自动恢复。调用sleep不会释放对象锁。
wait是object类的方法,对此对象调用wait方法导致本线程方法对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
 
【33】当一个线程进入一个对象的一个synchronized方法后,其他线程是否可进入此对象的其他方法?
1、其他对象前是否加了synchronized关键字,如果没加,就可以
2、如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3、如果其他各方法都加了synchronized关键字,并且内部没有调用wait方法,则不能。
4、如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。
 
【34】线程的基本概念、线程的基本状态以及状态之间的关系
一个新的线程可以使用两种方法创建:1、继承thread类。2、实现runnable接口,创建之后通过start方法进入到运行状态,在运行状态中可以使用yield方法进行礼让,但是仍然可以进行,如果现在一个线程需要暂停的话,可以使用suspend(暂时挂起,resume表示挂起恢复)、sleep、wait方法,如果现在让线程不再执行,则可以通过stop结束,run方法运行完也表示结束。其中suspend、resume、stop方法都可能产生死锁的问题,所以不建议使用了。应该通过设置标示位来控制线程的停止运行。
 
一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个CPU,它怎么能够同时执行多段程序?从宏观上来看,CPU一会儿执行a线索,一会执行b线索,切换时间很快,给人的感觉是a、b在同时执行,好比大家在一个办公室上网,只有一条链接到外部网线,其实,这条网线一会为a传数据,一会为b传数据,由于切换时间很短暂,大家感觉都在同时上网。
 
状态:就绪、运行、synchronized阻塞,wait和sleep挂起、结束。wait必须在synchronized内部调用。
调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转换为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,有阻塞转为运行,在这种情况下可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。
 
【35】
 
数据库部分part2
【1】触发器
触发器是一种特殊的存储过程,主要是通过事件而触发并被执行的,它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级运算。如某表上的触发器上包含对另一张表的数据操作。而该操作又会导致该表触发器被触发。
 
【2】存储过程
存储过程是一个预编译的sql语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次sql,使用存储过程就比单纯sql语句执行要快。可以用一个命令对象来调用存储过程。
 
【3】删除表的方法
delete truncate drop
drop是删除表,使用drop之后表的结构和表的数据都会被删除,truncate和delete是删除表中的数据,但不删除表本省,truncate和delete相比,truncate要快很多,但是缺点是无法回滚,包括索引等都会被成初始值,数据就无法恢复。
 
【4】索引
索引就是一种特殊的查询表,书户口的搜索引擎可以利用他加速对数据的检索。它很类似现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。索引可以是唯一的,创建索引允许指定单个列或者多个列。
缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。
 
【5】事务?锁?
事务处理:数据的操作是一个整体,可以理解为一个完整的业务,如果其中出错,则所有的操作都应该不再执行,而且回归到最原始的状态,而这一个操作流程就是 事务的操作。所有的事物操作都针对每一个session进行的,每一个链接到数据库的用户都成为一个session,每一个session之间彼此独立,不会有任何的通讯,而每一个session独享自己的事务控制,而事务控制之中有两个命令:rollback和commit。
问题出现死锁:例如某一个session在更新数据时还没有提交事务,其他session是无法更新的,必须等待之前的session提交后才可以。
 
解释:
事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就会被失败,以后的操作就会回滚到操作之前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性、一致性、隔离性和持久性。
锁:
在所有的DBMS中,锁是实现事务的关键。锁可以保证事务的完整性和并发性。与现实生活中的锁一样,它可以使某些数据的拥有者,在某段时间内不能使用某些数据或数据结构,锁还分级别。
 
【6】视图?游标?
视图是一种虚拟的表,具有和物理表相同得功能,可以对视图进行增、改、查操作,视图通常是有一个表或者多个表的行或列的自己。对视图的修改不影响基本表。使得或者数据更容易,相比多表查询。
 
游标:游动的光标。游标是映射在结果集中一行数据上的位置实体,有了游标,用户就可以访问结果集中任意一行数据了,将游标放置到某行后,即可对该行数据进行操作。例如:提取当前行的数据。
游标是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中额特定行,从结果集的当前行检索一行或多行,可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。
 
【7】表连接方式?
内连接:只有两个元素表相匹配的才能在结果集中显示
自连接:自己跟自己关联查询,数据表使用不同的别名。
外连接:
  • 左外连接  左边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。
  • 右外连接:右边为驱动表,驱动表的数据全部显示,匹配日表不匹配的不会显示。
  • 全外连接:连接的表中不匹配的数据全部都会显示出来。
交叉连接:笛卡尔效应,显示的结果是链接表数的乘积。
 
【8】主键?外键?
主键是本表中是惟一的,不可唯空的,外键可以重复可以唯空;
外键和另一张表的主键关联,不能创建对应表中不存储的外键。
 
【9】在数据库中查询语句速度很慢,如何优化?
解答:
1、建索引
2、减少表之间的关联
3、优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,吧数据量大的表排在前面。
4、简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据。
5、尽量用preparedStatement来查询,不要用Statement
 
【10】数据库三范式
第一范式(1NF)
第二范式(2NF)
第三范式(3NF)
 
【11】union 和 union all有什么不同?
union在进行表链接后 会筛选掉重复的记录,所以在表链接后对所产生的结果集进行排序运算。删除重复的记录再返回结果。实际大部分时不会产生重复的记录,最常见的是过程表和历史表union
union all只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
从效率上说,union all要比union快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用union all
 
【12】用JDBC如何调用存储过程
package com.wyp.test;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
 
public class JdbcTest {
    /**
     * @param args
     */
 
    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Connection cn = null;
        CallableStatement cstmt = null;
        try {
            //这里最好不要这么干,因为驱动名写死在程序中了
            Class.forName("com.mysql.jdbc.Driver");
            //实际项目中 应用DataSource数据 ,如果用框架 这个数据源不需要要编码创建,只需
            //DataSource ds = context.loopup()  cn = ds.getConnection();
            cn = DriverManager.getConnection("jdbc:mysql:///test", "root", "");
            cstmt = cn.prepareCall("{call insert_Student(?,?,?)}");
            cstmt.registerOutParameter(3, Types.INTEGER);
            cstmt.setString(1, "wu");
            cstmt.setInt(2, 25);
            cstmt.execute();
            //get第几个 不同数据库不一样,建议不写
            System.out.println(cstmt.getString(3));
        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(cstmt != null)
                    cstmt.close();
                if(cn != null)
                    cn.close();
            }catch(SQLException e) {
                e.printStackTrace();
            }
        }
    }
 
}
 
【13】JDBC中的PreparedStatement相比Statement的好处
1、提高性能
2、防止sql注入
【14】什么是防止sql注入
 
【15】JDBC连接数据库
 
 
【20】Oracle 和 MySQL的区别
1、库函数不同
2、Oracle是用表空间来管理的,MySQL不是
3、显示当前所有的表、用户、改变连接用户、显示当前连接用户、执行外部脚本的语句的不同。
4、分页查询,MySQL 用limit oracle用rownum
5、sql的语法的不同
 
【21】varchar2  、 varchar 和 char区别
1、char的长度是固定的,而varchar2的长度是可以变化的,比如,存储字符串“abc”,对于char(20)表示存储的字符将占20个字节,包含17个空,而同样的varchar2(20)只占了3个字节,20 只是最大值,当你存储的字符小于20时,按实际长度存储
2、char的效率要被varchar2的效率高
3、目前varchar是varchar2的同义词。工业标准呢的varchar类型可以存储空字符串,但是Oracle不能这样做,尽管它保留了以后这样子做的权利。Oraclei自己开发了一个数据类型varchar2,这个类型不是一个标准的varchar,他将在数据库中varchar列可以存储空字符串的特定改为存储null值,如果想有向后兼容的能力,Oracle建议使用varchar2而不是varchar。
 
【22】Statement和preparedstatement有什么区别?
后者的效率比前者高,在使用preparedstatement对象执行sql时候,命令被数据库编译和解析,然后被放到命令缓冲区,然后每当执行同一个preparedstatement时候,他就被再解析一次,但不会被编译,在缓冲区可以发现预编译的命令,而且可以重新使用。
如果要写insert update delete 最好使用preparedstatement,在有大量用户的企业级应用软件中,经常会执行相同的sql,使用preparedstatement会增加整体的性能。
 
xml部分part3
【1】解析技术
1、DOM:处理大型文件时其性能下降的非常厉害
2、SAX
3、DOM4J
4、JDOM
 
【2】xml技术的运用
 
【3】编程:用java解析xml方式
【4】xml的文档定义
【5】xml和 html的区别
【6】xml文件和普通文件的区别
【7】JSON
JSON(javascript object notation)是一种轻量级的数据交换格式,主要用于传送数据。
JSON可以将JavaScript对象中表示的一组数据转换为字符串,
 
框架部分part7
【1】Structs2?
 
【2】hibernate
1、面向对象设计的软件内部运行可以理解为在不断创建各种新对象、建立对象之间的关系,调用对象方法来改变各个对象的状态和对象消亡的过程,不管程序运行过程和操作怎么样,本质上都是得到一个结果,程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化。
2、为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保持到
持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息。从Java程序的运行功能上来讲,保存对象状态的功能相比系统运行的其他功能来说,应该是一个很不起眼的附属功能,java采用jdbc来实现这个功能,这个不起眼的功能却要编写大量的代码,而做的事情仅仅是保存对象和恢复对象,并且那些大量的jdbc代码并没有什么技术含量,基本上市采用一套例行公事的标准代码模板来编写,是一种苦活和重复性的工作。
3、通过数据库保存java程序运行时产生的对象和恢复对象,其实就是实现了java对象与关心数据库记录的映射关系,称为ORM ,人们可以通过封装JDBC代码来实现了这个功能,封装出来的产品称之为ORM框架,hibernate就是其中一种流行的框架,使用hibernate框架,不用写JDBC代码,仅仅是调用一个save方法,就可以将对象保存到关系数据库中,仅仅是调用一个get方法,就可以从数据库中加载出一个对象。
4、使用hibernate基本流程:配置configuration对象,产生sessionfactory、创建session对象、启动事务、完成CRUD操作,提交事务,关闭session。
5、使用hibernate时,先要配置hibernate.cfg.xml文件,其中配置数据库连接信息和方言等,还要为每个实体配置相应的hbm.xml文件,hibernate.cfg.xml文件需要登记每个hbm.xml文件。
6、在应用hibernate时,重点要了解session的缓存原理,级联、延迟加载和hql查询。
 
1)hibernate数据的三个状态。
把数据库比喻成一个登记簿,当我们把信息登记到登记簿上的时候,这个过程就是持久化过程。当登记完成之后,登记簿上的数据就是持久态数据,所谓持久态就是一直存在的状态。当我们徐亚用数据的时候,就会从登记簿上查信息,我们查到的信息记录在临时的纸张或者脑海里,然后登记簿会放回原位,这时候临时纸张上或者脑海里的数据就是游离态,随时可能被遗忘,在hibernate中就是随时会被销毁的数据。瞬态数据和游离态数据类似,个人信息还没登记到登记簿上的时候,信息就是瞬态,一旦登记到登记簿上就变成持久态,然后再查询到的就是游离态。
a.瞬时状态(临时状态)
当new对象时,处于瞬时状态(如果程序运行玩了,该对象会被垃圾回收)
b.持久状态
跟session有关,就是持久状态
持久状态的对象,任何的修改,都会影响到数据库中与之对应的数据
c.托管状态(游离状态)
当session不在管理对象时候,脱离了session的管理,处于托管状态的对象,修改属性,对数据库数据没有任何影响。
企业开发时,使用saveOrUpdate(obj);来替代save(obj)或update(obj)方法。
避免因为状态的改变,导致方法出错,saveOrUpdate( obj )
可以根据obj的状态,来选择是save()还是update()
 
2)load 和 get 区别
1、如果数据库中,没有userId的对象,如果通过get方法加载,则返回的是一个null;
如果通过load则返回一个代理对象,如果后面代码调用user对象的某个属性,会抛出objectNotFoundException.
2、load支持延迟加载,get不支持
 
3)getCurrentSession 和 openSession 区别
1、getCurrentSession创建的session会绑定到当前线程,而openSession不会
2、getCurrentSession创建的线程会在事务中回滚或事物提交后自动关闭,而openSession必须手动关闭。
 
4)工作原理
1、读取并解析配置文件
2、读取解析映射信息,创建sessionFactory
3、打卡session
4、创建事物transation
5、持久化操作
6、提交事务
7、关闭session
8、关闭sessionfactory
 
5)为什么要用hibernate?
1、对jdbc访问数据库的代码做了封装,大大简化了数据库访问层繁琐的重复性代码
2、hibernate是一个基于JDBC的主流持久性框架,是一个优秀的ORM实现,它很大程度的简化DAO的编程工作
3、hibernate使用java反射机制,而不是字节码增强程序来实现透明性
 
6)hibernate如何延迟加载?
lazy策略为延迟加载策略,hibernate通过jdk代码对其进行实现,即使用延迟加载的对象,在获取对象的时候返回的是对象的代理,而不是对象的真正的引用,只有在对象真正被调用的时候,hibernate才会对其进行查询,返回真正的对象。
 
这在某种程度上对性能祈祷一定的优化。hibernate的延迟加载还可以减少程序与数据库的连接次数,因为使用了延迟加载,hibernate将延缓执行sql数据,减少对数据库的访问次数,从而提高执行效率。
 
内部缓存存在hibernate中又叫一级缓存,属于应用事务级缓存。
二级缓存:是sessionfactory级别缓存,它是属于进程范围货群集范围的缓存,这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载,hibernate还为查询结果提供了一个查询缓存,依赖于二级缓存。
 
 
7)缓存
一级缓存 session缓存
 一级缓存 session级缓存,其生命周期很短,与session相互对应。一级缓存由hibernate进行管理,属于事务范围的缓存。
当程序调用session的load、get、save、saveOrUpdate、update方法或查询接口方法时,hibernate会对实体对象进行缓存;当通过load方法或get方法查询实体对象时,hibernate会首先到缓存中查找,在找不到实体对象的情况下,hibernate才会发出sql语句到数据库中查询,从而提高了hibernate的使用效率。
 
二级缓存sessionfactory缓存
二级缓存是sessionfactory级的缓存,其生命周期与sessionfactory一致。二级缓存可以在多个session之间共享,属于进程范围或群集范围的缓存。
二级缓存是一个可插拔的缓存插件,它的使用需要第三方缓存产品的支持。在hibernate框架中,通过hibernate配置文件配置二级缓存的使用策略。
注:对于二级缓存,可以使用一些不经常更新的数据或参考的数据,此时其性能会得到明显的提升。例如一个新闻网站,当发布一条热点新闻时,会有成千上万的访问量,而此条新闻并没有发生任何的变化,如果每一个用户访问都要查询数据库,势必对系统性能造成一定的影响,此时可以考虑应用二级缓存。如果经常变换的数据则不应应用二级缓存。
 
8)优化hibernate
使用双向一对多关联,不使用单向一对多
灵活使用单向一对多
不使用一对一,用多对一取代
配置对象缓存,不适合集合缓存
一对多集合使用bag,多对多使用set
继承类使用显示多态
表字段要少,表关联不要怕多,有二级缓存
 
9)hibernate的主键生成策略
1、
 
【3】ORM
对象到关系的映射
类-->表   对象-->表中的每一条数据  属性-->表中的列   特殊的属性-->主键(作为每条书的标识)
 
 
【3】spring
 
设计模式part8
经典案例part9
 
拼命敲
原文地址:https://www.cnblogs.com/wuyuwuyueping/p/9125620.html