转载

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...