天天看点

牛客java选择题每日打卡Day12

牛客java选择题每日打卡Day12

👩‍💻博客主页:京与旧铺的博客主页

✨欢迎关注🖱点赞🎀收藏⭐留言✒

🔮本文由京与旧铺原创

😘系列专栏:java学习

👕参考网站:牛客网

💻首发时间:🎞2022年6月13日🎠

🎨你做三四月的事,八九月就会有答案,一起加油吧

🀄如果觉得博主的文章还不错的话,请三连支持一下博主哦

🎧最后的话,作者是一个新人,在很多方面还做的不好,欢迎大佬指正,一起学习哦,冲冲冲

💬推荐一款模拟面试、刷题神器👉​​​点击进入网站​​

牛客java选择题每日打卡Day12

🛒导航小助手🎪

文章目录

  • ​​牛客java选择题每日打卡Day12​​
  • ​​🛒导航小助手🎪​​
  • ​​@[toc]​​
  • ​​😥选择题1​​
  • ​​正确答案: B C D 你的答案: B C D (正确)​​
  • ​​😫选择题2​​
  • ​​正确答案: A C 你的答案: A C D (错误)​​
  • ​​😣选择题3​​
  • ​​正确答案: C 你的答案: C (正确)​​
  • ​​😋选择题4​​
  • ​​正确答案: C 你的答案: B (错误)​​
  • ​​A.一个类可以有多个构造方法,实际上就是方法的重载,正确​​
  • ​​B.用final修饰的类不能被继承,方法不能被覆盖,正确​​
  • ​​C.如果没有构造方法,编译器会自动添加一个空参构造方法,错误​​
  • ​​D.由源码可知,数组内部采用字符数组存储,该字符数组用final修饰,长度一旦确定不可再变,正确​​
  • ​​😀选择题5​​
  • ​​正确答案: B 你的答案: C (错误)​​
  • ​​🥱选择题6​​
  • ​​正确答案: D 你的答案: B (错误)​​
  • ​​🤔选择题7​​
  • ​​正确答案: A B C D 你的答案: A B D (错误)​​
  • ​​一、单例模式的定义​​
  • ​​二、单例模式的设计要素​​
  • ​​三、单例模式的6种实现及各实现的优缺点​​
  • ​​(一)懒汉式(线程不安全)​​
  • ​​(二)饿汉式(线程安全)​​
  • ​​(三)懒汉式(线程安全)​​
  • ​​(四)双重检查锁实现(线程安全)​​
  • ​​(五)静态内部类实现(线程安全)​​
  • ​​(六)枚举类实现(线程安全)​​
  • ​​四、单例模式的应用场景​​
  • ​​四、单例模式的应用场景​​

😥选择题1

以下各类中哪几个是线程安全的?( )

正确答案: B C D 你的答案: B C D (正确)

ArrayList
Vector
Hashtable
Stack      

在集合框架中,有些类是线程安全的,这些都是jdk1.1中的出现的。在jdk1.2之后,就出现许许多多非线程安全的类。 下面是这些线程安全的同步的类:

vector:就比arraylist多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。

statck:堆栈类,先进后出

hashtable:就比hashmap多了个线程安全

enumeration:枚举,相当于迭代器

除了这些之外,其他的都是非线程安全的类和接口。

😫选择题2

下面的对象创建方法中哪些会调用构造方法 ()?

正确答案: A C 你的答案: A C D (错误)

new语句创建对象
调用Java.io.ObjectInputStream的readObject方法
java反射机制使用java.lang.Class或java.lang.reflect.Constructor的newInstance()方法
调用对象的clone()方法      

构造函数的作用是完成对象的初始化。当程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化。而选项B、D中,对象的初始化并不是通过构造函数完成的,而是读取别的内存区域中的对象的各个域来完成。

😣选择题3

下面有关maven和ant的描述,描述错误的是?

正确答案: C 你的答案: C (正确)

Ant 没有正式的约定如一个一般项目的目录结构,你必须明确的告诉 Ant 哪里去找源代码
Maven 拥有约定,因为你遵循了约定,它已经知道你的源代码在哪里
maven和ant都有“生命周期”的概念,当你输入一个命令后,maven或者ant会执行一系列的有序的步骤,直到到达你指定的生命周期
Ant构建文件默认命名为build.xml,Maven默认构建文件为pom.xml      

Ant和Maven都是基于Java的构建(build)工具。理论上来说,有些类似于(Unix)C中的make ,但没有make的缺陷。Ant是软件构建工具,Maven的定位是软件项目管理和理解工具。

Ant特点 ›

没有一个约定的目录结构 ›必须明确让ant做什么,什么时候做,然后编译,打包 ›没有生命周期,必须定义目标及其实现的任务序列 ›没有集成依赖管理

Maven特点

›拥有约定,知道你的代码在哪里,放到哪里去 ›拥有一个生命周期,例如执行 mvn install 就可以自动执行编译,测试,打包等构建过程 ›只需要定义一个pom.xml,然后把源码放到默认的目录,Maven帮你处理其他事情 ›拥有依赖管理,仓库管理

