精华内容
下载资源
问答
  • Java实习生面试题整理
    万次阅读 多人点赞
    2018-09-14 10:16:34

    一、数据类型

    包装类型

    八个基本类型:

    • boolean/1
    • byte/8
    • char/16
    • short/16
    • int/32
    • float/32
    • long/64
    • double/64

    基本类型都有对应的包装类型,基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成。

    Integer x = 2;     // 装箱
    int y = x;         // 拆箱

    缓存池

    new Integer(123) 与 Integer.valueOf(123) 的区别在于:

    • new Integer(123) 每次都会新建一个对象
    • Integer.valueOf(123) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。
    Integer x = new Integer(123);
    Integer y = new Integer(123);
    System.out.println(x == y);    // false
    Integer z = Integer.valueOf(123);
    Integer k = Integer.valueOf(123);
    System.out.println(z == k);   // true

    valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容。

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

    在 Java 8 中,Integer 缓存池的大小默认为 -128~127。

    static final int low = -128;
    static final int high;
    static final Integer cache[];
    
    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;
    
        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    
        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    编译器会在自动装箱过程调用 valueOf() 方法,因此多个 Integer 实例使用自动装箱来创建并且值相同,那么就会引用相同的对象。

    Integer m = 123;
    Integer n = 123;
    System.out.println(m == n); // true

    基本类型对应的缓冲池如下:

    • boolean values true and false
    • all byte values
    • short values between -128 and 127
    • int values between -128 and 127
    • char in the range \u0000 to \u007F

    在使用这些基本类型对应的包装类型时,就可以直接使用缓冲池中的对象。

    StackOverflow : Differences between new Integer(123), Integer.valueOf(123) and just 123

    二、String

    概览

    String 被声明为 final,因此它不可被继承。

    内部使用 char 数组存储数据,该数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组。并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        /** The value is used for character storage. */
        private final char value[];

    不可变的好处

    1. 可以缓存 hash 值

    因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算。

    2. String Pool 的需要

    如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。

     

    3. 安全性

    String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 对象的那一方以为现在连接的是其它主机,而实际情况却不一定是。

    4. 线程安全

    String 不可变性天生具备线程安全,可以在多个线程中安全地使用。

    Program Creek : Why String is immutable in Java?

    String, StringBuffer and StringBuilder

    1. 可变性

    • String 不可变
    • StringBuffer 和 StringBuilder 可变

    2. 线程安全

    • String 不可变,因此是线程安全的
    • StringBuilder 不是线程安全的
    • StringBuffer 是线程安全的,内部使用 synchronized 进行同步

    StackOverflow : String, StringBuffer, and StringBuilder

    String.intern()

    使用 String.intern() 可以保证相同内容的字符串变量引用同一的内存对象。

    下面示例中,s1 和 s2 采用 new String() 的方式新建了两个不同对象,而 s3 是通过 s1.intern() 方法取得一个对象引用。intern() 首先把 s1 引用的对象放到 String Pool(字符串常量池)中,然后返回这个对象引用。因此 s3 和 s1 引用的是同一个字符串常量池的对象。

    String s1 = new String("aaa");
    String s2 = new String("aaa");
    System.out.println(s1 == s2);           // false
    String s3 = s1.intern();
    System.out.println(s1.intern() == s3);  // true

    如果是采用 "bbb" 这种使用双引号的形式创建字符串实例,会自动地将新建的对象放入 String Pool 中。

    String s4 = "bbb";
    String s5 = "bbb";
    System.out.println(s4 == s5);  // true

    在 Java 7 之前,字符串常量池被放在运行时常量池中,它属于永久代。而在 Java 7,字符串常量池被移到 Native Method 中。这是因为永久代的空间有限,在大量使用字符串的场景下会导致 OutOfMemoryError 错误。

    三、运算

    参数传递

    Java 的参数是以值传递的形式传入方法中,而不是引用传递。

    以下代码中 Dog dog 的 dog 是一个指针,存储的是对象的地址。在将一个参数传入一个方法时,本质上是将对象的地址以值的方式传递到形参中。因此在方法中改变指针引用的对象,那么这两个指针此时指向的是完全不同的对象,一方改变其所指向对象的内容对另一方没有影响。

    public class Dog {
        String name;
    
        Dog(String name) {
            this.name = name;
        }
    
        String getName() {
            return this.name;
        }
    
        void setName(String name) {
            this.name = name;
        }
    
        String getObjectAddress() {
            return super.toString();
        }
    }
    public class PassByValueExample {
        public static void main(String[] args) {
            Dog dog = new Dog("A");
            System.out.println(dog.getObjectAddress()); // Dog@4554617c
            func(dog);
            System.out.println(dog.getObjectAddress()); // Dog@4554617c
            System.out.println(dog.getName());          // A
        }
    
        private static void func(Dog dog) {
            System.out.println(dog.getObjectAddress()); // Dog@4554617c
            dog = new Dog("B");
            System.out.println(dog.getObjectAddress()); // Dog@74a14482
            System.out.println(dog.getName());          // B
        }
    }

     但是如果在方法中改变对象的字段值会改变原对象该字段值,因为改变的是同一个地址指向的内容。

    class PassByValueExample {
        public static void main(String[] args) {
            Dog dog = new Dog("A");
            func(dog);
            System.out.println(dog.getName());          // B
        }
    
        private static void func(Dog dog) {
            dog.setName("B");
        }
    }

    StackOverflow: Is Java “pass-by-reference” or “pass-by-value”?

    float 与 double

    1.1 字面量属于 double 类型,不能直接将 1.1 直接赋值给 float 变量,因为这是向下转型。Java 不能隐式执行向下转型,因为这会使得精度降低。

    // float f = 1.1;

    1.1f 字面量才是 float 类型。

    float f = 1.1f;

    隐式类型转换

    因为字面量 1 是 int 类型,它比 short 类型精度要高,因此不能隐式地将 int 类型下转型为 short 类型。

    short s1 = 1;
    // s1 = s1 + 1;

    但是使用 += 运算符可以执行隐式类型转换。

    s1 += 1;

    上面的语句相当于将 s1 + 1 的计算结果进行了向下转型:

    s1 = (short) (s1 + 1);

    StackOverflow : Why don't Java's +=, -=, *=, /= compound assignment operators require casting?

    switch

    从 Java 7 开始,可以在 switch 条件判断语句中使用 String 对象。

    String s = "a";
    switch (s) {
        case "a":
            System.out.println("aaa");
            break;
        case "b":
            System.out.println("bbb");
            break;
    }

    switch 不支持 long,是因为 switch 的设计初衷是对那些只有少数的几个值进行等值判断,如果值过于复杂,那么还是用 if 比较合适。

    // long x = 111;
    // switch (x) { // Incompatible types. Found: 'long', required: 'char, byte, short, int, Character, Byte, Short, Integer, String, or an enum'
    //     case 111:
    //         System.out.println(111);
    //         break;
    //     case 222:
    //         System.out.println(222);
    //         break;
    // }

    StackOverflow : Why can't your switch statement data type be long, Java?

    四、继承

    访问权限

    Java 中有三个访问权限修饰符:private、protected 以及 public,如果不加访问修饰符,表示包级可见。

    可以对类或类中的成员(字段以及方法)加上访问修饰符。

    • 类可见表示其它类可以用这个类创建实例对象。
    • 成员可见表示其它类可以用这个类的实例对象访问到该成员;

    protected 用于修饰成员,表示在继承体系中成员对于子类可见,但是这个访问修饰符对于类没有意义。

    设计良好的模块会隐藏所有的实现细节,把它的 API 与它的实现清晰地隔离开来。模块之间只通过它们的 API 进行通信,一个模块不需要知道其他模块的内部工作情况,这个概念被称为信息隐藏或封装。因此访问权限应当尽可能地使每个类或者成员不被外界访问。

    如果子类的方法重写了父类的方法,那么子类中该方法的访问级别不允许低于父类的访问级别。这是为了确保可以使用父类实例的地方都可以使用子类实例,也就是确保满足里氏替换原则。

    字段决不能是公有的,因为这么做的话就失去了对这个字段修改行为的控制,客户端可以对其随意修改。例如下面的例子中,AccessExample 拥有 id 共有字段,如果在某个时刻,我们想要使用 int 去存储 id 字段,那么就需要去修改所有的客户端代码。

    public class AccessExample {
        public String id;
    }

    可以使用公有的 getter 和 setter 方法来替换公有字段,这样的话就可以控制对字段的修改行为。

    public class AccessExample {
    
        private int id;
    
        public String getId() {
            return id + "";
        }
    
        public void setId(String id) {
            this.id = Integer.valueOf(id);
        }
    }

    但是也有例外,如果是包级私有的类或者私有的嵌套类,那么直接暴露成员不会有特别大的影响。

    public class AccessWithInnerClassExample {
        private class InnerClass {
            int x;
        }
    
        private InnerClass innerClass;
    
        public AccessWithInnerClassExample() {
            innerClass = new InnerClass();
        }
    
        public int getValue() {
            return innerClass.x;  // 直接访问
        }
    }

    抽象类与接口

    1. 抽象类

    抽象类和抽象方法都使用 abstract 关键字进行声明。抽象类一般会包含抽象方法,抽象方法一定位于抽象类中。

    抽象类和普通类最大的区别是,抽象类不能被实例化,需要继承抽象类才能实例化其子类。

    public abstract class AbstractClassExample {
    
        protected int x;
        private int y;
    
        public abstract void func1();
    
        public void func2() {
            System.out.println("func2");
        }
    }
    public class AbstractExtendClassExample extends AbstractClassExample {
        @Override
        public void func1() {
            System.out.println("func1");
        }
    }
    // AbstractClassExample ac1 = new AbstractClassExample(); // 'AbstractClassExample' is abstract; cannot be instantiated
    AbstractClassExample ac2 = new AbstractExtendClassExample();
    ac2.func1();

    2. 接口

    接口是抽象类的延伸,在 Java 8 之前,它可以看成是一个完全抽象的类,也就是说它不能有任何的方法实现。

    从 Java 8 开始,接口也可以拥有默认的方法实现,这是因为不支持默认方法的接口的维护成本太高了。在 Java 8 之前,如果一个接口想要添加新的方法,那么要修改所有实现了该接口的类。

    接口的成员(字段 + 方法)默认都是 public 的,并且不允许定义为 private 或者 protected。

    接口的字段默认都是 static 和 final 的。

    public interface InterfaceExample {
        void func1();
    
        default void func2(){
            System.out.println("func2");
        }
    
        int x = 123;
        // int y;               // Variable 'y' might not have been initialized
        public int z = 0;       // Modifier 'public' is redundant for interface fields
        // private int k = 0;   // Modifier 'private' not allowed here
        // protected int l = 0; // Modifier 'protected' not allowed here
        // private void fun3(); // Modifier 'private' not allowed here
    }
    public class InterfaceImplementExample implements InterfaceExample {
        @Override
        public void func1() {
            System.out.println("func1");
        }
    }
    // InterfaceExample ie1 = new InterfaceExample(); // 'InterfaceExample' is abstract; cannot be instantiated
    InterfaceExample ie2 = new InterfaceImplementExample();
    ie2.func1();
    System.out.println(InterfaceExample.x);

    3. 比较

    • 从设计层面上看,抽象类提供了一种 IS-A 关系,那么就必须满足里式替换原则,即子类对象必须能够替换掉所有父类对象。而接口更像是一种 LIKE-A 关系,它只是提供一种方法实现契约,并不要求接口和实现接口的类具有 IS-A 关系。
    • 从使用上来看,一个类可以实现多个接口,但是不能继承多个抽象类。
    • 接口的字段只能是 static 和 final 类型的,而抽象类的字段没有这种限制。
    • 接口的成员只能是 public 的,而抽象类的成员可以有多种访问权限。

    4. 使用选择

    使用接口:

    • 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法;
    • 需要使用多重继承。

    使用抽象类:

    • 需要在几个相关的类中共享代码。
    • 需要能控制继承来的成员的访问权限,而不是都为 public。
    • 需要继承非静态和非常量字段。

    在很多情况下,接口优先于抽象类,因为接口没有抽象类严格的类层次结构要求,可以灵活地为一个类添加行为。并且从 Java 8 开始,接口也可以有默认的方法实现,使得修改接口的成本也变的很低。

    super

    • 访问父类的构造函数:可以使用 super() 函数访问父类的构造函数,从而委托父类完成一些初始化的工作。
    • 访问父类的成员:如果子类重写了父类的中某个方法的实现,可以通过使用 super 关键字来引用父类的方法实现。
    public class SuperExample {
        protected int x;
        protected int y;
    
        public SuperExample(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        public void func() {
            System.out.println("SuperExample.func()");
        }
    }
    public class SuperExtendExample extends SuperExample {
        private int z;
    
        public SuperExtendExample(int x, int y, int z) {
            super(x, y);
            this.z = z;
        }
    
        @Override
        public void func() {
            super.func();
            System.out.println("SuperExtendExample.func()");
        }
    }
    SuperExample e = new SuperExtendExample(1, 2, 3);
    e.func();
    SuperExample.func()
    SuperExtendExample.func()

    Using the Keyword super

    重写与重载

    1. 重写(Override)

    存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法。

    为了满足里式替换原则,重写有有以下两个限制:

    • 子类方法的访问权限必须大于等于父类方法;
    • 子类方法的返回类型必须是父类方法返回类型或为其子类型。

    使用 @Override 注解,可以让编译器帮忙检查是否满足上面的两个限制条件。

    2. 重载(Overload)

    存在于同一个类中,指一个方法与已经存在的方法名称上相同,但是参数类型、个数、顺序至少有一个不同。

    应该注意的是,返回值不同,其它都相同不算是重载。

    五、Object 通用方法

    概览

    public final native Class<?> getClass()
    
    public native int hashCode()
    
    public boolean equals(Object obj)
    
    protected native Object clone() throws CloneNotSupportedException
    
    public String toString()
    
    public final native void notify()
    
    public final native void notifyAll()
    
    public final native void wait(long timeout) throws InterruptedException
    
    public final void wait(long timeout, int nanos) throws InterruptedException
    
    public final void wait() throws InterruptedException
    
    protected void finalize() throws Throwable {}

    equals()

    1. 等价关系

    (一)自反性

    x.equals(x); // true

    (二)对称性

    x.equals(y) == y.equals(x); // true

    (三)传递性

    if (x.equals(y) && y.equals(z))
        x.equals(z); // true;

    (四)一致性

    多次调用 equals() 方法结果不变

    x.equals(y) == x.equals(y); // true

    (五)与 null 的比较

    对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false

    x.equals(null); // false;

    2. equals() 与 ==

    • 对于基本类型,== 判断两个值是否相等,基本类型没有 equals() 方法。
    • 对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。
    Integer x = new Integer(1);
    Integer y = new Integer(1);
    System.out.println(x.equals(y)); // true
    System.out.println(x == y);      // false

    3. 实现

    • 检查是否为同一个对象的引用,如果是直接返回 true;
    • 检查是否是同一个类型,如果不是,直接返回 false;
    • 将 Object 对象进行转型;
    • 判断每个关键域是否相等。
    public class EqualExample {
        private int x;
        private int y;
        private int z;
    
        public EqualExample(int x, int y, int z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    
            EqualExample that = (EqualExample) o;
    
            if (x != that.x) return false;
            if (y != that.y) return false;
            return z == that.z;
        }
    }

    hashCode()

    hasCode() 返回散列值,而 equals() 是用来判断两个对象是否等价。等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价。

    在覆盖 equals() 方法时应当总是覆盖 hashCode() 方法,保证等价的两个对象散列值也相等。

    下面的代码中,新建了两个等价的对象,并将它们添加到 HashSet 中。我们希望将这两个对象当成一样的,只在集合中添加一个对象,但是因为 EqualExample 没有实现 hasCode() 方法,因此这两个对象的散列值是不同的,最终导致集合添加了两个等价的对象。

    EqualExample e1 = new EqualExample(1, 1, 1);
    EqualExample e2 = new EqualExample(1, 1, 1);
    System.out.println(e1.equals(e2)); // true
    HashSet<EqualExample> set = new HashSet<>();
    set.add(e1);
    set.add(e2);
    System.out.println(set.size());   // 2

    理想的散列函数应当具有均匀性,即不相等的对象应当均匀分布到所有可能的散列值上。这就要求了散列函数要把所有域的值都考虑进来,可以将每个域都当成 R 进制的某一位,然后组成一个 R 进制的整数。R 一般取 31,因为它是一个奇素数,如果是偶数的话,当出现乘法溢出,信息就会丢失,因为与 2 相乘相当于向左移一位。

    一个数与 31 相乘可以转换成移位和减法:31*x == (x<<5)-x,编译器会自动进行这个优化。

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + x;
        result = 31 * result + y;
        result = 31 * result + z;
        return result;
    }

    toString()

    默认返回 ToStringExample@4554617c 这种形式,其中 @ 后面的数值为散列码的无符号十六进制表示。

    public class ToStringExample {
        private int number;
    
        public ToStringExample(int number) {
            this.number = number;
        }
    }
    ToStringExample example = new ToStringExample(123);
    System.out.println(example.toString());
    ToStringExample@4554617c

    clone()

    1. cloneable

    clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。

    public class CloneExample {
        private int a;
        private int b;
    }
    CloneExample e1 = new CloneExample();
    // CloneExample e2 = e1.clone(); // 'clone()' has protected access in 'java.lang.Object'

    重写 clone() 得到以下实现:

    public class CloneExample {
        private int a;
        private int b;
    
        @Override
        protected CloneExample clone() throws CloneNotSupportedException {
            return (CloneExample)super.clone();
        }
    }
    CloneExample e1 = new CloneExample();
    try {
        CloneExample e2 = e1.clone();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    java.lang.CloneNotSupportedException: CloneExample

    以上抛出了 CloneNotSupportedException,这是因为 CloneExample 没有实现 Cloneable 接口。

    应该注意的是,clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一个 protected 方法。Cloneable 接口只是规定,如果一个类没有实现 Cloneable 接口又调用了 clone() 方法,就会抛出 CloneNotSupportedException。

    public class CloneExample implements Cloneable {
        private int a;
        private int b;
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }

    2. 浅拷贝

    拷贝对象和原始对象的引用类型引用同一个对象。

    public class ShallowCloneExample implements Cloneable {
        private int[] arr;
    
        public ShallowCloneExample() {
            arr = new int[10];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = i;
            }
        }
    
        public void set(int index, int value) {
            arr[index] = value;
        }
    
        public int get(int index) {
            return arr[index];
        }
    
        @Override
        protected ShallowCloneExample clone() throws CloneNotSupportedException {
            return (ShallowCloneExample) super.clone();
        }
    }
    ShallowCloneExample e1 = new ShallowCloneExample();
    ShallowCloneExample e2 = null;
    try {
        e2 = e1.clone();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    e1.set(2, 222);
    System.out.println(e2.get(2)); // 222

     3. 深拷贝

    拷贝对象和原始对象的引用类型引用不同对象。

    public class DeepCloneExample implements Cloneable {
        private int[] arr;
    
        public DeepCloneExample() {
            arr = new int[10];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = i;
            }
        }
    
        public void set(int index, int value) {
            arr[index] = value;
        }
    
        public int get(int index) {
            return arr[index];
        }
    
        @Override
        protected DeepCloneExample clone() throws CloneNotSupportedException {
            DeepCloneExample result = (DeepCloneExample) super.clone();
            result.arr = new int[arr.length];
            for (int i = 0; i < arr.length; i++) {
                result.arr[i] = arr[i];
            }
            return result;
        }
    }
    DeepCloneExample e1 = new DeepCloneExample();
    DeepCloneExample e2 = null;
    try {
        e2 = e1.clone();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    e1.set(2, 222);
    System.out.println(e2.get(2)); // 2

     4. clone() 的替代方案

    使用 clone() 方法来拷贝一个对象即复杂又有风险,它会抛出异常,并且还需要类型转换。Effective Java 书上讲到,最好不要去使用 clone(),可以使用拷贝构造函数或者拷贝工厂来拷贝一个对象。

    public class CloneConstructorExample {
        private int[] arr;
    
        public CloneConstructorExample() {
            arr = new int[10];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = i;
            }
        }
    
        public CloneConstructorExample(CloneConstructorExample original) {
            arr = new int[original.arr.length];
            for (int i = 0; i < original.arr.length; i++) {
                arr[i] = original.arr[i];
            }
        }
    
        public void set(int index, int value) {
            arr[index] = value;
        }
    
        public int get(int index) {
            return arr[index];
        }
    }
    CloneConstructorExample e1 = new CloneConstructorExample();
    CloneConstructorExample e2 = new CloneConstructorExample(e1);
    e1.set(2, 222);
    System.out.println(e2.get(2)); // 2

    六、关键字

    final

    1. 数据

    声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量。

    • 对于基本类型,final 使数值不变;
    • 对于引用类型,final 使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。
    final int x = 1;
    // x = 2;  // cannot assign value to final variable 'x'
    final A y = new A();
    y.a = 1;

    2. 方法

    声明方法不能被子类重写。

    private 方法隐式地被指定为 final,如果在子类中定义的方法和基类中的一个 private 方法签名相同,此时子类的方法不是重写基类方法,而是在子类中定义了一个新的方法。

    3. 类

    声明类不允许被继承。

    static

    1. 静态变量

    • 静态变量:又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它;静态变量在内存中只存在一份。
    • 实例变量:每创建一个实例就会产生一个实例变量,它与该实例同生共死。
    public class A {
        private int x;         // 实例变量
        private static int y;  // 静态变量
    
        public static void main(String[] args) {
            // int x = A.x;  // Non-static field 'x' cannot be referenced from a static context
            A a = new A();
            int x = a.x;
            int y = A.y;
        }
    }

    2. 静态方法

    静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法(abstract)。

    public abstract class A {
        public static void func1(){
        }
        // public abstract static void func2();  // Illegal combination of modifiers: 'abstract' and 'static'
    }

    只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字。

    public class A {
        private static int x;
        private int y;
    
        public static void func1(){
            int a = x;
            // int b = y;  // Non-static field 'y' cannot be referenced from a static context
            // int b = this.y;     // 'A.this' cannot be referenced from a static context
        }
    }

    3. 静态语句块

    静态语句块在类初始化时运行一次。

    public class A {
        static {
            System.out.println("123");
        }
    
        public static void main(String[] args) {
            A a1 = new A();
            A a2 = new A();
        }
    }
    123

    4. 静态内部类

    非静态内部类依赖于外部类的实例,而静态内部类不需要。

    public class OuterClass {
        class InnerClass {
        }
    
        static class StaticInnerClass {
        }
    
        public static void main(String[] args) {
            // InnerClass innerClass = new InnerClass(); // 'OuterClass.this' cannot be referenced from a static context
            OuterClass outerClass = new OuterClass();
            InnerClass innerClass = outerClass.new InnerClass();
            StaticInnerClass staticInnerClass = new StaticInnerClass();
        }
    }

    静态内部类不能访问外部类的非静态的变量和方法。

    5. 静态导包

    在使用静态变量和方法时不用再指明 ClassName,从而简化代码,但可读性大大降低。

    import static com.xxx.ClassName.*

    6. 初始化顺序

    静态变量和静态语句块优先于实例变量和普通语句块,静态变量和静态语句块的初始化顺序取决于它们在代码中的顺序。

    public static String staticField = "静态变量";
    static {
        System.out.println("静态语句块");
    }
    public String field = "实例变量";
    {
        System.out.println("普通语句块");
    }

    最后才是构造函数的初始化。

    public InitialOrderTest() {
        System.out.println("构造函数");
    }

    存在继承的情况下,初始化顺序为:

    • 父类(静态变量、静态语句块)
    • 子类(静态变量、静态语句块)
    • 父类(实例变量、普通语句块)
    • 父类(构造函数)
    • 子类(实例变量、普通语句块)
    • 子类(构造函数)

    七、反射

    每个类都有一个 Class 对象,包含了与类有关的信息。当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。

    类加载相当于 Class 对象的加载。类在第一次使用时才动态加载到 JVM 中,可以使用 Class.forName("com.mysql.jdbc.Driver") 这种方式来控制类的加载,该方法会返回一个 Class 对象。

    反射可以提供运行时的类信息,并且这个类可以在运行时才加载进来,甚至在编译时期该类的 .class 不存在也可以加载进来。

    Class 和 java.lang.reflect 一起对反射提供了支持,java.lang.reflect 类库主要包含了以下三个类:

    • Field :可以使用 get() 和 set() 方法读取和修改 Field 对象关联的字段;
    • Method :可以使用 invoke() 方法调用与 Method 对象关联的方法;
    • Constructor :可以用 Constructor 创建新的对象。

    Advantages of Using Reflection:

    • Extensibility Features : An application may make use of external, user-defined classes by creating instances of extensibility objects using their fully-qualified names.
    • Class Browsers and Visual Development Environments : A class browser needs to be able to enumerate the members of classes. Visual development environments can benefit from making use of type information available in reflection to aid the developer in writing correct code.
    • Debuggers and Test Tools : Debuggers need to be able to examine private members on classes. Test harnesses can make use of reflection to systematically call a discoverable set APIs defined on a class, to insure a high level of code coverage in a test suite.

    Drawbacks of Reflection:

    Reflection is powerful, but should not be used indiscriminately. If it is possible to perform an operation without using reflection, then it is preferable to avoid using it. The following concerns should be kept in mind when accessing code via reflection.

    • Performance Overhead : Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.

    • Security Restrictions : Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context, such as in an Applet.

    • Exposure of Internals :Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.

    • Trail: The Reflection API

    • 深入解析 Java 反射(1)- 基础

    八、异常

    Throwable 可以用来表示任何可以作为异常抛出的类,分为两种: Error 和 Exception。其中 Error 用来表示 JVM 无法处理的错误,Exception 分为两种:

    • 受检异常 :需要用 try...catch... 语句捕获并进行处理,并且可以从异常中恢复;
    • 非受检异常 :是程序运行时错误,例如除 0 会引发 Arithmetic Exception,此时程序崩溃并且无法恢复。

     

    九、泛型

    public class Box<T> {
        // T stands for "Type"
        private T t;
        public void set(T t) { this.t = t; }
        public T get() { return t; }
    }

    十、注解

    Java 注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。

    注解 Annotation 实现原理与自定义注解例子

    十一、特性

    Java 各版本的新特性

    New highlights in Java SE 8

    1. Lambda Expressions
    2. Pipelines and Streams
    3. Date and Time API
    4. Default Methods
    5. Type Annotations
    6. Nashhorn JavaScript Engine
    7. Concurrent Accumulators
    8. Parallel operations
    9. PermGen Error Removed

    New highlights in Java SE 7

    1. Strings in Switch Statement
    2. Type Inference for Generic Instance Creation
    3. Multiple Exception Handling
    4. Support for Dynamic Languages
    5. Try with Resources
    6. Java nio Package
    7. Binary Literals, Underscore in literals
    8. Diamond Syntax

    Java 与 C++ 的区别

    • Java 是纯粹的面向对象语言,所有的对象都继承自 java.lang.Object,C++ 为了兼容 C 即支持面向对象也支持面向过程。
    • Java 通过虚拟机从而实现跨平台特性,但是 C++ 依赖于特定的平台。
    • Java 没有指针,它的引用可以理解为安全指针,而 C++ 具有和 C 一样的指针。
    • Java 支持自动垃圾回收,而 C++ 需要手动回收。
    • Java 不支持多重继承,只能通过实现多个接口来达到相同目的,而 C++ 支持多重继承。
    • Java 不支持操作符重载,虽然可以对两个 String 对象支持加法运算,但是这是语言内置支持的操作,不属于操作符重载,而 C++ 可以。
    • Java 的 goto 是保留字,但是不可用,C++ 可以使用 goto。
    • Java 不支持条件编译,C++ 通过 #ifdef #ifndef 等预处理命令从而实现条件编译。

    What are the main differences between Java and C++?

    JRE or JDK

    • JRE is the JVM program, Java application need to run on JRE.
    • JDK is a superset of JRE, JRE + tools for developing java programs. e.g, it provides the compiler "javac"

    参考资料

    • Eckel B. Java 编程思想[M]. 机械工业出版社, 2002.
    • Bloch J. Effective java[M]. Addison-Wesley Professional, 2017.

    我有一个微信公众号,经常会分享一些Java技术相关的干货;如果你喜欢我的分享,可以用微信搜索“Java团长”或者“javatuanzhang”关注。 

    更多相关内容
  • 【绝对干货】java面试笔试题及答案

    千次阅读 2021-07-13 19:07:33
    提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。 备战阿里时我花的最多的时间就是在学习技术上,占了我...

    一面(电话面+后期在线coding)

    ①你们为什么要使用mongdoDb?你们的这个系统中涉及到哪些表?

    ②hytrix 的实现原理是什么?隔离策略有哪些?你们使用的是哪一些?你们项目中哪些地方使用到了,使用场景是什么?为什么要使用?

    ③spirng 源码。

    ④rocketMq 的设计理念,数据存储,设计思想等。

    ⑤ConcurrentHashMap的底层实现原理

    ⑥你线上问题解决经验是什么?遇到了什么问题?应该怎么去解决?

    ⑦在线编码: 两个有序链表,合并成一个链表,然后进行算法的时间复杂度,空间复杂度分析。

    二面(电话面+后期在线coding)

    ①tcp协议和uDP 协议的区别是什么?

    ②3次握手和4次挥手的过程是什么样的?

    ③怎么保证接口的幂等性?

    ④mysql的存储引擎的数据结构是什么?相比其余的数据结构,有什么优缺点?

    ⑤说一下你对SpringCloud,SpringBoot,Spring的理解

    ⑥java 在编译和运行过程中分别作了什么?

    ⑦在线编码: 给定一个字符串,单词之间以空格分隔,要求里面的单词倒装过来。

    三面(电话面,技术交叉面)

    ①介绍一下springCloud 的组件,各组件的作用,你们是怎么用,你的理解是什么?

    ②springCloudbus 关联的消息中间有几种?支持哪几种?你觉的什么场景下,会用到springCLoudBus?

    ③springCloud里面的限流,限流是怎么内部实现的?怎么去挡住多余的请求,怎么实现限流的(线程池的工作原理)?

    ④什么时候该用mongoDB,什么时候使用mysql?该如何选择?

    ⑤你做过的项目数据量有多大呢?如果现在数据量特别大,或者一张表一种放不下了,应该怎么处理?分布分表应该怎么做?具体的某一张表怎么拆?(涉及到主键生成,各种主键生成策略对比,数据分片,以及关联数据的存储,主从复制)

    ⑥java 官方提供的创建的线程池的方式有几种?分别是什么?

    ⑦你们使用的java 版本是什么?java最新的版本是多少?你们为什么还在使用java8呢?

    ⑧你们的垃圾回收器是什么的? 为什么是使用CMS而不是G1? 你能介绍一下像CMS垃圾回收器,从对象创建,内存分配到垃圾回收整个过程吗?

    ⑨介绍一下策略模式,应该怎么用? 它能解决什么问题?从编码领域系统设计方,介绍一下我们怎么去实现一个策略模式?

    学习指南(按照开发经验对程序员进行分层)

    0~1年(搬砖):

    • Java基础(基本语法、面向对象、继承、多态、接口和抽象类、异常、内部类、集合、泛型、反射、I/O等)
    • Web编程(Servlet+MySQL数据库+商品管理系统实战)
    • SSM框架入门到精通(Spring+SpringMVC+Mybatis+SSM商品管理系统实战)
    • SpringBoot(SpringBoot+SpringBoot商品管理系统实战)

    1~3年(技工):

    • JVM深度进阶(JVM内存区域+JVM运行时内存+垃圾回收与算法+JAVA 四种引用类型+GC分代收集算法 VS 分区收集算法+GC垃圾收集器等)
    • 并发编程深度进阶(并发机制的底层实现原理+内存模型+并发编程基础+锁+并发容器和框架+原子类操作+并发工具类+线程池+实战)
    • MySQL深度进阶(Mysq|存储引擎选型及注意事项+解读Mysq|的共享锁及排它锁+分区+事务隔离级别+索引+Sql优化)
    • 数据结构与算法(Java程序员面试必问)

    3~5年(包工头):

    • 分布式消息中间件(Zookpeer+Kafka+MQ+dubbo+SpringCloud等)
    • 数据库(主从复制+读写分离+分库分表)
    • 高效存储(Redis+MongoDB)

    5年以上(设计师):

    • 分布式扩展到微服务(SpringBoot+SpringCloudAlibaba+Docker)
    • SSM框架源码解读(Spring高级源码+SpringMVC源码+Mybatis源码)

    10年以上(送外卖送快递):

    进入饿了么,开始送外卖(开个玩笑)

    难道这样就够了吗?不,远远不够!

    提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

    备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记,以及学习视频都是可以点击这里免费领取的!

    我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

    今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    image.png

    mg-G5KR1HlO-1626174440846)]

    [外链图片转存中…(img-Le3pY2Jp-1626174440847)]

    [外链图片转存中…(img-O3e1kGPt-1626174440848)]

    展开全文
  • 二、回顾整理阿里面试题 基本就这样了,还有一些零星的问题想不起来了,答案也整理出来了。 自我介绍 JVM如何加载一个类的过程,双亲委派模型中有哪些方法? HashMap如何实现的? HashMap和ConcurrentHashMap区别...

    二、回顾整理阿里面试题

    基本就这样了,还有一些零星的问题想不起来了,答案也整理出来了。

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    • 自我介绍
    • JVM如何加载一个类的过程,双亲委派模型中有哪些方法?
    • HashMap如何实现的?
    • HashMap和ConcurrentHashMap区别, Concurrent HashMap 线程安全hashtable吗, ConcurrentHashMap如何保证 线程安全?
    • HashMap和HashTable 区别,HashTable线程安全吗?
    • 进程间通信有哪几种方式
    • JVM分为哪些区,每一个区干吗的?
    • JVM如何GC,新生代,老年代大对象,永久代,都储存哪些东西?
    • GC用的引用可达性分析算法中,哪些对象可作为GCRoots对象?
    • 快速排序,过程,复杂度
    • 什么是二叉平衡树,如何插入节点,删除节点,说出关键步骤。
    • TCP如何保证可靠传输?三次握手过程
    • TCP 和 UDP 的区别
    • 滑动窗口算法?
    • Linux下你常用的命令有哪些
    • 操作系统什么情况下会死锁?
    • 常用的hash算法有哪些
    • 什么是一致性哈希?
    • 如何理解分布式锁?
    • 数据库中的范式有哪些?
    • 数据库中的索引的结构?什么情况下适合建索引?
    • Java中的NIO,BIO,AIO分别是什么?
    • 用什么工具调试程序?JConsole,用过吗?
    • 现在有一个进程挂起了,如何用工具查出原因?
    • 线程同步与阻塞的关系?同步一定阻塞吗?阻塞一定同步吗?
    • 同步和异步有什么区别?
    • 线程池用过吗?
    • 如何创建单例模式?说了双重检查,他说不是线程安全的。如何高效的创建的一个高效的单例?
    • concurrent包下面,都用过什么?
    • 常用的数据库有哪些?redis用过吗?
    • 了解hadoop吗?说说hadoop的组件有哪些?hdfs,hive,hbase,zookeeper。说下mapreduce编程模型。
    • 你知道的开源协议有哪些?
    • 你知道的开源软件有哪些?
    • 你最近在看的书有哪些?
    • 你有什么问题要问我吗?

    啃完这份超全的面试宝典,终获蚂蚁金服offer!

    自从进入阿里工作后,我才感觉到了自己从事这份职业所在的意义,我也庆幸自己没有在受挫的时候放弃这个职业。

    宝典大概分为这几块:

    • Java基础
    • 数据库
    • Java 虚拟机
    • JSP&Servlet
    • spring&Hibernate
    • 操作系统
    • Linux
    • 计算机网络
    • 算法

    Java基础

    1、面对对象和面向过程的区别?用面向过程可以实现面向对象吗?那是不是不能面向对象

    2、static和final的区别和用途

    3、HashMap和Concurrent HashMap区别,Concurrent HashMap线程安全吗,Concurrent HashMap如何保证线程安全

    4、因为别人知道源码怎实现的,故意构造相同的hash的字符串进行攻击,怎么处理,那jdk7怎么办?

    5、Java序列化,如何实现序列化和反序列化,常见的序列化协议有哪些

    6、Java实现多线程的方式及三种方式的区别

    7、线程安全

    8、多线程如何进行信息交互

    9、Java是否有内存泄露和内存溢出

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    数据库

    1、常见的数据库类型有哪些?redis用过吗

    2、数据库中的范式有哪些?

    3、数据库中的索引的结构?什么情况下适合建索引?

    4、脏读、不可重复读和幻读

    6、MyISA和InnDB引擎的区别

    7、数据库ACID

    8、事务隔离级别

    9、数据库中的分页查询语句怎么写?

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    Java虚拟机

    1、JVM垃圾处理方法(标记清除、复制、标记整理)

    2、JVM如何GC,新生代,老年代,持久代,都储存哪些东西,以及各个区的作用?

    3、GC用的引用可达性分析算法中,哪些对象可作为GC Roots对象

    4、什么时候进行MinGC,FulilGc

    5、各个垃圾收集器是怎么工作的

    6、Java虚拟机内存的划分,每个区域的功能

    7、用什么工具可以查出内存泄露

    8、JVM如何加载一个类的过程,双亲委派模型中有哪些方法有没有可能父类加载器,加载同一个类?如果加载同一个类,该使用哪一个类?

    9、Java是如何进行对象实例化的

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    JSP&Servlet

    1、Servlet的生命周期

    2、Jsp和Servlet的区别

    3、保存会话状态,有哪些方式、区别如何

    4、cookie和session的区别

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    spring&Hibernate

    1、spring ioc、AOP的理解以及实现的原理

    2、IOC容器的加载过程

    3、动态代理与cglib实现的区别

    4、代理的实现原理

    5、Hlbernate一级缓存与二级缓存之间的区别

    6、spring mvc的原理

    7、简述Hibernate常见优化策略

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    操作系统

    1、操作系统下生命情况会死锁?

    2、如何理解分布式锁

    3、进程间通信有哪几种方式?

    4、线程同步与阻塞的关系?同步一定要阻塞吗?阻塞一定要同步吗?

    5、操作系统如何进行分页调度?

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    Linux

    1、linux下如何进行进程调度的?

    2、linux下你常用的命令有哪些?

    计算机网络

    1、Http和https的区别

    2、TCP如何保证可靠传输三次握手过程

    3、为什么TCP连接需要三次握手,两次不可以吗,为什么

    4、如果客户端不断的发生请求连接会怎么样?

    5、GET和POST的区别

    6、TCP和UDP区别如何改进TCP

    7、从输入网址到获得页面的过程

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    算法

    1、如何判断一个单链表是否有环?

    2、快速排序,过程,复杂度?什么情况下适用,什么情况下不适用?

    3、什么是二叉平衡树,如何插入节点,删除节点

    5、二分搜索的过程

    6、归并排序的过程?时间复杂度空间复杂度?

    7、给你一万个数,如何找出里面所有重复的数?用所有你能想到的办法,时间复杂度和空间复杂度分别是多少?

    8、给你一个数组,如何里面找到和为k的两个数

    9、100000个数找出最小或最大的10个?

    image.png

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    三、难道这样就够了吗?不,远远不够!

    提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

    备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记,以及学习视频都是可以分享给大家的!

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

    image.png

    最后总结

    搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析,以及算法刷题LeetCode中文版的小伙伴们可以点赞后点击这里即可免费获取!

    最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化

    image

    面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析,以及算法刷题LeetCode中文版的小伙伴们可以点赞后点击这里即可免费获取!

    最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化

    [外链图片转存中…(img-sUuFMuDs-1624867233986)]

    展开全文
  • 这就是这篇文章的目的,**帮你搜集了大量的面试题,已经整理成了一个Java面试手册PDF,《互联网面试2400页》,目前有65份PDF,共有2400多页,**后续还会不断的完善更新。 直接进入正题,由于pdf文档里的细节内容...

    前言

    最其实不管什么时候,找工作都跑不了面试。目前很多小编都做了面试手册了,那就是别人家的孩子都有糖了,作为一个自觉的小编,必须搞。

    容我先絮叨一下,制作这个面试手册差不多花了3个多星期时间,过程还是比较磨人的,但是也很期待。要是因为我做的手册,帮助到了大家,那就真的开心啊!这就是这篇文章的目的,**帮你搜集了大量的面试题,已经整理成了一个Java面试手册PDF,《互联网面试2400页》,目前有65份PDF,共有2400多页,**后续还会不断的完善更新。

    直接进入正题,由于pdf文档里的细节内容实在过多所以只编辑了部分知识点的章节粗略的介绍下,每个章节小节点里面都有更细化的内容!

    题库非常全面

    包括 Java 集合、JVM、多线程、并发编程、设计模式、Spring全家桶、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat等大厂面试题等、等技术栈!

    应聘求职

    每年这个时候,都是应届生求职以及在职人员跳槽的高峰期。对于即将成为程序员的应届毕业生们。在求职过程中怎样确定目标公司和目标职位,大家在求职过程中要注意哪些细节?这些都是大家所关心的话题。

    ①应聘渠道:

    ⑴学校招聘会;

    ⑵社会招聘渠道:Boss,企业官网等等。

    ②应聘流程:

    编写简历→投递简历→筛选简历→电话面试→(笔试)→面试→确定薪酬→入职→后续流程

    简历书写

    据统计,80%的简历都是不合格的。不少人事管理者抱怨收到的许多简历在格式上很精权。简历应该如何做到在格式上简洁明了,重点突出?求职信应该如何有足够的内容推销自己?如何控制长度,言简意赅?相信读了本章,你会对简历的撰写有一个新的认识。

    ①简历注意事项:

    ⑴实事求是;

    ⑵注意内容长短,排版;

    ⑶千万不可只准备一份简历。每一家公司的要求是不同的,职位的要求也是不一样的,除了一些必须包含的信息以外,应该针对不同的职位准备不同的简历,去掉每个职位不需要的信息,而突出需要的信息。

    ②简历模板:

    Java基础知识

    ①Java程序员知识:

    ②Java语法基础:

    ③数据类型以及类型转换:

    ④数组和集合的使用:

    ⑤Java图形用户界面:

    Java高级特性

    ①输入输出流:

    ②多线程编程:

    ③Java反射机制:

    ④Java网络编程:

    ⑤Java对数据库的操作:

    JavaEE相关问题

    ①Web开发相关技术:

    ②Struts、Spring、Hibernate组合:

    ③EJB与JPA相关问题:

    算法与设计模式

    ①Java编程试题:

    总目录展示

    该笔记共八个节点(由浅入深),分为三大模块。

    高性能。 秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键。该笔记将从设计数据的动静分离方案、热点的发现与隔离、请求的削峰与分层过滤、服务端的极致优化这4个方面重点介绍。

    一致性。 秒杀中商品减库存的实现方式同样关键。可想而知,有限数量的商品在同一时刻被很多倍的请求同时来减库存,减库存又分为“拍下减库存”“付款减库存”以及预扣等几种,在大并发更新的过程中都要保证数据的准确性,其难度可想而知。因此,将用一个节点来专门讲解如何设计秒杀减库存方案。

    高可用。 虽然介绍了很多极致的优化思路,但现实中总难免出现一些我们考虑不到的情况,所以要保证系统的高可用和正确性,还要设计一个PlanB来兜底,以便在最坏情况发生时仍然能够从容应对。笔记的最后,将带你思考可以从哪些环节来设计兜底方案。


    篇幅有限,无法一个模块一个模块详细的展示(这些要点都收集在了这份《高并发秒杀顶级教程》里),觉得有需要的码友们,麻烦各位转发一下(可以帮助更多的人看到哟!)点这里,即可获得免费下载的方式!!

    由于内容太多,这里只截取部分的内容。需要这份《高并发秒杀顶级教程》的小伙伴,麻烦各位帮忙点赞分享支持一下(可以帮助更多的人看到哟!)
    img-W1PaK6ZL-1624435701201)]

    [外链图片转存中…(img-5N9z05p4-1624435701202)]

    由于内容太多,这里只截取部分的内容。需要这份《高并发秒杀顶级教程》的小伙伴,麻烦各位帮忙点赞分享支持一下(可以帮助更多的人看到哟!)

    展开全文
  • Java面试笔试题大汇总(最全+详细答案) Java面试笔试题大汇总(最全+详细答案)
  • Java高频面试题笔记

    2019-11-20 20:38:52
    额,java学校的课刚结课,发现我啥也不会,正好,学习一下java面试常考题,然后写了一部分笔记 不是很全,但是我自己看记录一下吧 ...
  • Java面试题内容聚合

    万次阅读 多人点赞 2019-07-31 11:45:18
    这是一份常见Java面试题分类汇总,希望对大家有用! 初级面试题 Java面试题-基础篇一 Java面试题-基础篇二 Java面试题-集合框架篇三 Java面试题-基础篇四 Java面试题-基础篇五 Java面试题-javaweb篇六 ...
  • 二、我们先来看看这份笔记到底有什么 1、先把kubernetes跑起来(先跑起来+创建kubernetes集群+部署应用+访问应用+Scale应用+滚动更新) 2、重要概念 3、部署kubernetes Cluster(安装docker+安装 kubelet.kubeadm...
  • java常用算法面试题,总结到位

    千次阅读 2021-06-29 14:02:00
    01 MySQL相关 1.1 面试问题 MySQL有哪些锁? 解释一下ACID都是什么 Innodb中索引的实现 B+树 AUTO_INCREMENT原理(考察...1.2 我的MySQL学习笔记 (1)20个高频MySQL面试知识点 事务四大特性(ACID)原子性、一致性、
  • Java面试题以及答案(小生).pdf java面试题(题库全).doc JS 数据库答案.doc Land.the.Tech.Job.You.Love-人人都有好工作—IT行业求职面试必读.pdf Linux命令大全完整版.doc sql查询语句练习.doc Web服务器的工作...
  • java面试题大全

    万次阅读 多人点赞 2018-02-05 17:55:40
    过完年,又有大批人要换工作了,这里整理了很全的java面试笔试题,希望对大家有所帮助! 面试题部分! SSH框架面试题集锦 ...Java面试题-基础篇一 ...Java面试题-基础篇二 ...Java面试题-集合框架篇三
  • 学习完java之后,大家肯定是要出去找java相关的工作的,并且找工作都要面试,为了能够在面试中显示出自己的能力,很多小伙伴都想知道java面试题怎么记?那么接下来,我们就来给大家讲解一下这方面的内容。其实面试题...
  • java笔试题 WexNote Notes for learning 图床已经全部更新完毕 希望各位朋友们如果觉得还不错就给我点个星或者分享给其他朋友,一起学习 如果我里面有哪些方面有问题或者缺漏的话,请大家在issue中提出,也方便我...
  • 对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一。因为并发编程是Java语言中最为晦涩的知识点,它涉及操作系统、内存、CPU、编程语言等多方面的基础能力,更为考验一个程序员的内功。 ...
  • 单例模式 饿汉式:在类初始化时直接创建实例对象,不管你是否需要这个对象,都会创建。 没有线程安全问题 实现步骤: 私有化构造器 自行创建,并且用静态变量保存 向外提供这个实例 强调这是一个单例,我们可以...
  • 2018年最新Java面试题及答案整理

    万次阅读 多人点赞 2018-05-09 10:40:33
    下列面试题都是在网上收集的,本人抱着学习的态度找了下参考答案,有不足的地方还请指正,更多精彩内容可以关注我的微信公众号:Java团长 基础篇 基本功 面向对象特征 封装,继承,多态和抽象 封装 封装给...
  • Java面试题以及答案(小生).pdf java面试题(题库全).doc JS 数据库答案.doc Land.the.Tech.Job.You.Love-人人都有好工作—IT行业求职面试必读.pdf Linux命令大全完整版.doc sql查询语句练习.doc Web服务器的工作...
  • RabbitMQ应用与面试 《一线大厂Java面试真题解析+Java核心总结学习笔记+最新全套讲解视频+实战项目源码》开源 Java优秀开源项目: ali1024.coding.net/public/P7/Java/git github.com/spring-projects 最后 毕竟...
  • 这篇文章主要介绍了26道Spring经典面试题总结(附带答案)的相关资料,小编在网上看到的觉得挺不错的,现在分享给大家,希望对你们有所帮助。 另外本人整理收藏了多家公司面试知识点整理 ,以及各种Java核心知识点免费...
  • Java基础核心笔记总结 由于篇幅限制,我就只以截图展示目录内容以及部分笔记内容,获取完整版王者级核心宝典只需要点击点赞+关注即可获取领取方式! 在这个部分我们总结了Java的基础知识,涵盖了:概述、开发环境...
  • 然后这位同学把整理的笔记放到了github上,并且加入了自己平时积累的很多面试题。 现在那个项目已经有10000+的star,成为了GitHub上一个热门的Java相关的项目。 下面是面试题内容的部分截图展示: 这位同学对每个...
  • Java面试题总结 - Java集合篇(附答案)

    千次阅读 多人点赞 2021-05-29 20:25:21
    第二章 Java集合 一、Java容器都有哪些? 1、Collection (1)set HashSet、TreeSet (2)list ArrayList、LinkedList、Vector 2、Map HashMap、HashTable、TreeMap 二、Collection 和 Collections 有什么...
  • Java面试题-基础篇四

    千次阅读 2018-03-19 19:14:25
    31、String s = new String("xyz");创建了几个StringObject?是否可以继承String类?  两个或一个都有可能,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管...Java中高级面试题部分答案解析(4)
  • 面试题包含了不同技术层面的面试问题,同时也能对一些没有面试开发经验的小白给予不可估量的包装, 让你的薪水绝对翻倍, 本人亲试有效.Java面试题84集、java面试专属及面试必问课程,所有的面试题有视屏讲解, 解答方案....
  • 挑战10个最难回答的Java面试题(附答案)

    万次阅读 多人点赞 2019-08-12 10:28:36
    译者:Yujiaao ...2.面试题内容聚合 3.设计模式内容聚合 4.Mybatis内容聚合 5.多线程内容聚合 这是我收集的10个最棘手的Java面试问题列表。这些问题主要来自 Java 核心部分 ,不涉及 Java EE 相关问题。...
  • 像阿里巴巴,亚马逊,谷歌,微软等在内的所有科技巨头对Spring都有很大的贡献,因此Spring经常在大厂面试的时候被问到,下面我选了几道关于pring源码的面试题,看大家能不能回答出来: IOC源码主要流程 bean相互...
  • 2022届校招Java面试题汇总(含题解)

    千次阅读 2021-08-23 17:20:21
    本文将笔者在面试中遇到的真实题目汇总成集,初衷是为了每次面试完能够及时复盘,以便查漏补缺。此外,如果能给他人以参考也是好的。
  • 恒生电子JAVA笔试试题 #《Thinking In Java》学习笔记 [TOC] 阅读计划 章节列表 对象导论 一切都是对象 操作符 控制执行流程 初始化与清理 访问权限控制 复用类 多态 接口 内部类 持有对象 通过异常处理错误 字符串 ...
  • public boolean equals(Object obj) { return (this == obj); }

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 68,659
精华内容 27,463
关键字:

java面试题笔记

java 订阅