转载

Java基础面试题及答案解析(11)

点击上方“ Java知音 ”,选择“置顶公众号”

技术文章第一时间送达!

知音专栏

Javaweb练手项目源码下载

常用设计模式完整系列篇

100套IT类简历模板下载

Java常见面试题汇总篇

手写一段单例中的懒汉模式和饿汉模式,并且简单说一下他们的区别

懒汉模式:

public class LazySingleton {
    //懒汉式单例模式
    //在类加载时,不创建实例,因此类加载速度快,但运行时获取对象的速度慢
    
    
    private static LazySingleton intance = null;
     //静态私用成员,没有初始化
    
    private LazySingleton()
    {
        //私有构造函数
    }
    
    public static synchronized LazySingleton getInstance()    
    //静态,同步,公开访问点
    {
        if(intance == null)
        {
            intance = new LazySingleton();
        }
        return intance;
    }
}

饿汉模式:

public class EagerSingleton {
    //饿汉单例模式
    //类加载较慢,但获取对象的速度快
    
    private static EagerSingleton instance = new EagerSingleton();
  //静态私有成员,已初始化
    
    private EagerSingleton() 
    {
        //私有构造函数
    }
    
    public static EagerSingleton getInstance()    
    //静态,不用同步
    {
        return instance;
    }
}

懒汉模式和饿汉模式的比较:

饿汉模式的特点是加载类时比较慢,但运行时获取对象的速度比较快,线程安全。饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。

懒汉模式的特点是加载类时比较快,但是在运行时获取对象的速度比较慢,线程不安全, 懒汉式如果在创建实例对象时不加上 synchronized 则会导致对象的访问不是线程安全的。

Array 和 ArrayList 有何区别?什么时候更适合用 Array ?

存储内容比较:

Array 数组可以包含基本类型和对象类型, ArrayList 只能包含对象类型。

Array 数组存放的一定是同种类型的元素, ArrayList 可以存放任意对象( object 的子类)。

空间大小比较:

Array 的空间大小是固定的,空间不够时也不能再次申请,所以需要事前确定合适的空间大小。

ArrayList 的空间是动态增长的,如果空间不够,它会创建一个空间比原空间大的新数组,然后将所有元素复制到新数组中,接着抛弃旧数组。而且,每次添加新的元素的时候都会检查内部数组的空间是否足够。(比较麻烦的地方)。

方法上的比较:

ArrayList 作为 Array 的增强版,在方法上比 Array 更多样化,比如添加全部 addAll() 、删除全部 removeAll() 、返回迭代器 iterator() 等。

适用场景:

如果想要保存一些在整个程序运行期间都会存在而且不变的数据,我们可以将它们放进一个全局数组里;但是如果我们单纯只是想要以数组的形式保存数据,而不对数据进行增加等操作,只是方便我们进行查找的话,那么,我们就选择 ArrayList 。

而且还有一个地方是必须知道的,就是如果我们需要对元素进行频繁的移动或删除,或者是处理的是超大量的数据,那么,使用 ArrayList 就真的不是一个好的选择,因为它的效率很低,我们可以考虑选择 LinkedList 。

Tomcat 服务器优化(内存,并发连接数,缓存)

  • 内存优化:主要是对 Tomcat 启动参数进行优化,我们可以在 Tomcat 启动脚本中修改它的最大内存数等等。

  • 线程数优化: Tomcat 的并发连接参数,主要在 Tomcat 配置文件中 server.xml 中配置,比如修改最小空闲连接线程数,用于提高系统处理性能等等。

  • 优化缓存:打开压缩功能,修改参数,比如压缩的输出内容大小默认为 2KB ,可以适当的修改。

多线程中 sleep() 、 wait() 、 yield() 和 join() 的用法与区别

1.sleep() 方法

在指定时间内让当前正在执行的线程暂停执行,但不会释放 “锁标志”。不推荐使用。

sleep() 使当前线程进入阻塞状态,在指定时间内不会执行。

2.wait() 方法

在其他线程调用对象的 notify 或 notifyAll 方法前,当前线程处于等待状态。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。

当前线程必须拥有当前对象锁。如果当前线程不是此锁的拥有者,会抛出 IllegalMonitorStateException 异常。

唤醒当前对象锁的等待线程使用 notify 或 notifyAll 方法,也必须拥有相同的对象锁,否则也会抛出 IllegalMonitorStateException 异常。

waite() 和 notify() 必须在 synchronized 函数或 synchronized block 中进行调用。如果在 non-synchronized 函数和 non-synchronized block 中进行调用,虽然能编译通过,但在运行时会发生 IllegalMonitorStateException 的异常。

3.yield 方法

暂停当前正在执行的线程对象。

yield() 只是使当前线程重新回到可执行状态,所以执行 yield() 的线程有可能在进入到可执行状态后马上又被执行。

yield() 只能使同优先级或更高优先级的线程有执行的机会。

4.join 方法

等待该线程终止。

等待调用 join 方法的线程结束,再继续执行。如: t.join(); 它主要用于等待 t 线程运行结束,若无此句, main 则会执行完毕,导致结果不可预测。

线程和进程的区别?

进程和线程都是一个时间段的描述,是 CPU 工作时间段的描述,不过是颗粒大小不同。

进程是资源的分配和调度的一个独立单元,而线程是 CPU 调度的基本单元。

同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进行至少包括一个线程。

进程的创建调用 fork 或者 vfork ,而线程的创建调用 pthread_create ,进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束。

线程是轻两级的进程,它的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的。

线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源。

线程有自己的私有属性 TCB ,线程 id ,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块 PCB ,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志。

Java基础面试题及答案解析(11)

原文  https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247485181&idx=1&sn=af40ee5c4facc80290646c27a39cf9ce&chksm=ebd639d1dca1b0c79790536186e96d85b0895295484b0e775aa40dbeb91f3de002b841302892#rd
正文到此结束
Loading...