Job hopping is not frequent, but I have participated in a lot of interviews (telephone interview, face to face interview), big/small companies, Internet/traditional software companies, confused (high eyes and low skills, lack of actual combat experience, failed), and also met people. Fortunately, I was not discouraged by failure, and kept checking and making up for mistakes during this process. I have developed the habit of being practical, tracing to the source and making continuous improvement. I hereby write down some interview questions I have experienced and conceived. If you have any questions, please feel free to discuss them.

1. Similarities and differences between synchronized and reentrantlock

The same

Both implement multithreaded synchronization and memory visibility semantics

Both are reentrant locks

The difference between

Implement different synchronized mechanism through the Java object lock head tag and the Monitor object implementation already by CAS, ASQ (AbstractQueuedSynchronizer) and Locksupport (for blocking and unblocking) implements synchronized relying on the JVM memory model to ensure that multithreaded memory visibility reentrantLocks containing shared variables pass ASQ’s volatile state Ensure visibility of multithreaded memory containing shared variables

Synchronized can modify instance methods (to lock instance objects), static methods (to lock class objects), and code blocks (to display specified lock objects). Reentrantlock Displays the trylock()/lock() methods that need to release the lock ina finally block

Reentrantlock provides rich semantic reentrantLocks such as finite time waiting locks (set expiration time), lockInterruptibly (lockInterruptibly), and condition (which provides await, signal, and other methods) Provide fair lock and non-fair lock synchronized

2. Why does concurrenthashMap read without locking

jdk1.7

1) Key, hash, and next ina HashEntry are final, and only table headers can be inserted or deleted

2) The HashEntry value field is declared volatile

3) Null keys and values are not allowed. When a reader reads a HashEntry value field with a value of NULL, it knows that a collision has occurred — reordering has occurred (putting sets the bytecode instruction of the new value object to reorder). You need to lock and re-read the value

4) Volatile count coordinates memory visibility between read-write threads. Write changes count after write, read reads count first, and write changes can be seen according to the happen-before transitivity principle

jdk1.8

1) Node val and next are volatile

2) The tabAt and casTabAt counterpart unsafe operations implement the volatile semantics

3. The role of ContextClassLoader

Load classes by bypassing the parent delegate mechanism of the class loader, such as the Serviceloader implementation

Use the thread-context class loader to load classes. Ensure that multiple threads that need to communicate have the same class loader to prevent classcastExceptions caused by different class loaders.

4. Tomcat class loading mechanism




Different applications use different WebApp classloaders to achieve the effect of application isolation. JSP classloaders are below webApp classloaders

Jar packages Shared by different applications can be placed in the Shared class loader/Shared directory

5. Osgi class loading mechanism




The OSGi class loading model is reticulated and can delegate between modules (bundles)

The key to implementing modular hot deployment in OSGi is the implementation of a custom class loader mechanism. Each Bundle has its own class loader. When a Bundle needs to be replaced, the Bundle is replaced with a similar loader to achieve hot replacement of code

When a classload request is received, OSGi performs a class search in the following order:

1) Delegate classes starting with Java.* to the parent class loader

(2) otherwise, the delegate list list. Org configuration file. The osgi framework. Bootdelegation) defined within the class assigned to the parent class loader loads

3) Otherwise, check whether it is declared in import-package, and if so, delegate the load to the class loader of the Bundle of the Export class

4) Otherwise, check if it is declared in require-bundle, and if so, delegate the classloading request to the required Bundle’s classloader

5) Otherwise, find the current Bundle’s ClassPath and load it using your own class loader

6) Otherwise, check whether the class is in its own Fragment Bundle. If so, delegate the load to the class loader of the Fragment Bundle

7) Otherwise, find the Bundle for the Dynamic import-package (Dynamic Import is loaded only when the Package is actually used) and delegate the load to the corresponding Bundle’s classloader

8) Otherwise, class lookup fails

6. How do I terminate a thread that has been running

