Java Road to God: Java Interview Preparation (10)

6, IO style

6.1 What is serialization and how to achieve serialization

Serialization is a mechanism for processing object streams. The so-called object stream is to stream the content of the object. The streamed objects can be transmitted between networks, and serialization is to solve the problems caused by the read and write operations of the object stream.

Serialization implementation: implement the Serializable interface for the class that needs to be serialized

7. Network programming

8. Exception handling

8.1 How to customize exceptions in Java

Inherit the Exception class

//或者继承RuntimeException(运行时异常) 
public class MyException extends Exception {
    
     
 
  private static final long serialVersionUID = 1L; 
 
  // 提供无参数的构造方法
  public MyException() {
    
     
  } 
 
  // 提供一个有参数的构造方法,可自动生成
  public MyException(String message) {
    
     
    super(message);// 把参数传递给Throwable的带String参数的构造方法 
  } 
 
} 

8.2 What are the two types of exceptions in Java? What's the difference between them

There are two kinds of exceptions in Java, which are checked exceptions and unchecked exceptions, which are also called compiled exceptions and runtime exceptions.

Checked exception (compilation exception): This exception needs to be declared on a method or class using the throws statement, or caught using try...catch. Generally, a smart compiler like IDEA can detect it directly

Unchecked exceptions (runtime exceptions): exceptions that occur after the program runs, such as array subscript out of bounds, OOM, etc.

8.3 What is the difference between Exception and Error in Java

Both Exception and Error are subclasses of Throwable.

Exception is an unexpected situation that can be expected in the normal operation of the program, and can be dealt with accordingly

Error causes the program to be in an abnormal and unrecoverable state

8.4 What is the difference between throw and throws

throw:

1. Act on the method, which means that a specific exception is thrown, which is handled by the statement in the method body

2. The action that is specifically thrown out, so what it throws is an abnormal entity class. If throw is executed, some kind of exception must be thrown

throws:

1. Act on the declaration of the method, which means that if an exception is thrown, the caller of the method will handle the exception

2. The main purpose is to declare that this method will throw a certain type of exception, so that the user knows the type of exception

3. Abnormality is a possibility, and it does not necessarily happen

9. Classes and objects

9.1 The relationship between classes and objects

A class is an abstraction of an object, and an object is a concrete instance of the class. Classes are abstract and do not take up memory, while objects are concrete and take up storage space. A class is a blueprint for creating objects. It is a software template that defines methods and variables included in a specific type of object.

Classes and objects are like the relationship between drawings and objects, and the relationship between molds and castings.

9.2 The difference between process-oriented and object-oriented

Both are software development ideas, first process-oriented, then object-oriented. In large-scale projects, object-oriented development ideas are introduced to address the process-oriented shortcomings

metaphor

Process-oriented is egg fried rice, and object-oriented is rice topped. The advantage of rice bowls is that the "dish" and "rice" are separated, which improves the flexibility of making rice bowls. If you are not satisfied with the meal, change the meal, and if you are not satisfied, change the meal. The terminology of software engineering is that "maintainability" is better, and the degree of coupling between "fan" and "cai" is relatively low.

the difference

Different programming ideas: Process-oriented focuses on the development of functions that realize functions, while object-oriented first abstracts classes, attributes and methods, and then completes functions by instantiating classes and executing methods.

Encapsulation: All have encapsulation, but process-oriented encapsulation is function, while object-oriented encapsulation is data and function.

Object-oriented has inheritance and polymorphism, while process-oriented has no inheritance and polymorphism, so the advantage of object-oriented is obvious.

9.3 What are the characteristics of object-oriented? Please use examples in life to describe

Three characteristics of object-oriented: encapsulation, inheritance, and polymorphism.

Abstraction : Abstraction is the process of constructing a class by summarizing the common characteristics of a class of objects, including data abstraction and behavior abstraction. Abstraction only pays attention to the properties and behaviors of the object, and does not pay attention to the details of these behaviors

Encapsulation : It is generally considered that encapsulation is to bind data and methods of manipulating data, and access to data can only be through a defined interface. The essence of object-oriented is to portray the real world as a series of completely autonomous and closed objects. The method we write in the class is a kind of encapsulation of implementation details; we write a class is the encapsulation of data and data operations. It can be said that encapsulation is to hide everything that can be hidden, and only provide the simplest programming interface to the outside world

Watching TV in life, LCD TV is very thin, but the structure inside is very complicated. As users, we only need to know how to use it.

