Java面试----Java基础重难点篇

Java代码执行顺序:

package com.liuyong;

public class Test {
    public static void main(String[] args) {
        Fu fu = new Zi();
    }
}

class Fu {
    static {
        System.out.println("静态代码块Fu");
    }

    {
        System.out.println("构造代码块Fu");
    }

    public Fu() {
        System.out.println("构造方法Fu");
    }
}

class Zi extends Fu {
    static {
        System.out.println("静态代码块Zi");
    }

    {
        System.out.println("构造代码块Zi");
    }

    public Zi() {
        System.out.println("构造方法Zi");
    }
}

输出结果为:
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi

冒泡排序:每次比较相邻的2个数,将较大的数放前面

package com.liuyong;

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int flag = 0;
        int[] arr = {1, 6, 3, 8, 5};
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                if (arr[i] < arr[j]) {
                    flag = arr[i];
                    arr[i] = arr[j];
                    arr[j] = flag;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

选择排序:比较选择最小元素,放在最前面,已排序元素位置保持不变,后面依次如此

package com.liuyong;

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int flag = 0;
        int[] arr = {1, 6, 3, 8, 5};
        for (int i = 0; i < arr.length; i++) {
            int lowerIndex = i;
            for (int j = i+1; j < arr.length; j++) {
                if(arr[j]<arr[lowerIndex]){
                    //找到最小值索引
                    lowerIndex = j;
                }
            }
            flag = arr[i];
            arr[i] = arr[lowerIndex];
            arr[lowerIndex] = flag;
        }
        System.out.println(Arrays.toString(arr));
    }
}

数组排序:使用工具类排序

package com.liuyong;

import org.apache.commons.lang3.ArrayUtils;

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int flag = 0;
        int[] arr = {1, 6, 3, 8, 5};
        Arrays.sort(arr);
        System.out.println("数组升序排列: " + Arrays.toString(arr));
        ArrayUtils.reverse(arr);
        System.out.println("数组逆序排列 " + Arrays.toString(arr));
    }
}

需要添加此依赖才能使用ArrayUtils工具类

        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-lang3artifactId>
            <version>3.5version>
        dependency>

包装数据类型高频区间的数据缓存

包装数据类型在-128~127区间进行缓存,float和double类型不会进行缓存

package com.liuyong;

public class Test {
    public static void main(String[] args) {
        Integer a = 127;
        Integer b = 127;
        System.out.println(a == b); //true
        Integer c =128;
        Integer d =128;
        System.out.println(c == d); //false
    }
}

String和StringBuffer作为方法参数传递时的差异

String类被final修饰,作为方法参数时传递的是副本,StringBuffer作为方法参数时传递的是对象的引用

package com.liuyong;

public class Test {
    public static void main(String[] args) {
        String string = "string";
        stringArg(string);
        System.out.println(string);//string

        StringBuffer sb = new StringBuffer("stringBuffer");
        stringBufferArg(sb);
        System.out.println(sb);//stringBuffer hello

    }

    public static void stringArg(String s) {
        s = "string hello!";
    }

    public static void stringBufferArg(StringBuffer sb) {
        sb.append(" hello");
    }
}

Java中造成内存泄漏的原因

内存泄漏指:对象不在程序中使用,但是没有被GC自动回收掉,一直占据在内存中
内存泄漏的原因:
1.短生命周期引用指向长生命周期对象.例如:缓存中的对象
2.连接未关闭.例如:数据库连接,IO流等对象
3.内部类持有外部类
4.改变对象Hash值.例如:将对象存入集合,修改对象Hash值,导致无法删除集合中的对象

包装数据类型的有点

1.高频区间的数据缓存.Integer类型在-128~127间会使用缓存(Float,Double没有高频区间数据缓存)
2.包装数据类型属于对象,会有一些属性和方法
3.包装数据类型可以作为范型
4.包装数据类型会提供一些类型转换的方法
5.支持序列化

数组比较

String[] strArr = {"刘备", "张飞", "关羽"};
String[] strArr2 = {"刘备", "张飞", "关羽"};
System.out.println(Arrays.equals(strArr, strArr2));//true
System.out.println(strArr.equals(strArr2));//false
System.out.println(strArr == strArr2);//false

第一种方式重写了equals方法,比较对象的值,第二种和第三中方式没有重写equals方法,比较的是对象的内存地址值

判断字符串数组中是否含有某字符串

方式1:将数组转集合,通过集合的contains(“key”)的方法进行判断

package com.liuyong;

import java.util.Arrays;

public class Study {
    public static void main(String[] args) {
        String[] arr = {"刘备", "关羽", "张飞"};
        boolean b = Arrays.asList(arr).contains("刘备");
        System.out.println(b);
    }
}

方式2:通过数组中二分查找的方法判断

package com.liuyong;

import java.util.Arrays;

public class Study {
    public static void main(String[] args) {
        String[] arr = {"刘备", "关羽", "张飞"};
        Arrays.sort(arr);
        int boo = Arrays.binarySearch(arr, "刘备");
        System.out.println(boo >= 0);
    }
}

修改数组的前2个元素

使用Arrays.fill(arr[],fromIndex,toIndex,val)填充方法

package com.liuyong;

import java.util.Arrays;

public class Study {
    public static void main(String[] args) {
        String[] arr = {"刘备", "关羽", "张飞"};
        Arrays.fill(arr, 0, 2, "马超");
        System.out.println(Arrays.toString(arr));
    }
}

