java 的接口可以实现接口吗?抽象类呢?

来源:互联网 发布:mac怎么看硬盘文件 编辑:程序博客网 时间:2024/05/19 01:14

面试中可能会遇到这样的问题:

1.接口可以实现接口吗?

ans:不可以实现,但是可以继承一个或多个接口.

2.抽象类可以实现接口吗?

ans:可以

3.接口默认的修饰符

所有的接口 成员变量默认都是:puiblic static final 

所有接口的 方法默认都是public abstract

如果你只想用A接口中的某一个方法,可以写一个抽象类 实现A接口,然后实现你想用的那个方法,方法体可以为空,在具体的实现类里面 继承抽象类,然后实现抽象类中的方法即可

接口和抽象类的区别:

1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。

2、抽象类要被子类继承,接口要被类实现。

3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现(java8中 接口可以有实现方法 使用default修饰

public interface IEat extends IEat2,IEat3{public default int haveBreakFast(){return 0;}public abstract int haveBreakFast2();}

4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。

5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。

6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果

7、抽象类里可以没有抽象方法

8、抽象方法要被实现,所以不能是静态的,也不能是私有的。

9、接口可继承接口,并可多继承接口,但类只能单继承。


4.事务的4种隔离级别

1).未提交读(read uncommitted):会出现脏读、不可重复读和幻读。脏读的设计只是为了提供非阻塞读,但是对于oracle来说,默认就提供非阻塞读,

 即查询不会受到任何增删改操作的影像,因为oracle提供了undo来存放更新前的数据。

2).提交读(read committed):会出现不可重复读和幻读。oracle的默认事务隔离级别。

3).重复读(repeatable read):会出现幻读。

 4).串行化(serializable):隔离级别最高,不允许出现脏读、不可重复读和幻读。即一个事务执行结束了另一个事务才能执行。当然并发性也就最差。

 除了这四种,oracle还提供read only隔离级别,即只支持读,在该级别中,该事务只能看到事务开始那一刻提交的修改。 

 脏读:一个事务可以读物另一个事务未提交的数据。

 不可重复读:在一个事务中不同时间段查询出现不同的结果,可能被更新可能被删除。

 幻读:在一个事务中不同时间段查询,记录数不同。与不可重复读的区别是:在幻读中,已经读取的数据不会改变,只是与以前相比,会有更多的数据满足查询条件。

5.Cloneable接口是一个空接口,仅用于标记对象,Cloneable接口里面是没有clone()方法,里面的的clone()方法是Object类里面的方法!默认实现是一个Native方法。

所有的类默认继承Object类

浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2A2中包含对B2B1copy)的引用,B2中包含对C2C1copy)的引用。

若不对clone()方法进行改写,则调用此方法得到的对象即为浅拷贝

6.equals方法 在object中依然是==来比较的,也就是比较的是两个对象的引用地址。而String方法中重写了equals方法一下是Object和String中的源码:

//Object中的equals方法 public boolean equals(Object obj) {        return (this == obj);}//String中的equals方法public boolean equals(Object anObject) {        if (this == anObject) {            return true;        }        if (anObject instanceof String) {            String anotherString = (String)anObject;            int n = value.length;            if (n == anotherString.value.length) {                char v1[] = value;                char v2[] = anotherString.value;                int i = 0;                while (n-- != 0) {                    if (v1[i] != v2[i])                        return false;                    i++;                }                return true;            }        }        return false;    }


7.java异常结构图



其他详情 参考地址:http://blog.csdn.net/huhui_cs/article/details/38817791

     http://blog.csdn.net/mccand1234/article/details/51579425

补充:try catch(中有return语句) finally 

try中的return语句调用的函数先于finally中调用的函数执行,也就是说return语句先执行,finally语句后执行,所以,返回的结果是2。return并不是让函数马上返回,而是return语句执行后,将把返回结果放置进函数栈中,此时函数并不是马上返回,它要执行finally语句后才真正开始返回。