Inheritance : Inheritance is the process of obtaining inheritance information from an existing class to create a new class. The class that provides inheritance information is called the parent class (superclass, base class); the class that gets the inheritance information is called the subclass (derived class). Inheritance allows the changing software system to have a certain continuity, and inheritance is also an important means of encapsulating variable factors in the program

Polymorphism : polymorphism refers to allow objects of different sub-types respond differently to the same message. Simply put, it calls the same method with the same object reference but does different things. Polymorphism is divided into compile-time polymorphism and runtime polymorphism. If the method of an object is regarded as a service provided by the object to the outside world, then the runtime polymorphism can be explained as: when system A accesses the service provided by system B, system B has multiple ways to provide services, but everything is right for A The system is transparent (just like the electric shaver is A system, its power supply system is B system, B system can use battery power or AC power, or even solar energy, A system will only pass B type The object invokes the method of power supply, but does not know what the underlying implementation of the power supply system is and how it gained power). Method overload (overload) achieves compile-time polymorphism (also known as pre-binding), and method override (override) achieves runtime polymorphism (also known as post-binding). Run-time polymorphism is the essence of object-oriented. To achieve polymorphism, two things need to be done: 1. Method rewriting (the subclass inherits the parent class and rewrites the existing or abstract methods in the parent class); . Object modeling (using the parent type to refer to the subtype object, so that the same reference calling the same method will show different behaviors according to the subtype object).

9.4 What is the difference between a static inner class and an inner class

Static inner classes do not need to have references to outer classes. But the non-static inner class needs to hold a reference to the outer class.

Static inner classes can have static members (methods, properties), while non-static inner classes cannot have static members (methods, properties).

Non-static inner classes can access the static and non-static members of the outer class. The static inner class cannot access the non-static members of the outer class, but can only access the static members of the outer class.

The instantiation method is different:

  1. Static inner class: does not depend on the instance of the outer class, directly instantiates the inner class object

  2. Non-static inner class: generate inner class objects through object instances of outer classes

9.5 The order of class loading and polymorphic calls

public class ClassLoadTest {
    
    
    public static void main(String[] args) {
    
    
        A a=new B();
        System.out.println(a.x);

    }
}

class A{
    
    
     int x=5;

    static {
    
    
        System.out.println("static A");
    }

    {
    
    
        System.out.println("AAAAAAAAAAAAAAA");
    }

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

}

class B extends A{
    
    
     int x=10;

    static {
    
    
        System.out.println("static B");
    }

    {
    
    
        System.out.println("BBBBBBBBBBBB");
    }

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

}

9.6 Do you know the bytecode? What are the bytecodes? Integer x=5,int y=5, what steps have been taken to compare x==y

1. The execution of bytecode is carried out on the stack.

2. Through the compiler in the JDK, use the javac (java Compiler) command to compile the source code into a bytecode file (.class) for use by the JVM; then load the bytecode through the classLoader class loader; java source code --> compile Into .class bytecode --> CL load bytecode --> bytecode verifier --> bytecode interpreter --> hardware

3. What are the bytecode instructions: monitorenter instruction, monitorexit instruction: lock and unlock at the corresponding position of the bytecode;
iadd/ ladd/ fadd/ dadd instruction: addition of int/long/float/double, pop the top two numbers on the stack , After the sum is pushed onto the top of the stack; sub: subtraction
load instruction: load local variables into the stack; store instruction: save the data in the stack to the local variable table
new instruction: create an object; dup instruction: copy the stack of the top operand value

4. The application of bytecode enhancement technology in spring AOP, ORM framework, and hot deployment. // todo

From the perspective of bytecode, int y=5 is simply pressed into an int type variable and assigned a value of 5, while Integer x=5 will call the Integer.valueOf() method. x==y will use the if_icmp instruction to compare.

9.7 Talk about the class loading mechanism, which class loaders are there, and which files are loaded by these class loaders

When our Java code is compiled, the corresponding class file will be generated. Then when we ran the java Demo command, we actually started the JVM virtual machine to execute the contents of the class bytecode file. The JVM virtual machine's process of executing class bytecode can be divided into seven stages: loading, verifying, preparing, parsing, initializing, using, and unloading.

Classification of class loaders

  • The first one: startup class/boot class: Bootstrap ClassLoader is
    implemented in C/C++ language, nested inside the JVM, java programs cannot directly manipulate this class.
    It is used to load Java core class libraries, such as: JAVA_HOME/jre/lib/rt.jar, resources.jar, packages under the sun.boot.class.path path, and is used to provide packages required for jvm operation.

It is not inherited from java.lang.ClassLoader, it has no parent class loader