多态中,属性看左边,方法看右边

package com.liuyong;

class A {
    public int x = 0;
    public static int y = 0;

    public void m() {
        System.out.print("A");
    }
}

class B extends A {
    public int x = 1;
    public static int y = 1;

    public void m() {
        System.out.print("B");
    }

    public static void main(String[] args) {
        A myClass = new B();
        System.out.print(myClass.x);
        System.out.print(myClass.y);
        myClass.m();
    }
}

多态:父类引用指向子类对象;接口的引用指向实现类对象
多态对象调用属性时,只能访问父类的属性
多态对象调用方法时,如果子类重写父类方法,就调用子类重写方法,否则调用父类自己的方法

匿名内部类

匿名内部类:没有名字的内部类.使用的前提条件:必须要继承一个父类或实现一个接口.不能定义任何静态成员和方法

//接口
interface Anonymity {
    void hello();
}

class Test {
    public static void main(String[] args) {
        //接口的实现
        Anonymity anonymityOuter = new Anonymity() {
            @Override
            public void hello() {
                System.out.println("hello");
            }
        };
        anonymityOuter.hello();
    }
}

JDK8推出,接口中被static和default修饰的方法可以有方法体

package com.liuyong;

public interface Hero {
    static void eat(){
        System.out.println("i am eat");
    }
    default void drink(){
        System.out.println("i like drink");
    }
}

对象复制和常量复制

 package com.liuyong;

public class Study {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 等号赋值( 基本类型)
        int i1 = 6;
        int i2 = i1;
        // 修改 number2 的值
        i2 = 9;
        System.out.println("number:" + i1);//6
        System.out.println("number2:" + i2);//9
        // 等号赋值(对象)
        Person p = new Person();
        p.name = "张飞";
        p.age = 20;
        Person p2 = p;
        // 修改 dog2 的值
        p.name = "关羽";
        p.age = 30;
        System.out.println(p.name + "," + p.age + "岁");//关羽,30岁
        System.out.println(p2.name + "," + p2.age + "岁");//关羽,30岁
    }
}
class Person{
    String name;
    Integer age;
}

由此可知,等号复制变量是产生一个新的变量,等号复制对象是生成一个对象引用指向原有对象

浅clone方式复制对象

package com.liuyong;

public class Study {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 等号赋值(对象)
        Person p = new Person();
        Children child = new Children();
        p.name = "张飞";
        p.age = 20;
        child.address="蜀国";
        p.child=child;
        Person p2 = (Person)p.clone();
        // 修改p2的属性值
        p2.name = "关羽";
        p2.age = 30;
        p2.child.address="中国";
        System.out.println(p.name + "," + p.age + "岁"+","+p.child.address);//张飞,20岁,中国
        System.out.println(p2.name + "," + p2.age + "岁"+","+p2.child.address);//关羽,20岁,中国
    }
}
class Person implements Cloneable{
    Children child;
    String name;
    Integer age;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Children{
    String address;
}

clone步骤:实现Cloneable接口,重写clone()方法
浅clone复制对象 时,对于对象中基本数据类型的变量进行了复制,对于对象中引用数据类型的变量只是对象的引用指向同一个内存地址

深clone方式clone对象

package com.liuyong;

public class Study {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 等号赋值(对象)
        Person p = new Person();
        Children child = new Children();
        p.name = "张飞";
        p.age = 20;
        child.address="蜀国";
        p.child=child;
        Person p2 = (Person)p.clone();
        // 修改 dog2 的值
        p2.name = "关羽";
        p2.age = 30;
        p2.child.address="中国";
        System.out.println(p.name + "," + p.age + "岁"+","+p.child.address);//张飞,20岁,蜀国
        System.out.println(p2.name + "," + p2.age + "岁"+","+p2.child.address);//关羽,20岁,中国
    }
}
class Person implements Cloneable{
    Children child;
    String name;
    Integer age;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person person = (Person)super.clone();
        person.child = (Children) child.clone();
        return person;
    }
}
class Children implements Cloneable{
    String address;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

集合排序的2种方式

方式一:继承comparable排序接口,重写compareTo(Object o)排序方法

package com.liuyong;


import java.util.Arrays;

public class Study {
    public static void main(String[] args) {
        Animal[] animalArr = {new Animal("dog", 18), 
        					  new Animal("cat", 15), 
                              new Animal("tiger", 30)};
        Arrays.sort(animalArr);
        for (Animal animal : animalArr) {
            System.out.println(animal.name+"==="+animal.age);
        }

    }
}

class Animal implements Comparable<Animal> {
    String name;
    Integer age;

    public Animal(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Animal a) {
        return age - a.age;
    }
}

方式二:创建一个排序实现类继承comparator接口,重写compare()排序方法

package com.liuyong;

import java.util.Arrays;
import java.util.Comparator;

public class Study {
    public static void main(String[] args) {
        Animal[] animalArr = {new Animal("dog", 18),
                new Animal("cat", 15),
                new Animal("tiger", 30)};
        Arrays.sort(animalArr,new AnimalComparator());
        for (Animal animal : animalArr) {
            System.out.println(animal.name+"==="+animal.age);
        }

    }
}
class AnimalComparator implements Comparator<Animal>{

    @Override
    public int compare(Animal animal1, Animal animal2) {
        return animal1.age - animal2.age;
    }
}
class Animal{
    String name;
    Integer age;

    public Animal(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

你可能感兴趣的:(Java面试)