每日十道面试题(四)

    xiaoxiao2021-03-25  69

    1. 编程题:写一个单例模式出来

    懒汉模式

    public class Singleton { private static Singleton instance = null; private static Object lockObject = new Object(); //私有构造方法 private Singleton() { } public static Singleton getInstance() { if (instance == null){ synchronized (lockObject){ if (instance == null){ instance = new Singleton(); } } } return instance; } }

    注意:

    第一个判空是为了只有在创建实例的时候进行加同步锁。第二个判空是为了防止多个线程竞争创建实例,重复创建实例。

    饿汉模式

    public class Singleton{ private Singleton(){ } private static final Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } }

    饿汉式和懒汉式区别

    这两种乍看上去非常相似,其实是有区别的,主要两点

    1、线程安全:

    饿汉式是线程安全的,可以直接用于多线程而不会出现问题,懒汉式就不行,它是线程不安全的,如果用于多线程可能会被实例化多次,失去单例的作用。

    如果要把懒汉式用于多线程,有两种方式保证安全性,一种是在getInstance方法上加同步,另一种是在使用该单例方法前后加双锁。

    2、资源加载:

    饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,会占据一定的内存,相应的在调用时速度也会更快,

    而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次掉用时要初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。

    2. 作用域public, private, protected,以及不写时的区别?

    作用域当前类同一包子孙类其他包public√√√√protected√√√×默认√√××private√×××

    3. ArrayList和Vector的区别?

    Vector是线程安全的,同步的,ArrayList不是线程安全的,不是同步的数据增长:Vector每次默认增长原来的一倍,而ArrayList却是原来的一半

    4. char变量中可不可以存储一个中文汉字,为什么?

    可以,因为java中采用unicode编码,一个char为16个字节,所以放一个中文是没有问题的。

    5. 线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?

    继承自Thread或者实现Runnable接口,实现Callable接口,重写call函数,同步实现可以利用synchronized和wait以及notify。

    Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。

    Callable和Runnable有几点不同:

    Callable规定的方法是call(),而Runnable规定的方法是run(). Callable的任务执行后可返回值,而Runnable的任务是不能返回值的call()方法可抛出异常,而run()方法是不能抛出异常的。 运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果.通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果 class TaskWithResult implements Callable<String> { private int id; public TaskWithResult(int id) { this.id = id; } @Override public String call() throws Exception { return "result of TaskWithResult " + id; } } public class CallableTest { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService exec = Executors.newCachedThreadPool(); ArrayList<Future<String>> results = new ArrayList<Future<String>>(); //Future 相当于是用来存放Executor执行的结果的一种容器 for (int i = 0; i < 10; i++) { results.add(exec.submit(new TaskWithResult(i))); } for (Future<String> fs : results) { if (fs.isDone()) { System.out.println(fs.get()); } else { System.out.println("Future result is not yet complete"); } } exec.shutdown(); } }

    6. 继承时候类的执行顺序问题?

    先执行父类的构造方法,再执行子类的构造方法

    7. float型float f = 3.4是否正确?

    不正确。可以是float f = 3.4f;或者float f = (float)3.4;

    8. 介绍java中的Collection FrameWork(包括如何写自己的数据结构)

    Collection[List[LinkedList,ArrayList, Vector[Stack]], Set]

    Map[HashMap, HashTable, WeakHashMap, TreeMap]

    Collection是最基本的集合接口,一个Collection代表一组Object,即元素,而Map提供的是key到value的映射。

    9. String与StringBuffer,StringBuilder的区别。

    String对象不可变,StringBuffer长度可变,另外StringBuilder是线程不安全的,StringBuffer是线程安全的,所以如果我们需要拼接字符,那么使用StringBuffer和StringBuilder是不错的。在单线程中StringBuilder的性能比StringBuffer性能高

    10. java异常处理机制

    Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Error表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。

    异常处理方式

    1) 检查到异常出现,设置对象值为空字符串或一个默认值; 2) 检测到异常出现,根本不执行某操作,直接跳转到其他处理中。 3) 检查到异常出现,提示用户操作有错误。

    转载请注明原文地址: https://ju.6miu.com/read-17279.html

    最新回复(0)