😋选择题4

下面叙述错误的是 ( )

正确答案: C 你的答案: B (错误)

一个类可以有多个构造方法
最终类不能派生子类,最终方法不能被覆盖
如果一个类中没有定义构造方法,则Java在生成这个类的实例时不会调用构造方法。
数组一旦创建之后,就不能再改变其长度      

A.一个类可以有多个构造方法,实际上就是方法的重载,正确

B.用final修饰的类不能被继承,方法不能被覆盖,正确

C.如果没有构造方法,编译器会自动添加一个空参构造方法,错误

D.由源码可知,数组内部采用字符数组存储,该字符数组用final修饰,长度一旦确定不可再变,正确

😀选择题5

try括号里有return语句, finally执行顺序

正确答案: B 你的答案: C (错误)

不执行finally代码
return前执行
return后执行      

选项B;我相信仔细看的话,每一本Java书都有讲过。“假设利用 return 语句从 try 语句块中退出。在方法返回前,finally子句的内容将被执行。如果 finally 子句中也有一个 return 语句,这个返回值将会覆盖原始的返回值。”

public static void main(String[] args) {
        int k = f_test();
        System.out.println(k);
    }
    
    public static int f_test(){
        int a = 0;
        try{
            a = 1;
            return a;
        }
        finally{
            System.out.println("It is in final chunk.");
            a = 2;
            return a;
        }
    }      

输出:

It is in final chunk.

2

🥱选择题6

有变量int i = 0; int a = i++; int b = ++a; int c = a+b; int d = (a == 1)?b:c; 请问a和d的值分别是多少?( )。

正确答案: D 你的答案: B (错误)

2,4
1, 4
1, 2
1,1      

int i = 0; //i=0

int a = i++; //a=i,a=0,i++,i=1

int b = ++a; //a++,a=1,b=a,b=1

int c = a+b;//c=2

int d = (a == 1)?b:c;//a==1,d=b,d=1

🤔选择题7

以下哪种方式实现的单例是线程安全的

正确答案: A B C D 你的答案: A B D (错误)

枚举
静态内部类
双检锁模式
饿汉式      

一、单例模式的定义

定义: 确保一个类只有一个实例,并提供该实例的全局访问点。

这样做的好处是:有些实例,全局只需要一个就够了,使用单例模式就可以避免一个全局使用的类,频繁的创建与销毁,耗费系统资源。

二、单例模式的设计要素

  • 一个私有构造函数 (确保只能单例类自己创建实例)
  • 一个私有静态变量 (确保只有一个实例)
  • 一个公有静态函数 (给使用者提供调用方法)

简单来说就是,单例类的构造方法不让其他人修改和使用;并且单例类自己只创建一个实例,这个实例,其他人也无法修改和直接使用;然后单例类提供一个调用方法,想用这个实例,只能调用。这样就确保了全局只创建了一次实例。

三、单例模式的6种实现及各实现的优缺点

(一)懒汉式(线程不安全)

实现:

public class Singleton {
     private static Singleton uniqueInstance;

     private Singleton() {

    }

    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}      

说明: 先不创建实例,当第一次被调用时,再创建实例,所以被称为懒汉式。

优点: 延迟了实例化,如果不需要使用该类,就不会被实例化,节约了系统资源。

缺点: 线程不安全,多线程环境下,如果多个线程同时进入了 if (uniqueInstance == null) ,若此时还未实例化,也就是uniqueInstance == null,那么就会有多个线程执行 uniqueInstance = new Singleton(); ,就会实例化多个实例;

(二)饿汉式(线程安全)

实现:

public class Singleton {

    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        return uniqueInstance;
    }

}      

说明: 先不管需不需要使用这个实例,直接先实例化好实例 (饿死鬼一样,所以称为饿汉式),然后当需要使用的时候,直接调方法就可以使用了。

优点: 提前实例化好了一个实例,避免了线程不安全问题的出现。

缺点: 直接实例化好了实例,不再延迟实例化;若系统没有使用这个实例,或者系统运行很久之后才需要使用这个实例,都会操作系统的资源浪费。

(三)懒汉式(线程安全)

实现:

public class Singleton {
    private static Singleton uniqueInstance;

    private static singleton() {
    }

    private static synchronized Singleton getUinqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }

}      

说明: 实现和 线程不安全的懒汉式 几乎一样,唯一不同的点是,在get方法上 加了一把 锁。如此一来,多个线程访问,每次只有拿到锁的的线程能够进入该方法,避免了多线程不安全问题的出现。

优点: 延迟实例化,节约了资源,并且是线程安全的。

缺点: 虽然解决了线程安全问题,但是性能降低了。因为,即使实例已经实例化了,既后续不会再出现线程安全问题了,但是锁还在,每次还是只能拿到锁的线程进入该方***使线程阻塞,等待时间过长。

(四)双重检查锁实现(线程安全)

实现:

public class Singleton {

