Java Foundation + Collections + Multithreading +JVM

1.1 Java based

1.1.1 Three Features of the Java language

Encapsulation: Abstract data types encapsulate data and data-based operations together as an indivisible and separate entity. Data is protected inside an abstract data type, hiding as much of the internal details as possible, and keeping only some external interfaces to communicate with the outside world.

Inheritance: The technique of using the definition of an existing class as a base to create a new class. The definition of a new class can add new data or new functions, or use the functions of the parent class, but cannot selectively inherit from the parent class. By using inheritance, we can easily reuse previous code, which can greatly improve the efficiency of development.

Polymorphisms: Which class instance objects a reference variable refers to, and which class implements the method calls made by the reference variable, must be determined during program execution.

1.1.2 Object-oriented and procedural

Process-oriented focuses on each step and sequence, object-oriented focuses on participants, and what does each participant need to do

1.1.3 Eight basic data types

type The number of bytes
boolean ?
byte 1
char 2
short 2
int 4
long 8
float 4
double 8

1.1.3.1 Packaging classes and basic data types

  1. At the beginning of the assignment, the data type is basically 0 and the wrapper class is NULL
  2. The eight basic data types are not objects, and the wrapper classes are
  3. Different storage locations
  4. The wrapper class has a constant pool int that buffers data from -128 to 127

  1. Anyway, Integer and new Integer are not equal. New objects are stored in the heap, while Integer constants that are not new are stored in the constant pool (in the method area). They have different memory addresses, so they are false.
  2. Both integers are non-new, true if the number is between -128 and 127, false otherwise. Integer i2 = integer.valueof (128); The valueOf() function caches numbers between -128 and 127.
  3. Both of them come out of new. Both of them are false. Again, the memory address is different.
  4. Int is true when compared to Integer(whether new or not) because Integer is automatically unboxed into int.

1.1.4 Overloading and overriding

  1. Overloading is the same method that can do different things depending on the input data

  2. Overrides are when a subclass inherits the same method from the parent class, with the same input data, but to make a different response from the parent class, you override the parent class method

    Difference: Overloading occurs at compile time and overwriting occurs at run time

1.1.5 Sting type

1.1.4.1 String, StringBuffer, StringBuilder

2. StringBuilder and StringBuffer are both char[] but not finalCopy the code

1.1.4.2 Thread Safety Problem

String objects are immutable, and each modification creates a new String, so it’s thread-safe

StringBuilder threads are not safe

StringBuffer thread safety ===== the source code is modified with Synchronized

1.1.4.3 hashcode String

