Complete Works of Java Interview Questions(7)

Complete Works of Java Interview Questions(7)

Baiyu IT haha

61. How many ways are there to write multi-threaded programs?

Answer: There are two ways to implement multithreading before Java 5: one is to inherit the Thread class; the other is to implement the Runnable interface. Both methods must override the run() method to define the behavior of the thread. The latter is recommended, because inheritance in Java is single inheritance. A class has a parent class. If you inherit the Thread class, you cannot inherit other classes. Obviously, using the Runnable interface is more flexible.

Added: After Java 5, there is a third way to create a thread: implement the Callable interface, the call method in this interface can generate a return value when the thread execution ends, the code is as follows:


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class MyTask implements Callable<Integer> {
    private int upperBounds;
    public MyTask(int upperBounds) {
        this.upperBounds = upperBounds;
    }
    @Override
    public Integer call() throws Exception {
        int sum = 0; 
        for(int i = 1; i <= upperBounds; i++) {
            sum += i;
        }
        return sum;
    }
}
class Test {
    public static void main(String[] args) throws Exception {
        List<Future<Integer>> list = new ArrayList<>();
        ExecutorService service = Executors.newFixedThreadPool(10);
        for(int i = 0; i < 10; i++) {
            list.add(service.submit(new MyTask((int) (Math.random() * 100))));
        }
        int sum = 0;
        for(Future<Integer> future : list) {
            // while(!future.isDone()) ;
            sum += future.get();
        }
        System.out.println(sum);
    }
}

62. How to use synchronized keyword?

Answer: The synchronized keyword can mark objects or methods as synchronized to achieve mutually exclusive access to objects and methods. You can use synchronized(object) {…} to define a synchronized code block, or use synchronized as a method modification when declaring a method symbol. The usage of the synchronized keyword has been demonstrated in the example of question 60.

63. Give examples of synchronous and asynchronous.

Answer: If there are critical resources in the system (the number of resources is less than the number of threads competing for resources), for example, the data being written may be read by another thread in the future, or the data being read may have been written by another thread. , Then these data must be accessed synchronously (exclusive locks in database operations are the best example). When an application calls a method on an object that takes a long time to execute, and does not want the program to wait for the method to return, it should use asynchronous programming. In many cases, it is more efficient to use asynchronous methods. In fact, the so-called synchronization refers to blocking operations, and asynchronous refers to non-blocking operations.

64. To start a thread, do you call the run() or start() method?

Answer: To start a thread is to call the start() method to make the virtual processor represented by the thread in a runnable state. This means that it can be scheduled and executed by the JVM. This does not mean that the thread will run immediately. The run() method is a callback method after the thread starts.

65. What is a thread pool?

Answer: In object-oriented programming, creating and destroying objects is time-consuming, because creating an object requires access to memory resources or more resources. This is especially true in Java, where the virtual machine will try to track every object so that it can be garbage collected after the object is destroyed. Therefore, one way to improve the efficiency of the service program is to reduce the number of creation and destruction of objects as much as possible, especially the creation and destruction of some resource-intensive objects. This is the reason for the "pooled resource" technology. The thread pool, as the name implies, is to create several executable threads in advance and put them into a pool (container). When you need to get threads from the pool, you don’t need to create them. You don’t need to destroy the threads but put them back into the pool when you need them. The cost of destroying thread objects.
The Executor interface in Java 5+ defines a tool for executing threads. Its subtype, thread pool interface, is ExecutorService. It is more complicated to configure a thread pool, especially when the principle of the thread pool is not very clear. Therefore, some static factory methods are provided on the Executors side of the tool class to generate some commonly used thread pools, as shown below:

  • newSingleThreadExecutor: Create a single-threaded thread pool. This thread pool has only one thread working, which is equivalent to a single thread performing all tasks serially. If the only thread ends abnormally, there will be a new thread to replace it. This thread pool guarantees that the order of execution of all tasks is executed in the order of task submission.
  • newFixedThreadPool: Create a fixed-size thread pool. Every time a task is submitted, a thread is created until the thread reaches the maximum size of the thread pool. Once the size of the thread pool reaches the maximum, it will remain unchanged. If a thread ends due to an abnormal execution, the thread pool will be supplemented with a new thread.
  • newCachedThreadPool: Create a cacheable thread pool. If the size of the thread pool exceeds the threads required to process tasks, some idle threads (without performing tasks for 60 seconds) will be recycled. When the number of tasks increases, the thread pool can intelligently add new threads to process tasks. This thread pool does not limit the size of the thread pool. The size of the thread pool is completely dependent on the maximum thread size that the operating system (or JVM) can create.
  • newScheduledThreadPool: Create a thread pool of unlimited size. This thread pool supports the needs of timed and periodic execution of tasks.
  • newSingleThreadExecutor: Create a single-threaded thread pool. This thread pool supports the needs of timed and periodic execution of tasks.
    The example in question 60 demonstrates the code that creates a thread pool through the Executors tool class and uses the thread pool to execute threads. If you want to use the thread pool on the server, it is strongly recommended to use the newFixedThreadPool method to create the thread pool, so that you can get better performance.

    66. The basic state of threads and the relationship between states?

    answer:
    Complete Works of Java Interview Questions(7)

