14 Java interview questions frequently asked by big factories

insert image description here

5 minutes to read this article


  1. Similarities and differences between synchronized and reentrantlock

Both implement multi-thread synchronization and memory visibility semantics

reentrant lock

difference

The implementation mechanism is different. Synchronized implements reentrant lock through java object head lock mark and Monitor object. Implements synchronized through CAS, ASQ (AbstractQueued Synchronizer) and locksupport (for blocking and unblocking). Reentrant lock relies on jvm memory model to ensure multi-threaded memory visibility including shared variables. ASQ's volatile state guarantees multithreaded memory visibility including shared variables

Synchronized can be used in different ways to modify instance methods (lock instance objects), static methods (lock class objects), code blocks (display specified lock objects) reentrantlock shows that calling trylock()/lock() methods needs to be released in the finally block Lock

Reentrantlock provides rich semantics such as limited time waiting lock (set expiration time), lock Interruptibly, condition (provide await, signal, etc. methods) Cannot be interrupted

  1. Why does concurrenthashmap read without locking

jdk1.7

1) The key, hash, and next in HashEntry are all final types, and only the header can be inserted and deleted

2) The value field of the HashEntry class is declared as volatile

3) It is not allowed to use null as the key and value. When the reading thread reads that the value of the value field of a HashEntry is null, it knows that a conflict has occurred—a reordering phenomenon has occurred (put sets the bytecode of the new value object Instruction reordering), this value needs to be re-read after locking

4) The volatile variable count coordinates the memory visibility between the read and write threads. After the write operation, the count is modified, and the read operation reads the count first. According to the happen-before transitive principle, the modified read operation of the write operation can be seen

jdk1.8

1) Both val and next of Node are volatile

2) The unsafe operation corresponding to tabAt and casTabAt implements volatile semantics

  1. The role of ContextClassLoader (thread context class loader)

Override the parent delegation mechanism of the class loader to load classes, such as service loader implementation

Use the thread context class loader to load classes. Pay attention to ensure that the class loaders between multiple threads that need to communicate should be the same to prevent type conversion exceptions (ClassCastException) caused by different class loaders.

  1. tomcat class loading mechanism
    picture

Different applications use different webapp class loaders to achieve the effect of application isolation. Below the webapp class loader is the jsp class loader

The jar packages shared by different applications can be placed in the Shared class loader/shared directory.

  1. osgi class loading mechanism

picture

The osgi class loading model is meshed and can be delegated between modules (Bundle)

The key to osgi's modular hot deployment is the implementation of the custom class loader mechanism. Each Bundle has its own class loader. When a Bundle needs to be replaced, the Bundle and the class loader are replaced together to implement the code hot replacement for

When a class loading request is received, osgi will search for classes in the following order:

1) Delegate classes starting with java.* to the parent class loader for loading

2) Otherwise, delegate the classes in the delegation list (defined in the configuration file org.osgi.framework.bootdelegation) to the parent class loader to load

3) Otherwise, check whether it is declared in Import-Package, if yes, delegate to the class loader of the Bundle of the Export class to load

4) Otherwise, check if declared in Require-Bundle, if yes, delegate classloading request to required bundle's classloader

5) Otherwise, find the ClassPath of the current Bundle and load it with your own class loader

6) Otherwise, find out whether the class is in its own Fragment Bundle, and if so, delegate to the Fragment Bundle's class loader to load

7) Otherwise, find the Bundle of Dynamic Import-Package (Dynamic Import is only loaded when the Package is actually used), and delegate to the class loader corresponding to the Bundle to load

8) Otherwise, class lookup fails.

  1. How to end a thread that has been running

Use the exit flag, this flag variable must be visible to multiple threads

Use interrupt in conjunction with isInterrupted().

  1. Threadlocal usage scenarios and problems

Threadlocal cannot solve the problem of multi-threaded shared variables. The objects contained in the same threadlocal have different copies in different threads without interfering with each other.

It is used to store thread context variables, which is convenient for the same thread to read variables multiple times before and after, such as transactions, database connection connections, and more used in web programming