8. 索引的优化问题

where,having,order by,group by等会使用到索引

索引失效的情况:

如果 使用like则只有xx%这种形式才会使用索引;

如果where中是 or的关系,或NOT IN或<>则索引无效(感觉各个说明有问题,怎么说的都有

复合索引:

如果是联合索引 ab字段 则 a,ab,会使用索引 b不会使用索引需要单独建立  符合最左原则

 mysql 的存储引擎:

MyISAM 不支持事务,用于只读程序提高性能。数据文件(.MYD),索引文件(.MYI)和结构文件(.frm)

参考文档:http://www.cnblogs.com/baochuan/archive/2012/03/15/2398276.html

InnoDB支持acid事务,行几锁,并发

Berkeley DB 支持事务



9.union和unionall的区别

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。

请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。


union和union all的区别是,union会自动过滤多个结果集合中的重复结果,而union all则将所有的结果全部显示出来,不管是不是重复。 所以union all的效率会高很多

Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序; 

Union All:对两个结果集进行并集操作,包括重复行,不进行排序; 

Intersect:对两个结果集进行交集操作,不包括重复行,同时进行默认规则的排序; 

Minus:对两个结果集进行差操作,不包括重复行,同时进行默认规则的排序。 

可以在最后一个结果集中指定Order by子句改变排序方式。 


left join 和right join和inner join的区别

left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
inner join(等值连接) 只返回两个表中联结字段相等的行

10.将字符串中的第一个,号替换成-,第二个替换成;

String s="1989,0,25";
s=s.replaceFirst(",", "-").replaceFirst(",", ":");

11.看下一下代码能否实现1.0依次减去0.1,0.2,0.3......直至减到0;

Double num = 1.0;for (Double i = 0.1d; i <= num; i += 0.1) {System.out.println("i" + i);num -= i;System.out.println(num);}



ans:不能,这里主要考察double精度的问题。

结果:i0.1
0.9
i0.2
0.7
i0.30000000000000004
0.3999999999999999


总结:

Java中的简单浮点数类型float和double不能够进行运算,因为大多数情况下是正常的,但是偶尔会出现如上所示的问题。这个问题其实不是JAVA的bug,因为计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制转化为十进制浮点数时,精度容易丢失,导致精度下降。

  要保证精度就要使用BigDecimal类,而且不能直接从double直接转BigDecimal,要将double转string再转BigDecimal。也就是不能使用BigDecimal(double val) 方法,你会发现没有效果。要使用BigDecimal(String val) 方法。

12.string字符串有没有长度限制

抄一下:

我们可以使用串接操作符得到一个长度更长的字符串,那么,String对象最多能容纳多少字符呢?查看String的源代码我们可以得知类String中是使用域 count 来记录对象字符的数量,而count 的类型为 int,因此,我们可以推测最长的长度为 2^32,也就是4G。  不过,我们在编写源代码的时候,如果使用 Sting str = "aaaa";的形式定义一个字符串,那么双引号里面的ASCII字符最多只能有 65534 个。为什么呢?因为在class文件的规范中, CONSTANT_Utf8_info表中使用一个16位的无符号整数来记录字符串的长度的,最多能表示 65536个字节,而java class 文件是使用一种变体UTF-8格式来存放字符的,null值使用两个字节来表示,因此只下 65536- 2 = 65534个字节。也正是变体UTF-8的原因,如果字符串中含有中文等非ASCII字符,那么双引号中字符的数量会更(一个中文字符占用三个字节)。如果超出这个数量,在编译的时候编译器会报错.
拓展:


12.

info可以看到所有库的key数量

dbsize则是当前库key的数量

keys *这种数据量小还可以,大的时候可以直接搞死生产环境。

dbsize和keys *统计的key数可能是不一样的,如果没记错的话,keys *统计的是当前db有效的key,而dbsize统计的是所有未被销毁的key(有效和未被销毁是不一样的,具体可以了解redis的过期策略)

13.初始化顺序

1)没有子类:   静态块/静态变量( 谁在前先执行谁)->构造块/构造方法(先构造块)