Note: Running means running state, Runnable means ready state (everything is ready, only owes CPU), Blocked means blocking state, there are many situations in blocking state, which may be because the wait() method is called to enter the waiting pool, or it may be The execution of the synchronization method or synchronization code block enters the waiting lock pool, or the sleep() method or join() method is called to wait for the end of sleep or other threads, or because an I/O interruption occurs.

67. Briefly describe the similarities and differences between synchronized and java.util.concurrent.locks.Lock?

Answer: Lock is a new API introduced after Java 5. Compared with the keyword synchronized, the main similarities are: Lock can complete all the functions realized by synchronized; the main difference: Lock has more precise thread semantics and better than synchronized Performance, and it is not mandatory to obtain a lock. Synchronized will automatically release the lock, and Lock must require the programmer to release it manually, and it is best to release it in the finally block (this is the best place to release external resources).

68. How to realize serialization in Java and what is the significance?

Answer: Serialization is a mechanism for processing object streams. The so-called object stream is to stream the content of objects. You can read and write the streamed objects, and you can also transfer the streamed objects between networks. Serialization is to solve the problems that may arise during the read and write operations of the object stream (the data may be out of order if it is not serialized).
To achieve serialization, you need to make a class implement the Serializable interface, which is an identifying interface, mark that the object of this class can be serialized, and then use an output stream to construct an object output stream and pass the writeObject(Object) method You can write out the implementation object (that is, save its state); if you need to deserialize it, you can use an input stream to create an object input stream, and then read the object from the stream through the readObject method. In addition to achieving object persistence, serialization can also be used for deep cloning of objects (see question 29).

69. How many types of streams are there in Java?

Answer: Byte stream and character stream. The byte stream is inherited from InputStream and OutputStream, and the character stream is inherited from Reader and Writer. There are many other streams in the java.io package, mainly to improve performance and ease of use. There are two points to note about Java I/O: one is two symmetry (the symmetry of input and output, the symmetry of bytes and characters); the other is two design modes (adapter mode and decoration mode). In addition, the flow in Java is different from C# in that it has only one dimension and one direction.

Interview Questions-Programming to realize file copy. (This topic often appears during the written test, the following code gives two implementation schemes)


import java.io.FileInputStream;
import java.io.FileOutputStream;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public final class MyUtil {
    private MyUtil() {
        throw new AssertionError();
    }
    public static void fileCopy(String source, String target) throws IOException {
        try (InputStream in = new FileInputStream(source)) {
            try (OutputStream out = new FileOutputStream(target)) {
                byte[] buffer = new byte[4096];
                int bytesToRead;
                while((bytesToRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesToRead);
                }
            }
        }
    }
    public static void fileCopyNIO(String source, String target) throws IOException {
        try (FileInputStream in = new FileInputStream(source)) {
            try (FileOutputStream out = new FileOutputStream(target)) {
                FileChannel inChannel = in.getChannel();
                FileChannel outChannel = out.getChannel();
                ByteBuffer buffer = ByteBuffer.allocate(4096);
                while(inChannel.read(buffer) != -1) {
                    buffer.flip();
                    outChannel.write(buffer);
                    buffer.clear();
                }
            }
        }
    }
}

Note : The Java 7 TWR is used above. After using TWR, you don't need to release external resources in finally, which makes the code more elegant.

70. Write a method, enter a file name and a string, and count the number of times this string appears in the file.

Answer: The code is as follows:


import java.io.BufferedReader;
import java.io.FileReader;
public final class MyUtil {
    // 工具类中的方法都是静态方式访问的因此将构造器私有不允许创建对象(绝对好习惯)
    private MyUtil() {
        throw new AssertionError();
    }

    /**     * 统计给定文件中给定字符串的出现次数     *     * @param filename  文件名     * @param word 字符串     * @return 字符串在文件中出现的次数     */
    public static int countWordInFile(String filename, String word) {
        int counter = 0;
        try (FileReader fr = new FileReader(filename)) {
            try (BufferedReader br = new BufferedReader(fr)) {
                String line = null;
                while ((line = br.readLine()) != null) {
                    int index = -1;
                    while (line.length() >= word.length() && (index = line.indexOf(word)) >= 0) {
                        counter++;
                        line = line.substring(index + word.length());
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return counter;
    }
}

Guess you like

Origin blog.51cto.com/15061944/2593694