The method of calculating hashCode in the String class is relatively simple, which is to calculate the ASCII value of each character with the weight of 31, and use natural overflow to equivalent modulus. The hashing formula can be calculated as s[0]*31^(n-1) + S [1]*31^(n-2) +... + s[n-1] + s[n-1] + s[n-1] + s[n-1Copy the code

1.1.4.4 String stitching Problem. Procedure

reference

1. String The String is allocated in memory
	String s1 = new String("Hello world");
        String s2 = "Hello world";
        System.out.println(s1 == s2);  //false
        System.out.println(s1.equals(s2)); //true
Copy the code

In JDK1.8, the string constant pool is in the heap, and the runtime constant pool is in the original space.

2. String constant concatenation
String str3 = "Hello"+" word";
String str4 = "Hello word";
System.out.println(str3 == str4); //true
Copy the code

Here is an example of string constant concatenation: at compile time, the JVM compiler optimizes the string and STR3 is optimized to “Hello Word”. Str3 and STR4 refer to the same string constant pool, so the == comparison is true

String constants + string variables, concatenation between string variables
                String str5 = "Hello";
		String str6 = " word";
		String str7 = "Hello word";
		String str8 = str5+" word";
		System.out.println(str7 == str8);  //false

Copy the code

When a String concatenates a String with a + sign, if a String variable is involved, the underlying implementation is actually passed to the Append () method of StringBuilder as follows

                StringBuilder sb = new StringBuilder( );
		sb.append(str5);
		sb.append(" word");
		str8 = sb.toString();

Copy the code

The toString() method of StringBuilder creates a new String underneath, so str8 reopens the heap, and str7 points to the constant pool, so str7 == str8 is false. Variable string concatenation and constant string concatenation have different results. Because variable string concatenation is space first, and then concatenation.

1.1.6 Interfaces and Abstract Classes

  1. An interface cannot have any variable other than static or final, whereas an abstract class may not
  2. A class can implement multiple interfaces, but only one abstract class. The interface itself can extend multiple interfaces through the extends keyword.
  3. The default modifier for interface methods is public, and abstract methods can have public, protected, and default modifiers. (Abstract methods cannot use the private keyword because they are intended to be overridden!)
  4. From the design level, abstraction is the abstraction of class, is a kind of template design, and interface is the abstraction of behavior, is a kind of behavior specification.

1.1.7 Final Keyword

The final keyword is used in three main places: variables, methods, and classes.

  1. For a final variable, if it is of a primitive data type, its value cannot be changed once initialized; If a variable is a reference type, it cannot be made to point to another object after it is initialized.

  2. When you modify a class with final, it indicates that the class cannot be inherited. All member methods ina final class are implicitly specified as final methods.

  3. There are two reasons to use the final method. The first reason is to lock the method in case any inherited classes change its meaning.

    The second reason is efficiency. In earlier Versions of Java implementations, final methods were converted to inline calls. But if the method is too large, you may not see any performance gains from inline calls (these optimizations with final methods are no longer required in current Java versions). All private methods ina class are implicitly specified as final

1.2 the JVM

1.2.1 Why compilation and interpretation coexist

Why interpretation and compilation coexist: Hot code introduces a JIT compiler, which is runtime compilation. When the JIT compiler completes the first compilation, it saves the machine code corresponding to the bytecode for direct use next time. And we know that machine code is certainly more efficient than Java interpreters. This also explains why we often talk about Java as a compilation and interpretation language

Compilation in Java: Java files are compiled by Javac into.class files, introducing hot code, using a JIT compiler (with two dots!!)

Interpretation in Java: Interpreted by the JVM into machine-executable binaries

1.2.2 Object Structure

Remember the object header: Mark Word Klass Word array length

1.2.3 Memory model

Vm stack error: StackOverFlowError, OutOfMemoryError

Local method stack error: StackOverFlowError, OutOfMemoryError

OutOfMemoryError: Heap Space OutOfMemoryError: GC Overhead Limit Error

Each thread corresponds to a virtual machine stack, and each virtual machine stack corresponds to multiple stack frames. In each stack frame, there are local variable tables, operation on the stack, dynamic links, and return addresses

1.2.4 Process of class loading

  1. Loading:

    1. During the load phase, the virtual machine needs to do the following three things:
      • Gets the binary byte stream that defines a class by its fully qualified name
      • Transform the static storage structure represented by this byte stream into the runtime data structure of the method area.
      • Generate a java.lang.Class object in memory that represents the Class and acts as an access point for the Class’s various data in the method area.
  2. Connection stage:

    1. Verification: Ensures that the loaded classes are correct and that the byte stream of the Class file contains information that meets the requirements of the current VIRTUAL machine and does not compromise the security of the virtual machine. File validation, metadata validation, bytecode validation, symbol reference validation

    2. Preparation: Allocates memory for static variables of the class and assigns them default values

      1. Only static variables that are static are allocated and assigned default values (such as 0, 0L, NULL, false, etc.).

      2. Final static literal constants are assigned initial values directly (initial values are not assigned default values; if they are not literal static constants, they are assigned default values just like static variables

    3. Resolution:

      1. The process of replacing symbolic references in a constant pool with direct references (memory addresses) (in this case static resolution)

      2. A symbolic reference is a set of symbols that describe a target, which can be any literal. Concepts that are part of compilation principles include fully qualified names including classes and interfaces, field names and descriptors, and method names and descriptors.

  3. Initialization: Assigns initial values to static variables of a class

    There are two ways to assign an initial value:

    • Specify an initial value when defining a static variable. Private static String x=”123″;
    • Assign values to static variables in static code blocks. Such as the static {x = “123”; }

JVM related materials

(Early binding and late binding)

Static linking When a bytecode file is loaded into the JVM, if the target method being called is known at compile time and the runtime remains the same. The process of converting a symbolic reference to a calling method in this case into a direct reference is called static chaining.

Dynamic linking If the invoked method cannot be determined at compile time, that is to say, the symbolic reference of the invoked method can only be converted into a direct reference during the program run time. Because this reference conversion process is dynamic, it is also called dynamic linking. (polymorphism)

Symbolic references and direct references


1. Symbolic References:

A symbolic reference is a set of symbols that describe the referenced object. The symbol can be any literal, as long as it is used unambiguously to locate the object. For example, it appears in Class files as constants of the types CONSTANT_Class_info, CONSTANT_Fieldref_info, CONSTANT_Methodref_info, etc. Symbolic references are independent of the memory layout of the virtual machine, and the target of the reference is not necessarily loaded into memory. In Java, a Java class will be compiled into a class file. The Java class does not know the actual address of the referenced class at compile time, so it can only use symbolic references instead.

For example, org.simple.People refers to org.simple.Language. At compile time, People does not know the actual memory address of Language, so it can only use the symbol org.simple.Language (assuming this, Of course, it is actually represented by a constant like CONSTANT_Class_info) to represent the address of the Language class. The memory layout of various virtual machine implementations may differ, but they all accept the same symbolic references because the literal form of symbolic references is explicitly defined in the Class file format of the Java Virtual Machine specification.

2. Direct quotes:

A direct reference can be

(1) A pointer to a target (for example, a direct reference to a Class object, a Class variable, or a Class method may be a pointer to the method area)

(2) Relative offsets (e.g., direct references to instance variables and instance methods are offsets)

(3) A handle that can be indirectly located to the target

A direct reference is related to the vm layout. The direct reference translated from the same symbol reference on different VM instances may not be the same. If there is a direct reference, the target of the reference must already be loaded into memory.


1.2.5 Class loader

Bootstrap class-loader Bootstrap class-loader

Load the jar file under jre/lib, such as rt.jar.

It is a super-citizen, and even when Security Manager is turned on, the JDK gives AllPermission to the program it loads.

We can usually get the parent loader using the following method, but in the usual JDK/JRE implementation, the extension class loader getParent() can only return NULL

Extension or Ext class-loader

The extension mechanism is responsible for loading the JAR packages we put under the JRE /lib/ext/ directory.

This directory can also be overridden by setting “java.ext.dirs”.

(3) Application or App class-loader

Overwrite loadClass to break the parent delegate

Overwrite findClass to maintain parent delegates

Definclass () converts bytecode to Class

In the default implementation of loadClass, the findClass method is called, so if you override findClass, the call is still loaded by loadClass and passed to the upper level, as follows: The last step is to call your own findClass

Check to see if the class has already been loaded

2. If there is no load, call the loadClass() method of the parent loader to load

3. If the parent loader is empty, the startup class loader is used as the parent loader by default.

4. If the parent class fails to load, throw a ClassNotFoundException and call your own findClass() method to load it.

If you override LoadClass, you can override *definclass to break the parent delegate

The parent delegate principle is broken in JDBC by introducing ThreadContextClassLoader (thread context loader, by default AppClassLoader).

(4) Advantages of parental delegation mechanism

  • Avoid reloading classes
  • Protect program security and prevent the core API from being tampered with
    • Custom class: java.lang.string (useless)
    • Custom class: java.lang.ShkStart (error: prevents creation of java.lang classes)

(5) SPI mechanism

SPI focuses on the idea of a slot. You can load META – INFO /service using a ServiceLoader, which returns an iterator. Note that the class name of the file needs to correspond to the interface you want to load.

public class SpiTest {
    public static void main(String[] args) {
        ServiceLoader<People> load = ServiceLoader.load(People.class);
        Iterator<People> loaders = load.iterator();

        while (loaders.hasNext()) {
            loaders.next().run();
            System.out.println(1); }}}Copy the code

1.2.6 Object creation process

  1. Class loading

  2. Allocate memory

    1. The free list

    2. Pointer to the collision

    3. The choice between the two approaches depends on whether the Java heap memory is tidy. Whether the Java heap memory is tidy depends on

      Whether the GC collector’s algorithm is “mark-clean”, “mark-tidy” (also known as “mark-compress”), and, notably, copy

      Algorithm memory is also tidy

    4. Concurrency issues

      1. CAS+ fails and retry
      2. TLAB: a small block of memory is allocated directly to the thread in Eden
  3. Initialize a zero value

  4. Set the object header

  5. Execute the init method