堆的形状是一颗完全二叉树
===============================================
public class B {
public static B t1 = new B();
public static B t2 = new B();
{
System.out.println("构造块");
}
void hi () {
System.out.println("方法");
}
static {
System.out.println("静态块");
}
public static void main(String[] args) {
B t = new B();
}
}
Output:
构造块
构造块
静态块
构造块
===============================================
public class Base
{
private String baseName = "base";
public Base()
{
callName();
}
public void callName()
{
System. out. println(baseName);
}
static class Sub extends Base
{
private String baseName = "sub";
public void callName()
{
System. out. println (baseName) ;
}
}
public static void main(String[] args)
{
Base b = new Sub();
}
}
Output is: null
new Sub();在创造派生类的过程中首先创建基类对象,然后才能创建派生类。
创建基类即默认调用Base()方法,在方法中调用callName()方法,由于派生类中存在此方法,则被调用的callName()方法是派生类中的方法,此时派生类还未构造,所以变量baseName的值为null
===============================================
java object默认的基本方法:
protected Object clone () //创建并返回此对象的一个副本。
boolean equals (Object obj) //指示某个其他对象是否与此对象“相等”。
protected void finalize () //当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
Class<? extends Object> getClass () //返回一个对象的运行时类。
int hashCode () //返回该对象的哈希码值。
void notify () //唤醒在此对象监视器上等待的单个线程。
void notifyAll () //唤醒在此对象监视器上等待的所有线程。
String toString () //返回该对象的字符串表示。
void wait () //导致当前的线程等待,直到其他线程调用此对象的 notify () 方法或 notifyAll () 方法。
void wait ( long timeout) //导致当前的线程等待,直到其他线程调用此对象的 notify () 方法或 notifyAll () 方法,或者超过指定的时间量。
void wait ( long timeout, int nanos) //导致当前的线程等待,直到其他线程调用此对象的 notify () 方法或 notifyAll () 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
===============================================
class Value{
public int i=15;
}
public class Test{
public static void main(String argv[]){
Test t=new Test( );
t.first( );
}
public void first( ){
int i=5;
Value v=new Value( );
v.i=25;
second(v,i);
System.out.println(v.i);
}
public void second(Value v,int i){
i = 0;
v.i = 20;
Value val = new Value( );
v = val;
System.out.println(v.i+" "+i);
}
}
Output: 15 0 20
===============================================
public class Test{
static{
int x=5; // x is local variable
}
static int x,y;
public static void main(String args[]){
x--;
myMethod( );
System.out.println(x+y+ ++x);
}
public static void myMethod( ){
y=x++ + ++x;
}
}
Output: 3
===============================================
class Foo {
final int i;
int j;
public void doSomething() {
System.out.println(++j + i);
}
}
Output: Compilation Error, final variable must be initialized
===============================================
public static void main(String[] args) {
short a =128;
byte b =(byte) a;
System.out.println(a);
System.out.println(b);
}
Output: 128 -128
===============================================
在try的括号里面有return一个值,那在哪里执行finally里的代码? return前执行
Java 虚拟机会把 finally 语句块作为 subroutine(对于这个 subroutine 不知该如何翻译为好,干脆就不翻译了,免得产生歧义和误解。)直接插入到 try 语句块或者 catch 语句块的控制转移语句之前。但是,还有另外一个不可忽视的因素,那就是在执行 subroutine(也就是 finally 语句块)之前,try 或者 catch 语句块会保留其返回值到本地变量表(Local Variable Table)中。待 subroutine 执行完毕之后,再恢复保留的返回值到操作数栈中,然后通过 return 或者 throw 语句将其返回给该方法的调用者(invoker)。请注意,前文中我们曾经提到过 return、throw 和 break、continue 的区别,对于这条规则(保留返回值),只适用于 return 和 throw 语句,不适用于 break 和 continue 语句,因为它们根本就没有返回值。
===============================================
口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。另外,接口和抽象类在方法上有区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
3. 抽象类中的抽象方法的访问类型可以是public,protected和默认类型
4. 抽象类中可以包含静态方法,接口中不能包含静态方法
5. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型
7. 一个类可以实现多个接口,但只能继承一个抽象类。二者在应用方面也有一定的区别:接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码。
===============================================
public class StringDemo{
private static final String MESSAGE="taobao";
public static void main(String [] args) {
String a ="tao"+"bao";
String b="tao";
String c="bao";
System.out.println(a==MESSAGE);
System.out.println((b+c)==MESSAGE);
}
}
Output: true false
1,字符串在java中存储在字符串常量区中
2,==判断的是对象引用是否是同一个引用,判断字符串相等要用equals方法
首先判断a==MESSAGE 同一份字符串常量在内存中只有一份,因此是同一地址,返回true
再次比较(b+c)==MESSAGE 这相当于 new String(b+c)==MESSAGE 这里new了一个String对象,存放在堆中不在指向常量池,所以返回false
===============================================
在一颗度为4的树T中,若有20个度为4的结点,10个度为3的结点,1个度为2的结点,10个度为1的结点,则树T的叶结点个数是_______。
任何一棵树中,结点个数比分支个数多一
分支个数等于20*4+10*3+1*2+10*1=122
所以这棵树一共有123个结点
度不为零的结点数目为20+10+1+10=41
所以叶子结点也就是度为零的结点个数为123-41=82
===============================================
子类A继承父类B, A a = new A(); 则父类B构造函数、父类B静态代码块、父类B非静态代码块、子类A构造函数、子类A静态代码块、子类A非静态代码块 执行的先后顺序是?
父类B静态代码块->父类B构造函数->父类B非静态代码块->子类A静态代码块->子类A构造函数->子类A非静态代码块
===============================================
在下面说列举的逻辑测试覆盖中,测试覆盖最强的是? 条件组合覆盖
条件覆盖CC(Condition Coverage),设计足够多的测试用例,运行被测程序,使得每一判定语句中每个逻辑条件的可能取值至少满足一次。条件覆盖率的公式:条件覆盖率=被评价到的条件取值的数量/条件取值的总数X100%[1] 条件覆盖的缺点:只考虑到每个判定语句中的每个表达式,没有考虑到各个条件分支(或者涉及不到全部分支),即不能够满足判定覆盖.
条件组合覆盖,也称多条件覆盖MCC (Multiple Condition Coverage),设计足够多的测试用例,使得每个判定中条件的各种可能组合都至少出现一次(以数轴形式划分区域,提取交集,建立最少的测试用例)。这种方法包含了“分支覆盖”和“条件覆盖”的各种要求。满足条件组合覆盖一定满足判定覆盖、条件覆盖、判定条件覆盖。条件组合覆盖率的公式:条件组合覆盖率=被评价到的条件取值组合的数量/条件取值组合的总数条件组合覆盖的缺点:判定语句较多时,条件组合值比较多。
语句覆盖 SC(Statement Coverage),就是设计若干个测试用例,运行被测程序,使得程序中每一可执行语句至少执行一次。这里的“若干个”,意味着使用测试用例越少越好。语句覆盖在测试中主要发现缺陷或错误语句。
判定条件覆盖CDC(Condition/ Decision Coverage),设计足够多的测试用例,使得判定中的每个条件的所有可能(真/假)至少出现一次,并且每个判定本身的判定结果也至少出现一次。[1] 判定条件覆盖率的公式:条件判定覆盖率=被评价到的条件取值和判定分支的数量/(条件取值总数+判定分支总数).判定条件覆盖的缺点:没有考虑单个判定对整体结果的影响,无法发现逻辑错误。
===============================================
优化Hibernate所鼓励的7大措施:
1.尽量使用many-to-one,避免使用单项one-to-many
2.灵活使用单向one-to-many
3.不用一对一,使用多对一代替一对一
4.配置对象缓存,不使用集合缓存
5.一对多使用Bag 多对一使用Set
6.继承使用显示多态 HQL:from object polymorphism="exlicit" 避免查处所有对象
7.消除大表,使用二级缓存
===============================================
用于解决CPU指令乱序、编译器重排、多CPU内存同步等带来的问题的机制是?
内存屏障可以限制CPU对内存的访问,表现在高级编程语言中就是加锁.
内存屏障,也称内存栅栏,内存栅障,屏障指令等, 是一类同步屏障指令,使得CPU或编译器在对内存随机访问的操作中的一个同步点,使得此点之前的所有读写操作都执行后才可以开始执行此点之后的操作。 大多数现代计算机为了提高性能而采取乱序执行,这使得内存屏障成为必须。 语义上,内存屏障之前的所有写操作都要写入内存;内存屏障之后的读操作都可以获得同步屏障之前的写操作的结果。因此,对于敏感的程序块,写操作之后、读操作之前可以插入内存屏障。
===============================================
jdbc api应用的基本操作
1.导入jdbc操作相关包
import java.sql.*;
2. 写好异常捕获结构
try{}catch()finally{}
3. 加载驱动程序
例:Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
4. 获得连接对象
例:Connection con=DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=accp","sa","123");
5. 创建sql语句执行对象(预处理语句集对象)
例:PreparedStatement ps=conn.prepareStatement("insert into student values('张三','男')");
6. 执行sql命令
int count = ps.executeUpdate();
注意如果是查询就必须返回结果集:然后从结果集中取数据
ResultSet rs=ps.executeQuery();
while(rs.next())
{
String str1=rs.getString(1);//列下标从1开始
int num1=rs.getInt(2);
}
7.关闭预处理语句集对象和结果集对象
rs.close();
ps.close();
8.关闭连接对象
conn.close();
===============================================
文件系统中的最小存储单元是逻辑块,也就是这里所说的Block;
block越大,inode越少,适合存储大文件的文件系统;block越小,inode越多,适合存储文件多而小的文件系统。
要格式化档案系统为Ext3,亦可以使用命令mkfs.ext3,block块可以用mkfs.ext3 -b来制定快的大小,每个block块最多可存放一个文件;
block存放文件的数据,每个block最多存放一个文件,而当一个block存放不下的情况下,会占用下一个block。
===============================================
#define A_NUM 10000000
#define B_NUM 1000
void t1 ( ) {
int i, j;
for ( i = 0; i < A_NUM; i ++ ) {
for ( j = 0; j < B_NUM; j ++ ) {
b[ j ] ++;
}
}
}
void t2 ( ) {
int i, j;
for ( j = 0; j < B_NUM; j ++ ) {
for ( i = 0; i < A_NUM; i ++ ) {
a[ i ] ++;
}
}
}
tl运行速度快.
进行数组访问时,操作系统需要将相关内存页面载入cache中,一个页面的大小是有限的,如果程序需要访问页面外的内存数据,操作系统需要进行换页操作,这个操作是耗时的。t1访问的内存区域大小为1000,系统不需要或极少需要换页。t2需要访问的内存区域大小为1000000,系统需要多次换页,比较耗时。简单的讲,t1具有较好的程序局部性。
===============================================
进程阻塞的原因不包括__A______。
-
时间片切换
-
等待I/O
-
进程sleep
-
等待解锁
进程有3个状态:就绪态。执行态、阻塞态。三种状态的转换包含有:
就绪->执行,执行->就绪,执行->阻塞,阻塞->就绪
等待I/O、进程sleep、等待解锁等原因都会导致进程暂停。关于"时间片切换",当进程已经获得了除cpu外所有的资源,这时的状态就是就绪态,当分配到了时间片就成了执行态,当时间片用完之前一直未进入阻塞态的话,此后便继续进入就绪态。所以进程的就绪与阻塞是完全不同的。