2021/1/12 牛客百题总结

我不生产代码,我只是代码的搬运工

1.Integer不同创建方法之间的区别

Integer有三种创建方法,分别是

Integer a=new Integer(100);
Integer b=100;
Integer c=Integer.valueOf(100)

下面进行比较:

Integer a1=new Integer(100);
Integer b1=100;
Integer c1=Integer.valueOf(100)
a==a1 //Output:false 因为new创建的是引用对象,两个引用对象比较堆中地址,地址不同;
b==b1//Output:true,但是将b与b1改成400后结果为false
c==c1//结果与b相同
  • 这是由于valueOf的源码导致的
public static Integer valueOf(int i) {
    
        
       if(i >= -128 && i <= IntegerCache.high)    
           return IntegerCache.cache[i + 128];    
       else    
           return new Integer(i);    
}   
  • 当valueOf或者自动装箱的数在-128到127之间时,会直接查看内存,因此并不会使用new新建对象,而超出范围,则会new,因此结果为false

举例:

Integer i01=59;
int i02=59;
Integer i03=Integer.valueOf(59);
Integer i04=new Integer(59);
// i01==i02==i03,i04与上述三个不相等

2.构造方法的几个特点

1.构造方法可以被重载,一个构造方法可以通过this关键字调用另一个构造方法,this语句必须位于构造方法的第一行;(但不可以被重写)

2.当一个类中没有定义任何构造方法,Java将自动提供一个缺省构造方法;

3.子类通过super关键字调用父类的一个构造方法;

4.当子类的某个构造方法没有通过super关键字调用父类的构造方法,通过这个构造方法创建子类对象时,会自动先调用父类的缺省构造方法

5,构造方法不能被static、final、synchronized、abstract、native修饰,但可以被public、protected,default,private修饰;

6.构造方法不是类的成员方法;

7.构造方法不能被继承。

3.一个Java源程序文件中定义几个类和接口,则编译该文件后生成几个以.class为后缀的字节码文件

在这里插入图片描述

4.PreparedStatement知识点

PreparedStatement是预编译的,使用PreparedStatement有几个好处

a. 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。

b. 安全性好,有效防止Sql注入等问题。

c. 对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;

d. 代码的可读性和可维护性。

  • CallableStatement接口扩展PreparedStatement,用来调用存储过程,它提供了对输出和输入/输出参数的支持。CallableStatement
    接口还具有对 PreparedStatement 接口提供的输入参数的支持。

继承关系:
在这里插入图片描述

5.Maven and Ant

  • Ant和Maven都是基于Java的构建(build)工具。理论上来说,有些类似于(Unix)C中的make ,但没有make的缺陷。Ant是软件构建工具,Maven的定位是软件项目管理和理解工具。
  • Ant构建文件默认命名为build.xml,Maven默认构建文件为pom.xml
  • Ant特点:
  • 1.没有一个约定的目录结构
    2.必须明确让ant做什么,什么时候做,然后编译,打包
    3.没有生命周期,必须定义目标及其实现的任务序列
    4.没有集成依赖管理 Maven特点:
    1.拥有约定,知道你的代码在哪里,放到哪里去
    2.拥有一个生命周期,例如执行 mvn install 就可以自动执行编译,测试,打包等构建过程
    3.只需要定义一个pom.xml,然后把源码放到默认的目录,Maven帮你处理其他事情
    4.拥有依赖管理,仓库管理

6.正则表达式字符

正则表达式中的字符介绍

7.Java中的修饰符

在这里插入图片描述

8.使用泛型的好处

1,类型安全。

  • 泛型的主要目标是提高 Java程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

2,消除强制类型转换。

  • 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

3,潜在的性能收益。

  • 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。

9.类的加载顺序

public class Base
{
    
    
    private String baseName = "base";
    public Base()
    {
    
    
        callName();
    }

    public void callName()
    {
    
    
        System. out. println(baseName);
    }

    static class Sub extends Base
    {
    
    
        private String baseName = "sub";
        public void callName()
        {
    
    
            System. out. println (baseName) ;
        }
    }
    public static void main(String[] args)
    {
    
    
        Base b = new Sub();
    }
}

1.类的加载顺序:

(1) 父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)

(2) 子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法 )

(3) 父类非静态代码块( 包括非静态初始化块,非静态属性 )

(4) 父类构造函数

(5) 子类非静态代码块 ( 包括非静态初始化块,非静态属性 )

(6) 子类构造函数

其中:类中静态块按照声明顺序执行,并且(1)和(2)不需要调用new类实例的时候就执行了(意思就是在类加载到方法区的时候执行的)

2.其次,需要理解子类覆盖父类方法的问题,也就是方法重写实现多态问题。

Base b = new Sub();它为多态的一种表现形式,声明是Base,实现是Sub类, 理解为 b 编译时表现为Base类特性,运行时表现为Sub类特性。

当子类覆盖了父类的方法后,意思是父类的方法已经被重写,题中 父类初始化调用的方法为子类实现的方法,子类实现的方法中调用的baseName为子类中的私有属性。