2)有子类:    父类静态块/父类静态变量( 谁在前先执行谁)->子类父类静态块/父类静态变量( 谁在前先执行谁)->父类构造块/构造方法(先构造块)->子类构造块/构造方法(先构造块)

静态块只执行一次,构造块/构造方法每new一次类就会执行一次

14.下面哪个流类属于面向字符的输入流( )

A BufferedWriter B FileInputStream C ObjectInputStream D InputStreamReader




答案:D
解析:Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式。
面向字节的操作为以8位为单位对二进制的数据进行操作,对数据不进行转换,这些类都是InputStream和OutputStream的子类。
面向字符的操作为以字符为单位对数据进行操作,在读的时候将二进制数据转为字符,在写的时候将字符转为二进制数据,这些类都是Reader和Writer的子类。
总结:以InputStream(输入)/OutputStream(输出)为后缀的是字节流
以Reader(输入)/Writer(输出)为后缀的是字符流
扩展:Java流类图结构,一目了然,解决大部分选择题:



15.spring ioc注入方式  有说3种的

 a、接口注入;
b、setter方法注入;
c、构造方法注入;

参考文档:http://blog.csdn.net/u011637069/article/details/51958918

有说四种的:

  • 1.Set注入
  • 2.构造器注入
  • 3.静态工厂的方法注入
  • 4.实例工厂的方法注入
  • 参考文档:http://www.cnblogs.com/java-class/p/4727775.html
16.jsp9大内置对象


参考文档:http://blog.csdn.net/xiazdong/article/details/6848382

17.创建线程的两种方式:

1.继承Thread类,并重写run();

2.实现runnable接口,并实现run();

待补充:




18.子父类中 如果方法被重写 new 谁就调谁的方法,如果是静态的话则 前面的类型是谁则就调用谁的方法,静态方法不能被重写
19.hashMap的实现原理

hashMap是基于数组➕链表的数据结构存储,初始化长度为16,put方法时,先判断key是否为空,为空的话直接放在位置0,否则,计算key的hash值,然后根据hash值计算下标,根据下标取出entry链表,for循环,如果key的值已经存在,则替换旧的value,并返回oldvalue; ,否则的话就调用addEntry方法,添加新的.
get(key)的时候,则首先判断key是否为空,为空则获取key为null的value并返回.否则 计算key的hash值,然后根据hash值,获取索引位置,根据索引获取Entry链表,for循环 如果hash值相等,并且e.key==key获取e.key.equals(key)则返回value;
hashmap和hashtable区别:1.线程是否安全,hashtable是线程安全的 方法由synchronized修饰2是否允许null键值对,hahsMap允许,另一个会抛出null指针异常. 

hashMap put源码

 public V put(K key, V value) {        if (table == EMPTY_TABLE) {            inflateTable(threshold);        }        if (key == null)            return putForNullKey(value);        int hash = hash(key);        int i = indexFor(hash, table.length);        for (Entry<K,V> e = table[i]; e != null; e = e.next) {            Object k;            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {                V oldValue = e.value;                e.value = value;                e.recordAccess(this);                return oldValue;            }        }        modCount++;        addEntry(hash, key, value, i);        return null;    }
get 源码

 public V get(Object key) {        if (key == null)            return getForNullKey();        Entry<K,V> entry = getEntry(key);        return null == entry ? null : entry.getValue();    }
final Entry<K,V> getEntry(Object key) {        if (size == 0) {            return null;        }        int hash = (key == null) ? 0 : hash(key);        for (Entry<K,V> e = table[indexFor(hash, table.length)];             e != null;             e = e.next) {            Object k;            if (e.hash == hash &&                ((k = e.key) == key || (key != null && key.equals(k))))                return e;        }        return null;    }





4 0
原创粉丝点击