Interview questions④

1. The principle of synchronized implementation

        Synchronized can modify code blocks, static methods, and instances to ensure the visibility of data, the atomicity of data operations, and the order of program execution order

Lock status: (after java6, sychronized has been optimized, and it is no longer a simple heavyweight lock)

no lock:

        The newly created object is in a lock-free state

Bias lock:

        When a thread acquires the lock, the lock will enter the biased mode. When the thread requests the lock again, no synchronization is required, which is used to reduce the time wasted when the same thread acquires the lock multiple times. It is suitable for scenarios without lock competition

Lightweight lock (spin):

       When there is competition, the state of the lock enters a lightweight lock, which is suitable for the occasion where threads execute synchronization blocks alternately. When accessing the same lock at the same time, it will cause invalidation, and then enter the spin state, waiting to try to acquire

Heavyweight locks (mutex locks):

        When the light-weight lock spins for many times and cannot be acquired or when the competition is fierce, the state of the lock expands to a heavyweight lock

       The monitor object monitor is the underlying implementation principle of heavyweight locks. It is like a room, which contains protected data. The monitor ensures that only one thread enters the room to access data at a time; the monitor is implemented by ObjectMonitor (written in c++ ), there are many parameters such as _owner (pointing to the address of the thread holding the ObjectMonitor object), _WaitSet (storing the thread in the wait state) and _EntryList (storing the thread in the waiting lock blocking state) 

        Synchronized is implemented based on objects. Objects in java are stored in heap memory, including three parts: object header, sample data, and object filling. The object header contains MarkWord (including four types of lock information, hashcode) and ClassPoint (.class file). Synchronized locks the code block/method, and achieves synchronization through the acquisition (monitorenter) and release (monitorexit) of the monitor of the object/adding the sychronized flag after the Access flags of the class file of the method so that the thread holds the monitor-execute method-releases the monitor

2. Understanding of happens-before

        Happens-Before is a visibility model. JMM (Java Memory Model) provides developers with memory visibility guarantees for cross-domain threads through the Happens-Before relationship. If the execution result of one operation is visible to another operation, then the two operations There must be a Happens-Before relationship between them;

        The Happens-Before relationship only describes the visibility of the results, and does not indicate the sequence of instruction execution, that is, as long as it does not affect the results, reordering of instructions is still allowed (reordering of instructions can improve execution efficiency)

Happens-before rule:

Program sequence rules: No matter how each operation in a thread is reordered, the execution result of the thread cannot be changed

Transitive rules: that is, A Happens-Before B, B Happens-Before C launches A Happens-Before C

volatile variable rule: a write to a volatile modified variable happens-before any subsequent read

Monitor lock rules: a thread releases a lock, happens-before locks a subsequent thread

Thread start rule: Thread A executes the ThreadB.start() operation, and the previous operation happens-before any operation in thread B

3. Implementation principle of volatile

