有趣的Java-J04

来源:互联网 发布:网络博客推广话术 编辑:程序博客网 时间:2024/06/11 02:47

1.你知道哪些查找算法,效率如何?

查找算法从来都不是一个冷门的面试题,在大量的数据面前,查找算法的好与坏尤其重要,这将关乎到应用的性能,而采用怎样的查找算法,那得需要具体的数据环境而定,因此我们需要知道一些常用的查找算法,以便于我们在需要查找算法的地方分析出合适的一种查找算法,由于查找算法内容比较多,笔者就偷一下懒,使用大神的博客:
http://blog.csdn.net/beauty_1991/article/details/51306249

2.说一下泛型的擦除和翻译过程

要解释这个问题,你要懂泛型的知识,其实就是类型变量的擦除与翻译,擦除和翻译是有一定规则的,总结后有如下三点:

1.将类型变量声明去掉,也就是”<…>”通通去掉
2.所有使用类型变量的位置被替换成该类型变量的上限类型
3.返回值为类型变量的方法,编译器会在调用此方法的时候插入合适的强制类型转换,让此方法的返回值的类型与返回区域类型变量的值保持一致

第1点理解非常容易,无非就是移除类型变量的声明嘛,第2点里面涉及到一个上限类型,那么一个类型变量的上限类型是什么呢?这个跟类型变量有没有使用“extends”有关,看看下面的例子,你就会知道类型变量的上限类型是什么了?

   <K> -->这个类型变量的声明没有指定上限类型,所以上限类型为原始的类型Object   <J extends List> -->这个类型变量的声明指定了上限类型,所以类型变量J的上限类型为List   <H extends Person,I> -->这个我就不说了,应该懂了上限类型了吧!

上限类型的意思是这个类型变量的类型值必须是这个类型变量对应的上限类型或者上限类型的子类,否则,编译器不允许通过。既然有上限类型,那么肯定会有下限类型:

 < k super Student > -->这个泛型的声明指定的下限类型是Student,意思就是说泛型变量K一定不能为Student的子类

下面来讲个实例,看完这个实例,泛型的核心知识擦除和翻译你就应该掌握了:

有这么一个泛型类(擦除翻译前):

public class MyClass<T> {    public T getT(T t){        System.out.println(t);        return t;    }    public <K extends List,V> void shuChu(K k,V v){        System.out.println(k);        System.out.println(v);    }}

我们来分析一下,对于泛型变量T而言,它是类层面的泛型变量,并且它没有指定任何上限类型,那么泛型变量T的声明”< T >”被去掉,在使用了泛型变量T的地方被替换成原始类型Object类,再看看泛型方法shuChu(),它声明了两个泛型变量分别为K和V,K指定了上限类型为List,所以在使用泛型变量T的位置将会被替换成List,而泛型变量V没有指定上限类型,所以泛型变量V的上限类型也是原始类型Object类。
然后执行以下代码:

public class MyClass{    public Object getT(Object t){        System.out.println(t);        return t;    }    public void shuChu(List k,Object v){        System.out.println(k);        System.out.println(v);    }}

然后执行以下代码:

    MyClass<String> myClass = new MyClass<String>();//1    String str = myClass.getT("ss");//2    myClass.shuChu(new ArrayList<String>(),true);//3 

有个奇怪的地方,你会发现第2处并没有报错,看到擦除翻译后的代码中getT()方法明明返回的是Object,怎么能使用String的引用来进行赋值操作呢?你怀疑的很有道理,你再看看笔者开始写的擦除翻译的3要点的第三个要点,你会知道原因。“3.返回值为类型变量的方法,编译器会在调用此方法的时插入合适的强制类型转换,让此方法的返回值的类型与返回区域类型变量的值保持一致”,擦除翻译过程中getT()方法返回区域的T是被替换成上限类型Object,实际上在替换的时候,编译器已经记住了getT()是一个返回类型区域为类型变量的方法,并且在代码“//1”处已经确认这个强制转换的合适类型为:String,也就是笔者提到的第3要点,在代码“//2”处,编译器是把getT()返回的Object类型强制转换为String类型,这就是泛型最难理解的位置,搞清楚这个,那么泛型你就掌握了一大半,剩下的只是如何设计好一个泛型类而已。

3.Java线程池有哪些?说说其特性

Java通过Executors提供四种线程池,分别为:

  • 1.newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  • 2.newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  • 3.newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
  • 4.newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

详细用法看以下链接:
http://blog.csdn.net/u011974987/article/details/51027795

4.面向对象的六大原则是什么?你所知道的设计模式有哪些,只说设计模式的名字,不用说明特性

刚好笔者最近在整理Android设计模式(包含Java设计模式),不妨直接关注笔者Android设计模式系列文章,一起来复习和学习一下,目前在慢慢更新当中。

http://blog.csdn.net/clandellen/article/details/77800272

Java 中一般认为有 23 种设计模式,我们不需要所有的都会,但是其中常用的几种设计模式应该去掌握。下面列出了所有的设计模式。需要掌握的设计模式我单独列出来了,当然能掌握的越多越好。

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录
模式、状态模式、访问者模式、中介者模式、解释器模式。

5.Java多线程中wait()方法和sleep()方法的区别

1、每个对象都有一个锁来控制同步访问,Synchronized关键字可以和对象的锁交互,来实现同步方法或同步块。sleep()方法正在执行的线程主动让出CPU(然后CPU就可以去执行其他任务),在sleep指定时间后CPU再回到该线程继续往下执行(注意:sleep方法只让出了CPU,而并不会释放同步资源锁!!!);wait()方法则是指当前线程让自己暂时退让出同步资源锁,以便其他正在等待该资源的线程得到该资源进而运行,只有调用了notify()方法,之前调用wait()的线程才会解除wait状态,可以去参与竞争同步资源锁,进而得到执行。(注意:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权利重新参与线程的调度);

2、sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用;

3、sleep()是线程线程类(Thread)的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复;wait()是Object的方法,调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态;

下篇问题预览:

1.单例模式有几种?分别说说每一种的特性

2.用于自定义注解的元注解有哪些?分别作用是什么?试着写出一个简单的用来记录方法信息的注解

3.ArrayList内部用什么实现的?

4.String,StringBuffer,StringBuilder区别与特性

5.String str1 =”a”; String str2 = str1+”b”;String str3 = new String(str2);这段代码共生成几个对象?

下篇文章传送门:
http://blog.csdn.net/ClAndEllen/article/details/77879734