java面试题(二)
1.游标。为什么不赞成使用游标?(存储过程,索引,视图,函数)
2.http协议断点续传......
3.源代码配置管理
4.网络爬虫
答案来自网络
1.如何在类外创建一个方法
不能
2.......
3.安卓常见面试题
4.String ,StringBuffer ,StringBulder 线程安全性比较
-------------------------------start------------------------------------
String 和StringBuffer 的区别
JAVA平台提供了两个类: String和StringBuffer ,它们可以储存和操作字符串,即包含多个字符的字符数据。这个 String类提供了数值不可改变的字符串。而这个 StringBuffer类提供的字符串可以进行修改。当你知道字符数据要改变的时候你就可以使用 StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据。 另外,String实现了equals 方法,new String(“abc”).equals(new String(“abc”)的结果为true,而StringBuffer 没有实现 equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的结果为false。
接着要举一个具体的例子来说明,我们要把 1到100 的所有数字拼起来,组成一个串。
StringBuffer sbf = new StringBuffer();
for(int i=0;i<100;i++) {
sbf.append(i);
}
上面的代码效率很高,因为只创建了一个 StringBuffer对象,而下面的代码效率很低,因为创建了 101个对象。
String str = new String();
for(int i=0;i<100;i++) {
str = str + i;
}
String覆盖了 equals方法和hashCode 方法,而 StringBuffer没有覆盖equals 方法和hashCode方法,所以,将 StringBuffer对象存储进Java集合类中时会出现问题。
在讲两者区别时,应把循环的次数搞成 10000,然后用endTime-beginTime 来比较两者执行的时间差异,最后还要 讲讲StringBuilder与StringBuffer 的区别。 (区别如下)
StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容,可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。(从 JDK 5 开始,为该类补充了一个单个线程使用的等价类,即 StringBuilder。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。)
StringBuilder一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API ,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。(如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。但将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer。)
StringBuffer和 Stringbuilder上的主要操作都是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。 append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“ start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“ startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“ starlet”。
通常,如果 sb 引用 StringBuilder 的一个实例,则 sb.append(x) 和 sb.insert(sb.length(), x) 具有相同的效果。只要发生有关源序列(如在源序列中追加或插入)的操作,该类就只在执行此操作的字符串缓冲区上而不是在源上实现同步。
-------------------------------end------------------------------------
5.集合框架Collection
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set-|EnumSet , LinkedHashSet , HashSet , TreeSet
Map
├Hashtable
├HashMap
└WeakHashMap
琴弦第七——)java学习笔记
http://my.eoe.cn/794406
6.class文件包含的内容
-----------------------class 文件概述start----------------------------------
-----------------------class 文件概述end----------------------------------
7.实现一个简单的oa系统
8.如何try{}...catch(){}之后继续抛异常?
-----------------------涉及:java中异常处理机制 start-----------------------------
-----------------------java中异常处理机制 end----------------------------------
9.如何声明一个常量
四种方式:
1.利用接口的方式(接口中变量默认static final)
2.利用枚举类型(Enum)
3.普通类声明中static final
4.利用方法获得类似于方法三
-----------------------------深入jvm笔记---start-----------------------------------java不仅仅是一门编程语言还是一门技术,包含四方面:java编程语言,java类文件格式,java虚拟机和java应用程序接口(java API) 。这几个方面的关系:JVM在它的生存周期中有一个明确的任务,那就是运行 Java程序,因此 当Java程序启动的时候,就产生 JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。每个 JVM都有两种机制,一个是装载具有合适名称的类 (类或是接口 ),叫做 类装载子系统 ;另外的一个负责执行包含在已装载的类或接口中的指令,叫做 运行引擎。每个 JVM又包括方法区、堆、 Java栈、程序计数器和本地方法栈这五个部分,这几个部分和类装载机制与运行引擎机制一起组成的体系结构 图为:jvm的体系结构图JVM的每个实例都有一个它自己的方法域和一个堆,运行于 JVM内的所有的线程都共享这些区域;当虚拟机装载类文件的时候,它解析其中的二进制数据所包含的类信息,并把它们放到方法域中;当程序运行的时候, JVM把程序初始化的所有对象置于堆上;而每个线程创建的时候,都会拥有自己的程序计数器和 Java栈, ( 其中程序计数器中的值指向下一条即将被执行的指令,线程的 Java栈则存储为该线程调用Java方法的状态;本地方法调用的状态被存储在本地方法栈,该方法栈依赖于具体的实现 ) 。Java不规定具体使用的垃圾回收算法 ,可以根据系统的需求使用各种各样的算法。每个线程一旦被创建就拥有了自己的程序计数器。当 线程执行Java方法的时候,它包含该线程正在被执行的指令的地址。但是若线程执行的是一个本地的方法,那么程序计数器的值就不会被定义。java虚拟机的栈有三个区域:局部变量区,运行环境区,操作数区。关于java的异常处理机制:异常捕捉异常情况在Java中被称作Error(错误)或Exception(异常),是Throwable类的子类,在程序中的原因是:①动态链接错,如无法找到所需的class文件。②运行时错,如对一个空指针的引用。程序使用了throw语句。当异常发生时,Java虚拟机采取如下措施:? 检查与当前方法相联系的catch子句表。每个catch子句包含其有效指令范围,能够处理的异常类型,以及处理异常的代码块地址。? 与异常相匹配的catch子句应该符合下面的条件:造成异常的指令在其指令范围之内,发生的异常类型是其能处理的异常类型的子类型。如果找到了匹配的catch子句,那么系统转移到指定的异常处理块处执行;如果没有找到异常处理块,重复寻找匹配的catch子句的过程,直到当前方法的所有嵌套的 catch子句都被检查过。? 由于虚拟机从第一个匹配的catch子句处继续执行,所以catch子句表中的顺序是很重要的。因为Java代码是结构化的,因此总可以把某个方法的所有的异常处理器都按序排列到一个表中,对任意可能的程序计数器的值,都可以用线性的顺序找到合适的异常处理块,以处理在该程序计数器值下发生的异常情况。? 如果找不到匹配的catch子句,那么当前方法得到一个"未截获异常"的结果并返回到当前方法的调用者,好像异常刚刚在其调用者中发生一样。如果在调用者中仍然没有找到相应的异常处理块,那么这种错误将被传播下去。如果错误被传播到最顶层,那么系统将调用一个缺省的异常处理块。java虚拟机的执行过程:java virtual machine 调用某个指定类的main方法---->传递字符串参数(是指定的类被装载同时衔接该类所使用的其他类型)Class Loader只管加载,只要符合文件结构就加载,至于说能不能运行,则不是它负责的,那是由 Execution Engine负责的。 Stack 栈栈也叫栈内存,是Java程序的运行区,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束,该栈就Over。问题出来了:栈中存的是那些数据呢?又什么是格式呢?栈中的数据都是以栈帧(Stack Frame)的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法(Method)和运行期数据的数据集,当一个方法A被调用时就产生了一个栈帧F1,并被压入到栈中,A方法又调用了B方法,于是产生栈帧F2也被压入栈,执行完毕后,先弹出F2栈帧,再弹出F1栈帧,遵循“先进后出”原则。那栈帧中到底存在着什么数据呢?栈帧中主要保存3类数据:本地变量(Local Variables),包括输入参数和输出参数以及方法内的变量;栈操作(Operand Stack),记录出栈、入栈的操作;栈帧数据(Frame Data),包括类文件、方法等等。Heap堆内存分为三个部分:·1.永久存储区,用于存放自身所携带的Class,interface的源数据,此区域的数据不会被垃圾回收,关闭JVM才回释放该区域数据所占用的内存。·2.新生区,新生区是类的诞生、成长、消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集,结束生命. 3.养老区用于保存从新生区筛选出来的 JAVA对象,一般池对象都在这个区域活跃。 Method Area 方法区方法区是被所有线程共享,该区域保存所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。堆和栈:堆是在java虚拟机启动的时候创建,主要存放new出来的对象(包括对象变量以及对象方法)以及数组对象,但是对象中的临时变量是存在栈中的。 栈是跟随线程的,有线程就有栈,堆是跟随JVM的,有JVM就有堆内存。类变量和实例变量:静态变量存在方法区中,实例变量存在堆内存中。为什么会产生stackOverFlowError:一个线程把stack内存全部耗尽了,一般是递归函数造成的。jvm中除了Heap 和Method Area是共享的其他的都是私有的。JIT:java文件被编译成字节码(针对JVM的)--->翻译成原生码才能被机器执行。Just in time JVM中提供一个工具,把字节码编译成原生码,以后你来访问的时候直接访问原生码。关于class文件:Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量表 (constant_pool table),用于存放编译期已可知的常量,这部分内容将在类加载后进入方法区(永久代)存放。
-----------------------------深入jvm笔记---end-----------------------------------