面向对象
面向对象的特性
- 抽象:忽略一个主题中与当前目标无关的那些方面,以便充分地注意与当前目标有关的方面,包含两个方面:过程抽象和数据抽象
- 封装:把过程和数据包围起来,对数据的访问只能通过已定义的界面
- 继承:一种联结类的层次模型,并且允许和鼓励类的重用
- 多态:允许不同类的对象对同一信息做出不同响应,或者同一类的对象的同一行为对不同消息做出不同的响应;具有灵活、抽象,行为共享,代码共享的优势,很好的解决了应用程序函数同名问题
什么是继承
继承的优缺点
- 优点:提高重用性和开发效率
- 缺点:高耦合
属性覆盖
1)private变量受访问权限的限制,不能被覆盖2)属性的值取自父类还是子类并不取决于我们创建对象的类型,而是取决于我们定义的变量的类型3)default、protected和public修饰符并不影响属性的覆盖4)静态变量和静态常量属于类,不属于对象,因此他们不能被覆盖5)常量可以被覆盖6)对于基本数据类型和对象,适用同样的覆盖规律
重载和重写
方法的签名:方法名称、参数数量、参数类型、参数顺序
方法的签名:方法名称、参数数量、参数类型、参数顺序
什么是多态?
一种类型表现出多种状态
一种类型表现出多种状态
前期绑定与后期绑定
前期绑定:在程序运行前进行绑定,由编译器和连接程序实现,如:静态方法,final方法和private方法
后期绑定:在运行时根据对象的类型进行绑定,由方法调用机制实现,除了前期绑定外的方法都是后期绑定,多态就是在后期绑定这种机制上实现的
多态的好处
消除了类之间的耦合性——假入没有多态,就需要在相同接口处针对每个子类定义一个接口
限定符
- private:类
- 空:类、包
- protected:类、包、子类
- public:类、包、子类、其他
- abstract:不可与static、final、synchronized和native共存
- static
- final
- synchronized
- native
- if
- switch
- 支持的数据类型:byte、short、int、char和对应的封装类(Java5以上),Enum类型(Java5以上),String(Java7以上)
- ...
- goto:保留字,不使用
- final
-
- 定义常量(包含静态和非静态的)
- 初始化:1)定义时;2)非静态常量可在初始化块中初始化,不可在静态初始化块;3)静态常量可在静态初始化块初始化,不可在初始化块;4)非静态常量可在构造器中初始化,但静态常量不可以;
未初始化:编译时报错 - 性能问题:常量有更高的效率
-
- 定义方法的参数
- 定义方法:不允许被子类重写,但是可以继承使用
- 定义类:final类不允许被继承,编译器在处理时把所有方法也当做final的(不能用于抽象类和接口)
- finally:放在try/catch语句中,附带的语句块始终会执行,即便使用了return,conitue和break等跳转语句
- finalize:java.lang.Obejct的方法,在GC清理对象时调用,如果抛出无法捕获的异常,GC将终止当前对象的清理(也可以主动调用System.funFinaliaeronExit(true)来调用所有对象的final方法)
- ...
区分不同数据类型
- 原始数据类型
- 包装类
- final类
- 普通类
- 接口
- 枚举
- 内部类
-
- 成员内部类
- 静态内部类
- 匿名内部类
- 局部内部类
- ...
bype | java.lang.Byte | 8 | -128至127 |
short | java.lang.Short | 16 | -32768至32767 |
int | java.lang.Integer | 32 | -2147483648至2147483647 |
long | java.lang.Long | 64 | -92233720368477808至92233720368477807 |
float | java.lang.Float | 32 | 约-3.40282347E38至3.40282347E38(有效小数为6-7位) |
double | java.lang.Double | 64 | 约-1.797693134862317E308至1.797693134862317E308(有效小数为15) |
char | java.lang.Character | 16 | 一个字节 |
boolean | java.lang.Boolean | - | - |
大小:java.lang.包装类名.SIZE
最小值:java.lang.包装类名.MIN_VALUE
最大值:java.lang.包装类名.MAX_VALUE
其他:java.lang.Float和float,java.lang.Double和double的最小值和最大值不一致
原始数据类型和封装类的区别
其他:java.lang.Float和float,java.lang.Double和double的最小值和最大值不一致
- 大小和速度问题
- 数据结构存储
- 缺省值
- 基础数据类型与包装类:Java5.0(1.5)开始可以自动转换
- 数值类型
-
- 未带有字符后缀表示的整数默认为int类型
- 未带有字符后缀表示的浮点数默认为double类型
- 如果一个整数的值超过了int类型能够表示的范围,则必须增加后缀"L"
- 自动转换
-
- 类型大小:bype < short/char < int < long < float < double
- 小类型变量赋值给大类型变量时,可以自动转换
- 大类型变量赋值给小类型变量时,编译错误
- int型数值可以赋值给所有数值类型的变量,比int小的类型会检查是否溢出
- long型数值可以赋给long,float,double
- float型数值可以赋给float和double
- double型数值可以赋给double
- 强制转换:略
字符串-到底创建了几个对象?
String、StringBuffer与StringBuilder之间区别
中文汉字
ascii表的字符可以赋值给bype,中文汉字不可以(中文汉字占用两个字节),Java默认编码使用UTF-16BE
按字节截取含有中文汉字的字符串
StringBuffer.reverse()
内部类
成员内部类
- String str = "..."; //一个对象或0个,位于常量池
- String str = new String("..."); //两个或一个对象,一个在堆中,一个在常量池
- String str = new String(String变量); //一个对象,位于堆中
- String str = new String(char value[]); //一个对象,位于堆中
String、StringBuffer与StringBuilder之间区别
中文汉字
ascii表的字符可以赋值给bype,中文汉字不可以(中文汉字占用两个字节),Java默认编码使用UTF-16BE
char a = '我'; System.out.println(Integer.toBinaryString(a)); //110001000010001,及98 17 String b = "我"; b.getBytes("UTF-16BE"); //98 17
//b.getBytes(); //根据源代码文件所使用的编码相同
|
按字节截取含有中文汉字的字符串
- 1)获取字符串在不同编码下的字节数:String.getBytes(encodingName).length,配合new String(byte[] bytes, String charsetName),可以字符串转为不同的编码格式
- 2)获取字符串在平台默认编码下的字节数:String.getBytes().length,平台的默认编码跟源代码的文件编码一致
- 3)实现思路:按字符一个个获取字符串里的字符,针对每个字符使用String.getBytes().length来获取占用的字节数,然后减去需要获取的字节总数,直至小于等于0
StringBuffer.reverse()
内部类
成员内部类
- 作为外部类的一个成员存在,与外部类的属性、方法并列
- 定义规则:1)不能定义静态变量;2)不能定义静态方法
- 实例化:外部类名称.内部类名称 变量名 = 外部类实例.new 内部类名称();
- 属性访问/方法调用
-
- 可以访问外部类的任意成员,无论限定符是什么,无论是静态还是非静态
- 外部类不可以访问内部类的私有成员
- 外部类和内部类没有同名变量/方法时,如果在内部类存在该变量则访问内部类,不存在访问外部类,都不存在编译不通过
- 外部类和内部类有同名变量/方法时,如果要访问内部类变量则直接写“变量”或“this.变量”,如果要访问外部类变量则写“外部类名称.this.变量”
- 应用:无
- ...
- 在方法中定义的内部类,与局部变量类似
- 定义规则
-
- 类修饰符只能使用abstract和final
- 不可定义静态变量
- 不可定义静态方法
- 属性访问/方法调用
-
- 可以访问定义内部类的所在程序块的局部变量(即方法内的变量),但是变量必须是final的
- 定义内部类的所在方法是非静态方法,可以访问外部类的所有成员
- 定义内部类的所在方法是静态方法,可以访问外部类的静态成员
- 外部类和内部类没有同名变量/方法时,如果在内部类存在该变量则访问内部类,不存在访问外部类,都不存在编译不通过
- 外部类和内部类有同名变量/方法时,如果要访问内部类变量则直接写“变量”或“this.变量”,如果要访问外部类变量则写“外部类名称.this.变量”
- 应用:无
- 定义规则:
-
- 静态内部类定义在类中,任何方法外,用static定义
- 允许使用修饰符public,protected,default,private
- 允许定义静态变量和非静态变量
- 允许定义静态方法和非静态方法
- 实例化:外部类名称.内部类名称 变量名 = new 外部类名称.内部类名称(); //如果在当前外部类则无需加上外部类名称标识
- 属性和方法调用:只能访问外部类的静态成员和方法
- 应用:略
匿名内部类
- 一种特殊的局部内部类,它是通过匿名类实现接口
- 定义规则:
-
- new 类名/接口名...
- 匿名内部类如果继承自接口,必须实现指定接口的方法,且无参数
- 匿名内部类如果继承自类,参数必须按父类的构造函数的参数传递
- 特点
-
- 一个类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是覆盖。
- 类名没有意义,也就是不需要使用到
- 只是为了获得一个对象实例,不需要知道其实际类型
- 属性访问/方法调用:类似局部内部类
- 应用:接口回调
计算
- +、-、*、/、%
-
- 两个操作数中有一个是double类型的,另一个转会转换成double类型,并且结果也是double类型
- 否则,两个操作数中有一个是float类型的,另一个转会转换成float类型,并且结果也是float类型
- 否则,两个操作数中有一个是long类型的,另一个转会转换成long类型,并且结果也是long类型
- 否则,两个操作数都转换成int类型,并且结果也是int类型
- +=、-=、*=、/=、%=
运算符右边的数值(变量不可以)将首先被强制转换成与运算符左边变量相同的类型,然后再执行计算,并且运算结果与运算符左边变量类型相同 - ==
- 只要两个操作数中有一个是基本类型,就是比较他们的数值是否相等
- 否则,判断这两个对象的内存地址是否相等
- java.lang.Math
- floor:取一个小于等于参数值的最大整数
- round:取一个小于等于参数值加0.5的最大整数,即floor(参数值 + 0.5)
- 自增/自减
-
- 支持数据类型:1)除了boolean的基本数据类型;2)除了boolean的基本数据类型的包装类(Java5.0及以上版本)
-
- 用法
前缀式:先计算后取值
后缀事:先取值后计算 - 其他:1)运算结果的数据类型与被运算的变量的类型相同
- 用法
- ...
- 支持的数据类型:byte、short、char、int和long,以及对应的包装类(Java5.0及以上版本)
- 运算符
-
- &(按位与运算):略
- |(按位或运算):略
- ^(按位异或运算):当被运算的两个值中任意一个为1,另外一个为0时,运算结果为1;否则为0
- ~(按非运算)
- ...
- 支持的数据类型:byte、short、char、int和long,以及对应的包装类(Java5.0及以上版本)
- 运算符
-
- <<(左移位):低位补0
- >>(右移位):正数高位补0,负数高位补1
- >>>(无符号右移位):高位补0
- 规则:
- 运用:
- 使用最有效率的方法计算出2乘以8等于几?——2 << 8
- ...
- 支持的数据类型:布尔值和能产生布尔值的表达式
- 遵循短路形式
-
- ...
数据流分类
- 字节流:数据流中最小的数据单元是字节
- 字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节
IO层次体系结构
- 流式
-
- 字节流:InputStream、OutputStream
- 字符流:Writer、Reader
- 非流式:File、RandonAccessFile
- 其他
IO流类库
结构
- InputStream
-
- FileInputStream
- OutputStream
- Reader
- Writer
- ...
按I/O类型来总体分类
- Memory
-
- 从/向内存数组读写数据: CharArrayReader、 CharArrayWriter、ByteArrayInputStream、ByteArrayOutputStream
- 从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream
- Pipe管道:实现管道的输入和输出(进程间通信): PipedReader、PipedWriter、PipedInputStream、PipedOutputStream
- File文件流:对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream
- ObjectSerialization对象输入、输出:ObjectInputStream、ObjectOutputStream
- DataConversion数据流:按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream
- Printing:包含方便的打印方法 :PrintWriter、PrintStream
- Buffering缓冲:在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream
- Filtering滤流:在数据进行读或写时进行过滤:FilterReader、FilterWriter、FilterInputStream、FilterOutputStream过
- Concatenation合并输入:多个输入流连接成一个输入流 :SequenceInputStream
- Counting计数:读入数据时对行记数 :LineNumberReader、LineNumberInputStream
- Peeking Ahead:通过缓存机制,进行预读 :PushbackReader、PushbackInputStream
- Converting between Bytes and Characters:按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter
按数据来源和去向分类
- File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter
- byte[]:ByteArrayInputStream, ByteArrayOutputStream
- Char[]: CharArrayReader, CharArrayWriter
- String: StringBufferInputStream, StringReader, StringWriter
- 网络数据流:InputStream, OutputStream, Reader, Writer
IO异常
- EOFException: 非正常到达文件尾或输入流尾时,抛出这种类型的异常
- FileNotFoundException:当文件找不到时,抛出的异常
- InterruptedIOException:当I/O操作被中断时,抛出这种类型的异常
序列化是什么?
集合类结构?
java.util.Collection和java.util.Collections的区别?
ArrayList和Vector的区别
ArrayList和Vector的区别
- ArrayList是非线程安全的,Vector是线程安全的
- ArrayList每次增长一半,Vector每次增长1倍
- HashTable是线程安全的,HashMap不是
- HashMap是自Java1.2开始增加的类
- HashMap支持key为null
ArrayList,Vector和LinkedList的存储性能和特性
略
时间工具类
世界时间标准
- UTC
- GMT
- 实例化:1)无参构造函数;2)指定毫秒数的构造函数;
- 属性:getTime()/setTime(long time)
- 大小比较:before,after,compareTo
- 其他:直接获取和改变年月日时分秒等属性的方法不赞成使用
日期类(java.util.Calendar)
- 实现类
java.util.GregorianClalendar - 实例化
1)使用系统当前时间的日期;2)指定年月日时分秒等属性值来初始化 - 属性:get(int field),field值如下所示:
-
- Calendar.YEAR
- Calendar.MONTH
- Calendar.WEEK_OF_YEAR
- DAY_OF_YEAR
- Calendar.DATE/Calendar.DAY_OF_MONTH
- Calendar.DAY_OF_WEEK_IN_MONTH:对应星期在该月中的出现次数
- Calendar.DAY_OF_WEEK
- Calendar.AM_PM
- Calendar.HOUR
- Calendar.HOUR_OF_DAY
- Calendar.MILLISECOND
- Calendar.MINUTE
- Calendar.Second
- ...
- 类:java.text.SimpleDateFormat
- 格式
z:时区G:年代y:年份M:月份w:年中周,W:月中周E:星期,F:对应星期在该月中的出现次数,D:年中天,d:月中天h:小时(1到12),H:小时(0到23),k:小时(1到24),K:小时(0到11),a:上午/下午m:分s:秒S:毫秒转义:'
- 格式化输出:format(Date date)
- 格式化输入:parse(String str)
- ...
类加载机制?
垃圾回收机制?
Java可能发生内存泄露吗?
什么是Java内存泄露
什么是Java内存泄露
内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
在C++中,内存泄漏的范围更大一些。有些对象被分配了内存空间,然后却不可达,由于C++中没有GC,这些内存将永远收不回来。在Java中,这些不可达的对象都由GC负责回收,因此程序员不需要考虑这部分的内存泄露。
泄露原因
实例1、静态集合类像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放,因为他们也将一直被Vector等应用着。2、内部类和外部类的引用容易出现内存泄露的问题3、监听器的使用,java中往往会使用到监听器,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。4、大量临时变量的使用,没有及时将对象设置为null也可能导致内存的泄露5、数据库的连接没有关闭情况,包括连接池方法连接数据库,如果没有关闭ResultSet等也都可能出现内存泄露的问题。
Vector v=new Vector(10); for (int i=1;i<100; i++) { Object o=new Object(); v.add(o); o=null; } //此时,所有的Object对象都没有被释放,因为变量v引用这些对象。 |
变量初始化顺序
父类静态变量和静态初始化块,子类静态变量和静态初始化块,父类变量和初始化块,父类构造函数,子类变量和初始化块,子类构造函数
备注:
1)静态变量和静态初始化块,变量和初始化块之间是按代码的编写顺序来初始化的
2)变量要在初始化块之前声明,否则无法编译
父类静态变量和静态初始化块,子类静态变量和静态初始化块,父类变量和初始化块,父类构造函数,子类变量和初始化块,子类构造函数
备注:
1)静态变量和静态初始化块,变量和初始化块之间是按代码的编写顺序来初始化的
2)变量要在初始化块之前声明,否则无法编译
多线程
线程的实现方式
1)继承java.lang.Thread类;
2)实现java.lang.Runnable接口;
两者相近,使用继承后不能在继承别的类,而实现接口没有该问题
如何启动线程?
start方法
线程的状态
1)继承java.lang.Thread类;
2)实现java.lang.Runnable接口;
两者相近,使用继承后不能在继承别的类,而实现接口没有该问题
如何启动线程?
start方法
线程的状态
- NEW/新增/初始化
线程对象已被创建,但还没有被启动(new与start之间) - RUNNABLE/可运行/就绪
调用了start方法之后(在Java虚拟机上运行着,但可能在等待分配相应的运行资源) - BLOCKED
正在等待其他进程释放同步锁,或者进入了一个同步块/方法但在运行时调用了某个对象继承自java.lang.Object的wait()方法 - WAIT/等待
当前线程调用了java.lang.Object.wait()、java.lang.Thread.join()或者java.Util.concurrent.LockSupport.park()方法
某个对象.wait():正在等待其他线程调用这个对象的notify或者notifyAll
某个线程.join():正在等待这儿线程运行结束 - TIMED_WAITING/定时等待
当前线程调用了java.lang.Object.wait(long timeout)、java.lang.Thread.join(long mills)、java.Util.concurrent.LockSupport.PackNanos(long nanos)、java.Util.concurrent.LockSupport.packUntil(long deadline)方法 - TERMINATED/死亡/终止
1)线程执行完run()方法中的全部代码
2)run()在运行过程中抛出了异常,且没有被捕获
Java5.0及以上版本:新建、可运行、阻塞、等待、定时等待、死亡
sleep和wait的区别
sleep和wait的区别
- sleep
- 方式:java.lang.Thread.sleep(静态方法)
- 效果:让调用它的线程沉睡执行的时间,但并不会让线程释放它所持有的同步锁
- 其他:可通过调用睡眠线程的interrupt方法中断睡眠(睡眠线程会抛出InterruptException异常)
- wait
- 方式:某个对象.wait(非静态方法)
- 效果:让调用它的线程进入等待或定时等待状态,直至其他线程再次调用“某个对象”的notify或notifyAll方法,在等待期间会释放持有的所有同步资源
- 其他:同sleep一致,会被interrupt中断
- 同步方法
-
- 用法:方法增加synchronized修饰符,要求方法不可以是抽象方法或接口方法
- 排他性:
当任意一个线程进入到一个对象的任意一个非静态同步方法时,这个对象的所有非静态同步方法都被锁定了——将当前对象作为同步锁
当任意一个线程进入到一个类的任意一个静态同步方法时,这个对象的所有静态同步方法都被锁定了——将当前类作为同步锁
- 同步块:指定对一个象作为同步锁
- 同步方法+同步块:如果一个对象既有同步方法又有同步块,那么只有任意一个同步方法或者同步块执行,都会将该对象锁定
- java.utils.Concurrent.locks
-
- 简介:Java5.0新增的工具包,实现Lock接口的类具有与synchronized关键字同样的功能,且更加强大
- 实现类
java.utils.concurrent.locks.ReetrantLock - 用法:
lock.lock;try{}catch(Exception e){}finally{lock.unlock()}
lock():用于锁定对象
unlock():用于释放对象的锁
异常捕获:确保锁一定会被释放,否则会导致死锁
synchronized:会把一个对象的所有同步方法和同步块看做一个整体,只要被某个线程调用了,其他线程就无法执行
lock:可以把一个对象按照逻辑关系把需要tongue的方法或代码进行分组,为每组创建一个Lock类型的对象
死锁的必要条件
- 互斥:线程所使用的资源中至少有一个是不能共享的,他在同一时刻只能由一个线程使用
- 持有并等待:至少有一个线程已经持有了资源,并且正在等待获取其他的线程所持有的资源
- 非抢占式:如果一个线程已经持有了某个资源,那么在这个线程释放这个资源之前,别的线程不能把它抢夺过去
- 循环等待:假设有N个线程在运行,第一个线程持有了一个资源,并且正在等待获取第二个线程持有的资源,而第二个线程正在等待获取第三个线程持有的资源,以此类推......第N个线程正在等待获取第一个线程持有的资源,由此形成循环等待
- 作用:提高对象的使用率,从而达到提高程序效率的目的
- 简单实现:Task、TaskQueue、TaskThread、ThreadPoolService
- java实现:java5.0及以上版本提供了线程池功能(java.utils.concurrent)
为什么反对使用线程的stop和suspend方法?
反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止,假如一个线程正在执行:synchronized void { x = 3; y = 4;} 由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x = 3;时,被调用了 stop()方法,即使在同步块中,它也干脆地stop了,这样就产生了不完整的残废数据。而多线程编程中最最基础的条件要保证数据的完整性,所以请忘记线程的stop方法,以后我们再也不要说“停止线程”了。而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果 很难检查出真正的问题所在。
suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此 时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就 会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用 wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程
备注
1)stop()会抛出一个不可检查的异常ThreadDeath,但不应该通过捕获ThreadDeath来解决stop问题
因为:在一个线程里ThreadDeath可能在任何地方抛出;在catch和finally也可能会抛出ThreadDeath;
因为:在一个线程里ThreadDeath可能在任何地方抛出;在catch和finally也可能会抛出ThreadDeath;
2)Thread.stop(Throwable)也是反对使用的
可能抛出同步方法不准备处理的异常
3)用什么方法替代Thread.stop()?
使用标志位来控制线程的线程,这个标志位要是violate的
3)用什么方法替代Thread.stop()?
使用标志位来控制线程的线程,这个标志位要是violate的
4)怎么终止一个正在阻塞状态或等待状态的线程?
Thread.interrupt
线程的中断机制?
异常
最长见的runtime exception
- NullPointException
- ArithmeticException
- IndexOutOfBoundException
- BufferOverflowException
- ClassCastException
- IllegalArgumentException
- error:程序无法处理的错误,表示运行应用程序中较严重的问题,例如VirtualMachineError(虚拟机运行错误)和OutOfMemoryError,遇到这种错误JVM一般选择现场终止
- exception:程序本身可以处理的异常,
- 可检查异常: 除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常
- 不可检查异常:包括运行时异常(RuntimeException与其子类)和错误(Error)
- 运行时异常:RuntimeException类及其子类异常
- 非运行时异常:RuntimeException以外的异常,类型上都属于Exception类及其子类
- 在finally语句块中发生了异常
- 在前面的代码中用了System.exit()退出程序
- 程序所在的线程死亡,关闭CPU,如计算机断电、失火、或遭遇病毒攻击
Servlet/JSP
jsp有哪些内置对象?
- request
- response
- pageContext
- page
- session
- application
- out
- config
- exception
四个作用域
- page
- request
- session
- application
jsp有哪些动作?
- jsp:useBean
- jsp:setProperty
- jsp:getProperty
- jsp:forward
- jsp:plugin
- jsp:param
- jsp:include
JSP中include指令和include动作的区别?
- 语法不同
动作:<jsp:include
命令:<%@ inlude... - 包含内容不同
动作:动态页面,且可以带参数
命令:静态页面 - 执行时间不同
动作:请求阶段
命令:翻译阶段 - ...
Servlet的生命周期
加载->实例化->初始化(init)->处理请求(service)->销毁(destroy)
Forward和Redirect的区别?
略
JDBC/JDO/JPA
JDO是什么?
略
JPA是什么?
略
JDO vs JPA?
为什么使用JDO?
数据连接池的工作原理?
略
XML
XML有哪些解析技术,以及区别?
- DOM:处理大型文件时性能下降的非常厉害,DOM在解析文件之前把整个文档装入内存,适合对XML的随机访问
- SAX:是事件驱动型的XML解析方式,在遇到像文件开头和文件结尾,或者标签开头和标签结束时,会触发时间,通过在回调时间中写入处理代码来处理XML,适合对XML的顺序访问
- STAX:Stream API for XML
XML的应用?
- 数据存储
- 信息配置
- 数据交换
XML文档定义有几种形式?它们之间的本质区别?
- DTD
- scheme:本身是xml,可以被XML解析器解析
编程题
单例模式
有好几种方式:初始化位置不同,是否是线程安全的等