It loads the extension class loader and application class loader, and becomes their parent class loader

For safety reasons, the startup class only loads the classes starting with the package name: java, javax, sun

  • The second one: Extension ClassLoader: Extension ClassLoader
    written in Java language, implemented by sun.misc.Launcher$ExtClassLoader, we can use Java program to operate this loader
    derived from java.lang.ClassLoader, the parent class loader is the startup class Loader

Load the class library from the system property: java.ext.dirs directory, or load the class library from the JDK installation directory: jre/lib/ext directory. We can put our own package in the above directory and it will be automatically loaded.

  • The third: Application Classloader: Application Classloader
    written in Java language, implemented by sun.misc.Launcher$AppClassLoader.
    Derived and inherited from java.lang.ClassLoader, the parent class loader is the startup class loader

It is responsible for loading the class library under the path specified by the environment variable classpath or the system property java.class.path

It is the default class loader in the program, and the classes in our Java program are all loaded by it.

We can get and operate this loader through ClassLoader#getSystemClassLoader()

  • Fourth: custom loader.
    Under normal circumstances, the above three loader can satisfy our daily development work. When we are not satisfied, we can also customize the loader,
    such as using the network to load Java classes, in order to ensure the safety of transmission. , Using encryption operation, then the above three loaders can not load this class, this time you need to customize the loader

9.8 Demo of Handwriting Class Loading

To implement your own class loader, you only need to inherit the ClassLoader class. And we want to break the parental delegation rules, then we must rewrite the loadClass method, because by default the loadClass method follows the parental delegation rules.

public class CustomClassLoader extends ClassLoader{

    private static final String CLASS_FILE_SUFFIX = ".class";

    //AppClassLoader的父类加载器
    private ClassLoader extClassLoader;

    public CustomClassLoader(){
        ClassLoader j = String.class.getClassLoader();
        if (j == null) {
            j = getSystemClassLoader();
            while (j.getParent() != null) {
                j = j.getParent();
            }
        }
        this.extClassLoader = j ;
    }

    protected Class<?> loadClass(String name, boolean resolve){

        Class cls = null;
        cls = findLoadedClass(name);
        if (cls != null){
            return cls;
        }
        //获取ExtClassLoader
        ClassLoader extClassLoader = getExtClassLoader() ;
        //确保自定义的类不会覆盖Java的核心类
        try {
            cls = extClassLoader.loadClass(name);
            if (cls != null){
                return cls;
            }
        }catch (ClassNotFoundException e ){

        }
        cls = findClass(name);
        return cls;
    }

    @Override
    public Class<?> findClass(String name) {
        byte[] bt = loadClassData(name);
        return defineClass(name, bt, 0, bt.length);
    }

    private byte[] loadClassData(String className) {
        // 读取Class文件呢
        InputStream is = getClass().getClassLoader().getResourceAsStream(className.replace(".", "/")+CLASS_FILE_SUFFIX);
        ByteArrayOutputStream byteSt = new ByteArrayOutputStream();
        // 写入byteStream
        int len =0;
        try {
            while((len=is.read())!=-1){
                byteSt.write(len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 转换为数组
        return byteSt.toByteArray();
    }

    public ClassLoader getExtClassLoader(){
        return extClassLoader;
    }
}


9.9 How are objects stored in java

In Java, all objects are dynamically allocated on the heap. This is different from C++. C++ objects are either allocated on the stack or on the heap. In C++, we use new() to allocate an object, this object will be allocated on the heap, if it is not global or static, then it will be allocated on the stack.

In Java, only when we declare a type variable, we only create a reference (memory will not be allocated for the object). In order to allocate memory for an object, we must use new(). So the object is always allocated on the heap.

9.10 What's in the object header information

Due to the object-oriented idea of ​​Java, a large number of storage objects are required in the JVM. In order to implement some additional functions during storage, some mark fields need to be added to the objects to enhance the object functions. These mark fields constitute the object header.

1.1. Ordinary objects

|--------------------------------------------------------------|
|                     Object Header (64 bits)                  |
|------------------------------------|-------------------------|
|        Mark Word (32 bits)         |    Klass Word (32 bits) |
|------------------------------------|-------------------------|

1.2. Array Object

|---------------------------------------------------------------------------------|
|                                 Object Header (96 bits)                         |
|--------------------------------|-----------------------|------------------------|
|        Mark Word(32bits)       |    Klass Word(32bits) |  array length(32bits)  |
|--------------------------------|-----------------------|------------------------|

Guess you like

Origin blog.csdn.net/weixin_54707168/article/details/113975540
Recommended