As a person who hasn’t opened an IDE for several years, filling in the hole he dug and answering the title of the previous article should also fully demonstrate that once you really master it, it is actually very unforgettable. Of course, on the other hand, it seems to show that the progress of Java language level is limited over the years.

These subjects I am completely according to the advanced Java programming ideas to design, many students may think memorize answers can go to deal with some of the interview, regardless of why this is difficult to back, in fact as long as the interviewer a little bit level, usually on the subject of ask method will have a lot of change, it is easy to tell the interviewer, And the interviewer should be based on the background of the interviewer to ask questions, rather than the same, so I think the most hope is that you can seriously study and master the knowledge behind the knowledge, so that the same should be changed.

  1. How many threads are there when 100 connections are made to the Server based on the BIO implementation? How many threads will it be based on NIO? Why is that?


    A: Because BIO is not NIO like event mechanism, the connection of the IO, whether or not there is actually a read/write, must be blocked on the current thread, for the Server based on the BIO implementation is usually a thread to accept the connection, when the connection is established, I/O reads and writes for this connection are put into a special processing thread, so when 100 connections are created, it usually results in 1 Accept thread + 100 processing threads.

    NIO event to trigger, this can be achieved in need read/write to deal with, don’t block the current thread, NIO in dealing with I/o read and write, when read or written from nic buffer buffer, this is a serial process, so use too multithreading IO events in fact also nothing important meaning, because usually deal with faster connection events, I/O events usually take CPU core +1 or CPU core * 2, and the reason for this is that I/O threads usually do light things like parsing protocols and reading and writing from buffers, which can be concurrent, so why not just use one thread, This is because when there are too many concurrent I/O events, the efficiency of one thread is not enough to exert the capacity of the multi-core CPU, resulting in a bottleneck. This will be more obvious in the scenario of distributed cache type. According to this, it is easier to understand why when writing programs based on Netty, etc., Instead of doing too many actions directly in the IO thread, you should move those actions to another thread pool to keep the IO events processed efficiently.

    As you can see from the above, the advantages of NIO are obvious for most scenarios where a large number of connections are required, but concurrent reads and writes do not occur simultaneously.

    There is a lot of room for variation in this approach to BIO and NIO, and it can be expanded to ask the fundamental differences between AIO and BIO and NIO.

  2. How many threads are used to process I/O events on the niO-based Server, and why?


    Answer: see the answer in 1.

  3. In a typical client cluster ->LB-> server cluster structure, if the client uses connection pooling, long connection mode, what problems do you think might occur? What if the client uses a single long connection? If there is a problem, how do you think it should be solved?


    A: This question is quite open, and there are various answers. Here I would like to talk about a big pit that I myself ran into when I was here, which is also the biggest risk in such a structure.

    The client uses connection pool, long connection, and connects to the back-end server cluster through LB. Under such a structure, because the client only sees the VIP provided by LB, a serious problem is that the server cluster is unbalanced, especially when the server cluster is released and restarted. In the worst case, the server cluster may not start at all.

    The same problem occurs when the client uses a single long connection.

    That year, the earliest time of our system is to use this way, resulting in a serious fault, the server won’t start, because partial caused the pressure is released in a small machine, the capacity is not enough to collapse, the processing time had dropped the VIP disable first, server cluster all ready, Then VIP enable, just barely carry over.

    Such problems can be difficult to solve, such as disconnecting the long connection when it reaches a certain condition, but the role of the long connection is reduced. The fundamental solution is to remove the intermediate LB in such scenarios and replace it with a mechanism similar to service registration/discovery.

    Some students answered that the risk is that the LB connection will explode, which may underestimate the ability of LB equipment. It is completely ok in a certain scale, after all, there are few enterprises with the scale of Ali.

  4. How exactly does CGLIB differ from Java’s dynamic proxy?

    A: I don’t know much about it myself, but in a nutshell CGLIB can proxy classes, which is very helpful in implementing scenarios like Spring AOP enhancement.

  5. How do the following two codes behave differently when implementing FrameDecoder based on Netty?

    The first kind of

    private void callDecode(…) {

           List<Object> results = new ArrayList<Object>();

           while (cumulation.readable()) {

                 int oldReaderIndex = cumulation.readerIndex();

                 Object frame = decode(context, channel, cumulation);

                 if (frame == null) {

                      if (oldReaderIndex == cumulation.readerIndex())

                            break;

                      else

                           continue;

                }

               else if (oldReaderIndex == cumulation.readerIndex()) {

    throw new IllegalStateException( “…..” );

                }

                results.add(frame);

         }

         if(results.size() > 0)

             fireMessageReceived(context, remoteAddress, results);

    }

    The second,

    private void callDecode(…) {

           int oldReaderIndex = cumulation.readerIndex();

           Object frame = decode(context, channel, cumulation);

    if (frame ! = null)

                   fireMessageReceived(context, remoteAddress, frame);

    }


    A: The first kind is a large amount of concurrency will have a lot of advantages, the reason is that when is a large amount of concurrency, a flow in the event may have more than one can handle object, before also said that the models are usually based on the NIO IO thread pool + business processing thread pool model, how to fully make IO thread more efficient concurrent determines the capacity of the server, The first processing method can effectively reduce the CONTEXT switch between THE IO thread pool and the business processing thread pool, thus improving the processing efficiency of the IO thread.

  6. With Executors. NewCachedThreadPool create a thread pool, in the process of running a risk is possible?


    One of the biggest risks of newCachedThreadPool is that it may create too many threads, so that no thread can be created.

    How many resources does it take to create 100 threads? What are the limits on how many thread pools a Java process can create?

  7. New ThreadPoolExecutor (10100, 10, TimeUnit MILLISECONDS, new LinkedBlockingQueue (10)); For a thread pool created this way, what happens when an 11th task is submitted to the pool for execution when there are already 10 tasks running? Why?


    A: I’ve been in this trap since I started learning ThreadPoolExecutor, and it seems logical to keep creating threads to handle concurrent tasks until the number of threads reaches the Max. In fact, the implementation of ThreadPoolExecutor will fill the Queue when coreSize is full, and will create a thread to process the Queue only when the Queue is full and the Max hasn’t arrived. So this problem will be put in the Queue when the 11th task is submitted, so for the API used, Don’t take it for granted. It’s better to look at the implementation.

    If you were to design a class similar to ThreadPoolExecutor, what would you do?

  8. What is the general purpose of implementing a custom ThreadFactory?


    A: The usual function is to give a name to a thread, so that you can check the problem later. Many students who have checked the problem will find that jStack comes out after a bunch of threads can not see the meaning of the name how crashed.

  9. Besides using Object.wait and Object.notifyAll for thread interaction, which other implementations do you use?

    There are many different ways to implement thread interaction, including BlockingQueue, CountDownLatch, and CyclicBarrier.

  10. Why is ConcurrentHashMap more efficient than HashMap at high concurrency?

    A: It is mainly the split lock used in ConcurrentHashMap implementation, and the clever use of final and volatile. There are many articles on the web that will not be discussed here.

  11. What is the common reason why AtomicInteger and AtomicBoolean classes are efficient at high concurrency?

    A: CAS, CAS is a hardware level primitive, you can use this to achieve lock-free algorithm, online interpretation of the article is also very much, here will not expand.

  12. Use Queue wisely to implement a high concurrency production/consumption scenario, with some core code snippets.

    A: LinkedBlockingQueue, ArrayBlockingQueue, ArrayBlockingQueue, ArrayBlockingQueue, ArrayBlockingQueue Or if you implement a Queue yourself what would you do?

  13. Please enable 10 tasks to start simultaneously, give some code snippets.

    A: With the help of CyclicBarrier implementation, the reason to give code fragments, is to see the code proficiency, write code to write more, it is completely possible to handwritten a simple compilation without error, runnable code.

    How cyclicbarriers are implemented?

  14. What command-line tools can be used to view startup parameter values of the current Java program, such as Heap Size, at runtime.

    A: Jinfo-flags, this is mainly depends on the Java some tools to check the situation, other tools can do similar effect actually ok.

  15. What command-line tool can be used to view the GC status of a running Java program? Please specify the command line format.

    A: It is usually possible to use jstat -gcutil [pid] [frequency, such as how many milliseconds] [how many times] to see the current GC situation, and if gc log is already enabled, you can view the GC log directly.

    If you want to open a GC log, you can see how it is normally opened, the specific command line parameters, the interpretation of a GC log, etc.

  16. What tools can be used to track the execution time of a method, request parameter information, etc., while the Java program is running, and explain the implementation principle of the tool.

    A: Btrace, Arthas, uses the JVM Attach Agent, ASM, and Instrumentation to dynamically replace bytecode to dynamically track application performance.

    This can further understand the master degree of the principle. You can also tell a case of investigation with the help of these tools to see the practice.

  17. When a Java application receives a request and does not respond for a long time, how do you usually troubleshoot this problem?

    A: This is a very open question for a number of reasons. Generally speaking, you need to verify that the request has come in, and if so, you need to comb through how the Java application receives the request, and then jStack looks at the corresponding thread pool to see if anything is stuck.

    Again, the way to develop the problem is to ask about an actual case.

  18. How do you troubleshoot a Java process that suddenly disappears?

    A: This question is also very open, generally speaking, first look at the Java process log, such as hs_err_[pid]. Log, if yes, look at the log content, the corresponding processing; If there is core dump, use GDB to check. You can also use dmesg to see if the OS killed for any reason; There are also some operation logs of the operation and maintenance system.

    Again, the way to develop the problem is to ask about an actual case.

  19. With the following code idea, what do you think is the risk at runtime? How can it be improved?

    public List<User> getUsers(String[] userIds){

    // Find the user record that matches the userIds from the database

    // Assemble the returned record into a User object, put it into a List and return it

    }

    A: The biggest risk of this question is that there is no limit to the number of userIds, which may result in searching a large amount of data from the database and assembling it into User objects. On the one hand, this may make the database unable to support, and on the other hand, it may lead to OOM in Java. Code like this has caused very serious failures in the past.

    The reason for asking this question is to remind you to code defensively.

  20. What is the difference between these two types of code at run time? Why is that?

    The first kind of

    private static final boolean isLoggerDebugEnabled = log.isDebugEnabled();

    public void xx(User user){

         if(isLoggerDebugEnabled){

              log.debug(“enter xx method, user id is: ” + user.getId());

         }

    }

    The second,

    public void xx(User user){

         log.debug(“enter xx method, user id is: ” + user.getId());

    }


    A: If the debug level of log is not enabled, the first method does not appear string concatenation, and the second method appears, causing some memory waste in the young area, so the first method is better, because the first method is optimized directly during compilation in the Java runtime, and the whole code is removed completely.

    This question can be extended to ask what compilation optimization techniques are available.

  21. Why do Java programs usually execute slowly at startup and faster after processing a few requests, and how does AOT help?

    A: Because Java is still in the interpretive execution at the start stage, dealt with some requests as C1 and C2 compiled after intervention, will be optimized into machine code, and with the aid of all kinds of advanced optimization runtime data (for example above 20), makes the Java program into a state of high speed running, this also is the Java the language a lot of advantages, The gap between programmers is narrowed to a certain extent, and there will not be too bad Java programs.

    AOT helps by compiling some code directly into machine code before startup, so that interpretation execution can be skipped immediately after startup and more efficient execution can be performed.

    This topic is a bit big, I will invite the professional JVM students to write a post, by the way, tell you how ali’s scene to solve the problem of slow startup, including you can also check out Azul’s ReadyNow! , JEP JWarmup of Ariti.

  22. Parallel GC, CMS GC, ZGC, and Azul Pauseless GC are the main differences? Can you also briefly describe the principle behind it?

    Answer: this problem than on the problem return big, first simple answer below, the back special topic will write.

    The Young section of Parallel GC adopts mark-copy algorithm, and The Old section adopts Mark-sweep-Compact. Parallel is executed, so The Parallel GC will stop-the-world when YGC and FGC are executed. But the GC will also be faster to complete.

    CMS GC also uses Mark-copy in the Young area and Concurrent mark-sweep in the Old area, so it determines that THE STW time caused by CMS GC in the Old area is shorter, avoiding too large delay impact on applications.

    The G1 GC uses the Garbage First algorithm, which is more complex and better implemented. In theory, it can be more efficient than THE CMS GC with less impact on the application.

    ZGC and Azul Pauseless GC use very different algorithms, especially Pauseless GC, where an important trick is to add Read barriers to better identify the references changes that are most critical to the GC.

    On the one hand, it can be an algorithm. On the other hand, it can be a more specific implementation, such as how GC implements STW.

  23. Write a program that will run as yGC firing 5 times, then FGC firing 3 times, then YGC firing 3 times, then FGC firing 1 time, give the code and start parameters.

    A: I don’t write this, post as if also has written a long time ago, need to be based on Java memory management of the generational, GC trigger mechanism to design the corresponding code, we have more this kind of topic change, on the one hand, can adjust the trigger form of GC, on the other hand can be activated by adjusting the parameters of the GC form, to see whether really thoroughly grasp the knowledge of GC.

  24. What is the main difference between Go Coroutine and Java threading? If the Java language wants to implement Coroutine transparently, what do you see as the main challenges?

    Answer: this question is also very big, answer briefly first, write the topic behind.

    The Thread mechanism of Java is mainly based on Native threads. The Coroutine of Go is a kind of “Thread” managed by the process itself. Therefore, in the scenario of high concurrency, the Coroutine can effectively reduce the heavy Native Thread context switch, so as to improve the concurrent processing ability.

    However, many Coroutine implementations of Java versions are not very transparent and have many restrictions, which makes it difficult to use Java. What is more difficult is that there are many places where Native threads directly block, such as synchronized, various locks and BIO. How to make these places transparent and non-block native threads in Coroutine environment is the key problem. If you are interested, you can pay attention to Project Loom of Openjdk and AJDK Coroutine Wisp of Ali.


Welcome to follow my public account helloJavacases,

Talk about advanced programming skills,

Talking about system design,

Talk about technical direction,

Talk about where your career is going.