preface
Many friends ask, how short time assault Java through the interview?
Before the interview is still necessary to targeted brush some questions, many friends of the actual combat ability is very strong, but the theory is weak, do not prepare before the interview is very at a disadvantage. Here is a list of interview questions that can help you review before the interview and find a good job. It also saves you the time of searching for information on the Internet.
Spring, Spring MVC, Spring Boot, Mybatis MySQL, Redis, messaging middleware MQ, Distributed and microservices. Continuously updated…
The full version of Java interview questions address: 105 Java interview questions summary | including parsing the answers
content | address |
---|---|
Java based | In this paper, |
Multithreading and concurrency | Not updated |
Spring | Not updated |
Spring MVC, Spring Boot | Not updated |
MyBatis | Not updated |
MySQL | Not updated |
Redis | Not updated |
Distributed and microservices | Not updated |
MQ | Not updated |
1. Object oriented
What is object orientation?
Contrast is process-oriented, two different ways of approaching problems
Process oriented pays more attention to each step and order of things, object oriented pays more attention to which participants (objects) of things, and what each needs to do
For example: the washing machine washes clothes
Process oriented tasks will be dissected into a series of steps (function), 1, open the washing machine — — — — – > 2, put clothes — — — — — > 3, put the washing powder — — — — – > 4, cleaning — — — — – > 5, drying
Object orientation will split out two objects: man and washing machine:
Man: Turn on the washing machine to put clothes and washing powder
Washing machine: washing and drying
As you can see from the examples above, process orientation is more straightforward and efficient, while object orientation is easier to reuse, extend, and maintain
object-oriented
Encapsulation: The meaning of encapsulation is to clearly identify all member functions and data items that are allowed to be used externally
Internal details are transparent to external calls, which do not need to modify or care about the internal implementation
(1) Javabean attributes private, provide getSet external access, because the attribute assignment or access logic can only be determined by the Javabean itself. You can’t tinker with it from the outside
private String name; public void setName(String name){ this.name = "tuling_"+name; } The name has its own naming convention and obviously cannot be assigned directly from outsideCopy the code
(2) ORM framework
Operation database, we do not need to care about how the link is established, SQL is how to execute, just need to introduce Mybatis, adjust the method can
Inheritance: Inherits the methods of the base class and makes your own changes and/or extensions
Methods or attributes that are generic to a subclass use the parent class directly, without having to redefine them themselves
Polymorphic: External calls to the same method execute different logic depending on the class of the object.
Inheritance, method overrides, parent class references to subclass objects
Superclass type variable name = new subclass object; Variable name. Method name ();Copy the code
Subclass-specific functions cannot be called
JDK, JRE, JVM
The JDK:
Java Develpment Kit Java development tool
JRE:
Java Runtime Environment Java Runtime Environment
The JVM:
Java Virtual Machine Java Virtual Machine
== = equals
== compares values in the stack, the base data type is the variable value, and the reference type is the address of the memory object in the heap
Equals: object is also used to compare equals: object by default, which is usually overridden
Object
public Boolean equals(Object obj) {
return (this == obj);
}
Copy the code
String
public Boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- ! = 0) { if (v1[i] ! = v2[i]) return false; i++; } return true; } } return false; }Copy the code
As you can see from the above code, the equals() method copied from the String class actually compares the contents of two strings.
public class StringDemo { public static void main(String args[]) { String str1 = "Hello"; String str2 = new String("Hello"); String str3 = str2; Println (str1 == str2); // Pass system.out.println (str1 == str2); // false System.out.println(str1 == str3); // false System.out.println(str2 == str3); // true System.out.println(str1.equals(str2)); // true System.out.println(str1.equals(str3)); // true System.out.println(str2.equals(str3)); // true } }Copy the code
4. HashCode and equals
HashCode is introduced:
HashCode () is used to get a hashCode, also known as a hashCode; It actually returns an int. The purpose of this hash code is to determine the index position of the object in the hash table. HashCode () is defined in the JDK’s object.java, and any class in Java contains a hashCode() function.
Hash table stores key-value pairs. It can quickly retrieve the corresponding value according to the key. That’s where the hash code comes in! (Can quickly find the desired object)
Why have hashCode:
To illustrate why hashCode is needed, use how a HashSet checks for duplicates as an example:
When an object is added to a HashSet, the HashSet evaluates the object’s Hashcode value to determine where the object is added. If not, the HashSet assumes that the object is not repeated. But if a value is found, the equals () method is called to check that the two objects are really the same. If they are the same, the HashSet will not let the join succeed. If it is different, it will be rehashed to another location. This greatly reduces the number of equals counts, which in turn greatly increases the execution speed.
(1) If two objects are equal, the Hashcode must also be the same
(2) If two objects are equal, calling equals returns true on both objects
(3) If two objects have the same hashcode value, they are not necessarily equal
(4) Therefore, if equals is overridden, hashCode must also be overridden
(5) The default behavior of hashCode() is to generate unique values for objects on the heap. If hashCode() is not overridden, the two objects of the class will never be equal anyway (even if they point to the same data)
5, the final
The final
Modifier class: Indicates that the class cannot be inherited
Modifier: Indicates that methods cannot be overridden by subclasses, but can be overridden
Modifier variable: Indicates that a variable cannot change its value once it has been assigned a value.
(1) Modify member variables
If final modifies a class variable, the initial value can only be specified ina static initialization block or when the class variable is declared. If final modifies a member variable, you can execute the initial value ina non-static initializer block, declare the variable, or ina constructor.
(2) Modify local variables
The system does not initialize local variables, which must be displayed by the programmer. So when you modify a local variable with final, you can either specify a default value at definition (later code can’t reassign a value to a variable) or you can assign an initial value to a final variable without specifying a default value (only once) in later code
public class FinalVar { final static int a = 0; /** static{a = 0; } */ final int b = 0; /*{b = 0;} /*{b = 0; }*/ public static void main(String[] args) { final int localA; // Local variables are declared to be uninitialized. localA = 0; //localA = 1; But a second assignment is not allowed}}Copy the code
(3) Modify base type data and reference type data
If a variable 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. But the value of the reference is mutable.
Public class FinalReferenceTest{public static void main(){final int[] iArr={1,2,3,4}; iArr[2]=-3; / / legal iArr = null; Final Person p = new Person(25); p.setAge(24); / / legal p = null; // illegal}}Copy the code
Why can local inner classes and anonymous inner classes only access local final variables?
After compiling, two class files, test.class test1.class, are generated
Public class Test {public static void main(String[] args) {} public void main(final int b) { Final int a = 10; // final int a = 10; Public void run() {system.out.println (a); // New Thread(){public void run() {system.out.println (a); System.out.println(b); }; } .start(); } } class OutClass { private int age = 12; public void outPrint(final int x) { class InClass { public void InPrint() { System.out.println(x); System.out.println(age); } } new InClass().InPrint(); }}Copy the code
The first thing to know is that inner classes and outer classes are at the same level. Inner classes are not defined in a method and destroyed as soon as the method completes execution.
This is where the problem arises: when the outer class’s method ends, the local variable is destroyed, but the inner class object may still exist (it dies only if no one references it again). Here’s a contradiction: the inner class object accesses a variable that doesn’t exist. To solve this problem, a copy of the local variable is made as a member variable of the inner class, so that when the local variable dies, the inner class can still access it. What is actually accessed is the “copy” of the local variable. This is like extending the life of the local variable
When copying a local variable into a member variable of an inner class, we must ensure that the two variables are the same. If we change a member variable in an inner class, the local variable in a method must also change.
I set the local variable to final, and after I initialize it, I won’t let you modify the variable again, so that the inner class member variables and method local variables are consistent. This is actually a compromise. Keeps local variables consistent with the copies created within the inner class.
String, StringBuffer, StringBuilder
Strings are final and immutable, and each operation produces a new String
Both StringBuffer and StringBuilder operate on the original object
StringBuffer is thread-safe, StringBuilder threads are not
The StringBuffer methods are all synchronized modified
Performance: StringBuilder > StringBuffer > String
Scenario: Use the latter two when you often need to change the contents of a string
StringBuilder is preferred, and StringBuffer is used when multiple threads are using shared variables
The difference between overloading and overwriting
Overloading:
The method name must be the same, the parameter type must be different, the number of parameters must be different, and the method return value and access modifier can be different.
Rewrite:
In the parent class, the method name and parameter list must be the same, the return value range must be smaller than or equal to the parent class, the exception range must be smaller than or equal to the parent class, and the access modifier range must be larger than or equal to the parent class. If the superclass method access modifier is private, the subclass cannot override the method.
Public int add(int a,String b) public String add(int a,String bCopy the code
8. The difference between interfaces and abstract classes
(1) Abstract classes can have ordinary member functions, while interfaces can only have public abstract methods.
(2) Member variables in an abstract class can be of any type, whereas member variables in an interface can only be of public static final type.
(3) Only one abstract class can be inherited, and multiple interfaces can be implemented.
Interfaces are designed to constrain the behavior of classes (or rather “have” constraints, since interfaces cannot dictate what classes cannot do), providing a mechanism to enforce the same behavior from different classes. It only restricts the presence or absence of behavior, but not how to implement it.
Abstract classes are designed for code reuse. When different classes have some of the same behavior (denoted as behavior set A), and some of the behavior is implemented in the same way (A nontrue subset of A, denoted as B), you can have the classes all be derived from an abstract class. Implementing B in this abstract class, instead of having all subclasses implement B, achieves code reuse. A minus B is left to the subclasses themselves. It is because a-b is not implemented here that the abstract class is not allowed to be instantiated (otherwise it will not be executed when called to A-B).
An abstract class is an abstraction of the essence of a class, expressing the relationship is A, for example: BMW is a Car. Abstract class contains and implements the general features of the subclass, and abstracts the differentiated features of the subclass to be implemented by the subclass.
An interface is an abstraction of behavior that expresses a like A relationship. For example: Bird like a Aircraft, but essentially it is a Bird. The core of an interface is to define the behavior, that is, what the implementation class can do, regardless of who the implementation class body is or how it is implemented.
Usage scenarios: Use abstract classes when you focus on the essence of a thing; When you focus on an operation, use interfaces.
Abstract classes are much more powerful than interfaces, but they are expensive to define. Because high-level languages (and by practical design) can only inherit one class per class. In this class, you must inherit or write all the commonalities of all its subclasses. Although the interface is much less functional, it is only a description of an action. And you can implement multiple interfaces simultaneously in a single class. The difficulty is reduced at the design stage
9, The difference between List and Set
List
Sequential, store objects in the order in which they were entered, repeatable, allow multiple Null element objects, you can use Iterator to fetch all elements, iterating through, and you can use get(int index) to get the specified subscript element
Set
Unordered, non-repeatable, allows a maximum of one Null element object, can only use the Iterator interface to retrieve all elements, iterating through each element
10. ArrayList vs. LinkedList
ArrayList:
Based on dynamic array, continuous memory storage, suitable for subscript access (random access), expansion mechanism: Because the length of the array is fixed, it is necessary to create a new array if the data exceeds the length, and then copy the data of the old array into the new array. If the data is not inserted into the tail of the array, it will also involve the movement of elements (copy the data later and insert the new element). Using tail interpolation and specifying initial capacity can greatly improve performance even beyond linkedList (which requires creating a large number of Node objects)
LinkedList:
Based on linked lists, it can be stored in scattered memory, suitable for data insertion and deletion operations, not suitable for query: need to traverse one by one
Iterator must be used to traverse the LinkedList, rather than the for loop, because the list needs to be retraversed every time the for body retrieves an element through get(I), which is a performance drain.
Also, do not attempt to return an element index like indexOf and use it for traversal. Use indexlOf to traverse the list, traversing the entire list when the result is empty.
11. What is the difference between HashMap and HashTable? What is the underlying implementation?
The difference between:
(1) The HashMap method does not have synchronized modification, so the thread is not safe and the HashTable thread is safe;
(2) A HashMap allows keys and values to be null, whereas a HashTable does not
Underlying implementation: array + linked list implementation
Jdk8 starts with the list height reaching 8 and the array length exceeding 64. The list changes to a red-black tree, and the element’s inner class Node Node exists
(1) Compute the hash value of the key, and then modulo the array length to the array subscript.
(2) If there is no hash conflict (no element at subscript position), create Node directly and store it in array
(3) If hash conflict occurs, equal comparison is performed first. If the element is the same, the element will be replaced; if the element is different, the height of the linked list will be determined and inserted into the linked list. If the height of the linked list reaches 8, and the array length reaches 64, the red-black tree will be transformed into a red-black tree
(4) If the key is null, the location array with subscript 0 exists
ConcurrentHashMap principle, jdK7 and JDK8 version differences
Jdk7:
Data structure: ReentrantLock+Segment+HashEntry. A Segment contains an array of Hashentries, and each HashEntry is a linked list
Element queries: Second hash, the first hash to the Segment and the second hash to the head of the list in which the element is located
ReentrantLock: Segment Segment inherits ReentrantLock, locks the Segment, does not affect other segments, the concurrency can be specified by the constructor. Array expansion does not affect other segments
The get method does not require locking and is volatile guaranteed
Jdk8:
Data structure: synchronized+CAS+Node+ red-black tree. Val and next of Node are volatile to ensure visibility
Find, replace, and assign all use CAS
Lock: the head node of the chain table does not affect the read and write of other elements. The lock granularity is finer and the efficiency is higher. During capacity expansion, all read and write operations are blocked and concurrent capacity expansion is performed
Read operation without lock:
Val and next of Node are volatile, and the array visible to each other by the reader thread is volatile to ensure that the reader thread is aware of the expansion
13. What is bytecode? What are the benefits of adopting bytecode?
Compilers and interpreters in Java:
Java introduced the concept of a virtual machine, a virtual machine with a layer of abstraction between the machine and the compiler. This virtual machine provides a common interface for compilers on any platform.
The compiler simply faces the virtual machine, generates code that the virtual machine understands, and then the interpreter translates the virtual machine code into system-specific machine code for execution. In Java, this code for the virtual machine to understand is called bytecodes (files with a.class extension), which are not oriented to any particular processor, just to the virtual machine.
The interpreter for each platform is different, but the virtual machine implemented is the same. Java source programs are compiled by the compiler into bytecodes, which are interpreted and executed by the virtual machine. The virtual machine sends each byte code to be executed to the interpreter, which translates it into machine code on a particular machine and runs it on that particular machine. This explains the coexistence of compilation and interpretation in Java.
Java source code — — — — — — — — > > compiler JVM executable Java bytecode (that is, the virtual instruction) — — — — — — — — > > JVM JVM interpreter — — — — — > machine executable binary machine code — — — — > program is running.
Advantages of using bytecode:
Java solves the problem of low efficiency of traditional interpreted languages by means of bytecode to some extent, and at the same time retains the portability of interpreted languages. So Java programs run more efficiently, and because bytecode is not specific to a particular machine, Java programs can run on many different machines without recompiling.
Exception architecture in Java
All exceptions in Java come from the top-level superclass Throwable.
There are two subclasses of Throwable, Exception and Error.
Error is an Error that the program cannot handle, and when it does, the program is forced to stop running.
Exception does not cause the program to stop and is divided into two parts: RunTimeException RunTimeException and CheckedException check Exception.
RunTimeException usually occurs during program execution and causes the current thread of the program to fail. CheckedException occurs during program compilation and causes the program to fail.
15. Java class loader
The JDK comes with three class loaders: Bootstrap ClassLoader, ExtClassLoader, and AppClassLoader.
BootStrapClassLoader is the parent class loader of ExtClassLoader. By default, BootStrapClassLoader loads jar packages and class files in %JAVA_HOME%lib.
ExtClassLoader is the parent class loader of AppClassLoader. It loads jar packages and class classes in the %JAVA_HOME%/lib/ext folder.
AppClassLoader is the parent class of the custom class loader and is responsible for loading class files in the classpath. System ClassLoader, thread context loader inherits the ClassLoader to implement a custom ClassLoader
16. Parental delegation model
Benefits of the parent delegation model:
The main reason is to keep user-written classes from dynamically replacing some of Java’s core classes, such as String. It also avoids double loading of classes, because the JVM distinguishes classes not just by class name, but by the same class file being loaded by different classloaders as two different classes
17. How does GC determine if an object can be reclaimed
Reference counting method: each object has a reference counting attribute. When a new reference is added, the count is increased by 1; when a reference is released, the count is decreased by 1; when the count is 0, it can be reclaimed.
Reachability analysis: Search down from GC Roots, and the search path is called reference chain. When an object is not connected to GCRoots by any reference chain, the object is proved to be unavailable and the virtual machine is judged to be a recyclable object.
In reference counting, A may refer to B, and B may refer to A, even if they are no longer used, but the cross-reference counter =1 can never be reclaimed.
The objects of GC Roots are:
The virtual machine stack (the local variable table in the stack frame) references the object method area in the class static attribute reference object method area in the constant reference object Native method stack reference object
The unreachable object in the reachability algorithm is not immediately dead, the object has a chance to save itself. When an object is declared dead by the system, it must go through at least two labeling processes: the first is to find that there is no reference chain connected to GC Roots after reachable analysis, and the second is to determine whether finalize() method needs to be implemented in the Finalizer queue automatically established by the virtual machine.
When the object becomes unreachable (GC Roots), GC will judge whether the object overlays finalize method. If not, it will be directly recycled. Otherwise, if objects have not executed finalize method, put them into F-Queue, and let a low-priority thread execute Finalize method of objects in the Queue. After the finalize method is executed, GC will judge whether the object is reachable or not. If not, GC will recycle the Finalize () method. Otherwise, objects can only be “resurrected” once per object
Finalize () method is not recommended because of its high running cost and great uncertainty, which cannot guarantee the call order of objects. We recommend to forget it.