The role of volatile:

        It can ensure the visibility of shared variables in a multi-threaded environment (a thread modifies a shared variable, and other threads can immediately see the modified value, and the invisibility is mainly caused by the consistency problem caused by the CPU's third-level cache in parallel. )

        It can shield the rearrangement of CPU instructions in a multi-threaded environment (the order in which CPU instructions are written and executed in a multi-threaded environment are inconsistent, resulting in visibility problems, and the memory shielding instructions provided by the CPU can avoid rearrangement)

        For shared variables modified by volatile, the JVM will automatically add a #Lock assembly instruction (to flush the current processor cache line data to the system memory, and this flushing operation to the main memory will cause other CPUs to cache the shared variable memory address Data invalid), automatically add bus lock or cache lock according to CPU model, and set memory shield before and after variable write operation to prohibit instruction rearrangement, and insert two memory barriers after variable read operation to prohibit rearrangement of read and write instructions .

        Volatile can be regarded as lightweight sychronized. Volatile cannot guarantee atomicity. When the operation itself is atomic, using volatile is better than sychronized

Bus lock: Lock the front side bus of the CPU so that only one thread can communicate with the memory at a time

cache lock:

The bus lock causes the CPU efficiency to drop greatly. In order to improve the cache lock, only the target data in the CPU L3 cache is locked.

4. What is the first, second and third paradigm

First Normal Form (1NF): Each table in the database must be atomic, that is, the value of each column is indivisible

Second Normal Form (2NF): On the basis of satisfying the first normal form, the non-primary key columns must be completely dependent on the primary key columns

Third Normal Form (3NF):

        On the basis of satisfying the second normal form, it is required that each non-primary key column in the database cannot transitively depend on the primary key, that is, it must directly depend on the primary key

BCNF (Boyce-Codd Normal Form):

        On the basis of satisfying the third normal form, any non-primary key column cannot partially depend on the primary key column. That is to say, when the primary key is determined, there cannot be partial dependence on the primary key

Fourth Normal Form (4NF):

        On the basis of satisfying BCNF, eliminate multi-valued dependencies (multi-valued dependencies refer to the many-to-many relationship between one set of attributes and another set of attributes in a relational schema, that is, the value of one set of attributes may correspond to many value of another set of attributes)

The setting paradigm is used to normalize the database schema to avoid problems such as data redundancy, insertion exceptions, and update exceptions. The main purpose is to improve the data organization, query efficiency and maintainability of the database.

5. What are the new features of jdk8

Lambda expressions: Express anonymous functions or unnamed methods in a more concise way, and pass these functions as parameters to methods or store them in variables, making the code more concise

Method reference: further optimize the Lambda expression of the function that calls the method that has been implemented, eliminating the need to pass parameters

Stream stream: Provides a new way to simplify collection and array operations, providing many methods (sorting, comparison, etc.)

Optional class: It can be used to prevent null pointer exceptions, and objects that are not sure whether they are empty can be wrapped with Optional

Added new date APIs: localtime, clock, localdate (both are immutable, suitable for multi-threaded environments)

Interface update: methods can be implemented with default or static keywords in interfaces,

Functional interface: declaration containing only one abstract method (only functional interfaces can be abbreviated into lambda expressions)

6. Spring boot startup process

Load the startup class: In the main method of the startup class with @SpringBootApplication, start by running the SpringApplication.run() method

[@SpringBootApplication is composed of @EnableAutoConfiguration (import the automatic configuration AutoConfigurationSelector class to load the configuration with @Configuration added), @SpringBootConfiguration (equivalent to @Configuration) and @ComponentScan (automatically scan and load qualified beans)】

Service construction: building SpringApplication

        1. Record the resource loader and main method class in memory;

        2. Determine the type of Web service (Servlet-tomcat);

        3. Load the initialization class: read the registration initialization, context initialization, and listener configuration in the META-INF file;

        4. Determine the class where the main method is located (the startup class itself) by running the stack (stackTrace);

Enter the run method

Environment preparation:

        1.new BootstrapContext (startup context)

        2. Call the initialization initialize method in the startup registration initializer (there is no default)

        3. Set java.awt.headless to true (indicates that input devices such as lack of display and keyboard are also started normally)

        4. Start the running listener (SpringApplicationRunListeners), and then publish the startup event (obtain and load the EventPublishRunListener in the spring.factories configuration file of the spring-boot project, and introduce the listener configuration)

        5. Build a configurable environment Environment (default Servlet type): load system environment variables and jvm system properties into the memory collection of propertySources for later access; configure the environment parameter args passed in at startup by configuring the environment configureEnvironment method, At the same time, add an empty configuration configurationProperties in the first position of the propertySources collection (subsequent use)

        6. Send the environment loading completion event. The eight listeners just loaded will listen to it, and some of them will be processed accordingly. For example, the environment configuration post-processing listener will load the environment configuration post-processor EnviromenPostProccessor in the spring.factories configuration file ( Here the listener uses the observer mode, serial execution)

        7. Use spring.beninfo.ignore=true (Bean metadata information is not loaded, properties, methods, constructors) to improve application performance, print Banner diagram (startup banner)

Container creation: (ApplicationContext)

        1. Create a container (context) through createApplicationContext. First, create a container ConfigurabaleApplicationContext according to the service type (default Servlet). In this process, a Bean factory for storing and producing bean instances will be created, and configurations for parsing annotations such as @Component and @ComponentScan will be created. Class post-processor ConfigurationClassPostProccessor, creating an automatic annotation Bean post-processor AutowiredAnnotationBeanPostProcessor for parsing @Autowired, @Value and other annotations

        2. Initialize the container properties through the prepareContext method, first use the postProcessApplicationContext method to set the Bean name generator, resource loader, type converter, etc., execute context initialization (implement container ID, warning log processing, log monitoring, etc.) ApplicationContextInitializer, and register for the container Startup parameters, Bean reference strategy, Banner, lazy loading strategy, etc.

        3. Load resource definition collections such as startup classes into BeanDefinitionMap (Bean definition pool) through the Bean definition loader, so as to facilitate subsequent creation of Bean objects based on Bean definitions

        4. Publish resource loading completion event

Filling Containers: Autowiring Beans

        1. Through the prepareRefresh method, prepare the servlet-related environment Environment on the basis of the existing system environment, assign values ​​to the servlet initialization parameters servletContextInitParams and servletConfigInitParams through the initialization attribute resource initServletPropertySources method, and then use the validateRequiredProperties method to check whether there are required environment variables (you can Set some environment variables as required through setRequiredProperties in the custom initialization property resource InitPropertySources method), and finally complete the listener and event initialization, and the environment preparation is completed

        2. Call the obtainFreshBeanFactory method (if ClassPathXmlApplicationContext is selected as the container, the BeanFactory will be reconstructed and the Bean definition will be reloaded, while the servletWebServerApplicationContext selected as the container will not perform any processing)

        3. Call the prepareBeanFactory method to load system-level processors such as the class loader BeanClassLoader, the expression parser BeanExpressionResolver, and the configuration file processor PropertyEditorRegistar, and two Bean post-processors (analyze the ApplicationContextAwareProcessor of the Aware interface, and process the registration and destruction of custom listeners ApplicationListenerDetector), and also register some special beans (BeanFactory container itself, ApplicationContext, system environment Environment, system properties, etc.) into special object pools and singleton pools

        4. Call the PostProcessBeanFactory method to make additional settings or modifications to the BeanFactory (define request, session and other servlet-related scopes, register servlet-related ServletRequest, ServletResponse, HttpSession and other special classes)

        5. Execute the InvokeBeanFactoryPostProcessors method, execute the BeanFactory post processor beanFactoryPostProcessor (including the configuration processor ConfigurationClassPostProcessor, which loads all @Configuration configuration classes, and retrieves the specified Bean scanning path componentScans, and then scans through the doScan method in the Bean scanner ClassPathBeanDefinitionScanner For each class, put all scanned bean definitions into the bean definition pool beanDefinitionMap, and also scan classes and methods annotated with @Bean, @Import, etc., and put their corresponding bean definitions into the bean definition Pool, and then you can construct corresponding Bean objects through these Bean definitions)

        6. Retrieve all Bean post-processors through the registerBeanPostProcessors method, sort them according to the specified order, and then put them into the post-processor pool beanPostProcessor. Each Bean post-processor will be separated before and after the Bean initialization Execute the corresponding logic

        7. Obtain two beans from the singleton pool through the initMessageSource method and the initApplicationEventMulticaster method and place them in the ApplicationContext: messageSource (for internationalization, you can customize the messageSource bean and combine the messages.properties configuration file for multi-language switching configuration), applicationEventMulticaster (Used to customize broadcast events, events can be published through the publicshEvent method)

        8. Construct and start the Web server through onRefresh, first find the application server Bean (tomcat by default) that implements the ServletWebServerFactory interface, construct a Tomcat object through the getWebServer method, start it through the start method, and the web server starts running

        9. Find all listener beans in the bean through the registerListeners method, and register them in the above message broadcaster applicationEventMulticaster

        10. Produce all our beans through finishBeanFactoryInitialization (construct objects - fill properties - initialize instances - register and destroy, see the life cycle of springbean for details), and put them into the singleton pool singletonObjects after the beans are generated

        11. Construct and register the lifecycle manager lifecycleProcessor through the finishRefresh method, and at the same time call the start method in all beans that implement the declaration cycle interface Lifecycle (the corresponding stop method will be called automatically when the container is closed), and publish a container refresh completed Event, SpringBoot officially started and completed

7. What are service circuit breakers and service downgrades, and what are their differences?

        Service fusing and service degradation are common fault-tolerant mechanisms in the microservice architecture, which are used to handle exceptions during service calls

Service fuse:

        Service fusing is a protection mechanism, which is used to prevent continuous requests to the service when the service is unstable or faulty; when the service call fails, the circuit breaker will be opened and the service will be closed directly. service, and if the success rate is high, close the circuit breaker to resume normal service

Service downgrade:

        When the service fails or the performance drops, provide an alternate solution or return the default value to ensure that the user or client can get a basic response instead of a long wait or error;

8. Understanding of ThreadLocal

        ThreadLocal is another way to solve the problem of inconsistency in multi-threaded shared data access, which is different from locking.

        ThreadLocal itself does not store data. It uses the ThreadLocals attribute (the ThreadLocalMap object defined in ThreadLocal). When calling the set(T value) method of ThreadLocal, it uses its own reference (this) as the key and the value passed in by the user Stored in the Map as a value, which means that the read and write operations of each thread are based on a private copy of the thread itself, and the data between threads are isolated from each other and do not affect each other, so ThreadLocal-based operations are not thread-safe question. (The idea of ​​exchanging space for time improves the execution efficiency of the program)

        When using ThreaLocal, call the remove method to clean up ThreadLocal variables in time, otherwise it may cause memory leaks

9. Mybatis cache mechanism

        Mybatis cache is to save the data frequently queried by users into the memory to improve query efficiency. Mybatis provides two mechanisms of first-level cache and second-level cache to optimize database access (in a distributed environment, it is better to use Redis directly, and the development cost is low. safer)

Level 1 cache (local cache):

        It is used to save the results of the user's query during a session. The user can only use one sqlSession in a session. The first-level cache is automatically enabled and cannot be disabled. By default, the Local Cache is checked first. If not, the database is checked again, and the data is put into the Local Cache (in Excutor held by Sqlsession)

Second level cache (global cache):

        It is a cache at the mapper level. For the storage of the query results of a table, different sqlsessions can be shared, that is, the operation statements under the same namespace are all connected to the same Cache

Session: A session is a complete communication, including multiple request responses, and the request is sent by the same user

sqlsession: the interface used by the user during a session with the database

10. What are the types of references in Java

        The garbage collection mechanism mainly depends on whether the object has a reference pointing to the object, and the programmer can determine the life cycle of some objects by specifying different references, which is beneficial for the JVM to perform garbage collection

Strong reference: It is a reference to an ordinary object and will never be garbage collected

Soft reference: When the memory space is insufficient, it will be garbage collected, usually used to implement memory-sensitive cache

Weak reference: Regardless of whether there is enough memory, it will be garbage collected

Phantom reference: does not affect the life cycle of the object, and provides a way to ensure that after the object is finalized, the action is taken before the memory is reclaimed

おすすめ

転載: blog.csdn.net/LB_bei/article/details/132509647