    private volatile static Singleton uniqueInstance;

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }  
}      

说明: 双重检查数相当于是改进了 线程安全的懒汉式。线程安全的懒汉式 的缺点是性能降低了,造成的原因是因为即使实例已经实例化,依然每次都会有锁。而现在,我们将锁的位置变了,并且多加了一个检查。 也就是,先判断实例是否已经存在,若已经存在了,则不会执行判断方法内的有锁方法了。 而如果,还没有实例化的时候,多个线程进去了,也没有事,因为里面的方法有锁,只会让一个线程进入最内层方法并实例化实例。如此一来,最多最多,也就是第一次实例化的时候,会有线程阻塞的情况,后续便不会再有线程阻塞的问题。

为什么使用 volatile 关键字修饰了 uniqueInstance 实例变量 ?

uniqueInstance = new Singleton(); 这段代码执行时分为三步:

  1. 为 uniqueInstance 分配内存空间
  2. 初始化 uniqueInstance
  3. 将 uniqueInstance 指向分配的内存地址

正常的执行顺序当然是 1>2>3 ,但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1>3>2。

单线程环境时,指令重排并没有什么问题;多线程环境时,会导致有些线程可能会获取到还没初始化的实例。

例如:线程A 只执行了 1 和 3 ,此时线程B来调用 getUniqueInstance(),发现 uniqueInstance 不为空,便获取 uniqueInstance 实例,但是其实此时的 uniqueInstance 还没有初始化。

解决办法就是加一个 volatile 关键字修饰 uniqueInstance ,volatile 会禁止 JVM 的指令重排,就可以保证多线程环境下的安全运行。

优点: 延迟实例化,节约了资源;线程安全;并且相对于 线程安全的懒汉式,性能提高了。

缺点: volatile 关键字,对性能也有一些影响。

(五)静态内部类实现(线程安全)

实现:

public class Singleton {

    private Singleton() {
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getUniqueInstance() {
        return SingletonHolder.INSTANCE;
    }

}      

说明: 首先,当外部类 Singleton 被加载时,静态内部类 SingletonHolder 并没有被加载进内存。当调用 getUniqueInstance() 方法时,会运行 return SingletonHolder.INSTANCE; ,触发了 SingletonHolder.INSTANCE ,此时静态内部类 SingletonHolder 才会被加载进内存,并且初始化 INSTANCE 实例,而且 JVM 会确保 INSTANCE 只被实例化一次。

优点: 延迟实例化,节约了资源;且线程安全;性能也提高了。

(六)枚举类实现(线程安全)

实现:

public enum Singleton {

    INSTANCE;

    //添加自己需要的操作
    public void doSomeThing() {

    }

}      

说明: 默认枚举实例的创建就是线程安全的,且在任何情况下都是单例。

优点: 写法简单,线程安全,天然防止反射和反序列化调用。

  • 防止反序列化

    **序列化:**把java对象转换为字节序列的过程;

    反序列化: 通过这些字节序列在内存中新建java对象的过程;

    说明: 反序列化 将一个单例实例对象写到磁盘再读回来,从而获得了一个新的实例。

    我们要防止反序列化,避免得到多个实例。

    枚举类天然防止反序列化。

    其他单例模式 可以通过 重写 readResolve() 方法,从而防止反序列化,使实例唯一重写 readResolve() :

private Object readResolve() throws ObjectStreamException{
        return singleton;
}      

四、单例模式的应用场景

应用场景举例:

  • 网站计数器。
  • 应用程序的日志应用。
  • Web项目中的配置对象的读取。
  • 数据库连接池。
  • 多线程池。

使用场景总结:

  • 频繁实例化然后又销毁的对象,使用单例模式可以提高性能。
  • 经常使用的对象,但实例化时耗费时间或者资源多,如数据库连接池,使用单例模式,可以提高性能,降低资源损坏。

    类天然防止反序列化。**

    其他单例模式 可以通过 重写 readResolve() 方法,从而防止反序列化,使实例唯一重写 readResolve() :

private Object readResolve() throws ObjectStreamException{
        return singleton;
}      

四、单例模式的应用场景

应用场景举例:

  • 网站计数器。
  • 应用程序的日志应用。
  • Web项目中的配置对象的读取。
  • 数据库连接池。
  • 多线程池。
  • 频繁实例化然后又销毁的对象,使用单例模式可以提高性能。
  • 经常使用的对象,但实例化时耗费时间或者资源多,如数据库连接池,使用单例模式,可以提高性能,降低资源损坏。
  • 使用线程池之类的控制资源时,使用单例模式,可以方便资源之间的通信。
  • 结束语🏆🏆🏆

    🔥推荐一款模拟面试、刷题神器网站

    点击跳转进入网站​​​点击进入​​​ 1、算法篇(398题):面试必刷100题、算法入门、面试高频榜单

    2、SQL篇(82题):快速入门、SQL必知必会、SQL进阶挑战、面试真题

    3、大厂笔试真题:字节跳动、美团、百度、腾讯…