由1.可知,此时只执行到步骤4.,子类非静态代码块和初始化步骤还没有到,子类中的baseName还没有被初始化。所以此时 baseName为空。 所以为null。

10.垃圾收集机制

在这里插入图片描述

1,新生代:

(1)所有对象创建在新生代的Eden区,当Eden区满后触发新生代的Minor GC,将Eden区和非空闲Survivor区存活的对象复制到另外一个空闲的Survivor区中。

(2)保证一个Survivor区是空的,新生代Minor GC就是在两个Survivor区之间相互复制存活对象,直到Survivor区满为止。

2,老年代:

当Survivor区也满了之后就通过Minor GC将对象复制到老年代。老年代也满了的话,就将触发Full GC,针对整个堆(包括新生代、老年代、持久代)进行垃圾回收。

3,持久代:

持久代如果满了,将触发Full GC。

11.synchronized机制

public class Test {
    
    
    private synchronized void a() {
    
    
    }
    private void b() {
    
    
        synchronized (this) {
    
    
        }
    }
    private synchronized static void c() {
    
    
    }
    private void d() {
    
    
        synchronized (Test.class) {
    
    
        }
    }
}

//修饰非静态方法 锁的是this 对象

//修饰静态方法 锁的是class对象

12.try-catch-finally中return问题

情况1:

  • try{} catch(){}finally{} return;
  • 显然程序按顺序执行。

情况2:

  • try{ return; }catch(){} finally{} return;
  • 先执行try块中return语句(包括return语句中的表达式运算),但不返回;
  • 执行finally语句中全部代码 最后执行try中return 返回
  • finally块之后的语句return不执行,因为程序在try中已经return。

情况3:

  • try{ } catch(){return;} finally{} return;
  • 程序先执行try,如果遇到异常执行catch块,
  • 有异常:
  • 执行catch中return语句,但不返回
  • 执行finally语句中全部代码, 最后执行catch块中return返回。
  • finally块后的return语句不再执行。
  • 无异常:
  • 执行完try再finally再return…

情况4:

  • try{ return; }catch(){} finally{return;}

  • 执行try块return语句(包括return语句中的表达式运算),但不返回;

  • 再执行finally块,

  • 执行finally块,有return,从这里返回。

  • 此时finally块的return值,就是代码执行完后的值
    情况5:

  • try{} catch(){return;}finally{return;}

  • 程序执行catch块中return语句(包括return语句中的表达式运算),但不返回;

  • 再执行finally块,

  • 执行finally块,有return,从这里返回。
    情况6:

  • try{ return;}catch(){return;} finally{return;}

  • 程序执行try块中return语句(包括return语句中的表达式运算),但不返回

  • 有异常:

  • 执行catch块中return语句(包括return语句中的表达式运算),但不返回;

  • 再执行finally块

  • 执行finally块,有return,从这里返回。

  • 无异常:

  • 再执行finally块 执行finally块,有return,从这里返回。

13.String与==问题

public class Demo {
    
    
    public static void main(String args[]) {
    
    
        String str1 = new String("hello");
        String str2 = new String("hello");
        String str3 = "hello";
        String str4 = "hello";
        String str5 = "he"+"llo";
        String str6 = "he";
        String str7 = "llo";
        System.out.println(str1==str2);
        System.out.println(str1==str3);
        System.out.println(str3==str4);
        System.out.println(str3=="hello");
        System.out.println(str4==(str6+str7));
    }
}

new出的String对象存储在堆当中。

String str3=“hello"存储在字符串常量池中。

String str5=”he"+“llo” 因为String是不可更改的,因此这个String对象是new出的。

13.Stream、File与IO

在这里插入图片描述

14. byte b = (byte)129

1.强制类型转换

将int类型强制转换成byte类型

00000000 00000000 00000000 10000001只保留最后8位100000001

2.源码、补码、反码

源码:10000001

反码:11111110

补码:11111111

结果:-127

15.加载驱动程序的方法

  • 加载驱动方法

  • 1.Class.forName(“com.microsoft.sqlserver.jdbc.SQLServerDriver”);

    2.DriverManager.registerDriver(new com.mysql.jdbc.Driver());

    3.System.setProperty(“jdbc.drivers”, “com.mysql.jdbc.Driver”);

16.Collection接口与Map接口

在这里插入图片描述

16.子进程与父进程

  • 子进程得到的是除了代码段是与父进程共享以外,其他所有的都是得到父进程的一个副本,子进程的所有资源都继承父进程,得到父进程资源的副本,子进程可获得父进程的所有堆和栈的数据,但二者并不共享地址空间。两个是单独的进程,继承了以后二者就没有什么关联了,子进程单独运行;进程的线程之间共享由进程获得的资源,但线程拥有属于自己的一小部分资源,就是栈空间,保存其运行状态和局部自动变量的。

17.线程的锁机制

参考:Java线程】锁机制:synchronized、Lock、Condition

猜你喜欢

转载自blog.csdn.net/qq_52212721/article/details/112521986
今日推荐