Question: Note that threadlocal is used in the thread pool scenario, because the actual variable value is stored in the threadlocalmap type variable of thread. If the value is not removed or set first, the old value may be obtained

Problem: Pay attention to the memory leak in the thread pool scenario. Although threadlocal get/set will clear the key (the key is a threadlocal weak reference, and the value is a strong reference, causing the value not to be released) to be a null entry, it is best to remove it.

  1. The process of thread pool from startup to work

When just created, there are no threads in it

When calling execute() to add a task:

1) If the number of running threads is less than the core parameter corePoolSize, continue to create threads to run this task

2) Otherwise, if the number of running threads is greater than or equal to corePoolSize, add the task to the blocking queue

3) Otherwise, if the queue is full and the number of threads running at the same time is less than the core parameter maximumPoolSize, continue to create threads to run this task

4) Otherwise, if the queue is full and the number of threads running at the same time is greater than or equal to maximumPoolSize, it will be processed according to the set rejection policy

5) Complete a task and continue to process the next task

6) When there is no task to continue processing, the thread is interrupted or the thread pool is closed, the thread exits execution, and if the thread pool is closed, the thread ends

7) Otherwise, determine whether the number of threads running in the thread pool is greater than the number of core threads, if yes, the thread ends, otherwise the thread is blocked. Therefore, after all thread pool tasks are executed, the remaining thread pool size is corePoolSize.

  1. The difference between blocking queue BlockingQueue take and poll

poll(time): Take away the first object in the BlockingQueue. If it cannot be taken out immediately, you can wait for the time specified by the time parameter, and return null if it cannot be taken out

take(): Take the first object in the BlockingQueue. If the BlockingQueue is empty, block until a new object is added to the BlockingQueue.

  1. How to get results from FutureTask without blocking

get(long timeout,TimeUnit unit), return when timeout

Polling, first judge whether it is finished through isDone(), and then call get().

  1. If the blockingqueue stores critical data, how should the system go down?

Open question, welcome to discuss

Persisting the queue is cumbersome. It needs to persist the production data to the disk. It returns only after the persistence is successful. The consumer thread loads data from the disk into the memory blocking queue, maintains the consumption offset, and loads data from the disk according to the consumption offset at startup.

Join the message queue to ensure that messages are not lost, generate serial numbers, consume idempotent, and determine the production status after the system restarts according to the consumption process.

  1. The difference between NIO and traditional I/O

To save threads, NIO has changed from the original need for each thread to block reading and writing to a single thread (i.e. Selector) responsible for processing the collection of interest events (SelectionKey) for multiple channel registrations (registers) (the bottom layer relies on the epoll provided by the operating system ( )), netty bossgroup handles accept connection (I don’t understand why bossgroup needs to set up multiple threads), workergroup handles specific business processes and data reading and writing

NIO provides non-blocking operations

Traditional I/O processes data in the form of streams, while NIO processes data in blocks. NIO provides bytebuffers, which are divided into in-heap and off-heap buffers. When reading and writing, they are first placed in the buffer, and then passed by the kernel. The channel is transmitted to the opposite end, and the off-heap buffer does not go to the kernel, which improves performance.

  1. Repeatable strings are stored in the list, how to delete a certain string

Call iterator related methods to delete

Reverse deletion prevents array rearrangement caused by positive sequence deletion, and index skips array elements.

  1. What are the GC ROOTS (more related to daily development is the memory leak related to this)

All Java threads currently active stack frames point to references to objects in the GC heap, so unused objects are set to null in time to improve memory recovery efficiency

Objects referenced by static variables, so reduce the size of static variables, especially static collection variables, and objects stored in collections override euqls() and hashcode() to prevent continuous growth

The object referenced by the native method JNI

Objects referenced by constants in the method area, thus reducing calls to String.intern() on long strings

The class object loaded by the classloader, so when the custom classloader is invalid, set null in time and pay attention to the isolation between objects loaded by the classloader

References to objects in the GC heap in some static data structures in the jvm.

Guess you like

Origin blog.csdn.net/m0_54861649/article/details/126471160
Recommended