Using the exit flag, this flag variable should be visible to multiple threads

Use interrupt with isInterrupted()

7. Usage scenarios and problems of ThreadLocal

Threadlocal does not solve the problem of multiple threads sharing variables. Objects contained in a threadLocal have different copies in different threads, which do not interfere with each other

Used to store thread context variables, convenient for the same thread to read variables before and after many times, such as transaction, database connection connection, more used in Web programming

Problem: Note that the thread pool scenario uses ThreadLocal, because the actual variable value is stored in the thread’s ThreadLocalMap variable. If the value is not removed and is not set first, the old value may be returned

Question: Note memory leaks in the thread pool scenario. Although get/set of a threadLocal removes null entries whose key is a weak reference of a threadlocal and whose value is a strong reference, it is better to remove them

8. Thread pool from start to work flow

When it was created, there were no threads

When you call 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 the task

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

3) Otherwise, if the queue is full and the number of running threads is smaller than the core parameter maximumPoolSize, continue to create threads to run the task

4) Otherwise, if the queue is full and the number of running threads is greater than or equal to maximumPoolSize, it is processed according to the set reject policy

5) Finish one task and move on to the next

6) The thread exits when no task is processed, the thread is interrupted or the thread pool is closed. If the thread pool is closed, the thread terminates

7) Otherwise, determine whether the number of threads running in the thread pool is greater than the number of core threads. If so, the thread terminates; otherwise, the thread blocks. Therefore, after all thread pool tasks are completed, the remaining thread pool size is corePoolSize

8) The 14 Java interview questions listed in this article are only a few of the interview questions I have encountered, and I will continue to sort out the other questions. I also recommend an architecture exchange learning group: 697579751, which will share some videos recorded by senior architects: Spring, MyBatis, Netty source code analysis, high concurrency, high performance, distributed, microservice architecture principles, JVM performance optimization has become an architect’s essential knowledge system. Also can receive free learning resources, I believe that has worked and encountered a technical bottleneck code friends, in this group will have the content you need.

9. Difference between BlockingQueue take and poll

Poll (time) : Poll (time) : Removes the first object in BlockingQueue. If it cannot be retrieved immediately, wait for the time parameter and return null if it cannot be retrieved

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

10. How do I get results from FutureTask without blocking

Get (long timeout,TimeUnit unit)

Polling, isDone() to determine whether it is finished, then call get()

11. What if blockingQueue stores critical data and the system goes down

Open question, welcome to discuss

The consumer thread loads data from disk to the memory blocking queue, maintains the consumption offset, and loads data from disk according to the consumption offset when starting

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

12. Differences between NIO and traditional I/O

Threads are saved. Instead of blocking reads and writes for each thread, NIO is a collection of selectionkeys (epoll() provided by the operating system at the bottom) handled by a single thread (Selector). Netty BossGroup handles accept connections. Workergroup handles business processes and data reads and writes

NIO provides non-blocking operations

While traditional I/O processes data in streams, NIO processes data in blocks. NIO provides ByteBuffer, which is divided into in-heap and out-of-heap buffers. Read and write data are first stored in this buffer and then transmitted by the kernel to the peer end through channels

13. How do I delete a repeatable string from a list

Call iterator related methods to delete

Reverse delete to prevent array rearrangement caused by positive delete. Index skips array elements

14. What GC ROOTS are there (more relevant to daily development are memory leaks associated with this)

All Java threads currently have active stack frames that refer to objects in the GC heap, so null objects that are not needed can improve memory reclamation efficiency

Static variables reference objects, so reduce the size of static variables, especially static collection variables, which store objects overridden euqls() and hashcode() to prevent continuous growth

The object referenced by the local method JNI

Constants in the method area refer to objects, so reduce calls to string.intern () on long strings.

The class object is loaded by the classloader, so if the custom classLoader is invalid, null it immediately and pay attention to the isolation between the classloader loading objects

References to objects in the GC heap in some static data structure in the JVM